aboutsummaryrefslogtreecommitdiffhomepage
path: root/main/app/sprinkles/core/assets/SiteAssets
diff options
context:
space:
mode:
Diffstat (limited to 'main/app/sprinkles/core/assets/SiteAssets')
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/css/main.css250
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/css/slick.css2
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/icons/BurgerMenuShort.svg57
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/icons/ExploreGlobeOutline.svg210
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/icons/FriendFeedOutline.svg82
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/icons/MessageBubbleOutline.svg73
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/icons/UserGroupOutline.svg80
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/icons/UserOutline.svg54
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/js/chat.js117
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/js/encryption.js3407
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/js/fontawesome.js5
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/js/jquery.js4
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/js/language.js36
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/js/linkify.js369
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/js/main.js91
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/js/modernizr.js1
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/js/slick.js556
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/languages/ExcelFile.xlsbin0 -> 52736 bytes
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/languages/json/Translations.json50
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/languages/json/de.json14
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/languages/json/en.json14
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/languages/json/fr.json14
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/languages/json/kl.json14
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/Chatserver/bin/WebChatServer.php18
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/Chatserver/src/ChatProcessor.php118
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/SavePublicKey.php17
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/composer.json11
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/composer.lock943
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/scripts.php12
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/stylesheet.php6
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/autoload.php7
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/.gitignore5
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/.travis.yml20
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/CHANGELOG.md135
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/LICENSE19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/Makefile42
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/README.md83
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/composer.json36
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/phpunit.xml.dist30
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/AbstractConnectionDecorator.php41
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/App.php145
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/ComponentInterface.php31
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/ConnectionInterface.php26
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Http/CloseResponseTrait.php22
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Http/HttpRequestParser.php64
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Http/HttpServer.php76
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Http/HttpServerInterface.php14
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Http/NoOpHttpServerController.php18
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Http/OriginCheck.php65
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Http/Router.php96
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/MessageComponentInterface.php5
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/MessageInterface.php12
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Server/EchoServer.php23
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Server/FlashPolicy.php200
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Server/IoConnection.php38
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Server/IoServer.php140
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Server/IpBlackList.php111
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Session/Serialize/HandlerInterface.php16
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Session/Serialize/PhpBinaryHandler.php33
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Session/Serialize/PhpHandler.php49
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Session/SessionProvider.php243
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Session/Storage/Proxy/VirtualProxy.php54
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Session/Storage/VirtualSessionStorage.php88
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/Exception.php5
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/JsonException.php31
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/ServerProtocol.php161
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/Topic.php99
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/TopicManager.php125
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/WampConnection.php115
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/WampServer.php67
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/WampServerInterface.php43
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/ConnContext.php20
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/MessageCallableInterface.php8
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/MessageComponentInterface.php6
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/WsConnection.php45
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/WsServer.php225
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/WsServerInterface.php14
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/autobahn/bin/fuzzingserver.php36
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/autobahn/fuzzingclient-all.json15
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/autobahn/fuzzingclient-profile.json12
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/autobahn/fuzzingclient-quick.json12
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/bootstrap.php4
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/AbstractMessageComponentTestCase.php50
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/Component.php35
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/Connection.php20
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/ConnectionDecorator.php22
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/WampComponent.php43
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/NullComponent.php28
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Wamp/Stub/WsWampServerInterface.php7
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/WebSocket/Stub/WsMessageComponentInterface.php7
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/AbstractConnectionDecoratorTest.php147
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Http/HttpRequestParserTest.php50
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Http/HttpServerTest.php64
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Http/OriginCheckTest.php46
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Http/RouterTest.php165
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Server/EchoServerTest.php26
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Server/FlashPolicyComponentTest.php152
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Server/IoConnectionTest.php32
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Server/IoServerTest.php118
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Server/IpBlackListComponentTest.php125
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Session/Serialize/PhpHandlerTest.php43
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Session/SessionComponentTest.php124
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Session/Storage/VirtualSessionStoragePDOTest.php53
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Wamp/ServerProtocolTest.php295
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Wamp/TopicManagerTest.php226
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Wamp/TopicTest.php164
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Wamp/WampConnectionTest.php77
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Wamp/WampServerTest.php49
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/ClassLoader.php445
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/LICENSE21
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/autoload_classmap.php84
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/autoload_files.php15
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/autoload_namespaces.php10
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/autoload_psr4.php28
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/autoload_real.php70
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/autoload_static.php238
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/installed.json1125
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/.gitignore2
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/.travis.yml24
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/CHANGELOG.md35
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/LICENSE19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/README.md83
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/composer.json29
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/doc/00-intro.md28
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/doc/01-api.md91
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/doc/02-plugin-system.md155
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/examples/benchmark-emit-no-arguments.php28
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/examples/benchmark-emit-once.php30
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/examples/benchmark-emit-one-argument.php28
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/examples/benchmark-emit.php28
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/examples/benchmark-remove-listener-once.php39
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/phpunit.xml.dist24
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/src/Evenement/EventEmitter.php17
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/src/Evenement/EventEmitterInterface.php22
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php135
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/tests/Evenement/Tests/EventEmitterTest.php438
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/tests/Evenement/Tests/Listener.php51
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/tests/Evenement/Tests/functions.php17
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/CHANGELOG.md110
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/LICENSE19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/README.md739
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/composer.json39
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/AppendStream.php233
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/BufferStream.php137
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/CachingStream.php138
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/DroppingStream.php42
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/FnStream.php149
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/InflateStream.php52
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/LazyOpenStream.php39
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/LimitStream.php155
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/MessageTrait.php183
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/MultipartStream.php153
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/NoSeekStream.php22
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/PumpStream.php165
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/Request.php142
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/Response.php132
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/ServerRequest.php358
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/Stream.php257
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/StreamDecoratorTrait.php149
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/StreamWrapper.php121
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/UploadedFile.php316
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/Uri.php702
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/UriNormalizer.php216
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/UriResolver.php219
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/functions.php828
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/functions_include.php6
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/CHANGELOG-1.0.md36
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/CHANGELOG-1.1.md57
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/CHANGELOG-1.2.md49
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/Gemfile5
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/LICENSE19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/README.md345
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/composer.json56
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/package.json19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCache.php174
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCollection.php238
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCollectionInterface.php59
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetInterface.php166
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetReference.php164
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/BaseAsset.php181
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/FileAsset.php78
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/GlobAsset.php115
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/HttpAsset.php79
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/Iterator/AssetCollectionFilterIterator.php84
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/Iterator/AssetCollectionIterator.php128
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/StringAsset.php55
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/AssetManager.php89
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/AssetWriter.php94
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Cache/ApcCache.php66
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Cache/ArrayCache.php58
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Cache/CacheInterface.php53
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Cache/ConfigCache.php123
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Cache/ExpiringCache.php60
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Cache/FilesystemCache.php65
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Exception/Exception.php21
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Exception/FilterException.php73
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticExtension.php76
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterFunction.php24
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterInvoker.php59
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterNode.php22
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticNode.php165
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticTokenParser.php198
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/TwigFormulaLoader.php108
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/TwigResource.php56
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/ValueContainer.php79
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/AssetFactory.php424
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/LazyAssetManager.php210
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/BasePhpFormulaLoader.php160
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/CachedFormulaLoader.php68
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/FormulaLoaderInterface.php34
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/FunctionCallsFormulaLoader.php53
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/CoalescingDirectoryResource.php112
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/DirectoryResource.php133
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/FileResource.php47
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/IteratorResourceInterface.php21
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/ResourceInterface.php43
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Worker/CacheBustingWorker.php70
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Worker/EnsureFilterWorker.php61
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Worker/WorkerInterface.php33
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/AutoprefixerFilter.php87
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/BaseCssFilter.php54
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/BaseNodeFilter.php44
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/BaseProcessFilter.php57
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CallablesFilter.php62
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CleanCssFilter.php343
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CoffeeScriptFilter.php83
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CompassFilter.php391
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssCacheBustingFilter.php65
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssEmbedFilter.php143
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssImportFilter.php108
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssMinFilter.php72
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssRewriteFilter.php102
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/DartFilter.php73
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/DependencyExtractorInterface.php34
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/EmberPrecompileFilter.php87
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/FilterCollection.php82
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/FilterInterface.php36
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/BaseCompilerFilter.php101
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/CompilerApiFilter.php130
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/CompilerJarFilter.php112
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/GssFilter.php142
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/HandlebarsFilter.php106
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/HashableInterface.php27
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/JSMinFilter.php34
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/JSMinPlusFilter.php34
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/JSqueezeFilter.php77
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/JpegoptimFilter.php81
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/JpegtranFilter.php103
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/LessFilter.php206
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/LessphpFilter.php167
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/MinifyCssCompressorFilter.php35
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/OptiPngFilter.php75
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/PackagerFilter.php65
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/PackerFilter.php56
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/PhpCssEmbedFilter.php52
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/PngoutFilter.php128
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/ReactJsxFilter.php75
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/RooleFilter.php84
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/Sass/BaseSassFilter.php95
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/Sass/SassFilter.php186
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/Sass/ScssFilter.php28
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/SassphpFilter.php132
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/ScssphpFilter.php147
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/SeparatorFilter.php47
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/SprocketsFilter.php152
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/StylusFilter.php126
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/TypeScriptFilter.php80
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/UglifyCssFilter.php120
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/UglifyJs2Filter.php152
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/UglifyJsFilter.php160
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/BaseCompressorFilter.php117
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/CssCompressorFilter.php28
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/JsCompressorFilter.php61
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/FilterManager.php64
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Util/CssUtils.php138
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Util/FilesystemUtils.php84
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Util/LessUtils.php24
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Util/SassUtils.php22
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Util/TraversableString.php44
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Util/VarUtils.php84
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/ValueSupplierInterface.php29
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/functions.php125
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/lmammino/jsmin4assetic/LICENSE19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/lmammino/jsmin4assetic/README.markdown21
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/lmammino/jsmin4assetic/composer.json26
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/lmammino/jsmin4assetic/src/JSMin.php379
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/lmammino/jsmin4assetic/src/JSMinUnterminatedCommentException.php5
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/lmammino/jsmin4assetic/src/JSMinUnterminatedRegExpException.php5
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/lmammino/jsmin4assetic/src/JSMinUnterminatedStringException.php5
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/CONTRIBUTING.md59
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/Dockerfile13
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/LICENSE18
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/bin/minifycss45
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/bin/minifyjs45
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/composer.json38
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/data/js/keywords_after.txt7
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/data/js/keywords_before.txt26
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/data/js/keywords_reserved.txt63
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/data/js/operators.txt46
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/data/js/operators_after.txt43
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/data/js/operators_before.txt43
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/docker-compose.yml31
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/src/CSS.php736
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/src/Exception.php20
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/src/Exceptions/BasicException.php23
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/src/Exceptions/FileImportException.php21
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/src/Exceptions/IOException.php21
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/src/JS.php598
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/src/Minify.php454
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/path-converter/LICENSE18
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/path-converter/composer.json28
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/path-converter/src/Converter.php195
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/path-converter/src/ConverterInterface.php24
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/path-converter/src/NoConverter.php23
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/natxet/CssMin/README3
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/natxet/CssMin/composer.json26
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/natxet/CssMin/src/CssMin.php5155
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/.coveralls.yml3
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/.gitignore2
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/.scrutinizer.yml19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/.travis.yml9
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/CONTRIBUTING.md38
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/Dockerfile.tests5
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/LICENSE21
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/README.md91
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/build.php25
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/composer.json30
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/composer.lock1963
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/docker-compose.yml8
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/phpunit.xml10
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/AbstractGenerator.php19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/All.php62
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/Alliteration.php59
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/Generator.php16
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/Vgng.php138
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/adjectives.txt233
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/nouns.txt313
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/video_game_names.txt1276
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/tests/AllTest.php72
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/tests/AlliterationTest.php66
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/tests/VgngTest.php67
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/LICENSE22
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/build-phar.sh5
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/composer.json37
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey5
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc11
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/byte_safe_strings.php181
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/cast_to_int.php75
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/error_polyfill.php49
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/random.php225
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/random_bytes_com_dotnet.php88
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/random_bytes_dev_urandom.php167
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/random_bytes_libsodium.php88
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/random_bytes_libsodium_legacy.php92
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/random_bytes_mcrypt.php77
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/random_int.php190
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/other/build_phar.php57
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/psalm-autoload.php9
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/psalm.xml18
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/CHANGELOG.md36
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/LICENSE19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/README.md13
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/composer.json26
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/src/MessageInterface.php187
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/src/RequestInterface.php129
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/src/ResponseInterface.php68
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/src/ServerRequestInterface.php261
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/src/StreamInterface.php158
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/src/UploadedFileInterface.php123
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/src/UriInterface.php323
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/.gitignore4
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/.travis.yml20
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/LICENSE19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/README.md13
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/composer.json32
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/phpunit.xml.dist27
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Handshake/ClientNegotiator.php53
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Handshake/NegotiatorInterface.php47
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Handshake/RequestVerifier.php140
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Handshake/ResponseVerifier.php52
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Handshake/ServerNegotiator.php136
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Messaging/CloseFrameChecker.php24
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Messaging/DataInterface.php34
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Messaging/Frame.php473
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Messaging/FrameInterface.php38
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Messaging/Message.php123
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Messaging/MessageBuffer.php231
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Messaging/MessageInterface.php20
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/AbResultsTest.php30
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/ab/clientRunner.php228
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/ab/fuzzingclient.json14
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/ab/fuzzingserver.json10
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/ab/run_ab_tests.sh11
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/ab/startServer.php55
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/bootstrap.php19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/unit/Handshake/RequestVerifierTest.php177
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/unit/Handshake/ResponseVerifierTest.php34
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/unit/Handshake/ServerNegotiatorTest.php175
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/unit/Messaging/FrameTest.php501
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/unit/Messaging/MessageBufferTest.php39
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/unit/Messaging/MessageTest.php58
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/.gitignore2
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/.travis.yml25
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/CHANGELOG.md35
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/LICENSE19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/README.md171
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/composer.json19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/phpunit.xml.dist20
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/src/ArrayCache.php29
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/src/CacheInterface.php13
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/tests/ArrayCacheTest.php60
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/tests/CallableStub.php10
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/tests/TestCase.php43
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/.gitignore2
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/.travis.yml29
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/CHANGELOG.md179
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/LICENSE19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/README.md209
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/composer.json24
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/examples/01-one.php22
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/examples/02-concurrent.php27
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/examples/03-cached.php40
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/examples/04-query-a-and-aaaa.php32
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/phpunit.xml.dist25
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/BadServerException.php7
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Config/Config.php127
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Config/FilesystemFactory.php73
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Config/HostsFile.php151
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Model/HeaderBag.php56
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Model/Message.php100
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Model/Record.php21
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Protocol/BinaryDumper.php62
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Protocol/Parser.php254
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/CachedExecutor.php55
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/CancellationException.php7
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/Executor.php156
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/ExecutorInterface.php8
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/HostsFileExecutor.php89
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/Query.php19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/RecordBag.php27
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/RecordCache.php82
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/RetryExecutor.php44
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/TimeoutException.php7
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/TimeoutExecutor.php32
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/RecordNotFoundException.php7
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Resolver/Factory.php103
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Resolver/Resolver.php100
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/CallableStub.php10
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Config/ConfigTest.php189
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Config/FilesystemFactoryTest.php70
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Config/HostsFileTest.php170
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Fixtures/etc/resolv.conf1
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/FunctionalResolverTest.php71
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Model/MessageTest.php30
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Protocol/BinaryDumperTest.php48
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Protocol/ParserTest.php343
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Query/CachedExecutorTest.php100
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Query/ExecutorTest.php308
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Query/HostsFileExecutorTest.php126
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Query/RecordBagTest.php64
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Query/RecordCacheTest.php123
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Query/RetryExecutorTest.php197
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Query/TimeoutExecutorTest.php115
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Resolver/FactoryTest.php131
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Resolver/ResolveAliasesTest.php100
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Resolver/ResolverTest.php129
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/TestCase.php61
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/.gitignore3
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/.travis.yml39
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/CHANGELOG.md316
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/LICENSE19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/README.md702
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/composer.json21
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/01-timers.php15
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/02-periodic.php16
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/03-ticks.php15
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/04-signals.php19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/11-consume-stdin.php30
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/12-generate-yes.php41
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/13-http-client-blocking.php35
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/14-http-client-async.php63
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/21-http-server.php36
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/91-benchmark-ticks.php15
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/92-benchmark-timers.php15
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/93-benchmark-ticks-delay.php22
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/94-benchmark-timers-delay.php22
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/95-benchmark-memory.php67
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/phpunit.xml.dist25
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/ExtEvLoop.php252
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/ExtEventLoop.php259
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/ExtLibevLoop.php199
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/ExtLibeventLoop.php283
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/Factory.php41
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/LoopInterface.php463
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/SignalsHandler.php63
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/StreamSelectLoop.php275
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/Tick/FutureTickQueue.php60
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/Timer/Timer.php55
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/Timer/Timers.php109
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/TimerInterface.php27
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/AbstractLoopTest.php621
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/CallableStub.php10
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/ExtEvLoopTest.php17
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/ExtEventLoopTest.php84
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/ExtLibevLoopTest.php22
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/ExtLibeventLoopTest.php58
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/SignalsHandlerTest.php55
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/StreamSelectLoopTest.php148
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/TestCase.php53
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/Timer/AbstractTimerTest.php122
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/Timer/ExtEvTimerTest.php17
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/Timer/ExtEventTimerTest.php17
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/Timer/ExtLibevTimerTest.php17
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/Timer/ExtLibeventTimerTest.php17
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/Timer/StreamSelectTimerTest.php13
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/Timer/TimersTest.php27
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/bootstrap.php15
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/travis-init.sh42
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/.gitignore2
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/.travis.yml26
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/CHANGELOG.md40
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/LICENSE21
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/README.md372
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/composer.json28
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/phpunit.xml.dist19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/src/TimeoutException.php22
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/src/functions.php70
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/tests/CallableStub.php10
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/tests/FunctionRejectTest.php49
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/tests/FunctionResolveTest.php71
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/tests/FunctionTimeoutTest.php169
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/tests/TestCase.php61
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/tests/TimeoutExceptionTest.php15
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/.gitignore5
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/.travis.yml22
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/CHANGELOG.md96
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/LICENSE22
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/README.md840
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/composer.json29
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/phpunit.xml.dist28
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/CancellablePromiseInterface.php11
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/CancellationQueue.php55
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/Deferred.php60
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/Exception/LengthException.php7
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/ExtendedPromiseInterface.php26
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/FulfilledPromise.php68
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/LazyPromise.php63
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/Promise.php216
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/PromiseInterface.php11
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/PromisorInterface.php11
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/RejectedPromise.php76
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/UnhandledRejectionException.php31
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/functions.php244
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/functions_include.php5
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/CancellationQueueTest.php100
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/DeferredTest.php42
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FulfilledPromiseTest.php50
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionAllTest.php114
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionAnyTest.php204
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionCheckTypehintTest.php118
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionMapTest.php198
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionRaceTest.php211
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionReduceTest.php347
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionRejectTest.php64
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionResolveTest.php171
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionSomeTest.php258
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/LazyPromiseTest.php107
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseAdapter/CallbackPromiseAdapter.php40
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseAdapter/PromiseAdapterInterface.php14
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest.php84
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/CancelTestTrait.php231
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/FullTestTrait.php15
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/NotifyTestTrait.php336
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/PromiseFulfilledTestTrait.php351
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/PromisePendingTestTrait.php68
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/PromiseRejectedTestTrait.php512
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/PromiseSettledTestTrait.php86
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/RejectTestTrait.php368
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/ResolveTestTrait.php312
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/RejectedPromiseTest.php50
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/Stub/CallableStub.php10
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/TestCase.php43
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/bootstrap.php7
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/fixtures/SimpleFulfilledTestPromise.php21
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/fixtures/SimpleFulfilledTestThenable.php21
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/fixtures/SimpleRejectedTestPromise.php21
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/fixtures/SimpleTestCancellable.php13
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/fixtures/SimpleTestCancellableThenable.php18
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/.gitignore2
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/.travis.yml49
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/CHANGELOG.md451
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/LICENSE19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/README.md1419
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/composer.json29
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/01-echo-server.php42
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/02-chat-server.php59
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/03-http-server.php57
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/11-http-client.php36
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/12-https-client.php36
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/21-netcat-client.php68
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/22-http-client.php60
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/91-benchmark-server.php60
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/99-generate-self-signed.php31
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/localhost.pem49
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/localhost_swordfish.pem51
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/phpunit.xml.dist25
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/Connection.php178
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/ConnectionInterface.php119
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/Connector.php136
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/ConnectorInterface.php58
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/DnsConnector.php111
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/FixedUriConnector.php41
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/LimitingServer.php203
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/SecureConnector.php64
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/SecureServer.php192
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/Server.php73
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/ServerInterface.php151
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/StreamEncryption.php146
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/TcpConnector.php122
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/TcpServer.php236
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/TimeoutConnector.php25
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/UnixConnector.php44
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/UnixServer.php130
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/ConnectionTest.php47
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/ConnectorTest.php128
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/DnsConnectorTest.php111
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/FixedUriConnectorTest.php19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/FunctionalConnectorTest.php32
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/FunctionalSecureServerTest.php438
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/FunctionalTcpServerTest.php324
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/IntegrationTest.php171
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/LimitingServerTest.php195
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/SecureConnectorTest.php74
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/SecureIntegrationTest.php204
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/SecureServerTest.php105
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/ServerTest.php173
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/Stub/CallableStub.php10
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/Stub/ConnectionStub.php63
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/Stub/ServerStub.php18
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/TcpConnectorTest.php255
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/TcpServerTest.php285
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/TestCase.php101
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/TimeoutConnectorTest.php103
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/UnixConnectorTest.php64
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/UnixServerTest.php283
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/.gitignore2
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/.travis.yml50
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/CHANGELOG.md377
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/LICENSE19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/README.md1224
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/composer.json25
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/examples/01-http.php40
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/examples/02-https.php40
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/examples/11-cat.php28
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/examples/91-benchmark-throughput.php62
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/phpunit.xml.dist25
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/CompositeStream.php82
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/DuplexResourceStream.php224
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/DuplexStreamInterface.php39
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/ReadableResourceStream.php177
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/ReadableStreamInterface.php362
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/ThroughStream.php190
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/Util.php75
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/WritableResourceStream.php171
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/WritableStreamInterface.php347
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/CallableStub.php10
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/CompositeStreamTest.php267
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/DuplexResourceStreamIntegrationTest.php352
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/DuplexResourceStreamTest.php495
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/EnforceBlockingWrapper.php35
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/FunctionalInternetTest.php122
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/ReadableResourceStreamTest.php372
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/Stub/ReadableStreamStub.php61
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/TestCase.php54
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/ThroughStreamTest.php267
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/UtilTest.php273
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/WritableStreamResourceTest.php534
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/.gitignore3
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/AcceptHeader.php168
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/AcceptHeaderItem.php209
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/ApacheRequest.php43
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/BinaryFileResponse.php359
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/CHANGELOG.md159
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Cookie.php289
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Exception/ConflictingHeadersException.php21
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Exception/RequestExceptionInterface.php21
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Exception/SuspiciousOperationException.php20
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/ExpressionRequestMatcher.php47
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/Exception/AccessDeniedException.php28
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/Exception/FileException.php21
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/Exception/FileNotFoundException.php28
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/Exception/UnexpectedTypeException.php20
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/Exception/UploadException.php21
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/File.php136
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/MimeType/ExtensionGuesser.php94
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/MimeType/ExtensionGuesserInterface.php27
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/MimeType/FileBinaryMimeTypeGuesser.php85
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/MimeType/FileinfoMimeTypeGuesser.php69
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/MimeType/MimeTypeExtensionGuesser.php808
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/MimeType/MimeTypeGuesser.php142
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/MimeType/MimeTypeGuesserInterface.php35
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/Stream.php28
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/UploadedFile.php266
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/FileBag.php144
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/HeaderBag.php331
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/IpUtils.php156
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/JsonResponse.php220
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/LICENSE19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/ParameterBag.php234
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/README.md14
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/RedirectResponse.php109
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Request.php2154
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/RequestMatcher.php178
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/RequestMatcherInterface.php27
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/RequestStack.php103
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Response.php1298
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/ResponseHeaderBag.php340
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/ServerBag.php102
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Attribute/AttributeBag.php148
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Attribute/AttributeBagInterface.php72
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Attribute/NamespacedAttributeBag.php153
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Flash/AutoExpireFlashBag.php161
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Flash/FlashBag.php152
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Flash/FlashBagInterface.php93
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Session.php273
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/SessionBagInterface.php46
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/SessionBagProxy.php82
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/SessionInterface.php180
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/AbstractSessionHandler.php168
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/MemcacheSessionHandler.php120
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/MemcachedSessionHandler.php124
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/MongoDbSessionHandler.php255
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/NativeFileSessionHandler.php55
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/NativeSessionHandler.php24
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/NullSessionHandler.php76
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php910
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/StrictSessionHandler.php103
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/WriteCheckSessionHandler.php92
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/MetadataBag.php168
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/MockArraySessionStorage.php256
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/MockFileSessionStorage.php152
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php445
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/PhpBridgeSessionStorage.php59
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php122
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Proxy/NativeProxy.php40
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php85
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/SessionStorageInterface.php137
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/StreamedResponse.php144
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/AcceptHeaderItemTest.php113
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/AcceptHeaderTest.php103
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/ApacheRequestTest.php93
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/BinaryFileResponseTest.php352
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/CookieTest.php223
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/ExpressionRequestMatcherTest.php69
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/FakeFile.php45
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/FileTest.php180
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/Fixtures/.unknownextension1
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/Fixtures/directory/.empty0
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/Fixtures/other-file.example0
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/Fixtures/testbin0 -> 35 bytes
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/Fixtures/test.gifbin0 -> 35 bytes
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/MimeType/MimeTypeTest.php90
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/UploadedFileTest.php273
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/FileBagTest.php175
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/HeaderBagTest.php205
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/IpUtilsTest.php104
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/JsonResponseTest.php257
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/ParameterBagTest.php194
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/RedirectResponseTest.php97
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/RequestMatcherTest.php151
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/RequestStackTest.php70
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/RequestTest.php2329
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/ResponseHeaderBagTest.php363
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/ResponseTest.php1003
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/ResponseTestCase.php89
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/ServerBagTest.php170
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Attribute/AttributeBagTest.php186
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Attribute/NamespacedAttributeBagTest.php182
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Flash/AutoExpireFlashBagTest.php161
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Flash/FlashBagTest.php132
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/SessionTest.php242
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/AbstractSessionHandlerTest.php61
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/common.inc151
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/empty_destroys.expected17
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/empty_destroys.php8
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/read_only.expected14
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/read_only.php8
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/regenerate.expected24
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/regenerate.php10
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/storage.expected20
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/storage.php24
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/with_cookie.expected15
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/with_cookie.php8
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/with_cookie_and_session.expected24
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/with_cookie_and_session.php13
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/MemcacheSessionHandlerTest.php135
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php139
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/MongoDbSessionHandlerTest.php333
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/NativeFileSessionHandlerTest.php77
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/NativeSessionHandlerTest.php38
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/NullSessionHandlerTest.php59
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php411
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/StrictSessionHandlerTest.php189
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/WriteCheckSessionHandlerTest.php97
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/MetadataBagTest.php139
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/MockArraySessionStorageTest.php131
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/MockFileSessionStorageTest.php127
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/NativeSessionStorageTest.php277
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/PhpBridgeSessionStorageTest.php96
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Proxy/AbstractProxyTest.php113
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Proxy/NativeProxyTest.php38
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Proxy/SessionHandlerProxyTest.php124
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/StreamedResponseTest.php126
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/schema/http-status-codes.rng31
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/schema/iana-registry.rng198
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/composer.json38
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/phpunit.xml.dist31
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-mbstring/LICENSE19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-mbstring/Mbstring.php791
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-mbstring/README.md13
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php1101
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php1109
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-mbstring/bootstrap.php58
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-mbstring/composer.json34
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/LICENSE19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Php70.php74
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/README.md28
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Resources/stubs/ArithmeticError.php5
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Resources/stubs/AssertionError.php5
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Resources/stubs/DivisionByZeroError.php5
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Resources/stubs/Error.php5
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Resources/stubs/ParseError.php5
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Resources/stubs/SessionUpdateTimestampHandlerInterface.php23
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Resources/stubs/TypeError.php5
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/bootstrap.php27
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/composer.json33
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/.gitignore3
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/CHANGELOG.md57
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Exception/ExceptionInterface.php21
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Exception/InvalidArgumentException.php21
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Exception/LogicException.php21
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Exception/ProcessFailedException.php54
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Exception/ProcessTimedOutException.php69
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Exception/RuntimeException.php21
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/ExecutableFinder.php88
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/InputStream.php92
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/LICENSE19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/PhpExecutableFinder.php94
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/PhpProcess.php76
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Pipes/AbstractPipes.php168
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Pipes/PipesInterface.php67
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Pipes/UnixPipes.php150
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Pipes/WindowsPipes.php196
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Process.php1751
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/ProcessBuilder.php280
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/ProcessUtils.php123
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/README.md13
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/ExecutableFinderTest.php133
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/NonStopableProcess.php47
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/PhpExecutableFinderTest.php72
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/PhpProcessTest.php48
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/PipeStdinInStdoutStdErrStreamSelect.php72
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/ProcessBuilderTest.php226
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/ProcessFailedExceptionTest.php137
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/ProcessTest.php1621
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/ProcessUtilsTest.php53
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/SignalListener.php21
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/composer.json33
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/phpunit.xml.dist30
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/.gitignore3
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Annotation/Route.php144
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/CHANGELOG.md228
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/CompiledRoute.php169
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/DependencyInjection/RoutingResolverPass.php49
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Exception/ExceptionInterface.php21
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Exception/InvalidParameterException.php21
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Exception/MethodNotAllowedException.php41
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Exception/MissingMandatoryParametersException.php22
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Exception/NoConfigurationException.php21
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Exception/ResourceNotFoundException.php23
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Exception/RouteNotFoundException.php21
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Generator/ConfigurableRequirementsInterface.php55
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Generator/Dumper/GeneratorDumper.php37
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Generator/Dumper/GeneratorDumperInterface.php39
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Generator/Dumper/PhpGeneratorDumper.php118
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Generator/UrlGenerator.php321
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Generator/UrlGeneratorInterface.php86
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/LICENSE19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/AnnotationClassLoader.php269
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/AnnotationDirectoryLoader.php93
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/AnnotationFileLoader.php142
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/ClosureLoader.php46
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/Configurator/CollectionConfigurator.php81
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/Configurator/ImportConfigurator.php49
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/Configurator/RouteConfigurator.php34
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/Configurator/RoutingConfigurator.php62
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/Configurator/Traits/AddTrait.php55
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/Configurator/Traits/RouteTrait.php131
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/DependencyInjection/ServiceRouterLoader.php40
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/DirectoryLoader.php58
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/GlobFileLoader.php47
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/ObjectRouteLoader.php95
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/PhpFileLoader.php75
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/XmlFileLoader.php359
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/YamlFileLoader.php233
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/schema/routing/routing-1.0.xsd148
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/Dumper/DumperCollection.php159
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/Dumper/DumperRoute.php57
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/Dumper/MatcherDumper.php37
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/Dumper/MatcherDumperInterface.php39
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/Dumper/PhpMatcherDumper.php429
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/Dumper/StaticPrefixCollection.php238
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/RedirectableUrlMatcher.php65
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/RedirectableUrlMatcherInterface.php31
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/RequestMatcherInterface.php39
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/TraceableUrlMatcher.php141
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/UrlMatcher.php252
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/UrlMatcherInterface.php41
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/README.md13
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/RequestContext.php336
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/RequestContextAwareInterface.php27
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Route.php558
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/RouteCollection.php280
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/RouteCollectionBuilder.php380
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/RouteCompiler.php316
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/RouteCompilerInterface.php30
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Router.php388
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/RouterInterface.php32
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Annotation/RouteTest.php50
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/CompiledRouteTest.php27
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/DependencyInjection/RoutingResolverPassTest.php36
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/AbstractClass.php16
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/BarClass.php19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/BazClass.php19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/FooClass.php16
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/FooTrait.php13
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/CustomCompiledRoute.php18
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/CustomRouteCompiler.php26
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/CustomXmlFileLoader.php26
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/OtherAnnotatedClasses/AnonymousClassInTrait.php24
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/OtherAnnotatedClasses/NoStartTagClass.php3
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/OtherAnnotatedClasses/VariadicClass.php19
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/RedirectableUrlMatcher.php30
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/annotated.php0
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/bad_format.yml3
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/bar.xml0
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/import__controller.xml10
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/import__controller.yml4
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_controller.xml8
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_controller.yml3
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_override_defaults.xml10
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_override_defaults.yml5
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/override_defaults.xml10
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/override_defaults.yml5
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/routing.xml14
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/routing.yml11
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/directory/recurse/routes1.yml2
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/directory/recurse/routes2.yml2
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/directory/routes3.yml2
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/directory_import/import.yml3
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher0.php37
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher1.php318
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher2.php380
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher3.php55
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher4.php112
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher5.php209
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher6.php213
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher7.php249
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/empty.yml0
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/file_resource.yml0
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/foo.xml0
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/foo1.xml0
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/bar.xml8
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/bar.yml4
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/baz.xml8
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/baz.yml4
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_multiple.xml8
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_multiple.yml2
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_single.xml8
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_single.yml2
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/php_dsl.php7
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/php_dsl_bar.php12
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/php_dsl_baz.php12
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/incomplete.yml2
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/list_defaults.xml20
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/list_in_list_defaults.xml22
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/list_in_map_defaults.xml22
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/list_null_values.xml22
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/map_defaults.xml20
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/map_in_list_defaults.xml22
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/map_in_map_defaults.xml22
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/map_null_values.xml22
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/missing_id.xml8
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/missing_path.xml8
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/namespaceprefix.xml16
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonesense_resource_plus_path.yml3
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonesense_type_without_resource.yml3
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonvalid.xml10
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonvalid.yml1
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonvalid2.yml1
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonvalidkeys.yml3
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonvalidnode.xml8
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonvalidroute.xml12
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/null_values.xml12
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/php_dsl.php22
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/php_dsl_sub.php14
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/scalar_defaults.xml33
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/special_route_name.yml2
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/validpattern.php18
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/validpattern.xml15
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/validpattern.yml13
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/validresource.php18
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/validresource.xml13
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/validresource.yml8
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/with_define_path_variable.php5
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/withdoctype.xml3
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Generator/Dumper/PhpGeneratorDumperTest.php181
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Generator/UrlGeneratorTest.php724
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/AbstractAnnotationLoaderTest.php33
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/AnnotationClassLoaderTest.php255
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/AnnotationDirectoryLoaderTest.php98
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/AnnotationFileLoaderTest.php91
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/ClosureLoaderTest.php49
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/DirectoryLoaderTest.php74
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/GlobFileLoaderTest.php45
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/ObjectRouteLoaderTest.php123
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/PhpFileLoaderTest.php133
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/XmlFileLoaderTest.php385
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/YamlFileLoaderTest.php206
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/DumpedRedirectableUrlMatcherTest.php43
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/DumpedUrlMatcherTest.php48
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/Dumper/DumperCollectionTest.php34
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php459
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/Dumper/StaticPrefixCollectionTest.php175
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/RedirectableUrlMatcherTest.php124
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/TraceableUrlMatcherTest.php122
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/UrlMatcherTest.php509
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/RequestContextTest.php160
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/RouteCollectionBuilderTest.php364
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/RouteCollectionTest.php305
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/RouteCompilerTest.php389
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/RouteTest.php258
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/RouterTest.php163
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/composer.json56
-rw-r--r--main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/phpunit.xml.dist30
1045 files changed, 131402 insertions, 0 deletions
diff --git a/main/app/sprinkles/core/assets/SiteAssets/css/main.css b/main/app/sprinkles/core/assets/SiteAssets/css/main.css
new file mode 100644
index 0000000..68bb4a3
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/css/main.css
@@ -0,0 +1,250 @@
+/******
+GENERAL
+******/
+* {
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-overflow-scrolling: touch;
+
+ outline: none;
+ ie-dummy: expression(this.hideFocus=true);
+}
+
+::-webkit-scrollbar {
+ width: 0;
+ background: transparent;
+}
+
+body {
+ font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
+ height: 100%;
+ width: 100%;
+ overflow: hidden;
+ background-color: #0c1d34;
+ color: #426A91;
+ margin: 0;
+ padding: 0;
+ border: 0;
+}
+
+.main {
+ height: 100%;
+}
+
+a {
+ text-decoration: none;
+ color: #4a93c0;
+}
+
+hr {
+ width: 100%;
+ display: block;
+ height: 1px;
+ border: 0;
+ border-top: 1px solid #112a42;
+ margin: 1em 0;
+ padding: 0;
+}
+
+/*******
+FLICKITY
+*******/
+.main-carousel {
+ background: #EEE;
+}
+
+.carousel-cell {
+ width: 100%;
+ height: calc(100vh - 75px);
+ height: -moz-calc(100vh - 75px);
+ height: -webkit-calc(100vh - 75px);
+ height: -o-calc(100vh - 75px);
+ height: calc(100vh - 75px);
+ background: #0c1d34;
+ counter-increment: carousel-cell;
+}
+
+/******
+HEADER
+******/
+.header {
+ display: flex;
+ flex-wrap: nowrap;
+ justify-content: space-between;
+ align-content: center;
+ margin: 20px;
+}
+
+.LeftButtonHeader {
+ width: 20px;
+ height: 20px;
+ -webkit-filter: invert(.5);
+ -moz-filter: invert(.5);
+}
+
+.HeaderCaption {
+ color: lightgrey;
+}
+
+.RightButtonHeader {
+ width: 20px;
+ height: 20px;
+ -webkit-filter: invert(.5);
+ -moz-filter: invert(.5);
+}
+
+/***********
+GENERAL TABS
+***********/
+.MainInTab {
+ height: 100%;
+}
+
+/**********
+CHAT WINDOW
+**********/
+.ChatWindow {
+ position: relative;
+ height: 100%;
+ margin: 5px;
+}
+
+.ChatMessages {
+ overflow-y: scroll;
+ max-height: calc(100% - 135px); /* navbar + input + some margin*/
+ max-height: -moz-calc(100% - 135px);
+ max-height: -webkit-calc(100% - 135px);
+ max-height: -o-calc(100% - 135px);
+ height: 100%;
+ width: 100%;
+}
+
+.ChatMessage {
+ display: block;
+ position: relative;
+ min-width: 50px;
+ max-width: 50%;
+ width: auto;
+ height: auto;
+ word-wrap: break-word;
+ text-align: center;
+ padding: 10px;
+}
+
+.ServerChatMessage {
+ display: inline-block;
+ position: relative;
+ left: 50%;
+ transform: translateX(-50%);
+ text-align: center;
+ padding: 5px;
+ -webkit-border-radius: 25px;
+ -moz-border-radius: 25px;
+ border-radius: 25px;
+ background: linear-gradient(to right, #ad4eff, #7c41f9);
+ color: #FFF;
+ font-size: x-small;
+}
+
+.MessageSent {
+ float: right;
+ background-color: #12213b;
+}
+
+.AloneMessage {
+ -webkit-border-radius: 25px;
+ -moz-border-radius: 25px;
+ border-radius: 25px;
+}
+
+.TopMessage {
+ -webkit-border-radius: 25px 25px 10px 10px;
+ -moz-border-radius: 25px 25px 10px 10px;
+ border-radius: 25px 25px 10px 10px;
+}
+
+.MiddleMessage {
+ -webkit-border-radius: 10px;
+ -moz-border-radius: 10px;
+ border-radius: 10px;
+}
+
+.BottomMessage {
+ -webkit-border-radius: 10px 10px 25px 25px;
+ -moz-border-radius: 10px 10px 25px 25px;
+ border-radius: 10px 10px 25px 25px;
+}
+
+.MessageReceived {
+ float: left;
+ background-color: #13223c;
+}
+
+.ChatInput {
+ position: absolute;
+ margin: auto;
+ bottom: 90px; /* 75+15 */
+ left: 0;
+ z-index: 600;
+ width: 100%;
+ height: 40px;
+ border: none;
+ color: #FFF;
+ background-color: #13223C;
+}
+
+#ChatTextInput {
+ display: none;
+}
+
+/*****
+NAVBAR
+*****/
+.Navbar {
+ display: flex;
+ flex-wrap: nowrap;
+ justify-content: center;
+ align-content: center;
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ height: 75px;
+ width: 100%;
+ background-color: #13223c;
+}
+
+.NavbarIconWrap {
+ margin: auto;
+}
+
+.NavbarIconWrap img {
+ height: 30px;
+ width: 30px;
+ filter: invert(.5);
+ -webkit-filter: invert(.5);
+ -moz-filter: invert(.5);
+}
+
+.NavbarLine {
+ position: absolute;
+ bottom: 73px;
+ left: 0;
+ width: 20% !important;
+ height: 2px;
+ background: #eb12b5;
+}
+
+.ActiveTab {
+ -webkit-transition: -moz-transform .3s ease-out;
+ -moz-transition: -webkit-transform .3s ease-out;
+
+ filter: invert(19%) sepia(93%) saturate(4612%) hue-rotate(303deg) brightness(98%) contrast(101%);
+ -webkit-filter: invert(19%) sepia(93%) saturate(4612%) hue-rotate(303deg) brightness(98%) contrast(101%);
+ -moz-filter: invert(19%) sepia(93%) saturate(4612%) hue-rotate(303deg) brightness(98%) contrast(101%);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/css/slick.css b/main/app/sprinkles/core/assets/SiteAssets/css/slick.css
new file mode 100644
index 0000000..f2465cb
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/css/slick.css
@@ -0,0 +1,2 @@
+.slick-slider{position:relative;display:block;box-sizing:border-box;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-touch-callout:none;-khtml-user-select:none;-ms-touch-action:pan-y;touch-action:pan-y;-webkit-tap-highlight-color:transparent}.slick-list{position:relative;display:block;overflow:hidden;margin:0;padding:0}.slick-list:focus{outline:0}.slick-list.dragging{cursor:pointer;cursor:hand}.slick-slider .slick-list,.slick-slider .slick-track{-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.slick-track{position:relative;top:0;left:0;display:block;margin-left:auto;margin-right:auto}.slick-track:after,.slick-track:before{display:table;content:''}.slick-track:after{clear:both}.slick-loading .slick-track{visibility:hidden}.slick-slide{display:none;float:left;height:100%;min-height:1px}[dir=rtl] .slick-slide{float:right}.slick-slide img{display:block}.slick-slide.slick-loading img{display:none}.slick-slide.dragging img{pointer-events:none}.slick-initialized .slick-slide{display:block}.slick-loading .slick-slide{visibility:hidden}.slick-vertical .slick-slide{display:block;height:auto;border:1px solid transparent}.slick-arrow.slick-hidden{display:none}
+/*# sourceMappingURL=slick.min.css.map */ \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/icons/BurgerMenuShort.svg b/main/app/sprinkles/core/assets/SiteAssets/icons/BurgerMenuShort.svg
new file mode 100644
index 0000000..1bf78bd
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/icons/BurgerMenuShort.svg
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 384.97 384.97" style="enable-background:new 0 0 384.97 384.97;" xml:space="preserve">
+<g>
+ <g id="Menu_1_">
+ <path d="M12.03,120.303h360.909c6.641,0,12.03-5.39,12.03-12.03c0-6.641-5.39-12.03-12.03-12.03H12.03
+ c-6.641,0-12.03,5.39-12.03,12.03C0,114.913,5.39,120.303,12.03,120.303z"/>
+ <path d="M372.939,180.455H12.03c-6.641,0-12.03,5.39-12.03,12.03s5.39,12.03,12.03,12.03h360.909c6.641,0,12.03-5.39,12.03-12.03
+ S379.58,180.455,372.939,180.455z"/>
+ <path d="M372.939,264.667H132.333c-6.641,0-12.03,5.39-12.03,12.03c0,6.641,5.39,12.03,12.03,12.03h240.606
+ c6.641,0,12.03-5.39,12.03-12.03C384.97,270.056,379.58,264.667,372.939,264.667z"/>
+ </g>
+ <g>
+ </g>
+ <g>
+ </g>
+ <g>
+ </g>
+ <g>
+ </g>
+ <g>
+ </g>
+ <g>
+ </g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+</svg>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/icons/ExploreGlobeOutline.svg b/main/app/sprinkles/core/assets/SiteAssets/icons/ExploreGlobeOutline.svg
new file mode 100644
index 0000000..6778254
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/icons/ExploreGlobeOutline.svg
@@ -0,0 +1,210 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
+<g>
+ <g>
+ <path d="M256,0C114.842,0,0,114.842,0,256s114.842,256,256,256s256-114.842,256-256S397.158,0,256,0z M256,494.933
+ C124.254,494.933,17.067,387.746,17.067,256S124.254,17.067,256,17.067S494.933,124.254,494.933,256S387.746,494.933,256,494.933z
+ "/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M145.067,128h-51.2c-4.71,0-8.533,3.823-8.533,8.533s3.823,8.533,8.533,8.533h51.2c4.71,0,8.533-3.823,8.533-8.533
+ S149.777,128,145.067,128z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M85.333,170.667H68.267c-4.71,0-8.533,3.823-8.533,8.533s3.823,8.533,8.533,8.533h17.067c4.71,0,8.533-3.823,8.533-8.533
+ S90.044,170.667,85.333,170.667z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M452.267,170.667H435.2c-4.71,0-8.533,3.823-8.533,8.533s3.823,8.533,8.533,8.533h17.067c4.71,0,8.533-3.823,8.533-8.533
+ S456.977,170.667,452.267,170.667z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M460.8,221.867h-34.133c-4.71,0-8.533,3.823-8.533,8.533s3.823,8.533,8.533,8.533H460.8c4.71,0,8.533-3.823,8.533-8.533
+ S465.51,221.867,460.8,221.867z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M418.133,128h-51.2c-4.71,0-8.533,3.823-8.533,8.533s3.823,8.533,8.533,8.533h51.2c4.71,0,8.533-3.823,8.533-8.533
+ S422.844,128,418.133,128z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M315.733,128H196.267c-4.71,0-8.533,3.823-8.533,8.533s3.823,8.533,8.533,8.533h119.467c4.71,0,8.533-3.823,8.533-8.533
+ S320.444,128,315.733,128z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M315.733,42.667H196.267c-4.71,0-8.533,3.823-8.533,8.533s3.823,8.533,8.533,8.533h119.467
+ c4.71,0,8.533-3.823,8.533-8.533S320.444,42.667,315.733,42.667z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M384,85.333h-76.8c-4.71,0-8.533,3.823-8.533,8.533c0,4.71,3.823,8.533,8.533,8.533H384c4.71,0,8.533-3.823,8.533-8.533
+ C392.533,89.156,388.71,85.333,384,85.333z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M264.533,85.333h-128c-4.71,0-8.533,3.823-8.533,8.533c0,4.71,3.823,8.533,8.533,8.533h128
+ c4.71,0,8.533-3.823,8.533-8.533C273.067,89.156,269.244,85.333,264.533,85.333z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M213.333,170.667h-76.8c-4.71,0-8.533,3.823-8.533,8.533s3.823,8.533,8.533,8.533h76.8c4.71,0,8.533-3.823,8.533-8.533
+ S218.044,170.667,213.333,170.667z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M384,170.667H256c-4.71,0-8.533,3.823-8.533,8.533s3.823,8.533,8.533,8.533h128c4.71,0,8.533-3.823,8.533-8.533
+ S388.71,170.667,384,170.667z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M110.933,221.867H51.2c-4.71,0-8.533,3.823-8.533,8.533s3.823,8.533,8.533,8.533h59.733c4.71,0,8.533-3.823,8.533-8.533
+ S115.644,221.867,110.933,221.867z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M384,221.867h-51.2c-4.71,0-8.533,3.823-8.533,8.533s3.823,8.533,8.533,8.533H384c4.71,0,8.533-3.823,8.533-8.533
+ S388.71,221.867,384,221.867z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M281.6,221.867H162.133c-4.71,0-8.533,3.823-8.533,8.533s3.823,8.533,8.533,8.533H281.6c4.71,0,8.533-3.823,8.533-8.533
+ S286.31,221.867,281.6,221.867z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M418.133,366.933h-51.2c-4.71,0-8.533,3.823-8.533,8.533s3.823,8.533,8.533,8.533h51.2c4.71,0,8.533-3.823,8.533-8.533
+ S422.844,366.933,418.133,366.933z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M443.733,324.267h-17.067c-4.71,0-8.533,3.823-8.533,8.533c0,4.71,3.823,8.533,8.533,8.533h17.067
+ c4.71,0,8.533-3.823,8.533-8.533C452.267,328.09,448.444,324.267,443.733,324.267z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M76.8,324.267H59.733c-4.71,0-8.533,3.823-8.533,8.533c0,4.71,3.823,8.533,8.533,8.533H76.8
+ c4.71,0,8.533-3.823,8.533-8.533C85.333,328.09,81.51,324.267,76.8,324.267z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M85.333,273.067H51.2c-4.71,0-8.533,3.823-8.533,8.533s3.823,8.533,8.533,8.533h34.133c4.71,0,8.533-3.823,8.533-8.533
+ S90.044,273.067,85.333,273.067z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M145.067,366.933h-51.2c-4.71,0-8.533,3.823-8.533,8.533S89.156,384,93.867,384h51.2c4.71,0,8.533-3.823,8.533-8.533
+ S149.777,366.933,145.067,366.933z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M315.733,366.933H196.267c-4.71,0-8.533,3.823-8.533,8.533s3.823,8.533,8.533,8.533h119.467
+ c4.71,0,8.533-3.823,8.533-8.533S320.444,366.933,315.733,366.933z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M315.733,452.267H196.267c-4.71,0-8.533,3.823-8.533,8.533s3.823,8.533,8.533,8.533h119.467
+ c4.71,0,8.533-3.823,8.533-8.533S320.444,452.267,315.733,452.267z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M204.8,409.6H128c-4.71,0-8.533,3.823-8.533,8.533s3.823,8.533,8.533,8.533h76.8c4.71,0,8.533-3.823,8.533-8.533
+ S209.51,409.6,204.8,409.6z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M375.467,409.6h-128c-4.71,0-8.533,3.823-8.533,8.533s3.823,8.533,8.533,8.533h128c4.71,0,8.533-3.823,8.533-8.533
+ S380.177,409.6,375.467,409.6z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M375.467,324.267h-76.8c-4.71,0-8.533,3.823-8.533,8.533c0,4.71,3.823,8.533,8.533,8.533h76.8
+ c4.71,0,8.533-3.823,8.533-8.533C384,328.09,380.177,324.267,375.467,324.267z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M256,324.267H128c-4.71,0-8.533,3.823-8.533,8.533c0,4.71,3.823,8.533,8.533,8.533h128c4.71,0,8.533-3.823,8.533-8.533
+ C264.533,328.09,260.71,324.267,256,324.267z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M460.8,273.067h-59.733c-4.71,0-8.533,3.823-8.533,8.533s3.823,8.533,8.533,8.533H460.8c4.71,0,8.533-3.823,8.533-8.533
+ S465.51,273.067,460.8,273.067z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M179.2,273.067H128c-4.71,0-8.533,3.823-8.533,8.533s3.823,8.533,8.533,8.533h51.2c4.71,0,8.533-3.823,8.533-8.533
+ S183.91,273.067,179.2,273.067z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M349.867,273.067H230.4c-4.71,0-8.533,3.823-8.533,8.533s3.823,8.533,8.533,8.533h119.467c4.71,0,8.533-3.823,8.533-8.533
+ S354.577,273.067,349.867,273.067z"/>
+ </g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+</svg>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/icons/FriendFeedOutline.svg b/main/app/sprinkles/core/assets/SiteAssets/icons/FriendFeedOutline.svg
new file mode 100644
index 0000000..4243deb
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/icons/FriendFeedOutline.svg
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
+<g>
+ <g>
+ <path d="M437.987,364.012c-16.803,0-32.306,5.639-44.741,15.111l-78.364-78.364c9.472-12.435,15.113-27.941,15.113-44.743
+ c0-8.022-1.3-15.743-3.673-22.982l80.656-39.105c10.544,14.579,27.682,24.091,47.009,24.091c31.978,0,57.995-26.017,57.995-57.995
+ s-26.017-57.995-57.995-57.995c-31.978,0-57.995,26.017-57.995,57.995c0,5.522,0.792,10.858,2.24,15.921l-80.651,39.103
+ c-11.522-17.262-30.101-29.415-51.58-32.331v-26.583c13.881-4.281,23.998-17.228,23.998-32.494
+ c0-18.747-15.251-33.997-33.997-33.997s-33.997,15.251-33.997,33.997c0,15.268,10.117,28.215,23.998,32.494v26.583
+ c-12.937,1.756-24.82,6.858-34.744,14.418l-64.638-64.638c15.761-20.207,21.332-46.978,14.505-72.065
+ c-1.451-5.33-6.947-8.475-12.274-7.022c-5.329,1.45-8.472,6.945-7.022,12.274c5.81,21.349-0.244,44.309-15.794,59.993
+ c-0.065,0.062-0.134,0.115-0.198,0.179c-0.056,0.056-0.104,0.118-0.158,0.175c-24.185,24.003-63.387,23.951-87.501-0.164
+ c-24.172-24.171-24.172-63.502,0-87.674c15.287-15.288,36.997-21.459,58.076-16.511c5.373,1.26,10.757-2.072,12.02-7.449
+ c1.262-5.376-2.073-10.757-7.449-12.02C72.958-4.328,44.252,3.834,24.035,24.05c-31.969,31.969-31.969,83.987,0,115.957
+ c15.985,15.985,36.981,23.977,57.978,23.977c17.851,0,35.688-5.799,50.459-17.352l64.643,64.643
+ c-9.471,12.435-15.11,27.939-15.11,44.739c0,40.801,33.193,73.994,73.994,73.994c16.802,0,32.305-5.639,44.739-15.11
+ l78.365,78.364c-9.472,12.435-15.111,27.94-15.111,44.741c0,40.801,33.193,73.994,73.994,73.994
+ c40.801,0,73.994-33.193,73.994-73.994C511.981,397.204,478.787,364.012,437.987,364.012z M453.985,122.026
+ c20.951,0,37.997,17.046,37.997,37.997c0,20.951-17.046,37.997-37.997,37.997c-20.951,0-37.997-17.046-37.997-37.997
+ C415.988,139.071,433.034,122.026,453.985,122.026z M242,123.637c0-7.719,6.279-13.999,13.999-13.999
+ c7.719,0,13.999,6.279,13.999,13.999c0,7.719-6.279,13.999-13.999,13.999C248.28,137.636,242,131.357,242,123.637z
+ M255.999,310.011c-29.774,0-53.996-24.222-53.996-53.996c0-29.774,24.222-53.996,53.996-53.996s53.996,24.222,53.996,53.996
+ C309.995,285.788,285.773,310.011,255.999,310.011z M437.987,492.002c-29.774,0-53.996-24.222-53.996-53.996
+ c0-29.774,24.222-53.996,53.996-53.996s53.996,24.222,53.996,53.996C491.982,467.78,467.76,492.002,437.987,492.002z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M140.333,24.394l-0.359-0.361c-3.914-3.895-10.244-3.881-14.141,0.034c-3.896,3.915-3.881,10.245,0.034,14.141
+ l0.258,0.261c1.956,1.974,4.53,2.962,7.104,2.962c2.543,0,5.087-0.964,7.036-2.896C144.19,34.649,144.22,28.318,140.333,24.394z"
+ />
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M165.827,346.187c-3.905-3.905-10.236-3.905-14.141,0L91.31,406.563c-9.431-6.638-20.911-10.553-33.296-10.553
+ c-31.978,0-57.995,26.017-57.995,57.995C0.019,485.983,26.036,512,58.014,512c31.978,0,57.995-26.017,57.995-57.995
+ c0-12.387-3.916-23.869-10.557-33.301l60.375-60.375C169.732,356.424,169.732,350.092,165.827,346.187z M58.014,492.002
+ c-20.951,0-37.997-17.046-37.997-37.997c0-20.951,17.046-37.997,37.997-37.997c20.951,0,37.997,17.046,37.997,37.997
+ C96.011,474.956,78.965,492.002,58.014,492.002z"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path d="M189.575,322.44c-1.86-1.86-4.44-2.93-7.069-2.93s-5.21,1.07-7.069,2.93c-1.86,1.86-2.93,4.44-2.93,7.069
+ s1.07,5.21,2.93,7.069c1.86,1.86,4.44,2.93,7.069,2.93c2.63,0,5.21-1.07,7.069-2.93c1.86-1.86,2.93-4.44,2.93-7.069
+ S191.434,324.299,189.575,322.44z"/>
+ </g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+</svg>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/icons/MessageBubbleOutline.svg b/main/app/sprinkles/core/assets/SiteAssets/icons/MessageBubbleOutline.svg
new file mode 100644
index 0000000..81ea5cc
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/icons/MessageBubbleOutline.svg
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 60 60" style="enable-background:new 0 0 60 60;" xml:space="preserve">
+<g>
+ <path d="M19.5,27h14c0.552,0,1-0.447,1-1s-0.448-1-1-1h-14c-0.552,0-1,0.447-1,1S18.948,27,19.5,27z"/>
+ <path d="M39,32H14c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S39.552,32,39,32z"/>
+ <path d="M39,39H14c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S39.552,39,39,39z"/>
+ <path d="M55.894,37.041C58.582,33.271,60,28.913,60,24.414C60,11.504,48.337,1,34,1c-9.871,0-18.998,5.142-23.344,13.114
+ C4.201,18.379,0,25.255,0,33c0,4.499,1.418,8.856,4.106,12.627c-0.51,5.578-1.86,9.713-3.813,11.666
+ c-0.304,0.304-0.38,0.769-0.188,1.153C0.276,58.789,0.625,59,1,59c0.046,0,0.093-0.003,0.139-0.01
+ c0.35-0.049,8.433-1.213,14.317-4.586c3.33,1.334,6.875,2.01,10.544,2.01c8.525,0,16.104-3.714,20.848-9.44
+ c5.512,2.486,11.738,3.392,12.012,3.43c0.047,0.007,0.094,0.01,0.14,0.01c0.375,0,0.724-0.211,0.895-0.554
+ c0.192-0.385,0.116-0.85-0.188-1.153C57.754,46.754,56.404,42.619,55.894,37.041z M26,54.414c-2.891,0-5.694-0.458-8.364-1.349
+ c3.334-2.09,3.338-2.255,3.335-2.82c-0.001-0.349-0.19-0.68-0.488-0.86c-0.449-0.271-1.026-0.146-1.328,0.271
+ c-0.492,0.385-2.502,1.673-4.294,2.778l0,0c-3.701,2.236-8.645,3.518-11.559,4.128c1.797-3.174,2.535-7.623,2.83-11.136
+ c0.02-0.242-0.048-0.482-0.192-0.678C3.362,41.255,2,37.192,2,33c0-7.219,4.028-13.61,10.18-17.491
+ c0.388-0.245,0.781-0.48,1.182-0.702c0.09-0.05,0.179-0.102,0.271-0.151c0.42-0.227,0.849-0.437,1.282-0.639
+ c0.158-0.074,0.316-0.147,0.475-0.218c0.44-0.195,0.885-0.379,1.336-0.548c0.157-0.059,0.317-0.112,0.476-0.168
+ c0.357-0.126,0.717-0.244,1.08-0.354c0.166-0.05,0.33-0.103,0.498-0.151c0.471-0.133,0.946-0.251,1.426-0.357
+ c0.166-0.037,0.334-0.07,0.502-0.104c0.432-0.087,0.866-0.165,1.304-0.23c0.1-0.015,0.199-0.034,0.3-0.048
+ c0.528-0.073,1.061-0.126,1.596-0.167c0.139-0.011,0.279-0.02,0.419-0.029c0.555-0.034,1.113-0.058,1.674-0.058
+ c10.752,0,19.876,6.342,22.919,15.053C49.622,28.65,50,30.786,50,33c0,0.484-0.025,0.964-0.061,1.443
+ c-0.009,0.124-0.02,0.248-0.032,0.372c-0.042,0.446-0.096,0.89-0.169,1.33c-0.006,0.034-0.009,0.068-0.015,0.102
+ c-0.078,0.459-0.18,0.914-0.292,1.367c-0.033,0.133-0.068,0.266-0.103,0.399c-0.109,0.406-0.23,0.81-0.366,1.21
+ c-0.029,0.084-0.057,0.168-0.087,0.252c-0.14,0.395-0.297,0.785-0.463,1.171c-0.061,0.142-0.124,0.284-0.188,0.425
+ c-0.186,0.406-0.381,0.809-0.595,1.205c-0.05,0.092-0.105,0.181-0.156,0.272c-0.185,0.33-0.381,0.656-0.586,0.979
+ c-0.085,0.133-0.169,0.267-0.257,0.398c-0.248,0.371-0.506,0.737-0.78,1.096C41.528,50.686,34.243,54.414,26,54.414z
+ M48.094,45.343c0.042-0.06,0.076-0.123,0.117-0.184c0.233-0.343,0.456-0.693,0.669-1.047c0.119-0.199,0.23-0.4,0.343-0.601
+ c0.124-0.222,0.245-0.445,0.362-0.671c0.105-0.203,0.21-0.407,0.308-0.612c0.152-0.319,0.295-0.641,0.432-0.967
+ c0.096-0.229,0.186-0.46,0.274-0.691c0.109-0.286,0.213-0.573,0.31-0.863c0.062-0.188,0.122-0.376,0.179-0.565
+ c0.096-0.316,0.182-0.635,0.263-0.957c0.035-0.14,0.075-0.278,0.108-0.419c0.104-0.45,0.191-0.905,0.265-1.364
+ c0.023-0.141,0.04-0.283,0.06-0.424c0.051-0.356,0.092-0.715,0.125-1.076c0.013-0.145,0.027-0.289,0.037-0.434
+ C51.977,33.981,52,33.493,52,33C52,20.09,40.337,9.586,26,9.586c-0.479,0-0.955,0.014-1.428,0.037
+ c-0.171,0.008-0.341,0.024-0.512,0.035c-0.298,0.02-0.595,0.04-0.89,0.069c-0.212,0.021-0.423,0.047-0.634,0.073
+ c-0.248,0.03-0.495,0.06-0.74,0.097c-0.235,0.034-0.469,0.073-0.702,0.113c-0.213,0.037-0.425,0.076-0.636,0.117
+ c-0.254,0.05-0.508,0.102-0.76,0.158c-0.178,0.04-0.354,0.084-0.53,0.127c-0.275,0.068-0.551,0.135-0.823,0.211
+ c-0.122,0.034-0.242,0.072-0.363,0.108c-1.042,0.304-2.061,0.668-3.055,1.091c-0.076,0.032-0.152,0.062-0.228,0.095
+ c-0.09,0.039-0.182,0.073-0.272,0.113C18.882,6.45,26.186,3,34,3c13.234,0,24,9.606,24,21.414c0,4.191-1.362,8.255-3.939,11.749
+ c-0.144,0.195-0.212,0.436-0.192,0.678c0.295,3.513,1.032,7.96,2.829,11.134C54.51,47.516,51.182,46.678,48.094,45.343z"/>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+</svg>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/icons/UserGroupOutline.svg b/main/app/sprinkles/core/assets/SiteAssets/icons/UserGroupOutline.svg
new file mode 100644
index 0000000..ca8c11c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/icons/UserGroupOutline.svg
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 475.851 475.851" style="enable-background:new 0 0 475.851 475.851;" xml:space="preserve">
+<g>
+ <g>
+ <g>
+ <path d="M151.549,145.274c0,23.39,9.145,50.385,24.462,72.214c17.389,24.78,39.376,38.427,61.911,38.427
+ c22.534,0,44.521-13.647,61.91-38.428c15.317-21.828,24.462-48.824,24.462-72.213c0-47.626-38.746-86.372-86.372-86.372
+ C190.296,58.902,151.549,97.648,151.549,145.274z M237.922,73.902c39.354,0,71.372,32.018,71.372,71.372
+ c0,20.118-8.33,44.487-21.74,63.598c-14.29,20.364-32.38,32.043-49.632,32.043c-17.252,0-35.342-11.679-49.632-32.043
+ c-13.41-19.11-21.741-43.479-21.741-63.598C166.549,105.919,198.567,73.902,237.922,73.902z"/>
+ <path d="M302.372,239.167c-2.862-1.363-6.273-0.778-8.52,1.461c-16.775,16.728-36.117,25.569-55.935,25.569
+ c-19.821,0-39.158-8.841-55.923-25.567c-2.246-2.241-5.659-2.826-8.521-1.463c-25.254,12.022-46.628,30.829-61.811,54.388
+ c-15.596,24.2-23.84,52.277-23.84,81.195v0.121c0,2.116,0.894,4.134,2.461,5.556c40.492,36.722,92.922,56.945,147.633,56.945
+ s107.141-20.224,147.632-56.945c1.568-1.422,2.462-3.439,2.462-5.556v-0.121c0-28.918-8.242-56.995-23.834-81.194
+ C348.997,269.995,327.625,251.188,302.372,239.167z M237.918,422.372c-49.861,0-97.685-18.023-135.057-50.827
+ c0.583-24.896,7.956-48.986,21.411-69.865c12.741-19.77,30.322-35.823,51.058-46.676c18.746,17.157,40.285,26.193,62.588,26.193
+ c22.3,0,43.842-9.035,62.598-26.193c20.734,10.853,38.313,26.906,51.053,46.676c13.452,20.877,20.823,44.968,21.406,69.865
+ C335.602,404.349,287.778,422.372,237.918,422.372z"/>
+ <path d="M455.077,243.89c-13.23-20.532-31.856-36.923-53.864-47.399c-2.862-1.363-6.275-0.778-8.52,1.461
+ c-14.312,14.271-30.79,21.815-47.654,21.815c-9.142,0-18.184-2.205-26.873-6.553c-3.706-1.853-8.209-0.353-10.063,3.351
+ c-1.854,3.705-0.354,8.21,3.351,10.063c10.793,5.401,22.093,8.139,33.586,8.139c19.335,0,38.004-7.737,54.288-22.437
+ c17.504,9.298,32.348,22.934,43.141,39.685c11.445,17.763,17.756,38.243,18.338,59.416
+ c-18.524,16.158-40.553,28.449-63.91,35.634c-3.959,1.218-6.182,5.415-4.964,9.374c0.992,3.225,3.96,5.297,7.166,5.297
+ c0.73,0,1.474-0.107,2.208-0.333c26.509-8.154,51.435-22.362,72.082-41.088c1.568-1.422,2.462-3.439,2.462-5.556v-0.105
+ C475.85,289.45,468.666,264.98,455.077,243.89z"/>
+ <path d="M130.493,210.473c7.93,0,15.841-1.934,23.516-5.748c3.709-1.843,5.222-6.345,3.379-10.054
+ c-1.843-3.71-6.345-5.222-10.054-3.379c-5.582,2.774-11.248,4.18-16.841,4.18c-14.541,0-29.836-9.914-41.964-27.2
+ c-11.449-16.318-18.562-37.112-18.562-54.266c0-33.375,27.152-60.527,60.526-60.527c15.752,0,30.67,6.022,42.006,16.958
+ c2.98,2.875,7.729,2.792,10.604-0.19c2.876-2.981,2.791-7.729-0.19-10.604c-14.146-13.647-32.763-21.163-52.42-21.163
+ c-41.646,0-75.526,33.881-75.526,75.527c0,20.38,7.957,43.887,21.283,62.881C91.445,198.545,110.709,210.473,130.493,210.473z"/>
+ <path d="M61.034,340.143c-16.753-7.222-32.209-16.972-45.989-29.004c0.582-21.112,6.875-41.53,18.291-59.243
+ c10.761-16.698,25.561-30.294,43.01-39.566c16.239,14.662,34.856,22.376,54.139,22.376c11.587,0,22.969-2.785,33.829-8.277
+ c3.696-1.87,5.177-6.381,3.308-10.078c-1.869-3.697-6.381-5.177-10.078-3.308c-8.742,4.421-17.846,6.663-27.059,6.663
+ c-16.811,0-33.238-7.522-47.504-21.754c-2.246-2.24-5.658-2.825-8.521-1.462c-21.954,10.451-40.534,26.8-53.733,47.28
+ C7.167,264.811,0,289.221,0,314.362v0.103c0,2.116,0.894,4.134,2.461,5.556c15.629,14.174,33.338,25.579,52.634,33.897
+ c0.968,0.417,1.975,0.615,2.966,0.615c2.904,0,5.668-1.697,6.891-4.533C66.591,346.196,64.837,341.783,61.034,340.143z"/>
+ <path d="M69.854,351.003c-2.671,6.443,4.532,12.832,10.617,9.387c3.238-1.834,4.683-5.937,3.227-9.385
+ C81.291,344.86,72.32,345.053,69.854,351.003z"/>
+ <path d="M83.698,351.005C83.888,351.455,83.518,350.545,83.698,351.005L83.698,351.005z"/>
+ <path d="M303.345,70.438c11.336-10.936,26.254-16.958,42.006-16.958c33.374,0,60.526,27.152,60.526,60.527
+ c0,17.154-7.112,37.947-18.563,54.266c-12.128,17.286-27.424,27.2-41.964,27.2c-5.593,0-11.259-1.406-16.841-4.18
+ c-3.711-1.844-8.212-0.331-10.055,3.379c-1.843,3.709-0.33,8.21,3.379,10.054c7.675,3.814,15.587,5.748,23.517,5.748
+ c19.783,0,39.048-11.927,54.243-33.585c13.327-18.994,21.283-42.501,21.283-62.881c0-41.646-33.881-75.527-75.526-75.527
+ c-19.657,0-38.273,7.516-52.42,21.163c-2.981,2.875-3.066,7.624-0.19,10.604C295.614,73.229,300.363,73.314,303.345,70.438z"/>
+ </g>
+ </g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+</svg>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/icons/UserOutline.svg b/main/app/sprinkles/core/assets/SiteAssets/icons/UserOutline.svg
new file mode 100644
index 0000000..6051129
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/icons/UserOutline.svg
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 404.347 404.347" style="enable-background:new 0 0 404.347 404.347;" xml:space="preserve">
+<g>
+ <g>
+ <g>
+ <path d="M202.178,209.972c23.96,0,47.357-14.538,65.881-40.936c16.348-23.296,26.107-52.099,26.107-77.048
+ C294.167,41.266,252.9,0,202.178,0c-50.722,0-91.988,41.266-91.988,91.988c0,24.949,9.759,53.752,26.107,77.048
+ C154.821,195.434,178.218,209.972,202.178,209.972z M202.178,15c42.451,0,76.988,34.537,76.988,76.988
+ c0,21.655-8.961,47.876-23.385,68.432c-15.409,21.958-34.946,34.552-53.603,34.552c-18.657,0-38.194-12.594-53.603-34.552
+ c-14.424-20.556-23.385-46.777-23.385-68.432C125.19,49.537,159.727,15,202.178,15z"/>
+ <path d="M336.974,251.115c-16.208-25.154-39.025-45.233-65.987-58.068c-2.864-1.363-6.274-0.778-8.52,1.461
+ c-18.071,18.021-38.92,27.545-60.293,27.545c-21.376,0-42.222-9.524-60.282-27.544c-2.246-2.241-5.658-2.827-8.521-1.463
+ c-26.962,12.835-49.782,32.915-65.992,58.068c-16.651,25.837-25.452,55.813-25.452,86.686v0.13c0,2.116,0.894,4.134,2.461,5.556
+ c43.276,39.247,99.312,60.861,157.785,60.861s114.508-21.614,157.785-60.861c1.567-1.422,2.461-3.439,2.461-5.556v-0.13
+ C362.421,306.927,353.622,276.951,336.974,251.115z M202.174,389.348c-53.621,0-105.055-19.417-145.212-54.743
+ c0.583-26.855,8.514-52.847,23.026-75.365c13.767-21.361,32.788-38.686,55.227-50.357c20.045,18.453,43.094,28.17,66.959,28.17
+ c23.861,0,46.914-9.719,66.969-28.171c22.437,11.67,41.458,28.996,55.222,50.357c14.509,22.517,22.438,48.508,23.021,75.365
+ C307.229,369.93,255.795,389.348,202.174,389.348z"/>
+ </g>
+ </g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+</svg>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/js/chat.js b/main/app/sprinkles/core/assets/SiteAssets/js/chat.js
new file mode 100644
index 0000000..bcb910b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/js/chat.js
@@ -0,0 +1,117 @@
+/************
+ GENERATE KEYS
+ ************/
+if (localStorage.getItem('KeysGenerated') === null || localStorage.getItem('KeysGenerated') !== "true") {
+ // GENERATE -- LATER ON LOGIN!
+ var EncryptionPhrase = "PASSWORD 123"; // THE USERS PASSWORD
+ var RSABitLength = 1024;
+ var PrivateKeyString = cryptico.generateRSAKey(EncryptionPhrase, RSABitLength);
+ var PublicKeyString = cryptico.publicKeyString(PrivateKeyString);
+ // SAVE TO DATABASE
+ $.ajax({
+ type: "POST",
+ url: "assets/php/SavePublicKey.php",
+ data: {
+ UserID: "1", // TEMPORARY
+ PublicKeyString: PublicKeyString
+ },
+ async: true,
+ error: function () {
+ console.error("Error while saving public key to database!");
+ },
+ success: function () {
+ localStorage.setItem('KeysGenerated', "true");
+ }
+ });
+}
+
+
+/******
+ GENERAL
+ ******/
+
+var ChatTextInput = $("#ChatTextInput");
+var SubscribeTextInput = $("#SubscribeTextInput");
+var ChatMessages = $("#ChatMessages");
+
+var WebSocket = new WebSocket('wss://marvinborner.ddnss.de:1337');
+
+WebSocket.onopen = function () {
+ console.log("Chat connection established!");
+};
+
+WebSocket.onmessage = function (e) {
+ var LastMessage = $(".ChatMessage:last");
+ var MessageObject = JSON.parse(e.data);
+ if (MessageObject.ServerMessage === false) {
+ if (MessageObject.WasHimself === true) { //MessageObject.Username
+ if (!LastMessage.hasClass("MessageSent")) {
+ ChatMessages.append("<div class='ChatMessage MessageSent AloneMessage'>" + MessageObject.Message + "</div><br><br>");
+ } else if (LastMessage.hasClass("MessageSent")) {
+ if (LastMessage.hasClass("AloneMessage")) {
+ LastMessage.removeClass("AloneMessage");
+ LastMessage.addClass("TopMessage");
+ } else if (LastMessage.hasClass("BottomMessage")) {
+ LastMessage.removeClass("BottomMessage");
+ LastMessage.addClass("MiddleMessage");
+ }
+ ChatMessages.append("<div class='ChatMessage MessageSent BottomMessage'>" + MessageObject.Message + "</div><br><br>");
+ }
+ $('.MessageSent').linkify({
+ target: "_blank"
+ });
+ } else if (MessageObject.WasHimself === false) {
+ if (!LastMessage.hasClass("MessageReceived")) {
+ ChatMessages.append("<div class='ChatMessage MessageReceived AloneMessage'>" + MessageObject.Message + "</div><br><br>");
+ } else if (LastMessage.hasClass("MessageReceived")) {
+ if (LastMessage.hasClass("AloneMessage")) {
+ LastMessage.removeClass("AloneMessage");
+ LastMessage.addClass("TopMessage");
+ } else if (LastMessage.hasClass("BottomMessage")) {
+ LastMessage.removeClass("BottomMessage");
+ LastMessage.addClass("MiddleMessage");
+ }
+ ChatMessages.append("<div class='ChatMessage MessageReceived BottomMessage'>" + MessageObject.Message + "</div><br><br>");
+ }
+ $('.MessageReceived').linkify({
+ target: "_blank"
+ });
+ }
+ } else if (MessageObject.ServerMessage === true) {
+ if (MessageObject.ServerMessageType === "GroupJoin") {
+ if (MessageObject.WasHimself === false) {
+ ChatMessages.append("<div class='ServerChatMessage'>" + MessageObject.Username + " <span data-lang='joined the group'></span>.</div><br><br>");
+ } else if (MessageObject.WasHimself === true) {
+ ChatMessages.empty();
+ ChatMessages.append("<div class='ServerChatMessage'><span data-lang='You joined the group'> " + MessageObject.GroupName + "</span>.</div><br><br>");
+ }
+ } else if (MessageObject.ServerMessageType === "UserDisconnect") {
+ ChatMessages.append("<div class='ServerChatMessage'>" + MessageObject.Username + " <span data-lang='has disconnected from the server'></span>.</div><br><br>");
+ }
+ }
+ initiateLanguage(); // need further work (performance)
+};
+
+ChatTextInput.keyup(function (e) {
+ if (e.keyCode === 13) {
+ sendMessage(ChatTextInput.val());
+ ChatTextInput.val("");
+ }
+});
+
+SubscribeTextInput.keyup(function (e) {
+ if (e.keyCode === 13) {
+ subscribe(SubscribeTextInput.val());
+ }
+});
+
+function subscribe(channel) {
+ WebSocket.send(JSON.stringify({ClientMessageType: "Subscribe", Channel: channel}));
+ SubscribeTextInput.hide();
+ ChatTextInput.show();
+}
+
+function sendMessage(msg) {
+ WebSocket.send(JSON.stringify({ClientMessageType: "Message", Message: msg}));
+ ChatTextInput.val("");
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/js/encryption.js b/main/app/sprinkles/core/assets/SiteAssets/js/encryption.js
new file mode 100644
index 0000000..7826bbb
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/js/encryption.js
@@ -0,0 +1,3407 @@
+// Copyright (c) 2005 Tom Wu
+// All Rights Reserved.
+// See "LICENSE" for details.
+// Basic JavaScript BN library - subset useful for RSA encryption.
+
+// Bits per digit
+var dbits;
+
+// JavaScript engine analysis
+var canary = 0xdeadbeefcafe;
+var j_lm = ((canary & 0xffffff) == 0xefcafe);
+
+// (public) Constructor
+
+function BigInteger(a, b, c) {
+ if (a != null) if ("number" === typeof a) this.fromNumber(a, b, c);
+ else if (b == null && "string" !== typeof a) this.fromString(a, 256);
+ else this.fromString(a, b);
+}
+
+// return new, unset BigInteger
+
+function nbi() {
+ return new BigInteger(null);
+}
+
+// am: Compute w_j += (x*this_i), propagate carries,
+// c is initial carry, returns final carry.
+// c < 3*dvalue, x < 2*dvalue, this_i < dvalue
+// We need to select the fastest one that works in this environment.
+// am1: use a single mult and divide to get the high bits,
+// max digit bits should be 26 because
+// max internal value = 2*dvalue^2-2*dvalue (< 2^53)
+
+function am1(i, x, w, j, c, n) {
+ while (--n >= 0) {
+ var v = x * this[i++] + w[j] + c;
+ c = Math.floor(v / 0x4000000);
+ w[j++] = v & 0x3ffffff;
+ }
+ return c;
+}
+
+// am2 avoids a big mult-and-extract completely.
+// Max digit bits should be <= 30 because we do bitwise ops
+// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
+
+function am2(i, x, w, j, c, n) {
+ var xl = x & 0x7fff,
+ xh = x >> 15;
+ while (--n >= 0) {
+ var l = this[i] & 0x7fff;
+ var h = this[i++] >> 15;
+ var m = xh * l + h * xl;
+ l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff);
+ c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30);
+ w[j++] = l & 0x3fffffff;
+ }
+ return c;
+}
+
+// Alternately, set max digit bits to 28 since some
+// browsers slow down when dealing with 32-bit numbers.
+
+function am3(i, x, w, j, c, n) {
+ var xl = x & 0x3fff,
+ xh = x >> 14;
+ while (--n >= 0) {
+ var l = this[i] & 0x3fff;
+ var h = this[i++] >> 14;
+ var m = xh * l + h * xl;
+ l = xl * l + ((m & 0x3fff) << 14) + w[j] + c;
+ c = (l >> 28) + (m >> 14) + xh * h;
+ w[j++] = l & 0xfffffff;
+ }
+ return c;
+}
+
+if (j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
+ BigInteger.prototype.am = am2;
+ dbits = 30;
+}
+else if (j_lm && (navigator.appName != "Netscape")) {
+ BigInteger.prototype.am = am1;
+ dbits = 26;
+}
+else { // Mozilla/Netscape seems to prefer am3
+ BigInteger.prototype.am = am3;
+ dbits = 28;
+}
+
+BigInteger.prototype.DB = dbits;
+BigInteger.prototype.DM = ((1 << dbits) - 1);
+BigInteger.prototype.DV = (1 << dbits);
+
+var BI_FP = 52;
+BigInteger.prototype.FV = Math.pow(2, BI_FP);
+BigInteger.prototype.F1 = BI_FP - dbits;
+BigInteger.prototype.F2 = 2 * dbits - BI_FP;
+
+// Digit conversions
+var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
+var BI_RC = new Array();
+var rr, vv;
+rr = "0".charCodeAt(0);
+for (vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv;
+rr = "a".charCodeAt(0);
+for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
+rr = "A".charCodeAt(0);
+for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
+
+function int2char(n) {
+ return BI_RM.charAt(n);
+}
+
+function intAt(s, i) {
+ var c = BI_RC[s.charCodeAt(i)];
+ return (c == null) ? -1 : c;
+}
+
+// (protected) copy this to r
+
+function bnpCopyTo(r) {
+ for (var i = this.t - 1; i >= 0; --i) r[i] = this[i];
+ r.t = this.t;
+ r.s = this.s;
+}
+
+// (protected) set from integer value x, -DV <= x < DV
+
+function bnpFromInt(x) {
+ this.t = 1;
+ this.s = (x < 0) ? -1 : 0;
+ if (x > 0) this[0] = x;
+ else if (x < -1) this[0] = x + DV;
+ else this.t = 0;
+}
+
+// return bigint initialized to value
+
+function nbv(i) {
+ var r = nbi();
+ r.fromInt(i);
+ return r;
+}
+
+// (protected) set from string and radix
+
+function bnpFromString(s, b) {
+ var k;
+ if (b == 16) k = 4;
+ else if (b == 8) k = 3;
+ else if (b == 256) k = 8; // byte array
+ else if (b == 2) k = 1;
+ else if (b == 32) k = 5;
+ else if (b == 4) k = 2;
+ else {
+ this.fromRadix(s, b);
+ return;
+ }
+ this.t = 0;
+ this.s = 0;
+ var i = s.length,
+ mi = false,
+ sh = 0;
+ while (--i >= 0) {
+ var x = (k == 8) ? s[i] & 0xff : intAt(s, i);
+ if (x < 0) {
+ if (s.charAt(i) == "-") mi = true;
+ continue;
+ }
+ mi = false;
+ if (sh == 0) this[this.t++] = x;
+ else if (sh + k > this.DB) {
+ this[this.t - 1] |= (x & ((1 << (this.DB - sh)) - 1)) << sh;
+ this[this.t++] = (x >> (this.DB - sh));
+ }
+ else this[this.t - 1] |= x << sh;
+ sh += k;
+ if (sh >= this.DB) sh -= this.DB;
+ }
+ if (k == 8 && (s[0] & 0x80) != 0) {
+ this.s = -1;
+ if (sh > 0) this[this.t - 1] |= ((1 << (this.DB - sh)) - 1) << sh;
+ }
+ this.clamp();
+ if (mi) BigInteger.ZERO.subTo(this, this);
+}
+
+// (protected) clamp off excess high words
+
+function bnpClamp() {
+ var c = this.s & this.DM;
+ while (this.t > 0 && this[this.t - 1] == c) --this.t;
+}
+
+// (public) return string representation in given radix
+
+function bnToString(b) {
+ if (this.s < 0) return "-" + this.negate().toString(b);
+ var k;
+ if (b == 16) k = 4;
+ else if (b == 8) k = 3;
+ else if (b == 2) k = 1;
+ else if (b == 32) k = 5;
+ else if (b == 64) k = 6;
+ else if (b == 4) k = 2;
+ else return this.toRadix(b);
+ var km = (1 << k) - 1,
+ d, m = false,
+ r = "",
+ i = this.t;
+ var p = this.DB - (i * this.DB) % k;
+ if (i-- > 0) {
+ if (p < this.DB && (d = this[i] >> p) > 0) {
+ m = true;
+ r = int2char(d);
+ }
+ while (i >= 0) {
+ if (p < k) {
+ d = (this[i] & ((1 << p) - 1)) << (k - p);
+ d |= this[--i] >> (p += this.DB - k);
+ }
+ else {
+ d = (this[i] >> (p -= k)) & km;
+ if (p <= 0) {
+ p += this.DB;
+ --i;
+ }
+ }
+ if (d > 0) m = true;
+ if (m) r += int2char(d);
+ }
+ }
+ return m ? r : "0";
+}
+
+// (public) -this
+
+function bnNegate() {
+ var r = nbi();
+ BigInteger.ZERO.subTo(this, r);
+ return r;
+}
+
+// (public) |this|
+
+function bnAbs() {
+ return (this.s < 0) ? this.negate() : this;
+}
+
+// (public) return + if this > a, - if this < a, 0 if equal
+
+function bnCompareTo(a) {
+ var r = this.s - a.s;
+ if (r != 0) return r;
+ var i = this.t;
+ r = i - a.t;
+ if (r != 0) return r;
+ while (--i >= 0) if ((r = this[i] - a[i]) != 0) return r;
+ return 0;
+}
+
+// returns bit length of the integer x
+
+function nbits(x) {
+ var r = 1,
+ t;
+ if ((t = x >>> 16) != 0) {
+ x = t;
+ r += 16;
+ }
+ if ((t = x >> 8) != 0) {
+ x = t;
+ r += 8;
+ }
+ if ((t = x >> 4) != 0) {
+ x = t;
+ r += 4;
+ }
+ if ((t = x >> 2) != 0) {
+ x = t;
+ r += 2;
+ }
+ if ((t = x >> 1) != 0) {
+ x = t;
+ r += 1;
+ }
+ return r;
+}
+
+// (public) return the number of bits in "this"
+
+function bnBitLength() {
+ if (this.t <= 0) return 0;
+ return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM));
+}
+
+// (protected) r = this << n*DB
+
+function bnpDLShiftTo(n, r) {
+ var i;
+ for (i = this.t - 1; i >= 0; --i) r[i + n] = this[i];
+ for (i = n - 1; i >= 0; --i) r[i] = 0;
+ r.t = this.t + n;
+ r.s = this.s;
+}
+
+// (protected) r = this >> n*DB
+
+function bnpDRShiftTo(n, r) {
+ for (var i = n; i < this.t; ++i) r[i - n] = this[i];
+ r.t = Math.max(this.t - n, 0);
+ r.s = this.s;
+}
+
+// (protected) r = this << n
+
+function bnpLShiftTo(n, r) {
+ var bs = n % this.DB;
+ var cbs = this.DB - bs;
+ var bm = (1 << cbs) - 1;
+ var ds = Math.floor(n / this.DB),
+ c = (this.s << bs) & this.DM,
+ i;
+ for (i = this.t - 1; i >= 0; --i) {
+ r[i + ds + 1] = (this[i] >> cbs) | c;
+ c = (this[i] & bm) << bs;
+ }
+ for (i = ds - 1; i >= 0; --i) r[i] = 0;
+ r[ds] = c;
+ r.t = this.t + ds + 1;
+ r.s = this.s;
+ r.clamp();
+}
+
+// (protected) r = this >> n
+
+function bnpRShiftTo(n, r) {
+ r.s = this.s;
+ var ds = Math.floor(n / this.DB);
+ if (ds >= this.t) {
+ r.t = 0;
+ return;
+ }
+ var bs = n % this.DB;
+ var cbs = this.DB - bs;
+ var bm = (1 << bs) - 1;
+ r[0] = this[ds] >> bs;
+ for (var i = ds + 1; i < this.t; ++i) {
+ r[i - ds - 1] |= (this[i] & bm) << cbs;
+ r[i - ds] = this[i] >> bs;
+ }
+ if (bs > 0) r[this.t - ds - 1] |= (this.s & bm) << cbs;
+ r.t = this.t - ds;
+ r.clamp();
+}
+
+// (protected) r = this - a
+
+function bnpSubTo(a, r) {
+ var i = 0,
+ c = 0,
+ m = Math.min(a.t, this.t);
+ while (i < m) {
+ c += this[i] - a[i];
+ r[i++] = c & this.DM;
+ c >>= this.DB;
+ }
+ if (a.t < this.t) {
+ c -= a.s;
+ while (i < this.t) {
+ c += this[i];
+ r[i++] = c & this.DM;
+ c >>= this.DB;
+ }
+ c += this.s;
+ }
+ else {
+ c += this.s;
+ while (i < a.t) {
+ c -= a[i];
+ r[i++] = c & this.DM;
+ c >>= this.DB;
+ }
+ c -= a.s;
+ }
+ r.s = (c < 0) ? -1 : 0;
+ if (c < -1) r[i++] = this.DV + c;
+ else if (c > 0) r[i++] = c;
+ r.t = i;
+ r.clamp();
+}
+
+// (protected) r = this * a, r != this,a (HAC 14.12)
+// "this" should be the larger one if appropriate.
+
+function bnpMultiplyTo(a, r) {
+ var x = this.abs(),
+ y = a.abs();
+ var i = x.t;
+ r.t = i + y.t;
+ while (--i >= 0) r[i] = 0;
+ for (i = 0; i < y.t; ++i) r[i + x.t] = x.am(0, y[i], r, i, 0, x.t);
+ r.s = 0;
+ r.clamp();
+ if (this.s != a.s) BigInteger.ZERO.subTo(r, r);
+}
+
+// (protected) r = this^2, r != this (HAC 14.16)
+
+function bnpSquareTo(r) {
+ var x = this.abs();
+ var i = r.t = 2 * x.t;
+ while (--i >= 0) r[i] = 0;
+ for (i = 0; i < x.t - 1; ++i) {
+ var c = x.am(i, x[i], r, 2 * i, 0, 1);
+ if ((r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= x.DV) {
+ r[i + x.t] -= x.DV;
+ r[i + x.t + 1] = 1;
+ }
+ }
+ if (r.t > 0) r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1);
+ r.s = 0;
+ r.clamp();
+}
+
+// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
+// r != q, this != m. q or r may be null.
+
+function bnpDivRemTo(m, q, r) {
+ var pm = m.abs();
+ if (pm.t <= 0) return;
+ var pt = this.abs();
+ if (pt.t < pm.t) {
+ if (q != null) q.fromInt(0);
+ if (r != null) this.copyTo(r);
+ return;
+ }
+ if (r == null) r = nbi();
+ var y = nbi(),
+ ts = this.s,
+ ms = m.s;
+ var nsh = this.DB - nbits(pm[pm.t - 1]); // normalize modulus
+ if (nsh > 0) {
+ pm.lShiftTo(nsh, y);
+ pt.lShiftTo(nsh, r);
+ }
+ else {
+ pm.copyTo(y);
+ pt.copyTo(r);
+ }
+ var ys = y.t;
+ var y0 = y[ys - 1];
+ if (y0 == 0) return;
+ var yt = y0 * (1 << this.F1) + ((ys > 1) ? y[ys - 2] >> this.F2 : 0);
+ var d1 = this.FV / yt,
+ d2 = (1 << this.F1) / yt,
+ e = 1 << this.F2;
+ var i = r.t,
+ j = i - ys,
+ t = (q == null) ? nbi() : q;
+ y.dlShiftTo(j, t);
+ if (r.compareTo(t) >= 0) {
+ r[r.t++] = 1;
+ r.subTo(t, r);
+ }
+ BigInteger.ONE.dlShiftTo(ys, t);
+ t.subTo(y, y); // "negative" y so we can replace sub with am later
+ while (y.t < ys) y[y.t++] = 0;
+ while (--j >= 0) {
+ // Estimate quotient digit
+ var qd = (r[--i] == y0) ? this.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2);
+ if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) { // Try it out
+ y.dlShiftTo(j, t);
+ r.subTo(t, r);
+ while (r[i] < --qd) r.subTo(t, r);
+ }
+ }
+ if (q != null) {
+ r.drShiftTo(ys, q);
+ if (ts != ms) BigInteger.ZERO.subTo(q, q);
+ }
+ r.t = ys;
+ r.clamp();
+ if (nsh > 0) r.rShiftTo(nsh, r); // Denormalize remainder
+ if (ts < 0) BigInteger.ZERO.subTo(r, r);
+}
+
+// (public) this mod a
+
+function bnMod(a) {
+ var r = nbi();
+ this.abs().divRemTo(a, null, r);
+ if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r);
+ return r;
+}
+
+// Modular reduction using "classic" algorithm
+
+function Classic(m) {
+ this.m = m;
+}
+
+function cConvert(x) {
+ if (x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);
+ else return x;
+}
+
+function cRevert(x) {
+ return x;
+}
+
+function cReduce(x) {
+ x.divRemTo(this.m, null, x);
+}
+
+function cMulTo(x, y, r) {
+ x.multiplyTo(y, r);
+ this.reduce(r);
+}
+
+function cSqrTo(x, r) {
+ x.squareTo(r);
+ this.reduce(r);
+}
+
+Classic.prototype.convert = cConvert;
+Classic.prototype.revert = cRevert;
+Classic.prototype.reduce = cReduce;
+Classic.prototype.mulTo = cMulTo;
+Classic.prototype.sqrTo = cSqrTo;
+
+// (protected) return "-1/this % 2^DB"; useful for Mont. reduction
+// justification:
+// xy == 1 (mod m)
+// xy = 1+km
+// xy(2-xy) = (1+km)(1-km)
+// x[y(2-xy)] = 1-k^2m^2
+// x[y(2-xy)] == 1 (mod m^2)
+// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
+// should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
+// JS multiply "overflows" differently from C/C++, so care is needed here.
+
+function bnpInvDigit() {
+ if (this.t < 1) return 0;
+ var x = this[0];
+ if ((x & 1) == 0) return 0;
+ var y = x & 3; // y == 1/x mod 2^2
+ y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4
+ y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8
+ y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16
+ // last step - calculate inverse mod DV directly;
+ // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
+ y = (y * (2 - x * y % this.DV)) % this.DV; // y == 1/x mod 2^dbits
+ // we really want the negative inverse, and -DV < y < DV
+ return (y > 0) ? this.DV - y : -y;
+}
+
+// Montgomery reduction
+
+function Montgomery(m) {
+ this.m = m;
+ this.mp = m.invDigit();
+ this.mpl = this.mp & 0x7fff;
+ this.mph = this.mp >> 15;
+ this.um = (1 << (m.DB - 15)) - 1;
+ this.mt2 = 2 * m.t;
+}
+
+// xR mod m
+
+function montConvert(x) {
+ var r = nbi();
+ x.abs().dlShiftTo(this.m.t, r);
+ r.divRemTo(this.m, null, r);
+ if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r);
+ return r;
+}
+
+// x/R mod m
+
+function montRevert(x) {
+ var r = nbi();
+ x.copyTo(r);
+ this.reduce(r);
+ return r;
+}
+
+// x = x/R mod m (HAC 14.32)
+
+function montReduce(x) {
+ while (x.t <= this.mt2) // pad x so am has enough room later
+ x[x.t++] = 0;
+ for (var i = 0; i < this.m.t; ++i) {
+ // faster way of calculating u0 = x[i]*mp mod DV
+ var j = x[i] & 0x7fff;
+ var u0 = (j * this.mpl + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & x.DM;
+ // use am to combine the multiply-shift-add into one call
+ j = i + this.m.t;
+ x[j] += this.m.am(0, u0, x, i, 0, this.m.t);
+ // propagate carry
+ while (x[j] >= x.DV) {
+ x[j] -= x.DV;
+ x[++j]++;
+ }
+ }
+ x.clamp();
+ x.drShiftTo(this.m.t, x);
+ if (x.compareTo(this.m) >= 0) x.subTo(this.m, x);
+}
+
+// r = "x^2/R mod m"; x != r
+
+function montSqrTo(x, r) {
+ x.squareTo(r);
+ this.reduce(r);
+}
+
+// r = "xy/R mod m"; x,y != r
+
+function montMulTo(x, y, r) {
+ x.multiplyTo(y, r);
+ this.reduce(r);
+}
+
+Montgomery.prototype.convert = montConvert;
+Montgomery.prototype.revert = montRevert;
+Montgomery.prototype.reduce = montReduce;
+Montgomery.prototype.mulTo = montMulTo;
+Montgomery.prototype.sqrTo = montSqrTo;
+
+// (protected) true iff this is even
+
+function bnpIsEven() {
+ return ((this.t > 0) ? (this[0] & 1) : this.s) == 0;
+}
+
+// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
+
+function bnpExp(e, z) {
+ if (e > 0xffffffff || e < 1) return BigInteger.ONE;
+ var r = nbi(),
+ r2 = nbi(),
+ g = z.convert(this),
+ i = nbits(e) - 1;
+ g.copyTo(r);
+ while (--i >= 0) {
+ z.sqrTo(r, r2);
+ if ((e & (1 << i)) > 0) z.mulTo(r2, g, r);
+ else {
+ var t = r;
+ r = r2;
+ r2 = t;
+ }
+ }
+ return z.revert(r);
+}
+
+// (public) this^e % m, 0 <= e < 2^32
+
+function bnModPowInt(e, m) {
+ var z;
+ if (e < 256 || m.isEven()) z = new Classic(m);
+ else z = new Montgomery(m);
+ return this.exp(e, z);
+}
+
+// protected
+BigInteger.prototype.copyTo = bnpCopyTo;
+BigInteger.prototype.fromInt = bnpFromInt;
+BigInteger.prototype.fromString = bnpFromString;
+BigInteger.prototype.clamp = bnpClamp;
+BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
+BigInteger.prototype.drShiftTo = bnpDRShiftTo;
+BigInteger.prototype.lShiftTo = bnpLShiftTo;
+BigInteger.prototype.rShiftTo = bnpRShiftTo;
+BigInteger.prototype.subTo = bnpSubTo;
+BigInteger.prototype.multiplyTo = bnpMultiplyTo;
+BigInteger.prototype.squareTo = bnpSquareTo;
+BigInteger.prototype.divRemTo = bnpDivRemTo;
+BigInteger.prototype.invDigit = bnpInvDigit;
+BigInteger.prototype.isEven = bnpIsEven;
+BigInteger.prototype.exp = bnpExp;
+
+// public
+BigInteger.prototype.toString = bnToString;
+BigInteger.prototype.negate = bnNegate;
+BigInteger.prototype.abs = bnAbs;
+BigInteger.prototype.compareTo = bnCompareTo;
+BigInteger.prototype.bitLength = bnBitLength;
+BigInteger.prototype.mod = bnMod;
+BigInteger.prototype.modPowInt = bnModPowInt;
+
+// "constants"
+BigInteger.ZERO = nbv(0);
+BigInteger.ONE = nbv(1);
+
+
+function bnClone() {
+ var r = nbi();
+ this.copyTo(r);
+ return r;
+}
+
+// (public) return value as integer
+
+function bnIntValue() {
+ if (this.s < 0) {
+ if (this.t == 1) return this[0] - this.DV;
+ else if (this.t == 0) return -1;
+ }
+ else if (this.t == 1) return this[0];
+ else if (this.t == 0) return 0;
+ // assumes 16 < DB < 32
+ return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0];
+}
+
+// (public) return value as byte
+
+function bnByteValue() {
+ return (this.t == 0) ? this.s : (this[0] << 24) >> 24;
+}
+
+// (public) return value as short (assumes DB>=16)
+
+function bnShortValue() {
+ return (this.t == 0) ? this.s : (this[0] << 16) >> 16;
+}
+
+// (protected) return x s.t. r^x < DV
+
+function bnpChunkSize(r) {
+ return Math.floor(Math.LN2 * this.DB / Math.log(r));
+}
+
+// (public) 0 if this == 0, 1 if this > 0
+
+function bnSigNum() {
+ if (this.s < 0) return -1;
+ else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0;
+ else return 1;
+}
+
+// (protected) convert to radix string
+
+function bnpToRadix(b) {
+ if (b == null) b = 10;
+ if (this.signum() == 0 || b < 2 || b > 36) return "0";
+ var cs = this.chunkSize(b);
+ var a = Math.pow(b, cs);
+ var d = nbv(a),
+ y = nbi(),
+ z = nbi(),
+ r = "";
+ this.divRemTo(d, y, z);
+ while (y.signum() > 0) {
+ r = (a + z.intValue()).toString(b).substr(1) + r;
+ y.divRemTo(d, y, z);
+ }
+ return z.intValue().toString(b) + r;
+}
+
+// (protected) convert from radix string
+
+function bnpFromRadix(s, b) {
+ this.fromInt(0);
+ if (b == null) b = 10;
+ var cs = this.chunkSize(b);
+ var d = Math.pow(b, cs),
+ mi = false,
+ j = 0,
+ w = 0;
+ for (var i = 0; i < s.length; ++i) {
+ var x = intAt(s, i);
+ if (x < 0) {
+ if (s.charAt(i) == "-" && this.signum() == 0) mi = true;
+ continue;
+ }
+ w = b * w + x;
+ if (++j >= cs) {
+ this.dMultiply(d);
+ this.dAddOffset(w, 0);
+ j = 0;
+ w = 0;
+ }
+ }
+ if (j > 0) {
+ this.dMultiply(Math.pow(b, j));
+ this.dAddOffset(w, 0);
+ }
+ if (mi) BigInteger.ZERO.subTo(this, this);
+}
+
+// (protected) alternate constructor
+
+function bnpFromNumber(a, b, c) {
+ if ("number" == typeof b) {
+ // new BigInteger(int,int,RNG)
+ if (a < 2) this.fromInt(1);
+ else {
+ this.fromNumber(a, c);
+ if (!this.testBit(a - 1)) // force MSB set
+ this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this);
+ if (this.isEven()) this.dAddOffset(1, 0); // force odd
+ while (!this.isProbablePrime(b)) {
+ this.dAddOffset(2, 0);
+ if (this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a - 1), this);
+ }
+ }
+ }
+ else {
+ // new BigInteger(int,RNG)
+ var x = new Array(),
+ t = a & 7;
+ x.length = (a >> 3) + 1;
+ b.nextBytes(x);
+ if (t > 0) x[0] &= ((1 << t) - 1);
+ else x[0] = 0;
+ this.fromString(x, 256);
+ }
+}
+
+// (public) convert to bigendian byte array
+
+function bnToByteArray() {
+ var i = this.t,
+ r = new Array();
+ r[0] = this.s;
+ var p = this.DB - (i * this.DB) % 8,
+ d, k = 0;
+ if (i-- > 0) {
+ if (p < this.DB && (d = this[i] >> p) != (this.s & this.DM) >> p) r[k++] = d | (this.s << (this.DB - p));
+ while (i >= 0) {
+ if (p < 8) {
+ d = (this[i] & ((1 << p) - 1)) << (8 - p);
+ d |= this[--i] >> (p += this.DB - 8);
+ }
+ else {
+ d = (this[i] >> (p -= 8)) & 0xff;
+ if (p <= 0) {
+ p += this.DB;
+ --i;
+ }
+ }
+ if ((d & 0x80) != 0) d |= -256;
+ if (k == 0 && (this.s & 0x80) != (d & 0x80)) ++k;
+ if (k > 0 || d != this.s) r[k++] = d;
+ }
+ }
+ return r;
+}
+
+function bnEquals(a) {
+ return (this.compareTo(a) == 0);
+}
+
+function bnMin(a) {
+ return (this.compareTo(a) < 0) ? this : a;
+}
+
+function bnMax(a) {
+ return (this.compareTo(a) > 0) ? this : a;
+}
+
+// (protected) r = this op a (bitwise)
+
+function bnpBitwiseTo(a, op, r) {
+ var i, f, m = Math.min(a.t, this.t);
+ for (i = 0; i < m; ++i) r[i] = op(this[i], a[i]);
+ if (a.t < this.t) {
+ f = a.s & this.DM;
+ for (i = m; i < this.t; ++i) r[i] = op(this[i], f);
+ r.t = this.t;
+ }
+ else {
+ f = this.s & this.DM;
+ for (i = m; i < a.t; ++i) r[i] = op(f, a[i]);
+ r.t = a.t;
+ }
+ r.s = op(this.s, a.s);
+ r.clamp();
+}
+
+// (public) this & a
+
+function op_and(x, y) {
+ return x & y;
+}
+
+function bnAnd(a) {
+ var r = nbi();
+ this.bitwiseTo(a, op_and, r);
+ return r;
+}
+
+// (public) this | a
+
+function op_or(x, y) {
+ return x | y;
+}
+
+function bnOr(a) {
+ var r = nbi();
+ this.bitwiseTo(a, op_or, r);
+ return r;
+}
+
+// (public) this ^ a
+
+function op_xor(x, y) {
+ return x ^ y;
+}
+
+function bnXor(a) {
+ var r = nbi();
+ this.bitwiseTo(a, op_xor, r);
+ return r;
+}
+
+// (public) this & ~a
+
+function op_andnot(x, y) {
+ return x & ~y;
+}
+
+function bnAndNot(a) {
+ var r = nbi();
+ this.bitwiseTo(a, op_andnot, r);
+ return r;
+}
+
+// (public) ~this
+
+function bnNot() {
+ var r = nbi();
+ for (var i = 0; i < this.t; ++i) r[i] = this.DM & ~this[i];
+ r.t = this.t;
+ r.s = ~this.s;
+ return r;
+}
+
+// (public) this << n
+
+function bnShiftLeft(n) {
+ var r = nbi();
+ if (n < 0) this.rShiftTo(-n, r);
+ else this.lShiftTo(n, r);
+ return r;
+}
+
+// (public) this >> n
+
+function bnShiftRight(n) {
+ var r = nbi();
+ if (n < 0) this.lShiftTo(-n, r);
+ else this.rShiftTo(n, r);
+ return r;
+}
+
+// return index of lowest 1-bit in x, x < 2^31
+
+function lbit(x) {
+ if (x == 0) return -1;
+ var r = 0;
+ if ((x & 0xffff) == 0) {
+ x >>= 16;
+ r += 16;
+ }
+ if ((x & 0xff) == 0) {
+ x >>= 8;
+ r += 8;
+ }
+ if ((x & 0xf) == 0) {
+ x >>= 4;
+ r += 4;
+ }
+ if ((x & 3) == 0) {
+ x >>= 2;
+ r += 2;
+ }
+ if ((x & 1) == 0) ++r;
+ return r;
+}
+
+// (public) returns index of lowest 1-bit (or -1 if none)
+
+function bnGetLowestSetBit() {
+ for (var i = 0; i < this.t; ++i)
+ if (this[i] != 0) return i * this.DB + lbit(this[i]);
+ if (this.s < 0) return this.t * this.DB;
+ return -1;
+}
+
+// return number of 1 bits in x
+
+function cbit(x) {
+ var r = 0;
+ while (x != 0) {
+ x &= x - 1;
+ ++r;
+ }
+ return r;
+}
+
+// (public) return number of set bits
+
+function bnBitCount() {
+ var r = 0,
+ x = this.s & this.DM;
+ for (var i = 0; i < this.t; ++i) r += cbit(this[i] ^ x);
+ return r;
+}
+
+// (public) true iff nth bit is set
+
+function bnTestBit(n) {
+ var j = Math.floor(n / this.DB);
+ if (j >= this.t) return (this.s != 0);
+ return ((this[j] & (1 << (n % this.DB))) != 0);
+}
+
+// (protected) this op (1<<n)
+
+function bnpChangeBit(n, op) {
+ var r = BigInteger.ONE.shiftLeft(n);
+ this.bitwiseTo(r, op, r);
+ return r;
+}
+
+// (public) this | (1<<n)
+
+function bnSetBit(n) {
+ return this.changeBit(n, op_or);
+}
+
+// (public) this & ~(1<<n)
+
+function bnClearBit(n) {
+ return this.changeBit(n, op_andnot);
+}
+
+// (public) this ^ (1<<n)
+
+function bnFlipBit(n) {
+ return this.changeBit(n, op_xor);
+}
+
+// (protected) r = this + a
+
+function bnpAddTo(a, r) {
+ var i = 0,
+ c = 0,
+ m = Math.min(a.t, this.t);
+ while (i < m) {
+ c += this[i] + a[i];
+ r[i++] = c & this.DM;
+ c >>= this.DB;
+ }
+ if (a.t < this.t) {
+ c += a.s;
+ while (i < this.t) {
+ c += this[i];
+ r[i++] = c & this.DM;
+ c >>= this.DB;
+ }
+ c += this.s;
+ }
+ else {
+ c += this.s;
+ while (i < a.t) {
+ c += a[i];
+ r[i++] = c & this.DM;
+ c >>= this.DB;
+ }
+ c += a.s;
+ }
+ r.s = (c < 0) ? -1 : 0;
+ if (c > 0) r[i++] = c;
+ else if (c < -1) r[i++] = this.DV + c;
+ r.t = i;
+ r.clamp();
+}
+
+// (public) this + a
+
+function bnAdd(a) {
+ var r = nbi();
+ this.addTo(a, r);
+ return r;
+}
+
+// (public) this - a
+
+function bnSubtract(a) {
+ var r = nbi();
+ this.subTo(a, r);
+ return r;
+}
+
+// (public) this * a
+
+function bnMultiply(a) {
+ var r = nbi();
+ this.multiplyTo(a, r);
+ return r;
+}
+
+// (public) this^2
+
+function bnSquare() {
+ var r = nbi();
+ this.squareTo(r);
+ return r;
+}
+
+// (public) this / a
+
+function bnDivide(a) {
+ var r = nbi();
+ this.divRemTo(a, r, null);
+ return r;
+}
+
+// (public) this % a
+
+function bnRemainder(a) {
+ var r = nbi();
+ this.divRemTo(a, null, r);
+ return r;
+}
+
+// (public) [this/a,this%a]
+
+function bnDivideAndRemainder(a) {
+ var q = nbi(),
+ r = nbi();
+ this.divRemTo(a, q, r);
+ return new Array(q, r);
+}
+
+// (protected) this *= n, this >= 0, 1 < n < DV
+
+function bnpDMultiply(n) {
+ this[this.t] = this.am(0, n - 1, this, 0, 0, this.t);
+ ++this.t;
+ this.clamp();
+}
+
+// (protected) this += n << w words, this >= 0
+
+function bnpDAddOffset(n, w) {
+ if (n == 0) return;
+ while (this.t <= w) this[this.t++] = 0;
+ this[w] += n;
+ while (this[w] >= this.DV) {
+ this[w] -= this.DV;
+ if (++w >= this.t) this[this.t++] = 0;
+ ++this[w];
+ }
+}
+
+// A "null" reducer
+
+function NullExp() {
+}
+
+function nNop(x) {
+ return x;
+}
+
+function nMulTo(x, y, r) {
+ x.multiplyTo(y, r);
+}
+
+function nSqrTo(x, r) {
+ x.squareTo(r);
+}
+
+NullExp.prototype.convert = nNop;
+NullExp.prototype.revert = nNop;
+NullExp.prototype.mulTo = nMulTo;
+NullExp.prototype.sqrTo = nSqrTo;
+
+// (public) this^e
+
+function bnPow(e) {
+ return this.exp(e, new NullExp());
+}
+
+// (protected) r = lower n words of "this * a", a.t <= n
+// "this" should be the larger one if appropriate.
+
+function bnpMultiplyLowerTo(a, n, r) {
+ var i = Math.min(this.t + a.t, n);
+ r.s = 0; // assumes a,this >= 0
+ r.t = i;
+ while (i > 0) r[--i] = 0;
+ var j;
+ for (j = r.t - this.t; i < j; ++i) r[i + this.t] = this.am(0, a[i], r, i, 0, this.t);
+ for (j = Math.min(a.t, n); i < j; ++i) this.am(0, a[i], r, i, 0, n - i);
+ r.clamp();
+}
+
+// (protected) r = "this * a" without lower n words, n > 0
+// "this" should be the larger one if appropriate.
+
+function bnpMultiplyUpperTo(a, n, r) {
+ --n;
+ var i = r.t = this.t + a.t - n;
+ r.s = 0; // assumes a,this >= 0
+ while (--i >= 0) r[i] = 0;
+ for (i = Math.max(n - this.t, 0); i < a.t; ++i)
+ r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n);
+ r.clamp();
+ r.drShiftTo(1, r);
+}
+
+// Barrett modular reduction
+
+function Barrett(m) {
+ // setup Barrett
+ this.r2 = nbi();
+ this.q3 = nbi();
+ BigInteger.ONE.dlShiftTo(2 * m.t, this.r2);
+ this.mu = this.r2.divide(m);
+ this.m = m;
+}
+
+function barrettConvert(x) {
+ if (x.s < 0 || x.t > 2 * this.m.t) return x.mod(this.m);
+ else if (x.compareTo(this.m) < 0) return x;
+ else {
+ var r = nbi();
+ x.copyTo(r);
+ this.reduce(r);
+ return r;
+ }
+}
+
+function barrettRevert(x) {
+ return x;
+}
+
+// x = x mod m (HAC 14.42)
+
+function barrettReduce(x) {
+ x.drShiftTo(this.m.t - 1, this.r2);
+ if (x.t > this.m.t + 1) {
+ x.t = this.m.t + 1;
+ x.clamp();
+ }
+ this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3);
+ this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2);
+ while (x.compareTo(this.r2) < 0) x.dAddOffset(1, this.m.t + 1);
+ x.subTo(this.r2, x);
+ while (x.compareTo(this.m) >= 0) x.subTo(this.m, x);
+}
+
+// r = x^2 mod m; x != r
+
+function barrettSqrTo(x, r) {
+ x.squareTo(r);
+ this.reduce(r);
+}
+
+// r = x*y mod m; x,y != r
+
+function barrettMulTo(x, y, r) {
+ x.multiplyTo(y, r);
+ this.reduce(r);
+}
+
+Barrett.prototype.convert = barrettConvert;
+Barrett.prototype.revert = barrettRevert;
+Barrett.prototype.reduce = barrettReduce;
+Barrett.prototype.mulTo = barrettMulTo;
+Barrett.prototype.sqrTo = barrettSqrTo;
+
+// (public) this^e % m (HAC 14.85)
+
+function bnModPow(e, m) {
+ var i = e.bitLength(),
+ k, r = nbv(1),
+ z;
+ if (i <= 0) return r;
+ else if (i < 18) k = 1;
+ else if (i < 48) k = 3;
+ else if (i < 144) k = 4;
+ else if (i < 768) k = 5;
+ else k = 6;
+ if (i < 8) z = new Classic(m);
+ else if (m.isEven()) z = new Barrett(m);
+ else z = new Montgomery(m);
+
+ // precomputation
+ var g = new Array(),
+ n = 3,
+ k1 = k - 1,
+ km = (1 << k) - 1;
+ g[1] = z.convert(this);
+ if (k > 1) {
+ var g2 = nbi();
+ z.sqrTo(g[1], g2);
+ while (n <= km) {
+ g[n] = nbi();
+ z.mulTo(g2, g[n - 2], g[n]);
+ n += 2;
+ }
+ }
+
+ var j = e.t - 1,
+ w, is1 = true,
+ r2 = nbi(),
+ t;
+ i = nbits(e[j]) - 1;
+ while (j >= 0) {
+ if (i >= k1) w = (e[j] >> (i - k1)) & km;
+ else {
+ w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i);
+ if (j > 0) w |= e[j - 1] >> (this.DB + i - k1);
+ }
+
+ n = k;
+ while ((w & 1) == 0) {
+ w >>= 1;
+ --n;
+ }
+ if ((i -= n) < 0) {
+ i += this.DB;
+ --j;
+ }
+ if (is1) { // ret == 1, don't bother squaring or multiplying it
+ g[w].copyTo(r);
+ is1 = false;
+ }
+ else {
+ while (n > 1) {
+ z.sqrTo(r, r2);
+ z.sqrTo(r2, r);
+ n -= 2;
+ }
+ if (n > 0) z.sqrTo(r, r2);
+ else {
+ t = r;
+ r = r2;
+ r2 = t;
+ }
+ z.mulTo(r2, g[w], r);
+ }
+
+ while (j >= 0 && (e[j] & (1 << i)) == 0) {
+ z.sqrTo(r, r2);
+ t = r;
+ r = r2;
+ r2 = t;
+ if (--i < 0) {
+ i = this.DB - 1;
+ --j;
+ }
+ }
+ }
+ return z.revert(r);
+}
+
+// (public) gcd(this,a) (HAC 14.54)
+
+function bnGCD(a) {
+ var x = (this.s < 0) ? this.negate() : this.clone();
+ var y = (a.s < 0) ? a.negate() : a.clone();
+ if (x.compareTo(y) < 0) {
+ var t = x;
+ x = y;
+ y = t;
+ }
+ var i = x.getLowestSetBit(),
+ g = y.getLowestSetBit();
+ if (g < 0) return x;
+ if (i < g) g = i;
+ if (g > 0) {
+ x.rShiftTo(g, x);
+ y.rShiftTo(g, y);
+ }
+ while (x.signum() > 0) {
+ if ((i = x.getLowestSetBit()) > 0) x.rShiftTo(i, x);
+ if ((i = y.getLowestSetBit()) > 0) y.rShiftTo(i, y);
+ if (x.compareTo(y) >= 0) {
+ x.subTo(y, x);
+ x.rShiftTo(1, x);
+ }
+ else {
+ y.subTo(x, y);
+ y.rShiftTo(1, y);
+ }
+ }
+ if (g > 0) y.lShiftTo(g, y);
+ return y;
+}
+
+// (protected) this % n, n < 2^26
+
+function bnpModInt(n) {
+ if (n <= 0) return 0;
+ var d = this.DV % n,
+ r = (this.s < 0) ? n - 1 : 0;
+ if (this.t > 0) if (d == 0) r = this[0] % n;
+ else for (var i = this.t - 1; i >= 0; --i) r = (d * r + this[i]) % n;
+ return r;
+}
+
+// (public) 1/this % m (HAC 14.61)
+
+function bnModInverse(m) {
+ var ac = m.isEven();
+ if ((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO;
+ var u = m.clone(),
+ v = this.clone();
+ var a = nbv(1),
+ b = nbv(0),
+ c = nbv(0),
+ d = nbv(1);
+ while (u.signum() != 0) {
+ while (u.isEven()) {
+ u.rShiftTo(1, u);
+ if (ac) {
+ if (!a.isEven() || !b.isEven()) {
+ a.addTo(this, a);
+ b.subTo(m, b);
+ }
+ a.rShiftTo(1, a);
+ }
+ else if (!b.isEven()) b.subTo(m, b);
+ b.rShiftTo(1, b);
+ }
+ while (v.isEven()) {
+ v.rShiftTo(1, v);
+ if (ac) {
+ if (!c.isEven() || !d.isEven()) {
+ c.addTo(this, c);
+ d.subTo(m, d);
+ }
+ c.rShiftTo(1, c);
+ }
+ else if (!d.isEven()) d.subTo(m, d);
+ d.rShiftTo(1, d);
+ }
+ if (u.compareTo(v) >= 0) {
+ u.subTo(v, u);
+ if (ac) a.subTo(c, a);
+ b.subTo(d, b);
+ }
+ else {
+ v.subTo(u, v);
+ if (ac) c.subTo(a, c);
+ d.subTo(b, d);
+ }
+ }
+ if (v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO;
+ if (d.compareTo(m) >= 0) return d.subtract(m);
+ if (d.signum() < 0) d.addTo(m, d);
+ else return d;
+ if (d.signum() < 0) return d.add(m);
+ else return d;
+}
+
+var lowprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997];
+var lplim = (1 << 26) / lowprimes[lowprimes.length - 1];
+
+// (public) test primality with certainty >= 1-.5^t
+
+function bnIsProbablePrime(t) {
+ var i, x = this.abs();
+ if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) {
+ for (i = 0; i < lowprimes.length; ++i)
+ if (x[0] == lowprimes[i]) return true;
+ return false;
+ }
+ if (x.isEven()) return false;
+ i = 1;
+ while (i < lowprimes.length) {
+ var m = lowprimes[i],
+ j = i + 1;
+ while (j < lowprimes.length && m < lplim) m *= lowprimes[j++];
+ m = x.modInt(m);
+ while (i < j) if (m % lowprimes[i++] == 0) return false;
+ }
+ return x.millerRabin(t);
+}
+
+// (protected) true if probably prime (HAC 4.24, Miller-Rabin)
+
+function bnpMillerRabin(t) {
+ var n1 = this.subtract(BigInteger.ONE);
+ var k = n1.getLowestSetBit();
+ if (k <= 0) return false;
+ var r = n1.shiftRight(k);
+ t = (t + 1) >> 1;
+ if (t > lowprimes.length) t = lowprimes.length;
+ var a = nbi();
+ for (var i = 0; i < t; ++i) {
+ //Pick bases at random, instead of starting at 2
+ a.fromInt(lowprimes[Math.floor(Math.random() * lowprimes.length)]);
+ var y = a.modPow(r, this);
+ if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) {
+ var j = 1;
+ while (j++ < k && y.compareTo(n1) != 0) {
+ y = y.modPowInt(2, this);
+ if (y.compareTo(BigInteger.ONE) == 0) return false;
+ }
+ if (y.compareTo(n1) != 0) return false;
+ }
+ }
+ return true;
+}
+
+// protected
+BigInteger.prototype.chunkSize = bnpChunkSize;
+BigInteger.prototype.toRadix = bnpToRadix;
+BigInteger.prototype.fromRadix = bnpFromRadix;
+BigInteger.prototype.fromNumber = bnpFromNumber;
+BigInteger.prototype.bitwiseTo = bnpBitwiseTo;
+BigInteger.prototype.changeBit = bnpChangeBit;
+BigInteger.prototype.addTo = bnpAddTo;
+BigInteger.prototype.dMultiply = bnpDMultiply;
+BigInteger.prototype.dAddOffset = bnpDAddOffset;
+BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo;
+BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo;
+BigInteger.prototype.modInt = bnpModInt;
+BigInteger.prototype.millerRabin = bnpMillerRabin;
+
+// public
+BigInteger.prototype.clone = bnClone;
+BigInteger.prototype.intValue = bnIntValue;
+BigInteger.prototype.byteValue = bnByteValue;
+BigInteger.prototype.shortValue = bnShortValue;
+BigInteger.prototype.signum = bnSigNum;
+BigInteger.prototype.toByteArray = bnToByteArray;
+BigInteger.prototype.equals = bnEquals;
+BigInteger.prototype.min = bnMin;
+BigInteger.prototype.max = bnMax;
+BigInteger.prototype.and = bnAnd;
+BigInteger.prototype.or = bnOr;
+BigInteger.prototype.xor = bnXor;
+BigInteger.prototype.andNot = bnAndNot;
+BigInteger.prototype.not = bnNot;
+BigInteger.prototype.shiftLeft = bnShiftLeft;
+BigInteger.prototype.shiftRight = bnShiftRight;
+BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit;
+BigInteger.prototype.bitCount = bnBitCount;
+BigInteger.prototype.testBit = bnTestBit;
+BigInteger.prototype.setBit = bnSetBit;
+BigInteger.prototype.clearBit = bnClearBit;
+BigInteger.prototype.flipBit = bnFlipBit;
+BigInteger.prototype.add = bnAdd;
+BigInteger.prototype.subtract = bnSubtract;
+BigInteger.prototype.multiply = bnMultiply;
+BigInteger.prototype.divide = bnDivide;
+BigInteger.prototype.remainder = bnRemainder;
+BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder;
+BigInteger.prototype.modPow = bnModPow;
+BigInteger.prototype.modInverse = bnModInverse;
+BigInteger.prototype.pow = bnPow;
+BigInteger.prototype.gcd = bnGCD;
+BigInteger.prototype.isProbablePrime = bnIsProbablePrime;
+
+// JSBN-specific extension
+BigInteger.prototype.square = bnSquare;
+
+// seedrandom.js version 2.0.
+// Author: David Bau 4/2/2011
+//
+// Defines a method Math.seedrandom() that, when called, substitutes
+// an explicitly seeded RC4-based algorithm for Math.random(). Also
+// supports automatic seeding from local or network sources of entropy.
+//
+// Usage:
+//
+// <script src=http://davidbau.com/encode/seedrandom-min.js></script>
+//
+// Math.seedrandom('yipee'); Sets Math.random to a function that is
+// initialized using the given explicit seed.
+//
+// Math.seedrandom(); Sets Math.random to a function that is
+// seeded using the current time, dom state,
+// and other accumulated local entropy.
+// The generated seed string is returned.
+//
+// Math.seedrandom('yowza', true);
+// Seeds using the given explicit seed mixed
+// together with accumulated entropy.
+//
+// <script src="http://bit.ly/srandom-512"></script>
+// Seeds using physical random bits downloaded
+// from random.org.
+//
+// <script src="https://jsonlib.appspot.com/urandom?callback=Math.seedrandom">
+// </script> Seeds using urandom bits from call.jsonlib.com,
+// which is faster than random.org.
+//
+// Examples:
+//
+// Math.seedrandom("hello"); // Use "hello" as the seed.
+// document.write(Math.random()); // Always 0.5463663768140734
+// document.write(Math.random()); // Always 0.43973793770592234
+// var rng1 = Math.random; // Remember the current prng.
+//
+// var autoseed = Math.seedrandom(); // New prng with an automatic seed.
+// document.write(Math.random()); // Pretty much unpredictable.
+//
+// Math.random = rng1; // Continue "hello" prng sequence.
+// document.write(Math.random()); // Always 0.554769432473455
+//
+// Math.seedrandom(autoseed); // Restart at the previous seed.
+// document.write(Math.random()); // Repeat the 'unpredictable' value.
+//
+// Notes:
+//
+// Each time seedrandom('arg') is called, entropy from the passed seed
+// is accumulated in a pool to help generate future seeds for the
+// zero-argument form of Math.seedrandom, so entropy can be injected over
+// time by calling seedrandom with explicit data repeatedly.
+//
+// On speed - This javascript implementation of Math.random() is about
+// 3-10x slower than the built-in Math.random() because it is not native
+// code, but this is typically fast enough anyway. Seeding is more expensive,
+// especially if you use auto-seeding. Some details (timings on Chrome 4):
+//
+// Our Math.random() - avg less than 0.002 milliseconds per call
+// seedrandom('explicit') - avg less than 0.5 milliseconds per call
+// seedrandom('explicit', true) - avg less than 2 milliseconds per call
+// seedrandom() - avg about 38 milliseconds per call
+//
+// LICENSE (BSD):
+//
+// Copyright 2010 David Bau, all rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// 2. 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.
+//
+// 3. Neither the name of this module 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
+// OWNER 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.
+//
+/**
+ * All code is in an anonymous closure to keep the global namespace clean.
+ *
+ * @param {number=} overflow
+ * @param {number=} startdenom
+ */
+(function (pool, math, width, chunks, significance, overflow, startdenom) {
+
+
+ //
+ // seedrandom()
+ // This is the seedrandom function described above.
+ //
+ math['seedrandom'] = function seedrandom(seed, use_entropy) {
+ var key = [];
+ var arc4;
+
+ // Flatten the seed string or build one from local entropy if needed.
+ seed = mixkey(flatten(
+ use_entropy ? [seed, pool] : arguments.length ? seed : [new Date().getTime(), pool, window], 3), key);
+
+ // Use the seed to initialize an ARC4 generator.
+ arc4 = new ARC4(key);
+
+ // Mix the randomness into accumulated entropy.
+ mixkey(arc4.S, pool);
+
+ // Override Math.random
+ // This function returns a random double in [0, 1) that contains
+ // randomness in every bit of the mantissa of the IEEE 754 value.
+ math['random'] = function random() { // Closure to return a random double:
+ var n = arc4.g(chunks); // Start with a numerator n < 2 ^ 48
+ var d = startdenom; // and denominator d = 2 ^ 48.
+ var x = 0; // and no 'extra last byte'.
+ while (n < significance) { // Fill up all significant digits by
+ n = (n + x) * width; // shifting numerator and
+ d *= width; // denominator and generating a
+ x = arc4.g(1); // new least-significant-byte.
+ }
+ while (n >= overflow) { // To avoid rounding up, before adding
+ n /= 2; // last byte, shift everything
+ d /= 2; // right using integer math until
+ x >>>= 1; // we have exactly the desired bits.
+ }
+ return (n + x) / d; // Form the number within [0, 1).
+ };
+
+ // Return the seed that was used
+ return seed;
+ };
+
+ //
+ // ARC4
+ //
+ // An ARC4 implementation. The constructor takes a key in the form of
+ // an array of at most (width) integers that should be 0 <= x < (width).
+ //
+ // The g(count) method returns a pseudorandom integer that concatenates
+ // the next (count) outputs from ARC4. Its return value is a number x
+ // that is in the range 0 <= x < (width ^ count).
+ //
+ /** @constructor */
+
+ function ARC4(key) {
+ var t, u, me = this,
+ keylen = key.length;
+ var i = 0,
+ j = me.i = me.j = me.m = 0;
+ me.S = [];
+ me.c = [];
+
+ // The empty key [] is treated as [0].
+ if (!keylen) {
+ key = [keylen++];
+ }
+
+ // Set up S using the standard key scheduling algorithm.
+ while (i < width) {
+ me.S[i] = i++;
+ }
+ for (i = 0; i < width; i++) {
+ t = me.S[i];
+ j = lowbits(j + t + key[i % keylen]);
+ u = me.S[j];
+ me.S[i] = u;
+ me.S[j] = t;
+ }
+
+ // The "g" method returns the next (count) outputs as one number.
+ me.g = function getnext(count) {
+ var s = me.S;
+ var i = lowbits(me.i + 1);
+ var t = s[i];
+ var j = lowbits(me.j + t);
+ var u = s[j];
+ s[i] = u;
+ s[j] = t;
+ var r = s[lowbits(t + u)];
+ while (--count) {
+ i = lowbits(i + 1);
+ t = s[i];
+ j = lowbits(j + t);
+ u = s[j];
+ s[i] = u;
+ s[j] = t;
+ r = r * width + s[lowbits(t + u)];
+ }
+ me.i = i;
+ me.j = j;
+ return r;
+ };
+ // For robust unpredictability discard an initial batch of values.
+ // See http://www.rsa.com/rsalabs/node.asp?id=2009
+ me.g(width);
+ }
+
+ //
+ // flatten()
+ // Converts an object tree to nested arrays of strings.
+ //
+ /** @param {Object=} result
+ * @param {string=} prop
+ * @param {string=} typ */
+
+ function flatten(obj, depth, result, prop, typ) {
+ result = [];
+ typ = typeof (obj);
+ if (depth && typ == 'object') {
+ for (prop in obj) {
+ if (prop.indexOf('S') < 5) { // Avoid FF3 bug (local/sessionStorage)
+ try {
+ result.push(flatten(obj[prop], depth - 1));
+ }
+ catch (e) {
+ }
+ }
+ }
+ }
+ return (result.length ? result : obj + (typ != 'string' ? '\0' : ''));
+ }
+
+ //
+ // mixkey()
+ // Mixes a string seed into a key that is an array of integers, and
+ // returns a shortened string seed that is equivalent to the result key.
+ //
+ /** @param {number=} smear
+ * @param {number=} j */
+
+ function mixkey(seed, key, smear, j) {
+ seed += ''; // Ensure the seed is a string
+ smear = 0;
+ for (j = 0; j < seed.length; j++) {
+ key[lowbits(j)] = lowbits((smear ^= key[lowbits(j)] * 19) + seed.charCodeAt(j));
+ }
+ seed = '';
+ for (j in key) {
+ seed += String.fromCharCode(key[j]);
+ }
+ return seed;
+ }
+
+ //
+ // lowbits()
+ // A quick "n mod width" for width a power of 2.
+ //
+
+
+ function lowbits(n) {
+ return n & (width - 1);
+ }
+
+ //
+ // The following constants are related to IEEE 754 limits.
+ //
+ startdenom = math.pow(width, chunks);
+ significance = math.pow(2, significance);
+ overflow = significance * 2;
+
+ //
+ // When seedrandom.js is loaded, we immediately mix a few bits
+ // from the built-in RNG into the entropy pool. Because we do
+ // not want to intefere with determinstic PRNG state later,
+ // seedrandom will not call math.random on its own again after
+ // initialization.
+ //
+ mixkey(math.random(), pool);
+
+ // End anonymous scope, and pass initial values.
+})([], // pool: entropy pool starts empty
+ Math, // math: package containing random, pow, and seedrandom
+ 256, // width: each RC4 output is 0 <= x < 256
+ 6, // chunks: at least six RC4 outputs for each double
+ 52 // significance: there are 52 significant digits in a double
+);
+
+
+// This is not really a random number generator object, and two SeededRandom
+// objects will conflict with one another, but it's good enough for generating
+// the rsa key.
+function SeededRandom() {
+}
+
+function SRnextBytes(ba) {
+ var i;
+ for (i = 0; i < ba.length; i++) {
+ ba[i] = Math.floor(Math.random() * 256);
+ }
+}
+
+SeededRandom.prototype.nextBytes = SRnextBytes;
+
+// prng4.js - uses Arcfour as a PRNG
+
+function Arcfour() {
+ this.i = 0;
+ this.j = 0;
+ this.S = new Array();
+}
+
+// Initialize arcfour context from key, an array of ints, each from [0..255]
+function ARC4init(key) {
+ var i, j, t;
+ for (i = 0; i < 256; ++i)
+ this.S[i] = i;
+ j = 0;
+ for (i = 0; i < 256; ++i) {
+ j = (j + this.S[i] + key[i % key.length]) & 255;
+ t = this.S[i];
+ this.S[i] = this.S[j];
+ this.S[j] = t;
+ }
+ this.i = 0;
+ this.j = 0;
+}
+
+function ARC4next() {
+ var t;
+ this.i = (this.i + 1) & 255;
+ this.j = (this.j + this.S[this.i]) & 255;
+ t = this.S[this.i];
+ this.S[this.i] = this.S[this.j];
+ this.S[this.j] = t;
+ return this.S[(t + this.S[this.i]) & 255];
+}
+
+Arcfour.prototype.init = ARC4init;
+Arcfour.prototype.next = ARC4next;
+
+// Plug in your RNG constructor here
+function prng_newstate() {
+ return new Arcfour();
+}
+
+// Pool size must be a multiple of 4 and greater than 32.
+// An array of bytes the size of the pool will be passed to init()
+var rng_psize = 256;
+
+// Random number generator - requires a PRNG backend, e.g. prng4.js
+
+// For best results, put code like
+// <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'>
+// in your main HTML document.
+
+var rng_state;
+var rng_pool;
+var rng_pptr;
+
+// Mix in a 32-bit integer into the pool
+function rng_seed_int(x) {
+ rng_pool[rng_pptr++] ^= x & 255;
+ rng_pool[rng_pptr++] ^= (x >> 8) & 255;
+ rng_pool[rng_pptr++] ^= (x >> 16) & 255;
+ rng_pool[rng_pptr++] ^= (x >> 24) & 255;
+ if (rng_pptr >= rng_psize) rng_pptr -= rng_psize;
+}
+
+// Mix in the current time (w/milliseconds) into the pool
+function rng_seed_time() {
+ rng_seed_int(new Date().getTime());
+}
+
+// Initialize the pool with junk if needed.
+if (rng_pool == null) {
+ rng_pool = new Array();
+ rng_pptr = 0;
+ var t;
+ if (navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) {
+ // Extract entropy (256 bits) from NS4 RNG if available
+ var z = window.crypto.random(32);
+ for (t = 0; t < z.length; ++t)
+ rng_pool[rng_pptr++] = z.charCodeAt(t) & 255;
+ }
+ while (rng_pptr < rng_psize) { // extract some randomness from Math.random()
+ t = Math.floor(65536 * Math.random());
+ rng_pool[rng_pptr++] = t >>> 8;
+ rng_pool[rng_pptr++] = t & 255;
+ }
+ rng_pptr = 0;
+ rng_seed_time();
+ //rng_seed_int(window.screenX);
+ //rng_seed_int(window.screenY);
+}
+
+function rng_get_byte() {
+ if (rng_state == null) {
+ rng_seed_time();
+ rng_state = prng_newstate();
+ rng_state.init(rng_pool);
+ for (rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr)
+ rng_pool[rng_pptr] = 0;
+ rng_pptr = 0;
+ //rng_pool = null;
+ }
+ // TODO: allow reseeding after first request
+ return rng_state.next();
+}
+
+function rng_get_bytes(ba) {
+ var i;
+ for (i = 0; i < ba.length; ++i) ba[i] = rng_get_byte();
+}
+
+function SecureRandom() {
+}
+
+SecureRandom.prototype.nextBytes = rng_get_bytes;
+
+
+/**
+ *
+ * Secure Hash Algorithm (SHA256)
+ * http://www.webtoolkit.info/
+ *
+ * Original code by Angel Marin, Paul Johnston.
+ *
+ **/
+
+function SHA256(s) {
+
+ var chrsz = 8;
+ var hexcase = 0;
+
+ function safe_add(x, y) {
+ var lsw = (x & 0xFFFF) + (y & 0xFFFF);
+ var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+ return (msw << 16) | (lsw & 0xFFFF);
+ }
+
+ function S(X, n) {
+ return (X >>> n) | (X << (32 - n));
+ }
+
+ function R(X, n) {
+ return (X >>> n);
+ }
+
+ function Ch(x, y, z) {
+ return ((x & y) ^ ((~x) & z));
+ }
+
+ function Maj(x, y, z) {
+ return ((x & y) ^ (x & z) ^ (y & z));
+ }
+
+ function Sigma0256(x) {
+ return (S(x, 2) ^ S(x, 13) ^ S(x, 22));
+ }
+
+ function Sigma1256(x) {
+ return (S(x, 6) ^ S(x, 11) ^ S(x, 25));
+ }
+
+ function Gamma0256(x) {
+ return (S(x, 7) ^ S(x, 18) ^ R(x, 3));
+ }
+
+ function Gamma1256(x) {
+ return (S(x, 17) ^ S(x, 19) ^ R(x, 10));
+ }
+
+ function core_sha256(m, l) {
+ var K = new Array(0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 0xE49B69C1, 0xEFBE4786, 0xFC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x6CA6351, 0x14292967, 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2);
+ var HASH = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19);
+ var W = new Array(64);
+ var a, b, c, d, e, f, g, h, i, j;
+ var T1, T2;
+
+ m[l >> 5] |= 0x80 << (24 - l % 32);
+ m[((l + 64 >> 9) << 4) + 15] = l;
+
+ for (var i = 0; i < m.length; i += 16) {
+ a = HASH[0];
+ b = HASH[1];
+ c = HASH[2];
+ d = HASH[3];
+ e = HASH[4];
+ f = HASH[5];
+ g = HASH[6];
+ h = HASH[7];
+
+ for (var j = 0; j < 64; j++) {
+ if (j < 16) W[j] = m[j + i];
+ else W[j] = safe_add(safe_add(safe_add(Gamma1256(W[j - 2]), W[j - 7]), Gamma0256(W[j - 15])), W[j - 16]);
+
+ T1 = safe_add(safe_add(safe_add(safe_add(h, Sigma1256(e)), Ch(e, f, g)), K[j]), W[j]);
+ T2 = safe_add(Sigma0256(a), Maj(a, b, c));
+
+ h = g;
+ g = f;
+ f = e;
+ e = safe_add(d, T1);
+ d = c;
+ c = b;
+ b = a;
+ a = safe_add(T1, T2);
+ }
+
+ HASH[0] = safe_add(a, HASH[0]);
+ HASH[1] = safe_add(b, HASH[1]);
+ HASH[2] = safe_add(c, HASH[2]);
+ HASH[3] = safe_add(d, HASH[3]);
+ HASH[4] = safe_add(e, HASH[4]);
+ HASH[5] = safe_add(f, HASH[5]);
+ HASH[6] = safe_add(g, HASH[6]);
+ HASH[7] = safe_add(h, HASH[7]);
+ }
+ return HASH;
+ }
+
+ function str2binb(str) {
+ var bin = Array();
+ var mask = (1 << chrsz) - 1;
+ for (var i = 0; i < str.length * chrsz; i += chrsz) {
+ bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (24 - i % 32);
+ }
+ return bin;
+ }
+
+ function Utf8Encode(string) {
+ string = string.replace(/\r\n/g, "\n");
+ var utftext = "";
+
+ for (var n = 0; n < string.length; n++) {
+
+ var c = string.charCodeAt(n);
+
+ if (c < 128) {
+ utftext += String.fromCharCode(c);
+ }
+ else if ((c > 127) && (c < 2048)) {
+ utftext += String.fromCharCode((c >> 6) | 192);
+ utftext += String.fromCharCode((c & 63) | 128);
+ }
+ else {
+ utftext += String.fromCharCode((c >> 12) | 224);
+ utftext += String.fromCharCode(((c >> 6) & 63) | 128);
+ utftext += String.fromCharCode((c & 63) | 128);
+ }
+
+ }
+
+ return utftext;
+ }
+
+ function binb2hex(binarray) {
+ var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
+ var str = "";
+ for (var i = 0; i < binarray.length * 4; i++) {
+ str += hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8 + 4)) & 0xF) +
+ hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8)) & 0xF);
+ }
+ return str;
+ }
+
+ s = Utf8Encode(s);
+ return binb2hex(core_sha256(str2binb(s), s.length * chrsz));
+}
+
+var sha256 = {}
+sha256.hex = function (s) {
+ return SHA256(s);
+}
+
+/**
+ *
+ * Secure Hash Algorithm (SHA1)
+ * http://www.webtoolkit.info/
+ *
+ **/
+
+function SHA1(msg) {
+
+ function rotate_left(n, s) {
+ var t4 = (n << s) | (n >>> (32 - s));
+ return t4;
+ };
+
+ function lsb_hex(val) {
+ var str = "";
+ var i;
+ var vh;
+ var vl;
+
+ for (i = 0; i <= 6; i += 2) {
+ vh = (val >>> (i * 4 + 4)) & 0x0f;
+ vl = (val >>> (i * 4)) & 0x0f;
+ str += vh.toString(16) + vl.toString(16);
+ }
+ return str;
+ };
+
+ function cvt_hex(val) {
+ var str = "";
+ var i;
+ var v;
+
+ for (i = 7; i >= 0; i--) {
+ v = (val >>> (i * 4)) & 0x0f;
+ str += v.toString(16);
+ }
+ return str;
+ };
+
+
+ function Utf8Encode(string) {
+ string = string.replace(/\r\n/g, "\n");
+ var utftext = "";
+
+ for (var n = 0; n < string.length; n++) {
+
+ var c = string.charCodeAt(n);
+
+ if (c < 128) {
+ utftext += String.fromCharCode(c);
+ }
+ else if ((c > 127) && (c < 2048)) {
+ utftext += String.fromCharCode((c >> 6) | 192);
+ utftext += String.fromCharCode((c & 63) | 128);
+ }
+ else {
+ utftext += String.fromCharCode((c >> 12) | 224);
+ utftext += String.fromCharCode(((c >> 6) & 63) | 128);
+ utftext += String.fromCharCode((c & 63) | 128);
+ }
+
+ }
+
+ return utftext;
+ };
+
+ var blockstart;
+ var i, j;
+ var W = new Array(80);
+ var H0 = 0x67452301;
+ var H1 = 0xEFCDAB89;
+ var H2 = 0x98BADCFE;
+ var H3 = 0x10325476;
+ var H4 = 0xC3D2E1F0;
+ var A, B, C, D, E;
+ var temp;
+
+ msg = Utf8Encode(msg);
+
+ var msg_len = msg.length;
+
+ var word_array = new Array();
+ for (i = 0; i < msg_len - 3; i += 4) {
+ j = msg.charCodeAt(i) << 24 | msg.charCodeAt(i + 1) << 16 |
+ msg.charCodeAt(i + 2) << 8 | msg.charCodeAt(i + 3);
+ word_array.push(j);
+ }
+
+ switch (msg_len % 4) {
+ case 0:
+ i = 0x080000000;
+ break;
+ case 1:
+ i = msg.charCodeAt(msg_len - 1) << 24 | 0x0800000;
+ break;
+
+ case 2:
+ i = msg.charCodeAt(msg_len - 2) << 24 | msg.charCodeAt(msg_len - 1) << 16 | 0x08000;
+ break;
+
+ case 3:
+ i = msg.charCodeAt(msg_len - 3) << 24 | msg.charCodeAt(msg_len - 2) << 16 | msg.charCodeAt(msg_len - 1) << 8 | 0x80;
+ break;
+ }
+
+ word_array.push(i);
+
+ while ((word_array.length % 16) != 14) word_array.push(0);
+
+ word_array.push(msg_len >>> 29);
+ word_array.push((msg_len << 3) & 0x0ffffffff);
+
+
+ for (blockstart = 0; blockstart < word_array.length; blockstart += 16) {
+
+ for (i = 0; i < 16; i++) W[i] = word_array[blockstart + i];
+ for (i = 16; i <= 79; i++) W[i] = rotate_left(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
+
+ A = H0;
+ B = H1;
+ C = H2;
+ D = H3;
+ E = H4;
+
+ for (i = 0; i <= 19; i++) {
+ temp = (rotate_left(A, 5) + ((B & C) | (~B & D)) + E + W[i] + 0x5A827999) & 0x0ffffffff;
+ E = D;
+ D = C;
+ C = rotate_left(B, 30);
+ B = A;
+ A = temp;
+ }
+
+ for (i = 20; i <= 39; i++) {
+ temp = (rotate_left(A, 5) + (B ^ C ^ D) + E + W[i] + 0x6ED9EBA1) & 0x0ffffffff;
+ E = D;
+ D = C;
+ C = rotate_left(B, 30);
+ B = A;
+ A = temp;
+ }
+
+ for (i = 40; i <= 59; i++) {
+ temp = (rotate_left(A, 5) + ((B & C) | (B & D) | (C & D)) + E + W[i] + 0x8F1BBCDC) & 0x0ffffffff;
+ E = D;
+ D = C;
+ C = rotate_left(B, 30);
+ B = A;
+ A = temp;
+ }
+
+ for (i = 60; i <= 79; i++) {
+ temp = (rotate_left(A, 5) + (B ^ C ^ D) + E + W[i] + 0xCA62C1D6) & 0x0ffffffff;
+ E = D;
+ D = C;
+ C = rotate_left(B, 30);
+ B = A;
+ A = temp;
+ }
+
+ H0 = (H0 + A) & 0x0ffffffff;
+ H1 = (H1 + B) & 0x0ffffffff;
+ H2 = (H2 + C) & 0x0ffffffff;
+ H3 = (H3 + D) & 0x0ffffffff;
+ H4 = (H4 + E) & 0x0ffffffff;
+
+ }
+
+ var temp = cvt_hex(H0) + cvt_hex(H1) + cvt_hex(H2) + cvt_hex(H3) + cvt_hex(H4);
+
+ return temp.toLowerCase();
+
+}
+
+var sha1 = {}
+sha1.hex = function (s) {
+ return SHA1(s);
+}
+
+/**
+ *
+ * MD5 (Message-Digest Algorithm)
+ * http://www.webtoolkit.info/
+ *
+ **/
+
+var MD5 = function (string) {
+
+ function RotateLeft(lValue, iShiftBits) {
+ return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
+ }
+
+ function AddUnsigned(lX, lY) {
+ var lX4, lY4, lX8, lY8, lResult;
+ lX8 = (lX & 0x80000000);
+ lY8 = (lY & 0x80000000);
+ lX4 = (lX & 0x40000000);
+ lY4 = (lY & 0x40000000);
+ lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
+ if (lX4 & lY4) {
+ return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
+ }
+ if (lX4 | lY4) {
+ if (lResult & 0x40000000) {
+ return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
+ } else {
+ return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
+ }
+ } else {
+ return (lResult ^ lX8 ^ lY8);
+ }
+ }
+
+ function F(x, y, z) {
+ return (x & y) | ((~x) & z);
+ }
+
+ function G(x, y, z) {
+ return (x & z) | (y & (~z));
+ }
+
+ function H(x, y, z) {
+ return (x ^ y ^ z);
+ }
+
+ function I(x, y, z) {
+ return (y ^ (x | (~z)));
+ }
+
+ function FF(a, b, c, d, x, s, ac) {
+ a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
+ return AddUnsigned(RotateLeft(a, s), b);
+ };
+
+ function GG(a, b, c, d, x, s, ac) {
+ a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
+ return AddUnsigned(RotateLeft(a, s), b);
+ };
+
+ function HH(a, b, c, d, x, s, ac) {
+ a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
+ return AddUnsigned(RotateLeft(a, s), b);
+ };
+
+ function II(a, b, c, d, x, s, ac) {
+ a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
+ return AddUnsigned(RotateLeft(a, s), b);
+ };
+
+ function ConvertToWordArray(string) {
+ var lWordCount;
+ var lMessageLength = string.length;
+ var lNumberOfWords_temp1 = lMessageLength + 8;
+ var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64;
+ var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16;
+ var lWordArray = Array(lNumberOfWords - 1);
+ var lBytePosition = 0;
+ var lByteCount = 0;
+ while (lByteCount < lMessageLength) {
+ lWordCount = (lByteCount - (lByteCount % 4)) / 4;
+ lBytePosition = (lByteCount % 4) * 8;
+ lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount) << lBytePosition));
+ lByteCount++;
+ }
+ lWordCount = (lByteCount - (lByteCount % 4)) / 4;
+ lBytePosition = (lByteCount % 4) * 8;
+ lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
+ lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
+ lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
+ return lWordArray;
+ };
+
+ function WordToHex(lValue) {
+ var WordToHexValue = "", WordToHexValue_temp = "", lByte, lCount;
+ for (lCount = 0; lCount <= 3; lCount++) {
+ lByte = (lValue >>> (lCount * 8)) & 255;
+ WordToHexValue_temp = "0" + lByte.toString(16);
+ WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length - 2, 2);
+ }
+ return WordToHexValue;
+ };
+
+ function Utf8Encode(string) {
+ string = string.replace(/\r\n/g, "\n");
+ var utftext = "";
+
+ for (var n = 0; n < string.length; n++) {
+
+ var c = string.charCodeAt(n);
+
+ if (c < 128) {
+ utftext += String.fromCharCode(c);
+ }
+ else if ((c > 127) && (c < 2048)) {
+ utftext += String.fromCharCode((c >> 6) | 192);
+ utftext += String.fromCharCode((c & 63) | 128);
+ }
+ else {
+ utftext += String.fromCharCode((c >> 12) | 224);
+ utftext += String.fromCharCode(((c >> 6) & 63) | 128);
+ utftext += String.fromCharCode((c & 63) | 128);
+ }
+
+ }
+
+ return utftext;
+ };
+
+ var x = Array();
+ var k, AA, BB, CC, DD, a, b, c, d;
+ var S11 = 7, S12 = 12, S13 = 17, S14 = 22;
+ var S21 = 5, S22 = 9, S23 = 14, S24 = 20;
+ var S31 = 4, S32 = 11, S33 = 16, S34 = 23;
+ var S41 = 6, S42 = 10, S43 = 15, S44 = 21;
+
+ string = Utf8Encode(string);
+
+ x = ConvertToWordArray(string);
+
+ a = 0x67452301;
+ b = 0xEFCDAB89;
+ c = 0x98BADCFE;
+ d = 0x10325476;
+
+ for (k = 0; k < x.length; k += 16) {
+ AA = a;
+ BB = b;
+ CC = c;
+ DD = d;
+ a = FF(a, b, c, d, x[k + 0], S11, 0xD76AA478);
+ d = FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756);
+ c = FF(c, d, a, b, x[k + 2], S13, 0x242070DB);
+ b = FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);
+ a = FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF);
+ d = FF(d, a, b, c, x[k + 5], S12, 0x4787C62A);
+ c = FF(c, d, a, b, x[k + 6], S13, 0xA8304613);
+ b = FF(b, c, d, a, x[k + 7], S14, 0xFD469501);
+ a = FF(a, b, c, d, x[k + 8], S11, 0x698098D8);
+ d = FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF);
+ c = FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
+ b = FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE);
+ a = FF(a, b, c, d, x[k + 12], S11, 0x6B901122);
+ d = FF(d, a, b, c, x[k + 13], S12, 0xFD987193);
+ c = FF(c, d, a, b, x[k + 14], S13, 0xA679438E);
+ b = FF(b, c, d, a, x[k + 15], S14, 0x49B40821);
+ a = GG(a, b, c, d, x[k + 1], S21, 0xF61E2562);
+ d = GG(d, a, b, c, x[k + 6], S22, 0xC040B340);
+ c = GG(c, d, a, b, x[k + 11], S23, 0x265E5A51);
+ b = GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);
+ a = GG(a, b, c, d, x[k + 5], S21, 0xD62F105D);
+ d = GG(d, a, b, c, x[k + 10], S22, 0x2441453);
+ c = GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681);
+ b = GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);
+ a = GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6);
+ d = GG(d, a, b, c, x[k + 14], S22, 0xC33707D6);
+ c = GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87);
+ b = GG(b, c, d, a, x[k + 8], S24, 0x455A14ED);
+ a = GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905);
+ d = GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);
+ c = GG(c, d, a, b, x[k + 7], S23, 0x676F02D9);
+ b = GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
+ a = HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942);
+ d = HH(d, a, b, c, x[k + 8], S32, 0x8771F681);
+ c = HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122);
+ b = HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C);
+ a = HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44);
+ d = HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9);
+ c = HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60);
+ b = HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
+ a = HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6);
+ d = HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA);
+ c = HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085);
+ b = HH(b, c, d, a, x[k + 6], S34, 0x4881D05);
+ a = HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039);
+ d = HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
+ c = HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
+ b = HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665);
+ a = II(a, b, c, d, x[k + 0], S41, 0xF4292244);
+ d = II(d, a, b, c, x[k + 7], S42, 0x432AFF97);
+ c = II(c, d, a, b, x[k + 14], S43, 0xAB9423A7);
+ b = II(b, c, d, a, x[k + 5], S44, 0xFC93A039);
+ a = II(a, b, c, d, x[k + 12], S41, 0x655B59C3);
+ d = II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92);
+ c = II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
+ b = II(b, c, d, a, x[k + 1], S44, 0x85845DD1);
+ a = II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F);
+ d = II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
+ c = II(c, d, a, b, x[k + 6], S43, 0xA3014314);
+ b = II(b, c, d, a, x[k + 13], S44, 0x4E0811A1);
+ a = II(a, b, c, d, x[k + 4], S41, 0xF7537E82);
+ d = II(d, a, b, c, x[k + 11], S42, 0xBD3AF235);
+ c = II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);
+ b = II(b, c, d, a, x[k + 9], S44, 0xEB86D391);
+ a = AddUnsigned(a, AA);
+ b = AddUnsigned(b, BB);
+ c = AddUnsigned(c, CC);
+ d = AddUnsigned(d, DD);
+ }
+
+ var temp = WordToHex(a) + WordToHex(b) + WordToHex(c) + WordToHex(d);
+
+ return temp.toLowerCase();
+}
+
+// Depends on jsbn.js and rng.js
+// Version 1.1: support utf-8 encoding in pkcs1pad2
+// convert a (hex) string to a bignum object
+
+
+function parseBigInt(str, r) {
+ return new BigInteger(str, r);
+}
+
+function linebrk(s, n) {
+ var ret = "";
+ var i = 0;
+ while (i + n < s.length) {
+ ret += s.substring(i, i + n) + "\n";
+ i += n;
+ }
+ return ret + s.substring(i, s.length);
+}
+
+function byte2Hex(b) {
+ if (b < 0x10) return "0" + b.toString(16);
+ else return b.toString(16);
+}
+
+// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint
+
+
+function pkcs1pad2(s, n) {
+ if (n < s.length + 11) { // TODO: fix for utf-8
+ //alert("Message too long for RSA (n=" + n + ", l=" + s.length + ")");
+ //return null;
+ throw "Message too long for RSA (n=" + n + ", l=" + s.length + ")";
+ }
+ var ba = new Array();
+ var i = s.length - 1;
+ while (i >= 0 && n > 0) {
+ var c = s.charCodeAt(i--);
+ if (c < 128) { // encode using utf-8
+ ba[--n] = c;
+ }
+ else if ((c > 127) && (c < 2048)) {
+ ba[--n] = (c & 63) | 128;
+ ba[--n] = (c >> 6) | 192;
+ }
+ else {
+ ba[--n] = (c & 63) | 128;
+ ba[--n] = ((c >> 6) & 63) | 128;
+ ba[--n] = (c >> 12) | 224;
+ }
+ }
+ ba[--n] = 0;
+ var rng = new SecureRandom();
+ var x = new Array();
+ while (n > 2) { // random non-zero pad
+ x[0] = 0;
+ while (x[0] == 0) rng.nextBytes(x);
+ ba[--n] = x[0];
+ }
+ ba[--n] = 2;
+ ba[--n] = 0;
+ return new BigInteger(ba);
+}
+
+// "empty" RSA key constructor
+
+
+function RSAKey() {
+ this.n = null;
+ this.e = 0;
+ this.d = null;
+ this.p = null;
+ this.q = null;
+ this.dmp1 = null;
+ this.dmq1 = null;
+ this.coeff = null;
+}
+
+// Set the public key fields N and e from hex strings
+
+
+function RSASetPublic(N, E) {
+ if (N != null && E != null && N.length > 0 && E.length > 0) {
+ this.n = parseBigInt(N, 16);
+ this.e = parseInt(E, 16);
+ }
+ else alert("Invalid RSA public key");
+}
+
+// Perform raw public operation on "x": return x^e (mod n)
+
+
+function RSADoPublic(x) {
+ return x.modPowInt(this.e, this.n);
+}
+
+// Return the PKCS#1 RSA encryption of "text" as an even-length hex string
+
+
+function RSAEncrypt(text) {
+ var m = pkcs1pad2(text, (this.n.bitLength() + 7) >> 3);
+ if (m == null) return null;
+ var c = this.doPublic(m);
+ if (c == null) return null;
+ var h = c.toString(16);
+ if ((h.length & 1) == 0) return h;
+ else return "0" + h;
+}
+
+// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string
+//function RSAEncryptB64(text) {
+// var h = this.encrypt(text);
+// if(h) return hex2b64(h); else return null;
+//}
+// protected
+RSAKey.prototype.doPublic = RSADoPublic;
+
+// public
+RSAKey.prototype.setPublic = RSASetPublic;
+RSAKey.prototype.encrypt = RSAEncrypt;
+
+// Version 1.1: support utf-8 decoding in pkcs1unpad2
+// Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext
+
+function pkcs1unpad2(d, n) {
+ var b = d.toByteArray();
+ var i = 0;
+ while (i < b.length && b[i] == 0) ++i;
+ if (b.length - i != n - 1 || b[i] != 2) return null;
+ ++i;
+ while (b[i] != 0)
+ if (++i >= b.length) return null;
+ var ret = "";
+ while (++i < b.length) {
+ var c = b[i] & 255;
+ if (c < 128) { // utf-8 decode
+ ret += String.fromCharCode(c);
+ }
+ else if ((c > 191) && (c < 224)) {
+ ret += String.fromCharCode(((c & 31) << 6) | (b[i + 1] & 63));
+ ++i;
+ }
+ else {
+ ret += String.fromCharCode(((c & 15) << 12) | ((b[i + 1] & 63) << 6) | (b[i + 2] & 63));
+ i += 2;
+ }
+ }
+ return ret;
+}
+
+// Set the private key fields N, e, and d from hex strings
+function RSASetPrivate(N, E, D) {
+ if (N != null && E != null && N.length > 0 && E.length > 0) {
+ this.n = parseBigInt(N, 16);
+ this.e = parseInt(E, 16);
+ this.d = parseBigInt(D, 16);
+ }
+ else alert("Invalid RSA private key");
+}
+
+// Set the private key fields N, e, d and CRT params from hex strings
+function RSASetPrivateEx(N, E, D, P, Q, DP, DQ, C) {
+ if (N != null && E != null && N.length > 0 && E.length > 0) {
+ this.n = parseBigInt(N, 16);
+ this.e = parseInt(E, 16);
+ this.d = parseBigInt(D, 16);
+ this.p = parseBigInt(P, 16);
+ this.q = parseBigInt(Q, 16);
+ this.dmp1 = parseBigInt(DP, 16);
+ this.dmq1 = parseBigInt(DQ, 16);
+ this.coeff = parseBigInt(C, 16);
+ }
+ else alert("Invalid RSA private key");
+}
+
+// Generate a new random private key B bits long, using public expt E
+function RSAGenerate(B, E) {
+ var rng = new SeededRandom();
+ var qs = B >> 1;
+ this.e = parseInt(E, 16);
+ var ee = new BigInteger(E, 16);
+ for (; ;) {
+ for (; ;) {
+ this.p = new BigInteger(B - qs, 1, rng);
+ if (this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.p.isProbablePrime(10)) break;
+ }
+ for (; ;) {
+ this.q = new BigInteger(qs, 1, rng);
+ if (this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.q.isProbablePrime(10)) break;
+ }
+ if (this.p.compareTo(this.q) <= 0) {
+ var t = this.p;
+ this.p = this.q;
+ this.q = t;
+ }
+ var p1 = this.p.subtract(BigInteger.ONE);
+ var q1 = this.q.subtract(BigInteger.ONE);
+ var phi = p1.multiply(q1);
+ if (phi.gcd(ee).compareTo(BigInteger.ONE) == 0) {
+ this.n = this.p.multiply(this.q);
+ this.d = ee.modInverse(phi);
+ this.dmp1 = this.d.mod(p1);
+ this.dmq1 = this.d.mod(q1);
+ this.coeff = this.q.modInverse(this.p);
+ break;
+ }
+ }
+}
+
+// Perform raw private operation on "x": return x^d (mod n)
+function RSADoPrivate(x) {
+ if (this.p == null || this.q == null) return x.modPow(this.d, this.n);
+ // TODO: re-calculate any missing CRT params
+ var xp = x.mod(this.p).modPow(this.dmp1, this.p);
+ var xq = x.mod(this.q).modPow(this.dmq1, this.q);
+ while (xp.compareTo(xq) < 0)
+ xp = xp.add(this.p);
+ return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq);
+}
+
+// Return the PKCS#1 RSA decryption of "ctext".
+// "ctext" is an even-length hex string and the output is a plain string.
+function RSADecrypt(ctext) {
+ var c = parseBigInt(ctext, 16);
+ var m = this.doPrivate(c);
+ if (m == null) return null;
+ return pkcs1unpad2(m, (this.n.bitLength() + 7) >> 3);
+}
+
+// protected
+RSAKey.prototype.doPrivate = RSADoPrivate;
+
+// public
+RSAKey.prototype.setPrivate = RSASetPrivate;
+RSAKey.prototype.setPrivateEx = RSASetPrivateEx;
+RSAKey.prototype.generate = RSAGenerate;
+RSAKey.prototype.decrypt = RSADecrypt;
+
+
+//
+// rsa-sign.js - adding signing functions to RSAKey class.
+//
+//
+// version: 1.0 (2010-Jun-03)
+//
+// Copyright (c) 2010 Kenji Urushima (kenji.urushima@gmail.com)
+//
+// This software is licensed under the terms of the MIT License.
+// http://www.opensource.org/licenses/mit-license.php
+//
+// The above copyright and license notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// Depends on:
+// function sha1.hex(s) of sha1.js
+// jsbn.js
+// jsbn2.js
+// rsa.js
+// rsa2.js
+//
+// keysize / pmstrlen
+// 512 / 128
+// 1024 / 256
+// 2048 / 512
+// 4096 / 1024
+// As for _RSASGIN_DIHEAD values for each hash algorithm, see PKCS#1 v2.1 spec (p38).
+var _RSASIGN_DIHEAD = [];
+_RSASIGN_DIHEAD['sha1'] = "3021300906052b0e03021a05000414";
+_RSASIGN_DIHEAD['sha256'] = "3031300d060960864801650304020105000420";
+//_RSASIGN_DIHEAD['md2'] = "3020300c06082a864886f70d020205000410";
+//_RSASIGN_DIHEAD['md5'] = "3020300c06082a864886f70d020505000410";
+//_RSASIGN_DIHEAD['sha384'] = "3041300d060960864801650304020205000430";
+//_RSASIGN_DIHEAD['sha512'] = "3051300d060960864801650304020305000440";
+var _RSASIGN_HASHHEXFUNC = [];
+_RSASIGN_HASHHEXFUNC['sha1'] = sha1.hex;
+_RSASIGN_HASHHEXFUNC['sha256'] = sha256.hex;
+
+// ========================================================================
+// Signature Generation
+// ========================================================================
+
+function _rsasign_getHexPaddedDigestInfoForString(s, keySize, hashAlg) {
+ var pmStrLen = keySize / 4;
+ var hashFunc = _RSASIGN_HASHHEXFUNC[hashAlg];
+ var sHashHex = hashFunc(s);
+
+ var sHead = "0001";
+ var sTail = "00" + _RSASIGN_DIHEAD[hashAlg] + sHashHex;
+ var sMid = "";
+ var fLen = pmStrLen - sHead.length - sTail.length;
+ for (var i = 0; i < fLen; i += 2) {
+ sMid += "ff";
+ }
+ sPaddedMessageHex = sHead + sMid + sTail;
+ return sPaddedMessageHex;
+}
+
+function _rsasign_signString(s, hashAlg) {
+ var hPM = _rsasign_getHexPaddedDigestInfoForString(s, this.n.bitLength(), hashAlg);
+ var biPaddedMessage = parseBigInt(hPM, 16);
+ var biSign = this.doPrivate(biPaddedMessage);
+ var hexSign = biSign.toString(16);
+ return hexSign;
+}
+
+function _rsasign_signStringWithSHA1(s) {
+ var hPM = _rsasign_getHexPaddedDigestInfoForString(s, this.n.bitLength(), 'sha1');
+ var biPaddedMessage = parseBigInt(hPM, 16);
+ var biSign = this.doPrivate(biPaddedMessage);
+ var hexSign = biSign.toString(16);
+ return hexSign;
+}
+
+function _rsasign_signStringWithSHA256(s) {
+ var hPM = _rsasign_getHexPaddedDigestInfoForString(s, this.n.bitLength(), 'sha256');
+ var biPaddedMessage = parseBigInt(hPM, 16);
+ var biSign = this.doPrivate(biPaddedMessage);
+ var hexSign = biSign.toString(16);
+ return hexSign;
+}
+
+// ========================================================================
+// Signature Verification
+// ========================================================================
+
+function _rsasign_getDecryptSignatureBI(biSig, hN, hE) {
+ var rsa = new RSAKey();
+ rsa.setPublic(hN, hE);
+ var biDecryptedSig = rsa.doPublic(biSig);
+ return biDecryptedSig;
+}
+
+function _rsasign_getHexDigestInfoFromSig(biSig, hN, hE) {
+ var biDecryptedSig = _rsasign_getDecryptSignatureBI(biSig, hN, hE);
+ var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');
+ return hDigestInfo;
+}
+
+function _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo) {
+ for (var algName in _RSASIGN_DIHEAD) {
+ var head = _RSASIGN_DIHEAD[algName];
+ var len = head.length;
+ if (hDigestInfo.substring(0, len) == head) {
+ var a = [algName, hDigestInfo.substring(len)];
+ return a;
+ }
+ }
+ return [];
+}
+
+function _rsasign_verifySignatureWithArgs(sMsg, biSig, hN, hE) {
+ var hDigestInfo = _rsasign_getHexDigestInfoFromSig(biSig, hN, hE);
+ var digestInfoAry = _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo);
+ if (digestInfoAry.length == 0) return false;
+ var algName = digestInfoAry[0];
+ var diHashValue = digestInfoAry[1];
+ var ff = _RSASIGN_HASHHEXFUNC[algName];
+ var msgHashValue = ff(sMsg);
+ return (diHashValue == msgHashValue);
+}
+
+function _rsasign_verifyHexSignatureForMessage(hSig, sMsg) {
+ var biSig = parseBigInt(hSig, 16);
+ var result = _rsasign_verifySignatureWithArgs(sMsg, biSig, this.n.toString(16), this.e.toString(16));
+ return result;
+}
+
+function _rsasign_verifyString(sMsg, hSig) {
+ hSig = hSig.replace(/[ \n]+/g, "");
+ var biSig = parseBigInt(hSig, 16);
+ var biDecryptedSig = this.doPublic(biSig);
+ var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');
+ var digestInfoAry = _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo);
+
+ if (digestInfoAry.length == 0) return false;
+ var algName = digestInfoAry[0];
+ var diHashValue = digestInfoAry[1];
+ var ff = _RSASIGN_HASHHEXFUNC[algName];
+ var msgHashValue = ff(sMsg);
+ return (diHashValue == msgHashValue);
+}
+
+RSAKey.prototype.signString = _rsasign_signString;
+RSAKey.prototype.signStringWithSHA1 = _rsasign_signStringWithSHA1;
+RSAKey.prototype.signStringWithSHA256 = _rsasign_signStringWithSHA256;
+
+RSAKey.prototype.verifyString = _rsasign_verifyString;
+RSAKey.prototype.verifyHexSignatureForMessage = _rsasign_verifyHexSignatureForMessage;
+
+/*
+ * jsaes version 0.1 - Copyright 2006 B. Poettering
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA
+ */
+
+// later modifications by wwwtyro@github
+
+var aes = (function () {
+
+ var my = {};
+
+ my.Sbox = new Array(99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22);
+
+ my.ShiftRowTab = new Array(0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11);
+
+ my.Init = function () {
+ my.Sbox_Inv = new Array(256);
+ for (var i = 0; i < 256; i++)
+ my.Sbox_Inv[my.Sbox[i]] = i;
+
+ my.ShiftRowTab_Inv = new Array(16);
+ for (var i = 0; i < 16; i++)
+ my.ShiftRowTab_Inv[my.ShiftRowTab[i]] = i;
+
+ my.xtime = new Array(256);
+ for (var i = 0; i < 128; i++) {
+ my.xtime[i] = i << 1;
+ my.xtime[128 + i] = (i << 1) ^ 0x1b;
+ }
+ }
+
+ my.Done = function () {
+ delete my.Sbox_Inv;
+ delete my.ShiftRowTab_Inv;
+ delete my.xtime;
+ }
+
+ my.ExpandKey = function (key) {
+ var kl = key.length,
+ ks, Rcon = 1;
+ switch (kl) {
+ case 16:
+ ks = 16 * (10 + 1);
+ break;
+ case 24:
+ ks = 16 * (12 + 1);
+ break;
+ case 32:
+ ks = 16 * (14 + 1);
+ break;
+ default:
+ alert("my.ExpandKey: Only key lengths of 16, 24 or 32 bytes allowed!");
+ }
+ for (var i = kl; i < ks; i += 4) {
+ var temp = key.slice(i - 4, i);
+ if (i % kl == 0) {
+ temp = new Array(my.Sbox[temp[1]] ^ Rcon, my.Sbox[temp[2]], my.Sbox[temp[3]], my.Sbox[temp[0]]);
+ if ((Rcon <<= 1) >= 256) Rcon ^= 0x11b;
+ }
+ else if ((kl > 24) && (i % kl == 16)) temp = new Array(my.Sbox[temp[0]], my.Sbox[temp[1]], my.Sbox[temp[2]], my.Sbox[temp[3]]);
+ for (var j = 0; j < 4; j++)
+ key[i + j] = key[i + j - kl] ^ temp[j];
+ }
+ }
+
+ my.Encrypt = function (block, key) {
+ var l = key.length;
+ my.AddRoundKey(block, key.slice(0, 16));
+ for (var i = 16; i < l - 16; i += 16) {
+ my.SubBytes(block, my.Sbox);
+ my.ShiftRows(block, my.ShiftRowTab);
+ my.MixColumns(block);
+ my.AddRoundKey(block, key.slice(i, i + 16));
+ }
+ my.SubBytes(block, my.Sbox);
+ my.ShiftRows(block, my.ShiftRowTab);
+ my.AddRoundKey(block, key.slice(i, l));
+ }
+
+ my.Decrypt = function (block, key) {
+ var l = key.length;
+ my.AddRoundKey(block, key.slice(l - 16, l));
+ my.ShiftRows(block, my.ShiftRowTab_Inv);
+ my.SubBytes(block, my.Sbox_Inv);
+ for (var i = l - 32; i >= 16; i -= 16) {
+ my.AddRoundKey(block, key.slice(i, i + 16));
+ my.MixColumns_Inv(block);
+ my.ShiftRows(block, my.ShiftRowTab_Inv);
+ my.SubBytes(block, my.Sbox_Inv);
+ }
+ my.AddRoundKey(block, key.slice(0, 16));
+ }
+
+ my.SubBytes = function (state, sbox) {
+ for (var i = 0; i < 16; i++)
+ state[i] = sbox[state[i]];
+ }
+
+ my.AddRoundKey = function (state, rkey) {
+ for (var i = 0; i < 16; i++)
+ state[i] ^= rkey[i];
+ }
+
+ my.ShiftRows = function (state, shifttab) {
+ var h = new Array().concat(state);
+ for (var i = 0; i < 16; i++)
+ state[i] = h[shifttab[i]];
+ }
+
+ my.MixColumns = function (state) {
+ for (var i = 0; i < 16; i += 4) {
+ var s0 = state[i + 0],
+ s1 = state[i + 1];
+ var s2 = state[i + 2],
+ s3 = state[i + 3];
+ var h = s0 ^ s1 ^ s2 ^ s3;
+ state[i + 0] ^= h ^ my.xtime[s0 ^ s1];
+ state[i + 1] ^= h ^ my.xtime[s1 ^ s2];
+ state[i + 2] ^= h ^ my.xtime[s2 ^ s3];
+ state[i + 3] ^= h ^ my.xtime[s3 ^ s0];
+ }
+ }
+
+ my.MixColumns_Inv = function (state) {
+ for (var i = 0; i < 16; i += 4) {
+ var s0 = state[i + 0],
+ s1 = state[i + 1];
+ var s2 = state[i + 2],
+ s3 = state[i + 3];
+ var h = s0 ^ s1 ^ s2 ^ s3;
+ var xh = my.xtime[h];
+ var h1 = my.xtime[my.xtime[xh ^ s0 ^ s2]] ^ h;
+ var h2 = my.xtime[my.xtime[xh ^ s1 ^ s3]] ^ h;
+ state[i + 0] ^= h1 ^ my.xtime[s0 ^ s1];
+ state[i + 1] ^= h2 ^ my.xtime[s1 ^ s2];
+ state[i + 2] ^= h1 ^ my.xtime[s2 ^ s3];
+ state[i + 3] ^= h2 ^ my.xtime[s3 ^ s0];
+ }
+ }
+
+ return my;
+
+}());
+
+
+var cryptico = (function () {
+
+ var my = {};
+
+ aes.Init();
+
+ var base64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+
+ my.b256to64 = function (t) {
+ var a, c, n;
+ var r = '', l = 0, s = 0;
+ var tl = t.length;
+ for (n = 0; n < tl; n++) {
+ c = t.charCodeAt(n);
+ if (s == 0) {
+ r += base64Chars.charAt((c >> 2) & 63);
+ a = (c & 3) << 4;
+ }
+ else if (s == 1) {
+ r += base64Chars.charAt((a | (c >> 4) & 15));
+ a = (c & 15) << 2;
+ }
+ else if (s == 2) {
+ r += base64Chars.charAt(a | ((c >> 6) & 3));
+ l += 1;
+ r += base64Chars.charAt(c & 63);
+ }
+ l += 1;
+ s += 1;
+ if (s == 3) s = 0;
+ }
+ if (s > 0) {
+ r += base64Chars.charAt(a);
+ l += 1;
+ r += '=';
+ l += 1;
+ }
+ if (s == 1) {
+ r += '=';
+ }
+ return r;
+ }
+
+ my.b64to256 = function (t) {
+ var c, n;
+ var r = '', s = 0, a = 0;
+ var tl = t.length;
+ for (n = 0; n < tl; n++) {
+ c = base64Chars.indexOf(t.charAt(n));
+ if (c >= 0) {
+ if (s) r += String.fromCharCode(a | (c >> (6 - s)) & 255);
+ s = (s + 2) & 7;
+ a = (c << s) & 255;
+ }
+ }
+ return r;
+ }
+
+ my.b16to64 = function (h) {
+ var i;
+ var c;
+ var ret = "";
+ if (h.length % 2 == 1) {
+ h = "0" + h;
+ }
+ for (i = 0; i + 3 <= h.length; i += 3) {
+ c = parseInt(h.substring(i, i + 3), 16);
+ ret += base64Chars.charAt(c >> 6) + base64Chars.charAt(c & 63);
+ }
+ if (i + 1 == h.length) {
+ c = parseInt(h.substring(i, i + 1), 16);
+ ret += base64Chars.charAt(c << 2);
+ }
+ else if (i + 2 == h.length) {
+ c = parseInt(h.substring(i, i + 2), 16);
+ ret += base64Chars.charAt(c >> 2) + base64Chars.charAt((c & 3) << 4);
+ }
+ while ((ret.length & 3) > 0) ret += "=";
+ return ret;
+ }
+
+ my.b64to16 = function (s) {
+ var ret = "";
+ var i;
+ var k = 0;
+ var slop;
+ for (i = 0; i < s.length; ++i) {
+ if (s.charAt(i) == "=") break;
+ v = base64Chars.indexOf(s.charAt(i));
+ if (v < 0) continue;
+ if (k == 0) {
+ ret += int2char(v >> 2);
+ slop = v & 3;
+ k = 1;
+ }
+ else if (k == 1) {
+ ret += int2char((slop << 2) | (v >> 4));
+ slop = v & 0xf;
+ k = 2;
+ }
+ else if (k == 2) {
+ ret += int2char(slop);
+ ret += int2char(v >> 2);
+ slop = v & 3;
+ k = 3;
+ }
+ else {
+ ret += int2char((slop << 2) | (v >> 4));
+ ret += int2char(v & 0xf);
+ k = 0;
+ }
+ }
+ if (k == 1) ret += int2char(slop << 2);
+ return ret;
+ }
+
+ // Converts a string to a byte array.
+ my.string2bytes = function (string) {
+ var bytes = new Array();
+ for (var i = 0; i < string.length; i++) {
+ bytes.push(string.charCodeAt(i));
+ }
+ return bytes;
+ }
+
+ // Converts a byte array to a string.
+ my.bytes2string = function (bytes) {
+ var string = "";
+ for (var i = 0; i < bytes.length; i++) {
+ string += String.fromCharCode(bytes[i]);
+ }
+ return string;
+ }
+
+ // Returns a XOR b, where a and b are 16-byte byte arrays.
+ my.blockXOR = function (a, b) {
+ var xor = new Array(16);
+ for (var i = 0; i < 16; i++) {
+ xor[i] = a[i] ^ b[i];
+ }
+ return xor;
+ }
+
+ // Returns a 16-byte initialization vector.
+ my.blockIV = function () {
+ var r = new SecureRandom();
+ var IV = new Array(16);
+ r.nextBytes(IV);
+ return IV;
+ }
+
+ // Returns a copy of bytes with zeros appended to the end
+ // so that the (length of bytes) % 16 == 0.
+ my.pad16 = function (bytes) {
+ var newBytes = bytes.slice(0);
+ var padding = (16 - (bytes.length % 16)) % 16;
+ for (i = bytes.length; i < bytes.length + padding; i++) {
+ newBytes.push(0);
+ }
+ return newBytes;
+ }
+
+ // Removes trailing zeros from a byte array.
+ my.depad = function (bytes) {
+ var newBytes = bytes.slice(0);
+ while (newBytes[newBytes.length - 1] == 0) {
+ newBytes = newBytes.slice(0, newBytes.length - 1);
+ }
+ return newBytes;
+ }
+
+ // AES CBC Encryption.
+ my.encryptAESCBC = function (plaintext, key) {
+ var exkey = key.slice(0);
+ aes.ExpandKey(exkey);
+ var blocks = my.string2bytes(plaintext);
+ blocks = my.pad16(blocks);
+ var encryptedBlocks = my.blockIV();
+ for (var i = 0; i < blocks.length / 16; i++) {
+ var tempBlock = blocks.slice(i * 16, i * 16 + 16);
+ var prevBlock = encryptedBlocks.slice((i) * 16, (i) * 16 + 16);
+ tempBlock = my.blockXOR(prevBlock, tempBlock);
+ aes.Encrypt(tempBlock, exkey);
+ encryptedBlocks = encryptedBlocks.concat(tempBlock);
+ }
+ var ciphertext = my.bytes2string(encryptedBlocks);
+ return my.b256to64(ciphertext)
+ }
+
+ // AES CBC Decryption.
+ my.decryptAESCBC = function (encryptedText, key) {
+ var exkey = key.slice(0);
+ aes.ExpandKey(exkey);
+ var encryptedText = my.b64to256(encryptedText);
+ var encryptedBlocks = my.string2bytes(encryptedText);
+ var decryptedBlocks = new Array();
+ for (var i = 1; i < encryptedBlocks.length / 16; i++) {
+ var tempBlock = encryptedBlocks.slice(i * 16, i * 16 + 16);
+ var prevBlock = encryptedBlocks.slice((i - 1) * 16, (i - 1) * 16 + 16);
+ aes.Decrypt(tempBlock, exkey);
+ tempBlock = my.blockXOR(prevBlock, tempBlock);
+ decryptedBlocks = decryptedBlocks.concat(tempBlock);
+ }
+ decryptedBlocks = my.depad(decryptedBlocks);
+ return my.bytes2string(decryptedBlocks);
+ }
+
+ // Wraps a string to 60 characters.
+ my.wrap60 = function (string) {
+ var outstr = "";
+ for (var i = 0; i < string.length; i++) {
+ if (i % 60 == 0 && i != 0) outstr += "\n";
+ outstr += string[i];
+ }
+ return outstr;
+ }
+
+ // Generate a random key for the AES-encrypted message.
+ my.generateAESKey = function () {
+ var key = new Array(32);
+ var r = new SecureRandom();
+ r.nextBytes(key);
+ return key;
+ }
+
+ // Generates an RSA key from a passphrase.
+ my.generateRSAKey = function (passphrase, bitlength) {
+ Math.seedrandom(sha256.hex(passphrase));
+ var rsa = new RSAKey();
+ rsa.generate(bitlength, "03");
+ return rsa;
+ }
+
+ // Returns the ascii-armored version of the public key.
+ my.publicKeyString = function (rsakey) {
+ pubkey = my.b16to64(rsakey.n.toString(16));
+ return pubkey;
+ }
+
+ // Returns an MD5 sum of a publicKeyString for easier identification.
+ my.publicKeyID = function (publicKeyString) {
+ return MD5(publicKeyString);
+ }
+
+ my.publicKeyFromString = function (string) {
+ var N = my.b64to16(string.split("|")[0]);
+ var E = "03";
+ var rsa = new RSAKey();
+ rsa.setPublic(N, E);
+ return rsa
+ }
+
+ my.encrypt = function (plaintext, publickeystring, signingkey) {
+ var cipherblock = "";
+ var aeskey = my.generateAESKey();
+ try {
+ var publickey = my.publicKeyFromString(publickeystring);
+ cipherblock += my.b16to64(publickey.encrypt(my.bytes2string(aeskey))) + "?";
+ }
+ catch (err) {
+ return {status: "Invalid public key"};
+ }
+ if (signingkey) {
+ signString = cryptico.b16to64(signingkey.signString(plaintext, "sha256"));
+ plaintext += "::52cee64bb3a38f6403386519a39ac91c::";
+ plaintext += cryptico.publicKeyString(signingkey);
+ plaintext += "::52cee64bb3a38f6403386519a39ac91c::";
+ plaintext += signString;
+ }
+ cipherblock += my.encryptAESCBC(plaintext, aeskey);
+ return {status: "success", cipher: cipherblock};
+ }
+
+ my.decrypt = function (ciphertext, key) {
+ var cipherblock = ciphertext.split("?");
+ var aeskey = key.decrypt(my.b64to16(cipherblock[0]));
+ if (aeskey == null) {
+ return {status: "failure"};
+ }
+ aeskey = my.string2bytes(aeskey);
+ var plaintext = my.decryptAESCBC(cipherblock[1], aeskey).split("::52cee64bb3a38f6403386519a39ac91c::");
+ if (plaintext.length == 3) {
+ var publickey = my.publicKeyFromString(plaintext[1]);
+ var signature = my.b64to16(plaintext[2]);
+ if (publickey.verifyString(plaintext[0], signature)) {
+ return {
+ status: "success",
+ plaintext: plaintext[0],
+ signature: "verified",
+ publicKeyString: my.publicKeyString(publickey)
+ };
+ }
+ else {
+ return {
+ status: "success",
+ plaintext: plaintext[0],
+ signature: "forged",
+ publicKeyString: my.publicKeyString(publickey)
+ };
+ }
+ }
+ else {
+ return {status: "success", plaintext: plaintext[0], signature: "unsigned"};
+ }
+ }
+
+ return my;
+
+}()); \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/js/fontawesome.js b/main/app/sprinkles/core/assets/SiteAssets/js/fontawesome.js
new file mode 100644
index 0000000..497accc
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/js/fontawesome.js
@@ -0,0 +1,5 @@
+/*!
+ * Font Awesome Free 5.0.10 by @fontawesome - https://fontawesome.com
+ * License - https://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
+ */
+!function(){"use strict";var c={};try{"undefined"!=typeof window&&(c=window)}catch(c){}var l=(c.navigator||{}).userAgent,h=void 0===l?"":l,v=c,z=(~h.indexOf("MSIE")||h.indexOf("Trident/"),"___FONT_AWESOME___"),e=function(){try{return!0}catch(c){return!1}}(),a=[1,2,3,4,5,6,7,8,9,10],m=a.concat([11,12,13,14,15,16,17,18,19,20]);["xs","sm","lg","fw","ul","li","border","pull-left","pull-right","spin","pulse","rotate-90","rotate-180","rotate-270","flip-horizontal","flip-vertical","stack","stack-1x","stack-2x","inverse","layers","layers-text","layers-counter"].concat(a.map(function(c){return c+"x"})).concat(m.map(function(c){return"w-"+c}));var s=v||{};s[z]||(s[z]={}),s[z].styles||(s[z].styles={}),s[z].hooks||(s[z].hooks={}),s[z].shims||(s[z].shims=[]);var t=s[z],f=Object.assign||function(c){for(var l=1;l<arguments.length;l++){var h=arguments[l];for(var v in h)Object.prototype.hasOwnProperty.call(h,v)&&(c[v]=h[v])}return c};var r={"500px":[448,512,[],"f26e","M103.3 344.3c-6.5-14.2-6.9-18.3 7.4-23.1 25.6-8 8 9.2 43.2 49.2h.3v-93.9c1.2-50.2 44-92.2 97.7-92.2 53.9 0 97.7 43.5 97.7 96.8 0 63.4-60.8 113.2-128.5 93.3-10.5-4.2-2.1-31.7 8.5-28.6 53 0 89.4-10.1 89.4-64.4 0-61-77.1-89.6-116.9-44.6-23.5 26.4-17.6 42.1-17.6 157.6 50.7 31 118.3 22 160.4-20.1 24.8-24.8 38.5-58 38.5-93 0-35.2-13.8-68.2-38.8-93.3-24.8-24.8-57.8-38.5-93.3-38.5s-68.8 13.8-93.5 38.5c-.3.3-16 16.5-21.2 23.9l-.5.6c-3.3 4.7-6.3 9.1-20.1 6.1-6.9-1.7-14.3-5.8-14.3-11.8V20c0-5 3.9-10.5 10.5-10.5h241.3c8.3 0 8.3 11.6 8.3 15.1 0 3.9 0 15.1-8.3 15.1H130.3v132.9h.3c104.2-109.8 282.8-36 282.8 108.9 0 178.1-244.8 220.3-310.1 62.8zm63.3-260.8c-.5 4.2 4.6 24.5 14.6 20.6C306 56.6 384 144.5 390.6 144.5c4.8 0 22.8-15.3 14.3-22.8-93.2-89-234.5-57-238.3-38.2zM393 414.7C283 524.6 94 475.5 61 310.5c0-12.2-30.4-7.4-28.9 3.3 24 173.4 246 256.9 381.6 121.3 6.9-7.8-12.6-28.4-20.7-20.4zM213.6 306.6c0 4 4.3 7.3 5.5 8.5 3 3 6.1 4.4 8.5 4.4 3.8 0 2.6.2 22.3-19.5 19.6 19.3 19.1 19.5 22.3 19.5 5.4 0 18.5-10.4 10.7-18.2L265.6 284l18.2-18.2c6.3-6.8-10.1-21.8-16.2-15.7L249.7 268c-18.6-18.8-18.4-19.5-21.5-19.5-5 0-18 11.7-12.4 17.3L234 284c-18.1 17.9-20.4 19.2-20.4 22.6z"],"accessible-icon":[448,512,[],"f368","M423.9 255.8L411 413.1c-3.3 40.7-63.9 35.1-60.6-4.9l10-122.5-41.1 2.3c10.1 20.7 15.8 43.9 15.8 68.5 0 41.2-16.1 78.7-42.3 106.5l-39.3-39.3c57.9-63.7 13.1-167.2-74-167.2-25.9 0-49.5 9.9-67.2 26L73 243.2c22-20.7 50.1-35.1 81.4-40.2l75.3-85.7-42.6-24.8-51.6 46c-30 26.8-70.6-18.5-40.5-45.4l68-60.7c9.8-8.8 24.1-10.2 35.5-3.6 0 0 139.3 80.9 139.5 81.1 16.2 10.1 20.7 36 6.1 52.6L285.7 229l106.1-5.9c18.5-1.1 33.6 14.4 32.1 32.7zm-64.9-154c28.1 0 50.9-22.8 50.9-50.9C409.9 22.8 387.1 0 359 0c-28.1 0-50.9 22.8-50.9 50.9 0 28.1 22.8 50.9 50.9 50.9zM179.6 456.5c-80.6 0-127.4-90.6-82.7-156.1l-39.7-39.7C36.4 287 24 320.3 24 356.4c0 130.7 150.7 201.4 251.4 122.5l-39.7-39.7c-16 10.9-35.3 17.3-56.1 17.3z"],accusoft:[640,512,[],"f369","M482.2 372.1C476.5 365.2 250 75 242.3 65.5c-13.7-17.2 0-16.8 19.2-16.9 9.7-.1 106.3-.6 116.5-.6 24.1-.1 28.7.6 38.4 12.8 2.1 2.7 205.1 245.8 207.2 248.3 5.5 6.7 15.2 19.1 7.2 23.4-2.4 1.3-114.6 47.7-117.8 48.9-10.1 4-17.5 6.8-30.8-9.3m114.7-5.6s-115 50.4-117.5 51.6c-16 7.3-26.9-3.2-36.7-14.6l-57.1-74c-5.4-.9-60.4-9.6-65.3-9.3-3.1.2-9.6.8-14.4 2.9-4.9 2.1-145.2 52.8-150.2 54.7-5.1 2-11.4 3.6-11.1 7.6.2 2.5 2 2.6 4.6 3.5 2.7.8 300.9 67.6 308 69.1 15.6 3.3 38.5 10.5 53.6 1.7 2.1-1.2 123.8-76.4 125.8-77.8 5.4-4 4.3-6.8-1.7-8.2-2.3-.3-24.6-4.7-38-7.2m-326-181.3s-12 1.6-25 15.1c-9 9.3-242.1 239.1-243.4 240.9-7 10 1.6 6.8 15.7 1.7.8 0 114.5-36.6 114.5-36.6.5-.6-.1-.1.6-.6-.4-5.1-.8-26.2-1-27.7-.6-5.2 2.2-6.9 7-8.9l92.6-33.8c.6-.8 88.5-81.7 90.2-83.3v-1l-51.2-65.8"],adn:[496,512,[],"f170","M248 167.5l64.9 98.8H183.1l64.9-98.8zM496 256c0 136.9-111.1 248-248 248S0 392.9 0 256 111.1 8 248 8s248 111.1 248 248zm-99.8 82.7L248 115.5 99.8 338.7h30.4l33.6-51.7h168.6l33.6 51.7h30.2z"],adversal:[512,512,[],"f36a","M482.1 32H28.7C5.8 32 0 37.9 0 60.9v390.2C0 474.4 5.8 480 28.7 480h453.4c24.4 0 29.9-5.2 29.9-29.7V62.2c0-24.6-5.4-30.2-29.9-30.2zM178.4 220.3c-27.5-20.2-72.1-8.7-84.2 23.4-4.3 11.1-9.3 9.5-17.5 8.3-9.7-1.5-17.2-3.2-22.5-5.5-28.8-11.4 8.6-55.3 24.9-64.3 41.1-21.4 83.4-22.2 125.3-4.8 40.9 16.8 34.5 59.2 34.5 128.5 2.7 25.8-4.3 58.3 9.3 88.8 1.9 4.4.4 7.9-2.7 10.7-8.4 6.7-39.3 2.2-46.6-7.4-1.9-2.2-1.8-3.6-3.9-6.2-3.6-3.9-7.3-2.2-11.9 1-57.4 36.4-140.3 21.4-147-43.3-3.1-29.3 12.4-57.1 39.6-71 38.2-19.5 112.2-11.8 114-30.9 1.1-10.2-1.9-20.1-11.3-27.3zm286.7 222c0 15.1-11.1 9.9-17.8 9.9H52.4c-7.4 0-18.2 4.8-17.8-10.7.4-13.9 10.5-9.1 17.1-9.1 132.3-.4 264.5-.4 396.8 0 6.8 0 16.6-4.4 16.6 9.9zm3.8-340.5v291c0 5.7-.7 13.9-8.1 13.9-12.4-.4-27.5 7.1-36.1-5.6-5.8-8.7-7.8-4-12.4-1.2-53.4 29.7-128.1 7.1-144.4-85.2-6.1-33.4-.7-67.1 15.7-100 11.8-23.9 56.9-76.1 136.1-30.5v-71c0-26.2-.1-26.2 26-26.2 3.1 0 6.6.4 9.7 0 10.1-.8 13.6 4.4 13.6 14.3-.1.2-.1.3-.1.5zm-51.5 232.3c-19.5 47.6-72.9 43.3-90 5.2-15.1-33.3-15.5-68.2.4-101.5 16.3-34.1 59.7-35.7 81.5-4.8 20.6 28.8 14.9 84.6 8.1 101.1zm-294.8 35.3c-7.5-1.3-33-3.3-33.7-27.8-.4-13.9 7.8-23 19.8-25.8 24.4-5.9 49.3-9.9 73.7-14.7 8.9-2 7.4 4.4 7.8 9.5 1.4 33-26.1 59.2-67.6 58.8z"],affiliatetheme:[512,512,[],"f36b","M159.7 237.4C108.4 308.3 43.1 348.2 14 326.6-15.2 304.9 2.8 230 54.2 159.1c51.3-70.9 116.6-110.8 145.7-89.2 29.1 21.6 11.1 96.6-40.2 167.5zm351.2-57.3C437.1 303.5 319 367.8 246.4 323.7c-25-15.2-41.3-41.2-49-73.8-33.6 64.8-92.8 113.8-164.1 133.2 49.8 59.3 124.1 96.9 207 96.9 150 0 271.6-123.1 271.6-274.9.1-8.5-.3-16.8-1-25z"],algolia:[448,512,[],"f36c","M229.3 182.6c-49.3 0-89.2 39.9-89.2 89.2 0 49.3 39.9 89.2 89.2 89.2s89.2-39.9 89.2-89.2c0-49.3-40-89.2-89.2-89.2zm62.7 56.6l-58.9 30.6c-1.8.9-3.8-.4-3.8-2.3V201c0-1.5 1.3-2.7 2.7-2.6 26.2 1 48.9 15.7 61.1 37.1.7 1.3.2 3-1.1 3.7zM389.1 32H58.9C26.4 32 0 58.4 0 90.9V421c0 32.6 26.4 59 58.9 59H389c32.6 0 58.9-26.4 58.9-58.9V90.9C448 58.4 421.6 32 389.1 32zm-202.6 84.7c0-10.8 8.7-19.5 19.5-19.5h45.3c10.8 0 19.5 8.7 19.5 19.5v15.4c0 1.8-1.7 3-3.3 2.5-12.3-3.4-25.1-5.1-38.1-5.1-13.5 0-26.7 1.8-39.4 5.5-1.7.5-3.4-.8-3.4-2.5v-15.8zm-84.4 37l9.2-9.2c7.6-7.6 19.9-7.6 27.5 0l7.7 7.7c1.1 1.1 1 3-.3 4-6.2 4.5-12.1 9.4-17.6 14.9-5.4 5.4-10.4 11.3-14.8 17.4-1 1.3-2.9 1.5-4 .3l-7.7-7.7c-7.6-7.5-7.6-19.8 0-27.4zm127.2 244.8c-70 0-126.6-56.7-126.6-126.6s56.7-126.6 126.6-126.6c70 0 126.6 56.6 126.6 126.6 0 69.8-56.7 126.6-126.6 126.6z"],amazon:[448,512,[],"f270","M257.2 162.7c-48.7 1.8-169.5 15.5-169.5 117.5 0 109.5 138.3 114 183.5 43.2 6.5 10.2 35.4 37.5 45.3 46.8l56.8-56S341 288.9 341 261.4V114.3C341 89 316.5 32 228.7 32 140.7 32 94 87 94 136.3l73.5 6.8c16.3-49.5 54.2-49.5 54.2-49.5 40.7-.1 35.5 29.8 35.5 69.1zm0 86.8c0 80-84.2 68-84.2 17.2 0-47.2 50.5-56.7 84.2-57.8v40.6zm136 163.5c-7.7 10-70 67-174.5 67S34.2 408.5 9.7 379c-6.8-7.7 1-11.3 5.5-8.3C88.5 415.2 203 488.5 387.7 401c7.5-3.7 13.3 2 5.5 12zm39.8 2.2c-6.5 15.8-16 26.8-21.2 31-5.5 4.5-9.5 2.7-6.5-3.8s19.3-46.5 12.7-55c-6.5-8.3-37-4.3-48-3.2-10.8 1-13 2-14-.3-2.3-5.7 21.7-15.5 37.5-17.5 15.7-1.8 41-.8 46 5.7 3.7 5.1 0 27.1-6.5 43.1z"],"amazon-pay":[611,512,[],"f42c","M0 325.2c2.3-4.2 5.2-4.9 9.7-2.5 10.4 5.6 20.6 11.4 31.2 16.7 40.7 20.4 83.2 35.6 127.4 46.3 20.9 5 41.9 9 63.2 11.8 31.5 4.2 63.2 6 95 5.2 17.4-.4 34.8-1.8 52.1-3.8 56.4-6.7 110.9-20.8 163.3-42.8 2.9-1.2 5.9-2 9.1-1.2 6.7 1.8 9 9 4.1 13.9-2.8 2.8-6.3 5.1-9.6 7.4-30.7 21.1-64.2 36.4-99.6 47.9-24.6 7.9-49.6 13.8-75.1 17.6-17.6 2.6-35.4 4.4-53.2 4.8-.8 0-1.7.2-2.5.3H294c-.8-.1-1.7-.3-2.5-.3-3.6-.2-7.2-.3-10.7-.4-16.9-.7-33.7-2.6-50.4-5.3-27.4-4.5-54.2-11.4-80.4-20.9-54.1-19.6-102.6-48.6-145.6-87-1.8-1.6-3-3.8-4.4-5.7v-2zM158 65c-1.4.2-2.9.4-4.3.6-14 1.7-26.6 6.9-38 15.1-2.4 1.7-4.6 3.5-7.1 5.4-.2-.5-.4-1-.4-1.4-.4-2.7-.8-5.5-1.3-8.2-.7-4.6-3-6.6-7.6-6.6H87.8c-6.9 0-8.2 1.3-8.2 8.2v209.3c0 1 0 2 .1 3 .2 3 2 4.9 4.9 5 7 .1 14.1.1 21.1 0 2.9 0 4.7-2 5-5 .1-1 .1-2 .1-3V215c1.1.9 1.7 1.4 2.2 1.9 17.9 14.9 38.5 19.8 61 15.4 20.4-4 34.6-16.5 43.8-34.9 7-13.9 9.9-28.7 10.3-44.1.5-17.1-1.2-33.9-8.1-49.8-8.5-19.6-22.6-32.5-43.9-36.9-3.2-.7-6.5-1-9.8-1.5-2.8-.1-5.5-.1-8.3-.1zm-47.4 41.9c0-1.5.4-2.4 1.7-3.3 13.7-9.5 28.8-14.5 45.6-13.2 14.9 1.1 27.1 8.4 33.5 25.9 3.9 10.7 4.9 21.8 4.9 33 0 10.4-.8 20.6-4 30.6-6.8 21.3-22.4 29.4-42.6 28.5-14-.6-26.2-6-37.4-13.9-1.2-.9-1.7-1.7-1.7-3.3.1-14.1 0-28.1 0-42.2 0-14 .1-28 0-42.1zM316.3 65c-1 .1-2 .3-2.9.4-9.8.5-19.4 1.7-28.9 4.1-6.1 1.6-12 3.8-17.9 5.8-3.6 1.2-5.4 3.8-5.3 7.7.1 3.3-.1 6.6 0 9.9.1 4.8 2.1 6.1 6.8 4.9 7.8-2 15.6-4.2 23.5-5.7 12.3-2.3 24.7-3.3 37.2-1.4 6.5 1 12.6 2.9 16.8 8.4 3.7 4.8 5.1 10.5 5.3 16.4.3 8.3.2 16.6.3 24.9 0 .4-.1.9-.2 1.4-.5-.1-.9 0-1.3-.1-10.5-2.5-21.1-4.3-32-4.9-11.3-.6-22.5.1-33.3 3.9-12.9 4.5-23.3 12.3-29.4 24.9-4.7 9.8-5.4 20.2-3.9 30.7 2 14 9 24.8 21.4 31.7 11.9 6.6 24.8 7.4 37.9 5.4 15.1-2.3 28.5-8.7 40.3-18.4.4-.4.9-.7 1.6-1.1.6 3.8 1.1 7.4 1.8 11 .6 3.1 2.5 5.1 5.4 5.2 5.4.1 10.9.1 16.3 0 2.7-.1 4.5-1.9 4.8-4.7.1-.9.1-1.9.1-2.8v-106c0-4.3-.2-8.6-.9-12.9-1.9-12.9-7.4-23.5-19-30.4-6.7-4-14.1-6-21.8-7.1-3.6-.5-7.2-.8-10.8-1.3-3.9.1-7.9.1-11.9.1zm35 127.7c0 1.3-.4 2.2-1.5 3-11.2 8.1-23.5 13.5-37.4 14.9-5.7.6-11.4.4-16.8-1.8-6.3-2.5-10.4-6.9-12.4-13.3s-2-13-.1-19.4c2.5-8.3 8.4-13 16.4-15.6 8.1-2.6 16.5-3 24.8-2.2 8.4.7 16.6 2.3 25 3.4 1.6.2 2.1 1 2.1 2.6-.1 4.8 0 9.5 0 14.3-.1 4.7-.2 9.4-.1 14.1zm259.9 129.4c-1-5-4.8-6.9-9.1-8.3-6.8-2.3-13.9-3.3-21-3.9-13.1-1.1-26.2-.5-39.2 1.9-14.3 2.7-27.9 7.3-40 15.6-1.4 1-2.8 2.1-3.7 3.5-.7 1.1-.9 2.8-.5 4 .4 1.5 2.1 1.9 3.6 1.8.7 0 1.5 0 2.2-.1 7.8-.8 15.5-1.7 23.3-2.5 11.4-1.1 22.9-1.8 34.3-.9 4.8.3 9.7 1.4 14.4 2.7 5.1 1.4 7.4 5.2 7.6 10.4.4 8-1.4 15.7-3.5 23.3-4.1 15.4-10 30.3-15.8 45.1-.4 1-.8 2-1 3-.5 2.9 1.2 4.8 4.1 4.1 1.7-.4 3.6-1.3 4.8-2.5 4.4-4.3 8.9-8.6 12.7-13.4 12.8-16.4 20.3-35.3 24.7-55.6.8-3.6 1.4-7.3 2.1-10.9v-17.3zM479.1 198.9c-12.9-35.7-25.8-71.5-38.7-107.2-2-5.7-4.2-11.3-6.3-16.9-1.1-2.9-3.2-4.8-6.4-4.8-7.6-.1-15.2-.2-22.9-.1-2.5 0-3.7 2-3.2 4.5.5 2.1 1.1 4.1 1.9 6.1 19.6 48.5 39.3 97.1 59.1 145.5 1.7 4.1 2.1 7.6.2 11.8-3.3 7.3-5.9 15-9.3 22.3-3 6.5-8 11.4-15.2 13.3-5.1 1.4-10.2 1.6-15.4 1.1-2.5-.2-5-.8-7.5-1-3.4-.2-5.1 1.3-5.2 4.8-.1 3.3-.1 6.6 0 9.9.1 5.5 2 8 7.4 8.9 5.6 1 11.3 1.9 16.9 2 17.1.4 30.7-6.5 39.5-21.4 3.5-5.9 6.7-12.1 9.2-18.4 23.7-59.8 47.1-119.7 70.6-179.6.7-1.8 1.3-3.6 1.6-5.5.4-2.8-.9-4.4-3.7-4.4-6.6-.1-13.3 0-19.9 0-3.7 0-6.3 1.6-7.7 5.2-.5 1.4-1.1 2.7-1.6 4.1-11.6 33.3-23.2 66.6-34.8 100-2.5 7.2-5.1 14.5-7.7 22.2-.4-1.1-.6-1.7-.9-2.4z"],amilia:[448,512,[],"f36d","M240.1 32c-61.9 0-131.5 16.9-184.2 55.4-5.1 3.1-9.1 9.2-7.2 19.4 1.1 5.1 5.1 27.4 10.2 39.6 4.1 10.2 14.2 10.2 20.3 6.1 32.5-22.3 96.5-47.7 152.3-47.7 57.9 0 58.9 28.4 58.9 73.1v38.5C203 227.7 78.2 251 46.7 264.2 11.2 280.5 16.3 357.7 16.3 376s15.2 104 124.9 104c47.8 0 113.7-20.7 153.3-42.1v25.4c0 3 2.1 8.2 6.1 9.1 3.1 1 50.7 2 59.9 2s62.5.3 66.5-.7c4.1-1 5.1-6.1 5.1-9.1V168c-.1-80.3-57.9-136-192-136zm-87.9 327.7c0-12.2-3-42.7 18.3-52.9 24.3-13.2 75.1-29.4 119.8-33.5V380c-21.4 13.2-48.7 24.4-79.1 24.4-52.8 0-58.9-33.5-59-44.7"],android:[448,512,[],"f17b","M89.6 204.5v115.8c0 15.4-12.1 27.7-27.5 27.7-15.3 0-30.1-12.4-30.1-27.7V204.5c0-15.1 14.8-27.5 30.1-27.5 15.1 0 27.5 12.4 27.5 27.5zm10.8 157c0 16.4 13.2 29.6 29.6 29.6h19.9l.3 61.1c0 36.9 55.2 36.6 55.2 0v-61.1h37.2v61.1c0 36.7 55.5 36.8 55.5 0v-61.1h20.2c16.2 0 29.4-13.2 29.4-29.6V182.1H100.4v179.4zm248-189.1H99.3c0-42.8 25.6-80 63.6-99.4l-19.1-35.3c-2.8-4.9 4.3-8 6.7-3.8l19.4 35.6c34.9-15.5 75-14.7 108.3 0L297.5 34c2.5-4.3 9.5-1.1 6.7 3.8L285.1 73c37.7 19.4 63.3 56.6 63.3 99.4zm-170.7-55.5c0-5.7-4.6-10.5-10.5-10.5-5.7 0-10.2 4.8-10.2 10.5s4.6 10.5 10.2 10.5c5.9 0 10.5-4.8 10.5-10.5zm113.4 0c0-5.7-4.6-10.5-10.2-10.5-5.9 0-10.5 4.8-10.5 10.5s4.6 10.5 10.5 10.5c5.6 0 10.2-4.8 10.2-10.5zm94.8 60.1c-15.1 0-27.5 12.1-27.5 27.5v115.8c0 15.4 12.4 27.7 27.5 27.7 15.4 0 30.1-12.4 30.1-27.7V204.5c0-15.4-14.8-27.5-30.1-27.5z"],angellist:[448,512,[],"f209","M347.1 215.4c11.7-32.6 45.4-126.9 45.4-157.1 0-26.6-15.7-48.9-43.7-48.9-44.6 0-84.6 131.7-97.1 163.1C242 144 196.6 0 156.6 0c-31.1 0-45.7 22.9-45.7 51.7 0 35.3 34.2 126.8 46.6 162-6.3-2.3-13.1-4.3-20-4.3-23.4 0-48.3 29.1-48.3 52.6 0 8.9 4.9 21.4 8 29.7-36.9 10-51.1 34.6-51.1 71.7C46 435.6 114.4 512 210.6 512c118 0 191.4-88.6 191.4-202.9 0-43.1-6.9-82-54.9-93.7zM311.7 108c4-12.3 21.1-64.3 37.1-64.3 8.6 0 10.9 8.9 10.9 16 0 19.1-38.6 124.6-47.1 148l-34-6 33.1-93.7zM142.3 48.3c0-11.9 14.5-45.7 46.3 47.1l34.6 100.3c-15.6-1.3-27.7-3-35.4 1.4-10.9-28.8-45.5-119.7-45.5-148.8zM140 244c29.3 0 67.1 94.6 67.1 107.4 0 5.1-4.9 11.4-10.6 11.4-20.9 0-76.9-76.9-76.9-97.7.1-7.7 12.7-21.1 20.4-21.1zm184.3 186.3c-29.1 32-66.3 48.6-109.7 48.6-59.4 0-106.3-32.6-128.9-88.3-17.1-43.4 3.8-68.3 20.6-68.3 11.4 0 54.3 60.3 54.3 73.1 0 4.9-7.7 8.3-11.7 8.3-16.1 0-22.4-15.5-51.1-51.4-29.7 29.7 20.5 86.9 58.3 86.9 26.1 0 43.1-24.2 38-42 3.7 0 8.3.3 11.7-.6 1.1 27.1 9.1 59.4 41.7 61.7 0-.9 2-7.1 2-7.4 0-17.4-10.6-32.6-10.6-50.3 0-28.3 21.7-55.7 43.7-71.7 8-6 17.7-9.7 27.1-13.1 9.7-3.7 20-8 27.4-15.4-1.1-11.2-5.7-21.1-16.9-21.1-27.7 0-120.6 4-120.6-39.7 0-6.7.1-13.1 17.4-13.1 32.3 0 114.3 8 138.3 29.1 18.1 16.1 24.3 113.2-31 174.7zm-98.6-126c9.7 3.1 19.7 4 29.7 6-7.4 5.4-14 12-20.3 19.1-2.8-8.5-6.2-16.8-9.4-25.1z"],angrycreative:[640,512,[],"f36e","M640 238.2l-3.2 28.2-34.5 2.3-2 18.1 34.5-2.3-3.2 28.2-34.4 2.2-2.3 20.1 34.4-2.2-3 26.1-64.7 4.1 12.7-113.2L527 365.2l-31.9 2-23.8-117.8 30.3-2 13.6 79.4 31.7-82.4 93.1-6.2zM426.8 371.5l28.3-1.8L468 249.6l-28.4 1.9-12.8 120zM162 388.1l-19.4-36-3.5 37.4-28.2 1.7 2.7-29.1c-11 18-32 34.3-56.9 35.8C23.9 399.9-3 377 .3 339.7c2.6-29.3 26.7-62.8 67.5-65.4 37.7-2.4 47.6 23.2 51.3 28.8l2.8-30.8 38.9-2.5c20.1-1.3 38.7 3.7 42.5 23.7l2.6-26.6 64.8-4.2-2.7 27.9-36.4 2.4-1.7 17.9 36.4-2.3-2.7 27.9-36.4 2.3-1.9 19.9 36.3-2.3-2.1 20.8 55-117.2 23.8-1.6L370.4 369l8.9-85.6-22.3 1.4 2.9-27.9 75-4.9-3 28-24.3 1.6-9.7 91.9-58 3.7-4.3-15.6-39.4 2.5-8 16.3-126.2 7.7zm-44.3-70.2l-26.4 1.7C84.6 307.2 76.9 303 65 303.8c-19 1.2-33.3 17.5-34.6 33.3-1.4 16 7.3 32.5 28.7 31.2 12.8-.8 21.3-8.6 28.9-18.9l27-1.7 2.7-29.8zm56.1-7.7c1.2-12.9-7.6-13.6-26.1-12.4l-2.7 28.5c14.2-.9 27.5-2.1 28.8-16.1zm21.1 70.8l5.8-60c-5 13.5-14.7 21.1-27.9 26.6l22.1 33.4zm135.4-45l-7.9-37.8-15.8 39.3 23.7-1.5zm-170.1-74.6l-4.3-17.5-39.6 2.6-8.1 18.2-31.9 2.1 57-121.9 23.9-1.6 30.7 102 9.9-104.7 27-1.8 37.8 63.6 6.5-66.6 28.5-1.9-4 41.2c7.4-13.5 22.9-44.7 63.6-47.5 40.5-2.8 52.4 29.3 53.4 30.3l3.3-32 39.3-2.7c12.7-.9 27.8.3 36.3 9.7l-4.4-11.9 32.2-2.2 12.9 43.2 23-45.7 31-2.2-43.6 78.4-4.8 44.3-28.4 1.9 4.8-44.3-15.8-43c1 22.3-9.2 40.1-32 49.6l25.2 38.8-36.4 2.4-19.2-36.8-4 38.3-28.4 1.9 3.3-31.5c-6.7 9.3-19.7 35.4-59.6 38-26.2 1.7-45.6-10.3-55.4-39.2l-4 40.3-25 1.6-37.6-63.3-6.3 66.2-56.8 3.7zm276.6-82.1c10.2-.7 17.5-2.1 21.6-4.3 4.5-2.4 7-6.4 7.6-12.1.6-5.3-.6-8.8-3.4-10.4-3.6-2.1-10.6-2.8-22.9-2l-2.9 28.8zM327.7 214c5.6 5.9 12.7 8.5 21.3 7.9 4.7-.3 9.1-1.8 13.3-4.1 5.5-3 10.6-8 15.1-14.3l-34.2 2.3 2.4-23.9 63.1-4.3 1.2-12-31.2 2.1c-4.1-3.7-7.8-6.6-11.1-8.1-4-1.7-8.1-2.8-12.2-2.5-8 .5-15.3 3.6-22 9.2-7.7 6.4-12 14.5-12.9 24.4-1.1 9.6 1.4 17.3 7.2 23.3zm-201.3 8.2l23.8-1.6-8.3-37.6-15.5 39.2z"],angular:[415,512,[],"f420","M169.7 268.1h76.2l-38.1-91.6-38.1 91.6zM207.8 32L0 106.4l31.8 275.7 176 97.9 176-97.9 31.8-275.7L207.8 32zM338 373.8h-48.6l-26.2-65.4H152.6l-26.2 65.4H77.7L207.8 81.5 338 373.8z"],"app-store":[512,512,[],"f36f","M255.9 120.9l9.1-15.7c5.6-9.8 18.1-13.1 27.9-7.5 9.8 5.6 13.1 18.1 7.5 27.9l-87.5 151.5h63.3c20.5 0 32 24.1 23.1 40.8H113.8c-11.3 0-20.4-9.1-20.4-20.4 0-11.3 9.1-20.4 20.4-20.4h52l66.6-115.4-20.8-36.1c-5.6-9.8-2.3-22.2 7.5-27.9 9.8-5.6 22.2-2.3 27.9 7.5l8.9 15.7zm-78.7 218l-19.6 34c-5.6 9.8-18.1 13.1-27.9 7.5-9.8-5.6-13.1-18.1-7.5-27.9l14.6-25.2c16.4-5.1 29.8-1.2 40.4 11.6zm168.9-61.7h53.1c11.3 0 20.4 9.1 20.4 20.4 0 11.3-9.1 20.4-20.4 20.4h-29.5l19.9 34.5c5.6 9.8 2.3 22.2-7.5 27.9-9.8 5.6-22.2 2.3-27.9-7.5-33.5-58.1-58.7-101.6-75.4-130.6-17.1-29.5-4.9-59.1 7.2-69.1 13.4 23 33.4 57.7 60.1 104zM256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm216 248c0 118.7-96.1 216-216 216-118.7 0-216-96.1-216-216 0-118.7 96.1-216 216-216 118.7 0 216 96.1 216 216z"],"app-store-ios":[448,512,[],"f370","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM127 384.5c-5.5 9.6-17.8 12.8-27.3 7.3-9.6-5.5-12.8-17.8-7.3-27.3l14.3-24.7c16.1-4.9 29.3-1.1 39.6 11.4L127 384.5zm138.9-53.9H84c-11 0-20-9-20-20s9-20 20-20h51l65.4-113.2-20.5-35.4c-5.5-9.6-2.2-21.8 7.3-27.3 9.6-5.5 21.8-2.2 27.3 7.3l8.9 15.4 8.9-15.4c5.5-9.6 17.8-12.8 27.3-7.3 9.6 5.5 12.8 17.8 7.3 27.3l-85.8 148.6h62.1c20.2 0 31.5 23.7 22.7 40zm98.1 0h-29l19.6 33.9c5.5 9.6 2.2 21.8-7.3 27.3-9.6 5.5-21.8 2.2-27.3-7.3-32.9-56.9-57.5-99.7-74-128.1-16.7-29-4.8-58 7.1-67.8 13.1 22.7 32.7 56.7 58.9 102h52c11 0 20 9 20 20 0 11.1-9 20-20 20z"],apper:[640,512,[],"f371","M42.1 239.1c22.2 0 29 2.8 33.5 14.6h.8v-22.9c0-11.3-4.8-15.4-17.9-15.4-11.3 0-14.4 2.5-15.1 12.8H4.8c.3-13.9 1.5-19.1 5.8-24.4C17.9 195 29.5 192 56.7 192c33 0 47.1 5 53.9 18.9 2 4.3 4 15.6 4 23.7v76.3H76.3l1.3-19.1h-1c-5.3 15.6-13.6 20.4-35.5 20.4-30.3 0-41.1-10.1-41.1-37.3 0-25.2 12.3-35.8 42.1-35.8zm17.1 48.1c13.1 0 16.9-3 16.9-13.4 0-9.1-4.3-11.6-19.6-11.6-13.1 0-17.9 3-17.9 12.1-.1 10.4 3.7 12.9 20.6 12.9zm77.8-94.9h38.3l-1.5 20.6h.8c9.1-17.1 15.9-20.9 37.5-20.9 14.4 0 24.7 3 31.5 9.1 9.8 8.6 12.8 20.4 12.8 48.1 0 30-3 43.1-12.1 52.9-6.8 7.3-16.4 10.1-33.2 10.1-20.4 0-29.2-5.5-33.8-21.2h-.8v70.3H137v-169zm80.9 60.7c0-27.5-3.3-32.5-20.7-32.5-16.9 0-20.7 5-20.7 28.7 0 28 3.5 33.5 21.2 33.5 16.4 0 20.2-5.6 20.2-29.7zm57.9-60.7h38.3l-1.5 20.6h.8c9.1-17.1 15.9-20.9 37.5-20.9 14.4 0 24.7 3 31.5 9.1 9.8 8.6 12.8 20.4 12.8 48.1 0 30-3 43.1-12.1 52.9-6.8 7.3-16.4 10.1-33.3 10.1-20.4 0-29.2-5.5-33.8-21.2h-.8v70.3h-39.5v-169zm80.9 60.7c0-27.5-3.3-32.5-20.7-32.5-16.9 0-20.7 5-20.7 28.7 0 28 3.5 33.5 21.2 33.5 16.4 0 20.2-5.6 20.2-29.7zm53.8-3.8c0-25.4 3.3-37.8 12.3-45.8 8.8-8.1 22.2-11.3 45.1-11.3 42.8 0 55.7 12.8 55.7 55.7v11.1h-75.3c-.3 2-.3 4-.3 4.8 0 16.9 4.5 21.9 20.1 21.9 13.9 0 17.9-3 17.9-13.9h37.5v2.3c0 9.8-2.5 18.9-6.8 24.7-7.3 9.8-19.6 13.6-44.3 13.6-27.5 0-41.6-3.3-50.6-12.3-8.5-8.5-11.3-21.3-11.3-50.8zm76.4-11.6c-.3-1.8-.3-3.3-.3-3.8 0-12.3-3.3-14.6-19.6-14.6-14.4 0-17.1 3-18.1 15.1l-.3 3.3h38.3zm55.6-45.3h38.3l-1.8 19.9h.7c6.8-14.9 14.4-20.2 29.7-20.2 10.8 0 19.1 3.3 23.4 9.3 5.3 7.3 6.8 14.4 6.8 34 0 1.5 0 5 .2 9.3h-35c.3-1.8.3-3.3.3-4 0-15.4-2-19.4-10.3-19.4-6.3 0-10.8 3.3-13.1 9.3-1 3-1 4.3-1 12.3v68h-38.3V192.3z"],apple:[376,512,[],"f179","M314.7 268.7c-.2-36.7 16.4-64.4 50-84.8-18.8-26.9-47.2-41.7-84.7-44.6-35.5-2.8-74.3 20.7-88.5 20.7-15 0-49.4-19.7-76.4-19.7C59.3 141.2 0 184.8 0 273.5c0 26.2 4.8 53.3 14.4 81.2 12.8 36.7 59 126.7 107.2 125.2 25.2-.6 43-17.9 75.8-17.9 31.8 0 48.3 17.9 76.4 17.9 48.6-.7 90.4-82.5 102.6-119.3-65.2-30.7-61.7-90-61.7-91.9zm-56.6-164.2c27.3-32.4 24.8-61.9 24-72.5-24.1 1.4-52 16.4-67.9 34.9-17.5 19.8-27.8 44.3-25.6 71.9 26.1 2 49.9-11.4 69.5-34.3z"],"apple-pay":[640,512,[],"f415","M116.9 158.5c-7.5 8.9-19.5 15.9-31.5 14.9-1.5-12 4.4-24.8 11.3-32.6 7.5-9.1 20.6-15.6 31.3-16.1 1.2 12.4-3.7 24.7-11.1 33.8m10.9 17.2c-17.4-1-32.3 9.9-40.5 9.9-8.4 0-21-9.4-34.8-9.1-17.9.3-34.5 10.4-43.6 26.5-18.8 32.3-4.9 80 13.3 106.3 8.9 13 19.5 27.3 33.5 26.8 13.3-.5 18.5-8.6 34.5-8.6 16.1 0 20.8 8.6 34.8 8.4 14.5-.3 23.6-13 32.5-26 10.1-14.8 14.3-29.1 14.5-29.9-.3-.3-28-10.9-28.3-42.9-.3-26.8 21.9-39.5 22.9-40.3-12.5-18.6-32-20.6-38.8-21.1m100.4-36.2v194.9h30.3v-66.6h41.9c38.3 0 65.1-26.3 65.1-64.3s-26.4-64-64.1-64h-73.2zm30.3 25.5h34.9c26.3 0 41.3 14 41.3 38.6s-15 38.8-41.4 38.8h-34.8V165zm162.2 170.9c19 0 36.6-9.6 44.6-24.9h.6v23.4h28v-97c0-28.1-22.5-46.3-57.1-46.3-32.1 0-55.9 18.4-56.8 43.6h27.3c2.3-12 13.4-19.9 28.6-19.9 18.5 0 28.9 8.6 28.9 24.5v10.8l-37.8 2.3c-35.1 2.1-54.1 16.5-54.1 41.5.1 25.2 19.7 42 47.8 42zm8.2-23.1c-16.1 0-26.4-7.8-26.4-19.6 0-12.3 9.9-19.4 28.8-20.5l33.6-2.1v11c0 18.2-15.5 31.2-36 31.2zm102.5 74.6c29.5 0 43.4-11.3 55.5-45.4L640 193h-30.8l-35.6 115.1h-.6L537.4 193h-31.6L557 334.9l-2.8 8.6c-4.6 14.6-12.1 20.3-25.5 20.3-2.4 0-7-.3-8.9-.5v23.4c1.8.4 9.3.7 11.6.7z"],asymmetrik:[576,512,[],"f372","M517.5 309.2c38.8-40 58.1-80 58.5-116.1.8-65.5-59.4-118.2-169.4-135C277.9 38.4 118.1 73.6 0 140.5 52 114 110.6 92.3 170.7 82.3c74.5-20.5 153-25.4 221.3-14.8C544.5 91.3 588.8 195 490.8 299.2c-10.2 10.8-22 21.1-35 30.6L304.9 103.4 114.7 388.9c-65.6-29.4-76.5-90.2-19.1-151.2 20.8-22.2 48.3-41.9 79.5-58.1 20-12.2 39.7-22.6 62-30.7-65.1 20.3-122.7 52.9-161.6 92.9-27.7 28.6-41.4 57.1-41.7 82.9-.5 35.1 23.4 65.1 68.4 83l-34.5 51.7h101.6l22-34.4c22.2 1 45.3 0 68.6-2.7l-22.8 37.1h135.5L340 406.3c18.6-5.3 36.9-11.5 54.5-18.7l45.9 71.8H542L468.6 349c18.5-12.1 35-25.5 48.9-39.8zm-187.6 80.5l-25-40.6-32.7 53.3c-23.4 3.5-46.7 5.1-69.2 4.4l101.9-159.3 78.7 123c-17.2 7.4-35.3 13.9-53.7 19.2z"],audible:[640,512,[],"f373","M640 199.9v54l-320 200L0 254v-54l320 200 320-200.1zm-194.5 72l47.1-29.4c-37.2-55.8-100.7-92.6-172.7-92.6-72 0-135.5 36.7-172.6 92.4h.3c2.5-2.3 5.1-4.5 7.7-6.7 89.7-74.4 219.4-58.1 290.2 36.3zm-220.1 18.8c16.9-11.9 36.5-18.7 57.4-18.7 34.4 0 65.2 18.4 86.4 47.6l45.4-28.4c-20.9-29.9-55.6-49.5-94.8-49.5-38.9 0-73.4 19.4-94.4 49zM103.6 161.1c131.8-104.3 318.2-76.4 417.5 62.1l.7 1 48.8-30.4C517.1 112.1 424.8 58.1 319.9 58.1c-103.5 0-196.6 53.5-250.5 135.6 9.9-10.5 22.7-23.5 34.2-32.6zm467 32.7z"],autoprefixer:[640,512,[],"f41c","M318.4 16l-161 480h77.5l25.4-81.4h119.5L405 496h77.5L318.4 16zm-40.3 341.9l41.2-130.4h1.5l40.9 130.4h-83.6zM640 405l-10-31.4L462.1 358l19.4 56.5L640 405zm-462.1-47L10 373.7 0 405l158.5 9.4 19.4-56.4z"],avianex:[512,512,[],"f374","M453.1 32h-312c-38.9 0-76.2 31.2-83.3 69.7L1.2 410.3C-5.9 448.8 19.9 480 58.9 480h312c38.9 0 76.2-31.2 83.3-69.7l56.7-308.5c7-38.6-18.8-69.8-57.8-69.8zm-58.2 347.3l-32 13.5-115.4-110c-14.7 10-29.2 19.5-41.7 27.1l22.1 64.2-17.9 12.7-40.6-61-52.4-48.1 15.7-15.4 58 31.1c9.3-10.5 20.8-22.6 32.8-34.9L203 228.9l-68.8-99.8 18.8-28.9 8.9-4.8L265 207.8l4.9 4.5c19.4-18.8 33.8-32.4 33.8-32.4 7.7-6.5 21.5-2.9 30.7 7.9 9 10.5 10.6 24.7 2.7 31.3-1.8 1.3-15.5 11.4-35.3 25.6l4.5 7.3 94.9 119.4-6.3 7.9z"],aviato:[640,512,[],"f421","M107.2 283.5l-19-41.8H36.1l-19 41.8H0l62.2-131.4 62.2 131.4h-17.2zm-45-98.1l-19.6 42.5h39.2l-19.6-42.5zm112.7 102.4l-62.2-131.4h17.1l45.1 96 45.1-96h17l-62.1 131.4zm80.6-4.3V156.4H271v127.1h-15.5zm209.1-115.6v115.6h-17.3V167.9h-41.2v-11.5h99.6v11.5h-41.1zM640 218.8c0 9.2-1.7 17.8-5.1 25.8-3.4 8-8.2 15.1-14.2 21.1-6 6-13.1 10.8-21.1 14.2-8 3.4-16.6 5.1-25.8 5.1s-17.8-1.7-25.8-5.1c-8-3.4-15.1-8.2-21.1-14.2-6-6-10.8-13-14.2-21.1-3.4-8-5.1-16.6-5.1-25.8s1.7-17.8 5.1-25.8c3.4-8 8.2-15.1 14.2-21.1 6-6 13-8.4 21.1-11.9 8-3.4 16.6-5.1 25.8-5.1s17.8 1.7 25.8 5.1c8 3.4 15.1 5.8 21.1 11.9 6 6 10.7 13.1 14.2 21.1 3.4 8 5.1 16.6 5.1 25.8zm-15.5 0c0-7.3-1.3-14-3.9-20.3-2.6-6.3-6.2-11.7-10.8-16.3-4.6-4.6-10-8.2-16.2-10.9-6.2-2.7-12.8-4-19.8-4s-13.6 1.3-19.8 4c-6.2 2.7-11.6 6.3-16.2 10.9-4.6 4.6-8.2 10-10.8 16.3-2.6 6.3-3.9 13.1-3.9 20.3 0 7.3 1.3 14 3.9 20.3 2.6 6.3 6.2 11.7 10.8 16.3 4.6 4.6 10 8.2 16.2 10.9 6.2 2.7 12.8 4 19.8 4s13.6-1.3 19.8-4c6.2-2.7 11.6-6.3 16.2-10.9 4.6-4.6 8.2-10 10.8-16.3 2.6-6.3 3.9-13.1 3.9-20.3zm-94.8 96.7v-6.3l88.9-10-242.9 13.4c.6-2.2 1.1-4.6 1.4-7.2.3-2 .5-4.2.6-6.5l64.8-8.1-64.9 1.9c0-.4-.1-.7-.1-1.1-2.8-17.2-25.5-23.7-25.5-23.7l-1.1-26.3h23.8l19 41.8h17.1L348.6 152l-62.2 131.4h17.1l19-41.8h23.6L345 268s-22.7 6.5-25.5 23.7c-.1.3-.1.7-.1 1.1l-64.9-1.9 64.8 8.1c.1 2.3.3 4.4.6 6.5.3 2.6.8 5 1.4 7.2L78.4 299.2l88.9 10v6.3c-5.9.9-10.5 6-10.5 12.2 0 6.8 5.6 12.4 12.4 12.4 6.8 0 12.4-5.6 12.4-12.4 0-6.2-4.6-11.3-10.5-12.2v-5.8l80.3 9v5.4c-5.7 1.1-9.9 6.2-9.9 12.1 0 6.8 5.6 10.2 12.4 10.2 6.8 0 12.4-3.4 12.4-10.2 0-6-4.3-11-9.9-12.1v-4.9l28.4 3.2v23.7h-5.9V360h5.9v-6.6h5v6.6h5.9v-13.8h-5.9V323l38.3 4.3c8.1 11.4 19 13.6 19 13.6l-.1 6.7-5.1.2-.1 12.1h4.1l.1-5h5.2l.1 5h4.1l-.1-12.1-5.1-.2-.1-6.7s10.9-2.1 19-13.6l38.3-4.3v23.2h-5.9V360h5.9v-6.6h5v6.6h5.9v-13.8h-5.9v-23.7l28.4-3.2v4.9c-5.7 1.1-9.9 6.2-9.9 12.1 0 6.8 5.6 10.2 12.4 10.2 6.8 0 12.4-3.4 12.4-10.2 0-6-4.3-11-9.9-12.1v-5.4l80.3-9v5.8c-5.9.9-10.5 6-10.5 12.2 0 6.8 5.6 12.4 12.4 12.4 6.8 0 12.4-5.6 12.4-12.4-.2-6.3-4.7-11.4-10.7-12.3zm-200.8-87.6l19.6-42.5 19.6 42.5h-17.9l-1.7-40.3-1.7 40.3h-17.9z"],aws:[512,512,[],"f375","M261.2 136.1c-14 57.5-13.1 54.4-25.8 107-1.6 6.5-4.1 8.4-10.7 8.5h-14.4c-5.8-.1-8.2-1.6-9.9-7.3-12.3-39.4-28.8-94.1-39.9-130.7-4.1-13.5-1.4-13.2 9.3-12.9 3.7.1 7.3 0 11 0 5.1.1 7.7 2 9.1 7.1 3.6 12.9 6 22.8 26.6 104.1.4 1.6.9 3.1 1.4 4.6h1.1c.5-2 1.1-3.9 1.6-5.9 7.8-32.9 15.5-65.9 23.3-98.8 2.4-10.2 6.7-11.2 17-11.2h7.6c6.9.1 9 1.5 10.7 8.3 6 23.4 23.5 101.8 26.7 110.4 5.1-18.3-1.8 7.9 28.5-109 2.1-8.1 4.1-9.7 12.3-9.7h12.7c5.4.1 7 1.8 5.7 7.1-2.4 9.5-2.9 9.9-41.3 132.9-3.1 9.9-4.2 10.8-14.6 10.8h-10.6c-7.3 0-9.2-1.3-11-8.4-4.3-16.2-23.3-95.7-26.4-106.9zM125.4 247.3c4.2 5.8 8.1 6.3 14.1 2.4l6.3-4.2c6.8-4.5 7.3-6.3 3.6-13.5-4.3-8.4-6.4-17.3-6.3-26.9 0-3.1.6-55.7-.9-66.8-2.7-19.3-12.5-32.8-31.7-38.7-10.7-3.4-21.7-3.3-32.7-3-15.1.4-29.4 4.6-42.8 11.4-1.8.9-3.7 3.1-4.1 4.9-.8 3.9-1.1 8.1-.7 12.1.6 5.9 2.6 7 8.2 5.1 5.1-1.7 10-3.9 15.1-5.4 14.5-4.4 29.2-6.4 44.1-1.7 7.1 2.2 11.7 6.9 14.3 13.8 3 7.9 2.4 16.1 2.4 24.2 0 5.5-.1 5.5-5.5 4.5-13.9-2.6-27.7-5-41.9-3.1-15.2 2.1-28.6 7.3-38.2 20-9.1 12-10 25.6-7.4 39.5 2.8 15 11.8 25.7 26.4 30.4 20.6 6.7 40.1 3.3 57.7-9.5 3.8-2.8 7.2-6.2 11.1-9.5 3.1 5 5.8 9.7 8.9 14zm-15.3-61.6c3 .4 4.5 1.9 4.3 5.1-.2 3.8.1 7.6-.3 11.4-1.2 11.7-7.7 19.7-17.9 24.9-8.2 4.2-16.9 5.8-26.1 5-15.2-1.3-21-13.1-19.6-26.3C51.8 193.2 59 186.2 72 184c13.8-2.4 16-1.1 38.1 1.7zm348.8 65.1c21.3-8.6 32.9-26.2 29.2-50-2.2-14.6-11.8-24.2-25.2-29.5-14.7-5.9-33.8-10.3-48.1-18.2-4.4-2.4-7.4-6.3-7.6-11.9-.4-11.1 4.2-17.2 15.4-19.8 9.3-2.1 18.8-2.2 28.1-.4 7.3 1.4 14.3 4.2 21.4 6.3 2.8.9 5.9 2.1 7.8-1.6 3.8-7.3.4-18.7-7.3-21.8-22.5-9-45.5-11.6-68.2-1.6-14.6 6.4-24.6 17.4-26 34.2-1.6 19.3 6.9 33.4 24.1 41.7 7.7 3.7 16.1 5.9 24.2 8.9 8.1 3 16.2 5.8 24.1 9.1 12.3 5.3 11.6 24.2 1.2 30-27.7 15.3-64.9-2.4-69.2-3.8-3.3-1.1-5.3.2-6.3 3.7-3 11.3.7 18.8 11.6 22.7 21.7 7.9 49.6 10.5 70.8 2zM296 413.5c50.8-5.8 98.7-20.8 142.7-47 8-4.7 15.5-10.3 23.1-15.7 7.3-5.2 3.2-18.4-11.3-12.2-54.4 23.2-111.2 36.1-170.2 38.9-30.5 1.5-60.8-.3-91.1-4.7-63.1-9.2-122.4-29.2-177.6-61.2-2.1-1.2-4.2-2.5-6.5-3-4.9-1.1-7.7 4.7-2.4 9.7 24 22.1 50.3 40.8 79.1 55.7 53.7 27.7 110.5 42.7 171.2 42 14.4-.8 28.8-.9 43-2.5zm174.7-92.2c14.8.8 19.4 5.9 15.7 20.2-3.8 14.8-9.3 29.2-13.9 43.8-.9 2.9-4.2 6.3-.8 8.8 3.7 2.6 6.5-1 9-3.3 10.2-9.5 17.4-21 22.5-33.8 5.4-13.4 9.3-27.2 8.7-41.9-.2-6.2-1.8-8.8-7.8-10.5-5.4-1.5-11-2.8-16.5-3.2-21.6-1.8-42.5.5-62 10.6-3.1 1.6-6 3.7-8.7 5.9-1.1.9-3.2 5.3 2.4 6.1 1.9.3 3.9-.1 5.9-.3 16.9-1.6 28.6-3.3 45.5-2.4z"],bandcamp:[496,512,[],"f2d5","M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm48.2 326.1h-181L199.9 178h181l-84.7 156.1z"],behance:[576,512,[],"f1b4","M232 237.2c31.8-15.2 48.4-38.2 48.4-74 0-70.6-52.6-87.8-113.3-87.8H0v354.4h171.8c64.4 0 124.9-30.9 124.9-102.9 0-44.5-21.1-77.4-64.7-89.7zM77.9 135.9H151c28.1 0 53.4 7.9 53.4 40.5 0 30.1-19.7 42.2-47.5 42.2h-79v-82.7zm83.3 233.7H77.9V272h84.9c34.3 0 56 14.3 56 50.6 0 35.8-25.9 47-57.6 47zm358.5-240.7H376V94h143.7v34.9zM576 305.2c0-75.9-44.4-139.2-124.9-139.2-78.2 0-131.3 58.8-131.3 135.8 0 79.9 50.3 134.7 131.3 134.7 61.3 0 101-27.6 120.1-86.3H509c-6.7 21.9-34.3 33.5-55.7 33.5-41.3 0-63-24.2-63-65.3h185.1c.3-4.2.6-8.7.6-13.2zM390.4 274c2.3-33.7 24.7-54.8 58.5-54.8 35.4 0 53.2 20.8 56.2 54.8H390.4z"],"behance-square":[448,512,[],"f1b5","M186.5 293c0 19.3-14 25.4-31.2 25.4h-45.1v-52.9h46c18.6.1 30.3 7.8 30.3 27.5zm-7.7-82.3c0-17.7-13.7-21.9-28.9-21.9h-39.6v44.8H153c15.1 0 25.8-6.6 25.8-22.9zm132.3 23.2c-18.3 0-30.5 11.4-31.7 29.7h62.2c-1.7-18.5-11.3-29.7-30.5-29.7zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM271.7 185h77.8v-18.9h-77.8V185zm-43 110.3c0-24.1-11.4-44.9-35-51.6 17.2-8.2 26.2-17.7 26.2-37 0-38.2-28.5-47.5-61.4-47.5H68v192h93.1c34.9-.2 67.6-16.9 67.6-55.9zM380 280.5c0-41.1-24.1-75.4-67.6-75.4-42.4 0-71.1 31.8-71.1 73.6 0 43.3 27.3 73 71.1 73 33.2 0 54.7-14.9 65.1-46.8h-33.7c-3.7 11.9-18.6 18.1-30.2 18.1-22.4 0-34.1-13.1-34.1-35.3h100.2c.1-2.3.3-4.8.3-7.2z"],bimobject:[448,512,[],"f378","M416 32H32C14.4 32 0 46.4 0 64v384c0 17.6 14.4 32 32 32h384c17.6 0 32-14.4 32-32V64c0-17.6-14.4-32-32-32zm-64 257.4c0 49.4-11.4 82.6-103.8 82.6h-16.9c-44.1 0-62.4-14.9-70.4-38.8h-.9V368H96V136h64v74.7h1.1c4.6-30.5 39.7-38.8 69.7-38.8h17.3c92.4 0 103.8 33.1 103.8 82.5v35zm-64-28.9v22.9c0 21.7-3.4 33.8-38.4 33.8h-45.3c-28.9 0-44.1-6.5-44.1-35.7v-19c0-29.3 15.2-35.7 44.1-35.7h45.3c35-.2 38.4 12 38.4 33.7z"],bitbucket:[512,512,[],"f171","M23.1 32C14.2 31.9 7 38.9 6.9 47.8c0 .9.1 1.8.2 2.8L74.9 462c1.7 10.4 10.7 18 21.2 18.1h325.1c7.9.1 14.7-5.6 16-13.4l67.8-416c1.4-8.7-4.5-16.9-13.2-18.3-.9-.1-1.8-.2-2.8-.2L23.1 32zm285.3 297.3H204.6l-28.1-146.8h157l-25.1 146.8z"],bitcoin:[512,512,[],"f379","M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-141.651-35.33c4.937-32.999-20.191-50.739-54.55-62.573l11.146-44.702-27.213-6.781-10.851 43.524c-7.154-1.783-14.502-3.464-21.803-5.13l10.929-43.81-27.198-6.781-11.153 44.686c-5.922-1.349-11.735-2.682-17.377-4.084l.031-.14-37.53-9.37-7.239 29.062s20.191 4.627 19.765 4.913c11.022 2.751 13.014 10.044 12.68 15.825l-12.696 50.925c.76.194 1.744.473 2.829.907-.907-.225-1.876-.473-2.876-.713l-17.796 71.338c-1.349 3.348-4.767 8.37-12.471 6.464.271.395-19.78-4.937-19.78-4.937l-13.51 31.147 35.414 8.827c6.588 1.651 13.045 3.379 19.4 5.006l-11.262 45.213 27.182 6.781 11.153-44.733a1038.209 1038.209 0 0 0 21.687 5.627l-11.115 44.523 27.213 6.781 11.262-45.128c46.404 8.781 81.299 5.239 95.986-36.727 11.836-33.79-.589-53.281-25.004-65.991 17.78-4.098 31.174-15.792 34.747-39.949zm-62.177 87.179c-8.41 33.79-65.308 15.523-83.755 10.943l14.944-59.899c18.446 4.603 77.6 13.717 68.811 48.956zm8.417-87.667c-7.673 30.736-55.031 15.12-70.393 11.292l13.548-54.327c15.363 3.828 64.836 10.973 56.845 43.035z"],bity:[496,512,[],"f37a","M78.4 67.2C173.8-22 324.5-24 421.5 71c14.3 14.1-6.4 37.1-22.4 21.5-84.8-82.4-215.8-80.3-298.9-3.2-16.3 15.1-36.5-8.3-21.8-22.1zm98.9 418.6c19.3 5.7 29.3-23.6 7.9-30C73 421.9 9.4 306.1 37.7 194.8c5-19.6-24.9-28.1-30.2-7.1-32.1 127.4 41.1 259.8 169.8 298.1zm148.1-2c121.9-40.2 192.9-166.9 164.4-291-4.5-19.7-34.9-13.8-30 7.9 24.2 107.7-37.1 217.9-143.2 253.4-21.2 7-10.4 36 8.8 29.7zm-62.9-79l.2-71.8c0-8.2-6.6-14.8-14.8-14.8-8.2 0-14.8 6.7-14.8 14.8l-.2 71.8c0 8.2 6.6 14.8 14.8 14.8s14.8-6.6 14.8-14.8zm71-269c2.1 90.9 4.7 131.9-85.5 132.5-92.5-.7-86.9-44.3-85.5-132.5 0-21.8-32.5-19.6-32.5 0v71.6c0 69.3 60.7 90.9 118 90.1 57.3.8 118-20.8 118-90.1v-71.6c0-19.6-32.5-21.8-32.5 0z"],"black-tie":[448,512,[],"f27e","M0 32v448h448V32H0zm316.5 325.2L224 445.9l-92.5-88.7 64.5-184-64.5-86.6h184.9L252 173.2l64.5 184z"],blackberry:[512,512,[],"f37b","M166 116.9c0 23.4-16.4 49.1-72.5 49.1H23.4l21-88.8h67.8c42.1 0 53.8 23.3 53.8 39.7zm126.2-39.7h-67.8L205.7 166h70.1c53.8 0 70.1-25.7 70.1-49.1.1-16.4-11.6-39.7-53.7-39.7zM88.8 208.1H21L0 296.9h70.1c56.1 0 72.5-23.4 72.5-49.1 0-16.3-11.7-39.7-53.8-39.7zm180.1 0h-67.8l-18.7 88.8h70.1c53.8 0 70.1-23.4 70.1-49.1 0-16.3-11.7-39.7-53.7-39.7zm189.3-53.8h-67.8l-18.7 88.8h70.1c53.8 0 70.1-23.4 70.1-49.1.1-16.3-11.6-39.7-53.7-39.7zm-28 137.9h-67.8L343.7 381h70.1c56.1 0 70.1-23.4 70.1-49.1 0-16.3-11.6-39.7-53.7-39.7zM240.8 346H173l-18.7 88.8h70.1c56.1 0 70.1-25.7 70.1-49.1.1-16.3-11.6-39.7-53.7-39.7z"],blogger:[448,512,[],"f37c","M162.4 196c4.8-4.9 6.2-5.1 36.4-5.1 27.2 0 28.1.1 32.1 2.1 5.8 2.9 8.3 7 8.3 13.6 0 5.9-2.4 10-7.6 13.4-2.8 1.8-4.5 1.9-31.1 2.1-16.4.1-29.5-.2-31.5-.8-10.3-2.9-14.1-17.7-6.6-25.3zm61.4 94.5c-53.9 0-55.8.2-60.2 4.1-3.5 3.1-5.7 9.4-5.1 13.9.7 4.7 4.8 10.1 9.2 12 2.2 1 14.1 1.7 56.3 1.2l47.9-.6 9.2-1.5c9-5.1 10.5-17.4 3.1-24.4-5.3-4.7-5-4.7-60.4-4.7zm223.4 130.1c-3.5 28.4-23 50.4-51.1 57.5-7.2 1.8-9.7 1.9-172.9 1.8-157.8 0-165.9-.1-172-1.8-8.4-2.2-15.6-5.5-22.3-10-5.6-3.8-13.9-11.8-17-16.4-3.8-5.6-8.2-15.3-10-22C.1 423 0 420.3 0 256.3 0 93.2 0 89.7 1.8 82.6 8.1 57.9 27.7 39 53 33.4c7.3-1.6 332.1-1.9 340-.3 21.2 4.3 37.9 17.1 47.6 36.4 7.7 15.3 7-1.5 7.3 180.6.2 115.8 0 164.5-.7 170.5zm-85.4-185.2c-1.1-5-4.2-9.6-7.7-11.5-1.1-.6-8-1.3-15.5-1.7-12.4-.6-13.8-.8-17.8-3.1-6.2-3.6-7.9-7.6-8-18.3 0-20.4-8.5-39.4-25.3-56.5-12-12.2-25.3-20.5-40.6-25.1-3.6-1.1-11.8-1.5-39.2-1.8-42.9-.5-52.5.4-67.1 6.2-27 10.7-46.3 33.4-53.4 62.4-1.3 5.4-1.6 14.2-1.9 64.3-.4 62.8 0 72.1 4 84.5 9.7 30.7 37.1 53.4 64.6 58.4 9.2 1.7 122.2 2.1 133.7.5 20.1-2.7 35.9-10.8 50.7-25.9 10.7-10.9 17.4-22.8 21.8-38.5 3.2-10.9 2.9-88.4 1.7-93.9z"],"blogger-b":[448,512,[],"f37d","M446.6 222.7c-1.8-8-6.8-15.4-12.5-18.5-1.8-1-13-2.2-25-2.7-20.1-.9-22.3-1.3-28.7-5-10.1-5.9-12.8-12.3-12.9-29.5-.1-33-13.8-63.7-40.9-91.3-19.3-19.7-40.9-33-65.5-40.5-5.9-1.8-19.1-2.4-63.3-2.9-69.4-.8-84.8.6-108.4 10C45.9 59.5 14.7 96.1 3.3 142.9 1.2 151.7.7 165.8.2 246.8c-.6 101.5.1 116.4 6.4 136.5 15.6 49.6 59.9 86.3 104.4 94.3 14.8 2.7 197.3 3.3 216 .8 32.5-4.4 58-17.5 81.9-41.9 17.3-17.7 28.1-36.8 35.2-62.1 4.9-17.6 4.5-142.8 2.5-151.7zm-322.1-63.6c7.8-7.9 10-8.2 58.8-8.2 43.9 0 45.4.1 51.8 3.4 9.3 4.7 13.4 11.3 13.4 21.9 0 9.5-3.8 16.2-12.3 21.6-4.6 2.9-7.3 3.1-50.3 3.3-26.5.2-47.7-.4-50.8-1.2-16.6-4.7-22.8-28.5-10.6-40.8zm191.8 199.8l-14.9 2.4-77.5.9c-68.1.8-87.3-.4-90.9-2-7.1-3.1-13.8-11.7-14.9-19.4-1.1-7.3 2.6-17.3 8.2-22.4 7.1-6.4 10.2-6.6 97.3-6.7 89.6-.1 89.1-.1 97.6 7.8 12.1 11.3 9.5 31.2-4.9 39.4z"],bluetooth:[448,512,[],"f293","M292.6 171.1L249.7 214l-.3-86 43.2 43.1m-43.2 219.8l43.1-43.1-42.9-42.9-.2 86zM416 259.4C416 465 344.1 512 230.9 512S32 465 32 259.4 115.4 0 228.6 0 416 53.9 416 259.4zm-158.5 0l79.4-88.6L211.8 36.5v176.9L138 139.6l-27 26.9 92.7 93-92.7 93 26.9 26.9 73.8-73.8 2.3 170 127.4-127.5-83.9-88.7z"],"bluetooth-b":[320,512,[],"f294","M196.48 260.023l92.626-103.333L143.125 0v206.33l-86.111-86.111-31.406 31.405 108.061 108.399L25.608 368.422l31.406 31.405 86.111-86.111L145.84 512l148.552-148.644-97.912-103.333zm40.86-102.996l-49.977 49.978-.338-100.295 50.315 50.317zM187.363 313.04l49.977 49.978-50.315 50.316.338-100.294z"],btc:[384,512,[],"f15a","M310.204 242.638c27.73-14.18 45.377-39.39 41.28-81.3-5.358-57.351-52.458-76.573-114.85-81.929V0h-48.528v77.203c-12.605 0-25.525.315-38.444.63V0h-48.528v79.409c-17.842.539-38.622.276-97.37 0v51.678c38.314-.678 58.417-3.14 63.023 21.427v217.429c-2.925 19.492-18.524 16.685-53.255 16.071L3.765 443.68c88.481 0 97.37.315 97.37.315V512h48.528v-67.06c13.234.315 26.154.315 38.444.315V512h48.528v-68.005c81.299-4.412 135.647-24.894 142.895-101.467 5.671-61.446-23.32-88.862-69.326-99.89zM150.608 134.553c27.415 0 113.126-8.507 113.126 48.528 0 54.515-85.71 48.212-113.126 48.212v-96.74zm0 251.776V279.821c32.772 0 133.127-9.138 133.127 53.255-.001 60.186-100.355 53.253-133.127 53.253z"],buromobelexperte:[448,512,[],"f37f","M0 32v128h128V32H0zm120 120H8V40h112v112zm40-120v128h128V32H160zm120 120H168V40h112v112zm40-120v128h128V32H320zm120 120H328V40h112v112zM0 192v128h128V192H0zm120 120H8V200h112v112zm40-120v128h128V192H160zm120 120H168V200h112v112zm40-120v128h128V192H320zm120 120H328V200h112v112zM0 352v128h128V352H0zm120 120H8V360h112v112zm40-120v128h128V352H160zm120 120H168V360h112v112zm40-120v128h128V352H320z"],buysellads:[448,512,[],"f20d","M224 150.7l42.9 160.7h-85.8L224 150.7zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-65.3 325.3l-94.5-298.7H159.8L65.3 405.3H156l111.7-91.6 24.2 91.6h90.8z"],"cc-amazon-pay":[576,512,[],"f42d","M124.7 201.8c.1-11.8 0-23.5 0-35.3v-35.3c0-1.3.4-2 1.4-2.7 11.5-8 24.1-12.1 38.2-11.1 12.5.9 22.7 7 28.1 21.7 3.3 8.9 4.1 18.2 4.1 27.7 0 8.7-.7 17.3-3.4 25.6-5.7 17.8-18.7 24.7-35.7 23.9-11.7-.5-21.9-5-31.4-11.7-.9-.8-1.4-1.6-1.3-2.8zm154.9 14.6c4.6 1.8 9.3 2 14.1 1.5 11.6-1.2 21.9-5.7 31.3-12.5.9-.6 1.3-1.3 1.3-2.5-.1-3.9 0-7.9 0-11.8 0-4-.1-8 0-12 0-1.4-.4-2-1.8-2.2-7-.9-13.9-2.2-20.9-2.9-7-.6-14-.3-20.8 1.9-6.7 2.2-11.7 6.2-13.7 13.1-1.6 5.4-1.6 10.8.1 16.2 1.6 5.5 5.2 9.2 10.4 11.2zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zm-207.5 23.9c.4 1.7.9 3.4 1.6 5.1 16.5 40.6 32.9 81.3 49.5 121.9 1.4 3.5 1.7 6.4.2 9.9-2.8 6.2-4.9 12.6-7.8 18.7-2.6 5.5-6.7 9.5-12.7 11.2-4.2 1.1-8.5 1.3-12.9.9-2.1-.2-4.2-.7-6.3-.8-2.8-.2-4.2 1.1-4.3 4-.1 2.8-.1 5.6 0 8.3.1 4.6 1.6 6.7 6.2 7.5 4.7.8 9.4 1.6 14.2 1.7 14.3.3 25.7-5.4 33.1-17.9 2.9-4.9 5.6-10.1 7.7-15.4 19.8-50.1 39.5-100.3 59.2-150.5.6-1.5 1.1-3 1.3-4.6.4-2.4-.7-3.6-3.1-3.7-5.6-.1-11.1 0-16.7 0-3.1 0-5.3 1.4-6.4 4.3-.4 1.1-.9 2.3-1.3 3.4l-29.1 83.7c-2.1 6.1-4.2 12.1-6.5 18.6-.4-.9-.6-1.4-.8-1.9-10.8-29.9-21.6-59.9-32.4-89.8-1.7-4.7-3.5-9.5-5.3-14.2-.9-2.5-2.7-4-5.4-4-6.4-.1-12.8-.2-19.2-.1-2.2 0-3.3 1.6-2.8 3.7zM242.4 206c1.7 11.7 7.6 20.8 18 26.6 9.9 5.5 20.7 6.2 31.7 4.6 12.7-1.9 23.9-7.3 33.8-15.5.4-.3.8-.6 1.4-1 .5 3.2.9 6.2 1.5 9.2.5 2.6 2.1 4.3 4.5 4.4 4.6.1 9.1.1 13.7 0 2.3-.1 3.8-1.6 4-3.9.1-.8.1-1.6.1-2.3v-88.8c0-3.6-.2-7.2-.7-10.8-1.6-10.8-6.2-19.7-15.9-25.4-5.6-3.3-11.8-5-18.2-5.9-3-.4-6-.7-9.1-1.1h-10c-.8.1-1.6.3-2.5.3-8.2.4-16.3 1.4-24.2 3.5-5.1 1.3-10 3.2-15 4.9-3 1-4.5 3.2-4.4 6.5.1 2.8-.1 5.6 0 8.3.1 4.1 1.8 5.2 5.7 4.1 6.5-1.7 13.1-3.5 19.7-4.8 10.3-1.9 20.7-2.7 31.1-1.2 5.4.8 10.5 2.4 14.1 7 3.1 4 4.2 8.8 4.4 13.7.3 6.9.2 13.9.3 20.8 0 .4-.1.7-.2 1.2-.4 0-.8 0-1.1-.1-8.8-2.1-17.7-3.6-26.8-4.1-9.5-.5-18.9.1-27.9 3.2-10.8 3.8-19.5 10.3-24.6 20.8-4.1 8.3-4.6 17-3.4 25.8zM98.7 106.9v175.3c0 .8 0 1.7.1 2.5.2 2.5 1.7 4.1 4.1 4.2 5.9.1 11.8.1 17.7 0 2.5 0 4-1.7 4.1-4.1.1-.8.1-1.7.1-2.5v-60.7c.9.7 1.4 1.2 1.9 1.6 15 12.5 32.2 16.6 51.1 12.9 17.1-3.4 28.9-13.9 36.7-29.2 5.8-11.6 8.3-24.1 8.7-37 .5-14.3-1-28.4-6.8-41.7-7.1-16.4-18.9-27.3-36.7-30.9-2.7-.6-5.5-.8-8.2-1.2h-7c-1.2.2-2.4.3-3.6.5-11.7 1.4-22.3 5.8-31.8 12.7-2 1.4-3.9 3-5.9 4.5-.1-.5-.3-.8-.4-1.2-.4-2.3-.7-4.6-1.1-6.9-.6-3.9-2.5-5.5-6.4-5.6h-9.7c-5.9-.1-6.9 1-6.9 6.8zM493.6 339c-2.7-.7-5.1 0-7.6 1-43.9 18.4-89.5 30.2-136.8 35.8-14.5 1.7-29.1 2.8-43.7 3.2-26.6.7-53.2-.8-79.6-4.3-17.8-2.4-35.5-5.7-53-9.9-37-8.9-72.7-21.7-106.7-38.8-8.8-4.4-17.4-9.3-26.1-14-3.8-2.1-6.2-1.5-8.2 2.1v1.7c1.2 1.6 2.2 3.4 3.7 4.8 36 32.2 76.6 56.5 122 72.9 21.9 7.9 44.4 13.7 67.3 17.5 14 2.3 28 3.8 42.2 4.5 3 .1 6 .2 9 .4.7 0 1.4.2 2.1.3h17.7c.7-.1 1.4-.3 2.1-.3 14.9-.4 29.8-1.8 44.6-4 21.4-3.2 42.4-8.1 62.9-14.7 29.6-9.6 57.7-22.4 83.4-40.1 2.8-1.9 5.7-3.8 8-6.2 4.3-4.4 2.3-10.4-3.3-11.9zm50.4-27.7c-.8-4.2-4-5.8-7.6-7-5.7-1.9-11.6-2.8-17.6-3.3-11-.9-22-.4-32.8 1.6-12 2.2-23.4 6.1-33.5 13.1-1.2.8-2.4 1.8-3.1 3-.6.9-.7 2.3-.5 3.4.3 1.3 1.7 1.6 3 1.5.6 0 1.2 0 1.8-.1l19.5-2.1c9.6-.9 19.2-1.5 28.8-.8 4.1.3 8.1 1.2 12 2.2 4.3 1.1 6.2 4.4 6.4 8.7.3 6.7-1.2 13.1-2.9 19.5-3.5 12.9-8.3 25.4-13.3 37.8-.3.8-.7 1.7-.8 2.5-.4 2.5 1 4 3.4 3.5 1.4-.3 3-1.1 4-2.1 3.7-3.6 7.5-7.2 10.6-11.2 10.7-13.8 17-29.6 20.7-46.6.7-3 1.2-6.1 1.7-9.1.2-4.7.2-9.6.2-14.5z"],"cc-amex":[576,512,[],"f1f3","M576 255.4c-37.9-.2-44.2-.9-54.5 5v-5c-45.3 0-53.5-1.7-64.9 5.2v-5.2h-78.2v5.1c-11.4-6.5-21.4-5.1-75.7-5.1v5.6c-6.3-3.7-14.5-5.6-24.3-5.6h-58c-3.5 3.8-12.5 13.7-15.7 17.2-12.7-14.1-10.5-11.6-15.5-17.2h-83.1v92.3h82c3.3-3.5 12.9-13.9 16.1-17.4 12.7 14.3 10.3 11.7 15.4 17.4h48.9c0-14.7.1-8.3.1-23 11.5.2 24.3-.2 34.3-6.2 0 13.9-.1 17.1-.1 29.2h39.6c0-18.5.1-7.4.1-25.3 6.2 0 7.7 0 9.4.1.1 1.3 0 0 0 25.2 152.8 0 145.9 1.1 156.7-4.5v4.5c34.8 0 54.8 2.2 67.5-6.1V432c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V228.3h26.6c4.2-10.1 2.2-5.3 6.4-15.3h19.2c4.2 10 2.2 5.2 6.4 15.3h52.9v-11.4c2.2 5 1.1 2.5 5.1 11.4h29.5c2.4-5.5 2.6-5.8 5.1-11.4v11.4h135.5v-25.1c6.4 0 8-.1 9.8.2 0 0-.2 10.9.1 24.8h66.5v-8.9c7.4 5.9 17.4 8.9 29.7 8.9h26.8c4.2-10.1 2.2-5.3 6.4-15.3h19c6.5 15 .2.5 6.6 15.3h52.8v-21.9c11.8 19.7 7.8 12.9 13.2 21.9h41.6v-92h-39.9v18.4c-12.2-20.2-6.3-10.4-11.2-18.4h-43.3v20.6c-6.2-14.6-4.6-10.8-8.8-20.6h-32.4c-.4 0-2.3.2-2.3-.3h-27.6c-12.8 0-23.1 3.2-30.7 9.3v-9.3h-39.9v5.3c-10.8-6.1-20.7-5.1-64.4-5.3-.1 0-11.6-.1-11.6 0h-103c-2.5 6.1-6.8 16.4-12.6 30-2.8-6-11-23.8-13.9-30h-46V157c-7.4-17.4-4.7-11-9-21.1H22.9c-3.4 7.9-13.7 32-23.1 53.9V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48v175.4zm-186.6-80.6c-.3.2-1.4 2.2-1.4 7.6 0 6 .9 7.7 1.1 7.9.2.1 1.1.5 3.4.5l7.3-16.9c-1.1 0-2.1-.1-3.1-.1-5.6 0-7 .7-7.3 1zm-19.9 130.9c9.2 3.3 11 9.5 11 18.4l-.1 13.8h-16.6l.1-11.5c0-11.8-3.8-13.8-14.8-13.8h-17.6l-.1 25.3h-16.6l.1-69.3h39.4c13 0 27.1 2.3 27.1 18.7-.1 7.6-4.2 15.3-11.9 18.4zm-6.3-15.4c0-6.4-5.6-7.4-10.7-7.4h-21v15.6h20.7c5.6 0 11-1.3 11-8.2zm181.7-7.1H575v-14.6h-32.9c-12.8 0-23.8 6.6-23.8 20.7 0 33 42.7 12.8 42.7 27.4 0 5.1-4.3 6.4-8.4 6.4h-32l-.1 14.8h32c8.4 0 17.6-1.8 22.5-8.9v-25.8c-10.5-13.8-39.3-1.3-39.3-13.5 0-5.8 4.6-6.5 9.2-6.5zm-99.2-.3v-14.3h-55.2l-.1 69.3h55.2l.1-14.3-38.6-.3v-13.8H445v-14.1h-37.8v-12.5h38.5zm42.2 40.1h-32.2l-.1 14.8h32.2c14.8 0 26.2-5.6 26.2-22 0-33.2-42.9-11.2-42.9-26.3 0-5.6 4.9-6.4 9.2-6.4h30.4v-14.6h-33.2c-12.8 0-23.5 6.6-23.5 20.7 0 33 42.7 12.5 42.7 27.4-.1 5.4-4.7 6.4-8.8 6.4zm-78.1-158.7c-17.4-.3-33.2-4.1-33.2 19.7 0 11.8 2.8 19.9 16.1 19.9h7.4l23.5-54.5h24.8l27.9 65.4v-65.4h25.3l29.1 48.1v-48.1h16.9v69H524l-31.2-51.9v51.9h-33.7l-6.6-15.3h-34.3l-6.4 15.3h-19.2c-22.8 0-33-11.8-33-34 0-23.3 10.5-35.3 34-35.3h16.1v15.2zm14.3 24.5h22.8l-11.2-27.6-11.6 27.6zm-72.6-39.6h-16.9v69.3h16.9v-69.3zm-38.1 37.3c9.5 3.3 11 9.2 11 18.4v13.5h-16.6c-.3-14.8 3.6-25.1-14.8-25.1h-18v25.1h-16.4v-69.3l39.1.3c13.3 0 27.4 2 27.4 18.4.1 8-4.3 15.7-11.7 18.7zm-6.7-15.3c0-6.4-5.6-7.4-10.7-7.4h-21v15.3h20.7c5.7 0 11-1.3 11-7.9zm-59.5-7.4v-14.6h-55.5v69.3h55.5v-14.3h-38.9v-13.8h37.8v-14.1h-37.8v-12.5h38.9zm-84.6 54.7v-54.2l-24 54.2H124l-24-54.2v54.2H66.2l-6.4-15.3H25.3l-6.4 15.3H1l29.7-69.3h24.5l28.1 65.7v-65.7h27.1l21.7 47 19.7-47h27.6v69.3h-16.8zM53.9 188.8l-11.5-27.6-11.2 27.6h22.7zm253 102.5c0 27.9-30.4 23.3-49.3 23.3l-.1 23.3h-32.2l-20.4-23-21.3 23h-65.4l.1-69.3h66.5l20.5 22.8 21-22.8H279c15.6 0 27.9 5.4 27.9 22.7zm-112.7 11.8l-17.9-20.2h-41.7v12.5h36.3v14.1h-36.3v13.8h40.6l19-20.2zM241 276l-25.3 27.4 25.3 28.1V276zm48.3 15.3c0-6.1-4.6-8.4-10.2-8.4h-21.5v17.6h21.2c5.9 0 10.5-2.8 10.5-9.2z"],"cc-apple-pay":[576,512,[],"f416","M302.2 218.4c0 17.2-10.5 27.1-29 27.1h-24.3v-54.2h24.4c18.4 0 28.9 9.8 28.9 27.1zm47.5 62.6c0 8.3 7.2 13.7 18.5 13.7 14.4 0 25.2-9.1 25.2-21.9v-7.7l-23.5 1.5c-13.3.9-20.2 5.8-20.2 14.4zM576 79v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V79c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM127.8 197.2c8.4.7 16.8-4.2 22.1-10.4 5.2-6.4 8.6-15 7.7-23.7-7.4.3-16.6 4.9-21.9 11.3-4.8 5.5-8.9 14.4-7.9 22.8zm60.6 74.5c-.2-.2-19.6-7.6-19.8-30-.2-18.7 15.3-27.7 16-28.2-8.8-13-22.4-14.4-27.1-14.7-12.2-.7-22.6 6.9-28.4 6.9-5.9 0-14.7-6.6-24.3-6.4-12.5.2-24.2 7.3-30.5 18.6-13.1 22.6-3.4 56 9.3 74.4 6.2 9.1 13.7 19.1 23.5 18.7 9.3-.4 13-6 24.2-6 11.3 0 14.5 6 24.3 5.9 10.2-.2 16.5-9.1 22.8-18.2 6.9-10.4 9.8-20.4 10-21zm135.4-53.4c0-26.6-18.5-44.8-44.9-44.8h-51.2v136.4h21.2v-46.6h29.3c26.8 0 45.6-18.4 45.6-45zm90 23.7c0-19.7-15.8-32.4-40-32.4-22.5 0-39.1 12.9-39.7 30.5h19.1c1.6-8.4 9.4-13.9 20-13.9 13 0 20.2 6 20.2 17.2v7.5l-26.4 1.6c-24.6 1.5-37.9 11.6-37.9 29.1 0 17.7 13.7 29.4 33.4 29.4 13.3 0 25.6-6.7 31.2-17.4h.4V310h19.6v-68zM516 210.9h-21.5l-24.9 80.6h-.4l-24.9-80.6H422l35.9 99.3-1.9 6c-3.2 10.2-8.5 14.2-17.9 14.2-1.7 0-4.9-.2-6.2-.3v16.4c1.2.4 6.5.5 8.1.5 20.7 0 30.4-7.9 38.9-31.8L516 210.9z"],"cc-diners-club":[576,512,[],"f24c","M239.7 79.9c-96.9 0-175.8 78.6-175.8 175.8 0 96.9 78.9 175.8 175.8 175.8 97.2 0 175.8-78.9 175.8-175.8 0-97.2-78.6-175.8-175.8-175.8zm-39.9 279.6c-41.7-15.9-71.4-56.4-71.4-103.8s29.7-87.9 71.4-104.1v207.9zm79.8.3V151.6c41.7 16.2 71.4 56.7 71.4 104.1s-29.7 87.9-71.4 104.1zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM329.7 448h-90.3c-106.2 0-193.8-85.5-193.8-190.2C45.6 143.2 133.2 64 239.4 64h90.3c105 0 200.7 79.2 200.7 193.8 0 104.7-95.7 190.2-200.7 190.2z"],"cc-discover":[576,512,[],"f1f2","M83 212.1c0 7.9-3.2 15.5-8.9 20.7-4.9 4.4-11.6 6.4-21.9 6.4H48V185h4.2c10.3 0 16.7 1.7 21.9 6.6 5.7 5 8.9 12.6 8.9 20.5zM504.8 184h-4.9v24.9h4.7c10.3 0 15.8-4.4 15.8-12.8 0-7.9-5.5-12.1-15.6-12.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM428 253h45.3v-13.8H444V217h28.3v-13.8H444V185h29.3v-14H428v82zm-86.2-82l35 84.2h8.6l35.5-84.2h-17.5l-22.2 55.2-21.9-55.2h-17.5zm-83 41.6c0 24.6 19.9 44.6 44.6 44.6 24.6 0 44.6-19.9 44.6-44.6 0-24.6-19.9-44.6-44.6-44.6-24.6 0-44.6 19.9-44.6 44.6zm-68-.5c0 32.5 33.6 52.5 63.3 38.2v-19c-19.3 19.3-46.8 5.8-46.8-19.2 0-23.7 26.7-39.1 46.8-19v-19c-30.2-15-63.3 6.8-63.3 38zm-33.9 28.3c-7.6 0-13.8-3.7-17.5-10.8l-10.3 9.9c17.8 26.1 56.6 18.2 56.6-11.3 0-13.1-5.4-19-23.6-25.6-9.6-3.4-12.3-5.9-12.3-10.3 0-8.7 14.5-14.1 24.9-2.5l8.4-10.8c-19.1-17.1-49.7-8.9-49.7 14.3 0 11.3 5.2 17.2 20.2 22.7 25.7 9.1 14.7 24.4 3.3 24.4zm-57.4-28.3c0-24.1-18-41.1-44.1-41.1H32v82h23.4c30.9 0 44.1-22.4 44.1-40.9zm23.4-41.1h-16v82h16v-82zM544 288c-33.3 20.8-226.4 124.4-416 160h401c8.2 0 15-6.8 15-15V288zm0-35l-25.9-34.5c12.1-2.5 18.7-10.6 18.7-23.2 0-28.5-30.3-24.4-52.9-24.4v82h16v-32.8h2.2l22.2 32.8H544z"],"cc-jcb":[576,512,[],"f24b","M431.5 244.3V212c41.2 0 38.5.2 38.5.2 7.3 1.3 13.3 7.3 13.3 16 0 8.8-6 14.5-13.3 15.8-1.2.4-3.3.3-38.5.3zm42.8 20.2c-2.8-.7-3.3-.5-42.8-.5v35c39.6 0 40 .2 42.8-.5 7.5-1.5 13.5-8 13.5-17 0-8.7-6-15.5-13.5-17zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM182 192.3h-57c0 67.1 10.7 109.7-35.8 109.7-19.5 0-38.8-5.7-57.2-14.8v28c30 8.3 68 8.3 68 8.3 97.9 0 82-47.7 82-131.2zm178.5 4.5c-63.4-16-165-14.9-165 59.3 0 77.1 108.2 73.6 165 59.2V287C312.9 311.7 253 309 253 256s59.8-55.6 107.5-31.2v-28zM544 286.5c0-18.5-16.5-30.5-38-32v-.8c19.5-2.7 30.3-15.5 30.3-30.2 0-19-15.7-30-37-31 0 0 6.3-.3-120.3-.3v127.5h122.7c24.3.1 42.3-12.9 42.3-33.2z"],"cc-mastercard":[576,512,[],"f1f1","M482.9 410.3c0 6.8-4.6 11.7-11.2 11.7-6.8 0-11.2-5.2-11.2-11.7 0-6.5 4.4-11.7 11.2-11.7 6.6 0 11.2 5.2 11.2 11.7zm-310.8-11.7c-7.1 0-11.2 5.2-11.2 11.7 0 6.5 4.1 11.7 11.2 11.7 6.5 0 10.9-4.9 10.9-11.7-.1-6.5-4.4-11.7-10.9-11.7zm117.5-.3c-5.4 0-8.7 3.5-9.5 8.7h19.1c-.9-5.7-4.4-8.7-9.6-8.7zm107.8.3c-6.8 0-10.9 5.2-10.9 11.7 0 6.5 4.1 11.7 10.9 11.7 6.8 0 11.2-4.9 11.2-11.7 0-6.5-4.4-11.7-11.2-11.7zm105.9 26.1c0 .3.3.5.3 1.1 0 .3-.3.5-.3 1.1-.3.3-.3.5-.5.8-.3.3-.5.5-1.1.5-.3.3-.5.3-1.1.3-.3 0-.5 0-1.1-.3-.3 0-.5-.3-.8-.5-.3-.3-.5-.5-.5-.8-.3-.5-.3-.8-.3-1.1 0-.5 0-.8.3-1.1 0-.5.3-.8.5-1.1.3-.3.5-.3.8-.5.5-.3.8-.3 1.1-.3.5 0 .8 0 1.1.3.5.3.8.3 1.1.5s.2.6.5 1.1zm-2.2 1.4c.5 0 .5-.3.8-.3.3-.3.3-.5.3-.8 0-.3 0-.5-.3-.8-.3 0-.5-.3-1.1-.3h-1.6v3.5h.8V426h.3l1.1 1.4h.8l-1.1-1.3zM576 81v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V81c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM64 220.6c0 76.5 62.1 138.5 138.5 138.5 27.2 0 53.9-8.2 76.5-23.1-72.9-59.3-72.4-171.2 0-230.5-22.6-15-49.3-23.1-76.5-23.1-76.4-.1-138.5 62-138.5 138.2zm224 108.8c70.5-55 70.2-162.2 0-217.5-70.2 55.3-70.5 162.6 0 217.5zm-142.3 76.3c0-8.7-5.7-14.4-14.7-14.7-4.6 0-9.5 1.4-12.8 6.5-2.4-4.1-6.5-6.5-12.2-6.5-3.8 0-7.6 1.4-10.6 5.4V392h-8.2v36.7h8.2c0-18.9-2.5-30.2 9-30.2 10.2 0 8.2 10.2 8.2 30.2h7.9c0-18.3-2.5-30.2 9-30.2 10.2 0 8.2 10 8.2 30.2h8.2v-23zm44.9-13.7h-7.9v4.4c-2.7-3.3-6.5-5.4-11.7-5.4-10.3 0-18.2 8.2-18.2 19.3 0 11.2 7.9 19.3 18.2 19.3 5.2 0 9-1.9 11.7-5.4v4.6h7.9V392zm40.5 25.6c0-15-22.9-8.2-22.9-15.2 0-5.7 11.9-4.8 18.5-1.1l3.3-6.5c-9.4-6.1-30.2-6-30.2 8.2 0 14.3 22.9 8.3 22.9 15 0 6.3-13.5 5.8-20.7.8l-3.5 6.3c11.2 7.6 32.6 6 32.6-7.5zm35.4 9.3l-2.2-6.8c-3.8 2.1-12.2 4.4-12.2-4.1v-16.6h13.1V392h-13.1v-11.2h-8.2V392h-7.6v7.3h7.6V416c0 17.6 17.3 14.4 22.6 10.9zm13.3-13.4h27.5c0-16.2-7.4-22.6-17.4-22.6-10.6 0-18.2 7.9-18.2 19.3 0 20.5 22.6 23.9 33.8 14.2l-3.8-6c-7.8 6.4-19.6 5.8-21.9-4.9zm59.1-21.5c-4.6-2-11.6-1.8-15.2 4.4V392h-8.2v36.7h8.2V408c0-11.6 9.5-10.1 12.8-8.4l2.4-7.6zm10.6 18.3c0-11.4 11.6-15.1 20.7-8.4l3.8-6.5c-11.6-9.1-32.7-4.1-32.7 15 0 19.8 22.4 23.8 32.7 15l-3.8-6.5c-9.2 6.5-20.7 2.6-20.7-8.6zm66.7-18.3H408v4.4c-8.3-11-29.9-4.8-29.9 13.9 0 19.2 22.4 24.7 29.9 13.9v4.6h8.2V392zm33.7 0c-2.4-1.2-11-2.9-15.2 4.4V392h-7.9v36.7h7.9V408c0-11 9-10.3 12.8-8.4l2.4-7.6zm40.3-14.9h-7.9v19.3c-8.2-10.9-29.9-5.1-29.9 13.9 0 19.4 22.5 24.6 29.9 13.9v4.6h7.9v-51.7zm7.6-75.1v4.6h.8V302h1.9v-.8h-4.6v.8h1.9zm6.6 123.8c0-.5 0-1.1-.3-1.6-.3-.3-.5-.8-.8-1.1-.3-.3-.8-.5-1.1-.8-.5 0-1.1-.3-1.6-.3-.3 0-.8.3-1.4.3-.5.3-.8.5-1.1.8-.5.3-.8.8-.8 1.1-.3.5-.3 1.1-.3 1.6 0 .3 0 .8.3 1.4 0 .3.3.8.8 1.1.3.3.5.5 1.1.8.5.3 1.1.3 1.4.3.5 0 1.1 0 1.6-.3.3-.3.8-.5 1.1-.8.3-.3.5-.8.8-1.1.3-.6.3-1.1.3-1.4zm3.2-124.7h-1.4l-1.6 3.5-1.6-3.5h-1.4v5.4h.8v-4.1l1.6 3.5h1.1l1.4-3.5v4.1h1.1v-5.4zm4.4-80.5c0-76.2-62.1-138.3-138.5-138.3-27.2 0-53.9 8.2-76.5 23.1 72.1 59.3 73.2 171.5 0 230.5 22.6 15 49.5 23.1 76.5 23.1 76.4.1 138.5-61.9 138.5-138.4z"],"cc-paypal":[576,512,[],"f1f4","M186.3 258.2c0 12.2-9.7 21.5-22 21.5-9.2 0-16-5.2-16-15 0-12.2 9.5-22 21.7-22 9.3 0 16.3 5.7 16.3 15.5zM80.5 209.7h-4.7c-1.5 0-3 1-3.2 2.7l-4.3 26.7 8.2-.3c11 0 19.5-1.5 21.5-14.2 2.3-13.4-6.2-14.9-17.5-14.9zm284 0H360c-1.8 0-3 1-3.2 2.7l-4.2 26.7 8-.3c13 0 22-3 22-18-.1-10.6-9.6-11.1-18.1-11.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM128.3 215.4c0-21-16.2-28-34.7-28h-40c-2.5 0-5 2-5.2 4.7L32 294.2c-.3 2 1.2 4 3.2 4h19c2.7 0 5.2-2.9 5.5-5.7l4.5-26.6c1-7.2 13.2-4.7 18-4.7 28.6 0 46.1-17 46.1-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.2 8.2-5.8-8.5-14.2-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9 0 20.2-4.9 26.5-11.9-.5 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H200c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm40.5 97.9l63.7-92.6c.5-.5.5-1 .5-1.7 0-1.7-1.5-3.5-3.2-3.5h-19.2c-1.7 0-3.5 1-4.5 2.5l-26.5 39-11-37.5c-.8-2.2-3-4-5.5-4h-18.7c-1.7 0-3.2 1.8-3.2 3.5 0 1.2 19.5 56.8 21.2 62.1-2.7 3.8-20.5 28.6-20.5 31.6 0 1.8 1.5 3.2 3.2 3.2h19.2c1.8-.1 3.5-1.1 4.5-2.6zm159.3-106.7c0-21-16.2-28-34.7-28h-39.7c-2.7 0-5.2 2-5.5 4.7l-16.2 102c-.2 2 1.3 4 3.2 4h20.5c2 0 3.5-1.5 4-3.2l4.5-29c1-7.2 13.2-4.7 18-4.7 28.4 0 45.9-17 45.9-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.3 8.2-5.5-8.5-14-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9.3 0 20.5-4.9 26.5-11.9-.3 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H484c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm47.5-33.3c0-2-1.5-3.5-3.2-3.5h-18.5c-1.5 0-3 1.2-3.2 2.7l-16.2 104-.3.5c0 1.8 1.5 3.5 3.5 3.5h16.5c2.5 0 5-2.9 5.2-5.7L544 191.2v-.3zm-90 51.8c-12.2 0-21.7 9.7-21.7 22 0 9.7 7 15 16.2 15 12 0 21.7-9.2 21.7-21.5.1-9.8-6.9-15.5-16.2-15.5z"],"cc-stripe":[576,512,[],"f1f5","M396.9 256.5c0 19.1-8.8 33.4-21.9 33.4-8.3 0-13.3-3-16.8-6.7l-.2-52.8c3.7-4.1 8.8-7 17-7 12.9-.1 21.9 14.5 21.9 33.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM122.2 281.1c0-42.3-54.3-34.7-54.3-50.7 0-5.5 4.6-7.7 12.1-7.7 10.8 0 24.5 3.3 35.3 9.1v-33.4c-11.8-4.7-23.5-6.5-35.3-6.5-28.8 0-48 15-48 40.2 0 39.3 54 32.9 54 49.9 0 6.6-5.7 8.7-13.6 8.7-11.8 0-26.9-4.9-38.9-11.3v33.9c13.2 5.7 26.6 8.1 38.8 8.1 29.6-.2 49.9-14.7 49.9-40.3zm68.9-86.9h-27v-30.8l-34.7 7.4-.2 113.9c0 21 15.8 36.5 36.9 36.5 11.6 0 20.2-2.1 24.9-4.7v-28.9c-4.5 1.8-27 8.3-27-12.6v-50.5h27v-30.3zm73.8 0c-4.7-1.7-21.3-4.8-29.6 10.5l-2.2-10.5h-30.7v124.5h35.5v-84.4c8.4-11 22.6-8.9 27.1-7.4v-32.7zm44.2 0h-35.7v124.5h35.7V194.2zm0-47.3l-35.7 7.6v28.9l35.7-7.6v-28.9zm122.7 108.8c0-41.3-23.5-63.8-48.4-63.8-13.9 0-22.9 6.6-27.8 11.1l-1.8-8.8h-31.3V360l35.5-7.5.1-40.2c5.1 3.7 12.7 9 25.1 9 25.4-.1 48.6-20.5 48.6-65.6zm112.2 1.2c0-36.4-17.6-65.1-51.3-65.1-33.8 0-54.3 28.7-54.3 64.9 0 42.8 24.2 64.5 58.8 64.5 17 0 29.7-3.9 39.4-9.2v-28.6c-9.7 4.9-20.8 7.9-34.9 7.9-13.8 0-26-4.9-27.6-21.5h69.5c.1-2 .4-9.4.4-12.9zm-51.6-36.1c-8.9 0-18.7 6.7-18.7 22.7h36.7c0-16-9.3-22.7-18-22.7z"],"cc-visa":[576,512,[],"f1f0","M470.1 231.3s7.6 37.2 9.3 45H446c3.3-8.9 16-43.5 16-43.5-.2.3 3.3-9.1 5.3-14.9l2.8 13.4zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM152.5 331.2L215.7 176h-42.5l-39.3 106-4.3-21.5-14-71.4c-2.3-9.9-9.4-12.7-18.2-13.1H32.7l-.7 3.1c15.8 4 29.9 9.8 42.2 17.1l35.8 135h42.5zm94.4.2L272.1 176h-40.2l-25.1 155.4h40.1zm139.9-50.8c.2-17.7-10.6-31.2-33.7-42.3-14.1-7.1-22.7-11.9-22.7-19.2.2-6.6 7.3-13.4 23.1-13.4 13.1-.3 22.7 2.8 29.9 5.9l3.6 1.7 5.5-33.6c-7.9-3.1-20.5-6.6-36-6.6-39.7 0-67.6 21.2-67.8 51.4-.3 22.3 20 34.7 35.2 42.2 15.5 7.6 20.8 12.6 20.8 19.3-.2 10.4-12.6 15.2-24.1 15.2-16 0-24.6-2.5-37.7-8.3l-5.3-2.5-5.6 34.9c9.4 4.3 26.8 8.1 44.8 8.3 42.2.1 69.7-20.8 70-53zM528 331.4L495.6 176h-31.1c-9.6 0-16.9 2.8-21 12.9l-59.7 142.5H426s6.9-19.2 8.4-23.3H486c1.2 5.5 4.8 23.3 4.8 23.3H528z"],centercode:[512,512,[],"f380","M329.2 268.6c-3.8 35.2-35.4 60.6-70.6 56.8-35.2-3.8-60.6-35.4-56.8-70.6 3.8-35.2 35.4-60.6 70.6-56.8 35.1 3.8 60.6 35.4 56.8 70.6zm-85.8 235.1C96.7 496-8.2 365.5 10.1 224.3c11.2-86.6 65.8-156.9 139.1-192 161-77.1 349.7 37.4 354.7 216.6 4.1 147-118.4 262.2-260.5 254.8zm179.9-180c27.9-118-160.5-205.9-237.2-234.2-57.5 56.3-69.1 188.6-33.8 344.4 68.8 15.8 169.1-26.4 271-110.2z"],chrome:[496,512,[],"f268","M131.5 217.5L55.1 100.1c47.6-59.2 119-91.8 192-92.1 42.3-.3 85.5 10.5 124.8 33.2 43.4 25.2 76.4 61.4 97.4 103L264 133.4c-58.1-3.4-113.4 29.3-132.5 84.1zm32.9 38.5c0 46.2 37.4 83.6 83.6 83.6s83.6-37.4 83.6-83.6-37.4-83.6-83.6-83.6-83.6 37.3-83.6 83.6zm314.9-89.2L339.6 174c37.9 44.3 38.5 108.2 6.6 157.2L234.1 503.6c46.5 2.5 94.4-7.7 137.8-32.9 107.4-62 150.9-192 107.4-303.9zM133.7 303.6L40.4 120.1C14.9 159.1 0 205.9 0 256c0 124 90.8 226.7 209.5 244.9l63.7-124.8c-57.6 10.8-113.2-20.8-139.5-72.5z"],cloudscale:[448,512,[],"f383","M318.1 154l-9.4 7.6c-22.5-19.3-51.5-33.6-83.3-33.6C153.8 128 96 188.8 96 260.3c0 6.6.4 13.1 1.4 19.4-2-56 41.8-97.4 92.6-97.4 24.2 0 46.2 9.4 62.6 24.7l-25.2 20.4c-8.3-.9-16.8 1.8-23.1 8.1-11.1 11-11.1 28.9 0 40 11.1 11 28.9 11 40 0 6.3-6.3 9-14.9 8.1-23.1l75.2-88.8c6.3-6.5-3.3-15.9-9.5-9.6zm-83.8 111.5c-5.6 5.5-14.6 5.5-20.2 0-5.6-5.6-5.6-14.6 0-20.2s14.6-5.6 20.2 0 5.6 14.7 0 20.2zM224 32C100.5 32 0 132.5 0 256s100.5 224 224 224 224-100.5 224-224S347.5 32 224 32zm0 384c-88.2 0-160-71.8-160-160S135.8 96 224 96s160 71.8 160 160-71.8 160-160 160z"],cloudsmith:[332,512,[],"f384","M332.5 419.9c0 46.4-37.6 84.1-84 84.1s-84-37.7-84-84.1 37.6-84 84-84 84 37.6 84 84zm-84-243.9c46.4 0 80-37.6 80-84s-33.6-84-80-84-88 37.6-88 84-29.6 76-76 76-84 41.6-84 88 37.6 80 84 80 84-33.6 84-80 33.6-80 80-80z"],cloudversify:[616,512,[],"f385","M148.6 304c8.2 68.5 67.4 115.5 146 111.3 51.2 43.3 136.8 45.8 186.4-5.6 69.2 1.1 118.5-44.6 131.5-99.5 14.8-62.5-18.2-132.5-92.1-155.1-33-88.1-131.4-101.5-186.5-85-57.3 17.3-84.3 53.2-99.3 109.7-7.8 2.7-26.5 8.9-45 24.1 11.7 0 15.2 8.9 15.2 19.5v20.4c0 10.7-8.7 19.5-19.5 19.5h-20.2c-10.7 0-19.5-6-19.5-16.7V240H98.8C95 240 88 244.3 88 251.9v40.4c0 6.4 5.3 11.8 11.7 11.8h48.9zm227.4 8c-10.7 46.3 21.7 72.4 55.3 86.8C324.1 432.6 259.7 348 296 288c-33.2 21.6-33.7 71.2-29.2 92.9-17.9-12.4-53.8-32.4-57.4-79.8-3-39.9 21.5-75.7 57-93.9C297 191.4 369.9 198.7 400 248c-14.1-48-53.8-70.1-101.8-74.8 30.9-30.7 64.4-50.3 114.2-43.7 69.8 9.3 133.2 82.8 67.7 150.5 35-16.3 48.7-54.4 47.5-76.9l10.5 19.6c11.8 22 15.2 47.6 9.4 72-9.2 39-40.6 68.8-79.7 76.5-32.1 6.3-83.1-5.1-91.8-59.2zM128 208H88.2c-8.9 0-16.2-7.3-16.2-16.2v-39.6c0-8.9 7.3-16.2 16.2-16.2H128c8.9 0 16.2 7.3 16.2 16.2v39.6c0 8.9-7.3 16.2-16.2 16.2zM10.1 168C4.5 168 0 163.5 0 157.9v-27.8c0-5.6 4.5-10.1 10.1-10.1h27.7c5.5 0 10.1 4.5 10.1 10.1v27.8c0 5.6-4.5 10.1-10.1 10.1H10.1zM168 142.7v-21.4c0-5.1 4.2-9.3 9.3-9.3h21.4c5.1 0 9.3 4.2 9.3 9.3v21.4c0 5.1-4.2 9.3-9.3 9.3h-21.4c-5.1 0-9.3-4.2-9.3-9.3zM56 235.5v25c0 6.3-5.1 11.5-11.4 11.5H19.4C13.1 272 8 266.8 8 260.5v-25c0-6.3 5.1-11.5 11.4-11.5h25.1c6.4 0 11.5 5.2 11.5 11.5z"],codepen:[512,512,[],"f1cb","M502.285 159.704l-234-156c-7.987-4.915-16.511-4.96-24.571 0l-234 156C3.714 163.703 0 170.847 0 177.989v155.999c0 7.143 3.714 14.286 9.715 18.286l234 156.022c7.987 4.915 16.511 4.96 24.571 0l234-156.022c6-3.999 9.715-11.143 9.715-18.286V177.989c-.001-7.142-3.715-14.286-9.716-18.285zM278 63.131l172.286 114.858-76.857 51.429L278 165.703V63.131zm-44 0v102.572l-95.429 63.715-76.857-51.429L234 63.131zM44 219.132l55.143 36.857L44 292.846v-73.714zm190 229.715L61.714 333.989l76.857-51.429L234 346.275v102.572zm22-140.858l-77.715-52 77.715-52 77.715 52-77.715 52zm22 140.858V346.275l95.429-63.715 76.857 51.429L278 448.847zm190-156.001l-55.143-36.857L468 219.132v73.714z"],codiepie:[472,512,[],"f284","M422.5 202.9c30.7 0 33.5 53.1-.3 53.1h-10.8v44.3h-26.6v-97.4h37.7zM472 352.6C429.9 444.5 350.4 504 248 504 111 504 0 393 0 256S111 8 248 8c97.4 0 172.8 53.7 218.2 138.4l-186 108.8L472 352.6zm-38.5 12.5l-60.3-30.7c-27.1 44.3-70.4 71.4-122.4 71.4-82.5 0-149.2-66.7-149.2-148.9 0-82.5 66.7-149.2 149.2-149.2 48.4 0 88.9 23.5 116.9 63.4l59.5-34.6c-40.7-62.6-104.7-100-179.2-100-121.2 0-219.5 98.3-219.5 219.5S126.8 475.5 248 475.5c78.6 0 146.5-42.1 185.5-110.4z"],connectdevelop:[576,512,[],"f20e","M550.5 241l-50.089-86.786c1.071-2.142 1.875-4.553 1.875-7.232 0-8.036-6.696-14.733-14.732-15.001l-55.447-95.893c.536-1.607 1.071-3.214 1.071-4.821 0-8.571-6.964-15.268-15.268-15.268-4.821 0-8.839 2.143-11.786 5.625H299.518C296.839 18.143 292.821 16 288 16s-8.839 2.143-11.518 5.625H170.411C167.464 18.143 163.447 16 158.625 16c-8.303 0-15.268 6.696-15.268 15.268 0 1.607.536 3.482 1.072 4.821l-55.983 97.233c-5.356 2.41-9.107 7.5-9.107 13.661 0 .535.268 1.071.268 1.607l-53.304 92.143c-7.232 1.339-12.59 7.5-12.59 15 0 7.232 5.089 13.393 12.054 15l55.179 95.358c-.536 1.607-.804 2.946-.804 4.821 0 7.232 5.089 13.393 12.054 14.732l51.697 89.732c-.536 1.607-1.071 3.482-1.071 5.357 0 8.571 6.964 15.268 15.268 15.268 4.821 0 8.839-2.143 11.518-5.357h106.875C279.161 493.857 283.447 496 288 496s8.839-2.143 11.518-5.357h107.143c2.678 2.946 6.696 4.821 10.982 4.821 8.571 0 15.268-6.964 15.268-15.268 0-1.607-.267-2.946-.803-4.285l51.697-90.268c6.964-1.339 12.054-7.5 12.054-14.732 0-1.607-.268-3.214-.804-4.821l54.911-95.358c6.964-1.339 12.322-7.5 12.322-15-.002-7.232-5.092-13.393-11.788-14.732zM153.535 450.732l-43.66-75.803h43.66v75.803zm0-83.839h-43.66c-.268-1.071-.804-2.142-1.339-3.214l44.999-47.41v50.624zm0-62.411l-50.357 53.304c-1.339-.536-2.679-1.34-4.018-1.607L43.447 259.75c.535-1.339.535-2.679.535-4.018s0-2.41-.268-3.482l51.965-90c2.679-.268 5.357-1.072 7.768-2.679l50.089 51.965v92.946zm0-102.322l-45.803-47.41c1.339-2.143 2.143-4.821 2.143-7.767 0-.268-.268-.804-.268-1.072l43.928-15.804v72.053zm0-80.625l-43.66 15.804 43.66-75.536v59.732zm326.519 39.108l.804 1.339L445.5 329.125l-63.75-67.232 98.036-101.518.268.268zM291.75 355.107l11.518 11.786H280.5l11.25-11.786zm-.268-11.25l-83.303-85.446 79.553-84.375 83.036 87.589-79.286 82.232zm5.357 5.893l79.286-82.232 67.5 71.25-5.892 28.125H313.714l-16.875-17.143zM410.411 44.393c1.071.536 2.142 1.072 3.482 1.34l57.857 100.714v.536c0 2.946.803 5.624 2.143 7.767L376.393 256l-83.035-87.589L410.411 44.393zm-9.107-2.143L287.732 162.518l-57.054-60.268 166.339-60h4.287zm-123.483 0c2.678 2.678 6.16 4.285 10.179 4.285s7.5-1.607 10.179-4.285h75L224.786 95.821 173.893 42.25h103.928zm-116.249 5.625l1.071-2.142a33.834 33.834 0 0 0 2.679-.804l51.161 53.84-54.911 19.821V47.875zm0 79.286l60.803-21.964 59.732 63.214-79.553 84.107-40.982-42.053v-83.304zm0 92.678L198 257.607l-36.428 38.304v-76.072zm0 87.858l42.053-44.464 82.768 85.982-17.143 17.678H161.572v-59.196zm6.964 162.053c-1.607-1.607-3.482-2.678-5.893-3.482l-1.071-1.607v-89.732h99.91l-91.607 94.821h-1.339zm129.911 0c-2.679-2.41-6.428-4.285-10.447-4.285s-7.767 1.875-10.447 4.285h-96.429l91.607-94.821h38.304l91.607 94.821H298.447zm120-11.786l-4.286 7.5c-1.339.268-2.41.803-3.482 1.339l-89.196-91.875h114.376l-17.412 83.036zm12.856-22.232l12.858-60.803h21.964l-34.822 60.803zm34.822-68.839h-20.357l4.553-21.16 17.143 18.214c-.535.803-1.071 1.874-1.339 2.946zm66.161-107.411l-55.447 96.697c-1.339.535-2.679 1.071-4.018 1.874l-20.625-21.964 34.554-163.928 45.803 79.286c-.267 1.339-.803 2.678-.803 4.285 0 1.339.268 2.411.536 3.75z"],contao:[512,512,[],"f26d","M45.4 305c14.4 67.1 26.4 129 68.2 175H34c-18.7 0-34-15.2-34-34V66c0-18.7 15.2-34 34-34h57.7C77.9 44.6 65.6 59.2 54.8 75.6c-45.4 70-27 146.8-9.4 229.4zM478 32h-90.2c21.4 21.4 39.2 49.5 52.7 84.1l-137.1 29.3c-14.9-29-37.8-53.3-82.6-43.9-24.6 5.3-41 19.3-48.3 34.6-8.8 18.7-13.2 39.8 8.2 140.3 21.1 100.2 33.7 117.7 49.5 131.2 12.9 11.1 33.4 17 58.3 11.7 44.5-9.4 55.7-40.7 57.4-73.2l137.4-29.6c3.2 71.5-18.7 125.2-57.4 163.6H478c18.7 0 34-15.2 34-34V66c0-18.8-15.2-34-34-34z"],cpanel:[640,512,[],"f388","M52.9 213.7h40l-6.2 23.6c-1.9 6.5-7.4 10.9-14.3 10.9H53.8c-24.9 0-24.7 37.4 0 37.4h11.3c4.2 0 7.6 3.9 6.4 8.3L64.4 320H52c-33.5 0-59-31.4-50.3-65.2 7.3-27 28.3-41.1 51.2-41.1M73.1 320L108 189.9c1.8-6.4 7.2-10.9 14.3-10.9h37c24.1 0 45.4 16.4 51 41.2 6.6 29.1-14.5 65.3-51.7 65.3h-32l6.4-23.8c1.8-6.2 7.3-10.8 14.3-10.8h10.3c12.4 0 20.8-11.7 18.3-22.6-2.1-9.2-9.9-14.8-18.3-14.8h-19.8L112 309.2c-1.9 6.2-7.4 10.7-14.2 10.7l-24.7.1m220.6-69.4c.3-1 1.9-5.3-2.1-5.3h-57.5c-9.7 0-16.6-8.9-14.2-18.5l3.5-13.4h77.9c18.8 0 33.3 17.6 28.5 36.8l-14 51.8c-2.8 10.6-12.2 17.8-23.4 17.8l-57.5-.2c-42.9 0-38.5-63.8.7-63.8H284l-3.5 13.2c-1.9 6.2-7.4 10.8-14.2 10.8h-21.6c-5.3 0-5.3 7.9 0 7.9h34.9c4.6 0 5.1-3.9 5.5-5.3l8.6-31.8m103.1-36.9c34.4 0 59.3 32.3 50.3 65.4l-8.8 33.1c-1.2 4.9-5.7 7.8-10.3 7.8h-19.1c-4.5 0-7.6-4-6.4-8.3l10.6-40c3.3-11.6-5.6-23.4-18.1-23.4h-19.8l-17.2 64c-1.2 4.8-5.6 7.8-10.4 7.8h-18.9c-4.2 0-7.6-3.9-6.4-8.3l26.2-98h48.3M498 251.6l-8 30c-.9 3.3 1.5 6.7 5.1 6.7h73.3l-5.7 21c-1.9 6.2-7.4 10.7-14.2 10.7h-66.7c-20 0-33.3-19-28.3-36.7l10.8-40c4.8-17.6 20.7-29.6 38.6-29.6h47.3c19 0 33.2 17.7 28.3 36.8l-3.2 12c-2.9 11-12.7 17.6-23.2 17.6h-53.4l3.5-13c1.6-6.2 7.2-10.8 14.2-10.8H538c2 0 3.3-1 3.9-3l.7-2.6c.7-2.7-1.3-5.1-3.9-5.1h-32.9c-4.1 0-6.9 2.1-7.8 6zm70.2 68.4l35.6-133.1c1.2-4.7 5.5-7.9 10.4-7.9h18.9c4.5 0 7.7 4 6.5 8.3l-26.5 98.2c-5.1 20.7-24.2 34.5-44.9 34.5"],"creative-commons":[512,512,[],"f25e","M255.547 8C392.884 8 504 114.439 504 256.004 504 405.979 381.106 504 255.562 504 122.319 504 8 394.557 8 256.004 8 124.825 113.486 8 255.547 8zm.899 44.734c-120.341 0-203.727 100.568-203.727 203.278 0 106.515 88.984 202.394 203.727 202.394 101.528 0 202.821-79.442 202.821-202.387-.001-114.773-91.773-203.285-202.821-203.285zm-3.108 162.093l-33.225 17.275c-5.395-11.203-15.25-19.926-27.459-19.926-22.134 0-33.217 14.609-33.217 43.842 0 23.842 9.446 43.842 33.217 43.842 14.469 0 24.653-7.091 30.566-21.259l30.551 15.5c-12.813 23.899-36.887 38.975-65.101 38.975-43.162 0-73.959-27.272-73.959-77.052 0-49.541 32.706-77.059 72.634-77.059 30.714-.013 52.701 11.946 65.993 35.862zm143.044 0l-32.775 17.275c-5.517-11.482-15.324-19.926-27.9-19.926-22.142 0-33.225 14.609-33.225 43.842 0 23.906 9.502 43.842 33.225 43.842 14.454 0 24.645-7.091 30.543-21.259l31 15.5c-13.363 23.869-37.451 38.975-65.086 38.975-43.439 0-73.959-26.988-73.959-77.052 0-49.523 32.698-77.059 72.626-77.059 30.706-.013 52.569 11.946 65.551 35.862z"],css3:[512,512,[],"f13c","M480 32l-64 368-223.3 80L0 400l19.6-94.8h82l-8 40.6L210 390.2l134.1-44.4 18.8-97.1H29.5l16-82h333.7l10.5-52.7H56.3l16.3-82H480z"],"css3-alt":[384,512,[],"f38b","M0 32l34.9 395.8L192 480l157.1-52.2L384 32H0zm313.1 80l-4.8 47.3L193 208.6l-.3.1h111.5l-12.8 146.6-98.2 28.7-98.8-29.2-6.4-73.9h48.9l3.2 38.3 52.6 13.3 54.7-15.4 3.7-61.6-166.3-.5v-.1l-.2.1-3.6-46.3L193.1 162l6.5-2.7H76.7L70.9 112h242.2z"],cuttlefish:[440,512,[],"f38c","M344 305.5c-17.5 31.6-57.4 54.5-96 54.5-56.6 0-104-47.4-104-104s47.4-104 104-104c38.6 0 78.5 22.9 96 54.5 13.7-50.9 41.7-93.3 87-117.8C385.7 39.1 320.5 8 248 8 111 8 0 119 0 256s111 248 248 248c72.5 0 137.7-31.1 183-80.7-45.3-24.5-73.3-66.9-87-117.8z"],"d-and-d":[576,512,[],"f38d","M82.5 98.9c-.6-17.2 2-33.8 12.7-48.2.3 7.4 1.2 14.5 4.2 21.6 5.9-27.5 19.7-49.3 42.3-65.5-1.9 5.9-3.5 11.8-3 17.7 8.7-7.4 18.8-17.8 44.4-22.7 14.7-2.8 29.7-2 42.1 1 38.5 9.3 61 34.3 69.7 72.3 5.3 23.1.7 45-8.3 66.4-5.2 12.4-12 24.4-20.7 35.1-2-1.9-3.9-3.8-5.8-5.6-42.8-40.8-26.8-25.2-37.4-37.4-1.1-1.2-1-2.2-.1-3.6 8.3-13.5 11.8-28.2 10-44-1.1-9.8-4.3-18.9-11.3-26.2-14.5-15.3-39.2-15-53.5.6-11.4 12.5-14.1 27.4-10.9 43.6.2 1.3.4 2.7 0 3.9-3.4 13.7-4.6 27.6-2.5 41.6.1.5.1 1.1.1 1.6 0 .3-.1.5-.2 1.1-21.8-11-36-28.3-43.2-52.2-8.3 17.8-11.1 35.5-6.6 54.1-15.6-15.2-21.3-34.3-22-55.2zm469.6 123.2c-11.6-11.6-25-20.4-40.1-26.6-12.8-5.2-26-7.9-39.9-7.1-10 .6-19.6 3.1-29 6.4-2.5.9-5.1 1.6-7.7 2.2-4.9 1.2-7.3-3.1-4.7-6.8 3.2-4.6 3.4-4.2 15-12 .6-.4 1.2-.8 2.2-1.5h-2.5c-.6 0-1.2.2-1.9.3-19.3 3.3-30.7 15.5-48.9 29.6-10.4 8.1-13.8 3.8-12-.5 1.4-3.5 3.3-6.7 5.1-10 1-1.8 2.3-3.4 3.5-5.1-.2-.2-.5-.3-.7-.5-27 18.3-46.7 42.4-57.7 73.3.3.3.7.6 1 .9.3-.6.5-1.2.9-1.7 10.4-12.1 22.8-21.8 36.6-29.8 18.2-10.6 37.5-18.3 58.7-20.2 4.3-.4 8.7-.1 13.1-.1-1.8.7-3.5.9-5.3 1.1-18.5 2.4-35.5 9-51.5 18.5-30.2 17.9-54.5 42.2-75.1 70.4-.3.4-.4.9-.7 1.3 14.5 5.3 24 17.3 36.1 25.6.2-.1.3-.2.4-.4l1.2-2.7c12.2-26.9 27-52.3 46.7-74.5 16.7-18.8 38-25.3 62.5-20 5.9 1.3 11.4 4.4 17.2 6.8 2.3-1.4 5.1-3.2 8-4.7 8.4-4.3 17.4-7 26.7-9 14.7-3.1 29.5-4.9 44.5-1.3v-.5c-.5-.4-1.2-.8-1.7-1.4zM316.7 397.6c-39.4-33-22.8-19.5-42.7-35.6-.8.9 0-.2-1.9 3-11.2 19.1-25.5 35.3-44 47.6-10.3 6.8-21.5 11.8-34.1 11.8-21.6 0-38.2-9.5-49.4-27.8-12-19.5-13.3-40.7-8.2-62.6 7.8-33.8 30.1-55.2 38.6-64.3-18.7-6.2-33 1.7-46.4 13.9.8-13.9 4.3-26.2 11.8-37.3-24.3 10.6-45.9 25-64.8 43.9-.3-5.8 5.4-43.7 5.6-44.7.3-2.7-.6-5.3-3-7.4-24.2 24.7-44.5 51.8-56.1 84.6 7.4-5.9 14.9-11.4 23.6-16.2-8.3 22.3-19.6 52.8-7.8 101.1 4.6 19 11.9 36.8 24.1 52.3 2.9 3.7 6.3 6.9 9.5 10.3.2-.2.4-.3.6-.5-1.4-7-2.2-14.1-1.5-21.9 2.2 3.2 3.9 6 5.9 8.6 12.6 16 28.7 27.4 47.2 35.6 25 11.3 51.1 13.3 77.9 8.6 54.9-9.7 90.7-48.6 116-98.8 1-1.8.6-2.9-.9-4.2zm172-46.4c-9.5-3.1-22.2-4.2-28.7-2.9 9.9 4 14.1 6.6 18.8 12 12.6 14.4 10.4 34.7-5.4 45.6-11.7 8.1-24.9 10.5-38.9 9.1-1.2-.1-2.3-.4-3-.6 2.8-3.7 6-7 8.1-10.8 9.4-16.8 5.4-42.1-8.7-56.1-2.1-2.1-4.6-3.9-7-5.9-.3 1.3-.1 2.1.1 2.8 4.2 16.6-8.1 32.4-24.8 31.8-7.6-.3-13.9-3.8-19.6-8.5-19.5-16.1-39.1-32.1-58.5-48.3-5.9-4.9-12.5-8.1-20.1-8.7-4.6-.4-9.3-.6-13.9-.9-5.9-.4-8.8-2.8-10.4-8.4-.9-3.4-1.5-6.8-2.2-10.2-1.5-8.1-6.2-13-14.3-14.2-4.4-.7-8.9-1-13.3-1.5-13-1.4-19.8-7.4-22.6-20.3-5 11-1.6 22.4 7.3 29.9 4.5 3.8 9.3 7.3 13.8 11.2 4.6 3.8 7.4 8.7 7.9 14.8.4 4.7.8 9.5 1.8 14.1 2.2 10.6 8.9 18.4 17 25.1 16.5 13.7 33 27.3 49.5 41.1 17.9 15 13.9 32.8 13 56-.9 22.9 12.2 42.9 33.5 51.2 1 .4 2 .6 3.6 1.1-15.7-18.2-10.1-44.1.7-52.3.3 2.2.4 4.3.9 6.4 9.4 44.1 45.4 64.2 85 56.9 16-2.9 30.6-8.9 42.9-19.8 2-1.8 3.7-4.1 5.9-6.5-19.3 4.6-35.8.1-50.9-10.6.7-.3 1.3-.3 1.9-.3 21.3 1.8 40.6-3.4 57-17.4 19.5-16.6 26.6-42.9 17.4-66-8.3-20.1-23.6-32.3-43.8-38.9zM99.4 179.3c-5.3-9.2-13.2-15.6-22.1-21.3 13.7-.5 26.6.2 39.6 3.7-7-12.2-8.5-24.7-5-38.7 5.3 11.9 13.7 20.1 23.6 26.8 19.7 13.2 35.7 19.6 46.7 30.2 3.4 3.3 6.3 7.1 9.6 10.9-.8-2.1-1.4-4.1-2.2-6-5-10.6-13-18.6-22.6-25-1.8-1.2-2.8-2.5-3.4-4.5-3.3-12.5-3-25.1-.7-37.6 1-5.5 2.8-10.9 4.5-16.3.8-2.4 2.3-4.6 4-6.6.6 6.9 0 25.5 19.6 46 10.8 11.3 22.4 21.9 33.9 32.7 9 8.5 18.3 16.7 25.5 26.8 1.1 1.6 2.2 3.3 3.8 4.7-5-13-14.2-24.1-24.2-33.8-9.6-9.3-19.4-18.4-29.2-27.4-3.3-3-4.6-6.7-5.1-10.9-1.2-10.4 0-20.6 4.3-30.2.5-1 1.1-2 1.9-3.3.5 4.2.6 7.9 1.4 11.6 4.8 23.1 20.4 36.3 49.3 63.5 10 9.4 19.3 19.2 25.6 31.6 4.8 9.3 7.3 19 5.7 29.6-.1.6.5 1.7 1.1 2 6.2 2.6 10 6.9 9.7 14.3 7.7-2.6 12.5-8 16.4-14.5 4.2 20.2-9.1 50.3-27.2 58.7.4-4.5 5-23.4-16.5-27.7-6.8-1.3-12.8-1.3-22.9-2.1 4.7-9 10.4-20.6.5-22.4-24.9-4.6-52.8 1.9-57.8 4.6 8.2.4 16.3 1 23.5 3.3-2 6.5-4 12.7-5.8 18.9-1.9 6.5 2.1 14.6 9.3 9.6 1.2-.9 2.3-1.9 3.3-2.7-3.1 17.9-2.9 15.9-2.8 18.3.3 10.2 9.5 7.8 15.7 7.3-2.5 11.8-29.5 27.3-45.4 25.8 7-4.7 12.7-10.3 15.9-17.9-6.5.8-12.9 1.6-19.2 2.4l-.3-.9c4.7-3.4 8-7.8 10.2-13.1 8.7-21.1-3.6-38-25-39.9-9.1-.8-17.8.8-25.9 5.5 6.2-15.6 17.2-26.6 32.6-34.5-15.2-4.3-8.9-2.7-24.6-6.3 14.6-9.3 30.2-13.2 46.5-14.6-5.2-3.2-48.1-3.6-70.2 20.9 7.9 1.4 15.5 2.8 23.2 4.2-23.8 7-44 19.7-62.4 35.6 1.1-4.8 2.7-9.5 3.3-14.3.6-4.5.8-9.2.1-13.6-1.5-9.4-8.9-15.1-19.7-16.3-7.9-.9-15.6.1-23.3 1.3-.9.1-1.7.3-2.9 0 15.8-14.8 36-21.7 53.1-33.5 6-4.5 6.8-8.2 3-14.9zm128.4 26.8c3.3 16 12.6 25.5 23.8 24.3-4.6-11.3-12.1-19.5-23.8-24.3z"],dashcube:[448,512,[],"f210","M326.6 104H110.4c-51.1 0-91.2 43.3-91.2 93.5V427c0 50.5 40.1 85 91.2 85h227.2c51.1 0 91.2-34.5 91.2-85V0L326.6 104zM153.9 416.5c-17.7 0-32.4-15.1-32.4-32.8V240.8c0-17.7 14.7-32.5 32.4-32.5h140.7c17.7 0 32 14.8 32 32.5v123.5l51.1 52.3H153.9z"],delicious:[448,512,[],"f1a5","M446.5 68c-.4-1.5-.9-3-1.4-4.5-.9-2.5-2-4.8-3.3-7.1-1.4-2.4-3-4.8-4.7-6.9-2.1-2.5-4.4-4.8-6.9-6.8-1.1-.9-2.2-1.7-3.3-2.5-1.3-.9-2.6-1.7-4-2.4-1.8-1-3.6-1.8-5.5-2.5-1.7-.7-3.5-1.3-5.4-1.7-3.8-1-7.9-1.5-12-1.5H48C21.5 32 0 53.5 0 80v352c0 4.1.5 8.2 1.5 12 2 7.7 5.8 14.6 11 20.3 1 1.1 2.1 2.2 3.3 3.3 5.7 5.2 12.6 9 20.3 11 3.8 1 7.9 1.5 12 1.5h352c26.5 0 48-21.5 48-48V80c-.1-4.1-.6-8.2-1.6-12zM416 432c0 8.8-7.2 16-16 16H224V256H32V80c0-8.8 7.2-16 16-16h176v192h192v176z"],deploydog:[512,512,[],"f38e","M382.2 136h51.7v239.6h-51.7v-20.7c-19.8 24.8-52.8 24.1-73.8 14.7-26.2-11.7-44.3-38.1-44.3-71.8 0-29.8 14.8-57.9 43.3-70.8 20.2-9.1 52.7-10.6 74.8 12.9V136zm-64.7 161.8c0 18.2 13.6 33.5 33.2 33.5 19.8 0 33.2-16.4 33.2-32.9 0-17.1-13.7-33.2-33.2-33.2-19.6 0-33.2 16.4-33.2 32.6zM188.5 136h51.7v239.6h-51.7v-20.7c-19.8 24.8-52.8 24.1-73.8 14.7-26.2-11.7-44.3-38.1-44.3-71.8 0-29.8 14.8-57.9 43.3-70.8 20.2-9.1 52.7-10.6 74.8 12.9V136zm-64.7 161.8c0 18.2 13.6 33.5 33.2 33.5 19.8 0 33.2-16.4 33.2-32.9 0-17.1-13.7-33.2-33.2-33.2-19.7 0-33.2 16.4-33.2 32.6zM448 96c17.5 0 32 14.4 32 32v256c0 17.5-14.4 32-32 32H64c-17.5 0-32-14.4-32-32V128c0-17.5 14.4-32 32-32h384m0-32H64C28.8 64 0 92.8 0 128v256c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V128c0-35.2-28.8-64-64-64z"],deskpro:[480,512,[],"f38f","M205.9 512l31.1-38.4c12.3-.2 25.6-1.4 36.5-6.6 38.9-18.6 38.4-61.9 38.3-63.8-.1-5-.8-4.4-28.9-37.4H362c-.2 50.1-7.3 68.5-10.2 75.7-9.4 23.7-43.9 62.8-95.2 69.4-8.7 1.1-32.8 1.2-50.7 1.1zm200.4-167.7c38.6 0 58.5-13.6 73.7-30.9l-175.5-.3-17.4 31.3 119.2-.1zm-43.6-223.9v168.3h-73.5l-32.7 55.5H250c-52.3 0-58.1-56.5-58.3-58.9-1.2-13.2-21.3-11.6-20.1 1.8 1.4 15.8 8.8 40 26.4 57.1h-91c-25.5 0-110.8-26.8-107-114V16.9C0 .9 9.7.3 15 .1h82c.2 0 .3.1.5.1 4.3-.4 50.1-2.1 50.1 43.7 0 13.3 20.2 13.4 20.2 0 0-18.2-5.5-32.8-15.8-43.7h84.2c108.7-.4 126.5 79.4 126.5 120.2zm-132.5 56l64 29.3c13.3-45.5-42.2-71.7-64-29.3z"],deviantart:[320,512,[],"f1bd","M320 93.2l-98.2 179.1 7.4 9.5H320v127.7H159.1l-13.5 9.2-43.7 84c-.3 0-8.6 8.6-9.2 9.2H0v-93.2l93.2-179.4-7.4-9.2H0V102.5h156l13.5-9.2 43.7-84c.3 0 8.6-8.6 9.2-9.2H320v93.1z"],digg:[512,512,[],"f1a6","M81.7 172.3H0v174.4h132.7V96h-51v76.3zm0 133.4H50.9v-92.3h30.8v92.3zm297.2-133.4v174.4h81.8v28.5h-81.8V416H512V172.3H378.9zm81.8 133.4h-30.8v-92.3h30.8v92.3zm-235.6 41h82.1v28.5h-82.1V416h133.3V172.3H225.1v174.4zm51.2-133.3h30.8v92.3h-30.8v-92.3zM153.3 96h51.3v51h-51.3V96zm0 76.3h51.3v174.4h-51.3V172.3z"],"digital-ocean":[512,512,[],"f391","M256 504v-96.1c101.8 0 180.8-100.9 141.7-208-14.3-39.6-46.1-71.4-85.8-85.7-107.1-38.8-208.1 39.9-208.1 141.7H8C8 93.7 164.9-32.8 335 20.3c74.2 23.3 133.6 82.4 156.6 156.6C544.8 347.2 418.6 504 256 504zm.3-191.4h-95.6v95.6h95.6v-95.6zm-95.6 95.6H87v73.6h73.7v-73.6zM87 346.6H25.4v61.6H87v-61.6z"],discord:[448,512,[],"f392","M297.216 243.2c0 15.616-11.52 28.416-26.112 28.416-14.336 0-26.112-12.8-26.112-28.416s11.52-28.416 26.112-28.416c14.592 0 26.112 12.8 26.112 28.416zm-119.552-28.416c-14.592 0-26.112 12.8-26.112 28.416s11.776 28.416 26.112 28.416c14.592 0 26.112-12.8 26.112-28.416.256-15.616-11.52-28.416-26.112-28.416zM448 52.736V512c-64.494-56.994-43.868-38.128-118.784-107.776l13.568 47.36H52.48C23.552 451.584 0 428.032 0 398.848V52.736C0 23.552 23.552 0 52.48 0h343.04C424.448 0 448 23.552 448 52.736zm-72.96 242.688c0-82.432-36.864-149.248-36.864-149.248-36.864-27.648-71.936-26.88-71.936-26.88l-3.584 4.096c43.52 13.312 63.744 32.512 63.744 32.512-60.811-33.329-132.244-33.335-191.232-7.424-9.472 4.352-15.104 7.424-15.104 7.424s21.248-20.224 67.328-33.536l-2.56-3.072s-35.072-.768-71.936 26.88c0 0-36.864 66.816-36.864 149.248 0 0 21.504 37.12 78.08 38.912 0 0 9.472-11.52 17.152-21.248-32.512-9.728-44.8-30.208-44.8-30.208 3.766 2.636 9.976 6.053 10.496 6.4 43.21 24.198 104.588 32.126 159.744 8.96 8.96-3.328 18.944-8.192 29.44-15.104 0 0-12.8 20.992-46.336 30.464 7.68 9.728 16.896 20.736 16.896 20.736 56.576-1.792 78.336-38.912 78.336-38.912z"],discourse:[448,512,[],"f393","M225.9 32C103.3 32 0 130.5 0 252.1 0 256 .1 480 .1 480l225.8-.2c122.7 0 222.1-102.3 222.1-223.9C448 134.3 348.6 32 225.9 32zM224 384c-19.4 0-37.9-4.3-54.4-12.1L88.5 392l22.9-75c-9.8-18.1-15.4-38.9-15.4-61 0-70.7 57.3-128 128-128s128 57.3 128 128-57.3 128-128 128z"],dochub:[416,512,[],"f394","M397.9 160H256V19.6L397.9 160zM304 192v130c0 66.8-36.5 100.1-113.3 100.1H96V84.8h94.7c12 0 23.1.8 33.1 2.5v-84C212.9 1.1 201.4 0 189.2 0H0v512h189.2C329.7 512 400 447.4 400 318.1V192h-96z"],docker:[640,512,[],"f395","M349.9 236.3h-66.1v-59.4h66.1v59.4zm0-204.3h-66.1v60.7h66.1V32zm78.2 144.8H362v59.4h66.1v-59.4zm-156.3-72.1h-66.1v60.1h66.1v-60.1zm78.1 0h-66.1v60.1h66.1v-60.1zm276.8 100c-14.4-9.7-47.6-13.2-73.1-8.4-3.3-24-16.7-44.9-41.1-63.7l-14-9.3-9.3 14c-18.4 27.8-23.4 73.6-3.7 103.8-8.7 4.7-25.8 11.1-48.4 10.7H2.4c-8.7 50.8 5.8 116.8 44 162.1 37.1 43.9 92.7 66.2 165.4 66.2 157.4 0 273.9-72.5 328.4-204.2 21.4.4 67.6.1 91.3-45.2 1.5-2.5 6.6-13.2 8.5-17.1l-13.3-8.9zm-511.1-27.9h-66v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm-78.1-72.1h-66.1v60.1h66.1v-60.1z"],draft2digital:[480,512,[],"f396","M369.9 425.4V371l47.1 27.2-47.1 27.2zM82.4 380.6c25.5-27.3 97.7-104.7 150.9-170 35.1-43.1 40.3-82.4 28.4-112.7-7.4-18.8-17.5-30.2-24.3-35.7 45.3 2.1 68 23.4 82.2 38.3 0 0 42.4 48.2 5.8 113.3-37 65.9-110.9 147.5-128.5 166.7H82.4zm51.8-219.2c0 12.4-10 22.4-22.4 22.4-12.4 0-22.4-10-22.4-22.4 0-12.4 10-22.4 22.4-22.4 12.4 0 22.4 10.1 22.4 22.4M336 315.9v64.7h-91.3c30.8-35 81.8-95.9 111.8-149.3 35.2-62.6 16.1-123.4-12.8-153.3-4.4-4.6-62.2-62.9-166-41.2-59.1 12.4-89.4 43.4-104.3 67.3-13.1 20.9-17 39.8-18.2 47.7-5.5 33 19.4 67.1 56.7 67.1 31.7 0 57.3-25.7 57.3-57.4 0-27.1-19.7-52.1-48-56.8 1.8-7.3 17.7-21.1 26.3-24.7 41.1-17.3 78 5.2 83.3 33.5 8.3 44.3-37.1 90.4-69.7 127.6C84.5 328.1 18.3 396.8 0 415.9l336-.1V480l144-81.9-144-82.2z"],dribbble:[512,512,[],"f17d","M256 8C119.252 8 8 119.252 8 256s111.252 248 248 248 248-111.252 248-248S392.748 8 256 8zm163.97 114.366c29.503 36.046 47.369 81.957 47.835 131.955-6.984-1.477-77.018-15.682-147.502-6.818-5.752-14.041-11.181-26.393-18.617-41.614 78.321-31.977 113.818-77.482 118.284-83.523zM396.421 97.87c-3.81 5.427-35.697 48.286-111.021 76.519-34.712-63.776-73.185-116.168-79.04-124.008 67.176-16.193 137.966 1.27 190.061 47.489zm-230.48-33.25c5.585 7.659 43.438 60.116 78.537 122.509-99.087 26.313-186.36 25.934-195.834 25.809C62.38 147.205 106.678 92.573 165.941 64.62zM44.17 256.323c0-2.166.043-4.322.108-6.473 9.268.19 111.92 1.513 217.706-30.146 6.064 11.868 11.857 23.915 17.174 35.949-76.599 21.575-146.194 83.527-180.531 142.306C64.794 360.405 44.17 310.73 44.17 256.323zm81.807 167.113c22.127-45.233 82.178-103.622 167.579-132.756 29.74 77.283 42.039 142.053 45.189 160.638-68.112 29.013-150.015 21.053-212.768-27.882zm248.38 8.489c-2.171-12.886-13.446-74.897-41.152-151.033 66.38-10.626 124.7 6.768 131.947 9.055-9.442 58.941-43.273 109.844-90.795 141.978z"],"dribbble-square":[448,512,[],"f397","M90.2 228.2c8.9-42.4 37.4-77.7 75.7-95.7 3.6 4.9 28 38.8 50.7 79-64 17-120.3 16.8-126.4 16.7zM314.6 154c-33.6-29.8-79.3-41.1-122.6-30.6 3.8 5.1 28.6 38.9 51 80 48.6-18.3 69.1-45.9 71.6-49.4zM140.1 364c40.5 31.6 93.3 36.7 137.3 18-2-12-10-53.8-29.2-103.6-55.1 18.8-93.8 56.4-108.1 85.6zm98.8-108.2c-3.4-7.8-7.2-15.5-11.1-23.2C159.6 253 93.4 252.2 87.4 252c0 1.4-.1 2.8-.1 4.2 0 35.1 13.3 67.1 35.1 91.4 22.2-37.9 67.1-77.9 116.5-91.8zm34.9 16.3c17.9 49.1 25.1 89.1 26.5 97.4 30.7-20.7 52.5-53.6 58.6-91.6-4.6-1.5-42.3-12.7-85.1-5.8zm-20.3-48.4c4.8 9.8 8.3 17.8 12 26.8 45.5-5.7 90.7 3.4 95.2 4.4-.3-32.3-11.8-61.9-30.9-85.1-2.9 3.9-25.8 33.2-76.3 53.9zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-64 176c0-88.2-71.8-160-160-160S64 167.8 64 256s71.8 160 160 160 160-71.8 160-160z"],dropbox:[528,512,[],"f16b","M264.4 116.3l-132 84.3 132 84.3-132 84.3L0 284.1l132.3-84.3L0 116.3 132.3 32l132.1 84.3zM131.6 395.7l132-84.3 132 84.3-132 84.3-132-84.3zm132.8-111.6l132-84.3-132-83.6L395.7 32 528 116.3l-132.3 84.3L528 284.8l-132.3 84.3-131.3-85z"],drupal:[448,512,[],"f1a9","M319.5 114.7c-22.2-14-43.5-19.5-64.7-33.5-13-8.8-31.3-30-46.5-48.3-2.7 29.3-11.5 41.2-22 49.5-21.3 17-34.8 22.2-53.5 32.3C117 123 32 181.5 32 290.5 32 399.7 123.8 480 225.8 480 327.5 480 416 406 416 294c0-112.3-83-171-96.5-179.3zm2.5 325.6c-20.1 20.1-90.1 28.7-116.7 4.2-4.8-4.8.3-12 6.5-12 0 0 17 13.3 51.5 13.3 27 0 46-7.7 54.5-14 6.1-4.6 8.4 4.3 4.2 8.5zm-54.5-52.6c8.7-3.6 29-3.8 36.8 1.3 4.1 2.8 16.1 18.8 6.2 23.7-8.4 4.2-1.2-15.7-26.5-15.7-14.7 0-19.5 5.2-26.7 11-7 6-9.8 8-12.2 4.7-6-8.2 15.9-22.3 22.4-25zM360 405c-15.2-1-45.5-48.8-65-49.5-30.9-.9-104.1 80.7-161.3 42-38.8-26.6-14.6-104.8 51.8-105.2 49.5-.5 83.8 49 108.5 48.5 21.3-.3 61.8-41.8 81.8-41.8 48.7 0 23.3 109.3-15.8 106z"],dyalog:[416,512,[],"f399","M0 32v119.2h64V96h107.2C284.6 96 352 176.2 352 255.9 352 332 293.4 416 171.2 416H0v64h171.2C331.9 480 416 367.3 416 255.9c0-58.7-22.1-113.4-62.3-154.3C308.9 56 245.7 32 171.2 32H0z"],earlybirds:[480,512,[],"f39a","M313.2 47.5c1.2-13 21.3-14 36.6-8.7.9.3 26.2 9.7 19 15.2-27.9-7.4-56.4 18.2-55.6-6.5zm-201 6.9c30.7-8.1 62 20 61.1-7.1-1.3-14.2-23.4-15.3-40.2-9.6-1 .3-28.7 10.5-20.9 16.7zM319.4 160c-8.8 0-16 7.2-16 16s7.2 16 16 16 16-7.2 16-16-7.2-16-16-16zm-159.7 0c-8.8 0-16 7.2-16 16s7.2 16 16 16 16-7.2 16-16-7.2-16-16-16zm318.5 163.2c-9.9 24-40.7 11-63.9-1.2-13.5 69.1-58.1 111.4-126.3 124.2.3.9-2-.1 24 1 33.6 1.4 63.8-3.1 97.4-8-19.8-13.8-11.4-37.1-9.8-38.1 1.4-.9 14.7 1.7 21.6 11.5 8.6-12.5 28.4-14.8 30.2-13.6 1.6 1.1 6.6 20.9-6.9 34.6 4.7-.9 8.2-1.6 9.8-2.1 2.6-.8 17.7 11.3 3.1 13.3-14.3 2.3-22.6 5.1-47.1 10.8-45.9 10.7-85.9 11.8-117.7 12.8l1 11.6c3.8 18.1-23.4 24.3-27.6 6.2.8 17.9-27.1 21.8-28.4-1l-.5 5.3c-.7 18.4-28.4 17.9-28.3-.6-7.5 13.5-28.1 6.8-26.4-8.5l1.2-12.4c-36.7.9-59.7 3.1-61.8 3.1-20.9 0-20.9-31.6 0-31.6 2.4 0 27.7 1.3 63.2 2.8-61.1-15.5-103.7-55-114.9-118.2-25 12.8-57.5 26.8-68.2.8-10.5-25.4 21.5-42.6 66.8-73.4.7-6.6 1.6-13.3 2.7-19.8-14.4-19.6-11.6-36.3-16.1-60.4-16.8 2.4-23.2-9.1-23.6-23.1.3-7.3 2.1-14.9 2.4-15.4 1.1-1.8 10.1-2 12.7-2.6 6-31.7 50.6-33.2 90.9-34.5 19.7-21.8 45.2-41.5 80.9-48.3C203.3 29 215.2 8.5 216.2 8c1.7-.8 21.2 4.3 26.3 23.2 5.2-8.8 18.3-11.4 19.6-10.7 1.1.6 6.4 15-4.9 25.9 40.3 3.5 72.2 24.7 96 50.7 36.1 1.5 71.8 5.9 77.1 34 2.7.6 11.6.8 12.7 2.6.3.5 2.1 8.1 2.4 15.4-.5 13.9-6.8 25.4-23.6 23.1-3.2 17.3-2.7 32.9-8.7 47.7 2.4 11.7 4 23.8 4.8 36.4 37 25.4 70.3 42.5 60.3 66.9zM207.4 159.9c.9-44-37.9-42.2-78.6-40.3-21.7 1-38.9 1.9-45.5 13.9-11.4 20.9 5.9 92.9 23.2 101.2 9.8 4.7 73.4 7.9 86.3-7.1 8.2-9.4 15-49.4 14.6-67.7zm52 58.3c-4.3-12.4-6-30.1-15.3-32.7-2-.5-9-.5-11 0-10 2.8-10.8 22.1-17 37.2 15.4 0 19.3 9.7 23.7 9.7 4.3 0 6.3-11.3 19.6-14.2zm135.7-84.7c-6.6-12.1-24.8-12.9-46.5-13.9-40.2-1.9-78.2-3.8-77.3 40.3-.5 18.3 5 58.3 13.2 67.8 13 14.9 76.6 11.8 86.3 7.1 15.8-7.6 36.5-78.9 24.3-101.3z"],edge:[512,512,[],"f282","M25.714 228.163c.111-.162.23-.323.342-.485-.021.162-.045.323-.065.485h-.277zm460.572 15.508c0-44.032-7.754-84.465-28.801-122.405C416.498 47.879 343.912 8.001 258.893 8.001 118.962 7.724 40.617 113.214 26.056 227.679c42.429-61.312 117.073-121.376 220.375-124.966 0 0 109.666 0 99.419 104.957H169.997c6.369-37.386 18.554-58.986 34.339-78.926-75.048 34.893-121.85 96.096-120.742 188.315.83 71.448 50.124 144.836 120.743 171.976 83.357 31.847 192.776 7.2 240.132-21.324V363.307c-80.864 56.494-270.871 60.925-272.255-67.572h314.073v-52.064z"],elementor:[448,512,[],"f430","M425.6 32H22.4C10 32 0 42 0 54.4v403.2C0 470 10 480 22.4 480h403.2c12.4 0 22.4-10 22.4-22.4V54.4C448 42 438 32 425.6 32M164.3 355.5h-39.8v-199h39.8v199zm159.3 0H204.1v-39.8h119.5v39.8zm0-79.6H204.1v-39.8h119.5v39.8zm0-79.7H204.1v-39.8h119.5v39.8z"],ember:[640,512,[],"f423","M639.9 254.6c-1.1-10.7-10.7-6.8-10.7-6.8s-15.6 12.1-29.3 10.7c-13.7-1.3-9.4-32-9.4-32s3-28.1-5.1-30.4c-8.1-2.4-18 7.3-18 7.3s-12.4 13.7-18.3 31.2l-1.6.5s1.9-30.6-.3-37.6c-1.6-3.5-16.4-3.2-18.8 3s-14.2 49.2-15 67.2c0 0-23.1 19.6-43.3 22.8s-25-9.4-25-9.4 54.8-15.3 52.9-59.1c-1.9-43.8-44.2-27.6-49-24-4.6 3.5-29.4 18.4-36.6 59.7-.2 1.4-.7 7.5-.7 7.5s-21.2 14.2-33 18c0 0 33-55.6-7.3-80.9-18.3-11-32.8 12.1-32.8 12.1s54.5-60.7 42.5-112c-5.8-24.4-18-27.1-29.2-23.1-17 6.7-23.5 16.7-23.5 16.7s-22 32-27.1 79.5-12.6 105.1-12.6 105.1-10.5 10.2-20.2 10.7-5.4-28.7-5.4-28.7 7.5-44.6 7-52.1-1.1-11.6-9.9-14.2c-8.9-2.7-18.5 8.6-18.5 8.6s-25.5 38.7-27.7 44.6l-1.3 2.4-1.3-1.6s18-52.7.8-53.5c-17.2-.8-28.5 18.8-28.5 18.8s-19.6 32.8-20.4 36.5l-1.3-1.6s8.1-38.2 6.4-47.6c-1.6-9.4-10.5-7.5-10.5-7.5s-11.3-1.3-14.2 5.9-13.7 55.3-15 70.7c0 0-28.2 20.2-46.8 20.4-18.5.3-16.7-11.8-16.7-11.8s68-23.3 49.4-69.2c-8.3-11.8-18-15.5-31.7-15.3-13.7.3-30.3 8.6-41.3 33.3-5.3 11.8-6.8 23-7.8 31.5 0 0-12.3 2.4-18.8-2.9s-10 0-10 0-11.2 14-.1 18.3 28.1 6.1 28.1 6.1c1.6 7.5 6.2 19.5 19.6 29.7 20.2 15.3 58.8-1.3 58.8-1.3l15.9-8.8s.5 14.6 12.1 16.7c11.6 2.1 16.4 1 36.5-47.9 11.8-25 12.6-23.6 12.6-23.6l1.3-.3s-9.1 46.8-5.6 59.7C187.7 319.4 203 318 203 318s8.3 2.4 15-21.2c6.7-23.6 19.6-49.9 19.6-49.9h1.6s-5.6 48.1 3 63.7c8.6 15.6 30.9 5.3 30.9 5.3s15.6-7.8 18-10.2c0 0 18.5 15.8 44.6 12.9 58.3-11.5 79.1-25.9 79.1-25.9s10 24.4 41.1 26.7c35.5 2.7 54.8-18.6 54.8-18.6s-.3 13.5 12.1 18.6c12.4 5.1 20.7-22.8 20.7-22.8l20.7-57.2h1.9s1.1 37.3 21.5 43.2 47-13.7 47-13.7 6.4-3.5 5.3-14.3zm-578 5.3c.8-32 21.8-45.9 29-39 7.3 7 4.6 22-9.1 31.4-13.7 9.5-19.9 7.6-19.9 7.6zm272.8-123.8s19.1-49.7 23.6-25.5-40 96.2-40 96.2c.5-16.2 16.4-70.7 16.4-70.7zm22.8 138.4c-12.6 33-43.3 19.6-43.3 19.6s-3.5-11.8 6.4-44.9 33.3-20.2 33.3-20.2 16.2 12.4 3.6 45.5zm84.6-14.6s-3-10.5 8.1-30.6c11-20.2 19.6-9.1 19.6-9.1s9.4 10.2-1.3 25.5-26.4 14.2-26.4 14.2z"],empire:[496,512,[],"f1d1","M287.6 54.2c-10.8-2.2-22.1-3.3-33.5-3.6V32.4c78.1 2.2 146.1 44 184.6 106.6l-15.8 9.1c-6.1-9.7-12.7-18.8-20.2-27.1l-18 15.5c-26-29.6-61.4-50.7-101.9-58.4l4.8-23.9zM53.4 322.4l23-7.7c-6.4-18.3-10-38.2-10-58.7s3.3-40.4 9.7-58.7l-22.7-7.7c3.6-10.8 8.3-21.3 13.6-31l-15.8-9.1C34 181 24.1 217.5 24.1 256s10 75 27.1 106.6l15.8-9.1c-5.3-10-9.7-20.3-13.6-31.1zM213.1 434c-40.4-8-75.8-29.1-101.9-58.7l-18 15.8c-7.5-8.6-14.4-17.7-20.2-27.4l-16 9.4c38.5 62.3 106.8 104.3 184.9 106.6v-18.3c-11.3-.3-22.7-1.7-33.5-3.6l4.7-23.8zM93.3 120.9l18 15.5c26-29.6 61.4-50.7 101.9-58.4l-4.7-23.8c10.8-2.2 22.1-3.3 33.5-3.6V32.4C163.9 34.6 95.9 76.4 57.4 139l15.8 9.1c6-9.7 12.6-18.9 20.1-27.2zm309.4 270.2l-18-15.8c-26 29.6-61.4 50.7-101.9 58.7l4.7 23.8c-10.8 1.9-22.1 3.3-33.5 3.6v18.3c78.1-2.2 146.4-44.3 184.9-106.6l-16.1-9.4c-5.7 9.7-12.6 18.8-20.1 27.4zM496 256c0 137-111 248-248 248S0 393 0 256 111 8 248 8s248 111 248 248zm-12.2 0c0-130.1-105.7-235.8-235.8-235.8S12.2 125.9 12.2 256 117.9 491.8 248 491.8 483.8 386.1 483.8 256zm-39-106.6l-15.8 9.1c5.3 9.7 10 20.2 13.6 31l-22.7 7.7c6.4 18.3 9.7 38.2 9.7 58.7s-3.6 40.4-10 58.7l23 7.7c-3.9 10.8-8.3 21-13.6 31l15.8 9.1C462 331 471.9 294.5 471.9 256s-9.9-75-27.1-106.6zm-183 177.7c16.3-3.3 30.4-11.6 40.7-23.5l51.2 44.8c11.9-13.6 21.3-29.3 27.1-46.8l-64.2-22.1c2.5-7.5 3.9-15.2 3.9-23.5s-1.4-16.1-3.9-23.5l64.5-22.1c-6.1-17.4-15.5-33.2-27.4-46.8l-51.2 44.8c-10.2-11.9-24.4-20.5-40.7-23.8l13.3-66.4c-8.6-1.9-17.7-2.8-27.1-2.8-9.4 0-18.5.8-27.1 2.8l13.3 66.4c-16.3 3.3-30.4 11.9-40.7 23.8l-51.2-44.8c-11.9 13.6-21.3 29.3-27.4 46.8l64.5 22.1c-2.5 7.5-3.9 15.2-3.9 23.5s1.4 16.1 3.9 23.5l-64.2 22.1c5.8 17.4 15.2 33.2 27.1 46.8l51.2-44.8c10.2 11.9 24.4 20.2 40.7 23.5l-13.3 66.7c8.6 1.7 17.7 2.8 27.1 2.8 9.4 0 18.5-1.1 27.1-2.8l-13.3-66.7z"],envira:[448,512,[],"f299","M0 32c477.6 0 366.6 317.3 367.1 366.3L448 480h-26l-70.4-71.2c-39 4.2-124.4 34.5-214.4-37C47 300.3 52 214.7 0 32zm79.7 46c-49.7-23.5-5.2 9.2-5.2 9.2 45.2 31.2 66 73.7 90.2 119.9 31.5 60.2 79 139.7 144.2 167.7 65 28 34.2 12.5 6-8.5-28.2-21.2-68.2-87-91-130.2-31.7-60-61-118.6-144.2-158.1z"],erlang:[640,512,[],"f39d","M21.7 246.4c-.1 86.8 29 159.5 78.7 212.1H0v-405h87.2c-41.5 50.2-65.6 116.2-65.5 192.9zM640 53.6h-83.6c31.4 42.7 48.7 97.5 46.2 162.7.5 6 .5 11.7 0 24.1H230.2c-.2 109.7 38.9 194.9 138.6 195.3 68.5-.3 118-51 151.9-106.1l96.4 48.2c-17.4 30.9-36.5 57.8-57.9 80.8H640v-405zm-80.8 405s0-.1 0 0h-.2.2zm-3.1-405h.3l-.1-.1-.2.1zm-230.7 9.6c-45.9.1-85.1 33.5-89.2 83.2h169.9c-1.1-49.7-34.5-83.1-80.7-83.2z"],ethereum:[320,512,[],"f42e","M311.9 260.8L160 353.6 8 260.8 160 0l151.9 260.8zM160 383.4L8 290.6 160 512l152-221.4-152 92.8z"],etsy:[384,512,[],"f2d7","M384 348c-1.75 10.75-13.75 110-15.5 132-117.879-4.299-219.895-4.743-368.5 0v-25.5c45.457-8.948 60.627-8.019 61-35.25 1.793-72.322 3.524-244.143 0-322-1.029-28.46-12.13-26.765-61-36v-25.5c73.886 2.358 255.933 8.551 362.999-3.75-3.5 38.25-7.75 126.5-7.75 126.5H332C320.947 115.665 313.241 68 277.25 68h-137c-10.25 0-10.75 3.5-10.75 9.75V241.5c58 .5 88.5-2.5 88.5-2.5 29.77-.951 27.56-8.502 40.75-65.251h25.75c-4.407 101.351-3.91 61.829-1.75 160.25H257c-9.155-40.086-9.065-61.045-39.501-61.5 0 0-21.5-2-88-2v139c0 26 14.25 38.25 44.25 38.25H263c63.636 0 66.564-24.996 98.751-99.75H384z"],expeditedssl:[496,512,[],"f23e","M248 43.4C130.6 43.4 35.4 138.6 35.4 256S130.6 468.6 248 468.6 460.6 373.4 460.6 256 365.4 43.4 248 43.4zm-97.4 132.9c0-53.7 43.7-97.4 97.4-97.4s97.4 43.7 97.4 97.4v26.6c0 5-3.9 8.9-8.9 8.9h-17.7c-5 0-8.9-3.9-8.9-8.9v-26.6c0-82.1-124-82.1-124 0v26.6c0 5-3.9 8.9-8.9 8.9h-17.7c-5 0-8.9-3.9-8.9-8.9v-26.6zM389.7 380c0 9.7-8 17.7-17.7 17.7H124c-9.7 0-17.7-8-17.7-17.7V238.3c0-9.7 8-17.7 17.7-17.7h248c9.7 0 17.7 8 17.7 17.7V380zm-248-137.3v132.9c0 2.5-1.9 4.4-4.4 4.4h-8.9c-2.5 0-4.4-1.9-4.4-4.4V242.7c0-2.5 1.9-4.4 4.4-4.4h8.9c2.5 0 4.4 1.9 4.4 4.4zm141.7 48.7c0 13-7.2 24.4-17.7 30.4v31.6c0 5-3.9 8.9-8.9 8.9h-17.7c-5 0-8.9-3.9-8.9-8.9v-31.6c-10.5-6.1-17.7-17.4-17.7-30.4 0-19.7 15.8-35.4 35.4-35.4s35.5 15.8 35.5 35.4zM248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 478.3C121 486.3 17.7 383 17.7 256S121 25.7 248 25.7 478.3 129 478.3 256 375 486.3 248 486.3z"],facebook:[448,512,[],"f09a","M448 56.7v398.5c0 13.7-11.1 24.7-24.7 24.7H309.1V306.5h58.2l8.7-67.6h-67v-43.2c0-19.6 5.4-32.9 33.5-32.9h35.8v-60.5c-6.2-.8-27.4-2.7-52.2-2.7-51.6 0-87 31.5-87 89.4v49.9h-58.4v67.6h58.4V480H24.7C11.1 480 0 468.9 0 455.3V56.7C0 43.1 11.1 32 24.7 32h398.5c13.7 0 24.8 11.1 24.8 24.7z"],"facebook-f":[264,512,[],"f39e","M76.7 512V283H0v-91h76.7v-71.7C76.7 42.4 124.3 0 193.8 0c33.3 0 61.9 2.5 70.2 3.6V85h-48.2c-37.8 0-45.1 18-45.1 44.3V192H256l-11.7 91h-73.6v229"],"facebook-messenger":[448,512,[],"f39f","M224 32C15.9 32-77.5 278 84.6 400.6V480l75.7-42c142.2 39.8 285.4-59.9 285.4-198.7C445.8 124.8 346.5 32 224 32zm23.4 278.1L190 250.5 79.6 311.6l121.1-128.5 57.4 59.6 110.4-61.1-121.1 128.5z"],"facebook-square":[448,512,[],"f082","M448 80v352c0 26.5-21.5 48-48 48h-85.3V302.8h60.6l8.7-67.6h-69.3V192c0-19.6 5.4-32.9 33.5-32.9H384V98.7c-6.2-.8-27.4-2.7-52.2-2.7-51.6 0-87 31.5-87 89.4v49.9H184v67.6h60.9V480H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48z"],firefox:[480,512,[],"f269","M478.1 235.3c-.7-4.5-1.4-7.1-1.4-7.1s-1.8 2-4.7 5.9c-.9-10.7-2.8-21.2-5.8-31.6-3.7-12.9-8.5-25.4-14.5-37.4-3.8-8-8.2-15.6-13.3-22.8-1.8-2.7-3.7-5.4-5.6-7.9-8.8-14.4-19-23.3-30.7-40-7.6-12.8-12.9-26.9-15.4-41.6-3.2 8.9-5.7 18-7.4 27.3-12.1-12.2-22.5-20.8-28.9-26.7C319.4 24.2 323 9.1 323 9.1S264.7 74.2 289.9 142c8.7 23 23.8 43.1 43.4 57.9 24.4 20.2 50.8 36 64.7 76.6-11.2-21.3-28.1-39.2-48.8-51.5 6.2 14.7 9.4 30.6 9.3 46.5 0 61-49.6 110.5-110.6 110.4-8.3 0-16.5-.9-24.5-2.8-9.5-1.8-18.7-4.9-27.4-9.3-12.9-7.8-24-18.1-32.8-30.3l-.2-.3 2 .7c4.6 1.6 9.2 2.8 14 3.7 18.7 4 38.3 1.7 55.6-6.6 17.5-9.7 28-16.9 36.6-14h.2c8.4 2.7 15-5.5 9-14-10.4-13.4-27.4-20-44.2-17-17.5 2.5-33.5 15-56.4 2.9-1.5-.8-2.9-1.6-4.3-2.5-1.6-.9 4.9 1.3 3.4.3-5-2.5-9.8-5.4-14.4-8.6-.3-.3 3.5 1.1 3.1.8-5.9-4-11-9.2-15-15.2-4.1-7.4-4.5-16.4-1-24.1 2.1-3.8 5.4-6.9 9.3-8.7 3 1.5 4.8 2.6 4.8 2.6s-1.3-2.5-2.1-3.8c.3-.1.5 0 .8-.2 2.6 1.1 8.3 4 11.4 5.8 2.1 1.1 3.8 2.7 5.2 4.7 0 0 1-.5.3-2.7-1.1-2.7-2.9-5-5.4-6.6h.2c2.3 1.2 4.5 2.6 6.6 4.1 1.9-4.4 2.8-9.2 2.6-14 .2-2.6-.2-5.3-1.1-7.8-.8-1.6.5-2.2 1.9-.5-.2-1.3-.7-2.5-1.2-3.7v-.1s.8-1.1 1.2-1.5c1-1 2.1-1.9 3.4-2.7 7.2-4.5 14.8-8.4 22.7-11.6 6.4-2.8 11.7-4.9 12.8-5.6 1.6-1 3.1-2.2 4.5-3.5 5.3-4.5 9-10.8 10.2-17.7.1-.9.2-1.8.3-2.8v-1.5c-.9-3.5-6.9-6.1-38.4-9.1-11.1-1.8-20-10.1-22.5-21.1v.1c-.4 1.1-.9 2.3-1.3 3.5.4-1.2.8-2.3 1.3-3.5v-.2c6-15.7 16.8-29.1 30.8-38.3.8-.7-3.2.2-2.4-.5 2.7-1.3 5.4-2.5 8.2-3.5 1.4-.6-6-3.4-12.6-2.7-4 .2-8 1.2-11.7 2.8 1.6-1.3 6.2-3.1 5.1-3.1-8.4 1.6-16.5 4.7-23.9 9 0-.8.1-1.5.5-2.2-5.9 2.5-11 6.5-15 11.5.1-.9.2-1.8.2-2.7-2.7 2-5.2 4.3-7.3 6.9l-.1.1c-17.4-6.7-36.3-8.3-54.6-4.7l-.2-.1h.2c-3.8-3.1-7.1-6.7-9.7-10.9l-.2.1-.4-.2c-1.2-1.8-2.4-3.8-3.7-6-.9-1.6-1.8-3.4-2.7-5.2 0-.1-.1-.2-.2-.2-.4 0-.6 1.7-.9 1.3v-.1c-3.2-8.3-4.7-17.2-4.4-26.2l-.2.1c-5.1 3.5-9 8.6-11.1 14.5-.9 2.1-1.6 3.3-2.2 4.5v-.5c.1-1.1.6-3.3.5-3.1-.1.2-.2.3-.3.4-1.5 1.7-2.9 3.7-3.9 5.8-.9 1.9-1.7 3.9-2.3 5.9-.1.3 0-.3 0-1s.1-2 0-1.7l-.3.7c-6.7 14.9-10.9 30.8-12.4 47.1-.4 2.8-.6 5.6-.5 8.3v.2c-4.8 5.2-9 11-12.7 17.1-12.1 20.4-21.1 42.5-26.8 65.6 4-8.8 8.8-17.2 14.3-25.1C5.5 228.5 0 257.4 0 286.6c1.8-8.6 4.2-17 7-25.3-1.7 34.5 4.9 68.9 19.4 100.3 19.4 43.5 51.6 80 92.3 104.7 16.6 11.2 34.7 19.9 53.8 25.8 2.5.9 5.1 1.8 7.7 2.7-.8-.3-1.6-.7-2.4-1 22.6 6.8 46.2 10.3 69.8 10.3 83.7 0 111.3-31.9 113.8-35 4.1-3.7 7.5-8.2 9.9-13.3 1.6-.7 3.2-1.4 4.9-2.1l1-.5 1.9-.9c12.6-5.9 24.5-13.4 35.3-22.1 16.3-11.7 27.9-28.7 32.9-48.1 3-7.1 3.1-15 .4-22.2.9-1.4 1.7-2.8 2.7-4.3 18-28.9 28.2-61.9 29.6-95.9v-2.8c0-7.3-.6-14.5-1.9-21.6z"],"first-order":[448,512,[],"f2b0","M12.9 229.2c.1-.1.2-.3.3-.4 0 .1 0 .3-.1.4h-.2zM224 96.6c-7.1 0-14.6.6-21.4 1.7l3.7 67.4-22-64c-14.3 3.7-27.7 9.4-40 16.6l29.4 61.4-45.1-50.9c-11.4 8.9-21.7 19.1-30.6 30.9l50.6 45.4-61.1-29.7c-7.1 12.3-12.9 25.7-16.6 40l64.3 22.6-68-4c-.9 7.1-1.4 14.6-1.4 22s.6 14.6 1.4 21.7l67.7-4-64 22.6c3.7 14.3 9.4 27.7 16.6 40.3l61.1-29.7L97.7 352c8.9 11.7 19.1 22.3 30.9 30.9l44.9-50.9-29.5 61.4c12.3 7.4 25.7 13.1 40 16.9l22.3-64.6-4 68c7.1 1.1 14.6 1.7 21.7 1.7 7.4 0 14.6-.6 21.7-1.7l-4-68.6 22.6 65.1c14.3-4 27.7-9.4 40-16.9L274.9 332l44.9 50.9c11.7-8.9 22-19.1 30.6-30.9l-50.6-45.1 61.1 29.4c7.1-12.3 12.9-25.7 16.6-40.3l-64-22.3 67.4 4c1.1-7.1 1.4-14.3 1.4-21.7s-.3-14.9-1.4-22l-67.7 4 64-22.3c-3.7-14.3-9.1-28-16.6-40.3l-60.9 29.7 50.6-45.4c-8.9-11.7-19.1-22-30.6-30.9l-45.1 50.9 29.4-61.1c-12.3-7.4-25.7-13.1-40-16.9L241.7 166l4-67.7c-7.1-1.2-14.3-1.7-21.7-1.7zM443.4 128v256L224 512 4.6 384V128L224 0l219.4 128zm-17.1 10.3L224 20.9 21.7 138.3v235.1L224 491.1l202.3-117.7V138.3zM224 37.1l187.7 109.4v218.9L224 474.9 36.3 365.4V146.6L224 37.1zm0 50.9c-92.3 0-166.9 75.1-166.9 168 0 92.6 74.6 167.7 166.9 167.7 92 0 166.9-75.1 166.9-167.7 0-92.9-74.9-168-166.9-168z"],firstdraft:[384,512,[],"f3a1","M384 192h-64v128H192v128H0v-25.6h166.4v-128h128v-128H384V192zm-25.6 38.4v128h-128v128H64V512h192V384h128V230.4h-25.6zm25.6 192h-89.6V512H320v-64h64v-25.6zM0 0v384h128V256h128V128h128V0H0z"],flickr:[448,512,[],"f16e","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM144.5 319c-35.1 0-63.5-28.4-63.5-63.5s28.4-63.5 63.5-63.5 63.5 28.4 63.5 63.5-28.4 63.5-63.5 63.5zm159 0c-35.1 0-63.5-28.4-63.5-63.5s28.4-63.5 63.5-63.5 63.5 28.4 63.5 63.5-28.4 63.5-63.5 63.5z"],flipboard:[448,512,[],"f44d","M0 32v448h448V32H0zm358.4 179.2h-89.6v89.6h-89.6v89.6H89.6V121.6h268.8v89.6z"],fly:[384,512,[],"f417","M197.8 427.8c12.9 11.7 33.7 33.3 33.2 50.7 0 .8-.1 1.6-.1 2.5-1.8 19.8-18.8 31.1-39.1 31-25-.1-39.9-16.8-38.7-35.8 1-16.2 20.5-36.7 32.4-47.6 2.3-2.1 2.7-2.7 5.6-3.6 3.4 0 3.9.3 6.7 2.8zM331.9 67.3c-16.3-25.7-38.6-40.6-63.3-52.1C243.1 4.5 214-.2 192 0c-44.1 0-71.2 13.2-81.1 17.3C57.3 45.2 26.5 87.2 28 158.6c7.1 82.2 97 176 155.8 233.8 1.7 1.6 4.5 4.5 6.2 5.1l3.3.1c2.1-.7 1.8-.5 3.5-2.1 52.3-49.2 140.7-145.8 155.9-215.7 7-39.2 3.1-72.5-20.8-112.5zM186.8 351.9c-28-51.1-65.2-130.7-69.3-189-3.4-47.5 11.4-131.2 69.3-136.7v325.7zM328.7 180c-16.4 56.8-77.3 128-118.9 170.3C237.6 298.4 275 217 277 158.4c1.6-45.9-9.8-105.8-48-131.4 88.8 18.3 115.5 98.1 99.7 153z"],"font-awesome":[448,512,[],"f2b4","M397.8 32H50.2C22.7 32 0 54.7 0 82.2v347.6C0 457.3 22.7 480 50.2 480h347.6c27.5 0 50.2-22.7 50.2-50.2V82.2c0-27.5-22.7-50.2-50.2-50.2zm-45.4 284.3c0 4.2-3.6 6-7.8 7.8-16.7 7.2-34.6 13.7-53.8 13.7-26.9 0-39.4-16.7-71.7-16.7-23.3 0-47.8 8.4-67.5 17.3-1.2.6-2.4.6-3.6 1.2V385c0 1.8 0 3.6-.6 4.8v1.2c-2.4 8.4-10.2 14.3-19.1 14.3-11.3 0-20.3-9-20.3-20.3V166.4c-7.8-6-13.1-15.5-13.1-26.3 0-18.5 14.9-33.5 33.5-33.5 18.5 0 33.5 14.9 33.5 33.5 0 10.8-4.8 20.3-13.1 26.3v18.5c1.8-.6 3.6-1.2 5.4-2.4 18.5-7.8 40.6-14.3 61.5-14.3 22.7 0 40.6 6 60.9 13.7 4.2 1.8 8.4 2.4 13.1 2.4 22.7 0 47.8-16.1 53.8-16.1 4.8 0 9 3.6 9 7.8v140.3z"],"font-awesome-alt":[448,512,[],"f35c","M397.8 67.8c7.8 0 14.3 6.6 14.3 14.3v347.6c0 7.8-6.6 14.3-14.3 14.3H50.2c-7.8 0-14.3-6.6-14.3-14.3V82.2c0-7.8 6.6-14.3 14.3-14.3h347.6m0-35.9H50.2C22.7 32 0 54.7 0 82.2v347.6C0 457.3 22.7 480 50.2 480h347.6c27.5 0 50.2-22.7 50.2-50.2V82.2c0-27.5-22.7-50.2-50.2-50.2zm-58.5 139.2c-6 0-29.9 15.5-52.6 15.5-4.2 0-8.4-.6-12.5-2.4-19.7-7.8-37-13.7-59.1-13.7-20.3 0-41.8 6.6-59.7 13.7-1.8.6-3.6 1.2-4.8 1.8v-17.9c7.8-6 12.5-14.9 12.5-25.7 0-17.9-14.3-32.3-32.3-32.3s-32.3 14.3-32.3 32.3c0 10.2 4.8 19.7 12.5 25.7v212.1c0 10.8 9 19.7 19.7 19.7 9 0 16.1-6 18.5-13.7V385c.6-1.8.6-3 .6-4.8V336c1.2 0 2.4-.6 3-1.2 19.7-8.4 43-16.7 65.7-16.7 31.1 0 43 16.1 69.3 16.1 18.5 0 36.4-6.6 52-13.7 4.2-1.8 7.2-3.6 7.2-7.8V178.3c1.8-4.1-2.3-7.1-7.7-7.1z"],"font-awesome-flag":[448,512,[],"f425","M444.373 359.424c0 7.168-6.144 10.24-13.312 13.312-28.672 12.288-59.392 23.552-92.16 23.552-46.08 0-67.584-28.672-122.88-28.672-39.936 0-81.92 14.336-115.712 29.696-2.048 1.024-4.096 1.024-6.144 2.048v77.824c0 21.405-16.122 34.816-33.792 34.816-19.456 0-34.816-15.36-34.816-34.816V102.4C12.245 92.16 3.029 75.776 3.029 57.344 3.029 25.6 28.629 0 60.373 0s57.344 25.6 57.344 57.344c0 18.432-8.192 34.816-22.528 45.056v31.744c4.124-1.374 58.768-28.672 114.688-28.672 65.27 0 97.676 27.648 126.976 27.648 38.912 0 81.92-27.648 92.16-27.648 8.192 0 15.36 6.144 15.36 13.312v240.64z"],fonticons:[448,512,[],"f280","M0 32v448h448V32H0zm167.4 196h67.4l-11.1 37.3H168v112.9c0 5.8-2 6.7 3.2 7.3l43.5 4.1v25.1H84V389l21.3-2c5.2-.6 6.7-2.3 6.7-7.9V267.7c0-2.3-2.9-2.3-5.8-2.3H84V228h28v-21c0-49.6 26.5-70 77.3-70 34.1 0 64.7 8.2 64.7 52.8l-50.7 6.1c.3-18.7-4.4-23-16.3-23-18.4 0-19 9.9-19 27.4v23.3c0 2.4-3.5 4.4-.6 4.4zM364 414.7H261.3v-25.1l20.4-2.6c5.2-.6 7.6-1.7 7.6-7.3V271.8c0-4.1-2.9-6.7-6.7-7.9l-24.2-6.4 6.7-29.5h80.2v151.7c0 5.8-2.6 6.4 2.9 7.3l15.7 2.6v25.1zm-21.9-255.5l9 33.2-7.3 7.3-31.2-16.6-31.2 16.6-7.3-7.3 9-33.2-21.8-24.2 3.5-9.6h27.7l15.5-28h9.3l15.5 28h27.7l3.5 9.6-21.9 24.2z"],"fonticons-fi":[384,512,[],"f3a2","M114.4 224h92.4l-15.2 51.2h-76.4V433c0 8-2.8 9.2 4.4 10l59.6 5.6V483H0v-35.2l29.2-2.8c7.2-.8 9.2-3.2 9.2-10.8V278.4c0-3.2-4-3.2-8-3.2H0V224h38.4v-28.8c0-68 36.4-96 106-96 46.8 0 88.8 11.2 88.8 72.4l-69.6 8.4c.4-25.6-6-31.6-22.4-31.6-25.2 0-26 13.6-26 37.6v32c0 3.2-4.8 6-.8 6zM384 483H243.2v-34.4l28-3.6c7.2-.8 10.4-2.4 10.4-10V287c0-5.6-4-9.2-9.2-10.8l-33.2-8.8 9.2-40.4h110v208c0 8-3.6 8.8 4 10l21.6 3.6V483zm-30-347.2l12.4 45.6-10 10-42.8-22.8-42.8 22.8-10-10 12.4-45.6-30-36.4 4.8-10h38L307.2 51H320l21.2 38.4h38l4.8 13.2-30 33.2z"],"fort-awesome":[512,512,[],"f286","M489.2 287.9h-27.4c-2.6 0-4.6 2-4.6 4.6v32h-36.6V146.2c0-2.6-2-4.6-4.6-4.6h-27.4c-2.6 0-4.6 2-4.6 4.6v32h-36.6v-32c0-2.6-2-4.6-4.6-4.6h-27.4c-2.6 0-4.6 2-4.6 4.6v32h-36.6v-32c0-6-8-4.6-11.7-4.6v-38c8.3-2 17.1-3.4 25.7-3.4 10.9 0 20.9 4.3 31.4 4.3 4.6 0 27.7-1.1 27.7-8v-60c0-2.6-2-4.6-4.6-4.6-5.1 0-15.1 4.3-24 4.3-9.7 0-20.9-4.3-32.6-4.3-8 0-16 1.1-23.7 2.9v-4.9c5.4-2.6 9.1-8.3 9.1-14.3 0-20.7-31.4-20.8-31.4 0 0 6 3.7 11.7 9.1 14.3v111.7c-3.7 0-11.7-1.4-11.7 4.6v32h-36.6v-32c0-2.6-2-4.6-4.6-4.6h-27.4c-2.6 0-4.6 2-4.6 4.6v32H128v-32c0-2.6-2-4.6-4.6-4.6H96c-2.6 0-4.6 2-4.6 4.6v178.3H54.8v-32c0-2.6-2-4.6-4.6-4.6H22.8c-2.6 0-4.6 2-4.6 4.6V512h182.9v-96c0-72.6 109.7-72.6 109.7 0v96h182.9V292.5c.1-2.6-1.9-4.6-4.5-4.6zm-288.1-4.5c0 2.6-2 4.6-4.6 4.6h-27.4c-2.6 0-4.6-2-4.6-4.6v-64c0-2.6 2-4.6 4.6-4.6h27.4c2.6 0 4.6 2 4.6 4.6v64zm146.4 0c0 2.6-2 4.6-4.6 4.6h-27.4c-2.6 0-4.6-2-4.6-4.6v-64c0-2.6 2-4.6 4.6-4.6h27.4c2.6 0 4.6 2 4.6 4.6v64z"],"fort-awesome-alt":[512,512,[],"f3a3","M211.7 241.1v51.7c0 2.1-1.6 3.7-3.7 3.7h-22.2c-2.1 0-3.7-1.6-3.7-3.7v-51.7c0-2.1 1.6-3.7 3.7-3.7H208c2.1 0 3.7 1.6 3.7 3.7zm114.5-3.7H304c-2.1 0-3.7 1.6-3.7 3.7v51.7c0 2.1 1.6 3.7 3.7 3.7h22.2c2.1 0 3.7-1.6 3.7-3.7v-51.7c-.1-2.1-1.7-3.7-3.7-3.7zm-29.1 263.2c-.9.1-1.7.3-2.6.4-1 .2-2.1.3-3.1.5-.9.1-1.8.3-2.8.4-1 .1-2 .3-3 .4-1 .1-2 .2-2.9.3-1 .1-1.9.2-2.9.3-1 .1-2.1.2-3.1.3-.9.1-1.8.2-2.7.2-1.1.1-2.3.1-3.4.2-.8 0-1.7.1-2.5.1-1.3.1-2.6.1-3.9.1-.7 0-1.4.1-2.1.1-2 0-4 .1-6 .1s-4 0-6-.1c-.7 0-1.4 0-2.1-.1-1.3 0-2.6-.1-3.9-.1-.8 0-1.7-.1-2.5-.1-1.1-.1-2.3-.1-3.4-.2-.9-.1-1.8-.1-2.7-.2-1-.1-2.1-.2-3.1-.3-1-.1-1.9-.2-2.9-.3-1-.1-2-.2-2.9-.3-1-.1-2-.2-3-.4-.9-.1-1.8-.3-2.8-.4-1-.1-2.1-.3-3.1-.5-.9-.1-1.7-.3-2.6-.4-65.6-10.9-122.5-47.7-160-99.4-.2-.2-.3-.5-.5-.7-.8-1.1-1.6-2.2-2.3-3.3-.3-.4-.6-.8-.8-1.2-.7-1.1-1.4-2.1-2.1-3.2-.3-.5-.6-.9-.9-1.4-.7-1.1-1.4-2.1-2-3.2-.3-.5-.6-.9-.9-1.4-.7-1.1-1.3-2.2-2-3.3-.2-.4-.5-.8-.7-1.2-2.4-4-4.6-8.1-6.8-12.2-.1-.2-.2-.3-.3-.5-.6-1.1-1.1-2.2-1.7-3.3-.3-.6-.6-1.1-.8-1.7-.5-1-1-2.1-1.5-3.1-.3-.7-.6-1.3-.9-2-.5-1-.9-2-1.4-3l-.9-2.1c-.4-1-.9-2-1.3-3-.3-.7-.6-1.5-.9-2.2l-1.2-3c-.3-.8-.6-1.5-.9-2.3-.4-1-.8-2-1.1-3-.3-.9-.6-1.8-1-2.8-.6-1.6-1.1-3.3-1.7-4.9-.3-.9-.6-1.8-.9-2.8-.3-.9-.5-1.8-.8-2.7-.3-.9-.6-1.9-.8-2.8-.3-.9-.5-1.8-.8-2.7-.3-1-.5-1.9-.8-2.9-.2-.9-.5-1.8-.7-2.7-.3-1-.5-2-.7-3-.2-.9-.4-1.7-.6-2.6-.2-1.1-.5-2.2-.7-3.2-.2-.8-.3-1.6-.5-2.4-.3-1.3-.5-2.7-.8-4-.1-.6-.2-1.1-.3-1.7l-.9-5.7c-.1-.6-.2-1.3-.3-1.9-.2-1.3-.4-2.6-.5-3.9-.1-.8-.2-1.5-.3-2.3-.1-1.2-.3-2.4-.4-3.6-.1-.8-.2-1.6-.2-2.4-.1-1.2-.2-2.4-.3-3.5-.1-.8-.1-1.6-.2-2.4-.1-1.2-.2-2.4-.2-3.7 0-.8-.1-1.5-.1-2.3-.1-1.3-.1-2.7-.2-4 0-.7 0-1.3-.1-2 0-2-.1-4-.1-6 0-53.5 16.9-103 45.8-143.6 2.3-3.2 4.7-6.4 7.1-9.5 4.9-6.2 10.1-12.3 15.6-18 2.7-2.9 5.5-5.7 8.4-8.4 2.9-2.7 5.8-5.4 8.8-8 4.5-3.9 9.1-7.6 13.9-11.2 1.6-1.2 3.2-2.4 4.8-3.5C140 34.2 171.7 20.1 206 13c16.1-3.3 32.9-5 50-5s33.8 1.7 50 5c34.3 7 66 21.1 93.6 40.7 1.6 1.2 3.2 2.3 4.8 3.5 4.8 3.6 9.4 7.3 13.9 11.2 12 10.4 23 21.9 32.8 34.4 2.5 3.1 4.8 6.3 7.1 9.5C487.1 153 504 202.5 504 256c0 2 0 4-.1 6 0 .7 0 1.3-.1 2 0 1.3-.1 2.7-.2 4 0 .8-.1 1.5-.1 2.3-.1 1.2-.1 2.4-.2.7-.1.8-.1 1.6-.2 2.4-.1 1.2-.2 2.4-.3 3.5-.1.8-.2 1.6-.2 2.4-.1 1.2-.3 2.4-.4 3.6-.1.8-.2 1.5-.3 2.3-.2 1.3-.4 2.6-.5 3.9-.1.6-.2 1.3-.3 1.9l-.9 5.7c-.1.6-.2 1.1-.3 1.7-.2 1.3-.5 2.7-.8 4-.2.8-.3 1.6-.5 2.4-.2 1.1-.5 2.2-.7 3.2-.2.9-.4 1.7-.6 2.6-.2 1-.5 2-.7 3-.2.9-.5 1.8-.7 2.7-.3 1-.5 1.9-.8 2.9-.2.9-.5 1.8-.8 2.7-.3.9-.6 1.9-.8 2.8-.3.9-.5 1.8-.8 2.7-.3.9-.6 1.8-.9 2.8-.5 1.6-1.1 3.3-1.7 4.9-.3.9-.6 1.8-1 2.8-.4 1-.7 2-1.1 3-.3.8-.6 1.5-.9 2.3l-1.2 3c-.3.7-.6 1.5-.9 2.2-.4 1-.8 2-1.3 3l-.9 2.1c-.4 1-.9 2-1.4 3-.3.7-.6 1.3-.9 2-.5 1-1 2.1-1.5 3.1-.3.6-.6 1.1-.8 1.7-.6 1.1-1.1 2.2-1.7 3.3-.1.2-.2.3-.3.5-2.2 4.1-4.4 8.2-6.8 12.2-.2.4-.5.8-.7 1.2-.7 1.1-1.3 2.2-2 3.3-.3.5-.6.9-.9 1.4-.7 1.1-1.4 2.1-2 3.2-.3.5-.6.9-.9 1.4-.7 1.1-1.4 2.1-2.1 3.2-.3.4-.6.8-.8 1.2-.8 1.1-1.5 2.2-2.3 3.3-.2.2-.3.5-.5.7-37.6 54.7-94.5 91.4-160.1 102.4zm117.3-86.2c13-13 24.2-27.4 33.6-42.9v-71.3c0-2.1-1.6-3.7-3.7-3.7h-22.2c-2.1 0-3.7 1.6-3.7 3.7V326h-29.5V182c0-2.1-1.6-3.7-3.7-3.7h-22.1c-2.1 0-3.7 1.6-3.7 3.7v25.9h-29.5V182c0-2.1-1.6-3.7-3.7-3.7H304c-2.1 0-3.7 1.6-3.7 3.7v25.9h-29.5V182c0-4.8-6.5-3.7-9.5-3.7v-30.7c6.7-1.6 13.8-2.8 20.8-2.8 8.8 0 16.8 3.5 25.4 3.5 3.7 0 22.4-.9 22.4-6.5V93.4c0-2.1-1.6-3.7-3.7-3.7-4.2 0-12.2 3.5-19.4 3.5-7.9 0-16.9-3.5-26.3-3.5-6.5 0-12.9.9-19.2 2.3v-3.9c4.4-2.1 7.4-6.7 7.4-11.5 0-16.8-25.4-16.8-25.4 0 0 4.8 3 9.5 7.4 11.5v90.2c-3 0-9.5-1.1-9.5 3.7v25.9h-29.5V182c0-2.1-1.6-3.7-3.7-3.7h-22.2c-2.1 0-3.7 1.6-3.7 3.7v25.9h-29.5V182c0-2.1-1.6-3.7-3.7-3.7h-22.1c-2.1 0-3.7 1.6-3.7 3.7v144H93.5v-25.8c0-2.1-1.6-3.7-3.7-3.7H67.7c-2.1 0-3.7 1.6-3.7 3.7v71.3c9.4 15.5 20.6 29.9 33.6 42.9 20.6 20.6 44.5 36.7 71.2 48 13.9 5.9 28.2 10.3 42.9 13.2v-75.8c0-58.6 88.6-58.6 88.6 0v75.8c14.7-2.9 29-7.4 42.9-13.2 26.7-11.3 50.6-27.4 71.2-48"],forumbee:[448,512,[],"f211","M5.8 309.7C2 292.7 0 275.5 0 258.3 0 135 99.8 35 223.1 35c16.6 0 33.3 2 49.3 5.5C149 87.5 51.9 186 5.8 309.7zm392.9-189.2C385 103 369 87.8 350.9 75.2c-149.6 44.3-266.3 162.1-309.7 312 12.5 18.1 28 35.6 45.2 49 43.1-151.3 161.2-271.7 312.3-315.7zm15.8 252.7c15.2-25.1 25.4-53.7 29.5-82.8-79.4 42.9-145 110.6-187.6 190.3 30-4.4 58.9-15.3 84.6-31.3 35 13.1 70.9 24.3 107 33.6-9.3-36.5-20.4-74.5-33.5-109.8zm29.7-145.5c-2.6-19.5-7.9-38.7-15.8-56.8C290.5 216.7 182 327.5 137.1 466c18.1 7.6 37 12.5 56.6 15.2C240 367.1 330.5 274.4 444.2 227.7z"],foursquare:[368,512,[],"f180","M323.1 3H49.9C12.4 3 0 31.3 0 49.1v433.8c0 20.3 12.1 27.7 18.2 30.1 6.2 2.5 22.8 4.6 32.9-7.1C180 356.5 182.2 354 182.2 354c3.1-3.4 3.4-3.1 6.8-3.1h83.4c35.1 0 40.6-25.2 44.3-39.7l48.6-243C373.8 25.8 363.1 3 323.1 3zm-16.3 73.8l-11.4 59.7c-1.2 6.5-9.5 13.2-16.9 13.2H172.1c-12 0-20.6 8.3-20.6 20.3v13c0 12 8.6 20.6 20.6 20.6h90.4c8.3 0 16.6 9.2 14.8 18.2-1.8 8.9-10.5 53.8-11.4 58.8-.9 4.9-6.8 13.5-16.9 13.5h-73.5c-13.5 0-17.2 1.8-26.5 12.6 0 0-8.9 11.4-89.5 108.3-.9.9-1.8.6-1.8-.3V75.9c0-7.7 6.8-16.6 16.6-16.6h219c8.2 0 15.6 7.7 13.5 17.5z"],"free-code-camp":[576,512,[],"f2c5","M69.3 144.5c-41 68.5-36.4 163 1 227C92.5 409.7 120 423.9 120 438c0 6.8-6 13-12.8 13C87.7 451 8 375.5 8 253.2c0-111.5 78-186 97.1-186 6 0 14.9 4.8 14.9 11.1 0 12.7-28.3 28.6-50.7 66.2zm195.8 213.8c4.5 1.8 12.3 5.2 12.3-1.2 0-2.7-2.2-2.9-4.3-3.6-8.5-3.4-14-7.7-19.1-15.2-8.2-12.1-10.1-24.2-10.1-38.6 0-32.1 44.2-37.9 44.2-70 0-12.3-7.7-15.9-7.7-19.3 0-2.2.7-2.2 2.9-2.2 8 0 19.1 13.3 22.5 19.8 2.2 4.6 2.4 6 2.4 11.1 0 7-.7 14.2-.7 21.3 0 27 31.9 19.8 31.9 6.8 0-6-3.6-11.6-3.6-17.4 0-.7 0-1.2.7-1.2 3.4 0 9.4 7.7 11.1 10.1 5.8 8.9 8.5 20.8 8.5 31.4 0 32.4-29.5 49-29.5 56 0 1 2.9 7.7 12.1 1.9 29.7-15.1 53.1-47.6 53.1-89.8 0-33.6-8.7-57.7-32.1-82.6-3.9-4.1-16.4-16.9-22.5-16.9-8.2 0 7.2 18.6 7.2 31.2 0 7.2-4.8 12.3-12.3 12.3-11.6 0-14.5-25.4-15.9-33.3-5.8-33.8-12.8-58.2-46.4-74.1-10.4-5-36.5-11.8-36.5-2.2 0 2.4 2.7 4.1 4.6 5.1 9.2 5.6 19.6 21.4 19.6 38.2 0 46.1-57.7 88.2-57.7 136.2-.2 40.3 28.1 72.6 65.3 86.2zM470.4 67c-6 0-14.4 6.5-14.4 12.6 0 8.7 12.1 19.6 17.6 25.4 81.6 85.1 78.6 214.3 17.6 291-7 8.9-35.3 35.3-35.3 43.5 0 5.1 8.2 11.4 13.2 11.4 25.4 0 98.8-80.8 98.8-185.7C568 145.9 491.8 67 470.4 67zm-42.3 323.1H167c-9.4 0-15.5 7.5-15.5 16.4 0 8.5 7 15.5 15.5 15.5h261.1c9.4 0 11.9-7.5 11.9-16.4 0-8.5-3.5-15.5-11.9-15.5z"],freebsd:[448,512,[],"f3a4","M303.7 96.2c11.1-11.1 115.5-77 139.2-53.2 23.7 23.7-42.1 128.1-53.2 139.2-11.1 11.1-39.4.9-63.1-22.9-23.8-23.7-34.1-52-22.9-63.1zM109.9 68.1C73.6 47.5 22 24.6 5.6 41.1c-16.6 16.6 7.1 69.4 27.9 105.7 18.5-32.2 44.8-59.3 76.4-78.7zM406.7 174c3.3 11.3 2.7 20.7-2.7 26.1-20.3 20.3-87.5-27-109.3-70.1-18-32.3-11.1-53.4 14.9-48.7 5.7-3.6 12.3-7.6 19.6-11.6-29.8-15.5-63.6-24.3-99.5-24.3-119.1 0-215.6 96.5-215.6 215.6 0 119 96.5 215.6 215.6 215.6S445.3 380.1 445.3 261c0-38.4-10.1-74.5-27.7-105.8-3.9 7-7.6 13.3-10.9 18.8z"],"get-pocket":[448,512,[],"f265","M407.6 64h-367C18.5 64 0 82.5 0 104.6v135.2C0 364.5 99.7 464 224.2 464c124 0 223.8-99.5 223.8-224.2V104.6c0-22.4-17.7-40.6-40.4-40.6zm-162 268.5c-12.4 11.8-31.4 11.1-42.4 0C89.5 223.6 88.3 227.4 88.3 209.3c0-16.9 13.8-30.7 30.7-30.7 17 0 16.1 3.8 105.2 89.3 90.6-86.9 88.6-89.3 105.5-89.3 16.9 0 30.7 13.8 30.7 30.7 0 17.8-2.9 15.7-114.8 123.2z"],gg:[512,512,[],"f260","M179.2 230.4l102.4 102.4-102.4 102.4L0 256 179.2 76.8l44.8 44.8-25.6 25.6-19.2-19.2-128 128 128 128 51.5-51.5-77.1-76.5 25.6-25.6zM332.8 76.8L230.4 179.2l102.4 102.4 25.6-25.6-77.1-76.5 51.5-51.5 128 128-128 128-19.2-19.2-25.6 25.6 44.8 44.8L512 256 332.8 76.8z"],"gg-circle":[512,512,[],"f261","M257 8C120 8 9 119 9 256s111 248 248 248 248-111 248-248S394 8 257 8zm-49.5 374.8L81.8 257.1l125.7-125.7 35.2 35.4-24.2 24.2-11.1-11.1-77.2 77.2 77.2 77.2 26.6-26.6-53.1-52.9 24.4-24.4 77.2 77.2-75 75.2zm99-2.2l-35.2-35.2 24.1-24.4 11.1 11.1 77.2-77.2-77.2-77.2-26.5 26.5 53.1 52.9-24.4 24.4-77.2-77.2 75-75L432.2 255 306.5 380.6z"],git:[448,512,[],"f1d3","M18.8 221.7c0 25.3 16.2 60 41.5 68.5v1c-18.8 8.3-24 50.6 1 65.8v1C34 367 16 384.3 16 414.2c0 51.5 48.8 65.8 91.5 65.8 52 0 90.7-18.7 90.7-76 0-70.5-101-44.5-101-82.8 0-13.5 7.2-18.7 19.7-21.3 41.5-7.7 67.5-40 67.5-82.2 0-7.3-1.5-14.2-4-21 6.7-1.5 13.2-3.3 19.7-5.5v-50.5c-17.2 6.8-35.7 11.8-54.5 11.8-53.8-31-126.8 1.3-126.8 69.2zm87.7 163.8c17 0 41.2 3 41.2 25 0 21.8-19.5 26.3-37.7 26.3-17.3 0-43.3-2.7-43.3-25.2.1-22.3 22.1-26.1 39.8-26.1zM103.3 256c-22 0-31.3-13-31.3-33.8 0-49.3 61-48.8 61-.5 0 20.3-8 34.3-29.7 34.3zM432 305.5v49c-13.3 7.3-30.5 9.8-45.5 9.8-53.5 0-59.8-42.2-59.8-85.7v-87.7h.5v-1c-7 0-7.3-1.6-24 1v-47.5h24c0-22.3.3-31-1.5-41.2h56.7c-2 13.8-1.5 27.5-1.5 41.2h51v47.5s-19.3-1-51-1V281c0 14.8 3.3 32.8 21.8 32.8 9.8 0 21.3-2.8 29.3-8.3zM286 68.7c0 18.7-14.5 36.2-33.8 36.2-19.8 0-34.5-17.2-34.5-36.2 0-19.3 14.5-36.7 34.5-36.7C272 32 286 50 286 68.7zm-6.2 74.5c-1.8 14.6-1.6 199.8 0 217.8h-55.5c1.6-18.1 1.8-203 0-217.8h55.5z"],"git-square":[448,512,[],"f1d2","M140.1 348.5c12.1 0 29.5 2.1 29.5 17.9 0 15.5-13.9 18.8-27 18.8-12.3 0-30.9-2-30.9-18s15.7-18.7 28.4-18.7zm-24.7-116.6c0 14.8 6.6 24.1 22.3 24.1 15.5 0 21.2-10 21.2-24.5.1-34.4-43.5-34.8-43.5.4zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-241 93.7c-12.3 4.8-25.5 8.4-38.9 8.4-38.5-22.1-90.7.9-90.7 49.5 0 18 11.6 42.9 29.6 48.9v.7c-13.4 5.9-17.1 36.1.7 47v.7c-19.5 6.4-32.3 18.8-32.3 40.2 0 36.8 34.8 47 65.4 47 37.1 0 64.8-13.4 64.8-54.3 0-50.4-72.1-31.8-72.1-59.1 0-9.6 5.2-13.4 14.1-15.2 29.6-5.5 48.2-28.6 48.2-58.7 0-5.2-1.1-10.2-2.9-15 4.8-1.1 9.5-2.3 14.1-3.9v-36.2zm56.8 1.8h-39.6c1.3 10.6 1.1 142.6 0 155.5h39.6c-1.1-12.8-1.2-145.1 0-155.5zm4.5-53.3c0-13.4-10-26.2-24.1-26.2-14.3 0-24.6 12.5-24.6 26.2 0 13.6 10.5 25.9 24.6 25.9 13.7 0 24.1-12.5 24.1-25.9zm104.3 53.3h-36.4c0-9.8-.4-19.6 1.1-29.5h-40.5c1.3 7.3 1.1 13.6 1.1 29.5h-17.1v33.9c11.9-1.9 12.1-.7 17.1-.7v.7h-.4v62.7c0 31.1 4.5 61.2 42.7 61.2 10.7 0 23-1.8 32.5-7v-35c-5.7 3.9-13.9 5.9-20.9 5.9-13.2 0-15.5-12.9-15.5-23.4v-65.2c22.7 0 36.4.7 36.4.7v-33.8z"],github:[496,512,[],"f09b","M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"],"github-alt":[480,512,[],"f113","M186.1 328.7c0 20.9-10.9 55.1-36.7 55.1s-36.7-34.2-36.7-55.1 10.9-55.1 36.7-55.1 36.7 34.2 36.7 55.1zM480 278.2c0 31.9-3.2 65.7-17.5 95-37.9 76.6-142.1 74.8-216.7 74.8-75.8 0-186.2 2.7-225.6-74.8-14.6-29-20.2-63.1-20.2-95 0-41.9 13.9-81.5 41.5-113.6-5.2-15.8-7.7-32.4-7.7-48.8 0-21.5 4.9-32.3 14.6-51.8 45.3 0 74.3 9 108.8 36 29-6.9 58.8-10 88.7-10 27 0 54.2 2.9 80.4 9.2 34-26.7 63-35.2 107.8-35.2 9.8 19.5 14.6 30.3 14.6 51.8 0 16.4-2.6 32.7-7.7 48.2 27.5 32.4 39 72.3 39 114.2zm-64.3 50.5c0-43.9-26.7-82.6-73.5-82.6-18.9 0-37 3.4-56 6-14.9 2.3-29.8 3.2-45.1 3.2-15.2 0-30.1-.9-45.1-3.2-18.7-2.6-37-6-56-6-46.8 0-73.5 38.7-73.5 82.6 0 87.8 80.4 101.3 150.4 101.3h48.2c70.3 0 150.6-13.4 150.6-101.3zm-82.6-55.1c-25.8 0-36.7 34.2-36.7 55.1s10.9 55.1 36.7 55.1 36.7-34.2 36.7-55.1-10.9-55.1-36.7-55.1z"],"github-square":[448,512,[],"f092","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM277.3 415.7c-8.4 1.5-11.5-3.7-11.5-8 0-5.4.2-33 .2-55.3 0-15.6-5.2-25.5-11.3-30.7 37-4.1 76-9.2 76-73.1 0-18.2-6.5-27.3-17.1-39 1.7-4.3 7.4-22-1.7-45-13.9-4.3-45.7 17.9-45.7 17.9-13.2-3.7-27.5-5.6-41.6-5.6-14.1 0-28.4 1.9-41.6 5.6 0 0-31.8-22.2-45.7-17.9-9.1 22.9-3.5 40.6-1.7 45-10.6 11.7-15.6 20.8-15.6 39 0 63.6 37.3 69 74.3 73.1-4.8 4.3-9.1 11.7-10.6 22.3-9.5 4.3-33.8 11.7-48.3-13.9-9.1-15.8-25.5-17.1-25.5-17.1-16.2-.2-1.1 10.2-1.1 10.2 10.8 5 18.4 24.2 18.4 24.2 9.7 29.7 56.1 19.7 56.1 19.7 0 13.9.2 36.5.2 40.6 0 4.3-3 9.5-11.5 8-66-22.1-112.2-84.9-112.2-158.3 0-91.8 70.2-161.5 162-161.5S388 165.6 388 257.4c.1 73.4-44.7 136.3-110.7 158.3zm-98.1-61.1c-1.9.4-3.7-.4-3.9-1.7-.2-1.5 1.1-2.8 3-3.2 1.9-.2 3.7.6 3.9 1.9.3 1.3-1 2.6-3 3zm-9.5-.9c0 1.3-1.5 2.4-3.5 2.4-2.2.2-3.7-.9-3.7-2.4 0-1.3 1.5-2.4 3.5-2.4 1.9-.2 3.7.9 3.7 2.4zm-13.7-1.1c-.4 1.3-2.4 1.9-4.1 1.3-1.9-.4-3.2-1.9-2.8-3.2.4-1.3 2.4-1.9 4.1-1.5 2 .6 3.3 2.1 2.8 3.4zm-12.3-5.4c-.9 1.1-2.8.9-4.3-.6-1.5-1.3-1.9-3.2-.9-4.1.9-1.1 2.8-.9 4.3.6 1.3 1.3 1.8 3.3.9 4.1zm-9.1-9.1c-.9.6-2.6 0-3.7-1.5s-1.1-3.2 0-3.9c1.1-.9 2.8-.2 3.7 1.3 1.1 1.5 1.1 3.3 0 4.1zm-6.5-9.7c-.9.9-2.4.4-3.5-.6-1.1-1.3-1.3-2.8-.4-3.5.9-.9 2.4-.4 3.5.6 1.1 1.3 1.3 2.8.4 3.5zm-6.7-7.4c-.4.9-1.7 1.1-2.8.4-1.3-.6-1.9-1.7-1.5-2.6.4-.6 1.5-.9 2.8-.4 1.3.7 1.9 1.8 1.5 2.6z"],gitkraken:[592,512,[],"f3a6","M565.7 118.1c-2.3-6.1-9.3-9.2-15.3-6.6-5.7 2.4-8.5 8.9-6.3 14.6 10.9 29 16.9 60.5 16.9 93.3 0 134.6-100.3 245.7-230.2 262.7V358.4c7.9-1.5 15.5-3.6 23-6.2v104c106.7-25.9 185.9-122.1 185.9-236.8 0-91.8-50.8-171.8-125.8-213.3-5.7-3.2-13-.9-15.9 5-2.7 5.5-.6 12.2 4.7 15.1 67.9 37.6 113.9 110 113.9 193.2 0 93.3-57.9 173.1-139.8 205.4v-92.2c14.2-4.5 24.9-17.7 24.9-33.5 0-13.1-6.8-24.4-17.3-30.5 8.3-79.5 44.5-58.6 44.5-83.9V170c0-38-87.9-161.8-129-164.7-2.5-.2-5-.2-7.6 0C251.1 8.3 163.2 132 163.2 170v14.8c0 25.3 36.3 4.3 44.5 83.9-10.6 6.1-17.3 17.4-17.3 30.5 0 15.8 10.6 29 24.8 33.5v92.2c-81.9-32.2-139.8-112-139.8-205.4 0-83.1 46-155.5 113.9-193.2 5.4-3 7.4-9.6 4.7-15.1-2.9-5.9-10.1-8.2-15.9-5-75 41.5-125.8 121.5-125.8 213.3 0 114.7 79.2 210.8 185.9 236.8v-104c7.6 2.5 15.1 4.6 23 6.2v123.7C131.4 465.2 31 354.1 31 219.5c0-32.8 6-64.3 16.9-93.3 2.2-5.8-.6-12.2-6.3-14.6-6-2.6-13 .4-15.3 6.6C14.5 149.7 8 183.8 8 219.5c0 155.1 122.6 281.6 276.3 287.8V361.4c6.8.4 15 .5 23.4 0v145.8C461.4 501.1 584 374.6 584 219.5c0-35.7-6.5-69.8-18.3-101.4zM365.9 275.5c13 0 23.7 10.5 23.7 23.7 0 13.1-10.6 23.7-23.7 23.7-13 0-23.7-10.5-23.7-23.7 0-13.1 10.6-23.7 23.7-23.7zm-139.8 47.3c-13.2 0-23.7-10.7-23.7-23.7s10.5-23.7 23.7-23.7c13.1 0 23.7 10.6 23.7 23.7 0 13-10.5 23.7-23.7 23.7z"],gitlab:[512,512,[],"f296","M29.782 199.732L256 493.714 8.074 309.699c-6.856-5.142-9.712-13.996-7.141-21.993l28.849-87.974zm75.405-174.806c-3.142-8.854-15.709-8.854-18.851 0L29.782 199.732h131.961L105.187 24.926zm56.556 174.806L256 493.714l94.257-293.982H161.743zm349.324 87.974l-28.849-87.974L256 493.714l247.926-184.015c6.855-5.142 9.711-13.996 7.141-21.993zm-85.404-262.78c-3.142-8.854-15.709-8.854-18.851 0l-56.555 174.806h131.961L425.663 24.926z"],gitter:[384,512,[],"f426","M66.4 322.5H16V0h50.4v322.5zM166.9 76.1h-50.4V512h50.4V76.1zm100.6 0h-50.4V512h50.4V76.1zM368 76h-50.4v247H368V76z"],glide:[448,512,[],"f2a5","M252.8 148.6c0 8.8-1.6 17.7-3.4 26.4-5.8 27.8-11.6 55.8-17.3 83.6-1.4 6.3-8.3 4.9-13.7 4.9-23.8 0-30.5-26-30.5-45.5 0-29.3 11.2-68.1 38.5-83.1 4.3-2.5 9.2-4.2 14.1-4.2 11.4 0 12.3 8.3 12.3 17.9zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-64 187c0-5.1-20.8-37.7-25.5-39.5-2.2-.9-7.2-2.3-9.6-2.3-23.1 0-38.7 10.5-58.2 21.5l-.5-.5c4.3-29.4 14.6-57.2 14.6-87.4 0-44.6-23.8-62.7-67.5-62.7-71.7 0-108 70.8-108 123.5 0 54.7 32 85 86.3 85 7.5 0 6.9-.6 6.9 2.3-10.5 80.3-56.5 82.9-56.5 58.9 0-24.4 28-36.5 28.3-38-.2-7.6-29.3-17.2-36.7-17.2-21.1 0-32.7 33-32.7 50.6 0 32.3 20.4 54.7 53.3 54.7 48.2 0 83.4-49.7 94.3-91.7 9.4-37.7 7-39.4 12.3-42.1 20-10.1 35.8-16.8 58.4-16.8 11.1 0 19 2.3 36.7 5.2 1.8.1 4.1-1.7 4.1-3.5z"],"glide-g":[448,512,[],"f2a6","M407.1 211.2c-3.5-1.4-11.6-3.8-15.4-3.8-37.1 0-62.2 16.8-93.5 34.5l-.9-.9c7-47.3 23.5-91.9 23.5-140.4C320.8 29.1 282.6 0 212.4 0 97.3 0 39 113.7 39 198.4 39 286.3 90.3 335 177.6 335c12 0 11-1 11 3.8-16.9 128.9-90.8 133.1-90.8 94.6 0-39.2 45-58.6 45.5-61-.3-12.2-47-27.6-58.9-27.6-33.9.1-52.4 51.2-52.4 79.3C32 476 64.8 512 117.5 512c77.4 0 134-77.8 151.4-145.4 15.1-60.5 11.2-63.3 19.7-67.6 32.2-16.2 57.5-27 93.8-27 17.8 0 30.5 3.7 58.9 8.4 2.9 0 6.7-2.9 6.7-5.8 0-8-33.4-60.5-40.9-63.4zm-175.3-84.4c-9.3 44.7-18.6 89.6-27.8 134.3-2.3 10.2-13.3 7.8-22 7.8-38.3 0-49-41.8-49-73.1 0-47 18-109.3 61.8-133.4 7-4.1 14.8-6.7 22.6-6.7 18.6 0 20 13.3 20 28.7-.1 14.3-2.7 28.5-5.6 42.4z"],gofore:[400,512,[],"f3a7","M324 319.8h-13.2v34.7c-24.5 23.1-56.3 35.8-89.9 35.8-73.2 0-132.4-60.2-132.4-134.4 0-74.1 59.2-134.4 132.4-134.4 35.3 0 68.6 14 93.6 39.4l62.3-63.3C335 55.3 279.7 32 220.7 32 98 32 0 132.6 0 256c0 122.5 97 224 220.7 224 63.2 0 124.5-26.2 171-82.5-2-27.6-13.4-77.7-67.7-77.7zm-12.1-112.5H205.6v89H324c33.5 0 60.5 15.1 76 41.8v-30.6c0-65.2-40.4-100.2-88.1-100.2z"],goodreads:[448,512,[],"f3a8","M299.9 191.2c5.1 37.3-4.7 79-35.9 100.7-22.3 15.5-52.8 14.1-70.8 5.7-37.1-17.3-49.5-58.6-46.8-97.2 4.3-60.9 40.9-87.9 75.3-87.5 46.9-.2 71.8 31.8 78.2 78.3zM448 88v336c0 30.9-25.1 56-56 56H56c-30.9 0-56-25.1-56-56V88c0-30.9 25.1-56 56-56h336c30.9 0 56 25.1 56 56zM330 313.2s-.1-34-.1-217.3h-29v40.3c-.8.3-1.2-.5-1.6-1.2-9.6-20.7-35.9-46.3-76-46-51.9.4-87.2 31.2-100.6 77.8-4.3 14.9-5.8 30.1-5.5 45.6 1.7 77.9 45.1 117.8 112.4 115.2 28.9-1.1 54.5-17 69-45.2.5-1 1.1-1.9 1.7-2.9.2.1.4.1.6.2.3 3.8.2 30.7.1 34.5-.2 14.8-2 29.5-7.2 43.5-7.8 21-22.3 34.7-44.5 39.5-17.8 3.9-35.6 3.8-53.2-1.2-21.5-6.1-36.5-19-41.1-41.8-.3-1.6-1.3-1.3-2.3-1.3h-26.8c.8 10.6 3.2 20.3 8.5 29.2 24.2 40.5 82.7 48.5 128.2 37.4 49.9-12.3 67.3-54.9 67.4-106.3z"],"goodreads-g":[384,512,[],"f3a9","M42.6 403.3h2.8c12.7 0 25.5 0 38.2.1 1.6 0 3.1-.4 3.6 2.1 7.1 34.9 30 54.6 62.9 63.9 26.9 7.6 54.1 7.8 81.3 1.8 33.8-7.4 56-28.3 68-60.4 8-21.5 10.7-43.8 11-66.5.1-5.8.3-47-.2-52.8l-.9-.3c-.8 1.5-1.7 2.9-2.5 4.4-22.1 43.1-61.3 67.4-105.4 69.1-103 4-169.4-57-172-176.2-.5-23.7 1.8-46.9 8.3-69.7C58.3 47.7 112.3.6 191.6 0c61.3-.4 101.5 38.7 116.2 70.3.5 1.1 1.3 2.3 2.4 1.9V10.6h44.3c0 280.3.1 332.2.1 332.2-.1 78.5-26.7 143.7-103 162.2-69.5 16.9-159 4.8-196-57.2-8-13.5-11.8-28.3-13-44.5zM188.9 36.5c-52.5-.5-108.5 40.7-115 133.8-4.1 59 14.8 122.2 71.5 148.6 27.6 12.9 74.3 15 108.3-8.7 47.6-33.2 62.7-97 54.8-154-9.7-71.1-47.8-120-119.6-119.7z"],google:[488,512,[],"f1a0","M488 261.8C488 403.3 391.1 504 248 504 110.8 504 0 393.2 0 256S110.8 8 248 8c66.8 0 123 24.5 166.3 64.9l-67.5 64.9C258.5 52.6 94.3 116.6 94.3 256c0 86.5 69.1 156.6 153.7 156.6 98.2 0 135-70.4 140.8-106.9H248v-85.3h236.1c2.3 12.7 3.9 24.9 3.9 41.4z"],"google-drive":[512,512,[],"f3aa","M339 314.9L175.4 32h161.2l163.6 282.9H339zm-137.5 23.6L120.9 480h310.5L512 338.5H201.5zM154.1 67.4L0 338.5 80.6 480 237 208.8 154.1 67.4z"],"google-play":[512,512,[],"f3ab","M325.3 234.3L104.6 13l280.8 161.2-60.1 60.1zM47 0C34 6.8 25.3 19.2 25.3 35.3v441.3c0 16.1 8.7 28.5 21.7 35.3l256.6-256L47 0zm425.2 225.6l-58.9-34.1-65.7 64.5 65.7 64.5 60.1-34.1c18-14.3 18-46.5-1.2-60.8zM104.6 499l280.8-161.2-60.1-60.1L104.6 499z"],"google-plus":[496,512,[],"f2b3","M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm-70.7 372c-68.8 0-124-55.5-124-124s55.2-124 124-124c31.3 0 60.1 11 83 32.3l-33.6 32.6c-13.2-12.9-31.3-19.1-49.4-19.1-42.9 0-77.2 35.5-77.2 78.1s34.2 78.1 77.2 78.1c32.6 0 64.9-19.1 70.1-53.3h-70.1v-42.6h116.9c1.3 6.8 1.9 13.6 1.9 20.7 0 70.8-47.5 121.2-118.8 121.2zm230.2-106.2v35.5H372v-35.5h-35.5v-35.5H372v-35.5h35.5v35.5h35.2v35.5h-35.2z"],"google-plus-g":[640,512,[],"f0d5","M386.061 228.496c1.834 9.692 3.143 19.384 3.143 31.956C389.204 370.205 315.599 448 204.8 448c-106.084 0-192-85.915-192-192s85.916-192 192-192c51.864 0 95.083 18.859 128.611 50.292l-52.126 50.03c-14.145-13.621-39.028-29.599-76.485-29.599-65.484 0-118.92 54.221-118.92 121.277 0 67.056 53.436 121.277 118.92 121.277 75.961 0 104.513-54.745 108.965-82.773H204.8v-66.009h181.261zm185.406 6.437V179.2h-56.001v55.733h-55.733v56.001h55.733v55.733h56.001v-55.733H627.2v-56.001h-55.733z"],"google-plus-square":[448,512,[],"f0d4","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM164 356c-55.3 0-100-44.7-100-100s44.7-100 100-100c27 0 49.5 9.8 67 26.2l-27.1 26.1c-7.4-7.1-20.3-15.4-39.8-15.4-34.1 0-61.9 28.2-61.9 63.2 0 34.9 27.8 63.2 61.9 63.2 39.6 0 54.4-28.5 56.8-43.1H164v-34.4h94.4c1 5 1.6 10.1 1.6 16.6 0 57.1-38.3 97.6-96 97.6zm220-81.8h-29v29h-29.2v-29h-29V245h29v-29H355v29h29v29.2z"],"google-wallet":[448,512,[],"f1ee","M156.8 126.8c37.6 60.6 64.2 113.1 84.3 162.5-8.3 33.8-18.8 66.5-31.3 98.3-13.2-52.3-26.5-101.3-56-148.5 6.5-36.4 2.3-73.6 3-112.3zM109.3 200H16.1c-6.5 0-10.5 7.5-6.5 12.7C51.8 267 81.3 330.5 101.3 400h103.5c-16.2-69.7-38.7-133.7-82.5-193.5-3-4-8-6.5-13-6.5zm47.8-88c68.5 108 130 234.5 138.2 368H409c-12-138-68.4-265-143.2-368H157.1zm251.8-68.5c-1.8-6.8-8.2-11.5-15.2-11.5h-88.3c-5.3 0-9 5-7.8 10.3 13.2 46.5 22.3 95.5 26.5 146 48.2 86.2 79.7 178.3 90.6 270.8 15.8-60.5 25.3-133.5 25.3-203 0-73.6-12.1-145.1-31.1-212.6z"],gratipay:[496,512,[],"f184","M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm114.6 226.4l-113 152.7-112.7-152.7c-8.7-11.9-19.1-50.4 13.6-72 28.1-18.1 54.6-4.2 68.5 11.9 15.9 17.9 46.6 16.9 61.7 0 13.9-16.1 40.4-30 68.1-11.9 32.9 21.6 22.6 60 13.8 72z"],grav:[512,512,[],"f2d6","M301.1 212c4.4 4.4 4.4 11.9 0 16.3l-9.7 9.7c-4.4 4.7-11.9 4.7-16.6 0l-10.5-10.5c-4.4-4.7-4.4-11.9 0-16.6l9.7-9.7c4.4-4.4 11.9-4.4 16.6 0l10.5 10.8zm-30.2-19.7c3-3 3-7.8 0-10.5-2.8-3-7.5-3-10.5 0-2.8 2.8-2.8 7.5 0 10.5 3.1 2.8 7.8 2.8 10.5 0zm-26 5.3c-3 2.8-3 7.5 0 10.2 2.8 3 7.5 3 10.5 0 2.8-2.8 2.8-7.5 0-10.2-3-3-7.7-3-10.5 0zm72.5-13.3c-19.9-14.4-33.8-43.2-11.9-68.1 21.6-24.9 40.7-17.2 59.8.8 11.9 11.3 29.3 24.9 17.2 48.2-12.5 23.5-45.1 33.2-65.1 19.1zm47.7-44.5c-8.9-10-23.3 6.9-15.5 16.1 7.4 9 32.1 2.4 15.5-16.1zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-66.2 42.6c2.5-16.1-20.2-16.6-25.2-25.7-13.6-24.1-27.7-36.8-54.5-30.4 11.6-8 23.5-6.1 23.5-6.1.3-6.4 0-13-9.4-24.9 3.9-12.5.3-22.4.3-22.4 15.5-8.6 26.8-24.4 29.1-43.2 3.6-31-18.8-59.2-49.8-62.8-22.1-2.5-43.7 7.7-54.3 25.7-23.2 40.1 1.4 70.9 22.4 81.4-14.4-1.4-34.3-11.9-40.1-34.3-6.6-25.7 2.8-49.8 8.9-61.4 0 0-4.4-5.8-8-8.9 0 0-13.8 0-24.6 5.3 11.9-15.2 25.2-14.4 25.2-14.4 0-6.4-.6-14.9-3.6-21.6-5.4-11-23.8-12.9-31.7 2.8.1-.2.3-.4.4-.5-5 11.9-1.1 55.9 16.9 87.2-2.5 1.4-9.1 6.1-13 10-21.6 9.7-56.2 60.3-56.2 60.3-28.2 10.8-77.2 50.9-70.6 79.7.3 3 1.4 5.5 3 7.5-2.8 2.2-5.5 5-8.3 8.3-11.9 13.8-5.3 35.2 17.7 24.4 15.8-7.2 29.6-20.2 36.3-30.4 0 0-5.5-5-16.3-4.4 27.7-6.6 34.3-9.4 46.2-9.1 8 3.9 8-34.3 8-34.3 0-14.7-2.2-31-11.1-41.5 12.5 12.2 29.1 32.7 28 60.6-.8 18.3-15.2 23-15.2 23-9.1 16.6-43.2 65.9-30.4 106 0 0-9.7-14.9-10.2-22.1-17.4 19.4-46.5 52.3-24.6 64.5 26.6 14.7 108.8-88.6 126.2-142.3 34.6-20.8 55.4-47.3 63.9-65 22 43.5 95.3 94.5 101.1 59z"],gripfire:[384,512,[],"f3ac","M171.8 503.8c0-5.3 4.8-12.2 4.8-22.3 0-15.2-13-39.9-78.1-86.6C64.2 365.8 32 336.4 32 286.6 32 171.9 179.1 110.1 179.1 18c0-3.3-.2-6.7-.6-10 5.1 2.4 39.1 43.3 39.1 90.4 0 80.5-105.1 129.2-105.1 203 0 26.9 16.6 47.2 32.6 69.5 22.5 30.2 44.2 56.9 44.2 86.5-.1 14.5-4.4 29.7-17.5 46.4zm146-241.4c1.5 8.4 2.2 16.6 2.2 24.6 0 51.8-29.4 97.5-67.3 136.8-1 1-2.2 2.4-3.2 2.4-3.6 0-35.5-41.6-35.5-53.2 0 0 41.8-55.7 41.8-96.9 0-10.8-2.7-21.7-9.1-33.4-1.5 32.3-55.7 87.7-58.1 87.7-2.7 0-17.9-22-17.9-42.1 0-5.3 1-10.7 3.2-15.8 2.4-5.5 56.6-72 56.6-116.7 0-6.2-1-12-3.4-17.1l-4-7.2c16.7 6.5 82.6 64.1 94.7 130.9"],grunt:[384,512,[],"f3ad","M61.3 189.3c-1.1 10 5.2 19.1 5.2 19.1.7-7.5 2.2-12.8 4-16.6.4 10.3 3.2 23.5 12.8 34.1 6.9 7.6 35.6 23.3 54.9 6.1 1 2.4 2.1 5.3 3 8.5 2.9 10.3-2.7 25.3-2.7 25.3s15.1-17.1 13.9-32.5c10.8-.5 21.4-8.4 21.1-19.5 0 0-18.9 10.4-35.5-8.8-9.7-11.2-40.9-42-83.1-31.8 4.3 1 8.9 2.4 13.5 4.1h-.1c-4.2 2-6.5 7.1-7 12zm28.3-1.8c19.5 11 37.4 25.7 44.9 37-5.7 3.3-21.7 10.4-38-1.7-10.3-7.6-9.8-26.2-6.9-35.3zm79.2 233.7c2.2 2.3 1.5 5.3.9 6.8-1.1 2.7-5.5 11.6-13 19.8-2.7 2.9-6.6 4.6-11 4.6-4.3 0-8.7-1.6-11.8-4.3-2.3-2.1-10.2-9.5-13.7-18.6-1.3-3.4-1-6.1.9-8.1 1.3-1.3 4-2.9 9.5-2.9H160c4.1 0 7 .9 8.8 2.7zm62.9-187.9c-1.2 15.5 13.9 32.5 13.9 32.5s-5.6-15-2.7-25.3c.9-3.2 2-6 3-8.5 19.3 17.3 48 1.5 54.8-6.1 9.6-10.6 12.3-23.8 12.8-34.1 1.8 3.8 3.4 9.1 4 16.6 0 0 6.4-9.1 5.2-19.1-.6-5-2.9-10-7-11.8h-.1c4.6-1.8 9.2-3.2 13.5-4.1-42.3-10.2-73.4 20.6-83.1 31.8-16.7 19.2-35.5 8.8-35.5 8.8-.2 10.9 10.4 18.9 21.2 19.3zm17.8-8.8c7.5-11.4 25.4-26 44.9-37 3 9.1 3.4 27.7-7 35.4-16.3 12.1-32.2 5-37.9 1.6-.1.1 0 0 0 0zM263 421.4c1.9 1.9 2.2 4.6.9 7.9-3.5 8.9-11.4 16.1-13.7 18.1-3.1 2.6-7.4 4.2-11.8 4.2s-8.3-1.6-11-4.5c-7.5-8-12-16.7-13-19.3-.6-1.5-1.3-4.4.9-6.7 1.7-1.8 4.7-2.7 8.9-2.7h29.4c5.4.1 8.1 1.7 9.4 3zm-98.3-251.5c9.9 6 18.8 8.1 27.3 8.3 8.5-.2 17.4-2.3 27.3-8.3 0 0-14.5 17.7-27.2 17.8h-.2c-12.7-.2-27.2-17.8-27.2-17.8zm184.5 147.4c-2.4 17.9-13 33.8-24.6 43.7-3.1-22.7-3.7-55.5-3.7-62.4 0-14.7 9.5-24.5 12.2-26.1 2.5-1.5 5.4-3 8.3-4.6 18-9.6 40.4-21.6 40.4-43.7 0-16.2-9.3-23.2-15.4-27.8-.8-.6-1.5-1.1-2.2-1.7-2.1-1.7-3.7-3-4.3-4.4-4.4-9.8-3.6-34.2-1.7-37.6.6-.6 16.7-20.9 11.8-39.2-2-7.4-6.9-13.3-14.1-17-5.3-2.7-11.9-4.2-19.5-4.5-.1-2-.5-3.9-.9-5.9-.6-2.6-1.1-5.3-.9-8.1.4-4.7.8-9 2.2-11.3 8.4-13.3 28.8-17.6 29-17.6l12.3-2.4-8.1-9.5c-.1-.2-17.3-17.5-46.3-17.5-7.9 0-16 1.3-24.1 3.9-24.2 7.8-42.9 30.5-49.4 39.3-3.1-1-6.3-1.9-9.6-2.7-4.2-15.8 9-38.5 9-38.5s-13.6-3-33.7 15.2c-2.6-6.5-8.1-20.5-1.8-37.2C184.6 10.1 177.2 26 175 40.4c-7.6-5.4-6.7-23.1-7.2-27.6-7.5.9-29.2 21.9-28.2 48.3-2 .5-3.9 1.1-5.9 1.7-6.5-8.8-25.1-31.5-49.4-39.3-7.9-2.2-16-3.5-23.9-3.5-29 0-46.1 17.3-46.3 17.5L6 46.9l12.3 2.4c.2 0 20.6 4.3 29 17.6 1.4 2.2 1.8 6.6 2.2 11.3.2 2.8-.4 5.5-.9 8.1-.4 1.9-.8 3.9-.9 5.9-7.7.3-14.2 1.8-19.5 4.5-7.2 3.7-12.1 9.6-14.1 17-5 18.2 11.2 38.5 11.8 39.2 1.9 3.4 2.7 27.8-1.7 37.6-.6 1.4-2.2 2.7-4.3 4.4-.7.5-1.4 1.1-2.2 1.7-6.1 4.6-15.4 11.7-15.4 27.8 0 22.1 22.4 34.1 40.4 43.7 3 1.6 5.8 3.1 8.3 4.6 2.7 1.6 12.2 11.4 12.2 26.1 0 6.9-.6 39.7-3.7 62.4-11.6-9.9-22.2-25.9-24.6-43.8 0 0-29.2 22.6-20.6 70.8 5.2 29.5 23.2 46.1 47 54.7 8.8 19.1 29.4 45.7 67.3 49.6C143 504.3 163 512 192.2 512h.2c29.1 0 49.1-7.7 63.6-19.5 37.9-3.9 58.5-30.5 67.3-49.6 23.8-8.7 41.7-25.2 47-54.7 8.2-48.4-21.1-70.9-21.1-70.9zM305.7 37.7c5.6-1.8 11.6-2.7 17.7-2.7 11 0 19.9 3 24.7 5-3.1 1.4-6.4 3.2-9.7 5.3-2.4-.4-5.6-.8-9.2-.8-10.5 0-20.5 3.1-28.7 8.9-12.3 8.7-18 16.9-20.7 22.4-2.2-1.3-4.5-2.5-7.1-3.7-1.6-.8-3.1-1.5-4.7-2.2 6.1-9.1 19.9-26.5 37.7-32.2zm21 18.2c-.8 1-1.6 2.1-2.3 3.2-3.3 5.2-3.9 11.6-4.4 17.8-.5 6.4-1.1 12.5-4.4 17-4.2.8-8.1 1.7-11.5 2.7-2.3-3.1-5.6-7-10.5-11.2 1.4-4.8 5.5-16.1 13.5-22.5 5.6-4.3 12.2-6.7 19.6-7zM45.6 45.3c-3.3-2.2-6.6-4-9.7-5.3 4.8-2 13.7-5 24.7-5 6.1 0 12 .9 17.7 2.7 17.8 5.8 31.6 23.2 37.7 32.1-1.6.7-3.2 1.4-4.8 2.2-2.5 1.2-4.9 2.5-7.1 3.7-2.6-5.4-8.3-13.7-20.7-22.4-8.3-5.8-18.2-8.9-28.8-8.9-3.4.1-6.6.5-9 .9zm44.7 40.1c-4.9 4.2-8.3 8-10.5 11.2-3.4-.9-7.3-1.9-11.5-2.7C65 89.5 64.5 83.4 64 77c-.5-6.2-1.1-12.6-4.4-17.8-.7-1.1-1.5-2.2-2.3-3.2 7.4.3 14 2.6 19.5 7 8 6.3 12.1 17.6 13.5 22.4zM58.1 259.9c-2.7-1.6-5.6-3.1-8.4-4.6-14.9-8-30.2-16.3-30.2-30.5 0-11.1 4.3-14.6 8.9-18.2l.5-.4c.7-.6 1.4-1.2 2.2-1.8-.9 7.2-1.9 13.3-2.7 14.9 0 0 12.1-15 15.7-44.3 1.4-11.5-1.1-34.3-5.1-43 .2 4.9 0 9.8-.3 14.4-.4-.8-.8-1.6-1.3-2.2-3.2-4-11.8-17.5-9.4-26.6.9-3.5 3.1-6 6.7-7.8 3.8-1.9 8.8-2.9 15.1-2.9 12.3 0 25.9 3.7 32.9 6 25.1 8 55.4 30.9 64.1 37.7.2.2.4.3.4.3l5.6 3.9-3.5-5.8c-.2-.3-19.1-31.4-53.2-46.5 2-2.9 7.4-8.1 21.6-15.1 21.4-10.5 46.5-15.8 74.3-15.8 27.9 0 52.9 5.3 74.3 15.8 14.2 6.9 19.6 12.2 21.6 15.1-34 15.1-52.9 46.2-53.1 46.5l-3.5 5.8 5.6-3.9s.2-.1.4-.3c8.7-6.8 39-29.8 64.1-37.7 7-2.2 20.6-6 32.9-6 6.3 0 11.3 1 15.1 2.9 3.5 1.8 5.7 4.4 6.7 7.8 2.5 9.1-6.1 22.6-9.4 26.6-.5.6-.9 1.3-1.3 2.2-.3-4.6-.5-9.5-.3-14.4-4 8.8-6.5 31.5-5.1 43 3.6 29.3 15.7 44.3 15.7 44.3-.8-1.6-1.8-7.7-2.7-14.9.7.6 1.5 1.2 2.2 1.8l.5.4c4.6 3.7 8.9 7.1 8.9 18.2 0 14.2-15.4 22.5-30.2 30.5-2.9 1.5-5.7 3.1-8.4 4.6-8.7 5-18 16.7-19.1 34.2-.9 14.6.9 49.9 3.4 75.9-12.4 4.8-26.7 6.4-39.7 6.8-2-4.1-3.9-8.5-5.5-13.1-.7-2-19.6-51.1-26.4-62.2 5.5 39 17.5 73.7 23.5 89.6-3.5-.5-7.3-.7-11.7-.7h-117c-4.4 0-8.3.3-11.7.7 6-15.9 18.1-50.6 23.5-89.6-6.8 11.2-25.7 60.3-26.4 62.2-1.6 4.6-3.5 9-5.5 13.1-13-.4-27.2-2-39.7-6.8 2.5-26 4.3-61.2 3.4-75.9-.9-17.4-10.3-29.2-19-34.2zM34.8 404.6c-12.1-20-8.7-54.1-3.7-59.1 10.9 34.4 47.2 44.3 74.4 45.4-2.7 4.2-5.2 7.6-7 10l-1.4 1.4c-7.2 7.8-8.6 18.5-4.1 31.8-22.7-.1-46.3-9.8-58.2-29.5zm45.7 43.5c6 1.1 12.2 1.9 18.6 2.4 3.5 8 7.4 15.9 12.3 23.1-14.4-5.9-24.4-16-30.9-25.5zM192 498.2c-60.6-.1-78.3-45.8-84.9-64.7-3.7-10.5-3.4-18.2.9-23.1 2.9-3.3 9.5-7.2 24.6-7.2h118.8c15.1 0 21.8 3.9 24.6 7.2 4.2 4.8 4.5 12.6.9 23.1-6.6 18.8-24.3 64.6-84.9 64.7zm80.6-24.6c4.9-7.2 8.8-15.1 12.3-23.1 6.4-.5 12.6-1.3 18.6-2.4-6.5 9.5-16.5 19.6-30.9 25.5zm76.6-69c-12 19.7-35.6 29.3-58.1 29.7 4.5-13.3 3.1-24.1-4.1-31.8-.4-.5-.9-1-1.4-1.5-1.8-2.4-4.3-5.8-7-10 27.2-1.2 63.5-11 74.4-45.4 5 5 8.4 39.1-3.8 59z"],gulp:[256,512,[],"f3ae","M209.8 391.1l-14.1 24.6-4.6 80.2c0 8.9-28.3 16.1-63.1 16.1s-63.1-7.2-63.1-16.1l-5.8-79.4-14.9-25.4c41.2 17.3 126 16.7 165.6 0zm-196-253.3l13.6 125.5c5.9-20 20.8-47 40-55.2 6.3-2.7 12.7-2.7 18.7.9 5.2 3 9.6 9.3 10.1 11.8 1.2 6.5-2 9.1-4.5 9.1-3 0-5.3-4.6-6.8-7.3-4.1-7.3-10.3-7.6-16.9-2.8-6.9 5-12.9 13.4-17.1 20.7-5.1 8.8-9.4 18.5-12 28.2-1.5 5.6-2.9 14.6-.6 19.9 1 2.2 2.5 3.6 4.9 3.6 5 0 12.3-6.6 15.8-10.1 4.5-4.5 10.3-11.5 12.5-16l5.2-15.5c2.6-6.8 9.9-5.6 9.9 0 0 10.2-3.7 13.6-10 34.7-5.8 19.5-7.6 25.8-7.6 25.8-.7 2.8-3.4 7.5-6.3 7.5-1.2 0-2.1-.4-2.6-1.2-1-1.4-.9-5.3-.8-6.3.2-3.2 6.3-22.2 7.3-25.2-2 2.2-4.1 4.4-6.4 6.6-5.4 5.1-14.1 11.8-21.5 11.8-3.4 0-5.6-.9-7.7-2.4l7.6 79.6c2 5 39.2 17.1 88.2 17.1 49.1 0 86.3-12.2 88.2-17.1l10.9-94.6c-5.7 5.2-12.3 11.6-19.6 14.8-5.4 2.3-17.4 3.8-17.4-5.7 0-5.2 9.1-14.8 14.4-21.5 1.4-1.7 4.7-5.9 4.7-8.1 0-2.9-6-2.2-11.7 2.5-3.2 2.7-6.2 6.3-8.7 9.7-4.3 6-6.6 11.2-8.5 15.5-6.2 14.2-4.1 8.6-9.1 22-5 13.3-4.2 11.8-5.2 14-.9 1.9-2.2 3.5-4 4.5-1.9 1-4.5.9-6.1-.3-.9-.6-1.3-1.9-1.3-3.7 0-.9.1-1.8.3-2.7 1.5-6.1 7.8-18.1 15-34.3 1.6-3.7 1-2.6.8-2.3-6.2 6-10.9 8.9-14.4 10.5-5.8 2.6-13 2.6-14.5-4.1-.1-.4-.1-.8-.2-1.2-11.8 9.2-24.3 11.7-20-8.1-4.6 8.2-12.6 14.9-22.4 14.9-4.1 0-7.1-1.4-8.6-5.1-2.3-5.5 1.3-14.9 4.6-23.8 1.7-4.5 4-9.9 7.1-16.2 1.6-3.4 4.2-5.4 7.6-4.5.6.2 1.1.4 1.6.7 2.6 1.8 1.6 4.5.3 7.2-3.8 7.5-7.1 13-9.3 20.8-.9 3.3-2 9 1.5 9 2.4 0 4.7-.8 6.9-2.4 4.6-3.4 8.3-8.5 11.1-13.5 2-3.6 4.4-8.3 5.6-12.3.5-1.7 1.1-3.3 1.8-4.8 1.1-2.5 2.6-5.1 5.2-5.1 1.3 0 2.4.5 3.2 1.5 1.7 2.2 1.3 4.5.4 6.9-2 5.6-4.7 10.6-6.9 16.7-1.3 3.5-2.7 8-2.7 11.7 0 3.4 3.7 2.6 6.8 1.2 2.4-1.1 4.8-2.8 6.8-4.5 1.2-4.9.9-3.8 26.4-68.2 1.3-3.3 3.7-4.7 6.1-4.7 1.2 0 2.2.4 3.2 1.1 1.7 1.3 1.7 4.1 1 6.2-.7 1.9-.6 1.3-4.5 10.5-5.2 12.1-8.6 20.8-13.2 31.9-1.9 4.6-7.7 18.9-8.7 22.3-.6 2.2-1.3 5.8 1 5.8 5.4 0 19.3-13.1 23.1-17 .2-.3.5-.4.9-.6.6-1.9 1.2-3.7 1.7-5.5 1.4-3.8 2.7-8.2 5.3-11.3.8-1 1.7-1.6 2.7-1.6 2.8 0 4.2 1.2 4.2 4 0 1.1-.7 5.1-1.1 6.2 1.4-1.5 2.9-3 4.5-4.5 15-13.9 25.7-6.8 25.7.2 0 7.4-8.9 17.7-13.8 23.4-1.6 1.9-4.9 5.4-5 6.4 0 1.3.9 1.8 2.2 1.8 2 0 6.4-3.5 8-4.7 5-3.9 11.8-9.9 16.6-14.1l14.8-136.8c-30.5 17.1-197.6 17.2-228.3.2zm229.7-8.5c0 21-231.2 21-231.2 0 0-8.8 51.8-15.9 115.6-15.9 9 0 17.8.1 26.3.4l12.6-48.7L228.1.6c1.4-1.4 5.8-.2 9.9 3.5s6.6 7.9 5.3 9.3l-.1.1L185.9 74l-10 40.7c39.9 2.6 67.6 8.1 67.6 14.6zm-69.4 4.6c0-.8-.9-1.5-2.5-2.1l-.2.8c0 1.3-5 2.4-11.1 2.4s-11.1-1.1-11.1-2.4c0-.1 0-.2.1-.3l.2-.7c-1.8.6-3 1.4-3 2.3 0 2.1 6.2 3.7 13.7 3.7 7.7.1 13.9-1.6 13.9-3.7z"],"hacker-news":[448,512,[],"f1d4","M0 32v448h448V32H0zm21.2 197.2H21c.1-.1.2-.3.3-.4 0 .1 0 .3-.1.4zm218 53.9V384h-31.4V281.3L128 128h37.3c52.5 98.3 49.2 101.2 59.3 125.6 12.3-27 5.8-24.4 60.6-125.6H320l-80.8 155.1z"],"hacker-news-square":[448,512,[],"f3af","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM21.2 229.2H21c.1-.1.2-.3.3-.4 0 .1 0 .3-.1.4zm218 53.9V384h-31.4V281.3L128 128h37.3c52.5 98.3 49.2 101.2 59.3 125.6 12.3-27 5.8-24.4 60.6-125.6H320l-80.8 155.1z"],hips:[640,512,[],"f452","M0 80.2c0-1.8.9-2.7 2.7-2.7h40.9c1.9 0 2.8.9 2.8 2.7v81.2c15.2-7.7 31.7-11.5 49.8-11.4 24 .1 44.2 6.2 60.3 18 18.7 13.5 28 31.9 28 55.3v136.1c0 1.9-.9 2.8-2.7 2.8h-27.3c-9.1 0-16.4-7.3-16.4-16.3V223.3c0-.9 2.7-27-45.8-27-48.6 0-45.8 26.2-45.8 27v136.1c0 1.9-.9 2.8-2.8 2.8h-41c-1.8 0-2.7-.9-2.7-2.8V80.2zm497.7 221.5c13.7 10.2 34.1 19.1 58.4 19.1 23.3 0 32.8-4.5 36.5-13.6 3-7.9-.6-16.1-12.2-21.2l-53.6-23.5c-21.4-9.4-33.8-24-37.2-43.6-5.7-33.7 22.2-53.3 22.7-53.7 13.2-9.6 32-15.4 58.5-15.4 19 0 37.4 3.3 55.1 9.9 1.3.5 1.9 1.3 1.9 2.6V207c0 2.1-2.3 3.4-4 2.4-39.7-20.7-76.6-12.3-84-6.8-6.6 4.9-6 12.5 2.6 16.1L600 244c16.5 7.1 28.1 18.4 34.9 34.1 5.5 12.6 6.6 25.6 3.1 39.1-9.6 36.9-44.9 45.5-45.6 45.8-10.5 3.1-23.6 4.3-36.3 4.3-16.6 0-32.6-2.7-48.2-8.2-9.7-3.4-14.6-10.3-14.6-20.7V304c0-2.1 2.3-3.7 4.4-2.3zM376.2 149.8c-31.7 0-104.2 20.1-104.2 103.5v183.5c0 .8.6 2.7 2.7 2.7h40.9c1.9 0 2.8-.9 2.8-2.7V348c16.5 12.7 35.8 19.1 57.7 19.1 60.5 0 108.7-48.5 108.7-108.7.1-60.3-48.2-108.6-108.6-108.6zm0 170.9c-17.2 0-31.9-6.1-44-18.2-12.2-12.2-18.2-26.8-18.2-44 0-34.5 27.6-62.2 62.2-62.2 34.5 0 62.2 27.6 62.2 62.2.1 34.3-27.3 62.2-62.2 62.2zm-124.6 38.7c0 1.9-.9 2.8-2.8 2.8h-40.9c-1.6 0-2.7-1.4-2.7-2.8V157.6c0-1.4 1.1-2.8 2.7-2.8h40.9c1.9 0 2.8.9 2.8 2.8v201.8M228.3 72.5c15.9 0 28.9 12.7 28.9 28.9 0 15.8-12.7 28.9-28.9 28.9s-28.9-13.3-28.9-28.9c.1-16 13-28.9 28.9-28.9"],"hire-a-helper":[512,512,[],"f3b0","M443.1 0H71.9C67.9 37.3 37.4 67.8 0 71.7v371.5c37.4 4.9 66 32.4 71.9 68.8h372.2c3-36.4 32.5-65.8 67.9-69.8V71.7c-36.4-5.9-65-35.3-68.9-71.7zm-37 404.9c-36.3 0-18.8-2-55.1-2-35.8 0-21 2-56.1 2-5.9 0-4.9-8.2 0-9.8 22.8-7.6 22.9-10.2 24.6-12.8 10.4-15.6 5.9-83 5.9-113 0-5.3-6.4-12.8-13.8-12.8H200.4c-7.4 0-13.8 7.5-13.8 12.8 0 30-4.5 97.4 5.9 113 1.7 2.5 1.8 5.2 24.6 12.8 4.9 1.6 6 9.8 0 9.8-35.1 0-20.3-2-56.1-2-36.3 0-18.8 2-55.1 2-7.9 0-5.8-10.8 0-10.8 10.2-3.4 13.5-3.5 21.7-13.8 7.7-12.9 7.9-44.4 7.9-127.8V151.3c0-22.2-12.2-28.3-28.6-32.4-8.8-2.2-4-11.8 1-11.8 36.5 0 20.6 2 57.1 2 32.7 0 16.5-2 49.2-2 3.3 0 8.5 8.3 1 10.8-4.9 1.6-27.6 3.7-27.6 39.3 0 45.6-.2 55.8 1 68.8 0 1.3 2.3 12.8 12.8 12.8h109.2c10.5 0 12.8-11.5 12.8-12.8 1.2-13 1-23.2 1-68.8 0-35.6-22.7-37.7-27.6-39.3-7.5-2.5-2.3-10.8 1-10.8 32.7 0 16.5 2 49.2 2 36.5 0 20.6-2 57.1-2 4.9 0 9.9 9.6 1 11.8-16.4 4.1-28.6 10.3-28.6 32.4v101.2c0 83.4.1 114.9 7.9 127.8 8.2 10.2 11.4 10.4 21.7 13.8 5.8 0 7.8 10.8 0 10.8z"],hooli:[640,512,[],"f427","M508.4 352h57.9V156.7L508.4 184v168zm73.7-110.5V352H640V241.5h-57.9zm-250.7-8.9c-18.2-18.2-50.4-17.1-50.4-17.1s-32.2-1.1-50.4 17.1c-1.9 1.9-3.7 3.9-5.3 6-38.2-29.6-72.5-46.5-102.1-61.1v-20.7l-22.5 10.6c-54.4-22.1-89-18.2-97.3.1 0 0-24.9 32.8 61.9 110.9v-31c-48.8-54.6-39-76.1-35.3-79.2 13.5-11.4 37.5-8 64.4 2.1L65.2 184v63.3c13.1 14.7 30.5 31.5 53.5 50.4l4.5 3.6v-29.8c0-6.9 1.7-18.2 10.8-18.2s10.6 6.9 10.6 15V317c18 12.2 37.3 22.1 57.7 29.6v-93.9c0-18.7-13.4-37.4-40.6-37.4-15.8-.1-30.5 8.2-38.5 21.9v-54.3c41.9 20.9 83.9 46.5 99.9 58.3-10.2 14.6-9.3 28.1-9.3 43.7 0 18.7-1.4 34.3 16.8 52.5 18.2 18.2 50.4 17.1 50.4 17.1s32.3 1.1 50.4-17.1c18.2-18.2 16.7-33.8 16.7-52.5 0-18.5 1.5-34.2-16.7-52.3zm-39.7 71.9c0 3.6-1.8 12.5-10.7 12.5-8.9 0-10.7-8.9-10.7-12.5v-40.4c0-8.7 7.3-10.9 10.7-10.9 3.4 0 10.7 2.1 10.7 10.9v40.4zm185.7-71.9c-18.2-18.2-50.4-17.1-50.4-17.1s-32.3-1.1-50.4 17.1c-18.2 18.2-16.8 33.9-16.8 52.6 0 18.7-1.4 34.3 16.8 52.5 18.2 18.2 50.4 17.1 50.4 17.1s32.3 1.1 50.4-17.1c18.2-18.2 16.8-33.8 16.8-52.5-.1-18.8 1.3-34.5-16.8-52.6zm-39.8 71.9c0 3.6-1.8 12.5-10.7 12.5-8.9 0-10.7-8.9-10.7-12.5v-40.4c0-8.7 7.3-10.9 10.7-10.9 3.4 0 10.7 2.1 10.7 10.9v40.4zm173.5-73c15.9 0 28.9-12.9 28.9-28.9s-12.9-24.5-28.9-24.5c-15.9 0-28.9 8.6-28.9 24.5s12.9 28.9 28.9 28.9zM144.5 352l38.3.8c-13.2-4.6-26-10.2-38.3-16.8v16zm-21.4 0v-28.6c-6.5-4.2-13-8.7-19.4-13.6-14.8-11.2-27.5-21.7-38.5-31.5V352h57.9zm59.7.8c36.5 12.5 69.9 14.2 94.7 7.2-19.9.2-45.8-2.6-75.3-13.3v5.3l-19.4.8z"],hotjar:[448,512,[],"f3b1","M414.9 161.5C340.2 29 121.1 0 121.1 0S222.2 110.4 93 197.7C11.3 252.8-21 324.4 14 402.6c26.8 59.9 83.5 84.3 144.6 93.4-29.2-55.1-6.6-122.4-4.1-129.6 57.1 86.4 165 0 110.8-93.9 71 15.4 81.6 138.6 27.1 215.5 80.5-25.3 134.1-88.9 148.8-145.6 15.5-59.3 3.7-127.9-26.3-180.9z"],houzz:[414,512,[],"f27c","M258.9 330.7H154.3V480H0V32h109.5v104.5l305.1 85.6V480H258.9V330.7z"],html5:[384,512,[],"f13b","M0 32l34.9 395.8L191.5 480l157.6-52.2L384 32H0zm308.2 127.9H124.4l4.1 49.4h175.6l-13.6 148.4-97.9 27v.3h-1.1l-98.7-27.3-6-75.8h47.7L138 320l53.5 14.5 53.7-14.5 6-62.2H84.3L71.5 112.2h241.1l-4.4 47.7z"],hubspot:[512,512,[],"f3b2","M267.4 211.6c-25.1 23.7-40.8 57.3-40.8 94.6 0 29.3 9.7 56.3 26 78L203.1 434c-4.4-1.6-9.1-2.5-14-2.5-10.8 0-20.9 4.2-28.5 11.8-7.6 7.6-11.8 17.8-11.8 28.6s4.2 20.9 11.8 28.5c7.6 7.6 17.8 11.6 28.5 11.6 10.8 0 20.9-3.9 28.6-11.6 7.6-7.6 11.8-17.8 11.8-28.5 0-4.2-.6-8.2-1.9-12.1l50-50.2c22 16.9 49.4 26.9 79.3 26.9 71.9 0 130-58.3 130-130.2 0-65.2-47.7-119.2-110.2-128.7V116c17.5-7.4 28.2-23.8 28.2-42.9 0-26.1-20.9-47.9-47-47.9S311.2 47 311.2 73.1c0 19.1 10.7 35.5 28.2 42.9v61.2c-15.2 2.1-29.6 6.7-42.7 13.6-27.6-20.9-117.5-85.7-168.9-124.8 1.2-4.4 2-9 2-13.8C129.8 23.4 106.3 0 77.4 0 48.6 0 25.2 23.4 25.2 52.2c0 28.9 23.4 52.3 52.2 52.3 9.8 0 18.9-2.9 26.8-7.6l163.2 114.7zm89.5 163.6c-38.1 0-69-30.9-69-69s30.9-69 69-69 69 30.9 69 69-30.9 69-69 69z"],imdb:[448,512,[],"f2d8","M350.5 288.7c0 5.4 1.6 14.4-6.2 14.4-1.6 0-3-.8-3.8-2.4-2.2-5.1-1.1-44.1-1.1-44.7 0-3.8-1.1-12.7 4.9-12.7 7.3 0 6.2 7.3 6.2 12.7v32.7zM265 229.9c0-9.7 1.6-16-10.3-16v83.7c12.2.3 10.3-8.7 10.3-18.4v-49.3zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM21.3 228.8c-.1.1-.2.3-.3.4h.3v-.4zM97 192H64v127.8h33V192zm113.3 0h-43.1l-7.6 59.9c-2.7-20-5.4-40.1-8.7-59.9h-42.8v127.8h29v-84.5l12.2 84.5h20.6l11.6-86.4v86.4h28.7V192zm86.3 45.3c0-8.1.3-16.8-1.4-24.4-4.3-22.5-31.4-20.9-49-20.9h-24.6v127.8c86.1.1 75 6 75-82.5zm85.9 17.3c0-17.3-.8-30.1-22.2-30.1-8.9 0-14.9 2.7-20.9 9.2V192h-31.7v127.8h29.8l1.9-8.1c5.7 6.8 11.9 9.8 20.9 9.8 19.8 0 22.2-15.2 22.2-30.9v-36z"],instagram:[448,512,[],"f16d","M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z"],"internet-explorer":[512,512,[],"f26b","M483.049 159.706c10.855-24.575 21.424-60.438 21.424-87.871 0-72.722-79.641-98.371-209.673-38.577-107.632-7.181-211.221 73.67-237.098 186.457 30.852-34.862 78.271-82.298 121.977-101.158C125.404 166.85 79.128 228.002 43.992 291.725 23.246 329.651 0 390.94 0 436.747c0 98.575 92.854 86.5 180.251 42.006 31.423 15.43 66.559 15.573 101.695 15.573 97.124 0 184.249-54.294 216.814-146.022H377.927c-52.509 88.593-196.819 52.996-196.819-47.436H509.9c6.407-43.581-1.655-95.715-26.851-141.162zM64.559 346.877c17.711 51.15 53.703 95.871 100.266 123.304-88.741 48.94-173.267 29.096-100.266-123.304zm115.977-108.873c2-55.151 50.276-94.871 103.98-94.871 53.418 0 101.981 39.72 103.981 94.871H180.536zm184.536-187.6c21.425-10.287 48.563-22.003 72.558-22.003 31.422 0 54.274 21.717 54.274 53.722 0 20.003-7.427 49.007-14.569 67.867-26.28-42.292-65.986-81.584-112.263-99.586z"],ioxhost:[640,512,[],"f208","M616 160h-67.3C511.2 70.7 422.9 8 320 8 183 8 72 119 72 256c0 16.4 1.6 32.5 4.7 48H24c-13.3 0-24 10.8-24 24 0 13.3 10.7 24 24 24h67.3c37.5 89.3 125.8 152 228.7 152 137 0 248-111 248-248 0-16.4-1.6-32.5-4.7-48H616c13.3 0 24-10.8 24-24 0-13.3-10.7-24-24-24zm-96 96c0 110.5-89.5 200-200 200-75.7 0-141.6-42-175.5-104H424c13.3 0 24-10.8 24-24 0-13.3-10.7-24-24-24H125.8c-3.8-15.4-5.8-31.4-5.8-48 0-110.5 89.5-200 200-200 75.7 0 141.6 42 175.5 104H216c-13.3 0-24 10.8-24 24 0 13.3 10.7 24 24 24h298.2c3.8 15.4 5.8 31.4 5.8 48zm-304-24h208c13.3 0 24 10.7 24 24 0 13.2-10.7 24-24 24H216c-13.3 0-24-10.7-24-24 0-13.2 10.7-24 24-24z"],itunes:[448,512,[],"f3b4","M223.6 80.3C129 80.3 52.5 157 52.5 251.5S129 422.8 223.6 422.8s171.2-76.7 171.2-171.2c0-94.6-76.7-171.3-171.2-171.3zm79.4 240c-3.2 13.6-13.5 21.2-27.3 23.8-12.1 2.2-22.2 2.8-31.9-5-11.8-10-12-26.4-1.4-36.8 8.4-8 20.3-9.6 38-12.8 3-.5 5.6-1.2 7.7-3.7 3.2-3.6 2.2-2 2.2-80.8 0-5.6-2.7-7.1-8.4-6.1-4 .7-91.9 17.1-91.9 17.1-5 1.1-6.7 2.6-6.7 8.3 0 116.1.5 110.8-1.2 118.5-2.1 9-7.6 15.8-14.9 19.6-8.3 4.6-23.4 6.6-31.4 5.2-21.4-4-28.9-28.7-14.4-42.9 8.4-8 20.3-9.6 38-12.8 3-.5 5.6-1.2 7.7-3.7 5-5.7.9-127 2.6-133.7.4-2.6 1.5-4.8 3.5-6.4 2.1-1.7 5.8-2.7 6.7-2.7 101-19 113.3-21.4 115.1-21.4 5.7-.4 9 3 9 8.7-.1 170.6.4 161.4-1 167.6zM345.2 32H102.8C45.9 32 0 77.9 0 134.8v242.4C0 434.1 45.9 480 102.8 480h242.4c57 0 102.8-45.9 102.8-102.8V134.8C448 77.9 402.1 32 345.2 32zM223.6 444c-106.3 0-192.5-86.2-192.5-192.5S117.3 59 223.6 59s192.5 86.2 192.5 192.5S329.9 444 223.6 444z"],"itunes-note":[384,512,[],"f3b5","M381.9 388.2c-6.4 27.4-27.2 42.8-55.1 48-24.5 4.5-44.9 5.6-64.5-10.2-23.9-20.1-24.2-53.4-2.7-74.4 17-16.2 40.9-19.5 76.8-25.8 6-1.1 11.2-2.5 15.6-7.4 6.4-7.2 4.4-4.1 4.4-163.2 0-11.2-5.5-14.3-17-12.3-8.2 1.4-185.7 34.6-185.7 34.6-10.2 2.2-13.4 5.2-13.4 16.7 0 234.7 1.1 223.9-2.5 239.5-4.2 18.2-15.4 31.9-30.2 39.5-16.8 9.3-47.2 13.4-63.4 10.4-43.2-8.1-58.4-58-29.1-86.6 17-16.2 40.9-19.5 76.8-25.8 6-1.1 11.2-2.5 15.6-7.4 10.1-11.5 1.8-256.6 5.2-270.2.8-5.2 3-9.6 7.1-12.9 4.2-3.5 11.8-5.5 13.4-5.5 204-38.2 228.9-43.1 232.4-43.1 11.5-.8 18.1 6 18.1 17.6.2 344.5 1.1 326-1.8 338.5z"],java:[377,512,[],"f4e4","M121.6 396s-19.6 11.4 13.9 15.2c40.6 4.6 61.3 4 106-4.5 0 0 11.8 7.4 28.2 13.8C169.5 463.4 42.9 418 121.6 396m-12.2-56.1s-21.9 16.2 11.6 19.7c43.3 4.5 77.6 4.8 136.8-6.6 0 0 8.2 8.3 21.1 12.8-121.3 35.5-256.3 2.9-169.5-25.9m103.2-95.1c24.7 28.4-6.5 54-6.5 54s62.7-32.4 33.9-72.9c-26.9-37.8-47.5-56.6 64.1-121.3.1 0-175.2 43.8-91.5 140.2m132.6 192.6s14.5 11.9-15.9 21.2c-57.9 17.5-240.8 22.8-291.6.7-18.3-7.9 16-19 26.8-21.3 11.2-2.4 17.7-2 17.7-2-20.3-14.3-131.3 28.1-56.4 40.2 204.2 33.2 372.4-14.9 319.4-38.8M131 281.8s-93.1 22.1-33 30.1c25.4 3.4 76 2.6 123.1-1.3 38.5-3.2 77.2-10.2 77.2-10.2s-13.6 5.8-23.4 12.5c-94.5 24.9-277 13.3-224.5-12.1 44.5-21.4 80.6-19 80.6-19m167 93.3c96.1-49.9 51.6-97.9 20.6-91.4-7.6 1.6-11 3-11 3s2.8-4.4 8.2-6.3c61.3-21.6 108.5 63.6-19.8 97.3 0-.1 1.5-1.4 2-2.6M240 0s53.2 53.2-50.5 135c-83.1 65.6-19 103.1 0 145.8-48.5-43.8-84.1-82.3-60.2-118.2C164.4 110.1 261.5 84.5 240 0m-99.5 510.4c92.2 5.9 233.8-3.3 237.1-46.9 0 0-6.4 16.5-76.2 29.7-78.7 14.8-175.8 13.1-233.3 3.6 0-.1 11.8 9.7 72.4 13.6"],jenkins:[512,512,[],"f3b6","M487.1 425c-1.4-11.2-19-23.1-28.2-31.9-5.1-5-29-23.1-30.4-29.9-1.4-6.6 9.7-21.5 13.3-28.9 5.1-10.7 8.8-23.7 11.3-32.6 18.8-66.1 20.7-156.9-6.2-211.2-10.2-20.6-38.6-49-56.4-62.5-42-31.7-119.6-35.3-170.1-16.6-14.1 5.2-27.8 9.8-40.1 17.1-33.1 19.4-68.3 32.5-78.1 71.6-24.2 10.8-31.5 41.8-30.3 77.8.2 7 4.1 15.8 2.7 22.4-.7 3.3-5.2 7.6-6.1 9.8-11.6 27.7-2.3 64 11.1 83.7 8.1 11.9 21.5 22.4 39.2 25.2.7 10.6 3.3 19.7 8.2 30.4 3.1 6.8 14.7 19 10.4 27.7-2.2 4.4-21 13.8-27.3 17.6C89 407.2 73.7 415 54.2 429c-12.6 9-32.3 10.2-29.2 31.1 2.1 14.1 10.1 31.6 14.7 45.8.7 2 1.4 4.1 2.1 6h422c4.9-15.3 9.7-30.9 14.6-47.2 3.4-11.4 10.2-27.8 8.7-39.7zM205.9 33.7c1.8-.5 3.4.7 4.9 2.4-.2 5.2-5.4 5.1-8.9 6.8-5.4 6.7-13.4 9.8-20 17.2-6.8 7.5-14.4 27.7-23.4 30-4.5 1.1-9.7-.8-13.6-.5-10.4.7-17.7 6-28.3 7.5 13.6-29.9 56.1-54 89.3-63.4zm-104.8 93.6c13.5-14.9 32.1-24.1 54.8-25.9 11.7 29.7-8.4 65-.9 97.6 2.3 9.9 10.2 25.4-2.4 25.7.3-28.3-34.8-46.3-61.3-29.6-1.8-21.5-4.9-51.7 9.8-67.8zm36.7 200.2c-1-4.1-2.7-12.9-2.3-15.1 1.6-8.7 17.1-12.5 11-24.7-11.3-.1-13.8 10.2-24.1 11.3-26.7 2.6-45.6-35.4-44.4-58.4 1-19.5 17.6-38.2 40.1-35.8 16 1.8 21.4 19.2 24.5 34.7 9.2.5 22.5-.4 26.9-7.6-.6-17.5-8.8-31.6-8.2-47.7 1-30.3 17.5-57.6 4.8-87.4 13.6-30.9 53.5-55.3 83.1-70 36.6-18.3 94.9-3.7 129.3 15.8 19.7 11.1 34.4 32.7 48.3 50.7-19.5-5.8-36.1 4.2-33.1 20.3 16.3-14.9 44.2-.2 52.5 16.4 7.9 15.8 7.8 39.3 9 62.8 2.9 57-10.4 115.9-39.1 157.1-7.7 11-14.1 23-24.9 30.6-26 18.2-65.4 34.7-99.2 23.4-44.7-15-65-44.8-89.5-78.8.7 18.7 13.8 34.1 26.8 48.4 11.3 12.5 25 26.6 39.7 32.4-12.3-2.9-31.1-3.8-36.2 7.2-28.6-1.9-55.1-4.8-68.7-24.2-10.6-15.4-21.4-41.4-26.3-61.4zm222 124.1c4.1-3 11.1-2.9 17.4-3.6-5.4-2.7-13-3.7-19.3-2.2-.1-4.2-2-6.8-3.2-10.2 10.6-3.8 35.5-28.5 49.6-20.3 6.7 3.9 9.5 26.2 10.1 37 .4 9-.8 18-4.5 22.8-18.8-.6-35.8-2.8-50.7-7 .9-6.1-1-12.1.6-16.5zm-17.2-20c-16.8.8-26-1.2-38.3-10.8.2-.8 1.4-.5 1.5-1.4 18 8 40.8-3.3 59-4.9-7.9 5.1-14.6 11.6-22.2 17.1zm-12.1 33.2c-1.6-9.4-3.5-12-2.8-20.2 25-16.6 29.7 28.6 2.8 20.2zM226 438.6c-11.6-.7-48.1-14-38.5-23.7 9.4 6.5 27.5 4.9 41.3 7.3.8 4.4-2.8 10.2-2.8 16.4zM57.7 497.1c-4.3-12.7-9.2-25.1-14.8-36.9 30.8-23.8 65.3-48.9 102.2-63.5 2.8-1.1 23.2 25.4 26.2 27.6 16.5 11.7 37 21 56.2 30.2 1.2 8.8 3.9 20.2 8.7 35.5.7 2.3 1.4 4.7 2.2 7.2H57.7zm240.6 5.7h-.8c.3-.2.5-.4.8-.5v.5zm7.5-5.7c2.1-1.4 4.3-2.8 6.4-4.3 1.1 1.4 2.2 2.8 3.2 4.3h-9.6zm15.1-24.7c-10.8 7.3-20.6 18.3-33.3 25.2-6 3.3-27 11.7-33.4 10.2-3.6-.8-3.9-5.3-5.4-9.5-3.1-9-10.1-23.4-10.8-37-.8-17.2-2.5-46 16-42.4 14.9 2.9 32.3 9.7 43.9 16.1 7.1 3.9 11.1 8.6 21.9 9.5-.1 1.4-.1 2.8-.2 4.3-5.9 3.9-15.3 3.8-21.8 7.1 9.5.4 17 2.7 23.5 5.9-.1 3.4-.3 7-.4 10.6zm53.4 24.7h-14c-.1-3.2-2.8-5.8-6.1-5.8s-5.9 2.6-6.1 5.8h-17.4c-2.8-4.4-5.7-8.6-8.9-12.5 2.1-2.2 4-4.7 6-6.9 9 3.7 14.8-4.9 21.7-4.2 7.9.8 14.2 11.7 25.4 11l-.6 12.6zm8.7 0c.2-4 .4-7.8.6-11.5 15.6-7.3 29 1.3 35.7 11.5H383zm83.4-37c-2.3 11.2-5.8 24-9.9 37.1-.2-.1-.4-.1-.6-.1H428c.6-1.1 1.2-2.2 1.9-3.3-2.6-6.1-9-8.7-10.9-15.5 12.1-22.7 6.5-93.4-24.2-78.5 4.3-6.3 15.6-11.5 20.8-19.3 13 10.4 20.8 20.3 33.2 31.4 6.8 6 20 13.3 21.4 23.1.8 5.5-2.6 18.9-3.8 25.1zM222.2 130.5c5.4-14.9 27.2-34.7 45-32 7.7 1.2 18 8.2 12.2 17.7-30.2-7-45.2 12.6-54.4 33.1-8.1-2-4.9-13.1-2.8-18.8zm184.1 63.1c8.2-3.6 22.4-.7 29.6-5.3-4.2-11.5-10.3-21.4-9.3-37.7.5 0 1 0 1.4.1 6.8 14.2 12.7 29.2 21.4 41.7-5.7 13.5-43.6 25.4-43.1 1.2zm20.4-43zm-117.2 45.7c-6.8-10.9-19-32.5-14.5-45.3 6.5 11.9 8.6 24.4 17.8 33.3 4.1 4 12.2 9 8.2 20.2-.9 2.7-7.8 8.6-11.7 9.7-14.4 4.3-47.9.9-36.6-17.1 11.9.7 27.9 7.8 36.8-.8zm27.3 70c3.8 6.6 1.4 18.7 12.1 20.6 20.2 3.4 43.6-12.3 58.1-17.8 9-15.2-.8-20.7-8.9-30.5-16.6-20-38.8-44.8-38-74.7 6.7-4.9 7.3 7.4 8.2 9.7 8.7 20.3 30.4 46.2 46.3 63.5 3.9 4.3 10.3 8.4 11 11.2 2.1 8.2-5.4 18-4.5 23.5-21.7 13.9-45.8 29.1-81.4 25.6-7.4-6.7-10.3-21.4-2.9-31.1zm-201.3-9.2c-6.8-3.9-8.4-21-16.4-21.4-11.4-.7-9.3 22.2-9.3 35.5-7.8-7.1-9.2-29.1-3.5-40.3-6.6-3.2-9.5 3.6-13.1 5.9 4.7-34.1 49.8-15.8 42.3 20.3zm299.6 28.8c-10.1 19.2-24.4 40.4-54 41-.6-6.2-1.1-15.6 0-19.4 22.7-2.2 36.6-13.7 54-21.6zm-141.9 12.4c18.9 9.9 53.6 11 79.3 10.2 1.4 5.6 1.3 12.6 1.4 19.4-33 1.8-72-6.4-80.7-29.6zm92.2 46.7c-1.7 4.3-5.3 9.3-9.8 11.1-12.1 4.9-45.6 8.7-62.4-.3-10.7-5.7-17.5-18.5-23.4-26-2.8-3.6-16.9-12.9-.2-12.9 13.1 32.7 58 29 95.8 28.1z"],joget:[496,512,[],"f3b7","M227.5 468.7c-9-13.6-19.9-33.3-23.7-42.4-5.7-13.7-27.2-45.6 31.2-67.1 51.7-19.1 176.7-16.5 208.8-17.6-4 9-8.6 17.9-13.9 26.6-40.4 65.5-110.4 101.5-182 101.5-6.8 0-13.6-.4-20.4-1M66.1 143.9C128 43.4 259.6 12.2 360.1 74.1c74.8 46.1 111.2 130.9 99.3 212.7-24.9-.5-179.3-3.6-230.3-4.9-55.5-1.4-81.7-20.8-58.5-48.2 23.2-27.4 51.1-40.7 68.9-51.2 17.9-10.5 27.3-33.7-23.6-29.7C87.3 161.5 48.6 252.1 37.6 293c-8.8-49.7-.1-102.7 28.5-149.1m-29.2-18c-71.9 116.6-35.6 269.3 81 341.2 116.6 71.9 269.3 35.6 341.2-80.9 71.9-116.6 35.6-269.4-81-341.2-40.5-25.1-85.5-37-129.9-37C165 8 83.8 49.9 36.9 125.9m244.4 110.4c-31.5 20.5-65.3 31.3-65.3 31.3l169.5-1.6 46.5-23.4s3.6-9.5-19.1-15.5c-22.7-6-57 11.3-86.7 27.2-29.7 15.8-31.1 8.2-31.1 8.2s40.2-28.1 50.7-34.5c10.5-6.4 31.9-14 13.4-24.6-3.2-1.8-6.7-2.7-10.4-2.7-17.8 0-41.5 18.7-67.5 35.6"],joomla:[448,512,[],"f1aa","M.6 92.1C.6 58.8 27.4 32 60.4 32c30 0 54.5 21.9 59.2 50.2 32.6-7.6 67.1.6 96.5 30l-44.3 44.3c-20.5-20.5-42.6-16.3-55.4-3.5-14.3 14.3-14.3 37.9 0 52.2l99.5 99.5-44 44.3c-87.7-87.2-49.7-49.7-99.8-99.7-26.8-26.5-35-64.8-24.8-98.9C20.4 144.6.6 120.7.6 92.1zm129.5 116.4l44.3 44.3c10-10 89.7-89.7 99.7-99.8 14.3-14.3 37.6-14.3 51.9 0 12.8 12.8 17 35-3.5 55.4l44 44.3c31.2-31.2 38.5-67.6 28.9-101.2 29.2-4.1 51.9-29.2 51.9-59.5 0-33.2-26.8-60.1-59.8-60.1-30.3 0-55.4 22.5-59.5 51.6-33.8-9.9-71.7-1.5-98.3 25.1-18.3 19.1-71.1 71.5-99.6 99.9zm266.3 152.2c8.2-32.7-.9-68.5-26.3-93.9-11.8-12.2 5 4.7-99.5-99.7l-44.3 44.3 99.7 99.7c14.3 14.3 14.3 37.6 0 51.9-12.8 12.8-35 17-55.4-3.5l-44 44.3c27.6 30.2 68 38.8 102.7 28 5.5 27.4 29.7 48.1 58.9 48.1 33 0 59.8-26.8 59.8-60.1 0-30.2-22.5-55-51.6-59.1zm-84.3-53.1l-44-44.3c-87 86.4-50.4 50.4-99.7 99.8-14.3 14.3-37.6 14.3-51.9 0-13.1-13.4-16.9-35.3 3.2-55.4l-44-44.3c-30.2 30.2-38 65.2-29.5 98.3-26.7 6-46.2 29.9-46.2 58.2C0 453.2 26.8 480 59.8 480c28.6 0 52.5-19.8 58.6-46.7 32.7 8.2 68.5-.6 94.2-26 32.1-32 12.2-12.4 99.5-99.7z"],js:[448,512,[],"f3b8","M0 32v448h448V32H0zm243.8 349.4c0 43.6-25.6 63.5-62.9 63.5-33.7 0-53.2-17.4-63.2-38.5l34.3-20.7c6.6 11.7 12.6 21.6 27.1 21.6 13.8 0 22.6-5.4 22.6-26.5V237.7h42.1v143.7zm99.6 63.5c-39.1 0-64.4-18.6-76.7-43l34.3-19.8c9 14.7 20.8 25.6 41.5 25.6 17.4 0 28.6-8.7 28.6-20.8 0-14.4-11.4-19.5-30.7-28l-10.5-4.5c-30.4-12.9-50.5-29.2-50.5-63.5 0-31.6 24.1-55.6 61.6-55.6 26.8 0 46 9.3 59.8 33.7L368 290c-7.2-12.9-15-18-27.1-18-12.3 0-20.1 7.8-20.1 18 0 12.6 7.8 17.7 25.9 25.6l10.5 4.5c35.8 15.3 55.9 31 55.9 66.2 0 37.8-29.8 58.6-69.7 58.6z"],"js-square":[448,512,[],"f3b9","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM243.8 381.4c0 43.6-25.6 63.5-62.9 63.5-33.7 0-53.2-17.4-63.2-38.5l34.3-20.7c6.6 11.7 12.6 21.6 27.1 21.6 13.8 0 22.6-5.4 22.6-26.5V237.7h42.1v143.7zm99.6 63.5c-39.1 0-64.4-18.6-76.7-43l34.3-19.8c9 14.7 20.8 25.6 41.5 25.6 17.4 0 28.6-8.7 28.6-20.8 0-14.4-11.4-19.5-30.7-28l-10.5-4.5c-30.4-12.9-50.5-29.2-50.5-63.5 0-31.6 24.1-55.6 61.6-55.6 26.8 0 46 9.3 59.8 33.7L368 290c-7.2-12.9-15-18-27.1-18-12.3 0-20.1 7.8-20.1 18 0 12.6 7.8 17.7 25.9 25.6l10.5 4.5c35.8 15.3 55.9 31 55.9 66.2 0 37.8-29.8 58.6-69.7 58.6z"],jsfiddle:[576,512,[],"f1cc","M510.634 237.462c-4.727-2.621-5.664-5.748-6.381-10.776-2.352-16.488-3.539-33.619-9.097-49.095-35.895-99.957-153.99-143.386-246.849-91.646-27.37 15.25-48.971 36.369-65.493 63.903-3.184-1.508-5.458-2.71-7.824-3.686-30.102-12.421-59.049-10.121-85.331 9.167-25.531 18.737-36.422 44.548-32.676 76.408.355 3.025-1.967 7.621-4.514 9.545-39.712 29.992-56.031 78.065-41.902 124.615 13.831 45.569 57.514 79.796 105.608 81.433 30.291 1.031 60.637.546 90.959.539 84.041-.021 168.09.531 252.12-.48 52.664-.634 96.108-36.873 108.212-87.293 11.54-48.074-11.144-97.3-56.832-122.634zm21.107 156.88c-18.23 22.432-42.343 35.253-71.28 35.65-56.874.781-113.767.23-170.652.23 0 .7-163.028.159-163.728.154-43.861-.332-76.739-19.766-95.175-59.995-18.902-41.245-4.004-90.848 34.186-116.106 9.182-6.073 12.505-11.566 10.096-23.136-5.49-26.361 4.453-47.956 26.42-62.981 22.987-15.723 47.422-16.146 72.034-3.083 10.269 5.45 14.607 11.564 22.198-2.527 14.222-26.399 34.557-46.727 60.671-61.294 97.46-54.366 228.37 7.568 230.24 132.697.122 8.15 2.412 12.428 9.848 15.894 57.56 26.829 74.456 96.122 35.142 144.497zm-87.789-80.499c-5.848 31.157-34.622 55.096-66.666 55.095-16.953-.001-32.058-6.545-44.079-17.705-27.697-25.713-71.141-74.98-95.937-93.387-20.056-14.888-41.99-12.333-60.272 3.782-49.996 44.071 15.859 121.775 67.063 77.188 4.548-3.96 7.84-9.543 12.744-12.844 8.184-5.509 20.766-.884 13.168 10.622-17.358 26.284-49.33 38.197-78.863 29.301-28.897-8.704-48.84-35.968-48.626-70.179 1.225-22.485 12.364-43.06 35.414-55.965 22.575-12.638 46.369-13.146 66.991 2.474C295.68 280.7 320.467 323.97 352.185 343.47c24.558 15.099 54.254 7.363 68.823-17.506 28.83-49.209-34.592-105.016-78.868-63.46-3.989 3.744-6.917 8.932-11.41 11.72-10.975 6.811-17.333-4.113-12.809-10.353 20.703-28.554 50.464-40.44 83.271-28.214 31.429 11.714 49.108 44.366 42.76 78.186z"],keycdn:[512,512,[],"f3ba","M63.8 409.3l60.5-59c32.1 42.8 71.1 66 126.6 67.4 30.5.7 60.3-7 86.4-22.4 5.1 5.3 18.5 19.5 20.9 22-32.2 20.7-69.6 31.1-108.1 30.2-43.3-1.1-84.6-16.7-117.7-44.4.3-.6-38.2 37.5-38.6 37.9 9.5 29.8-13.1 62.4-46.3 62.4C20.7 503.3 0 481.7 0 454.9c0-34.3 33.1-56.6 63.8-45.6zm354.9-252.4c19.1 31.3 29.6 67.4 28.7 104-1.1 44.8-19 87.5-48.6 121 .3.3 23.8 25.2 24.1 25.5 9.6-1.3 19.2 2 25.9 9.1 11.3 12 10.9 30.9-1.1 42.4-12 11.3-30.9 10.9-42.4-1.1-6.7-7-9.4-16.8-7.6-26.3-24.9-26.6-44.4-47.2-44.4-47.2 42.7-34.1 63.3-79.6 64.4-124.2.7-28.9-7.2-57.2-21.1-82.2l22.1-21zM104 53.1c6.7 7 9.4 16.8 7.6 26.3l45.9 48.1c-4.7 3.8-13.3 10.4-22.8 21.3-25.4 28.5-39.6 64.8-40.7 102.9-.7 28.9 6.1 57.2 20 82.4l-22 21.5C72.7 324 63.1 287.9 64.2 250.9c1-44.6 18.3-87.6 47.5-121.1l-25.3-26.4c-9.6 1.3-19.2-2-25.9-9.1-11.3-12-10.9-30.9 1.1-42.4C73.5 40.7 92.2 41 104 53.1zM464.9 8c26 0 47.1 22.4 47.1 48.3S490.9 104 464.9 104c-6.3.1-14-1.1-15.9-1.8l-62.9 59.7c-32.7-43.6-76.7-65.9-126.9-67.2-30.5-.7-60.3 6.8-86.2 22.4l-21.1-22C184.1 74.3 221.5 64 260 64.9c43.3 1.1 84.6 16.7 117.7 44.6l41.1-38.6c-1.5-4.7-2.2-9.6-2.2-14.5C416.5 29.7 438.9 8 464.9 8zM256.7 113.4c5.5 0 10.9.4 16.4 1.1 78.1 9.8 133.4 81.1 123.8 159.1-9.8 78.1-81.1 133.4-159.1 123.8-78.1-9.8-133.4-81.1-123.8-159.2 9.3-72.4 70.1-124.6 142.7-124.8zm-59 119.4c.6 22.7 12.2 41.8 32.4 52.2l-11 51.7h73.7l-11-51.7c20.1-10.9 32.1-29 32.4-52.2-.4-32.8-25.8-57.5-58.3-58.3-32.1.8-57.3 24.8-58.2 58.3zM256 160"],kickstarter:[448,512,[],"f3bb","M400 480H48c-26.4 0-48-21.6-48-48V80c0-26.4 21.6-48 48-48h352c26.4 0 48 21.6 48 48v352c0 26.4-21.6 48-48 48zM199.6 178.5c0-30.7-17.6-45.1-39.7-45.1-25.8 0-40 19.8-40 44.5v154.8c0 25.8 13.7 45.6 40.5 45.6 21.5 0 39.2-14 39.2-45.6v-41.8l60.6 75.7c12.3 14.9 39 16.8 55.8 0 14.6-15.1 14.8-36.8 4-50.4l-49.1-62.8 40.5-58.7c9.4-13.5 9.5-34.5-5.6-49.1-16.4-15.9-44.6-17.3-61.4 7l-44.8 64.7v-38.8z"],"kickstarter-k":[384,512,[],"f3bc","M147.3 114.4c0-56.2-32.5-82.4-73.4-82.4C26.2 32 0 68.2 0 113.4v283c0 47.3 25.3 83.4 74.9 83.4 39.8 0 72.4-25.6 72.4-83.4v-76.5l112.1 138.3c22.7 27.2 72.1 30.7 103.2 0 27-27.6 27.3-67.4 7.4-92.2l-90.8-114.8 74.9-107.4c17.4-24.7 17.5-63.1-10.4-89.8-30.3-29-82.4-31.6-113.6 12.8L147.3 185v-70.6z"],korvue:[446,512,[],"f42f","M386.5 34h-327C26.8 34 0 60.8 0 93.5v327.1C0 453.2 26.8 480 59.5 480h327.1c33 0 59.5-26.8 59.5-59.5v-327C446 60.8 419.2 34 386.5 34zM87.1 120.8h96v116l61.8-116h110.9l-81.2 132H87.1v-132zm161.8 272.1l-65.7-113.6v113.6h-96V262.1h191.5l88.6 130.8H248.9z"],laravel:[640,512,[],"f3bd","M637.5 241.6c-4.2-4.8-62.8-78.1-73.1-90.5-10.3-12.4-15.4-10.2-21.7-9.3-6.4.9-80.5 13.4-89.1 14.8-8.6 1.5-14 4.9-8.7 12.3 4.7 6.6 53.4 75.7 64.2 90.9l-193.7 46.4L161.2 48.7c-6.1-9.1-7.4-12.3-21.4-11.6-14 .6-120.9 9.5-128.5 10.2-7.6.6-16 4-8.4 22s129 279.6 132.4 287.2c3.4 7.6 12.2 20 32.8 15 21.1-5.1 94.3-24.2 134.3-34.7 21.1 38.3 64.2 115.9 72.2 127 10.6 14.9 18 12.4 34.3 7.4 12.8-3.9 199.6-71.1 208-74.5 8.4-3.5 13.6-5.9 7.9-14.4-4.2-6.2-53.5-72.2-79.3-106.8 17.7-4.7 80.6-21.4 87.3-23.3 7.9-2 9-5.8 4.7-10.6zm-352.2 72c-2.3.5-110.8 26.5-116.6 27.8-5.8 1.3-5.8.7-6.5-1.3-.7-2-129-266.7-130.8-270-1.8-3.3-1.7-5.9 0-5.9s102.5-9 106-9.2c3.6-.2 3.2.6 4.5 2.8 0 0 142.2 245.4 144.6 249.7 2.6 4.3 1.1 5.6-1.2 6.1zm306 57.4c1.7 2.7 3.5 4.5-2 6.4-5.4 2-183.7 62.1-187.1 63.6-3.5 1.5-6.2 2-10.6-4.5s-62.4-106.8-62.4-106.8L518 280.6c4.7-1.5 6.2-2.5 9.2 2.2 2.9 4.8 62.4 85.5 64.1 88.2zm12.1-134.1c-4.2.9-73.6 18.1-73.6 18.1l-56.7-77.8c-1.6-2.3-2.9-4.5 1.1-5s68.4-12.2 71.3-12.8c2.9-.7 5.4-1.5 9 3.4 3.6 4.9 52.6 67 54.5 69.4 1.8 2.3-1.4 3.7-5.6 4.7z"],lastfm:[512,512,[],"f202","M225.8 367.1l-18.8-51s-30.5 34-76.2 34c-40.5 0-69.2-35.2-69.2-91.5 0-72.1 36.4-97.9 72.1-97.9 66.5 0 74.8 53.3 100.9 134.9 18.8 56.9 54 102.6 155.4 102.6 72.7 0 122-22.3 122-80.9 0-72.9-62.7-80.6-115-92.1-25.8-5.9-33.4-16.4-33.4-34 0-19.9 15.8-31.7 41.6-31.7 28.2 0 43.4 10.6 45.7 35.8l58.6-7c-4.7-52.8-41.1-74.5-100.9-74.5-52.8 0-104.4 19.9-104.4 83.9 0 39.9 19.4 65.1 68 76.8 44.9 10.6 79.8 13.8 79.8 45.7 0 21.7-21.1 30.5-61 30.5-59.2 0-83.9-31.1-97.9-73.9-32-96.8-43.6-163-161.3-163C45.7 113.8 0 168.3 0 261c0 89.1 45.7 137.2 127.9 137.2 66.2 0 97.9-31.1 97.9-31.1z"],"lastfm-square":[448,512,[],"f203","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-92.2 312.9c-63.4 0-85.4-28.6-97.1-64.1-16.3-51-21.5-84.3-63-84.3-22.4 0-45.1 16.1-45.1 61.2 0 35.2 18 57.2 43.3 57.2 28.6 0 47.6-21.3 47.6-21.3l11.7 31.9s-19.8 19.4-61.2 19.4c-51.3 0-79.9-30.1-79.9-85.8 0-57.9 28.6-92 82.5-92 73.5 0 80.8 41.4 100.8 101.9 8.8 26.8 24.2 46.2 61.2 46.2 24.9 0 38.1-5.5 38.1-19.1 0-19.9-21.8-22-49.9-28.6-30.4-7.3-42.5-23.1-42.5-48 0-40 32.3-52.4 65.2-52.4 37.4 0 60.1 13.6 63 46.6l-36.7 4.4c-1.5-15.8-11-22.4-28.6-22.4-16.1 0-26 7.3-26 19.8 0 11 4.8 17.6 20.9 21.3 32.7 7.1 71.8 12 71.8 57.5.1 36.7-30.7 50.6-76.1 50.6z"],leanpub:[576,512,[],"f212","M386.539 111.485l15.096 248.955-10.979-.275c-36.232-.824-71.64 8.783-102.657 27.997-31.016-19.214-66.424-27.997-102.657-27.997-45.564 0-82.07 10.705-123.516 27.723L93.117 129.6c28.546-11.803 61.484-18.115 92.226-18.115 41.173 0 73.836 13.175 102.657 42.544 27.723-28.271 59.013-41.721 98.539-42.544zM569.07 448c-25.526 0-47.485-5.215-70.542-15.645-34.31-15.645-69.993-24.978-107.871-24.978-38.977 0-74.934 12.901-102.657 40.623-27.723-27.723-63.68-40.623-102.657-40.623-37.878 0-73.561 9.333-107.871 24.978C55.239 442.236 32.731 448 8.303 448H6.93L49.475 98.859C88.726 76.626 136.486 64 181.775 64 218.83 64 256.984 71.685 288 93.095 319.016 71.685 357.17 64 394.225 64c45.289 0 93.049 12.626 132.3 34.859L569.07 448zm-43.368-44.741l-34.036-280.246c-30.742-13.999-67.248-21.41-101.009-21.41-38.428 0-74.385 12.077-102.657 38.702-28.272-26.625-64.228-38.702-102.657-38.702-33.761 0-70.267 7.411-101.009 21.41L50.298 403.259c47.211-19.487 82.894-33.486 135.045-33.486 37.604 0 70.817 9.606 102.657 29.644 31.84-20.038 65.052-29.644 102.657-29.644 52.151 0 87.834 13.999 135.045 33.486z"],less:[640,512,[],"f41d","M612.7 219c0-20.5 3.2-32.6 3.2-54.6 0-34.2-12.6-45.2-40.5-45.2h-20.5v24.2h6.3c14.2 0 17.3 4.7 17.3 22.1 0 16.3-1.6 32.6-1.6 51.5 0 24.2 7.9 33.6 23.6 37.3v1.6c-15.8 3.7-23.6 13.1-23.6 37.3 0 18.9 1.6 34.2 1.6 51.5 0 17.9-3.7 22.6-17.3 22.6v.5h-6.3V393h20.5c27.8 0 40.5-11 40.5-45.2 0-22.6-3.2-34.2-3.2-54.6 0-11 6.8-22.6 27.3-23.6v-27.3c-20.5-.7-27.3-12.3-27.3-23.3zm-105.6 32c-15.8-6.3-30.5-10-30.5-20.5 0-7.9 6.3-12.6 17.9-12.6s22.1 4.7 33.6 13.1l21-27.8c-13.1-10-31-20.5-55.2-20.5-35.7 0-59.9 20.5-59.9 49.4 0 25.7 22.6 38.9 41.5 46.2 16.3 6.3 32.1 11.6 32.1 22.1 0 7.9-6.3 13.1-20.5 13.1-13.1 0-26.3-5.3-40.5-16.3l-21 30.5c15.8 13.1 39.9 22.1 59.9 22.1 42 0 64.6-22.1 64.6-51s-22.5-41-43-47.8zm-358.9 59.4c-3.7 0-8.4-3.2-8.4-13.1V119.1H65.2c-28.4 0-41 11-41 45.2 0 22.6 3.2 35.2 3.2 54.6 0 11-6.8 22.6-27.3 23.6v27.3c20.5.5 27.3 12.1 27.3 23.1 0 19.4-3.2 31-3.2 53.6 0 34.2 12.6 45.2 40.5 45.2h20.5v-24.2h-6.3c-13.1 0-17.3-5.3-17.3-22.6s1.6-32.1 1.6-51.5c0-24.2-7.9-33.6-23.6-37.3v-1.6c15.8-3.7 23.6-13.1 23.6-37.3 0-18.9-1.6-34.2-1.6-51.5s3.7-22.1 17.3-22.1H93v150.8c0 32.1 11 53.1 43.1 53.1 10 0 17.9-1.6 23.6-3.7l-5.3-34.2c-3.1.8-4.6.8-6.2.8zM379.9 251c-16.3-6.3-31-10-31-20.5 0-7.9 6.3-12.6 17.9-12.6 11.6 0 22.1 4.7 33.6 13.1l21-27.8c-13.1-10-31-20.5-55.2-20.5-35.7 0-59.9 20.5-59.9 49.4 0 25.7 22.6 38.9 41.5 46.2 16.3 6.3 32.1 11.6 32.1 22.1 0 7.9-6.3 13.1-20.5 13.1-13.1 0-26.3-5.3-40.5-16.3l-20.5 30.5c15.8 13.1 39.9 22.1 59.9 22.1 42 0 64.6-22.1 64.6-51 .1-28.9-22.5-41-43-47.8zm-155-68.8c-38.4 0-75.1 32.1-74.1 82.5 0 52 34.2 82.5 79.3 82.5 18.9 0 39.9-6.8 56.2-17.9l-15.8-27.8c-11.6 6.8-22.6 10-34.2 10-21 0-37.3-10-41.5-34.2H290c.5-3.7 1.6-11 1.6-19.4.6-42.6-22.6-75.7-66.7-75.7zm-30 66.2c3.2-21 15.8-31 30.5-31 18.9 0 26.3 13.1 26.3 31h-56.8z"],line:[448,512,[],"f3c0","M272.1 204.2v71.1c0 1.8-1.4 3.2-3.2 3.2h-11.4c-1.1 0-2.1-.6-2.6-1.3l-32.6-44v42.2c0 1.8-1.4 3.2-3.2 3.2h-11.4c-1.8 0-3.2-1.4-3.2-3.2v-71.1c0-1.8 1.4-3.2 3.2-3.2H219c1 0 2.1.5 2.6 1.4l32.6 44v-42.2c0-1.8 1.4-3.2 3.2-3.2h11.4c1.8-.1 3.3 1.4 3.3 3.1zm-82-3.2h-11.4c-1.8 0-3.2 1.4-3.2 3.2v71.1c0 1.8 1.4 3.2 3.2 3.2h11.4c1.8 0 3.2-1.4 3.2-3.2v-71.1c0-1.7-1.4-3.2-3.2-3.2zm-27.5 59.6h-31.1v-56.4c0-1.8-1.4-3.2-3.2-3.2h-11.4c-1.8 0-3.2 1.4-3.2 3.2v71.1c0 .9.3 1.6.9 2.2.6.5 1.3.9 2.2.9h45.7c1.8 0 3.2-1.4 3.2-3.2v-11.4c0-1.7-1.4-3.2-3.1-3.2zM332.1 201h-45.7c-1.7 0-3.2 1.4-3.2 3.2v71.1c0 1.7 1.4 3.2 3.2 3.2h45.7c1.8 0 3.2-1.4 3.2-3.2v-11.4c0-1.8-1.4-3.2-3.2-3.2H301v-12h31.1c1.8 0 3.2-1.4 3.2-3.2V234c0-1.8-1.4-3.2-3.2-3.2H301v-12h31.1c1.8 0 3.2-1.4 3.2-3.2v-11.4c-.1-1.7-1.5-3.2-3.2-3.2zM448 113.7V399c-.1 44.8-36.8 81.1-81.7 81H81c-44.8-.1-81.1-36.9-81-81.7V113c.1-44.8 36.9-81.1 81.7-81H367c44.8.1 81.1 36.8 81 81.7zm-61.6 122.6c0-73-73.2-132.4-163.1-132.4-89.9 0-163.1 59.4-163.1 132.4 0 65.4 58 120.2 136.4 130.6 19.1 4.1 16.9 11.1 12.6 36.8-.7 4.1-3.3 16.1 14.1 8.8 17.4-7.3 93.9-55.3 128.2-94.7 23.6-26 34.9-52.3 34.9-81.5z"],linkedin:[448,512,[],"f08c","M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z"],"linkedin-in":[448,512,[],"f0e1","M100.3 480H7.4V180.9h92.9V480zM53.8 140.1C24.1 140.1 0 115.5 0 85.8 0 56.1 24.1 32 53.8 32c29.7 0 53.8 24.1 53.8 53.8 0 29.7-24.1 54.3-53.8 54.3zM448 480h-92.7V334.4c0-34.7-.7-79.2-48.3-79.2-48.3 0-55.7 37.7-55.7 76.7V480h-92.8V180.9h89.1v40.8h1.3c12.4-23.5 42.7-48.3 87.9-48.3 94 0 111.3 61.9 111.3 142.3V480z"],linode:[448,512,[],"f2b8","M437.4 226.3c-.3-.9-.9-1.4-1.4-2l-70-38.6c-.9-.6-2-.6-3.1 0l-58.9 36c-.9.6-1.4 1.7-1.4 2.6l-.9 31.4-24-16c-.9-.6-2.3-.6-3.1 0L240 260.9l-1.4-35.1c0-.9-.6-2-1.4-2.3l-36-24.3 33.7-17.4c1.1-.6 1.7-1.7 1.7-2.9l-5.7-132.3c0-.9-.9-2-1.7-2.6L138.6.3c-.9-.3-1.7-.3-2.3-.3L12.6 38.6c-1.4.6-2.3 2-2 3.7L38 175.4c.9 3.4 34 27.4 38.6 30.9l-26.9 12.9c-1.4.9-2 2.3-1.7 3.4l20.6 100.3c.6 2.9 23.7 23.1 27.1 26.3l-17.4 10.6c-.9.6-1.7 2-1.4 3.1 1.4 7.1 15.4 77.7 16.9 79.1l65.1 69.1c.6.6 1.4.6 2.3.9.6 0 1.1-.3 1.7-.6l83.7-66.9c.9-.6 1.1-1.4 1.1-2.3l-2-46 28 23.7c1.1.9 2.9.9 4 0l66.9-53.4c.9-.6 1.1-1.4 1.1-2.3l2.3-33.4 20.3 14c1.1.9 2.6.9 3.7 0l54.6-43.7c.6-.3 1.1-1.1 1.1-2 .9-6.5 10.3-70.8 9.7-72.8zm-204.8 4.8l4 92.6-90.6 61.2-14-96.6 100.6-57.2zm-7.7-180l5.4 126-106.6 55.4L104 97.7l120.9-46.6zM44 173.1L18 48l79.7 49.4 19.4 132.9L44 173.1zm30.6 147.8L55.7 230l70 58.3 13.7 93.4-64.8-60.8zm24.3 117.7l-13.7-67.1 61.7 60.9 9.7 67.4-57.7-61.2zm64.5 64.5l-10.6-70.9 85.7-61.4 3.1 70-78.2 62.3zm82-115.1c0-3.4.9-22.9-2-25.1l-24.3-20 22.3-14.9c2.3-1.7 1.1-5.7 1.1-8l29.4 22.6.6 68.3-27.1-22.9zm94.3-25.4l-60.9 48.6-.6-68.6 65.7-46.9-4.2 66.9zm27.7-25.7l-19.1-13.4 2-34c.3-.9-.3-2-1.1-2.6L308 259.7l.6-30 64.6 40.6-5.8 66.6zm54.6-39.8l-48.3 38.3 5.7-65.1 51.1-36.6-8.5 63.4z"],linux:[448,512,[],"f17c","M196.1 123.6c-.2-1.4 1.9-2.3 3.2-2.9 1.7-.7 3.9-1 5.5-.1.4.2.8.7.6 1.1-.4 1.2-2.4 1-3.5 1.6-1 .5-1.8 1.7-3 1.7-1 .1-2.7-.4-2.8-1.4zm24.7-.3c1 .5 1.8 1.7 3 1.7 1.1 0 2.8-.4 2.9-1.5.2-1.4-1.9-2.3-3.2-2.9-1.7-.7-3.9-1-5.5-.1-.4.2-.8.7-.6 1.1.3 1.3 2.3 1.1 3.4 1.7zm214.7 310.2c-.5 8.2-6.5 13.8-13.9 18.3-14.9 9-37.3 15.8-50.9 32.2l-2.6-2.2 2.6 2.2c-14.2 16.9-31.7 26.6-48.3 27.9-16.5 1.3-32-6.3-40.3-23v-.1c-1.1-2.1-1.9-4.4-2.5-6.7-21.5 1.2-40.2-5.3-55.1-4.1-22 1.2-35.8 6.5-48.3 6.6-4.8 10.6-14.3 17.6-25.9 20.2-16 3.7-36.1 0-55.9-10.4l1.6-3-1.6 3c-18.5-9.8-42-8.9-59.3-12.5-8.7-1.8-16.3-5-20.1-12.3-3.7-7.3-3-17.3 2.2-31.7 1.7-5.1.4-12.7-.8-20.8-.6-3.9-1.2-7.9-1.2-11.8 0-4.3.7-8.5 2.8-12.4 4.5-8.5 11.8-12.1 18.5-14.5 6.7-2.4 12.8-4 17-8.3 5.2-5.5 10.1-14.4 16.6-20.2-2.6-17.2.2-35.4 6.2-53.3 12.6-37.9 39.2-74.2 58.1-96.7 16.1-22.9 20.8-41.3 22.5-64.7C158 103.4 132.4-.2 234.8 0c80.9.1 76.3 85.4 75.8 131.3-.3 30.1 16.3 50.5 33.4 72 15.2 18 35.1 44.3 46.5 74.4 9.3 24.6 12.9 51.8 3.7 79.1 1.4.5 2.8 1.2 4.1 2 1.4.8 2.7 1.8 4 2.9 6.6 5.6 8.7 14.3 10.5 22.4 1.9 8.1 3.6 15.7 7.2 19.7 11.1 12.4 15.9 21.5 15.5 29.7zM220.8 109.1c3.6.9 8.9 2.4 13 4.4-2.1-12.2 4.5-23.5 11.8-23 8.9.3 13.9 15.5 9.1 27.3-.8 1.9-2.8 3.4-3.9 4.6 6.7 2.3 11 4.1 12.6 4.9 7.9-9.5 10.8-26.2 4.3-40.4-9.8-21.4-34.2-21.8-44 .4-3.2 7.2-3.9 14.9-2.9 21.8zm-46.2 18.8c7.8-5.7 6.9-4.7 5.9-5.5-8-6.9-6.6-27.4 1.8-28.1 6.3-.5 10.8 10.7 9.6 19.6 3.1-2.1 6.7-3.6 10.2-4.6 1.7-19.3-9-33.5-19.1-33.5-18.9 0-24 37.5-8.4 52.1zm-9.4 20.9c1.5 4.9 6.1 10.5 14.7 15.3 7.8 4.6 12 11.5 20 15 2.6 1.1 5.7 1.9 9.6 2.1 18.4 1.1 27.1-11.3 38.2-14.9 11.7-3.7 20.1-11 22.7-18.1 3.2-8.5-2.1-14.7-10.5-18.2-11.3-4.9-16.3-5.2-22.6-9.3-10.3-6.6-18.8-8.9-25.9-8.9-14.4 0-23.2 9.8-27.9 14.2-.5.5-7.9 5.9-14.1 10.5-4.2 3.3-5.6 7.4-4.2 12.3zm-33.5 252.8L112.1 366c-6.8-9.2-13.8-14.8-21.9-16-7.7-1.2-12.6 1.4-17.7 6.9-4.8 5.1-8.8 12.3-14.3 18-7.8 6.5-9.3 6.2-19.6 9.9-6.3 2.2-11.3 4.6-14.8 11.3-2.7 5-2.1 12.2-.9 20 1.2 7.9 3 16.3.6 23.9v.2c-5 13.7-5 21.7-2.6 26.4 7.9 15.4 46.6 6.1 76.5 21.9 31.4 16.4 72.6 17.1 75.3-18 2.1-20.5-31.5-49-41-68.9zm153.9 35.8c3.2-11 6.3-21.3 6.8-29 .8-15.2 1.6-28.7 4.4-39.9 3.1-12.6 9.3-23.1 21.4-27.3 2.3-21.1 18.7-21.1 38.3-12.5 18.9 8.5 26 16 22.8 26.1 1 0 2-.1 4.2 0 5.2-16.9-14.3-28-30.7-34.8 2.9-12 2.4-24.1-.4-35.7-6-25.3-22.6-47.8-35.2-59-2.3-.1-2.1 1.9 2.6 6.5 11.6 10.7 37.1 49.2 23.3 84.9-3.9-1-7.6-1.5-10.9-1.4-5.3-29.1-17.5-53.2-23.6-64.6-11.5-21.4-29.5-65.3-37.2-95.7-4.5 6.4-12.4 11.9-22.3 15-4.7 1.5-9.7 5.5-15.9 9-13.9 8-30 8.8-42.4-1.2-4.5-3.6-8-7.6-12.6-10.3-1.6-.9-5.1-3.3-6.2-4.1-2 37.8-27.3 85.3-39.3 112.7-8.3 19.7-13.2 40.8-13.8 61.5-21.8-29.1-5.9-66.3 2.6-82.4 9.5-17.6 11-22.5 8.7-20.8-8.6 14-22 36.3-27.2 59.2-2.7 11.9-3.2 24 .3 35.2 3.5 11.2 11.1 21.5 24.6 29.9 0 0 24.8 14.3 38.3 32.5 7.4 10 9.7 18.7 7.4 24.9-2.5 6.7-9.6 8.9-16.7 8.9 4.8 6 10.3 13 14.4 19.6 37.6 25.7 82.2 15.7 114.3-7.2zM415 408.5c-10-11.3-7.2-33.1-17.1-41.6-6.9-6-13.6-5.4-22.6-5.1-7.7 8.8-25.8 19.6-38.4 16.3-11.5-2.9-18-16.3-18.8-29.5-.3.2-.7.3-1 .5-7.1 3.9-11.1 10.8-13.7 21.1-2.5 10.2-3.4 23.5-4.2 38.7-.7 11.8-6.2 26.4-9.9 40.6-3.5 13.2-5.8 25.2-1.1 36.3 7.2 14.5 19.5 20.4 33.7 19.3 14.2-1.1 30.4-9.8 43.6-25.5 22-26.6 62.3-29.7 63.2-46.5.3-5.1-3.1-13-13.7-24.6zM173.3 148.7c2 1.9 4.7 4.5 8 7.1 6.6 5.2 15.8 10.6 27.3 10.6 11.6 0 22.5-5.9 31.8-10.8 4.9-2.6 10.9-7 14.8-10.4 3.9-3.4 5.9-6.3 3.1-6.6-2.8-.3-2.6 2.6-6 5.1-4.4 3.2-9.7 7.4-13.9 9.8-7.4 4.2-19.5 10.2-29.9 10.2-10.4 0-18.7-4.8-24.9-9.7-3.1-2.5-5.7-5-7.7-6.9-1.5-1.4-1.9-4.6-4.3-4.9-1.4-.1-1.8 3.7 1.7 6.5z"],lyft:[512,512,[],"f3c3","M0 81.1h77.8v208.7c0 33.1 15 52.8 27.2 61-12.7 11.1-51.2 20.9-80.2-2.8C7.8 334 0 310.7 0 289V81.1zm485.9 173.5v-22h23.8v-76.8h-26.1c-10.1-46.3-51.2-80.7-100.3-80.7-56.6 0-102.7 46-102.7 102.7V357c16 2.3 35.4-.3 51.7-14 17.1-14 24.8-37.2 24.8-59v-6.7h38.8v-76.8h-38.8v-23.3c0-34.6 52.2-34.6 52.2 0v77.1c0 56.6 46 102.7 102.7 102.7v-76.5c-14.5 0-26.1-11.7-26.1-25.9zm-294.3-99v113c0 15.4-23.8 15.4-23.8 0v-113H91v132.7c0 23.8 8 54 45 63.9 37 9.8 58.2-10.6 58.2-10.6-2.1 13.4-14.5 23.3-34.9 25.3-15.5 1.6-35.2-3.6-45-7.8v70.3c25.1 7.5 51.5 9.8 77.6 4.7 47.1-9.1 76.8-48.4 76.8-100.8V155.1h-77.1v.5z"],magento:[448,512,[],"f3c4","M445.7 127.9V384l-63.4 36.5V164.7L223.8 73.1 65.2 164.7l.4 255.9L2.3 384V128.1L224.2 0l221.5 127.9zM255.6 420.5L224 438.9l-31.8-18.2v-256l-63.3 36.6.1 255.9 94.9 54.9 95.1-54.9v-256l-63.4-36.6v255.9z"],maxcdn:[512,512,[],"f136","M461.1 442.7h-97.4L415.6 200c2.3-10.2.9-19.5-4.4-25.7-5-6.1-13.7-9.6-24.2-9.6h-49.3l-59.5 278h-97.4l59.5-278h-83.4l-59.5 278H0l59.5-278-44.6-95.4H387c39.4 0 75.3 16.3 98.3 44.9 23.3 28.6 31.8 67.4 23.6 105.9l-47.8 222.6z"],medapps:[320,512,[],"f3c6","M118.3 238.4c3.5-12.5 6.9-33.6 13.2-33.6 8.3 1.8 9.6 23.4 18.6 36.6 4.6-23.5 5.3-85.1 14.1-86.7 9-.7 19.7 66.5 22 77.5 9.9 4.1 48.9 6.6 48.9 6.6 1.9 7.3-24 7.6-40 7.8-4.6 14.8-5.4 27.7-11.4 28-4.7.2-8.2-28.8-17.5-49.6l-9.4 65.5c-4.4 13-15.5-22.5-21.9-39.3-3.3-.1-62.4-1.6-47.6-7.8l31-5zM228 448c21.2 0 21.2-32 0-32H92c-21.2 0-21.2 32 0 32h136zm-24 64c21.2 0 21.2-32 0-32h-88c-21.2 0-21.2 32 0 32h88zm34.2-141.5c3.2-18.9 5.2-36.4 11.9-48.8 7.9-14.7 16.1-28.1 24-41 24.6-40.4 45.9-75.2 45.9-125.5C320 69.6 248.2 0 160 0S0 69.6 0 155.2c0 50.2 21.3 85.1 45.9 125.5 7.9 12.9 16 26.3 24 41 6.7 12.5 8.7 29.8 11.9 48.9 3.5 21 36.1 15.7 32.6-5.1-3.6-21.7-5.6-40.7-15.3-58.6C66.5 246.5 33 211.3 33 155.2 33 87.3 90 32 160 32s127 55.3 127 123.2c0 56.1-33.5 91.3-66.1 151.6-9.7 18-11.7 37.4-15.3 58.6-3.4 20.6 29 26.4 32.6 5.1z"],medium:[448,512,[],"f23a","M0 32v448h448V32H0zm372.2 106.1l-24 23c-2.1 1.6-3.1 4.2-2.7 6.7v169.3c-.4 2.6.6 5.2 2.7 6.7l23.5 23v5.1h-118V367l24.3-23.6c2.4-2.4 2.4-3.1 2.4-6.7V199.8l-67.6 171.6h-9.1L125 199.8v115c-.7 4.8 1 9.7 4.4 13.2l31.6 38.3v5.1H71.2v-5.1l31.6-38.3c3.4-3.5 4.9-8.4 4.1-13.2v-133c.4-3.7-1-7.3-3.8-9.8L75 138.1V133h87.3l67.4 148L289 133.1h83.2v5z"],"medium-m":[512,512,[],"f3c7","M71.5 142.3c.6-5.9-1.7-11.8-6.1-15.8L20.3 72.1V64h140.2l108.4 237.7L364.2 64h133.7v8.1l-38.6 37c-3.3 2.5-5 6.7-4.3 10.8v272c-.7 4.1 1 8.3 4.3 10.8l37.7 37v8.1H307.3v-8.1l39.1-37.9c3.8-3.8 3.8-5 3.8-10.8V171.2L241.5 447.1h-14.7L100.4 171.2v184.9c-1.1 7.8 1.5 15.6 7 21.2l50.8 61.6v8.1h-144v-8L65 377.3c5.4-5.6 7.9-13.5 6.5-21.2V142.3z"],medrt:[544,512,[],"f3c8","M113.7 256c0 121.8 83.9 222.8 193.5 241.1-18.7 4.5-38.2 6.9-58.2 6.9C111.4 504 0 393 0 256S111.4 8 248.9 8c20.1 0 39.6 2.4 58.2 6.9C197.5 33.2 113.7 134.2 113.7 256m297.4 100.3c-77.7 55.4-179.6 47.5-240.4-14.6 5.5 14.1 12.7 27.7 21.7 40.5 61.6 88.2 182.4 109.3 269.7 47 87.3-62.3 108.1-184.3 46.5-272.6-9-12.9-19.3-24.3-30.5-34.2 37.4 78.8 10.7 178.5-67 233.9m-218.8-244c-1.4 1-2.7 2.1-4 3.1 64.3-17.8 135.9 4 178.9 60.5 35.7 47 42.9 106.6 24.4 158 56.7-56.2 67.6-142.1 22.3-201.8-50-65.5-149.1-74.4-221.6-19.8M296 224c-4.4 0-8-3.6-8-8v-40c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v40c0 4.4-3.6 8-8 8h-40c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h40c4.4 0 8 3.6 8 8v40c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8v-40c0-4.4 3.6-8 8-8h40c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8h-40z"],meetup:[512,512,[],"f2e0","M99 414.3c1.1 5.7-2.3 11.1-8 12.3-5.4 1.1-10.9-2.3-12-8-1.1-5.4 2.3-11.1 7.7-12.3 5.4-1.2 11.1 2.3 12.3 8zm143.1 71.4c-6.3 4.6-8 13.4-3.7 20 4.6 6.6 13.4 8.3 20 3.7 6.3-4.6 8-13.4 3.4-20-4.2-6.5-13.1-8.3-19.7-3.7zm-86-462.3c6.3-1.4 10.3-7.7 8.9-14-1.1-6.6-7.4-10.6-13.7-9.1-6.3 1.4-10.3 7.7-9.1 14 1.4 6.6 7.6 10.6 13.9 9.1zM34.4 226.3c-10-6.9-23.7-4.3-30.6 6-6.9 10-4.3 24 5.7 30.9 10 7.1 23.7 4.6 30.6-5.7 6.9-10.4 4.3-24.1-5.7-31.2zm272-170.9c10.6-6.3 13.7-20 7.7-30.3-6.3-10.6-19.7-14-30-7.7s-13.7 20-7.4 30.6c6 10.3 19.4 13.7 29.7 7.4zm-191.1 58c7.7-5.4 9.4-16 4.3-23.7s-15.7-9.4-23.1-4.3c-7.7 5.4-9.4 16-4.3 23.7 5.1 7.8 15.6 9.5 23.1 4.3zm372.3 156c-7.4 1.7-12.3 9.1-10.6 16.9 1.4 7.4 8.9 12.3 16.3 10.6 7.4-1.4 12.3-8.9 10.6-16.6-1.5-7.4-8.9-12.3-16.3-10.9zm39.7-56.8c-1.1-5.7-6.6-9.1-12-8-5.7 1.1-9.1 6.9-8 12.6 1.1 5.4 6.6 9.1 12.3 8 5.4-1.5 9.1-6.9 7.7-12.6zM447 138.9c-8.6 6-10.6 17.7-4.9 26.3 5.7 8.6 17.4 10.6 26 4.9 8.3-6 10.3-17.7 4.6-26.3-5.7-8.7-17.4-10.9-25.7-4.9zm-6.3 139.4c26.3 43.1 15.1 100-26.3 129.1-17.4 12.3-37.1 17.7-56.9 17.1-12 47.1-69.4 64.6-105.1 32.6-1.1.9-2.6 1.7-3.7 2.9-39.1 27.1-92.3 17.4-119.4-22.3-9.7-14.3-14.6-30.6-15.1-46.9-65.4-10.9-90-94-41.1-139.7-28.3-46.9.6-107.4 53.4-114.9C151.6 70 234.1 38.6 290.1 82c67.4-22.3 136.3 29.4 130.9 101.1 41.1 12.6 52.8 66.9 19.7 95.2zm-70 74.3c-3.1-20.6-40.9-4.6-43.1-27.1-3.1-32 43.7-101.1 40-128-3.4-24-19.4-29.1-33.4-29.4-13.4-.3-16.9 2-21.4 4.6-2.9 1.7-6.6 4.9-11.7-.3-6.3-6-11.1-11.7-19.4-12.9-12.3-2-17.7 2-26.6 9.7-3.4 2.9-12 12.9-20 9.1-3.4-1.7-15.4-7.7-24-11.4-16.3-7.1-40 4.6-48.6 20-12.9 22.9-38 113.1-41.7 125.1-8.6 26.6 10.9 48.6 36.9 47.1 11.1-.6 18.3-4.6 25.4-17.4 4-7.4 41.7-107.7 44.6-112.6 2-3.4 8.9-8 14.6-5.1 5.7 3.1 6.9 9.4 6 15.1-1.1 9.7-28 70.9-28.9 77.7-3.4 22.9 26.9 26.6 38.6 4 3.7-7.1 45.7-92.6 49.4-98.3 4.3-6.3 7.4-8.3 11.7-8 3.1 0 8.3.9 7.1 10.9-1.4 9.4-35.1 72.3-38.9 87.7-4.6 20.6 6.6 41.4 24.9 50.6 11.4 5.7 62.5 15.7 58.5-11.1zm5.7 92.3c-10.3 7.4-12.9 22-5.7 32.6 7.1 10.6 21.4 13.1 32 6 10.6-7.4 13.1-22 6-32.6-7.4-10.6-21.7-13.5-32.3-6z"],microsoft:[448,512,[],"f3ca","M0 32h214.6v214.6H0V32zm233.4 0H448v214.6H233.4V32zM0 265.4h214.6V480H0V265.4zm233.4 0H448V480H233.4V265.4z"],mix:[448,512,[],"f3cb","M0 64v348.9c0 56.2 88 58.1 88 0V174.3c7.9-52.9 88-50.4 88 6.5v175.3c0 57.9 96 58 96 0V240c5.3-54.7 88-52.5 88 4.3v23.8c0 59.9 88 56.6 88 0V64H0z"],mixcloud:[640,512,[],"f289","M424.43 219.729C416.124 134.727 344.135 68 256.919 68c-72.266 0-136.224 46.516-159.205 114.074-54.545 8.029-96.63 54.822-96.63 111.582 0 62.298 50.668 112.966 113.243 112.966h289.614c52.329 0 94.969-42.362 94.969-94.693 0-45.131-32.118-83.063-74.48-92.2zm-20.489 144.53H114.327c-39.04 0-70.881-31.564-70.881-70.604s31.841-70.604 70.881-70.604c18.827 0 36.548 7.475 49.838 20.766 19.963 19.963 50.133-10.227 30.18-30.18-14.675-14.398-32.672-24.365-52.053-29.349 19.935-44.3 64.79-73.926 114.628-73.926 69.496 0 125.979 56.483 125.979 125.702 0 13.568-2.215 26.857-6.369 39.594-8.943 27.517 32.133 38.939 40.147 13.29 2.769-8.306 4.984-16.889 6.369-25.472 19.381 7.476 33.502 26.303 33.502 48.453 0 28.795-23.535 52.33-52.607 52.33zm235.069-52.33c0 44.024-12.737 86.386-37.102 122.657-4.153 6.092-10.798 9.414-17.72 9.414-16.317 0-27.127-18.826-17.443-32.949 19.381-29.349 29.903-63.682 29.903-99.122s-10.521-69.773-29.903-98.845c-15.655-22.831 19.361-47.24 35.163-23.534 24.366 35.993 37.102 78.356 37.102 122.379zm-70.88 0c0 31.565-9.137 62.021-26.857 88.325-4.153 6.091-10.798 9.136-17.72 9.136-17.201 0-27.022-18.979-17.443-32.948 13.013-19.104 19.658-41.255 19.658-64.513 0-22.981-6.645-45.408-19.658-64.512-15.761-22.986 19.008-47.095 35.163-23.535 17.719 26.026 26.857 56.483 26.857 88.047z"],mizuni:[496,512,[],"f3cc","M248 8C111 8 0 119.1 0 256c0 137 111 248 248 248s248-111 248-248C496 119.1 385 8 248 8zm-80 351.9c-31.4 10.6-58.8 27.3-80 48.2V136c0-22.1 17.9-40 40-40s40 17.9 40 40v223.9zm120-9.9c-12.9-2-26.2-3.1-39.8-3.1-13.8 0-27.2 1.1-40.2 3.1V136c0-22.1 17.9-40 40-40s40 17.9 40 40v214zm120 57.7c-21.2-20.8-48.6-37.4-80-48V136c0-22.1 17.9-40 40-40s40 17.9 40 40v271.7z"],modx:[448,512,[],"f285","M356 241.8l36.7 23.7V480l-133-83.8L356 241.8zM440 75H226.3l-23 37.8 153.5 96.5L440 75zm-89 142.8L55.2 32v214.5l46 29L351 217.8zM97 294.2L8 437h213.7l125-200.5L97 294.2z"],monero:[496,512,[],"f3d0","M352 384h108.4C417 455.9 338.1 504 248 504S79 455.9 35.6 384H144V256.2L248 361l104-105v128zM88 336V128l159.4 159.4L408 128v208h74.8c8.5-25.1 13.2-52 13.2-80C496 119 385 8 248 8S0 119 0 256c0 28 4.6 54.9 13.2 80H88z"],napster:[496,512,[],"f3d2","M298.3 373.6c-14.2 13.6-31.3 24.1-50.4 30.5-19-6.4-36.2-16.9-50.3-30.5h100.7zm44-199.6c20-16.9 43.6-29.2 69.6-36.2V299c0 219.4-328 217.6-328 .3V137.7c25.9 6.9 49.6 19.6 69.5 36.4 56.8-40 132.5-39.9 188.9-.1zm-208.8-58.5c64.4-60 164.3-60.1 228.9-.2-7.1 3.5-13.9 7.3-20.6 11.5-58.7-30.5-129.2-30.4-187.9.1-6.3-4-13.9-8.2-20.4-11.4zM43.8 93.2v69.3c-58.4 36.5-58.4 121.1.1 158.3 26.4 245.1 381.7 240.3 407.6 1.5l.3-1.7c58.7-36.3 58.9-121.7.2-158.2V93.2c-17.3.5-34 3-50.1 7.4-82-91.5-225.5-91.5-307.5.1-16.3-4.4-33.1-7-50.6-7.5zM259.2 352s36-.3 61.3-1.5c10.2-.5 21.1-4 25.5-6.5 26.3-15.1 25.4-39.2 26.2-47.4-79.5-.6-99.9-3.9-113 55.4zm-135.5-55.3c.8 8.2-.1 32.3 26.2 47.4 4.4 2.5 15.2 6 25.5 6.5 25.3 1.1 61.3 1.5 61.3 1.5-13.2-59.4-33.7-56.1-113-55.4zm169.1 123.4c-3.2-5.3-6.9-7.3-6.9-7.3-24.8 7.3-52.2 6.9-75.9 0 0 0-2.9 1.5-6.4 6.6-2.8 4.1-3.7 9.6-3.7 9.6 29.1 17.6 67.1 17.6 96.2 0-.1-.1-.3-4-3.3-8.9z"],"nintendo-switch":[448,512,[],"f418","M95.9 33.5c-44.6 8-80.5 41-91.8 84.4C0 133.6-.3 142.8.2 264.4.4 376 .5 378.6 2.4 387.3c10.3 46.5 43.3 79.6 90.3 90.5 6.1 1.4 13.9 1.7 64.1 1.9 51.9.4 57.3.3 58.7-1.1 1.4-1.4 1.5-19.3 1.5-222.2 0-150.5-.3-221.3-.9-222.6-.9-1.7-2.5-1.8-56.9-1.7-44.2.1-57.5.4-63.3 1.4zm83.9 222.6V444l-37.8-.5c-34.8-.4-38.5-.6-45.5-2.3-29.9-7.7-52-30.7-58.3-60.7-2-9.4-2-240.1-.1-249.3 5.6-26.1 23.7-47.7 48-57.4 12.2-4.9 17.9-5.5 57.6-5.6l35.9-.1v188zm-75.9-131.2c-5.8 1.1-14.7 5.6-19.5 9.7-9.7 8.4-14.6 20.4-13.8 34.5.4 7.3.8 9.3 3.8 15.2 4.4 9 10.9 15.6 19.9 20 6.2 3.1 7.8 3.4 15.9 3.7 7.3.3 9.9 0 14.8-1.7 20.1-6.8 32.3-26.3 28.8-46.4-3.9-23.7-26.6-39.7-49.9-35zm158.2-92.3c-.4.3-.6 100.8-.6 223.5 0 202.3.1 222.8 1.5 223.4 2.5.9 74.5.6 83.4-.4 37.7-4.3 71-27.2 89-61.2 2.3-4.4 5.4-11.7 7-16.2 5.8-17.4 5.7-12.8 5.7-146.1 0-106.4-.2-122.3-1.5-129-9.2-48.3-46.1-84.8-94.5-93.1-6.5-1.1-16.5-1.4-48.8-1.4-22.4-.1-40.9.2-41.2.5zm99.1 202.1c14.5 3.8 26.3 14.8 31.2 28.9 3.1 8.7 3 21.5-.1 29.5-5.7 14.7-16.8 25-31.1 28.8-23.2 6-47.9-8-54.6-31-2-7-1.9-18.9.4-26.2 6.9-22.7 31-36.1 54.2-30z"],node:[640,512,[],"f419","M316.3 452c-2.1 0-4.2-.6-6.1-1.6L291 439c-2.9-1.6-1.5-2.2-.5-2.5 3.8-1.3 4.6-1.6 8.7-4 .4-.2 1-.1 1.4.1l14.8 8.8c.5.3 1.3.3 1.8 0L375 408c.5-.3.9-.9.9-1.6v-66.7c0-.7-.3-1.3-.9-1.6l-57.8-33.3c-.5-.3-1.2-.3-1.8 0l-57.8 33.3c-.6.3-.9 1-.9 1.6v66.7c0 .6.4 1.2.9 1.5l15.8 9.1c8.6 4.3 13.9-.8 13.9-5.8v-65.9c0-.9.7-1.7 1.7-1.7h7.3c.9 0 1.7.7 1.7 1.7v65.9c0 11.5-6.2 18-17.1 18-3.3 0-6 0-13.3-3.6l-15.2-8.7c-3.7-2.2-6.1-6.2-6.1-10.5v-66.7c0-4.3 2.3-8.4 6.1-10.5l57.8-33.4c3.7-2.1 8.5-2.1 12.1 0l57.8 33.4c3.7 2.2 6.1 6.2 6.1 10.5v66.7c0 4.3-2.3 8.4-6.1 10.5l-57.8 33.4c-1.7 1.1-3.8 1.7-6 1.7zm46.7-65.8c0-12.5-8.4-15.8-26.2-18.2-18-2.4-19.8-3.6-19.8-7.8 0-3.5 1.5-8.1 14.8-8.1 11.9 0 16.3 2.6 18.1 10.6.2.8.8 1.3 1.6 1.3h7.5c.5 0 .9-.2 1.2-.5.3-.4.5-.8.4-1.3-1.2-13.8-10.3-20.2-28.8-20.2-16.5 0-26.3 7-26.3 18.6 0 12.7 9.8 16.1 25.6 17.7 18.9 1.9 20.4 4.6 20.4 8.3 0 6.5-5.2 9.2-17.4 9.2-15.3 0-18.7-3.8-19.8-11.4-.1-.8-.8-1.4-1.7-1.4h-7.5c-.9 0-1.7.7-1.7 1.7 0 9.7 5.3 21.3 30.6 21.3 18.5 0 29-7.2 29-19.8zm54.5-50.1c0 6.1-5 11.1-11.1 11.1s-11.1-5-11.1-11.1c0-6.3 5.2-11.1 11.1-11.1 6-.1 11.1 4.8 11.1 11.1zm-1.8 0c0-5.2-4.2-9.3-9.4-9.3-5.1 0-9.3 4.1-9.3 9.3 0 5.2 4.2 9.4 9.3 9.4 5.2-.1 9.4-4.3 9.4-9.4zm-4.5 6.2h-2.6c-.1-.6-.5-3.8-.5-3.9-.2-.7-.4-1.1-1.3-1.1h-2.2v5h-2.4v-12.5h4.3c1.5 0 4.4 0 4.4 3.3 0 2.3-1.5 2.8-2.4 3.1 1.7.1 1.8 1.2 2.1 2.8.1 1 .3 2.7.6 3.3zm-2.8-8.8c0-1.7-1.2-1.7-1.8-1.7h-2v3.5h1.9c1.6 0 1.9-1.1 1.9-1.8zM137.3 191c0-2.7-1.4-5.1-3.7-6.4l-61.3-35.3c-1-.6-2.2-.9-3.4-1h-.6c-1.2 0-2.3.4-3.4 1L3.7 184.6C1.4 185.9 0 188.4 0 191l.1 95c0 1.3.7 2.5 1.8 3.2 1.1.7 2.5.7 3.7 0L42 268.3c2.3-1.4 3.7-3.8 3.7-6.4v-44.4c0-2.6 1.4-5.1 3.7-6.4l15.5-8.9c1.2-.7 2.4-1 3.7-1 1.3 0 2.6.3 3.7 1l15.5 8.9c2.3 1.3 3.7 3.8 3.7 6.4v44.4c0 2.6 1.4 5.1 3.7 6.4l36.4 20.9c1.1.7 2.6.7 3.7 0 1.1-.6 1.8-1.9 1.8-3.2l.2-95zM472.5 87.3v176.4c0 2.6-1.4 5.1-3.7 6.4l-61.3 35.4c-2.3 1.3-5.1 1.3-7.4 0l-61.3-35.4c-2.3-1.3-3.7-3.8-3.7-6.4v-70.8c0-2.6 1.4-5.1 3.7-6.4l61.3-35.4c2.3-1.3 5.1-1.3 7.4 0l15.3 8.8c1.7 1 3.9-.3 3.9-2.2v-94c0-2.8 3-4.6 5.5-3.2l36.5 20.4c2.3 1.2 3.8 3.7 3.8 6.4zm-46 128.9c0-.7-.4-1.3-.9-1.6l-21-12.2c-.6-.3-1.3-.3-1.9 0l-21 12.2c-.6.3-.9.9-.9 1.6v24.3c0 .7.4 1.3.9 1.6l21 12.1c.6.3 1.3.3 1.8 0l21-12.1c.6-.3.9-.9.9-1.6v-24.3zm209.8-.7c2.3-1.3 3.7-3.8 3.7-6.4V192c0-2.6-1.4-5.1-3.7-6.4l-60.9-35.4c-2.3-1.3-5.1-1.3-7.4 0l-61.3 35.4c-2.3 1.3-3.7 3.8-3.7 6.4v70.8c0 2.7 1.4 5.1 3.7 6.4l60.9 34.7c2.2 1.3 5 1.3 7.3 0l36.8-20.5c2.5-1.4 2.5-5 0-6.4L550 241.6c-1.2-.7-1.9-1.9-1.9-3.2v-22.2c0-1.3.7-2.5 1.9-3.2l19.2-11.1c1.1-.7 2.6-.7 3.7 0l19.2 11.1c1.1.7 1.9 1.9 1.9 3.2v17.4c0 2.8 3.1 4.6 5.6 3.2l36.7-21.3zM559 219c-.4.3-.7.7-.7 1.2v13.6c0 .5.3 1 .7 1.2l11.8 6.8c.4.3 1 .3 1.4 0L584 235c.4-.3.7-.7.7-1.2v-13.6c0-.5-.3-1-.7-1.2l-11.8-6.8c-.4-.3-1-.3-1.4 0L559 219zm-254.2 43.5v-70.4c0-2.6-1.6-5.1-3.9-6.4l-61.1-35.2c-2.1-1.2-5-1.4-7.4 0l-61.1 35.2c-2.3 1.3-3.9 3.7-3.9 6.4v70.4c0 2.8 1.9 5.2 4 6.4l61.2 35.2c2.4 1.4 5.2 1.3 7.4 0l61-35.2c1.8-1 3.1-2.7 3.6-4.7.1-.5.2-1.1.2-1.7zm-74.3-124.9l-.8.5h1.1l-.3-.5zm76.2 130.2l-.4-.7v.9l.4-.2z"],"node-js":[448,512,[],"f3d3","M224 508c-6.7 0-13.5-1.8-19.4-5.2l-61.7-36.5c-9.2-5.2-4.7-7-1.7-8 12.3-4.3 14.8-5.2 27.9-12.7 1.4-.8 3.2-.5 4.6.4l47.4 28.1c1.7 1 4.1 1 5.7 0l184.7-106.6c1.7-1 2.8-3 2.8-5V149.3c0-2.1-1.1-4-2.9-5.1L226.8 37.7c-1.7-1-4-1-5.7 0L36.6 144.3c-1.8 1-2.9 3-2.9 5.1v213.1c0 2 1.1 4 2.9 4.9l50.6 29.2c27.5 13.7 44.3-2.4 44.3-18.7V167.5c0-3 2.4-5.3 5.4-5.3h23.4c2.9 0 5.4 2.3 5.4 5.3V378c0 36.6-20 57.6-54.7 57.6-10.7 0-19.1 0-42.5-11.6l-48.4-27.9C8.1 389.2.7 376.3.7 362.4V149.3c0-13.8 7.4-26.8 19.4-33.7L204.6 9c11.7-6.6 27.2-6.6 38.8 0l184.7 106.7c12 6.9 19.4 19.8 19.4 33.7v213.1c0 13.8-7.4 26.7-19.4 33.7L243.4 502.8c-5.9 3.4-12.6 5.2-19.4 5.2zm149.1-210.1c0-39.9-27-50.5-83.7-58-57.4-7.6-63.2-11.5-63.2-24.9 0-11.1 4.9-25.9 47.4-25.9 37.9 0 51.9 8.2 57.7 33.8.5 2.4 2.7 4.2 5.2 4.2h24c1.5 0 2.9-.6 3.9-1.7s1.5-2.6 1.4-4.1c-3.7-44.1-33-64.6-92.2-64.6-52.7 0-84.1 22.2-84.1 59.5 0 40.4 31.3 51.6 81.8 56.6 60.5 5.9 65.2 14.8 65.2 26.7 0 20.6-16.6 29.4-55.5 29.4-48.9 0-59.6-12.3-63.2-36.6-.4-2.6-2.6-4.5-5.3-4.5h-23.9c-3 0-5.3 2.4-5.3 5.3 0 31.1 16.9 68.2 97.8 68.2 58.4-.1 92-23.2 92-63.4z"],npm:[576,512,[],"f3d4","M288 288h-32v-64h32v64zm288-128v192H288v32H160v-32H0V160h576zm-416 32H32v128h64v-96h32v96h32V192zm160 0H192v160h64v-32h64V192zm224 0H352v128h64v-96h32v96h32v-96h32v96h32V192z"],ns8:[640,512,[],"f3d5","M187.1 159.9l-34.2 113.7-54.5-113.7H49L0 320h44.9L76 213.5 126.6 320h56.9L232 159.9h-44.9zm452.5-.9c-2.9-18-23.9-28.1-42.1-31.3-44.6-7.8-101.9 16.3-88.5 58.8v.1c-43.8 8.7-74.3 26.8-94.2 48.2-3-9.8-13.6-16.6-34-16.6h-87.6c-9.3 0-12.9-2.3-11.5-7.4 1.6-5.5 1.9-6.8 3.7-12.2 2.1-6.4 7.8-7.1 13.3-7.1h133.5l9.7-31.5c-139.7 0-144.5-.5-160.1 1.2-12.3 1.3-23.5 4.8-30.6 15-6.8 9.9-14.4 35.6-17.6 47.1-5.4 19.4-.6 28.6 32.8 28.6h87.3c7.8 0 8.8 2.7 7.7 6.6-1.1 4.4-2.8 10-4.5 14.6-1.6 4.2-4.7 7.4-13.8 7.4H216.3L204.7 320c139.9 0 145.3-.6 160.9-2.3 6.6-.7 13-2.1 18.5-4.9.2 3.7.5 7.3 1.2 10.8 5.4 30.5 27.4 52.3 56.8 59.5 48.6 11.9 108.7-16.8 135.1-68 18.7-36.2 14.1-76.2-3.4-105.5h.1c29.6-5.9 70.3-22 65.7-50.6zM530.7 263.7c-5.9 29.5-36.6 47.8-61.6 43.9-30.9-4.8-38.5-39.5-14.1-64.8 16.2-16.8 45.2-24 68.5-26.9 6.7 14.1 10.3 32 7.2 47.8zm21.8-83.1c-4.2-6-9.8-18.5-2.5-26.3 6.7-7.2 20.9-10.1 31.8-7.7 15.3 3.4 19.7 15.9 4.9 24.4-10.7 6.1-23.6 8.1-34.2 9.6z"],nutritionix:[400,512,[],"f3d6","M88 8.1S221.4-.1 209 112.5c0 0 19.1-74.9 103-40.6 0 0-17.7 74-88 56 0 0 14.6-54.6 66.1-56.6 0 0-39.9-10.3-82.1 48.8 0 0-19.8-94.5-93.6-99.7 0 0 75.2 19.4 77.6 107.5 0 .1-106.4 7-104-119.8zm312 315.6c0 48.5-9.7 95.3-32 132.3-42.2 30.9-105 48-168 48-62.9 0-125.8-17.1-168-48C9.7 419 0 372.2 0 323.7 0 275.3 17.7 229 40 192c42.2-30.9 97.1-48.6 160-48.6 63 0 117.8 17.6 160 48.6 22.3 37 40 83.3 40 131.7zM120 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zM192 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zM264 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zM336 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm24-39.6c-4.8-22.3-7.4-36.9-16-56-38.8-19.9-90.5-32-144-32S94.8 180.1 56 200c-8.8 19.5-11.2 33.9-16 56 42.2-7.9 98.7-14.8 160-14.8s117.8 6.9 160 14.8z"],odnoklassniki:[320,512,[],"f263","M275.1 334c-27.4 17.4-65.1 24.3-90 26.9l20.9 20.6 76.3 76.3c27.9 28.6-17.5 73.3-45.7 45.7-19.1-19.4-47.1-47.4-76.3-76.6L84 503.4c-28.2 27.5-73.6-17.6-45.4-45.7 19.4-19.4 47.1-47.4 76.3-76.3l20.6-20.6c-24.6-2.6-62.9-9.1-90.6-26.9-32.6-21-46.9-33.3-34.3-59 7.4-14.6 27.7-26.9 54.6-5.7 0 0 36.3 28.9 94.9 28.9s94.9-28.9 94.9-28.9c26.9-21.1 47.1-8.9 54.6 5.7 12.4 25.7-1.9 38-34.5 59.1zM30.3 129.7C30.3 58 88.6 0 160 0s129.7 58 129.7 129.7c0 71.4-58.3 129.4-129.7 129.4s-129.7-58-129.7-129.4zm66 0c0 35.1 28.6 63.7 63.7 63.7s63.7-28.6 63.7-63.7c0-35.4-28.6-64-63.7-64s-63.7 28.6-63.7 64z"],"odnoklassniki-square":[448,512,[],"f264","M184.2 177.1c0-22.1 17.9-40 39.8-40s39.8 17.9 39.8 40c0 22-17.9 39.8-39.8 39.8s-39.8-17.9-39.8-39.8zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-305.1 97.1c0 44.6 36.4 80.9 81.1 80.9s81.1-36.2 81.1-80.9c0-44.8-36.4-81.1-81.1-81.1s-81.1 36.2-81.1 81.1zm174.5 90.7c-4.6-9.1-17.3-16.8-34.1-3.6 0 0-22.7 18-59.3 18s-59.3-18-59.3-18c-16.8-13.2-29.5-5.5-34.1 3.6-7.9 16.1 1.1 23.7 21.4 37 17.3 11.1 41.2 15.2 56.6 16.8l-12.9 12.9c-18.2 18-35.5 35.5-47.7 47.7-17.6 17.6 10.7 45.8 28.4 28.6l47.7-47.9c18.2 18.2 35.7 35.7 47.7 47.9 17.6 17.2 46-10.7 28.6-28.6l-47.7-47.7-13-12.9c15.5-1.6 39.1-5.9 56.2-16.8 20.4-13.3 29.3-21 21.5-37z"],opencart:[640,512,[],"f23d","M423.3 440.7c0 25.3-20.3 45.6-45.6 45.6s-45.8-20.3-45.8-45.6 20.6-45.8 45.8-45.8c25.4 0 45.6 20.5 45.6 45.8zm-253.9-45.8c-25.3 0-45.6 20.6-45.6 45.8s20.3 45.6 45.6 45.6 45.8-20.3 45.8-45.6-20.5-45.8-45.8-45.8zm291.7-270C158.9 124.9 81.9 112.1 0 25.7c34.4 51.7 53.3 148.9 373.1 144.2 333.3-5 130 86.1 70.8 188.9 186.7-166.7 319.4-233.9 17.2-233.9z"],openid:[448,512,[],"f19b","M271.5 432l-68 32C88.5 453.7 0 392.5 0 318.2c0-71.5 82.5-131 191.7-144.3v43c-71.5 12.5-124 53-124 101.3 0 51 58.5 93.3 135.7 103v-340l68-33.2v384zM448 291l-131.3-28.5 36.8-20.7c-19.5-11.5-43.5-20-70-24.8v-43c46.2 5.5 87.7 19.5 120.3 39.3l35-19.8L448 291z"],opera:[496,512,[],"f26a","M313.9 32.7c-170.2 0-252.6 223.8-147.5 355.1 36.5 45.4 88.6 75.6 147.5 75.6 36.3 0 70.3-11.1 99.4-30.4-43.8 39.2-101.9 63-165.3 63-3.9 0-8 0-11.9-.3C104.6 489.6 0 381.1 0 248 0 111 111 0 248 0h.8c63.1.3 120.7 24.1 164.4 63.1-29-19.4-63.1-30.4-99.3-30.4zm101.8 397.7c-40.9 24.7-90.7 23.6-132-5.8 56.2-20.5 97.7-91.6 97.7-176.6 0-84.7-41.2-155.8-97.4-176.6 41.8-29.2 91.2-30.3 132.9-5 105.9 98.7 105.5 265.7-1.2 364z"],"optin-monster":[576,512,[],"f23c","M550.671 450.303c0 11.62-15.673 19.457-32.158 14.863-12.16-3.243-31.346-17.565-36.211-27.294-5.674-11.62 4.054-32.698 18.916-30.806 15.674 1.621 49.453 25.401 49.453 43.237zM372.86 75.223c-3.783-72.151-100.796-79.718-125.928-23.51 44.588-24.321 90.257-15.673 125.928 23.51zM74.795 407.066c-15.673 1.621-49.452 25.401-49.452 43.237 0 11.62 15.673 19.457 32.157 14.863 12.16-3.243 31.076-17.565 35.94-27.294 5.946-11.62-3.782-32.698-18.645-30.806zm497.765 14.322c1.081 3.513 1.892 7.026 1.892 10.809.81 31.616-44.317 64.045-73.503 65.125-17.295.81-34.59-8.377-42.696-23.51-113.497 4.053-226.994 4.864-340.22 0-8.377 15.133-25.672 24.05-42.967 23.51-28.915-1.081-74.043-33.509-73.503-65.125.27-3.783.811-7.296 1.892-10.809-5.566-9.463-4.845-15.282 5.405-11.62 3.243-5.134 7.026-9.458 11.08-13.782-2.57-10.917 1.27-14.094 11.079-9.188 4.594-3.243 9.998-6.485 15.944-9.188 0-15.757 11.839-11.131 17.295-5.675 12.467-1.78 20.129.709 26.753 5.675v-19.726c-12.987 0-40.641-11.375-45.94-36.212-4.974-20.725 2.607-38.075 25.132-47.56.81-5.945 8.107-14.052 14.862-15.944 7.567-1.892 12.431 4.594 14.052 10.269 7.425 0 17.757 1.465 21.078 8.107 5.405-.541 11.079-1.352 16.484-1.892-2.432-1.892-5.134-3.513-8.107-4.594-5.134-8.917-13.782-11.079-24.591-11.62 0-.81 0-1.621.27-2.702-19.727-.541-44.048-5.675-54.857-17.835-21.321-23.638-15.935-83.577 12.16-103.498 8.377-5.675 21.618-.811 22.699 9.728 2.425 20.598.399 26.833 26.212 25.942 8.107-7.836 16.755-14.592 26.483-19.997-14.862-1.352-28.914 1.621-43.778 3.783 12.752-12.48 23.953-25.442 56.748-42.427 23.511-11.89 49.993-20.808 76.205-23.239-18.646-7.837-39.993-11.891-59.721-16.484 76.475-16.214 174.569-22.159 244.289 37.562 18.105 15.403 32.427 36.211 42.696 59.992 39.799 4.853 36.47-5.581 38.643-25.132 1.081-10.269 14.322-15.403 22.699-9.458 14.862 10.539 22.159 30.806 24.59 48.101 2.162 17.835.27 41.345-12.43 55.127-10.809 12.16-34.32 17.565-53.776 18.105v2.703c-11.08.27-20.268 2.432-25.673 11.62-2.972 1.081-5.674 2.703-8.377 4.594 5.675.54 11.35 1.351 16.755 1.891 1.869-5.619 12.535-8.377 21.077-8.377 1.621-5.405 6.756-11.89 14.052-10.269s14.052 9.998 14.863 15.944c10.809 4.324 22.159 12.16 25.131 25.672 1.892 8.107 1.621 15.133.27 21.888-5.726 25.262-33.361 36.212-45.939 36.212 0 6.756 0 13.241-.27 19.726 8.01-6.006 16.367-7.158 26.752-5.675 5.919-5.919 17.565-9.41 17.565 5.675 5.675 2.703 11.349 5.945 15.944 9.188 10.1-5.051 13.669-.539 10.809 9.188 4.053 4.323 8.107 8.917 11.079 13.782 10.136-3.62 11.021 2.078 5.409 11.62zm-73.773-254.016c17.295 6.756 26.212 22.159 30.265 35.67 1.081-10.539-2.702-39.453-13.782-51.073-7.296-7.296-14.052-5.134-14.052.81.001 6.216-1.35 11.62-2.431 14.593zm-18.646 12.43c12.971 15.673 17.024 41.615 12.7 62.963 10.809-2.162 20.537-6.215 26.212-12.16 1.892-2.162 3.783-4.864 4.864-7.566-1.081-21.348-10.269-42.697-29.725-48.912-3.242 3.243-9.187 4.864-14.051 5.675zm-21.889.811c7.567 20.537 12.431 42.696 14.322 64.585 3.513 0 7.567-.27 11.62-.811 5.945-24.321-.27-51.614-14.052-63.504-3.783 0-8.107 0-11.89-.27zM77.768 167.372c-1.081-2.973-2.432-8.377-2.432-14.593 0-5.945-7.026-8.107-14.052-.81-11.35 11.62-14.863 40.534-13.782 51.073 4.053-13.512 12.971-28.915 30.266-35.67zm5.675 75.394c-4.324-21.348-.27-47.291 12.701-62.963-4.865-.811-10.809-2.432-14.052-5.675-19.457 6.215-28.375 27.563-29.726 48.912 1.351 2.702 2.972 5.404 4.864 7.566 5.675 6.215 15.403 9.998 26.213 12.16zm41.345-61.073c-5.134 1.081-9.998 2.973-14.862 4.865l-12.16 5.134v-.27c-7.296 14.052-9.999 34.319-5.405 52.965 4.594.541 8.647.811 12.7.811 2.432-22.159 9.188-43.778 19.727-63.505zm88.095-23.239c0 42.155 34.319 76.205 76.205 76.205s76.205-34.05 76.205-76.205c0-41.886-34.319-75.935-76.205-75.935s-76.205 34.049-76.205 75.935zm152.41 97.283c9.969 50.608 3.299 64.692 16.484 58.099 15.944-8.107 22.699-39.183 22.97-57.019-12.971-.81-26.213-.81-39.454-1.08zm-71.611-.541v-.27c-.27 5.134.27 38.103 4.324 41.075 11.079 5.405 39.453 4.594 51.073 1.081 5.405-1.621 2.432-37.022 1.621-41.886-18.916-.27-38.102-.27-57.018 0zm-14.053 0v-.27c-19.456.27-38.642.27-57.829.811-1.892 9.187-4.594 48.911 1.892 51.614 12.971 5.675 41.616 5.134 54.586 1.621 4.595-2.432 2.433-45.399 1.351-53.776zm-85.662 57.56c5.405 2.432 8.647 2.432 9.728-4.324 1.892-8.647 2.432-36.752 4.865-52.155-12.16.27-24.591.811-36.752 1.621-5.405 19.727.27 45.129 22.159 54.858zm-65.666-11.08c43.778 47.02 92.689 85.663 155.923 106.47 67.558-19.186 115.659-59.991 163.219-107.011-11.095-4.315-7.715-10.363-7.296-11.62-8.918-.81-17.835-1.892-26.483-2.702-9.458 32.968-35.94 52.965-46.75 31.616-2.702-5.134-3.513-11.62-4.594-16.754-3.783 8.377-13.242 8.107-24.591 8.918-13.241 1.081-31.617 1.351-44.048-2.972-2.972 12.971-11.079 12.971-26.752 14.322-14.052 1.352-48.642 4.054-54.857-10.809-1.081 28.644-35.13 9.998-45.129-7.026-3.243-5.675-5.405-11.35-7.026-17.565-7.837.81-15.673 1.621-23.511 2.702 2.443 3.663 1.549 9.052-8.105 12.431zM115.6 453.545c-5.674-23.239-18.646-49.722-33.508-54.046-22.429-6.756-68.909 23.51-66.207 54.586 12.701 19.457 39.994 35.67 59.181 36.481 17.835.81 35.94-11.08 39.724-28.914.539-2.432.81-5.134.81-8.107zm7.296-5.944c33.509-19.457 69.179-35.671 105.931-47.02-38.643-20.537-68.098-47.831-97.283-77.016-2.162 1.352-5.134 2.432-7.836 3.513-1.637 4.91 8.718 5.33 5.405 12.431-2.162 4.054-8.648 7.567-15.133 9.188-2.161 2.702-5.134 4.864-7.836 6.485h-.27c-.27 13.511-.27 27.024.27 40.535 8.939 15.964 15.426 33.314 16.752 51.884zm320.764 12.7c-36.752-21.348-74.044-41.345-115.659-52.965-13.782 6.215-27.833 11.349-42.155 15.403-2.162.811-2.162.811-4.324 0-11.89-3.783-23.239-8.107-34.859-13.241-40.265 11.62-77.286 29.185-112.416 50.803h-.27v.27c.27 0 .27 0 .27-.27 103.227 4.054 206.455 3.513 309.413 0zm27.023-64.045l-.27.27c.541-13.782.811-27.563.811-41.345-2.973-1.621-5.675-4.054-8.107-6.756-6.485-1.351-12.971-5.134-15.133-8.918-1.892-4.053 1.351-7.566 5.945-10.269-.27-.541-.541-1.621-.541-2.432-2.972-.811-5.405-1.892-7.567-3.243-31.616 29.455-65.396 56.749-103.498 76.746 38.914 11.62 75.935 28.104 111.875 47.561 1.05-14.692 7.231-35.749 16.485-51.614zm23.24 3.244c-14.593 4.323-27.834 30.806-33.509 54.046 0 23.826 21.278 37.897 40.534 37.022 19.186-.811 46.48-17.024 59.181-36.481 2.973-31.077-43.507-61.344-66.206-54.587zM290.709 134.133c.045 0 .089.003.134.003.046 0 .09-.003.136-.003h-.27zm0 96.743c28.645 0 51.884-21.618 51.884-48.371 0-36.092-40.507-58.079-72.151-44.318 9.458 2.972 16.484 11.62 16.484 21.618 0 23.257-33.291 31.955-46.48 11.35-7.297 34.067 19.368 59.721 50.263 59.721zM68.039 474.083c.54 6.486 12.16 12.701 21.618 9.458 6.756-2.703 14.593-10.539 17.295-16.214 2.973-7.026-1.081-19.997-9.728-18.375-8.917 1.621-29.725 16.754-29.185 25.131zm410.75-25.131c-8.377-1.621-12.431 11.349-9.458 18.375 2.432 5.675 10.269 13.511 17.295 16.214 9.187 3.243 21.078-2.972 21.348-9.458.811-8.377-20.267-23.51-29.185-25.131z"],osi:[495,512,[],"f41a","M0 259.2C2.3 123.4 97.4 26.8 213.8 11.1c138.8-18.6 255.6 75.8 278 201.1 21.3 118.8-44 230-151.6 274-9.3 3.8-14.4 1.7-18-7.7-17.8-46.3-35.6-92.7-53.4-139-3.1-8.1-1-13.2 7-16.8 24.2-11 39.3-29.4 43.3-55.8 6.4-42.4-24.5-78.7-64.5-82.2-39-3.4-71.8 23.7-77.5 59.7-5.2 33 11.1 63.7 41.9 77.7 9.6 4.4 11.5 8.6 7.8 18.4-17.9 46.6-35.8 93.2-53.7 139.9-2.6 6.9-8.3 9.3-15.5 6.5-52.6-20.3-101.4-61-130.8-119C1.9 318.7 1.6 280.2 0 259.2zm20.9-1.9c.4 6.6.6 14.3 1.3 22.1 6.3 71.9 49.6 143.5 131 183.1 3.2 1.5 4.4.8 5.6-2.3 14.9-39.1 29.9-78.2 45-117.3 1.3-3.3.6-4.8-2.4-6.7-31.6-19.9-47.3-48.5-45.6-86 1-21.6 9.3-40.5 23.8-56.3 30-32.7 77-39.8 115.5-17.6 31.9 18.4 49.5 53.8 45.2 90.4-3.6 30.6-19.3 53.9-45.7 69.8-2.7 1.6-3.5 2.9-2.3 6 15.2 39.2 30.2 78.4 45.2 117.7 1.2 3.1 2.4 3.8 5.6 2.3 35.5-16.6 65.2-40.3 88.1-72 34.8-48.2 49.1-101.9 42.3-161C459.8 112 354.1 14.7 218 31.5 111.9 44.5 22.7 134 20.9 257.3z"],page4:[496,512,[],"f3d7","M248 504C111 504 0 393 0 256S111 8 248 8c20.9 0 41.3 2.6 60.7 7.5L42.3 392H248v112zm0-143.6V146.8L98.6 360.4H248zm96 31.6v92.7c45.7-19.2 84.5-51.7 111.4-92.7H344zm57.4-138.2l-21.2 8.4 21.2 8.3v-16.7zm-20.3 54.5c-6.7 0-8 6.3-8 12.9v7.7h16.2v-10c0-5.9-2.3-10.6-8.2-10.6zM496 256c0 37.3-8.2 72.7-23 104.4H344V27.3C433.3 64.8 496 153.1 496 256zM360.4 143.6h68.2V96h-13.9v32.6h-13.9V99h-13.9v29.6h-12.7V96h-13.9v47.6zm68.1 185.3H402v-11c0-15.4-5.6-25.2-20.9-25.2-15.4 0-20.7 10.6-20.7 25.9v25.3h68.2v-15zm0-103l-68.2 29.7V268l68.2 29.5v-16.6l-14.4-5.7v-26.5l14.4-5.9v-16.9zm-4.8-68.5h-35.6V184H402v-12.2h11c8.6 15.8 1.3 35.3-18.6 35.3-22.5 0-28.3-25.3-15.5-37.7l-11.6-10.6c-16.2 17.5-12.2 63.9 27.1 63.9 34 0 44.7-35.9 29.3-65.3z"],pagelines:[384,512,[],"f18c","M384 312.7c-55.1 136.7-187.1 54-187.1 54-40.5 81.8-107.4 134.4-184.6 134.7-16.1 0-16.6-24.4 0-24.4 64.4-.3 120.5-42.7 157.2-110.1-41.1 15.9-118.6 27.9-161.6-82.2 109-44.9 159.1 11.2 178.3 45.5 9.9-24.4 17-50.9 21.6-79.7 0 0-139.7 21.9-149.5-98.1 119.1-47.9 152.6 76.7 152.6 76.7 1.6-16.7 3.3-52.6 3.3-53.4 0 0-106.3-73.7-38.1-165.2 124.6 43 61.4 162.4 61.4 162.4.5 1.6.5 23.8 0 33.4 0 0 45.2-89 136.4-57.5-4.2 134-141.9 106.4-141.9 106.4-4.4 27.4-11.2 53.4-20 77.5 0 0 83-91.8 172-20z"],palfed:[576,512,[],"f3d8","M384.9 193.9c0-47.4-55.2-44.2-95.4-29.8-1.3 39.4-2.5 80.7-3 119.8.7 2.8 2.6 6.2 15.1 6.2 36.8 0 83.4-42.8 83.3-96.2zm-194.5 72.2c.2 0 6.5-2.7 11.2-2.7 26.6 0 20.7 44.1-14.4 44.1-21.5 0-37.1-18.1-37.1-43 0-42 42.9-95.6 100.7-126.5 1-12.4 3-22 10.5-28.2 11.2-9 26.6-3.5 29.5 11.1 72.2-22.2 135.2 1 135.2 72 0 77.9-79.3 152.6-140.1 138.2-.1 39.4.9 74.4 2.7 100v.2c.2 3.4.6 12.5-5.3 19.1-9.6 10.6-33.4 10-36.4-22.3-4.1-44.4.2-206.1 1.4-242.5-21.5 15-58.5 50.3-58.5 75.9.2 2.5.4 4 .6 4.6zM8 181.1s-.1 37.4 38.4 37.4h30l22.4 217.2s0 44.3 44.7 44.3h288.9s44.7-.4 44.7-44.3l22.4-217.2h30s38.4 1.2 38.4-37.4c0 0 .1-37.4-38.4-37.4h-30.1c-7.3-25.6-30.2-74.3-119.4-74.3h-28V50.3s-2.7-18.4-21.1-18.4h-85.8s-21.1 0-21.1 18.4v19.1h-28.1s-105 4.2-120.5 74.3h-29S8 142.5 8 181.1z"],patreon:[512,512,[],"f3d9","M512 194.8c0 101.3-82.4 183.8-183.8 183.8-101.7 0-184.4-82.4-184.4-183.8 0-101.6 82.7-184.3 184.4-184.3C429.6 10.5 512 93.2 512 194.8zM0 501.5h90v-491H0v491z"],paypal:[384,512,[],"f1ed","M111.4 295.9c-3.5 19.2-17.4 108.7-21.5 134-.3 1.8-1 2.5-3 2.5H12.3c-7.6 0-13.1-6.6-12.1-13.9L58.8 46.6c1.5-9.6 10.1-16.9 20-16.9 152.3 0 165.1-3.7 204 11.4 60.1 23.3 65.6 79.5 44 140.3-21.5 62.6-72.5 89.5-140.1 90.3-43.4.7-69.5-7-75.3 24.2zM357.1 152c-1.8-1.3-2.5-1.8-3 1.3-2 11.4-5.1 22.5-8.8 33.6-39.9 113.8-150.5 103.9-204.5 103.9-6.1 0-10.1 3.3-10.9 9.4-22.6 140.4-27.1 169.7-27.1 169.7-1 7.1 3.5 12.9 10.6 12.9h63.5c8.6 0 15.7-6.3 17.4-14.9.7-5.4-1.1 6.1 14.4-91.3 4.6-22 14.3-19.7 29.3-19.7 71 0 126.4-28.8 142.9-112.3 6.5-34.8 4.6-71.4-23.8-92.6z"],periscope:[448,512,[],"f3da","M370 63.6C331.4 22.6 280.5 0 226.6 0 111.9 0 18.5 96.2 18.5 214.4c0 75.1 57.8 159.8 82.7 192.7C137.8 455.5 192.6 512 226.6 512c41.6 0 112.9-94.2 120.9-105 24.6-33.1 82-118.3 82-192.6 0-56.5-21.1-110.1-59.5-150.8zM226.6 493.9c-42.5 0-190-167.3-190-279.4 0-107.4 83.9-196.3 190-196.3 100.8 0 184.7 89 184.7 196.3.1 112.1-147.4 279.4-184.7 279.4zM338 206.8c0 59.1-51.1 109.7-110.8 109.7-100.6 0-150.7-108.2-92.9-181.8v.4c0 24.5 20.1 44.4 44.8 44.4 24.7 0 44.8-19.9 44.8-44.4 0-18.2-11.1-33.8-26.9-40.7 76.6-19.2 141 39.3 141 112.4z"],phabricator:[496,512,[],"f3db","M323 262.1l-.1-13s21.7-19.8 21.1-21.2l-9.5-20c-.6-1.4-29.5-.5-29.5-.5l-9.4-9.3s.2-28.5-1.2-29.1l-20.1-9.2c-1.4-.6-20.7 21-20.7 21l-13.1-.2s-20.5-21.4-21.9-20.8l-20 8.3c-1.4.5.2 28.9.2 28.9l-9.1 9.1s-29.2-.9-29.7.4l-8.1 19.8c-.6 1.4 21 21 21 21l.1 12.9s-21.7 19.8-21.1 21.2l9.5 20c.6 1.4 29.5.5 29.5.5l9.4 9.3s-.2 31.8 1.2 32.3l20.1 8.3c1.4.6 20.7-23.5 20.7-23.5l13.1.2s20.5 23.8 21.8 23.3l20-7.5c1.4-.6-.2-32.1-.2-32.1l9.1-9.1s29.2.9 29.7-.5l8.1-19.8c.7-1.1-20.9-20.7-20.9-20.7zm-44.9-8.7c.7 17.1-12.8 31.6-30.1 32.4-17.3.8-32.1-12.5-32.8-29.6-.7-17.1 12.8-31.6 30.1-32.3 17.3-.8 32.1 12.5 32.8 29.5zm201.2-37.9l-97-97-.1.1c-75.1-73.3-195.4-72.8-269.8 1.6-50.9 51-27.8 27.9-95.7 95.3-22.3 22.3-22.3 58.7 0 81 69.9 69.4 46.4 46 97.4 97l.1-.1c75.1 73.3 195.4 72.9 269.8-1.6 51-50.9 27.9-27.9 95.3-95.3 22.3-22.3 22.3-58.7 0-81zM140.4 363.8c-59.6-59.5-59.6-156 0-215.5 59.5-59.6 156-59.5 215.6 0 59.5 59.5 59.6 156 0 215.6-59.6 59.5-156 59.4-215.6-.1z"],"phoenix-framework":[640,512,[],"f3dc","M212.9 344.3c3.8-.1 22.8-1.4 25.6-2.2-2.4-2.6-43.6-1-68-49.6-4.3-8.6-7.5-17.6-6.4-27.6 2.9-25.5 32.9-30 52-18.5 36 21.6 63.3 91.3 113.7 97.5 37 4.5 84.6-17 108.2-45.4-.6-.1-.8-.2-1-.1-.4.1-.8.2-1.1.3-33.3 12.1-94.3 9.7-134.7-14.8-37.6-22.8-53.1-58.7-51.8-74.6 1.8-21.3 22.9-23.2 35.9-19.6 14.4 3.9 24.4 17.6 38.9 27.4 15.6 10.4 32.9 13.7 51.3 10.3 14.9-2.7 34.4-12.3 36.5-14.5-1.1-.1-1.8-.1-2.5-.2-6.2-.6-12.4-.8-18.5-1.7C279.8 194.5 262.1 47.4 138.5 37.9 94.2 34.5 39.1 46 2.2 72.9c-.8.6-1.5 1.2-2.2 1.8.1.2.1.3.2.5.8 0 1.6-.1 2.4-.2 6.3-1 12.5-.8 18.7.3 23.8 4.3 47.7 23.1 55.9 76.5 5.3 34.3-.7 50.8 8 86.1 19 77.1 91 107.6 127.7 106.4zM75.3 64.9c-.9-1-.9-1.2-1.3-2 12.1-2.6 24.2-4.1 36.6-4.8-1.1 14.7-22.2 21.3-35.3 6.8zm196.9 350.5c-42.8 1.2-92-26.7-123.5-61.4-4.6-5-16.8-20.2-18.6-23.4l.4-.4c6.6 4.1 25.7 18.6 54.8 27 24.2 7 48.1 6.3 71.6-3.3 22.7-9.3 41-.5 43.1 2.9-18.5 3.8-20.1 4.4-24 7.9-5.1 4.4-4.6 11.7 7 17.2 26.2 12.4 63-2.8 97.2 25.4 2.4 2 8.1 7.8 10.1 10.7-.1.2-.3.3-.4.5-4.8-1.5-16.4-7.5-40.2-9.3-24.7-2-46.3 5.3-77.5 6.2zm174.8-252c16.4-5.2 41.3-13.4 66.5-3.3 16.1 6.5 26.2 18.7 32.1 34.6 3.5 9.4 5.1 19.7 5.1 28.7-.2 0-.4 0-.6.1-.2-.4-.4-.9-.5-1.3-5-22-29.9-43.8-67.6-29.9-50.2 18.6-130.4 9.7-176.9-48-.7-.9-2.4-1.7-1.3-3.2.1-.2 2.1.6 3 1.3 18.1 13.4 38.3 21.9 60.3 26.2 30.5 6.1 54.6 2.9 79.9-5.2zm102.7 117.5c-32.4.2-33.8 50.1-103.6 64.4-18.2 3.7-38.7 4.6-44.9 4.2v-.4c2.8-1.5 14.7-2.6 29.7-16.6 7.9-7.3 15.3-15.1 22.8-22.9 19.5-20.2 41.4-42.2 81.9-39 23.1 1.8 29.3 8.2 36.1 12.7.3.2.4.5.7.9-.5 0-.7.1-.9 0-7-2.7-14.3-3.3-21.8-3.3zm-12.3-24.1c-.1.2-.1.4-.2.6-28.9-4.4-48-7.9-68.5 4-17 9.9-31.4 20.5-62 24.4-27.1 3.4-45.1 2.4-66.1-8-.3-.2-.6-.4-1-.6 0-.2.1-.3.1-.5 24.9 3.8 36.4 5.1 55.5-5.8 22.3-12.9 40.1-26.6 71.3-31 29.6-4.1 51.3 2.5 70.9 16.9zM268.6 97.3c-.6-.6-1.1-1.2-2.1-2.3 7.6 0 29.7-1.2 53.4 8.4 19.7 8 32.2 21 50.2 32.9 11.1 7.3 23.4 9.3 36.4 8.1 4.3-.4 8.5-1.2 12.8-1.7.4-.1.9 0 1.5.3-.6.4-1.2.9-1.8 1.2-8.1 4-16.7 6.3-25.6 7.1-26.1 2.6-50.3-3.7-73.4-15.4-19.3-9.9-36.4-22.9-51.4-38.6zM640 335.7c-3.5 3.1-22.7 11.6-42.7 5.3-12.3-3.9-19.5-14.9-31.6-24.1-10-7.6-20.9-7.9-28.1-8.4.6-.8.9-1.2 1.2-1.4 14.8-9.2 30.5-12.2 47.3-6.5 12.5 4.2 19.2 13.5 30.4 24.2 10.8 10.4 21 9.9 23.1 10.5.1-.1.2 0 .4.4zm-212.5 137c2.2 1.2 1.6 1.5 1.5 2-18.5-1.4-33.9-7.6-46.8-22.2-21.8-24.7-41.7-27.9-48.6-29.7.5-.2.8-.4 1.1-.4 13.1.1 26.1.7 38.9 3.9 25.3 6.4 35 25.4 41.6 35.3 3.2 4.8 7.3 8.3 12.3 11.1z"],php:[640,512,[],"f457","M320 104.5c171.4 0 303.2 72.2 303.2 151.5S491.3 407.5 320 407.5c-171.4 0-303.2-72.2-303.2-151.5S148.7 104.5 320 104.5m0-16.8C143.3 87.7 0 163 0 256s143.3 168.3 320 168.3S640 349 640 256 496.7 87.7 320 87.7zM218.2 242.5c-7.9 40.5-35.8 36.3-70.1 36.3l13.7-70.6c38 0 63.8-4.1 56.4 34.3zM97.4 350.3h36.7l8.7-44.8c41.1 0 66.6 3 90.2-19.1 26.1-24 32.9-66.7 14.3-88.1-9.7-11.2-25.3-16.7-46.5-16.7h-70.7L97.4 350.3zm185.7-213.6h36.5l-8.7 44.8c31.5 0 60.7-2.3 74.8 10.7 14.8 13.6 7.7 31-8.3 113.1h-37c15.4-79.4 18.3-86 12.7-92-5.4-5.8-17.7-4.6-47.4-4.6l-18.8 96.6h-36.5l32.7-168.6zM505 242.5c-8 41.1-36.7 36.3-70.1 36.3l13.7-70.6c38.2 0 63.8-4.1 56.4 34.3zM384.2 350.3H421l8.7-44.8c43.2 0 67.1 2.5 90.2-19.1 26.1-24 32.9-66.7 14.3-88.1-9.7-11.2-25.3-16.7-46.5-16.7H417l-32.8 168.7z"],"pied-piper":[448,512,[],"f2ae","M32 419L0 479.2l.8-328C.8 85.3 54 32 120 32h327.2c-93 28.9-189.9 94.2-253.9 168.6C122.7 282 82.6 338 32 419M448 32S305.2 98.8 261.6 199.1c-23.2 53.6-28.9 118.1-71 158.6-28.9 27.8-69.8 38.2-105.3 56.3-23.2 12-66.4 40.5-84.9 66h328.4c66 0 119.3-53.3 119.3-119.2-.1 0-.1-328.8-.1-328.8z"],"pied-piper-alt":[576,512,[],"f1a8","M242 187c6.3-11.8 13.2-17 25.9-21.8 27.3-10.3 40.2-30.5 58.9-51.1 11.9 8.4 12 24.6 31.6 23v21.8l6.3.3c37.4-14.4 74.7-30.2 106.6-54.6 48.3-36.8 52.9-50 81.3-100l2-2.6c-.6 14.1-6.3 27.3-12.4 39.9-30.5 63.8-78.7 100.3-146.8 116.7-12.4 2.9-26.4 3.2-37.6 8.9 1.4 9.8 13.2 18.1 13.2 23 0 3.4-5.5 7.2-7.5 8.6-11.2-12.9-16.1-19.3-22.7-22.1-7.6-3.5-63.9-6.4-98.8 10zm137.9 256.9c-19 0-64.1 9.5-79.9 19.8l6.9 45.1c35.7 6.1 70.1 3.6 106-9.8-4.8-10-23.5-55.1-33-55.1zM244 246c-3.2-2-6.3-2.9-10.1-2.9-6.6 0-12.6 3.2-19.3 3.7l1.7 4.9L244 246zm-12.6 31.8l24.1 61.2 21-13.8-31.3-50.9-13.8 3.5zM555.5 0l-.6 1.1-.3.9.6-.6.3-1.4zm-59.2 382.1c-33.9-56.9-75.3-118.4-150-115.5l-.3-6c-1.1-13.5 32.8 3.2 35.1-31l-14.4 7.2c-19.8-45.7-8.6-54.3-65.5-54.3-14.7 0-26.7 1.7-41.4 4.6 2.9 18.6 2.2 36.7-10.9 50.3l19.5 5.5c-1.7 3.2-2.9 6.3-2.9 9.8 0 21 42.8 2.9 42.8 33.6 0 18.4-36.8 60.1-54.9 60.1-8 0-53.7-50-53.4-60.1l.3-4.6 52.3-11.5c13-2.6 12.3-22.7-2.9-22.7-3.7 0-43.1 9.2-49.4 10.6-2-5.2-7.5-14.1-13.8-14.1-3.2 0-6.3 3.2-9.5 4-9.2 2.6-31 2.9-21.5 20.1L15.9 298.5c-5.5 1.1-8.9 6.3-8.9 11.8 0 6 5.5 10.9 11.5 10.9 8 0 131.3-28.4 147.4-32.2 2.6 3.2 4.6 6.3 7.8 8.6 20.1 14.4 59.8 85.9 76.4 85.9 24.1 0 58-22.4 71.3-41.9 3.2-4.3 6.9-7.5 12.4-6.9.6 13.8-31.6 34.2-33 43.7-1.4 10.2-1 35.2-.3 41.1 26.7 8.1 52-3.6 77.9-2.9 4.3-21 10.6-41.9 9.8-63.5l-.3-9.5c-1.4-34.2-10.9-38.5-34.8-58.6-1.1-1.1-2.6-2.6-3.7-4 2.2-1.4 1.1-1 4.6-1.7 88.5 0 56.3 183.6 111.5 229.9 33.1-15 72.5-27.9 103.5-47.2-29-25.6-52.6-45.7-72.7-79.9zm-196.2 46v27.3l11.8-3.4-2.9-23.8h-8.9zm76.1 2.9c0-1.4-.6-3.2-.9-4.6-26.8 0-36.9 3.8-59.5 6.3l2 12.4c9-1.5 58.4-6.6 58.4-14.1z"],"pied-piper-hat":[640,512,[],"f4e5","M640 24.9c-80.8 53.6-89.4 92.5-96.4 104.4-6.7 12.2-11.7 60.3-23.3 83.6-11.7 23.6-54.2 42.2-66.1 50-11.7 7.8-28.3 38.1-41.9 64.2-108.1-4.4-167.4 38.8-259.2 93.6 29.4-9.7 43.3-16.7 43.3-16.7 94.2-36 139.3-68.3 281.1-49.2 1.1 0 1.9.6 2.8.8 3.9 2.2 5.3 6.9 3.1 10.8l-53.9 95.8c-2.5 4.7-7.8 7.2-13.1 6.1-126.8-23.8-226.9 17.3-318.9 18.6C24.1 488 0 453.4 0 451.8c0-1.1.6-1.7 1.7-1.7 0 0 38.3 0 103.1-15.3C178.4 294.5 244 245.4 315.4 245.4c0 0 71.7 0 90.6 61.9 22.8-39.7 28.3-49.2 28.3-49.2 5.3-9.4 35-77.2 86.4-141.4 51.5-64 90.4-79.9 119.3-91.8z"],"pied-piper-pp":[448,512,[],"f1a7","M205.3 174.6c0 21.1-14.2 38.1-31.7 38.1-7.1 0-12.8-1.2-17.2-3.7v-68c4.4-2.7 10.1-4.2 17.2-4.2 17.5 0 31.7 16.9 31.7 37.8zm52.6 67c-7.1 0-12.8 1.5-17.2 4.2v68c4.4 2.5 10.1 3.7 17.2 3.7 17.4 0 31.7-16.9 31.7-37.8 0-21.1-14.3-38.1-31.7-38.1zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM185 255.1c41 0 74.2-35.6 74.2-79.6 0-44-33.2-79.6-74.2-79.6-12 0-24.1 3.2-34.6 8.8h-45.7V311l51.8-10.1v-50.6c8.6 3.1 18.1 4.8 28.5 4.8zm158.4 25.3c0-44-33.2-79.6-73.9-79.6-3.2 0-6.4.2-9.6.7-3.7 12.5-10.1 23.8-19.2 33.4-13.8 15-32.2 23.8-51.8 24.8V416l51.8-10.1v-50.6c8.6 3.2 18.2 4.7 28.7 4.7 40.8 0 74-35.6 74-79.6z"],pinterest:[496,512,[],"f0d2","M496 256c0 137-111 248-248 248-25.6 0-50.2-3.9-73.4-11.1 10.1-16.5 25.2-43.5 30.8-65 3-11.6 15.4-59 15.4-59 8.1 15.4 31.7 28.5 56.8 28.5 74.8 0 128.7-68.8 128.7-154.3 0-81.9-66.9-143.2-152.9-143.2-107 0-163.9 71.8-163.9 150.1 0 36.4 19.4 81.7 50.3 96.1 4.7 2.2 7.2 1.2 8.3-3.3.8-3.4 5-20.3 6.9-28.1.6-2.5.3-4.7-1.7-7.1-10.1-12.5-18.3-35.3-18.3-56.6 0-54.7 41.4-107.6 112-107.6 60.9 0 103.6 41.5 103.6 100.9 0 67.1-33.9 113.6-78 113.6-24.3 0-42.6-20.1-36.7-44.8 7-29.5 20.5-61.3 20.5-82.6 0-19-10.2-34.9-31.4-34.9-24.9 0-44.9 25.7-44.9 60.2 0 22 7.4 36.8 7.4 36.8s-24.5 103.8-29 123.2c-5 21.4-3 51.6-.9 71.2C65.4 450.9 0 361.1 0 256 0 119 111 8 248 8s248 111 248 248z"],"pinterest-p":[384,512,[],"f231","M204 6.5C101.4 6.5 0 74.9 0 185.6 0 256 39.6 296 63.6 296c9.9 0 15.6-27.6 15.6-35.4 0-9.3-23.7-29.1-23.7-67.8 0-80.4 61.2-137.4 140.4-137.4 68.1 0 118.5 38.7 118.5 109.8 0 53.1-21.3 152.7-90.3 152.7-24.9 0-46.2-18-46.2-43.8 0-37.8 26.4-74.4 26.4-113.4 0-66.2-93.9-54.2-93.9 25.8 0 16.8 2.1 35.4 9.6 50.7-13.8 59.4-42 147.9-42 209.1 0 18.9 2.7 37.5 4.5 56.4 3.4 3.8 1.7 3.4 6.9 1.5 50.4-69 48.6-82.5 71.4-172.8 12.3 23.4 44.1 36 69.3 36 106.2 0 153.9-103.5 153.9-196.8C384 71.3 298.2 6.5 204 6.5z"],"pinterest-square":[448,512,[],"f0d3","M448 80v352c0 26.5-21.5 48-48 48H154.4c9.8-16.4 22.4-40 27.4-59.3 3-11.5 15.3-58.4 15.3-58.4 8 15.3 31.4 28.2 56.3 28.2 74.1 0 127.4-68.1 127.4-152.7 0-81.1-66.2-141.8-151.4-141.8-106 0-162.2 71.1-162.2 148.6 0 36 19.2 80.8 49.8 95.1 4.7 2.2 7.1 1.2 8.2-3.3.8-3.4 5-20.1 6.8-27.8.6-2.5.3-4.6-1.7-7-10.1-12.3-18.3-34.9-18.3-56 0-54.2 41-106.6 110.9-106.6 60.3 0 102.6 41.1 102.6 99.9 0 66.4-33.5 112.4-77.2 112.4-24.1 0-42.1-19.9-36.4-44.4 6.9-29.2 20.3-60.7 20.3-81.8 0-53-75.5-45.7-75.5 25 0 21.7 7.3 36.5 7.3 36.5-31.4 132.8-36.1 134.5-29.6 192.6l2.2.8H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48z"],playstation:[576,512,[],"f3df","M570.9 372.3c-11.3 14.2-38.8 24.3-38.8 24.3L327 470.2v-54.3l150.9-53.8c17.1-6.1 19.8-14.8 5.8-19.4-13.9-4.6-39.1-3.3-56.2 2.9L327 381.1v-56.4c23.2-7.8 47.1-13.6 75.7-16.8 40.9-4.5 90.9.6 130.2 15.5 44.2 14 49.2 34.7 38 48.9zm-224.4-92.5v-139c0-16.3-3-31.3-18.3-35.6-11.7-3.8-19 7.1-19 23.4v347.9l-93.8-29.8V32c39.9 7.4 98 24.9 129.2 35.4C424.1 94.7 451 128.7 451 205.2c0 74.5-46 102.8-104.5 74.6zM43.2 410.2c-45.4-12.8-53-39.5-32.3-54.8 19.1-14.2 51.7-24.9 51.7-24.9l134.5-47.8v54.5l-96.8 34.6c-17.1 6.1-19.7 14.8-5.8 19.4 13.9 4.6 39.1 3.3 56.2-2.9l46.4-16.9v48.8c-51.6 9.3-101.4 7.3-153.9-10z"],"product-hunt":[512,512,[],"f288","M326.3 218.8c0 20.5-16.7 37.2-37.2 37.2h-70.3v-74.4h70.3c20.5 0 37.2 16.7 37.2 37.2zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-128.1-37.2c0-47.9-38.9-86.8-86.8-86.8H169.2v248h49.6v-74.4h70.3c47.9 0 86.8-38.9 86.8-86.8z"],pushed:[432,512,[],"f3e1","M407 111.9l-98.5-9 14-33.4c10.4-23.5-10.8-40.4-28.7-37L22.5 76.9c-15.1 2.7-26 18.3-21.4 36.6l105.1 348.3c6.5 21.3 36.7 24.2 47.7 7l35.3-80.8 235.2-231.3c16.4-16.8 4.3-42.9-17.4-44.8zM297.6 53.6c5.1-.7 7.5 2.5 5.2 7.4L286 100.9 108.6 84.6l189-31zM22.7 107.9c-3.1-5.1 1-10 6.1-9.1l248.7 22.7-96.9 230.7L22.7 107.9zM136 456.4c-2.6 4-7.9 3.1-9.4-1.2L43.5 179.7l127.7 197.6c-7 15-35.2 79.1-35.2 79.1zm272.8-314.5L210.1 337.3l89.7-213.7 106.4 9.7c4 1.1 5.7 5.3 2.6 8.6z"],python:[448,512,[],"f3e2","M167.8 36.4c-45.2 8-53.4 24.7-53.4 55.6v40.7h106.9v13.6h-147c-31.1 0-58.3 18.7-66.8 54.2-9.8 40.7-10.2 66.1 0 108.6 7.6 31.6 25.7 54.2 56.8 54.2H101v-48.8c0-35.3 30.5-66.4 66.8-66.4h106.8c29.7 0 53.4-24.5 53.4-54.3V91.9c0-29-24.4-50.7-53.4-55.6-35.8-5.9-74.7-5.6-106.8.1zm-6.7 28.4c11 0 20.1 9.2 20.1 20.4s-9 20.3-20.1 20.3c-11.1 0-20.1-9.1-20.1-20.3.1-11.3 9-20.4 20.1-20.4zm185.2 81.4v47.5c0 36.8-31.2 67.8-66.8 67.8H172.7c-29.2 0-53.4 25-53.4 54.3v101.8c0 29 25.2 46 53.4 54.3 33.8 9.9 66.3 11.7 106.8 0 26.9-7.8 53.4-23.5 53.4-54.3v-40.7H226.2v-13.6h160.2c31.1 0 42.6-21.7 53.4-54.2 11.2-33.5 10.7-65.7 0-108.6-7.7-30.9-22.3-54.2-53.4-54.2h-40.1zM286.2 404c11.1 0 20.1 9.1 20.1 20.3 0 11.3-9 20.4-20.1 20.4-11 0-20.1-9.2-20.1-20.4.1-11.3 9.1-20.3 20.1-20.3z"],qq:[448,512,[],"f1d6","M433.754 420.445c-11.526 1.393-44.86-52.741-44.86-52.741 0 31.345-16.136 72.247-51.051 101.786 16.842 5.192 54.843 19.167 45.803 34.421-7.316 12.343-125.51 7.881-159.632 4.037-34.122 3.844-152.316 8.306-159.632-4.037-9.045-15.25 28.918-29.214 45.783-34.415-34.92-29.539-51.059-70.445-51.059-101.792 0 0-33.334 54.134-44.859 52.741-5.37-.65-12.424-29.644 9.347-99.704 10.261-33.024 21.995-60.478 40.144-105.779C60.683 98.063 108.982.006 224 0c113.737.006 163.156 96.133 160.264 214.963 18.118 45.223 29.912 72.85 40.144 105.778 21.768 70.06 14.716 99.053 9.346 99.704z"],quinscape:[489,512,[],"f459","M301.9 474.6h-1.3c-87.3 0-158.1-70.8-158.1-158.1s70.8-158.1 158.1-158.1c94.9 0 168.2 83.1 157 176.6 4 5.1 8.2 9.6 11.2 15.3 13.4-30.3 20.3-62.4 20.3-97.7C489.1 117.5 379.6 8 244.5 8 109.5 8 0 117.5 0 252.6s109.5 244.6 244.5 244.6c24.8 0 47.8-3.2 70.4-10.1-5.2-3.5-9-8.2-13.4-12.6l.4.1zm-21.2-69.8c0-54.8 44.4-99.2 99.2-99.2 54.8 0 99.2 44.4 99.2 99.2 0 54.8-44.4 99.2-99.2 99.2-54.8 0-99.2-44.4-99.2-99.2"],quora:[448,512,[],"f2c4","M440.5 386.7h-29.3c-1.5 13.5-10.5 30.8-33 30.8-20.5 0-35.3-14.2-49.5-35.8 44.2-34.2 74.7-87.5 74.7-153C403.5 111.2 306.8 32 205 32 105.3 32 7.3 111.7 7.3 228.7c0 134.1 131.3 221.6 249 189C276 451.3 302 480 351.5 480c81.8 0 90.8-75.3 89-93.3zM297 329.2C277.5 300 253.3 277 205.5 277c-30.5 0-54.3 10-69 22.8l12.2 24.3c6.2-3 13-4 19.8-4 35.5 0 53.7 30.8 69.2 61.3-10 3-20.7 4.2-32.7 4.2-75 0-107.5-53-107.5-156.7C97.5 124.5 130 71 205 71c76.2 0 108.7 53.5 108.7 157.7.1 41.8-5.4 75.6-16.7 100.5z"],ravelry:[512,512,[],"f2d9","M407.4 61.5C331.6 22.1 257.8 31 182.9 66c-11.3 5.2-15.5 10.6-19.9 19-10.3 19.2-16.2 37.4-19.9 52.7-21.2 25.6-36.4 56.1-43.3 89.9-10.6 18-20.9 41.4-23.1 71.4 0 0-.7 7.6-.5 7.9-35.3-4.6-76.2-27-76.2-27 9.1 14.5 61.3 32.3 76.3 37.9 0 0 1.7 98 64.5 131.2-11.3-17.2-13.3-20.2-13.3-20.2S94.8 369 100.4 324.7c.7 0 1.5.2 2.2.2 23.9 87.4 103.2 151.4 196.9 151.4 6.2 0 12.1-.2 18-.7 14 1.5 27.6.5 40.1-3.9 6.9-2.2 13.8-6.4 20.2-10.8 70.2-39.1 100.9-82 123.1-147.7 5.4-16 8.1-35.5 9.8-52.2 8.7-82.3-30.6-161.6-103.3-199.5zM138.8 163.2s-1.2 12.3-.7 19.7c-3.4 2.5-10.1 8.1-18.2 16.7 5.2-12.8 11.3-25.1 18.9-36.4zm-31.2 121.9c4.4-17.2 13.3-39.1 29.8-55.1 0 0 1.7 48 15.8 90.1l-41.4-6.9c-2.2-9.2-3.5-18.5-4.2-28.1zm7.9 42.8c14.8 3.2 34 7.6 43.1 9.1 27.3 76.8 108.3 124.3 108.3 124.3 1 .5 1.7.7 2.7 1-73.1-11.6-132.7-64.7-154.1-134.4zM386 444.1c-14.5 4.7-36.2 8.4-64.7 3.7 0 0-91.1-23.1-127.5-107.8 38.2.7 52.4-.2 78-3.9 39.4-5.7 79-16.2 115-33 11.8-5.4 11.1-19.4 9.6-29.8-2-12.8-11.1-12.1-21.4-4.7 0 0-82 58.6-189.8 53.7-18.7-32-26.8-110.8-26.8-110.8 41.4-35.2 83.2-59.6 168.4-52.4.2-6.4 3-27.1-20.4-28.1 0 0-93.5-11.1-146 33.5 2.5-16.5 5.9-29.3 11.1-39.4 34.2-30.8 79-49.5 128.3-49.5 106.4 0 193 87.1 193 194.5-.2 76-43.8 142-106.8 174z"],react:[512,512,[],"f41b","M418.2 177.2c-5.4-1.8-10.8-3.5-16.2-5.1.9-3.7 1.7-7.4 2.5-11.1 12.3-59.6 4.2-107.5-23.1-123.3-26.3-15.1-69.2.6-112.6 38.4-4.3 3.7-8.5 7.6-12.5 11.5-2.7-2.6-5.5-5.2-8.3-7.7-45.5-40.4-91.1-57.4-118.4-41.5-26.2 15.2-34 60.3-23 116.7 1.1 5.6 2.3 11.1 3.7 16.7-6.4 1.8-12.7 3.8-18.6 5.9C38.3 196.2 0 225.4 0 255.6c0 31.2 40.8 62.5 96.3 81.5 4.5 1.5 9 3 13.6 4.3-1.5 6-2.8 11.9-4 18-10.5 55.5-2.3 99.5 23.9 114.6 27 15.6 72.4-.4 116.6-39.1 3.5-3.1 7-6.3 10.5-9.7 4.4 4.3 9 8.4 13.6 12.4 42.8 36.8 85.1 51.7 111.2 36.6 27-15.6 35.8-62.9 24.4-120.5-.9-4.4-1.9-8.9-3-13.5 3.2-.9 6.3-1.9 9.4-2.9 57.7-19.1 99.5-50 99.5-81.7 0-30.3-39.4-59.7-93.8-78.4zM282.9 92.3c37.2-32.4 71.9-45.1 87.7-36 16.9 9.7 23.4 48.9 12.8 100.4-.7 3.4-1.4 6.7-2.3 10-22.2-5-44.7-8.6-67.3-10.6-13-18.6-27.2-36.4-42.6-53.1 3.9-3.7 7.7-7.2 11.7-10.7zm-130 189.1c4.6 8.8 9.3 17.5 14.3 26.1 5.1 8.7 10.3 17.4 15.8 25.9-15.6-1.7-31.1-4.2-46.4-7.5 4.4-14.4 9.9-29.3 16.3-44.5zm0-50.6c-6.3-14.9-11.6-29.5-16-43.6 14.4-3.2 29.7-5.8 45.6-7.8-5.3 8.3-10.5 16.8-15.4 25.4-4.9 8.5-9.7 17.2-14.2 26zm11.4 25.3c6.6-13.8 13.8-27.3 21.4-40.6 7.6-13.3 15.8-26.2 24.4-38.9 15-1.1 30.3-1.7 45.9-1.7 15.6 0 31 .6 45.9 1.7 8.5 12.6 16.6 25.5 24.3 38.7 7.7 13.2 14.9 26.7 21.7 40.4-6.7 13.8-13.9 27.4-21.6 40.8-7.6 13.3-15.7 26.2-24.2 39-14.9 1.1-30.4 1.6-46.1 1.6-15.7 0-30.9-.5-45.6-1.4-8.7-12.7-16.9-25.7-24.6-39-7.7-13.3-14.8-26.8-21.5-40.6zm180.6 51.2c5.1-8.8 9.9-17.7 14.6-26.7 6.4 14.5 12 29.2 16.9 44.3-15.5 3.5-31.2 6.2-47 8 5.4-8.4 10.5-17 15.5-25.6zm14.4-76.5c-4.7-8.8-9.5-17.6-14.5-26.2-4.9-8.5-10-16.9-15.3-25.2 16.1 2 31.5 4.7 45.9 8-4.6 14.8-10 29.2-16.1 43.4zM256.2 118.3c10.5 11.4 20.4 23.4 29.6 35.8-19.8-.9-39.7-.9-59.5 0 9.8-12.9 19.9-24.9 29.9-35.8zM140.2 57c16.8-9.8 54.1 4.2 93.4 39 2.5 2.2 5 4.6 7.6 7-15.5 16.7-29.8 34.5-42.9 53.1-22.6 2-45 5.5-67.2 10.4-1.3-5.1-2.4-10.3-3.5-15.5-9.4-48.4-3.2-84.9 12.6-94zm-24.5 263.6c-4.2-1.2-8.3-2.5-12.4-3.9-21.3-6.7-45.5-17.3-63-31.2-10.1-7-16.9-17.8-18.8-29.9 0-18.3 31.6-41.7 77.2-57.6 5.7-2 11.5-3.8 17.3-5.5 6.8 21.7 15 43 24.5 63.6-9.6 20.9-17.9 42.5-24.8 64.5zm116.6 98c-16.5 15.1-35.6 27.1-56.4 35.3-11.1 5.3-23.9 5.8-35.3 1.3-15.9-9.2-22.5-44.5-13.5-92 1.1-5.6 2.3-11.2 3.7-16.7 22.4 4.8 45 8.1 67.9 9.8 13.2 18.7 27.7 36.6 43.2 53.4-3.2 3.1-6.4 6.1-9.6 8.9zm24.5-24.3c-10.2-11-20.4-23.2-30.3-36.3 9.6.4 19.5.6 29.5.6 10.3 0 20.4-.2 30.4-.7-9.2 12.7-19.1 24.8-29.6 36.4zm130.7 30c-.9 12.2-6.9 23.6-16.5 31.3-15.9 9.2-49.8-2.8-86.4-34.2-4.2-3.6-8.4-7.5-12.7-11.5 15.3-16.9 29.4-34.8 42.2-53.6 22.9-1.9 45.7-5.4 68.2-10.5 1 4.1 1.9 8.2 2.7 12.2 4.9 21.6 5.7 44.1 2.5 66.3zm18.2-107.5c-2.8.9-5.6 1.8-8.5 2.6-7-21.8-15.6-43.1-25.5-63.8 9.6-20.4 17.7-41.4 24.5-62.9 5.2 1.5 10.2 3.1 15 4.7 46.6 16 79.3 39.8 79.3 58 0 19.6-34.9 44.9-84.8 61.4zM256 210.2c25.3 0 45.8 20.5 45.8 45.8 0 25.3-20.5 45.8-45.8 45.8-25.3 0-45.8-20.5-45.8-45.8 0-25.3 20.5-45.8 45.8-45.8"],readme:[576,512,[],"f4d5","M528.3 46.5H388.5c-48.1 0-89.9 33.3-100.4 80.3-10.6-47-52.3-80.3-100.4-80.3H48c-26.5 0-48 21.5-48 48v245.8c0 26.5 21.5 48 48 48h89.7c102.2 0 132.7 24.4 147.3 75 .7 2.8 5.2 2.8 6 0 14.7-50.6 45.2-75 147.3-75H528c26.5 0 48-21.5 48-48V94.6c0-26.4-21.3-47.9-47.7-48.1zM242 311.9c0 1.9-1.5 3.5-3.5 3.5H78.2c-1.9 0-3.5-1.5-3.5-3.5V289c0-1.9 1.5-3.5 3.5-3.5h160.4c1.9 0 3.5 1.5 3.5 3.5v22.9zm0-60.9c0 1.9-1.5 3.5-3.5 3.5H78.2c-1.9 0-3.5-1.5-3.5-3.5v-22.9c0-1.9 1.5-3.5 3.5-3.5h160.4c1.9 0 3.5 1.5 3.5 3.5V251zm0-60.9c0 1.9-1.5 3.5-3.5 3.5H78.2c-1.9 0-3.5-1.5-3.5-3.5v-22.9c0-1.9 1.5-3.5 3.5-3.5h160.4c1.9 0 3.5 1.5 3.5 3.5v22.9zm259.3 121.7c0 1.9-1.5 3.5-3.5 3.5H337.5c-1.9 0-3.5-1.5-3.5-3.5v-22.9c0-1.9 1.5-3.5 3.5-3.5h160.4c1.9 0 3.5 1.5 3.5 3.5v22.9zm0-60.9c0 1.9-1.5 3.5-3.5 3.5H337.5c-1.9 0-3.5-1.5-3.5-3.5V228c0-1.9 1.5-3.5 3.5-3.5h160.4c1.9 0 3.5 1.5 3.5 3.5v22.9zm0-60.9c0 1.9-1.5 3.5-3.5 3.5H337.5c-1.9 0-3.5-1.5-3.5-3.5v-22.8c0-1.9 1.5-3.5 3.5-3.5h160.4c1.9 0 3.5 1.5 3.5 3.5V190z"],rebel:[512,512,[],"f1d0","M256.5 504C117.2 504 9 387.8 13.2 249.9 16 170.7 56.4 97.7 129.7 49.5c.3 0 1.9-.6 1.1.8-5.8 5.5-111.3 129.8-14.1 226.4 49.8 49.5 90 2.5 90 2.5 38.5-50.1-.6-125.9-.6-125.9-10-24.9-45.7-40.1-45.7-40.1l28.8-31.8c24.4 10.5 43.2 38.7 43.2 38.7.8-29.6-21.9-61.4-21.9-61.4L255.1 8l44.3 50.1c-20.5 28.8-21.9 62.6-21.9 62.6 13.8-23 43.5-39.3 43.5-39.3l28.5 31.8c-27.4 8.9-45.4 39.9-45.4 39.9-15.8 28.5-27.1 89.4.6 127.3 32.4 44.6 87.7-2.8 87.7-2.8 102.7-91.9-10.5-225-10.5-225-6.1-5.5.8-2.8.8-2.8 50.1 36.5 114.6 84.4 116.2 204.8C500.9 400.2 399 504 256.5 504z"],"red-river":[448,512,[],"f3e3","M353.2 32H94.8C42.4 32 0 74.4 0 126.8v258.4C0 437.6 42.4 480 94.8 480h258.4c52.4 0 94.8-42.4 94.8-94.8V126.8c0-52.4-42.4-94.8-94.8-94.8zM144.9 200.9v56.3c0 27-21.9 48.9-48.9 48.9V151.9c0-13.2 10.7-23.9 23.9-23.9h154.2c0 27-21.9 48.9-48.9 48.9h-56.3c-12.3-.6-24.6 11.6-24 24zm176.3 72h-56.3c-12.3-.6-24.6 11.6-24 24v56.3c0 27-21.9 48.9-48.9 48.9V247.9c0-13.2 10.7-23.9 23.9-23.9h154.2c0 27-21.9 48.9-48.9 48.9z"],reddit:[512,512,[],"f1a1","M201.5 305.5c-13.8 0-24.9-11.1-24.9-24.6 0-13.8 11.1-24.9 24.9-24.9 13.6 0 24.6 11.1 24.6 24.9 0 13.6-11.1 24.6-24.6 24.6zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-132.3-41.2c-9.4 0-17.7 3.9-23.8 10-22.4-15.5-52.6-25.5-86.1-26.6l17.4-78.3 55.4 12.5c0 13.6 11.1 24.6 24.6 24.6 13.8 0 24.9-11.3 24.9-24.9s-11.1-24.9-24.9-24.9c-9.7 0-18 5.8-22.1 13.8l-61.2-13.6c-3-.8-6.1 1.4-6.9 4.4l-19.1 86.4c-33.2 1.4-63.1 11.3-85.5 26.8-6.1-6.4-14.7-10.2-24.1-10.2-34.9 0-46.3 46.9-14.4 62.8-1.1 5-1.7 10.2-1.7 15.5 0 52.6 59.2 95.2 132 95.2 73.1 0 132.3-42.6 132.3-95.2 0-5.3-.6-10.8-1.9-15.8 31.3-16 19.8-62.5-14.9-62.5zM302.8 331c-18.2 18.2-76.1 17.9-93.6 0-2.2-2.2-6.1-2.2-8.3 0-2.5 2.5-2.5 6.4 0 8.6 22.8 22.8 87.3 22.8 110.2 0 2.5-2.2 2.5-6.1 0-8.6-2.2-2.2-6.1-2.2-8.3 0zm7.7-75c-13.6 0-24.6 11.1-24.6 24.9 0 13.6 11.1 24.6 24.6 24.6 13.8 0 24.9-11.1 24.9-24.6 0-13.8-11-24.9-24.9-24.9z"],"reddit-alien":[512,512,[],"f281","M440.3 203.5c-15 0-28.2 6.2-37.9 15.9-35.7-24.7-83.8-40.6-137.1-42.3L293 52.3l88.2 19.8c0 21.6 17.6 39.2 39.2 39.2 22 0 39.7-18.1 39.7-39.7s-17.6-39.7-39.7-39.7c-15.4 0-28.7 9.3-35.3 22l-97.4-21.6c-4.9-1.3-9.7 2.2-11 7.1L246.3 177c-52.9 2.2-100.5 18.1-136.3 42.8-9.7-10.1-23.4-16.3-38.4-16.3-55.6 0-73.8 74.6-22.9 100.1-1.8 7.9-2.6 16.3-2.6 24.7 0 83.8 94.4 151.7 210.3 151.7 116.4 0 210.8-67.9 210.8-151.7 0-8.4-.9-17.2-3.1-25.1 49.9-25.6 31.5-99.7-23.8-99.7zM129.4 308.9c0-22 17.6-39.7 39.7-39.7 21.6 0 39.2 17.6 39.2 39.7 0 21.6-17.6 39.2-39.2 39.2-22 .1-39.7-17.6-39.7-39.2zm214.3 93.5c-36.4 36.4-139.1 36.4-175.5 0-4-3.5-4-9.7 0-13.7 3.5-3.5 9.7-3.5 13.2 0 27.8 28.5 120 29 149 0 3.5-3.5 9.7-3.5 13.2 0 4.1 4 4.1 10.2.1 13.7zm-.8-54.2c-21.6 0-39.2-17.6-39.2-39.2 0-22 17.6-39.7 39.2-39.7 22 0 39.7 17.6 39.7 39.7-.1 21.5-17.7 39.2-39.7 39.2z"],"reddit-square":[448,512,[],"f1a2","M283.2 345.5c2.7 2.7 2.7 6.8 0 9.2-24.5 24.5-93.8 24.6-118.4 0-2.7-2.4-2.7-6.5 0-9.2 2.4-2.4 6.5-2.4 8.9 0 18.7 19.2 81 19.6 100.5 0 2.4-2.3 6.6-2.3 9 0zm-91.3-53.8c0-14.9-11.9-26.8-26.5-26.8-14.9 0-26.8 11.9-26.8 26.8 0 14.6 11.9 26.5 26.8 26.5 14.6 0 26.5-11.9 26.5-26.5zm90.7-26.8c-14.6 0-26.5 11.9-26.5 26.8 0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-11.9 26.8-26.5 0-14.9-11.9-26.8-26.8-26.8zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-99.7 140.6c-10.1 0-19 4.2-25.6 10.7-24.1-16.7-56.5-27.4-92.5-28.6l18.7-84.2 59.5 13.4c0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-12.2 26.8-26.8 0-14.6-11.9-26.8-26.8-26.8-10.4 0-19.3 6.2-23.8 14.9l-65.7-14.6c-3.3-.9-6.5 1.5-7.4 4.8l-20.5 92.8c-35.7 1.5-67.8 12.2-91.9 28.9-6.5-6.8-15.8-11-25.9-11-37.5 0-49.8 50.4-15.5 67.5-1.2 5.4-1.8 11-1.8 16.7 0 56.5 63.7 102.3 141.9 102.3 78.5 0 142.2-45.8 142.2-102.3 0-5.7-.6-11.6-2.1-17 33.6-17.2 21.2-67.2-16.1-67.2z"],rendact:[496,512,[],"f3e4","M248 8C111 8 0 119 0 256s111 248 248 248c18.6 0 36.7-2.1 54.1-5.9-5.6-7.4-10.8-14.4-15.9-21.3-12.4 2.1-25.2 3.3-38.3 3.3C124.3 480 24 379.7 24 256S124.3 32 248 32s224 100.3 224 224c0 71-33 134.2-84.5 175.3-25.9 18.8-39.1 21.4-83.5-44.2-78.7-112.9-48-71.1-73.7-108.3 72.8 8.9 228.5-72 168.6-168.6C314-26.8 15 93.8 59.7 226.4c3.2 9.8 14.4 38.6 45.6 38.6 2 0 2.6-.6 2-1.7-4.4-8.7-20.1-9.8-20.1-37.4 0-40.5 40.5-89.6 100.3-120 66.1-32.3 131.9-30.2 158.2 5.4 27.2 38.3-20.9 119.2-120.4 136.9 7.5-9.4 57-75.2 62.8-84 22.7-34.6 23.6-49 14-59.2-15.5-16.9-29.5-10.3-50.7-11.7-10.8-.9-113.7 181.2-136.4 216.9-5.9 9-21.2 34.1-21.2 50.9 0 21.3 2.8 51.4 20.6 51.4 10.6 0 8-18.7 8-26.6 0-12.9 27.4-49.4 74.8-104.6 20.4 36.1 57.7 114.3 130.2 209.7 98-33.1 168.5-125.8 168.5-235C496 119 385 8 248 8z"],renren:[512,512,[],"f18b","M214 169.1c0 110.4-61 205.4-147.6 247.4C30 373.2 8 317.7 8 256.6 8 133.9 97.1 32.2 214 12.5v156.6zM255 504c-42.9 0-83.3-11-118.5-30.4C193.7 437.5 239.9 382.9 255 319c15.5 63.9 61.7 118.5 118.8 154.7C338.7 493 298.3 504 255 504zm190.6-87.5C359 374.5 298 279.6 298 169.1V12.5c116.9 19.7 206 121.4 206 244.1 0 61.1-22 116.6-58.4 159.9z"],replyd:[448,512,[],"f3e6","M320 480H128C57.6 480 0 422.4 0 352V160C0 89.6 57.6 32 128 32h192c70.4 0 128 57.6 128 128v192c0 70.4-57.6 128-128 128zM193.4 273.2c-6.1-2-11.6-3.1-16.4-3.1-7.2 0-13.5 1.9-18.9 5.6-5.4 3.7-9.6 9-12.8 15.8h-1.1l-4.2-18.3h-28v138.9h36.1v-89.7c1.5-5.4 4.4-9.8 8.7-13.2 4.3-3.4 9.8-5.1 16.2-5.1 4.6 0 9.8 1 15.6 3.1l4.8-34zm115.2 103.4c-3.2 2.4-7.7 4.8-13.7 7.1-6 2.3-12.8 3.5-20.4 3.5-12.2 0-21.1-3-26.5-8.9-5.5-5.9-8.5-14.7-9-26.4h83.3c.9-4.8 1.6-9.4 2.1-13.9.5-4.4.7-8.6.7-12.5 0-10.7-1.6-19.7-4.7-26.9-3.2-7.2-7.3-13-12.5-17.2-5.2-4.3-11.1-7.3-17.8-9.2-6.7-1.8-13.5-2.8-20.6-2.8-21.1 0-37.5 6.1-49.2 18.3s-17.5 30.5-17.5 55c0 22.8 5.2 40.7 15.6 53.7 10.4 13.1 26.8 19.6 49.2 19.6 10.7 0 20.9-1.5 30.4-4.6 9.5-3.1 17.1-6.8 22.6-11.2l-12-23.6zm-21.8-70.3c3.8 5.4 5.3 13.1 4.6 23.1h-51.7c.9-9.4 3.7-17 8.2-22.6 4.5-5.6 11.5-8.5 21-8.5 8.2-.1 14.1 2.6 17.9 8zm79.9 2.5c4.1 3.9 9.4 5.8 16.1 5.8 7 0 12.6-1.9 16.7-5.8s6.1-9.1 6.1-15.6-2-11.6-6.1-15.4c-4.1-3.8-9.6-5.7-16.7-5.7-6.7 0-12 1.9-16.1 5.7-4.1 3.8-6.1 8.9-6.1 15.4s2 11.7 6.1 15.6zm0 100.5c4.1 3.9 9.4 5.8 16.1 5.8 7 0 12.6-1.9 16.7-5.8s6.1-9.1 6.1-15.6-2-11.6-6.1-15.4c-4.1-3.8-9.6-5.7-16.7-5.7-6.7 0-12 1.9-16.1 5.7-4.1 3.8-6.1 8.9-6.1 15.4 0 6.6 2 11.7 6.1 15.6z"],resolving:[496,512,[],"f3e7","M281.2 278.2c46-13.3 49.6-23.5 44-43.4L314 195.5c-6.1-20.9-18.4-28.1-71.1-12.8L54.7 236.8l28.6 98.6 197.9-57.2zM248.5 8C131.4 8 33.2 88.7 7.2 197.5l221.9-63.9c34.8-10.2 54.2-11.7 79.3-8.2 36.3 6.1 52.7 25 61.4 55.2l10.7 37.8c8.2 28.1 1 50.6-23.5 73.6-19.4 17.4-31.2 24.5-61.4 33.2L203 351.8l220.4 27.1 9.7 34.2-48.1 13.3-286.8-37.3 23 80.2c36.8 22 80.3 34.7 126.3 34.7 137 0 248.5-111.4 248.5-248.3C497 119.4 385.5 8 248.5 8zM38.3 388.6L0 256.8c0 48.5 14.3 93.4 38.3 131.8z"],rocketchat:[448,512,[],"f3e8","M448 256.2c0-87.2-99.6-153.3-219.8-153.3-18.8 0-37.3 1.6-55.3 4.8-11.1-10.5-24.2-20-38-27.4C61.2 44.2 0 79.4 0 79.4s56.9 47.1 47.6 88.3c-52.3 52.3-52.5 124.1 0 176.6C56.9 385.6 0 432.6 0 432.6s61.2 35.2 134.9-.8c13.8-7.5 26.9-16.9 38-27.4 18 3.2 36.5 4.8 55.3 4.8 120.3-.1 219.8-65.8 219.8-153zm-219.7 124c-23.7 0-46.3-2.8-67.3-7.8-21.3 25.8-68.1 61.7-113.6 50.1 14.8-16 36.7-43.1 32-87.6-27.3-21.4-43.6-48.7-43.6-78.5 0-68.4 86.2-123.9 192.5-123.9S420.8 188 420.8 256.4c0 68.3-86.2 123.8-192.5 123.8zm25.6-123.9c0 14.2-11.5 25.8-25.6 25.8-14.1 0-25.6-11.5-25.6-25.8 0-14.2 11.5-25.8 25.6-25.8 14.1 0 25.6 11.6 25.6 25.8zm88.9 0c0 14.2-11.4 25.8-25.6 25.8-14.1 0-25.6-11.5-25.6-25.8 0-14.2 11.4-25.8 25.6-25.8 14.1 0 25.6 11.6 25.6 25.8zm-177.9 0c0 14.2-11.4 25.8-25.6 25.8-14.1 0-25.6-11.5-25.6-25.8 0-14.2 11.4-25.8 25.6-25.8 14.2 0 25.6 11.6 25.6 25.8z"],rockrms:[496,512,[],"f3e9","M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm157.4 419.5h-90l-112-131.3c-17.9-20.4-3.9-56.1 26.6-56.1h75.3l-84.6-99.3-84.3 98.9h-90L193.5 67.2c14.4-18.4 41.3-17.3 54.5 0l157.7 185.1c19 22.8 2 57.2-27.6 56.1-.6 0-74.2.2-74.2.2l101.5 118.9z"],safari:[512,512,[],"f267","M236.9 256.8c0-9.1 6.6-17.7 16.3-17.7 8.9 0 17.4 6.4 17.4 16.1 0 9.1-6.4 17.7-16.1 17.7-9 0-17.6-6.7-17.6-16.1zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-26.6 0c0-122.3-99.1-221.4-221.4-221.4S34.6 133.7 34.6 256 133.7 477.4 256 477.4 477.4 378.3 477.4 256zm-72.5 96.6c0 3.6 13 10.2 16.3 12.2-27.4 41.5-69.8 71.4-117.9 83.3l-4.4-18.5c-.3-2.5-1.9-2.8-4.2-2.8-1.9 0-3 2.8-2.8 4.2l4.4 18.8c-13.3 2.8-26.8 4.2-40.4 4.2-36.3 0-72-10.2-103-29.1 1.7-2.8 12.2-18 12.2-20.2 0-1.9-1.7-3.6-3.6-3.6-3.9 0-12.2 16.6-14.7 19.9-41.8-27.7-72-70.6-83.6-119.6l19.1-4.2c2.2-.6 2.8-2.2 2.8-4.2 0-1.9-2.8-3-4.4-2.8L62 294.5c-2.5-12.7-3.9-25.5-3.9-38.5 0-37.1 10.5-73.6 30.2-104.9 2.8 1.7 16.1 10.8 18.3 10.8 1.9 0 3.6-1.4 3.6-3.3 0-3.9-14.7-11.3-18-13.6 28.2-41.2 71.1-70.9 119.8-81.9l4.2 18.5c.6 2.2 2.2 2.8 4.2 2.8s3-2.8 2.8-4.4L219 61.7c12.2-2.2 24.6-3.6 37.1-3.6 37.1 0 73.3 10.5 104.9 30.2-1.9 2.8-10.8 15.8-10.8 18 0 1.9 1.4 3.6 3.3 3.6 3.9 0 11.3-14.4 13.3-17.7 41 27.7 70.3 70 81.7 118.2l-15.5 3.3c-2.5.6-2.8 2.2-2.8 4.4 0 1.9 2.8 3 4.2 2.8l15.8-3.6c2.5 12.7 3.9 25.7 3.9 38.7 0 36.3-10 72-28.8 102.7-2.8-1.4-14.4-9.7-16.6-9.7-2.1 0-3.8 1.7-3.8 3.6zm-33.2-242.2c-13 12.2-134.2 123.7-137.6 129.5l-96.6 160.5c12.7-11.9 134.2-124 137.3-129.3l96.9-160.7z"],sass:[640,512,[],"f41e","M551.1 291.9c-22.4.1-41.8 5.5-58 13.5-5.9-11.9-12-22.3-13-30.1-1.2-9.1-2.5-14.5-1.1-25.3s7.7-26.1 7.6-27.2c-.1-1.1-1.4-6.6-14.3-6.7-12.9-.1-24 2.5-25.3 5.9-1.3 3.4-3.8 11.1-5.3 19.1-2.3 11.7-25.8 53.5-39.1 75.3-4.4-8.5-8.1-16-8.9-22-1.2-9.1-2.5-14.5-1.1-25.3s7.7-26.1 7.6-27.2c-.1-1.1-1.4-6.6-14.3-6.7-12.9-.1-24 2.5-25.3 5.9-1.3 3.4-2.7 11.4-5.3 19.1-2.6 7.7-33.9 77.3-42.1 95.4-4.2 9.2-7.8 16.6-10.4 21.6s-.2.3-.4.9c-2.2 4.3-3.5 6.7-3.5 6.7v.1c-1.7 3.2-3.6 6.1-4.5 6.1-.6 0-1.9-8.4.3-19.9 4.7-24.2 15.8-61.8 15.7-63.1-.1-.7 2.1-7.2-7.3-10.7-9.1-3.3-12.4 2.2-13.2 2.2-.8 0-1.4 2-1.4 2s10.1-42.4-19.4-42.4c-18.4 0-44 20.2-56.6 38.5-7.9 4.3-25 13.6-43 23.5-6.9 3.8-14 7.7-20.7 11.4-.5-.5-.9-1-1.4-1.5-35.8-38.2-101.9-65.2-99.1-116.5 1-18.7 7.5-67.8 127.1-127.4 98-48.8 176.4-35.4 189.9-5.6 19.4 42.5-41.9 121.6-143.7 133-38.8 4.3-59.2-10.7-64.3-16.3-5.3-5.9-6.1-6.2-8.1-5.1-3.3 1.8-1.2 7 0 10.1 3 7.9 15.5 21.9 36.8 28.9 18.7 6.1 64.2 9.5 119.2-11.8C367 196.5 415.1 130.2 401 74.7 386.6 18.3 293.1-.2 204.6 31.2 151.9 49.9 94.9 79.3 53.9 117.6 5.2 163.2-2.6 202.9.6 219.5c11.4 58.9 92.6 97.3 125.1 125.7-1.6.9-3.1 1.7-4.5 2.5-16.3 8.1-78.2 40.5-93.7 74.7-17.5 38.8 2.9 66.6 16.3 70.4 41.8 11.6 84.6-9.3 107.6-43.6s20.2-79.1 9.6-99.5c-.1-.3-.3-.5-.4-.8 4.2-2.5 8.5-5 12.8-7.5 8.3-4.9 16.4-9.4 23.5-13.3-4 10.8-6.9 23.8-8.4 42.6-1.8 22 7.3 50.5 19.1 61.7 5.2 4.9 11.5 5 15.4 5 13.8 0 20-11.4 26.9-25 8.5-16.6 16-35.9 16-35.9s-9.4 52.2 16.3 52.2c9.4 0 18.8-12.1 23-18.3v.1s.2-.4.7-1.2c1-1.5 1.5-2.4 1.5-2.4v-.3c3.8-6.5 12.1-21.4 24.6-46 16.2-31.8 31.7-71.5 31.7-71.5s1.4 9.7 6.2 25.8c2.8 9.5 8.7 19.9 13.4 30-3.8 5.2-6.1 8.2-6.1 8.2s0 .1.1.2c-3 4-6.4 8.3-9.9 12.5-12.8 15.2-28 32.6-30 37.6-2.4 5.9-1.8 10.3 2.8 13.7 3.4 2.6 9.4 3 15.7 2.5 11.5-.8 19.6-3.6 23.5-5.4 6.2-2.2 13.4-5.7 20.2-10.6 12.5-9.2 20.1-22.4 19.4-39.8-.4-9.6-3.5-19.2-7.3-28.2 1.1-1.6 2.3-3.3 3.4-5 19.8-28.9 35.1-60.6 35.1-60.6s1.4 9.7 6.2 25.8c2.4 8.1 7.1 17 11.4 25.7-18.6 15.1-30.1 32.6-34.1 44.1-7.4 21.3-1.6 30.9 9.3 33.1 4.9 1 11.9-1.3 17.1-3.5 6.5-2.2 14.3-5.7 21.6-11.1 12.5-9.2 24.6-22.1 23.8-39.6-.3-7.9-2.5-15.8-5.4-23.4 15.7-6.6 36.1-10.2 62.1-7.2 55.7 6.5 66.6 41.3 64.5 55.8-2.1 14.6-13.8 22.6-17.7 25-3.9 2.4-5.1 3.3-4.8 5.1.5 2.6 2.3 2.5 5.6 1.9 4.6-.8 29.2-11.8 30.3-38.7 1.6-34-31.1-71.4-89-71.1zM121.8 436.6c-18.4 20.1-44.2 27.7-55.3 21.3C54.6 451 59.3 421.4 82 400c13.8-13 31.6-25 43.4-32.4 2.7-1.6 6.6-4 11.4-6.9.8-.5 1.2-.7 1.2-.7.9-.6 1.9-1.1 2.9-1.7 8.3 30.4.3 57.2-19.1 78.3zm134.4-91.4c-6.4 15.7-19.9 55.7-28.1 53.6-7-1.8-11.3-32.3-1.4-62.3 5-15.1 15.6-33.1 21.9-40.1 10.1-11.3 21.2-14.9 23.8-10.4 3.5 5.9-12.2 49.4-16.2 59.2zm111 53c-2.7 1.4-5.2 2.3-6.4 1.6-.9-.5 1.1-2.4 1.1-2.4s13.9-14.9 19.4-21.7c3.2-4 6.9-8.7 10.9-13.9 0 .5.1 1 .1 1.6-.1 17.9-17.3 30-25.1 34.8zm85.6-19.5c-2-1.4-1.7-6.1 5-20.7 2.6-5.7 8.6-15.3 19-24.5 1.2 3.8 1.9 7.4 1.9 10.8-.1 22.5-16.2 30.9-25.9 34.4z"],schlix:[448,512,[],"f3ea","M350.5 157.7l-54.2-46.1 73.4-39 78.3 44.2-97.5 40.9zM192 122.1l45.7-28.2 34.7 34.6-55.4 29-25-35.4zm-65.1 6.6l31.9-22.1L176 135l-36.7 22.5-12.4-28.8zm-23.3 88.2l-8.8-34.8 29.6-18.3 13.1 35.3-33.9 17.8zm-21.2-83.7l23.9-18.1 8.9 24-26.7 18.3-6.1-24.2zM59 206.5l-3.6-28.4 22.3-15.5 6.1 28.7L59 206.5zm-30.6 16.6l20.8-12.8 3.3 33.4-22.9 12-1.2-32.6zM1.4 268l19.2-10.2.4 38.2-21 8.8L1.4 268zm59.1 59.3l-28.3 8.3-1.6-46.8 25.1-10.7 4.8 49.2zM99 263.2l-31.1 13-5.2-40.8L90.1 221l8.9 42.2zM123.2 377l-41.6 5.9-8.1-63.5 35.2-10.8 14.5 68.4zm28.5-139.9l21.2 57.1-46.2 13.6-13.7-54.1 38.7-16.6zm85.7 230.5l-70.9-3.3-24.3-95.8 55.2-8.6 40 107.7zm-84.9-279.7l42.2-22.4 28 45.9-50.8 21.3-19.4-44.8zm41 94.9l61.3-18.7 52.8 86.6-79.8 11.3-34.3-79.2zm51.4-85.6l67.3-28.8 65.5 65.4-88.6 26.2-44.2-62.8z"],scribd:[384,512,[],"f28a","M42.3 252.7c-16.1-19-24.7-45.9-24.8-79.9 0-100.4 75.2-153.1 167.2-153.1 98.6-1.6 156.8 49 184.3 70.6l-50.5 72.1-37.3-24.6 26.9-38.6c-36.5-24-79.4-36.5-123-35.8-50.7-.8-111.7 27.2-111.7 76.2 0 18.7 11.2 20.7 28.6 15.6 23.3-5.3 41.9.6 55.8 14 26.4 24.3 23.2 67.6-.7 91.9-29.2 29.5-85.2 27.3-114.8-8.4zm317.7 5.9c-15.5-18.8-38.9-29.4-63.2-28.6-38.1-2-71.1 28-70.5 67.2-.7 16.8 6 33 18.4 44.3 14.1 13.9 33 19.7 56.3 14.4 17.4-5.1 28.6-3.1 28.6 15.6 0 4.3-.5 8.5-1.4 12.7-16.7 40.9-59.5 64.4-121.4 64.4-51.9.2-102.4-16.4-144.1-47.3l33.7-39.4-35.6-27.4L0 406.3l15.4 13.8c52.5 46.8 120.4 72.5 190.7 72.2 51.4 0 94.4-10.5 133.6-44.1 57.1-51.4 54.2-149.2 20.3-189.6z"],searchengin:[460,512,[],"f3eb","M220.6 130.3l-67.2 28.2V43.2L98.7 233.5l54.7-24.2v130.3l67.2-209.3zm-83.2-96.7l-1.3 4.7-15.2 52.9C80.6 106.7 52 145.8 52 191.5c0 52.3 34.3 95.9 83.4 105.5v53.6C57.5 340.1 0 272.4 0 191.6c0-80.5 59.8-147.2 137.4-158zm311.4 447.2c-11.2 11.2-23.1 12.3-28.6 10.5-5.4-1.8-27.1-19.9-60.4-44.4-33.3-24.6-33.6-35.7-43-56.7-9.4-20.9-30.4-42.6-57.5-52.4l-9.7-14.7c-24.7 16.9-53 26.9-81.3 28.7l2.1-6.6 15.9-49.5c46.5-11.9 80.9-54 80.9-104.2 0-54.5-38.4-102.1-96-107.1V32.3C254.4 37.4 320 106.8 320 191.6c0 33.6-11.2 64.7-29 90.4l14.6 9.6c9.8 27.1 31.5 48 52.4 57.4s32.2 9.7 56.8 43c24.6 33.2 42.7 54.9 44.5 60.3s.7 17.3-10.5 28.5zm-9.9-17.9c0-4.4-3.6-8-8-8s-8 3.6-8 8 3.6 8 8 8 8-3.6 8-8z"],sellcast:[448,512,[],"f2da","M353.4 32H94.7C42.6 32 0 74.6 0 126.6v258.7C0 437.4 42.6 480 94.7 480h258.7c52.1 0 94.7-42.6 94.7-94.6V126.6c0-52-42.6-94.6-94.7-94.6zm-50 316.4c-27.9 48.2-89.9 64.9-138.2 37.2-22.9 39.8-54.9 8.6-42.3-13.2l15.7-27.2c5.9-10.3 19.2-13.9 29.5-7.9 18.6 10.8-.1-.1 18.5 10.7 27.6 15.9 63.4 6.3 79.4-21.3 15.9-27.6 6.3-63.4-21.3-79.4-17.8-10.2-.6-.4-18.6-10.6-24.6-14.2-3.4-51.9 21.6-37.5 18.6 10.8-.1-.1 18.5 10.7 48.4 28 65.1 90.3 37.2 138.5zm21.8-208.8c-17 29.5-16.3 28.8-19 31.5-6.5 6.5-16.3 8.7-26.5 3.6-18.6-10.8.1.1-18.5-10.7-27.6-15.9-63.4-6.3-79.4 21.3s-6.3 63.4 21.3 79.4c0 0 18.5 10.6 18.6 10.6 24.6 14.2 3.4 51.9-21.6 37.5-18.6-10.8.1.1-18.5-10.7-48.2-27.8-64.9-90.1-37.1-138.4 27.9-48.2 89.9-64.9 138.2-37.2l4.8-8.4c14.3-24.9 52-3.3 37.7 21.5z"],sellsy:[640,512,[],"f213","M539.71 237.308c3.064-12.257 4.29-24.821 4.29-37.384C544 107.382 468.618 32 376.076 32c-77.22 0-144.634 53.012-163.02 127.781-15.322-13.176-34.934-20.53-55.157-20.53-46.271 0-83.962 37.69-83.962 83.961 0 7.354.92 15.015 3.065 22.369-42.9 20.225-70.785 63.738-70.785 111.234C6.216 424.843 61.68 480 129.401 480h381.198c67.72 0 123.184-55.157 123.184-123.184.001-56.384-38.916-106.025-94.073-119.508zM199.88 401.554c0 8.274-7.048 15.321-15.321 15.321H153.61c-8.274 0-15.321-7.048-15.321-15.321V290.626c0-8.273 7.048-15.321 15.321-15.321h30.949c8.274 0 15.321 7.048 15.321 15.321v110.928zm89.477 0c0 8.274-7.048 15.321-15.322 15.321h-30.949c-8.274 0-15.321-7.048-15.321-15.321V270.096c0-8.274 7.048-15.321 15.321-15.321h30.949c8.274 0 15.322 7.048 15.322 15.321v131.458zm89.477 0c0 8.274-7.047 15.321-15.321 15.321h-30.949c-8.274 0-15.322-7.048-15.322-15.321V238.84c0-8.274 7.048-15.321 15.322-15.321h30.949c8.274 0 15.321 7.048 15.321 15.321v162.714zm87.027 0c0 8.274-7.048 15.321-15.322 15.321h-28.497c-8.274 0-15.321-7.048-15.321-15.321V176.941c0-8.579 7.047-15.628 15.321-15.628h28.497c8.274 0 15.322 7.048 15.322 15.628v224.613z"],servicestack:[496,512,[],"f3ec","M88 216c81.7 10.2 273.7 102.3 304 232H0c99.5-8.1 184.5-137 88-232zm32-152c32.3 35.6 47.7 83.9 46.4 133.6C249.3 231.3 373.7 321.3 400 448h96C455.3 231.9 222.8 79.5 120 64z"],shirtsinbulk:[448,512,[],"f214","M395.208 221.583H406v33.542h-10.792v-33.542zm0-9.625H406v-33.542h-10.792v33.542zm0 86.333H406V264.75h-10.792v33.541zM358.75 135.25h-33.542v10.5h33.542v-10.5zm36.458 206.208H406v-33.542h-10.792v33.542zM311.5 135.25h-33.542v10.5H311.5v-10.5zm-47.25 0H231v10.5h33.25v-10.5zm-47.25 0h-33.25v10.5H217v-10.5zm178.208 33.542H406V135.25h-33.542v10.5h22.75v23.042zm-255.792 259l30.625 13.417 4.375-9.917-30.625-13.417-4.375 9.917zM179.083 445l30.334 13.708 4.374-9.916-30.333-13.417-4.375 9.625zm216.125-60.375H406v-33.542h-10.792v33.542zm-334.833 8.167L91 406.208l4.375-9.624-30.625-13.709-4.375 9.917zm39.666 17.499l30.625 13.417 4.375-9.917-30.625-13.416-4.375 9.916zm132.417 38.501l4.375 9.916L267.459 445l-4.375-9.625-30.626 13.417zm118.417-52.208l4.375 9.624 30.624-13.416-4.374-9.917-30.625 13.709zM311.5 413.791l4.375 9.917 30.625-13.417-4.374-9.916-30.626 13.416zm-39.667 17.501l4.375 9.917 30.625-13.417-4.375-9.917-30.625 13.417zM311.5 46.583h-33.542v10.5H311.5v-10.5zm94.209 0h-33.251v10.5h33.251v-10.5zm-188.709 0h-33.25v10.5H217v-10.5zm141.75 0h-33.542v10.5h33.542v-10.5zm-94.5 0H231v10.5h33.25v-10.5zM448 3.708v406l-226.334 98.584L0 409.708v-406h448zm-29.166 116.958H29.166V390.75l192.792 85.75 196.875-85.75V120.666zm0-87.791H29.166V91.5h389.667V32.875zM75.542 46.583H42.291v10.5h33.251v-10.5zm94.5 0H136.5v10.5h33.542v-10.5zm-47.251 0H89.25v10.5h33.542v-10.5zm7.584 236.542c0-50.167 41.125-91.292 91.292-91.292 50.458 0 91.292 41.125 91.292 91.292 0 50.458-40.833 91.292-91.292 91.292-50.167-.001-91.292-40.834-91.292-91.292zm120.75 18.084c0 13.125-23.917 14.291-32.666 14.291-12.25 0-29.75-2.625-35.875-14.875h-.875L172.666 319c14.876 9.333 29.167 12.25 47.25 12.25 19.542 0 51.042-5.833 51.042-31.209 0-48.125-78.458-16.333-78.458-37.916 0-13.125 20.708-14.875 29.75-14.875 10.791 0 29.166 3.208 35.583 13.124h.875l8.751-16.916c-15.167-6.125-27.417-11.959-44.334-11.959-20.125 0-49.583 6.417-49.583 31.792 0 44.334 77.583 11.959 77.583 37.918zM122.791 135.25H89.25v10.5h33.542v-10.5zm-69.999 10.5h22.75v-10.5H42v33.542h10.792V145.75zm0 32.666H42v33.542h10.792v-33.542zm117.25-43.166H136.5v10.5h33.542v-10.5zm-117.25 86.333H42v33.542h10.792v-33.542zm0 86.334H42v33.542h10.792v-33.542zm0-43.167H42v33.542h10.792V264.75zm0 86.333H42v33.542h10.792v-33.542z"],simplybuilt:[512,512,[],"f215","M481.2 64h-106c-14.5 0-26.6 11.8-26.6 26.3v39.6H163.3V90.3c0-14.5-12-26.3-26.6-26.3h-106C16.1 64 4.3 75.8 4.3 90.3v331.4c0 14.5 11.8 26.3 26.6 26.3h450.4c14.8 0 26.6-11.8 26.6-26.3V90.3c-.2-14.5-12-26.3-26.7-26.3zM149.8 355.8c-36.6 0-66.4-29.7-66.4-66.4 0-36.9 29.7-66.6 66.4-66.6 36.9 0 66.6 29.7 66.6 66.6 0 36.7-29.7 66.4-66.6 66.4zm212.4 0c-36.9 0-66.6-29.7-66.6-66.6 0-36.6 29.7-66.4 66.6-66.4 36.6 0 66.4 29.7 66.4 66.4 0 36.9-29.8 66.6-66.4 66.6z"],sistrix:[448,512,[],"f3ee","M448 449L301.2 300.2c20-27.9 31.9-62.2 31.9-99.2 0-93.1-74.7-168.9-166.5-168.9C74.7 32 0 107.8 0 200.9s74.7 168.9 166.5 168.9c39.8 0 76.3-14.2 105-37.9l146 148.1 30.5-31zM166.5 330.8c-70.6 0-128.1-58.3-128.1-129.9S95.9 71 166.5 71s128.1 58.3 128.1 129.9-57.4 129.9-128.1 129.9z"],skyatlas:[640,512,[],"f216","M640 329.3c0 65.9-52.5 114.4-117.5 114.4-165.9 0-196.6-249.7-359.7-249.7-146.9 0-147.1 212.2 5.6 212.2 42.5 0 90.9-17.8 125.3-42.5 5.6-4.1 16.9-16.3 22.8-16.3s10.9 5 10.9 10.9c0 7.8-13.1 19.1-18.7 24.1-40.9 35.6-100.3 61.2-154.7 61.2-83.4.1-154-59-154-144.9s67.5-149.1 152.8-149.1c185.3 0 222.5 245.9 361.9 245.9 99.9 0 94.8-139.7 3.4-139.7-17.5 0-35 11.6-46.9 11.6-8.4 0-15.9-7.2-15.9-15.6 0-11.6 5.3-23.7 5.3-36.3 0-66.6-50.9-114.7-116.9-114.7-53.1 0-80 36.9-88.8 36.9-6.2 0-11.2-5-11.2-11.2 0-5.6 4.1-10.3 7.8-14.4 25.3-28.8 64.7-43.7 102.8-43.7 79.4 0 139.1 58.4 139.1 137.8 0 6.9-.3 13.7-1.2 20.6 11.9-3.1 24.1-4.7 35.9-4.7 60.7 0 111.9 45.3 111.9 107.2z"],skype:[448,512,[],"f17e","M424.7 299.8c2.9-14 4.7-28.9 4.7-43.8 0-113.5-91.9-205.3-205.3-205.3-14.9 0-29.7 1.7-43.8 4.7C161.3 40.7 137.7 32 112 32 50.2 32 0 82.2 0 144c0 25.7 8.7 49.3 23.3 68.2-2.9 14-4.7 28.9-4.7 43.8 0 113.5 91.9 205.3 205.3 205.3 14.9 0 29.7-1.7 43.8-4.7 19 14.6 42.6 23.3 68.2 23.3 61.8 0 112-50.2 112-112 .1-25.6-8.6-49.2-23.2-68.1zm-194.6 91.5c-65.6 0-120.5-29.2-120.5-65 0-16 9-30.6 29.5-30.6 31.2 0 34.1 44.9 88.1 44.9 25.7 0 42.3-11.4 42.3-26.3 0-18.7-16-21.6-42-28-62.5-15.4-117.8-22-117.8-87.2 0-59.2 58.6-81.1 109.1-81.1 55.1 0 110.8 21.9 110.8 55.4 0 16.9-11.4 31.8-30.3 31.8-28.3 0-29.2-33.5-75-33.5-25.7 0-42 7-42 22.5 0 19.8 20.8 21.8 69.1 33 41.4 9.3 90.7 26.8 90.7 77.6 0 59.1-57.1 86.5-112 86.5z"],slack:[448,512,[],"f198","M244.2 217.5l19.3 57.7-59.8 20-19.3-57.7 59.8-20zm41.4 243.7C131.6 507.4 65 471.6 18.8 317.6S8.4 97 162.4 50.8C316.4 4.6 383 40.4 429.2 194.4c46.2 154 10.4 220.6-143.6 266.8zM366.2 265c-3.9-12.2-17.2-18.6-29.4-14.7l-29 9.7-19.3-57.7 29-9.7c12.2-3.9 18.6-17.2 14.7-29.4-3.9-12.2-17.2-18.6-29.4-14.7l-29 9.7-10-30.1c-3.9-12.2-17.2-18.6-29.4-14.7-12.2 3.9-18.6 17.2-14.7 29.4l10 30.1-59.8 20.1-10-30.1c-3.9-12.2-17.2-18.6-29.4-14.7-12.2 3.9-18.6 17.2-14.7 29.4l10 30.1-29 9.7c-12.2 3.9-18.6 17.2-14.7 29.4 3.2 9.3 12.2 15.4 21.5 15.8 4.3.6 7.7-1 36.9-10.7l19.3 57.7-29 9.7c-12.2 3.9-18.6 17.2-14.7 29.4 3.2 9.3 12.2 15.4 21.5 15.8 4.3.6 7.7-1 36.9-10.7l10 30.1c3.7 10.8 15.8 18.6 29.4 14.7 12.2-3.9 18.6-17.2 14.7-29.4l-10-30.1 59.8-20.1 10 30.1c3.7 10.8 15.8 18.6 29.4 14.7 12.2-3.9 18.6-17.2 14.7-29.4l-10-30.1 29-9.7c12.2-4.2 18.6-17.5 14.7-29.6z"],"slack-hash":[448,512,[],"f3ef","M446.2 270.4c-6.2-19-26.9-29.1-46-22.9l-45.4 15.1-30.3-90 45.4-15.1c19.1-6.2 29.1-26.8 23-45.9-6.2-19-26.9-29.1-46-22.9l-45.4 15.1-15.7-47c-6.2-19-26.9-29.1-46-22.9-19.1 6.2-29.1 26.8-23 45.9l15.7 47-93.4 31.2-15.7-47c-6.2-19-26.9-29.1-46-22.9-19.1 6.2-29.1 26.8-23 45.9l15.7 47-45.3 15c-19.1 6.2-29.1 26.8-23 45.9 5 14.5 19.1 24 33.6 24.6 6.8 1 12-1.6 57.7-16.8l30.3 90L78 354.8c-19 6.2-29.1 26.9-23 45.9 5 14.5 19.1 24 33.6 24.6 6.8 1 12-1.6 57.7-16.8l15.7 47c5.9 16.9 24.7 29 46 22.9 19.1-6.2 29.1-26.8 23-45.9l-15.7-47 93.6-31.3 15.7 47c5.9 16.9 24.7 29 46 22.9 19.1-6.2 29.1-26.8 23-45.9l-15.7-47 45.4-15.1c19-6 29.1-26.7 22.9-45.7zm-254.1 47.2l-30.3-90.2 93.5-31.3 30.3 90.2-93.5 31.3z"],slideshare:[512,512,[],"f1e7","M249.429 211.436c0 31.716-27.715 57.717-61.717 57.717-34.001 0-61.716-26.001-61.716-57.717 0-32.001 27.715-57.716 61.716-57.716 34.001 0 61.717 25.715 61.717 57.716zm254.294 50.002c-18.286 22.573-53.144 50.288-106.289 72.003C453.722 525.163 260 555.735 263.143 457.446c0 1.714-.286-52.859-.286-93.432-4.285-.858-8.571-2-13.714-3.143 0 40.858-.286 98.289-.286 96.575C252 555.735 58.278 525.163 114.566 333.441c-53.145-21.715-88.003-49.43-106.29-72.003-9.143-13.714.858-28.287 16.001-17.715 2 1.428 4.285 2.857 6.285 4.285V49.716C30.563 22.287 51.135 0 76.565 0h359.157c25.429 0 46.002 22.287 46.002 49.716v198.293l6-4.285c15.143-10.573 25.143 4 15.999 17.714zm-46.572-189.15c0-32.858-10.572-45.716-40.859-45.716H98.566c-31.716 0-40.573 10.858-40.573 45.716v192.293c67.717 35.43 125.72 29.144 157.435 28.001 13.429-.286 22.001 2.286 27.144 7.715 1.689 1.687 10.023 9.446 20.287 17.143 1.143-15.715 10.001-25.715 33.716-24.858 32.287 1.428 91.718 7.715 160.577-29.716V72.288zM331.146 153.72c-34.002 0-61.716 25.715-61.716 57.716 0 31.716 27.715 57.717 61.716 57.717 34.287 0 61.716-26.001 61.716-57.717 0-32.001-27.429-57.716-61.716-57.716z"],snapchat:[496,512,[],"f2ab","M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm169.5 338.9c-3.5 8.1-18.1 14-44.8 18.2-1.4 1.9-2.5 9.8-4.3 15.9-1.1 3.7-3.7 5.9-8.1 5.9h-.2c-6.2 0-12.8-2.9-25.8-2.9-17.6 0-23.7 4-37.4 13.7-14.5 10.3-28.4 19.1-49.2 18.2-21 1.6-38.6-11.2-48.5-18.2-13.8-9.7-19.8-13.7-37.4-13.7-12.5 0-20.4 3.1-25.8 3.1-5.4 0-7.5-3.3-8.3-6-1.8-6.1-2.9-14.1-4.3-16-13.8-2.1-44.8-7.5-45.5-21.4-.2-3.6 2.3-6.8 5.9-7.4 46.3-7.6 67.1-55.1 68-57.1 0-.1.1-.2.2-.3 2.5-5 3-9.2 1.6-12.5-3.4-7.9-17.9-10.7-24-13.2-15.8-6.2-18-13.4-17-18.3 1.6-8.5 14.4-13.8 21.9-10.3 5.9 2.8 11.2 4.2 15.7 4.2 3.3 0 5.5-.8 6.6-1.4-1.4-23.9-4.7-58 3.8-77.1C183.1 100 230.7 96 244.7 96c.6 0 6.1-.1 6.7-.1 34.7 0 68 17.8 84.3 54.3 8.5 19.1 5.2 53.1 3.8 77.1 1.1.6 2.9 1.3 5.7 1.4 4.3-.2 9.2-1.6 14.7-4.2 4-1.9 9.6-1.6 13.6 0 6.3 2.3 10.3 6.8 10.4 11.9.1 6.5-5.7 12.1-17.2 16.6-1.4.6-3.1 1.1-4.9 1.7-6.5 2.1-16.4 5.2-19 11.5-1.4 3.3-.8 7.5 1.6 12.5.1.1.1.2.2.3.9 2 21.7 49.5 68 57.1 4 1 7.1 5.5 4.9 10.8z"],"snapchat-ghost":[512,512,[],"f2ac","M510.846 392.673c-5.211 12.157-27.239 21.089-67.36 27.318-2.064 2.786-3.775 14.686-6.507 23.956-1.625 5.566-5.623 8.869-12.128 8.869l-.297-.005c-9.395 0-19.203-4.323-38.852-4.323-26.521 0-35.662 6.043-56.254 20.588-21.832 15.438-42.771 28.764-74.027 27.399-31.646 2.334-58.025-16.908-72.871-27.404-20.714-14.643-29.828-20.582-56.241-20.582-18.864 0-30.736 4.72-38.852 4.72-8.073 0-11.213-4.922-12.422-9.04-2.703-9.189-4.404-21.263-6.523-24.13-20.679-3.209-67.31-11.344-68.498-32.15a10.627 10.627 0 0 1 8.877-11.069c69.583-11.455 100.924-82.901 102.227-85.934.074-.176.155-.344.237-.515 3.713-7.537 4.544-13.849 2.463-18.753-5.05-11.896-26.872-16.164-36.053-19.796-23.715-9.366-27.015-20.128-25.612-27.504 2.437-12.836 21.725-20.735 33.002-15.453 8.919 4.181 16.843 6.297 23.547 6.297 5.022 0 8.212-1.204 9.96-2.171-2.043-35.936-7.101-87.29 5.687-115.969C158.122 21.304 229.705 15.42 250.826 15.42c.944 0 9.141-.089 10.11-.089 52.148 0 102.254 26.78 126.723 81.643 12.777 28.65 7.749 79.792 5.695 116.009 1.582.872 4.357 1.942 8.599 2.139 6.397-.286 13.815-2.389 22.069-6.257 6.085-2.846 14.406-2.461 20.48.058l.029.01c9.476 3.385 15.439 10.215 15.589 17.87.184 9.747-8.522 18.165-25.878 25.018-2.118.835-4.694 1.655-7.434 2.525-9.797 3.106-24.6 7.805-28.616 17.271-2.079 4.904-1.256 11.211 2.46 18.748.087.168.166.342.239.515 1.301 3.03 32.615 74.46 102.23 85.934 6.427 1.058 11.163 7.877 7.725 15.859z"],"snapchat-square":[448,512,[],"f2ad","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-6.5 314.9c-3.5 8.1-18.1 14-44.8 18.2-1.4 1.9-2.5 9.8-4.3 15.9-1.1 3.7-3.7 5.9-8.1 5.9h-.2c-6.2 0-12.8-2.9-25.8-2.9-17.6 0-23.7 4-37.4 13.7-14.5 10.3-28.4 19.1-49.2 18.2-21 1.6-38.6-11.2-48.5-18.2-13.8-9.7-19.8-13.7-37.4-13.7-12.5 0-20.4 3.1-25.8 3.1-5.4 0-7.5-3.3-8.3-6-1.8-6.1-2.9-14.1-4.3-16-13.8-2.1-44.8-7.5-45.5-21.4-.2-3.6 2.3-6.8 5.9-7.4 46.3-7.6 67.1-55.1 68-57.1 0-.1.1-.2.2-.3 2.5-5 3-9.2 1.6-12.5-3.4-7.9-17.9-10.7-24-13.2-15.8-6.2-18-13.4-17-18.3 1.6-8.5 14.4-13.8 21.9-10.3 5.9 2.8 11.2 4.2 15.7 4.2 3.3 0 5.5-.8 6.6-1.4-1.4-23.9-4.7-58 3.8-77.1C159.1 100 206.7 96 220.7 96c.6 0 6.1-.1 6.7-.1 34.7 0 68 17.8 84.3 54.3 8.5 19.1 5.2 53.1 3.8 77.1 1.1.6 2.9 1.3 5.7 1.4 4.3-.2 9.2-1.6 14.7-4.2 4-1.9 9.6-1.6 13.6 0 6.3 2.3 10.3 6.8 10.4 11.9.1 6.5-5.7 12.1-17.2 16.6-1.4.6-3.1 1.1-4.9 1.7-6.5 2.1-16.4 5.2-19 11.5-1.4 3.3-.8 7.5 1.6 12.5.1.1.1.2.2.3.9 2 21.7 49.5 68 57.1 4 1 7.1 5.5 4.9 10.8z"],soundcloud:[640,512,[],"f1be","M111.4 256.3l5.8 65-5.8 68.3c-.3 2.5-2.2 4.4-4.4 4.4s-4.2-1.9-4.2-4.4l-5.6-68.3 5.6-65c0-2.2 1.9-4.2 4.2-4.2 2.2 0 4.1 2 4.4 4.2zm21.4-45.6c-2.8 0-4.7 2.2-5 5l-5 105.6 5 68.3c.3 2.8 2.2 5 5 5 2.5 0 4.7-2.2 4.7-5l5.8-68.3-5.8-105.6c0-2.8-2.2-5-4.7-5zm25.5-24.1c-3.1 0-5.3 2.2-5.6 5.3l-4.4 130 4.4 67.8c.3 3.1 2.5 5.3 5.6 5.3 2.8 0 5.3-2.2 5.3-5.3l5.3-67.8-5.3-130c0-3.1-2.5-5.3-5.3-5.3zM7.2 283.2c-1.4 0-2.2 1.1-2.5 2.5L0 321.3l4.7 35c.3 1.4 1.1 2.5 2.5 2.5s2.2-1.1 2.5-2.5l5.6-35-5.6-35.6c-.3-1.4-1.1-2.5-2.5-2.5zm23.6-21.9c-1.4 0-2.5 1.1-2.5 2.5l-6.4 57.5 6.4 56.1c0 1.7 1.1 2.8 2.5 2.8s2.5-1.1 2.8-2.5l7.2-56.4-7.2-57.5c-.3-1.4-1.4-2.5-2.8-2.5zm25.3-11.4c-1.7 0-3.1 1.4-3.3 3.3L47 321.3l5.8 65.8c.3 1.7 1.7 3.1 3.3 3.1 1.7 0 3.1-1.4 3.1-3.1l6.9-65.8-6.9-68.1c0-1.9-1.4-3.3-3.1-3.3zm25.3-2.2c-1.9 0-3.6 1.4-3.6 3.6l-5.8 70 5.8 67.8c0 2.2 1.7 3.6 3.6 3.6s3.6-1.4 3.9-3.6l6.4-67.8-6.4-70c-.3-2.2-2-3.6-3.9-3.6zm241.4-110.9c-1.1-.8-2.8-1.4-4.2-1.4-2.2 0-4.2.8-5.6 1.9-1.9 1.7-3.1 4.2-3.3 6.7v.8l-3.3 176.7 1.7 32.5 1.7 31.7c.3 4.7 4.2 8.6 8.9 8.6s8.6-3.9 8.6-8.6l3.9-64.2-3.9-177.5c-.4-3-2-5.8-4.5-7.2zm-26.7 15.3c-1.4-.8-2.8-1.4-4.4-1.4s-3.1.6-4.4 1.4c-2.2 1.4-3.6 3.9-3.6 6.7l-.3 1.7-2.8 160.8s0 .3 3.1 65.6v.3c0 1.7.6 3.3 1.7 4.7 1.7 1.9 3.9 3.1 6.4 3.1 2.2 0 4.2-1.1 5.6-2.5 1.7-1.4 2.5-3.3 2.5-5.6l.3-6.7 3.1-58.6-3.3-162.8c-.3-2.8-1.7-5.3-3.9-6.7zm-111.4 22.5c-3.1 0-5.8 2.8-5.8 6.1l-4.4 140.6 4.4 67.2c.3 3.3 2.8 5.8 5.8 5.8 3.3 0 5.8-2.5 6.1-5.8l5-67.2-5-140.6c-.2-3.3-2.7-6.1-6.1-6.1zm376.7 62.8c-10.8 0-21.1 2.2-30.6 6.1-6.4-70.8-65.8-126.4-138.3-126.4-17.8 0-35 3.3-50.3 9.4-6.1 2.2-7.8 4.4-7.8 9.2v249.7c0 5 3.9 8.6 8.6 9.2h218.3c43.3 0 78.6-35 78.6-78.3.1-43.6-35.2-78.9-78.5-78.9zm-296.7-60.3c-4.2 0-7.5 3.3-7.8 7.8l-3.3 136.7 3.3 65.6c.3 4.2 3.6 7.5 7.8 7.5 4.2 0 7.5-3.3 7.5-7.5l3.9-65.6-3.9-136.7c-.3-4.5-3.3-7.8-7.5-7.8zm-53.6-7.8c-3.3 0-6.4 3.1-6.4 6.7l-3.9 145.3 3.9 66.9c.3 3.6 3.1 6.4 6.4 6.4 3.6 0 6.4-2.8 6.7-6.4l4.4-66.9-4.4-145.3c-.3-3.6-3.1-6.7-6.7-6.7zm26.7 3.4c-3.9 0-6.9 3.1-6.9 6.9L227 321.3l3.9 66.4c.3 3.9 3.1 6.9 6.9 6.9s6.9-3.1 6.9-6.9l4.2-66.4-4.2-141.7c0-3.9-3-6.9-6.9-6.9z"],speakap:[448,512,[],"f3f3","M352 32H96C43.2 32 0 75.2 0 128v256c0 52.8 43.2 96 96 96h256c52.8 0 96-43.2 96-96V128c0-52.8-43.2-96-96-96zM221 382.9c-39.6 0-81.9-17.8-81.9-53.7V302H179v17.8c0 15.1 19.5 24.5 41.9 24.5 24.2 0 41.3-10.4 41.3-29.5 0-23.8-27.2-31.9-54.7-42.6-31.9-12.4-63.1-26.2-63.1-69.1 0-48 38.6-66.4 79.9-66.4 37.6 0 75.5 14.1 75.5 41.9v31.2h-39.9v-16.1c0-12.1-17.8-18.5-35.6-18.5-19.5 0-35.6 8.1-35.6 26.2 0 22.1 22.5 29.2 47 38.9 35.9 12.4 71.1 27.2 71.1 71.5.1 48.6-40.8 71.1-85.8 71.1z"],spotify:[496,512,[],"f1bc","M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm100.7 364.9c-4.2 0-6.8-1.3-10.7-3.6-62.4-37.6-135-39.2-206.7-24.5-3.9 1-9 2.6-11.9 2.6-9.7 0-15.8-7.7-15.8-15.8 0-10.3 6.1-15.2 13.6-16.8 81.9-18.1 165.6-16.5 237 26.2 6.1 3.9 9.7 7.4 9.7 16.5s-7.1 15.4-15.2 15.4zm26.9-65.6c-5.2 0-8.7-2.3-12.3-4.2-62.5-37-155.7-51.9-238.6-29.4-4.8 1.3-7.4 2.6-11.9 2.6-10.7 0-19.4-8.7-19.4-19.4s5.2-17.8 15.5-20.7c27.8-7.8 56.2-13.6 97.8-13.6 64.9 0 127.6 16.1 177 45.5 8.1 4.8 11.3 11 11.3 19.7-.1 10.8-8.5 19.5-19.4 19.5zm31-76.2c-5.2 0-8.4-1.3-12.9-3.9-71.2-42.5-198.5-52.7-280.9-29.7-3.6 1-8.1 2.6-12.9 2.6-13.2 0-23.3-10.3-23.3-23.6 0-13.6 8.4-21.3 17.4-23.9 35.2-10.3 74.6-15.2 117.5-15.2 73 0 149.5 15.2 205.4 47.8 7.8 4.5 12.9 10.7 12.9 22.6 0 13.6-11 23.3-23.2 23.3z"],"stack-exchange":[448,512,[],"f18d","M17.7 332.3h412.7v22c0 37.7-29.3 68-65.3 68h-19L259.3 512v-89.7H83c-36 0-65.3-30.3-65.3-68v-22zm0-23.6h412.7v-85H17.7v85zm0-109.4h412.7v-85H17.7v85zM365 0H83C47 0 17.7 30.3 17.7 67.7V90h412.7V67.7C430.3 30.3 401 0 365 0z"],"stack-overflow":[384,512,[],"f16c","M293.7 300l-181.2-84.5 16.7-36.5 181.3 84.7-16.8 36.3zm48-76L188.2 95.7l-25.5 30.8 153.5 128.3 25.5-30.8zm39.6-31.7L262 32l-32 24 119.3 160.3 32-24zM290.7 311L95 269.7 86.8 309l195.7 41 8.2-39zm31.6 129H42.7V320h-40v160h359.5V320h-40v120zm-39.8-80h-200v39.7h200V360z"],staylinked:[440,512,[],"f3f5","M201.6 127.4c4.1-3.2 10.3-3 13.8.5l170 167.3-2.7-2.7 44.3 41.3c3.7 3.5 3.3 9-.7 12.2l-198 163.9c-9.9 7.6-17.3.8-17.3.8L2.3 314.6c-3.5-3.5-3-9 1.2-12.2l45.8-34.9c4.2-3.2 10.4-3 13.9.5l151.9 147.5c3.7 3.5 10 3.7 14.2.4l93.2-74c4.1-3.2 4.5-8.7.9-12.2l-84-81.3c-3.6-3.5-9.9-3.7-14-.5l-.1.1c-4.1 3.2-10.4 3-14-.5l-68.1-64.3c-3.5-3.5-3.1-9 1.1-12.2l57.3-43.6m14.8 257.3c3.7 3.5 10.1 3.7 14.3.4l50.2-38.8-.3-.3 7.7-6c4.2-3.2 4.6-8.7.9-12.2l-57.1-54.4c-3.6-3.5-10-3.7-14.2-.5l-.1.1c-4.2 3.2-10.5 3.1-14.2-.4L109 180.8c-3.6-3.5-3.1-8.9 1.1-12.2l92.2-71.5c4.1-3.2 10.3-3 13.9.5l160.4 159c3.7 3.5 10 3.7 14.1.5l45.8-35.8c4.1-3.2 4.4-8.7.7-12.2L226.7 2.5c-1.5-1.2-8-5.5-16.3 1.1L3.6 165.7c-4.2 3.2-4.8 8.7-1.2 12.2l42.3 41.7"],steam:[496,512,[],"f1b6","M496 256c0 137-111.2 248-248.4 248-113.8 0-209.6-76.3-239-180.4l95.2 39.3c6.4 32.1 34.9 56.4 68.9 56.4 39.2 0 71.9-32.4 70.2-73.5l84.5-60.2c52.1 1.3 95.8-40.9 95.8-93.5 0-51.6-42-93.5-93.7-93.5s-93.7 42-93.7 93.5v1.2L176.6 279c-15.5-.9-30.7 3.4-43.5 12.1L0 236.1C10.2 108.4 117.1 8 247.6 8 384.8 8 496 119 496 256zM155.7 384.3l-30.5-12.6a52.79 52.79 0 0 0 27.2 25.8c26.9 11.2 57.8-1.6 69-28.4 5.4-13 5.5-27.3.1-40.3-5.4-13-15.5-23.2-28.5-28.6-12.9-5.4-26.7-5.2-38.9-.6l31.5 13c19.8 8.2 29.2 30.9 20.9 50.7-8.3 19.9-31 29.2-50.8 21zm173.8-129.9c-34.4 0-62.4-28-62.4-62.3s28-62.3 62.4-62.3 62.4 28 62.4 62.3-27.9 62.3-62.4 62.3zm.1-15.6c25.9 0 46.9-21 46.9-46.8 0-25.9-21-46.8-46.9-46.8s-46.9 21-46.9 46.8c.1 25.8 21.1 46.8 46.9 46.8z"],"steam-square":[448,512,[],"f1b7","M185.2 356.5c7.7-18.5-1-39.7-19.6-47.4l-29.5-12.2c11.4-4.3 24.3-4.5 36.4.5 12.2 5.1 21.6 14.6 26.7 26.7 5 12.2 5 25.6-.1 37.7-10.5 25.1-39.4 37-64.6 26.5-11.6-4.8-20.4-13.6-25.4-24.2l28.5 11.8c18.6 7.8 39.9-.9 47.6-19.4zM400 32H48C21.5 32 0 53.5 0 80v160.7l116.6 48.1c12-8.2 26.2-12.1 40.7-11.3l55.4-80.2v-1.1c0-48.2 39.3-87.5 87.6-87.5s87.6 39.3 87.6 87.5c0 49.2-40.9 88.7-89.6 87.5l-79 56.3c1.6 38.5-29.1 68.8-65.7 68.8-31.8 0-58.5-22.7-64.5-52.7L0 319.2V432c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-99.7 222.5c-32.2 0-58.4-26.1-58.4-58.3s26.2-58.3 58.4-58.3 58.4 26.2 58.4 58.3-26.2 58.3-58.4 58.3zm.1-14.6c24.2 0 43.9-19.6 43.9-43.8 0-24.2-19.6-43.8-43.9-43.8-24.2 0-43.9 19.6-43.9 43.8 0 24.2 19.7 43.8 43.9 43.8z"],"steam-symbol":[448,512,[],"f3f6","M395.5 177.5c0 33.8-27.5 61-61 61-33.8 0-61-27.3-61-61s27.3-61 61-61c33.5 0 61 27.2 61 61zm52.5.2c0 63-51 113.8-113.7 113.8L225 371.3c-4 43-40.5 76.8-84.5 76.8-40.5 0-74.7-28.8-83-67L0 358V250.7L97.2 290c15.1-9.2 32.2-13.3 52-11.5l71-101.7c.5-62.3 51.5-112.8 114-112.8C397 64 448 115 448 177.7zM203 363c0-34.7-27.8-62.5-62.5-62.5-4.5 0-9 .5-13.5 1.5l26 10.5c25.5 10.2 38 39 27.7 64.5-10.2 25.5-39.2 38-64.7 27.5-10.2-4-20.5-8.3-30.7-12.2 10.5 19.7 31.2 33.2 55.2 33.2 34.7 0 62.5-27.8 62.5-62.5zm207.5-185.3c0-42-34.3-76.2-76.2-76.2-42.3 0-76.5 34.2-76.5 76.2 0 42.2 34.3 76.2 76.5 76.2 41.9.1 76.2-33.9 76.2-76.2z"],"sticker-mule":[576,512,[],"f3f7","M353.1 509.8c-5.9 2.9-32.1 3.2-36.5-.5-4.1-3-2.2-11.9-1.5-15 2.2-15-2.5-7.9-9.8-11.5-3.1-1.5-4.1-5.5-4.6-10-.5-1.5-1-2.5-1.5-3.5-1.7-10.7 6.8-33.6 8.2-43.4 4.9-23.7-.7-37.2 1.5-46.9 3.7-16.2 4.1-3.5 4.1-29.9-1.4-25.9 3.3-36.9.5-38.9-14.8 0-64.3 10.7-112.2 2-46.1-8.9-59.4-29-65.4-30.9-10.3-4.5-23.2.5-27.3 7-.1.1-35 70.6-39.6 87.8-6.2 20.5-.5 47.4 4.1 66.8 0 .1 4.5 14.6 10.3 19.5 2.1 1.5 5.1 2.5 7.2 4.5 2.8 2.7 9.4 15.2 9.8 16 2.6 4.5 3.6 8-1.5 10.5-3.6 2-9.3 2.5-14.4 2.5-2.6.5-1.5 3.5-3.1 5-2.9 2.8-20.7 6.1-29.9 2.5-2.6-1-5.7-3-6.2-5-1.5-4 2.1-9-1-12.5-4.5-2.9-13.1-2-17-12-2.2-5.4-2.6-7.6-2.6-49.4 0-9.7-5.9-38.7-8.2-46.9-1.5-5.5-1.5-11.5 0-16 .3-.9 4.1-4.6 4.1-13-1-1.5-4.6-.5-5.1-1.5-10.4-80.6-5.9-79-7.7-98.3-1.5-16-10.9-43.9-6.7-64.3.5-2.4 3.4-21 24.2-38.9 31-26.7 48.4-38.3 159-11.5 1.1.4 66.3 21.1 110.7-9 15.5-11.3 28.8-11.3 35.5-16 .1-.1 61.7-52.1 87-65.3 47.2-29.4 69.9-16.7 75.1-18 4.7-1 13.4-25.8 17-25.8 5.5 0 1.6 20.2 3.6 25.9.5 2 3.6 5 6.2 5 2.3 0 1.7-.8 10.3-5 8.4-5.4 14.9-17.6 20.6-17 11.7 1.6-19 41.6-19 46.9 0 2 .2.8 4.6 9.5 2.6 5.5 4.6 13.5 6.2 20 8.3 29.7 5.7 14.6 13.4 36.9 20.2 50.1 20.6 45.2 20.6 52.9 0 7.5-4.1 11-7.2 16.5-1.5 3-4.6 7.5-7.2 8-2.7.7 7-1.5-13.4 2.5-7.2 1-13.4-4.5-14.9-9.5-1.6-4.7 2.8-10.1-11.8-22.9-10.3-10-21.1-11.3-31.9-17-9.8-5.7-11.9 1-18 8-18 22.9-34 46.9-52 69.8-11.8 15-24.2 30.4-33.5 47.4-3.9 6.8-9.5 28.1-10.3 29.9-6.2 17.7-5.5 25.8-16.5 68.3-3.1 10-5.7 21.4-8.7 32.4-2.2 6.8-7.4 49.3-.5 59.4 2.1 3.5 8.7 4.5 11.3 8 .1.1 9.6 18.2 9.3 20 0 6.1-9.4 5.6-11.3 6.5-4.8 2.9-3.8 5.9-6.4 7.4"],strava:[369,512,[],"f428","M301.6 292l-43.9 88.2-44.6-88.2h-67.6l112.2 220 111.5-220h-67.6zM151.4 0L0 292h89.2l62.2-116.1L213.1 292h88.5L151.4 0z"],stripe:[640,512,[],"f429","M640 261.6c0-45.5-22-81.4-64.2-81.4s-67.9 35.9-67.9 81.1c0 53.5 30.3 78.2 73.5 78.2 21.2 0 37.1-4.8 49.2-11.5v-33.4c-12.1 6.1-26 9.8-43.6 9.8-17.3 0-32.5-6.1-34.5-26.9h86.9c.2-2.3.6-11.6.6-15.9m-87.9-16.8c0-20 12.3-28.4 23.4-28.4 10.9 0 22.5 8.4 22.5 28.4h-45.9zm-112.9-64.6c-17.4 0-28.6 8.2-34.8 13.9l-2.3-11H363v204.8l44.4-9.4.1-50.2c6.4 4.7 15.9 11.2 31.4 11.2 31.8 0 60.8-23.2 60.8-79.6.1-51.6-29.3-79.7-60.5-79.7m-10.6 122.5c-10.4 0-16.6-3.8-20.9-8.4l-.3-66c4.6-5.1 11-8.8 21.2-8.8 16.2 0 27.4 18.2 27.4 41.4.1 23.9-10.9 41.8-27.4 41.8M346.4 124v36.2l-44.6 9.5v-36.2l44.6-9.5m-44.5 59.2h44.6v153.2h-44.6V183.2zm-47.8 13.1c10.4-19.1 31.1-15.2 37.1-13.1V224c-5.7-1.8-23.4-4.5-33.9 9.3v103.1H213V183.2h38.4l2.7 13.1m-89-13.1h33.7V221h-33.7v63.2c0 26.2 28 18 33.7 15.7v33.8c-5.9 3.2-16.6 5.9-31.2 5.9-26.3 0-46.1-17-46.1-43.3l.2-142.4 43.3-9.2.1 38.5zM44.9 228.3c0 20 67.9 10.5 67.9 63.4 0 32-25.4 47.8-62.3 47.8-15.3 0-32-3-48.5-10.1v-40c14.9 8.1 33.9 14.2 48.6 14.2 9.9 0 17-2.7 17-10.9 0-21.2-67.5-13.2-67.5-62.4 0-31.4 24-50.2 60-50.2 14.7 0 29.4 2.3 44.1 8.1V230c-13.5-7.3-30.7-11.4-44.2-11.4-9.3.1-15.1 2.8-15.1 9.7"],"stripe-s":[362,512,[],"f42a","M144.3 154.6c0-22.3 18.6-30.9 48.4-30.9 43.4 0 98.5 13.3 141.9 36.7V26.1C287.3 7.2 240.1 0 192.8 0 77.1 0 0 60.4 0 161.4c0 157.9 216.8 132.3 216.8 200.4 0 26.4-22.9 34.9-54.7 34.9-47.2 0-108.2-19.5-156.1-45.5v128.5c53 22.8 106.8 32.4 156 32.4 118.6 0 200.3-51 200.3-153.6 0-170.2-218-139.7-218-203.9"],studiovinari:[512,512,[],"f3f8","M480.3 187.7l4.2 28v28l-25.1 44.1-39.8 78.4-56.1 67.5-79.1 37.8-17.7 24.5-7.7 12-9.6 4s17.3-63.6 19.4-63.6c2.1 0 20.3.7 20.3.7l66.7-38.6-92.5 26.1-55.9 36.8-22.8 28-6.6 1.4 20.8-73.6 6.9-5.5 20.7 12.9 88.3-45.2 56.8-51.5 14.8-68.4-125.4 23.3 15.2-18.2-173.4-53.3 81.9-10.5-166-122.9L133.5 108 32.2 0l252.9 126.6-31.5-38L378 163 234.7 64l18.7 38.4-49.6-18.1L158.3 0l194.6 122L310 66.2l108 96.4 12-8.9-21-16.4 4.2-37.8L451 89.1l29.2 24.7 11.5 4.2-7 6.2 8.5 12-13.1 7.4-10.3 20.2 10.5 23.9z"],stumbleupon:[512,512,[],"f1a4","M502.9 266v69.7c0 62.1-50.3 112.4-112.4 112.4-61.8 0-112.4-49.8-112.4-111.3v-70.2l34.3 16 51.1-15.2V338c0 14.7 12 26.5 26.7 26.5S417 352.7 417 338v-72h85.9zm-224.7-58.2l34.3 16 51.1-15.2V173c0-60.5-51.1-109-112.1-109-60.8 0-112.1 48.2-112.1 108.2v162.4c0 14.9-12 26.7-26.7 26.7S86 349.5 86 334.6V266H0v69.7C0 397.7 50.3 448 112.4 448c61.6 0 112.4-49.5 112.4-110.8V176.9c0-14.7 12-26.7 26.7-26.7s26.7 12 26.7 26.7v30.9z"],"stumbleupon-circle":[496,512,[],"f1a3","M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 177.5c-9.8 0-17.8 8-17.8 17.8v106.9c0 40.9-33.9 73.9-74.9 73.9-41.4 0-74.9-33.5-74.9-74.9v-46.5h57.3v45.8c0 10 8 17.8 17.8 17.8s17.8-7.9 17.8-17.8V200.1c0-40 34.2-72.1 74.7-72.1 40.7 0 74.7 32.3 74.7 72.6v23.7l-34.1 10.1-22.9-10.7v-20.6c.1-9.6-7.9-17.6-17.7-17.6zm167.6 123.6c0 41.4-33.5 74.9-74.9 74.9-41.2 0-74.9-33.2-74.9-74.2V263l22.9 10.7 34.1-10.1v47.1c0 9.8 8 17.6 17.8 17.6s17.8-7.9 17.8-17.6v-48h57.3c-.1 45.9-.1 46.4-.1 46.4z"],superpowers:[448,512,[],"f2dd","M448 32c-83.3 11-166.8 22-250 33-92 12.5-163.3 86.7-169 180-3.3 55.5 18 109.5 57.8 148.2L0 480c83.3-11 166.5-22 249.8-33 91.8-12.5 163.3-86.8 168.7-179.8 3.5-55.5-18-109.5-57.7-148.2L448 32zm-79.7 232.3c-4.2 79.5-74 139.2-152.8 134.5-79.5-4.7-140.7-71-136.3-151 4.5-79.2 74.3-139.3 153-134.5 79.3 4.7 140.5 71 136.1 151z"],supple:[640,512,[],"f3f9","M640 262.5c0 64.1-109 116.1-243.5 116.1-24.8 0-48.6-1.8-71.1-5 7.7.4 15.5.6 23.4.6 134.5 0 243.5-56.9 243.5-127.1 0-29.4-19.1-56.4-51.2-78 60 21.1 98.9 55.1 98.9 93.4zM47.7 227.9c-.1-70.2 108.8-127.3 243.3-127.6 7.9 0 15.6.2 23.3.5-22.5-3.2-46.3-4.9-71-4.9C108.8 96.3-.1 148.5 0 212.6c.1 38.3 39.1 72.3 99.3 93.3-32.3-21.5-51.5-48.6-51.6-78zm60.2 39.9s10.5 13.2 29.3 13.2c17.9 0 28.4-11.5 28.4-25.1 0-28-40.2-25.1-40.2-39.7 0-5.4 5.3-9.1 12.5-9.1 5.7 0 11.3 2.6 11.3 6.6v3.9h14.2v-7.9c0-12.1-15.4-16.8-25.4-16.8-16.5 0-28.5 10.2-28.5 24.1 0 26.6 40.2 25.4 40.2 39.9 0 6.6-5.8 10.1-12.3 10.1-11.9 0-20.7-10.1-20.7-10.1l-8.8 10.9zm120.8-73.6v54.4c0 11.3-7.1 17.8-17.8 17.8-10.7 0-17.8-6.5-17.8-17.7v-54.5h-15.8v55c0 18.9 13.4 31.9 33.7 31.9 20.1 0 33.4-13 33.4-31.9v-55h-15.7zm34.4 85.4h15.8v-29.5h15.5c16 0 27.2-11.5 27.2-28.1s-11.2-27.8-27.2-27.8h-39.1v13.4h7.8v72zm15.8-43v-29.1h12.9c8.7 0 13.7 5.7 13.7 14.4 0 8.9-5.1 14.7-14 14.7h-12.6zm57 43h15.8v-29.5h15.5c16 0 27.2-11.5 27.2-28.1s-11.2-27.8-27.2-27.8h-39.1v13.4h7.8v72zm15.7-43v-29.1h12.9c8.7 0 13.7 5.7 13.7 14.4 0 8.9-5 14.7-14 14.7h-12.6zm57.1 34.8c0 5.8 2.4 8.2 8.2 8.2h37.6c5.8 0 8.2-2.4 8.2-8.2v-13h-14.3v5.2c0 1.7-1 2.6-2.6 2.6h-18.6c-1.7 0-2.6-1-2.6-2.6v-61.2c0-5.7-2.4-8.2-8.2-8.2H401v13.4h5.2c1.7 0 2.6 1 2.6 2.6v61.2zm63.4 0c0 5.8 2.4 8.2 8.2 8.2H519c5.7 0 8.2-2.4 8.2-8.2v-13h-14.3v5.2c0 1.7-1 2.6-2.6 2.6h-19.7c-1.7 0-2.6-1-2.6-2.6v-20.3h27.7v-13.4H488v-22.4h19.2c1.7 0 2.6 1 2.6 2.6v5.2H524v-13c0-5.7-2.5-8.2-8.2-8.2h-51.6v13.4h7.8v63.9zm58.9-76v5.9h1.6v-5.9h2.7v-1.2h-7v1.2h2.7zm5.7-1.2v7.1h1.5v-5.7l2.3 5.7h1.3l2.3-5.7v5.7h1.5v-7.1h-2.3l-2.1 5.1-2.1-5.1h-2.4z"],telegram:[496,512,[],"f2c6","M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm121.8 169.9l-40.7 191.8c-3 13.6-11.1 16.9-22.4 10.5l-62-45.7-29.9 28.8c-3.3 3.3-6.1 6.1-12.5 6.1l4.4-63.1 114.9-103.8c5-4.4-1.1-6.9-7.7-2.5l-142 89.4-61.2-19.1c-13.3-4.2-13.6-13.3 2.8-19.7l239.1-92.2c11.1-4 20.8 2.7 17.2 19.5z"],"telegram-plane":[448,512,[],"f3fe","M446.7 98.6l-67.6 318.8c-5.1 22.5-18.4 28.1-37.3 17.5l-103-75.9-49.7 47.8c-5.5 5.5-10.1 10.1-20.7 10.1l7.4-104.9 190.9-172.5c8.3-7.4-1.8-11.5-12.9-4.1L117.8 284 16.2 252.2c-22.1-6.9-22.5-22.1 4.6-32.7L418.2 66.4c18.4-6.9 34.5 4.1 28.5 32.2z"],"tencent-weibo":[384,512,[],"f1d5","M72.3 495.8c1.4 19.9-27.6 22.2-29.7 2.9C31 368.8 73.7 259.2 144 185.5c-15.6-34 9.2-77.1 50.6-77.1 30.3 0 55.1 24.6 55.1 55.1 0 44-49.5 70.8-86.9 45.1-65.7 71.3-101.4 169.8-90.5 287.2zM192 .1C66.1.1-12.3 134.3 43.7 242.4 52.4 259.8 79 246.9 70 229 23.7 136.4 91 29.8 192 29.8c75.4 0 136.9 61.4 136.9 136.9 0 90.8-86.9 153.9-167.7 133.1-19.1-4.1-25.6 24.4-6.6 29.1 110.7 23.2 204-60 204-162.3C358.6 74.7 284 .1 192 .1z"],themeisle:[512,512,[],"f2b2","M208 88.286c0-10 6.286-21.714 17.715-21.714 11.142 0 17.714 11.714 17.714 21.714 0 10.285-6.572 21.714-17.714 21.714C214.286 110 208 98.571 208 88.286zm304 160c0 36.001-11.429 102.286-36.286 129.714-22.858 24.858-87.428 61.143-120.857 70.572l-1.143.286v32.571c0 16.286-12.572 30.571-29.143 30.571-10 0-19.429-5.714-24.572-14.286-5.427 8.572-14.856 14.286-24.856 14.286-10 0-19.429-5.714-24.858-14.286-5.142 8.572-14.571 14.286-24.57 14.286-10.286 0-19.429-5.714-24.858-14.286-5.143 8.572-14.571 14.286-24.571 14.286-18.857 0-29.429-15.714-29.429-32.857-16.286 12.285-35.715 19.428-56.571 19.428-22 0-43.429-8.285-60.286-22.857 10.285-.286 20.571-2.286 30.285-5.714-20.857-5.714-39.428-18.857-52-36.286 21.37 4.645 46.209 1.673 67.143-11.143-22-22-56.571-58.857-68.572-87.428C1.143 321.714 0 303.714 0 289.429c0-49.714 20.286-160 86.286-160 10.571 0 18.857 4.858 23.143 14.857a158.792 158.792 0 0 1 12-15.428c2-2.572 5.714-5.429 7.143-8.286 7.999-12.571 11.714-21.142 21.714-34C182.571 45.428 232 17.143 285.143 17.143c6 0 12 .285 17.714 1.143C313.714 6.571 328.857 0 344.572 0c14.571 0 29.714 6 40 16.286.857.858 1.428 2.286 1.428 3.428 0 3.714-10.285 13.429-12.857 16.286 4.286 1.429 15.714 6.858 15.714 12 0 2.857-2.857 5.143-4.571 7.143 31.429 27.714 49.429 67.143 56.286 108 4.286-5.143 10.285-8.572 17.143-8.572 10.571 0 20.857 7.144 28.571 14.001C507.143 187.143 512 221.714 512 248.286zM188 89.428c0 18.286 12.571 37.143 32.286 37.143 19.714 0 32.285-18.857 32.285-37.143 0-18-12.571-36.857-32.285-36.857-19.715 0-32.286 18.858-32.286 36.857zM237.714 194c0-19.714 3.714-39.143 8.571-58.286-52.039 79.534-13.531 184.571 68.858 184.571 21.428 0 42.571-7.714 60-20 2-7.429 3.714-14.857 3.714-22.572 0-14.286-6.286-21.428-20.572-21.428-4.571 0-9.143.857-13.429 1.714-63.343 12.668-107.142 3.669-107.142-63.999zm-41.142 254.858c0-11.143-8.858-20.857-20.286-20.857-11.429 0-20 9.715-20 20.857v32.571c0 11.143 8.571 21.142 20 21.142 11.428 0 20.286-9.715 20.286-21.142v-32.571zm49.143 0c0-11.143-8.572-20.857-20-20.857-11.429 0-20.286 9.715-20.286 20.857v32.571c0 11.143 8.857 21.142 20.286 21.142 11.428 0 20-10 20-21.142v-32.571zm49.713 0c0-11.143-8.857-20.857-20.285-20.857-11.429 0-20.286 9.715-20.286 20.857v32.571c0 11.143 8.857 21.142 20.286 21.142 11.428 0 20.285-9.715 20.285-21.142v-32.571zm49.715 0c0-11.143-8.857-20.857-20.286-20.857-11.428 0-20.286 9.715-20.286 20.857v32.571c0 11.143 8.858 21.142 20.286 21.142 11.429 0 20.286-10 20.286-21.142v-32.571zM421.714 286c-30.857 59.142-90.285 102.572-158.571 102.572-96.571 0-160.571-84.572-160.571-176.572 0-16.857 2-33.429 6-49.714-20 33.715-29.714 72.572-29.714 111.429 0 60.286 24.857 121.715 71.429 160.857 5.143-9.714 14.857-16.286 26-16.286 10 0 19.428 5.714 24.571 14.286 5.429-8.571 14.571-14.286 24.858-14.286 10 0 19.428 5.714 24.571 14.286 5.429-8.571 14.857-14.286 24.858-14.286 10 0 19.428 5.714 24.857 14.286 5.143-8.571 14.571-14.286 24.572-14.286 10.857 0 20.857 6.572 25.714 16 43.427-36.286 68.569-92 71.426-148.286zm10.572-99.714c0-53.714-34.571-105.714-92.572-105.714-30.285 0-58.571 15.143-78.857 36.857C240.862 183.812 233.41 254 302.286 254c28.805 0 97.357-28.538 84.286 36.857 28.857-26 45.714-65.714 45.714-104.571z"],trello:[448,512,[],"f181","M392 32H56C25.1 32 0 57.1 0 88v336c0 30.9 25.1 56 56 56h336c30.9 0 56-25.1 56-56V88c0-30.9-25.1-56-56-56zM194.9 371.4c0 14.8-12 26.9-26.9 26.9H85.1c-14.8 0-26.9-12-26.9-26.9V117.1c0-14.8 12-26.9 26.9-26.9H168c14.8 0 26.9 12 26.9 26.9v254.3zm194.9-112c0 14.8-12 26.9-26.9 26.9H280c-14.8 0-26.9-12-26.9-26.9V117.1c0-14.8 12-26.9 26.9-26.9h82.9c14.8 0 26.9 12 26.9 26.9v142.3z"],tripadvisor:[576,512,[],"f262","M166.4 280.521c0 13.236-10.73 23.966-23.966 23.966s-23.966-10.73-23.966-23.966 10.73-23.966 23.966-23.966 23.966 10.729 23.966 23.966zm264.962-23.956c-13.23 0-23.956 10.725-23.956 23.956 0 13.23 10.725 23.956 23.956 23.956 13.23 0 23.956-10.725 23.956-23.956-.001-13.231-10.726-23.956-23.956-23.956zm89.388 139.49c-62.667 49.104-153.276 38.109-202.379-24.559l-30.979 46.325-30.683-45.939c-48.277 60.39-135.622 71.891-197.885 26.055-64.058-47.158-77.759-137.316-30.601-201.374A186.762 186.762 0 0 0 0 139.416l90.286-.05a358.48 358.48 0 0 1 197.065-54.03 350.382 350.382 0 0 1 192.181 53.349l96.218.074a185.713 185.713 0 0 0-28.352 57.649c46.793 62.747 34.964 151.37-26.648 199.647zM259.366 281.761c-.007-63.557-51.535-115.075-115.092-115.068C80.717 166.7 29.2 218.228 29.206 281.785c.007 63.557 51.535 115.075 115.092 115.068 63.513-.075 114.984-51.539 115.068-115.052v-.04zm28.591-10.455c5.433-73.44 65.51-130.884 139.12-133.022a339.146 339.146 0 0 0-139.727-27.812 356.31 356.31 0 0 0-140.164 27.253c74.344 1.582 135.299 59.424 140.771 133.581zm251.706-28.767c-21.992-59.634-88.162-90.148-147.795-68.157-59.634 21.992-90.148 88.162-68.157 147.795v.032c22.038 59.607 88.198 90.091 147.827 68.113 59.615-22.004 90.113-88.162 68.125-147.783zm-326.039 37.975v.115c-.057 39.328-31.986 71.163-71.314 71.106-39.328-.057-71.163-31.986-71.106-71.314.057-39.328 31.986-71.163 71.314-71.106 39.259.116 71.042 31.94 71.106 71.199zm-24.512 0v-.084c-.051-25.784-20.994-46.645-46.778-46.594-25.784.051-46.645 20.994-46.594 46.777.051 25.784 20.994 46.645 46.777 46.594 25.726-.113 46.537-20.968 46.595-46.693zm313.423 0v.048c-.02 39.328-31.918 71.194-71.247 71.173s-71.194-31.918-71.173-71.247c.02-39.328 31.918-71.194 71.247-71.173 39.29.066 71.121 31.909 71.173 71.199zm-24.504-.008c-.009-25.784-20.918-46.679-46.702-46.67-25.784.009-46.679 20.918-46.67 46.702.009 25.784 20.918 46.678 46.702 46.67 25.765-.046 46.636-20.928 46.67-46.693v-.009z"],tumblr:[320,512,[],"f173","M309.8 480.3c-13.6 14.5-50 31.7-97.4 31.7-120.8 0-147-88.8-147-140.6v-144H17.9c-5.5 0-10-4.5-10-10v-68c0-7.2 4.5-13.6 11.3-16 62-21.8 81.5-76 84.3-117.1.8-11 6.5-16.3 16.1-16.3h70.9c5.5 0 10 4.5 10 10v115.2h83c5.5 0 10 4.4 10 9.9v81.7c0 5.5-4.5 10-10 10h-83.4V360c0 34.2 23.7 53.6 68 35.8 4.8-1.9 9-3.2 12.7-2.2 3.5.9 5.8 3.4 7.4 7.9l22 64.3c1.8 5 3.3 10.6-.4 14.5z"],"tumblr-square":[448,512,[],"f174","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-82.3 364.2c-8.5 9.1-31.2 19.8-60.9 19.8-75.5 0-91.9-55.5-91.9-87.9v-90h-29.7c-3.4 0-6.2-2.8-6.2-6.2v-42.5c0-4.5 2.8-8.5 7.1-10 38.8-13.7 50.9-47.5 52.7-73.2.5-6.9 4.1-10.2 10-10.2h44.3c3.4 0 6.2 2.8 6.2 6.2v72h51.9c3.4 0 6.2 2.8 6.2 6.2v51.1c0 3.4-2.8 6.2-6.2 6.2h-52.1V321c0 21.4 14.8 33.5 42.5 22.4 3-1.2 5.6-2 8-1.4 2.2.5 3.6 2.1 4.6 4.9l13.8 40.2c1 3.2 2 6.7-.3 9.1z"],twitch:[448,512,[],"f1e8","M40.1 32L10 108.9v314.3h107V480h60.2l56.8-56.8h87l117-117V32H40.1zm357.8 254.1L331 353H224l-56.8 56.8V353H76.9V72.1h321v214zM331 149v116.9h-40.1V149H331zm-107 0v116.9h-40.1V149H224z"],twitter:[512,512,[],"f099","M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"],"twitter-square":[448,512,[],"f081","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-48.9 158.8c.2 2.8.2 5.7.2 8.5 0 86.7-66 186.6-186.6 186.6-37.2 0-71.7-10.8-100.7-29.4 5.3.6 10.4.8 15.8.8 30.7 0 58.9-10.4 81.4-28-28.8-.6-53-19.5-61.3-45.5 10.1 1.5 19.2 1.5 29.6-1.2-30-6.1-52.5-32.5-52.5-64.4v-.8c8.7 4.9 18.9 7.9 29.6 8.3a65.447 65.447 0 0 1-29.2-54.6c0-12.2 3.2-23.4 8.9-33.1 32.3 39.8 80.8 65.8 135.2 68.6-9.3-44.5 24-80.6 64-80.6 18.9 0 35.9 7.9 47.9 20.7 14.8-2.8 29-8.3 41.6-15.8-4.9 15.2-15.2 28-28.8 36.1 13.2-1.4 26-5.1 37.8-10.2-8.9 13.1-20.1 24.7-32.9 34z"],typo3:[433,512,[],"f42b","M330.8 341c-7 2.3-11.6 2.3-18.5 2.3-57.2 0-140.6-198.5-140.6-264.9 0-24.7 5.4-32.4 13.9-39.4-69.5 8.5-149.3 34-176.3 66.4-5.4 7.7-9.3 20.8-9.3 37.1C0 246 106.8 480 184.1 480c36.3 0 97.3-59.5 146.7-139M294.5 32c71.8 0 138.8 11.6 138.8 52.5 0 82.6-52.5 182.3-78.8 182.3-47.9 0-101.7-132.1-101.7-198.5 0-30.9 11.6-36.3 41.7-36.3"],uber:[448,512,[],"f402","M414.1 32H33.9C15.2 32 0 47.2 0 65.9V446c0 18.8 15.2 34 33.9 34H414c18.7 0 33.9-15.2 33.9-33.9V65.9C448 47.2 432.8 32 414.1 32zM237.6 391.1C163 398.6 96.4 344.2 88.9 269.6h94.4V290c0 3.7 3 6.8 6.8 6.8H258c3.7 0 6.8-3 6.8-6.8v-67.9c0-3.7-3-6.8-6.8-6.8h-67.9c-3.7 0-6.8 3-6.8 6.8v20.4H88.9c7-69.4 65.4-122.2 135.1-122.2 69.7 0 128.1 52.8 135.1 122.2 7.5 74.5-46.9 141.1-121.5 148.6z"],uikit:[448,512,[],"f403","M443.9 128v256L218 512 0 384V169.7l87.6 45.1v117l133.5 75.5 135.8-75.5v-151l-101.1-57.6 87.6-53.1L443.9 128zM308.6 49.1L223.8 0l-88.6 54.8 86 47.3 87.4-53z"],uniregistry:[384,512,[],"f404","M281.1 220.1H384v-14.8H281.1v14.8zm0-37.1H384v-12.4H281.1V183zm0 74.2H384v-17.3H281.1v17.3zm-157.7 86.7H8.5c2.6 8.5 5.8 16.8 9.6 24.8h138.3c-12.9-5.7-24.1-14.2-33-24.8m145.7-12.4h109.7c1.8-7.3 3.1-14.7 3.9-22.3H278.3c-2.1 7.9-5.2 15.4-9.2 22.3m-41.5 37.1H367c3.7-8 5.8-16.2 8.5-24.8h-115c-8.8 10.7-20.1 19.2-32.9 24.8M384 32H281.1v2.5H384V32zM192 480c39.5 0 76.2-11.8 106.8-32.2H85.3C115.8 468.2 152.5 480 192 480m89.1-334.2H384V136H281.1v9.8zm0-37.1H384v-7.4H281.1v7.4zm0-37.1H384v-4.9H281.1v4.9zm-178.2 99H0V183h102.9v-12.4zM38.8 405.7h305.3c6.7-8.5 12.6-17.6 17.8-27.2H23c5.2 9.6 9.2 18.7 15.8 27.2m64.1-118.8v-12.4H0v12.4c0 2.5 0 5 .1 7.4h103.1c-.2-2.4-.3-4.9-.3-7.4m178.2 0c0 2.5-.1 5-.4 7.4h103.1c.1-2.5.2-4.9.2-7.4v-12.4H281.1v12.4zm-203 156h227.7c11.8-8.7 22.7-18.6 32.2-29.7H44.9c9.6 11 21.4 21 33.2 29.7m24.8-376.2H0v4.9h102.9v-4.9zm0-34.7H0v2.5h102.9V32zm0 173.3H0v14.8h102.9v-14.8zm0 34.6H0v17.3h102.9v-17.3zm0-103.9H0v9.9h102.9V136zm0-34.7H0v7.4h102.9v-7.4zm2.8 207.9H1.3c.9 7.6 2.2 15 3.9 22.3h109.7c-4-6.9-7.2-14.4-9.2-22.3"],untappd:[640,512,[],"f405","M401.3 49.9c-79.8 160.1-84.6 152.5-87.9 173.2l-5.2 32.8c-1.9 12-6.6 23.5-13.7 33.4L145.6 497.1c-7.6 10.6-20.4 16.2-33.4 14.6-40.3-5-77.8-32.2-95.3-68.5-5.7-11.8-4.5-25.8 3.1-36.4l148.9-207.9c7.1-9.9 16.4-18 27.2-23.7l29.3-15.5c18.5-9.8 9.7-11.9 135.6-138.9 1-4.8 1-7.3 3.6-8 3-.7 6.6-1 6.3-4.6l-.4-4.6c-.2-1.9 1.3-3.6 3.2-3.6 4.5-.1 13.2 1.2 25.6 10 12.3 8.9 16.4 16.8 17.7 21.1.6 1.8-.6 3.7-2.4 4.2l-4.5 1.1c-3.4.9-2.5 4.4-2.3 7.4.1 2.8-2.3 3.6-6.5 6.1zM230.1 36.4c3.4.9 2.5 4.4 2.3 7.4-.2 2.7 2.1 3.5 6.4 6 7.9 15.9 15.3 30.5 22.2 44 .7 1.3 2.3 1.5 3.3.5 11.2-12 24.6-26.2 40.5-42.6 1.3-1.4 1.4-3.5.1-4.9-8-8.2-16.5-16.9-25.6-26.1-1-4.7-1-7.3-3.6-8-3-.8-6.6-1-6.3-4.6.3-3.3 1.4-8.1-2.8-8.2-4.5-.1-13.2 1.1-25.6 10-12.3 8.9-16.4 16.8-17.7 21.1-1.4 4.2 3.6 4.6 6.8 5.4zM620 406.7L471.2 198.8c-13.2-18.5-26.6-23.4-56.4-39.1-11.2-5.9-14.2-10.9-30.5-28.9-1-1.1-2.9-.9-3.6.5-46.3 88.8-47.1 82.8-49 94.8-1.7 10.7-1.3 20 .3 29.8 1.9 12 6.6 23.5 13.7 33.4l148.9 207.9c7.6 10.6 20.2 16.2 33.1 14.7 40.3-4.9 78-32 95.7-68.6 5.4-11.9 4.3-25.9-3.4-36.6z"],usb:[640,512,[],"f287","M641.5 256c0 3.1-1.7 6.1-4.5 7.5L547.9 317c-1.4.8-2.8 1.4-4.5 1.4-1.4 0-3.1-.3-4.5-1.1-2.8-1.7-4.5-4.5-4.5-7.8v-35.6H295.7c25.3 39.6 40.5 106.9 69.6 106.9H392V354c0-5 3.9-8.9 8.9-8.9H490c5 0 8.9 3.9 8.9 8.9v89.1c0 5-3.9 8.9-8.9 8.9h-89.1c-5 0-8.9-3.9-8.9-8.9v-26.7h-26.7c-75.4 0-81.1-142.5-124.7-142.5H140.3c-8.1 30.6-35.9 53.5-69 53.5C32 327.3 0 295.3 0 256s32-71.3 71.3-71.3c33.1 0 61 22.8 69 53.5 39.1 0 43.9 9.5 74.6-60.4C255 88.7 273 95.7 323.8 95.7c7.5-20.9 27-35.6 50.4-35.6 29.5 0 53.5 23.9 53.5 53.5s-23.9 53.5-53.5 53.5c-23.4 0-42.9-14.8-50.4-35.6H294c-29.1 0-44.3 67.4-69.6 106.9h310.1v-35.6c0-3.3 1.7-6.1 4.5-7.8 2.8-1.7 6.4-1.4 8.9.3l89.1 53.5c2.8 1.1 4.5 4.1 4.5 7.2z"],ussunnah:[512,512,[],"f407","M156.8 285.1l5.7 14.4h-8.2c-1.3-3.2-3.1-7.7-3.8-9.5-2.5-6.3-1.1-8.4 0-10 1.9-2.7 3.2-4.4 3.6-5.2 0 2.2.8 5.7 2.7 10.3zm297.3 18.8c-2.1 13.8-5.7 27.1-10.5 39.7l43 23.4-44.8-18.8c-5.3 13.2-12 25.6-19.9 37.2l34.2 30.2-36.8-26.4c-8.4 11.8-18 22.6-28.7 32.3l24.9 34.7-28.1-31.8c-11 9.6-23.1 18-36.1 25.1l15.7 37.2-19.3-35.3c-13.1 6.8-27 12.1-41.6 15.9l6.7 38.4-10.5-37.4c-14.3 3.4-29.2 5.3-44.5 5.4L256 512l-1.9-38.4c-15.3-.1-30.2-2-44.5-5.3L199 505.6l6.7-38.2c-14.6-3.7-28.6-9.1-41.7-15.8l-19.2 35.1 15.6-37c-13-7-25.2-15.4-36.2-25.1l-27.9 31.6 24.7-34.4c-10.7-9.7-20.4-20.5-28.8-32.3l-36.5 26.2 33.9-29.9c-7.9-11.6-14.6-24.1-20-37.3l-44.4 18.7L67.8 344c-4.8-12.7-8.4-26.1-10.5-39.9l-51 9 50.3-14.2c-1.1-8.5-1.7-17.1-1.7-25.9 0-4.7.2-9.4.5-14.1L0 256l56-2.8c1.3-13.1 3.8-25.8 7.5-38.1L6.4 199l58.9 10.4c4-12 9.1-23.5 15.2-34.4l-55.1-30 58.3 24.6C90 159 97.2 149.2 105.3 140L55.8 96.4l53.9 38.7c8.1-8.6 17-16.5 26.6-23.6l-40-55.6 45.6 51.6c9.5-6.6 19.7-12.3 30.3-17.2l-27.3-64.9 33.8 62.1c10.5-4.4 21.4-7.9 32.7-10.4L199 6.4l19.5 69.2c11-2.1 22.3-3.2 33.8-3.4L256 0l3.6 72.2c11.5.2 22.8 1.4 33.8 3.5L313 6.4l-12.4 70.7c11.3 2.6 22.2 6.1 32.6 10.5l33.9-62.2-27.4 65.1c10.6 4.9 20.7 10.7 30.2 17.2l45.8-51.8-40.1 55.9c9.5 7.1 18.4 15 26.5 23.6l54.2-38.9-49.7 43.9c8 9.1 15.2 18.9 21.5 29.4l58.7-24.7-55.5 30.2c6.1 10.9 11.1 22.3 15.1 34.3l59.3-10.4-57.5 16.2c3.7 12.2 6.2 24.9 7.5 37.9L512 256l-56 2.8c.3 4.6.5 9.3.5 14.1 0 8.7-.6 17.3-1.6 25.8l50.7 14.3-51.5-9.1zm-21.8-31c0-97.5-79-176.5-176.5-176.5s-176.5 79-176.5 176.5 79 176.5 176.5 176.5 176.5-79 176.5-176.5zm-24 0c0 84.3-68.3 152.6-152.6 152.6s-152.6-68.3-152.6-152.6 68.3-152.6 152.6-152.6 152.6 68.3 152.6 152.6zM195 241c0 2.1 1.3 3.8 3.6 5.1 3.3 1.9 6.2 4.6 8.2 8.2 2.8-5.7 4.3-9.5 4.3-11.2 0-2.2-1.1-4.4-3.2-7-2.1-2.5-3.2-5.2-3.3-7.7-6.5 6.8-9.6 10.9-9.6 12.6zm-40.7-19c0 2.1 1.3 3.8 3.6 5.1 3.5 1.9 6.2 4.6 8.2 8.2 2.8-5.7 4.3-9.5 4.3-11.2 0-2.2-1.1-4.4-3.2-7-2.1-2.5-3.2-5.2-3.3-7.7-6.5 6.8-9.6 10.9-9.6 12.6zm-19 0c0 2.1 1.3 3.8 3.6 5.1 3.3 1.9 6.2 4.6 8.2 8.2 2.8-5.7 4.3-9.5 4.3-11.2 0-2.2-1.1-4.4-3.2-7-2.1-2.5-3.2-5.2-3.3-7.7-6.4 6.8-9.6 10.9-9.6 12.6zm204.9 87.9c-8.4-3-8.7-6.8-8.7-15.6V182c-8.2 12.5-14.2 18.6-18 18.6 6.3 14.4 9.5 23.9 9.5 28.3v64.3c0 2.2-2.2 6.5-4.7 6.5h-18c-2.8-7.5-10.2-26.9-15.3-40.3-2 2.5-7.2 9.2-10.7 13.7 2.4 1.6 4.1 3.6 5.2 6.3 2.6 6.7 6.4 16.5 7.9 20.2h-9.2c-3.9-10.4-9.6-25.4-11.8-31.1-2 2.5-7.2 9.2-10.7 13.7 2.4 1.6 4.1 3.6 5.2 6.3.8 2 2.8 7.3 4.3 10.9H256c-1.5-4.1-5.6-14.6-8.4-22-2 2.5-7.2 9.2-10.7 13.7 2.5 1.6 4.3 3.6 5.2 6.3.2.6.5 1.4.6 1.7H225c-4.6-13.9-11.4-27.7-11.4-34.1 0-2.2.3-5.1 1.1-8.2-8.8 10.8-14 15.9-14 25 0 7.5 10.4 28.3 10.4 33.3 0 1.7-.5 3.3-1.4 4.9-9.6-12.7-15.5-20.7-18.8-20.7h-12l-11.2-28c-3.8-9.6-5.7-16-5.7-18.8 0-3.8.5-7.7 1.7-12.2-1 1.3-3.7 4.7-5.5 7.1-.8-2.1-3.1-7.7-4.6-11.5-2.1 2.5-7.5 9.1-11.2 13.6.9 2.3 3.3 8.1 4.9 12.2-2.5 3.3-9.1 11.8-13.6 17.7-4 5.3-5.8 13.3-2.7 21.8 2.5 6.7 2 7.9-1.7 14.1H191c5.5 0 14.3 14 15.5 22 13.2-16 15.4-19.6 16.8-21.6h107c3.9 0 7.2-1.9 9.9-5.8zm20.1-26.6V181.7c-9 12.5-15.9 18.6-20.7 18.6 7.1 14.4 10.7 23.9 10.7 28.3v66.3c0 17.5 8.6 20.4 24 20.4 8.1 0 12.5-.8 13.7-2.7-4.3-1.6-7.6-2.5-9.9-3.3-8.1-3.2-17.8-7.4-17.8-26z"],vaadin:[448,512,[],"f408","M224.5 140.7c1.5-17.6 4.9-52.7 49.8-52.7h98.6c20.7 0 32.1-7.8 32.1-21.6V54.1c0-12.2 9.3-22.1 21.5-22.1S448 41.9 448 54.1v36.5c0 42.9-21.5 62-66.8 62H280.7c-30.1 0-33 14.7-33 27.1 0 1.3-.1 2.5-.2 3.7-.7 12.3-10.9 22.2-23.4 22.2s-22.7-9.8-23.4-22.2c-.1-1.2-.2-2.4-.2-3.7 0-12.3-3-27.1-33-27.1H66.8c-45.3 0-66.8-19.1-66.8-62V54.1C0 41.9 9.4 32 21.6 32s21.5 9.9 21.5 22.1v12.3C43.1 80.2 54.5 88 75.2 88h98.6c44.8 0 48.3 35.1 49.8 52.7h.9zM224 456c11.5 0 21.4-7 25.7-16.3 1.1-1.8 97.1-169.6 98.2-171.4 11.9-19.6-3.2-44.3-27.2-44.3-13.9 0-23.3 6.4-29.8 20.3L224 362l-66.9-117.7c-6.4-13.9-15.9-20.3-29.8-20.3-24 0-39.1 24.6-27.2 44.3 1.1 1.9 97.1 169.6 98.2 171.4 4.3 9.3 14.2 16.3 25.7 16.3z"],viacoin:[384,512,[],"f237","M384 32h-64l-80.7 192h-94.5L64 32H0l48 112H0v48h68.5l13.8 32H0v48h102.8L192 480l89.2-208H384v-48h-82.3l13.8-32H384v-48h-48l48-112zM192 336l-27-64h54l-27 64z"],viadeo:[448,512,[],"f2a9","M276.2 150.5v.7C258.3 98.6 233.6 47.8 205.4 0c43.3 29.2 67 100 70.8 150.5zm32.7 121.7c7.6 18.2 11 37.5 11 57 0 77.7-57.8 141-137.8 139.4l3.8-.3c74.2-46.7 109.3-118.6 109.3-205.1 0-38.1-6.5-75.9-18.9-112 1 11.7 1 23.7 1 35.4 0 91.8-18.1 241.6-116.6 280C95 455.2 49.4 398 49.4 329.2c0-75.6 57.4-142.3 135.4-142.3 16.8 0 33.7 3.1 49.1 9.6 1.7-15.1 6.5-29.9 13.4-43.3-19.9-7.2-41.2-10.7-62.5-10.7-161.5 0-238.7 195.9-129.9 313.7 67.9 74.6 192 73.9 259.8 0 56.6-61.3 60.9-142.4 36.4-201-12.7 8-27.1 13.9-42.2 17zM418.1 11.7c-31 66.5-81.3 47.2-115.8 80.1-12.4 12-20.6 34-20.6 50.5 0 14.1 4.5 27.1 12 38.8 47.4-11 98.3-46 118.2-90.7-.7 5.5-4.8 14.4-7.2 19.2-20.3 35.7-64.6 65.6-99.7 84.9 14.8 14.4 33.7 25.8 55 25.8 79 0 110.1-134.6 58.1-208.6z"],"viadeo-square":[448,512,[],"f2aa","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM280.7 381.2c-42.4 46.2-120 46.6-162.4 0-68-73.6-19.8-196.1 81.2-196.1 13.3 0 26.6 2.1 39.1 6.7-4.3 8.4-7.3 17.6-8.4 27.1-9.7-4.1-20.2-6-30.7-6-48.8 0-84.6 41.7-84.6 88.9 0 43 28.5 78.7 69.5 85.9 61.5-24 72.9-117.6 72.9-175 0-7.3 0-14.8-.6-22.1-11.2-32.9-26.6-64.6-44.2-94.5 27.1 18.3 41.9 62.5 44.2 94.1v.4c7.7 22.5 11.8 46.2 11.8 70 0 54.1-21.9 99-68.3 128.2l-2.4.2c50 1 86.2-38.6 86.2-87.2 0-12.2-2.1-24.3-6.9-35.7 9.5-1.9 18.5-5.6 26.4-10.5 15.3 36.6 12.6 87.3-22.8 125.6zM309 233.7c-13.3 0-25.1-7.1-34.4-16.1 21.9-12 49.6-30.7 62.3-53 1.5-3 4.1-8.6 4.5-12-12.5 27.9-44.2 49.8-73.9 56.7-4.7-7.3-7.5-15.5-7.5-24.3 0-10.3 5.2-24.1 12.9-31.6 21.6-20.5 53-8.5 72.4-50 32.5 46.2 13.1 130.3-36.3 130.3z"],viber:[512,512,[],"f409","M444 49.9C431.3 38.2 379.9.9 265.3.4c0 0-135.1-8.1-200.9 52.3C27.8 89.3 14.9 143 13.5 209.5c-1.4 66.5-3.1 191.1 117 224.9h.1l-.1 51.6s-.8 20.9 13 25.1c16.6 5.2 26.4-10.7 42.3-27.8 8.7-9.4 20.7-23.2 29.8-33.7 82.2 6.9 145.3-8.9 152.5-11.2 16.6-5.4 110.5-17.4 125.7-142 15.8-128.6-7.6-209.8-49.8-246.5zM457.9 287c-12.9 104-89 110.6-103 115.1-6 1.9-61.5 15.7-131.2 11.2 0 0-52 62.7-68.2 79-5.3 5.3-11.1 4.8-11-5.7 0-6.9.4-85.7.4-85.7-.1 0-.1 0 0 0-101.8-28.2-95.8-134.3-94.7-189.8 1.1-55.5 11.6-101 42.6-131.6 55.7-50.5 170.4-43 170.4-43 96.9.4 143.3 29.6 154.1 39.4 35.7 30.6 53.9 103.8 40.6 211.1zm-139-80.8c.4 8.6-12.5 9.2-12.9.6-1.1-22-11.4-32.7-32.6-33.9-8.6-.5-7.8-13.4.7-12.9 27.9 1.5 43.4 17.5 44.8 46.2zm20.3 11.3c1-42.4-25.5-75.6-75.8-79.3-8.5-.6-7.6-13.5.9-12.9 58 4.2 88.9 44.1 87.8 92.5-.1 8.6-13.1 8.2-12.9-.3zm47 13.4c.1 8.6-12.9 8.7-12.9.1-.6-81.5-54.9-125.9-120.8-126.4-8.5-.1-8.5-12.9 0-12.9 73.7.5 133 51.4 133.7 139.2zM374.9 329v.2c-10.8 19-31 40-51.8 33.3l-.2-.3c-21.1-5.9-70.8-31.5-102.2-56.5-16.2-12.8-31-27.9-42.4-42.4-10.3-12.9-20.7-28.2-30.8-46.6-21.3-38.5-26-55.7-26-55.7-6.7-20.8 14.2-41 33.3-51.8h.2c9.2-4.8 18-3.2 23.9 3.9 0 0 12.4 14.8 17.7 22.1 5 6.8 11.7 17.7 15.2 23.8 6.1 10.9 2.3 22-3.7 26.6l-12 9.6c-6.1 4.9-5.3 14-5.3 14s17.8 67.3 84.3 84.3c0 0 9.1.8 14-5.3l9.6-12c4.6-6 15.7-9.8 26.6-3.7 14.7 8.3 33.4 21.2 45.8 32.9 7 5.7 8.6 14.4 3.8 23.6z"],vimeo:[448,512,[],"f40a","M403.2 32H44.8C20.1 32 0 52.1 0 76.8v358.4C0 459.9 20.1 480 44.8 480h358.4c24.7 0 44.8-20.1 44.8-44.8V76.8c0-24.7-20.1-44.8-44.8-44.8zM377 180.8c-1.4 31.5-23.4 74.7-66 129.4-44 57.2-81.3 85.8-111.7 85.8-18.9 0-34.8-17.4-47.9-52.3-25.5-93.3-36.4-148-57.4-148-2.4 0-10.9 5.1-25.4 15.2l-15.2-19.6c37.3-32.8 72.9-69.2 95.2-71.2 25.2-2.4 40.7 14.8 46.5 51.7 20.7 131.2 29.9 151 67.6 91.6 13.5-21.4 20.8-37.7 21.8-48.9 3.5-33.2-25.9-30.9-45.8-22.4 15.9-52.1 46.3-77.4 91.2-76 33.3.9 49 22.5 47.1 64.7z"],"vimeo-square":[448,512,[],"f194","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-16.2 149.6c-1.4 31.1-23.2 73.8-65.3 127.9-43.5 56.5-80.3 84.8-110.4 84.8-18.7 0-34.4-17.2-47.3-51.6-25.2-92.3-35.9-146.4-56.7-146.4-2.4 0-10.8 5-25.1 15.1L64 192c36.9-32.4 72.1-68.4 94.1-70.4 24.9-2.4 40.2 14.6 46 51.1 20.5 129.6 29.6 149.2 66.8 90.5 13.4-21.2 20.6-37.2 21.5-48.3 3.4-32.8-25.6-30.6-45.2-22.2 15.7-51.5 45.8-76.5 90.1-75.1 32.9 1 48.4 22.4 46.5 64z"],"vimeo-v":[448,512,[],"f27d","M447.8 153.6c-2 43.6-32.4 103.3-91.4 179.1-60.9 79.2-112.4 118.8-154.6 118.8-26.1 0-48.2-24.1-66.3-72.3C100.3 250 85.3 174.3 56.2 174.3c-3.4 0-15.1 7.1-35.2 21.1L0 168.2c51.6-45.3 100.9-95.7 131.8-98.5 34.9-3.4 56.3 20.5 64.4 71.5 28.7 181.5 41.4 208.9 93.6 126.7 18.7-29.6 28.8-52.1 30.2-67.6 4.8-45.9-35.8-42.8-63.3-31 22-72.1 64.1-107.1 126.2-105.1 45.8 1.2 67.5 31.1 64.9 89.4z"],vine:[384,512,[],"f1ca","M384 254.7v52.1c-18.4 4.2-36.9 6.1-52.1 6.1-36.9 77.4-103 143.8-125.1 156.2-14 7.9-27.1 8.4-42.7-.8C137 452 34.2 367.7 0 102.7h74.5C93.2 261.8 139 343.4 189.3 404.5c27.9-27.9 54.8-65.1 75.6-106.9-49.8-25.3-80.1-80.9-80.1-145.6 0-65.6 37.7-115.1 102.2-115.1 114.9 0 106.2 127.9 81.6 181.5 0 0-46.4 9.2-63.5-20.5 3.4-11.3 8.2-30.8 8.2-48.5 0-31.3-11.3-46.6-28.4-46.6-18.2 0-30.8 17.1-30.8 50 .1 79.2 59.4 118.7 129.9 101.9z"],vk:[576,512,[],"f189","M545 117.7c3.7-12.5 0-21.7-17.8-21.7h-58.9c-15 0-21.9 7.9-25.6 16.7 0 0-30 73.1-72.4 120.5-13.7 13.7-20 18.1-27.5 18.1-3.7 0-9.4-4.4-9.4-16.9V117.7c0-15-4.2-21.7-16.6-21.7h-92.6c-9.4 0-15 7-15 13.5 0 14.2 21.2 17.5 23.4 57.5v86.8c0 19-3.4 22.5-10.9 22.5-20 0-68.6-73.4-97.4-157.4-5.8-16.3-11.5-22.9-26.6-22.9H38.8c-16.8 0-20.2 7.9-20.2 16.7 0 15.6 20 93.1 93.1 195.5C160.4 378.1 229 416 291.4 416c37.5 0 42.1-8.4 42.1-22.9 0-66.8-3.4-73.1 15.4-73.1 8.7 0 23.7 4.4 58.7 38.1 40 40 46.6 57.9 69 57.9h58.9c16.8 0 25.3-8.4 20.4-25-11.2-34.9-86.9-106.7-90.3-111.5-8.7-11.2-6.2-16.2 0-26.2.1-.1 72-101.3 79.4-135.6z"],vnv:[640,512,[],"f40b","M104.9 352c-34.1 0-46.4-30.4-46.4-30.4L2.6 210.1S-7.8 192 13 192h32.8c10.4 0 13.2 8.7 18.8 18.1l36.7 74.5s5.2 13.1 21.1 13.1 21.1-13.1 21.1-13.1l36.7-74.5c5.6-9.5 8.4-18.1 18.8-18.1h32.8c20.8 0 10.4 18.1 10.4 18.1l-55.8 111.5S174.2 352 140 352h-35.1zm395 0c-34.1 0-46.4-30.4-46.4-30.4l-55.9-111.5S387.2 192 408 192h32.8c10.4 0 13.2 8.7 18.8 18.1l36.7 74.5s5.2 13.1 21.1 13.1 21.1-13.1 21.1-13.1l36.8-74.5c5.6-9.5 8.4-18.1 18.8-18.1H627c20.8 0 10.4 18.1 10.4 18.1l-55.9 111.5S569.3 352 535.1 352h-35.2zM337.6 192c34.1 0 46.4 30.4 46.4 30.4l55.9 111.5s10.4 18.1-10.4 18.1h-32.8c-10.4 0-13.2-8.7-18.8-18.1l-36.7-74.5s-5.2-13.1-21.1-13.1c-15.9 0-21.1 13.1-21.1 13.1l-36.7 74.5c-5.6 9.4-8.4 18.1-18.8 18.1h-32.9c-20.8 0-10.4-18.1-10.4-18.1l55.9-111.5s12.2-30.4 46.4-30.4h35.1z"],vuejs:[448,512,[],"f41f","M356.9 64.3H280l-56 88.6-48-88.6H0L224 448 448 64.3h-91.1zm-301.2 32h53.8L224 294.5 338.4 96.3h53.8L224 384.5 55.7 96.3z"],weibo:[512,512,[],"f18a","M407 177.6c7.6-24-13.4-46.8-37.4-41.7-22 4.8-28.8-28.1-7.1-32.8 50.1-10.9 92.3 37.1 76.5 84.8-6.8 21.2-38.8 10.8-32-10.3zM214.8 446.7C108.5 446.7 0 395.3 0 310.4c0-44.3 28-95.4 76.3-143.7C176 67 279.5 65.8 249.9 161c-4 13.1 12.3 5.7 12.3 6 79.5-33.6 140.5-16.8 114 51.4-3.7 9.4 1.1 10.9 8.3 13.1 135.7 42.3 34.8 215.2-169.7 215.2zm143.7-146.3c-5.4-55.7-78.5-94-163.4-85.7-84.8 8.6-148.8 60.3-143.4 116s78.5 94 163.4 85.7c84.8-8.6 148.8-60.3 143.4-116zM347.9 35.1c-25.9 5.6-16.8 43.7 8.3 38.3 72.3-15.2 134.8 52.8 111.7 124-7.4 24.2 29.1 37 37.4 12 31.9-99.8-55.1-195.9-157.4-174.3zm-78.5 311c-17.1 38.8-66.8 60-109.1 46.3-40.8-13.1-58-53.4-40.3-89.7 17.7-35.4 63.1-55.4 103.4-45.1 42 10.8 63.1 50.2 46 88.5zm-86.3-30c-12.9-5.4-30 .3-38 12.9-8.3 12.9-4.3 28 8.6 34 13.1 6 30.8.3 39.1-12.9 8-13.1 3.7-28.3-9.7-34zm32.6-13.4c-5.1-1.7-11.4.6-14.3 5.4-2.9 5.1-1.4 10.6 3.7 12.9 5.1 2 11.7-.3 14.6-5.4 2.8-5.2 1.1-10.9-4-12.9z"],weixin:[576,512,[],"f1d7","M385.2 167.6c6.4 0 12.6.3 18.8 1.1C387.4 90.3 303.3 32 207.7 32 100.5 32 13 104.8 13 197.4c0 53.4 29.3 97.5 77.9 131.6l-19.3 58.6 68-34.1c24.4 4.8 43.8 9.7 68.2 9.7 6.2 0 12.1-.3 18.3-.8-4-12.9-6.2-26.6-6.2-40.8-.1-84.9 72.9-154 165.3-154zm-104.5-52.9c14.5 0 24.2 9.7 24.2 24.4 0 14.5-9.7 24.2-24.2 24.2-14.8 0-29.3-9.7-29.3-24.2.1-14.7 14.6-24.4 29.3-24.4zm-136.4 48.6c-14.5 0-29.3-9.7-29.3-24.2 0-14.8 14.8-24.4 29.3-24.4 14.8 0 24.4 9.7 24.4 24.4 0 14.6-9.6 24.2-24.4 24.2zM563 319.4c0-77.9-77.9-141.3-165.4-141.3-92.7 0-165.4 63.4-165.4 141.3S305 460.7 397.6 460.7c19.3 0 38.9-5.1 58.6-9.9l53.4 29.3-14.8-48.6C534 402.1 563 363.2 563 319.4zm-219.1-24.5c-9.7 0-19.3-9.7-19.3-19.6 0-9.7 9.7-19.3 19.3-19.3 14.8 0 24.4 9.7 24.4 19.3 0 10-9.7 19.6-24.4 19.6zm107.1 0c-9.7 0-19.3-9.7-19.3-19.6 0-9.7 9.7-19.3 19.3-19.3 14.5 0 24.4 9.7 24.4 19.3.1 10-9.9 19.6-24.4 19.6z"],whatsapp:[448,512,[],"f232","M380.9 97.1C339 55.1 283.2 32 223.9 32c-122.4 0-222 99.6-222 222 0 39.1 10.2 77.3 29.6 111L0 480l117.7-30.9c32.4 17.7 68.9 27 106.1 27h.1c122.3 0 224.1-99.6 224.1-222 0-59.3-25.2-115-67.1-157zm-157 341.6c-33.2 0-65.7-8.9-94-25.7l-6.7-4-69.8 18.3L72 359.2l-4.4-7c-18.5-29.4-28.2-63.3-28.2-98.2 0-101.7 82.8-184.5 184.6-184.5 49.3 0 95.6 19.2 130.4 54.1 34.8 34.9 56.2 81.2 56.1 130.5 0 101.8-84.9 184.6-186.6 184.6zm101.2-138.2c-5.5-2.8-32.8-16.2-37.9-18-5.1-1.9-8.8-2.8-12.5 2.8-3.7 5.6-14.3 18-17.6 21.8-3.2 3.7-6.5 4.2-12 1.4-32.6-16.3-54-29.1-75.5-66-5.7-9.8 5.7-9.1 16.3-30.3 1.8-3.7.9-6.9-.5-9.7-1.4-2.8-12.5-30.1-17.1-41.2-4.5-10.8-9.1-9.3-12.5-9.5-3.2-.2-6.9-.2-10.6-.2-3.7 0-9.7 1.4-14.8 6.9-5.1 5.6-19.4 19-19.4 46.3 0 27.3 19.9 53.7 22.6 57.4 2.8 3.7 39.1 59.7 94.8 83.8 35.2 15.2 49 16.5 66.6 13.9 10.7-1.6 32.8-13.4 37.4-26.4 4.6-13 4.6-24.1 3.2-26.4-1.3-2.5-5-3.9-10.5-6.6z"],"whatsapp-square":[448,512,[],"f40c","M224 122.8c-72.7 0-131.8 59.1-131.9 131.8 0 24.9 7 49.2 20.2 70.1l3.1 5-13.3 48.6 49.9-13.1 4.8 2.9c20.2 12 43.4 18.4 67.1 18.4h.1c72.6 0 133.3-59.1 133.3-131.8 0-35.2-15.2-68.3-40.1-93.2-25-25-58-38.7-93.2-38.7zm77.5 188.4c-3.3 9.3-19.1 17.7-26.7 18.8-12.6 1.9-22.4.9-47.5-9.9-39.7-17.2-65.7-57.2-67.7-59.8-2-2.6-16.2-21.5-16.2-41s10.2-29.1 13.9-33.1c3.6-4 7.9-5 10.6-5 2.6 0 5.3 0 7.6.1 2.4.1 5.7-.9 8.9 6.8 3.3 7.9 11.2 27.4 12.2 29.4s1.7 4.3.3 6.9c-7.6 15.2-15.7 14.6-11.6 21.6 15.3 26.3 30.6 35.4 53.9 47.1 4 2 6.3 1.7 8.6-1 2.3-2.6 9.9-11.6 12.5-15.5 2.6-4 5.3-3.3 8.9-2 3.6 1.3 23.1 10.9 27.1 12.9s6.6 3 7.6 4.6c.9 1.9.9 9.9-2.4 19.1zM400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM223.9 413.2c-26.6 0-52.7-6.7-75.8-19.3L64 416l22.5-82.2c-13.9-24-21.2-51.3-21.2-79.3C65.4 167.1 136.5 96 223.9 96c42.4 0 82.2 16.5 112.2 46.5 29.9 30 47.9 69.8 47.9 112.2 0 87.4-72.7 158.5-160.1 158.5z"],whmcs:[448,512,[],"f40d","M448 161v-21.3l-28.5-8.8-2.2-10.4 20.1-20.7L427 80.4l-29 7.5-7.2-7.5 7.5-28.2-19.1-11.6-21.3 21-10.7-3.2-7-26.4h-22.6l-6.2 26.4-12.1 3.2-19.7-21-19.4 11 8.1 27.7-8.1 8.4-28.5-7.5-11 19.1 20.7 21-2.9 10.4-28.5 7.8-.3 21.7 28.8 7.5 2.4 12.1-20.1 19.9 10.4 18.5 29.6-7.5 7.2 8.6-8.1 26.9 19.9 11.6 19.4-20.4 11.6 2.9 6.7 28.5 22.6.3 6.7-28.8 11.6-3.5 20.7 21.6 20.4-12.1-8.8-28 7.8-8.1 28.8 8.8 10.3-20.1-20.9-18.8 2.2-12.1 29.1-7zm-119.2 45.2c-31.3 0-56.8-25.4-56.8-56.8s25.4-56.8 56.8-56.8 56.8 25.4 56.8 56.8c0 31.5-25.4 56.8-56.8 56.8zm72.3 16.4l46.9 14.5V277l-55.1 13.4-4.1 22.7 38.9 35.3-19.2 37.9-54-16.7-14.6 15.2 16.7 52.5-38.3 22.7-38.9-40.5-21.7 6.6-12.6 54-42.4-.5-12.6-53.6-21.7-5.6-36.4 38.4-37.4-21.7 15.2-50.5-13.7-16.1-55.5 14.1-19.7-34.8 37.9-37.4-4.8-22.8-54-14.1.5-40.9L54 219.9l5.7-19.7-38.9-39.4L41.5 125l53.6 14.1 15.2-15.7-15.2-52 36.4-20.7 36.8 39.4L191 84l11.6-52H245l11.6 45.9L234 72l-6.3-1.7-3.3 5.7-11 19.1-3.3 5.6 4.6 4.6 17.2 17.4-.3 1-23.8 6.5-6.2 1.7-.1 6.4-.2 12.9C153.8 161.6 118 204 118 254.7c0 58.3 47.3 105.7 105.7 105.7 50.5 0 92.7-35.4 103.2-82.8l13.2.2 6.9.1 1.6-6.7 5.6-24 1.9-.6 17.1 17.8 4.7 4.9 5.8-3.4 20.4-12.1 5.8-3.5-2-6.5-6.8-21.2z"],"wikipedia-w":[640,512,[],"f266","M640 51.2l-.3 12.2c-28.1.8-45 15.8-55.8 40.3-25 57.8-103.3 240-155.3 358.6H415l-81.9-193.1c-32.5 63.6-68.3 130-99.2 193.1-.3.3-15 0-15-.3C172 352.3 122.8 243.4 75.8 133.4 64.4 106.7 26.4 63.4.2 63.7c0-3.1-.3-10-.3-14.2h161.9v13.9c-19.2 1.1-52.8 13.3-43.3 34.2 21.9 49.7 103.6 240.3 125.6 288.6 15-29.7 57.8-109.2 75.3-142.8-13.9-28.3-58.6-133.9-72.8-160-9.7-17.8-36.1-19.4-55.8-19.7V49.8l142.5.3v13.1c-19.4.6-38.1 7.8-29.4 26.1 18.9 40 30.6 68.1 48.1 104.7 5.6-10.8 34.7-69.4 48.1-100.8 8.9-20.6-3.9-28.6-38.6-29.4.3-3.6 0-10.3.3-13.6 44.4-.3 111.1-.3 123.1-.6v13.6c-22.5.8-45.8 12.8-58.1 31.7l-59.2 122.8c6.4 16.1 63.3 142.8 69.2 156.7L559.2 91.8c-8.6-23.1-36.4-28.1-47.2-28.3V49.6l127.8 1.1.2.5z"],windows:[448,512,[],"f17a","M0 93.7l183.6-25.3v177.4H0V93.7zm0 324.6l183.6 25.3V268.4H0v149.9zm203.8 28L448 480V268.4H203.8v177.9zm0-380.6v180.1H448V32L203.8 65.7z"],wordpress:[512,512,[],"f19a","M61.7 169.4l101.5 278C92.2 413 43.3 340.2 43.3 256c0-30.9 6.6-60.1 18.4-86.6zm337.9 75.9c0-26.3-9.4-44.5-17.5-58.7-10.8-17.5-20.9-32.4-20.9-49.9 0-19.6 14.8-37.8 35.7-37.8.9 0 1.8.1 2.8.2-37.9-34.7-88.3-55.9-143.7-55.9-74.3 0-139.7 38.1-177.8 95.9 5 .2 9.7.3 13.7.3 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l77.5 230.4L249.8 247l-33.1-90.8c-11.5-.7-22.3-2-22.3-2-11.5-.7-10.1-18.2 1.3-17.5 0 0 35.1 2.7 56 2.7 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l76.9 228.7 21.2-70.9c9-29.4 16-50.5 16-68.7zm-139.9 29.3l-63.8 185.5c19.1 5.6 39.2 8.7 60.1 8.7 24.8 0 48.5-4.3 70.6-12.1-.6-.9-1.1-1.9-1.5-2.9l-65.4-179.2zm183-120.7c.9 6.8 1.4 14 1.4 21.9 0 21.6-4 45.8-16.2 76.2l-65 187.9C426.2 403 468.7 334.5 468.7 256c0-37-9.4-71.8-26-102.1zM504 256c0 136.8-111.3 248-248 248C119.2 504 8 392.7 8 256 8 119.2 119.2 8 256 8c136.7 0 248 111.2 248 248zm-11.4 0c0-130.5-106.2-236.6-236.6-236.6C125.5 19.4 19.4 125.5 19.4 256S125.6 492.6 256 492.6c130.5 0 236.6-106.1 236.6-236.6z"],"wordpress-simple":[512,512,[],"f411","M256 8C119.3 8 8 119.2 8 256c0 136.7 111.3 248 248 248s248-111.3 248-248C504 119.2 392.7 8 256 8zM33 256c0-32.3 6.9-63 19.3-90.7l106.4 291.4C84.3 420.5 33 344.2 33 256zm223 223c-21.9 0-43-3.2-63-9.1l66.9-194.4 68.5 187.8c.5 1.1 1 2.1 1.6 3.1-23.1 8.1-48 12.6-74 12.6zm30.7-327.5c13.4-.7 25.5-2.1 25.5-2.1 12-1.4 10.6-19.1-1.4-18.4 0 0-36.1 2.8-59.4 2.8-21.9 0-58.7-2.8-58.7-2.8-12-.7-13.4 17.7-1.4 18.4 0 0 11.4 1.4 23.4 2.1l34.7 95.2L200.6 393l-81.2-241.5c13.4-.7 25.5-2.1 25.5-2.1 12-1.4 10.6-19.1-1.4-18.4 0 0-36.1 2.8-59.4 2.8-4.2 0-9.1-.1-14.4-.3C109.6 73 178.1 33 256 33c58 0 110.9 22.2 150.6 58.5-1-.1-1.9-.2-2.9-.2-21.9 0-37.4 19.1-37.4 39.6 0 18.4 10.6 33.9 21.9 52.3 8.5 14.8 18.4 33.9 18.4 61.5 0 19.1-7.3 41.2-17 72.1l-22.2 74.3-80.7-239.6zm81.4 297.2l68.1-196.9c12.7-31.8 17-57.2 17-79.9 0-8.2-.5-15.8-1.5-22.9 17.4 31.8 27.3 68.2 27.3 107 0 82.3-44.6 154.1-110.9 192.7z"],wpbeginner:[512,512,[],"f297","M462.799 322.374C519.01 386.682 466.961 480 370.944 480c-39.602 0-78.824-17.687-100.142-50.04-6.887.356-22.702.356-29.59 0C219.848 462.381 180.588 480 141.069 480c-95.49 0-148.348-92.996-91.855-157.626C-29.925 190.523 80.479 32 256.006 32c175.632 0 285.87 158.626 206.793 290.374zm-339.647-82.972h41.529v-58.075h-41.529v58.075zm217.18 86.072v-23.839c-60.506 20.915-132.355 9.198-187.589-33.971l.246 24.897c51.101 46.367 131.746 57.875 187.343 32.913zm-150.753-86.072h166.058v-58.075H189.579v58.075z"],wpexplorer:[512,512,[],"f2de","M512 256c0 141.2-114.7 256-256 256C114.8 512 0 397.3 0 256S114.7 0 256 0s256 114.7 256 256zm-32 0c0-123.2-100.3-224-224-224C132.5 32 32 132.5 32 256s100.5 224 224 224 224-100.5 224-224zM160.9 124.6l86.9 37.1-37.1 86.9-86.9-37.1 37.1-86.9zm110 169.1l46.6 94h-14.6l-50-100-48.9 100h-14l51.1-106.9-22.3-9.4 6-14 68.6 29.1-6 14.3-16.5-7.1zm-11.8-116.3l68.6 29.4-29.4 68.3L230 246l29.1-68.6zm80.3 42.9l54.6 23.1-23.4 54.3-54.3-23.1 23.1-54.3z"],wpforms:[448,512,[],"f298","M448 75.2v361.7c0 24.3-19 43.2-43.2 43.2H43.2C19.3 480 0 461.4 0 436.8V75.2C0 51.1 18.8 32 43.2 32h361.7c24 0 43.1 18.8 43.1 43.2zm-37.3 361.6V75.2c0-3-2.6-5.8-5.8-5.8h-9.3L285.3 144 224 94.1 162.8 144 52.5 69.3h-9.3c-3.2 0-5.8 2.8-5.8 5.8v361.7c0 3 2.6 5.8 5.8 5.8h361.7c3.2.1 5.8-2.7 5.8-5.8zM150.2 186v37H76.7v-37h73.5zm0 74.4v37.3H76.7v-37.3h73.5zm11.1-147.3l54-43.7H96.8l64.5 43.7zm210 72.9v37h-196v-37h196zm0 74.4v37.3h-196v-37.3h196zm-84.6-147.3l64.5-43.7H232.8l53.9 43.7zM371.3 335v37.3h-99.4V335h99.4z"],xbox:[512,512,[],"f412","M369.9 318.2c44.3 54.3 64.7 98.8 54.4 118.7-7.9 15.1-56.7 44.6-92.6 55.9-29.6 9.3-68.4 13.3-100.4 10.2-38.2-3.7-76.9-17.4-110.1-39C93.3 445.8 87 438.3 87 423.4c0-29.9 32.9-82.3 89.2-142.1 32-33.9 76.5-73.7 81.4-72.6 9.4 2.1 84.3 75.1 112.3 109.5zM188.6 143.8c-29.7-26.9-58.1-53.9-86.4-63.4-15.2-5.1-16.3-4.8-28.7 8.1-29.2 30.4-53.5 79.7-60.3 122.4-5.4 34.2-6.1 43.8-4.2 60.5 5.6 50.5 17.3 85.4 40.5 120.9 9.5 14.6 12.1 17.3 9.3 9.9-4.2-11-.3-37.5 9.5-64 14.3-39 53.9-112.9 120.3-194.4zm311.6 63.5C483.3 127.3 432.7 77 425.6 77c-7.3 0-24.2 6.5-36 13.9-23.3 14.5-41 31.4-64.3 52.8C367.7 197 427.5 283.1 448.2 346c6.8 20.7 9.7 41.1 7.4 52.3-1.7 8.5-1.7 8.5 1.4 4.6 6.1-7.7 19.9-31.3 25.4-43.5 7.4-16.2 15-40.2 18.6-58.7 4.3-22.5 3.9-70.8-.8-93.4zM141.3 43C189 40.5 251 77.5 255.6 78.4c.7.1 10.4-4.2 21.6-9.7 63.9-31.1 94-25.8 107.4-25.2-63.9-39.3-152.7-50-233.9-11.7-23.4 11.1-24 11.9-9.4 11.2z"],xing:[384,512,[],"f168","M162.7 210c-1.8 3.3-25.2 44.4-70.1 123.5-4.9 8.3-10.8 12.5-17.7 12.5H9.8c-7.7 0-12.1-7.5-8.5-14.4l69-121.3c.2 0 .2-.1 0-.3l-43.9-75.6c-4.3-7.8.3-14.1 8.5-14.1H100c7.3 0 13.3 4.1 18 12.2l44.7 77.5zM382.6 46.1l-144 253v.3L330.2 466c3.9 7.1.2 14.1-8.5 14.1h-65.2c-7.6 0-13.6-4-18-12.2l-92.4-168.5c3.3-5.8 51.5-90.8 144.8-255.2 4.6-8.1 10.4-12.2 17.5-12.2h65.7c8 0 12.3 6.7 8.5 14.1z"],"xing-square":[448,512,[],"f169","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM140.4 320.2H93.8c-5.5 0-8.7-5.3-6-10.3l49.3-86.7c.1 0 .1-.1 0-.2l-31.4-54c-3-5.6.2-10.1 6-10.1h46.6c5.2 0 9.5 2.9 12.9 8.7l31.9 55.3c-1.3 2.3-18 31.7-50.1 88.2-3.5 6.2-7.7 9.1-12.6 9.1zm219.7-214.1L257.3 286.8v.2l65.5 119c2.8 5.1.1 10.1-6 10.1h-46.6c-5.5 0-9.7-2.9-12.9-8.7l-66-120.3c2.3-4.1 36.8-64.9 103.4-182.3 3.3-5.8 7.4-8.7 12.5-8.7h46.9c5.7-.1 8.8 4.7 6 10z"],"y-combinator":[448,512,[],"f23b","M448 32v448H0V32h448zM236 287.5L313.5 142h-32.7L235 233c-4.7 9.3-9 18.3-12.8 26.8L210 233l-45.2-91h-35l76.7 143.8v94.5H236v-92.8z"],yahoo:[448,512,[],"f19e","M252 292l4 220c-12.7-2.2-23.5-3.9-32.3-3.9-8.4 0-19.2 1.7-32.3 3.9l4-220C140.4 197.2 85 95.2 21.4 0c11.9 3.1 23 3.9 33.2 3.9 9 0 20.4-.8 34.1-3.9 40.9 72.2 82.1 138.7 135 225.5C261 163.9 314.8 81.4 358.6 0c11.1 2.9 22 3.9 32.9 3.9 11.5 0 23.2-1 35-3.9C392.1 47.9 294.9 216.9 252 292z"],yandex:[256,512,[],"f413","M153.1 315.8L65.7 512H2l96-209.8c-45.1-22.9-75.2-64.4-75.2-141.1C22.7 53.7 90.8 0 171.7 0H254v512h-55.1V315.8h-45.8zm45.8-269.3h-29.4c-44.4 0-87.4 29.4-87.4 114.6 0 82.3 39.4 108.8 87.4 108.8h29.4V46.5z"],"yandex-international":[320,512,[],"f414","M129.5 512V345.9L18.5 48h55.8l81.8 229.7L250.2 0h51.3L180.8 347.8V512h-51.3z"],yelp:[384,512,[],"f1e9","M136.9 328c-1 .3-109.2 35.7-115.8 35.7-15.2-.9-18.5-16.2-19.9-31.2-1.5-14.2-1.4-29.8.3-46.8 1.9-18.8 5.5-45.1 24.2-44 4.8 0 67.1 25.9 112.7 44.4 17.1 6.8 18.6 35.8-1.5 41.9zm57.9-113.9c1.8 38.2-25.5 48.5-47.2 14.3L41.3 60.4c-1.5-6.6.3-12.4 5.3-17.4C62.2 26.5 146 3.2 168.1 8.9c7.5 1.9 12.1 6.1 13.8 12.6 1.3 8.3 11.5 167.4 12.9 192.6zm-1.4 164.8c0 4.6.2 116.4-1.7 121.5-2.3 6-7 9.7-14.3 11.2-10.1 1.7-27.1-1.9-51-10.7-22-8.1-56.7-21.5-49.3-42.5 2.8-6.9 51.4-62.8 77.3-93.6 12-15.2 39.8-5.5 39 14.1zm180.2-117.8c-5.6 3.7-110.8 28.2-118.1 30.6l.3-.6c-18.1 4.7-35.4-18.5-23.3-34.6 3.7-3.7 65.9-92.4 72.8-97 5.2-3.6 11.3-3.8 18.3-.6 18.4 8.8 55.1 63.1 57.4 84.6-.1 2.9 1.2 11.7-7.4 17.6zm10.1 130.7c-2.7 20.6-44.5 73.4-63.8 81-6.9 2.6-12.9 2-17.7-2-5-3.5-61.8-97.1-64.9-102.3-10.9-16.2 6.8-39.8 25.6-33.2 0 0 110.5 35.7 114.7 39.4 5.2 4.1 7.2 9.8 6.1 17.1z"],yoast:[448,512,[],"f2b1","M91.3 76h186l-7 18.9h-179c-39.7 0-71.9 31.6-71.9 70.3v205.4c0 35.4 24.9 70.3 84 70.3V460H91.3C41.2 460 0 419.8 0 370.5V165.2C0 115.9 40.7 76 91.3 76zm229.1-56h66.5C243.1 398.1 241.2 418.9 202.2 459.3c-20.8 21.6-49.3 31.7-78.3 32.7v-51.1c49.2-7.7 64.6-49.9 64.6-75.3 0-20.1.6-12.6-82.1-223.2h61.4L218.2 299 320.4 20zM448 161.5V460H234c6.6-9.6 10.7-16.3 12.1-19.4h182.5V161.5c0-32.5-17.1-51.9-48.2-62.9l6.7-17.6c41.7 13.6 60.9 43.1 60.9 80.5z"],youtube:[576,512,[],"f167","M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305zm-317.51 213.508V175.185l142.739 81.205-142.739 81.201z"],"youtube-square":[448,512,[],"f431","M186.8 202.1l95.2 54.1-95.2 54.1V202.1zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-42 176.3s0-59.6-7.6-88.2c-4.2-15.8-16.5-28.2-32.2-32.4C337.9 128 224 128 224 128s-113.9 0-142.2 7.7c-15.7 4.2-28 16.6-32.2 32.4-7.6 28.5-7.6 88.2-7.6 88.2s0 59.6 7.6 88.2c4.2 15.8 16.5 27.7 32.2 31.9C110.1 384 224 384 224 384s113.9 0 142.2-7.7c15.7-4.2 28-16.1 32.2-31.9 7.6-28.5 7.6-88.1 7.6-88.1z"]};!function(c){try{c()}catch(c){if(!e)throw c}}(function(){!function c(l,v){var h=Object.keys(v).reduce(function(c,l){var h=v[l];return h.icon?c[h.iconName]=h.icon:c[l]=h,c},{});"function"==typeof t.hooks.addPack?t.hooks.addPack(l,h):t.styles[l]=f({},t.styles[l]||{},h),"fas"===l&&c("fa",v)}("fab",r)})}(),function(){"use strict";var c={};try{"undefined"!=typeof window&&(c=window)}catch(c){}var l=(c.navigator||{}).userAgent,h=void 0===l?"":l,v=c,z=(~h.indexOf("MSIE")||h.indexOf("Trident/"),"___FONT_AWESOME___"),e=function(){try{return!0}catch(c){return!1}}(),a=[1,2,3,4,5,6,7,8,9,10],m=a.concat([11,12,13,14,15,16,17,18,19,20]);["xs","sm","lg","fw","ul","li","border","pull-left","pull-right","spin","pulse","rotate-90","rotate-180","rotate-270","flip-horizontal","flip-vertical","stack","stack-1x","stack-2x","inverse","layers","layers-text","layers-counter"].concat(a.map(function(c){return c+"x"})).concat(m.map(function(c){return"w-"+c}));var s=v||{};s[z]||(s[z]={}),s[z].styles||(s[z].styles={}),s[z].hooks||(s[z].hooks={}),s[z].shims||(s[z].shims=[]);var t=s[z],f=Object.assign||function(c){for(var l=1;l<arguments.length;l++){var h=arguments[l];for(var v in h)Object.prototype.hasOwnProperty.call(h,v)&&(c[v]=h[v])}return c};var r={"address-book":[448,512,[],"f2b9","M436 160c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20V48c0-26.51-21.49-48-48-48H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h320c26.51 0 48-21.49 48-48v-48h20c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20v-64h20c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20v-64h20zm-74 304H54a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h308a6 6 0 0 1 6 6v404a6 6 0 0 1-6 6zM128 208c0-44.183 35.817-80 80-80s80 35.817 80 80-35.817 80-80 80-80-35.817-80-80zm208 133.477V360c0 13.255-10.745 24-24 24H104c-13.255 0-24-10.745-24-24v-18.523c0-22.026 14.99-41.225 36.358-46.567l35.657-8.914c29.101 20.932 74.509 26.945 111.97 0l35.657 8.914C321.01 300.252 336 319.452 336 341.477z"],"address-card":[512,512,[],"f2bb","M464 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm-6 336H54a6 6 0 0 1-6-6V118a6 6 0 0 1 6-6h404a6 6 0 0 1 6 6v276a6 6 0 0 1-6 6zm-54-176H300c-6.627 0-12-5.373-12-12v-16c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v16c0 6.627-5.373 12-12 12zm0 72H300c-6.627 0-12-5.373-12-12v-16c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v16c0 6.627-5.373 12-12 12zM176 160c33.137 0 60 26.863 60 60s-26.863 60-60 60-60-26.863-60-60 26.863-60 60-60zm68.731 125.183l-26.742-6.686c-28.096 20.209-62.152 15.699-83.978 0l-26.742 6.686C91.243 289.189 80 303.589 80 320.108V334c0 9.941 8.059 18 18 18h156c9.941 0 18-8.059 18-18v-13.892c0-16.519-11.243-30.919-27.269-34.925z"],"arrow-alt-circle-down":[512,512,[],"f358","M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm-32-316v116h-67c-10.7 0-16 12.9-8.5 20.5l99 99c4.7 4.7 12.3 4.7 17 0l99-99c7.6-7.6 2.2-20.5-8.5-20.5h-67V140c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12z"],"arrow-alt-circle-left":[512,512,[],"f359","M8 256c0 137 111 248 248 248s248-111 248-248S393 8 256 8 8 119 8 256zm448 0c0 110.5-89.5 200-200 200S56 366.5 56 256 145.5 56 256 56s200 89.5 200 200zm-72-20v40c0 6.6-5.4 12-12 12H256v67c0 10.7-12.9 16-20.5 8.5l-99-99c-4.7-4.7-4.7-12.3 0-17l99-99c7.6-7.6 20.5-2.2 20.5 8.5v67h116c6.6 0 12 5.4 12 12z"],"arrow-alt-circle-right":[512,512,[],"f35a","M504 256C504 119 393 8 256 8S8 119 8 256s111 248 248 248 248-111 248-248zm-448 0c0-110.5 89.5-200 200-200s200 89.5 200 200-89.5 200-200 200S56 366.5 56 256zm72 20v-40c0-6.6 5.4-12 12-12h116v-67c0-10.7 12.9-16 20.5-8.5l99 99c4.7 4.7 4.7 12.3 0 17l-99 99c-7.6 7.6-20.5 2.2-20.5-8.5v-67H140c-6.6 0-12-5.4-12-12z"],"arrow-alt-circle-up":[512,512,[],"f35b","M256 504c137 0 248-111 248-248S393 8 256 8 8 119 8 256s111 248 248 248zm0-448c110.5 0 200 89.5 200 200s-89.5 200-200 200S56 366.5 56 256 145.5 56 256 56zm20 328h-40c-6.6 0-12-5.4-12-12V256h-67c-10.7 0-16-12.9-8.5-20.5l99-99c4.7-4.7 12.3-4.7 17 0l99 99c7.6 7.6 2.2 20.5-8.5 20.5h-67v116c0 6.6-5.4 12-12 12z"],bell:[448,512,[],"f0f3","M425.403 330.939c-16.989-16.785-34.546-34.143-34.546-116.083 0-83.026-60.958-152.074-140.467-164.762A31.843 31.843 0 0 0 256 32c0-17.673-14.327-32-32-32s-32 14.327-32 32a31.848 31.848 0 0 0 5.609 18.095C118.101 62.783 57.143 131.831 57.143 214.857c0 81.933-17.551 99.292-34.543 116.078C-25.496 378.441 9.726 448 66.919 448H160c0 35.346 28.654 64 64 64 35.346 0 64-28.654 64-64h93.08c57.19 0 92.415-69.583 44.323-117.061zM224 472c-13.234 0-24-10.766-24-24h48c0 13.234-10.766 24-24 24zm157.092-72H66.9c-16.762 0-25.135-20.39-13.334-32.191 28.585-28.585 51.577-55.724 51.577-152.952C105.143 149.319 158.462 96 224 96s118.857 53.319 118.857 118.857c0 97.65 23.221 124.574 51.568 152.952C406.278 379.661 397.783 400 381.092 400z"],"bell-slash":[576,512,[],"f1f6","M130.9 400c-16.762 0-25.135-20.39-13.334-32.191 25.226-25.226 46.094-49.338 50.649-121.48l-46.777-41.274a168.48 168.48 0 0 0-.296 9.802c0 81.933-17.551 99.292-34.543 116.078C38.504 378.441 73.726 448 130.919 448H224c0 35.346 28.654 64 64 64s64-28.654 64-64h44.777l-54.4-48H130.9zM288 472c-13.234 0-24-10.766-24-24h48c0 13.234-10.766 24-24 24zm283.867.553l-67.931-59.571c13.104-24.118 11.524-56.318-14.532-82.042-16.989-16.785-34.546-34.143-34.546-116.083 0-83.026-60.958-152.074-140.467-164.762A31.848 31.848 0 0 0 320 32c0-17.673-14.327-32-32-32s-32 14.327-32 32a31.848 31.848 0 0 0 5.609 18.095c-41.471 6.618-77.891 28.571-103.249 59.841L36.459 3.037c-5.058-4.436-12.777-3.956-17.24 1.071L3.056 22.313C-1.407 27.34-.925 35.012 4.134 39.447l535.408 469.516c5.058 4.436 12.777 3.956 17.24-1.071l16.163-18.205c4.462-5.027 3.98-12.699-1.078-17.134zM288 96c65.538 0 118.857 53.319 118.857 118.857 0 97.65 23.221 124.574 51.568 152.952 2.908 2.908 4.573 6.328 5.209 9.832L194.482 141.612C216.258 113.867 250.075 96 288 96z"],bookmark:[384,512,[],"f02e","M336 0H48C21.49 0 0 21.49 0 48v464l192-112 192 112V48c0-26.51-21.49-48-48-48zm0 428.43l-144-84-144 84V54a6 6 0 0 1 6-6h276c3.314 0 6 2.683 6 5.996V428.43z"],building:[448,512,[],"f1ad","M128 148v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12zm140 12h40c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12zm-128 96h40c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12zm128 0h40c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12zm-76 84v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm76 12h40c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12zm180 124v36H0v-36c0-6.6 5.4-12 12-12h19.5V24c0-13.3 10.7-24 24-24h337c13.3 0 24 10.7 24 24v440H436c6.6 0 12 5.4 12 12zM79.5 463H192v-67c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v67h112.5V49L80 48l-.5 415z"],calendar:[448,512,[],"f133","M400 64h-48V12c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v52H160V12c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v52H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zm-6 400H54c-3.3 0-6-2.7-6-6V160h352v298c0 3.3-2.7 6-6 6z"],"calendar-alt":[448,512,[],"f073","M148 288h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12zm108-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm96 0v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm-96 96v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm-96 0v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm192 0v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm96-260v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48zm-48 346V160H48v298c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"],"calendar-check":[448,512,[],"f274","M400 64h-48V12c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v52H160V12c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v52H48C21.49 64 0 85.49 0 112v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm-6 400H54a6 6 0 0 1-6-6V160h352v298a6 6 0 0 1-6 6zm-52.849-200.65L198.842 404.519c-4.705 4.667-12.303 4.637-16.971-.068l-75.091-75.699c-4.667-4.705-4.637-12.303.068-16.971l22.719-22.536c4.705-4.667 12.303-4.637 16.97.069l44.104 44.461 111.072-110.181c4.705-4.667 12.303-4.637 16.971.068l22.536 22.718c4.667 4.705 4.636 12.303-.069 16.97z"],"calendar-minus":[448,512,[],"f272","M124 328c-6.6 0-12-5.4-12-12v-24c0-6.6 5.4-12 12-12h200c6.6 0 12 5.4 12 12v24c0 6.6-5.4 12-12 12H124zm324-216v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48zm-48 346V160H48v298c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"],"calendar-plus":[448,512,[],"f271","M336 292v24c0 6.6-5.4 12-12 12h-76v76c0 6.6-5.4 12-12 12h-24c-6.6 0-12-5.4-12-12v-76h-76c-6.6 0-12-5.4-12-12v-24c0-6.6 5.4-12 12-12h76v-76c0-6.6 5.4-12 12-12h24c6.6 0 12 5.4 12 12v76h76c6.6 0 12 5.4 12 12zm112-180v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48zm-48 346V160H48v298c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"],"calendar-times":[448,512,[],"f273","M311.7 374.7l-17 17c-4.7 4.7-12.3 4.7-17 0L224 337.9l-53.7 53.7c-4.7 4.7-12.3 4.7-17 0l-17-17c-4.7-4.7-4.7-12.3 0-17l53.7-53.7-53.7-53.7c-4.7-4.7-4.7-12.3 0-17l17-17c4.7-4.7 12.3-4.7 17 0l53.7 53.7 53.7-53.7c4.7-4.7 12.3-4.7 17 0l17 17c4.7 4.7 4.7 12.3 0 17L257.9 304l53.7 53.7c4.8 4.7 4.8 12.3.1 17zM448 112v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48zm-48 346V160H48v298c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"],"caret-square-down":[448,512,[],"f150","M125.1 208h197.8c10.7 0 16.1 13 8.5 20.5l-98.9 98.3c-4.7 4.7-12.2 4.7-16.9 0l-98.9-98.3c-7.7-7.5-2.3-20.5 8.4-20.5zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"],"caret-square-left":[448,512,[],"f191","M272 157.1v197.8c0 10.7-13 16.1-20.5 8.5l-98.3-98.9c-4.7-4.7-4.7-12.2 0-16.9l98.3-98.9c7.5-7.7 20.5-2.3 20.5 8.4zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"],"caret-square-right":[448,512,[],"f152","M176 354.9V157.1c0-10.7 13-16.1 20.5-8.5l98.3 98.9c4.7 4.7 4.7 12.2 0 16.9l-98.3 98.9c-7.5 7.7-20.5 2.3-20.5-8.4zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"],"caret-square-up":[448,512,[],"f151","M322.9 304H125.1c-10.7 0-16.1-13-8.5-20.5l98.9-98.3c4.7-4.7 12.2-4.7 16.9 0l98.9 98.3c7.7 7.5 2.3 20.5-8.4 20.5zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"],"chart-bar":[512,512,[],"f080","M500 400c6.6 0 12 5.4 12 12v24c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h24c6.6 0 12 5.4 12 12v324h452zm-356-60v-72c0-6.6-5.4-12-12-12h-24c-6.6 0-12 5.4-12 12v72c0 6.6 5.4 12 12 12h24c6.6 0 12-5.4 12-12zm96 0V140c0-6.6-5.4-12-12-12h-24c-6.6 0-12 5.4-12 12v200c0 6.6 5.4 12 12 12h24c6.6 0 12-5.4 12-12zm96 0V204c0-6.6-5.4-12-12-12h-24c-6.6 0-12 5.4-12 12v136c0 6.6 5.4 12 12 12h24c6.6 0 12-5.4 12-12zm96 0V108c0-6.6-5.4-12-12-12h-24c-6.6 0-12 5.4-12 12v232c0 6.6 5.4 12 12 12h24c6.6 0 12-5.4 12-12z"],"check-circle":[512,512,[],"f058","M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 48c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m140.204 130.267l-22.536-22.718c-4.667-4.705-12.265-4.736-16.97-.068L215.346 303.697l-59.792-60.277c-4.667-4.705-12.265-4.736-16.97-.069l-22.719 22.536c-4.705 4.667-4.736 12.265-.068 16.971l90.781 91.516c4.667 4.705 12.265 4.736 16.97.068l172.589-171.204c4.704-4.668 4.734-12.266.067-16.971z"],"check-square":[448,512,[],"f14a","M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zm0 400H48V80h352v352zm-35.864-241.724L191.547 361.48c-4.705 4.667-12.303 4.637-16.97-.068l-90.781-91.516c-4.667-4.705-4.637-12.303.069-16.971l22.719-22.536c4.705-4.667 12.303-4.637 16.97.069l59.792 60.277 141.352-140.216c4.705-4.667 12.303-4.637 16.97.068l22.536 22.718c4.667 4.706 4.637 12.304-.068 16.971z"],circle:[512,512,[],"f111","M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200z"],clipboard:[384,512,[],"f328","M336 64h-80c0-35.29-28.71-64-64-64s-64 28.71-64 64H48C21.49 64 0 85.49 0 112v352c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm-6 400H54a6 6 0 0 1-6-6V118a6 6 0 0 1 6-6h42v36c0 6.627 5.373 12 12 12h168c6.627 0 12-5.373 12-12v-36h42a6 6 0 0 1 6 6v340a6 6 0 0 1-6 6zM192 40c13.255 0 24 10.745 24 24s-10.745 24-24 24-24-10.745-24-24 10.745-24 24-24"],clock:[512,512,[],"f017","M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm61.8-104.4l-84.9-61.7c-3.1-2.3-4.9-5.9-4.9-9.7V116c0-6.6 5.4-12 12-12h32c6.6 0 12 5.4 12 12v141.7l66.8 48.6c5.4 3.9 6.5 11.4 2.6 16.8L334.6 349c-3.9 5.3-11.4 6.5-16.8 2.6z"],clone:[512,512,[],"f24d","M464 0H144c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h320c26.51 0 48-21.49 48-48v-48h48c26.51 0 48-21.49 48-48V48c0-26.51-21.49-48-48-48zM362 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h42v224c0 26.51 21.49 48 48 48h224v42a6 6 0 0 1-6 6zm96-96H150a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h308a6 6 0 0 1 6 6v308a6 6 0 0 1-6 6z"],"closed-captioning":[512,512,[],"f20a","M464 64H48C21.5 64 0 85.5 0 112v288c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zm-6 336H54c-3.3 0-6-2.7-6-6V118c0-3.3 2.7-6 6-6h404c3.3 0 6 2.7 6 6v276c0 3.3-2.7 6-6 6zm-211.1-85.7c1.7 2.4 1.5 5.6-.5 7.7-53.6 56.8-172.8 32.1-172.8-67.9 0-97.3 121.7-119.5 172.5-70.1 2.1 2 2.5 3.2 1 5.7l-17.5 30.5c-1.9 3.1-6.2 4-9.1 1.7-40.8-32-94.6-14.9-94.6 31.2 0 48 51 70.5 92.2 32.6 2.8-2.5 7.1-2.1 9.2.9l19.6 27.7zm190.4 0c1.7 2.4 1.5 5.6-.5 7.7-53.6 56.9-172.8 32.1-172.8-67.9 0-97.3 121.7-119.5 172.5-70.1 2.1 2 2.5 3.2 1 5.7L420 220.2c-1.9 3.1-6.2 4-9.1 1.7-40.8-32-94.6-14.9-94.6 31.2 0 48 51 70.5 92.2 32.6 2.8-2.5 7.1-2.1 9.2.9l19.6 27.7z"],comment:[512,512,[],"f075","M256 32C114.6 32 0 125.1 0 240c0 47.6 19.9 91.2 52.9 126.3C38 405.7 7 439.1 6.5 439.5c-6.6 7-8.4 17.2-4.6 26S14.4 480 24 480c61.5 0 110-25.7 139.1-46.3C192 442.8 223.2 448 256 448c141.4 0 256-93.1 256-208S397.4 32 256 32zm0 368c-26.7 0-53.1-4.1-78.4-12.1l-22.7-7.2-19.5 13.8c-14.3 10.1-33.9 21.4-57.5 29 7.3-12.1 14.4-25.7 19.9-40.2l10.6-28.1-20.6-21.8C69.7 314.1 48 282.2 48 240c0-88.2 93.3-160 208-160s208 71.8 208 160-93.3 160-208 160z"],"comment-alt":[512,512,[],"f27a","M448 0H64C28.7 0 0 28.7 0 64v288c0 35.3 28.7 64 64 64h96v84c0 7.1 5.8 12 12 12 2.4 0 4.9-.7 7.1-2.4L304 416h144c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64zm16 352c0 8.8-7.2 16-16 16H288l-12.8 9.6L208 428v-60H64c-8.8 0-16-7.2-16-16V64c0-8.8 7.2-16 16-16h384c8.8 0 16 7.2 16 16v288z"],comments:[576,512,[],"f086","M532 386.2c27.5-27.1 44-61.1 44-98.2 0-80-76.5-146.1-176.2-157.9C368.3 72.5 294.3 32 208 32 93.1 32 0 103.6 0 192c0 37 16.5 71 44 98.2-15.3 30.7-37.3 54.5-37.7 54.9-6.3 6.7-8.1 16.5-4.4 25 3.6 8.5 12 14 21.2 14 53.5 0 96.7-20.2 125.2-38.8 9.2 2.1 18.7 3.7 28.4 4.9C208.1 407.6 281.8 448 368 448c20.8 0 40.8-2.4 59.8-6.8C456.3 459.7 499.4 480 553 480c9.2 0 17.5-5.5 21.2-14 3.6-8.5 1.9-18.3-4.4-25-.4-.3-22.5-24.1-37.8-54.8zm-392.8-92.3L122.1 305c-14.1 9.1-28.5 16.3-43.1 21.4 2.7-4.7 5.4-9.7 8-14.8l15.5-31.1L77.7 256C64.2 242.6 48 220.7 48 192c0-60.7 73.3-112 160-112s160 51.3 160 112-73.3 112-160 112c-16.5 0-33-1.9-49-5.6l-19.8-4.5zM498.3 352l-24.7 24.4 15.5 31.1c2.6 5.1 5.3 10.1 8 14.8-14.6-5.1-29-12.3-43.1-21.4l-17.1-11.1-19.9 4.6c-16 3.7-32.5 5.6-49 5.6-54 0-102.2-20.1-131.3-49.7C338 339.5 416 272.9 416 192c0-3.4-.4-6.7-.7-10C479.7 196.5 528 238.8 528 288c0 28.7-16.2 50.6-29.7 64z"],compass:[512,512,[],"f14e","M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 448c-110.532 0-200-89.451-200-200 0-110.531 89.451-200 200-200 110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200zm91.326-312.131l-33.359 137.779a24.005 24.005 0 0 1-6.772 11.729l-102.64 97.779c-17.104 16.293-45.56.434-39.88-23.024l33.359-137.779a23.997 23.997 0 0 1 6.772-11.729l102.642-97.779c17.285-16.47 45.494-.175 39.878 23.024zM256 224c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32z"],copy:[448,512,[],"f0c5","M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"],copyright:[512,512,[],"f1f9","M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 448c-110.532 0-200-89.451-200-200 0-110.531 89.451-200 200-200 110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200zm107.351-101.064c-9.614 9.712-45.53 41.396-104.065 41.396-82.43 0-140.484-61.425-140.484-141.567 0-79.152 60.275-139.401 139.762-139.401 55.531 0 88.738 26.62 97.593 34.779a11.965 11.965 0 0 1 1.936 15.322l-18.155 28.113c-3.841 5.95-11.966 7.282-17.499 2.921-8.595-6.776-31.814-22.538-61.708-22.538-48.303 0-77.916 35.33-77.916 80.082 0 41.589 26.888 83.692 78.277 83.692 32.657 0 56.843-19.039 65.726-27.225 5.27-4.857 13.596-4.039 17.82 1.738l19.865 27.17a11.947 11.947 0 0 1-1.152 15.518z"],"credit-card":[576,512,[],"f09d","M527.9 32H48.1C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48.1 48h479.8c26.6 0 48.1-21.5 48.1-48V80c0-26.5-21.5-48-48.1-48zM54.1 80h467.8c3.3 0 6 2.7 6 6v42H48.1V86c0-3.3 2.7-6 6-6zm467.8 352H54.1c-3.3 0-6-2.7-6-6V256h479.8v170c0 3.3-2.7 6-6 6zM192 332v40c0 6.6-5.4 12-12 12h-72c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h72c6.6 0 12 5.4 12 12zm192 0v40c0 6.6-5.4 12-12 12H236c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h136c6.6 0 12 5.4 12 12z"],"dot-circle":[512,512,[],"f192","M256 56c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m0-48C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 168c-44.183 0-80 35.817-80 80s35.817 80 80 80 80-35.817 80-80-35.817-80-80-80z"],edit:[576,512,[],"f044","M402.3 344.9l32-32c5-5 13.7-1.5 13.7 5.7V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h273.5c7.1 0 10.7 8.6 5.7 13.7l-32 32c-1.5 1.5-3.5 2.3-5.7 2.3H48v352h352V350.5c0-2.1.8-4.1 2.3-5.6zm156.6-201.8L296.3 405.7l-90.4 10c-26.2 2.9-48.5-19.2-45.6-45.6l10-90.4L432.9 17.1c22.9-22.9 59.9-22.9 82.7 0l43.2 43.2c22.9 22.9 22.9 60 .1 82.8zM460.1 174L402 115.9 216.2 301.8l-7.3 65.3 65.3-7.3L460.1 174zm64.8-79.7l-43.2-43.2c-4.1-4.1-10.8-4.1-14.8 0L436 82l58.1 58.1 30.9-30.9c4-4.2 4-10.8-.1-14.9z"],envelope:[512,512,[],"f0e0","M464 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm0 48v40.805c-22.422 18.259-58.168 46.651-134.587 106.49-16.841 13.247-50.201 45.072-73.413 44.701-23.208.375-56.579-31.459-73.413-44.701C106.18 199.465 70.425 171.067 48 152.805V112h416zM48 400V214.398c22.914 18.251 55.409 43.862 104.938 82.646 21.857 17.205 60.134 55.186 103.062 54.955 42.717.231 80.509-37.199 103.053-54.947 49.528-38.783 82.032-64.401 104.947-82.653V400H48z"],"envelope-open":[512,512,[],"f2b6","M494.586 164.516c-4.697-3.883-111.723-89.95-135.251-108.657C337.231 38.191 299.437 0 256 0c-43.205 0-80.636 37.717-103.335 55.859-24.463 19.45-131.07 105.195-135.15 108.549A48.004 48.004 0 0 0 0 201.485V464c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V201.509a48 48 0 0 0-17.414-36.993zM464 458a6 6 0 0 1-6 6H54a6 6 0 0 1-6-6V204.347c0-1.813.816-3.526 2.226-4.665 15.87-12.814 108.793-87.554 132.364-106.293C200.755 78.88 232.398 48 256 48c23.693 0 55.857 31.369 73.41 45.389 23.573 18.741 116.503 93.493 132.366 106.316a5.99 5.99 0 0 1 2.224 4.663V458zm-31.991-187.704c4.249 5.159 3.465 12.795-1.745 16.981-28.975 23.283-59.274 47.597-70.929 56.863C336.636 362.283 299.205 400 256 400c-43.452 0-81.287-38.237-103.335-55.86-11.279-8.967-41.744-33.413-70.927-56.865-5.21-4.187-5.993-11.822-1.745-16.981l15.258-18.528c4.178-5.073 11.657-5.843 16.779-1.726 28.618 23.001 58.566 47.035 70.56 56.571C200.143 320.631 232.307 352 256 352c23.602 0 55.246-30.88 73.41-45.389 11.994-9.535 41.944-33.57 70.563-56.568 5.122-4.116 12.601-3.346 16.778 1.727l15.258 18.526z"],"eye-slash":[576,512,[],"f070","M272.702 359.139c-80.483-9.011-136.212-86.886-116.93-167.042l116.93 167.042zM288 392c-102.556 0-192.092-54.701-240-136 21.755-36.917 52.1-68.342 88.344-91.658l-27.541-39.343C67.001 152.234 31.921 188.741 6.646 231.631a47.999 47.999 0 0 0 0 48.739C63.004 376.006 168.14 440 288 440a332.89 332.89 0 0 0 39.648-2.367l-32.021-45.744A284.16 284.16 0 0 1 288 392zm281.354-111.631c-33.232 56.394-83.421 101.742-143.554 129.492l48.116 68.74c3.801 5.429 2.48 12.912-2.949 16.712L450.23 509.83c-5.429 3.801-12.912 2.48-16.712-2.949L102.084 33.399c-3.801-5.429-2.48-12.912 2.949-16.712L125.77 2.17c5.429-3.801 12.912-2.48 16.712 2.949l55.526 79.325C226.612 76.343 256.808 72 288 72c119.86 0 224.996 63.994 281.354 159.631a48.002 48.002 0 0 1 0 48.738zM528 256c-44.157-74.933-123.677-127.27-216.162-135.007C302.042 131.078 296 144.83 296 160c0 30.928 25.072 56 56 56s56-25.072 56-56l-.001-.042c30.632 57.277 16.739 130.26-36.928 171.719l26.695 38.135C452.626 346.551 498.308 306.386 528 256z"],file:[384,512,[],"f15b","M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48z"],"file-alt":[384,512,[],"f15c","M288 248v28c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-28c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12zm-12 72H108c-6.6 0-12 5.4-12 12v28c0 6.6 5.4 12 12 12h168c6.6 0 12-5.4 12-12v-28c0-6.6-5.4-12-12-12zm108-188.1V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V48C0 21.5 21.5 0 48 0h204.1C264.8 0 277 5.1 286 14.1L369.9 98c9 8.9 14.1 21.2 14.1 33.9zm-128-80V128h76.1L256 51.9zM336 464V176H232c-13.3 0-24-10.7-24-24V48H48v416h288z"],"file-archive":[384,512,[],"f1c6","M369.941 97.941l-83.882-83.882A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V131.882a48 48 0 0 0-14.059-33.941zM256 51.882L332.118 128H256V51.882zM336 464H48V48h79.714v16h32V48H208v104c0 13.255 10.745 24 24 24h104v288zM192.27 96h-32V64h32v32zm-32 0v32h-32V96h32zm0 64v32h-32v-32h32zm32 0h-32v-32h32v32zm1.909 105.678A12 12 0 0 0 182.406 256H160.27v-32h-32v32l-19.69 97.106C101.989 385.611 126.834 416 160 416c33.052 0 57.871-30.192 51.476-62.62l-17.297-87.702zM160.27 390.073c-17.918 0-32.444-12.105-32.444-27.036 0-14.932 14.525-27.036 32.444-27.036s32.444 12.105 32.444 27.036c0 14.931-14.526 27.036-32.444 27.036zm32-166.073h-32v-32h32v32z"],"file-audio":[384,512,[],"f1c7","M369.941 97.941l-83.882-83.882A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V131.882a48 48 0 0 0-14.059-33.941zM332.118 128H256V51.882L332.118 128zM48 464V48h160v104c0 13.255 10.745 24 24 24h104v288H48zm144-76.024c0 10.691-12.926 16.045-20.485 8.485L136 360.486h-28c-6.627 0-12-5.373-12-12v-56c0-6.627 5.373-12 12-12h28l35.515-36.947c7.56-7.56 20.485-2.206 20.485 8.485v135.952zm41.201-47.13c9.051-9.297 9.06-24.133.001-33.439-22.149-22.752 12.235-56.246 34.395-33.481 27.198 27.94 27.212 72.444.001 100.401-21.793 22.386-56.947-10.315-34.397-33.481z"],"file-code":[384,512,[],"f1c9","M369.941 97.941l-83.882-83.882A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V131.882a48 48 0 0 0-14.059-33.941zM332.118 128H256V51.882L332.118 128zM48 464V48h160v104c0 13.255 10.745 24 24 24h104v288H48zm101.677-115.115L116.854 320l32.822-28.885a8.793 8.793 0 0 0 .605-12.624l-17.403-18.564c-3.384-3.613-8.964-3.662-12.438-.401L62.78 313.58c-3.703 3.474-3.704 9.367.001 12.84l57.659 54.055a8.738 8.738 0 0 0 6.012 2.381 8.746 8.746 0 0 0 6.427-2.782l17.403-18.563a8.795 8.795 0 0 0-.605-12.626zm84.284-127.85l-24.401-7.084a8.796 8.796 0 0 0-10.905 5.998L144.04 408.061c-1.353 4.66 1.338 9.552 5.998 10.905l24.403 7.084c4.68 1.355 9.557-1.354 10.905-5.998l54.612-188.112c1.354-4.66-1.337-9.552-5.997-10.905zm87.258 92.545l-57.658-54.055c-3.526-3.307-9.099-3.165-12.439.401l-17.403 18.563a8.795 8.795 0 0 0 .605 12.625L267.146 320l-32.822 28.885a8.793 8.793 0 0 0-.605 12.624l17.403 18.564a8.797 8.797 0 0 0 12.439.401h-.001l57.66-54.055c3.703-3.473 3.703-9.366-.001-12.839z"],"file-excel":[384,512,[],"f1c3","M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm212-240h-28.8c-4.4 0-8.4 2.4-10.5 6.3-18 33.1-22.2 42.4-28.6 57.7-13.9-29.1-6.9-17.3-28.6-57.7-2.1-3.9-6.2-6.3-10.6-6.3H124c-9.3 0-15 10-10.4 18l46.3 78-46.3 78c-4.7 8 1.1 18 10.4 18h28.9c4.4 0 8.4-2.4 10.5-6.3 21.7-40 23-45 28.6-57.7 14.9 30.2 5.9 15.9 28.6 57.7 2.1 3.9 6.2 6.3 10.6 6.3H260c9.3 0 15-10 10.4-18L224 320c.7-1.1 30.3-50.5 46.3-78 4.7-8-1.1-18-10.3-18z"],"file-image":[384,512,[],"f1c5","M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm32-48h224V288l-23.5-23.5c-4.7-4.7-12.3-4.7-17 0L176 352l-39.5-39.5c-4.7-4.7-12.3-4.7-17 0L80 352v64zm48-240c-26.5 0-48 21.5-48 48s21.5 48 48 48 48-21.5 48-48-21.5-48-48-48z"],"file-pdf":[384,512,[],"f1c1","M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm250.2-143.7c-12.2-12-47-8.7-64.4-6.5-17.2-10.5-28.7-25-36.8-46.3 3.9-16.1 10.1-40.6 5.4-56-4.2-26.2-37.8-23.6-42.6-5.9-4.4 16.1-.4 38.5 7 67.1-10 23.9-24.9 56-35.4 74.4-20 10.3-47 26.2-51 46.2-3.3 15.8 26 55.2 76.1-31.2 22.4-7.4 46.8-16.5 68.4-20.1 18.9 10.2 41 17 55.8 17 25.5 0 28-28.2 17.5-38.7zm-198.1 77.8c5.1-13.7 24.5-29.5 30.4-35-19 30.3-30.4 35.7-30.4 35zm81.6-190.6c7.4 0 6.7 32.1 1.8 40.8-4.4-13.9-4.3-40.8-1.8-40.8zm-24.4 136.6c9.7-16.9 18-37 24.7-54.7 8.3 15.1 18.9 27.2 30.1 35.5-20.8 4.3-38.9 13.1-54.8 19.2zm131.6-5s-5 6-37.3-7.8c35.1-2.6 40.9 5.4 37.3 7.8z"],"file-powerpoint":[384,512,[],"f1c4","M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm72-60V236c0-6.6 5.4-12 12-12h69.2c36.7 0 62.8 27 62.8 66.3 0 74.3-68.7 66.5-95.5 66.5V404c0 6.6-5.4 12-12 12H132c-6.6 0-12-5.4-12-12zm48.5-87.4h23c7.9 0 13.9-2.4 18.1-7.2 8.5-9.8 8.4-28.5.1-37.8-4.1-4.6-9.9-7-17.4-7h-23.9v52z"],"file-video":[384,512,[],"f1c8","M369.941 97.941l-83.882-83.882A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V131.882a48 48 0 0 0-14.059-33.941zM332.118 128H256V51.882L332.118 128zM48 464V48h160v104c0 13.255 10.745 24 24 24h104v288H48zm228.687-211.303L224 305.374V268c0-11.046-8.954-20-20-20H100c-11.046 0-20 8.954-20 20v104c0 11.046 8.954 20 20 20h104c11.046 0 20-8.954 20-20v-37.374l52.687 52.674C286.704 397.318 304 390.28 304 375.986V264.011c0-14.311-17.309-21.319-27.313-11.314z"],"file-word":[384,512,[],"f1c2","M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm220.1-208c-5.7 0-10.6 4-11.7 9.5-20.6 97.7-20.4 95.4-21 103.5-.2-1.2-.4-2.6-.7-4.3-.8-5.1.3.2-23.6-99.5-1.3-5.4-6.1-9.2-11.7-9.2h-13.3c-5.5 0-10.3 3.8-11.7 9.1-24.4 99-24 96.2-24.8 103.7-.1-1.1-.2-2.5-.5-4.2-.7-5.2-14.1-73.3-19.1-99-1.1-5.6-6-9.7-11.8-9.7h-16.8c-7.8 0-13.5 7.3-11.7 14.8 8 32.6 26.7 109.5 33.2 136 1.3 5.4 6.1 9.1 11.7 9.1h25.2c5.5 0 10.3-3.7 11.6-9.1l17.9-71.4c1.5-6.2 2.5-12 3-17.3l2.9 17.3c.1.4 12.6 50.5 17.9 71.4 1.3 5.3 6.1 9.1 11.6 9.1h24.7c5.5 0 10.3-3.7 11.6-9.1 20.8-81.9 30.2-119 34.5-136 1.9-7.6-3.8-14.9-11.6-14.9h-15.8z"],flag:[512,512,[],"f024","M336.174 80c-49.132 0-93.305-32-161.913-32-31.301 0-58.303 6.482-80.721 15.168a48.04 48.04 0 0 0 2.142-20.727C93.067 19.575 74.167 1.594 51.201.104 23.242-1.71 0 20.431 0 48c0 17.764 9.657 33.262 24 41.562V496c0 8.837 7.163 16 16 16h16c8.837 0 16-7.163 16-16v-83.443C109.869 395.28 143.259 384 199.826 384c49.132 0 93.305 32 161.913 32 58.479 0 101.972-22.617 128.548-39.981C503.846 367.161 512 352.051 512 335.855V95.937c0-34.459-35.264-57.768-66.904-44.117C409.193 67.309 371.641 80 336.174 80zM464 336c-21.783 15.412-60.824 32-102.261 32-59.945 0-102.002-32-161.913-32-43.361 0-96.379 9.403-127.826 24V128c21.784-15.412 60.824-32 102.261-32 59.945 0 102.002 32 161.913 32 43.271 0 96.32-17.366 127.826-32v240z"],folder:[512,512,[],"f07b","M464 128H272l-64-64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V176c0-26.51-21.49-48-48-48zm-6 272H54c-3.314 0-6-2.678-6-5.992V117.992A5.993 5.993 0 0 1 54 112h134.118l64 64H458a6 6 0 0 1 6 6v212a6 6 0 0 1-6 6z"],"folder-open":[576,512,[],"f07c","M527.943 224H480v-48c0-26.51-21.49-48-48-48H272l-64-64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h400a48.001 48.001 0 0 0 40.704-22.56l79.942-128c19.948-31.917-3.038-73.44-40.703-73.44zM54 112h134.118l64 64H426a6 6 0 0 1 6 6v42H152a48 48 0 0 0-41.098 23.202L48 351.449V117.993A5.993 5.993 0 0 1 54 112zm394 288H72l77.234-128H528l-80 128z"],frown:[496,512,[],"f119","M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm-80-216c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm160-64c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm-80 128c-40.2 0-78 17.7-103.8 48.6-8.5 10.2-7.1 25.3 3.1 33.8 10.2 8.5 25.3 7.1 33.8-3.1 16.6-19.9 41-31.4 66.9-31.4s50.3 11.4 66.9 31.4c4.8 5.7 11.6 8.6 18.5 8.6 5.4 0 10.9-1.8 15.4-5.6 10.2-8.5 11.5-23.6 3.1-33.8C326 321.7 288.2 304 248 304z"],futbol:[496,512,[],"f1e3","M483.8 179.4C449.8 74.6 352.6 8 248.1 8c-25.4 0-51.2 3.9-76.7 12.2C41.2 62.5-30.1 202.4 12.2 332.6 46.2 437.4 143.4 504 247.9 504c25.4 0 51.2-3.9 76.7-12.2 130.2-42.3 201.5-182.2 159.2-312.4zm-74.5 193.7l-52.2 6.4-43.7-60.9 24.4-75.2 71.1-22.1 38.9 36.4c-.2 30.7-7.4 61.1-21.7 89.2-4.7 9.3-10.7 17.8-16.8 26.2zm0-235.4l-10.4 53.1-70.7 22-64.2-46.5V92.5l47.4-26.2c39.2 13 73.4 38 97.9 71.4zM184.9 66.4L232 92.5v73.8l-64.2 46.5-70.6-22-10.1-52.5c24.3-33.4 57.9-58.6 97.8-71.9zM139 379.5L85.9 373c-14.4-20.1-37.3-59.6-37.8-115.3l39-36.4 71.1 22.2 24.3 74.3-43.5 61.7zm48.2 67l-22.4-48.1 43.6-61.7H287l44.3 61.7-22.4 48.1c-6.2 1.8-57.6 20.4-121.7 0z"],gem:[576,512,[],"f3a5","M464 0H112c-4 0-7.8 2-10 5.4L2 152.6c-2.9 4.4-2.6 10.2.7 14.2l276 340.8c4.8 5.9 13.8 5.9 18.6 0l276-340.8c3.3-4.1 3.6-9.8.7-14.2L474.1 5.4C471.8 2 468.1 0 464 0zm-19.3 48l63.3 96h-68.4l-51.7-96h56.8zm-202.1 0h90.7l51.7 96H191l51.6-96zm-111.3 0h56.8l-51.7 96H68l63.3-96zm-43 144h51.4L208 352 88.3 192zm102.9 0h193.6L288 435.3 191.2 192zM368 352l68.2-160h51.4L368 352z"],"hand-lizard":[576,512,[],"f258","M556.686 290.542L410.328 64.829C397.001 44.272 374.417 32 349.917 32H56C25.121 32 0 57.122 0 88v8c0 44.112 35.888 80 80 80h196.042l-18.333 48H144c-48.523 0-88 39.477-88 88 0 30.879 25.121 56 56 56h131.552c2.987 0 5.914.549 8.697 1.631L352 408.418V480h224V355.829c0-23.225-6.679-45.801-19.314-65.287zM528 432H400v-23.582c0-19.948-12.014-37.508-30.604-44.736l-99.751-38.788A71.733 71.733 0 0 0 243.552 320H112c-4.411 0-8-3.589-8-8 0-22.056 17.944-40 40-40h113.709c19.767 0 37.786-12.407 44.84-30.873l24.552-64.281c8.996-23.553-8.428-48.846-33.63-48.846H80c-17.645 0-32-14.355-32-32v-8c0-4.411 3.589-8 8-8h293.917c8.166 0 15.693 4.09 20.137 10.942l146.358 225.715A71.84 71.84 0 0 1 528 355.829V432z"],"hand-paper":[448,512,[],"f256","M372.57 112.641v-10.825c0-43.612-40.52-76.691-83.039-65.546-25.629-49.5-94.09-47.45-117.982.747C130.269 26.456 89.144 57.945 89.144 102v126.13c-19.953-7.427-43.308-5.068-62.083 8.871-29.355 21.796-35.794 63.333-14.55 93.153L132.48 498.569a32 32 0 0 0 26.062 13.432h222.897c14.904 0 27.835-10.289 31.182-24.813l30.184-130.958A203.637 203.637 0 0 0 448 310.564V179c0-40.62-35.523-71.992-75.43-66.359zm27.427 197.922c0 11.731-1.334 23.469-3.965 34.886L368.707 464h-201.92L51.591 302.303c-14.439-20.27 15.023-42.776 29.394-22.605l27.128 38.079c8.995 12.626 29.031 6.287 29.031-9.283V102c0-25.645 36.571-24.81 36.571.691V256c0 8.837 7.163 16 16 16h6.856c8.837 0 16-7.163 16-16V67c0-25.663 36.571-24.81 36.571.691V256c0 8.837 7.163 16 16 16h6.856c8.837 0 16-7.163 16-16V101.125c0-25.672 36.57-24.81 36.57.691V256c0 8.837 7.163 16 16 16h6.857c8.837 0 16-7.163 16-16v-76.309c0-26.242 36.57-25.64 36.57-.691v131.563z"],"hand-peace":[448,512,[],"f25b","M362.146 191.976c-13.71-21.649-38.761-34.016-65.006-30.341V74c0-40.804-32.811-74-73.141-74-40.33 0-73.14 33.196-73.14 74L160 168l-18.679-78.85C126.578 50.843 83.85 32.11 46.209 47.208 8.735 62.238-9.571 104.963 5.008 142.85l55.757 144.927c-30.557 24.956-43.994 57.809-24.733 92.218l54.853 97.999C102.625 498.97 124.73 512 148.575 512h205.702c30.744 0 57.558-21.44 64.555-51.797l27.427-118.999a67.801 67.801 0 0 0 1.729-15.203L448 256c0-44.956-43.263-77.343-85.854-64.024zM399.987 326c0 1.488-.169 2.977-.502 4.423l-27.427 119.001c-1.978 8.582-9.29 14.576-17.782 14.576H148.575c-6.486 0-12.542-3.621-15.805-9.449l-54.854-98c-4.557-8.141-2.619-18.668 4.508-24.488l26.647-21.764a16 16 0 0 0 4.812-18.139l-64.09-166.549C37.226 92.956 84.37 74.837 96.51 106.389l59.784 155.357A16 16 0 0 0 171.227 272h11.632c8.837 0 16-7.163 16-16V74c0-34.375 50.281-34.43 50.281 0v182c0 8.837 7.163 16 16 16h6.856c8.837 0 16-7.163 16-16v-28c0-25.122 36.567-25.159 36.567 0v28c0 8.837 7.163 16 16 16h6.856c8.837 0 16-7.163 16-16 0-25.12 36.567-25.16 36.567 0v70z"],"hand-point-down":[448,512,[],"f0a7","M188.8 512c45.616 0 83.2-37.765 83.2-83.2v-35.647a93.148 93.148 0 0 0 22.064-7.929c22.006 2.507 44.978-3.503 62.791-15.985C409.342 368.1 448 331.841 448 269.299V248c0-60.063-40-98.512-40-127.2v-2.679c4.952-5.747 8-13.536 8-22.12V32c0-17.673-12.894-32-28.8-32H156.8C140.894 0 128 14.327 128 32v64c0 8.584 3.048 16.373 8 22.12v2.679c0 6.964-6.193 14.862-23.668 30.183l-.148.129-.146.131c-9.937 8.856-20.841 18.116-33.253 25.851C48.537 195.798 0 207.486 0 252.8c0 56.928 35.286 92 83.2 92 8.026 0 15.489-.814 22.4-2.176V428.8c0 45.099 38.101 83.2 83.2 83.2zm0-48c-18.7 0-35.2-16.775-35.2-35.2V270.4c-17.325 0-35.2 26.4-70.4 26.4-26.4 0-35.2-20.625-35.2-44 0-8.794 32.712-20.445 56.1-34.926 14.575-9.074 27.225-19.524 39.875-30.799 18.374-16.109 36.633-33.836 39.596-59.075h176.752C364.087 170.79 400 202.509 400 248v21.299c0 40.524-22.197 57.124-61.325 50.601-8.001 14.612-33.979 24.151-53.625 12.925-18.225 19.365-46.381 17.787-61.05 4.95V428.8c0 18.975-16.225 35.2-35.2 35.2zM328 64c0-13.255 10.745-24 24-24s24 10.745 24 24-10.745 24-24 24-24-10.745-24-24z"],"hand-point-left":[512,512,[],"f0a5","M0 220.8C0 266.416 37.765 304 83.2 304h35.647a93.148 93.148 0 0 0 7.929 22.064c-2.507 22.006 3.503 44.978 15.985 62.791C143.9 441.342 180.159 480 242.701 480H264c60.063 0 98.512-40 127.2-40h2.679c5.747 4.952 13.536 8 22.12 8h64c17.673 0 32-12.894 32-28.8V188.8c0-15.906-14.327-28.8-32-28.8h-64c-8.584 0-16.373 3.048-22.12 8H391.2c-6.964 0-14.862-6.193-30.183-23.668l-.129-.148-.131-.146c-8.856-9.937-18.116-20.841-25.851-33.253C316.202 80.537 304.514 32 259.2 32c-56.928 0-92 35.286-92 83.2 0 8.026.814 15.489 2.176 22.4H83.2C38.101 137.6 0 175.701 0 220.8zm48 0c0-18.7 16.775-35.2 35.2-35.2h158.4c0-17.325-26.4-35.2-26.4-70.4 0-26.4 20.625-35.2 44-35.2 8.794 0 20.445 32.712 34.926 56.1 9.074 14.575 19.524 27.225 30.799 39.875 16.109 18.374 33.836 36.633 59.075 39.596v176.752C341.21 396.087 309.491 432 264 432h-21.299c-40.524 0-57.124-22.197-50.601-61.325-14.612-8.001-24.151-33.979-12.925-53.625-19.365-18.225-17.787-46.381-4.95-61.05H83.2C64.225 256 48 239.775 48 220.8zM448 360c13.255 0 24 10.745 24 24s-10.745 24-24 24-24-10.745-24-24 10.745-24 24-24z"],"hand-point-right":[512,512,[],"f0a4","M428.8 137.6h-86.177a115.52 115.52 0 0 0 2.176-22.4c0-47.914-35.072-83.2-92-83.2-45.314 0-57.002 48.537-75.707 78.784-7.735 12.413-16.994 23.317-25.851 33.253l-.131.146-.129.148C135.662 161.807 127.764 168 120.8 168h-2.679c-5.747-4.952-13.536-8-22.12-8H32c-17.673 0-32 12.894-32 28.8v230.4C0 435.106 14.327 448 32 448h64c8.584 0 16.373-3.048 22.12-8h2.679c28.688 0 67.137 40 127.2 40h21.299c62.542 0 98.8-38.658 99.94-91.145 12.482-17.813 18.491-40.785 15.985-62.791A93.148 93.148 0 0 0 393.152 304H428.8c45.435 0 83.2-37.584 83.2-83.2 0-45.099-38.101-83.2-83.2-83.2zm0 118.4h-91.026c12.837 14.669 14.415 42.825-4.95 61.05 11.227 19.646 1.687 45.624-12.925 53.625 6.524 39.128-10.076 61.325-50.6 61.325H248c-45.491 0-77.21-35.913-120-39.676V215.571c25.239-2.964 42.966-21.222 59.075-39.596 11.275-12.65 21.725-25.3 30.799-39.875C232.355 112.712 244.006 80 252.8 80c23.375 0 44 8.8 44 35.2 0 35.2-26.4 53.075-26.4 70.4h158.4c18.425 0 35.2 16.5 35.2 35.2 0 18.975-16.225 35.2-35.2 35.2zM88 384c0 13.255-10.745 24-24 24s-24-10.745-24-24 10.745-24 24-24 24 10.745 24 24z"],"hand-point-up":[448,512,[],"f0a6","M105.6 83.2v86.177a115.52 115.52 0 0 0-22.4-2.176c-47.914 0-83.2 35.072-83.2 92 0 45.314 48.537 57.002 78.784 75.707 12.413 7.735 23.317 16.994 33.253 25.851l.146.131.148.129C129.807 376.338 136 384.236 136 391.2v2.679c-4.952 5.747-8 13.536-8 22.12v64c0 17.673 12.894 32 28.8 32h230.4c15.906 0 28.8-14.327 28.8-32v-64c0-8.584-3.048-16.373-8-22.12V391.2c0-28.688 40-67.137 40-127.2v-21.299c0-62.542-38.658-98.8-91.145-99.94-17.813-12.482-40.785-18.491-62.791-15.985A93.148 93.148 0 0 0 272 118.847V83.2C272 37.765 234.416 0 188.8 0c-45.099 0-83.2 38.101-83.2 83.2zm118.4 0v91.026c14.669-12.837 42.825-14.415 61.05 4.95 19.646-11.227 45.624-1.687 53.625 12.925 39.128-6.524 61.325 10.076 61.325 50.6V264c0 45.491-35.913 77.21-39.676 120H183.571c-2.964-25.239-21.222-42.966-39.596-59.075-12.65-11.275-25.3-21.725-39.875-30.799C80.712 279.645 48 267.994 48 259.2c0-23.375 8.8-44 35.2-44 35.2 0 53.075 26.4 70.4 26.4V83.2c0-18.425 16.5-35.2 35.2-35.2 18.975 0 35.2 16.225 35.2 35.2zM352 424c13.255 0 24 10.745 24 24s-10.745 24-24 24-24-10.745-24-24 10.745-24 24-24z"],"hand-pointer":[448,512,[],"f25a","M358.182 179.361c-19.493-24.768-52.679-31.945-79.872-19.098-15.127-15.687-36.182-22.487-56.595-19.629V67c0-36.944-29.736-67-66.286-67S89.143 30.056 89.143 67v161.129c-19.909-7.41-43.272-5.094-62.083 8.872-29.355 21.795-35.793 63.333-14.55 93.152l109.699 154.001C134.632 501.59 154.741 512 176 512h178.286c30.802 0 57.574-21.5 64.557-51.797l27.429-118.999A67.873 67.873 0 0 0 448 326v-84c0-46.844-46.625-79.273-89.818-62.639zM80.985 279.697l27.126 38.079c8.995 12.626 29.031 6.287 29.031-9.283V67c0-25.12 36.571-25.16 36.571 0v175c0 8.836 7.163 16 16 16h6.857c8.837 0 16-7.164 16-16v-35c0-25.12 36.571-25.16 36.571 0v35c0 8.836 7.163 16 16 16H272c8.837 0 16-7.164 16-16v-21c0-25.12 36.571-25.16 36.571 0v21c0 8.836 7.163 16 16 16h6.857c8.837 0 16-7.164 16-16 0-25.121 36.571-25.16 36.571 0v84c0 1.488-.169 2.977-.502 4.423l-27.43 119.001c-1.978 8.582-9.29 14.576-17.782 14.576H176c-5.769 0-11.263-2.878-14.697-7.697l-109.712-154c-14.406-20.223 14.994-42.818 29.394-22.606zM176.143 400v-96c0-8.837 6.268-16 14-16h6c7.732 0 14 7.163 14 16v96c0 8.837-6.268 16-14 16h-6c-7.733 0-14-7.163-14-16zm75.428 0v-96c0-8.837 6.268-16 14-16h6c7.732 0 14 7.163 14 16v96c0 8.837-6.268 16-14 16h-6c-7.732 0-14-7.163-14-16zM327 400v-96c0-8.837 6.268-16 14-16h6c7.732 0 14 7.163 14 16v96c0 8.837-6.268 16-14 16h-6c-7.732 0-14-7.163-14-16z"],"hand-rock":[512,512,[],"f255","M408.864 79.052c-22.401-33.898-66.108-42.273-98.813-23.588-29.474-31.469-79.145-31.093-108.334-.022-47.16-27.02-108.71 5.055-110.671 60.806C44.846 105.407 0 140.001 0 187.429v56.953c0 32.741 14.28 63.954 39.18 85.634l97.71 85.081c4.252 3.702 3.11 5.573 3.11 32.903 0 17.673 14.327 32 32 32h252c17.673 0 32-14.327 32-32 0-23.513-1.015-30.745 3.982-42.37l42.835-99.656c6.094-14.177 9.183-29.172 9.183-44.568V146.963c0-52.839-54.314-88.662-103.136-67.911zM464 261.406a64.505 64.505 0 0 1-5.282 25.613l-42.835 99.655c-5.23 12.171-7.883 25.04-7.883 38.25V432H188v-10.286c0-16.37-7.14-31.977-19.59-42.817l-97.71-85.08C56.274 281.255 48 263.236 48 244.381v-56.953c0-33.208 52-33.537 52 .677v41.228a16 16 0 0 0 5.493 12.067l7 6.095A16 16 0 0 0 139 235.429V118.857c0-33.097 52-33.725 52 .677v26.751c0 8.836 7.164 16 16 16h7c8.836 0 16-7.164 16-16v-41.143c0-33.134 52-33.675 52 .677v40.466c0 8.836 7.163 16 16 16h7c8.837 0 16-7.164 16-16v-27.429c0-33.03 52-33.78 52 .677v26.751c0 8.836 7.163 16 16 16h7c8.837 0 16-7.164 16-16 0-33.146 52-33.613 52 .677v114.445z"],"hand-scissors":[512,512,[],"f257","M256 480l70-.013c5.114 0 10.231-.583 15.203-1.729l118.999-27.427C490.56 443.835 512 417.02 512 386.277V180.575c0-23.845-13.03-45.951-34.005-57.69l-97.999-54.853c-34.409-19.261-67.263-5.824-92.218 24.733L142.85 37.008c-37.887-14.579-80.612 3.727-95.642 41.201-15.098 37.642 3.635 80.37 41.942 95.112L168 192l-94-9.141c-40.804 0-74 32.811-74 73.14 0 40.33 33.196 73.141 74 73.141h87.635c-3.675 26.245 8.692 51.297 30.341 65.006C178.657 436.737 211.044 480 256 480zm0-48.013c-25.16 0-25.12-36.567 0-36.567 8.837 0 16-7.163 16-16v-6.856c0-8.837-7.163-16-16-16h-28c-25.159 0-25.122-36.567 0-36.567h28c8.837 0 16-7.163 16-16v-6.856c0-8.837-7.163-16-16-16H74c-34.43 0-34.375-50.281 0-50.281h182c8.837 0 16-7.163 16-16v-11.632a16 16 0 0 0-10.254-14.933L106.389 128.51c-31.552-12.14-13.432-59.283 19.222-46.717l166.549 64.091a16.001 16.001 0 0 0 18.139-4.812l21.764-26.647c5.82-7.127 16.348-9.064 24.488-4.508l98 54.854c5.828 3.263 9.449 9.318 9.449 15.805v205.701c0 8.491-5.994 15.804-14.576 17.782l-119.001 27.427a19.743 19.743 0 0 1-4.423.502h-70z"],"hand-spock":[512,512,[],"f259","M21.096 381.79l129.092 121.513a32 32 0 0 0 21.932 8.698h237.6c14.17 0 26.653-9.319 30.68-22.904l31.815-107.313A115.955 115.955 0 0 0 477 348.811v-36.839c0-4.051.476-8.104 1.414-12.045l31.73-133.41c10.099-42.412-22.316-82.738-65.544-82.525-4.144-24.856-22.543-47.165-49.85-53.992-35.803-8.952-72.227 12.655-81.25 48.75L296.599 184 274.924 52.01c-8.286-36.07-44.303-58.572-80.304-50.296-29.616 6.804-50.138 32.389-51.882 61.295-42.637.831-73.455 40.563-64.071 81.844l31.04 136.508c-27.194-22.515-67.284-19.992-91.482 5.722-25.376 26.961-24.098 69.325 2.871 94.707zm32.068-61.811l.002-.001c7.219-7.672 19.241-7.98 26.856-.813l53.012 49.894C143.225 378.649 160 371.4 160 357.406v-69.479c0-1.193-.134-2.383-.397-3.546l-34.13-150.172c-5.596-24.617 31.502-32.86 37.054-8.421l30.399 133.757a16 16 0 0 0 15.603 12.454h8.604c10.276 0 17.894-9.567 15.594-19.583l-41.62-181.153c-5.623-24.469 31.39-33.076 37.035-8.508l45.22 196.828A16 16 0 0 0 288.956 272h13.217a16 16 0 0 0 15.522-12.119l42.372-169.49c6.104-24.422 42.962-15.159 36.865 9.217L358.805 252.12c-2.521 10.088 5.115 19.88 15.522 19.88h9.694a16 16 0 0 0 15.565-12.295L426.509 146.6c5.821-24.448 42.797-15.687 36.966 8.802L431.72 288.81a100.094 100.094 0 0 0-2.72 23.162v36.839c0 6.548-.943 13.051-2.805 19.328L397.775 464h-219.31L53.978 346.836c-7.629-7.18-7.994-19.229-.814-26.857z"],handshake:[640,512,[],"f2b5","M519.2 127.9l-47.6-47.6A56.252 56.252 0 0 0 432 64H205.2c-14.8 0-29.1 5.9-39.6 16.3L118 127.9H0v255.7h64c17.6 0 31.8-14.2 31.9-31.7h9.1l84.6 76.4c30.9 25.1 73.8 25.7 105.6 3.8 12.5 10.8 26 15.9 41.1 15.9 18.2 0 35.3-7.4 48.8-24 22.1 8.7 48.2 2.6 64-16.8l26.2-32.3c5.6-6.9 9.1-14.8 10.9-23h57.9c.1 17.5 14.4 31.7 31.9 31.7h64V127.9H519.2zM48 351.6c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16c0 8.9-7.2 16-16 16zm390-6.9l-26.1 32.2c-2.8 3.4-7.8 4-11.3 1.2l-23.9-19.4-30 36.5c-6 7.3-15 4.8-18 2.4l-36.8-31.5-15.6 19.2c-13.9 17.1-39.2 19.7-55.3 6.6l-97.3-88H96V175.8h41.9l61.7-61.6c2-.8 3.7-1.5 5.7-2.3H262l-38.7 35.5c-29.4 26.9-31.1 72.3-4.4 101.3 14.8 16.2 61.2 41.2 101.5 4.4l8.2-7.5 108.2 87.8c3.4 2.8 3.9 7.9 1.2 11.3zm106-40.8h-69.2c-2.3-2.8-4.9-5.4-7.7-7.7l-102.7-83.4 12.5-11.4c6.5-6 7-16.1 1-22.6L367 167.1c-6-6.5-16.1-6.9-22.6-1l-55.2 50.6c-9.5 8.7-25.7 9.4-34.6 0-9.3-9.9-8.5-25.1 1.2-33.9l65.6-60.1c7.4-6.8 17-10.5 27-10.5l83.7-.2c2.1 0 4.1.8 5.5 2.3l61.7 61.6H544v128zm48 47.7c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16c0 8.9-7.2 16-16 16z"],hdd:[576,512,[],"f0a0","M567.403 235.642L462.323 84.589A48 48 0 0 0 422.919 64H153.081a48 48 0 0 0-39.404 20.589L8.597 235.642A48.001 48.001 0 0 0 0 263.054V400c0 26.51 21.49 48 48 48h480c26.51 0 48-21.49 48-48V263.054c0-9.801-3-19.366-8.597-27.412zM153.081 112h269.838l77.913 112H75.168l77.913-112zM528 400H48V272h480v128zm-32-64c0 17.673-14.327 32-32 32s-32-14.327-32-32 14.327-32 32-32 32 14.327 32 32zm-96 0c0 17.673-14.327 32-32 32s-32-14.327-32-32 14.327-32 32-32 32 14.327 32 32z"],heart:[512,512,[],"f004","M458.4 64.3C400.6 15.7 311.3 23 256 79.3 200.7 23 111.4 15.6 53.6 64.3-21.6 127.6-10.6 230.8 43 285.5l175.4 178.7c10 10.2 23.4 15.9 37.6 15.9 14.3 0 27.6-5.6 37.6-15.8L469 285.6c53.5-54.7 64.7-157.9-10.6-221.3zm-23.6 187.5L259.4 430.5c-2.4 2.4-4.4 2.4-6.8 0L77.2 251.8c-36.5-37.2-43.9-107.6 7.3-150.7 38.9-32.7 98.9-27.8 136.5 10.5l35 35.7 35-35.7c37.8-38.5 97.8-43.2 136.5-10.6 51.1 43.1 43.5 113.9 7.3 150.8z"],hospital:[448,512,[],"f0f8","M128 244v-40c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12zm140 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12zm-76 84v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm76 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12zm180 124v36H0v-36c0-6.627 5.373-12 12-12h19.5V85.035C31.5 73.418 42.245 64 55.5 64H144V24c0-13.255 10.745-24 24-24h112c13.255 0 24 10.745 24 24v40h88.5c13.255 0 24 9.418 24 21.035V464H436c6.627 0 12 5.373 12 12zM79.5 463H192v-67c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v67h112.5V112H304v24c0 13.255-10.745 24-24 24H168c-13.255 0-24-10.745-24-24v-24H79.5v351zM266 64h-26V38a6 6 0 0 0-6-6h-20a6 6 0 0 0-6 6v26h-26a6 6 0 0 0-6 6v20a6 6 0 0 0 6 6h26v26a6 6 0 0 0 6 6h20a6 6 0 0 0 6-6V96h26a6 6 0 0 0 6-6V70a6 6 0 0 0-6-6z"],hourglass:[384,512,[],"f254","M368 48h4c6.627 0 12-5.373 12-12V12c0-6.627-5.373-12-12-12H12C5.373 0 0 5.373 0 12v24c0 6.627 5.373 12 12 12h4c0 80.564 32.188 165.807 97.18 208C47.899 298.381 16 383.9 16 464h-4c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h360c6.627 0 12-5.373 12-12v-24c0-6.627-5.373-12-12-12h-4c0-80.564-32.188-165.807-97.18-208C336.102 213.619 368 128.1 368 48zM64 48h256c0 101.62-57.307 184-128 184S64 149.621 64 48zm256 416H64c0-101.62 57.308-184 128-184s128 82.38 128 184z"],"id-badge":[384,512,[],"f2c1","M0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V48c0-26.51-21.49-48-48-48H48C21.49 0 0 21.49 0 48zm336 32v378a6 6 0 0 1-6 6H54a6 6 0 0 1-6-6V80h288zm-144 80c38.66 0 70 31.34 70 70s-31.34 70-70 70-70-31.34-70-70 31.34-70 70-70zm80.187 146.047l-31.2-7.8c-32.779 23.577-72.51 18.316-97.974 0l-31.2 7.8C93.116 310.721 80 327.52 80 346.793V363c0 11.598 9.402 21 21 21h182c11.598 0 21-9.402 21-21v-16.207c0-19.273-13.116-36.072-31.813-40.746z"],"id-card":[512,512,[],"f2c2","M404 256H300c-6.627 0-12-5.373-12-12v-16c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v16c0 6.627-5.373 12-12 12zm12 60v-16c0-6.627-5.373-12-12-12H300c-6.627 0-12 5.373-12 12v16c0 6.627 5.373 12 12 12h104c6.627 0 12-5.373 12-12zm96-204v288c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48zm-48 282V144H48v250a6 6 0 0 0 6 6h404a6 6 0 0 0 6-6zM176 192c27.614 0 50 22.386 50 50s-22.386 50-50 50-50-22.386-50-50 22.386-50 50-50zm57.276 104.319l-22.285-5.571c-23.413 16.841-51.793 13.083-69.981 0l-22.285 5.571C105.369 299.658 96 311.657 96 325.423V337c0 8.284 6.716 15 15 15h130c8.284 0 15-6.716 15-15v-11.577c0-13.766-9.369-25.765-22.724-29.104z"],image:[512,512,[],"f03e","M464 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm-6 336H54a6 6 0 0 1-6-6V118a6 6 0 0 1 6-6h404a6 6 0 0 1 6 6v276a6 6 0 0 1-6 6zM128 152c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zM96 352h320v-80l-87.515-87.515c-4.686-4.686-12.284-4.686-16.971 0L192 304l-39.515-39.515c-4.686-4.686-12.284-4.686-16.971 0L96 304v48z"],images:[576,512,[],"f302","M480 416v16c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V176c0-26.51 21.49-48 48-48h16v48H54a6 6 0 0 0-6 6v244a6 6 0 0 0 6 6h372a6 6 0 0 0 6-6v-10h48zm42-336H150a6 6 0 0 0-6 6v244a6 6 0 0 0 6 6h372a6 6 0 0 0 6-6V86a6 6 0 0 0-6-6zm6-48c26.51 0 48 21.49 48 48v256c0 26.51-21.49 48-48 48H144c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h384zM264 144c0 22.091-17.909 40-40 40s-40-17.909-40-40 17.909-40 40-40 40 17.909 40 40zm-72 96l39.515-39.515c4.686-4.686 12.284-4.686 16.971 0L288 240l103.515-103.515c4.686-4.686 12.284-4.686 16.971 0L480 208v80H192v-48z"],keyboard:[576,512,[],"f11c","M528 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h480c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm8 336c0 4.411-3.589 8-8 8H48c-4.411 0-8-3.589-8-8V112c0-4.411 3.589-8 8-8h480c4.411 0 8 3.589 8 8v288zM170 270v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm-336 82v-28c0-6.627-5.373-12-12-12H82c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm384 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zM122 188v-28c0-6.627-5.373-12-12-12H82c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm-98 158v-16c0-6.627-5.373-12-12-12H180c-6.627 0-12 5.373-12 12v16c0 6.627 5.373 12 12 12h216c6.627 0 12-5.373 12-12z"],lemon:[512,512,[],"f094","M484.112 27.889C455.989-.233 416.108-8.057 387.059 8.865 347.604 31.848 223.504-41.111 91.196 91.197-41.277 223.672 31.923 347.472 8.866 387.058c-16.922 29.051-9.1 68.932 19.022 97.054 28.135 28.135 68.011 35.938 97.057 19.021 39.423-22.97 163.557 49.969 295.858-82.329 132.474-132.477 59.273-256.277 82.331-295.861 16.922-29.05 9.1-68.931-19.022-97.054zm-22.405 72.894c-38.8 66.609 45.6 165.635-74.845 286.08-120.44 120.443-219.475 36.048-286.076 74.843-22.679 13.207-64.035-27.241-50.493-50.488 38.8-66.609-45.6-165.635 74.845-286.08C245.573 4.702 344.616 89.086 411.219 50.292c22.73-13.24 64.005 27.288 50.488 50.491zm-169.861 8.736c1.37 10.96-6.404 20.957-17.365 22.327-54.846 6.855-135.779 87.787-142.635 142.635-1.373 10.989-11.399 18.734-22.326 17.365-10.961-1.37-18.735-11.366-17.365-22.326 9.162-73.286 104.167-168.215 177.365-177.365 10.953-1.368 20.956 6.403 22.326 17.364z"],"life-ring":[512,512,[],"f1cd","M256 504c136.967 0 248-111.033 248-248S392.967 8 256 8 8 119.033 8 256s111.033 248 248 248zm-103.398-76.72l53.411-53.411c31.806 13.506 68.128 13.522 99.974 0l53.411 53.411c-63.217 38.319-143.579 38.319-206.796 0zM336 256c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zm91.28 103.398l-53.411-53.411c13.505-31.806 13.522-68.128 0-99.974l53.411-53.411c38.319 63.217 38.319 143.579 0 206.796zM359.397 84.72l-53.411 53.411c-31.806-13.505-68.128-13.522-99.973 0L152.602 84.72c63.217-38.319 143.579-38.319 206.795 0zM84.72 152.602l53.411 53.411c-13.506 31.806-13.522 68.128 0 99.974L84.72 359.398c-38.319-63.217-38.319-143.579 0-206.796z"],lightbulb:[384,512,[],"f0eb","M272 428v28c0 10.449-6.68 19.334-16 22.629V488c0 13.255-10.745 24-24 24h-80c-13.255 0-24-10.745-24-24v-9.371c-9.32-3.295-16-12.18-16-22.629v-28c0-6.627 5.373-12 12-12h136c6.627 0 12 5.373 12 12zM128 176c0-35.29 28.71-64 64-64 8.837 0 16-7.164 16-16s-7.163-16-16-16c-52.935 0-96 43.065-96 96 0 8.836 7.164 16 16 16s16-7.164 16-16zm64-128c70.734 0 128 57.254 128 128 0 77.602-37.383 60.477-80.98 160h-94.04C101.318 236.33 64 253.869 64 176c0-70.735 57.254-128 128-128m0-48C94.805 0 16 78.803 16 176c0 101.731 51.697 91.541 90.516 192.674 3.55 9.249 12.47 15.326 22.376 15.326h126.215c9.906 0 18.826-6.078 22.376-15.326C316.303 267.541 368 277.731 368 176 368 78.803 289.195 0 192 0z"],"list-alt":[512,512,[],"f022","M464 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zm-6 400H54a6 6 0 0 1-6-6V86a6 6 0 0 1 6-6h404a6 6 0 0 1 6 6v340a6 6 0 0 1-6 6zm-42-92v24c0 6.627-5.373 12-12 12H204c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h200c6.627 0 12 5.373 12 12zm0-96v24c0 6.627-5.373 12-12 12H204c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h200c6.627 0 12 5.373 12 12zm0-96v24c0 6.627-5.373 12-12 12H204c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h200c6.627 0 12 5.373 12 12zm-252 12c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36zm0 96c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36zm0 96c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36z"],map:[576,512,[],"f279","M508.505 36.17L381.517 92.576 207.179 34.463a47.992 47.992 0 0 0-34.674 1.674l-144 64A48 48 0 0 0 0 144v287.967c0 34.938 35.991 57.864 67.495 43.863l126.988-56.406 174.339 58.113a47.992 47.992 0 0 0 34.674-1.674l144-64A48 48 0 0 0 576 368V80.033c0-34.938-35.991-57.864-67.495-43.863zM360 424l-144-48V88l144 48v288zm-312 8V144l120-53.333v288L48 432zm480-64l-120 53.333v-288L528 80v288z"],meh:[496,512,[],"f11a","M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm-80-216c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm160-64c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm8 144H160c-13.2 0-24 10.8-24 24s10.8 24 24 24h176c13.2 0 24-10.8 24-24s-10.8-24-24-24z"],"minus-square":[448,512,[],"f146","M108 284c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h232c6.6 0 12 5.4 12 12v32c0 6.6-5.4 12-12 12H108zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"],"money-bill-alt":[640,512,[],"f3d1","M320 144c-53.021 0-96 50.143-96 112 0 61.847 42.977 112 96 112 53 0 96-50.13 96-112 0-61.857-42.979-112-96-112zm48 164.428c0 7.477-3.917 11.572-11.572 11.572h-67.293c-7.656 0-11.573-4.095-11.573-11.572v-8.901c0-7.477 3.917-11.572 11.573-11.572h15.131v-39.878c0-5.163.534-10.503.534-10.503h-.356s-1.779 2.67-2.848 3.738c-4.451 4.273-10.504 4.451-15.666-1.068l-5.518-6.231c-5.342-5.341-4.984-11.216.534-16.379l21.72-19.939c4.449-4.095 8.366-5.697 14.42-5.697h12.105c7.656 0 11.75 3.916 11.75 11.572v84.384h15.488c7.655 0 11.572 4.094 11.572 11.572v8.902zM616 64H24C10.745 64 0 74.745 0 88v335c0 13.255 10.745 24 24 24h592c13.255 0 24-10.745 24-24V88c0-13.255-10.745-24-24-24zM512 400H128c0-44.183-35.817-80-80-80V192c44.183 0 80-35.817 80-80h384c0 44.183 35.817 80 80 80v128c-44.183 0-80 35.817-80 80z"],moon:[512,512,[],"f186","M279.135 512c78.756 0 150.982-35.804 198.844-94.775 28.27-34.831-2.558-85.722-46.249-77.401-82.348 15.683-158.272-47.268-158.272-130.792 0-48.424 26.06-92.292 67.434-115.836 38.745-22.05 28.999-80.788-15.022-88.919A257.936 257.936 0 0 0 279.135 0c-141.36 0-256 114.575-256 256 0 141.36 114.576 256 256 256zm0-464c12.985 0 25.689 1.201 38.016 3.478-54.76 31.163-91.693 90.042-91.693 157.554 0 113.848 103.641 199.2 215.252 177.944C402.574 433.964 344.366 464 279.135 464c-114.875 0-208-93.125-208-208s93.125-208 208-208z"],newspaper:[576,512,[],"f1ea","M552 64H112c-20.858 0-38.643 13.377-45.248 32H24c-13.255 0-24 10.745-24 24v272c0 30.928 25.072 56 56 56h496c13.255 0 24-10.745 24-24V88c0-13.255-10.745-24-24-24zM48 392V144h16v248c0 4.411-3.589 8-8 8s-8-3.589-8-8zm480 8H111.422c.374-2.614.578-5.283.578-8V112h416v288zM172 280h136c6.627 0 12-5.373 12-12v-96c0-6.627-5.373-12-12-12H172c-6.627 0-12 5.373-12 12v96c0 6.627 5.373 12 12 12zm28-80h80v40h-80v-40zm-40 140v-24c0-6.627 5.373-12 12-12h136c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12H172c-6.627 0-12-5.373-12-12zm192 0v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12H364c-6.627 0-12-5.373-12-12zm0-144v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12H364c-6.627 0-12-5.373-12-12zm0 72v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12H364c-6.627 0-12-5.373-12-12z"],"object-group":[512,512,[],"f247","M500 128c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12h-72c-6.627 0-12 5.373-12 12v12H96V44c0-6.627-5.373-12-12-12H12C5.373 32 0 37.373 0 44v72c0 6.627 5.373 12 12 12h12v256H12c-6.627 0-12 5.373-12 12v72c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-12h320v12c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-72c0-6.627-5.373-12-12-12h-12V128h12zm-52-64h32v32h-32V64zM32 64h32v32H32V64zm32 384H32v-32h32v32zm416 0h-32v-32h32v32zm-40-64h-12c-6.627 0-12 5.373-12 12v12H96v-12c0-6.627-5.373-12-12-12H72V128h12c6.627 0 12-5.373 12-12v-12h320v12c0 6.627 5.373 12 12 12h12v256zm-36-192h-84v-52c0-6.628-5.373-12-12-12H108c-6.627 0-12 5.372-12 12v168c0 6.628 5.373 12 12 12h84v52c0 6.628 5.373 12 12 12h200c6.627 0 12-5.372 12-12V204c0-6.628-5.373-12-12-12zm-268-24h144v112H136V168zm240 176H232v-24h76c6.627 0 12-5.372 12-12v-76h56v112z"],"object-ungroup":[576,512,[],"f248","M564 224c6.627 0 12-5.373 12-12v-72c0-6.627-5.373-12-12-12h-72c-6.627 0-12 5.373-12 12v12h-88v-24h12c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12h-72c-6.627 0-12 5.373-12 12v12H96V44c0-6.627-5.373-12-12-12H12C5.373 32 0 37.373 0 44v72c0 6.627 5.373 12 12 12h12v160H12c-6.627 0-12 5.373-12 12v72c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-12h88v24h-12c-6.627 0-12 5.373-12 12v72c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-12h224v12c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-72c0-6.627-5.373-12-12-12h-12V224h12zM352 64h32v32h-32V64zm0 256h32v32h-32v-32zM64 352H32v-32h32v32zm0-256H32V64h32v32zm32 216v-12c0-6.627-5.373-12-12-12H72V128h12c6.627 0 12-5.373 12-12v-12h224v12c0 6.627 5.373 12 12 12h12v160h-12c-6.627 0-12 5.373-12 12v12H96zm128 136h-32v-32h32v32zm280-64h-12c-6.627 0-12 5.373-12 12v12H256v-12c0-6.627-5.373-12-12-12h-12v-24h88v12c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-72c0-6.627-5.373-12-12-12h-12v-88h88v12c0 6.627 5.373 12 12 12h12v160zm40 64h-32v-32h32v32zm0-256h-32v-32h32v32z"],"paper-plane":[512,512,[],"f1d8","M440 6.5L24 246.4c-34.4 19.9-31.1 70.8 5.7 85.9L144 379.6V464c0 46.4 59.2 65.5 86.6 28.6l43.8-59.1 111.9 46.2c5.9 2.4 12.1 3.6 18.3 3.6 8.2 0 16.3-2.1 23.6-6.2 12.8-7.2 21.6-20 23.9-34.5l59.4-387.2c6.1-40.1-36.9-68.8-71.5-48.9zM192 464v-64.6l36.6 15.1L192 464zm212.6-28.7l-153.8-63.5L391 169.5c10.7-15.5-9.5-33.5-23.7-21.2L155.8 332.6 48 288 464 48l-59.4 387.3z"],"pause-circle":[512,512,[],"f28b","M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm96-280v160c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16zm-112 0v160c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16z"],"play-circle":[512,512,[],"f144","M371.7 238l-176-107c-15.8-8.8-35.7 2.5-35.7 21v208c0 18.4 19.8 29.8 35.7 21l176-101c16.4-9.1 16.4-32.8 0-42zM504 256C504 119 393 8 256 8S8 119 8 256s111 248 248 248 248-111 248-248zm-448 0c0-110.5 89.5-200 200-200s200 89.5 200 200-89.5 200-200 200S56 366.5 56 256z"],"plus-square":[448,512,[],"f0fe","M352 240v32c0 6.6-5.4 12-12 12h-88v88c0 6.6-5.4 12-12 12h-32c-6.6 0-12-5.4-12-12v-88h-88c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h88v-88c0-6.6 5.4-12 12-12h32c6.6 0 12 5.4 12 12v88h88c6.6 0 12 5.4 12 12zm96-160v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"],"question-circle":[512,512,[],"f059","M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200 0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200 200zm107.244-255.2c0 67.052-72.421 68.084-72.421 92.863V300c0 6.627-5.373 12-12 12h-45.647c-6.627 0-12-5.373-12-12v-8.659c0-35.745 27.1-50.034 47.579-61.516 17.561-9.845 28.324-16.541 28.324-29.579 0-17.246-21.999-28.693-39.784-28.693-23.189 0-33.894 10.977-48.942 29.969-4.057 5.12-11.46 6.071-16.666 2.124l-27.824-21.098c-5.107-3.872-6.251-11.066-2.644-16.363C184.846 131.491 214.94 112 261.794 112c49.071 0 101.45 38.304 101.45 88.8zM298 368c0 23.159-18.841 42-42 42s-42-18.841-42-42 18.841-42 42-42 42 18.841 42 42z"],registered:[512,512,[],"f25d","M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 448c-110.532 0-200-89.451-200-200 0-110.531 89.451-200 200-200 110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200zm110.442-81.791c-53.046-96.284-50.25-91.468-53.271-96.085 24.267-13.879 39.482-41.563 39.482-73.176 0-52.503-30.247-85.252-101.498-85.252h-78.667c-6.617 0-12 5.383-12 12V380c0 6.617 5.383 12 12 12h38.568c6.617 0 12-5.383 12-12v-83.663h31.958l47.515 89.303a11.98 11.98 0 0 0 10.593 6.36h42.81c9.14 0 14.914-9.799 10.51-17.791zM256.933 239.906h-33.875v-64.14h27.377c32.417 0 38.929 12.133 38.929 31.709-.001 20.913-11.518 32.431-32.431 32.431z"],save:[448,512,[],"f0c7","M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM272 80v80H144V80h128zm122 352H54a6 6 0 0 1-6-6V86a6 6 0 0 1 6-6h42v104c0 13.255 10.745 24 24 24h176c13.255 0 24-10.745 24-24V83.882l78.243 78.243a6 6 0 0 1 1.757 4.243V426a6 6 0 0 1-6 6zM224 232c-48.523 0-88 39.477-88 88s39.477 88 88 88 88-39.477 88-88-39.477-88-88-88zm0 128c-22.056 0-40-17.944-40-40s17.944-40 40-40 40 17.944 40 40-17.944 40-40 40z"],"share-square":[576,512,[],"f14d","M561.938 158.06L417.94 14.092C387.926-15.922 336 5.097 336 48.032v57.198c-42.45 1.88-84.03 6.55-120.76 17.99-35.17 10.95-63.07 27.58-82.91 49.42C108.22 199.2 96 232.6 96 271.94c0 61.697 33.178 112.455 84.87 144.76 37.546 23.508 85.248-12.651 71.02-55.74-15.515-47.119-17.156-70.923 84.11-78.76V336c0 42.993 51.968 63.913 81.94 33.94l143.998-144c18.75-18.74 18.75-49.14 0-67.88zM384 336V232.16C255.309 234.082 166.492 255.35 206.31 376 176.79 357.55 144 324.08 144 271.94c0-109.334 129.14-118.947 240-119.85V48l144 144-144 144zm24.74 84.493a82.658 82.658 0 0 0 20.974-9.303c7.976-4.952 18.286.826 18.286 10.214V464c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h132c6.627 0 12 5.373 12 12v4.486c0 4.917-2.987 9.369-7.569 11.152-13.702 5.331-26.396 11.537-38.05 18.585a12.138 12.138 0 0 1-6.28 1.777H54a6 6 0 0 0-6 6v340a6 6 0 0 0 6 6h340a6 6 0 0 0 6-6v-25.966c0-5.37 3.579-10.059 8.74-11.541z"],smile:[496,512,[],"f118","M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm84-143.4c-20.8 25-51.5 39.4-84 39.4s-63.2-14.3-84-39.4c-8.5-10.2-23.6-11.5-33.8-3.1-10.2 8.5-11.5 23.6-3.1 33.8 30 36 74.1 56.6 120.9 56.6s90.9-20.6 120.9-56.6c8.5-10.2 7.1-25.3-3.1-33.8-10.2-8.4-25.3-7.1-33.8 3.1zM168 240c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm160 0c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32z"],snowflake:[448,512,[],"f2dc","M438.237 355.927l-66.574-38.54 59.448-10.327c5.846-1.375 10.609-5.183 13.458-10.13 2.48-4.307 3.506-9.478 2.524-14.651-2.11-11.115-12.686-18.039-23.621-15.467l-85.423 31.115L255.914 256l82.136-41.926 85.423 31.115c10.936 2.572 21.512-4.352 23.621-15.467 2.111-11.115-5.046-22.209-15.981-24.781l-59.448-10.327 66.573-38.54c9.54-5.523 12.615-18.092 6.867-28.074-5.748-9.982-18.14-13.596-27.68-8.074l-66.574 38.54 20.805-56.787c3.246-10.782-2.758-22.542-13.413-26.268-10.654-3.725-21.922 1.997-25.168 12.779l-15.838 89.735-72.423 41.926V136l69.585-58.621c7.689-8.21 6.997-20.856-1.548-28.245-8.545-7.391-21.705-6.723-29.394 1.486l-38.644 46.46V20c0-11.046-9.318-20-20.813-20s-20.813 8.954-20.813 20v77.08l-38.644-46.46c-7.689-8.21-20.849-8.876-29.394-1.486-8.544 7.389-9.236 20.035-1.547 28.245L203.187 136v83.853l-72.423-41.926-15.838-89.736c-3.247-10.782-14.515-16.504-25.169-12.779-10.656 3.725-16.659 15.486-13.413 26.268l20.805 56.787-66.573-38.54c-9.54-5.523-21.933-1.908-27.68 8.074s-2.673 22.551 6.867 28.074l66.574 38.54-59.449 10.328C5.953 207.515-1.202 218.609.907 229.724c2.11 11.114 12.686 18.038 23.622 15.466l85.422-31.115L192.086 256l-82.136 41.926-85.423-31.115c-10.936-2.572-21.511 4.352-23.622 15.466-2.109 11.113 5.046 22.209 15.981 24.781l59.449 10.328-66.574 38.54C.223 361.449-2.852 374.018 2.896 384s18.14 13.597 27.68 8.074l66.574-38.54-20.805 56.786c-1.735 5.764-.828 11.805 2.02 16.751 2.48 4.307 6.433 7.784 11.392 9.517 10.655 3.725 21.923-1.997 25.169-12.779l15.838-89.736 72.423-41.926V376l-69.585 58.621c-7.69 8.21-6.997 20.855 1.547 28.245 8.544 7.388 21.705 6.723 29.394-1.487l38.644-46.46V492c0 11.046 9.318 20 20.813 20s20.813-8.954 20.813-20v-77.081l38.644 46.46c4.111 4.389 9.782 6.621 15.478 6.621 4.96 0 9.939-1.694 13.916-5.134 8.545-7.39 9.237-20.035 1.548-28.245L244.813 376v-83.853l72.423 41.926 15.838 89.736c3.246 10.782 14.514 16.504 25.168 12.779 10.653-3.726 16.659-15.487 13.412-26.268l-20.805-56.787 66.574 38.54c9.54 5.523 21.933 1.908 27.68-8.074 5.749-9.981 2.675-22.55-6.866-28.072z"],square:[448,512,[],"f0c8","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-6 400H54c-3.3 0-6-2.7-6-6V86c0-3.3 2.7-6 6-6h340c3.3 0 6 2.7 6 6v340c0 3.3-2.7 6-6 6z"],star:[576,512,[],"f005","M528.1 171.5L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6zM388.6 312.3l23.7 138.4L288 385.4l-124.3 65.3 23.7-138.4-100.6-98 139-20.2 62.2-126 62.2 126 139 20.2-100.6 98z"],"star-half":[576,512,[],"f089","M288 385.3l-124.3 65.4 23.7-138.4-100.6-98 139-20.2 62.2-126V0c-11.4 0-22.8 5.9-28.7 17.8L194 150.2 47.9 171.4c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.1 23 46 46.4 33.7L288 439.6v-54.3z"],"sticky-note":[448,512,[],"f249","M448 348.106V80c0-26.51-21.49-48-48-48H48C21.49 32 0 53.49 0 80v351.988c0 26.51 21.49 48 48 48h268.118a48 48 0 0 0 33.941-14.059l83.882-83.882A48 48 0 0 0 448 348.106zm-128 80v-76.118h76.118L320 428.106zM400 80v223.988H296c-13.255 0-24 10.745-24 24v104H48V80h352z"],"stop-circle":[512,512,[],"f28d","M504 256C504 119 393 8 256 8S8 119 8 256s111 248 248 248 248-111 248-248zm-448 0c0-110.5 89.5-200 200-200s200 89.5 200 200-89.5 200-200 200S56 366.5 56 256zm296-80v160c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h160c8.8 0 16 7.2 16 16z"],sun:[512,512,[],"f185","M220.116 487.936l-20.213-49.425a3.992 3.992 0 0 0-5.808-1.886l-45.404 28.104c-29.466 18.24-66.295-8.519-58.054-42.179l12.699-51.865a3.993 3.993 0 0 0-3.59-4.941l-53.251-3.951c-34.554-2.562-48.632-45.855-22.174-68.247L65.08 259.05a3.992 3.992 0 0 0 0-6.106l-40.76-34.497c-26.45-22.384-12.39-65.682 22.174-68.246l53.251-3.951a3.993 3.993 0 0 0 3.59-4.941L90.637 89.443c-8.239-33.656 28.581-60.42 58.054-42.179l45.403 28.104a3.993 3.993 0 0 0 5.808-1.887l20.213-49.425c13.116-32.071 58.638-32.081 71.758 0l20.212 49.424a3.994 3.994 0 0 0 5.809 1.887l45.403-28.104c29.464-18.236 66.297 8.513 58.054 42.179l-12.699 51.865a3.995 3.995 0 0 0 3.59 4.941l53.251 3.951c34.553 2.563 48.633 45.854 22.175 68.246l-40.76 34.497a3.993 3.993 0 0 0 0 6.107l40.76 34.496c26.511 22.441 12.322 65.689-22.175 68.247l-53.251 3.951a3.993 3.993 0 0 0-3.589 4.942l12.698 51.864c8.241 33.658-28.583 60.421-58.054 42.18l-45.403-28.104a3.994 3.994 0 0 0-5.809 1.887l-20.212 49.424c-13.159 32.178-58.675 31.993-71.757 0zm16.814-64.568l19.064 46.616 19.064-46.615c10.308-25.2 40.778-35.066 63.892-20.759l42.822 26.507-11.976-48.919c-6.475-26.444 12.38-52.339 39.487-54.349l50.226-3.726-38.444-32.536c-20.782-17.591-20.747-49.621.001-67.18l38.442-32.536-50.225-3.727c-27.151-2.015-45.95-27.948-39.488-54.349l11.978-48.919-42.823 26.507c-23.151 14.327-53.603 4.4-63.892-20.76l-19.064-46.615-19.064 46.617c-10.305 25.198-40.778 35.066-63.891 20.76l-42.823-26.508 11.977 48.918c6.474 26.446-12.381 52.338-39.488 54.35l-50.224 3.726 38.443 32.537c20.782 17.588 20.747 49.619 0 67.178L52.48 322.123l50.226 3.726c27.151 2.014 45.95 27.947 39.487 54.349l-11.977 48.919 42.823-26.507c23.188-14.355 53.622-4.352 63.891 20.758zM256 384c-70.58 0-128-57.421-128-128 0-70.58 57.42-128 128-128 70.579 0 128 57.42 128 128 0 70.579-57.421 128-128 128zm0-208c-44.112 0-80 35.888-80 80s35.888 80 80 80 80-35.888 80-80-35.888-80-80-80z"],"thumbs-down":[512,512,[],"f165","M466.27 225.31c4.674-22.647.864-44.538-8.99-62.99 2.958-23.868-4.021-48.565-17.34-66.99C438.986 39.423 404.117 0 327 0c-7 0-15 .01-22.22.01C201.195.01 168.997 40 128 40h-10.845c-5.64-4.975-13.042-8-21.155-8H32C14.327 32 0 46.327 0 64v240c0 17.673 14.327 32 32 32h64c11.842 0 22.175-6.438 27.708-16h7.052c19.146 16.953 46.013 60.653 68.76 83.4 13.667 13.667 10.153 108.6 71.76 108.6 57.58 0 95.27-31.936 95.27-104.73 0-18.41-3.93-33.73-8.85-46.54h36.48c48.602 0 85.82-41.565 85.82-85.58 0-19.15-4.96-34.99-13.73-49.84zM64 296c-13.255 0-24-10.745-24-24s10.745-24 24-24 24 10.745 24 24-10.745 24-24 24zm330.18 16.73H290.19c0 37.82 28.36 55.37 28.36 94.54 0 23.75 0 56.73-47.27 56.73-18.91-18.91-9.46-66.18-37.82-94.54C206.9 342.89 167.28 272 138.92 272H128V85.83c53.611 0 100.001-37.82 171.64-37.82h37.82c35.512 0 60.82 17.12 53.12 65.9 15.2 8.16 26.5 36.44 13.94 57.57 21.581 20.384 18.699 51.065 5.21 65.62 9.45 0 22.36 18.91 22.27 37.81-.09 18.91-16.71 37.82-37.82 37.82z"],"thumbs-up":[512,512,[],"f164","M466.27 286.69C475.04 271.84 480 256 480 236.85c0-44.015-37.218-85.58-85.82-85.58H357.7c4.92-12.81 8.85-28.13 8.85-46.54C366.55 31.936 328.86 0 271.28 0c-61.607 0-58.093 94.933-71.76 108.6-22.747 22.747-49.615 66.447-68.76 83.4H32c-17.673 0-32 14.327-32 32v240c0 17.673 14.327 32 32 32h64c14.893 0 27.408-10.174 30.978-23.95 44.509 1.001 75.06 39.94 177.802 39.94 7.22 0 15.22.01 22.22.01 77.117 0 111.986-39.423 112.94-95.33 13.319-18.425 20.299-43.122 17.34-66.99 9.854-18.452 13.664-40.343 8.99-62.99zm-61.75 53.83c12.56 21.13 1.26 49.41-13.94 57.57 7.7 48.78-17.608 65.9-53.12 65.9h-37.82c-71.639 0-118.029-37.82-171.64-37.82V240h10.92c28.36 0 67.98-70.89 94.54-97.46 28.36-28.36 18.91-75.63 37.82-94.54 47.27 0 47.27 32.98 47.27 56.73 0 39.17-28.36 56.72-28.36 94.54h103.99c21.11 0 37.73 18.91 37.82 37.82.09 18.9-12.82 37.81-22.27 37.81 13.489 14.555 16.371 45.236-5.21 65.62zM88 432c0 13.255-10.745 24-24 24s-24-10.745-24-24 10.745-24 24-24 24 10.745 24 24z"],"times-circle":[512,512,[],"f057","M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm101.8-262.2L295.6 256l62.2 62.2c4.7 4.7 4.7 12.3 0 17l-22.6 22.6c-4.7 4.7-12.3 4.7-17 0L256 295.6l-62.2 62.2c-4.7 4.7-12.3 4.7-17 0l-22.6-22.6c-4.7-4.7-4.7-12.3 0-17l62.2-62.2-62.2-62.2c-4.7-4.7-4.7-12.3 0-17l22.6-22.6c4.7-4.7 12.3-4.7 17 0l62.2 62.2 62.2-62.2c4.7-4.7 12.3-4.7 17 0l22.6 22.6c4.7 4.7 4.7 12.3 0 17z"],"trash-alt":[448,512,[],"f2ed","M192 188v216c0 6.627-5.373 12-12 12h-24c-6.627 0-12-5.373-12-12V188c0-6.627 5.373-12 12-12h24c6.627 0 12 5.373 12 12zm100-12h-24c-6.627 0-12 5.373-12 12v216c0 6.627 5.373 12 12 12h24c6.627 0 12-5.373 12-12V188c0-6.627-5.373-12-12-12zm132-96c13.255 0 24 10.745 24 24v12c0 6.627-5.373 12-12 12h-20v336c0 26.51-21.49 48-48 48H80c-26.51 0-48-21.49-48-48V128H12c-6.627 0-12-5.373-12-12v-12c0-13.255 10.745-24 24-24h74.411l34.018-56.696A48 48 0 0 1 173.589 0h100.823a48 48 0 0 1 41.16 23.304L349.589 80H424zm-269.611 0h139.223L276.16 50.913A6 6 0 0 0 271.015 48h-94.028a6 6 0 0 0-5.145 2.913L154.389 80zM368 128H80v330a6 6 0 0 0 6 6h276a6 6 0 0 0 6-6V128z"],user:[512,512,[],"f007","M423.309 291.025L402.221 285C431.798 243.89 436 202.294 436 180 436 80.649 355.484 0 256 0 156.649 0 76 80.516 76 180c0 22.299 4.198 63.884 33.779 105l-21.088 6.025C21.28 310.285 0 371.59 0 408.605v25.681C0 477.138 34.862 512 77.714 512h356.571C477.138 512 512 477.138 512 434.286v-25.681c0-36.247-20.725-98.161-88.691-117.58zM256 48c72.902 0 132 59.099 132 132s-59.098 132-132 132-132-59.099-132-132S183.098 48 256 48zm208 386.286c0 16.41-13.304 29.714-29.714 29.714H77.714C61.304 464 48 450.696 48 434.286v-25.681c0-33.167 21.987-62.316 53.878-71.427l46.103-13.172C162.683 335.058 200.427 360 256 360s93.317-24.942 108.019-35.994l46.103 13.172C442.013 346.29 464 375.438 464 408.605v25.681z"],"user-circle":[512,512,[],"f2bd","M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 48c110.457 0 200 89.543 200 200 0 36.982-10.049 71.611-27.548 101.328-7.072-25.444-25.663-54.208-63.93-65.374C377.207 271.782 384 248.414 384 224c0-70.689-57.189-128-128-128-70.689 0-128 57.19-128 128 0 24.414 6.793 47.783 19.478 67.954-38.299 11.175-56.876 39.913-63.938 65.362C66.046 327.601 56 292.976 56 256c0-110.457 89.543-200 200-200zm80 168c0 44.183-35.817 80-80 80s-80-35.817-80-80 35.817-80 80-80 80 35.817 80 80zM128 409.669v-27.758c0-20.41 13.53-38.348 33.156-43.955l24.476-6.993C206.342 344.648 230.605 352 256 352s49.658-7.352 70.369-21.038l24.476 6.993C370.47 343.563 384 361.5 384 381.911v27.758C349.315 438.592 304.693 456 256 456s-93.315-17.408-128-46.331z"],"window-close":[512,512,[],"f410","M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm0 394c0 3.3-2.7 6-6 6H54c-3.3 0-6-2.7-6-6V86c0-3.3 2.7-6 6-6h404c3.3 0 6 2.7 6 6v340zM356.5 194.6L295.1 256l61.4 61.4c4.6 4.6 4.6 12.1 0 16.8l-22.3 22.3c-4.6 4.6-12.1 4.6-16.8 0L256 295.1l-61.4 61.4c-4.6 4.6-12.1 4.6-16.8 0l-22.3-22.3c-4.6-4.6-4.6-12.1 0-16.8l61.4-61.4-61.4-61.4c-4.6-4.6-4.6-12.1 0-16.8l22.3-22.3c4.6-4.6 12.1-4.6 16.8 0l61.4 61.4 61.4-61.4c4.6-4.6 12.1-4.6 16.8 0l22.3 22.3c4.7 4.6 4.7 12.1 0 16.8z"],"window-maximize":[512,512,[],"f2d0","M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm0 394c0 3.3-2.7 6-6 6H54c-3.3 0-6-2.7-6-6V192h416v234z"],"window-minimize":[512,512,[],"f2d1","M480 480H32c-17.7 0-32-14.3-32-32s14.3-32 32-32h448c17.7 0 32 14.3 32 32s-14.3 32-32 32z"],"window-restore":[512,512,[],"f2d2","M464 0H144c-26.5 0-48 21.5-48 48v48H48c-26.5 0-48 21.5-48 48v320c0 26.5 21.5 48 48 48h320c26.5 0 48-21.5 48-48v-48h48c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-96 464H48V256h320v208zm96-96h-48V144c0-26.5-21.5-48-48-48H144V48h320v320z"]};!function(c){try{c()}catch(c){if(!e)throw c}}(function(){!function c(l,v){var h=Object.keys(v).reduce(function(c,l){var h=v[l];return h.icon?c[h.iconName]=h.icon:c[l]=h,c},{});"function"==typeof t.hooks.addPack?t.hooks.addPack(l,h):t.styles[l]=f({},t.styles[l]||{},h),"fas"===l&&c("fa",v)}("far",r)})}(),function(){"use strict";var c={};try{"undefined"!=typeof window&&(c=window)}catch(c){}var l=(c.navigator||{}).userAgent,h=void 0===l?"":l,v=c,z=(~h.indexOf("MSIE")||h.indexOf("Trident/"),"___FONT_AWESOME___"),e=function(){try{return!0}catch(c){return!1}}(),a=[1,2,3,4,5,6,7,8,9,10],m=a.concat([11,12,13,14,15,16,17,18,19,20]);["xs","sm","lg","fw","ul","li","border","pull-left","pull-right","spin","pulse","rotate-90","rotate-180","rotate-270","flip-horizontal","flip-vertical","stack","stack-1x","stack-2x","inverse","layers","layers-text","layers-counter"].concat(a.map(function(c){return c+"x"})).concat(m.map(function(c){return"w-"+c}));var s=v||{};s[z]||(s[z]={}),s[z].styles||(s[z].styles={}),s[z].hooks||(s[z].hooks={}),s[z].shims||(s[z].shims=[]);var t=s[z],f=Object.assign||function(c){for(var l=1;l<arguments.length;l++){var h=arguments[l];for(var v in h)Object.prototype.hasOwnProperty.call(h,v)&&(c[v]=h[v])}return c};var r={"address-book":[448,512,[],"f2b9","M436 160c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20V48c0-26.51-21.49-48-48-48H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h320c26.51 0 48-21.49 48-48v-48h20c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20v-64h20c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20v-64h20zm-228-32c44.183 0 80 35.817 80 80s-35.817 80-80 80-80-35.817-80-80 35.817-80 80-80zm128 232c0 13.255-10.745 24-24 24H104c-13.255 0-24-10.745-24-24v-18.523c0-22.026 14.99-41.225 36.358-46.567l35.657-8.914c29.101 20.932 74.509 26.945 111.97 0l35.657 8.914C321.01 300.252 336 319.452 336 341.477V360z"],"address-card":[512,512,[],"f2bb","M464 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm-288 80c38.66 0 70 31.34 70 70s-31.34 70-70 70-70-31.34-70-70 31.34-70 70-70zm112 203c0 11.598-9.402 21-21 21H85c-11.598 0-21-9.402-21-21v-16.207c0-19.272 13.116-36.072 31.813-40.746l31.2-7.8c25.464 18.316 65.195 23.577 97.974 0l31.2 7.8C274.884 294.721 288 311.52 288 330.793V347zm160-39c0 6.627-5.373 12-12 12H332c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v8zm0-64c0 6.627-5.373 12-12 12H332c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v8zm0-64c0 6.627-5.373 12-12 12H332c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v8z"],adjust:[512,512,[],"f042","M8 256c0 136.966 111.033 248 248 248s248-111.034 248-248S392.966 8 256 8 8 119.033 8 256zm248 184V72c101.705 0 184 82.311 184 184 0 101.705-82.311 184-184 184z"],"align-center":[448,512,[],"f037","M352 44v40c0 8.837-7.163 16-16 16H112c-8.837 0-16-7.163-16-16V44c0-8.837 7.163-16 16-16h224c8.837 0 16 7.163 16 16zM16 228h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 256h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm320-200H112c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16h224c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16z"],"align-justify":[448,512,[],"f039","M0 84V44c0-8.837 7.163-16 16-16h416c8.837 0 16 7.163 16 16v40c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16zm16 144h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 256h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0-128h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"],"align-left":[448,512,[],"f036","M288 44v40c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16V44c0-8.837 7.163-16 16-16h256c8.837 0 16 7.163 16 16zM0 172v40c0 8.837 7.163 16 16 16h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16zm16 312h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm256-200H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16h256c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16z"],"align-right":[448,512,[],"f038","M160 84V44c0-8.837 7.163-16 16-16h256c8.837 0 16 7.163 16 16v40c0 8.837-7.163 16-16 16H176c-8.837 0-16-7.163-16-16zM16 228h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 256h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm160-128h256c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H176c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"],allergies:[448,512,[],"f461","M416 112c-17.6 0-32 14.4-32 32v72c0 4.4-3.6 8-8 8h-16c-4.4 0-8-3.6-8-8V64c0-17.6-14.4-32-32-32s-32 14.4-32 32v152c0 4.4-3.6 8-8 8h-16c-4.4 0-8-3.6-8-8V32c0-17.6-14.4-32-32-32s-32 14.4-32 32v184c0 4.4-3.6 8-8 8h-16c-4.4 0-8-3.6-8-8V64c0-17.6-14.4-32-32-32S96 46.4 96 64v241l-23.6-32.5c-13-17.9-38-21.8-55.9-8.8s-21.8 38-8.8 55.9l125.6 172.7c9 12.4 23.5 19.8 38.8 19.8h197.6c22.3 0 41.6-15.3 46.7-37l26.5-112.7c3.2-13.7 4.9-28.3 5.1-42.3V144c0-17.6-14.4-32-32-32zM176 416c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16zm0-96c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16zm64 128c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16zm0-96c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16zm64 32c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16zm32 64c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16zm32-128c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16z"],ambulance:[640,512,[],"f0f9","M624 352h-16V243.9c0-12.7-5.1-24.9-14.1-33.9L494 110.1c-9-9-21.2-14.1-33.9-14.1H416V48c0-26.5-21.5-48-48-48H48C21.5 0 0 21.5 0 48v320c0 26.5 21.5 48 48 48h16c0 53 43 96 96 96s96-43 96-96h128c0 53 43 96 96 96s96-43 96-96h48c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zM160 464c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zm144-248c0 4.4-3.6 8-8 8h-56v56c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8v-56h-56c-4.4 0-8-3.6-8-8v-48c0-4.4 3.6-8 8-8h56v-56c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v56h56c4.4 0 8 3.6 8 8v48zm176 248c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zm80-208H416V144h44.1l99.9 99.9V256z"],"american-sign-language-interpreting":[640,512,[],"f2a3","M290.547 189.039c-20.295-10.149-44.147-11.199-64.739-3.89 42.606 0 71.208 20.475 85.578 50.576 8.576 17.899-5.148 38.071-23.617 38.071 18.429 0 32.211 20.136 23.617 38.071-14.725 30.846-46.123 50.854-80.298 50.854-.557 0-94.471-8.615-94.471-8.615l-66.406 33.347c-9.384 4.693-19.815.379-23.895-7.781L1.86 290.747c-4.167-8.615-1.111-18.897 6.946-23.621l58.072-33.069L108 159.861c6.39-57.245 34.731-109.767 79.743-146.726 11.391-9.448 28.341-7.781 37.51 3.613 9.446 11.394 7.78 28.067-3.612 37.516-12.503 10.559-23.618 22.509-32.509 35.57 21.672-14.729 46.679-24.732 74.186-28.067 14.725-1.945 28.063 8.336 29.73 23.065 1.945 14.728-8.336 28.067-23.062 29.734-16.116 1.945-31.12 7.503-44.178 15.284 26.114-5.713 58.712-3.138 88.079 11.115 13.336 6.669 18.893 22.509 12.224 35.848-6.389 13.06-22.504 18.617-35.564 12.226zm-27.229 69.472c-6.112-12.505-18.338-20.286-32.231-20.286a35.46 35.46 0 0 0-35.565 35.57c0 21.428 17.808 35.57 35.565 35.57 13.893 0 26.119-7.781 32.231-20.286 4.446-9.449 13.614-15.006 23.339-15.284-9.725-.277-18.893-5.835-23.339-15.284zm374.821-37.237c4.168 8.615 1.111 18.897-6.946 23.621l-58.071 33.069L532 352.16c-6.39 57.245-34.731 109.767-79.743 146.726-10.932 9.112-27.799 8.144-37.51-3.613-9.446-11.394-7.78-28.067 3.613-37.516 12.503-10.559 23.617-22.509 32.508-35.57-21.672 14.729-46.679 24.732-74.186 28.067-10.021 2.506-27.552-5.643-29.73-23.065-1.945-14.728 8.336-28.067 23.062-29.734 16.116-1.946 31.12-7.503 44.178-15.284-26.114 5.713-58.712 3.138-88.079-11.115-13.336-6.669-18.893-22.509-12.224-35.848 6.389-13.061 22.505-18.619 35.565-12.227 20.295 10.149 44.147 11.199 64.739 3.89-42.606 0-71.208-20.475-85.578-50.576-8.576-17.899 5.148-38.071 23.617-38.071-18.429 0-32.211-20.136-23.617-38.071 14.033-29.396 44.039-50.887 81.966-50.854l92.803 8.615 66.406-33.347c9.408-4.704 19.828-.354 23.894 7.781l44.455 88.926zm-229.227-18.618c-13.893 0-26.119 7.781-32.231 20.286-4.446 9.449-13.614 15.006-23.339 15.284 9.725.278 18.893 5.836 23.339 15.284 6.112 12.505 18.338 20.286 32.231 20.286a35.46 35.46 0 0 0 35.565-35.57c0-21.429-17.808-35.57-35.565-35.57z"],anchor:[576,512,[],"f13d","M12.971 352h32.394C67.172 454.735 181.944 512 288 512c106.229 0 220.853-57.38 242.635-160h32.394c10.691 0 16.045-12.926 8.485-20.485l-67.029-67.029c-4.686-4.686-12.284-4.686-16.971 0l-67.029 67.029c-7.56 7.56-2.206 20.485 8.485 20.485h35.146c-20.29 54.317-84.963 86.588-144.117 94.015V256h52c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-52v-5.47c37.281-13.178 63.995-48.725 64-90.518C384.005 43.772 341.605.738 289.37.01 235.723-.739 192 42.525 192 96c0 41.798 26.716 77.35 64 90.53V192h-52c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h52v190.015c-58.936-7.399-123.82-39.679-144.117-94.015h35.146c10.691 0 16.045-12.926 8.485-20.485l-67.029-67.029c-4.686-4.686-12.284-4.686-16.971 0L4.485 331.515C-3.074 339.074 2.28 352 12.971 352zM288 64c17.645 0 32 14.355 32 32s-14.355 32-32 32-32-14.355-32-32 14.355-32 32-32z"],"angle-double-down":[320,512,[],"f103","M143 256.3L7 120.3c-9.4-9.4-9.4-24.6 0-33.9l22.6-22.6c9.4-9.4 24.6-9.4 33.9 0l96.4 96.4 96.4-96.4c9.4-9.4 24.6-9.4 33.9 0L313 86.3c9.4 9.4 9.4 24.6 0 33.9l-136 136c-9.4 9.5-24.6 9.5-34 .1zm34 192l136-136c9.4-9.4 9.4-24.6 0-33.9l-22.6-22.6c-9.4-9.4-24.6-9.4-33.9 0L160 352.1l-96.4-96.4c-9.4-9.4-24.6-9.4-33.9 0L7 278.3c-9.4 9.4-9.4 24.6 0 33.9l136 136c9.4 9.5 24.6 9.5 34 .1z"],"angle-double-left":[448,512,[],"f100","M223.7 239l136-136c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9L319.9 256l96.4 96.4c9.4 9.4 9.4 24.6 0 33.9L393.7 409c-9.4 9.4-24.6 9.4-33.9 0l-136-136c-9.5-9.4-9.5-24.6-.1-34zm-192 34l136 136c9.4 9.4 24.6 9.4 33.9 0l22.6-22.6c9.4-9.4 9.4-24.6 0-33.9L127.9 256l96.4-96.4c9.4-9.4 9.4-24.6 0-33.9L201.7 103c-9.4-9.4-24.6-9.4-33.9 0l-136 136c-9.5 9.4-9.5 24.6-.1 34z"],"angle-double-right":[448,512,[],"f101","M224.3 273l-136 136c-9.4 9.4-24.6 9.4-33.9 0l-22.6-22.6c-9.4-9.4-9.4-24.6 0-33.9l96.4-96.4-96.4-96.4c-9.4-9.4-9.4-24.6 0-33.9L54.3 103c9.4-9.4 24.6-9.4 33.9 0l136 136c9.5 9.4 9.5 24.6.1 34zm192-34l-136-136c-9.4-9.4-24.6-9.4-33.9 0l-22.6 22.6c-9.4 9.4-9.4 24.6 0 33.9l96.4 96.4-96.4 96.4c-9.4 9.4-9.4 24.6 0 33.9l22.6 22.6c9.4 9.4 24.6 9.4 33.9 0l136-136c9.4-9.2 9.4-24.4 0-33.8z"],"angle-double-up":[320,512,[],"f102","M177 255.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 351.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 425.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1zm-34-192L7 199.7c-9.4 9.4-9.4 24.6 0 33.9l22.6 22.6c9.4 9.4 24.6 9.4 33.9 0l96.4-96.4 96.4 96.4c9.4 9.4 24.6 9.4 33.9 0l22.6-22.6c9.4-9.4 9.4-24.6 0-33.9l-136-136c-9.2-9.4-24.4-9.4-33.8 0z"],"angle-down":[320,512,[],"f107","M143 352.3L7 216.3c-9.4-9.4-9.4-24.6 0-33.9l22.6-22.6c9.4-9.4 24.6-9.4 33.9 0l96.4 96.4 96.4-96.4c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9l-136 136c-9.2 9.4-24.4 9.4-33.8 0z"],"angle-left":[256,512,[],"f104","M31.7 239l136-136c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9L127.9 256l96.4 96.4c9.4 9.4 9.4 24.6 0 33.9L201.7 409c-9.4 9.4-24.6 9.4-33.9 0l-136-136c-9.5-9.4-9.5-24.6-.1-34z"],"angle-right":[256,512,[],"f105","M224.3 273l-136 136c-9.4 9.4-24.6 9.4-33.9 0l-22.6-22.6c-9.4-9.4-9.4-24.6 0-33.9l96.4-96.4-96.4-96.4c-9.4-9.4-9.4-24.6 0-33.9L54.3 103c9.4-9.4 24.6-9.4 33.9 0l136 136c9.5 9.4 9.5 24.6.1 34z"],"angle-up":[320,512,[],"f106","M177 159.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 255.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 329.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1z"],archive:[512,512,[],"f187","M32 448c0 17.7 14.3 32 32 32h384c17.7 0 32-14.3 32-32V160H32v288zm160-212c0-6.6 5.4-12 12-12h104c6.6 0 12 5.4 12 12v8c0 6.6-5.4 12-12 12H204c-6.6 0-12-5.4-12-12v-8zM480 32H32C14.3 32 0 46.3 0 64v48c0 8.8 7.2 16 16 16h480c8.8 0 16-7.2 16-16V64c0-17.7-14.3-32-32-32z"],"arrow-alt-circle-down":[512,512,[],"f358","M504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zM212 140v116h-70.9c-10.7 0-16.1 13-8.5 20.5l114.9 114.3c4.7 4.7 12.2 4.7 16.9 0l114.9-114.3c7.6-7.6 2.2-20.5-8.5-20.5H300V140c0-6.6-5.4-12-12-12h-64c-6.6 0-12 5.4-12 12z"],"arrow-alt-circle-left":[512,512,[],"f359","M256 504C119 504 8 393 8 256S119 8 256 8s248 111 248 248-111 248-248 248zm116-292H256v-70.9c0-10.7-13-16.1-20.5-8.5L121.2 247.5c-4.7 4.7-4.7 12.2 0 16.9l114.3 114.9c7.6 7.6 20.5 2.2 20.5-8.5V300h116c6.6 0 12-5.4 12-12v-64c0-6.6-5.4-12-12-12z"],"arrow-alt-circle-right":[512,512,[],"f35a","M256 8c137 0 248 111 248 248S393 504 256 504 8 393 8 256 119 8 256 8zM140 300h116v70.9c0 10.7 13 16.1 20.5 8.5l114.3-114.9c4.7-4.7 4.7-12.2 0-16.9l-114.3-115c-7.6-7.6-20.5-2.2-20.5 8.5V212H140c-6.6 0-12 5.4-12 12v64c0 6.6 5.4 12 12 12z"],"arrow-alt-circle-up":[512,512,[],"f35b","M8 256C8 119 119 8 256 8s248 111 248 248-111 248-248 248S8 393 8 256zm292 116V256h70.9c10.7 0 16.1-13 8.5-20.5L264.5 121.2c-4.7-4.7-12.2-4.7-16.9 0l-115 114.3c-7.6 7.6-2.2 20.5 8.5 20.5H212v116c0 6.6 5.4 12 12 12h64c6.6 0 12-5.4 12-12z"],"arrow-circle-down":[512,512,[],"f0ab","M504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-143.6-28.9L288 302.6V120c0-13.3-10.7-24-24-24h-16c-13.3 0-24 10.7-24 24v182.6l-72.4-75.5c-9.3-9.7-24.8-9.9-34.3-.4l-10.9 11c-9.4 9.4-9.4 24.6 0 33.9L239 404.3c9.4 9.4 24.6 9.4 33.9 0l132.7-132.7c9.4-9.4 9.4-24.6 0-33.9l-10.9-11c-9.5-9.5-25-9.3-34.3.4z"],"arrow-circle-left":[512,512,[],"f0a8","M256 504C119 504 8 393 8 256S119 8 256 8s248 111 248 248-111 248-248 248zm28.9-143.6L209.4 288H392c13.3 0 24-10.7 24-24v-16c0-13.3-10.7-24-24-24H209.4l75.5-72.4c9.7-9.3 9.9-24.8.4-34.3l-11-10.9c-9.4-9.4-24.6-9.4-33.9 0L107.7 239c-9.4 9.4-9.4 24.6 0 33.9l132.7 132.7c9.4 9.4 24.6 9.4 33.9 0l11-10.9c9.5-9.5 9.3-25-.4-34.3z"],"arrow-circle-right":[512,512,[],"f0a9","M256 8c137 0 248 111 248 248S393 504 256 504 8 393 8 256 119 8 256 8zm-28.9 143.6l75.5 72.4H120c-13.3 0-24 10.7-24 24v16c0 13.3 10.7 24 24 24h182.6l-75.5 72.4c-9.7 9.3-9.9 24.8-.4 34.3l11 10.9c9.4 9.4 24.6 9.4 33.9 0L404.3 273c9.4-9.4 9.4-24.6 0-33.9L271.6 106.3c-9.4-9.4-24.6-9.4-33.9 0l-11 10.9c-9.5 9.6-9.3 25.1.4 34.4z"],"arrow-circle-up":[512,512,[],"f0aa","M8 256C8 119 119 8 256 8s248 111 248 248-111 248-248 248S8 393 8 256zm143.6 28.9l72.4-75.5V392c0 13.3 10.7 24 24 24h16c13.3 0 24-10.7 24-24V209.4l72.4 75.5c9.3 9.7 24.8 9.9 34.3.4l10.9-11c9.4-9.4 9.4-24.6 0-33.9L273 107.7c-9.4-9.4-24.6-9.4-33.9 0L106.3 240.4c-9.4 9.4-9.4 24.6 0 33.9l10.9 11c9.6 9.5 25.1 9.3 34.4-.4z"],"arrow-down":[448,512,[],"f063","M413.1 222.5l22.2 22.2c9.4 9.4 9.4 24.6 0 33.9L241 473c-9.4 9.4-24.6 9.4-33.9 0L12.7 278.6c-9.4-9.4-9.4-24.6 0-33.9l22.2-22.2c9.5-9.5 25-9.3 34.3.4L184 343.4V56c0-13.3 10.7-24 24-24h32c13.3 0 24 10.7 24 24v287.4l114.8-120.5c9.3-9.8 24.8-10 34.3-.4z"],"arrow-left":[448,512,[],"f060","M257.5 445.1l-22.2 22.2c-9.4 9.4-24.6 9.4-33.9 0L7 273c-9.4-9.4-9.4-24.6 0-33.9L201.4 44.7c9.4-9.4 24.6-9.4 33.9 0l22.2 22.2c9.5 9.5 9.3 25-.4 34.3L136.6 216H424c13.3 0 24 10.7 24 24v32c0 13.3-10.7 24-24 24H136.6l120.5 114.8c9.8 9.3 10 24.8.4 34.3z"],"arrow-right":[448,512,[],"f061","M190.5 66.9l22.2-22.2c9.4-9.4 24.6-9.4 33.9 0L441 239c9.4 9.4 9.4 24.6 0 33.9L246.6 467.3c-9.4 9.4-24.6 9.4-33.9 0l-22.2-22.2c-9.5-9.5-9.3-25 .4-34.3L311.4 296H24c-13.3 0-24-10.7-24-24v-32c0-13.3 10.7-24 24-24h287.4L190.9 101.2c-9.8-9.3-10-24.8-.4-34.3z"],"arrow-up":[448,512,[],"f062","M34.9 289.5l-22.2-22.2c-9.4-9.4-9.4-24.6 0-33.9L207 39c9.4-9.4 24.6-9.4 33.9 0l194.3 194.3c9.4 9.4 9.4 24.6 0 33.9L413 289.4c-9.5 9.5-25 9.3-34.3-.4L264 168.6V456c0 13.3-10.7 24-24 24h-32c-13.3 0-24-10.7-24-24V168.6L69.2 289.1c-9.3 9.8-24.8 10-34.3.4z"],"arrows-alt":[512,512,[],"f0b2","M352.201 425.775l-79.196 79.196c-9.373 9.373-24.568 9.373-33.941 0l-79.196-79.196c-15.119-15.119-4.411-40.971 16.971-40.97h51.162L228 284H127.196v51.162c0 21.382-25.851 32.09-40.971 16.971L7.029 272.937c-9.373-9.373-9.373-24.569 0-33.941L86.225 159.8c15.119-15.119 40.971-4.411 40.971 16.971V228H228V127.196h-51.23c-21.382 0-32.09-25.851-16.971-40.971l79.196-79.196c9.373-9.373 24.568-9.373 33.941 0l79.196 79.196c15.119 15.119 4.411 40.971-16.971 40.971h-51.162V228h100.804v-51.162c0-21.382 25.851-32.09 40.97-16.971l79.196 79.196c9.373 9.373 9.373 24.569 0 33.941L425.773 352.2c-15.119 15.119-40.971 4.411-40.97-16.971V284H284v100.804h51.23c21.382 0 32.09 25.851 16.971 40.971z"],"arrows-alt-h":[512,512,[],"f337","M377.941 169.941V216H134.059v-46.059c0-21.382-25.851-32.09-40.971-16.971L7.029 239.029c-9.373 9.373-9.373 24.568 0 33.941l86.059 86.059c15.119 15.119 40.971 4.411 40.971-16.971V296h243.882v46.059c0 21.382 25.851 32.09 40.971 16.971l86.059-86.059c9.373-9.373 9.373-24.568 0-33.941l-86.059-86.059c-15.119-15.12-40.971-4.412-40.971 16.97z"],"arrows-alt-v":[256,512,[],"f338","M214.059 377.941H168V134.059h46.059c21.382 0 32.09-25.851 16.971-40.971L144.971 7.029c-9.373-9.373-24.568-9.373-33.941 0L24.971 93.088c-15.119 15.119-4.411 40.971 16.971 40.971H88v243.882H41.941c-21.382 0-32.09 25.851-16.971 40.971l86.059 86.059c9.373 9.373 24.568 9.373 33.941 0l86.059-86.059c15.12-15.119 4.412-40.971-16.97-40.971z"],"assistive-listening-systems":[512,512,[],"f2a2","M216 260c0 15.464-12.536 28-28 28s-28-12.536-28-28c0-44.112 35.888-80 80-80s80 35.888 80 80c0 15.464-12.536 28-28 28s-28-12.536-28-28c0-13.234-10.767-24-24-24s-24 10.766-24 24zm24-176c-97.047 0-176 78.953-176 176 0 15.464 12.536 28 28 28s28-12.536 28-28c0-66.168 53.832-120 120-120s120 53.832 120 120c0 75.164-71.009 70.311-71.997 143.622L288 404c0 28.673-23.327 52-52 52-15.464 0-28 12.536-28 28s12.536 28 28 28c59.475 0 107.876-48.328 108-107.774.595-34.428 72-48.24 72-144.226 0-97.047-78.953-176-176-176zm-80 236c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zM32 448c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm480-187.993c0-1.518-.012-3.025-.045-4.531C510.076 140.525 436.157 38.47 327.994 1.511c-14.633-4.998-30.549 2.809-35.55 17.442-5 14.633 2.81 30.549 17.442 35.55 85.906 29.354 144.61 110.513 146.077 201.953l.003.188c.026 1.118.033 2.236.033 3.363 0 15.464 12.536 28 28 28s28.001-12.536 28.001-28zM152.971 439.029l-80-80L39.03 392.97l80 80 33.941-33.941z"],asterisk:[512,512,[],"f069","M478.21 334.093L336 256l142.21-78.093c11.795-6.477 15.961-21.384 9.232-33.037l-19.48-33.741c-6.728-11.653-21.72-15.499-33.227-8.523L296 186.718l3.475-162.204C299.763 11.061 288.937 0 275.48 0h-38.96c-13.456 0-24.283 11.061-23.994 24.514L216 186.718 77.265 102.607c-11.506-6.976-26.499-3.13-33.227 8.523l-19.48 33.741c-6.728 11.653-2.562 26.56 9.233 33.037L176 256 33.79 334.093c-11.795 6.477-15.961 21.384-9.232 33.037l19.48 33.741c6.728 11.653 21.721 15.499 33.227 8.523L216 325.282l-3.475 162.204C212.237 500.939 223.064 512 236.52 512h38.961c13.456 0 24.283-11.061 23.995-24.514L296 325.282l138.735 84.111c11.506 6.976 26.499 3.13 33.227-8.523l19.48-33.741c6.728-11.653 2.563-26.559-9.232-33.036z"],at:[512,512,[],"f1fa","M256 8C118.941 8 8 118.919 8 256c0 137.059 110.919 248 248 248 48.154 0 95.342-14.14 135.408-40.223 12.005-7.815 14.625-24.288 5.552-35.372l-10.177-12.433c-7.671-9.371-21.179-11.667-31.373-5.129C325.92 429.757 291.314 440 256 440c-101.458 0-184-82.542-184-184S154.542 72 256 72c100.139 0 184 57.619 184 160 0 38.786-21.093 79.742-58.17 83.693-17.349-.454-16.91-12.857-13.476-30.024l23.433-121.11C394.653 149.75 383.308 136 368.225 136h-44.981a13.518 13.518 0 0 0-13.432 11.993l-.01.092c-14.697-17.901-40.448-21.775-59.971-21.775-74.58 0-137.831 62.234-137.831 151.46 0 65.303 36.785 105.87 96 105.87 26.984 0 57.369-15.637 74.991-38.333 9.522 34.104 40.613 34.103 70.71 34.103C462.609 379.41 504 307.798 504 232 504 95.653 394.023 8 256 8zm-21.68 304.43c-22.249 0-36.07-15.623-36.07-40.771 0-44.993 30.779-72.729 58.63-72.729 22.292 0 35.601 15.241 35.601 40.77 0 45.061-33.875 72.73-58.161 72.73z"],"audio-description":[512,512,[],"f29e","M162.925 238.709l8.822 30.655h-25.606l9.041-30.652c1.277-4.421 2.651-9.994 3.872-15.245 1.22 5.251 2.594 10.823 3.871 15.242zm166.474-32.099h-14.523v98.781h14.523c29.776 0 46.175-17.678 46.175-49.776 0-32.239-17.49-49.005-46.175-49.005zM512 112v288c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48zM245.459 336.139l-57.097-168A12.001 12.001 0 0 0 177 160h-35.894a12.001 12.001 0 0 0-11.362 8.139l-57.097 168C70.003 343.922 75.789 352 84.009 352h29.133a12 12 0 0 0 11.535-8.693l8.574-29.906h51.367l8.793 29.977A12 12 0 0 0 204.926 352h29.172c8.22 0 14.006-8.078 11.361-15.861zm184.701-80.525c0-58.977-37.919-95.614-98.96-95.614h-57.366c-6.627 0-12 5.373-12 12v168c0 6.627 5.373 12 12 12H331.2c61.041 0 98.96-36.933 98.96-96.386z"],backward:[512,512,[],"f04a","M11.5 280.6l192 160c20.6 17.2 52.5 2.8 52.5-24.6V96c0-27.4-31.9-41.8-52.5-24.6l-192 160c-15.3 12.8-15.3 36.4 0 49.2zm256 0l192 160c20.6 17.2 52.5 2.8 52.5-24.6V96c0-27.4-31.9-41.8-52.5-24.6l-192 160c-15.3 12.8-15.3 36.4 0 49.2z"],"balance-scale":[640,512,[],"f24e","M352 448h168c13.255 0 24 10.745 24 24v16c0 13.255-10.745 24-24 24H120c-13.255 0-24-10.745-24-24v-16c0-13.255 10.745-24 24-24h168V153.324C264.469 143.04 246.836 121.778 241.603 96H120c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24h135.999C270.594 12.57 293.828 0 320 0s49.406 12.57 64.001 32H520c13.255 0 24 10.745 24 24v16c0 13.255-10.745 24-24 24H398.397c-5.233 25.778-22.866 47.04-46.397 57.324V448zm287.981-112c.001-16.182 1.342-8.726-85.048-181.506-17.647-35.294-68.186-35.358-85.865 0C381.94 328.75 384.019 320.331 384.019 336H384c0 44.183 57.308 80 128 80s128-35.817 128-80h-.019zM512 176l72 144H440l72-144zM255.981 336c.001-16.182 1.342-8.726-85.048-181.506-17.647-35.294-68.186-35.358-85.865 0C-2.06 328.75.019 320.331.019 336H0c0 44.183 57.308 80 128 80s128-35.817 128-80h-.019zM128 176l72 144H56l72-144z"],ban:[512,512,[],"f05e","M256 8C119.034 8 8 119.033 8 256s111.034 248 248 248 248-111.034 248-248S392.967 8 256 8zm130.108 117.892c65.448 65.448 70 165.481 20.677 235.637L150.47 105.216c70.204-49.356 170.226-44.735 235.638 20.676zM125.892 386.108c-65.448-65.448-70-165.481-20.677-235.637L361.53 406.784c-70.203 49.356-170.226 44.736-235.638-20.676z"],"band-aid":[640,512,[],"f462","M0 160v192c0 35.3 28.7 64 64 64h96V96H64c-35.3 0-64 28.7-64 64zm576-64h-96v320h96c35.3 0 64-28.7 64-64V160c0-35.3-28.7-64-64-64zM192 416h256V96H192v320zm176-232c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zm0 96c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zm-96-96c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zm0 96c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24z"],barcode:[512,512,[],"f02a","M0 448V64h18v384H0zm26.857-.273V64H36v383.727h-9.143zm27.143 0V64h8.857v383.727H54zm44.857 0V64h8.857v383.727h-8.857zm36 0V64h17.714v383.727h-17.714zm44.857 0V64h8.857v383.727h-8.857zm18 0V64h8.857v383.727h-8.857zm18 0V64h8.857v383.727h-8.857zm35.715 0V64h18v383.727h-18zm44.857 0V64h18v383.727h-18zm35.999 0V64h18.001v383.727h-18.001zm36.001 0V64h18.001v383.727h-18.001zm26.857 0V64h18v383.727h-18zm45.143 0V64h26.857v383.727h-26.857zm35.714 0V64h9.143v383.727H476zm18 .273V64h18v384h-18z"],bars:[448,512,[],"f0c9","M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"],"baseball-ball":[496,512,[],"f433","M368.5 363.9l28.8-13.9c11.1 22.9 26 43.2 44.1 60.9 34-42.5 54.5-96.3 54.5-154.9 0-58.5-20.4-112.2-54.2-154.6-17.8 17.3-32.6 37.1-43.6 59.5l-28.7-14.1c12.8-26 30-49 50.8-69C375.6 34.7 315 8 248 8 181.1 8 120.5 34.6 75.9 77.7c20.7 19.9 37.9 42.9 50.7 68.8l-28.7 14.1c-11-22.3-25.7-42.1-43.5-59.4C20.4 143.7 0 197.4 0 256c0 58.6 20.4 112.3 54.4 154.7 18.2-17.7 33.2-38 44.3-61l28.8 13.9c-12.9 26.7-30.3 50.3-51.5 70.7 44.5 43.1 105.1 69.7 172 69.7 66.8 0 127.3-26.5 171.9-69.5-21.1-20.4-38.5-43.9-51.4-70.6zm-228.3-32l-30.5-9.8c14.9-46.4 12.7-93.8-.6-134l30.4-10c15 45.6 18 99.9.7 153.8zm216.3-153.4l30.4 10c-13.2 40.1-15.5 87.5-.6 134l-30.5 9.8c-17.3-54-14.3-108.3.7-153.8z"],"basketball-ball":[496,512,[],"f434","M212.3 10.3c-43.8 6.3-86.2 24.1-122.2 53.8l77.4 77.4c27.8-35.8 43.3-81.2 44.8-131.2zM248 222L405.9 64.1c-42.4-35-93.6-53.5-145.5-56.1-1.2 63.9-21.5 122.3-58.7 167.7L248 222zM56.1 98.1c-29.7 36-47.5 78.4-53.8 122.2 50-1.5 95.5-17 131.2-44.8L56.1 98.1zm272.2 204.2c45.3-37.1 103.7-57.4 167.7-58.7-2.6-51.9-21.1-103.1-56.1-145.5L282 256l46.3 46.3zM248 290L90.1 447.9c42.4 34.9 93.6 53.5 145.5 56.1 1.3-64 21.6-122.4 58.7-167.7L248 290zm191.9 123.9c29.7-36 47.5-78.4 53.8-122.2-50.1 1.6-95.5 17.1-131.2 44.8l77.4 77.4zM167.7 209.7C122.3 246.9 63.9 267.3 0 268.4c2.6 51.9 21.1 103.1 56.1 145.5L214 256l-46.3-46.3zm116 292c43.8-6.3 86.2-24.1 122.2-53.8l-77.4-77.4c-27.7 35.7-43.2 81.2-44.8 131.2z"],bath:[512,512,[],"f2cd","M488 256H80V112c0-17.645 14.355-32 32-32 11.351 0 21.332 5.945 27.015 14.88-16.492 25.207-14.687 59.576 6.838 83.035-4.176 4.713-4.021 11.916.491 16.428l11.314 11.314c4.686 4.686 12.284 4.686 16.971 0l95.03-95.029c4.686-4.686 4.686-12.284 0-16.971l-11.314-11.314c-4.512-4.512-11.715-4.666-16.428-.491-17.949-16.469-42.294-21.429-64.178-15.365C163.281 45.667 139.212 32 112 32c-44.112 0-80 35.888-80 80v144h-8c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h8v32c0 28.43 12.362 53.969 32 71.547V456c0 13.255 10.745 24 24 24h16c13.255 0 24-10.745 24-24v-8h256v8c0 13.255 10.745 24 24 24h16c13.255 0 24-10.745 24-24v-32.453c19.638-17.578 32-43.117 32-71.547v-32h8c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24z"],"battery-empty":[640,512,[],"f244","M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48z"],"battery-full":[640,512,[],"f240","M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48zm-48 96H96v128h416V192z"],"battery-half":[640,512,[],"f242","M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48zm-240 96H96v128h224V192z"],"battery-quarter":[640,512,[],"f243","M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48zm-336 96H96v128h128V192z"],"battery-three-quarters":[640,512,[],"f241","M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48zm-144 96H96v128h320V192z"],bed:[576,512,[],"f236","M552 288c13.255 0 24 10.745 24 24v136h-96v-64H96v64H0V88c0-13.255 10.745-24 24-24h48c13.255 0 24 10.745 24 24v200h456zM192 96c-44.183 0-80 35.817-80 80s35.817 80 80 80 80-35.817 80-80-35.817-80-80-80zm384 128c0-53.019-42.981-96-96-96H312c-13.255 0-24 10.745-24 24v104h288v-32z"],beer:[448,512,[],"f0fc","M368 96h-48V56c0-13.255-10.745-24-24-24H24C10.745 32 0 42.745 0 56v400c0 13.255 10.745 24 24 24h272c13.255 0 24-10.745 24-24v-42.11l80.606-35.977C429.396 365.063 448 336.388 448 304.86V176c0-44.112-35.888-80-80-80zm16 208.86a16.018 16.018 0 0 1-9.479 14.611L320 343.805V160h48c8.822 0 16 7.178 16 16v128.86zM208 384c-8.836 0-16-7.164-16-16V144c0-8.836 7.164-16 16-16s16 7.164 16 16v224c0 8.836-7.164 16-16 16zm-96 0c-8.836 0-16-7.164-16-16V144c0-8.836 7.164-16 16-16s16 7.164 16 16v224c0 8.836-7.164 16-16 16z"],bell:[448,512,[],"f0f3","M433.884 366.059C411.634 343.809 384 316.118 384 208c0-79.394-57.831-145.269-133.663-157.83A31.845 31.845 0 0 0 256 32c0-17.673-14.327-32-32-32s-32 14.327-32 32c0 6.75 2.095 13.008 5.663 18.17C121.831 62.731 64 128.606 64 208c0 108.118-27.643 135.809-49.893 158.059C-16.042 396.208 5.325 448 48.048 448H160c0 35.346 28.654 64 64 64s64-28.654 64-64h111.943c42.638 0 64.151-51.731 33.941-81.941zM224 472a8 8 0 0 1 0 16c-22.056 0-40-17.944-40-40h16c0 13.234 10.766 24 24 24z"],"bell-slash":[576,512,[],"f1f6","M78.107 366.059C47.958 396.208 69.325 448 112.048 448H224c0 35.346 28.654 64 64 64 35.346 0 64-28.654 64-64h32.685L127.848 221.379c-2.198 97.078-28.439 123.378-49.741 144.68zM264 448c0 13.234 10.766 24 24 24a8 8 0 0 1 0 16c-22.056 0-40-17.944-40-40h16zm305.896 43.733l-10.762 12.086c-8.915 10.012-24.333 10.967-34.437 2.133L8.256 54.393C-1.848 45.558-2.811 30.28 6.104 20.267L16.865 8.181C25.781-1.831 41.199-2.786 51.303 6.049l113.81 99.512c24.017-28.778 57.946-48.996 96.55-55.39A31.85 31.85 0 0 1 256 32c0-17.673 14.327-32 32-32s32 14.327 32 32c0 6.75-2.095 13.008-5.663 18.17C390.169 62.731 448 128.606 448 208c0 108.118 27.634 135.809 49.884 158.059 12.149 12.149 15.923 27.776 13.33 42.121l56.53 49.427c10.104 8.835 11.067 24.113 2.152 34.126z"],bicycle:[640,512,[],"f206","M512.509 192.001c-16.373-.064-32.03 2.955-46.436 8.495l-77.68-125.153A24 24 0 0 0 368.001 64h-64c-8.837 0-16 7.163-16 16v16c0 8.837 7.163 16 16 16h50.649l14.896 24H256.002v-16c0-8.837-7.163-16-16-16h-87.459c-13.441 0-24.777 10.999-24.536 24.437.232 13.044 10.876 23.563 23.995 23.563h48.726l-29.417 47.52c-13.433-4.83-27.904-7.483-42.992-7.52C58.094 191.83.412 249.012.002 319.236-.413 390.279 57.055 448 128.002 448c59.642 0 109.758-40.793 123.967-96h52.033a24 24 0 0 0 20.406-11.367L410.37 201.77l14.938 24.067c-25.455 23.448-41.385 57.081-41.307 94.437.145 68.833 57.899 127.051 126.729 127.719 70.606.685 128.181-55.803 129.255-125.996 1.086-70.941-56.526-129.72-127.476-129.996zM186.75 265.772c9.727 10.529 16.673 23.661 19.642 38.228h-43.306l23.664-38.228zM128.002 400c-44.112 0-80-35.888-80-80s35.888-80 80-80c5.869 0 11.586.653 17.099 1.859l-45.505 73.509C89.715 331.327 101.213 352 120.002 352h81.3c-12.37 28.225-40.562 48-73.3 48zm162.63-96h-35.624c-3.96-31.756-19.556-59.894-42.383-80.026L237.371 184h127.547l-74.286 120zm217.057 95.886c-41.036-2.165-74.049-35.692-75.627-76.755-.812-21.121 6.633-40.518 19.335-55.263l44.433 71.586c4.66 7.508 14.524 9.816 22.032 5.156l13.594-8.437c7.508-4.66 9.817-14.524 5.156-22.032l-44.468-71.643a79.901 79.901 0 0 1 19.858-2.497c44.112 0 80 35.888 80 80-.001 45.54-38.252 82.316-84.313 79.885z"],binoculars:[512,512,[],"f1e5","M192 104H96V56c0-13.255 10.745-24 24-24h48c13.255 0 24 10.745 24 24v48zm224-48c0-13.255-10.745-24-24-24h-48c-13.255 0-24 10.745-24 24v48h96V56zM0 456c0 13.255 10.745 24 24 24h120c13.255 0 24-10.745 24-24v-16H0v16zm88-328c-13.255 0-24 10.745-24 24C64 256 0 272 0 416h168V312c0-13.255 10.745-24 24-24V128H88zm256 328c0 13.255 10.745 24 24 24h120c13.255 0 24-10.745 24-24v-16H344v16zM216 128v160h80V128h-80zm128 288h168c0-144-64-160-64-264 0-13.255-10.745-24-24-24H320v160c13.255 0 24 10.745 24 24v104z"],"birthday-cake":[448,512,[],"f1fd","M448 384c-28.02 0-31.26-32-74.5-32-43.43 0-46.825 32-74.75 32-27.695 0-31.454-32-74.75-32-42.842 0-47.218 32-74.5 32-28.148 0-31.202-32-74.75-32-43.547 0-46.653 32-74.75 32v-80c0-26.5 21.5-48 48-48h16V112h64v144h64V112h64v144h64V112h64v144h16c26.5 0 48 21.5 48 48v80zm0 128H0v-96c43.356 0 46.767-32 74.75-32 27.951 0 31.253 32 74.75 32 42.843 0 47.217-32 74.5-32 28.148 0 31.201 32 74.75 32 43.357 0 46.767-32 74.75-32 27.488 0 31.252 32 74.5 32v96zM96 96c-17.75 0-32-14.25-32-32 0-31 32-23 32-64 12 0 32 29.5 32 56s-14.25 40-32 40zm128 0c-17.75 0-32-14.25-32-32 0-31 32-23 32-64 12 0 32 29.5 32 56s-14.25 40-32 40zm128 0c-17.75 0-32-14.25-32-32 0-31 32-23 32-64 12 0 32 29.5 32 56s-14.25 40-32 40z"],blind:[384,512,[],"f29d","M380.15 510.837a8 8 0 0 1-10.989-2.687l-125.33-206.427a31.923 31.923 0 0 0 12.958-9.485l126.048 207.608a8 8 0 0 1-2.687 10.991zM142.803 314.338l-32.54 89.485 36.12 88.285c6.693 16.36 25.377 24.192 41.733 17.501 16.357-6.692 24.193-25.376 17.501-41.734l-62.814-153.537zM96 88c24.301 0 44-19.699 44-44S120.301 0 96 0 52 19.699 52 44s19.699 44 44 44zm154.837 169.128l-120-152c-4.733-5.995-11.75-9.108-18.837-9.112V96H80v.026c-7.146.003-14.217 3.161-18.944 9.24L0 183.766v95.694c0 13.455 11.011 24.791 24.464 24.536C37.505 303.748 48 293.1 48 280v-79.766l16-20.571v140.698L9.927 469.055c-6.04 16.609 2.528 34.969 19.138 41.009 16.602 6.039 34.968-2.524 41.009-19.138L136 309.638V202.441l-31.406-39.816a4 4 0 1 1 6.269-4.971l102.3 129.217c9.145 11.584 24.368 11.339 33.708 3.965 10.41-8.216 12.159-23.334 3.966-33.708z"],bold:[384,512,[],"f032","M304.793 243.891c33.639-18.537 53.657-54.16 53.657-95.693 0-48.236-26.25-87.626-68.626-104.179C265.138 34.01 240.849 32 209.661 32H24c-8.837 0-16 7.163-16 16v33.049c0 8.837 7.163 16 16 16h33.113v318.53H24c-8.837 0-16 7.163-16 16V464c0 8.837 7.163 16 16 16h195.69c24.203 0 44.834-1.289 66.866-7.584C337.52 457.193 376 410.647 376 350.014c0-52.168-26.573-91.684-71.207-106.123zM142.217 100.809h67.444c16.294 0 27.536 2.019 37.525 6.717 15.828 8.479 24.906 26.502 24.906 49.446 0 35.029-20.32 56.79-53.029 56.79h-76.846V100.809zm112.642 305.475c-10.14 4.056-22.677 4.907-31.409 4.907h-81.233V281.943h84.367c39.645 0 63.057 25.38 63.057 63.057.001 28.425-13.66 52.483-34.782 61.284z"],bolt:[320,512,[],"f0e7","M295.973 160H180.572L215.19 30.184C219.25 14.956 207.756 0 192 0H56C43.971 0 33.8 8.905 32.211 20.828l-31.996 240C-1.704 275.217 9.504 288 24.004 288h118.701L96.646 482.466C93.05 497.649 104.659 512 119.992 512c8.35 0 16.376-4.374 20.778-11.978l175.973-303.997c9.244-15.967-2.288-36.025-20.77-36.025z"],bomb:[512,512,[],"f1e2","M440.5 88.5l-52 52L415 167c9.4 9.4 9.4 24.6 0 33.9l-17.4 17.4c11.8 26.1 18.4 55.1 18.4 85.6 0 114.9-93.1 208-208 208S0 418.9 0 304 93.1 96 208 96c30.5 0 59.5 6.6 85.6 18.4L311 97c9.4-9.4 24.6-9.4 33.9 0l26.5 26.5 52-52 17.1 17zM500 60h-24c-6.6 0-12 5.4-12 12s5.4 12 12 12h24c6.6 0 12-5.4 12-12s-5.4-12-12-12zM440 0c-6.6 0-12 5.4-12 12v24c0 6.6 5.4 12 12 12s12-5.4 12-12V12c0-6.6-5.4-12-12-12zm33.9 55l17-17c4.7-4.7 4.7-12.3 0-17-4.7-4.7-12.3-4.7-17 0l-17 17c-4.7 4.7-4.7 12.3 0 17 4.8 4.7 12.4 4.7 17 0zm-67.8 0c4.7 4.7 12.3 4.7 17 0 4.7-4.7 4.7-12.3 0-17l-17-17c-4.7-4.7-12.3-4.7-17 0-4.7 4.7-4.7 12.3 0 17l17 17zm67.8 34c-4.7-4.7-12.3-4.7-17 0-4.7 4.7-4.7 12.3 0 17l17 17c4.7 4.7 12.3 4.7 17 0 4.7-4.7 4.7-12.3 0-17l-17-17zM112 272c0-35.3 28.7-64 64-64 8.8 0 16-7.2 16-16s-7.2-16-16-16c-52.9 0-96 43.1-96 96 0 8.8 7.2 16 16 16s16-7.2 16-16z"],book:[448,512,[],"f02d","M448 360V24c0-13.3-10.7-24-24-24H96C43 0 0 43 0 96v320c0 53 43 96 96 96h328c13.3 0 24-10.7 24-24v-16c0-7.5-3.5-14.3-8.9-18.7-4.2-15.4-4.2-59.3 0-74.7 5.4-4.3 8.9-11.1 8.9-18.6zM128 134c0-3.3 2.7-6 6-6h212c3.3 0 6 2.7 6 6v20c0 3.3-2.7 6-6 6H134c-3.3 0-6-2.7-6-6v-20zm0 64c0-3.3 2.7-6 6-6h212c3.3 0 6 2.7 6 6v20c0 3.3-2.7 6-6 6H134c-3.3 0-6-2.7-6-6v-20zm253.4 250H96c-17.7 0-32-14.3-32-32 0-17.6 14.4-32 32-32h285.4c-1.9 17.1-1.9 46.9 0 64z"],bookmark:[384,512,[],"f02e","M0 512V48C0 21.49 21.49 0 48 0h288c26.51 0 48 21.49 48 48v464L192 400 0 512z"],"bowling-ball":[496,512,[],"f436","M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zM120 192c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm64-96c0-17.7 14.3-32 32-32s32 14.3 32 32-14.3 32-32 32-32-14.3-32-32zm48 144c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z"],box:[512,512,[],"f466","M509.5 184.6L458.9 32.8C452.4 13.2 434.1 0 413.4 0H272v192h238.7c-.4-2.5-.4-5-1.2-7.4zM240 0H98.6c-20.7 0-39 13.2-45.5 32.8L2.5 184.6c-.8 2.4-.8 4.9-1.2 7.4H240V0zM0 224v240c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V224H0z"],"box-open":[640,512,[],"f49e","M53.2 41L1.7 143.8c-4.6 9.2.3 20.2 10.1 23l197.9 56.5c7.1 2 14.7-1 18.5-7.3L320 64 69.8 32.1c-6.9-.8-13.5 2.7-16.6 8.9zm585.1 102.8L586.8 41c-3.1-6.2-9.8-9.8-16.7-8.9L320 64l91.7 152.1c3.8 6.3 11.4 9.3 18.5 7.3l197.9-56.5c9.9-2.9 14.7-13.9 10.2-23.1zM425.7 256c-16.9 0-32.8-9-41.4-23.4L320 126l-64.2 106.6c-8.7 14.5-24.6 23.5-41.5 23.5-4.5 0-9-.6-13.3-1.9L64 215v178c0 14.7 10 27.5 24.2 31l216.2 54.1c10.2 2.5 20.9 2.5 31 0L551.8 424c14.2-3.6 24.2-16.4 24.2-31V215l-137 39.1c-4.3 1.3-8.8 1.9-13.3 1.9z"],boxes:[576,512,[],"f468","M560 288h-80v96l-32-21.3-32 21.3v-96h-80c-8.8 0-16 7.2-16 16v192c0 8.8 7.2 16 16 16h224c8.8 0 16-7.2 16-16V304c0-8.8-7.2-16-16-16zm-384-64h224c8.8 0 16-7.2 16-16V16c0-8.8-7.2-16-16-16h-80v96l-32-21.3L256 96V0h-80c-8.8 0-16 7.2-16 16v192c0 8.8 7.2 16 16 16zm64 64h-80v96l-32-21.3L96 384v-96H16c-8.8 0-16 7.2-16 16v192c0 8.8 7.2 16 16 16h224c8.8 0 16-7.2 16-16V304c0-8.8-7.2-16-16-16z"],braille:[640,512,[],"f2a1","M128 256c0 35.346-28.654 64-64 64S0 291.346 0 256s28.654-64 64-64 64 28.654 64 64zM64 384c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0-352C28.654 32 0 60.654 0 96s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64zm160 192c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0 160c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0-352c-35.346 0-64 28.654-64 64s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64zm224 192c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0 160c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0-352c-35.346 0-64 28.654-64 64s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64zm160 192c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0 160c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0-320c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32z"],briefcase:[512,512,[],"f0b1","M320 288h192v144c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V288h192v20c0 6.627 5.373 12 12 12h104c6.627 0 12-5.373 12-12v-20zm192-112v80H0v-80c0-26.51 21.49-48 48-48h80V80c0-26.51 21.49-48 48-48h160c26.51 0 48 21.49 48 48v48h80c26.51 0 48 21.49 48 48zM320 96H192v32h128V96z"],"briefcase-medical":[512,512,[],"f469","M464 128h-80V80c0-26.5-21.5-48-48-48H176c-26.5 0-48 21.5-48 48v48H48c-26.5 0-48 21.5-48 48v288c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V176c0-26.5-21.5-48-48-48zM192 96h128v32H192V96zm160 248c0 4.4-3.6 8-8 8h-56v56c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8v-56h-56c-4.4 0-8-3.6-8-8v-48c0-4.4 3.6-8 8-8h56v-56c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v56h56c4.4 0 8 3.6 8 8v48z"],bug:[512,512,[],"f188","M511.988 288.9c-.478 17.43-15.217 31.1-32.653 31.1H424v16c0 21.864-4.882 42.584-13.6 61.145l60.228 60.228c12.496 12.497 12.496 32.758 0 45.255-12.498 12.497-32.759 12.496-45.256 0l-54.736-54.736C345.886 467.965 314.351 480 280 480V236c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v244c-34.351 0-65.886-12.035-90.636-32.108l-54.736 54.736c-12.498 12.497-32.759 12.496-45.256 0-12.496-12.497-12.496-32.758 0-45.255l60.228-60.228C92.882 378.584 88 357.864 88 336v-16H32.666C15.23 320 .491 306.33.013 288.9-.484 270.816 14.028 256 32 256h56v-58.745l-46.628-46.628c-12.496-12.497-12.496-32.758 0-45.255 12.498-12.497 32.758-12.497 45.256 0L141.255 160h229.489l54.627-54.627c12.498-12.497 32.758-12.497 45.256 0 12.496 12.497 12.496 32.758 0 45.255L424 197.255V256h56c17.972 0 32.484 14.816 31.988 32.9zM257 0c-61.856 0-112 50.144-112 112h224C369 50.144 318.856 0 257 0z"],building:[448,512,[],"f1ad","M436 480h-20V24c0-13.255-10.745-24-24-24H56C42.745 0 32 10.745 32 24v456H12c-6.627 0-12 5.373-12 12v20h448v-20c0-6.627-5.373-12-12-12zM128 76c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12V76zm0 96c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12v-40zm52 148h-40c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12zm76 160h-64v-84c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v84zm64-172c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40zm0-96c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40zm0-96c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12V76c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40z"],bullhorn:[576,512,[],"f0a1","M576 224c0-20.896-13.36-38.666-32-45.258V64c0-35.346-28.654-64-64-64-64.985 56-142.031 128-272 128H48c-26.51 0-48 21.49-48 48v96c0 26.51 21.49 48 48 48h43.263c-18.742 64.65 2.479 116.379 18.814 167.44 1.702 5.32 5.203 9.893 9.922 12.88 20.78 13.155 68.355 15.657 93.773 5.151 16.046-6.633 19.96-27.423 7.522-39.537-18.508-18.026-30.136-36.91-19.795-60.858a12.278 12.278 0 0 0-1.045-11.673c-16.309-24.679-3.581-62.107 28.517-72.752C346.403 327.887 418.591 395.081 480 448c35.346 0 64-28.654 64-64V269.258c18.64-6.592 32-24.362 32-45.258zm-96 139.855c-54.609-44.979-125.033-92.94-224-104.982v-69.747c98.967-12.042 169.391-60.002 224-104.982v279.711z"],bullseye:[512,512,[],"f140","M256 72c101.689 0 184 82.295 184 184 0 101.689-82.295 184-184 184-101.689 0-184-82.295-184-184 0-101.689 82.295-184 184-184m0-64C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 184c35.29 0 64 28.71 64 64s-28.71 64-64 64-64-28.71-64-64 28.71-64 64-64m0-64c-70.692 0-128 57.308-128 128s57.308 128 128 128 128-57.308 128-128-57.308-128-128-128z"],burn:[384,512,[],"f46a","M192 0C79.7 101.3 0 220.9 0 300.5 0 425 79 512 192 512s192-87 192-211.5c0-79.9-80.2-199.6-192-300.5zm0 448c-56.5 0-96-39-96-94.8 0-13.5 4.6-61.5 96-161.2 91.4 99.7 96 147.7 96 161.2 0 55.8-39.5 94.8-96 94.8z"],bus:[512,512,[],"f207","M512 152v80c0 13.255-10.745 24-24 24h-8v168c0 13.255-10.745 24-24 24h-8v40c0 13.255-10.745 24-24 24h-48c-13.255 0-24-10.745-24-24v-40H160v40c0 13.255-10.745 24-24 24H88c-13.255 0-24-10.745-24-24v-40h-8c-13.255 0-24-10.745-24-24V256h-8c-13.255 0-24-10.745-24-24v-80c0-13.255 10.745-24 24-24h8V80C32 35.817 132.288 0 256 0s224 35.817 224 80v48h8c13.255 0 24 10.745 24 24zM112 320c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm288 0c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm32-56V120c0-13.255-10.745-24-24-24H104c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h304c13.255 0 24-10.745 24-24z"],calculator:[448,512,[],"f1ec","M0 464V48C0 21.49 21.49 0 48 0h352c26.51 0 48 21.49 48 48v416c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48zm384-284V76c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v104c0 6.627 5.373 12 12 12h296c6.627 0 12-5.373 12-12zM128 308v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm256 128V268c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v168c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-256 0v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm128-128v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm0 128v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12z"],calendar:[448,512,[],"f133","M12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm436-44v-36c0-26.5-21.5-48-48-48h-48V12c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v52H160V12c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v52H48C21.5 64 0 85.5 0 112v36c0 6.6 5.4 12 12 12h424c6.6 0 12-5.4 12-12z"],"calendar-alt":[448,512,[],"f073","M436 160H12c-6.6 0-12-5.4-12-12v-36c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48v36c0 6.6-5.4 12-12 12zM12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm116 204c0-6.6-5.4-12-12-12H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40zm0-128c0-6.6-5.4-12-12-12H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40zm128 128c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40zm0-128c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40zm128 128c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40zm0-128c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40z"],"calendar-check":[448,512,[],"f274","M436 160H12c-6.627 0-12-5.373-12-12v-36c0-26.51 21.49-48 48-48h48V12c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v52h128V12c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v52h48c26.51 0 48 21.49 48 48v36c0 6.627-5.373 12-12 12zM12 192h424c6.627 0 12 5.373 12 12v260c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V204c0-6.627 5.373-12 12-12zm333.296 95.947l-28.169-28.398c-4.667-4.705-12.265-4.736-16.97-.068L194.12 364.665l-45.98-46.352c-4.667-4.705-12.266-4.736-16.971-.068l-28.397 28.17c-4.705 4.667-4.736 12.265-.068 16.97l82.601 83.269c4.667 4.705 12.265 4.736 16.97.068l142.953-141.805c4.705-4.667 4.736-12.265.068-16.97z"],"calendar-minus":[448,512,[],"f272","M436 160H12c-6.6 0-12-5.4-12-12v-36c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48v36c0 6.6-5.4 12-12 12zM12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm304 192c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12H132c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h184z"],"calendar-plus":[448,512,[],"f271","M436 160H12c-6.6 0-12-5.4-12-12v-36c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48v36c0 6.6-5.4 12-12 12zM12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm316 140c0-6.6-5.4-12-12-12h-60v-60c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v60h-60c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h60v60c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-60h60c6.6 0 12-5.4 12-12v-40z"],"calendar-times":[448,512,[],"f273","M436 160H12c-6.6 0-12-5.4-12-12v-36c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48v36c0 6.6-5.4 12-12 12zM12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm257.3 160l48.1-48.1c4.7-4.7 4.7-12.3 0-17l-28.3-28.3c-4.7-4.7-12.3-4.7-17 0L224 306.7l-48.1-48.1c-4.7-4.7-12.3-4.7-17 0l-28.3 28.3c-4.7 4.7-4.7 12.3 0 17l48.1 48.1-48.1 48.1c-4.7 4.7-4.7 12.3 0 17l28.3 28.3c4.7 4.7 12.3 4.7 17 0l48.1-48.1 48.1 48.1c4.7 4.7 12.3 4.7 17 0l28.3-28.3c4.7-4.7 4.7-12.3 0-17L269.3 352z"],camera:[512,512,[],"f030","M512 144v288c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V144c0-26.5 21.5-48 48-48h88l12.3-32.9c7-18.7 24.9-31.1 44.9-31.1h125.5c20 0 37.9 12.4 44.9 31.1L376 96h88c26.5 0 48 21.5 48 48zM376 288c0-66.2-53.8-120-120-120s-120 53.8-120 120 53.8 120 120 120 120-53.8 120-120zm-32 0c0 48.5-39.5 88-88 88s-88-39.5-88-88 39.5-88 88-88 88 39.5 88 88z"],"camera-retro":[512,512,[],"f083","M48 32C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48H48zm0 32h106c3.3 0 6 2.7 6 6v20c0 3.3-2.7 6-6 6H38c-3.3 0-6-2.7-6-6V80c0-8.8 7.2-16 16-16zm426 96H38c-3.3 0-6-2.7-6-6v-36c0-3.3 2.7-6 6-6h138l30.2-45.3c1.1-1.7 3-2.7 5-2.7H464c8.8 0 16 7.2 16 16v74c0 3.3-2.7 6-6 6zM256 424c-66.2 0-120-53.8-120-120s53.8-120 120-120 120 53.8 120 120-53.8 120-120 120zm0-208c-48.5 0-88 39.5-88 88s39.5 88 88 88 88-39.5 88-88-39.5-88-88-88zm-48 104c-8.8 0-16-7.2-16-16 0-35.3 28.7-64 64-64 8.8 0 16 7.2 16 16s-7.2 16-16 16c-17.6 0-32 14.4-32 32 0 8.8-7.2 16-16 16z"],capsules:[576,512,[],"f46b","M555.3 300.1L424.2 112.8C401.9 81 366.4 64 330.4 64c-22.6 0-45.5 6.7-65.5 20.7-19.7 13.8-33.7 32.8-41.5 53.8C220.5 79.2 172 32 112 32 50.1 32 0 82.1 0 144v224c0 61.9 50.1 112 112 112s112-50.1 112-112V218.9c3.3 8.6 7.3 17.1 12.8 25L368 431.2c22.2 31.8 57.7 48.8 93.8 48.8 22.7 0 45.5-6.7 65.5-20.7 51.7-36.2 64.2-107.5 28-159.2zM160 256H64V144c0-26.5 21.5-48 48-48s48 21.5 48 48v112zm194.8 44.9l-65.6-93.7c-7.7-11-10.7-24.4-8.3-37.6 2.3-13.2 9.7-24.8 20.7-32.5 8.5-6 18.5-9.1 28.8-9.1 16.5 0 31.9 8 41.3 21.5l65.6 93.7-82.5 57.7z"],car:[512,512,[],"f1b9","M499.991 168h-54.815l-7.854-20.944c-9.192-24.513-25.425-45.351-46.942-60.263S343.651 64 317.472 64H194.528c-26.18 0-51.391 7.882-72.908 22.793-21.518 14.912-37.75 35.75-46.942 60.263L66.824 168H12.009c-8.191 0-13.974 8.024-11.384 15.795l8 24A12 12 0 0 0 20.009 216h28.815l-.052.14C29.222 227.093 16 247.997 16 272v48c0 16.225 6.049 31.029 16 42.309V424c0 13.255 10.745 24 24 24h48c13.255 0 24-10.745 24-24v-40h256v40c0 13.255 10.745 24 24 24h48c13.255 0 24-10.745 24-24v-61.691c9.951-11.281 16-26.085 16-42.309v-48c0-24.003-13.222-44.907-32.772-55.86l-.052-.14h28.815a12 12 0 0 0 11.384-8.205l8-24c2.59-7.771-3.193-15.795-11.384-15.795zm-365.388 1.528C143.918 144.689 168 128 194.528 128h122.944c26.528 0 50.61 16.689 59.925 41.528L391.824 208H120.176l14.427-38.472zM88 328c-17.673 0-32-14.327-32-32 0-17.673 14.327-32 32-32s48 30.327 48 48-30.327 16-48 16zm336 0c-17.673 0-48 1.673-48-16 0-17.673 30.327-48 48-48s32 14.327 32 32c0 17.673-14.327 32-32 32z"],"caret-down":[320,512,[],"f0d7","M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"],"caret-left":[192,512,[],"f0d9","M192 127.338v257.324c0 17.818-21.543 26.741-34.142 14.142L29.196 270.142c-7.81-7.81-7.81-20.474 0-28.284l128.662-128.662c12.599-12.6 34.142-3.676 34.142 14.142z"],"caret-right":[192,512,[],"f0da","M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662z"],"caret-square-down":[448,512,[],"f150","M448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM92.5 220.5l123 123c4.7 4.7 12.3 4.7 17 0l123-123c7.6-7.6 2.2-20.5-8.5-20.5H101c-10.7 0-16.1 12.9-8.5 20.5z"],"caret-square-left":[448,512,[],"f191","M400 480H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48zM259.515 124.485l-123.03 123.03c-4.686 4.686-4.686 12.284 0 16.971l123.029 123.029c7.56 7.56 20.485 2.206 20.485-8.485V132.971c.001-10.691-12.925-16.045-20.484-8.486z"],"caret-square-right":[448,512,[],"f152","M48 32h352c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48zm140.485 355.515l123.029-123.029c4.686-4.686 4.686-12.284 0-16.971l-123.029-123.03c-7.56-7.56-20.485-2.206-20.485 8.485v246.059c0 10.691 12.926 16.045 20.485 8.486z"],"caret-square-up":[448,512,[],"f151","M0 432V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48zm355.515-140.485l-123.03-123.03c-4.686-4.686-12.284-4.686-16.971 0L92.485 291.515c-7.56 7.56-2.206 20.485 8.485 20.485h246.059c10.691 0 16.045-12.926 8.486-20.485z"],"caret-up":[320,512,[],"f0d8","M288.662 352H31.338c-17.818 0-26.741-21.543-14.142-34.142l128.662-128.662c7.81-7.81 20.474-7.81 28.284 0l128.662 128.662c12.6 12.599 3.676 34.142-14.142 34.142z"],"cart-arrow-down":[576,512,[],"f218","M504.717 320H211.572l6.545 32h268.418c15.401 0 26.816 14.301 23.403 29.319l-5.517 24.276C523.112 414.668 536 433.828 536 456c0 31.202-25.519 56.444-56.824 55.994-29.823-.429-54.35-24.631-55.155-54.447-.44-16.287 6.085-31.049 16.803-41.548H231.176C241.553 426.165 248 440.326 248 456c0 31.813-26.528 57.431-58.67 55.938-28.54-1.325-51.751-24.385-53.251-52.917-1.158-22.034 10.436-41.455 28.051-51.586L93.883 64H24C10.745 64 0 53.255 0 40V24C0 10.745 10.745 0 24 0h102.529c11.401 0 21.228 8.021 23.513 19.19L159.208 64H551.99c15.401 0 26.816 14.301 23.403 29.319l-47.273 208C525.637 312.246 515.923 320 504.717 320zM403.029 192H360v-60c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v60h-43.029c-10.691 0-16.045 12.926-8.485 20.485l67.029 67.029c4.686 4.686 12.284 4.686 16.971 0l67.029-67.029c7.559-7.559 2.205-20.485-8.486-20.485z"],"cart-plus":[576,512,[],"f217","M504.717 320H211.572l6.545 32h268.418c15.401 0 26.816 14.301 23.403 29.319l-5.517 24.276C523.112 414.668 536 433.828 536 456c0 31.202-25.519 56.444-56.824 55.994-29.823-.429-54.35-24.631-55.155-54.447-.44-16.287 6.085-31.049 16.803-41.548H231.176C241.553 426.165 248 440.326 248 456c0 31.813-26.528 57.431-58.67 55.938-28.54-1.325-51.751-24.385-53.251-52.917-1.158-22.034 10.436-41.455 28.051-51.586L93.883 64H24C10.745 64 0 53.255 0 40V24C0 10.745 10.745 0 24 0h102.529c11.401 0 21.228 8.021 23.513 19.19L159.208 64H551.99c15.401 0 26.816 14.301 23.403 29.319l-47.273 208C525.637 312.246 515.923 320 504.717 320zM408 168h-48v-40c0-8.837-7.163-16-16-16h-16c-8.837 0-16 7.163-16 16v40h-48c-8.837 0-16 7.163-16 16v16c0 8.837 7.163 16 16 16h48v40c0 8.837 7.163 16 16 16h16c8.837 0 16-7.163 16-16v-40h48c8.837 0 16-7.163 16-16v-16c0-8.837-7.163-16-16-16z"],certificate:[512,512,[],"f0a3","M458.622 255.92l45.985-45.005c13.708-12.977 7.316-36.039-10.664-40.339l-62.65-15.99 17.661-62.015c4.991-17.838-11.829-34.663-29.661-29.671l-61.994 17.667-15.984-62.671C337.085.197 313.765-6.276 300.99 7.228L256 53.57 211.011 7.229c-12.63-13.351-36.047-7.234-40.325 10.668l-15.984 62.671-61.995-17.667C74.87 57.907 58.056 74.738 63.046 92.572l17.661 62.015-62.65 15.99C.069 174.878-6.31 197.944 7.392 210.915l45.985 45.005-45.985 45.004c-13.708 12.977-7.316 36.039 10.664 40.339l62.65 15.99-17.661 62.015c-4.991 17.838 11.829 34.663 29.661 29.671l61.994-17.667 15.984 62.671c4.439 18.575 27.696 24.018 40.325 10.668L256 458.61l44.989 46.001c12.5 13.488 35.987 7.486 40.325-10.668l15.984-62.671 61.994 17.667c17.836 4.994 34.651-11.837 29.661-29.671l-17.661-62.015 62.65-15.99c17.987-4.302 24.366-27.367 10.664-40.339l-45.984-45.004z"],"chart-area":[512,512,[],"f1fe","M500 384c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v308h436zM372.7 159.5L288 216l-85.3-113.7c-5.1-6.8-15.5-6.3-19.9 1L96 248v104h384l-89.9-187.8c-3.2-6.5-11.4-8.7-17.4-4.7z"],"chart-bar":[512,512,[],"f080","M500 384c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v308h436zm-308-44v-72c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v72c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm192 0V204c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v136c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm-96 0V140c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v200c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm192 0V108c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v232c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12z"],"chart-line":[512,512,[],"f201","M500 384c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v308h436zM456 96H344c-21.4 0-32.1 25.9-17 41l32.9 32.9-72 72.9-55.6-55.6c-4.7-4.7-12.2-4.7-16.9 0L96.4 305c-4.7 4.6-4.8 12.2-.2 16.9l28.5 29.4c4.7 4.8 12.4 4.9 17.1.1l82.1-82.1 55.5 55.5c4.7 4.7 12.3 4.7 17 0l109.2-109.2L439 249c15.1 15.1 41 4.4 41-17V120c0-13.3-10.7-24-24-24z"],"chart-pie":[576,512,[],"f200","M288 12.3V240h227.7c6.9 0 12.3-5.8 12-12.7-6.4-122.4-104.5-220.6-227-227-6.9-.3-12.7 5.1-12.7 12zM552.7 288c6.9 0 12.3 5.8 12 12.7-2.8 53.2-23.2 105.6-61.2 147.8-4.6 5.1-12.6 5.4-17.5.5L325 288h227.7zM401 433c4.8 4.8 4.7 12.8-.4 17.3-42.6 38.4-99 61.7-160.8 61.7C107.6 511.9-.2 403.8 0 271.5.2 143.4 100.8 38.9 227.3 32.3c6.9-.4 12.7 5.1 12.7 12V272l161 161z"],check:[512,512,[],"f00c","M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"],"check-circle":[512,512,[],"f058","M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"],"check-square":[448,512,[],"f14a","M400 480H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48zm-204.686-98.059l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.248-16.379-6.249-22.628 0L184 302.745l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.25 16.379 6.25 22.628.001z"],chess:[512,512,[],"f439","M199.821 217.633a6 6 0 0 1 6 6l-.001 20.766a6 6 0 0 1-6 6h-25.805c0 31.715-2.153 96.201 17.398 153.229H64.597C84.54 345.452 82.02 279.245 82.02 250.399H56.183a6 6 0 0 1-6-6l.002-20.766a6 6 0 0 1 6-6h143.636zM41.554 115.088l34.58 95.071h103.734l34.572-95.072c2.846-7.826-2.95-16.101-11.278-16.101H152v-30.22h21.57a6 6 0 0 0 6-6V40.383a6 6 0 0 0-6-6h-28.367V6a6 6 0 0 0-6-6H116.82a6 6 0 0 0-6 6v28.383H82.421a6 6 0 0 0-6 6v22.383a6 6 0 0 0 6 6H104v30.219H52.831c-8.328.001-14.124 8.276-11.277 16.103zM222.678 445.17v-28.067a6 6 0 0 0-6-6H39.322a6 6 0 0 0-6 6v28.067l-22.148 14.164a6 6 0 0 0-2.767 5.055V506a6 6 0 0 0 6 6h227.187a6 6 0 0 0 6-6v-41.612a6 6 0 0 0-2.767-5.055l-22.149-14.163zm90.578-144.225l24.88 16.963c.09 18.124-.167 63.904-11.905 114.522h147.526c-11.713-50.475-11.969-96.324-11.882-114.537l24.859-16.949a3.856 3.856 0 0 0 1.684-3.187v-69.901a3.857 3.857 0 0 0-3.857-3.857h-27.655a3.857 3.857 0 0 0-3.857 3.857v31.514h-22.737v-31.514a3.857 3.857 0 0 0-3.858-3.857h-52.918a3.857 3.857 0 0 0-3.857 3.857v31.514h-22.737v-31.514a3.857 3.857 0 0 0-3.857-3.857H315.43a3.857 3.857 0 0 0-3.857 3.857v69.901a3.855 3.855 0 0 0 1.683 3.188zm71.585 51.906c0-8.372 6.787-15.158 15.159-15.158s15.158 6.787 15.158 15.158v30.318h-30.317v-30.318zM504.62 470.059l-13.664-10.639v-15.552a3.857 3.857 0 0 0-3.857-3.857H312.915a3.857 3.857 0 0 0-3.857 3.857v15.552l-13.677 10.639a3.857 3.857 0 0 0-1.488 3.044v35.039a3.857 3.857 0 0 0 3.857 3.857h204.5a3.857 3.857 0 0 0 3.857-3.857v-35.04a3.859 3.859 0 0 0-1.487-3.043z"],"chess-bishop":[320,512,[],"f43a","M123.158 77.881C107.369 72.53 96 57.597 96 40c0-22.091 17.909-40 40-40h47.796c22.091 0 40 17.909 40 40 0 17.541-11.295 32.434-27.005 37.829 23.993 16.657 48.577 46.839 68.703 82.05L144.929 280.443a6 6 0 0 0 0 8.485l14.142 14.142a6 6 0 0 0 8.485 0L280.9 189.726c17.758 38.297 29.371 79.443 29.371 114.273 0 53.786-22.897 75.788-58.446 86.033V448H68.174v-57.97C32.631 379.784 9.739 357.781 9.739 304c0-78.029 58.281-187.766 113.419-226.119zM320 500v-24c0-6.627-5.373-12-12-12H12c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h296c6.627 0 12-5.373 12-12z"],"chess-board":[512,512,[],"f43c","M256 256v64h-64v-64h64zm0-256h-64v64h64V0zm0 256h64v-64h-64v64zM384 0h-64v64h64V0zm0 512h64v-64h-64v64zm128-64v-64h-64v64h64zm-384 64h64v-64h-64v64zm0-512H64v64h64V0zm384 192v-64h-64v64h64zm0 128v-64h-64v64h64zM0 512h64v-64H0v64zM0 64v64h64V64H0zm0 128v64h64v-64H0zm0 128v64h64v-64H0zm256 192h64v-64h-64v64zm-64-128v64h64v-64h-64zm64-192v-64h-64v64h64zM64 384v64h64v-64H64zm64-128H64v64h64v-64zm256 128h64v-64h-64v64zM512 0h-64v64h64V0zM384 256h64v-64h-64v64zm0-192v64h64V64h-64zm-64 320v64h64v-64h-64zm-192-64v64h64v-64h-64zm128 0v64h64v-64h-64zm-64-128h-64v64h64v-64zm-64-64H64v64h64v-64zm192 192h64v-64h-64v64zM192 128V64h-64v64h64zm128 0V64h-64v64h64zm0 64h64v-64h-64v64z"],"chess-king":[448,512,[],"f43f","M416 476v24c0 6.627-5.373 12-12 12H44c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h360c6.627 0 12 5.373 12 12zm-8.033-324H248v-48h50a6 6 0 0 0 6-6V62a6 6 0 0 0-6-6h-50V6a6 6 0 0 0-6-6h-36a6 6 0 0 0-6 6v50h-50a6 6 0 0 0-6 6v36a6 6 0 0 0 6 6h50v48H40.033c-27.574 0-46.879 27.244-37.738 53.259L87.582 448h272.836l85.287-242.741C454.846 179.244 435.541 152 407.967 152z"],"chess-knight":[384,512,[],"f441","M352 224v224H32v-46.557c0-30.302 17.12-58.003 44.223-71.554l57.243-28.622A48 48 0 0 0 160 258.334V208l-22.127 11.063a23.996 23.996 0 0 0-12.55 15.645l-11.835 47.338a12 12 0 0 1-7.185 8.231l-29.601 11.84a11.998 11.998 0 0 1-9.33-.176L7.126 275.167A12 12 0 0 1 0 264.201v-158.26c0-6.365 2.529-12.47 7.03-16.971L16 80 1.789 51.578A16.937 16.937 0 0 1 0 44c0-6.627 5.373-12 12-12h148c106.039 0 192 85.961 192 192zm20 240H12c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h360c6.627 0 12-5.373 12-12v-24c0-6.627-5.373-12-12-12zM52 128c-11.046 0-20 8.954-20 20s8.954 20 20 20 20-8.954 20-20-8.954-20-20-20z"],"chess-pawn":[320,512,[],"f443","M264 448H56s60-42.743 60-176H84c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h40.209C95.721 210.56 76 181.588 76 148c0-46.392 37.608-84 84-84s84 37.608 84 84c0 33.588-19.721 62.56-48.209 76H236c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12h-32c0 133.257 60 176 60 176zm28 16H28c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h264c6.627 0 12-5.373 12-12v-24c0-6.627-5.373-12-12-12z"],"chess-queen":[512,512,[],"f445","M436 512H76c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h360c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12zM255.579 0c-30.928 0-56 25.072-56 56s25.072 56 56 56 56-25.072 56-56-25.072-56-56-56zm204.568 154.634c-5.768-3.045-12.916-.932-16.082 4.77-8.616 15.516-22.747 37.801-44.065 37.801-28.714 0-30.625-19.804-31.686-57.542-.183-6.492-5.501-11.664-11.995-11.664h-41.006c-5.175 0-9.754 3.328-11.388 8.238-8.89 26.709-26.073 40.992-47.925 40.992s-39.034-14.283-47.925-40.992c-1.634-4.91-6.213-8.238-11.388-8.238h-41.005c-6.495 0-11.813 5.174-11.995 11.667-1.052 37.642-2.934 57.539-31.688 57.539-20.691 0-33.817-20.224-44.425-38.025-3.266-5.48-10.258-7.431-15.899-4.453l-39.179 20.679a12 12 0 0 0-5.51 15.145L112 448h288l105.014-257.448a12 12 0 0 0-5.51-15.145l-39.357-20.773z"],"chess-rook":[384,512,[],"f447","M81.241 215.027C80.957 258.92 77.411 348.076 48 448h287.982c-29.4-99.604-32.936-188.912-33.221-232.975l45.418-42.312a11.998 11.998 0 0 0 3.82-8.78V44c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v44h-48V44c0-6.627-5.373-12-12-12h-72c-6.627 0-12 5.373-12 12v44H96V44c0-6.627-5.373-12-12-12H44c-6.627 0-12 5.373-12 12v119.932c0 3.33 1.384 6.51 3.82 8.78l45.421 42.315zM160 256c0-17.673 14.327-32 32-32 17.673 0 32 14.327 32 32v64.004h-64V256zm224 220v24c0 6.627-5.373 12-12 12H12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h360c6.627 0 12 5.373 12 12z"],"chevron-circle-down":[512,512,[],"f13a","M504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zM273 369.9l135.5-135.5c9.4-9.4 9.4-24.6 0-33.9l-17-17c-9.4-9.4-24.6-9.4-33.9 0L256 285.1 154.4 183.5c-9.4-9.4-24.6-9.4-33.9 0l-17 17c-9.4 9.4-9.4 24.6 0 33.9L239 369.9c9.4 9.4 24.6 9.4 34 0z"],"chevron-circle-left":[512,512,[],"f137","M256 504C119 504 8 393 8 256S119 8 256 8s248 111 248 248-111 248-248 248zM142.1 273l135.5 135.5c9.4 9.4 24.6 9.4 33.9 0l17-17c9.4-9.4 9.4-24.6 0-33.9L226.9 256l101.6-101.6c9.4-9.4 9.4-24.6 0-33.9l-17-17c-9.4-9.4-24.6-9.4-33.9 0L142.1 239c-9.4 9.4-9.4 24.6 0 34z"],"chevron-circle-right":[512,512,[],"f138","M256 8c137 0 248 111 248 248S393 504 256 504 8 393 8 256 119 8 256 8zm113.9 231L234.4 103.5c-9.4-9.4-24.6-9.4-33.9 0l-17 17c-9.4 9.4-9.4 24.6 0 33.9L285.1 256 183.5 357.6c-9.4 9.4-9.4 24.6 0 33.9l17 17c9.4 9.4 24.6 9.4 33.9 0L369.9 273c9.4-9.4 9.4-24.6 0-34z"],"chevron-circle-up":[512,512,[],"f139","M8 256C8 119 119 8 256 8s248 111 248 248-111 248-248 248S8 393 8 256zm231-113.9L103.5 277.6c-9.4 9.4-9.4 24.6 0 33.9l17 17c9.4 9.4 24.6 9.4 33.9 0L256 226.9l101.6 101.6c9.4 9.4 24.6 9.4 33.9 0l17-17c9.4-9.4 9.4-24.6 0-33.9L273 142.1c-9.4-9.4-24.6-9.4-34 0z"],"chevron-down":[448,512,[],"f078","M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z"],"chevron-left":[320,512,[],"f053","M34.52 239.03L228.87 44.69c9.37-9.37 24.57-9.37 33.94 0l22.67 22.67c9.36 9.36 9.37 24.52.04 33.9L131.49 256l154.02 154.75c9.34 9.38 9.32 24.54-.04 33.9l-22.67 22.67c-9.37 9.37-24.57 9.37-33.94 0L34.52 272.97c-9.37-9.37-9.37-24.57 0-33.94z"],"chevron-right":[320,512,[],"f054","M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"],"chevron-up":[448,512,[],"f077","M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z"],child:[384,512,[],"f1ae","M120 72c0-39.765 32.235-72 72-72s72 32.235 72 72c0 39.764-32.235 72-72 72s-72-32.236-72-72zm254.627 1.373c-12.496-12.497-32.758-12.497-45.254 0L242.745 160H141.254L54.627 73.373c-12.496-12.497-32.758-12.497-45.254 0-12.497 12.497-12.497 32.758 0 45.255L104 213.254V480c0 17.673 14.327 32 32 32h16c17.673 0 32-14.327 32-32V368h16v112c0 17.673 14.327 32 32 32h16c17.673 0 32-14.327 32-32V213.254l94.627-94.627c12.497-12.497 12.497-32.757 0-45.254z"],circle:[512,512,[],"f111","M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z"],"circle-notch":[512,512,[],"f1ce","M288 39.056v16.659c0 10.804 7.281 20.159 17.686 23.066C383.204 100.434 440 171.518 440 256c0 101.689-82.295 184-184 184-101.689 0-184-82.295-184-184 0-84.47 56.786-155.564 134.312-177.219C216.719 75.874 224 66.517 224 55.712V39.064c0-15.709-14.834-27.153-30.046-23.234C86.603 43.482 7.394 141.206 8.003 257.332c.72 137.052 111.477 246.956 248.531 246.667C393.255 503.711 504 392.788 504 256c0-115.633-79.14-212.779-186.211-240.236C302.678 11.889 288 23.456 288 39.056z"],clipboard:[384,512,[],"f328","M384 112v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h80c0-35.29 28.71-64 64-64s64 28.71 64 64h80c26.51 0 48 21.49 48 48zM192 40c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24m96 114v-20a6 6 0 0 0-6-6H102a6 6 0 0 0-6 6v20a6 6 0 0 0 6 6h180a6 6 0 0 0 6-6z"],"clipboard-check":[384,512,[],"f46c","M336 64h-80c0-35.3-28.7-64-64-64s-64 28.7-64 64H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM192 40c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zm121.2 231.8l-143 141.8c-4.7 4.7-12.3 4.6-17-.1l-82.6-83.3c-4.7-4.7-4.6-12.3.1-17L99.1 285c4.7-4.7 12.3-4.6 17 .1l46 46.4 106-105.2c4.7-4.7 12.3-4.6 17 .1l28.2 28.4c4.7 4.8 4.6 12.3-.1 17z"],"clipboard-list":[384,512,[],"f46d","M336 64h-80c0-35.3-28.7-64-64-64s-64 28.7-64 64H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM96 424c-13.3 0-24-10.7-24-24s10.7-24 24-24 24 10.7 24 24-10.7 24-24 24zm0-96c-13.3 0-24-10.7-24-24s10.7-24 24-24 24 10.7 24 24-10.7 24-24 24zm0-96c-13.3 0-24-10.7-24-24s10.7-24 24-24 24 10.7 24 24-10.7 24-24 24zm96-192c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zm128 368c0 4.4-3.6 8-8 8H168c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h144c4.4 0 8 3.6 8 8v16zm0-96c0 4.4-3.6 8-8 8H168c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h144c4.4 0 8 3.6 8 8v16zm0-96c0 4.4-3.6 8-8 8H168c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h144c4.4 0 8 3.6 8 8v16z"],clock:[512,512,[],"f017","M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm57.1 350.1L224.9 294c-3.1-2.3-4.9-5.9-4.9-9.7V116c0-6.6 5.4-12 12-12h48c6.6 0 12 5.4 12 12v137.7l63.5 46.2c5.4 3.9 6.5 11.4 2.6 16.8l-28.2 38.8c-3.9 5.3-11.4 6.5-16.8 2.6z"],clone:[512,512,[],"f24d","M464 0c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48H176c-26.51 0-48-21.49-48-48V48c0-26.51 21.49-48 48-48h288M176 416c-44.112 0-80-35.888-80-80V128H48c-26.51 0-48 21.49-48 48v288c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48v-48H176z"],"closed-captioning":[512,512,[],"f20a","M464 64H48C21.5 64 0 85.5 0 112v288c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM218.1 287.7c2.8-2.5 7.1-2.1 9.2.9l19.5 27.7c1.7 2.4 1.5 5.6-.5 7.7-53.6 56.8-172.8 32.1-172.8-67.9 0-97.3 121.7-119.5 172.5-70.1 2.1 2 2.5 3.2 1 5.7l-17.5 30.5c-1.9 3.1-6.2 4-9.1 1.7-40.8-32-94.6-14.9-94.6 31.2.1 48 51.1 70.5 92.3 32.6zm190.4 0c2.8-2.5 7.1-2.1 9.2.9l19.5 27.7c1.7 2.4 1.5 5.6-.5 7.7-53.5 56.9-172.7 32.1-172.7-67.9 0-97.3 121.7-119.5 172.5-70.1 2.1 2 2.5 3.2 1 5.7L420 222.2c-1.9 3.1-6.2 4-9.1 1.7-40.8-32-94.6-14.9-94.6 31.2 0 48 51 70.5 92.2 32.6z"],cloud:[640,512,[],"f0c2","M537.585 226.56C541.725 215.836 544 204.184 544 192c0-53.019-42.981-96-96-96-19.729 0-38.065 5.954-53.316 16.159C367.042 64.248 315.288 32 256 32c-88.366 0-160 71.634-160 160 0 2.728.07 5.439.204 8.133C40.171 219.845 0 273.227 0 336c0 79.529 64.471 144 144 144h368c70.692 0 128-57.308 128-128 0-61.93-43.983-113.586-102.415-125.44z"],"cloud-download-alt":[640,512,[],"f381","M640 352c0 70.692-57.308 128-128 128H144C64.471 480 0 415.529 0 336c0-62.773 40.171-116.155 96.204-135.867A163.68 163.68 0 0 1 96 192c0-88.366 71.634-160 160-160 59.288 0 111.042 32.248 138.684 80.159C409.935 101.954 428.271 96 448 96c53.019 0 96 42.981 96 96 0 12.184-2.275 23.836-6.415 34.56C596.017 238.414 640 290.07 640 352zm-246.627-64H328V176c0-8.837-7.164-16-16-16h-48c-8.836 0-16 7.163-16 16v112h-65.373c-14.254 0-21.393 17.234-11.314 27.314l105.373 105.373c6.248 6.248 16.379 6.248 22.627 0l105.373-105.373c10.08-10.08 2.941-27.314-11.313-27.314z"],"cloud-upload-alt":[640,512,[],"f382","M640 352c0 70.692-57.308 128-128 128H144C64.471 480 0 415.529 0 336c0-62.773 40.171-116.155 96.204-135.867A163.68 163.68 0 0 1 96 192c0-88.366 71.634-160 160-160 59.288 0 111.042 32.248 138.684 80.159C409.935 101.954 428.271 96 448 96c53.019 0 96 42.981 96 96 0 12.184-2.275 23.836-6.415 34.56C596.017 238.414 640 290.07 640 352zm-235.314-91.314L299.314 155.314c-6.248-6.248-16.379-6.248-22.627 0L171.314 260.686c-10.08 10.08-2.941 27.314 11.313 27.314H248v112c0 8.837 7.164 16 16 16h48c8.836 0 16-7.163 16-16V288h65.373c14.254 0 21.393-17.234 11.313-27.314z"],code:[640,512,[],"f121","M278.9 511.5l-61-17.7c-6.4-1.8-10-8.5-8.2-14.9L346.2 8.7c1.8-6.4 8.5-10 14.9-8.2l61 17.7c6.4 1.8 10 8.5 8.2 14.9L293.8 503.3c-1.9 6.4-8.5 10.1-14.9 8.2zm-114-112.2l43.5-46.4c4.6-4.9 4.3-12.7-.8-17.2L117 256l90.6-79.7c5.1-4.5 5.5-12.3.8-17.2l-43.5-46.4c-4.5-4.8-12.1-5.1-17-.5L3.8 247.2c-5.1 4.7-5.1 12.8 0 17.5l144.1 135.1c4.9 4.6 12.5 4.4 17-.5zm327.2.6l144.1-135.1c5.1-4.7 5.1-12.8 0-17.5L492.1 112.1c-4.8-4.5-12.4-4.3-17 .5L431.6 159c-4.6 4.9-4.3 12.7.8 17.2L523 256l-90.6 79.7c-5.1 4.5-5.5 12.3-.8 17.2l43.5 46.4c4.5 4.9 12.1 5.1 17 .6z"],"code-branch":[384,512,[],"f126","M384 144c0-44.2-35.8-80-80-80s-80 35.8-80 80c0 36.4 24.3 67.1 57.5 76.8-.6 16.1-4.2 28.5-11 36.9-15.4 19.2-49.3 22.4-85.2 25.7-28.2 2.6-57.4 5.4-81.3 16.9v-144c32.5-10.2 56-40.5 56-76.3 0-44.2-35.8-80-80-80S0 35.8 0 80c0 35.8 23.5 66.1 56 76.3v199.3C23.5 365.9 0 396.2 0 432c0 44.2 35.8 80 80 80s80-35.8 80-80c0-34-21.2-63.1-51.2-74.6 3.1-5.2 7.8-9.8 14.9-13.4 16.2-8.2 40.4-10.4 66.1-12.8 42.2-3.9 90-8.4 118.2-43.4 14-17.4 21.1-39.8 21.6-67.9 31.6-10.8 54.4-40.7 54.4-75.9zM80 64c8.8 0 16 7.2 16 16s-7.2 16-16 16-16-7.2-16-16 7.2-16 16-16zm0 384c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16zm224-320c8.8 0 16 7.2 16 16s-7.2 16-16 16-16-7.2-16-16 7.2-16 16-16z"],coffee:[640,512,[],"f0f4","M192 384h192c53 0 96-43 96-96h32c70.6 0 128-57.4 128-128S582.6 32 512 32H120c-13.3 0-24 10.7-24 24v232c0 53 43 96 96 96zM512 96c35.3 0 64 28.7 64 64s-28.7 64-64 64h-32V96h32zm47.7 384H48.3c-47.6 0-61-64-36-64h583.3c25 0 11.8 64-35.9 64z"],cog:[512,512,[],"f013","M444.788 291.1l42.616 24.599c4.867 2.809 7.126 8.618 5.459 13.985-11.07 35.642-29.97 67.842-54.689 94.586a12.016 12.016 0 0 1-14.832 2.254l-42.584-24.595a191.577 191.577 0 0 1-60.759 35.13v49.182a12.01 12.01 0 0 1-9.377 11.718c-34.956 7.85-72.499 8.256-109.219.007-5.49-1.233-9.403-6.096-9.403-11.723v-49.184a191.555 191.555 0 0 1-60.759-35.13l-42.584 24.595a12.016 12.016 0 0 1-14.832-2.254c-24.718-26.744-43.619-58.944-54.689-94.586-1.667-5.366.592-11.175 5.459-13.985L67.212 291.1a193.48 193.48 0 0 1 0-70.199l-42.616-24.599c-4.867-2.809-7.126-8.618-5.459-13.985 11.07-35.642 29.97-67.842 54.689-94.586a12.016 12.016 0 0 1 14.832-2.254l42.584 24.595a191.577 191.577 0 0 1 60.759-35.13V25.759a12.01 12.01 0 0 1 9.377-11.718c34.956-7.85 72.499-8.256 109.219-.007 5.49 1.233 9.403 6.096 9.403 11.723v49.184a191.555 191.555 0 0 1 60.759 35.13l42.584-24.595a12.016 12.016 0 0 1 14.832 2.254c24.718 26.744 43.619 58.944 54.689 94.586 1.667 5.366-.592 11.175-5.459 13.985L444.788 220.9a193.485 193.485 0 0 1 0 70.2zM336 256c0-44.112-35.888-80-80-80s-80 35.888-80 80 35.888 80 80 80 80-35.888 80-80z"],cogs:[640,512,[],"f085","M512.1 191l-8.2 14.3c-3 5.3-9.4 7.5-15.1 5.4-11.8-4.4-22.6-10.7-32.1-18.6-4.6-3.8-5.8-10.5-2.8-15.7l8.2-14.3c-6.9-8-12.3-17.3-15.9-27.4h-16.5c-6 0-11.2-4.3-12.2-10.3-2-12-2.1-24.6 0-37.1 1-6 6.2-10.4 12.2-10.4h16.5c3.6-10.1 9-19.4 15.9-27.4l-8.2-14.3c-3-5.2-1.9-11.9 2.8-15.7 9.5-7.9 20.4-14.2 32.1-18.6 5.7-2.1 12.1.1 15.1 5.4l8.2 14.3c10.5-1.9 21.2-1.9 31.7 0L552 6.3c3-5.3 9.4-7.5 15.1-5.4 11.8 4.4 22.6 10.7 32.1 18.6 4.6 3.8 5.8 10.5 2.8 15.7l-8.2 14.3c6.9 8 12.3 17.3 15.9 27.4h16.5c6 0 11.2 4.3 12.2 10.3 2 12 2.1 24.6 0 37.1-1 6-6.2 10.4-12.2 10.4h-16.5c-3.6 10.1-9 19.4-15.9 27.4l8.2 14.3c3 5.2 1.9 11.9-2.8 15.7-9.5 7.9-20.4 14.2-32.1 18.6-5.7 2.1-12.1-.1-15.1-5.4l-8.2-14.3c-10.4 1.9-21.2 1.9-31.7 0zm-10.5-58.8c38.5 29.6 82.4-14.3 52.8-52.8-38.5-29.7-82.4 14.3-52.8 52.8zM386.3 286.1l33.7 16.8c10.1 5.8 14.5 18.1 10.5 29.1-8.9 24.2-26.4 46.4-42.6 65.8-7.4 8.9-20.2 11.1-30.3 5.3l-29.1-16.8c-16 13.7-34.6 24.6-54.9 31.7v33.6c0 11.6-8.3 21.6-19.7 23.6-24.6 4.2-50.4 4.4-75.9 0-11.5-2-20-11.9-20-23.6V418c-20.3-7.2-38.9-18-54.9-31.7L74 403c-10 5.8-22.9 3.6-30.3-5.3-16.2-19.4-33.3-41.6-42.2-65.7-4-10.9.4-23.2 10.5-29.1l33.3-16.8c-3.9-20.9-3.9-42.4 0-63.4L12 205.8c-10.1-5.8-14.6-18.1-10.5-29 8.9-24.2 26-46.4 42.2-65.8 7.4-8.9 20.2-11.1 30.3-5.3l29.1 16.8c16-13.7 34.6-24.6 54.9-31.7V57.1c0-11.5 8.2-21.5 19.6-23.5 24.6-4.2 50.5-4.4 76-.1 11.5 2 20 11.9 20 23.6v33.6c20.3 7.2 38.9 18 54.9 31.7l29.1-16.8c10-5.8 22.9-3.6 30.3 5.3 16.2 19.4 33.2 41.6 42.1 65.8 4 10.9.1 23.2-10 29.1l-33.7 16.8c3.9 21 3.9 42.5 0 63.5zm-117.6 21.1c59.2-77-28.7-164.9-105.7-105.7-59.2 77 28.7 164.9 105.7 105.7zm243.4 182.7l-8.2 14.3c-3 5.3-9.4 7.5-15.1 5.4-11.8-4.4-22.6-10.7-32.1-18.6-4.6-3.8-5.8-10.5-2.8-15.7l8.2-14.3c-6.9-8-12.3-17.3-15.9-27.4h-16.5c-6 0-11.2-4.3-12.2-10.3-2-12-2.1-24.6 0-37.1 1-6 6.2-10.4 12.2-10.4h16.5c3.6-10.1 9-19.4 15.9-27.4l-8.2-14.3c-3-5.2-1.9-11.9 2.8-15.7 9.5-7.9 20.4-14.2 32.1-18.6 5.7-2.1 12.1.1 15.1 5.4l8.2 14.3c10.5-1.9 21.2-1.9 31.7 0l8.2-14.3c3-5.3 9.4-7.5 15.1-5.4 11.8 4.4 22.6 10.7 32.1 18.6 4.6 3.8 5.8 10.5 2.8 15.7l-8.2 14.3c6.9 8 12.3 17.3 15.9 27.4h16.5c6 0 11.2 4.3 12.2 10.3 2 12 2.1 24.6 0 37.1-1 6-6.2 10.4-12.2 10.4h-16.5c-3.6 10.1-9 19.4-15.9 27.4l8.2 14.3c3 5.2 1.9 11.9-2.8 15.7-9.5 7.9-20.4 14.2-32.1 18.6-5.7 2.1-12.1-.1-15.1-5.4l-8.2-14.3c-10.4 1.9-21.2 1.9-31.7 0zM501.6 431c38.5 29.6 82.4-14.3 52.8-52.8-38.5-29.6-82.4 14.3-52.8 52.8z"],columns:[512,512,[],"f0db","M464 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM224 416H64V160h160v256zm224 0H288V160h160v256z"],comment:[512,512,[],"f075","M256 32C114.6 32 0 125.1 0 240c0 49.6 21.4 95 57 130.7C44.5 421.1 2.7 466 2.2 466.5c-2.2 2.3-2.8 5.7-1.5 8.7S4.8 480 8 480c66.3 0 116-31.8 140.6-51.4 32.7 12.3 69 19.4 107.4 19.4 141.4 0 256-93.1 256-208S397.4 32 256 32z"],"comment-alt":[512,512,[],"f27a","M448 0H64C28.7 0 0 28.7 0 64v288c0 35.3 28.7 64 64 64h96v84c0 9.8 11.2 15.5 19.1 9.7L304 416h144c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64z"],"comment-dots":[512,512,[],"f4ad","M256 32C114.6 32 0 125.1 0 240c0 49.6 21.4 95 57 130.7C44.5 421.1 2.7 466 2.2 466.5c-2.2 2.3-2.8 5.7-1.5 8.7S4.8 480 8 480c66.3 0 116-31.8 140.6-51.4 32.7 12.3 69 19.4 107.4 19.4 141.4 0 256-93.1 256-208S397.4 32 256 32zM128 272c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm128 0c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm128 0c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z"],"comment-slash":[640,512,[],"f4b3","M64 240c0 49.6 21.4 95 57 130.7-12.6 50.3-54.3 95.2-54.8 95.8-2.2 2.3-2.8 5.7-1.5 8.7 1.3 2.9 4.1 4.8 7.3 4.8 66.3 0 116-31.8 140.6-51.4 32.7 12.3 69 19.4 107.4 19.4 27.4 0 53.7-3.6 78.4-10L72.9 186.4c-5.6 17.1-8.9 35-8.9 53.6zm569.8 218.1l-114.4-88.4C554.6 334.1 576 289.2 576 240c0-114.9-114.6-208-256-208-65.1 0-124.2 20.1-169.4 52.7L45.5 3.4C38.5-2 28.5-.8 23 6.2L3.4 31.4c-5.4 7-4.2 17 2.8 22.4l588.4 454.7c7 5.4 17 4.2 22.5-2.8l19.6-25.3c5.4-6.8 4.1-16.9-2.9-22.3z"],comments:[576,512,[],"f086","M416 192c0-88.4-93.1-160-208-160S0 103.6 0 192c0 34.3 14.1 65.9 38 92-13.4 30.2-35.5 54.2-35.8 54.5-2.2 2.3-2.8 5.7-1.5 8.7S4.8 352 8 352c36.6 0 66.9-12.3 88.7-25 32.2 15.7 70.3 25 111.3 25 114.9 0 208-71.6 208-160zm122 220c23.9-26 38-57.7 38-92 0-66.9-53.5-124.2-129.3-148.1.9 6.6 1.3 13.3 1.3 20.1 0 105.9-107.7 192-240 192-10.8 0-21.3-.8-31.7-1.9C207.8 439.6 281.8 480 368 480c41 0 79.1-9.2 111.3-25 21.8 12.7 52.1 25 88.7 25 3.2 0 6.1-1.9 7.3-4.8 1.3-2.9.7-6.3-1.5-8.7-.3-.3-22.4-24.2-35.8-54.5z"],compass:[512,512,[],"f14e","M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM307.446 120.844l-102.642 97.779a23.997 23.997 0 0 0-6.772 11.729l-33.359 137.779c-5.68 23.459 22.777 39.318 39.88 23.024l102.64-97.779a23.99 23.99 0 0 0 6.772-11.729l33.359-137.779c5.618-23.198-22.591-39.493-39.878-23.024zM256 224c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32z"],compress:[448,512,[],"f066","M436 192H312c-13.3 0-24-10.7-24-24V44c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v84h84c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12zm-276-24V44c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v84H12c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h124c13.3 0 24-10.7 24-24zm0 300V344c0-13.3-10.7-24-24-24H12c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h84v84c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm192 0v-84h84c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12H312c-13.3 0-24 10.7-24 24v124c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12z"],copy:[448,512,[],"f0c5","M320 448v40c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V120c0-13.255 10.745-24 24-24h72v296c0 30.879 25.121 56 56 56h168zm0-344V0H152c-13.255 0-24 10.745-24 24v368c0 13.255 10.745 24 24 24h272c13.255 0 24-10.745 24-24V128H344c-13.2 0-24-10.8-24-24zm120.971-31.029L375.029 7.029A24 24 0 0 0 358.059 0H352v96h96v-6.059a24 24 0 0 0-7.029-16.97z"],copyright:[512,512,[],"f1f9","M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm117.134 346.753c-1.592 1.867-39.776 45.731-109.851 45.731-84.692 0-144.484-63.26-144.484-145.567 0-81.303 62.004-143.401 143.762-143.401 66.957 0 101.965 37.315 103.422 38.904a12 12 0 0 1 1.238 14.623l-22.38 34.655c-4.049 6.267-12.774 7.351-18.234 2.295-.233-.214-26.529-23.88-61.88-23.88-46.116 0-73.916 33.575-73.916 76.082 0 39.602 25.514 79.692 74.277 79.692 38.697 0 65.28-28.338 65.544-28.625 5.132-5.565 14.059-5.033 18.508 1.053l24.547 33.572a12.001 12.001 0 0 1-.553 14.866z"],couch:[640,512,[],"f4b8","M160 224v64h320v-64c0-35.3 28.7-64 64-64h32c0-53-43-96-96-96H160c-53 0-96 43-96 96h32c35.3 0 64 28.7 64 64zm416-32h-32c-17.7 0-32 14.3-32 32v96H128v-96c0-17.7-14.3-32-32-32H64c-35.3 0-64 28.7-64 64 0 23.6 13 44 32 55.1V432c0 8.8 7.2 16 16 16h64c8.8 0 16-7.2 16-16v-16h384v16c0 8.8 7.2 16 16 16h64c8.8 0 16-7.2 16-16V311.1c19-11.1 32-31.5 32-55.1 0-35.3-28.7-64-64-64z"],"credit-card":[576,512,[],"f09d","M0 432c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V256H0v176zm192-68c0-6.6 5.4-12 12-12h136c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H204c-6.6 0-12-5.4-12-12v-40zm-128 0c0-6.6 5.4-12 12-12h72c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12v-40zM576 80v48H0V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48z"],crop:[512,512,[],"f125","M488 352h-40V109.3l57-57c9.4-9.4 9.4-24.6 0-33.9L493.7 7c-9.4-9.4-24.6-9.4-33.9 0l-57 57H160V24c0-13.3-10.7-24-24-24H88C74.7 0 64 10.7 64 24v40H24C10.7 64 0 74.7 0 88v48c0 13.3 10.7 24 24 24h40v264c0 13.3 10.7 24 24 24h264v40c0 13.3 10.7 24 24 24h48c13.3 0 24-10.7 24-24v-40h40c13.3 0 24-10.7 24-24v-48c0-13.3-10.7-24-24-24zM306.7 160L160 306.7V160h146.7zM205.3 352L352 205.3V352H205.3z"],crosshairs:[512,512,[],"f05b","M500 224h-30.364C455.724 130.325 381.675 56.276 288 42.364V12c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v30.364C130.325 56.276 56.276 130.325 42.364 224H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h30.364C56.276 381.675 130.325 455.724 224 469.636V500c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-30.364C381.675 455.724 455.724 381.675 469.636 288H500c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12zM288 404.634V364c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40.634C165.826 392.232 119.783 346.243 107.366 288H148c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-40.634C119.768 165.826 165.757 119.783 224 107.366V148c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40.634C346.174 119.768 392.217 165.757 404.634 224H364c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40.634C392.232 346.174 346.243 392.217 288 404.634zM288 256c0 17.673-14.327 32-32 32s-32-14.327-32-32c0-17.673 14.327-32 32-32s32 14.327 32 32z"],cube:[512,512,[],"f1b2","M239.1 6.3l-208 78c-18.7 7-31.1 25-31.1 45v225.1c0 18.2 10.3 34.8 26.5 42.9l208 104c13.5 6.8 29.4 6.8 42.9 0l208-104c16.3-8.1 26.5-24.8 26.5-42.9V129.3c0-20-12.4-37.9-31.1-44.9l-208-78C262 2.2 250 2.2 239.1 6.3zM256 68.4l192 72v1.1l-192 78-192-78v-1.1l192-72zm32 356V275.5l160-65v133.9l-160 80z"],cubes:[512,512,[],"f1b3","M488.6 250.2L392 214V105.5c0-15-9.3-28.4-23.4-33.7l-100-37.5c-8.1-3.1-17.1-3.1-25.3 0l-100 37.5c-14.1 5.3-23.4 18.7-23.4 33.7V214l-96.6 36.2C9.3 255.5 0 268.9 0 283.9V394c0 13.6 7.7 26.1 19.9 32.2l100 50c10.1 5.1 22.1 5.1 32.2 0l103.9-52 103.9 52c10.1 5.1 22.1 5.1 32.2 0l100-50c12.2-6.1 19.9-18.6 19.9-32.2V283.9c0-15-9.3-28.4-23.4-33.7zM358 214.8l-85 31.9v-68.2l85-37v73.3zM154 104.1l102-38.2 102 38.2v.6l-102 41.4-102-41.4v-.6zm84 291.1l-85 42.5v-79.1l85-38.8v75.4zm0-112l-102 41.4-102-41.4v-.6l102-38.2 102 38.2v.6zm240 112l-85 42.5v-79.1l85-38.8v75.4zm0-112l-102 41.4-102-41.4v-.6l102-38.2 102 38.2v.6z"],cut:[448,512,[],"f0c4","M444.485 422.426c4.689 4.689 4.684 12.287 0 16.971-32.804 32.804-85.991 32.804-118.795 0L210.176 323.883l-24.859 24.859C189.63 359.657 192 371.552 192 384c0 53.019-42.981 96-96 96S0 437.019 0 384s42.981-96 96-96c4.536 0 8.995.322 13.363.93l32.93-32.93-32.93-32.93c-4.368.608-8.827.93-13.363.93-53.019 0-96-42.981-96-96s42.981-96 96-96 96 42.981 96 96c0 12.448-2.37 24.343-6.682 35.258l24.859 24.859L325.69 72.603c32.804-32.804 85.991-32.804 118.795 0 4.684 4.684 4.689 12.282 0 16.971L278.059 256l166.426 166.426zM96 96c-17.645 0-32 14.355-32 32s14.355 32 32 32 32-14.355 32-32-14.355-32-32-32m0 256c-17.645 0-32 14.355-32 32s14.355 32 32 32 32-14.355 32-32-14.355-32-32-32m112-108c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12z"],database:[448,512,[],"f1c0","M448 73.143v45.714C448 159.143 347.667 192 224 192S0 159.143 0 118.857V73.143C0 32.857 100.333 0 224 0s224 32.857 224 73.143zM448 176v102.857C448 319.143 347.667 352 224 352S0 319.143 0 278.857V176c48.125 33.143 136.208 48.572 224 48.572S399.874 209.143 448 176zm0 160v102.857C448 479.143 347.667 512 224 512S0 479.143 0 438.857V336c48.125 33.143 136.208 48.572 224 48.572S399.874 369.143 448 336z"],deaf:[512,512,[],"f2a4","M216 260c0 15.464-12.536 28-28 28s-28-12.536-28-28c0-44.112 35.888-80 80-80s80 35.888 80 80c0 15.464-12.536 28-28 28s-28-12.536-28-28c0-13.234-10.767-24-24-24s-24 10.766-24 24zm24-176c-97.047 0-176 78.953-176 176 0 15.464 12.536 28 28 28s28-12.536 28-28c0-66.168 53.832-120 120-120s120 53.832 120 120c0 75.164-71.009 70.311-71.997 143.622L288 404c0 28.673-23.327 52-52 52-15.464 0-28 12.536-28 28s12.536 28 28 28c59.475 0 107.876-48.328 108-107.774.595-34.428 72-48.24 72-144.226 0-97.047-78.953-176-176-176zm268.485-52.201L480.2 3.515c-4.687-4.686-12.284-4.686-16.971 0L376.2 90.544c-4.686 4.686-4.686 12.284 0 16.971l28.285 28.285c4.686 4.686 12.284 4.686 16.97 0l87.03-87.029c4.687-4.688 4.687-12.286 0-16.972zM168.97 314.745c-4.686-4.686-12.284-4.686-16.97 0L3.515 463.23c-4.686 4.686-4.686 12.284 0 16.971L31.8 508.485c4.687 4.686 12.284 4.686 16.971 0L197.256 360c4.686-4.686 4.686-12.284 0-16.971l-28.286-28.284z"],desktop:[576,512,[],"f108","M528 0H48C21.5 0 0 21.5 0 48v320c0 26.5 21.5 48 48 48h192l-16 48h-72c-13.3 0-24 10.7-24 24s10.7 24 24 24h272c13.3 0 24-10.7 24-24s-10.7-24-24-24h-72l-16-48h192c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-16 352H64V64h448v288z"],diagnoses:[640,512,[],"f470","M496 256c8.8 0 16-7.2 16-16s-7.2-16-16-16-16 7.2-16 16 7.2 16 16 16zm-176-80c48.5 0 88-39.5 88-88S368.5 0 320 0s-88 39.5-88 88 39.5 88 88 88zM59.8 364c10.2 15.3 29.3 17.8 42.9 9.8 16.2-9.6 56.2-31.7 105.3-48.6V416h224v-90.7c49.1 16.8 89.1 39 105.3 48.6 13.6 8 32.7 5.3 42.9-9.8l17.8-26.7c8.8-13.2 7.6-34.6-10-45.1-11.9-7.1-29.7-17-51.1-27.4-28.1 46.1-99.4 17.8-87.7-35.1C409.3 217.2 365.1 208 320 208c-57 0-112.9 14.5-160 32.2-.2 40.2-47.6 63.3-79.2 36-11.2 6-21.3 11.6-28.7 16-17.6 10.5-18.8 31.8-10 45.1L59.8 364zM368 344c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zm-96-96c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zm-160 8c8.8 0 16-7.2 16-16s-7.2-16-16-16-16 7.2-16 16 7.2 16 16 16zm512 192H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h608c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16z"],dna:[448,512,[],"f471","M.1 494.1c-1.1 9.5 6.3 17.8 15.9 17.8l32.3.1c8.1 0 14.9-5.9 16-13.9.7-4.9 1.8-11.1 3.4-18.1H380c1.6 6.9 2.9 13.2 3.5 18.1 1.1 8 7.9 14 16 13.9l32.3-.1c9.6 0 17.1-8.3 15.9-17.8-4.6-37.9-25.6-129-118.9-207.7-17.6 12.4-37.1 24.2-58.5 35.4 6.2 4.6 11.4 9.4 17 14.2H159.7c21.3-18.1 47-35.6 78.7-51.4C410.5 199.1 442.1 65.8 447.9 17.9 449 8.4 441.6.1 432 .1L399.6 0c-8.1 0-14.9 5.9-16 13.9-.7 4.9-1.8 11.1-3.4 18.1H67.8c-1.6-7-2.7-13.1-3.4-18.1-1.1-8-7.9-14-16-13.9L16.1.1C6.5.1-1 8.4.1 17.9 5.3 60.8 31.4 171.8 160 256 31.5 340.2 5.3 451.2.1 494.1zM224 219.6c-25.1-13.7-46.4-28.4-64.3-43.6h128.5c-17.8 15.2-39.1 30-64.2 43.6zM355.1 96c-5.8 10.4-12.8 21.1-21 32H114c-8.3-10.9-15.3-21.6-21-32h262.1zM92.9 416c5.8-10.4 12.8-21.1 21-32h219.4c8.3 10.9 15.4 21.6 21.2 32H92.9z"],"dollar-sign":[288,512,[],"f155","M209.2 233.4l-108-31.6C88.7 198.2 80 186.5 80 173.5c0-16.3 13.2-29.5 29.5-29.5h66.3c12.2 0 24.2 3.7 34.2 10.5 6.1 4.1 14.3 3.1 19.5-2l34.8-34c7.1-6.9 6.1-18.4-1.8-24.5C238 74.8 207.4 64.1 176 64V16c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v48h-2.5C45.8 64-5.4 118.7.5 183.6c4.2 46.1 39.4 83.6 83.8 96.6l102.5 30c12.5 3.7 21.2 15.3 21.2 28.3 0 16.3-13.2 29.5-29.5 29.5h-66.3C100 368 88 364.3 78 357.5c-6.1-4.1-14.3-3.1-19.5 2l-34.8 34c-7.1 6.9-6.1 18.4 1.8 24.5 24.5 19.2 55.1 29.9 86.5 30v48c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16v-48.2c46.6-.9 90.3-28.6 105.7-72.7 21.5-61.6-14.6-124.8-72.5-141.7z"],dolly:[576,512,[],"f472","M294.2 277.7c18 5 34.7 13.4 49.5 24.7l161.5-53.8c8.4-2.8 12.9-11.9 10.1-20.2L454.9 47.2c-2.8-8.4-11.9-12.9-20.2-10.1l-61.1 20.4 33.1 99.4L346 177l-33.1-99.4-61.6 20.5c-8.4 2.8-12.9 11.9-10.1 20.2l53 159.4zm281 48.7L565 296c-2.8-8.4-11.9-12.9-20.2-10.1l-213.5 71.2c-17.2-22-43.6-36.4-73.5-37L158.4 21.9C154 8.8 141.8 0 128 0H16C7.2 0 0 7.2 0 16v32c0 8.8 7.2 16 16 16h88.9l92.2 276.7c-26.1 20.4-41.7 53.6-36 90.5 6.1 39.4 37.9 72.3 77.3 79.2 60.2 10.7 112.3-34.8 113.4-92.6l213.3-71.2c8.3-2.8 12.9-11.8 10.1-20.2zM256 464c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48z"],"dolly-flatbed":[640,512,[],"f474","M208 320h384c8.8 0 16-7.2 16-16V48c0-8.8-7.2-16-16-16H448v128l-48-32-48 32V32H208c-8.8 0-16 7.2-16 16v256c0 8.8 7.2 16 16 16zm416 64H128V16c0-8.8-7.2-16-16-16H16C7.2 0 0 7.2 0 16v32c0 8.8 7.2 16 16 16h48v368c0 8.8 7.2 16 16 16h82.9c-1.8 5-2.9 10.4-2.9 16 0 26.5 21.5 48 48 48s48-21.5 48-48c0-5.6-1.2-11-2.9-16H451c-1.8 5-2.9 10.4-2.9 16 0 26.5 21.5 48 48 48s48-21.5 48-48c0-5.6-1.2-11-2.9-16H624c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16z"],donate:[512,512,[],"f4b9","M256 416c114.9 0 208-93.1 208-208S370.9 0 256 0 48 93.1 48 208s93.1 208 208 208zM233.8 97.4V80.6c0-9.2 7.4-16.6 16.6-16.6h11.1c9.2 0 16.6 7.4 16.6 16.6v17c15.5.8 30.5 6.1 43 15.4 5.6 4.1 6.2 12.3 1.2 17.1L306 145.6c-3.8 3.7-9.5 3.8-14 1-5.4-3.4-11.4-5.1-17.8-5.1h-38.9c-9 0-16.3 8.2-16.3 18.3 0 8.2 5 15.5 12.1 17.6l62.3 18.7c25.7 7.7 43.7 32.4 43.7 60.1 0 34-26.4 61.5-59.1 62.4v16.8c0 9.2-7.4 16.6-16.6 16.6h-11.1c-9.2 0-16.6-7.4-16.6-16.6v-17c-15.5-.8-30.5-6.1-43-15.4-5.6-4.1-6.2-12.3-1.2-17.1l16.3-15.5c3.8-3.7 9.5-3.8 14-1 5.4 3.4 11.4 5.1 17.8 5.1h38.9c9 0 16.3-8.2 16.3-18.3 0-8.2-5-15.5-12.1-17.6l-62.3-18.7c-25.7-7.7-43.7-32.4-43.7-60.1.1-34 26.4-61.5 59.1-62.4zM480 352h-32.5c-19.6 26-44.6 47.7-73 64h63.8c5.3 0 9.6 3.6 9.6 8v16c0 4.4-4.3 8-9.6 8H73.6c-5.3 0-9.6-3.6-9.6-8v-16c0-4.4 4.3-8 9.6-8h63.8c-28.4-16.3-53.3-38-73-64H32c-17.7 0-32 14.3-32 32v96c0 17.7 14.3 32 32 32h448c17.7 0 32-14.3 32-32v-96c0-17.7-14.3-32-32-32z"],"dot-circle":[512,512,[],"f192","M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm80 248c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80z"],dove:[512,512,[],"f4ba","M288 167.2v-28.1c-28.2-36.3-47.1-79.3-54.1-125.2-2.1-13.5-19-18.8-27.8-8.3-21.1 24.9-37.7 54.1-48.9 86.5 34.2 38.3 80 64.6 130.8 75.1zM400 64c-44.2 0-80 35.9-80 80.1v59.4C215.6 197.3 127 133 87 41.8c-5.5-12.5-23.2-13.2-29-.9C41.4 76 32 115.2 32 156.6c0 70.8 34.1 136.9 85.1 185.9 13.2 12.7 26.1 23.2 38.9 32.8l-143.9 36C1.4 414-3.4 426.4 2.6 435.7 20 462.6 63 508.2 155.8 512c8 .3 16-2.6 22.1-7.9l65.2-56.1H320c88.4 0 160-71.5 160-159.9V128l32-64H400zm0 96.1c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16z"],download:[512,512,[],"f019","M216 0h80c13.3 0 24 10.7 24 24v168h87.7c17.8 0 26.7 21.5 14.1 34.1L269.7 378.3c-7.5 7.5-19.8 7.5-27.3 0L90.1 226.1c-12.6-12.6-3.7-34.1 14.1-34.1H192V24c0-13.3 10.7-24 24-24zm296 376v112c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24V376c0-13.3 10.7-24 24-24h146.7l49 49c20.1 20.1 52.5 20.1 72.6 0l49-49H488c13.3 0 24 10.7 24 24zm-124 88c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20zm64 0c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20z"],edit:[576,512,[],"f044","M402.6 83.2l90.2 90.2c3.8 3.8 3.8 10 0 13.8L274.4 405.6l-92.8 10.3c-12.4 1.4-22.9-9.1-21.5-21.5l10.3-92.8L388.8 83.2c3.8-3.8 10-3.8 13.8 0zm162-22.9l-48.8-48.8c-15.2-15.2-39.9-15.2-55.2 0l-35.4 35.4c-3.8 3.8-3.8 10 0 13.8l90.2 90.2c3.8 3.8 10 3.8 13.8 0l35.4-35.4c15.2-15.3 15.2-40 0-55.2zM384 346.2V448H64V128h229.8c3.2 0 6.2-1.3 8.5-3.5l40-40c7.6-7.6 2.2-20.5-8.5-20.5H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V306.2c0-10.7-12.9-16-20.5-8.5l-40 40c-2.2 2.3-3.5 5.3-3.5 8.5z"],eject:[448,512,[],"f052","M448 384v64c0 17.673-14.327 32-32 32H32c-17.673 0-32-14.327-32-32v-64c0-17.673 14.327-32 32-32h384c17.673 0 32 14.327 32 32zM48.053 320h351.886c41.651 0 63.581-49.674 35.383-80.435L259.383 47.558c-19.014-20.743-51.751-20.744-70.767 0L12.67 239.565C-15.475 270.268 6.324 320 48.053 320z"],"ellipsis-h":[512,512,[],"f141","M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"],"ellipsis-v":[192,512,[],"f142","M96 184c39.8 0 72 32.2 72 72s-32.2 72-72 72-72-32.2-72-72 32.2-72 72-72zM24 80c0 39.8 32.2 72 72 72s72-32.2 72-72S135.8 8 96 8 24 40.2 24 80zm0 352c0 39.8 32.2 72 72 72s72-32.2 72-72-32.2-72-72-72-72 32.2-72 72z"],envelope:[512,512,[],"f0e0","M502.3 190.8c3.9-3.1 9.7-.2 9.7 4.7V400c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V195.6c0-5 5.7-7.8 9.7-4.7 22.4 17.4 52.1 39.5 154.1 113.6 21.1 15.4 56.7 47.8 92.2 47.6 35.7.3 72-32.8 92.3-47.6 102-74.1 131.6-96.3 154-113.7zM256 320c23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7 5.8-4.5 9.2-11.5 9.2-18.9v-19c0-26.5-21.5-48-48-48H48C21.5 64 0 85.5 0 112v19c0 7.4 3.4 14.3 9.2 18.9 30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4z"],"envelope-open":[512,512,[],"f2b6","M512 464c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V200.724a48 48 0 0 1 18.387-37.776c24.913-19.529 45.501-35.365 164.2-121.511C199.412 29.17 232.797-.347 256 .003c23.198-.354 56.596 29.172 73.413 41.433 118.687 86.137 139.303 101.995 164.2 121.512A48 48 0 0 1 512 200.724V464zm-65.666-196.605c-2.563-3.728-7.7-4.595-11.339-1.907-22.845 16.873-55.462 40.705-105.582 77.079-16.825 12.266-50.21 41.781-73.413 41.43-23.211.344-56.559-29.143-73.413-41.43-50.114-36.37-82.734-60.204-105.582-77.079-3.639-2.688-8.776-1.821-11.339 1.907l-9.072 13.196a7.998 7.998 0 0 0 1.839 10.967c22.887 16.899 55.454 40.69 105.303 76.868 20.274 14.781 56.524 47.813 92.264 47.573 35.724.242 71.961-32.771 92.263-47.573 49.85-36.179 82.418-59.97 105.303-76.868a7.998 7.998 0 0 0 1.839-10.967l-9.071-13.196z"],"envelope-square":[448,512,[],"f199","M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM178.117 262.104C87.429 196.287 88.353 196.121 64 177.167V152c0-13.255 10.745-24 24-24h272c13.255 0 24 10.745 24 24v25.167c-24.371 18.969-23.434 19.124-114.117 84.938-10.5 7.655-31.392 26.12-45.883 25.894-14.503.218-35.367-18.227-45.883-25.895zM384 217.775V360c0 13.255-10.745 24-24 24H88c-13.255 0-24-10.745-24-24V217.775c13.958 10.794 33.329 25.236 95.303 70.214 14.162 10.341 37.975 32.145 64.694 32.01 26.887.134 51.037-22.041 64.72-32.025 61.958-44.965 81.325-59.406 95.283-70.199z"],eraser:[512,512,[],"f12d","M497.941 273.941c18.745-18.745 18.745-49.137 0-67.882l-160-160c-18.745-18.745-49.136-18.746-67.883 0l-256 256c-18.745 18.745-18.745 49.137 0 67.882l96 96A48.004 48.004 0 0 0 144 480h356c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12H355.883l142.058-142.059zm-302.627-62.627l137.373 137.373L265.373 416H150.628l-80-80 124.686-124.686z"],"euro-sign":[320,512,[],"f153","M310.706 413.765c-1.314-6.63-7.835-10.872-14.424-9.369-10.692 2.439-27.422 5.413-45.426 5.413-56.763 0-101.929-34.79-121.461-85.449h113.689a12 12 0 0 0 11.708-9.369l6.373-28.36c1.686-7.502-4.019-14.631-11.708-14.631H115.22c-1.21-14.328-1.414-28.287.137-42.245H261.95a12 12 0 0 0 11.723-9.434l6.512-29.755c1.638-7.484-4.061-14.566-11.723-14.566H130.184c20.633-44.991 62.69-75.03 117.619-75.03 14.486 0 28.564 2.25 37.851 4.145 6.216 1.268 12.347-2.498 14.002-8.623l11.991-44.368c1.822-6.741-2.465-13.616-9.326-14.917C290.217 34.912 270.71 32 249.635 32 152.451 32 74.03 92.252 45.075 176H12c-6.627 0-12 5.373-12 12v29.755c0 6.627 5.373 12 12 12h21.569c-1.009 13.607-1.181 29.287-.181 42.245H12c-6.627 0-12 5.373-12 12v28.36c0 6.627 5.373 12 12 12h30.114C67.139 414.692 145.264 480 249.635 480c26.301 0 48.562-4.544 61.101-7.788 6.167-1.595 10.027-7.708 8.788-13.957l-8.818-44.49z"],"exchange-alt":[512,512,[],"f362","M0 168v-16c0-13.255 10.745-24 24-24h360V80c0-21.367 25.899-32.042 40.971-16.971l80 80c9.372 9.373 9.372 24.569 0 33.941l-80 80C409.956 271.982 384 261.456 384 240v-48H24c-13.255 0-24-10.745-24-24zm488 152H128v-48c0-21.314-25.862-32.08-40.971-16.971l-80 80c-9.372 9.373-9.372 24.569 0 33.941l80 80C102.057 463.997 128 453.437 128 432v-48h360c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24z"],exclamation:[192,512,[],"f12a","M176 432c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zM25.26 25.199l13.6 272C39.499 309.972 50.041 320 62.83 320h66.34c12.789 0 23.331-10.028 23.97-22.801l13.6-272C167.425 11.49 156.496 0 142.77 0H49.23C35.504 0 24.575 11.49 25.26 25.199z"],"exclamation-circle":[512,512,[],"f06a","M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"],"exclamation-triangle":[576,512,[],"f071","M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"],expand:[448,512,[],"f065","M0 180V56c0-13.3 10.7-24 24-24h124c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H64v84c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12zM288 44v40c0 6.6 5.4 12 12 12h84v84c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12V56c0-13.3-10.7-24-24-24H300c-6.6 0-12 5.4-12 12zm148 276h-40c-6.6 0-12 5.4-12 12v84h-84c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h124c13.3 0 24-10.7 24-24V332c0-6.6-5.4-12-12-12zM160 468v-40c0-6.6-5.4-12-12-12H64v-84c0-6.6-5.4-12-12-12H12c-6.6 0-12 5.4-12 12v124c0 13.3 10.7 24 24 24h124c6.6 0 12-5.4 12-12z"],"expand-arrows-alt":[448,512,[],"f31e","M448.1 344v112c0 13.3-10.7 24-24 24h-112c-21.4 0-32.1-25.9-17-41l36.2-36.2L224 295.6 116.8 402.9 153 439c15.1 15.1 4.4 41-17 41H24c-13.3 0-24-10.7-24-24V344c0-21.4 25.9-32.1 41-17l36.2 36.2L184.5 256 77.2 148.7 41 185c-15.1 15.1-41 4.4-41-17V56c0-13.3 10.7-24 24-24h112c21.4 0 32.1 25.9 17 41l-36.2 36.2L224 216.4l107.3-107.3L295.1 73c-15.1-15.1-4.4-41 17-41h112c13.3 0 24 10.7 24 24v112c0 21.4-25.9 32.1-41 17l-36.2-36.2L263.6 256l107.3 107.3 36.2-36.2c15.1-15.2 41-4.5 41 16.9z"],"external-link-alt":[576,512,[],"f35d","M576 24v127.984c0 21.461-25.96 31.98-40.971 16.971l-35.707-35.709-243.523 243.523c-9.373 9.373-24.568 9.373-33.941 0l-22.627-22.627c-9.373-9.373-9.373-24.569 0-33.941L442.756 76.676l-35.703-35.705C391.982 25.9 402.656 0 424.024 0H552c13.255 0 24 10.745 24 24zM407.029 270.794l-16 16A23.999 23.999 0 0 0 384 303.765V448H64V128h264a24.003 24.003 0 0 0 16.97-7.029l16-16C376.089 89.851 365.381 64 344 64H48C21.49 64 0 85.49 0 112v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V287.764c0-21.382-25.852-32.09-40.971-16.97z"],"external-link-square-alt":[448,512,[],"f360","M448 80v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48zm-88 16H248.029c-21.313 0-32.08 25.861-16.971 40.971l31.984 31.987L67.515 364.485c-4.686 4.686-4.686 12.284 0 16.971l31.029 31.029c4.687 4.686 12.285 4.686 16.971 0l195.526-195.526 31.988 31.991C358.058 263.977 384 253.425 384 231.979V120c0-13.255-10.745-24-24-24z"],eye:[576,512,[],"f06e","M569.354 231.631C512.969 135.949 407.81 72 288 72 168.14 72 63.004 135.994 6.646 231.631a47.999 47.999 0 0 0 0 48.739C63.031 376.051 168.19 440 288 440c119.86 0 224.996-63.994 281.354-159.631a47.997 47.997 0 0 0 0-48.738zM288 392c-75.162 0-136-60.827-136-136 0-75.162 60.826-136 136-136 75.162 0 136 60.826 136 136 0 75.162-60.826 136-136 136zm104-136c0 57.438-46.562 104-104 104s-104-46.562-104-104c0-17.708 4.431-34.379 12.236-48.973l-.001.032c0 23.651 19.173 42.823 42.824 42.823s42.824-19.173 42.824-42.823c0-23.651-19.173-42.824-42.824-42.824l-.032.001C253.621 156.431 270.292 152 288 152c57.438 0 104 46.562 104 104z"],"eye-dropper":[512,512,[],"f1fb","M177.38 206.64L39.03 344.97A24.01 24.01 0 0 0 32 361.94V424L0 480l32 32 56-32h62.06c6.36 0 12.47-2.53 16.97-7.03l138.35-138.33-128-128zm225.552 30.47l16.952 16.95c9.37 9.37 9.37 24.57 0 33.94l-40.973 40.97c-9.292 9.312-24.506 9.434-33.94 0L183.028 167.03c-9.37-9.37-9.37-24.57 0-33.94L224 92.12c9.289-9.309 24.502-9.438 33.94 0l16.992 16.99 82.606-82.601c35.19-35.19 92.5-35.5 128 0 40.49 48.08 29.66 98.34 0 128l-82.606 82.601z"],"eye-slash":[576,512,[],"f070","M286.693 391.984l32.579 46.542A333.958 333.958 0 0 1 288 440C168.19 440 63.031 376.051 6.646 280.369a47.999 47.999 0 0 1 0-48.739c24.023-40.766 56.913-75.775 96.024-102.537l57.077 81.539C154.736 224.82 152 240.087 152 256c0 74.736 60.135 135.282 134.693 135.984zm282.661-111.615c-31.667 53.737-78.747 97.46-135.175 125.475l.011.015 41.47 59.2c7.6 10.86 4.96 25.82-5.9 33.42l-13.11 9.18c-10.86 7.6-25.82 4.96-33.42-5.9L100.34 46.94c-7.6-10.86-4.96-25.82 5.9-33.42l13.11-9.18c10.86-7.6 25.82-4.96 33.42 5.9l51.038 72.617C230.68 75.776 258.905 72 288 72c119.81 0 224.969 63.949 281.354 159.631a48.002 48.002 0 0 1 0 48.738zM424 256c0-75.174-60.838-136-136-136-17.939 0-35.056 3.473-50.729 9.772l19.299 27.058c25.869-8.171 55.044-6.163 80.4 7.41h-.03c-23.65 0-42.82 19.17-42.82 42.82 0 23.626 19.147 42.82 42.82 42.82 23.65 0 42.82-19.17 42.82-42.82v-.03c18.462 34.49 16.312 77.914-8.25 110.95v.01l19.314 27.061C411.496 321.2 424 290.074 424 256zM262.014 356.727l-77.53-110.757c-5.014 52.387 29.314 98.354 77.53 110.757z"],"fast-backward":[512,512,[],"f049","M0 436V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v151.9L235.5 71.4C256.1 54.3 288 68.6 288 96v131.9L459.5 71.4C480.1 54.3 512 68.6 512 96v320c0 27.4-31.9 41.7-52.5 24.6L288 285.3V416c0 27.4-31.9 41.7-52.5 24.6L64 285.3V436c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12z"],"fast-forward":[512,512,[],"f050","M512 76v360c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12V284.1L276.5 440.6c-20.6 17.2-52.5 2.8-52.5-24.6V284.1L52.5 440.6C31.9 457.8 0 443.4 0 416V96c0-27.4 31.9-41.7 52.5-24.6L224 226.8V96c0-27.4 31.9-41.7 52.5-24.6L448 226.8V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12z"],fax:[512,512,[],"f1ac","M128 144v320c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V144c0-26.51 21.49-48 48-48h32c26.51 0 48 21.49 48 48zm384 64v256c0 26.51-21.49 48-48 48H192c-26.51 0-48-21.49-48-48V40c0-22.091 17.909-40 40-40h207.432a39.996 39.996 0 0 1 28.284 11.716l48.569 48.569A39.999 39.999 0 0 1 480 88.568v74.174c18.641 6.591 32 24.36 32 45.258zm-320-16h240V96h-24c-13.203 0-24-10.797-24-24V48H192v144zm96 204c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40zm0-128c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40zm128 128c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40zm0-128c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40z"],female:[256,512,[],"f182","M128 0c35.346 0 64 28.654 64 64s-28.654 64-64 64c-35.346 0-64-28.654-64-64S92.654 0 128 0m119.283 354.179l-48-192A24 24 0 0 0 176 144h-11.36c-22.711 10.443-49.59 10.894-73.28 0H80a24 24 0 0 0-23.283 18.179l-48 192C4.935 369.305 16.383 384 32 384h56v104c0 13.255 10.745 24 24 24h32c13.255 0 24-10.745 24-24V384h56c15.591 0 27.071-14.671 23.283-29.821z"],"fighter-jet":[640,512,[],"f0fb","M544 224l-128-16-48-16h-24L227.158 44h39.509C278.333 44 288 41.375 288 38s-9.667-6-21.333-6H152v12h16v164h-48l-66.667-80H18.667L8 138.667V208h8v16h48v2.666l-64 8v42.667l64 8V288H16v16H8v69.333L18.667 384h34.667L120 304h48v164h-16v12h114.667c11.667 0 21.333-2.625 21.333-6s-9.667-6-21.333-6h-39.509L344 320h24l48-16 128-16c96-21.333 96-26.583 96-32 0-5.417 0-10.667-96-32z"],file:[384,512,[],"f15b","M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm160-14.1v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"],"file-alt":[384,512,[],"f15c","M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm64 236c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12v8zm0-64c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12v8zm0-72v8c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12zm96-114.1v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"],"file-archive":[384,512,[],"f1c6","M224 136V0h-63.6v32h-32V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zM95.9 32h32v32h-32V32zm32.3 384c-33.2 0-58-30.4-51.4-62.9L96.4 256v-32h32v-32h-32v-32h32v-32h-32V96h32V64h32v32h-32v32h32v32h-32v32h32v32h-32v32h22.1c5.7 0 10.7 4.1 11.8 9.7l17.3 87.7c6.4 32.4-18.4 62.6-51.4 62.6zm32.7-53c0 14.9-14.5 27-32.4 27S96 378 96 363c0-14.9 14.5-27 32.4-27s32.5 12.1 32.5 27zM384 121.9v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"],"file-audio":[384,512,[],"f1c7","M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm-64 268c0 10.7-12.9 16-20.5 8.5L104 376H76c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h28l35.5-36.5c7.6-7.6 20.5-2.2 20.5 8.5v136zm33.2-47.6c9.1-9.3 9.1-24.1 0-33.4-22.1-22.8 12.2-56.2 34.4-33.5 27.2 27.9 27.2 72.4 0 100.4-21.8 22.3-56.9-10.4-34.4-33.5zm86-117.1c54.4 55.9 54.4 144.8 0 200.8-21.8 22.4-57-10.3-34.4-33.5 36.2-37.2 36.3-96.5 0-133.8-22.1-22.8 12.3-56.3 34.4-33.5zM384 121.9v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"],"file-code":[384,512,[],"f1c9","M384 121.941V128H256V0h6.059c6.365 0 12.47 2.529 16.971 7.029l97.941 97.941A24.005 24.005 0 0 1 384 121.941zM248 160c-13.2 0-24-10.8-24-24V0H24C10.745 0 0 10.745 0 24v464c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V160H248zM123.206 400.505a5.4 5.4 0 0 1-7.633.246l-64.866-60.812a5.4 5.4 0 0 1 0-7.879l64.866-60.812a5.4 5.4 0 0 1 7.633.246l19.579 20.885a5.4 5.4 0 0 1-.372 7.747L101.65 336l40.763 35.874a5.4 5.4 0 0 1 .372 7.747l-19.579 20.884zm51.295 50.479l-27.453-7.97a5.402 5.402 0 0 1-3.681-6.692l61.44-211.626a5.402 5.402 0 0 1 6.692-3.681l27.452 7.97a5.4 5.4 0 0 1 3.68 6.692l-61.44 211.626a5.397 5.397 0 0 1-6.69 3.681zm160.792-111.045l-64.866 60.812a5.4 5.4 0 0 1-7.633-.246l-19.58-20.885a5.4 5.4 0 0 1 .372-7.747L284.35 336l-40.763-35.874a5.4 5.4 0 0 1-.372-7.747l19.58-20.885a5.4 5.4 0 0 1 7.633-.246l64.866 60.812a5.4 5.4 0 0 1-.001 7.879z"],"file-excel":[384,512,[],"f1c3","M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm60.1 106.5L224 336l60.1 93.5c5.1 8-.6 18.5-10.1 18.5h-34.9c-4.4 0-8.5-2.4-10.6-6.3C208.9 405.5 192 373 192 373c-6.4 14.8-10 20-36.6 68.8-2.1 3.9-6.1 6.3-10.5 6.3H110c-9.5 0-15.2-10.5-10.1-18.5l60.3-93.5-60.3-93.5c-5.2-8 .6-18.5 10.1-18.5h34.8c4.4 0 8.5 2.4 10.6 6.3 26.1 48.8 20 33.6 36.6 68.5 0 0 6.1-11.7 36.6-68.5 2.1-3.9 6.2-6.3 10.6-6.3H274c9.5-.1 15.2 10.4 10.1 18.4zM384 121.9v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"],"file-image":[384,512,[],"f1c5","M384 121.941V128H256V0h6.059a24 24 0 0 1 16.97 7.029l97.941 97.941a24.002 24.002 0 0 1 7.03 16.971zM248 160c-13.2 0-24-10.8-24-24V0H24C10.745 0 0 10.745 0 24v464c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V160H248zm-135.455 16c26.51 0 48 21.49 48 48s-21.49 48-48 48-48-21.49-48-48 21.491-48 48-48zm208 240h-256l.485-48.485L104.545 328c4.686-4.686 11.799-4.201 16.485.485L160.545 368 264.06 264.485c4.686-4.686 12.284-4.686 16.971 0L320.545 304v112z"],"file-medical":[384,512,[],"f477","M377 105L279.1 7c-4.5-4.5-10.6-7-17-7H256v128h128v-6.1c0-6.3-2.5-12.4-7-16.9zm-153 31V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm64 160v48c0 4.4-3.6 8-8 8h-56v56c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8v-56h-56c-4.4 0-8-3.6-8-8v-48c0-4.4 3.6-8 8-8h56v-56c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v56h56c4.4 0 8 3.6 8 8z"],"file-medical-alt":[448,512,[],"f478","M288 136V0H88C74.7 0 64 10.7 64 24v232H8c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8h140.9c3 0 5.8 1.7 7.2 4.4l19.9 39.8 56.8-113.7c2.9-5.9 11.4-5.9 14.3 0l34.7 69.5H352c8.8 0 16 7.2 16 16s-7.2 16-16 16h-89.9L240 275.8l-56.8 113.7c-2.9 5.9-11.4 5.9-14.3 0L134.1 320H64v168c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H312c-13.2 0-24-10.8-24-24zm153-31L343.1 7c-4.5-4.5-10.6-7-17-7H320v128h128v-6.1c0-6.3-2.5-12.4-7-16.9z"],"file-pdf":[384,512,[],"f1c1","M181.9 256.1c-5-16-4.9-46.9-2-46.9 8.4 0 7.6 36.9 2 46.9zm-1.7 47.2c-7.7 20.2-17.3 43.3-28.4 62.7 18.3-7 39-17.2 62.9-21.9-12.7-9.6-24.9-23.4-34.5-40.8zM86.1 428.1c0 .8 13.2-5.4 34.9-40.2-6.7 6.3-29.1 24.5-34.9 40.2zM248 160h136v328c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24V24C0 10.7 10.7 0 24 0h200v136c0 13.2 10.8 24 24 24zm-8 171.8c-20-12.2-33.3-29-42.7-53.8 4.5-18.5 11.6-46.6 6.2-64.2-4.7-29.4-42.4-26.5-47.8-6.8-5 18.3-.4 44.1 8.1 77-11.6 27.6-28.7 64.6-40.8 85.8-.1 0-.1.1-.2.1-27.1 13.9-73.6 44.5-54.5 68 5.6 6.9 16 10 21.5 10 17.9 0 35.7-18 61.1-61.8 25.8-8.5 54.1-19.1 79-23.2 21.7 11.8 47.1 19.5 64 19.5 29.2 0 31.2-32 19.7-43.4-13.9-13.6-54.3-9.7-73.6-7.2zM377 105L279 7c-4.5-4.5-10.6-7-17-7h-6v128h128v-6.1c0-6.3-2.5-12.4-7-16.9zm-74.1 255.3c4.1-2.7-2.5-11.9-42.8-9 37.1 15.8 42.8 9 42.8 9z"],"file-powerpoint":[384,512,[],"f1c4","M193.7 271.2c8.8 0 15.5 2.7 20.3 8.1 9.6 10.9 9.8 32.7-.2 44.1-4.9 5.6-11.9 8.5-21.1 8.5h-26.9v-60.7h27.9zM377 105L279 7c-4.5-4.5-10.6-7-17-7h-6v128h128v-6.1c0-6.3-2.5-12.4-7-16.9zm-153 31V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm53 165.2c0 90.3-88.8 77.6-111.1 77.6V436c0 6.6-5.4 12-12 12h-30.8c-6.6 0-12-5.4-12-12V236.2c0-6.6 5.4-12 12-12h81c44.5 0 72.9 32.8 72.9 77z"],"file-video":[384,512,[],"f1c8","M384 121.941V128H256V0h6.059c6.365 0 12.47 2.529 16.971 7.029l97.941 97.941A24.005 24.005 0 0 1 384 121.941zM224 136V0H24C10.745 0 0 10.745 0 24v464c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V160H248c-13.2 0-24-10.8-24-24zm96 144.016v111.963c0 21.445-25.943 31.998-40.971 16.971L224 353.941V392c0 13.255-10.745 24-24 24H88c-13.255 0-24-10.745-24-24V280c0-13.255 10.745-24 24-24h112c13.255 0 24 10.745 24 24v38.059l55.029-55.013c15.011-15.01 40.971-4.491 40.971 16.97z"],"file-word":[384,512,[],"f1c2","M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm57.1 120H305c7.7 0 13.4 7.1 11.7 14.7l-38 168c-1.2 5.5-6.1 9.3-11.7 9.3h-38c-5.5 0-10.3-3.8-11.6-9.1-25.8-103.5-20.8-81.2-25.6-110.5h-.5c-1.1 14.3-2.4 17.4-25.6 110.5-1.3 5.3-6.1 9.1-11.6 9.1H117c-5.6 0-10.5-3.9-11.7-9.4l-37.8-168c-1.7-7.5 4-14.6 11.7-14.6h24.5c5.7 0 10.7 4 11.8 9.7 15.6 78 20.1 109.5 21 122.2 1.6-10.2 7.3-32.7 29.4-122.7 1.3-5.4 6.1-9.1 11.7-9.1h29.1c5.6 0 10.4 3.8 11.7 9.2 24 100.4 28.8 124 29.6 129.4-.2-11.2-2.6-17.8 21.6-129.2 1-5.6 5.9-9.5 11.5-9.5zM384 121.9v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"],film:[512,512,[],"f008","M488 64h-8v20c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12V64H96v20c0 6.6-5.4 12-12 12H44c-6.6 0-12-5.4-12-12V64h-8C10.7 64 0 74.7 0 88v336c0 13.3 10.7 24 24 24h8v-20c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v20h320v-20c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v20h8c13.3 0 24-10.7 24-24V88c0-13.3-10.7-24-24-24zM96 372c0 6.6-5.4 12-12 12H44c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-96c0 6.6-5.4 12-12 12H44c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-96c0 6.6-5.4 12-12 12H44c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm272 208c0 6.6-5.4 12-12 12H156c-6.6 0-12-5.4-12-12v-96c0-6.6 5.4-12 12-12h200c6.6 0 12 5.4 12 12v96zm0-168c0 6.6-5.4 12-12 12H156c-6.6 0-12-5.4-12-12v-96c0-6.6 5.4-12 12-12h200c6.6 0 12 5.4 12 12v96zm112 152c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-96c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-96c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40z"],filter:[512,512,[],"f0b0","M487.976 0H24.028C2.71 0-8.047 25.866 7.058 40.971L192 225.941V432c0 7.831 3.821 15.17 10.237 19.662l80 55.98C298.02 518.69 320 507.493 320 487.98V225.941l184.947-184.97C520.021 25.896 509.338 0 487.976 0z"],fire:[384,512,[],"f06d","M216 23.858c0-23.802-30.653-32.765-44.149-13.038C48 191.851 224 200 224 288c0 35.629-29.114 64.458-64.85 63.994C123.98 351.538 96 322.22 96 287.046v-85.51c0-21.703-26.471-32.225-41.432-16.504C27.801 213.158 0 261.332 0 320c0 105.869 86.131 192 192 192s192-86.131 192-192c0-170.29-168-193.003-168-296.142z"],"fire-extinguisher":[448,512,[],"f134","M434.027 26.329l-168 28C254.693 56.218 256 67.8 256 72h-58.332C208.353 36.108 181.446 0 144 0c-39.435 0-66.368 39.676-52.228 76.203-52.039 13.051-75.381 54.213-90.049 90.884-4.923 12.307 1.063 26.274 13.37 31.197 12.317 4.926 26.279-1.075 31.196-13.37C75.058 112.99 106.964 120 168 120v27.076c-41.543 10.862-72 49.235-72 94.129V488c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24V240c0-44.731-30.596-82.312-72-92.97V120h40c0 2.974-1.703 15.716 10.027 17.671l168 28C441.342 166.89 448 161.25 448 153.834V38.166c0-7.416-6.658-13.056-13.973-11.837zM144 72c-8.822 0-16-7.178-16-16s7.178-16 16-16 16 7.178 16 16-7.178 16-16 16z"],"first-aid":[576,512,[],"f479","M0 80v352c0 26.5 21.5 48 48 48h48V32H48C21.5 32 0 53.5 0 80zm128 400h320V32H128v448zm64-248c0-4.4 3.6-8 8-8h56v-56c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v56h56c4.4 0 8 3.6 8 8v48c0 4.4-3.6 8-8 8h-56v56c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8v-56h-56c-4.4 0-8-3.6-8-8v-48zM528 32h-48v448h48c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z"],flag:[512,512,[],"f024","M349.565 98.783C295.978 98.783 251.721 64 184.348 64c-24.955 0-47.309 4.384-68.045 12.013a55.947 55.947 0 0 0 3.586-23.562C118.117 24.015 94.806 1.206 66.338.048 34.345-1.254 8 24.296 8 56c0 19.026 9.497 35.825 24 45.945V488c0 13.255 10.745 24 24 24h16c13.255 0 24-10.745 24-24v-94.4c28.311-12.064 63.582-22.122 114.435-22.122 53.588 0 97.844 34.783 165.217 34.783 48.169 0 86.667-16.294 122.505-40.858C506.84 359.452 512 349.571 512 339.045v-243.1c0-23.393-24.269-38.87-45.485-29.016-34.338 15.948-76.454 31.854-116.95 31.854z"],"flag-checkered":[512,512,[],"f11e","M466.515 66.928C487.731 57.074 512 72.551 512 95.944v243.1c0 10.526-5.161 20.407-13.843 26.358-35.837 24.564-74.335 40.858-122.505 40.858-67.373 0-111.63-34.783-165.217-34.783-50.853 0-86.124 10.058-114.435 22.122V488c0 13.255-10.745 24-24 24H56c-13.255 0-24-10.745-24-24V101.945C17.497 91.825 8 75.026 8 56 8 24.296 34.345-1.254 66.338.048c28.468 1.158 51.779 23.968 53.551 52.404.52 8.342-.81 16.31-3.586 23.562C137.039 68.384 159.393 64 184.348 64c67.373 0 111.63 34.783 165.217 34.783 40.496 0 82.612-15.906 116.95-31.855zM96 134.63v70.49c29-10.67 51.18-17.83 73.6-20.91v-71.57c-23.5 2.17-40.44 9.79-73.6 21.99zm220.8 9.19c-26.417-4.672-49.886-13.979-73.6-21.34v67.42c24.175 6.706 47.566 16.444 73.6 22.31v-68.39zm-147.2 40.39v70.04c32.796-2.978 53.91-.635 73.6 3.8V189.9c-25.247-7.035-46.581-9.423-73.6-5.69zm73.6 142.23c26.338 4.652 49.732 13.927 73.6 21.34v-67.41c-24.277-6.746-47.54-16.45-73.6-22.32v68.39zM96 342.1c23.62-8.39 47.79-13.84 73.6-16.56v-71.29c-26.11 2.35-47.36 8.04-73.6 17.36v70.49zm368-221.6c-21.3 8.85-46.59 17.64-73.6 22.47v71.91c27.31-4.36 50.03-14.1 73.6-23.89V120.5zm0 209.96v-70.49c-22.19 14.2-48.78 22.61-73.6 26.02v71.58c25.07-2.38 48.49-11.04 73.6-27.11zM316.8 212.21v68.16c25.664 7.134 46.616 9.342 73.6 5.62v-71.11c-25.999 4.187-49.943 2.676-73.6-2.67z"],flask:[448,512,[],"f0c3","M437.2 403.5L320 215V64h8c13.3 0 24-10.7 24-24V24c0-13.3-10.7-24-24-24H120c-13.3 0-24 10.7-24 24v16c0 13.3 10.7 24 24 24h8v151L10.8 403.5C-18.5 450.6 15.3 512 70.9 512h306.2c55.7 0 89.4-61.5 60.1-108.5zM137.9 320l48.2-77.6c3.7-5.2 5.8-11.6 5.8-18.4V64h64v160c0 6.9 2.2 13.2 5.8 18.4l48.2 77.6h-172z"],folder:[512,512,[],"f07b","M464 128H272l-64-64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V176c0-26.51-21.49-48-48-48z"],"folder-open":[576,512,[],"f07c","M572.694 292.093L500.27 416.248A63.997 63.997 0 0 1 444.989 448H45.025c-18.523 0-30.064-20.093-20.731-36.093l72.424-124.155A64 64 0 0 1 152 256h399.964c18.523 0 30.064 20.093 20.73 36.093zM152 224h328v-48c0-26.51-21.49-48-48-48H272l-64-64H48C21.49 64 0 85.49 0 112v278.046l69.077-118.418C86.214 242.25 117.989 224 152 224z"],font:[448,512,[],"f031","M152 416h-24.013l26.586-80.782H292.8L319.386 416H296c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h136c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16h-26.739L275.495 42.746A16 16 0 0 0 260.382 32h-72.766a16 16 0 0 0-15.113 10.746L42.739 416H16c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h136c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16zm64.353-271.778c4.348-15.216 6.61-28.156 7.586-34.644.839 6.521 2.939 19.476 7.727 34.706l41.335 124.006h-98.619l41.971-124.068z"],"football-ball":[496,512,[],"f44e","M481.5 60.3c-4.8-18.2-19.1-32.5-37.3-37.4C420.3 16.5 383 8.9 339.4 8L496 164.8c-.8-43.5-8.2-80.6-14.5-104.5zm-467 391.4c4.8 18.2 19.1 32.5 37.3 37.4 23.9 6.4 61.2 14 104.8 14.9L0 347.2c.8 43.5 8.2 80.6 14.5 104.5zM4.2 283.4L220.4 500c132.5-19.4 248.8-118.7 271.5-271.4L275.6 12C143.1 31.4 26.8 130.7 4.2 283.4zm317.3-123.6c3.1-3.1 8.2-3.1 11.3 0l11.3 11.3c3.1 3.1 3.1 8.2 0 11.3l-28.3 28.3 28.3 28.3c3.1 3.1 3.1 8.2 0 11.3l-11.3 11.3c-3.1 3.1-8.2 3.1-11.3 0l-28.3-28.3-22.6 22.7 28.3 28.3c3.1 3.1 3.1 8.2 0 11.3l-11.3 11.3c-3.1 3.1-8.2 3.1-11.3 0L248 278.6l-22.6 22.6 28.3 28.3c3.1 3.1 3.1 8.2 0 11.3l-11.3 11.3c-3.1 3.1-8.2 3.1-11.3 0l-28.3-28.3-28.3 28.3c-3.1 3.1-8.2 3.1-11.3 0l-11.3-11.3c-3.1-3.1-3.1-8.2 0-11.3l28.3-28.3-28.3-28.2c-3.1-3.1-3.1-8.2 0-11.3l11.3-11.3c3.1-3.1 8.2-3.1 11.3 0l28.3 28.3 22.6-22.6-28.3-28.3c-3.1-3.1-3.1-8.2 0-11.3l11.3-11.3c3.1-3.1 8.2-3.1 11.3 0l28.3 28.3 22.6-22.6-28.3-28.3c-3.1-3.1-3.1-8.2 0-11.3l11.3-11.3c3.1-3.1 8.2-3.1 11.3 0l28.3 28.3 28.3-28.5z"],forward:[512,512,[],"f04e","M500.5 231.4l-192-160C287.9 54.3 256 68.6 256 96v320c0 27.4 31.9 41.8 52.5 24.6l192-160c15.3-12.8 15.3-36.4 0-49.2zm-256 0l-192-160C31.9 54.3 0 68.6 0 96v320c0 27.4 31.9 41.8 52.5 24.6l192-160c15.3-12.8 15.3-36.4 0-49.2z"],frown:[496,512,[],"f119","M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm80 168c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zm-160 0c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zm192.7 220.3c-3 2.5-6.6 3.7-10.2 3.7-4.6 0-9.1-2-12.3-5.8-22.4-26.8-55.3-42.2-90.2-42.2s-67.8 15.4-90.2 42.2c-5.6 6.8-15.7 7.7-22.5 2-6.8-5.7-7.7-15.7-2-22.5C161.7 339.6 203.6 320 248 320s86.3 19.6 114.7 53.8c5.7 6.7 4.8 16.8-2 22.5z"],futbol:[512,512,[],"f1e3","M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-48 0l-.003-.282-26.064 22.741-62.679-58.5 16.454-84.355 34.303 3.072c-24.889-34.216-60.004-60.089-100.709-73.141l13.651 31.939L256 139l-74.953-41.525 13.651-31.939c-40.631 13.028-75.78 38.87-100.709 73.141l34.565-3.073 16.192 84.355-62.678 58.5-26.064-22.741-.003.282c0 43.015 13.497 83.952 38.472 117.991l7.704-33.897 85.138 10.447 36.301 77.826-29.902 17.786c40.202 13.122 84.29 13.148 124.572 0l-29.902-17.786 36.301-77.826 85.138-10.447 7.704 33.897C442.503 339.952 456 299.015 456 256zm-248.102 69.571l-29.894-91.312L256 177.732l77.996 56.527-29.622 91.312h-96.476z"],gamepad:[640,512,[],"f11b","M480 96H160C71.6 96 0 167.6 0 256s71.6 160 160 160c44.8 0 85.2-18.4 114.2-48h91.5c29 29.6 69.5 48 114.2 48 88.4 0 160-71.6 160-160S568.4 96 480 96zM256 276c0 6.6-5.4 12-12 12h-52v52c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-52H76c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h52v-52c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h52c6.6 0 12 5.4 12 12v40zm184 68c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zm80-80c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48z"],gavel:[512,512,[],"f0e3","M504.971 199.362l-22.627-22.627c-9.373-9.373-24.569-9.373-33.941 0l-5.657 5.657L329.608 69.255l5.657-5.657c9.373-9.373 9.373-24.569 0-33.941L312.638 7.029c-9.373-9.373-24.569-9.373-33.941 0L154.246 131.48c-9.373 9.373-9.373 24.569 0 33.941l22.627 22.627c9.373 9.373 24.569 9.373 33.941 0l5.657-5.657 39.598 39.598-81.04 81.04-5.657-5.657c-12.497-12.497-32.758-12.497-45.255 0L9.373 412.118c-12.497 12.497-12.497 32.758 0 45.255l45.255 45.255c12.497 12.497 32.758 12.497 45.255 0l114.745-114.745c12.497-12.497 12.497-32.758 0-45.255l-5.657-5.657 81.04-81.04 39.598 39.598-5.657 5.657c-9.373 9.373-9.373 24.569 0 33.941l22.627 22.627c9.373 9.373 24.569 9.373 33.941 0l124.451-124.451c9.372-9.372 9.372-24.568 0-33.941z"],gem:[576,512,[],"f3a5","M485.5 0L576 160H474.9L405.7 0h79.8zm-128 0l69.2 160H149.3L218.5 0h139zm-267 0h79.8l-69.2 160H0L90.5 0zM0 192h100.7l123 251.7c1.5 3.1-2.7 5.9-5 3.3L0 192zm148.2 0h279.6l-137 318.2c-1 2.4-4.5 2.4-5.5 0L148.2 192zm204.1 251.7l123-251.7H576L357.3 446.9c-2.3 2.7-6.5-.1-5-3.2z"],genderless:[288,512,[],"f22d","M144 176c44.1 0 80 35.9 80 80s-35.9 80-80 80-80-35.9-80-80 35.9-80 80-80m0-64C64.5 112 0 176.5 0 256s64.5 144 144 144 144-64.5 144-144-64.5-144-144-144z"],gift:[512,512,[],"f06b","M32 448c0 17.7 14.3 32 32 32h160V320H32v128zm448-288h-42.1c6.2-12.1 10.1-25.5 10.1-40 0-48.5-39.5-88-88-88-41.6 0-68.5 21.3-103 68.3-34.5-47-61.4-68.3-103-68.3-48.5 0-88 39.5-88 88 0 14.5 3.8 27.9 10.1 40H32c-17.7 0-32 14.3-32 32v80c0 8.8 7.2 16 16 16h480c8.8 0 16-7.2 16-16v-80c0-17.7-14.3-32-32-32zm-326.1 0c-22.1 0-40-17.9-40-40s17.9-40 40-40c19.9 0 34.6 3.3 86.1 80h-86.1zm206.1 0h-86.1c51.4-76.5 65.7-80 86.1-80 22.1 0 40 17.9 40 40s-17.9 40-40 40zm-72 320h160c17.7 0 32-14.3 32-32V320H288v160z"],"glass-martini":[512,512,[],"f000","M507.3 27.3c10-10 2.9-27.3-11.3-27.3H16C1.8 0-5.4 17.2 4.7 27.3L216 238.6V472h-92c-15.5 0-28 12.5-28 28 0 6.6 5.4 12 12 12h296c6.6 0 12-5.4 12-12 0-15.5-12.5-28-28-28h-92V238.6L507.3 27.3z"],globe:[496,512,[],"f0ac","M336.5 160C322 70.7 287.8 8 248 8s-74 62.7-88.5 152h177zM152 256c0 22.2 1.2 43.5 3.3 64h185.3c2.1-20.5 3.3-41.8 3.3-64s-1.2-43.5-3.3-64H155.3c-2.1 20.5-3.3 41.8-3.3 64zm324.7-96c-28.6-67.9-86.5-120.4-158-141.6 24.4 33.8 41.2 84.7 50 141.6h108zM177.2 18.4C105.8 39.6 47.8 92.1 19.3 160h108c8.7-56.9 25.5-107.8 49.9-141.6zM487.4 192H372.7c2.1 21 3.3 42.5 3.3 64s-1.2 43-3.3 64h114.6c5.5-20.5 8.6-41.8 8.6-64s-3.1-43.5-8.5-64zM120 256c0-21.5 1.2-43 3.3-64H8.6C3.2 212.5 0 233.8 0 256s3.2 43.5 8.6 64h114.6c-2-21-3.2-42.5-3.2-64zm39.5 96c14.5 89.3 48.7 152 88.5 152s74-62.7 88.5-152h-177zm159.3 141.6c71.4-21.2 129.4-73.7 158-141.6h-108c-8.8 56.9-25.6 107.8-50 141.6zM19.3 352c28.6 67.9 86.5 120.4 158 141.6-24.4-33.8-41.2-84.7-50-141.6h-108z"],"golf-ball":[416,512,[],"f450","M96 416h224c0 17.7-14.3 32-32 32h-16c-17.7 0-32 14.3-32 32v20c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-20c0-17.7-14.3-32-32-32h-16c-17.7 0-32-14.3-32-32zm320-208c0 74.2-39 139.2-97.5 176h-221C39 347.2 0 282.2 0 208 0 93.1 93.1 0 208 0s208 93.1 208 208zm-180.1 43.9c18.3 0 33.1-14.8 33.1-33.1 0-14.4-9.3-26.3-22.1-30.9 9.6 26.8-15.6 51.3-41.9 41.9 4.6 12.8 16.5 22.1 30.9 22.1zm49.1 46.9c0-14.4-9.3-26.3-22.1-30.9 9.6 26.8-15.6 51.3-41.9 41.9 4.6 12.8 16.5 22.1 30.9 22.1 18.3 0 33.1-14.9 33.1-33.1zm64-64c0-14.4-9.3-26.3-22.1-30.9 9.6 26.8-15.6 51.3-41.9 41.9 4.6 12.8 16.5 22.1 30.9 22.1 18.3 0 33.1-14.9 33.1-33.1z"],"graduation-cap":[640,512,[],"f19d","M622.884 199.005l-275.817 85.1a96 96 0 0 1-54.134 0L92.398 222.232c-8.564 11.438-11.018 23.05-11.918 38.335C89.778 266.165 96 276.355 96 288c0 11.952-6.557 22.366-16.265 27.861l16.197 123.096c.63 4.786-3.1 9.043-7.932 9.043H40c-4.828 0-8.562-4.253-7.932-9.044L48.265 315.86C38.557 310.366 32 299.952 32 288c0-12.034 6.646-22.511 16.465-27.976.947-17.951 3.974-33.231 12.152-47.597l-43.502-13.422c-22.876-6.801-22.766-39.241 0-46.01l275.817-85.1a96 96 0 0 1 54.134 0l275.817 85.1c22.877 6.801 22.767 39.241.001 46.01zM356.503 314.682l-.207.064-.207.061a127.998 127.998 0 0 1-72.177 0l-.207-.061-.207-.064-150.914-46.57L120 352c0 35.346 89.543 64 200 64s200-28.654 200-64l-12.583-83.888-150.914 46.57z"],"h-square":[448,512,[],"f0fd","M448 80v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48zm-112 48h-32c-8.837 0-16 7.163-16 16v80H160v-80c0-8.837-7.163-16-16-16h-32c-8.837 0-16 7.163-16 16v224c0 8.837 7.163 16 16 16h32c8.837 0 16-7.163 16-16v-80h128v80c0 8.837 7.163 16 16 16h32c8.837 0 16-7.163 16-16V144c0-8.837-7.163-16-16-16z"],"hand-holding":[576,512,[],"f4bd","M565.3 328.1c-11.8-10.7-30.2-10-42.6 0L430.3 402c-11.3 9.1-25.4 14-40 14H272c-8.8 0-16-7.2-16-16s7.2-16 16-16h78.3c15.9 0 30.7-10.9 33.3-26.6 3.3-20-12.1-37.4-31.6-37.4H192c-27 0-53.1 9.3-74.1 26.3L71.4 384H16c-8.8 0-16 7.2-16 16v96c0 8.8 7.2 16 16 16h356.8c14.5 0 28.6-4.9 40-14L564 377c15.2-12.1 16.4-35.3 1.3-48.9z"],"hand-holding-heart":[576,512,[],"f4be","M275.3 250.5c7 7.4 18.4 7.4 25.5 0l108.9-114.2c31.6-33.2 29.8-88.2-5.6-118.8-30.8-26.7-76.7-21.9-104.9 7.7L288 36.9l-11.1-11.6C248.7-4.4 202.8-9.2 172 17.5c-35.3 30.6-37.2 85.6-5.6 118.8l108.9 114.2zm290 77.6c-11.8-10.7-30.2-10-42.6 0L430.3 402c-11.3 9.1-25.4 14-40 14H272c-8.8 0-16-7.2-16-16s7.2-16 16-16h78.3c15.9 0 30.7-10.9 33.3-26.6 3.3-20-12.1-37.4-31.6-37.4H192c-27 0-53.1 9.3-74.1 26.3L71.4 384H16c-8.8 0-16 7.2-16 16v96c0 8.8 7.2 16 16 16h356.8c14.5 0 28.6-4.9 40-14L564 377c15.2-12.1 16.4-35.3 1.3-48.9z"],"hand-holding-usd":[544,512,[],"f4c0","M257.6 144.3l50 14.3c3.6 1 6.1 4.4 6.1 8.1 0 4.6-3.8 8.4-8.4 8.4h-32.8c-3.6 0-7.1-.8-10.3-2.2-4.8-2.2-10.4-1.7-14.1 2l-17.5 17.5c-5.3 5.3-4.7 14.3 1.5 18.4 9.5 6.3 20.3 10.1 31.8 11.5V240c0 8.8 7.2 16 16 16h16c8.8 0 16-7.2 16-16v-17.6c30.3-3.6 53.3-31 49.3-63-2.9-23-20.7-41.3-42.9-47.7l-50-14.3c-3.6-1-6.1-4.4-6.1-8.1 0-4.6 3.8-8.4 8.4-8.4h32.8c3.6 0 7.1.8 10.3 2.2 4.8 2.2 10.4 1.7 14.1-2l17.5-17.5c5.3-5.3 4.7-14.3-1.5-18.4-9.5-6.3-20.3-10.1-31.8-11.5V16c0-8.8-7.2-16-16-16h-16c-8.8 0-16 7.2-16 16v17.6c-30.3 3.6-53.3 31-49.3 63 2.9 23 20.7 41.3 42.9 47.7zm276.3 183.8c-11.2-10.7-28.5-10-40.3 0L406.4 402c-10.7 9.1-24 14-37.8 14H256.9c-8.3 0-15.1-7.2-15.1-16s6.8-16 15.1-16h73.9c15.1 0 29-10.9 31.4-26.6 3.1-20-11.5-37.4-29.8-37.4H181.3c-25.5 0-50.2 9.3-69.9 26.3L67.5 384H15.1C6.8 384 0 391.2 0 400v96c0 8.8 6.8 16 15.1 16H352c13.7 0 27-4.9 37.8-14l142.8-121c14.4-12.1 15.5-35.3 1.3-48.9z"],"hand-lizard":[576,512,[],"f258","M384 480h192V363.778a95.998 95.998 0 0 0-14.833-51.263L398.127 54.368A48 48 0 0 0 357.544 32H24C10.745 32 0 42.745 0 56v16c0 30.928 25.072 56 56 56h229.981c12.844 0 21.556 13.067 16.615 24.923l-21.41 51.385A32 32 0 0 1 251.648 224H128c-35.346 0-64 28.654-64 64v8c0 13.255 10.745 24 24 24h147.406a47.995 47.995 0 0 1 25.692 7.455l111.748 70.811A24.001 24.001 0 0 1 384 418.539V480z"],"hand-paper":[448,512,[],"f256","M408.781 128.007C386.356 127.578 368 146.36 368 168.79V256h-8V79.79c0-22.43-18.356-41.212-40.781-40.783C297.488 39.423 280 57.169 280 79v177h-8V40.79C272 18.36 253.644-.422 231.219.007 209.488.423 192 18.169 192 40v216h-8V80.79c0-22.43-18.356-41.212-40.781-40.783C121.488 40.423 104 58.169 104 80v235.992l-31.648-43.519c-12.993-17.866-38.009-21.817-55.877-8.823-17.865 12.994-21.815 38.01-8.822 55.877l125.601 172.705A48 48 0 0 0 172.073 512h197.59c22.274 0 41.622-15.324 46.724-37.006l26.508-112.66a192.011 192.011 0 0 0 5.104-43.975V168c.001-21.831-17.487-39.577-39.218-39.993z"],"hand-peace":[448,512,[],"f25b","M408 216c-22.092 0-40 17.909-40 40h-8v-32c0-22.091-17.908-40-40-40s-40 17.909-40 40v32h-8V48c0-26.51-21.49-48-48-48s-48 21.49-48 48v208h-13.572L92.688 78.449C82.994 53.774 55.134 41.63 30.461 51.324 5.787 61.017-6.356 88.877 3.337 113.551l74.765 190.342-31.09 24.872c-15.381 12.306-19.515 33.978-9.741 51.081l64 112A39.998 39.998 0 0 0 136 512h240c18.562 0 34.686-12.77 38.937-30.838l32-136A39.97 39.97 0 0 0 448 336v-80c0-22.091-17.908-40-40-40z"],"hand-point-down":[384,512,[],"f0a7","M91.826 467.2V317.966c-8.248 5.841-16.558 10.57-24.918 14.153C35.098 345.752-.014 322.222 0 288c.008-18.616 10.897-32.203 29.092-40 28.286-12.122 64.329-78.648 77.323-107.534 7.956-17.857 25.479-28.453 43.845-28.464l.001-.002h171.526c11.812 0 21.897 8.596 23.703 20.269 7.25 46.837 38.483 61.76 38.315 123.731-.007 2.724.195 13.254.195 16 0 50.654-22.122 81.574-71.263 72.6-9.297 18.597-39.486 30.738-62.315 16.45-21.177 24.645-53.896 22.639-70.944 6.299V467.2c0 24.15-20.201 44.8-43.826 44.8-23.283 0-43.826-21.35-43.826-44.8zM112 72V24c0-13.255 10.745-24 24-24h192c13.255 0 24 10.745 24 24v48c0 13.255-10.745 24-24 24H136c-13.255 0-24-10.745-24-24zm212-24c0-11.046-8.954-20-20-20s-20 8.954-20 20 8.954 20 20 20 20-8.954 20-20z"],"hand-point-left":[512,512,[],"f0a5","M44.8 155.826h149.234c-5.841-8.248-10.57-16.558-14.153-24.918C166.248 99.098 189.778 63.986 224 64c18.616.008 32.203 10.897 40 29.092 12.122 28.286 78.648 64.329 107.534 77.323 17.857 7.956 28.453 25.479 28.464 43.845l.002.001v171.526c0 11.812-8.596 21.897-20.269 23.703-46.837 7.25-61.76 38.483-123.731 38.315-2.724-.007-13.254.195-16 .195-50.654 0-81.574-22.122-72.6-71.263-18.597-9.297-30.738-39.486-16.45-62.315-24.645-21.177-22.639-53.896-6.299-70.944H44.8c-24.15 0-44.8-20.201-44.8-43.826 0-23.283 21.35-43.826 44.8-43.826zM440 176h48c13.255 0 24 10.745 24 24v192c0 13.255-10.745 24-24 24h-48c-13.255 0-24-10.745-24-24V200c0-13.255 10.745-24 24-24zm24 212c11.046 0 20-8.954 20-20s-8.954-20-20-20-20 8.954-20 20 8.954 20 20 20z"],"hand-point-right":[512,512,[],"f0a4","M512 199.652c0 23.625-20.65 43.826-44.8 43.826h-99.851c16.34 17.048 18.346 49.766-6.299 70.944 14.288 22.829 2.147 53.017-16.45 62.315C353.574 425.878 322.654 448 272 448c-2.746 0-13.276-.203-16-.195-61.971.168-76.894-31.065-123.731-38.315C120.596 407.683 112 397.599 112 385.786V214.261l.002-.001c.011-18.366 10.607-35.889 28.464-43.845 28.886-12.994 95.413-49.038 107.534-77.323 7.797-18.194 21.384-29.084 40-29.092 34.222-.014 57.752 35.098 44.119 66.908-3.583 8.359-8.312 16.67-14.153 24.918H467.2c23.45 0 44.8 20.543 44.8 43.826zM96 200v192c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V200c0-13.255 10.745-24 24-24h48c13.255 0 24 10.745 24 24zM68 368c0-11.046-8.954-20-20-20s-20 8.954-20 20 8.954 20 20 20 20-8.954 20-20z"],"hand-point-up":[384,512,[],"f0a6","M135.652 0c23.625 0 43.826 20.65 43.826 44.8v99.851c17.048-16.34 49.766-18.346 70.944 6.299 22.829-14.288 53.017-2.147 62.315 16.45C361.878 158.426 384 189.346 384 240c0 2.746-.203 13.276-.195 16 .168 61.971-31.065 76.894-38.315 123.731C343.683 391.404 333.599 400 321.786 400H150.261l-.001-.002c-18.366-.011-35.889-10.607-43.845-28.464C93.421 342.648 57.377 276.122 29.092 264 10.897 256.203.008 242.616 0 224c-.014-34.222 35.098-57.752 66.908-44.119 8.359 3.583 16.67 8.312 24.918 14.153V44.8c0-23.45 20.543-44.8 43.826-44.8zM136 416h192c13.255 0 24 10.745 24 24v48c0 13.255-10.745 24-24 24H136c-13.255 0-24-10.745-24-24v-48c0-13.255 10.745-24 24-24zm168 28c-11.046 0-20 8.954-20 20s8.954 20 20 20 20-8.954 20-20-8.954-20-20-20z"],"hand-pointer":[448,512,[],"f25a","M448 240v96c0 3.084-.356 6.159-1.063 9.162l-32 136C410.686 499.23 394.562 512 376 512H168a40.004 40.004 0 0 1-32.35-16.473l-127.997-176c-12.993-17.866-9.043-42.883 8.822-55.876 17.867-12.994 42.884-9.043 55.877 8.823L104 315.992V40c0-22.091 17.908-40 40-40s40 17.909 40 40v200h8v-40c0-22.091 17.908-40 40-40s40 17.909 40 40v40h8v-24c0-22.091 17.908-40 40-40s40 17.909 40 40v24h8c0-22.091 17.908-40 40-40s40 17.909 40 40zm-256 80h-8v96h8v-96zm88 0h-8v96h8v-96zm88 0h-8v96h8v-96z"],"hand-rock":[512,512,[],"f255","M512 128.79c0-26.322-20.861-48.344-47.18-48.783C437.935 79.558 416 101.217 416 128h-8V96.79c0-26.322-20.861-48.344-47.18-48.783C333.935 47.558 312 69.217 312 96v32h-8V80.79c0-26.322-20.861-48.344-47.18-48.783C229.935 31.558 208 53.217 208 80v48h-8V96.79c0-26.322-20.861-48.344-47.18-48.783C125.935 47.558 104 69.217 104 96v136l-8-7.111V176.79c0-26.322-20.861-48.344-47.18-48.783C21.935 127.558 0 149.217 0 176v66.445a95.998 95.998 0 0 0 32.221 71.751l111.668 99.261A47.999 47.999 0 0 1 160 449.333V456c0 13.255 10.745 24 24 24h240c13.255 0 24-10.745 24-24v-2.921a96.01 96.01 0 0 1 7.523-37.254l48.954-116.265A96.002 96.002 0 0 0 512 262.306V128.79z"],"hand-scissors":[512,512,[],"f257","M216 440c0-22.092 17.909-40 40-40v-8h-32c-22.091 0-40-17.908-40-40s17.909-40 40-40h32v-8H48c-26.51 0-48-21.49-48-48s21.49-48 48-48h208v-13.572l-177.551-69.74c-24.674-9.694-36.818-37.555-27.125-62.228 9.693-24.674 37.554-36.817 62.228-27.124l190.342 74.765 24.872-31.09c12.306-15.381 33.978-19.515 51.081-9.741l112 64A40.002 40.002 0 0 1 512 168v240c0 18.562-12.77 34.686-30.838 38.937l-136 32A39.982 39.982 0 0 1 336 480h-80c-22.091 0-40-17.908-40-40z"],"hand-spock":[512,512,[],"f259","M10.872 316.585c15.139-16.086 40.454-16.854 56.543-1.713L128 371.893v-79.405L88.995 120.865c-4.896-21.542 8.598-42.974 30.14-47.87 21.549-4.894 42.975 8.599 47.87 30.141L201.747 256h9.833L164.016 48.966c-4.946-21.531 8.498-42.994 30.028-47.94 21.532-4.95 42.994 8.498 47.94 30.028L293.664 256h15.105l48.425-193.702c5.357-21.432 27.075-34.462 48.507-29.104 21.432 5.358 34.463 27.075 29.104 48.507L391.231 256h11.08l30.768-129.265c5.117-21.491 26.685-34.768 48.177-29.647 21.491 5.117 34.765 26.686 29.647 48.177l-36.292 152.467A96.024 96.024 0 0 0 472 319.967v42.102a96.002 96.002 0 0 1-3.96 27.287l-26.174 88.287C435.825 498.022 417.101 512 395.846 512H179.172a48.002 48.002 0 0 1-32.898-13.046L12.585 373.128c-16.087-15.141-16.853-40.456-1.713-56.543z"],hands:[640,512,[],"f4c2","M204.8 230.4c-10.6-14.1-30.7-17-44.8-6.4-14.1 10.6-17 30.7-6.4 44.8l38.1 50.8c4.8 6.4 4.1 15.3-1.5 20.9l-12.8 12.8c-6.7 6.7-17.6 6.2-23.6-1.1L64 244.4V96c0-17.7-14.3-32-32-32S0 78.3 0 96v218.4c0 10.9 3.7 21.5 10.5 30l104.1 134.3c5 6.5 8.4 13.9 10.4 21.7 1.8 6.9 8.1 11.6 15.3 11.6H272c8.8 0 16-7.2 16-16V384c0-27.7-9-54.6-25.6-76.8l-57.6-76.8zM608 64c-17.7 0-32 14.3-32 32v148.4l-89.8 107.8c-6 7.2-17 7.7-23.6 1.1l-12.8-12.8c-5.6-5.6-6.3-14.5-1.5-20.9l38.1-50.8c10.6-14.1 7.7-34.2-6.4-44.8-14.1-10.6-34.2-7.7-44.8 6.4l-57.6 76.8C361 329.4 352 356.3 352 384v112c0 8.8 7.2 16 16 16h131.7c7.1 0 13.5-4.7 15.3-11.6 2-7.8 5.4-15.2 10.4-21.7l104.1-134.3c6.8-8.5 10.5-19.1 10.5-30V96c0-17.7-14.3-32-32-32z"],"hands-helping":[640,512,[],"f4c4","M488 192H336v56c0 39.7-32.3 72-72 72s-72-32.3-72-72V126.4l-64.9 39C107.8 176.9 96 197.8 96 220.2v47.3l-80 46.2C.7 322.5-4.6 342.1 4.3 357.4l80 138.6c8.8 15.3 28.4 20.5 43.7 11.7L231.4 448H368c35.3 0 64-28.7 64-64h16c17.7 0 32-14.3 32-32v-64h8c13.3 0 24-10.7 24-24v-48c0-13.3-10.7-24-24-24zm147.7-37.4L555.7 16C546.9.7 527.3-4.5 512 4.3L408.6 64H306.4c-12 0-23.7 3.4-33.9 9.7L239 94.6c-9.4 5.8-15 16.1-15 27.1V248c0 22.1 17.9 40 40 40s40-17.9 40-40v-88h184c30.9 0 56 25.1 56 56v28.5l80-46.2c15.3-8.9 20.5-28.4 11.7-43.7z"],handshake:[640,512,[],"f2b5","M434.7 64h-85.9c-8 0-15.7 3-21.6 8.4l-98.3 90c-.1.1-.2.3-.3.4-16.6 15.6-16.3 40.5-2.1 56 12.7 13.9 39.4 17.6 56.1 2.7.1-.1.3-.1.4-.2l79.9-73.2c6.5-5.9 16.7-5.5 22.6 1 6 6.5 5.5 16.6-1 22.6l-26.1 23.9L504 313.8c2.9 2.4 5.5 5 7.9 7.7V128l-54.6-54.6c-5.9-6-14.1-9.4-22.6-9.4zM544 128.2v223.9c0 17.7 14.3 32 32 32h64V128.2h-96zm48 223.9c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16zM0 384h64c17.7 0 32-14.3 32-32V128.2H0V384zm48-63.9c8.8 0 16 7.2 16 16s-7.2 16-16 16-16-7.2-16-16c0-8.9 7.2-16 16-16zm435.9 18.6L334.6 217.5l-30 27.5c-29.7 27.1-75.2 24.5-101.7-4.4-26.9-29.4-24.8-74.9 4.4-101.7L289.1 64h-83.8c-8.5 0-16.6 3.4-22.6 9.4L128 128v223.9h18.3l90.5 81.9c27.4 22.3 67.7 18.1 90-9.3l.2-.2 17.9 15.5c15.9 13 39.4 10.5 52.3-5.4l31.4-38.6 5.4 4.4c13.7 11.1 33.9 9.1 45-4.7l9.5-11.7c11.2-13.8 9.1-33.9-4.6-45.1z"],hashtag:[448,512,[],"f292","M440.667 182.109l7.143-40c1.313-7.355-4.342-14.109-11.813-14.109h-74.81l14.623-81.891C377.123 38.754 371.468 32 363.997 32h-40.632a12 12 0 0 0-11.813 9.891L296.175 128H197.54l14.623-81.891C213.477 38.754 207.822 32 200.35 32h-40.632a12 12 0 0 0-11.813 9.891L132.528 128H53.432a12 12 0 0 0-11.813 9.891l-7.143 40C33.163 185.246 38.818 192 46.289 192h74.81L98.242 320H19.146a12 12 0 0 0-11.813 9.891l-7.143 40C-1.123 377.246 4.532 384 12.003 384h74.81L72.19 465.891C70.877 473.246 76.532 480 84.003 480h40.632a12 12 0 0 0 11.813-9.891L151.826 384h98.634l-14.623 81.891C234.523 473.246 240.178 480 247.65 480h40.632a12 12 0 0 0 11.813-9.891L315.472 384h79.096a12 12 0 0 0 11.813-9.891l7.143-40c1.313-7.355-4.342-14.109-11.813-14.109h-74.81l22.857-128h79.096a12 12 0 0 0 11.813-9.891zM261.889 320h-98.634l22.857-128h98.634l-22.857 128z"],hdd:[576,512,[],"f0a0","M576 304v96c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48v-96c0-26.51 21.49-48 48-48h480c26.51 0 48 21.49 48 48zm-48-80a79.557 79.557 0 0 1 30.777 6.165L462.25 85.374A48.003 48.003 0 0 0 422.311 64H153.689a48 48 0 0 0-39.938 21.374L17.223 230.165A79.557 79.557 0 0 1 48 224h480zm-48 96c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm-96 0c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32z"],heading:[512,512,[],"f1dc","M496 80V48c0-8.837-7.163-16-16-16H320c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h37.621v128H154.379V96H192c8.837 0 16-7.163 16-16V48c0-8.837-7.163-16-16-16H32c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h37.275v320H32c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h160c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16h-37.621V288H357.62v128H320c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h160c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16h-37.275V96H480c8.837 0 16-7.163 16-16z"],headphones:[512,512,[],"f025","M256 32C114.52 32 0 146.496 0 288v48a32 32 0 0 0 17.689 28.622l14.383 7.191C34.083 431.903 83.421 480 144 480h24c13.255 0 24-10.745 24-24V280c0-13.255-10.745-24-24-24h-24c-31.342 0-59.671 12.879-80 33.627V288c0-105.869 86.131-192 192-192s192 86.131 192 192v1.627C427.671 268.879 399.342 256 368 256h-24c-13.255 0-24 10.745-24 24v176c0 13.255 10.745 24 24 24h24c60.579 0 109.917-48.098 111.928-108.187l14.382-7.191A32 32 0 0 0 512 336v-48c0-141.479-114.496-256-256-256z"],heart:[512,512,[],"f004","M462.3 62.6C407.5 15.9 326 24.3 275.7 76.2L256 96.5l-19.7-20.3C186.1 24.3 104.5 15.9 49.7 62.6c-62.8 53.6-66.1 149.8-9.9 207.9l193.5 199.8c12.5 12.9 32.8 12.9 45.3 0l193.5-199.8c56.3-58.1 53-154.3-9.8-207.9z"],heartbeat:[512,512,[],"f21e","M320.2 243.8l-49.7 99.4c-6 12.1-23.4 11.7-28.9-.6l-56.9-126.3-30 71.7H60.6l182.5 186.5c7.1 7.3 18.6 7.3 25.7 0L451.4 288H342.3l-22.1-44.2zM473.7 73.9l-2.4-2.5c-51.5-52.6-135.8-52.6-187.4 0L256 100l-27.9-28.5c-51.5-52.7-135.9-52.7-187.4 0l-2.4 2.4C-10.4 123.7-12.5 203 31 256h102.4l35.9-86.2c5.4-12.9 23.6-13.2 29.4-.4l58.2 129.3 49-97.9c5.9-11.8 22.7-11.8 28.6 0l27.6 55.2H481c43.5-53 41.4-132.3-7.3-182.1z"],history:[512,512,[],"f1da","M504 255.531c.253 136.64-111.18 248.372-247.82 248.468-59.015.042-113.223-20.53-155.822-54.911-11.077-8.94-11.905-25.541-1.839-35.607l11.267-11.267c8.609-8.609 22.353-9.551 31.891-1.984C173.062 425.135 212.781 440 256 440c101.705 0 184-82.311 184-184 0-101.705-82.311-184-184-184-48.814 0-93.149 18.969-126.068 49.932l50.754 50.754c10.08 10.08 2.941 27.314-11.313 27.314H24c-8.837 0-16-7.163-16-16V38.627c0-14.254 17.234-21.393 27.314-11.314l49.372 49.372C129.209 34.136 189.552 8 256 8c136.81 0 247.747 110.78 248 247.531zm-180.912 78.784l9.823-12.63c8.138-10.463 6.253-25.542-4.21-33.679L288 256.349V152c0-13.255-10.745-24-24-24h-16c-13.255 0-24 10.745-24 24v135.651l65.409 50.874c10.463 8.137 25.541 6.253 33.679-4.21z"],"hockey-puck":[512,512,[],"f453","M0 160c0-53 114.6-96 256-96s256 43 256 96-114.6 96-256 96S0 213 0 160zm0 82.2V352c0 53 114.6 96 256 96s256-43 256-96V242.2c-113.4 82.3-398.5 82.4-512 0z"],home:[576,512,[],"f015","M488 312.7V456c0 13.3-10.7 24-24 24H348c-6.6 0-12-5.4-12-12V356c0-6.6-5.4-12-12-12h-72c-6.6 0-12 5.4-12 12v112c0 6.6-5.4 12-12 12H112c-13.3 0-24-10.7-24-24V312.7c0-3.6 1.6-7 4.4-9.3l188-154.8c4.4-3.6 10.8-3.6 15.3 0l188 154.8c2.7 2.3 4.3 5.7 4.3 9.3zm83.6-60.9L488 182.9V44.4c0-6.6-5.4-12-12-12h-56c-6.6 0-12 5.4-12 12V117l-89.5-73.7c-17.7-14.6-43.3-14.6-61 0L4.4 251.8c-5.1 4.2-5.8 11.8-1.6 16.9l25.5 31c4.2 5.1 11.8 5.8 16.9 1.6l235.2-193.7c4.4-3.6 10.8-3.6 15.3 0l235.2 193.7c5.1 4.2 12.7 3.5 16.9-1.6l25.5-31c4.2-5.2 3.4-12.7-1.7-16.9z"],hospital:[448,512,[],"f0f8","M448 492v20H0v-20c0-6.627 5.373-12 12-12h20V120c0-13.255 10.745-24 24-24h88V24c0-13.255 10.745-24 24-24h112c13.255 0 24 10.745 24 24v72h88c13.255 0 24 10.745 24 24v360h20c6.627 0 12 5.373 12 12zM308 192h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12zm-168 64h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12zm104 128h-40c-6.627 0-12 5.373-12 12v84h64v-84c0-6.627-5.373-12-12-12zm64-96h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12zm-116 12c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40zM182 96h26v26a6 6 0 0 0 6 6h20a6 6 0 0 0 6-6V96h26a6 6 0 0 0 6-6V70a6 6 0 0 0-6-6h-26V38a6 6 0 0 0-6-6h-20a6 6 0 0 0-6 6v26h-26a6 6 0 0 0-6 6v20a6 6 0 0 0 6 6z"],"hospital-alt":[576,512,[],"f47d","M544 96H416V32c0-17.7-14.3-32-32-32H192c-17.7 0-32 14.3-32 32v64H32c-17.7 0-32 14.3-32 32v368c0 8.8 7.2 16 16 16h544c8.8 0 16-7.2 16-16V128c0-17.7-14.3-32-32-32zM160 436c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-128c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm160 128c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-128c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm16-170c0 3.3-2.7 6-6 6h-26v26c0 3.3-2.7 6-6 6h-20c-3.3 0-6-2.7-6-6v-26h-26c-3.3 0-6-2.7-6-6v-20c0-3.3 2.7-6 6-6h26V86c0-3.3 2.7-6 6-6h20c3.3 0 6 2.7 6 6v26h26c3.3 0 6 2.7 6 6v20zm144 298c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-128c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40z"],"hospital-symbol":[512,512,[],"f47e","M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256 256-114.6 256-256S397.4 0 256 0zm112 376c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8v-88h-96v88c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V136c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v88h96v-88c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v240z"],hourglass:[384,512,[],"f254","M360 64c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24 0 90.965 51.016 167.734 120.842 192C75.016 280.266 24 357.035 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24 0-90.965-51.016-167.734-120.842-192C308.984 231.734 360 154.965 360 64z"],"hourglass-end":[384,512,[],"f253","M360 64c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24 0 90.965 51.016 167.734 120.842 192C75.016 280.266 24 357.035 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24 0-90.965-51.016-167.734-120.842-192C308.984 231.734 360 154.965 360 64zM192 208c-57.787 0-104-66.518-104-144h208c0 77.945-46.51 144-104 144z"],"hourglass-half":[384,512,[],"f252","M360 0H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24 0 90.965 51.016 167.734 120.842 192C75.016 280.266 24 357.035 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24 0-90.965-51.016-167.734-120.842-192C308.984 231.734 360 154.965 360 64c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24zm-75.078 384H99.08c17.059-46.797 52.096-80 92.92-80 40.821 0 75.862 33.196 92.922 80zm.019-256H99.078C91.988 108.548 88 86.748 88 64h208c0 22.805-3.987 44.587-11.059 64z"],"hourglass-start":[384,512,[],"f251","M360 0H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24 0 90.965 51.016 167.734 120.842 192C75.016 280.266 24 357.035 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24 0-90.965-51.016-167.734-120.842-192C308.984 231.734 360 154.965 360 64c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24zm-64 448H88c0-77.458 46.204-144 104-144 57.786 0 104 66.517 104 144z"],"i-cursor":[256,512,[],"f246","M256 52.048V12.065C256 5.496 250.726.148 244.158.066 211.621-.344 166.469.011 128 37.959 90.266.736 46.979-.114 11.913.114 5.318.157 0 5.519 0 12.114v39.645c0 6.687 5.458 12.078 12.145 11.998C38.111 63.447 96 67.243 96 112.182V224H60c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h36v112c0 44.932-56.075 48.031-83.95 47.959C5.404 447.942 0 453.306 0 459.952v39.983c0 6.569 5.274 11.917 11.842 11.999 32.537.409 77.689.054 116.158-37.894 37.734 37.223 81.021 38.073 116.087 37.845 6.595-.043 11.913-5.405 11.913-12V460.24c0-6.687-5.458-12.078-12.145-11.998C217.889 448.553 160 444.939 160 400V288h36c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-36V112.182c0-44.932 56.075-48.213 83.95-48.142 6.646.018 12.05-5.346 12.05-11.992z"],"id-badge":[384,512,[],"f2c1","M336 0H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V48c0-26.51-21.49-48-48-48zM128 44c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12H140c-6.627 0-12-5.373-12-12v-8zm64 116c44.183 0 80 35.817 80 80s-35.817 80-80 80-80-35.817-80-80 35.817-80 80-80zm128 232c0 13.255-10.745 24-24 24H88c-13.255 0-24-10.745-24-24v-18.523c0-22.026 14.99-41.225 36.358-46.567l35.656-8.914c29.101 20.932 74.509 26.945 111.97 0l35.656 8.914c21.37 5.342 36.36 24.542 36.36 46.567V392z"],"id-card":[512,512,[],"f2c2","M464 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zM256 350c0 9.941-8.059 18-18 18H82c-9.941 0-18-8.059-18-18v-13.892c0-16.519 11.243-30.919 27.269-34.925l26.742-6.686c21.826 15.699 55.882 20.209 83.978 0l26.743 6.686C244.757 305.189 256 319.589 256 336.108V350zM100 236c0-33.137 26.863-60 60-60s60 26.863 60 60-26.863 60-60 60-60-26.863-60-60zm348 104c0 6.627-5.373 12-12 12H300c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h136c6.627 0 12 5.373 12 12v8zm0-64c0 6.627-5.373 12-12 12H300c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h136c6.627 0 12 5.373 12 12v8zm0-64c0 6.627-5.373 12-12 12H300c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h136c6.627 0 12 5.373 12 12v8zm32-96c0 6.627-5.373 12-12 12H44c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v8z"],"id-card-alt":[576,512,[],"f47f","M512 64H384v96H192V64H64C28.7 64 0 92.7 0 128v320c0 35.3 28.7 64 64 64h96v-10.7c0-47.1 38.2-85.3 85.3-85.3h85.3c47.1 0 85.3 38.2 85.3 85.3V512h96c35.3 0 64-28.7 64-64V128c.1-35.3-28.6-64-63.9-64zM288 384c-44.2 0-80-35.8-80-80s35.8-80 80-80 80 35.8 80 80-35.8 80-80 80zm64-352c0-17.7-14.3-32-32-32h-64c-17.7 0-32 14.3-32 32v96h128V32z"],image:[512,512,[],"f03e","M464 448H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48zM112 120c-30.928 0-56 25.072-56 56s25.072 56 56 56 56-25.072 56-56-25.072-56-56-56zM64 384h384V272l-87.515-87.515c-4.686-4.686-12.284-4.686-16.971 0L208 320l-55.515-55.515c-4.686-4.686-12.284-4.686-16.971 0L64 336v48z"],images:[576,512,[],"f302","M480 416v16c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V176c0-26.51 21.49-48 48-48h16v208c0 44.112 35.888 80 80 80h336zm96-80V80c0-26.51-21.49-48-48-48H144c-26.51 0-48 21.49-48 48v256c0 26.51 21.49 48 48 48h384c26.51 0 48-21.49 48-48zM256 128c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-96 144l55.515-55.515c4.686-4.686 12.284-4.686 16.971 0L272 256l135.515-135.515c4.686-4.686 12.284-4.686 16.971 0L512 208v112H160v-48z"],inbox:[576,512,[],"f01c","M567.938 243.908L462.25 85.374A48.003 48.003 0 0 0 422.311 64H153.689a48 48 0 0 0-39.938 21.374L8.062 243.908A47.994 47.994 0 0 0 0 270.533V400c0 26.51 21.49 48 48 48h480c26.51 0 48-21.49 48-48V270.533a47.994 47.994 0 0 0-8.062-26.625zM162.252 128h251.497l85.333 128H376l-32 64H232l-32-64H76.918l85.334-128z"],indent:[448,512,[],"f03c","M0 84V44c0-8.837 7.163-16 16-16h416c8.837 0 16 7.163 16 16v40c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16zm176 144h256c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H176c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zM16 484h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm160-128h256c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H176c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm-52.687-111.313l-96-95.984C17.266 138.652 0 145.776 0 160.016v191.975c0 14.329 17.325 21.304 27.313 11.313l96-95.992c6.249-6.247 6.249-16.377 0-22.625z"],industry:[512,512,[],"f275","M475.115 163.781L336 252.309v-68.28c0-18.916-20.931-30.399-36.885-20.248L160 252.309V56c0-13.255-10.745-24-24-24H24C10.745 32 0 42.745 0 56v400c0 13.255 10.745 24 24 24h464c13.255 0 24-10.745 24-24V184.029c0-18.917-20.931-30.399-36.885-20.248z"],info:[192,512,[],"f129","M20 424.229h20V279.771H20c-11.046 0-20-8.954-20-20V212c0-11.046 8.954-20 20-20h112c11.046 0 20 8.954 20 20v212.229h20c11.046 0 20 8.954 20 20V492c0 11.046-8.954 20-20 20H20c-11.046 0-20-8.954-20-20v-47.771c0-11.046 8.954-20 20-20zM96 0C56.235 0 24 32.235 24 72s32.235 72 72 72 72-32.235 72-72S135.764 0 96 0z"],"info-circle":[512,512,[],"f05a","M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z"],italic:[320,512,[],"f033","M204.758 416h-33.849l62.092-320h40.725a16 16 0 0 0 15.704-12.937l6.242-32C297.599 41.184 290.034 32 279.968 32H120.235a16 16 0 0 0-15.704 12.937l-6.242 32C96.362 86.816 103.927 96 113.993 96h33.846l-62.09 320H46.278a16 16 0 0 0-15.704 12.935l-6.245 32C22.402 470.815 29.967 480 40.034 480h158.479a16 16 0 0 0 15.704-12.935l6.245-32c1.927-9.88-5.638-19.065-15.704-19.065z"],key:[512,512,[],"f084","M512 176.001C512 273.203 433.202 352 336 352c-11.22 0-22.19-1.062-32.827-3.069l-24.012 27.014A23.999 23.999 0 0 1 261.223 384H224v40c0 13.255-10.745 24-24 24h-40v40c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24v-78.059c0-6.365 2.529-12.47 7.029-16.971l161.802-161.802C163.108 213.814 160 195.271 160 176 160 78.798 238.797.001 335.999 0 433.488-.001 512 78.511 512 176.001zM336 128c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48-48 21.49-48 48z"],keyboard:[576,512,[],"f11c","M528 448H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h480c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48zM128 180v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-336 96v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-336 96v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm288 0v-40c0-6.627-5.373-12-12-12H172c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h232c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12z"],language:[640,512,[],"f1ab","M304 416H24c-13.255 0-24-10.745-24-24V120c0-13.255 10.745-24 24-24h280v320zm-120.676-72.622A12 12 0 0 0 194.839 352h22.863c8.22 0 14.007-8.078 11.362-15.861L171.61 167.085a12 12 0 0 0-11.362-8.139h-32.489a12.001 12.001 0 0 0-11.362 8.139L58.942 336.139C56.297 343.922 62.084 352 70.304 352h22.805a12 12 0 0 0 11.535-8.693l9.118-31.807h60.211l9.351 31.878zm-39.051-140.42s4.32 21.061 7.83 33.21l10.8 37.531h-38.07l11.07-37.531c3.51-12.15 7.83-33.21 7.83-33.21h.54zM616 416H336V96h280c13.255 0 24 10.745 24 24v272c0 13.255-10.745 24-24 24zm-36-228h-64v-16c0-6.627-5.373-12-12-12h-16c-6.627 0-12 5.373-12 12v16h-64c-6.627 0-12 5.373-12 12v16c0 6.627 5.373 12 12 12h114.106c-6.263 14.299-16.518 28.972-30.023 43.206-6.56-6.898-12.397-13.91-17.365-20.933-3.639-5.144-10.585-6.675-15.995-3.446l-7.28 4.346-6.498 3.879c-5.956 3.556-7.693 11.421-3.735 17.117 6.065 8.729 13.098 17.336 20.984 25.726-8.122 6.226-16.841 12.244-26.103 17.964-5.521 3.41-7.381 10.556-4.162 16.19l7.941 13.896c3.362 5.883 10.935 7.826 16.706 4.276 12.732-7.831 24.571-16.175 35.443-24.891 10.917 8.761 22.766 17.102 35.396 24.881 5.774 3.556 13.353 1.618 16.717-4.27l7.944-13.903c3.213-5.623 1.37-12.76-4.135-16.171a312.737 312.737 0 0 1-26.06-18.019c21.024-22.425 35.768-46.289 42.713-69.85H580c6.627 0 12-5.373 12-12v-16c0-6.625-5.373-11.998-12-11.998z"],laptop:[640,512,[],"f109","M512 64v256H128V64h384m16-64H112C85.5 0 64 21.5 64 48v288c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm100 416H389.5c-3 0-5.5 2.1-5.9 5.1C381.2 436.3 368 448 352 448h-64c-16 0-29.2-11.7-31.6-26.9-.5-2.9-3-5.1-5.9-5.1H12c-6.6 0-12 5.4-12 12v36c0 26.5 21.5 48 48 48h544c26.5 0 48-21.5 48-48v-36c0-6.6-5.4-12-12-12z"],leaf:[576,512,[],"f06c","M546.2 9.7c-5.6-12.5-21.6-13-28.3-1.2C486.9 62.4 431.4 96 368 96h-80C182 96 96 182 96 288c0 7 .8 13.7 1.5 20.5C161.3 262.8 253.4 224 384 224c8.8 0 16 7.2 16 16s-7.2 16-16 16C132.6 256 26 410.1 2.4 468c-6.6 16.3 1.2 34.9 17.5 41.6 16.4 6.8 35-1.1 41.8-17.3 1.5-3.6 20.9-47.9 71.9-90.6 32.4 43.9 94 85.8 174.9 77.2C465.5 467.5 576 326.7 576 154.3c0-50.2-10.8-102.2-29.8-144.6z"],lemon:[512,512,[],"f094","M489.038 22.963C465.944-.13 434.648-5.93 413.947 6.129c-58.906 34.312-181.25-53.077-321.073 86.746S40.441 355.041 6.129 413.945c-12.059 20.702-6.26 51.999 16.833 75.093 23.095 23.095 54.392 28.891 75.095 16.832 58.901-34.31 181.246 53.079 321.068-86.743S471.56 156.96 505.871 98.056c12.059-20.702 6.261-51.999-16.833-75.093zM243.881 95.522c-58.189 14.547-133.808 90.155-148.358 148.358-1.817 7.27-8.342 12.124-15.511 12.124-1.284 0-2.59-.156-3.893-.481-8.572-2.144-13.784-10.83-11.642-19.403C81.901 166.427 166.316 81.93 236.119 64.478c8.575-2.143 17.261 3.069 19.403 11.642s-3.069 17.259-11.641 19.402z"],"level-down-alt":[320,512,[],"f3be","M313.553 392.331L209.587 504.334c-9.485 10.214-25.676 10.229-35.174 0L70.438 392.331C56.232 377.031 67.062 352 88.025 352H152V80H68.024a11.996 11.996 0 0 1-8.485-3.515l-56-56C-4.021 12.926 1.333 0 12.024 0H208c13.255 0 24 10.745 24 24v328h63.966c20.878 0 31.851 24.969 17.587 40.331z"],"level-up-alt":[320,512,[],"f3bf","M313.553 119.669L209.587 7.666c-9.485-10.214-25.676-10.229-35.174 0L70.438 119.669C56.232 134.969 67.062 160 88.025 160H152v272H68.024a11.996 11.996 0 0 0-8.485 3.515l-56 56C-4.021 499.074 1.333 512 12.024 512H208c13.255 0 24-10.745 24-24V160h63.966c20.878 0 31.851-24.969 17.587-40.331z"],"life-ring":[512,512,[],"f1cd","M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm173.696 119.559l-63.399 63.399c-10.987-18.559-26.67-34.252-45.255-45.255l63.399-63.399a218.396 218.396 0 0 1 45.255 45.255zM256 352c-53.019 0-96-42.981-96-96s42.981-96 96-96 96 42.981 96 96-42.981 96-96 96zM127.559 82.304l63.399 63.399c-18.559 10.987-34.252 26.67-45.255 45.255l-63.399-63.399a218.372 218.372 0 0 1 45.255-45.255zM82.304 384.441l63.399-63.399c10.987 18.559 26.67 34.252 45.255 45.255l-63.399 63.399a218.396 218.396 0 0 1-45.255-45.255zm302.137 45.255l-63.399-63.399c18.559-10.987 34.252-26.67 45.255-45.255l63.399 63.399a218.403 218.403 0 0 1-45.255 45.255z"],lightbulb:[384,512,[],"f0eb","M272 428v28c0 10.449-6.68 19.334-16 22.629V488c0 13.255-10.745 24-24 24h-80c-13.255 0-24-10.745-24-24v-9.371c-9.32-3.295-16-12.18-16-22.629v-28c0-6.627 5.373-12 12-12h136c6.627 0 12 5.373 12 12zm-143.107-44c-9.907 0-18.826-6.078-22.376-15.327C67.697 267.541 16 277.731 16 176 16 78.803 94.805 0 192 0s176 78.803 176 176c0 101.731-51.697 91.541-90.516 192.673-3.55 9.249-12.47 15.327-22.376 15.327H128.893zM112 176c0-44.112 35.888-80 80-80 8.837 0 16-7.164 16-16s-7.163-16-16-16c-61.757 0-112 50.243-112 112 0 8.836 7.164 16 16 16s16-7.164 16-16z"],link:[512,512,[],"f0c1","M326.612 185.391c59.747 59.809 58.927 155.698.36 214.59-.11.12-.24.25-.36.37l-67.2 67.2c-59.27 59.27-155.699 59.262-214.96 0-59.27-59.26-59.27-155.7 0-214.96l37.106-37.106c9.84-9.84 26.786-3.3 27.294 10.606.648 17.722 3.826 35.527 9.69 52.721 1.986 5.822.567 12.262-3.783 16.612l-13.087 13.087c-28.026 28.026-28.905 73.66-1.155 101.96 28.024 28.579 74.086 28.749 102.325.51l67.2-67.19c28.191-28.191 28.073-73.757 0-101.83-3.701-3.694-7.429-6.564-10.341-8.569a16.037 16.037 0 0 1-6.947-12.606c-.396-10.567 3.348-21.456 11.698-29.806l21.054-21.055c5.521-5.521 14.182-6.199 20.584-1.731a152.482 152.482 0 0 1 20.522 17.197zM467.547 44.449c-59.261-59.262-155.69-59.27-214.96 0l-67.2 67.2c-.12.12-.25.25-.36.37-58.566 58.892-59.387 154.781.36 214.59a152.454 152.454 0 0 0 20.521 17.196c6.402 4.468 15.064 3.789 20.584-1.731l21.054-21.055c8.35-8.35 12.094-19.239 11.698-29.806a16.037 16.037 0 0 0-6.947-12.606c-2.912-2.005-6.64-4.875-10.341-8.569-28.073-28.073-28.191-73.639 0-101.83l67.2-67.19c28.239-28.239 74.3-28.069 102.325.51 27.75 28.3 26.872 73.934-1.155 101.96l-13.087 13.087c-4.35 4.35-5.769 10.79-3.783 16.612 5.864 17.194 9.042 34.999 9.69 52.721.509 13.906 17.454 20.446 27.294 10.606l37.106-37.106c59.271-59.259 59.271-155.699.001-214.959z"],"lira-sign":[384,512,[],"f195","M371.994 256h-48.019C317.64 256 312 260.912 312 267.246 312 368 230.179 416 144 416V256.781l134.603-29.912A12 12 0 0 0 288 215.155v-40.976c0-7.677-7.109-13.38-14.603-11.714L144 191.219V160.78l134.603-29.912A12 12 0 0 0 288 119.154V78.179c0-7.677-7.109-13.38-14.603-11.714L144 95.219V44c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v68.997L9.397 125.131A12 12 0 0 0 0 136.845v40.976c0 7.677 7.109 13.38 14.603 11.714L64 178.558v30.439L9.397 221.131A12 12 0 0 0 0 232.845v40.976c0 7.677 7.109 13.38 14.603 11.714L64 274.558V468c0 6.627 5.373 12 12 12h79.583c134.091 0 223.255-77.834 228.408-211.592.261-6.782-5.211-12.408-11.997-12.408z"],list:[512,512,[],"f03a","M128 116V76c0-8.837 7.163-16 16-16h352c8.837 0 16 7.163 16 16v40c0 8.837-7.163 16-16 16H144c-8.837 0-16-7.163-16-16zm16 176h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zM16 144h64c8.837 0 16-7.163 16-16V64c0-8.837-7.163-16-16-16H16C7.163 48 0 55.163 0 64v64c0 8.837 7.163 16 16 16zm0 160h64c8.837 0 16-7.163 16-16v-64c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v64c0 8.837 7.163 16 16 16zm0 160h64c8.837 0 16-7.163 16-16v-64c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v64c0 8.837 7.163 16 16 16z"],"list-alt":[512,512,[],"f022","M464 480H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48zM128 120c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm0 96c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm0 96c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm288-136v-32c0-6.627-5.373-12-12-12H204c-6.627 0-12 5.373-12 12v32c0 6.627 5.373 12 12 12h200c6.627 0 12-5.373 12-12zm0 96v-32c0-6.627-5.373-12-12-12H204c-6.627 0-12 5.373-12 12v32c0 6.627 5.373 12 12 12h200c6.627 0 12-5.373 12-12zm0 96v-32c0-6.627-5.373-12-12-12H204c-6.627 0-12 5.373-12 12v32c0 6.627 5.373 12 12 12h200c6.627 0 12-5.373 12-12z"],"list-ol":[512,512,[],"f0cb","M3.263 139.527c0-7.477 3.917-11.572 11.573-11.572h15.131V88.078c0-5.163.534-10.503.534-10.503h-.356s-1.779 2.67-2.848 3.738c-4.451 4.273-10.504 4.451-15.666-1.068l-5.518-6.231c-5.342-5.341-4.984-11.216.534-16.379l21.72-19.938C32.815 33.602 36.732 32 42.785 32H54.89c7.656 0 11.749 3.916 11.749 11.572v84.384h15.488c7.655 0 11.572 4.094 11.572 11.572v8.901c0 7.477-3.917 11.572-11.572 11.572H14.836c-7.656 0-11.573-4.095-11.573-11.572v-8.902zM2.211 304.591c0-47.278 50.955-56.383 50.955-69.165 0-7.18-5.954-8.755-9.28-8.755-3.153 0-6.479 1.051-9.455 3.852-5.079 4.903-10.507 7.004-16.111 2.451l-8.579-6.829c-5.779-4.553-7.18-9.805-2.803-15.409C13.592 201.981 26.025 192 47.387 192c19.437 0 44.476 10.506 44.476 39.573 0 38.347-46.753 46.402-48.679 56.909h39.049c7.529 0 11.557 4.027 11.557 11.382v8.755c0 7.354-4.028 11.382-11.557 11.382h-67.94c-7.005 0-12.083-4.028-12.083-11.382v-4.028zM5.654 454.61l5.603-9.28c3.853-6.654 9.105-7.004 15.584-3.152 4.903 2.101 9.63 3.152 14.359 3.152 10.155 0 14.358-3.502 14.358-8.23 0-6.654-5.604-9.106-15.934-9.106h-4.728c-5.954 0-9.28-2.101-12.258-7.88l-1.05-1.926c-2.451-4.728-1.226-9.806 2.801-14.884l5.604-7.004c6.829-8.405 12.257-13.483 12.257-13.483v-.35s-4.203 1.051-12.608 1.051H16.685c-7.53 0-11.383-4.028-11.383-11.382v-8.755c0-7.53 3.853-11.382 11.383-11.382h58.484c7.529 0 11.382 4.027 11.382 11.382v3.327c0 5.778-1.401 9.806-5.079 14.183l-17.509 20.137c19.611 5.078 28.716 20.487 28.716 34.845 0 21.363-14.358 44.126-48.503 44.126-16.636 0-28.192-4.728-35.896-9.455-5.779-4.202-6.304-9.805-2.626-15.934zM144 132h352c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"],"list-ul":[512,512,[],"f0ca","M96 96c0 26.51-21.49 48-48 48S0 122.51 0 96s21.49-48 48-48 48 21.49 48 48zM48 208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm0 160c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm96-236h352c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"],"location-arrow":[512,512,[],"f124","M443.683 4.529L27.818 196.418C-18.702 217.889-3.39 288 47.933 288H224v175.993c0 51.727 70.161 66.526 91.582 20.115L507.38 68.225c18.905-40.961-23.752-82.133-63.697-63.696z"],lock:[448,512,[],"f023","M400 224h-24v-72C376 68.2 307.8 0 224 0S72 68.2 72 152v72H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48zm-104 0H152v-72c0-39.7 32.3-72 72-72s72 32.3 72 72v72z"],"lock-open":[576,512,[],"f3c1","M423.5 0C339.5.3 272 69.5 272 153.5V224H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48h-48v-71.1c0-39.6 31.7-72.5 71.3-72.9 40-.4 72.7 32.1 72.7 72v80c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24v-80C576 68 507.5-.3 423.5 0z"],"long-arrow-alt-down":[256,512,[],"f309","M168 345.941V44c0-6.627-5.373-12-12-12h-56c-6.627 0-12 5.373-12 12v301.941H41.941c-21.382 0-32.09 25.851-16.971 40.971l86.059 86.059c9.373 9.373 24.569 9.373 33.941 0l86.059-86.059c15.119-15.119 4.411-40.971-16.971-40.971H168z"],"long-arrow-alt-left":[448,512,[],"f30a","M134.059 296H436c6.627 0 12-5.373 12-12v-56c0-6.627-5.373-12-12-12H134.059v-46.059c0-21.382-25.851-32.09-40.971-16.971L7.029 239.029c-9.373 9.373-9.373 24.569 0 33.941l86.059 86.059c15.119 15.119 40.971 4.411 40.971-16.971V296z"],"long-arrow-alt-right":[448,512,[],"f30b","M313.941 216H12c-6.627 0-12 5.373-12 12v56c0 6.627 5.373 12 12 12h301.941v46.059c0 21.382 25.851 32.09 40.971 16.971l86.059-86.059c9.373-9.373 9.373-24.569 0-33.941l-86.059-86.059c-15.119-15.119-40.971-4.411-40.971 16.971V216z"],"long-arrow-alt-up":[256,512,[],"f30c","M88 166.059V468c0 6.627 5.373 12 12 12h56c6.627 0 12-5.373 12-12V166.059h46.059c21.382 0 32.09-25.851 16.971-40.971l-86.059-86.059c-9.373-9.373-24.569-9.373-33.941 0l-86.059 86.059c-15.119 15.119-4.411 40.971 16.971 40.971H88z"],"low-vision":[576,512,[],"f2a8","M569.344 231.631C512.96 135.949 407.81 72 288 72c-28.468 0-56.102 3.619-82.451 10.409L152.778 10.24c-7.601-10.858-22.564-13.5-33.423-5.9l-13.114 9.178c-10.86 7.601-13.502 22.566-5.9 33.426l43.131 58.395C89.449 131.73 40.228 174.683 6.682 231.581c-.01.017-.023.033-.034.05-8.765 14.875-8.964 33.528 0 48.739 38.5 65.332 99.742 115.862 172.859 141.349L55.316 244.302A272.194 272.194 0 0 1 83.61 208.39l119.4 170.58h.01l40.63 58.04a330.055 330.055 0 0 0 78.94 1.17l-189.98-271.4a277.628 277.628 0 0 1 38.777-21.563l251.836 356.544c7.601 10.858 22.564 13.499 33.423 5.9l13.114-9.178c10.86-7.601 13.502-22.567 5.9-33.426l-43.12-58.377-.007-.009c57.161-27.978 104.835-72.04 136.81-126.301a47.938 47.938 0 0 0 .001-48.739zM390.026 345.94l-19.066-27.23c24.682-32.567 27.711-76.353 8.8-111.68v.03c0 23.65-19.17 42.82-42.82 42.82-23.828 0-42.82-19.349-42.82-42.82 0-23.65 19.17-42.82 42.82-42.82h.03c-24.75-13.249-53.522-15.643-79.51-7.68l-19.068-27.237C253.758 123.306 270.488 120 288 120c75.162 0 136 60.826 136 136 0 34.504-12.833 65.975-33.974 89.94z"],magic:[512,512,[],"f0d0","M101.1 505L7 410.9c-9.4-9.4-9.4-24.6 0-33.9L377 7c9.4-9.4 24.6-9.4 33.9 0l94.1 94.1c9.4 9.4 9.4 24.6 0 33.9L135 505c-9.3 9.3-24.5 9.3-33.9 0zM304 159.2l48.8 48.8 89.9-89.9-48.8-48.8-89.9 89.9zM138.9 39.3l-11.7 23.8-26.2 3.8c-4.7.7-6.6 6.5-3.2 9.8l19 18.5-4.5 26.1c-.8 4.7 4.1 8.3 8.3 6.1L144 115l23.4 12.3c4.2 2.2 9.1-1.4 8.3-6.1l-4.5-26.1 19-18.5c3.4-3.3 1.5-9.1-3.2-9.8L160.8 63l-11.7-23.8c-2-4.1-8.1-4.1-10.2.1zm97.7-20.7l-7.8 15.8-17.5 2.6c-3.1.5-4.4 4.3-2.1 6.5l12.6 12.3-3 17.4c-.5 3.1 2.8 5.5 5.6 4L240 69l15.6 8.2c2.8 1.5 6.1-.9 5.6-4l-3-17.4 12.6-12.3c2.3-2.2 1-6.1-2.1-6.5l-17.5-2.5-7.8-15.8c-1.4-3-5.4-3-6.8-.1zm-192 0l-7.8 15.8L19.3 37c-3.1.5-4.4 4.3-2.1 6.5l12.6 12.3-3 17.4c-.5 3.1 2.8 5.5 5.6 4L48 69l15.6 8.2c2.8 1.5 6.1-.9 5.6-4l-3-17.4 12.6-12.3c2.3-2.2 1-6.1-2.1-6.5l-17.5-2.5-7.8-15.8c-1.4-3-5.4-3-6.8-.1zm416 223.5l-7.8 15.8-17.5 2.5c-3.1.5-4.4 4.3-2.1 6.5l12.6 12.3-3 17.4c-.5 3.1 2.8 5.5 5.6 4l15.6-8.2 15.6 8.2c2.8 1.5 6.1-.9 5.6-4l-3-17.4 12.6-12.3c2.3-2.2 1-6.1-2.1-6.5l-17.5-2.5-7.8-15.8c-1.4-2.8-5.4-2.8-6.8 0z"],magnet:[512,512,[],"f076","M164.1 160H12c-6.6 0-12-5.4-12-12V68c0-19.9 16.1-36 36-36h104c19.9 0 36 16.1 36 36v80c.1 6.6-5.3 12-11.9 12zm348-12V67.9c0-19.9-16.1-36-36-36h-104c-19.9 0-36 16.1-36 36v80c0 6.6 5.4 12 12 12h152c6.6.1 12-5.3 12-11.9zm-164 44c-6.6 0-12 5.4-12 12v52c0 128.1-160 127.9-160 0v-52c0-6.6-5.4-12-12-12h-152c-6.7 0-12 5.4-12 12.1.1 21.4.6 40.3 0 53.3C.1 408 136.3 504 256.9 504 377.5 504 512 408 512 257.3c-.6-12.8-.2-33 0-53.2 0-6.7-5.3-12.1-12-12.1H348.1z"],male:[192,512,[],"f183","M96 0c35.346 0 64 28.654 64 64s-28.654 64-64 64-64-28.654-64-64S60.654 0 96 0m48 144h-11.36c-22.711 10.443-49.59 10.894-73.28 0H48c-26.51 0-48 21.49-48 48v136c0 13.255 10.745 24 24 24h16v136c0 13.255 10.745 24 24 24h64c13.255 0 24-10.745 24-24V352h16c13.255 0 24-10.745 24-24V192c0-26.51-21.49-48-48-48z"],map:[576,512,[],"f279","M576 56.015v335.97a23.998 23.998 0 0 1-13.267 21.466l-128 64C418.948 485.344 400 473.992 400 455.985v-335.97a23.998 23.998 0 0 1 13.267-21.466l128-64C557.052 26.656 576 38.008 576 56.015zm-206.253 42.07l-144-64c-15.751-7-33.747 4.461-33.747 21.932v335.967a24 24 0 0 0 14.253 21.931l144 64c15.751 7 33.747-4.461 33.747-21.931V120.017a24 24 0 0 0-14.253-21.932zm-228.48-63.536l-128 63.985A23.998 23.998 0 0 0 0 120v335.985c0 18.007 18.948 29.359 34.733 21.466l128-63.985A23.998 23.998 0 0 0 176 392V56.015c0-18.007-18.948-29.359-34.733-21.466z"],"map-marker":[384,512,[],"f041","M172.268 501.67C26.97 291.031 0 269.413 0 192 0 85.961 85.961 0 192 0s192 85.961 192 192c0 77.413-26.97 99.031-172.268 309.67-9.535 13.774-29.93 13.773-39.464 0z"],"map-marker-alt":[384,512,[],"f3c5","M172.268 501.67C26.97 291.031 0 269.413 0 192 0 85.961 85.961 0 192 0s192 85.961 192 192c0 77.413-26.97 99.031-172.268 309.67-9.535 13.774-29.93 13.773-39.464 0zM192 272c44.183 0 80-35.817 80-80s-35.817-80-80-80-80 35.817-80 80 35.817 80 80 80z"],"map-pin":[320,512,[],"f276","M192 300.813v172.82l-22.015 33.023c-4.75 7.125-15.219 7.125-19.969 0L128 473.633v-172.82a162.221 162.221 0 0 0 64 0zM160 0c79.529 0 144 64.471 144 144s-64.471 144-144 144S16 223.529 16 144 80.471 0 160 0M80 136c0-39.701 32.299-72 72-72a8 8 0 0 0 0-16c-48.523 0-88 39.477-88 88a8 8 0 0 0 16 0z"],"map-signs":[512,512,[],"f277","M487.515 104.485L439.03 152.97a23.998 23.998 0 0 1-16.97 7.029H56c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24h160v-8c0-13.255 10.745-24 24-24h32c13.255 0 24 10.745 24 24v8h126.059a24 24 0 0 1 16.97 7.029l48.485 48.485c4.687 4.687 4.687 12.285.001 16.971zM216 368v120c0 13.255 10.745 24 24 24h32c13.255 0 24-10.745 24-24V368h-80zm240-144H296v-48h-80v48H89.941a24 24 0 0 0-16.97 7.029l-48.485 48.485c-4.686 4.686-4.686 12.284 0 16.971l48.485 48.485a23.998 23.998 0 0 0 16.97 7.029H456c13.255 0 24-10.745 24-24v-80C480 234.745 469.255 224 456 224z"],mars:[384,512,[],"f222","M372 64h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-80.7 80.7c-22.2-14-48.5-22.1-76.7-22.1C64.5 160 0 224.5 0 304s64.5 144 144 144 144-64.5 144-144c0-28.2-8.1-54.5-22.1-76.7l80.7-80.7 16.9 16.9c7.6 7.6 20.5 2.2 20.5-8.5V76c0-6.6-5.4-12-12-12zM144 384c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z"],"mars-double":[512,512,[],"f227","M340 0h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-48.7 48.7C198.5 72.1 172.2 64 144 64 64.5 64 0 128.5 0 208s64.5 144 144 144 144-64.5 144-144c0-28.2-8.1-54.5-22.1-76.7l48.7-48.7 16.9 16.9c2.4 2.4 5.5 3.5 8.4 3.5 6.2 0 12.1-4.8 12.1-12V12c0-6.6-5.4-12-12-12zM144 288c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80zm356-128.1h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-48.7 48.7c-18.2-11.4-39-18.9-61.5-21.3-2.1 21.8-8.2 43.3-18.4 63.3 1.1 0 2.2-.1 3.2-.1 44.1 0 80 35.9 80 80s-35.9 80-80 80-80-35.9-80-80c0-1.1 0-2.2.1-3.2-20 10.2-41.5 16.4-63.3 18.4C168.4 455.6 229.6 512 304 512c79.5 0 144-64.5 144-144 0-28.2-8.1-54.5-22.1-76.7l48.7-48.7 16.9 16.9c2.4 2.4 5.4 3.5 8.4 3.5 6.2 0 12.1-4.8 12.1-12v-79c0-6.7-5.4-12.1-12-12.1z"],"mars-stroke":[384,512,[],"f229","M372 64h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-17.5 17.5-14.1-14.1c-4.7-4.7-12.3-4.7-17 0L224.5 133c-4.7 4.7-4.7 12.3 0 17l14.1 14.1-18 18c-22.2-14-48.5-22.1-76.7-22.1C64.5 160 0 224.5 0 304s64.5 144 144 144 144-64.5 144-144c0-28.2-8.1-54.5-22.1-76.7l18-18 14.1 14.1c4.7 4.7 12.3 4.7 17 0l28.3-28.3c4.7-4.7 4.7-12.3 0-17L329.2 164l17.5-17.5 16.9 16.9c7.6 7.6 20.5 2.2 20.5-8.5V76c-.1-6.6-5.5-12-12.1-12zM144 384c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z"],"mars-stroke-h":[480,512,[],"f22b","M476.2 247.5l-55.9-55.9c-7.6-7.6-20.5-2.2-20.5 8.5V224H376v-20c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v20h-27.6c-5.8-25.6-18.7-49.9-38.6-69.8C189.6 98 98.4 98 42.2 154.2c-56.2 56.2-56.2 147.4 0 203.6 56.2 56.2 147.4 56.2 203.6 0 19.9-19.9 32.8-44.2 38.6-69.8H312v20c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-20h23.9v23.9c0 10.7 12.9 16 20.5 8.5l55.9-55.9c4.6-4.7 4.6-12.3-.1-17zm-275.6 65.1c-31.2 31.2-81.9 31.2-113.1 0-31.2-31.2-31.2-81.9 0-113.1 31.2-31.2 81.9-31.2 113.1 0 31.2 31.1 31.2 81.9 0 113.1z"],"mars-stroke-v":[288,512,[],"f22a","M245.8 234.2c-19.9-19.9-44.2-32.8-69.8-38.6v-25.4h20c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20V81.4h23.9c10.7 0 16-12.9 8.5-20.5L152.5 5.1c-4.7-4.7-12.3-4.7-17 0L79.6 61c-7.6 7.6-2.2 20.5 8.5 20.5H112v24.7H92c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h20v25.4c-25.6 5.8-49.9 18.7-69.8 38.6-56.2 56.2-56.2 147.4 0 203.6 56.2 56.2 147.4 56.2 203.6 0 56.3-56.2 56.3-147.4 0-203.6zm-45.2 158.4c-31.2 31.2-81.9 31.2-113.1 0-31.2-31.2-31.2-81.9 0-113.1 31.2-31.2 81.9-31.2 113.1 0 31.2 31.1 31.2 81.9 0 113.1z"],medkit:[512,512,[],"f0fa","M96 480h320V128h-32V80c0-26.51-21.49-48-48-48H176c-26.51 0-48 21.49-48 48v48H96v352zm96-384h128v32H192V96zm320 80v256c0 26.51-21.49 48-48 48h-16V128h16c26.51 0 48 21.49 48 48zM64 480H48c-26.51 0-48-21.49-48-48V176c0-26.51 21.49-48 48-48h16v352zm288-208v32c0 8.837-7.163 16-16 16h-48v48c0 8.837-7.163 16-16 16h-32c-8.837 0-16-7.163-16-16v-48h-48c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h48v-48c0-8.837 7.163-16 16-16h32c8.837 0 16 7.163 16 16v48h48c8.837 0 16 7.163 16 16z"],meh:[496,512,[],"f11a","M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm-80 168c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zm176 192H152c-8.8 0-16-7.2-16-16s7.2-16 16-16h192c8.8 0 16 7.2 16 16s-7.2 16-16 16zm-16-128c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z"],mercury:[288,512,[],"f223","M288 208c0-44.2-19.9-83.7-51.2-110.1 2.5-1.8 4.9-3.8 7.2-5.8 24.7-21.2 39.8-48.8 43.2-78.8.9-7.1-4.7-13.3-11.9-13.3h-40.5C229 0 224.1 4.1 223 9.8c-2.4 12.5-9.6 24.3-20.7 33.8C187 56.8 166.3 64 144 64s-43-7.2-58.4-20.4C74.5 34.1 67.4 22.3 64.9 9.8 63.8 4.1 58.9 0 53.2 0H12.7C5.5 0-.1 6.2.8 13.3 4.2 43.4 19.2 71 44 92.2c2.3 2 4.7 3.9 7.2 5.8C19.9 124.3 0 163.8 0 208c0 68.5 47.9 125.9 112 140.4V400H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v36c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-36h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-51.6c64.1-14.5 112-71.9 112-140.4zm-224 0c0-44.1 35.9-80 80-80s80 35.9 80 80-35.9 80-80 80-80-35.9-80-80z"],microchip:[512,512,[],"f2db","M416 48v416c0 26.51-21.49 48-48 48H144c-26.51 0-48-21.49-48-48V48c0-26.51 21.49-48 48-48h224c26.51 0 48 21.49 48 48zm96 58v12a6 6 0 0 1-6 6h-18v6a6 6 0 0 1-6 6h-42V88h42a6 6 0 0 1 6 6v6h18a6 6 0 0 1 6 6zm0 96v12a6 6 0 0 1-6 6h-18v6a6 6 0 0 1-6 6h-42v-48h42a6 6 0 0 1 6 6v6h18a6 6 0 0 1 6 6zm0 96v12a6 6 0 0 1-6 6h-18v6a6 6 0 0 1-6 6h-42v-48h42a6 6 0 0 1 6 6v6h18a6 6 0 0 1 6 6zm0 96v12a6 6 0 0 1-6 6h-18v6a6 6 0 0 1-6 6h-42v-48h42a6 6 0 0 1 6 6v6h18a6 6 0 0 1 6 6zM30 376h42v48H30a6 6 0 0 1-6-6v-6H6a6 6 0 0 1-6-6v-12a6 6 0 0 1 6-6h18v-6a6 6 0 0 1 6-6zm0-96h42v48H30a6 6 0 0 1-6-6v-6H6a6 6 0 0 1-6-6v-12a6 6 0 0 1 6-6h18v-6a6 6 0 0 1 6-6zm0-96h42v48H30a6 6 0 0 1-6-6v-6H6a6 6 0 0 1-6-6v-12a6 6 0 0 1 6-6h18v-6a6 6 0 0 1 6-6zm0-96h42v48H30a6 6 0 0 1-6-6v-6H6a6 6 0 0 1-6-6v-12a6 6 0 0 1 6-6h18v-6a6 6 0 0 1 6-6z"],microphone:[384,512,[],"f130","M96 256V96c0-53.019 42.981-96 96-96s96 42.981 96 96v160c0 53.019-42.981 96-96 96s-96-42.981-96-96zm252-56h-24c-6.627 0-12 5.373-12 12v42.68c0 66.217-53.082 120.938-119.298 121.318C126.213 376.38 72 322.402 72 256v-44c0-6.627-5.373-12-12-12H36c-6.627 0-12 5.373-12 12v44c0 84.488 62.693 154.597 144 166.278V468h-68c-6.627 0-12 5.373-12 12v20c0 6.627 5.373 12 12 12h184c6.627 0 12-5.373 12-12v-20c0-6.627-5.373-12-12-12h-68v-45.722c81.307-11.681 144-81.79 144-166.278v-44c0-6.627-5.373-12-12-12z"],"microphone-slash":[512,512,[],"f131","M421.45 285.195L376 239.746V212c0-6.627 5.373-12 12-12h24c6.627 0 12 5.373 12 12v44c0 9.957-.881 19.71-2.55 29.195zM352 96c0-53.019-42.981-96-96-96-32.574 0-61.354 16.227-78.71 41.035L352 215.746V96zm152.971 363.716L52.284 7.029c-9.373-9.373-24.569-9.373-33.941 0L7.029 18.343c-9.372 9.373-9.372 24.568 0 33.941L160 205.254v49.577c0 53.089 43.436 97.452 96.524 97.167 14.626-.078 28.471-3.44 40.854-9.366l17.746 17.746c-17.529 9.971-37.794 15.666-59.372 15.622C189.355 375.864 136 321.053 136 254.656V212c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v44c0 84.488 62.693 154.597 144 166.278V468h-68c-6.627 0-12 5.373-12 12v20c0 6.627 5.373 12 12 12h184c6.627 0 12-5.373 12-12v-20c0-6.627-5.373-12-12-12h-68v-45.722c25.625-3.682 49.396-13.172 69.942-27.083L459.717 504.97c9.373 9.373 24.569 9.373 33.941 0l11.313-11.313c9.372-9.373 9.372-24.568 0-33.941z"],minus:[448,512,[],"f068","M424 318.2c13.3 0 24-10.7 24-24v-76.4c0-13.3-10.7-24-24-24H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h400z"],"minus-circle":[512,512,[],"f056","M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zM124 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H124z"],"minus-square":[448,512,[],"f146","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM92 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H92z"],mobile:[320,512,[],"f10b","M272 0H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h224c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zM160 480c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z"],"mobile-alt":[320,512,[],"f3cd","M272 0H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h224c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zM160 480c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm112-108c0 6.6-5.4 12-12 12H60c-6.6 0-12-5.4-12-12V60c0-6.6 5.4-12 12-12h200c6.6 0 12 5.4 12 12v312z"],"money-bill-alt":[640,512,[],"f3d1","M640 120v272c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V120c0-13.255 10.745-24 24-24h592c13.255 0 24 10.745 24 24zM96 384c0-35.346-28.654-64-64-64v64h64zm0-256H32v64c35.346 0 64-28.654 64-64zm304 128c0-53.021-35.816-96-80-96s-80 42.979-80 96c0 53.012 35.814 96 80 96 44.167 0 80-42.969 80-96zm208 64c-35.346 0-64 28.654-64 64h64v-64zm0-192h-64c0 35.346 28.654 64 64 64v-64zM277.563 299.527c0-7.477 3.917-11.572 11.573-11.572h15.131v-39.878c0-5.163.534-10.503.534-10.503h-.356s-1.779 2.67-2.848 3.738c-4.451 4.273-10.504 4.451-15.666-1.068l-5.518-6.231c-5.342-5.341-4.984-11.216.534-16.379l21.72-19.939c4.449-4.095 8.366-5.697 14.42-5.697h12.105c7.656 0 11.749 3.916 11.749 11.572v84.384h15.488c7.655 0 11.572 4.094 11.572 11.572v8.901c0 7.477-3.917 11.572-11.572 11.572h-67.293c-7.656 0-11.573-4.095-11.573-11.572v-8.9z"],moon:[512,512,[],"f186","M283.211 512c78.962 0 151.079-35.925 198.857-94.792 7.068-8.708-.639-21.43-11.562-19.35-124.203 23.654-238.262-71.576-238.262-196.954 0-72.222 38.662-138.635 101.498-174.394 9.686-5.512 7.25-20.197-3.756-22.23A258.156 258.156 0 0 0 283.211 0c-141.309 0-256 114.511-256 256 0 141.309 114.511 256 256 256z"],motorcycle:[640,512,[],"f21c","M512.949 192.003c-14.862-.108-29.14 2.322-42.434 6.874L437.589 144H520c13.255 0 24-10.745 24-24V88c0-13.255-10.745-24-24-24h-45.311a24 24 0 0 0-17.839 7.945l-37.496 41.663-22.774-37.956A24 24 0 0 0 376 64h-80c-8.837 0-16 7.163-16 16v16c0 8.837 7.163 16 16 16h66.411l19.2 32H227.904c-17.727-23.073-44.924-40-99.904-40H72.54c-13.455 0-24.791 11.011-24.536 24.464C48.252 141.505 58.9 152 72 152h56c24.504 0 38.686 10.919 47.787 24.769l-11.291 20.529c-13.006-3.865-26.871-5.736-41.251-5.21C55.857 194.549 1.565 249.605.034 317.021-1.603 389.076 56.317 448 128 448c59.642 0 109.744-40.794 123.953-96h84.236c13.673 0 24.589-11.421 23.976-25.077-2.118-47.12 17.522-93.665 56.185-125.026l12.485 20.808c-27.646 23.654-45.097 58.88-44.831 98.179.47 69.556 57.203 126.452 126.758 127.11 71.629.678 129.839-57.487 129.234-129.099-.588-69.591-57.455-126.386-127.047-126.892zM128 400c-44.112 0-80-35.888-80-80s35.888-80 80-80c4.242 0 8.405.341 12.469.982L98.97 316.434C90.187 332.407 101.762 352 120 352h81.297c-12.37 28.225-40.56 48-73.297 48zm388.351-.116C470.272 402.337 432 365.554 432 320c0-21.363 8.434-40.781 22.125-55.144l49.412 82.352c4.546 7.577 14.375 10.034 21.952 5.488l13.72-8.232c7.577-4.546 10.034-14.375 5.488-21.952l-48.556-80.927A80.005 80.005 0 0 1 512 240c45.554 0 82.338 38.273 79.884 84.352-2.16 40.558-34.974 73.372-75.533 75.532z"],"mouse-pointer":[320,512,[],"f245","M302.189 329.126H196.105l55.831 135.993c3.889 9.428-.555 19.999-9.444 23.999l-49.165 21.427c-9.165 4-19.443-.571-23.332-9.714l-53.053-129.136-86.664 89.138C18.729 472.71 0 463.554 0 447.977V18.299C0 1.899 19.921-6.096 30.277 5.443l284.412 292.542c11.472 11.179 3.007 31.141-12.5 31.141z"],music:[512,512,[],"f001","M470.4 1.5l-304 96C153.1 101.7 144 114 144 128v264.6c-14.1-5.4-30.5-8.6-48-8.6-53 0-96 28.7-96 64s43 64 96 64 96-28.7 96-64V220.5l272-85.9v194c-14.1-5.4-30.5-8.6-48-8.6-53 0-96 28.7-96 64s43 64 96 64 96-28.7 96-64V32c0-21.7-21.1-37-41.6-30.5z"],neuter:[288,512,[],"f22c","M288 176c0-79.5-64.5-144-144-144S0 96.5 0 176c0 68.5 47.9 125.9 112 140.4V468c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12V316.4c64.1-14.5 112-71.9 112-140.4zm-144 80c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z"],newspaper:[576,512,[],"f1ea","M552 64H88c-13.255 0-24 10.745-24 24v8H24c-13.255 0-24 10.745-24 24v272c0 30.928 25.072 56 56 56h472c26.51 0 48-21.49 48-48V88c0-13.255-10.745-24-24-24zM56 400a8 8 0 0 1-8-8V144h16v248a8 8 0 0 1-8 8zm236-16H140c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h152c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12zm208 0H348c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h152c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12zm-208-96H140c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h152c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12zm208 0H348c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h152c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12zm0-96H140c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h360c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12z"],"notes-medical":[384,512,[],"f481","M336 64h-80c0-35.3-28.7-64-64-64s-64 28.7-64 64H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM192 40c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zm96 304c0 4.4-3.6 8-8 8h-56v56c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8v-56h-56c-4.4 0-8-3.6-8-8v-48c0-4.4 3.6-8 8-8h56v-56c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v56h56c4.4 0 8 3.6 8 8v48zm0-192c0 4.4-3.6 8-8 8H104c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h176c4.4 0 8 3.6 8 8v16z"],"object-group":[512,512,[],"f247","M480 128V96h20c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v20H64V44c0-6.627-5.373-12-12-12H12C5.373 32 0 37.373 0 44v40c0 6.627 5.373 12 12 12h20v320H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-20h384v20c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20V128zM96 276V140c0-6.627 5.373-12 12-12h168c6.627 0 12 5.373 12 12v136c0 6.627-5.373 12-12 12H108c-6.627 0-12-5.373-12-12zm320 96c0 6.627-5.373 12-12 12H236c-6.627 0-12-5.373-12-12v-52h72c13.255 0 24-10.745 24-24v-72h84c6.627 0 12 5.373 12 12v136z"],"object-ungroup":[576,512,[],"f248","M64 320v26a6 6 0 0 1-6 6H6a6 6 0 0 1-6-6v-52a6 6 0 0 1 6-6h26V96H6a6 6 0 0 1-6-6V38a6 6 0 0 1 6-6h52a6 6 0 0 1 6 6v26h288V38a6 6 0 0 1 6-6h52a6 6 0 0 1 6 6v52a6 6 0 0 1-6 6h-26v192h26a6 6 0 0 1 6 6v52a6 6 0 0 1-6 6h-52a6 6 0 0 1-6-6v-26H64zm480-64v-32h26a6 6 0 0 0 6-6v-52a6 6 0 0 0-6-6h-52a6 6 0 0 0-6 6v26H408v72h8c13.255 0 24 10.745 24 24v64c0 13.255-10.745 24-24 24h-64c-13.255 0-24-10.745-24-24v-8H192v72h-26a6 6 0 0 0-6 6v52a6 6 0 0 0 6 6h52a6 6 0 0 0 6-6v-26h288v26a6 6 0 0 0 6 6h52a6 6 0 0 0 6-6v-52a6 6 0 0 0-6-6h-26V256z"],outdent:[448,512,[],"f03b","M0 84V44c0-8.837 7.163-16 16-16h416c8.837 0 16 7.163 16 16v40c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16zm208 144h224c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H208c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zM16 484h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm192-128h224c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H208c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zM4.687 267.313l96 95.984C110.734 373.348 128 366.224 128 351.984V160.008c0-14.329-17.325-21.304-27.313-11.313l-96 95.992c-6.249 6.248-6.249 16.378 0 22.626z"],"paint-brush":[512,512,[],"f1fc","M269.9 364.6c1.4 6.4 2.1 13 2.1 19.7 0 81.2-54.2 127.7-134.8 127.7C41.5 512 0 435.1 0 347.6c10.4 7.1 46.9 36.5 58.7 36.5 7 0 13-4 15.5-10.6 23.6-62.2 66.5-76.5 112.9-77.4 15.6 33.8 46.1 59.6 82.8 68.5zM460.6 0c-14.4 0-27.9 6.4-38.2 15.7C228.2 190 208 194.1 208 245.4c0 48.8 40.5 90.6 90.2 90.6 59 0 93.2-43.4 200.6-244.8 7-13.7 13.2-28.5 13.2-43.9C512 19.7 487.3 0 460.6 0z"],pallet:[640,512,[],"f482","M144 256h352c8.8 0 16-7.2 16-16V16c0-8.8-7.2-16-16-16H384v128l-64-32-64 32V0H144c-8.8 0-16 7.2-16 16v224c0 8.8 7.2 16 16 16zm480 128c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h48v64H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h608c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16h-48v-64h48zm-336 64H128v-64h160v64zm224 0H352v-64h160v64z"],"paper-plane":[512,512,[],"f1d8","M476 3.2L12.5 270.6c-18.1 10.4-15.8 35.6 2.2 43.2L121 358.4l287.3-253.2c5.5-4.9 13.3 2.6 8.6 8.3L176 407v80.5c0 23.6 28.5 32.9 42.5 15.8L282 426l124.6 52.2c14.2 6 30.4-2.9 33-18.2l72-432C515 7.8 493.3-6.8 476 3.2z"],paperclip:[448,512,[],"f0c6","M43.246 466.142c-58.43-60.289-57.341-157.511 1.386-217.581L254.392 34c44.316-45.332 116.351-45.336 160.671 0 43.89 44.894 43.943 117.329 0 162.276L232.214 383.128c-29.855 30.537-78.633 30.111-107.982-.998-28.275-29.97-27.368-77.473 1.452-106.953l143.743-146.835c6.182-6.314 16.312-6.422 22.626-.241l22.861 22.379c6.315 6.182 6.422 16.312.241 22.626L171.427 319.927c-4.932 5.045-5.236 13.428-.648 18.292 4.372 4.634 11.245 4.711 15.688.165l182.849-186.851c19.613-20.062 19.613-52.725-.011-72.798-19.189-19.627-49.957-19.637-69.154 0L90.39 293.295c-34.763 35.56-35.299 93.12-1.191 128.313 34.01 35.093 88.985 35.137 123.058.286l172.06-175.999c6.177-6.319 16.307-6.433 22.626-.256l22.877 22.364c6.319 6.177 6.434 16.307.256 22.626l-172.06 175.998c-59.576 60.938-155.943 60.216-214.77-.485z"],"parachute-box":[512,512,[],"f4cd","M511.9 175c-9.1-75.6-78.4-132.4-158.3-158.7C390 55.7 416 116.9 416 192h28.1L327.5 321.5c-2.5-.6-4.8-1.5-7.5-1.5h-48V192h112C384 76.8 315.1 0 256 0S128 76.8 128 192h112v128h-48c-2.7 0-5 .9-7.5 1.5L67.9 192H96c0-75.1 26-136.3 62.4-175.7C78.5 42.7 9.2 99.5.1 175c-1.1 9.1 6.8 17 16 17h8.7l136.7 151.9c-.7 2.6-1.6 5.2-1.6 8.1v128c0 17.7 14.3 32 32 32h128c17.7 0 32-14.3 32-32V352c0-2.9-.9-5.4-1.6-8.1L487.1 192h8.7c9.3 0 17.2-7.8 16.1-17z"],paragraph:[448,512,[],"f1dd","M408 32H177.531C88.948 32 16.045 103.335 16 191.918 15.956 280.321 87.607 352 176 352v104c0 13.255 10.745 24 24 24h32c13.255 0 24-10.745 24-24V112h32v344c0 13.255 10.745 24 24 24h32c13.255 0 24-10.745 24-24V112h40c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24z"],paste:[448,512,[],"f0ea","M128 184c0-30.879 25.122-56 56-56h136V56c0-13.255-10.745-24-24-24h-80.61C204.306 12.89 183.637 0 160 0s-44.306 12.89-55.39 32H24C10.745 32 0 42.745 0 56v336c0 13.255 10.745 24 24 24h104V184zm32-144c13.255 0 24 10.745 24 24s-10.745 24-24 24-24-10.745-24-24 10.745-24 24-24zm184 248h104v200c0 13.255-10.745 24-24 24H184c-13.255 0-24-10.745-24-24V184c0-13.255 10.745-24 24-24h136v104c0 13.2 10.8 24 24 24zm104-38.059V256h-96v-96h6.059a24 24 0 0 1 16.97 7.029l65.941 65.941a24.002 24.002 0 0 1 7.03 16.971z"],pause:[448,512,[],"f04c","M144 479H48c-26.5 0-48-21.5-48-48V79c0-26.5 21.5-48 48-48h96c26.5 0 48 21.5 48 48v352c0 26.5-21.5 48-48 48zm304-48V79c0-26.5-21.5-48-48-48h-96c-26.5 0-48 21.5-48 48v352c0 26.5 21.5 48 48 48h96c26.5 0 48-21.5 48-48z"],"pause-circle":[512,512,[],"f28b","M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm-16 328c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16v160zm112 0c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16v160z"],paw:[512,512,[],"f1b0","M85.231 330.958C36 330.958 0 273.792 0 231.5c0-28.292 16-58.042 49.538-58.042 49.231 0 85.231 57.458 85.231 99.75 0 28.292-15.692 57.75-49.538 57.75zm348 106.167c0 37.042-32 42.875-63.385 42.875-41.231 0-74.462-26.25-113.846-26.25-41.231 0-76.308 25.958-120.923 25.958-29.847 0-56.308-9.625-56.308-42.583C78.769 368 180.616 265.333 256 265.333s177.231 102.959 177.231 171.792zM182.462 203.792c-49.847 0-80-59.5-80-100.333C102.462 70.792 120.308 32 160 32c50.154 0 80 59.5 80 100.333 0 32.667-17.846 71.459-57.538 71.459zM272 132.333C272 91.5 301.846 32 352 32c39.692 0 57.539 38.792 57.539 71.458 0 40.833-30.154 100.333-80.001 100.333C289.846 203.792 272 165 272 132.333zM512 231.5c0 42.292-36 99.458-85.231 99.458-33.847 0-49.538-29.458-49.538-57.75 0-42.291 35.999-99.75 85.231-99.75C496 173.458 512 203.208 512 231.5z"],"pen-square":[448,512,[],"f14b","M400 480H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48v352c0 26.5-21.5 48-48 48zM238.1 177.9L102.4 313.6l-6.3 57.1c-.8 7.6 5.6 14.1 13.3 13.3l57.1-6.3L302.2 242c2.3-2.3 2.3-6.1 0-8.5L246.7 178c-2.5-2.4-6.3-2.4-8.6-.1zM345 165.1L314.9 135c-9.4-9.4-24.6-9.4-33.9 0l-23.1 23.1c-2.3 2.3-2.3 6.1 0 8.5l55.5 55.5c2.3 2.3 6.1 2.3 8.5 0L345 199c9.3-9.3 9.3-24.5 0-33.9z"],"pencil-alt":[512,512,[],"f303","M497.9 142.1l-46.1 46.1c-4.7 4.7-12.3 4.7-17 0l-111-111c-4.7-4.7-4.7-12.3 0-17l46.1-46.1c18.7-18.7 49.1-18.7 67.9 0l60.1 60.1c18.8 18.7 18.8 49.1 0 67.9zM284.2 99.8L21.6 362.4.4 483.9c-2.9 16.4 11.4 30.6 27.8 27.8l121.5-21.3 262.6-262.6c4.7-4.7 4.7-12.3 0-17l-111-111c-4.8-4.7-12.4-4.7-17.1 0zM124.1 339.9c-5.5-5.5-5.5-14.3 0-19.8l154-154c5.5-5.5 14.3-5.5 19.8 0s5.5 14.3 0 19.8l-154 154c-5.5 5.5-14.3 5.5-19.8 0zM88 424h48v36.3l-64.5 11.3-31.1-31.1L51.7 376H88v48z"],"people-carry":[640,512,[],"f4ce","M128 96c26.5 0 48-21.5 48-48S154.5 0 128 0 80 21.5 80 48s21.5 48 48 48zm384 0c26.5 0 48-21.5 48-48S538.5 0 512 0s-48 21.5-48 48 21.5 48 48 48zm125.7 372.1l-44-110-41.1 46.4-2 18.2 27.7 69.2c5 12.5 17 20.1 29.7 20.1 4 0 8-.7 11.9-2.3 16.4-6.6 24.4-25.2 17.8-41.6zm-34.2-209.8L585 178.1c-4.6-20-18.6-36.8-37.5-44.9-18.5-8-39-6.7-56.1 3.3-22.7 13.4-39.7 34.5-48.1 59.4L432 229.8 416 240v-96c0-8.8-7.2-16-16-16H240c-8.8 0-16 7.2-16 16v96l-16.1-10.2-11.3-33.9c-8.3-25-25.4-46-48.1-59.4-17.2-10-37.6-11.3-56.1-3.3-18.9 8.1-32.9 24.9-37.5 44.9l-18.4 80.2c-4.6 20 .7 41.2 14.4 56.7l67.2 75.9 10.1 92.6C130 499.8 143.8 512 160 512c1.2 0 2.3-.1 3.5-.2 17.6-1.9 30.2-17.7 28.3-35.3l-10.1-92.8c-1.5-13-6.9-25.1-15.6-35l-43.3-49 17.6-70.3 6.8 20.4c4.1 12.5 11.9 23.4 24.5 32.6l51.1 32.5c4.6 2.9 12.1 4.6 17.2 5h160c5.1-.4 12.6-2.1 17.2-5l51.1-32.5c12.6-9.2 20.4-20 24.5-32.6l6.8-20.4 17.6 70.3-43.3 49c-8.7 9.9-14.1 22-15.6 35l-10.1 92.8c-1.9 17.6 10.8 33.4 28.3 35.3 1.2.1 2.3.2 3.5.2 16.1 0 30-12.1 31.8-28.5l10.1-92.6 67.2-75.9c13.6-15.5 19-36.7 14.4-56.7zM46.3 358.1l-44 110c-6.6 16.4 1.4 35 17.8 41.6 16.8 6.6 35.1-1.7 41.6-17.8l27.7-69.2-2-18.2-41.1-46.4z"],percent:[448,512,[],"f295","M112 224c61.9 0 112-50.1 112-112S173.9 0 112 0 0 50.1 0 112s50.1 112 112 112zm0-160c26.5 0 48 21.5 48 48s-21.5 48-48 48-48-21.5-48-48 21.5-48 48-48zm224 224c-61.9 0-112 50.1-112 112s50.1 112 112 112 112-50.1 112-112-50.1-112-112-112zm0 160c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zM392.3.2l31.6-.1c19.4-.1 30.9 21.8 19.7 37.8L77.4 501.6a23.95 23.95 0 0 1-19.6 10.2l-33.4.1c-19.5 0-30.9-21.9-19.7-37.8l368-463.7C377.2 4 384.5.2 392.3.2z"],phone:[512,512,[],"f095","M493.4 24.6l-104-24c-11.3-2.6-22.9 3.3-27.5 13.9l-48 112c-4.2 9.8-1.4 21.3 6.9 28l60.6 49.6c-36 76.7-98.9 140.5-177.2 177.2l-49.6-60.6c-6.8-8.3-18.2-11.1-28-6.9l-112 48C3.9 366.5-2 378.1.6 389.4l24 104C27.1 504.2 36.7 512 48 512c256.1 0 464-207.5 464-464 0-11.2-7.7-20.9-18.6-23.4z"],"phone-slash":[640,512,[],"f3dd","M268.2 381.4l-49.6-60.6c-6.8-8.3-18.2-11.1-28-6.9l-112 48c-10.7 4.6-16.5 16.1-13.9 27.5l24 104c2.5 10.8 12.1 18.6 23.4 18.6 100.7 0 193.7-32.4 269.7-86.9l-80-61.8c-10.9 6.5-22.1 12.7-33.6 18.1zm365.6 76.7L475.1 335.5C537.9 256.4 576 156.9 576 48c0-11.2-7.7-20.9-18.6-23.4l-104-24c-11.3-2.6-22.9 3.3-27.5 13.9l-48 112c-4.2 9.8-1.4 21.3 6.9 28l60.6 49.6c-12.2 26.1-27.9 50.3-46 72.8L45.5 3.4C38.5-2 28.5-.8 23 6.2L3.4 31.4c-5.4 7-4.2 17 2.8 22.4l588.4 454.7c7 5.4 17 4.2 22.5-2.8l19.6-25.3c5.4-6.8 4.1-16.9-2.9-22.3z"],"phone-square":[448,512,[],"f098","M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM94 416c-7.033 0-13.057-4.873-14.616-11.627l-14.998-65a15 15 0 0 1 8.707-17.16l69.998-29.999a15 15 0 0 1 17.518 4.289l30.997 37.885c48.944-22.963 88.297-62.858 110.781-110.78l-37.886-30.997a15.001 15.001 0 0 1-4.289-17.518l30-69.998a15 15 0 0 1 17.16-8.707l65 14.998A14.997 14.997 0 0 1 384 126c0 160.292-129.945 290-290 290z"],"phone-volume":[384,512,[],"f2a0","M97.333 506.966c-129.874-129.874-129.681-340.252 0-469.933 5.698-5.698 14.527-6.632 21.263-2.422l64.817 40.513a17.187 17.187 0 0 1 6.849 20.958l-32.408 81.021a17.188 17.188 0 0 1-17.669 10.719l-55.81-5.58c-21.051 58.261-20.612 122.471 0 179.515l55.811-5.581a17.188 17.188 0 0 1 17.669 10.719l32.408 81.022a17.188 17.188 0 0 1-6.849 20.958l-64.817 40.513a17.19 17.19 0 0 1-21.264-2.422zM247.126 95.473c11.832 20.047 11.832 45.008 0 65.055-3.95 6.693-13.108 7.959-18.718 2.581l-5.975-5.726c-3.911-3.748-4.793-9.622-2.261-14.41a32.063 32.063 0 0 0 0-29.945c-2.533-4.788-1.65-10.662 2.261-14.41l5.975-5.726c5.61-5.378 14.768-4.112 18.718 2.581zm91.787-91.187c60.14 71.604 60.092 175.882 0 247.428-4.474 5.327-12.53 5.746-17.552.933l-5.798-5.557c-4.56-4.371-4.977-11.529-.93-16.379 49.687-59.538 49.646-145.933 0-205.422-4.047-4.85-3.631-12.008.93-16.379l5.798-5.557c5.022-4.813 13.078-4.394 17.552.933zm-45.972 44.941c36.05 46.322 36.108 111.149 0 157.546-4.39 5.641-12.697 6.251-17.856 1.304l-5.818-5.579c-4.4-4.219-4.998-11.095-1.285-15.931 26.536-34.564 26.534-82.572 0-117.134-3.713-4.836-3.115-11.711 1.285-15.931l5.818-5.579c5.159-4.947 13.466-4.337 17.856 1.304z"],"piggy-bank":[576,512,[],"f4d3","M560 224h-29.5c-8.8-20-21.6-37.7-37.4-52.5L512 96h-32c-29.4 0-55.4 13.5-73 34.3-7.6-1.1-15.1-2.3-23-2.3H256c-77.4 0-141.9 55-156.8 128H56c-14.8 0-26.5-13.5-23.5-28.8C34.7 215.8 45.4 208 57 208h1c3.3 0 6-2.7 6-6v-20c0-3.3-2.7-6-6-6-28.5 0-53.9 20.4-57.5 48.6C-3.9 258.8 22.7 288 56 288h40c0 52.2 25.4 98.1 64 127.3V496c0 8.8 7.2 16 16 16h64c8.8 0 16-7.2 16-16v-48h128v48c0 8.8 7.2 16 16 16h64c8.8 0 16-7.2 16-16v-80.7c11.8-8.9 22.3-19.4 31.3-31.3H560c8.8 0 16-7.2 16-16V240c0-8.8-7.2-16-16-16zm-128 64c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16zM256 96h128c5.4 0 10.7.4 15.9.8 0-.3.1-.5.1-.8 0-53-43-96-96-96s-96 43-96 96c0 2.1.5 4.1.6 6.2 15.2-3.9 31-6.2 47.4-6.2z"],pills:[576,512,[],"f484","M112 32C50.1 32 0 82.1 0 144v224c0 61.9 50.1 112 112 112s112-50.1 112-112V144c0-61.9-50.1-112-112-112zm48 224H64V144c0-26.5 21.5-48 48-48s48 21.5 48 48v112zm139.7-29.7c-3.5-3.5-9.4-3.1-12.3.8-45.3 62.5-40.4 150.1 15.9 206.4 56.3 56.3 143.9 61.2 206.4 15.9 4-2.9 4.3-8.8.8-12.3L299.7 226.3zm229.8-19c-56.3-56.3-143.9-61.2-206.4-15.9-4 2.9-4.3 8.8-.8 12.3l210.8 210.8c3.5 3.5 9.4 3.1 12.3-.8 45.3-62.6 40.5-150.1-15.9-206.4z"],plane:[576,512,[],"f072","M472 200H360.211L256.013 5.711A12 12 0 0 0 245.793 0h-57.787c-7.85 0-13.586 7.413-11.616 15.011L209.624 200H99.766l-34.904-58.174A12 12 0 0 0 54.572 136H12.004c-7.572 0-13.252 6.928-11.767 14.353l21.129 105.648L.237 361.646c-1.485 7.426 4.195 14.354 11.768 14.353l42.568-.002c4.215 0 8.121-2.212 10.289-5.826L99.766 312h109.858L176.39 496.989c-1.97 7.599 3.766 15.011 11.616 15.011h57.787a12 12 0 0 0 10.22-5.711L360.212 312H472c57.438 0 104-25.072 104-56s-46.562-56-104-56z"],play:[448,512,[],"f04b","M424.4 214.7L72.4 6.6C43.8-10.3 0 6.1 0 47.9V464c0 37.5 40.7 60.1 72.4 41.3l352-208c31.4-18.5 31.5-64.1 0-82.6z"],"play-circle":[512,512,[],"f144","M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm115.7 272l-176 101c-15.8 8.8-35.7-2.5-35.7-21V152c0-18.4 19.8-29.8 35.7-21l176 107c16.4 9.2 16.4 32.9 0 42z"],plug:[384,512,[],"f1e6","M256 144V32c0-17.673 14.327-32 32-32s32 14.327 32 32v112h-64zm112 16H16c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h16v32c0 77.406 54.969 141.971 128 156.796V512h64v-99.204c73.031-14.825 128-79.39 128-156.796v-32h16c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16zm-240-16V32c0-17.673-14.327-32-32-32S64 14.327 64 32v112h64z"],plus:[448,512,[],"f067","M448 294.2v-76.4c0-13.3-10.7-24-24-24H286.2V56c0-13.3-10.7-24-24-24h-76.4c-13.3 0-24 10.7-24 24v137.8H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h137.8V456c0 13.3 10.7 24 24 24h76.4c13.3 0 24-10.7 24-24V318.2H424c13.3 0 24-10.7 24-24z"],"plus-circle":[512,512,[],"f055","M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm144 276c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92h-92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"],"plus-square":[448,512,[],"f0fe","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"],podcast:[448,512,[],"f2ce","M267.429 488.563C262.286 507.573 242.858 512 224 512c-18.857 0-38.286-4.427-43.428-23.437C172.927 460.134 160 388.898 160 355.75c0-35.156 31.142-43.75 64-43.75s64 8.594 64 43.75c0 32.949-12.871 104.179-20.571 132.813zM156.867 288.554c-18.693-18.308-29.958-44.173-28.784-72.599 2.054-49.724 42.395-89.956 92.124-91.881C274.862 121.958 320 165.807 320 220c0 26.827-11.064 51.116-28.866 68.552-2.675 2.62-2.401 6.986.628 9.187 9.312 6.765 16.46 15.343 21.234 25.363 1.741 3.654 6.497 4.66 9.449 1.891 28.826-27.043 46.553-65.783 45.511-108.565-1.855-76.206-63.595-138.208-139.793-140.369C146.869 73.753 80 139.215 80 220c0 41.361 17.532 78.7 45.55 104.989 2.953 2.771 7.711 1.77 9.453-1.887 4.774-10.021 11.923-18.598 21.235-25.363 3.029-2.2 3.304-6.566.629-9.185zM224 0C100.204 0 0 100.185 0 224c0 89.992 52.602 165.647 125.739 201.408 4.333 2.118 9.267-1.544 8.535-6.31-2.382-15.512-4.342-30.946-5.406-44.339-.146-1.836-1.149-3.486-2.678-4.512-47.4-31.806-78.564-86.016-78.187-147.347.592-96.237 79.29-174.648 175.529-174.899C320.793 47.747 400 126.797 400 224c0 61.932-32.158 116.49-80.65 147.867-.999 14.037-3.069 30.588-5.624 47.23-.732 4.767 4.203 8.429 8.535 6.31C395.227 389.727 448 314.187 448 224 448 100.205 347.815 0 224 0zm0 160c-35.346 0-64 28.654-64 64s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64z"],poo:[512,512,[],"f2fe","M451.4 369.1C468.7 356 480 335.4 480 312c0-39.8-32.2-72-72-72h-14.1c13.4-11.7 22.1-28.8 22.1-48 0-35.3-28.7-64-64-64h-5.9c3.6-10.1 5.9-20.7 5.9-32 0-53-43-96-96-96-5.2 0-10.2.7-15.1 1.5C250.3 14.6 256 30.6 256 48c0 44.2-35.8 80-80 80h-16c-35.3 0-64 28.7-64 64 0 19.2 8.7 36.3 22.1 48H104c-39.8 0-72 32.2-72 72 0 23.4 11.3 44 28.6 57.1C26.3 374.6 0 404.1 0 440c0 39.8 32.2 72 72 72h368c39.8 0 72-32.2 72-72 0-35.9-26.3-65.4-60.6-70.9zM192 256c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zm159.5 139C341 422.9 293 448 256 448s-85-25.1-95.5-53c-2-5.3 2-11 7.8-11h175.4c5.8 0 9.8 5.7 7.8 11zM320 320c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z"],"pound-sign":[320,512,[],"f154","M308 352h-45.495c-6.627 0-12 5.373-12 12v50.848H128V288h84c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-84v-63.556c0-32.266 24.562-57.086 61.792-57.086 23.658 0 45.878 11.505 57.652 18.849 5.151 3.213 11.888 2.051 15.688-2.685l28.493-35.513c4.233-5.276 3.279-13.005-2.119-17.081C273.124 54.56 236.576 32 187.931 32 106.026 32 48 84.742 48 157.961V224H20c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h28v128H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h296c6.627 0 12-5.373 12-12V364c0-6.627-5.373-12-12-12z"],"power-off":[512,512,[],"f011","M400 54.1c63 45 104 118.6 104 201.9 0 136.8-110.8 247.7-247.5 248C120 504.3 8.2 393 8 256.4 7.9 173.1 48.9 99.3 111.8 54.2c11.7-8.3 28-4.8 35 7.7L162.6 90c5.9 10.5 3.1 23.8-6.6 31-41.5 30.8-68 79.6-68 134.9-.1 92.3 74.5 168.1 168 168.1 91.6 0 168.6-74.2 168-169.1-.3-51.8-24.7-101.8-68.1-134-9.7-7.2-12.4-20.5-6.5-30.9l15.8-28.1c7-12.4 23.2-16.1 34.8-7.8zM296 264V24c0-13.3-10.7-24-24-24h-32c-13.3 0-24 10.7-24 24v240c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24z"],"prescription-bottle":[384,512,[],"f485","M32 192h120c4.4 0 8 3.6 8 8v16c0 4.4-3.6 8-8 8H32v64h120c4.4 0 8 3.6 8 8v16c0 4.4-3.6 8-8 8H32v64h120c4.4 0 8 3.6 8 8v16c0 4.4-3.6 8-8 8H32v64c0 17.6 14.4 32 32 32h256c17.6 0 32-14.4 32-32V128H32v64zM360 0H24C10.8 0 0 10.8 0 24v48c0 13.2 10.8 24 24 24h336c13.2 0 24-10.8 24-24V24c0-13.2-10.8-24-24-24z"],"prescription-bottle-alt":[384,512,[],"f486","M360 0H24C10.8 0 0 10.8 0 24v48c0 13.2 10.8 24 24 24h336c13.2 0 24-10.8 24-24V24c0-13.2-10.8-24-24-24zM32 480c0 17.6 14.4 32 32 32h256c17.6 0 32-14.4 32-32V128H32v352zm64-184c0-4.4 3.6-8 8-8h56v-56c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v56h56c4.4 0 8 3.6 8 8v48c0 4.4-3.6 8-8 8h-56v56c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8v-56h-56c-4.4 0-8-3.6-8-8v-48z"],print:[512,512,[],"f02f","M464 192h-16V81.941a24 24 0 0 0-7.029-16.97L383.029 7.029A24 24 0 0 0 366.059 0H88C74.745 0 64 10.745 64 24v168H48c-26.51 0-48 21.49-48 48v132c0 6.627 5.373 12 12 12h52v104c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V384h52c6.627 0 12-5.373 12-12V240c0-26.51-21.49-48-48-48zm-80 256H128v-96h256v96zM128 224V64h192v40c0 13.2 10.8 24 24 24h40v96H128zm304 72c-13.254 0-24-10.746-24-24s10.746-24 24-24 24 10.746 24 24-10.746 24-24 24z"],procedures:[640,512,[],"f487","M528 224H272c-8.8 0-16 7.2-16 16v144H64V144c0-8.8-7.2-16-16-16H16c-8.8 0-16 7.2-16 16v352c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16v-48h512v48c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V336c0-61.9-50.1-112-112-112zM136 96h126.1l27.6 55.2c5.9 11.8 22.7 11.8 28.6 0L368 51.8 390.1 96H512c8.8 0 16-7.2 16-16s-7.2-16-16-16H409.9L382.3 8.8C376.4-3 359.6-3 353.7 8.8L304 108.2l-19.9-39.8c-1.4-2.7-4.1-4.4-7.2-4.4H136c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8zm24 256c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64z"],"puzzle-piece":[576,512,[],"f12e","M519.442 288.651c-41.519 0-59.5 31.593-82.058 31.593C377.409 320.244 432 144 432 144s-196.288 80-196.288-3.297c0-35.827 36.288-46.25 36.288-85.985C272 19.216 243.885 0 210.539 0c-34.654 0-66.366 18.891-66.366 56.346 0 41.364 31.711 59.277 31.711 81.75C175.885 207.719 0 166.758 0 166.758v333.237s178.635 41.047 178.635-28.662c0-22.473-40-40.107-40-81.471 0-37.456 29.25-56.346 63.577-56.346 33.673 0 61.788 19.216 61.788 54.717 0 39.735-36.288 50.158-36.288 85.985 0 60.803 129.675 25.73 181.23 25.73 0 0-34.725-120.101 25.827-120.101 35.962 0 46.423 36.152 86.308 36.152C556.712 416 576 387.99 576 354.443c0-34.199-18.962-65.792-56.558-65.792z"],qrcode:[448,512,[],"f029","M0 224h192V32H0v192zM64 96h64v64H64V96zm192-64v192h192V32H256zm128 128h-64V96h64v64zM0 480h192V288H0v192zm64-128h64v64H64v-64zm352-64h32v128h-96v-32h-32v96h-64V288h96v32h64v-32zm0 160h32v32h-32v-32zm-64 0h32v32h-32v-32z"],question:[384,512,[],"f128","M202.021 0C122.202 0 70.503 32.703 29.914 91.026c-7.363 10.58-5.093 25.086 5.178 32.874l43.138 32.709c10.373 7.865 25.132 6.026 33.253-4.148 25.049-31.381 43.63-49.449 82.757-49.449 30.764 0 68.816 19.799 68.816 49.631 0 22.552-18.617 34.134-48.993 51.164-35.423 19.86-82.299 44.576-82.299 106.405V320c0 13.255 10.745 24 24 24h72.471c13.255 0 24-10.745 24-24v-5.773c0-42.86 125.268-44.645 125.268-160.627C377.504 66.256 286.902 0 202.021 0zM192 373.459c-38.196 0-69.271 31.075-69.271 69.271 0 38.195 31.075 69.27 69.271 69.27s69.271-31.075 69.271-69.271-31.075-69.27-69.271-69.27z"],"question-circle":[512,512,[],"f059","M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zM262.655 90c-54.497 0-89.255 22.957-116.549 63.758-3.536 5.286-2.353 12.415 2.715 16.258l34.699 26.31c5.205 3.947 12.621 3.008 16.665-2.122 17.864-22.658 30.113-35.797 57.303-35.797 20.429 0 45.698 13.148 45.698 32.958 0 14.976-12.363 22.667-32.534 33.976C247.128 238.528 216 254.941 216 296v4c0 6.627 5.373 12 12 12h56c6.627 0 12-5.373 12-12v-1.333c0-28.462 83.186-29.647 83.186-106.667 0-58.002-60.165-102-116.531-102zM256 338c-25.365 0-46 20.635-46 46 0 25.364 20.635 46 46 46s46-20.636 46-46c0-25.365-20.635-46-46-46z"],quidditch:[640,512,[],"f458","M256.5 216.8L343.2 326s-16.6 102.4-76.6 150.1C206.7 523.8 0 510.2 0 510.2s3.8-23.1 11-55.4l94.6-112.2c4-4.7-.9-11.6-6.6-9.5l-60.4 22.1c14.4-41.7 32.7-80 54.6-97.5 59.9-47.8 163.3-40.9 163.3-40.9zm238 135c-44 0-79.8 35.8-79.8 79.9 0 44.1 35.7 79.9 79.8 79.9 44.1 0 79.8-35.8 79.8-79.9 0-44.2-35.8-79.9-79.8-79.9zM636.5 31L616.7 6c-5.5-6.9-15.5-8-22.4-2.6L361.8 181.3l-34.1-43c-5.1-6.4-15.1-5.2-18.6 2.2l-25.3 54.6 86.7 109.2 58.8-12.4c8-1.7 11.4-11.2 6.3-17.6l-34.1-42.9L634 53.5c6.9-5.5 8-15.6 2.5-22.5z"],"quote-left":[512,512,[],"f10d","M464 256h-80v-64c0-35.3 28.7-64 64-64h8c13.3 0 24-10.7 24-24V56c0-13.3-10.7-24-24-24h-8c-88.4 0-160 71.6-160 160v240c0 26.5 21.5 48 48 48h128c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48zm-288 0H96v-64c0-35.3 28.7-64 64-64h8c13.3 0 24-10.7 24-24V56c0-13.3-10.7-24-24-24h-8C71.6 32 0 103.6 0 192v240c0 26.5 21.5 48 48 48h128c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48z"],"quote-right":[512,512,[],"f10e","M464 32H336c-26.5 0-48 21.5-48 48v128c0 26.5 21.5 48 48 48h80v64c0 35.3-28.7 64-64 64h-8c-13.3 0-24 10.7-24 24v48c0 13.3 10.7 24 24 24h8c88.4 0 160-71.6 160-160V80c0-26.5-21.5-48-48-48zm-288 0H48C21.5 32 0 53.5 0 80v128c0 26.5 21.5 48 48 48h80v64c0 35.3-28.7 64-64 64h-8c-13.3 0-24 10.7-24 24v48c0 13.3 10.7 24 24 24h8c88.4 0 160-71.6 160-160V80c0-26.5-21.5-48-48-48z"],random:[512,512,[],"f074","M504.971 359.029c9.373 9.373 9.373 24.569 0 33.941l-80 79.984c-15.01 15.01-40.971 4.49-40.971-16.971V416h-58.785a12.004 12.004 0 0 1-8.773-3.812l-70.556-75.596 53.333-57.143L352 336h32v-39.981c0-21.438 25.943-31.998 40.971-16.971l80 79.981zM12 176h84l52.781 56.551 53.333-57.143-70.556-75.596A11.999 11.999 0 0 0 122.785 96H12c-6.627 0-12 5.373-12 12v56c0 6.627 5.373 12 12 12zm372 0v39.984c0 21.46 25.961 31.98 40.971 16.971l80-79.984c9.373-9.373 9.373-24.569 0-33.941l-80-79.981C409.943 24.021 384 34.582 384 56.019V96h-58.785a12.004 12.004 0 0 0-8.773 3.812L96 336H12c-6.627 0-12 5.373-12 12v56c0 6.627 5.373 12 12 12h110.785c3.326 0 6.503-1.381 8.773-3.812L352 176h32z"],recycle:[512,512,[],"f1b8","M184.561 261.903c3.232 13.997-12.123 24.635-24.068 17.168l-40.736-25.455-50.867 81.402C55.606 356.273 70.96 384 96.012 384H148c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12H96.115c-75.334 0-121.302-83.048-81.408-146.88l50.822-81.388-40.725-25.448c-12.081-7.547-8.966-25.961 4.879-29.158l110.237-25.45c8.611-1.988 17.201 3.381 19.189 11.99l25.452 110.237zm98.561-182.915l41.289 66.076-40.74 25.457c-12.051 7.528-9 25.953 4.879 29.158l110.237 25.45c8.672 1.999 17.215-3.438 19.189-11.99l25.45-110.237c3.197-13.844-11.99-24.719-24.068-17.168l-40.687 25.424-41.263-66.082c-37.521-60.033-125.209-60.171-162.816 0l-17.963 28.766c-3.51 5.62-1.8 13.021 3.82 16.533l33.919 21.195c5.62 3.512 13.024 1.803 16.536-3.817l17.961-28.743c12.712-20.341 41.973-19.676 54.257-.022zM497.288 301.12l-27.515-44.065c-3.511-5.623-10.916-7.334-16.538-3.821l-33.861 21.159c-5.62 3.512-7.33 10.915-3.818 16.536l27.564 44.112c13.257 21.211-2.057 48.96-27.136 48.96H320V336.02c0-14.213-17.242-21.383-27.313-11.313l-80 79.981c-6.249 6.248-6.249 16.379 0 22.627l80 79.989C302.689 517.308 320 510.3 320 495.989V448h95.88c75.274 0 121.335-82.997 81.408-146.88z"],redo:[512,512,[],"f01e","M500.333 0h-47.411c-6.853 0-12.314 5.729-11.986 12.574l3.966 82.759C399.416 41.899 331.672 8 256.001 8 119.34 8 7.899 119.526 8 256.187 8.101 393.068 119.096 504 256 504c63.926 0 122.202-24.187 166.178-63.908 5.113-4.618 5.354-12.561.482-17.433l-33.971-33.971c-4.466-4.466-11.64-4.717-16.38-.543C341.308 415.448 300.606 432 256 432c-97.267 0-176-78.716-176-176 0-97.267 78.716-176 176-176 60.892 0 114.506 30.858 146.099 77.8l-101.525-4.865c-6.845-.328-12.574 5.133-12.574 11.986v47.411c0 6.627 5.373 12 12 12h200.333c6.627 0 12-5.373 12-12V12c0-6.627-5.373-12-12-12z"],"redo-alt":[512,512,[],"f2f9","M256.455 8c66.269.119 126.437 26.233 170.859 68.685l35.715-35.715C478.149 25.851 504 36.559 504 57.941V192c0 13.255-10.745 24-24 24H345.941c-21.382 0-32.09-25.851-16.971-40.971l41.75-41.75c-30.864-28.899-70.801-44.907-113.23-45.273-92.398-.798-170.283 73.977-169.484 169.442C88.764 348.009 162.184 424 256 424c41.127 0 79.997-14.678 110.629-41.556 4.743-4.161 11.906-3.908 16.368.553l39.662 39.662c4.872 4.872 4.631 12.815-.482 17.433C378.202 479.813 319.926 504 256 504 119.034 504 8.001 392.967 8 256.002 7.999 119.193 119.646 7.755 256.455 8z"],registered:[512,512,[],"f25d","M285.363 207.475c0 18.6-9.831 28.431-28.431 28.431h-29.876v-56.14h23.378c28.668 0 34.929 8.773 34.929 27.709zM504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM363.411 360.414c-46.729-84.825-43.299-78.636-44.702-80.98 23.432-15.172 37.945-42.979 37.945-74.486 0-54.244-31.5-89.252-105.498-89.252h-70.667c-13.255 0-24 10.745-24 24V372c0 13.255 10.745 24 24 24h22.567c13.255 0 24-10.745 24-24v-71.663h25.556l44.129 82.937a24.001 24.001 0 0 0 21.188 12.727h24.464c18.261-.001 29.829-19.591 21.018-35.587z"],reply:[512,512,[],"f3e5","M8.309 189.836L184.313 37.851C199.719 24.546 224 35.347 224 56.015v80.053c160.629 1.839 288 34.032 288 186.258 0 61.441-39.581 122.309-83.333 154.132-13.653 9.931-33.111-2.533-28.077-18.631 45.344-145.012-21.507-183.51-176.59-185.742V360c0 20.7-24.3 31.453-39.687 18.164l-176.004-152c-11.071-9.562-11.086-26.753 0-36.328z"],"reply-all":[576,512,[],"f122","M136.309 189.836L312.313 37.851C327.72 24.546 352 35.348 352 56.015v82.763c129.182 10.231 224 52.212 224 183.548 0 61.441-39.582 122.309-83.333 154.132-13.653 9.931-33.111-2.533-28.077-18.631 38.512-123.162-3.922-169.482-112.59-182.015v84.175c0 20.701-24.3 31.453-39.687 18.164L136.309 226.164c-11.071-9.561-11.086-26.753 0-36.328zm-128 36.328L184.313 378.15C199.7 391.439 224 380.687 224 359.986v-15.818l-108.606-93.785A55.96 55.96 0 0 1 96 207.998a55.953 55.953 0 0 1 19.393-42.38L224 71.832V56.015c0-20.667-24.28-31.469-39.687-18.164L8.309 189.836c-11.086 9.575-11.071 26.767 0 36.328z"],retweet:[640,512,[],"f079","M629.657 343.598L528.971 444.284c-9.373 9.372-24.568 9.372-33.941 0L394.343 343.598c-9.373-9.373-9.373-24.569 0-33.941l10.823-10.823c9.562-9.562 25.133-9.34 34.419.492L480 342.118V160H292.451a24.005 24.005 0 0 1-16.971-7.029l-16-16C244.361 121.851 255.069 96 276.451 96H520c13.255 0 24 10.745 24 24v222.118l40.416-42.792c9.285-9.831 24.856-10.054 34.419-.492l10.823 10.823c9.372 9.372 9.372 24.569-.001 33.941zm-265.138 15.431A23.999 23.999 0 0 0 347.548 352H160V169.881l40.416 42.792c9.286 9.831 24.856 10.054 34.419.491l10.822-10.822c9.373-9.373 9.373-24.569 0-33.941L144.971 67.716c-9.373-9.373-24.569-9.373-33.941 0L10.343 168.402c-9.373 9.373-9.373 24.569 0 33.941l10.822 10.822c9.562 9.562 25.133 9.34 34.419-.491L96 169.881V392c0 13.255 10.745 24 24 24h243.549c21.382 0 32.09-25.851 16.971-40.971l-16.001-16z"],ribbon:[448,512,[],"f4d6","M6.1 444.3c-9.6 10.8-7.5 27.6 4.5 35.7l68.8 27.9c9.9 6.7 23.3 5 31.3-3.8l91.8-101.9-79.2-87.9-117.2 130zm435.8 0s-292-324.6-295.4-330.1c15.4-8.4 40.2-17.9 77.5-17.9s62.1 9.5 77.5 17.9c-3.3 5.6-56 64.6-56 64.6l79.1 87.7 34.2-38c28.7-31.9 33.3-78.6 11.4-115.5l-43.7-73.5c-4.3-7.2-9.9-13.3-16.8-18-40.7-27.6-127.4-29.7-171.4 0-6.9 4.7-12.5 10.8-16.8 18l-43.6 73.2c-1.5 2.5-37.1 62.2 11.5 116L337.5 504c8 8.9 21.4 10.5 31.3 3.8l68.8-27.9c11.9-8 14-24.8 4.3-35.6z"],road:[576,512,[],"f018","M567.3 383.6L429.9 78.2C426 69.5 417.4 64 408 64h-96.1l1.9 18.8c.7 7.1-4.8 13.2-11.9 13.2H274c-7.1 0-12.7-6.2-11.9-13.2L264 64h-96c-9.4 0-18 5.5-21.9 14.2L8.7 383.6C3.2 395.8 0 409.6 0 424c0 13.3 10.7 24 24 24h213.6c-7.1 0-12.7-6.2-11.9-13.2l10.8-104c.6-6.1 5.8-10.8 11.9-10.8h79.2c6.1 0 11.3 4.6 11.9 10.8l10.8 104c.7 7.1-4.8 13.2-11.9 13.2H552c13.2 0 24-10.7 24-24 0-13.9-3-27.7-8.7-40.4zM254.7 154.8l3.3-32c.6-6.1 5.8-10.8 11.9-10.8h36.2c6.1 0 11.3 4.6 11.9 10.8l3.3 32c.7 7.1-4.8 13.2-11.9 13.2h-42.8c-7.1 0-12.7-6.2-11.9-13.2zM321.8 288h-67.6c-7.1 0-12.7-6.2-11.9-13.2l7.4-72c.6-6.1 5.8-10.8 11.9-10.8h52.7c6.1 0 11.3 4.6 11.9 10.8l7.4 72c.9 7-4.7 13.2-11.8 13.2z"],rocket:[512,512,[],"f135","M505.1 19.1C503.8 13 499 8.2 492.9 6.9 460.7 0 435.5 0 410.4 0 307.2 0 245.3 55.2 199.1 128H94.9c-18.2 0-34.8 10.3-42.9 26.5L2.6 253.3c-8 16 3.6 34.7 21.5 34.7h95.1c-5.9 12.8-11.9 25.5-18 37.7-3.1 6.2-1.9 13.6 3 18.5l63.6 63.6c4.9 4.9 12.3 6.1 18.5 3 12.2-6.1 24.9-12 37.7-17.9V488c0 17.8 18.8 29.4 34.7 21.5l98.7-49.4c16.3-8.1 26.5-24.8 26.5-42.9V312.8c72.6-46.3 128-108.4 128-211.1.1-25.2.1-50.4-6.8-82.6zM400 160c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48z"],rss:[448,512,[],"f09e","M128.081 415.959c0 35.369-28.672 64.041-64.041 64.041S0 451.328 0 415.959s28.672-64.041 64.041-64.041 64.04 28.673 64.04 64.041zm175.66 47.25c-8.354-154.6-132.185-278.587-286.95-286.95C7.656 175.765 0 183.105 0 192.253v48.069c0 8.415 6.49 15.472 14.887 16.018 111.832 7.284 201.473 96.702 208.772 208.772.547 8.397 7.604 14.887 16.018 14.887h48.069c9.149.001 16.489-7.655 15.995-16.79zm144.249.288C439.596 229.677 251.465 40.445 16.503 32.01 7.473 31.686 0 38.981 0 48.016v48.068c0 8.625 6.835 15.645 15.453 15.999 191.179 7.839 344.627 161.316 352.465 352.465.353 8.618 7.373 15.453 15.999 15.453h48.068c9.034-.001 16.329-7.474 16.005-16.504z"],"rss-square":[448,512,[],"f143","M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM112 416c-26.51 0-48-21.49-48-48s21.49-48 48-48 48 21.49 48 48-21.49 48-48 48zm157.533 0h-34.335c-6.011 0-11.051-4.636-11.442-10.634-5.214-80.05-69.243-143.92-149.123-149.123-5.997-.39-10.633-5.431-10.633-11.441v-34.335c0-6.535 5.468-11.777 11.994-11.425 110.546 5.974 198.997 94.536 204.964 204.964.352 6.526-4.89 11.994-11.425 11.994zm103.027 0h-34.334c-6.161 0-11.175-4.882-11.427-11.038-5.598-136.535-115.204-246.161-251.76-251.76C68.882 152.949 64 147.935 64 141.774V107.44c0-6.454 5.338-11.664 11.787-11.432 167.83 6.025 302.21 141.191 308.205 308.205.232 6.449-4.978 11.787-11.432 11.787z"],"ruble-sign":[384,512,[],"f158","M239.36 320C324.48 320 384 260.542 384 175.071S324.48 32 239.36 32H76c-6.627 0-12 5.373-12 12v206.632H12c-6.627 0-12 5.373-12 12V308c0 6.627 5.373 12 12 12h52v32H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h52v52c0 6.627 5.373 12 12 12h58.56c6.627 0 12-5.373 12-12v-52H308c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12H146.56v-32h92.8zm-92.8-219.252h78.72c46.72 0 74.88 29.11 74.88 74.323 0 45.832-28.16 75.561-76.16 75.561h-77.44V100.748z"],"rupee-sign":[320,512,[],"f156","M308 96c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12H12C5.373 32 0 37.373 0 44v44.748c0 6.627 5.373 12 12 12h85.28c27.308 0 48.261 9.958 60.97 27.252H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h158.757c-6.217 36.086-32.961 58.632-74.757 58.632H12c-6.627 0-12 5.373-12 12v53.012c0 3.349 1.4 6.546 3.861 8.818l165.052 152.356a12.001 12.001 0 0 0 8.139 3.182h82.562c10.924 0 16.166-13.408 8.139-20.818L116.871 319.906c76.499-2.34 131.144-53.395 138.318-127.906H308c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-58.69c-3.486-11.541-8.28-22.246-14.252-32H308z"],save:[448,512,[],"f0c7","M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z"],search:[512,512,[],"f002","M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"],"search-minus":[512,512,[],"f010","M304 192v32c0 6.6-5.4 12-12 12H124c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12zm201 284.7L476.7 505c-9.4 9.4-24.6 9.4-33.9 0L343 405.3c-4.5-4.5-7-10.6-7-17V372c-35.3 27.6-79.7 44-128 44C93.1 416 0 322.9 0 208S93.1 0 208 0s208 93.1 208 208c0 48.3-16.4 92.7-44 128h16.3c6.4 0 12.5 2.5 17 7l99.7 99.7c9.3 9.4 9.3 24.6 0 34zM344 208c0-75.2-60.8-136-136-136S72 132.8 72 208s60.8 136 136 136 136-60.8 136-136z"],"search-plus":[512,512,[],"f00e","M304 192v32c0 6.6-5.4 12-12 12h-56v56c0 6.6-5.4 12-12 12h-32c-6.6 0-12-5.4-12-12v-56h-56c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h56v-56c0-6.6 5.4-12 12-12h32c6.6 0 12 5.4 12 12v56h56c6.6 0 12 5.4 12 12zm201 284.7L476.7 505c-9.4 9.4-24.6 9.4-33.9 0L343 405.3c-4.5-4.5-7-10.6-7-17V372c-35.3 27.6-79.7 44-128 44C93.1 416 0 322.9 0 208S93.1 0 208 0s208 93.1 208 208c0 48.3-16.4 92.7-44 128h16.3c6.4 0 12.5 2.5 17 7l99.7 99.7c9.3 9.4 9.3 24.6 0 34zM344 208c0-75.2-60.8-136-136-136S72 132.8 72 208s60.8 136 136 136 136-60.8 136-136z"],seedling:[512,512,[],"f4d8","M64 96H0c0 123.7 100.3 224 224 224v144c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V320C288 196.3 187.7 96 64 96zm384-64c-84.2 0-157.4 46.5-195.7 115.2 27.7 30.2 48.2 66.9 59 107.6C424 243.1 512 147.9 512 32h-64z"],server:[512,512,[],"f233","M480 160H32c-17.673 0-32-14.327-32-32V64c0-17.673 14.327-32 32-32h448c17.673 0 32 14.327 32 32v64c0 17.673-14.327 32-32 32zm-48-88c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm-64 0c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm112 248H32c-17.673 0-32-14.327-32-32v-64c0-17.673 14.327-32 32-32h448c17.673 0 32 14.327 32 32v64c0 17.673-14.327 32-32 32zm-48-88c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm-64 0c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm112 248H32c-17.673 0-32-14.327-32-32v-64c0-17.673 14.327-32 32-32h448c17.673 0 32 14.327 32 32v64c0 17.673-14.327 32-32 32zm-48-88c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm-64 0c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24z"],share:[512,512,[],"f064","M503.691 189.836L327.687 37.851C312.281 24.546 288 35.347 288 56.015v80.053C127.371 137.907 0 170.1 0 322.326c0 61.441 39.581 122.309 83.333 154.132 13.653 9.931 33.111-2.533 28.077-18.631C66.066 312.814 132.917 274.316 288 272.085V360c0 20.7 24.3 31.453 39.687 18.164l176.004-152c11.071-9.562 11.086-26.753 0-36.328z"],"share-alt":[448,512,[],"f1e0","M352 320c-22.608 0-43.387 7.819-59.79 20.895l-102.486-64.054a96.551 96.551 0 0 0 0-41.683l102.486-64.054C308.613 184.181 329.392 192 352 192c53.019 0 96-42.981 96-96S405.019 0 352 0s-96 42.981-96 96c0 7.158.79 14.13 2.276 20.841L155.79 180.895C139.387 167.819 118.608 160 96 160c-53.019 0-96 42.981-96 96s42.981 96 96 96c22.608 0 43.387-7.819 59.79-20.895l102.486 64.054A96.301 96.301 0 0 0 256 416c0 53.019 42.981 96 96 96s96-42.981 96-96-42.981-96-96-96z"],"share-alt-square":[448,512,[],"f1e1","M448 80v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48zM304 296c-14.562 0-27.823 5.561-37.783 14.671l-67.958-40.775a56.339 56.339 0 0 0 0-27.793l67.958-40.775C276.177 210.439 289.438 216 304 216c30.928 0 56-25.072 56-56s-25.072-56-56-56-56 25.072-56 56c0 4.797.605 9.453 1.74 13.897l-67.958 40.775C171.823 205.561 158.562 200 144 200c-30.928 0-56 25.072-56 56s25.072 56 56 56c14.562 0 27.823-5.561 37.783-14.671l67.958 40.775a56.088 56.088 0 0 0-1.74 13.897c0 30.928 25.072 56 56 56s56-25.072 56-56C360 321.072 334.928 296 304 296z"],"share-square":[576,512,[],"f14d","M568.482 177.448L424.479 313.433C409.3 327.768 384 317.14 384 295.985v-71.963c-144.575.97-205.566 35.113-164.775 171.353 4.483 14.973-12.846 26.567-25.006 17.33C155.252 383.105 120 326.488 120 269.339c0-143.937 117.599-172.5 264-173.312V24.012c0-21.174 25.317-31.768 40.479-17.448l144.003 135.988c10.02 9.463 10.028 25.425 0 34.896zM384 379.128V448H64V128h50.916a11.99 11.99 0 0 0 8.648-3.693c14.953-15.568 32.237-27.89 51.014-37.676C185.708 80.83 181.584 64 169.033 64H48C21.49 64 0 85.49 0 112v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48v-88.806c0-8.288-8.197-14.066-16.011-11.302a71.83 71.83 0 0 1-34.189 3.377c-7.27-1.046-13.8 4.514-13.8 11.859z"],"shekel-sign":[448,512,[],"f20b","M170.12 96H80v372c0 6.627-5.373 12-12 12H12c-6.627 0-12-5.373-12-12V44c0-6.627 5.373-12 12-12h168.36C265.48 32 325 89.6 325 175.071V359c0 6.627-5.373 12-12 12h-44c-13.255 0-24-10.745-24-24V170.323C245 125.11 216.839 96 170.12 96zM436 32h-56c-6.627 0-12 5.373-12 12v372h-90.12c-46.72 0-74.88-29.11-74.88-74.323V165c0-13.255-10.745-24-24-24h-44c-6.627 0-12 5.373-12 12v183.929C123 422.4 182.52 480 267.64 480H436c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12z"],"shield-alt":[512,512,[],"f3ed","M496 128c0 221.282-135.934 344.645-221.539 380.308a48 48 0 0 1-36.923 0C130.495 463.713 16 326.487 16 128a48 48 0 0 1 29.539-44.308l192-80a48 48 0 0 1 36.923 0l192 80A48 48 0 0 1 496 128zM256 446.313l.066.034c93.735-46.689 172.497-156.308 175.817-307.729L256 65.333v380.98z"],ship:[640,512,[],"f21a","M496.616 372.639l70.012-70.012c16.899-16.9 9.942-45.771-12.836-53.092L512 236.102V96c0-17.673-14.327-32-32-32h-64V24c0-13.255-10.745-24-24-24H248c-13.255 0-24 10.745-24 24v40h-64c-17.673 0-32 14.327-32 32v140.102l-41.792 13.433c-22.753 7.313-29.754 36.173-12.836 53.092l70.012 70.012C125.828 416.287 85.587 448 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24 61.023 0 107.499-20.61 143.258-59.396C181.677 487.432 216.021 512 256 512h128c39.979 0 74.323-24.568 88.742-59.396C508.495 491.384 554.968 512 616 512c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24-60.817 0-101.542-31.001-119.384-75.361zM192 128h256v87.531l-118.208-37.995a31.995 31.995 0 0 0-19.584 0L192 215.531V128z"],"shipping-fast":[640,512,[],"f48b","M624 352h-16V243.9c0-12.7-5.1-24.9-14.1-33.9L494 110.1c-9-9-21.2-14.1-33.9-14.1H416V48c0-26.5-21.5-48-48-48H112C85.5 0 64 21.5 64 48v48H8c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8h272c4.4 0 8 3.6 8 8v16c0 4.4-3.6 8-8 8H40c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8h208c4.4 0 8 3.6 8 8v16c0 4.4-3.6 8-8 8H8c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8h208c4.4 0 8 3.6 8 8v16c0 4.4-3.6 8-8 8H64v128c0 53 43 96 96 96s96-43 96-96h128c0 53 43 96 96 96s96-43 96-96h48c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zM160 464c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zm320 0c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zm80-208H416V144h44.1l99.9 99.9V256z"],"shopping-bag":[448,512,[],"f290","M352 160v-32C352 57.42 294.579 0 224 0 153.42 0 96 57.42 96 128v32H0v272c0 44.183 35.817 80 80 80h288c44.183 0 80-35.817 80-80V160h-96zm-192-32c0-35.29 28.71-64 64-64s64 28.71 64 64v32H160v-32zm160 120c-13.255 0-24-10.745-24-24s10.745-24 24-24 24 10.745 24 24-10.745 24-24 24zm-192 0c-13.255 0-24-10.745-24-24s10.745-24 24-24 24 10.745 24 24-10.745 24-24 24z"],"shopping-basket":[576,512,[],"f291","M576 216v16c0 13.255-10.745 24-24 24h-8l-26.113 182.788C514.509 462.435 494.257 480 470.37 480H105.63c-23.887 0-44.139-17.565-47.518-41.212L32 256h-8c-13.255 0-24-10.745-24-24v-16c0-13.255 10.745-24 24-24h67.341l106.78-146.821c10.395-14.292 30.407-17.453 44.701-7.058 14.293 10.395 17.453 30.408 7.058 44.701L170.477 192h235.046L326.12 82.821c-10.395-14.292-7.234-34.306 7.059-44.701 14.291-10.395 34.306-7.235 44.701 7.058L484.659 192H552c13.255 0 24 10.745 24 24zM312 392V280c0-13.255-10.745-24-24-24s-24 10.745-24 24v112c0 13.255 10.745 24 24 24s24-10.745 24-24zm112 0V280c0-13.255-10.745-24-24-24s-24 10.745-24 24v112c0 13.255 10.745 24 24 24s24-10.745 24-24zm-224 0V280c0-13.255-10.745-24-24-24s-24 10.745-24 24v112c0 13.255 10.745 24 24 24s24-10.745 24-24z"],"shopping-cart":[576,512,[],"f07a","M528.12 301.319l47.273-208C578.806 78.301 567.391 64 551.99 64H159.208l-9.166-44.81C147.758 8.021 137.93 0 126.529 0H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24h69.883l70.248 343.435C147.325 417.1 136 435.222 136 456c0 30.928 25.072 56 56 56s56-25.072 56-56c0-15.674-6.447-29.835-16.824-40h209.647C430.447 426.165 424 440.326 424 456c0 30.928 25.072 56 56 56s56-25.072 56-56c0-22.172-12.888-41.332-31.579-50.405l5.517-24.276c3.413-15.018-8.002-29.319-23.403-29.319H218.117l-6.545-32h293.145c11.206 0 20.92-7.754 23.403-18.681z"],shower:[512,512,[],"f2cc","M389.66 135.6L231.6 293.66c-9.37 9.37-24.57 9.37-33.94 0l-11.32-11.32c-9.37-9.37-9.37-24.57 0-33.94l.11-.11c-34.03-40.21-35.16-98.94-3.39-140.38-11.97-7.55-26.14-11.91-41.3-11.91C98.88 96 64 130.88 64 173.76V480H0V173.76C0 95.59 63.59 32 141.76 32c36.93 0 70.61 14.2 95.86 37.42 35.9-11.51 76.5-4.5 106.67 21.03l.11-.11c9.37-9.37 24.57-9.37 33.94 0l11.32 11.32c9.37 9.37 9.37 24.57 0 33.94zM384 208c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm32 0c0-8.837 7.163-16 16-16s16 7.163 16 16-7.163 16-16 16-16-7.163-16-16zm96 0c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-160 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm48-16c8.837 0 16 7.163 16 16s-7.163 16-16 16-16-7.163-16-16 7.163-16 16-16zm80 16c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-160 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm32 0c0-8.837 7.163-16 16-16s16 7.163 16 16-7.163 16-16 16-16-7.163-16-16zm96 0c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-128 32c0-8.837 7.163-16 16-16s16 7.163 16 16-7.163 16-16 16-16-7.163-16-16zm96 0c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-96 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm64 0c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-32 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-32 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16z"],sign:[512,512,[],"f4d9","M496 64H128V16c0-8.8-7.2-16-16-16H80c-8.8 0-16 7.2-16 16v48H16C7.2 64 0 71.2 0 80v32c0 8.8 7.2 16 16 16h48v368c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V128h368c8.8 0 16-7.2 16-16V80c0-8.8-7.2-16-16-16zM160 384h320V160H160v224z"],"sign-in-alt":[512,512,[],"f2f6","M416 448h-84c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h84c17.7 0 32-14.3 32-32V160c0-17.7-14.3-32-32-32h-84c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h84c53 0 96 43 96 96v192c0 53-43 96-96 96zm-47-201L201 79c-15-15-41-4.5-41 17v96H24c-13.3 0-24 10.7-24 24v96c0 13.3 10.7 24 24 24h136v96c0 21.5 26 32 41 17l168-168c9.3-9.4 9.3-24.6 0-34z"],"sign-language":[448,512,[],"f2a7","M91.434 483.987c-.307-16.018 13.109-29.129 29.13-29.129h62.293v-5.714H56.993c-16.021 0-29.437-13.111-29.13-29.129C28.16 404.491 40.835 392 56.428 392h126.429v-5.714H29.136c-16.021 0-29.437-13.111-29.13-29.129.297-15.522 12.973-28.013 28.566-28.013h154.286v-5.714H57.707c-16.021 0-29.437-13.111-29.13-29.129.297-15.522 12.973-28.013 28.566-28.013h168.566l-31.085-22.606c-12.762-9.281-15.583-27.149-6.302-39.912 9.281-12.761 27.15-15.582 39.912-6.302l123.361 89.715a34.287 34.287 0 0 1 14.12 27.728v141.136c0 15.91-10.946 29.73-26.433 33.374l-80.471 18.934a137.16 137.16 0 0 1-31.411 3.646H120c-15.593-.001-28.269-12.492-28.566-28.014zm73.249-225.701h36.423l-11.187-8.136c-18.579-13.511-20.313-40.887-3.17-56.536l-13.004-16.7c-9.843-12.641-28.43-15.171-40.88-5.088-12.065 9.771-14.133 27.447-4.553 39.75l36.371 46.71zm283.298-2.103l-5.003-152.452c-.518-15.771-13.722-28.136-29.493-27.619-15.773.518-28.137 13.722-27.619 29.493l1.262 38.415L283.565 11.019c-9.58-12.303-27.223-14.63-39.653-5.328-12.827 9.599-14.929 28.24-5.086 40.881l76.889 98.745-4.509 3.511-94.79-121.734c-9.58-12.303-27.223-14.63-39.653-5.328-12.827 9.599-14.929 28.24-5.086 40.881l94.443 121.288-4.509 3.511-77.675-99.754c-9.58-12.303-27.223-14.63-39.653-5.328-12.827 9.599-14.929 28.24-5.086 40.881l52.053 66.849c12.497-8.257 29.055-8.285 41.69.904l123.36 89.714c10.904 7.93 17.415 20.715 17.415 34.198v16.999l61.064-47.549a34.285 34.285 0 0 0 13.202-28.177z"],"sign-out-alt":[512,512,[],"f2f5","M497 273L329 441c-15 15-41 4.5-41-17v-96H152c-13.3 0-24-10.7-24-24v-96c0-13.3 10.7-24 24-24h136V88c0-21.4 25.9-32 41-17l168 168c9.3 9.4 9.3 24.6 0 34zM192 436v-40c0-6.6-5.4-12-12-12H96c-17.7 0-32-14.3-32-32V160c0-17.7 14.3-32 32-32h84c6.6 0 12-5.4 12-12V76c0-6.6-5.4-12-12-12H96c-53 0-96 43-96 96v192c0 53 43 96 96 96h84c6.6 0 12-5.4 12-12z"],signal:[640,512,[],"f012","M36 384h56c6.6 0 12 5.4 12 12v104c0 6.6-5.4 12-12 12H36c-6.6 0-12-5.4-12-12V396c0-6.6 5.4-12 12-12zm116-36v152c0 6.6 5.4 12 12 12h56c6.6 0 12-5.4 12-12V348c0-6.6-5.4-12-12-12h-56c-6.6 0-12 5.4-12 12zm128-80v232c0 6.6 5.4 12 12 12h56c6.6 0 12-5.4 12-12V268c0-6.6-5.4-12-12-12h-56c-6.6 0-12 5.4-12 12zm128-112v344c0 6.6 5.4 12 12 12h56c6.6 0 12-5.4 12-12V156c0-6.6-5.4-12-12-12h-56c-6.6 0-12 5.4-12 12zM536 12v488c0 6.6 5.4 12 12 12h56c6.6 0 12-5.4 12-12V12c0-6.6-5.4-12-12-12h-56c-6.6 0-12 5.4-12 12z"],sitemap:[640,512,[],"f0e8","M616 320h-48v-48c0-22.056-17.944-40-40-40H344v-40h48c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24H248c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h48v40H112c-22.056 0-40 17.944-40 40v48H24c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24V344c0-13.255-10.745-24-24-24h-48v-40h176v40h-48c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24V344c0-13.255-10.745-24-24-24h-48v-40h176v40h-48c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24V344c0-13.255-10.745-24-24-24z"],"sliders-h":[576,512,[],"f1de","M576 80v40c0 6.6-5.4 12-12 12H160v8c0 13.3-10.7 24-24 24h-16c-13.3 0-24-10.7-24-24v-8H12c-6.6 0-12-5.4-12-12V80c0-6.6 5.4-12 12-12h84v-8c0-13.3 10.7-24 24-24h16c13.3 0 24 10.7 24 24v8h404c6.6 0 12 5.4 12 12zm-12 148h-84v-8c0-13.3-10.7-24-24-24h-16c-13.3 0-24 10.7-24 24v8H12c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h404v8c0 13.3 10.7 24 24 24h16c13.3 0 24-10.7 24-24v-8h84c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12zm0 160H288v-8c0-13.3-10.7-24-24-24h-16c-13.3 0-24 10.7-24 24v8H12c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h212v8c0 13.3 10.7 24 24 24h16c13.3 0 24-10.7 24-24v-8h276c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12z"],smile:[496,512,[],"f118","M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm80 168c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zm-160 0c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zm194.8 170.2C334.3 380.4 292.5 400 248 400s-86.3-19.6-114.8-53.8c-5.7-6.8-4.7-16.9 2-22.5 6.8-5.7 16.9-4.7 22.5 2 22.4 26.9 55.2 42.2 90.2 42.2s67.8-15.4 90.2-42.2c5.7-6.8 15.7-7.7 22.5-2 6.9 5.7 7.8 15.8 2.2 22.5z"],smoking:[640,512,[],"f48d","M632 352h-48c-4.4 0-8 3.6-8 8v144c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V360c0-4.4-3.6-8-8-8zM553.3 87.1c-5.7-3.8-9.3-10-9.3-16.8V8c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v62.3c0 22 10.2 43.4 28.6 55.4 42.2 27.3 67.4 73.8 67.4 124V280c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8v-30.3c0-65.5-32.4-126.2-86.7-162.6zM432 352H48c-26.5 0-48 21.5-48 48v64c0 26.5 21.5 48 48 48h384c8.8 0 16-7.2 16-16V368c0-8.8-7.2-16-16-16zm-32 112H224v-64h176v64zm87.7-322.4C463.8 125 448 99.3 448 70.3V8c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v66.4c0 43.7 24.6 81.6 60.3 106.7 22.4 15.7 35.7 41.2 35.7 68.6V280c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8v-30.3c0-43.3-21-83.4-56.3-108.1zM536 352h-48c-4.4 0-8 3.6-8 8v144c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V360c0-4.4-3.6-8-8-8z"],snowflake:[448,512,[],"f2dc","M444.816 301.639a24.12 24.12 0 0 0 2.661-16.978c-2.725-12.966-15.339-21.245-28.174-18.492l-87.407 25.046L264 256l67.896-35.215 87.407 25.046c12.835 2.753 25.449-5.526 28.174-18.492 2.725-12.966-5.471-25.708-18.305-28.461l-47.477-7.137 53.077-30.956c11.363-6.627 15.257-21.306 8.696-32.785-6.561-11.479-21.091-15.412-32.454-8.785l-53.077 30.956 17.621-45.104c4.057-12.606-2.768-26.146-15.247-30.245-12.478-4.099-25.883 2.797-29.94 15.402l-22.232 88.99-60.38 35.215V144l65.175-63.945c8.778-9.852 7.987-25.027-1.766-33.894-9.753-8.867-24.775-8.068-33.552 1.784l-29.857 37.967V24c0-13.255-10.637-24-23.758-24s-23.758 10.745-23.758 24v61.912l-29.857-37.967c-8.779-9.852-23.799-10.652-33.552-1.784-9.753 8.867-10.543 24.042-1.766 33.894L200.242 144v70.431l-60.38-35.215-22.232-88.99c-4.057-12.605-17.462-19.501-29.94-15.402-12.478 4.099-19.304 17.64-15.247 30.245l17.62 45.104-53.077-30.956c-11.363-6.627-25.893-2.694-32.454 8.785s-2.667 26.157 8.696 32.785l53.077 30.956-47.477 7.137C5.993 201.634-2.203 214.375.523 227.341c2.725 12.965 15.339 21.245 28.174 18.492l87.407-25.046L184 256l-67.896 35.215-87.406-25.045c-12.835-2.753-25.449 5.526-28.174 18.492-2.725 12.967 5.47 25.708 18.305 28.461l47.477 7.137-53.077 30.956C1.866 357.843-2.027 372.521 4.533 384s21.091 15.412 32.454 8.785l53.077-30.956-17.62 45.104a24.157 24.157 0 0 0 2.022 19.428c2.831 4.953 7.416 8.909 13.224 10.816 12.478 4.099 25.883-2.797 29.94-15.402l22.232-88.99 60.38-35.215V368l-65.175 63.945c-8.778 9.852-7.987 25.027 1.766 33.894 9.754 8.868 24.774 8.068 33.552-1.784l29.857-37.967V488c0 13.255 10.637 24 23.758 24s23.758-10.745 23.758-24v-61.912l29.857 37.967A23.59 23.59 0 0 0 295.282 472a23.534 23.534 0 0 0 15.885-6.161c9.753-8.867 10.544-24.042 1.766-33.894L247.758 368v-70.431l60.38 35.215 22.232 88.99c4.057 12.605 17.462 19.501 29.94 15.402 12.479-4.099 19.304-17.64 15.247-30.245l-17.621-45.104 53.077 30.956c11.363 6.627 25.893 2.694 32.454-8.785s2.667-26.157-8.696-32.785l-53.077-30.956 47.477-7.137c6.86-1.469 12.394-5.793 15.645-11.481z"],sort:[320,512,[],"f0dc","M41 288h238c21.4 0 32.1 25.9 17 41L177 448c-9.4 9.4-24.6 9.4-33.9 0L24 329c-15.1-15.1-4.4-41 17-41zm255-105L177 64c-9.4-9.4-24.6-9.4-33.9 0L24 183c-15.1 15.1-4.4 41 17 41h238c21.4 0 32.1-25.9 17-41z"],"sort-alpha-down":[448,512,[],"f15d","M187.298 395.314l-79.984 80.002c-6.248 6.247-16.383 6.245-22.627 0L4.705 395.314C-5.365 385.244 1.807 368 16.019 368H64V48c0-8.837 7.163-16 16-16h32c8.837 0 16 7.163 16 16v320h47.984c14.241 0 21.363 17.264 11.314 27.314zm119.075-180.007A12 12 0 0 1 294.838 224h-35.717c-8.22 0-14.007-8.078-11.362-15.861l57.096-168A12 12 0 0 1 316.217 32h39.566c5.139 0 9.708 3.273 11.362 8.139l57.096 168C426.886 215.922 421.1 224 412.879 224h-35.735a12 12 0 0 1-11.515-8.622l-8.301-28.299h-42.863l-8.092 28.228zm22.857-78.697h13.367l-6.6-22.937-6.767 22.937zm12.575 287.323l67.451-95.698a12 12 0 0 0 2.192-6.913V300c0-6.627-5.373-12-12-12H274.522c-6.627 0-12 5.373-12 12v28.93c0 6.627 5.373 12 12 12h56.469c-.739.991-1.497 2.036-2.27 3.133l-67.203 95.205a12.001 12.001 0 0 0-2.196 6.92V468c0 6.627 5.373 12 12 12h129.355c6.627 0 12-5.373 12-12v-28.93c0-6.627-5.373-12-12-12h-61.146c.74-.993 1.5-2.039 2.274-3.137z"],"sort-alpha-up":[448,512,[],"f15e","M4.702 116.686l79.984-80.002c6.248-6.247 16.383-6.245 22.627 0l79.981 80.002c10.07 10.07 2.899 27.314-11.314 27.314H128v320c0 8.837-7.163 16-16 16H80c-8.837 0-16-7.163-16-16V144H16.016c-14.241 0-21.363-17.264-11.314-27.314zm301.671 98.621A12 12 0 0 1 294.838 224h-35.717c-8.22 0-14.007-8.078-11.362-15.861l57.096-168A12 12 0 0 1 316.217 32h39.566c5.139 0 9.708 3.273 11.362 8.139l57.096 168C426.886 215.922 421.1 224 412.879 224h-35.735a12 12 0 0 1-11.515-8.622l-8.301-28.299h-42.863l-8.092 28.228zm22.857-78.697h13.367l-6.6-22.937-6.767 22.937zm12.575 287.323l67.451-95.698a12 12 0 0 0 2.192-6.913V300c0-6.627-5.373-12-12-12H274.522c-6.627 0-12 5.373-12 12v28.93c0 6.627 5.373 12 12 12h56.469c-.739.991-1.497 2.036-2.27 3.133l-67.203 95.205a12.001 12.001 0 0 0-2.196 6.92V468c0 6.627 5.373 12 12 12h129.355c6.627 0 12-5.373 12-12v-28.93c0-6.627-5.373-12-12-12h-61.146c.74-.993 1.5-2.039 2.274-3.137z"],"sort-amount-down":[512,512,[],"f160","M187.298 395.314l-79.984 80.002c-6.248 6.247-16.383 6.245-22.627 0L4.705 395.314C-5.365 385.244 1.807 368 16.019 368H64V48c0-8.837 7.163-16 16-16h32c8.837 0 16 7.163 16 16v320h47.984c14.241 0 21.363 17.264 11.314 27.314zM240 96h256c8.837 0 16-7.163 16-16V48c0-8.837-7.163-16-16-16H240c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16zm-16 112v-32c0-8.837 7.163-16 16-16h192c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H240c-8.837 0-16-7.163-16-16zm0 256v-32c0-8.837 7.163-16 16-16h64c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-64c-8.837 0-16-7.163-16-16zm0-128v-32c0-8.837 7.163-16 16-16h128c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H240c-8.837 0-16-7.163-16-16z"],"sort-amount-up":[512,512,[],"f161","M4.702 116.686l79.984-80.002c6.248-6.247 16.383-6.245 22.627 0l79.981 80.002c10.07 10.07 2.899 27.314-11.314 27.314H128v320c0 8.837-7.163 16-16 16H80c-8.837 0-16-7.163-16-16V144H16.016c-14.241 0-21.363-17.264-11.314-27.314zM240 96h256c8.837 0 16-7.163 16-16V48c0-8.837-7.163-16-16-16H240c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16zm-16 112v-32c0-8.837 7.163-16 16-16h192c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H240c-8.837 0-16-7.163-16-16zm0 256v-32c0-8.837 7.163-16 16-16h64c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-64c-8.837 0-16-7.163-16-16zm0-128v-32c0-8.837 7.163-16 16-16h128c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H240c-8.837 0-16-7.163-16-16z"],"sort-down":[320,512,[],"f0dd","M41 288h238c21.4 0 32.1 25.9 17 41L177 448c-9.4 9.4-24.6 9.4-33.9 0L24 329c-15.1-15.1-4.4-41 17-41z"],"sort-numeric-down":[448,512,[],"f162","M308.811 113.787l-19.448-20.795c-4.522-4.836-4.274-12.421.556-16.95l43.443-40.741a11.999 11.999 0 0 1 8.209-3.247h31.591c6.627 0 12 5.373 12 12v127.07h25.66c6.627 0 12 5.373 12 12v28.93c0 6.627-5.373 12-12 12H301.649c-6.627 0-12-5.373-12-12v-28.93c0-6.627 5.373-12 12-12h25.414v-57.938c-7.254 6.58-14.211 4.921-18.252.601zm-30.57 238.569c0-32.653 23.865-67.356 68.094-67.356 38.253 0 79.424 28.861 79.424 92.228 0 51.276-32.237 105.772-91.983 105.772-17.836 0-30.546-3.557-38.548-6.781-5.79-2.333-8.789-8.746-6.922-14.703l9.237-29.48c2.035-6.496 9.049-9.983 15.467-7.716 13.029 4.602 27.878 5.275 38.103-4.138-38.742 5.072-72.872-25.36-72.872-67.826zm92.273 19.338c0-22.285-15.302-36.505-25.835-36.505-8.642 0-13.164 7.965-13.164 15.832 0 5.669 1.815 24.168 25.168 24.168 9.973 0 13.377-2.154 13.744-2.731.021-.046.087-.291.087-.764zM175.984 368H128V48c0-8.837-7.163-16-16-16H80c-8.837 0-16 7.163-16 16v320H16.019c-14.212 0-21.384 17.244-11.314 27.314l79.981 80.002c6.245 6.245 16.38 6.247 22.627 0l79.984-80.002c10.05-10.05 2.928-27.314-11.313-27.314z"],"sort-numeric-up":[448,512,[],"f163","M308.811 113.787l-19.448-20.795c-4.522-4.836-4.274-12.421.556-16.95l43.443-40.741a11.999 11.999 0 0 1 8.209-3.247h31.591c6.627 0 12 5.373 12 12v127.07h25.66c6.627 0 12 5.373 12 12v28.93c0 6.627-5.373 12-12 12H301.649c-6.627 0-12-5.373-12-12v-28.93c0-6.627 5.373-12 12-12h25.414v-57.938c-7.254 6.58-14.211 4.921-18.252.601zm-30.57 238.569c0-32.653 23.865-67.356 68.094-67.356 38.253 0 79.424 28.861 79.424 92.228 0 51.276-32.237 105.772-91.983 105.772-17.836 0-30.546-3.557-38.548-6.781-5.79-2.333-8.789-8.746-6.922-14.703l9.237-29.48c2.035-6.496 9.049-9.983 15.467-7.716 13.029 4.602 27.878 5.275 38.103-4.138-38.742 5.072-72.872-25.36-72.872-67.826zm92.273 19.338c0-22.285-15.302-36.505-25.835-36.505-8.642 0-13.164 7.965-13.164 15.832 0 5.669 1.815 24.168 25.168 24.168 9.973 0 13.377-2.154 13.744-2.731.021-.046.087-.291.087-.764zM16.016 144H64v320c0 8.837 7.163 16 16 16h32c8.837 0 16-7.163 16-16V144h47.981c14.212 0 21.384-17.244 11.314-27.314l-79.981-80.002c-6.245-6.245-16.38-6.247-22.627 0L4.702 116.686C-5.347 126.736 1.775 144 16.016 144z"],"sort-up":[320,512,[],"f0de","M279 224H41c-21.4 0-32.1-25.9-17-41L143 64c9.4-9.4 24.6-9.4 33.9 0l119 119c15.2 15.1 4.5 41-16.9 41z"],"space-shuttle":[640,512,[],"f197","M592.604 208.244C559.735 192.836 515.777 184 472 184H186.327c-4.952-6.555-10.585-11.978-16.72-16H376C229.157 137.747 219.403 32 96.003 32H96v128H80V32c-26.51 0-48 28.654-48 64v64c-23.197 0-32 10.032-32 24v40c0 13.983 8.819 24 32 24v16c-23.197 0-32 10.032-32 24v40c0 13.983 8.819 24 32 24v64c0 35.346 21.49 64 48 64V352h16v128h.003c123.4 0 133.154-105.747 279.997-136H169.606c6.135-4.022 11.768-9.445 16.72-16H472c43.777 0 87.735-8.836 120.604-24.244C622.282 289.845 640 271.992 640 256s-17.718-33.845-47.396-47.756zM488 296a8 8 0 0 1-8-8v-64a8 8 0 0 1 8-8c31.909 0 31.942 80 0 80z"],spinner:[512,512,[],"f110","M304 48c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-48 368c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm208-208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zM96 256c0-26.51-21.49-48-48-48S0 229.49 0 256s21.49 48 48 48 48-21.49 48-48zm12.922 99.078c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.491-48-48-48zm294.156 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.49-48-48-48zM108.922 60.922c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.491-48-48-48z"],square:[448,512,[],"f0c8","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z"],"square-full":[512,512,[],"f45c","M512 512H0V0h512v512z"],star:[576,512,[],"f005","M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"],"star-half":[576,512,[],"f089","M288 0c-11.4 0-22.8 5.9-28.7 17.8L194 150.2 47.9 171.4c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.1 23 46 46.4 33.7L288 439.6V0z"],"step-backward":[448,512,[],"f048","M64 468V44c0-6.6 5.4-12 12-12h48c6.6 0 12 5.4 12 12v176.4l195.5-181C352.1 22.3 384 36.6 384 64v384c0 27.4-31.9 41.7-52.5 24.6L136 292.7V468c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12z"],"step-forward":[448,512,[],"f051","M384 44v424c0 6.6-5.4 12-12 12h-48c-6.6 0-12-5.4-12-12V291.6l-195.5 181C95.9 489.7 64 475.4 64 448V64c0-27.4 31.9-41.7 52.5-24.6L312 219.3V44c0-6.6 5.4-12 12-12h48c6.6 0 12 5.4 12 12z"],stethoscope:[512,512,[],"f0f1","M447.1 112c-34.2.5-62.3 28.4-63 62.6-.5 24.3 12.5 45.6 32 56.8V344c0 57.3-50.2 104-112 104-60 0-109.2-44.1-111.9-99.2C265 333.8 320 269.2 320 192V36.6c0-11.4-8.1-21.3-19.3-23.5L237.8.5c-13-2.6-25.6 5.8-28.2 18.8L206.4 35c-2.6 13 5.8 25.6 18.8 28.2l30.7 6.1v121.4c0 52.9-42.2 96.7-95.1 97.2-53.4.5-96.9-42.7-96.9-96V69.4l30.7-6.1c13-2.6 21.4-15.2 18.8-28.2l-3.1-15.7C107.7 6.4 95.1-2 82.1.6L19.3 13C8.1 15.3 0 25.1 0 36.6V192c0 77.3 55.1 142 128.1 156.8C130.7 439.2 208.6 512 304 512c97 0 176-75.4 176-168V231.4c19.1-11.1 32-31.7 32-55.4 0-35.7-29.2-64.5-64.9-64zm.9 80c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16z"],"sticky-note":[448,512,[],"f249","M312 320h136V56c0-13.3-10.7-24-24-24H24C10.7 32 0 42.7 0 56v400c0 13.3 10.7 24 24 24h264V344c0-13.2 10.8-24 24-24zm129 55l-98 98c-4.5 4.5-10.6 7-17 7h-6V352h128v6.1c0 6.3-2.5 12.4-7 16.9z"],stop:[448,512,[],"f04d","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z"],"stop-circle":[512,512,[],"f28d","M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm96 328c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h160c8.8 0 16 7.2 16 16v160z"],stopwatch:[448,512,[],"f2f2","M432 304c0 114.9-93.1 208-208 208S16 418.9 16 304c0-104 76.3-190.2 176-205.5V64h-28c-6.6 0-12-5.4-12-12V12c0-6.6 5.4-12 12-12h120c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-28v34.5c37.5 5.8 71.7 21.6 99.7 44.6l27.5-27.5c4.7-4.7 12.3-4.7 17 0l28.3 28.3c4.7 4.7 4.7 12.3 0 17l-29.4 29.4-.6.6C419.7 223.3 432 262.2 432 304zm-176 36V188.5c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12V340c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12z"],"street-view":[512,512,[],"f21d","M192 64c0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64s-64-28.654-64-64zm112 80h-11.36c-22.711 10.443-49.59 10.894-73.28 0H208c-26.51 0-48 21.49-48 48v104c0 13.255 10.745 24 24 24h16v104c0 13.255 10.745 24 24 24h64c13.255 0 24-10.745 24-24V320h16c13.255 0 24-10.745 24-24V192c0-26.51-21.49-48-48-48zm85.642 189.152a72.503 72.503 0 0 1-29.01 27.009C391.133 365.251 480 385.854 480 416c0 46.304-167.656 64-224 64-70.303 0-224-20.859-224-64 0-30.123 88.361-50.665 119.367-55.839a72.516 72.516 0 0 1-29.01-27.009C74.959 343.395 0 367.599 0 416c0 77.111 178.658 96 256 96 77.249 0 256-18.865 256-96 0-48.403-74.967-72.606-122.358-82.848z"],strikethrough:[512,512,[],"f0cc","M496 288H16c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h480c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16zm-214.666 16c27.258 12.937 46.524 28.683 46.524 56.243 0 33.108-28.977 53.676-75.621 53.676-32.325 0-76.874-12.08-76.874-44.271V368c0-8.837-7.164-16-16-16H113.75c-8.836 0-16 7.163-16 16v19.204c0 66.845 77.717 101.82 154.487 101.82 88.578 0 162.013-45.438 162.013-134.424 0-19.815-3.618-36.417-10.143-50.6H281.334zm-30.952-96c-32.422-13.505-56.836-28.946-56.836-59.683 0-33.92 30.901-47.406 64.962-47.406 42.647 0 64.962 16.593 64.962 32.985V136c0 8.837 7.164 16 16 16h45.613c8.836 0 16-7.163 16-16v-30.318c0-52.438-71.725-79.875-142.575-79.875-85.203 0-150.726 40.972-150.726 125.646 0 22.71 4.665 41.176 12.777 56.547h129.823z"],subscript:[512,512,[],"f12c","M395.198 416c3.461-10.526 18.796-21.28 36.265-32.425 16.625-10.605 35.467-22.626 50.341-38.862 17.458-19.054 25.944-40.175 25.944-64.567 0-60.562-50.702-88.146-97.81-88.146-42.491 0-76.378 22.016-94.432 50.447-4.654 7.329-2.592 17.036 4.623 21.865l30.328 20.296c7.032 4.706 16.46 3.084 21.63-3.614 8.022-10.394 18.818-18.225 31.667-18.225 19.387 0 26.266 12.901 26.266 23.948 0 36.159-119.437 57.023-119.437 160.024 0 6.654.561 13.014 1.415 19.331 1.076 7.964 7.834 13.928 15.87 13.928H496c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16H395.198zM272 256c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-62.399a16 16 0 0 1-13.541-7.478l-45.701-72.615c-2.297-3.352-4.422-6.969-6.195-10.209-1.65 3.244-3.647 6.937-5.874 10.582l-44.712 72.147a15.999 15.999 0 0 1-13.6 7.572H16c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h26.325l56.552-82.709L46.111 96H16C7.163 96 0 88.837 0 80V48c0-8.837 7.163-16 16-16h68.806a16 16 0 0 1 13.645 7.644l39.882 65.126c2.072 3.523 4.053 7.171 5.727 10.37 1.777-3.244 3.92-6.954 6.237-10.537l40.332-65.035A15.999 15.999 0 0 1 204.226 32H272c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-27.979l-52.69 75.671L249.974 256H272z"],subway:[448,512,[],"f239","M448 96v256c0 51.815-61.624 96-130.022 96l62.98 49.721C386.905 502.417 383.562 512 376 512H72c-7.578 0-10.892-9.594-4.957-14.279L130.022 448C61.82 448 0 403.954 0 352V96C0 42.981 64 0 128 0h192c65 0 128 42.981 128 96zM200 232V120c0-13.255-10.745-24-24-24H72c-13.255 0-24 10.745-24 24v112c0 13.255 10.745 24 24 24h104c13.255 0 24-10.745 24-24zm200 0V120c0-13.255-10.745-24-24-24H272c-13.255 0-24 10.745-24 24v112c0 13.255 10.745 24 24 24h104c13.255 0 24-10.745 24-24zm-48 56c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm-256 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48z"],suitcase:[512,512,[],"f0f2","M128 480h256V80c0-26.5-21.5-48-48-48H176c-26.5 0-48 21.5-48 48v400zm64-384h128v32H192V96zm320 80v256c0 26.5-21.5 48-48 48h-48V128h48c26.5 0 48 21.5 48 48zM96 480H48c-26.5 0-48-21.5-48-48V176c0-26.5 21.5-48 48-48h48v352z"],sun:[512,512,[],"f185","M274.835 12.646l25.516 62.393c4.213 10.301 16.671 14.349 26.134 8.492l57.316-35.479c15.49-9.588 34.808 4.447 30.475 22.142l-16.03 65.475c-2.647 10.81 5.053 21.408 16.152 22.231l67.224 4.987c18.167 1.348 25.546 24.057 11.641 35.826L441.81 242.26c-8.495 7.19-8.495 20.289 0 27.479l51.454 43.548c13.906 11.769 6.527 34.478-11.641 35.826l-67.224 4.987c-11.099.823-18.799 11.421-16.152 22.231l16.03 65.475c4.332 17.695-14.986 31.73-30.475 22.142l-57.316-35.479c-9.463-5.858-21.922-1.81-26.134 8.492l-25.516 62.393c-6.896 16.862-30.774 16.862-37.67 0l-25.516-62.393c-4.213-10.301-16.671-14.349-26.134-8.492l-57.317 35.479c-15.49 9.588-34.808-4.447-30.475-22.142l16.03-65.475c2.647-10.81-5.053-21.408-16.152-22.231l-67.224-4.987c-18.167-1.348-25.546-24.057-11.641-35.826L70.19 269.74c8.495-7.19 8.495-20.289 0-27.479l-51.454-43.548c-13.906-11.769-6.527-34.478 11.641-35.826l67.224-4.987c11.099-.823 18.799-11.421 16.152-22.231l-16.03-65.475c-4.332-17.695 14.986-31.73 30.475-22.142l57.317 35.479c9.463 5.858 21.921 1.81 26.134-8.492l25.516-62.393c6.896-16.861 30.774-16.861 37.67 0zM392 256c0-74.991-61.01-136-136-136-74.991 0-136 61.009-136 136s61.009 136 136 136c74.99 0 136-61.009 136-136zm-32 0c0 57.346-46.654 104-104 104s-104-46.654-104-104 46.654-104 104-104 104 46.654 104 104z"],superscript:[512,512,[],"f12b","M395.198 256c3.461-10.526 18.796-21.28 36.265-32.425 16.625-10.605 35.467-22.626 50.341-38.862 17.458-19.054 25.944-40.175 25.944-64.567 0-60.562-50.702-88.146-97.81-88.146-42.491 0-76.378 22.016-94.432 50.447-4.654 7.329-2.592 17.036 4.623 21.865l30.328 20.296c7.032 4.706 16.46 3.084 21.63-3.614 8.022-10.394 18.818-18.225 31.667-18.225 19.387 0 26.266 12.901 26.266 23.948 0 36.159-119.437 57.023-119.437 160.024 0 6.654.561 13.014 1.415 19.331 1.076 7.964 7.834 13.928 15.87 13.928H496c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16H395.198zM272 416c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-62.399a16 16 0 0 1-13.541-7.478l-45.701-72.615c-2.297-3.352-4.422-6.969-6.195-10.209-1.65 3.244-3.647 6.937-5.874 10.582l-44.712 72.147a15.999 15.999 0 0 1-13.6 7.572H16c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h26.325l56.552-82.709L46.111 256H16c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h68.806a16 16 0 0 1 13.645 7.644l39.882 65.126c2.072 3.523 4.053 7.171 5.727 10.37 1.777-3.244 3.92-6.954 6.237-10.537l40.332-65.035a16 16 0 0 1 13.598-7.567H272c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-27.979l-52.69 75.671L249.974 416H272z"],sync:[512,512,[],"f021","M440.935 12.574l3.966 82.766C399.416 41.904 331.674 8 256 8 134.813 8 33.933 94.924 12.296 209.824 10.908 217.193 16.604 224 24.103 224h49.084c5.57 0 10.377-3.842 11.676-9.259C103.407 137.408 172.931 80 256 80c60.893 0 114.512 30.856 146.104 77.801l-101.53-4.865c-6.845-.328-12.574 5.133-12.574 11.986v47.411c0 6.627 5.373 12 12 12h200.333c6.627 0 12-5.373 12-12V12c0-6.627-5.373-12-12-12h-47.411c-6.853 0-12.315 5.729-11.987 12.574zM256 432c-60.895 0-114.517-30.858-146.109-77.805l101.868 4.871c6.845.327 12.573-5.134 12.573-11.986v-47.412c0-6.627-5.373-12-12-12H12c-6.627 0-12 5.373-12 12V500c0 6.627 5.373 12 12 12h47.385c6.863 0 12.328-5.745 11.985-12.599l-4.129-82.575C112.725 470.166 180.405 504 256 504c121.187 0 222.067-86.924 243.704-201.824 1.388-7.369-4.308-14.176-11.807-14.176h-49.084c-5.57 0-10.377 3.842-11.676 9.259C408.593 374.592 339.069 432 256 432z"],"sync-alt":[512,512,[],"f2f1","M370.72 133.28C339.458 104.008 298.888 87.962 255.848 88c-77.458.068-144.328 53.178-162.791 126.85-1.344 5.363-6.122 9.15-11.651 9.15H24.103c-7.498 0-13.194-6.807-11.807-14.176C33.933 94.924 134.813 8 256 8c66.448 0 126.791 26.136 171.315 68.685L463.03 40.97C478.149 25.851 504 36.559 504 57.941V192c0 13.255-10.745 24-24 24H345.941c-21.382 0-32.09-25.851-16.971-40.971l41.75-41.749zM32 296h134.059c21.382 0 32.09 25.851 16.971 40.971l-41.75 41.75c31.262 29.273 71.835 45.319 114.876 45.28 77.418-.07 144.315-53.144 162.787-126.849 1.344-5.363 6.122-9.15 11.651-9.15h57.304c7.498 0 13.194 6.807 11.807 14.176C478.067 417.076 377.187 504 256 504c-66.448 0-126.791-26.136-171.315-68.685L48.97 471.03C33.851 486.149 8 475.441 8 454.059V320c0-13.255 10.745-24 24-24z"],syringe:[512,512,[],"f48e","M201.5 174.8l55.7 55.8c3.1 3.1 3.1 8.2 0 11.3l-11.3 11.3c-3.1 3.1-8.2 3.1-11.3 0l-55.7-55.8-45.3 45.3 55.8 55.8c3.1 3.1 3.1 8.2 0 11.3l-11.3 11.3c-3.1 3.1-8.2 3.1-11.3 0L111 265.2l-26.4 26.4c-17.3 17.3-25.6 41.1-23 65.4l7.1 63.6L2.3 487c-3.1 3.1-3.1 8.2 0 11.3l11.3 11.3c3.1 3.1 8.2 3.1 11.3 0l66.3-66.3 63.6 7.1c23.9 2.6 47.9-5.4 65.4-23l181.9-181.9-135.7-135.7-64.9 65zm308.2-93.3L430.5 2.3c-3.1-3.1-8.2-3.1-11.3 0l-11.3 11.3c-3.1 3.1-3.1 8.2 0 11.3l28.3 28.3-45.3 45.3-56.6-56.6-17-17c-3.1-3.1-8.2-3.1-11.3 0l-33.9 33.9c-3.1 3.1-3.1 8.2 0 11.3l17 17L424.8 223l17 17c3.1 3.1 8.2 3.1 11.3 0l33.9-34c3.1-3.1 3.1-8.2 0-11.3l-73.5-73.5 45.3-45.3 28.3 28.3c3.1 3.1 8.2 3.1 11.3 0l11.3-11.3c3.1-3.2 3.1-8.2 0-11.4z"],table:[512,512,[],"f0ce","M464 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM224 416H64v-96h160v96zm0-160H64v-96h160v96zm224 160H288v-96h160v96zm0-160H288v-96h160v96z"],"table-tennis":[512,512,[],"f45d","M496.2 296.5C527.7 218.7 512 126.2 449 63.1 365.1-21 229-21 145.1 63.1l-56 56.1 211.5 211.5c46.1-62.1 131.5-77.4 195.6-34.2zm-217.9 79.7L57.9 155.9c-27.3 45.3-21.7 105 17.3 144.1l34.5 34.6L6.7 424c-8.6 7.5-9.1 20.7-1 28.8l53.4 53.5c8 8.1 21.2 7.6 28.7-1L177.1 402l35.7 35.7c19.7 19.7 44.6 30.5 70.3 33.3-7.1-17-11-35.6-11-55.1-.1-13.8 2.5-27 6.2-39.7zM416 320c-53 0-96 43-96 96s43 96 96 96 96-43 96-96-43-96-96-96z"],tablet:[448,512,[],"f10a","M400 0H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zM224 480c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z"],"tablet-alt":[448,512,[],"f3fa","M400 0H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zM224 480c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm176-108c0 6.6-5.4 12-12 12H60c-6.6 0-12-5.4-12-12V60c0-6.6 5.4-12 12-12h328c6.6 0 12 5.4 12 12v312z"],tablets:[640,512,[],"f490","M160 192C78.9 192 12.5 250.5.1 326.7c-.8 4.8 3.3 9.3 8.3 9.3h303.3c5 0 9.1-4.5 8.3-9.3C307.5 250.5 241.1 192 160 192zm151.6 176H8.4c-5 0-9.1 4.5-8.3 9.3C12.5 453.5 78.9 512 160 512s147.5-58.5 159.9-134.7c.8-4.8-3.3-9.3-8.3-9.3zM593.4 46.6c-56.5-56.5-144.2-61.4-206.9-16-4 2.9-4.3 8.9-.8 12.3L597 254.3c3.5 3.5 9.5 3.2 12.3-.8 45.5-62.7 40.6-150.4-15.9-206.9zM363 65.7c-3.5-3.5-9.5-3.2-12.3.8-45.4 62.7-40.5 150.4 15.9 206.9 56.5 56.5 144.2 61.4 206.9 15.9 4-2.9 4.3-8.9.8-12.3L363 65.7z"],"tachometer-alt":[576,512,[],"f3fd","M75.694 480a48.02 48.02 0 0 1-42.448-25.571C12.023 414.3 0 368.556 0 320 0 160.942 128.942 32 288 32s288 128.942 288 288c0 48.556-12.023 94.3-33.246 134.429A48.018 48.018 0 0 1 500.306 480H75.694zM512 288c-17.673 0-32 14.327-32 32 0 17.673 14.327 32 32 32s32-14.327 32-32c0-17.673-14.327-32-32-32zM288 128c17.673 0 32-14.327 32-32 0-17.673-14.327-32-32-32s-32 14.327-32 32c0 17.673 14.327 32 32 32zM64 288c-17.673 0-32 14.327-32 32 0 17.673 14.327 32 32 32s32-14.327 32-32c0-17.673-14.327-32-32-32zm65.608-158.392c-17.673 0-32 14.327-32 32 0 17.673 14.327 32 32 32s32-14.327 32-32c0-17.673-14.327-32-32-32zm316.784 0c-17.673 0-32 14.327-32 32 0 17.673 14.327 32 32 32s32-14.327 32-32c0-17.673-14.327-32-32-32zm-87.078 31.534c-12.627-4.04-26.133 2.92-30.173 15.544l-45.923 143.511C250.108 322.645 224 350.264 224 384c0 35.346 28.654 64 64 64 35.346 0 64-28.654 64-64 0-19.773-8.971-37.447-23.061-49.187l45.919-143.498c4.039-12.625-2.92-26.133-15.544-30.173z"],tag:[512,512,[],"f02b","M0 252.118V48C0 21.49 21.49 0 48 0h204.118a48 48 0 0 1 33.941 14.059l211.882 211.882c18.745 18.745 18.745 49.137 0 67.882L293.823 497.941c-18.745 18.745-49.137 18.745-67.882 0L14.059 286.059A48 48 0 0 1 0 252.118zM112 64c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48z"],tags:[640,512,[],"f02c","M497.941 225.941L286.059 14.059A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v204.118a48 48 0 0 0 14.059 33.941l211.882 211.882c18.744 18.745 49.136 18.746 67.882 0l204.118-204.118c18.745-18.745 18.745-49.137 0-67.882zM112 160c-26.51 0-48-21.49-48-48s21.49-48 48-48 48 21.49 48 48-21.49 48-48 48zm513.941 133.823L421.823 497.941c-18.745 18.745-49.137 18.745-67.882 0l-.36-.36L527.64 323.522c16.999-16.999 26.36-39.6 26.36-63.64s-9.362-46.641-26.36-63.64L331.397 0h48.721a48 48 0 0 1 33.941 14.059l211.882 211.882c18.745 18.745 18.745 49.137 0 67.882z"],tape:[640,512,[],"f4db","M224 192c-35.3 0-64 28.7-64 64s28.7 64 64 64 64-28.7 64-64-28.7-64-64-64zm400 224H380.6c41.5-40.7 67.4-97.3 67.4-160 0-123.7-100.3-224-224-224S0 132.3 0 256s100.3 224 224 224h400c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zm-400-64c-53 0-96-43-96-96s43-96 96-96 96 43 96 96-43 96-96 96z"],tasks:[512,512,[],"f0ae","M208 132h288c8.8 0 16-7.2 16-16V76c0-8.8-7.2-16-16-16H208c-8.8 0-16 7.2-16 16v40c0 8.8 7.2 16 16 16zm0 160h288c8.8 0 16-7.2 16-16v-40c0-8.8-7.2-16-16-16H208c-8.8 0-16 7.2-16 16v40c0 8.8 7.2 16 16 16zm0 160h288c8.8 0 16-7.2 16-16v-40c0-8.8-7.2-16-16-16H208c-8.8 0-16 7.2-16 16v40c0 8.8 7.2 16 16 16zM64 368c-26.5 0-48.6 21.5-48.6 48s22.1 48 48.6 48 48-21.5 48-48-21.5-48-48-48zm92.5-299l-72.2 72.2-15.6 15.6c-4.7 4.7-12.9 4.7-17.6 0L3.5 109.4c-4.7-4.7-4.7-12.3 0-17l15.7-15.7c4.7-4.7 12.3-4.7 17 0l22.7 22.1 63.7-63.3c4.7-4.7 12.3-4.7 17 0l17 16.5c4.6 4.7 4.6 12.3-.1 17zm0 159.6l-72.2 72.2-15.7 15.7c-4.7 4.7-12.9 4.7-17.6 0L3.5 269c-4.7-4.7-4.7-12.3 0-17l15.7-15.7c4.7-4.7 12.3-4.7 17 0l22.7 22.1 63.7-63.7c4.7-4.7 12.3-4.7 17 0l17 17c4.6 4.6 4.6 12.2-.1 16.9z"],taxi:[512,512,[],"f1ba","M461.951 243.865l-21.816-87.268A79.885 79.885 0 0 0 362.522 96H352V56c0-13.255-10.745-24-24-24H184c-13.255 0-24 10.745-24 24v40h-10.522a79.885 79.885 0 0 0-77.612 60.597L50.05 243.865C25.515 252.823 8 276.366 8 304v48c0 20.207 9.374 38.214 24 49.943V456c0 13.255 10.745 24 24 24h48c13.255 0 24-10.745 24-24v-40h256v40c0 13.255 10.745 24 24 24h48c13.255 0 24-10.745 24-24v-54.057c14.626-11.729 24-29.737 24-49.943v-48c0-27.634-17.515-51.177-42.049-60.135zM149.478 160h213.045a15.975 15.975 0 0 1 15.522 12.12l16.97 67.88h-278.03l16.97-67.881A15.976 15.976 0 0 1 149.478 160zM132 336c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36zm320 0c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36z"],terminal:[640,512,[],"f120","M257.981 272.971L63.638 467.314c-9.373 9.373-24.569 9.373-33.941 0L7.029 444.647c-9.357-9.357-9.375-24.522-.04-33.901L161.011 256 6.99 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L257.981 239.03c9.373 9.372 9.373 24.568 0 33.941zM640 456v-32c0-13.255-10.745-24-24-24H312c-13.255 0-24 10.745-24 24v32c0 13.255 10.745 24 24 24h304c13.255 0 24-10.745 24-24z"],"text-height":[576,512,[],"f034","M16 32h288c8.837 0 16 7.163 16 16v96c0 8.837-7.163 16-16 16h-35.496c-8.837 0-16-7.163-16-16V96h-54.761v320H232c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H88c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h34.257V96H67.496v48c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16V48c0-8.837 7.163-16 16-16zm475.308 4.685l79.995 80.001C581.309 126.693 574.297 144 559.99 144H512v224h48c15.639 0 20.635 17.991 11.313 27.314l-79.995 80.001c-6.247 6.247-16.381 6.245-22.626 0l-79.995-80.001C378.691 385.307 385.703 368 400.01 368H448V144h-48c-15.639 0-20.635-17.991-11.313-27.314l79.995-80.001c6.247-6.248 16.381-6.245 22.626 0z"],"text-width":[448,512,[],"f035","M16 32h416c8.837 0 16 7.163 16 16v96c0 8.837-7.163 16-16 16h-35.496c-8.837 0-16-7.163-16-16V96H261.743v128H296c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H152c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h34.257V96H67.496v48c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16V48c0-8.837 7.163-16 16-16zm427.315 340.682l-80.001-79.995C353.991 283.365 336 288.362 336 304v48H112v-47.99c0-14.307-17.307-21.319-27.314-11.313L4.685 372.692c-6.245 6.245-6.247 16.379 0 22.626l80.001 79.995C94.009 484.635 112 479.638 112 464v-48h224v47.99c0 14.307 17.307 21.319 27.314 11.313l80.001-79.995c6.245-6.245 6.248-16.379 0-22.626z"],th:[512,512,[],"f00a","M149.333 56v80c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24h101.333c13.255 0 24 10.745 24 24zm181.334 240v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.256 0 24.001-10.745 24.001-24zm32-240v80c0 13.255 10.745 24 24 24H488c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24zm-32 80V56c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.256 0 24.001-10.745 24.001-24zm-205.334 56H24c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24zM0 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H24c-13.255 0-24 10.745-24 24zm386.667-56H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24zm0 160H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24zM181.333 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24z"],"th-large":[512,512,[],"f009","M296 32h192c13.255 0 24 10.745 24 24v160c0 13.255-10.745 24-24 24H296c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24zm-80 0H24C10.745 32 0 42.745 0 56v160c0 13.255 10.745 24 24 24h192c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24zM0 296v160c0 13.255 10.745 24 24 24h192c13.255 0 24-10.745 24-24V296c0-13.255-10.745-24-24-24H24c-13.255 0-24 10.745-24 24zm296 184h192c13.255 0 24-10.745 24-24V296c0-13.255-10.745-24-24-24H296c-13.255 0-24 10.745-24 24v160c0 13.255 10.745 24 24 24z"],"th-list":[512,512,[],"f00b","M149.333 216v80c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24v-80c0-13.255 10.745-24 24-24h101.333c13.255 0 24 10.745 24 24zM0 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H24c-13.255 0-24 10.745-24 24zM125.333 32H24C10.745 32 0 42.745 0 56v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24zm80 448H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24zm-24-424v80c0 13.255 10.745 24 24 24H488c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24zm24 264H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24z"],thermometer:[512,512,[],"f491","M476.8 20.4c-37.5-30.7-95.5-26.3-131.9 10.2l-45.7 46 50.5 50.5c3.1 3.1 3.1 8.2 0 11.3l-11.3 11.3c-3.1 3.1-8.2 3.1-11.3 0l-50.4-50.5-45.1 45.4 50.3 50.4c3.1 3.1 3.1 8.2 0 11.3l-11.3 11.3c-3.1 3.1-8.2 3.1-11.3 0L209 167.4l-45.1 45.4L214 263c3.1 3.1 3.1 8.2 0 11.3l-11.3 11.3c-3.1 3.1-8.2 3.1-11.3 0l-50.1-50.2L96 281.1V382L7 471c-9.4 9.4-9.4 24.6 0 33.9 9.4 9.4 24.6 9.4 33.9 0l89-89h99.9L484 162.6c34.9-34.9 42.2-101.5-7.2-142.2z"],"thermometer-empty":[256,512,[],"f2cb","M192 384c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-35.346 28.654-64 64-64s64 28.654 64 64zm32-84.653c19.912 22.563 32 52.194 32 84.653 0 70.696-57.303 128-128 128-.299 0-.609-.001-.909-.003C56.789 511.509-.357 453.636.002 383.333.166 351.135 12.225 321.755 32 299.347V96c0-53.019 42.981-96 96-96s96 42.981 96 96v203.347zM208 384c0-34.339-19.37-52.19-32-66.502V96c0-26.467-21.533-48-48-48S80 69.533 80 96v221.498c-12.732 14.428-31.825 32.1-31.999 66.08-.224 43.876 35.563 80.116 79.423 80.42L128 464c44.112 0 80-35.888 80-80z"],"thermometer-full":[256,512,[],"f2c7","M224 96c0-53.019-42.981-96-96-96S32 42.981 32 96v203.347C12.225 321.756.166 351.136.002 383.333c-.359 70.303 56.787 128.176 127.089 128.664.299.002.61.003.909.003 70.698 0 128-57.304 128-128 0-32.459-12.088-62.09-32-84.653V96zm-96 368l-.576-.002c-43.86-.304-79.647-36.544-79.423-80.42.173-33.98 19.266-51.652 31.999-66.08V96c0-26.467 21.533-48 48-48s48 21.533 48 48v221.498c12.63 14.312 32 32.164 32 66.502 0 44.112-35.888 80-80 80zm64-80c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-23.685 12.876-44.349 32-55.417V96c0-17.673 14.327-32 32-32s32 14.327 32 32v232.583c19.124 11.068 32 31.732 32 55.417z"],"thermometer-half":[256,512,[],"f2c9","M192 384c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-23.685 12.876-44.349 32-55.417V224c0-17.673 14.327-32 32-32s32 14.327 32 32v104.583c19.124 11.068 32 31.732 32 55.417zm32-84.653c19.912 22.563 32 52.194 32 84.653 0 70.696-57.303 128-128 128-.299 0-.609-.001-.909-.003C56.789 511.509-.357 453.636.002 383.333.166 351.135 12.225 321.755 32 299.347V96c0-53.019 42.981-96 96-96s96 42.981 96 96v203.347zM208 384c0-34.339-19.37-52.19-32-66.502V96c0-26.467-21.533-48-48-48S80 69.533 80 96v221.498c-12.732 14.428-31.825 32.1-31.999 66.08-.224 43.876 35.563 80.116 79.423 80.42L128 464c44.112 0 80-35.888 80-80z"],"thermometer-quarter":[256,512,[],"f2ca","M192 384c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-23.685 12.876-44.349 32-55.417V288c0-17.673 14.327-32 32-32s32 14.327 32 32v40.583c19.124 11.068 32 31.732 32 55.417zm32-84.653c19.912 22.563 32 52.194 32 84.653 0 70.696-57.303 128-128 128-.299 0-.609-.001-.909-.003C56.789 511.509-.357 453.636.002 383.333.166 351.135 12.225 321.755 32 299.347V96c0-53.019 42.981-96 96-96s96 42.981 96 96v203.347zM208 384c0-34.339-19.37-52.19-32-66.502V96c0-26.467-21.533-48-48-48S80 69.533 80 96v221.498c-12.732 14.428-31.825 32.1-31.999 66.08-.224 43.876 35.563 80.116 79.423 80.42L128 464c44.112 0 80-35.888 80-80z"],"thermometer-three-quarters":[256,512,[],"f2c8","M192 384c0 35.346-28.654 64-64 64-35.346 0-64-28.654-64-64 0-23.685 12.876-44.349 32-55.417V160c0-17.673 14.327-32 32-32s32 14.327 32 32v168.583c19.124 11.068 32 31.732 32 55.417zm32-84.653c19.912 22.563 32 52.194 32 84.653 0 70.696-57.303 128-128 128-.299 0-.609-.001-.909-.003C56.789 511.509-.357 453.636.002 383.333.166 351.135 12.225 321.755 32 299.347V96c0-53.019 42.981-96 96-96s96 42.981 96 96v203.347zM208 384c0-34.339-19.37-52.19-32-66.502V96c0-26.467-21.533-48-48-48S80 69.533 80 96v221.498c-12.732 14.428-31.825 32.1-31.999 66.08-.224 43.876 35.563 80.116 79.423 80.42L128 464c44.112 0 80-35.888 80-80z"],"thumbs-down":[512,512,[],"f165","M0 56v240c0 13.255 10.745 24 24 24h80c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24H24C10.745 32 0 42.745 0 56zm40 200c0-13.255 10.745-24 24-24s24 10.745 24 24-10.745 24-24 24-24-10.745-24-24zm272 256c-20.183 0-29.485-39.293-33.931-57.795-5.206-21.666-10.589-44.07-25.393-58.902-32.469-32.524-49.503-73.967-89.117-113.111a11.98 11.98 0 0 1-3.558-8.521V59.901c0-6.541 5.243-11.878 11.783-11.998 15.831-.29 36.694-9.079 52.651-16.178C256.189 17.598 295.709.017 343.995 0h2.844c42.777 0 93.363.413 113.774 29.737 8.392 12.057 10.446 27.034 6.148 44.632 16.312 17.053 25.063 48.863 16.382 74.757 17.544 23.432 19.143 56.132 9.308 79.469l.11.11c11.893 11.949 19.523 31.259 19.439 49.197-.156 30.352-26.157 58.098-59.553 58.098H350.723C358.03 364.34 384 388.132 384 430.548 384 504 336 512 312 512z"],"thumbs-up":[512,512,[],"f164","M104 224H24c-13.255 0-24 10.745-24 24v240c0 13.255 10.745 24 24 24h80c13.255 0 24-10.745 24-24V248c0-13.255-10.745-24-24-24zM64 472c-13.255 0-24-10.745-24-24s10.745-24 24-24 24 10.745 24 24-10.745 24-24 24zM384 81.452c0 42.416-25.97 66.208-33.277 94.548h101.723c33.397 0 59.397 27.746 59.553 58.098.084 17.938-7.546 37.249-19.439 49.197l-.11.11c9.836 23.337 8.237 56.037-9.308 79.469 8.681 25.895-.069 57.704-16.382 74.757 4.298 17.598 2.244 32.575-6.148 44.632C440.202 511.587 389.616 512 346.839 512l-2.845-.001c-48.287-.017-87.806-17.598-119.56-31.725-15.957-7.099-36.821-15.887-52.651-16.178-6.54-.12-11.783-5.457-11.783-11.998v-213.77c0-3.2 1.282-6.271 3.558-8.521 39.614-39.144 56.648-80.587 89.117-113.111 14.804-14.832 20.188-37.236 25.393-58.902C282.515 39.293 291.817 0 312 0c24 0 72 8 72 81.452z"],thumbtack:[384,512,[],"f08d","M298.028 214.267L285.793 96H328c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24H56C42.745 0 32 10.745 32 24v48c0 13.255 10.745 24 24 24h42.207L85.972 214.267C37.465 236.82 0 277.261 0 328c0 13.255 10.745 24 24 24h136v104.007c0 1.242.289 2.467.845 3.578l24 48c2.941 5.882 11.364 5.893 14.311 0l24-48a8.008 8.008 0 0 0 .845-3.578V352h136c13.255 0 24-10.745 24-24-.001-51.183-37.983-91.42-85.973-113.733z"],"ticket-alt":[576,512,[],"f3ff","M128 160h320v192H128V160zm400 96c0 26.51 21.49 48 48 48v96c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48v-96c26.51 0 48-21.49 48-48s-21.49-48-48-48v-96c0-26.51 21.49-48 48-48h480c26.51 0 48 21.49 48 48v96c-26.51 0-48 21.49-48 48zm-48-104c0-13.255-10.745-24-24-24H120c-13.255 0-24 10.745-24 24v208c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V152z"],times:[384,512,[],"f00d","M323.1 441l53.9-53.9c9.4-9.4 9.4-24.5 0-33.9L279.8 256l97.2-97.2c9.4-9.4 9.4-24.5 0-33.9L323.1 71c-9.4-9.4-24.5-9.4-33.9 0L192 168.2 94.8 71c-9.4-9.4-24.5-9.4-33.9 0L7 124.9c-9.4 9.4-9.4 24.5 0 33.9l97.2 97.2L7 353.2c-9.4 9.4-9.4 24.5 0 33.9L60.9 441c9.4 9.4 24.5 9.4 33.9 0l97.2-97.2 97.2 97.2c9.3 9.3 24.5 9.3 33.9 0z"],"times-circle":[512,512,[],"f057","M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z"],tint:[384,512,[],"f043","M192 512c-98.435 0-178.087-79.652-178.087-178.087 0-111.196 101.194-154.065 148.522-311.825 9.104-30.116 51.099-28.778 59.13 0 47.546 158.486 148.522 200.069 148.522 311.825C370.087 432.348 290.435 512 192 512zm-42.522-171.826c-1.509-5.533-9.447-5.532-10.956 0-9.223 29.425-27.913 37.645-27.913 58.435C110.609 417.13 125.478 432 144 432s33.391-14.87 33.391-33.391c0-20.839-18.673-28.956-27.913-58.435z"],"toggle-off":[576,512,[],"f204","M384 64H192C85.961 64 0 149.961 0 256s85.961 192 192 192h192c106.039 0 192-85.961 192-192S490.039 64 384 64zM64 256c0-70.741 57.249-128 128-128 70.741 0 128 57.249 128 128 0 70.741-57.249 128-128 128-70.741 0-128-57.249-128-128zm320 128h-48.905c65.217-72.858 65.236-183.12 0-256H384c70.741 0 128 57.249 128 128 0 70.74-57.249 128-128 128z"],"toggle-on":[576,512,[],"f205","M576 256c0 106.039-85.961 192-192 192H192C85.961 448 0 362.039 0 256S85.961 64 192 64h192c106.039 0 192 85.961 192 192zM384 128c-70.741 0-128 57.249-128 128 0 70.741 57.249 128 128 128 70.741 0 128-57.249 128-128 0-70.741-57.249-128-128-128"],trademark:[640,512,[],"f25c","M97.119 163.133H12c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h248.559c6.627 0 12 5.373 12 12v43.133c0 6.627-5.373 12-12 12H175.44V404c0 6.627-5.373 12-12 12h-54.322c-6.627 0-12-5.373-12-12V163.133zM329.825 96h65.425a12 12 0 0 1 11.346 8.093l43.759 127.068c7.161 20.588 16.111 52.812 16.111 52.812h.896s8.95-32.224 16.111-52.812l43.758-127.068A12 12 0 0 1 538.577 96h65.41a12 12 0 0 1 11.961 11.03l24.012 296c.567 6.987-4.951 12.97-11.961 12.97h-54.101a12 12 0 0 1-11.972-11.182l-9.082-132.93c-1.79-24.168 0-53.706 0-53.706h-.896s-10.741 33.566-17.902 53.706l-30.7 84.731a12 12 0 0 1-11.282 7.912h-50.302a12 12 0 0 1-11.282-7.912l-30.7-84.731c-7.161-20.14-17.903-53.706-17.903-53.706h-.895s1.79 29.538 0 53.706l-9.082 132.93c-.428 6.295-5.66 11.182-11.97 11.182H305.4c-7.017 0-12.536-5.994-11.959-12.987l24.425-296A11.999 11.999 0 0 1 329.825 96z"],train:[448,512,[],"f238","M448 96v256c0 51.815-61.624 96-130.022 96l62.98 49.721C386.905 502.417 383.562 512 376 512H72c-7.578 0-10.892-9.594-4.957-14.279L130.022 448C61.82 448 0 403.954 0 352V96C0 42.981 64 0 128 0h192c65 0 128 42.981 128 96zm-48 136V120c0-13.255-10.745-24-24-24H72c-13.255 0-24 10.745-24 24v112c0 13.255 10.745 24 24 24h304c13.255 0 24-10.745 24-24zm-176 64c-30.928 0-56 25.072-56 56s25.072 56 56 56 56-25.072 56-56-25.072-56-56-56z"],transgender:[384,512,[],"f224","M372 0h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-80.7 80.7C198.5 104.1 172.2 96 144 96 64.5 96 0 160.5 0 240c0 68.5 47.9 125.9 112 140.4V408H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v28c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-28h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-27.6c64.1-14.6 112-71.9 112-140.4 0-28.2-8.1-54.5-22.1-76.7l80.7-80.7 16.9 16.9c7.6 7.6 20.5 2.2 20.5-8.5V12c0-6.6-5.4-12-12-12zM144 320c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z"],"transgender-alt":[480,512,[],"f225","M468 0h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-80.7 80.7C294.5 104.1 268.2 96 240 96c-28.2 0-54.5 8.1-76.7 22.1l-16.5-16.5 19.8-19.8c4.7-4.7 4.7-12.3 0-17l-28.3-28.3c-4.7-4.7-12.3-4.7-17 0l-19.8 19.8-19-19 16.9-16.9C107.1 12.9 101.7 0 91 0H12C5.4 0 0 5.4 0 12v79c0 10.7 12.9 16 20.5 8.5l16.9-16.9 19 19-19.8 19.8c-4.7 4.7-4.7 12.3 0 17l28.3 28.3c4.7 4.7 12.3 4.7 17 0l19.8-19.8 16.5 16.5C104.1 185.5 96 211.8 96 240c0 68.5 47.9 125.9 112 140.4V408h-36c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v28c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-28h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-27.6c64.1-14.6 112-71.9 112-140.4 0-28.2-8.1-54.5-22.1-76.7l80.7-80.7 16.9 16.9c7.6 7.6 20.5 2.2 20.5-8.5V12c0-6.6-5.4-12-12-12zM240 320c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z"],trash:[448,512,[],"f1f8","M0 84V56c0-13.3 10.7-24 24-24h112l9.4-18.7c4-8.2 12.3-13.3 21.4-13.3h114.3c9.1 0 17.4 5.1 21.5 13.3L312 32h112c13.3 0 24 10.7 24 24v28c0 6.6-5.4 12-12 12H12C5.4 96 0 90.6 0 84zm415.2 56.7L394.8 467c-1.6 25.3-22.6 45-47.9 45H101.1c-25.3 0-46.3-19.7-47.9-45L32.8 140.7c-.4-6.9 5.1-12.7 12-12.7h358.5c6.8 0 12.3 5.8 11.9 12.7z"],"trash-alt":[448,512,[],"f2ed","M0 84V56c0-13.3 10.7-24 24-24h112l9.4-18.7c4-8.2 12.3-13.3 21.4-13.3h114.3c9.1 0 17.4 5.1 21.5 13.3L312 32h112c13.3 0 24 10.7 24 24v28c0 6.6-5.4 12-12 12H12C5.4 96 0 90.6 0 84zm416 56v324c0 26.5-21.5 48-48 48H80c-26.5 0-48-21.5-48-48V140c0-6.6 5.4-12 12-12h360c6.6 0 12 5.4 12 12zm-272 68c0-8.8-7.2-16-16-16s-16 7.2-16 16v224c0 8.8 7.2 16 16 16s16-7.2 16-16V208zm96 0c0-8.8-7.2-16-16-16s-16 7.2-16 16v224c0 8.8 7.2 16 16 16s16-7.2 16-16V208zm96 0c0-8.8-7.2-16-16-16s-16 7.2-16 16v224c0 8.8 7.2 16 16 16s16-7.2 16-16V208z"],tree:[384,512,[],"f1bb","M377.33 375.429L293.906 288H328c21.017 0 31.872-25.207 17.448-40.479L262.79 160H296c20.878 0 31.851-24.969 17.587-40.331l-104-112.003c-9.485-10.214-25.676-10.229-35.174 0l-104 112.003C56.206 134.969 67.037 160 88 160h33.21l-82.659 87.521C24.121 262.801 34.993 288 56 288h34.094L6.665 375.429C-7.869 390.655 2.925 416 24.025 416H144c0 32.781-11.188 49.26-33.995 67.506C98.225 492.93 104.914 512 120 512h144c15.086 0 21.776-19.069 9.995-28.494-19.768-15.814-33.992-31.665-33.995-67.496V416h119.97c21.05 0 31.929-25.309 17.36-40.571z"],trophy:[576,512,[],"f091","M552 64H448V24c0-13.3-10.7-24-24-24H152c-13.3 0-24 10.7-24 24v40H24C10.7 64 0 74.7 0 88v56c0 35.7 22.5 72.4 61.9 100.7 31.5 22.7 69.8 37.1 110 41.7C203.3 338.5 240 360 240 360v72h-48c-35.3 0-64 20.7-64 56v12c0 6.6 5.4 12 12 12h296c6.6 0 12-5.4 12-12v-12c0-35.3-28.7-56-64-56h-48v-72s36.7-21.5 68.1-73.6c40.3-4.6 78.6-19 110-41.7 39.3-28.3 61.9-65 61.9-100.7V88c0-13.3-10.7-24-24-24zM99.3 192.8C74.9 175.2 64 155.6 64 144v-16h64.2c1 32.6 5.8 61.2 12.8 86.2-15.1-5.2-29.2-12.4-41.7-21.4zM512 144c0 16.1-17.7 36.1-35.3 48.8-12.5 9-26.7 16.2-41.8 21.4 7-25 11.8-53.6 12.8-86.2H512v16z"],truck:[640,512,[],"f0d1","M624 352h-16V243.9c0-12.7-5.1-24.9-14.1-33.9L494 110.1c-9-9-21.2-14.1-33.9-14.1H416V48c0-26.5-21.5-48-48-48H48C21.5 0 0 21.5 0 48v320c0 26.5 21.5 48 48 48h16c0 53 43 96 96 96s96-43 96-96h128c0 53 43 96 96 96s96-43 96-96h48c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zM160 464c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zm320 0c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zm80-208H416V144h44.1l99.9 99.9V256z"],"truck-loading":[640,512,[],"f4de","M50.2 375.6c2.3 8.5 11.1 13.6 19.6 11.3l216.4-58c8.5-2.3 13.6-11.1 11.3-19.6l-49.7-185.5c-2.3-8.5-11.1-13.6-19.6-11.3L151 133.3l24.8 92.7-61.8 16.5-24.8-92.7-77.3 20.7C3.4 172.8-1.7 181.6.6 190.1l49.6 185.5zM384 0c-17.7 0-32 14.3-32 32v323.6L5.9 450c-4.3 1.2-6.8 5.6-5.6 9.8l12.6 46.3c1.2 4.3 5.6 6.8 9.8 5.6l393.7-107.4C418.8 464.1 467.6 512 528 512c61.9 0 112-50.1 112-112V0H384zm144 448c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48z"],"truck-moving":[640,512,[],"f4df","M621.3 237.3l-58.5-58.5c-12-12-28.3-18.7-45.3-18.7H480V64c0-17.7-14.3-32-32-32H32C14.3 32 0 46.3 0 64v336c0 44.2 35.8 80 80 80 26.3 0 49.4-12.9 64-32.4 14.6 19.6 37.7 32.4 64 32.4 44.2 0 80-35.8 80-80 0-5.5-.6-10.8-1.6-16h163.2c-1.1 5.2-1.6 10.5-1.6 16 0 44.2 35.8 80 80 80s80-35.8 80-80c0-5.5-.6-10.8-1.6-16H624c8.8 0 16-7.2 16-16v-85.5c0-17-6.7-33.2-18.7-45.2zM80 432c-17.6 0-32-14.4-32-32s14.4-32 32-32 32 14.4 32 32-14.4 32-32 32zm128 0c-17.6 0-32-14.4-32-32s14.4-32 32-32 32 14.4 32 32-14.4 32-32 32zm272-224h37.5c4.3 0 8.3 1.7 11.3 4.7l43.3 43.3H480v-48zm48 224c-17.6 0-32-14.4-32-32s14.4-32 32-32 32 14.4 32 32-14.4 32-32 32z"],tty:[512,512,[],"f1e4","M5.37 103.822c138.532-138.532 362.936-138.326 501.262 0 6.078 6.078 7.074 15.496 2.583 22.681l-43.214 69.138a18.332 18.332 0 0 1-22.356 7.305l-86.422-34.569a18.335 18.335 0 0 1-11.434-18.846L351.741 90c-62.145-22.454-130.636-21.986-191.483 0l5.953 59.532a18.331 18.331 0 0 1-11.434 18.846l-86.423 34.568a18.334 18.334 0 0 1-22.356-7.305L2.787 126.502a18.333 18.333 0 0 1 2.583-22.68zM96 308v-40c0-6.627-5.373-12-12-12H44c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-336 96v-40c0-6.627-5.373-12-12-12H92c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zM96 500v-40c0-6.627-5.373-12-12-12H44c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm288 0v-40c0-6.627-5.373-12-12-12H140c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h232c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12z"],tv:[640,512,[],"f26c","M592 0H48C21.5 0 0 21.5 0 48v320c0 26.5 21.5 48 48 48h245.1v32h-160c-17.7 0-32 14.3-32 32s14.3 32 32 32h384c17.7 0 32-14.3 32-32s-14.3-32-32-32h-160v-32H592c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-16 352H64V64h512v288z"],umbrella:[576,512,[],"f0e9","M557.011 267.631c-51.432-45.217-107.572-43.698-158.567 30.731-5.298 7.861-14.906 7.165-19.736 0-2.483-3.624-32.218-60.808-90.708-60.808-45.766 0-70.542 31.378-90.709 60.808-4.829 7.165-14.436 7.861-19.734 0-50.904-74.285-106.613-76.406-158.567-30.731-10.21 8.264-20.912-1.109-18.696-9.481C32.146 134.573 158.516 64.612 288.001 64.612c128.793 0 256.546 69.961 287.706 193.538 2.206 8.322-8.426 17.793-18.696 9.481zM256 261.001V416c0 17.645-14.355 32-32 32s-32-14.355-32-32c0-17.673-14.327-32-32-32s-32 14.327-32 32c0 52.935 43.065 96 96 96s96-43.065 96-96V261.288c-21.836-10.806-45.425-9.737-64-.287zm64-211.007V32c0-17.673-14.327-32-32-32s-32 14.327-32 32v17.987a372.105 372.105 0 0 1 64 .007z"],underline:[448,512,[],"f0cd","M224.264 388.24c-91.669 0-156.603-51.165-156.603-151.392V64H39.37c-8.837 0-16-7.163-16-16V16c0-8.837 7.163-16 16-16h137.39c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-28.813v172.848c0 53.699 28.314 79.444 76.317 79.444 46.966 0 75.796-25.434 75.796-79.965V64h-28.291c-8.837 0-16-7.163-16-16V16c0-8.837 7.163-16 16-16h136.868c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-28.291v172.848c0 99.405-64.881 151.392-156.082 151.392zM16 448h416c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16z"],undo:[512,512,[],"f0e2","M212.333 224.333H12c-6.627 0-12-5.373-12-12V12C0 5.373 5.373 0 12 0h48c6.627 0 12 5.373 12 12v78.112C117.773 39.279 184.26 7.47 258.175 8.007c136.906.994 246.448 111.623 246.157 248.532C504.041 393.258 393.12 504 256.333 504c-64.089 0-122.496-24.313-166.51-64.215-5.099-4.622-5.334-12.554-.467-17.42l33.967-33.967c4.474-4.474 11.662-4.717 16.401-.525C170.76 415.336 211.58 432 256.333 432c97.268 0 176-78.716 176-176 0-97.267-78.716-176-176-176-58.496 0-110.28 28.476-142.274 72.333h98.274c6.627 0 12 5.373 12 12v48c0 6.627-5.373 12-12 12z"],"undo-alt":[512,512,[],"f2ea","M255.545 8c-66.269.119-126.438 26.233-170.86 68.685L48.971 40.971C33.851 25.851 8 36.559 8 57.941V192c0 13.255 10.745 24 24 24h134.059c21.382 0 32.09-25.851 16.971-40.971l-41.75-41.75c30.864-28.899 70.801-44.907 113.23-45.273 92.398-.798 170.283 73.977 169.484 169.442C423.236 348.009 349.816 424 256 424c-41.127 0-79.997-14.678-110.63-41.556-4.743-4.161-11.906-3.908-16.368.553L89.34 422.659c-4.872 4.872-4.631 12.815.482 17.433C133.798 479.813 192.074 504 256 504c136.966 0 247.999-111.033 248-247.998C504.001 119.193 392.354 7.755 255.545 8z"],"universal-access":[512,512,[],"f29a","M256 48c114.953 0 208 93.029 208 208 0 114.953-93.029 208-208 208-114.953 0-208-93.029-208-208 0-114.953 93.029-208 208-208m0-40C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 56C149.961 64 64 149.961 64 256s85.961 192 192 192 192-85.961 192-192S362.039 64 256 64zm0 44c19.882 0 36 16.118 36 36s-16.118 36-36 36-36-16.118-36-36 16.118-36 36-36zm117.741 98.023c-28.712 6.779-55.511 12.748-82.14 15.807.851 101.023 12.306 123.052 25.037 155.621 3.617 9.26-.957 19.698-10.217 23.315-9.261 3.617-19.699-.957-23.316-10.217-8.705-22.308-17.086-40.636-22.261-78.549h-9.686c-5.167 37.851-13.534 56.208-22.262 78.549-3.615 9.255-14.05 13.836-23.315 10.217-9.26-3.617-13.834-14.056-10.217-23.315 12.713-32.541 24.185-54.541 25.037-155.621-26.629-3.058-53.428-9.027-82.141-15.807-8.6-2.031-13.926-10.648-11.895-19.249s10.647-13.926 19.249-11.895c96.686 22.829 124.283 22.783 220.775 0 8.599-2.03 17.218 3.294 19.249 11.895 2.029 8.601-3.297 17.219-11.897 19.249z"],university:[512,512,[],"f19c","M496 128v16a8 8 0 0 1-8 8h-24v12c0 6.627-5.373 12-12 12H60c-6.627 0-12-5.373-12-12v-12H24a8 8 0 0 1-8-8v-16a8 8 0 0 1 4.941-7.392l232-88a7.996 7.996 0 0 1 6.118 0l232 88A8 8 0 0 1 496 128zm-24 304H40c-13.255 0-24 10.745-24 24v16a8 8 0 0 0 8 8h464a8 8 0 0 0 8-8v-16c0-13.255-10.745-24-24-24zM96 192v192H60c-6.627 0-12 5.373-12 12v20h416v-20c0-6.627-5.373-12-12-12h-36V192h-64v192h-64V192h-64v192h-64V192H96z"],unlink:[512,512,[],"f127","M304.083 405.907c4.686 4.686 4.686 12.284 0 16.971l-44.674 44.674c-59.263 59.262-155.693 59.266-214.961 0-59.264-59.265-59.264-155.696 0-214.96l44.675-44.675c4.686-4.686 12.284-4.686 16.971 0l39.598 39.598c4.686 4.686 4.686 12.284 0 16.971l-44.675 44.674c-28.072 28.073-28.072 73.75 0 101.823 28.072 28.072 73.75 28.073 101.824 0l44.674-44.674c4.686-4.686 12.284-4.686 16.971 0l39.597 39.598zm-56.568-260.216c4.686 4.686 12.284 4.686 16.971 0l44.674-44.674c28.072-28.075 73.75-28.073 101.824 0 28.072 28.073 28.072 73.75 0 101.823l-44.675 44.674c-4.686 4.686-4.686 12.284 0 16.971l39.598 39.598c4.686 4.686 12.284 4.686 16.971 0l44.675-44.675c59.265-59.265 59.265-155.695 0-214.96-59.266-59.264-155.695-59.264-214.961 0l-44.674 44.674c-4.686 4.686-4.686 12.284 0 16.971l39.597 39.598zm234.828 359.28l22.627-22.627c9.373-9.373 9.373-24.569 0-33.941L63.598 7.029c-9.373-9.373-24.569-9.373-33.941 0L7.029 29.657c-9.373 9.373-9.373 24.569 0 33.941l441.373 441.373c9.373 9.372 24.569 9.372 33.941 0z"],unlock:[448,512,[],"f09c","M400 256H152V152.9c0-39.6 31.7-72.5 71.3-72.9 40-.4 72.7 32.1 72.7 72v16c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24v-16C376 68 307.5-.3 223.5 0 139.5.3 72 69.5 72 153.5V256H48c-26.5 0-48 21.5-48 48v160c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48z"],"unlock-alt":[448,512,[],"f13e","M400 256H152V152.9c0-39.6 31.7-72.5 71.3-72.9 40-.4 72.7 32.1 72.7 72v16c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24v-16C376 68 307.5-.3 223.5 0 139.5.3 72 69.5 72 153.5V256H48c-26.5 0-48 21.5-48 48v160c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48zM264 408c0 22.1-17.9 40-40 40s-40-17.9-40-40v-48c0-22.1 17.9-40 40-40s40 17.9 40 40v48z"],upload:[512,512,[],"f093","M296 384h-80c-13.3 0-24-10.7-24-24V192h-87.7c-17.8 0-26.7-21.5-14.1-34.1L242.3 5.7c7.5-7.5 19.8-7.5 27.3 0l152.2 152.2c12.6 12.6 3.7 34.1-14.1 34.1H320v168c0 13.3-10.7 24-24 24zm216-8v112c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24V376c0-13.3 10.7-24 24-24h136v8c0 30.9 25.1 56 56 56h80c30.9 0 56-25.1 56-56v-8h136c13.3 0 24 10.7 24 24zm-124 88c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20zm64 0c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20z"],user:[512,512,[],"f007","M256 0c88.366 0 160 71.634 160 160s-71.634 160-160 160S96 248.366 96 160 167.634 0 256 0zm183.283 333.821l-71.313-17.828c-74.923 53.89-165.738 41.864-223.94 0l-71.313 17.828C29.981 344.505 0 382.903 0 426.955V464c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48v-37.045c0-44.052-29.981-82.45-72.717-93.134z"],"user-circle":[512,512,[],"f2bd","M8 256C8 119.033 119.033 8 256 8s248 111.033 248 248-111.033 248-248 248S8 392.967 8 256zm72.455 125.868C119.657 436.446 183.673 472 256 472s136.343-35.554 175.545-90.132c-3.141-26.99-22.667-49.648-49.538-56.366l-32.374-8.093C323.565 339.79 290.722 352 256 352s-67.565-12.21-93.634-34.591l-32.374 8.093c-26.87 6.718-46.396 29.376-49.537 56.366zM144 208c0 61.856 50.144 112 112 112s112-50.144 112-112S317.856 96 256 96s-112 50.144-112 112z"],"user-md":[448,512,[],"f0f0","M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zM104 424c0 13.3 10.7 24 24 24s24-10.7 24-24-10.7-24-24-24-24 10.7-24 24zm250.4-151.6l-34.4-5.7v55c36.5 7.4 64 39.8 64 78.4v56c0 7.6-5.4 14.2-12.9 15.7l-32.2 6.4c-4.3.9-8.5-1.9-9.4-6.3l-3.1-15.7c-.9-4.3 1.9-8.6 6.3-9.4l19.3-3.9V400c0-29.6-26.9-53-57.6-47.1-22.8 4.4-38.4 25.8-38.4 49v41l19.3 3.9c4.3.9 7.1 5.1 6.3 9.4l-3.1 15.7c-.9 4.3-5.1 7.1-9.4 6.3l-31.2-4.2c-7.9-1.1-13.8-7.8-13.8-15.9v-58c0-38.6 27.5-70.9 64-78.4v-47.2c-19.6 8.6-41.2 13.6-64 13.6-29.3 0-56.4-8.5-80-22.3v104.9c23.1 6.9 40 28.1 40 53.4 0 30.9-25.1 56-56 56s-56-25.1-56-56c0-25.3 16.9-46.5 40-53.4V269.3l-18.4 3.1c-54 9-93.6 55.7-93.6 110.5V480c0 17.7 14.3 32 32 32h384c17.7 0 32-14.3 32-32v-97.1c-.1-54.8-39.7-101.5-93.7-110.5z"],"user-plus":[640,512,[],"f234","M224 32c77.32 0 140 62.68 140 140s-62.68 140-140 140S84 249.32 84 172 146.68 32 224 32zm160.373 292.093l-62.399-15.6c-65.557 47.154-145.021 36.631-195.948 0l-62.399 15.6C26.233 333.442 0 367.04 0 405.585V438c0 23.196 18.804 42 42 42h364c23.196 0 42-18.804 42-42v-32.415c0-38.545-26.233-72.143-63.627-81.492zM628 224.889h-68.889V156c0-6.627-5.373-12-12-12h-38.222c-6.627 0-12 5.373-12 12l-.002 68.887-68.887.002c-6.627 0-12 5.373-12 12v38.222c0 6.627 5.373 12 12 12l68.887.002.002 68.887c0 6.627 5.373 12 12 12h38.222c6.627 0 12-5.373 12-12l.002-68.887 68.887-.002c6.627 0 12-5.373 12-12v-38.222c0-6.627-5.373-12-12-12z"],"user-secret":[448,512,[],"f21b","M388.829 295.324l20.972-55.052c2.992-7.854-2.809-16.272-11.214-16.272H340.39c7.45-16.236 11.61-34.297 11.61-53.333 0-3.631-.16-7.224-.456-10.778C391.083 152.074 416 140.684 416 128c0-13.263-27.231-25.112-69.947-32.937-9.185-32.805-27.178-65.797-40.714-82.85-9.452-11.908-25.873-15.634-39.471-8.834l-27.557 13.779a31.997 31.997 0 0 1-28.622 0l-27.557-13.78c-13.599-6.799-30.02-3.074-39.471 8.834-13.536 17.053-31.529 50.045-40.714 82.85C59.231 102.888 32 114.737 32 128c0 12.684 24.917 24.074 64.456 31.889A129.362 129.362 0 0 0 96 170.667c0 19.037 4.159 37.098 11.608 53.333h-57.41c-8.615 0-14.423 8.808-11.029 16.727l22.906 53.447C25.799 307.882 0 342.925 0 384v80c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48v-80c0-39.97-24.43-74.231-59.171-88.676zM184 488l-48-192 48 24 24 40-24 128zm80 0l-24-128 24-40 48-24-48 192zm54.778-303.746c-.008.043-4.299 3.231-5.125 5.771-3.861 11.864-7.026 24.572-16.514 33.359-10.071 9.327-47.957 22.405-63.996-25.029-2.837-8.395-15.447-8.398-18.285 0-16.963 50.168-56.019 32.417-63.996 25.029-9.488-8.786-12.653-21.495-16.514-33.359-.826-2.54-5.118-5.728-5.125-5.771-.554-2.925-.981-5.884-1.22-8.85-.309-3.848 10.078-3.658 11.078-3.747 26.303-2.326 52.303-.579 78.023 5.497 2.563.606 11.553.529 13.793 0 25.72-6.076 51.72-7.824 78.023-5.497 1.002.089 11.387-.102 11.078 3.747-.239 2.966-.666 5.925-1.22 8.85z"],"user-times":[640,512,[],"f235","M224 32c77.32 0 140 62.68 140 140s-62.68 140-140 140S84 249.32 84 172 146.68 32 224 32zm160.373 292.093l-62.399-15.6c-65.557 47.154-145.021 36.631-195.948 0l-62.399 15.6C26.233 333.442 0 367.04 0 405.585V438c0 23.196 18.804 42 42 42h364c23.196 0 42-18.804 42-42v-32.415c0-38.545-26.233-72.143-63.627-81.492zM587.897 256l48.596-48.598c4.675-4.675 4.675-12.256 0-16.931l-26.964-26.964c-4.675-4.675-12.256-4.675-16.931 0L544 212.105l-48.598-48.598c-4.675-4.675-12.256-4.675-16.931 0l-26.964 26.964c-4.675 4.675-4.675 12.256 0 16.931L500.103 256l-48.596 48.598c-4.675 4.675-4.675 12.256 0 16.931l26.964 26.964c4.675 4.675 12.256 4.675 16.931 0L544 299.897l48.598 48.596c4.675 4.675 12.256 4.675 16.931 0l26.964-26.964c4.675-4.675 4.675-12.256 0-16.931L587.897 256z"],users:[640,512,[],"f0c0","M320 64c57.99 0 105 47.01 105 105s-47.01 105-105 105-105-47.01-105-105S262.01 64 320 64zm113.463 217.366l-39.982-9.996c-49.168 35.365-108.766 27.473-146.961 0l-39.982 9.996C174.485 289.379 152 318.177 152 351.216V412c0 19.882 16.118 36 36 36h264c19.882 0 36-16.118 36-36v-60.784c0-33.039-22.485-61.837-54.537-69.85zM528 300c38.66 0 70-31.34 70-70s-31.34-70-70-70-70 31.34-70 70 31.34 70 70 70zm-416 0c38.66 0 70-31.34 70-70s-31.34-70-70-70-70 31.34-70 70 31.34 70 70 70zm24 112v-60.784c0-16.551 4.593-32.204 12.703-45.599-29.988 14.72-63.336 8.708-85.69-7.37l-26.655 6.664C14.99 310.252 0 329.452 0 351.477V392c0 13.255 10.745 24 24 24h112.169a52.417 52.417 0 0 1-.169-4zm467.642-107.09l-26.655-6.664c-27.925 20.086-60.89 19.233-85.786 7.218C499.369 318.893 504 334.601 504 351.216V412c0 1.347-.068 2.678-.169 4H616c13.255 0 24-10.745 24-24v-40.523c0-22.025-14.99-41.225-36.358-46.567z"],"utensil-spoon":[512,512,[],"f2e5","M480.1 31.9c-55-55.1-164.9-34.5-227.8 28.5-49.3 49.3-55.1 110-28.8 160.4L9 413.2c-11.6 10.5-12.1 28.5-1 39.5L59.3 504c11 11 29.1 10.5 39.5-1.1l192.4-214.4c50.4 26.3 111.1 20.5 160.4-28.8 63-62.9 83.6-172.8 28.5-227.8z"],utensils:[416,512,[],"f2e7","M207.9 15.2c.8 4.7 16.1 94.5 16.1 128.8 0 52.3-27.8 89.6-68.9 104.6L168 486.7c.7 13.7-10.2 25.3-24 25.3H80c-13.7 0-24.7-11.5-24-25.3l12.9-238.1C27.7 233.6 0 196.2 0 144 0 109.6 15.3 19.9 16.1 15.2 19.3-5.1 61.4-5.4 64 16.3v141.2c1.3 3.4 15.1 3.2 16 0 1.4-25.3 7.9-139.2 8-141.8 3.3-20.8 44.7-20.8 47.9 0 .2 2.7 6.6 116.5 8 141.8.9 3.2 14.8 3.4 16 0V16.3c2.6-21.6 44.8-21.4 48-1.1zm119.2 285.7l-15 185.1c-1.2 14 9.9 26 23.9 26h56c13.3 0 24-10.7 24-24V24c0-13.2-10.7-24-24-24-82.5 0-221.4 178.5-64.9 300.9z"],venus:[288,512,[],"f221","M288 176c0-79.5-64.5-144-144-144S0 96.5 0 176c0 68.5 47.9 125.9 112 140.4V368H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v36c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-36h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-51.6c64.1-14.5 112-71.9 112-140.4zm-224 0c0-44.1 35.9-80 80-80s80 35.9 80 80-35.9 80-80 80-80-35.9-80-80z"],"venus-double":[512,512,[],"f226","M288 176c0-79.5-64.5-144-144-144S0 96.5 0 176c0 68.5 47.9 125.9 112 140.4V368H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v36c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-36h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-51.6c64.1-14.5 112-71.9 112-140.4zm-224 0c0-44.1 35.9-80 80-80s80 35.9 80 80-35.9 80-80 80-80-35.9-80-80zm336 140.4V368h36c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-36v36c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-36h-36c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h36v-51.6c-21.2-4.8-40.6-14.3-57.2-27.3 14-16.7 25-36 32.1-57.1 14.5 14.8 34.7 24 57.1 24 44.1 0 80-35.9 80-80s-35.9-80-80-80c-22.3 0-42.6 9.2-57.1 24-7.1-21.1-18-40.4-32.1-57.1C303.4 43.6 334.3 32 368 32c79.5 0 144 64.5 144 144 0 68.5-47.9 125.9-112 140.4z"],"venus-mars":[576,512,[],"f228","M564 0h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-48.7 48.7C422.5 72.1 396.2 64 368 64c-33.7 0-64.6 11.6-89.2 30.9 14 16.7 25 36 32.1 57.1 14.5-14.8 34.7-24 57.1-24 44.1 0 80 35.9 80 80s-35.9 80-80 80c-22.3 0-42.6-9.2-57.1-24-7.1 21.1-18 40.4-32.1 57.1 24.5 19.4 55.5 30.9 89.2 30.9 79.5 0 144-64.5 144-144 0-28.2-8.1-54.5-22.1-76.7l48.7-48.7 16.9 16.9c2.4 2.4 5.4 3.5 8.4 3.5 6.2 0 12.1-4.8 12.1-12V12c0-6.6-5.4-12-12-12zM144 64C64.5 64 0 128.5 0 208c0 68.5 47.9 125.9 112 140.4V400H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v36c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-36h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-51.6c64.1-14.6 112-71.9 112-140.4 0-79.5-64.5-144-144-144zm0 224c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z"],vial:[480,512,[],"f492","M477.7 186.1L309.5 18.3c-3.1-3.1-8.2-3.1-11.3 0l-34 33.9c-3.1 3.1-3.1 8.2 0 11.3l11.2 11.1L33 316.5c-38.8 38.7-45.1 102-9.4 143.5 20.6 24 49.5 36 78.4 35.9 26.4 0 52.8-10 72.9-30.1l246.3-245.7 11.2 11.1c3.1 3.1 8.2 3.1 11.3 0l34-33.9c3.1-3 3.1-8.1 0-11.2zM318 256H161l148-147.7 78.5 78.3L318 256z"],vials:[640,512,[],"f493","M72 64h24v240c0 44.1 35.9 80 80 80s80-35.9 80-80V64h24c4.4 0 8-3.6 8-8V8c0-4.4-3.6-8-8-8H72c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8zm72 0h64v96h-64V64zm480 384H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h608c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zM360 64h24v240c0 44.1 35.9 80 80 80s80-35.9 80-80V64h24c4.4 0 8-3.6 8-8V8c0-4.4-3.6-8-8-8H360c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8zm72 0h64v96h-64V64z"],video:[576,512,[],"f03d","M336.2 64H47.8C21.4 64 0 85.4 0 111.8v288.4C0 426.6 21.4 448 47.8 448h288.4c26.4 0 47.8-21.4 47.8-47.8V111.8c0-26.4-21.4-47.8-47.8-47.8zm189.4 37.7L416 177.3v157.4l109.6 75.5c21.2 14.6 50.4-.3 50.4-25.8V127.5c0-25.4-29.1-40.4-50.4-25.8z"],"video-slash":[640,512,[],"f4e2","M633.8 458.1l-55-42.5c15.4-1.4 29.2-13.7 29.2-31.1v-257c0-25.5-29.1-40.4-50.4-25.8L448 177.3v137.2l-32-24.7v-178c0-26.4-21.4-47.8-47.8-47.8H123.9L45.5 3.4C38.5-2 28.5-.8 23 6.2L3.4 31.4c-5.4 7-4.2 17 2.8 22.4L42.7 82 416 370.6l178.5 138c7 5.4 17 4.2 22.5-2.8l19.6-25.3c5.5-6.9 4.2-17-2.8-22.4zM32 400.2c0 26.4 21.4 47.8 47.8 47.8h288.4c11.2 0 21.4-4 29.6-10.5L32 154.7v245.5z"],"volleyball-ball":[495,512,[],"f45f","M223.3 243.4c-.9-37-8.6-72.8-22.7-105.7-90.8 42.4-157.5 122.4-180.3 216.8 13.4 30.8 32.9 58.3 56.9 81.1 22.7-79.2 74.2-147.8 146.1-192.2zM186.4 109c-15-26.4-34.5-50.1-57.4-70.7C38 88.1-15.8 191.2 4 300.5c33.4-83.1 98.4-152 182.4-191.5zM374 274.1c8.6-99.8-27.3-197.5-97.5-264.4-14.7-1.7-51.6-5.5-98.9 8.5 57.3 59.3 91 138.2 93.5 222.7 32.5 17.7 67.3 29 102.9 33.2zm-124.7 9.5c-31.6 19.3-58.7 43.9-80.2 72.6 82 57.3 184.5 75.1 277.5 47.8 19.7-26.4 34.2-56.8 42.2-89.9-26.6 6.6-53.7 10.4-80.9 10.4-54.6-.1-108.9-14.1-158.6-40.9zM151 383.3c-15.2 26-25.7 54.4-32.1 84.2 37.6 23 81.7 36.5 129.1 36.5 61 0 116.7-22.1 159.9-58.6C295 461.5 204.6 420.6 151 383.3zM331.3 22.7c55.3 70.4 82.5 161.2 74.6 253.6 30.3.2 60.5-4.8 89.7-14.2 0-2 .3-4 .3-6 0-107.8-68.7-199.1-164.6-233.4z"],"volume-down":[384,512,[],"f027","M256 88.017v335.964c0 21.438-25.943 31.998-40.971 16.971L126.059 352H24c-13.255 0-24-10.745-24-24V184c0-13.255 10.745-24 24-24h102.059l88.971-88.954c15.01-15.01 40.97-4.49 40.97 16.971zM384 256c0-33.717-17.186-64.35-45.972-81.944-15.079-9.214-34.775-4.463-43.992 10.616s-4.464 34.775 10.615 43.992C314.263 234.538 320 244.757 320 256a32.056 32.056 0 0 1-13.802 26.332c-14.524 10.069-18.136 30.006-8.067 44.53 10.07 14.525 30.008 18.136 44.53 8.067C368.546 316.983 384 287.478 384 256z"],"volume-off":[256,512,[],"f026","M256 88.017v335.964c0 21.438-25.943 31.998-40.971 16.971L126.059 352H24c-13.255 0-24-10.745-24-24V184c0-13.255 10.745-24 24-24h102.059l88.971-88.954c15.01-15.01 40.97-4.49 40.97 16.971z"],"volume-up":[576,512,[],"f028","M256 88.017v335.964c0 21.438-25.943 31.998-40.971 16.971L126.059 352H24c-13.255 0-24-10.745-24-24V184c0-13.255 10.745-24 24-24h102.059l88.971-88.954c15.01-15.01 40.97-4.49 40.97 16.971zm182.056-77.876C422.982.92 403.283 5.668 394.061 20.745c-9.221 15.077-4.473 34.774 10.604 43.995C468.967 104.063 512 174.983 512 256c0 73.431-36.077 142.292-96.507 184.206-14.522 10.072-18.129 30.01-8.057 44.532 10.076 14.528 30.016 18.126 44.531 8.057C529.633 438.927 576 350.406 576 256c0-103.244-54.579-194.877-137.944-245.859zM480 256c0-68.547-36.15-129.777-91.957-163.901-15.076-9.22-34.774-4.471-43.994 10.607-9.22 15.078-4.471 34.774 10.607 43.994C393.067 170.188 416 211.048 416 256c0 41.964-20.62 81.319-55.158 105.276-14.521 10.073-18.128 30.01-8.056 44.532 6.216 8.96 16.185 13.765 26.322 13.765a31.862 31.862 0 0 0 18.21-5.709C449.091 377.953 480 318.938 480 256zm-96 0c0-33.717-17.186-64.35-45.972-81.944-15.079-9.214-34.775-4.463-43.992 10.616s-4.464 34.775 10.615 43.992C314.263 234.538 320 244.757 320 256a32.056 32.056 0 0 1-13.802 26.332c-14.524 10.069-18.136 30.006-8.067 44.53 10.07 14.525 30.008 18.136 44.53 8.067C368.546 316.983 384 287.478 384 256z"],warehouse:[640,512,[],"f494","M504 352H136.4c-4.4 0-8 3.6-8 8l-.1 48c0 4.4 3.6 8 8 8H504c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zm0 96H136.1c-4.4 0-8 3.6-8 8l-.1 48c0 4.4 3.6 8 8 8h368c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zm0-192H136.6c-4.4 0-8 3.6-8 8l-.1 48c0 4.4 3.6 8 8 8H504c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zm106.5-139L338.4 3.7a48.15 48.15 0 0 0-36.9 0L29.5 117C11.7 124.5 0 141.9 0 161.3V504c0 4.4 3.6 8 8 8h80c4.4 0 8-3.6 8-8V256c0-17.6 14.6-32 32.6-32h382.8c18 0 32.6 14.4 32.6 32v248c0 4.4 3.6 8 8 8h80c4.4 0 8-3.6 8-8V161.3c0-19.4-11.7-36.8-29.5-44.3z"],weight:[512,512,[],"f496","M448 64h-26c16.4 28.3 26 61 26 96 0 105.9-86.1 192-192 192S64 265.9 64 160c0-35 9.6-67.7 26-96H64C28.7 64 0 92.7 0 128v320c0 35.3 28.7 64 64 64h384c35.3 0 64-28.7 64-64V128c0-35.3-28.7-64-64-64zM256 320c88.4 0 160-71.6 160-160S344.4 0 256 0 96 71.6 96 160s71.6 160 160 160zm-.3-151.9l33.6-78.4c3.5-8.2 12.9-11.9 21-8.4s11.9 12.9 8.4 21L285 180.9c6.7 7.1 10.9 16.6 10.9 27.1 0 22.1-17.9 40-40 40s-40-17.9-40-40c.1-22 17.9-39.8 39.8-39.9z"],wheelchair:[512,512,[],"f193","M496.101 385.669l14.227 28.663c3.929 7.915.697 17.516-7.218 21.445l-65.465 32.886c-16.049 7.967-35.556 1.194-43.189-15.055L331.679 320H192c-15.925 0-29.426-11.71-31.679-27.475C126.433 55.308 128.38 70.044 128 64c0-36.358 30.318-65.635 67.052-63.929 33.271 1.545 60.048 28.905 60.925 62.201.868 32.933-23.152 60.423-54.608 65.039l4.67 32.69H336c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H215.182l4.572 32H352a32 32 0 0 1 28.962 18.392L438.477 396.8l36.178-18.349c7.915-3.929 17.517-.697 21.446 7.218zM311.358 352h-24.506c-7.788 54.204-54.528 96-110.852 96-61.757 0-112-50.243-112-112 0-41.505 22.694-77.809 56.324-97.156-3.712-25.965-6.844-47.86-9.488-66.333C45.956 198.464 0 261.963 0 336c0 97.047 78.953 176 176 176 71.87 0 133.806-43.308 161.11-105.192L311.358 352z"],wifi:[640,512,[],"f1eb","M384 416c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-35.346 28.654-64 64-64s64 28.654 64 64zm136.659-124.443c6.465-6.465 6.245-17.065-.564-23.167-113.793-101.985-286.526-101.869-400.19 0-6.809 6.102-7.029 16.702-.564 23.167l34.006 34.006c5.927 5.927 15.464 6.32 21.769.796 82.88-72.609 207.074-72.447 289.768 0 6.305 5.524 15.842 5.132 21.769-.796l34.006-34.006zm112.11-113.718c6.385-6.385 6.254-16.816-.35-22.973-175.768-163.86-449.134-163.8-624.837 0-6.604 6.157-6.735 16.589-.35 22.973l33.966 33.966c6.095 6.095 15.891 6.231 22.224.383 144.763-133.668 368.356-133.702 513.156 0 6.333 5.848 16.129 5.712 22.224-.383l33.967-33.966z"],"window-close":[512,512,[],"f410","M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-83.6 290.5c4.8 4.8 4.8 12.6 0 17.4l-40.5 40.5c-4.8 4.8-12.6 4.8-17.4 0L256 313.3l-66.5 67.1c-4.8 4.8-12.6 4.8-17.4 0l-40.5-40.5c-4.8-4.8-4.8-12.6 0-17.4l67.1-66.5-67.1-66.5c-4.8-4.8-4.8-12.6 0-17.4l40.5-40.5c4.8-4.8 12.6-4.8 17.4 0l66.5 67.1 66.5-67.1c4.8-4.8 12.6-4.8 17.4 0l40.5 40.5c4.8 4.8 4.8 12.6 0 17.4L313.3 256l67.1 66.5z"],"window-maximize":[512,512,[],"f2d0","M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-16 160H64v-84c0-6.6 5.4-12 12-12h360c6.6 0 12 5.4 12 12v84z"],"window-minimize":[512,512,[],"f2d1","M464 352H48c-26.5 0-48 21.5-48 48v32c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48v-32c0-26.5-21.5-48-48-48z"],"window-restore":[512,512,[],"f2d2","M512 48v288c0 26.5-21.5 48-48 48h-48V176c0-44.1-35.9-80-80-80H128V48c0-26.5 21.5-48 48-48h288c26.5 0 48 21.5 48 48zM384 176v288c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V176c0-26.5 21.5-48 48-48h288c26.5 0 48 21.5 48 48zm-68 28c0-6.6-5.4-12-12-12H76c-6.6 0-12 5.4-12 12v52h252v-52z"],"wine-glass":[288,512,[],"f4e3","M287.4 192.7l-16-178.1C270.7 6.3 263.9 0 255.7 0H32.3c-8.2 0-15 6.3-15.7 14.6L.6 192.7c-7.2 80 50.7 148.9 127.4 157.6V480H74.1c-24.5 0-33.2 32-20 32h179.8c13.1 0 4.5-32-20-32H160V350.3c76.7-8.8 134.6-77.6 127.4-157.6zM226.2 48l7.2 80H54.6l7.2-80h164.4z"],"won-sign":[576,512,[],"f159","M564 192c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-48.028l18.572-80.61c1.732-7.518-3.978-14.694-11.693-14.694h-46.107a11.998 11.998 0 0 0-11.736 9.5L450.73 128H340.839l-19.725-85.987a12 12 0 0 0-11.696-9.317H265.43a12 12 0 0 0-11.687 9.277L233.696 128H124.975L107.5 42.299a12 12 0 0 0-11.758-9.602H53.628c-7.686 0-13.39 7.124-11.709 14.624L60 128H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h62.342l7.171 32H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h83.856l40.927 182.624A12 12 0 0 0 148.492 480h56.767c5.583 0 10.428-3.85 11.689-9.288L259.335 288h55.086l42.386 182.712A12 12 0 0 0 368.496 480h56.826a12 12 0 0 0 11.694-9.306L479.108 288H564c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-70.146l7.373-32H564zm-425.976 0h80.757l-7.457 32h-66.776l-6.524-32zm45.796 150.029c-6.194 25.831-6.758 47.25-7.321 47.25h-1.126s-1.689-22.05-6.758-47.25L157.599 288h38.812l-12.591 54.029zM274.182 224l1.996-8.602c1.856-7.962 3.457-15.968 4.803-23.398h11.794c1.347 7.43 2.947 15.436 4.803 23.398l1.996 8.602h-25.392zm130.959 118.029c-5.068 25.2-6.758 47.25-6.758 47.25h-1.126c-.563 0-1.126-21.42-7.321-47.25L377.542 288h39.107l-11.508 54.029zM430.281 224h-67.42l-7.34-32h81.577l-6.817 32z"],wrench:[512,512,[],"f0ad","M481.156 200c9.3 0 15.12 10.155 10.325 18.124C466.295 259.992 420.419 288 368 288c-79.222 0-143.501-63.974-143.997-143.079C223.505 65.469 288.548-.001 368.002 0c52.362.001 98.196 27.949 123.4 69.743C496.24 77.766 490.523 88 481.154 88H376l-40 56 40 56h105.156zm-171.649 93.003L109.255 493.255c-24.994 24.993-65.515 24.994-90.51 0-24.993-24.994-24.993-65.516 0-90.51L218.991 202.5c16.16 41.197 49.303 74.335 90.516 90.503zM104 432c0-13.255-10.745-24-24-24s-24 10.745-24 24 10.745 24 24 24 24-10.745 24-24z"],"x-ray":[640,512,[],"f497","M240 384c-8.8 0-16 7.2-16 16s7.2 16 16 16 16-7.2 16-16-7.2-16-16-16zm160 32c8.8 0 16-7.2 16-16s-7.2-16-16-16-16 7.2-16 16 7.2 16 16 16zM624 0H16C7.2 0 0 7.2 0 16v32c0 8.8 7.2 16 16 16h608c8.8 0 16-7.2 16-16V16c0-8.8-7.2-16-16-16zm0 448h-48V96H64v352H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h608c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zM480 248c0 4.4-3.6 8-8 8H336v32h104c4.4 0 8 3.6 8 8v16c0 4.4-3.6 8-8 8H336v32h64c26.5 0 48 21.5 48 48s-21.5 48-48 48-48-21.5-48-48v-16h-64v16c0 26.5-21.5 48-48 48s-48-21.5-48-48 21.5-48 48-48h64v-32H200c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h104v-32H168c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h136v-32H200c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h104v-24c0-4.4 3.6-8 8-8h16c4.4 0 8 3.6 8 8v24h104c4.4 0 8 3.6 8 8v16c0 4.4-3.6 8-8 8H336v32h136c4.4 0 8 3.6 8 8v16z"],"yen-sign":[384,512,[],"f157","M351.208 32h-65.277a12 12 0 0 0-10.778 6.724l-55.39 113.163c-14.513 34.704-27.133 71.932-27.133 71.932h-1.262s-12.62-37.228-27.133-71.932l-55.39-113.163A11.997 11.997 0 0 0 98.068 32H32.792c-9.057 0-14.85 9.65-10.59 17.643L102.322 200H44c-6.627 0-12 5.373-12 12v32c0 6.627 5.373 12 12 12h88.162L152 293.228V320H44c-6.627 0-12 5.373-12 12v32c0 6.627 5.373 12 12 12h108v92c0 6.627 5.373 12 12 12h56c6.627 0 12-5.373 12-12v-92h108c6.627 0 12-5.373 12-12v-32c0-6.627-5.373-12-12-12H232v-26.772L251.838 256H340c6.627 0 12-5.373 12-12v-32c0-6.627-5.373-12-12-12h-58.322l80.12-150.357C366.058 41.65 360.266 32 351.208 32z"]};!function(c){try{c()}catch(c){if(!e)throw c}}(function(){!function c(l,v){var h=Object.keys(v).reduce(function(c,l){var h=v[l];return h.icon?c[h.iconName]=h.icon:c[l]=h,c},{});"function"==typeof t.hooks.addPack?t.hooks.addPack(l,h):t.styles[l]=f({},t.styles[l]||{},h),"fas"===l&&c("fa",v)}("fas",r)})}(),function(){"use strict";var c=function(){},l={},h={},v=null,z={mark:c,measure:c};try{"undefined"!=typeof window&&(l=window),"undefined"!=typeof document&&(h=document),"undefined"!=typeof MutationObserver&&(v=MutationObserver),"undefined"!=typeof performance&&(z=performance)}catch(c){}var e=(l.navigator||{}).userAgent,a=void 0===e?"":e,m=l,f=h,s=v,t=z,r=!!m.document,M=!!f.documentElement&&!!f.head&&"function"==typeof f.addEventListener&&"function"==typeof f.createElement,p=~a.indexOf("MSIE")||~a.indexOf("Trident/"),i="___FONT_AWESOME___",b=16,n="svg-inline--fa",g="data-fa-i2svg",H="data-fa-pseudo-element",V="fontawesome-i2svg",o=function(){try{return!0}catch(c){return!1}}(),C=[1,2,3,4,5,6,7,8,9,10],L=C.concat([11,12,13,14,15,16,17,18,19,20]),u=["class","data-prefix","data-icon","data-fa-transform","data-fa-mask"],d=["xs","sm","lg","fw","ul","li","border","pull-left","pull-right","spin","pulse","rotate-90","rotate-180","rotate-270","flip-horizontal","flip-vertical","stack","stack-1x","stack-2x","inverse","layers","layers-text","layers-counter"].concat(C.map(function(c){return c+"x"})).concat(L.map(function(c){return"w-"+c})),y=function(c,l){if(!(c instanceof l))throw new TypeError("Cannot call a class as a function")},w=function(){function v(c,l){for(var h=0;h<l.length;h++){var v=l[h];v.enumerable=v.enumerable||!1,v.configurable=!0,"value"in v&&(v.writable=!0),Object.defineProperty(c,v.key,v)}}return function(c,l,h){return l&&v(c.prototype,l),h&&v(c,h),c}}(),k=Object.assign||function(c){for(var l=1;l<arguments.length;l++){var h=arguments[l];for(var v in h)Object.prototype.hasOwnProperty.call(h,v)&&(c[v]=h[v])}return c},S=function(c){if(Array.isArray(c)){for(var l=0,h=Array(c.length);l<c.length;l++)h[l]=c[l];return h}return Array.from(c)},x=m.FontAwesomeConfig||{},A=Object.keys(x),q=k({familyPrefix:"fa",replacementClass:n,autoReplaceSvg:!0,autoAddCss:!0,autoA11y:!0,searchPseudoElements:!1,observeMutations:!0,keepOriginalSource:!0,measurePerformance:!1,showMissingIcons:!0},x);q.autoReplaceSvg||(q.observeMutations=!1);var O=k({},q);function j(l){var c=(1<arguments.length&&void 0!==arguments[1]?arguments[1]:{}).asNewDefault,h=void 0!==c&&c,v=Object.keys(O),z=h?function(c){return~v.indexOf(c)&&!~A.indexOf(c)}:function(c){return~v.indexOf(c)};Object.keys(l).forEach(function(c){z(c)&&(O[c]=l[c])})}m.FontAwesomeConfig=O;var N=m||{};N[i]||(N[i]={}),N[i].styles||(N[i].styles={}),N[i].hooks||(N[i].hooks={}),N[i].shims||(N[i].shims=[]);var E=N[i],P=[],_=!1;M&&((_=(f.documentElement.doScroll?/^loaded|^c/:/^loaded|^i|^c/).test(f.readyState))||f.addEventListener("DOMContentLoaded",function c(){f.removeEventListener("DOMContentLoaded",c),_=1,P.map(function(c){return c()})}));var T=function(c){M&&(_?setTimeout(c,0):P.push(c))},F=b,I={size:16,x:0,y:0,rotate:0,flipX:!1,flipY:!1};function R(c){if(c&&M){var l=f.createElement("style");l.setAttribute("type","text/css"),l.innerHTML=c;for(var h=f.head.childNodes,v=null,z=h.length-1;-1<z;z--){var e=h[z],a=(e.tagName||"").toUpperCase();-1<["STYLE","LINK"].indexOf(a)&&(v=e)}return f.head.insertBefore(l,v),c}}var W=0;function B(){return++W}function D(c){for(var l=[],h=(c||[]).length>>>0;h--;)l[h]=c[h];return l}function X(c){return c.classList?D(c.classList):(c.getAttribute("class")||"").split(" ").filter(function(c){return c})}function Y(c,l){var h,v=l.split("-"),z=v[0],e=v.slice(1).join("-");return z!==c||""===e||(h=e,~d.indexOf(h))?null:e}function U(c){return(""+c).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&#39;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function K(h){return Object.keys(h||{}).reduce(function(c,l){return c+(l+": ")+h[l]+";"},"")}function G(c){return c.size!==I.size||c.x!==I.x||c.y!==I.y||c.rotate!==I.rotate||c.flipX||c.flipY}function J(c){var l=c.transform,h=c.containerWidth,v=c.iconWidth;return{outer:{transform:"translate("+h/2+" 256)"},inner:{transform:"translate("+32*l.x+", "+32*l.y+") "+" "+("scale("+l.size/16*(l.flipX?-1:1)+", "+l.size/16*(l.flipY?-1:1)+") ")+" "+("rotate("+l.rotate+" 0 0)")},path:{transform:"translate("+v/2*-1+" -256)"}}}var Q={x:0,y:0,width:"100%",height:"100%"},Z=function(c){var l=c.children,h=c.attributes,v=c.main,z=c.mask,e=c.transform,a=v.width,m=v.icon,s=z.width,t=z.icon,f=J({transform:e,containerWidth:s,iconWidth:a}),r={tag:"rect",attributes:k({},Q,{fill:"white"})},M={tag:"g",attributes:k({},f.inner),children:[{tag:"path",attributes:k({},m.attributes,f.path,{fill:"black"})}]},i={tag:"g",attributes:k({},f.outer),children:[M]},n="mask-"+B(),H="clip-"+B(),V={tag:"defs",children:[{tag:"clipPath",attributes:{id:H},children:[t]},{tag:"mask",attributes:k({},Q,{id:n,maskUnits:"userSpaceOnUse",maskContentUnits:"userSpaceOnUse"}),children:[r,i]}]};return l.push(V,{tag:"rect",attributes:k({fill:"currentColor","clip-path":"url(#"+H+")",mask:"url(#"+n+")"},Q)}),{children:l,attributes:h}},$=function(c){var l=c.children,h=c.attributes,v=c.main,z=c.transform,e=K(c.styles);if(0<e.length&&(h.style=e),G(z)){var a=J({transform:z,containerWidth:v.width,iconWidth:v.width});l.push({tag:"g",attributes:k({},a.outer),children:[{tag:"g",attributes:k({},a.inner),children:[{tag:v.icon.tag,children:v.icon.children,attributes:k({},v.icon.attributes,a.path)}]}]})}else l.push(v.icon);return{children:l,attributes:h}},cc=function(c){var l=c.children,h=c.main,v=c.mask,z=c.attributes,e=c.styles,a=c.transform;if(G(a)&&h.found&&!v.found){var m=h.width/h.height/2,s=.5;z.style=K(k({},e,{"transform-origin":m+a.x/16+"em "+(s+a.y/16)+"em"}))}return[{tag:"svg",attributes:z,children:l}]},lc=function(c){var l=c.prefix,h=c.iconName,v=c.children,z=c.attributes,e=c.symbol,a=!0===e?l+"-"+O.familyPrefix+"-"+h:e;return[{tag:"svg",attributes:{style:"display: none;"},children:[{tag:"symbol",attributes:k({},z,{id:a}),children:v}]}]};function hc(c){var l=c.icons,h=l.main,v=l.mask,z=c.prefix,e=c.iconName,a=c.transform,m=c.symbol,s=c.title,t=c.extra,f=c.watchable,r=void 0!==f&&f,M=v.found?v:h,i=M.width,n=M.height,H="fa-w-"+Math.ceil(i/n*16),V=[O.replacementClass,e?O.familyPrefix+"-"+e:"",H].concat(t.classes).join(" "),o={children:[],attributes:k({},t.attributes,{"data-prefix":z,"data-icon":e,class:V,role:"img",xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 "+i+" "+n})};r&&(o.attributes[g]=""),s&&o.children.push({tag:"title",attributes:{id:o.attributes["aria-labelledby"]||"title-"+B()},children:[s]});var C=k({},o,{prefix:z,iconName:e,main:h,mask:v,transform:a,symbol:m,styles:t.styles}),L=v.found&&h.found?Z(C):$(C),u=L.children,d=L.attributes;return C.children=u,C.attributes=d,m?lc(C):cc(C)}function vc(c){var l=c.content,h=c.width,v=c.height,z=c.transform,e=c.title,a=c.extra,m=c.watchable,s=void 0!==m&&m,t=k({},a.attributes,e?{title:e}:{},{class:a.classes.join(" ")});s&&(t[g]="");var f,r,M,i,n,H,V,o,C,L=k({},a.styles);G(z)&&(L.transform=(r=(f={transform:z,startCentered:!0,width:h,height:v}).transform,M=f.width,i=void 0===M?b:M,n=f.height,H=void 0===n?b:n,V=f.startCentered,C="",C+=(o=void 0!==V&&V)&&p?"translate("+(r.x/F-i/2)+"em, "+(r.y/F-H/2)+"em) ":o?"translate(calc(-50% + "+r.x/F+"em), calc(-50% + "+r.y/F+"em)) ":"translate("+r.x/F+"em, "+r.y/F+"em) ",C+="scale("+r.size/F*(r.flipX?-1:1)+", "+r.size/F*(r.flipY?-1:1)+") ",C+="rotate("+r.rotate+"deg) "),L["-webkit-transform"]=L.transform);var u=K(L);0<u.length&&(t.style=u);var d=[];return d.push({tag:"span",attributes:t,children:[l]}),e&&d.push({tag:"span",attributes:{class:"sr-only"},children:[e]}),d}var zc=function(){},ec=O.measurePerformance&&t&&t.mark&&t.measure?t:{mark:zc,measure:zc},ac='FA "5.0.10"',mc=function(c){ec.mark(ac+" "+c+" ends"),ec.measure(ac+" "+c,ac+" "+c+" begins",ac+" "+c+" ends")},sc={begin:function(c){return ec.mark(ac+" "+c+" begins"),function(){return mc(c)}},end:mc},tc=function(c,l,h,v){var z,e,a,m,s,t=Object.keys(c),f=t.length,r=void 0!==v?(m=l,s=v,function(c,l,h,v){return m.call(s,c,l,h,v)}):l;for(void 0===h?(z=1,a=c[t[0]]):(z=0,a=h);z<f;z++)a=r(a,c[e=t[z]],e,c);return a},fc=E.styles,rc=E.shims,Mc={},ic={},nc={},Hc=function(){var c=function(v){return tc(fc,function(c,l,h){return c[h]=tc(l,v,{}),c},{})};Mc=c(function(c,l,h){return c[l[3]]=h,c}),ic=c(function(l,c,h){var v=c[2];return l[h]=h,v.forEach(function(c){l[c]=h}),l});var e="far"in fc;nc=tc(rc,function(c,l){var h=l[0],v=l[1],z=l[2];return"far"!==v||e||(v="fas"),c[h]={prefix:v,iconName:z},c},{})};Hc();var Vc=E.styles,oc=function(){return{prefix:null,iconName:null,rest:[]}};function Cc(c){return c.reduce(function(c,l){var h=Y(O.familyPrefix,l);if(Vc[l])c.prefix=l;else if(h){var v="fa"===c.prefix?nc[h]||{prefix:null,iconName:null}:{};c.iconName=v.iconName||h,c.prefix=v.prefix||c.prefix}else l!==O.replacementClass&&0!==l.indexOf("fa-w-")&&c.rest.push(l);return c},oc())}function Lc(c,l,h){if(c&&c[l]&&c[l][h])return{prefix:l,iconName:h,icon:c[l][h]}}function uc(c){var h,l=c.tag,v=c.attributes,z=void 0===v?{}:v,e=c.children,a=void 0===e?[]:e;return"string"==typeof c?U(c):"<"+l+" "+(h=z,Object.keys(h||{}).reduce(function(c,l){return c+(l+'="')+U(h[l])+'" '},"").trim())+">"+a.map(uc).join("")+"</"+l+">"}var dc=function(){};function pc(c){return"string"==typeof(c.getAttribute?c.getAttribute(g):null)}var bc={replace:function(c){var l=c[0],h=c[1].map(function(c){return uc(c)}).join("\n");if(l.parentNode&&l.outerHTML)l.outerHTML=h+(O.keepOriginalSource&&"svg"!==l.tagName.toLowerCase()?"\x3c!-- "+l.outerHTML+" --\x3e":"");else if(l.parentNode){var v=document.createElement("span");l.parentNode.replaceChild(v,l),v.outerHTML=h}},nest:function(c){var l=c[0],h=c[1];if(~X(l).indexOf(O.replacementClass))return bc.replace(c);var v=new RegExp(O.familyPrefix+"-.*");delete h[0].attributes.style;var z=h[0].attributes.class.split(" ").reduce(function(c,l){return l===O.replacementClass||l.match(v)?c.toSvg.push(l):c.toNode.push(l),c},{toNode:[],toSvg:[]});h[0].attributes.class=z.toSvg.join(" ");var e=h.map(function(c){return uc(c)}).join("\n");l.setAttribute("class",z.toNode.join(" ")),l.setAttribute(g,""),l.innerHTML=e}};function gc(h,c){var v="function"==typeof c?c:dc;0===h.length?v():(m.requestAnimationFrame||function(c){return c()})(function(){var c=!0===O.autoReplaceSvg?bc.replace:bc[O.autoReplaceSvg]||bc.replace,l=sc.begin("mutate");h.map(c),l(),v()})}var yc=!1;var wc=null;var kc=function(c){var l=c.getAttribute("style"),h=[];return l&&(h=l.split(";").reduce(function(c,l){var h=l.split(":"),v=h[0],z=h.slice(1);return v&&0<z.length&&(c[v]=z.join(":").trim()),c},{})),h};var Sc=function(c){var l,h,v,z,e=c.getAttribute("data-prefix"),a=c.getAttribute("data-icon"),m=void 0!==c.innerText?c.innerText.trim():"",s=Cc(X(c));return e&&a&&(s.prefix=e,s.iconName=a),s.prefix&&1<m.length?s.iconName=(v=s.prefix,z=c.innerText,ic[v][z]):s.prefix&&1===m.length&&(s.iconName=(l=s.prefix,h=function(c){for(var l="",h=0;h<c.length;h++)l+=("000"+c.charCodeAt(h).toString(16)).slice(-4);return l}(c.innerText),Mc[l][h])),s},xc=function(c){var l={size:16,x:0,y:0,flipX:!1,flipY:!1,rotate:0};return c?c.toLowerCase().split(" ").reduce(function(c,l){var h=l.toLowerCase().split("-"),v=h[0],z=h.slice(1).join("-");if(v&&"h"===z)return c.flipX=!0,c;if(v&&"v"===z)return c.flipY=!0,c;if(z=parseFloat(z),isNaN(z))return c;switch(v){case"grow":c.size=c.size+z;break;case"shrink":c.size=c.size-z;break;case"left":c.x=c.x-z;break;case"right":c.x=c.x+z;break;case"up":c.y=c.y-z;break;case"down":c.y=c.y+z;break;case"rotate":c.rotate=c.rotate+z}return c},l):l},Ac=function(c){return xc(c.getAttribute("data-fa-transform"))},qc=function(c){var l=c.getAttribute("data-fa-symbol");return null!==l&&(""===l||l)},Oc=function(c){var l=D(c.attributes).reduce(function(c,l){return"class"!==c.name&&"style"!==c.name&&(c[l.name]=l.value),c},{}),h=c.getAttribute("title");return O.autoA11y&&(h?l["aria-labelledby"]=O.replacementClass+"-title-"+B():l["aria-hidden"]="true"),l},jc=function(c){var l=c.getAttribute("data-fa-mask");return l?Cc(l.split(" ").map(function(c){return c.trim()})):oc()};function Nc(c){this.name="MissingIcon",this.message=c||"Icon unavailable",this.stack=(new Error).stack}(Nc.prototype=Object.create(Error.prototype)).constructor=Nc;var Ec={fill:"currentColor"},Pc={attributeType:"XML",repeatCount:"indefinite",dur:"2s"},_c={tag:"path",attributes:k({},Ec,{d:"M156.5,447.7l-12.6,29.5c-18.7-9.5-35.9-21.2-51.5-34.9l22.7-22.7C127.6,430.5,141.5,440,156.5,447.7z M40.6,272H8.5 c1.4,21.2,5.4,41.7,11.7,61.1L50,321.2C45.1,305.5,41.8,289,40.6,272z M40.6,240c1.4-18.8,5.2-37,11.1-54.1l-29.5-12.6 C14.7,194.3,10,216.7,8.5,240H40.6z M64.3,156.5c7.8-14.9,17.2-28.8,28.1-41.5L69.7,92.3c-13.7,15.6-25.5,32.8-34.9,51.5 L64.3,156.5z M397,419.6c-13.9,12-29.4,22.3-46.1,30.4l11.9,29.8c20.7-9.9,39.8-22.6,56.9-37.6L397,419.6z M115,92.4 c13.9-12,29.4-22.3,46.1-30.4l-11.9-29.8c-20.7,9.9-39.8,22.6-56.8,37.6L115,92.4z M447.7,355.5c-7.8,14.9-17.2,28.8-28.1,41.5 l22.7,22.7c13.7-15.6,25.5-32.9,34.9-51.5L447.7,355.5z M471.4,272c-1.4,18.8-5.2,37-11.1,54.1l29.5,12.6 c7.5-21.1,12.2-43.5,13.6-66.8H471.4z M321.2,462c-15.7,5-32.2,8.2-49.2,9.4v32.1c21.2-1.4,41.7-5.4,61.1-11.7L321.2,462z M240,471.4c-18.8-1.4-37-5.2-54.1-11.1l-12.6,29.5c21.1,7.5,43.5,12.2,66.8,13.6V471.4z M462,190.8c5,15.7,8.2,32.2,9.4,49.2h32.1 c-1.4-21.2-5.4-41.7-11.7-61.1L462,190.8z M92.4,397c-12-13.9-22.3-29.4-30.4-46.1l-29.8,11.9c9.9,20.7,22.6,39.8,37.6,56.9 L92.4,397z M272,40.6c18.8,1.4,36.9,5.2,54.1,11.1l12.6-29.5C317.7,14.7,295.3,10,272,8.5V40.6z M190.8,50 c15.7-5,32.2-8.2,49.2-9.4V8.5c-21.2,1.4-41.7,5.4-61.1,11.7L190.8,50z M442.3,92.3L419.6,115c12,13.9,22.3,29.4,30.5,46.1 l29.8-11.9C470,128.5,457.3,109.4,442.3,92.3z M397,92.4l22.7-22.7c-15.6-13.7-32.8-25.5-51.5-34.9l-12.6,29.5 C370.4,72.1,384.4,81.5,397,92.4z"})},Tc=k({},Pc,{attributeName:"opacity"}),Fc={tag:"g",children:[_c,{tag:"circle",attributes:k({},Ec,{cx:"256",cy:"364",r:"28"}),children:[{tag:"animate",attributes:k({},Pc,{attributeName:"r",values:"28;14;28;28;14;28;"})},{tag:"animate",attributes:k({},Tc,{values:"1;0;1;1;0;1;"})}]},{tag:"path",attributes:k({},Ec,{opacity:"1",d:"M263.7,312h-16c-6.6,0-12-5.4-12-12c0-71,77.4-63.9,77.4-107.8c0-20-17.8-40.2-57.4-40.2c-29.1,0-44.3,9.6-59.2,28.7 c-3.9,5-11.1,6-16.2,2.4l-13.1-9.2c-5.6-3.9-6.9-11.8-2.6-17.2c21.2-27.2,46.4-44.7,91.2-44.7c52.3,0,97.4,29.8,97.4,80.2 c0,67.6-77.4,63.5-77.4,107.8C275.7,306.6,270.3,312,263.7,312z"}),children:[{tag:"animate",attributes:k({},Tc,{values:"1;0;0;0;0;1;"})}]},{tag:"path",attributes:k({},Ec,{opacity:"0",d:"M232.5,134.5l7,168c0.3,6.4,5.6,11.5,12,11.5h9c6.4,0,11.7-5.1,12-11.5l7-168c0.3-6.8-5.2-12.5-12-12.5h-23 C237.7,122,232.2,127.7,232.5,134.5z"}),children:[{tag:"animate",attributes:k({},Tc,{values:"0;0;1;1;0;0;"})}]}]},Ic=E.styles,Rc="fa-layers-text",Wc=/Font Awesome 5 (Solid|Regular|Light|Brands)/,Bc={Solid:"fas",Regular:"far",Light:"fal",Brands:"fab"};function Dc(c,l){var h={found:!1,width:512,height:512,icon:Fc};if(c&&l&&Ic[l]&&Ic[l][c]){var v=Ic[l][c];h={found:!0,width:v[0],height:v[1],icon:{tag:"path",attributes:{fill:"currentColor",d:v.slice(4)[0]}}}}else if(c&&l&&!O.showMissingIcons)throw new Nc("Icon is missing for prefix "+l+" with icon name "+c);return h}function Xc(c){var l,h,v,z,e,a,m,s,t,f,r,M,i,n,H,V,o,C,L,u=(h=Sc(l=c),v=h.iconName,z=h.prefix,e=h.rest,a=kc(l),m=Ac(l),s=qc(l),t=Oc(l),f=jc(l),{iconName:v,title:l.getAttribute("title"),prefix:z,transform:m,symbol:s,mask:f,extra:{classes:e,styles:a,attributes:t}});return~u.extra.classes.indexOf(Rc)?function(c,l){var h=l.title,v=l.transform,z=l.extra,e=null,a=null;if(p){var m=parseInt(getComputedStyle(c).fontSize,10),s=c.getBoundingClientRect();e=s.width/m,a=s.height/m}return O.autoA11y&&!h&&(z.attributes["aria-hidden"]="true"),[c,vc({content:c.innerHTML,width:e,height:a,transform:v,title:h,extra:z,watchable:!0})]}(c,u):(r=c,i=(M=u).iconName,n=M.title,H=M.prefix,V=M.transform,o=M.symbol,C=M.mask,L=M.extra,[r,hc({icons:{main:Dc(i,H),mask:Dc(C.iconName,C.prefix)},prefix:H,iconName:i,transform:V,symbol:o,mask:C,title:n,extra:L,watchable:!0})])}function Yc(c){"function"==typeof c.remove?c.remove():c&&c.parentNode&&c.parentNode.removeChild(c)}function Uc(c){if(M){var l=sc.begin("searchPseudoElements");yc=!0,function(){D(c.querySelectorAll("*")).forEach(function(a){[":before",":after"].forEach(function(l){var c=m.getComputedStyle(a,l),h=c.getPropertyValue("font-family").match(Wc),v=D(a.children).filter(function(c){return c.getAttribute(H)===l})[0];if(v&&(v.nextSibling&&-1<v.nextSibling.textContent.indexOf(H)&&Yc(v.nextSibling),Yc(v),v=null),h&&!v){var z=c.getPropertyValue("content"),e=f.createElement("i");e.setAttribute("class",""+Bc[h[1]]),e.setAttribute(H,l),e.innerText=3===z.length?z.substr(1,1):z,":before"===l?a.insertBefore(e,a.firstChild):a.appendChild(e)}})})}(),yc=!1,l()}}function Kc(c){var l=1<arguments.length&&void 0!==arguments[1]?arguments[1]:null;if(M){var h=f.documentElement.classList,v=function(c){return h.add(V+"-"+c)},z=function(c){return h.remove(V+"-"+c)},e=Object.keys(Ic),a=["."+Rc+":not(["+g+"])"].concat(e.map(function(c){return"."+c+":not(["+g+"])"})).join(", ");if(0!==a.length){var m=D(c.querySelectorAll(a));if(0<m.length){v("pending"),z("complete");var s=sc.begin("onTree"),t=m.reduce(function(c,l){try{var h=Xc(l);h&&c.push(h)}catch(c){o||c instanceof Nc&&console.error(c)}return c},[]);s(),gc(t,function(){v("active"),v("complete"),z("pending"),"function"==typeof l&&l()})}}}}function Gc(c){var l=1<arguments.length&&void 0!==arguments[1]?arguments[1]:null,h=Xc(c);h&&gc([h],l)}var Jc=function(){var c=n,l=O.familyPrefix,h=O.replacementClass,v="svg:not(:root).svg-inline--fa{overflow:visible}.svg-inline--fa{display:inline-block;font-size:inherit;height:1em;overflow:visible;vertical-align:-.125em}.svg-inline--fa.fa-lg{vertical-align:-.225em}.svg-inline--fa.fa-w-1{width:.0625em}.svg-inline--fa.fa-w-2{width:.125em}.svg-inline--fa.fa-w-3{width:.1875em}.svg-inline--fa.fa-w-4{width:.25em}.svg-inline--fa.fa-w-5{width:.3125em}.svg-inline--fa.fa-w-6{width:.375em}.svg-inline--fa.fa-w-7{width:.4375em}.svg-inline--fa.fa-w-8{width:.5em}.svg-inline--fa.fa-w-9{width:.5625em}.svg-inline--fa.fa-w-10{width:.625em}.svg-inline--fa.fa-w-11{width:.6875em}.svg-inline--fa.fa-w-12{width:.75em}.svg-inline--fa.fa-w-13{width:.8125em}.svg-inline--fa.fa-w-14{width:.875em}.svg-inline--fa.fa-w-15{width:.9375em}.svg-inline--fa.fa-w-16{width:1em}.svg-inline--fa.fa-w-17{width:1.0625em}.svg-inline--fa.fa-w-18{width:1.125em}.svg-inline--fa.fa-w-19{width:1.1875em}.svg-inline--fa.fa-w-20{width:1.25em}.svg-inline--fa.fa-pull-left{margin-right:.3em;width:auto}.svg-inline--fa.fa-pull-right{margin-left:.3em;width:auto}.svg-inline--fa.fa-border{height:1.5em}.svg-inline--fa.fa-li{width:2em}.svg-inline--fa.fa-fw{width:1.25em}.fa-layers svg.svg-inline--fa{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.fa-layers{display:inline-block;height:1em;position:relative;text-align:center;vertical-align:-.125em;width:1em}.fa-layers svg.svg-inline--fa{-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-counter,.fa-layers-text{display:inline-block;position:absolute;text-align:center}.fa-layers-text{left:50%;top:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-counter{background-color:#ff253a;border-radius:1em;-webkit-box-sizing:border-box;box-sizing:border-box;color:#fff;height:1.5em;line-height:1;max-width:5em;min-width:1.5em;overflow:hidden;padding:.25em;right:0;text-overflow:ellipsis;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-bottom-right{bottom:0;right:0;top:auto;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:bottom right;transform-origin:bottom right}.fa-layers-bottom-left{bottom:0;left:0;right:auto;top:auto;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:bottom left;transform-origin:bottom left}.fa-layers-top-right{right:0;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-top-left{left:0;right:auto;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top left;transform-origin:top left}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:solid .08em #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.fa-rotate-90{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-webkit-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{-webkit-transform:scale(1,-1);transform:scale(1,-1)}.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1,-1);transform:scale(-1,-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;position:relative;width:2em}.fa-stack-1x,.fa-stack-2x{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.svg-inline--fa.fa-stack-1x{height:1em;width:1em}.svg-inline--fa.fa-stack-2x{height:2em;width:2em}.fa-inverse{color:#fff}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}";if("fa"!==l||h!==c){var z=new RegExp("\\.fa\\-","g"),e=new RegExp("\\."+c,"g");v=v.replace(z,"."+l+"-").replace(e,"."+h)}return v};var Qc=function(){function c(){y(this,c),this.definitions={}}return w(c,[{key:"add",value:function(){for(var l=this,c=arguments.length,h=Array(c),v=0;v<c;v++)h[v]=arguments[v];var z=h.reduce(this._pullDefinitions,{});Object.keys(z).forEach(function(c){l.definitions[c]=k({},l.definitions[c]||{},z[c]),function c(l,v){var h=Object.keys(v).reduce(function(c,l){var h=v[l];return h.icon?c[h.iconName]=h.icon:c[l]=h,c},{});"function"==typeof E.hooks.addPack?E.hooks.addPack(l,h):E.styles[l]=k({},E.styles[l]||{},h),"fas"===l&&c("fa",v)}(c,z[c])})}},{key:"reset",value:function(){this.definitions={}}},{key:"_pullDefinitions",value:function(e,c){var a=c.prefix&&c.iconName&&c.icon?{0:c}:c;return Object.keys(a).map(function(c){var l=a[c],h=l.prefix,v=l.iconName,z=l.icon;e[h]||(e[h]={}),e[h][v]=z}),e}}]),c}();function Zc(c){return{found:!0,width:c[0],height:c[1],icon:{tag:"path",attributes:{fill:"currentColor",d:c.slice(4)[0]}}}}var $c=!1;function cl(){O.autoAddCss&&($c||R(Jc()),$c=!0)}function ll(l,c){return Object.defineProperty(l,"abstract",{get:c}),Object.defineProperty(l,"html",{get:function(){return l.abstract.map(function(c){return uc(c)})}}),Object.defineProperty(l,"node",{get:function(){if(M){var c=f.createElement("div");return c.innerHTML=l.html,c.children}}}),l}function hl(c){var l=c.prefix,h=void 0===l?"fa":l,v=c.iconName;if(v)return Lc(zl.definitions,h,v)||Lc(E.styles,h,v)}var vl,zl=new Qc,el=(vl=function(c){var l=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{},h=l.transform,v=void 0===h?I:h,z=l.symbol,e=void 0!==z&&z,a=l.mask,m=void 0===a?null:a,s=l.title,t=void 0===s?null:s,f=l.classes,r=void 0===f?[]:f,M=l.attributes,i=void 0===M?{}:M,n=l.styles,H=void 0===n?{}:n;if(c){var V=c.prefix,o=c.iconName,C=c.icon;return ll(k({type:"icon"},c),function(){return cl(),O.autoA11y&&(t?i["aria-labelledby"]=O.replacementClass+"-title-"+B():i["aria-hidden"]="true"),hc({icons:{main:Zc(C),mask:m?Zc(m.icon):{found:!1,width:null,height:null,icon:{}}},prefix:V,iconName:o,transform:k({},I,v),symbol:e,title:t,extra:{attributes:i,styles:H,classes:r}})})}},function(c){var l=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{},h=(c||{}).icon?c:hl(c||{}),v=l.mask;return v&&(v=(v||{}).icon?v:hl(v||{})),vl(h,k({},l,{mask:v}))}),al={noAuto:function(){var c;j({autoReplaceSvg:c=!1,observeMutations:c}),wc&&wc.disconnect()},dom:{i2svg:function(){var c=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{};if(M){cl();var l=c.node,h=void 0===l?f:l,v=c.callback,z=void 0===v?function(){}:v;O.searchPseudoElements&&Uc(h),Kc(h,z)}},css:Jc,insertCss:function(){R(Jc())}},library:zl,parse:{transform:function(c){return xc(c)}},findIconDefinition:hl,icon:el,text:function(c){var l=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{},h=l.transform,v=void 0===h?I:h,z=l.title,e=void 0===z?null:z,a=l.classes,m=void 0===a?[]:a,s=l.attributes,t=void 0===s?{}:s,f=l.styles,r=void 0===f?{}:f;return ll({type:"text",content:c},function(){return cl(),vc({content:c,transform:k({},I,v),title:e,extra:{attributes:t,styles:r,classes:[O.familyPrefix+"-layers-text"].concat(S(m))}})})},layer:function(c){return ll({type:"layer"},function(){cl();var l=[];return c(function(c){Array.isArray(c)?c.map(function(c){l=l.concat(c.abstract)}):l=l.concat(c.abstract)}),[{tag:"span",attributes:{class:O.familyPrefix+"-layers"},children:l}]})}},ml=function(){M&&O.autoReplaceSvg&&al.dom.i2svg({node:f})};Object.defineProperty(al,"config",{get:function(){return O},set:function(c){j(c)}}),function(c){try{c()}catch(c){if(!o)throw c}}(function(){r&&(m.FontAwesome||(m.FontAwesome=al),T(function(){0<Object.keys(E.styles).length&&ml(),O.observeMutations&&"function"==typeof MutationObserver&&function(c){if(s){var z=c.treeCallback,e=c.nodeCallback,a=c.pseudoElementsCallback;wc=new s(function(c){yc||D(c).forEach(function(c){if("childList"===c.type&&0<c.addedNodes.length&&!pc(c.addedNodes[0])&&(O.searchPseudoElements&&a(c.target),z(c.target)),"attributes"===c.type&&c.target.parentNode&&O.searchPseudoElements&&a(c.target.parentNode),"attributes"===c.type&&pc(c.target)&&~u.indexOf(c.attributeName))if("class"===c.attributeName){var l=Cc(X(c.target)),h=l.prefix,v=l.iconName;h&&c.target.setAttribute("data-prefix",h),v&&c.target.setAttribute("data-icon",v)}else e(c.target)})}),M&&wc.observe(f.getElementsByTagName("body")[0],{childList:!0,attributes:!0,characterData:!0,subtree:!0})}}({treeCallback:Kc,nodeCallback:Gc,pseudoElementsCallback:Uc})})),E.hooks=k({},E.hooks,{addPack:function(c,l){E.styles[c]=k({},E.styles[c]||{},l),Hc(),ml()},addShims:function(c){var l;(l=E.shims).push.apply(l,S(c)),Hc(),ml()}})})}(); \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/js/jquery.js b/main/app/sprinkles/core/assets/SiteAssets/js/jquery.js
new file mode 100644
index 0000000..727074b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/js/jquery.js
@@ -0,0 +1,4 @@
+/*! jQuery v1.11.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */
+!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.1",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b=a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML="<div class='a'></div><div class='a i'></div>",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML="<select msallowclip=''><option selected=''></option></select>",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=lb(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=mb(b);function pb(){}pb.prototype=d.filters=d.pseudos,d.setFilters=new pb,g=fb.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R," ")}),h=h.slice(c.length));for(g in d.filter)!(e=X[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?fb.error(a):z(a,i).slice(0)};function qb(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;
+ if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?m.queue(this[0],a):void 0===b?this:this.each(function(){var c=m.queue(this,a,b);m._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&m.dequeue(this,a)})},dequeue:function(a){return this.each(function(){m.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=m.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=m._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=["Top","Right","Bottom","Left"],U=function(a,b){return a=b||a,"none"===m.css(a,"display")||!m.contains(a.ownerDocument,a)},V=m.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===m.type(c)){e=!0;for(h in c)m.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,m.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(m(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav></:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[m.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=Z.test(e)?this.mouseHooks:Y.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new m.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=f.srcElement||y),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,g.filter?g.filter(a,f):a},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button,g=b.fromElement;return null==a.pageX&&null!=b.clientX&&(d=a.target.ownerDocument||y,e=d.documentElement,c=d.body,a.pageX=b.clientX+(e&&e.scrollLeft||c&&c.scrollLeft||0)-(e&&e.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||c&&c.scrollTop||0)-(e&&e.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&g&&(a.relatedTarget=g===a.target?b.toElement:g),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==cb()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===cb()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return m.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return m.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=m.extend(new m.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?m.event.trigger(e,null,b):m.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},m.removeEvent=y.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]===K&&(a[d]=null),a.detachEvent(d,c))},m.Event=function(a,b){return this instanceof m.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?ab:bb):this.type=a,b&&m.extend(this,b),this.timeStamp=a&&a.timeStamp||m.now(),void(this[m.expando]=!0)):new m.Event(a,b)},m.Event.prototype={isDefaultPrevented:bb,isPropagationStopped:bb,isImmediatePropagationStopped:bb,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=ab,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=ab,a&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=ab,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},m.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){m.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!m.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),k.submitBubbles||(m.event.special.submit={setup:function(){return m.nodeName(this,"form")?!1:void m.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=m.nodeName(b,"input")||m.nodeName(b,"button")?b.form:void 0;c&&!m._data(c,"submitBubbles")&&(m.event.add(c,"submit._submit",function(a){a._submit_bubble=!0}),m._data(c,"submitBubbles",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&m.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){return m.nodeName(this,"form")?!1:void m.event.remove(this,"._submit")}}),k.changeBubbles||(m.event.special.change={setup:function(){return X.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(m.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._just_changed=!0)}),m.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),m.event.simulate("change",this,a,!0)})),!1):void m.event.add(this,"beforeactivate._change",function(a){var b=a.target;X.test(b.nodeName)&&!m._data(b,"changeBubbles")&&(m.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||m.event.simulate("change",this.parentNode,a,!0)}),m._data(b,"changeBubbles",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return m.event.remove(this,"._change"),!X.test(this.nodeName)}}),k.focusinBubbles||m.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){m.event.simulate(b,a.target,m.event.fix(a),!0)};m.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=m._data(d,b);e||d.addEventListener(a,c,!0),m._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=m._data(d,b)-1;e?m._data(d,b,e):(d.removeEventListener(a,c,!0),m._removeData(d,b))}}}),m.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(f in a)this.on(f,b,c,a[f],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=bb;else if(!d)return this;return 1===e&&(g=d,d=function(a){return m().off(a),g.apply(this,arguments)},d.guid=g.guid||(g.guid=m.guid++)),this.each(function(){m.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,m(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=bb),this.each(function(){m.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){m.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?m.event.trigger(a,b,c,!0):void 0}});function db(a){var b=eb.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}var eb="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",fb=/ jQuery\d+="(?:null|\d+)"/g,gb=new RegExp("<(?:"+eb+")[\\s/>]","i"),hb=/^\s+/,ib=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,jb=/<([\w:]+)/,kb=/<tbody/i,lb=/<|&#?\w+;/,mb=/<(?:script|style|link)/i,nb=/checked\s*(?:[^=]|=\s*.checked.)/i,ob=/^$|\/(?:java|ecma)script/i,pb=/^true\/(.*)/,qb=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,rb={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:k.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},sb=db(y),tb=sb.appendChild(y.createElement("div"));rb.optgroup=rb.option,rb.tbody=rb.tfoot=rb.colgroup=rb.caption=rb.thead,rb.th=rb.td;function ub(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ub(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function vb(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wb(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xb(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function yb(a){var b=pb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function zb(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Ab(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Bb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xb(b).text=a.text,yb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!gb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(tb.innerHTML=a.outerHTML,tb.removeChild(f=tb.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ub(f),h=ub(a),g=0;null!=(e=h[g]);++g)d[g]&&Bb(e,d[g]);if(b)if(c)for(h=h||ub(a),d=d||ub(f),g=0;null!=(e=h[g]);g++)Ab(e,d[g]);else Ab(a,f);return d=ub(f,"script"),d.length>0&&zb(d,!i&&ub(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=db(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(lb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(jb.exec(f)||["",""])[1].toLowerCase(),l=rb[i]||rb._default,h.innerHTML=l[1]+f.replace(ib,"<$1></$2>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&hb.test(f)&&p.push(b.createTextNode(hb.exec(f)[0])),!k.tbody){f="table"!==i||kb.test(f)?"<table>"!==l[1]||kb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ub(p,"input"),vb),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ub(o.appendChild(f),"script"),g&&zb(h),c)){e=0;while(f=h[e++])ob.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ub(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&zb(ub(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ub(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fb,""):void 0;if(!("string"!=typeof a||mb.test(a)||!k.htmlSerialize&&gb.test(a)||!k.leadingWhitespace&&hb.test(a)||rb[(jb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ib,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ub(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ub(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&nb.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ub(i,"script"),xb),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ub(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,yb),j=0;f>j;j++)d=g[j],ob.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qb,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Cb,Db={};function Eb(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fb(a){var b=y,c=Db[a];return c||(c=Eb(a,b),"none"!==c&&c||(Cb=(Cb||m("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Cb[0].contentWindow||Cb[0].contentDocument).document,b.write(),b.close(),c=Eb(a,b),Cb.detach()),Db[a]=c),c}!function(){var a;k.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,d;return c=y.getElementsByTagName("body")[0],c&&c.style?(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(y.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(d),a):void 0}}();var Gb=/^margin/,Hb=new RegExp("^("+S+")(?!px)[a-z%]+$","i"),Ib,Jb,Kb=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ib=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||m.contains(a.ownerDocument,a)||(g=m.style(a,b)),Hb.test(g)&&Gb.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):y.documentElement.currentStyle&&(Ib=function(a){return a.currentStyle},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Hb.test(g)&&!Kb.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Lb(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h;if(b=y.createElement("div"),b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=d&&d.style){c.cssText="float:left;opacity:.5",k.opacity="0.5"===c.opacity,k.cssFloat=!!c.cssFloat,b.style.backgroundClip="content-box",b.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===b.style.backgroundClip,k.boxSizing=""===c.boxSizing||""===c.MozBoxSizing||""===c.WebkitBoxSizing,m.extend(k,{reliableHiddenOffsets:function(){return null==g&&i(),g},boxSizingReliable:function(){return null==f&&i(),f},pixelPosition:function(){return null==e&&i(),e},reliableMarginRight:function(){return null==h&&i(),h}});function i(){var b,c,d,i;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),b.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",e=f=!1,h=!0,a.getComputedStyle&&(e="1%"!==(a.getComputedStyle(b,null)||{}).top,f="4px"===(a.getComputedStyle(b,null)||{width:"4px"}).width,i=b.appendChild(y.createElement("div")),i.style.cssText=b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",i.style.marginRight=i.style.width="0",b.style.width="1px",h=!parseFloat((a.getComputedStyle(i,null)||{}).marginRight)),b.innerHTML="<table><tr><td></td><td>t</td></tr></table>",i=b.getElementsByTagName("td"),i[0].style.cssText="margin:0;border:0;padding:0;display:none",g=0===i[0].offsetHeight,g&&(i[0].style.display="",i[1].style.display="none",g=0===i[0].offsetHeight),c.removeChild(d))}}}(),m.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Mb=/alpha\([^)]*\)/i,Nb=/opacity\s*=\s*([^)]*)/,Ob=/^(none|table(?!-c[ea]).+)/,Pb=new RegExp("^("+S+")(.*)$","i"),Qb=new RegExp("^([+-])=("+S+")","i"),Rb={position:"absolute",visibility:"hidden",display:"block"},Sb={letterSpacing:"0",fontWeight:"400"},Tb=["Webkit","O","Moz","ms"];function Ub(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Tb.length;while(e--)if(b=Tb[e]+c,b in a)return b;return d}function Vb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=m._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&U(d)&&(f[g]=m._data(d,"olddisplay",Fb(d.nodeName)))):(e=U(d),(c&&"none"!==c||!e)&&m._data(d,"olddisplay",e?c:m.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Wb(a,b,c){var d=Pb.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Xb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=m.css(a,c+T[f],!0,e)),d?("content"===c&&(g-=m.css(a,"padding"+T[f],!0,e)),"margin"!==c&&(g-=m.css(a,"border"+T[f]+"Width",!0,e))):(g+=m.css(a,"padding"+T[f],!0,e),"padding"!==c&&(g+=m.css(a,"border"+T[f]+"Width",!0,e)));return g}function Yb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ib(a),g=k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Jb(a,b,f),(0>e||null==e)&&(e=a.style[b]),Hb.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Xb(a,b,c||(g?"border":"content"),d,f)+"px"}m.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Jb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":k.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=m.camelCase(b),i=a.style;if(b=m.cssProps[h]||(m.cssProps[h]=Ub(i,h)),g=m.cssHooks[b]||m.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Qb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(m.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||m.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=m.camelCase(b);return b=m.cssProps[h]||(m.cssProps[h]=Ub(a.style,h)),g=m.cssHooks[b]||m.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Jb(a,b,d)),"normal"===f&&b in Sb&&(f=Sb[b]),""===c||c?(e=parseFloat(f),c===!0||m.isNumeric(e)?e||0:f):f}}),m.each(["height","width"],function(a,b){m.cssHooks[b]={get:function(a,c,d){return c?Ob.test(m.css(a,"display"))&&0===a.offsetWidth?m.swap(a,Rb,function(){return Yb(a,b,d)}):Yb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ib(a);return Wb(a,c,d?Xb(a,b,d,k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,e),e):0)}}}),k.opacity||(m.cssHooks.opacity={get:function(a,b){return Nb.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=m.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===m.trim(f.replace(Mb,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Mb.test(f)?f.replace(Mb,e):f+" "+e)}}),m.cssHooks.marginRight=Lb(k.reliableMarginRight,function(a,b){return b?m.swap(a,{display:"inline-block"},Jb,[a,"marginRight"]):void 0}),m.each({margin:"",padding:"",border:"Width"},function(a,b){m.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+T[d]+b]=f[d]||f[d-2]||f[0];return e}},Gb.test(a)||(m.cssHooks[a+b].set=Wb)}),m.fn.extend({css:function(a,b){return V(this,function(a,b,c){var d,e,f={},g=0;if(m.isArray(b)){for(d=Ib(a),e=b.length;e>g;g++)f[b[g]]=m.css(a,b[g],!1,d);return f}return void 0!==c?m.style(a,b,c):m.css(a,b)},a,b,arguments.length>1)},show:function(){return Vb(this,!0)},hide:function(){return Vb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){U(this)?m(this).show():m(this).hide()})}});function Zb(a,b,c,d,e){return new Zb.prototype.init(a,b,c,d,e)}m.Tween=Zb,Zb.prototype={constructor:Zb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")
+ },cur:function(){var a=Zb.propHooks[this.prop];return a&&a.get?a.get(this):Zb.propHooks._default.get(this)},run:function(a){var b,c=Zb.propHooks[this.prop];return this.pos=b=this.options.duration?m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Zb.propHooks._default.set(this),this}},Zb.prototype.init.prototype=Zb.prototype,Zb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Zb.propHooks.scrollTop=Zb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Zb.prototype.init,m.fx.step={};var $b,_b,ac=/^(?:toggle|show|hide)$/,bc=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cc=/queueHooks$/,dc=[ic],ec={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bc.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bc.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fc(){return setTimeout(function(){$b=void 0}),$b=m.now()}function gc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hc(a,b,c){for(var d,e=(ec[b]||[]).concat(ec["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ic(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fb(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fb(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ac.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fb(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hc(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jc(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kc(a,b,c){var d,e,f=0,g=dc.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$b||fc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$b||fc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jc(k,j.opts.specialEasing);g>f;f++)if(d=dc[f].call(j,a,k,j.opts))return d;return m.map(k,hc,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kc,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],ec[c]=ec[c]||[],ec[c].unshift(b)},prefilter:function(a,b){b?dc.unshift(a):dc.push(a)}}),m.speed=function(a,b,c){var d=a&&"object"==typeof a?m.extend({},a):{complete:c||!c&&b||m.isFunction(a)&&a,duration:a,easing:c&&b||b&&!m.isFunction(b)&&b};return d.duration=m.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in m.fx.speeds?m.fx.speeds[d.duration]:m.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){m.isFunction(d.old)&&d.old.call(this),d.queue&&m.dequeue(this,d.queue)},d},m.fn.extend({fadeTo:function(a,b,c,d){return this.filter(U).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=m.isEmptyObject(a),f=m.speed(b,c,d),g=function(){var b=kc(this,m.extend({},a),f);(e||m._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=m.timers,g=m._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&cc.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&m.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=m._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=m.timers,g=d?d.length:0;for(c.finish=!0,m.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),m.each(["toggle","show","hide"],function(a,b){var c=m.fn[b];m.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gc(b,!0),a,d,e)}}),m.each({slideDown:gc("show"),slideUp:gc("hide"),slideToggle:gc("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){m.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),m.timers=[],m.fx.tick=function(){var a,b=m.timers,c=0;for($b=m.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||m.fx.stop(),$b=void 0},m.fx.timer=function(a){m.timers.push(a),a()?m.fx.start():m.timers.pop()},m.fx.interval=13,m.fx.start=function(){_b||(_b=setInterval(m.fx.tick,m.fx.interval))},m.fx.stop=function(){clearInterval(_b),_b=null},m.fx.speeds={slow:600,fast:200,_default:400},m.fn.delay=function(a,b){return a=m.fx?m.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a,b,c,d,e;b=y.createElement("div"),b.setAttribute("className","t"),b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=y.createElement("select"),e=c.appendChild(y.createElement("option")),a=b.getElementsByTagName("input")[0],d.style.cssText="top:1px",k.getSetAttribute="t"!==b.className,k.style=/top/.test(d.getAttribute("style")),k.hrefNormalized="/a"===d.getAttribute("href"),k.checkOn=!!a.value,k.optSelected=e.selected,k.enctype=!!y.createElement("form").enctype,c.disabled=!0,k.optDisabled=!e.disabled,a=y.createElement("input"),a.setAttribute("value",""),k.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),k.radioValue="t"===a.value}();var lc=/\r/g;m.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=m.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,m(this).val()):a,null==e?e="":"number"==typeof e?e+="":m.isArray(e)&&(e=m.map(e,function(a){return null==a?"":a+""})),b=m.valHooks[this.type]||m.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=m.valHooks[e.type]||m.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(lc,""):null==c?"":c)}}}),m.extend({valHooks:{option:{get:function(a){var b=m.find.attr(a,"value");return null!=b?b:m.trim(m.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&m.nodeName(c.parentNode,"optgroup"))){if(b=m(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=m.makeArray(b),g=e.length;while(g--)if(d=e[g],m.inArray(m.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),m.each(["radio","checkbox"],function(){m.valHooks[this]={set:function(a,b){return m.isArray(b)?a.checked=m.inArray(m(a).val(),b)>=0:void 0}},k.checkOn||(m.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var mc,nc,oc=m.expr.attrHandle,pc=/^(?:checked|selected)$/i,qc=k.getSetAttribute,rc=k.input;m.fn.extend({attr:function(a,b){return V(this,m.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){m.removeAttr(this,a)})}}),m.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===K?m.prop(a,b,c):(1===f&&m.isXMLDoc(a)||(b=b.toLowerCase(),d=m.attrHooks[b]||(m.expr.match.bool.test(b)?nc:mc)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=m.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void m.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=m.propFix[c]||c,m.expr.match.bool.test(c)?rc&&qc||!pc.test(c)?a[d]=!1:a[m.camelCase("default-"+c)]=a[d]=!1:m.attr(a,c,""),a.removeAttribute(qc?c:d)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&m.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),nc={set:function(a,b,c){return b===!1?m.removeAttr(a,c):rc&&qc||!pc.test(c)?a.setAttribute(!qc&&m.propFix[c]||c,c):a[m.camelCase("default-"+c)]=a[c]=!0,c}},m.each(m.expr.match.bool.source.match(/\w+/g),function(a,b){var c=oc[b]||m.find.attr;oc[b]=rc&&qc||!pc.test(b)?function(a,b,d){var e,f;return d||(f=oc[b],oc[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,oc[b]=f),e}:function(a,b,c){return c?void 0:a[m.camelCase("default-"+b)]?b.toLowerCase():null}}),rc&&qc||(m.attrHooks.value={set:function(a,b,c){return m.nodeName(a,"input")?void(a.defaultValue=b):mc&&mc.set(a,b,c)}}),qc||(mc={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},oc.id=oc.name=oc.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},m.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:mc.set},m.attrHooks.contenteditable={set:function(a,b,c){mc.set(a,""===b?!1:b,c)}},m.each(["width","height"],function(a,b){m.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),k.style||(m.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var sc=/^(?:input|select|textarea|button|object)$/i,tc=/^(?:a|area)$/i;m.fn.extend({prop:function(a,b){return V(this,m.prop,a,b,arguments.length>1)},removeProp:function(a){return a=m.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),m.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!m.isXMLDoc(a),f&&(b=m.propFix[b]||b,e=m.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=m.find.attr(a,"tabindex");return b?parseInt(b,10):sc.test(a.nodeName)||tc.test(a.nodeName)&&a.href?0:-1}}}}),k.hrefNormalized||m.each(["href","src"],function(a,b){m.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),k.optSelected||(m.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),m.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){m.propFix[this.toLowerCase()]=this}),k.enctype||(m.propFix.enctype="encoding");var uc=/[\t\r\n\f]/g;m.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=m.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?m.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(m.isFunction(a)?function(c){m(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=m(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===K||"boolean"===c)&&(this.className&&m._data(this,"__className__",this.className),this.className=this.className||a===!1?"":m._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(uc," ").indexOf(b)>=0)return!0;return!1}}),m.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){m.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),m.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var vc=m.now(),wc=/\?/,xc=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;m.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=m.trim(b+"");return e&&!m.trim(e.replace(xc,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():m.error("Invalid JSON: "+b)},m.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||m.error("Invalid XML: "+b),c};var yc,zc,Ac=/#.*$/,Bc=/([?&])_=[^&]*/,Cc=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Dc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Ec=/^(?:GET|HEAD)$/,Fc=/^\/\//,Gc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Hc={},Ic={},Jc="*/".concat("*");try{zc=location.href}catch(Kc){zc=y.createElement("a"),zc.href="",zc=zc.href}yc=Gc.exec(zc.toLowerCase())||[];function Lc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(m.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Mc(a,b,c,d){var e={},f=a===Ic;function g(h){var i;return e[h]=!0,m.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Nc(a,b){var c,d,e=m.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&m.extend(!0,a,c),a}function Oc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Pc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}m.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:zc,type:"GET",isLocal:Dc.test(yc[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Jc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":m.parseJSON,"text xml":m.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Nc(Nc(a,m.ajaxSettings),b):Nc(m.ajaxSettings,a)},ajaxPrefilter:Lc(Hc),ajaxTransport:Lc(Ic),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=m.ajaxSetup({},b),l=k.context||k,n=k.context&&(l.nodeType||l.jquery)?m(l):m.event,o=m.Deferred(),p=m.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Cc.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||zc)+"").replace(Ac,"").replace(Fc,yc[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=m.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(c=Gc.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===yc[1]&&c[2]===yc[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(yc[3]||("http:"===yc[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=m.param(k.data,k.traditional)),Mc(Hc,k,b,v),2===t)return v;h=k.global,h&&0===m.active++&&m.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Ec.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(wc.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Bc.test(e)?e.replace(Bc,"$1_="+vc++):e+(wc.test(e)?"&":"?")+"_="+vc++)),k.ifModified&&(m.lastModified[e]&&v.setRequestHeader("If-Modified-Since",m.lastModified[e]),m.etag[e]&&v.setRequestHeader("If-None-Match",m.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Jc+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Mc(Ic,k,b,v)){v.readyState=1,h&&n.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Oc(k,v,c)),u=Pc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(m.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(m.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&n.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(n.trigger("ajaxComplete",[v,k]),--m.active||m.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return m.get(a,b,c,"json")},getScript:function(a,b){return m.get(a,void 0,b,"script")}}),m.each(["get","post"],function(a,b){m[b]=function(a,c,d,e){return m.isFunction(c)&&(e=e||d,d=c,c=void 0),m.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),m.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){m.fn[b]=function(a){return this.on(b,a)}}),m._evalUrl=function(a){return m.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},m.fn.extend({wrapAll:function(a){if(m.isFunction(a))return this.each(function(b){m(this).wrapAll(a.call(this,b))});if(this[0]){var b=m(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(m.isFunction(a)?function(b){m(this).wrapInner(a.call(this,b))}:function(){var b=m(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=m.isFunction(a);return this.each(function(c){m(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){m.nodeName(this,"body")||m(this).replaceWith(this.childNodes)}).end()}}),m.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!k.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||m.css(a,"display"))},m.expr.filters.visible=function(a){return!m.expr.filters.hidden(a)};var Qc=/%20/g,Rc=/\[\]$/,Sc=/\r?\n/g,Tc=/^(?:submit|button|image|reset|file)$/i,Uc=/^(?:input|select|textarea|keygen)/i;function Vc(a,b,c,d){var e;if(m.isArray(b))m.each(b,function(b,e){c||Rc.test(a)?d(a,e):Vc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==m.type(b))d(a,b);else for(e in b)Vc(a+"["+e+"]",b[e],c,d)}m.param=function(a,b){var c,d=[],e=function(a,b){b=m.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=m.ajaxSettings&&m.ajaxSettings.traditional),m.isArray(a)||a.jquery&&!m.isPlainObject(a))m.each(a,function(){e(this.name,this.value)});else for(c in a)Vc(c,a[c],b,e);return d.join("&").replace(Qc,"+")},m.fn.extend({serialize:function(){return m.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=m.prop(this,"elements");return a?m.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!m(this).is(":disabled")&&Uc.test(this.nodeName)&&!Tc.test(a)&&(this.checked||!W.test(a))}).map(function(a,b){var c=m(this).val();return null==c?null:m.isArray(c)?m.map(c,function(a){return{name:b.name,value:a.replace(Sc,"\r\n")}}):{name:b.name,value:c.replace(Sc,"\r\n")}}).get()}}),m.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&Zc()||$c()}:Zc;var Wc=0,Xc={},Yc=m.ajaxSettings.xhr();a.ActiveXObject&&m(a).on("unload",function(){for(var a in Xc)Xc[a](void 0,!0)}),k.cors=!!Yc&&"withCredentials"in Yc,Yc=k.ajax=!!Yc,Yc&&m.ajaxTransport(function(a){if(!a.crossDomain||k.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Wc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Xc[g],b=void 0,f.onreadystatechange=m.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Xc[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function Zc(){try{return new a.XMLHttpRequest}catch(b){}}function $c(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}m.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return m.globalEval(a),a}}}),m.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),m.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=y.head||m("head")[0]||y.documentElement;return{send:function(d,e){b=y.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var _c=[],ad=/(=)\?(?=&|$)|\?\?/;m.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=_c.pop()||m.expando+"_"+vc++;return this[a]=!0,a}}),m.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(ad.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&ad.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=m.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(ad,"$1"+e):b.jsonp!==!1&&(b.url+=(wc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||m.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,_c.push(e)),g&&m.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),m.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||y;var d=u.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=m.buildFragment([a],b,e),e&&e.length&&m(e).remove(),m.merge([],d.childNodes))};var bd=m.fn.load;m.fn.load=function(a,b,c){if("string"!=typeof a&&bd)return bd.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=m.trim(a.slice(h,a.length)),a=a.slice(0,h)),m.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&m.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?m("<div>").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cd=a.document.documentElement;function dd(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,"position"),l=m(a),n={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=m.css(a,"top"),i=m.css(a,"left"),j=("absolute"===k||"fixed"===k)&&m.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),"using"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dd(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===m.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],"html")||(c=a.offset()),c.top+=m.css(a[0],"borderTopWidth",!0),c.left+=m.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-m.css(d,"marginTop",!0),left:b.left-c.left-m.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cd;while(a&&!m.nodeName(a,"html")&&"static"===m.css(a,"position"))a=a.offsetParent;return a||cd})}}),m.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dd(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each(["top","left"],function(a,b){m.cssHooks[b]=Lb(k.pixelPosition,function(a,c){return c?(c=Jb(a,b),Hb.test(c)?m(a).position()[b]+"px":c):void 0})}),m.each({Height:"height",Width:"width"},function(a,b){m.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return V(this,function(b,c,d){var e;return m.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return m});var ed=a.jQuery,fd=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fd),b&&a.jQuery===m&&(a.jQuery=ed),m},typeof b===K&&(a.jQuery=a.$=m),m}); \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/js/language.js b/main/app/sprinkles/core/assets/SiteAssets/js/language.js
new file mode 100644
index 0000000..abe6a65
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/js/language.js
@@ -0,0 +1,36 @@
+function Translate() {
+ //initialization
+ this.init = function (lng) {
+ this.attribute = 'data-lang';
+ this.lng = lng;
+ };
+ //translate
+ this.process = function () {
+ var _self = this;
+ var xrhFile = new XMLHttpRequest();
+ //load content data
+ xrhFile.open("GET", "assets/languages/json/Translations.json", true);
+ xrhFile.onreadystatechange = function () {
+ if (xrhFile.readyState === 4) {
+ if (xrhFile.status === 200 || xrhFile.status === 0) {
+ var LngObject = JSON.parse(xrhFile.responseText);
+ var allDom = document.getElementsByTagName("*");
+ for (var i = 0; i < allDom.length; i++) {
+ var elem = allDom[i];
+ var key = elem.getAttribute(_self.attribute);
+
+ if (key != null) {
+ //console.log("Language initialized with language pack: " + _self.lng);
+ elem.innerHTML = LngObject[_self.lng][key];
+ }
+ }
+ }
+ }
+ };
+ xrhFile.send();
+ }
+}
+
+$(document).ready(function () {
+ initiateLanguage();
+});
diff --git a/main/app/sprinkles/core/assets/SiteAssets/js/linkify.js b/main/app/sprinkles/core/assets/SiteAssets/js/linkify.js
new file mode 100644
index 0000000..2778a90
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/js/linkify.js
@@ -0,0 +1,369 @@
+!function () {
+ "use strict";
+ var n = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (n) {
+ return typeof n
+ } : function (n) {
+ return n && "function" == typeof Symbol && n.constructor === Symbol && n !== Symbol.prototype ? "symbol" : typeof n
+ };
+ !function (e) {
+ function a(n, e) {
+ var a = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, t = Object.create(n.prototype);
+ for (var o in a) t[o] = a[o];
+ return t.constructor = e, e.prototype = t, e
+ }
+
+ function t(n) {
+ n = n || {}, this.defaultProtocol = n.hasOwnProperty("defaultProtocol") ? n.defaultProtocol : h.defaultProtocol, this.events = n.hasOwnProperty("events") ? n.events : h.events, this.format = n.hasOwnProperty("format") ? n.format : h.format, this.formatHref = n.hasOwnProperty("formatHref") ? n.formatHref : h.formatHref, this.nl2br = n.hasOwnProperty("nl2br") ? n.nl2br : h.nl2br, this.tagName = n.hasOwnProperty("tagName") ? n.tagName : h.tagName, this.target = n.hasOwnProperty("target") ? n.target : h.target, this.validate = n.hasOwnProperty("validate") ? n.validate : h.validate, this.ignoreTags = [], this.attributes = n.attributes || n.linkAttributes || h.attributes, this.className = n.hasOwnProperty("className") ? n.className : n.linkClass || h.className;
+ for (var e = n.hasOwnProperty("ignoreTags") ? n.ignoreTags : h.ignoreTags, a = 0; a < e.length; a++) this.ignoreTags.push(e[a].toUpperCase())
+ }
+
+ function o(n, e) {
+ for (var a = 0; a < n.length; a++) if (n[a] === e) return !0;
+ return !1
+ }
+
+ function r(n) {
+ return n
+ }
+
+ function i(n, e) {
+ return "url" === e ? "_blank" : null
+ }
+
+ function s() {
+ return function (n) {
+ this.j = [], this.T = n || null
+ }
+ }
+
+ function c(n, e, a, t) {
+ for (var o = 0, r = n.length, i = e, s = [], c = void 0; o < r && (c = i.next(n[o]));) i = c, o++;
+ if (o >= r) return [];
+ for (; o < r - 1;) c = new m(t), s.push(c), i.on(n[o], c), i = c, o++;
+ return c = new m(a), s.push(c), i.on(n[r - 1], c), s
+ }
+
+ function l() {
+ return function (n) {
+ n && (this.v = n)
+ }
+ }
+
+ function u(n) {
+ var e = n ? {v: n} : {};
+ return a(d, l(), e)
+ }
+
+ function g(n) {
+ return n instanceof x || n instanceof C
+ }
+
+ var h = {
+ defaultProtocol: "http",
+ events: null,
+ format: r,
+ formatHref: r,
+ nl2br: !1,
+ tagName: "a",
+ target: i,
+ validate: !0,
+ ignoreTags: [],
+ attributes: null,
+ className: "linkified"
+ };
+ t.prototype = {
+ resolve: function (n) {
+ var e = n.toHref(this.defaultProtocol);
+ return {
+ formatted: this.get("format", n.toString(), n),
+ formattedHref: this.get("formatHref", e, n),
+ tagName: this.get("tagName", e, n),
+ className: this.get("className", e, n),
+ target: this.get("target", e, n),
+ events: this.getObject("events", e, n),
+ attributes: this.getObject("attributes", e, n)
+ }
+ }, check: function (n) {
+ return this.get("validate", n.toString(), n)
+ }, get: function (e, a, t) {
+ var o = void 0, r = this[e];
+ if (!r) return r;
+ switch ("undefined" == typeof r ? "undefined" : n(r)) {
+ case"function":
+ return r(a, t.type);
+ case"object":
+ return o = r.hasOwnProperty(t.type) ? r[t.type] : h[e], "function" == typeof o ? o(a, t.type) : o
+ }
+ return r
+ }, getObject: function (n, e, a) {
+ var t = this[n];
+ return "function" == typeof t ? t(e, a.type) : t
+ }
+ };
+ var b = Object.freeze({defaults: h, Options: t, contains: o}), p = s();
+ p.prototype = {
+ defaultTransition: !1, on: function (n, e) {
+ if (n instanceof Array) {
+ for (var a = 0; a < n.length; a++) this.j.push([n[a], e]);
+ return this
+ }
+ return this.j.push([n, e]), this
+ }, next: function (n) {
+ for (var e = 0; e < this.j.length; e++) {
+ var a = this.j[e], t = a[0], o = a[1];
+ if (this.test(n, t)) return o
+ }
+ return this.defaultTransition
+ }, accepts: function () {
+ return !!this.T
+ }, test: function (n, e) {
+ return n === e
+ }, emit: function () {
+ return this.T
+ }
+ };
+ var m = a(p, s(), {
+ test: function (n, e) {
+ return n === e || e instanceof RegExp && e.test(n)
+ }
+ }), f = a(p, s(), {
+ jump: function (n) {
+ var e = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : null, a = this.next(new n(""));
+ return a === this.defaultTransition ? (a = new this.constructor(e), this.on(n, a)) : e && (a.T = e), a
+ }, test: function (n, e) {
+ return n instanceof e
+ }
+ }), d = l();
+ d.prototype = {
+ toString: function () {
+ return this.v + ""
+ }
+ };
+ var x = u(), y = u("@"), v = u(":"), k = u("."), w = u(), j = u(), z = u("\n"), O = u(), q = u("+"), N = u("#"),
+ S = u(), T = u("mailto:"), A = u("?"), L = u("/"), P = u("_"), E = u(), C = u(), R = u(), H = u("{"),
+ B = u("["), U = u("<"), M = u("("), D = u("}"), I = u("]"), K = u(">"), _ = u(")"), G = u("&"),
+ Y = Object.freeze({
+ Base: d,
+ DOMAIN: x,
+ AT: y,
+ COLON: v,
+ DOT: k,
+ PUNCTUATION: w,
+ LOCALHOST: j,
+ NL: z,
+ NUM: O,
+ PLUS: q,
+ POUND: N,
+ QUERY: A,
+ PROTOCOL: S,
+ MAILTO: T,
+ SLASH: L,
+ UNDERSCORE: P,
+ SYM: E,
+ TLD: C,
+ WS: R,
+ OPENBRACE: H,
+ OPENBRACKET: B,
+ OPENANGLEBRACKET: U,
+ OPENPAREN: M,
+ CLOSEBRACE: D,
+ CLOSEBRACKET: I,
+ CLOSEANGLEBRACKET: K,
+ CLOSEPAREN: _,
+ AMPERSAND: G
+ }),
+ Q = "aaa|aarp|abarth|abb|abbott|abbvie|abc|able|abogado|abudhabi|ac|academy|accenture|accountant|accountants|aco|active|actor|ad|adac|ads|adult|ae|aeg|aero|aetna|af|afamilycompany|afl|africa|ag|agakhan|agency|ai|aig|aigo|airbus|airforce|airtel|akdn|al|alfaromeo|alibaba|alipay|allfinanz|allstate|ally|alsace|alstom|am|americanexpress|americanfamily|amex|amfam|amica|amsterdam|analytics|android|anquan|anz|ao|aol|apartments|app|apple|aq|aquarelle|ar|arab|aramco|archi|army|arpa|art|arte|as|asda|asia|associates|at|athleta|attorney|au|auction|audi|audible|audio|auspost|author|auto|autos|avianca|aw|aws|ax|axa|az|azure|ba|baby|baidu|banamex|bananarepublic|band|bank|bar|barcelona|barclaycard|barclays|barefoot|bargains|baseball|basketball|bauhaus|bayern|bb|bbc|bbt|bbva|bcg|bcn|bd|be|beats|beauty|beer|bentley|berlin|best|bestbuy|bet|bf|bg|bh|bharti|bi|bible|bid|bike|bing|bingo|bio|biz|bj|black|blackfriday|blanco|blockbuster|blog|bloomberg|blue|bm|bms|bmw|bn|bnl|bnpparibas|bo|boats|boehringer|bofa|bom|bond|boo|book|booking|boots|bosch|bostik|boston|bot|boutique|box|br|bradesco|bridgestone|broadway|broker|brother|brussels|bs|bt|budapest|bugatti|build|builders|business|buy|buzz|bv|bw|by|bz|bzh|ca|cab|cafe|cal|call|calvinklein|cam|camera|camp|cancerresearch|canon|capetown|capital|capitalone|car|caravan|cards|care|career|careers|cars|cartier|casa|case|caseih|cash|casino|cat|catering|catholic|cba|cbn|cbre|cbs|cc|cd|ceb|center|ceo|cern|cf|cfa|cfd|cg|ch|chanel|channel|chase|chat|cheap|chintai|chloe|christmas|chrome|chrysler|church|ci|cipriani|circle|cisco|citadel|citi|citic|city|cityeats|ck|cl|claims|cleaning|click|clinic|clinique|clothing|cloud|club|clubmed|cm|cn|co|coach|codes|coffee|college|cologne|com|comcast|commbank|community|company|compare|computer|comsec|condos|construction|consulting|contact|contractors|cooking|cookingchannel|cool|coop|corsica|country|coupon|coupons|courses|cr|credit|creditcard|creditunion|cricket|crown|crs|cruise|cruises|csc|cu|cuisinella|cv|cw|cx|cy|cymru|cyou|cz|dabur|dad|dance|data|date|dating|datsun|day|dclk|dds|de|deal|dealer|deals|degree|delivery|dell|deloitte|delta|democrat|dental|dentist|desi|design|dev|dhl|diamonds|diet|digital|direct|directory|discount|discover|dish|diy|dj|dk|dm|dnp|do|docs|doctor|dodge|dog|doha|domains|dot|download|drive|dtv|dubai|duck|dunlop|duns|dupont|durban|dvag|dvr|dz|earth|eat|ec|eco|edeka|edu|education|ee|eg|email|emerck|energy|engineer|engineering|enterprises|epost|epson|equipment|er|ericsson|erni|es|esq|estate|esurance|et|etisalat|eu|eurovision|eus|events|everbank|exchange|expert|exposed|express|extraspace|fage|fail|fairwinds|faith|family|fan|fans|farm|farmers|fashion|fast|fedex|feedback|ferrari|ferrero|fi|fiat|fidelity|fido|film|final|finance|financial|fire|firestone|firmdale|fish|fishing|fit|fitness|fj|fk|flickr|flights|flir|florist|flowers|fly|fm|fo|foo|food|foodnetwork|football|ford|forex|forsale|forum|foundation|fox|fr|free|fresenius|frl|frogans|frontdoor|frontier|ftr|fujitsu|fujixerox|fun|fund|furniture|futbol|fyi|ga|gal|gallery|gallo|gallup|game|games|gap|garden|gb|gbiz|gd|gdn|ge|gea|gent|genting|george|gf|gg|ggee|gh|gi|gift|gifts|gives|giving|gl|glade|glass|gle|global|globo|gm|gmail|gmbh|gmo|gmx|gn|godaddy|gold|goldpoint|golf|goo|goodhands|goodyear|goog|google|gop|got|gov|gp|gq|gr|grainger|graphics|gratis|green|gripe|grocery|group|gs|gt|gu|guardian|gucci|guge|guide|guitars|guru|gw|gy|hair|hamburg|hangout|haus|hbo|hdfc|hdfcbank|health|healthcare|help|helsinki|here|hermes|hgtv|hiphop|hisamitsu|hitachi|hiv|hk|hkt|hm|hn|hockey|holdings|holiday|homedepot|homegoods|homes|homesense|honda|honeywell|horse|hospital|host|hosting|hot|hoteles|hotels|hotmail|house|how|hr|hsbc|ht|htc|hu|hughes|hyatt|hyundai|ibm|icbc|ice|icu|id|ie|ieee|ifm|ikano|il|im|imamat|imdb|immo|immobilien|in|industries|infiniti|info|ing|ink|institute|insurance|insure|int|intel|international|intuit|investments|io|ipiranga|iq|ir|irish|is|iselect|ismaili|ist|istanbul|it|itau|itv|iveco|iwc|jaguar|java|jcb|jcp|je|jeep|jetzt|jewelry|jio|jlc|jll|jm|jmp|jnj|jo|jobs|joburg|jot|joy|jp|jpmorgan|jprs|juegos|juniper|kaufen|kddi|ke|kerryhotels|kerrylogistics|kerryproperties|kfh|kg|kh|ki|kia|kim|kinder|kindle|kitchen|kiwi|km|kn|koeln|komatsu|kosher|kp|kpmg|kpn|kr|krd|kred|kuokgroup|kw|ky|kyoto|kz|la|lacaixa|ladbrokes|lamborghini|lamer|lancaster|lancia|lancome|land|landrover|lanxess|lasalle|lat|latino|latrobe|law|lawyer|lb|lc|lds|lease|leclerc|lefrak|legal|lego|lexus|lgbt|li|liaison|lidl|life|lifeinsurance|lifestyle|lighting|like|lilly|limited|limo|lincoln|linde|link|lipsy|live|living|lixil|lk|loan|loans|locker|locus|loft|lol|london|lotte|lotto|love|lpl|lplfinancial|lr|ls|lt|ltd|ltda|lu|lundbeck|lupin|luxe|luxury|lv|ly|ma|macys|madrid|maif|maison|makeup|man|management|mango|map|market|marketing|markets|marriott|marshalls|maserati|mattel|mba|mc|mckinsey|md|me|med|media|meet|melbourne|meme|memorial|men|menu|meo|merckmsd|metlife|mg|mh|miami|microsoft|mil|mini|mint|mit|mitsubishi|mk|ml|mlb|mls|mm|mma|mn|mo|mobi|mobile|mobily|moda|moe|moi|mom|monash|money|monster|mopar|mormon|mortgage|moscow|moto|motorcycles|mov|movie|movistar|mp|mq|mr|ms|msd|mt|mtn|mtr|mu|museum|mutual|mv|mw|mx|my|mz|na|nab|nadex|nagoya|name|nationwide|natura|navy|nba|nc|ne|nec|net|netbank|netflix|network|neustar|new|newholland|news|next|nextdirect|nexus|nf|nfl|ng|ngo|nhk|ni|nico|nike|nikon|ninja|nissan|nissay|nl|no|nokia|northwesternmutual|norton|now|nowruz|nowtv|np|nr|nra|nrw|ntt|nu|nyc|nz|obi|observer|off|office|okinawa|olayan|olayangroup|oldnavy|ollo|om|omega|one|ong|onl|online|onyourside|ooo|open|oracle|orange|org|organic|origins|osaka|otsuka|ott|ovh|pa|page|panasonic|panerai|paris|pars|partners|parts|party|passagens|pay|pccw|pe|pet|pf|pfizer|pg|ph|pharmacy|phd|philips|phone|photo|photography|photos|physio|piaget|pics|pictet|pictures|pid|pin|ping|pink|pioneer|pizza|pk|pl|place|play|playstation|plumbing|plus|pm|pn|pnc|pohl|poker|politie|porn|post|pr|pramerica|praxi|press|prime|pro|prod|productions|prof|progressive|promo|properties|property|protection|pru|prudential|ps|pt|pub|pw|pwc|py|qa|qpon|quebec|quest|qvc|racing|radio|raid|re|read|realestate|realtor|realty|recipes|red|redstone|redumbrella|rehab|reise|reisen|reit|reliance|ren|rent|rentals|repair|report|republican|rest|restaurant|review|reviews|rexroth|rich|richardli|ricoh|rightathome|ril|rio|rip|rmit|ro|rocher|rocks|rodeo|rogers|room|rs|rsvp|ru|rugby|ruhr|run|rw|rwe|ryukyu|sa|saarland|safe|safety|sakura|sale|salon|samsclub|samsung|sandvik|sandvikcoromant|sanofi|sap|sapo|sarl|sas|save|saxo|sb|sbi|sbs|sc|sca|scb|schaeffler|schmidt|scholarships|school|schule|schwarz|science|scjohnson|scor|scot|sd|se|search|seat|secure|security|seek|select|sener|services|ses|seven|sew|sex|sexy|sfr|sg|sh|shangrila|sharp|shaw|shell|shia|shiksha|shoes|shop|shopping|shouji|show|showtime|shriram|si|silk|sina|singles|site|sj|sk|ski|skin|sky|skype|sl|sling|sm|smart|smile|sn|sncf|so|soccer|social|softbank|software|sohu|solar|solutions|song|sony|soy|space|spiegel|spot|spreadbetting|sr|srl|srt|st|stada|staples|star|starhub|statebank|statefarm|statoil|stc|stcgroup|stockholm|storage|store|stream|studio|study|style|su|sucks|supplies|supply|support|surf|surgery|suzuki|sv|swatch|swiftcover|swiss|sx|sy|sydney|symantec|systems|sz|tab|taipei|talk|taobao|target|tatamotors|tatar|tattoo|tax|taxi|tc|tci|td|tdk|team|tech|technology|tel|telecity|telefonica|temasek|tennis|teva|tf|tg|th|thd|theater|theatre|tiaa|tickets|tienda|tiffany|tips|tires|tirol|tj|tjmaxx|tjx|tk|tkmaxx|tl|tm|tmall|tn|to|today|tokyo|tools|top|toray|toshiba|total|tours|town|toyota|toys|tr|trade|trading|training|travel|travelchannel|travelers|travelersinsurance|trust|trv|tt|tube|tui|tunes|tushu|tv|tvs|tw|tz|ua|ubank|ubs|uconnect|ug|uk|unicom|university|uno|uol|ups|us|uy|uz|va|vacations|vana|vanguard|vc|ve|vegas|ventures|verisign|versicherung|vet|vg|vi|viajes|video|vig|viking|villas|vin|vip|virgin|visa|vision|vista|vistaprint|viva|vivo|vlaanderen|vn|vodka|volkswagen|volvo|vote|voting|voto|voyage|vu|vuelos|wales|walmart|walter|wang|wanggou|warman|watch|watches|weather|weatherchannel|webcam|weber|website|wed|wedding|weibo|weir|wf|whoswho|wien|wiki|williamhill|win|windows|wine|winners|wme|wolterskluwer|woodside|work|works|world|wow|ws|wtc|wtf|xbox|xerox|xfinity|xihuan|xin|xn--11b4c3d|xn--1ck2e1b|xn--1qqw23a|xn--2scrj9c|xn--30rr7y|xn--3bst00m|xn--3ds443g|xn--3e0b707e|xn--3hcrj9c|xn--3oq18vl8pn36a|xn--3pxu8k|xn--42c2d9a|xn--45br5cyl|xn--45brj9c|xn--45q11c|xn--4gbrim|xn--54b7fta0cc|xn--55qw42g|xn--55qx5d|xn--5su34j936bgsg|xn--5tzm5g|xn--6frz82g|xn--6qq986b3xl|xn--80adxhks|xn--80ao21a|xn--80aqecdr1a|xn--80asehdb|xn--80aswg|xn--8y0a063a|xn--90a3ac|xn--90ae|xn--90ais|xn--9dbq2a|xn--9et52u|xn--9krt00a|xn--b4w605ferd|xn--bck1b9a5dre4c|xn--c1avg|xn--c2br7g|xn--cck2b3b|xn--cg4bki|xn--clchc0ea0b2g2a9gcd|xn--czr694b|xn--czrs0t|xn--czru2d|xn--d1acj3b|xn--d1alf|xn--e1a4c|xn--eckvdtc9d|xn--efvy88h|xn--estv75g|xn--fct429k|xn--fhbei|xn--fiq228c5hs|xn--fiq64b|xn--fiqs8s|xn--fiqz9s|xn--fjq720a|xn--flw351e|xn--fpcrj9c3d|xn--fzc2c9e2c|xn--fzys8d69uvgm|xn--g2xx48c|xn--gckr3f0f|xn--gecrj9c|xn--gk3at1e|xn--h2breg3eve|xn--h2brj9c|xn--h2brj9c8c|xn--hxt814e|xn--i1b6b1a6a2e|xn--imr513n|xn--io0a7i|xn--j1aef|xn--j1amh|xn--j6w193g|xn--jlq61u9w7b|xn--jvr189m|xn--kcrx77d1x4a|xn--kprw13d|xn--kpry57d|xn--kpu716f|xn--kput3i|xn--l1acc|xn--lgbbat1ad8j|xn--mgb9awbf|xn--mgba3a3ejt|xn--mgba3a4f16a|xn--mgba7c0bbn0a|xn--mgbaakc7dvf|xn--mgbaam7a8h|xn--mgbab2bd|xn--mgbai9azgqp6j|xn--mgbayh7gpa|xn--mgbb9fbpob|xn--mgbbh1a|xn--mgbbh1a71e|xn--mgbc0a9azcg|xn--mgbca7dzdo|xn--mgberp4a5d4ar|xn--mgbgu82a|xn--mgbi4ecexp|xn--mgbpl2fh|xn--mgbt3dhd|xn--mgbtx2b|xn--mgbx4cd0ab|xn--mix891f|xn--mk1bu44c|xn--mxtq1m|xn--ngbc5azd|xn--ngbe9e0a|xn--ngbrx|xn--node|xn--nqv7f|xn--nqv7fs00ema|xn--nyqy26a|xn--o3cw4h|xn--ogbpf8fl|xn--p1acf|xn--p1ai|xn--pbt977c|xn--pgbs0dh|xn--pssy2u|xn--q9jyb4c|xn--qcka1pmc|xn--qxam|xn--rhqv96g|xn--rovu88b|xn--rvc1e0am3e|xn--s9brj9c|xn--ses554g|xn--t60b56a|xn--tckwe|xn--tiq49xqyj|xn--unup4y|xn--vermgensberater-ctb|xn--vermgensberatung-pwb|xn--vhquv|xn--vuq861b|xn--w4r85el8fhu5dnra|xn--w4rs40l|xn--wgbh1c|xn--wgbl6a|xn--xhq521b|xn--xkc2al3hye2a|xn--xkc2dl3a5ee0h|xn--y9a3aq|xn--yfro4i67o|xn--ygbi2ammx|xn--zfr164b|xperia|xxx|xyz|yachts|yahoo|yamaxun|yandex|ye|yodobashi|yoga|yokohama|you|youtube|yt|yun|za|zappos|zara|zero|zip|zippo|zm|zone|zuerich|zw".split("|"),
+ W = "0123456789".split(""), X = "0123456789abcdefghijklmnopqrstuvwxyz".split(""),
+ Z = [" ", "\f", "\r", "\t", "\x0B", " ", " ", "᠎"], F = [], J = function (n) {
+ return new m(n)
+ }, V = J(), $ = J(O), nn = J(x), en = J(), an = J(R);
+ V.on("@", J(y)).on(".", J(k)).on("+", J(q)).on("#", J(N)).on("?", J(A)).on("/", J(L)).on("_", J(P)).on(":", J(v)).on("{", J(H)).on("[", J(B)).on("<", J(U)).on("(", J(M)).on("}", J(D)).on("]", J(I)).on(">", J(K)).on(")", J(_)).on("&", J(G)).on([",", ";", "!", '"', "'"], J(w)), V.on("\n", J(z)).on(Z, an), an.on(Z, an);
+ for (var tn = 0; tn < Q.length; tn++) {
+ var on = c(Q[tn], V, C, x);
+ F.push.apply(F, on)
+ }
+ var rn = c("file", V, x, x), sn = c("ftp", V, x, x), cn = c("http", V, x, x), ln = c("mailto", V, x, x);
+ F.push.apply(F, rn), F.push.apply(F, sn), F.push.apply(F, cn), F.push.apply(F, ln);
+ var un = rn.pop(), gn = sn.pop(), hn = cn.pop(), bn = ln.pop(), pn = J(x), mn = J(S), fn = J(T);
+ gn.on("s", pn).on(":", mn), hn.on("s", pn).on(":", mn), F.push(pn), un.on(":", mn), pn.on(":", mn), bn.on(":", fn);
+ var dn = c("localhost", V, j, x);
+ F.push.apply(F, dn), V.on(W, $), $.on("-", en).on(W, $).on(X, nn), nn.on("-", en).on(X, nn);
+ for (var xn = 0; xn < F.length; xn++) F[xn].on("-", en).on(X, nn);
+ en.on("-", en).on(W, nn).on(X, nn), V.defaultTransition = J(E);
+ var yn = function (n) {
+ for (var e = n.replace(/[A-Z]/g, function (n) {
+ return n.toLowerCase()
+ }), a = n.length, t = [], o = 0; o < a;) {
+ for (var r = V, i = null, s = 0, c = null, l = -1; o < a && (i = r.next(e[o]));) r = i, r.accepts() ? (l = 0, c = r) : l >= 0 && l++, s++, o++;
+ if (!(l < 0)) {
+ o -= l, s -= l;
+ var u = c.emit();
+ t.push(new u(n.substr(o - s, s)))
+ }
+ }
+ return t
+ }, vn = V, kn = Object.freeze({State: m, TOKENS: Y, run: yn, start: vn}), wn = l();
+ wn.prototype = {
+ type: "token", isLink: !1, toString: function () {
+ for (var n = [], e = 0; e < this.v.length; e++) n.push(this.v[e].toString());
+ return n.join("")
+ }, toHref: function () {
+ return this.toString()
+ }, toObject: function () {
+ var n = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : "http";
+ return {type: this.type, value: this.toString(), href: this.toHref(n)}
+ }
+ };
+ var jn = a(wn, l(), {type: "email", isLink: !0}), zn = a(wn, l(), {
+ type: "email", isLink: !0, toHref: function () {
+ return "mailto:" + this.toString()
+ }
+ }), On = a(wn, l(), {type: "text"}), qn = a(wn, l(), {type: "nl"}), Nn = a(wn, l(), {
+ type: "url", isLink: !0, toHref: function () {
+ for (var n = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : "http", e = !1, a = !1, t = this.v, o = [], r = 0; t[r] instanceof S;) e = !0, o.push(t[r].toString().toLowerCase()), r++;
+ for (; t[r] instanceof L;) a = !0, o.push(t[r].toString()), r++;
+ for (; g(t[r]);) o.push(t[r].toString().toLowerCase()), r++;
+ for (; r < t.length; r++) o.push(t[r].toString());
+ return o = o.join(""), e || a || (o = n + "://" + o), o
+ }, hasProtocol: function () {
+ return this.v[0] instanceof S
+ }
+ }), Sn = Object.freeze({Base: wn, MAILTOEMAIL: jn, EMAIL: zn, NL: qn, TEXT: On, URL: Nn}), Tn = function (n) {
+ return new f(n)
+ }, An = Tn(), Ln = Tn(), Pn = Tn(), En = Tn(), Cn = Tn(), Rn = Tn(), Hn = Tn(), Bn = Tn(Nn), Un = Tn(),
+ Mn = Tn(Nn), Dn = Tn(Nn), In = Tn(), Kn = Tn(), _n = Tn(), Gn = Tn(), Yn = Tn(), Qn = Tn(Nn), Wn = Tn(Nn),
+ Xn = Tn(Nn), Zn = Tn(Nn), Fn = Tn(), Jn = Tn(), Vn = Tn(), $n = Tn(), ne = Tn(), ee = Tn(), ae = Tn(zn),
+ te = Tn(), oe = Tn(zn), re = Tn(jn), ie = Tn(), se = Tn(), ce = Tn(), le = Tn(), ue = Tn(qn);
+ An.on(z, ue).on(S, Ln).on(T, Pn).on(L, En), Ln.on(L, En), En.on(L, Cn), An.on(C, Rn).on(x, Rn).on(j, Bn).on(O, Rn), Cn.on(C, Dn).on(x, Dn).on(O, Dn).on(j, Dn), Rn.on(k, Hn), ne.on(k, ee), Hn.on(C, Bn).on(x, Rn).on(O, Rn).on(j, Rn), ee.on(C, ae).on(x, ne).on(O, ne).on(j, ne), Bn.on(k, Hn), ae.on(k, ee), Bn.on(v, Un).on(L, Dn), Un.on(O, Mn), Mn.on(L, Dn), ae.on(v, te), te.on(O, oe);
+ var ge = [x, y, j, O, q, N, S, L, C, P, E, G], he = [v, k, A, w, D, I, K, _, H, B, U, M];
+ Dn.on(H, Kn).on(B, _n).on(U, Gn).on(M, Yn), In.on(H, Kn).on(B, _n).on(U, Gn).on(M, Yn), Kn.on(D, Dn), _n.on(I, Dn), Gn.on(K, Dn), Yn.on(_, Dn), Qn.on(D, Dn), Wn.on(I, Dn), Xn.on(K, Dn), Zn.on(_, Dn), Fn.on(D, Dn), Jn.on(I, Dn), Vn.on(K, Dn), $n.on(_, Dn), Kn.on(ge, Qn), _n.on(ge, Wn), Gn.on(ge, Xn), Yn.on(ge, Zn), Kn.on(he, Fn), _n.on(he, Jn), Gn.on(he, Vn), Yn.on(he, $n), Qn.on(ge, Qn), Wn.on(ge, Wn), Xn.on(ge, Xn), Zn.on(ge, Zn), Qn.on(he, Qn), Wn.on(he, Wn), Xn.on(he, Xn), Zn.on(he, Zn), Fn.on(ge, Qn), Jn.on(ge, Wn), Vn.on(ge, Xn), $n.on(ge, Zn), Fn.on(he, Fn), Jn.on(he, Jn), Vn.on(he, Vn), $n.on(he, $n), Dn.on(ge, Dn), In.on(ge, Dn), Dn.on(he, In), In.on(he, In), Pn.on(C, re).on(x, re).on(O, re).on(j, re), re.on(ge, re).on(he, ie), ie.on(ge, re).on(he, ie);
+ var be = [x, O, q, N, A, P, E, G, C];
+ Rn.on(be, se).on(y, ce), Bn.on(be, se).on(y, ce), Hn.on(be, se), se.on(be, se).on(y, ce).on(k, le), le.on(be, se), ce.on(C, ne).on(x, ne).on(j, ae);
+ var pe = function (n) {
+ for (var e = n.length, a = 0, t = [], o = []; a < e;) {
+ for (var r = An, i = null, s = null, c = 0, l = null, u = -1; a < e && !(i = r.next(n[a]));) o.push(n[a++]);
+ for (; a < e && (s = i || r.next(n[a]));) i = null, r = s, r.accepts() ? (u = 0, l = r) : u >= 0 && u++, a++, c++;
+ if (u < 0) for (var g = a - c; g < a; g++) o.push(n[g]); else {
+ o.length > 0 && (t.push(new On(o)), o = []), a -= u, c -= u;
+ var h = l.emit();
+ t.push(new h(n.slice(a - c, a)))
+ }
+ }
+ return o.length > 0 && t.push(new On(o)), t
+ }, me = Object.freeze({State: f, TOKENS: Sn, run: pe, start: An});
+ Array.isArray || (Array.isArray = function (n) {
+ return "[object Array]" === Object.prototype.toString.call(n)
+ });
+ var fe = function (n) {
+ return pe(yn(n))
+ }, de = function (n) {
+ for (var e = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : null, a = fe(n), t = [], o = 0; o < a.length; o++) {
+ var r = a[o];
+ !r.isLink || e && r.type !== e || t.push(r.toObject())
+ }
+ return t
+ }, xe = function (n) {
+ var e = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : null, a = fe(n);
+ return 1 === a.length && a[0].isLink && (!e || a[0].type === e)
+ };
+ e.find = de, e.inherits = a, e.options = b, e.parser = me, e.scanner = kn, e.test = xe, e.tokenize = fe
+ }(self.linkify = self.linkify || {})
+}();
+
+"use strict";
+!function (e, n, t) {
+ var i = function (n) {
+ function t(e, n, t) {
+ var i = t[t.length - 1];
+ e.replaceChild(i, n);
+ for (var a = t.length - 2; a >= 0; a--) e.insertBefore(t[a], i), i = t[a]
+ }
+
+ function i(e, n, t) {
+ for (var i = [], a = e, r = Array.isArray(a), o = 0, a = r ? a : a[Symbol.iterator](); ;) {
+ var l;
+ if (r) {
+ if (o >= a.length) break;
+ l = a[o++]
+ } else {
+ if (o = a.next(), o.done) break;
+ l = o.value
+ }
+ var f = l;
+ if ("nl" === f.type && n.nl2br) i.push(t.createElement("br")); else if (f.isLink && n.check(f)) {
+ var s = n.resolve(f), c = s.formatted, u = s.formattedHref, y = s.tagName, d = s.className,
+ m = s.target, k = s.events, h = s.attributes, v = t.createElement(y);
+ if (v.setAttribute("href", u), d && v.setAttribute("class", d), m && v.setAttribute("target", m), h) for (var g in h) v.setAttribute(g, h[g]);
+ if (k) for (var b in k) v.addEventListener ? v.addEventListener(b, k[b]) : v.attachEvent && v.attachEvent("on" + b, k[b]);
+ v.appendChild(t.createTextNode(c)), i.push(v)
+ } else i.push(t.createTextNode(f.toString()))
+ }
+ return i
+ }
+
+ function a(e, n, r) {
+ if (!e || e.nodeType !== u) throw new Error("Cannot linkify " + e + " - Invalid DOM Node type");
+ var o = n.ignoreTags;
+ if ("A" === e.tagName || f.contains(o, e.tagName)) return e;
+ for (var s = e.firstChild; s;) {
+ var d = void 0, m = void 0, k = void 0;
+ switch (s.nodeType) {
+ case u:
+ a(s, n, r);
+ break;
+ case y:
+ if (d = s.nodeValue, m = l(d), 0 === m.length || 1 === m.length && m[0] instanceof c) break;
+ k = i(m, n, r), t(e, s, k), s = k[k.length - 1]
+ }
+ s = s.nextSibling
+ }
+ return e
+ }
+
+ function r(n, t) {
+ var i = arguments.length > 2 && void 0 !== arguments[2] && arguments[2];
+ try {
+ i = i || document || e && e.document || global && global.document
+ } catch (r) {
+ }
+ if (!i) throw new Error("Cannot find document implementation. If you are in a non-browser environment like Node.js, pass the document implementation as the third argument to linkifyElement.");
+ return t = new s(t), a(n, t, i)
+ }
+
+ function o(n) {
+ function t(e) {
+ return e = r.normalize(e), this.each(function () {
+ r.helper(this, e, i)
+ })
+ }
+
+ var i = arguments.length > 1 && void 0 !== arguments[1] && arguments[1];
+ n.fn = n.fn || {};
+ try {
+ i = i || document || e && e.document || global && global.document
+ } catch (a) {
+ }
+ if (!i) throw new Error("Cannot find document implementation. If you are in a non-browser environment like Node.js, pass the document implementation as the second argument to linkify/jquery");
+ "function" != typeof n.fn.linkify && (n.fn.linkify = t, n(i).ready(function () {
+ n("[data-linkify]").each(function () {
+ var e = n(this), t = e.data(), i = t.linkify, a = t.linkifyNlbr,
+ o = {nl2br: !!a && 0 !== a && "false" !== a};
+ "linkifyAttributes" in t && (o.attributes = t.linkifyAttributes), "linkifyDefaultProtocol" in t && (o.defaultProtocol = t.linkifyDefaultProtocol), "linkifyEvents" in t && (o.events = t.linkifyEvents), "linkifyFormat" in t && (o.format = t.linkifyFormat), "linkifyFormatHref" in t && (o.formatHref = t.linkifyFormatHref), "linkifyTagname" in t && (o.tagName = t.linkifyTagname), "linkifyTarget" in t && (o.target = t.linkifyTarget), "linkifyValidate" in t && (o.validate = t.linkifyValidate), "linkifyIgnoreTags" in t && (o.ignoreTags = t.linkifyIgnoreTags), "linkifyClassName" in t ? o.className = t.linkifyClassName : "linkifyLinkclass" in t && (o.className = t.linkifyLinkclass), o = r.normalize(o);
+ var l = "this" === i ? e : e.find(i);
+ l.linkify(o)
+ })
+ }))
+ }
+
+ var l = n.tokenize, f = n.options, s = f.Options, c = n.parser.TOKENS.TEXT, u = 1, y = 3;
+ r.helper = a, r.normalize = function (e) {
+ return new s(e)
+ };
+ try {
+ !(void 0).define && (e.linkifyElement = r)
+ } catch (d) {
+ }
+ return o
+ }(n);
+ "function" != typeof t.fn.linkify && i(t)
+}(window, linkify, jQuery); \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/js/main.js b/main/app/sprinkles/core/assets/SiteAssets/js/main.js
new file mode 100644
index 0000000..d2123f5
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/js/main.js
@@ -0,0 +1,91 @@
+var MainTabWindows = $(".MainTabWindows");
+var NavbarIconWrap = $(".NavbarIconWrap");
+var Navbar = $(".Navbar");
+var NavbarLine = $(".NavbarLine");
+
+
+/******
+ NAVBAR
+ *****/
+var $el, leftPos, newWidth;
+NavbarLine
+ .css("left", $(".ActiveTab").position().left)
+ .data("origLeft", NavbarLine.position().left)
+ .data("origWidth", NavbarLine.width());
+NavbarIconWrap.on("click", function () {
+ NavbarIconWrap.removeClass("ActiveTab");
+ $(this).addClass("ActiveTab");
+ var index = $(this).attr('id');
+ MainTabWindows.slick('slickGoTo', index);
+ //$('.MainTabWindows').flickity().flickity('select', index);
+ $el = $(this);
+ leftPos = $el.position().left;
+ NavbarLine.stop().animate({
+ left: leftPos,
+ width: newWidth
+ }, 300);
+});
+
+/********
+ FLICKITY
+ *******/
+MainTabWindows.slick({
+ initialSlide: 2,
+ mobileFirst: true,
+ nextArrow: "",
+ prevArrow: "",
+ infinite: false,
+ zIndex: 500
+});
+
+MainTabWindows.on('beforeChange', function (event, slick, currentSlide, nextSlide) {
+ //console.log(nextSlide);
+ NavbarIconWrap.removeClass("ActiveTab");
+ $el = $("#" + nextSlide);
+ $el.addClass("ActiveTab");
+ leftPos = $el.position().left;
+ NavbarLine.stop().animate({
+ left: leftPos,
+ width: newWidth
+ }, 300);
+});
+
+/*
+$('.MainTabWindows').flickity({
+ cellAlign: 'left',
+ prevNextButtons: false,
+ pageDots: false,
+ friction: 0.3,
+ dragThreshold: ($("body").width() * 0.5),
+ initialIndex: 2,
+ wrapAround: true,
+ maxSwipeWidth: 0,
+ on: {
+ change: function (index) {
+ $(".NavbarIconWrap").removeClass("ActiveTab");
+ $el = $("#" + index);
+ $el.addClass("ActiveTab");
+ leftPos = $el.position().left;
+ $magicLine.stop().animate({
+ left: leftPos,
+ width: newWidth
+ }, 300);
+ },
+ dragStart: function () {
+ $(".ActiveTab").css({ transform: 'scale(1.05)' });
+ },
+ dragEnd: function () {
+ $(".NavbarIconWrap").css({ transform: 'scale(1.0)' });
+ }/*,
+ scroll: function (event, progress) {
+ var TotalWidth = $("body").width();
+ console.log(progress / 10);
+ leftPos = ((progress / 1000) * TotalWidth + 'px');
+ $magicLine.stop().animate({
+ left: leftPos,
+ width: newWidth
+ });
+ }*
+ }
+});
+*/ \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/js/modernizr.js b/main/app/sprinkles/core/assets/SiteAssets/js/modernizr.js
new file mode 100644
index 0000000..40dd2a9
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/js/modernizr.js
@@ -0,0 +1 @@
+window.Modernizr=function(e,t,n){function r(e){b.cssText=e}function o(e,t){return r(S.join(e+";")+(t||""))}function a(e,t){return typeof e===t}function i(e,t){return!!~(""+e).indexOf(t)}function c(e,t){for(var r in e){var o=e[r];if(!i(o,"-")&&b[o]!==n)return"pfx"==t?o:!0}return!1}function s(e,t,r){for(var o in e){var i=t[e[o]];if(i!==n)return r===!1?e[o]:a(i,"function")?i.bind(r||t):i}return!1}function u(e,t,n){var r=e.charAt(0).toUpperCase()+e.slice(1),o=(e+" "+k.join(r+" ")+r).split(" ");return a(t,"string")||a(t,"undefined")?c(o,t):(o=(e+" "+T.join(r+" ")+r).split(" "),s(o,t,n))}function l(){p.input=function(n){for(var r=0,o=n.length;o>r;r++)j[n[r]]=!!(n[r]in E);return j.list&&(j.list=!(!t.createElement("datalist")||!e.HTMLDataListElement)),j}("autocomplete autofocus list placeholder max min multiple pattern required step".split(" ")),p.inputtypes=function(e){for(var r,o,a,i=0,c=e.length;c>i;i++)E.setAttribute("type",o=e[i]),r="text"!==E.type,r&&(E.value=x,E.style.cssText="position:absolute;visibility:hidden;",/^range$/.test(o)&&E.style.WebkitAppearance!==n?(g.appendChild(E),a=t.defaultView,r=a.getComputedStyle&&"textfield"!==a.getComputedStyle(E,null).WebkitAppearance&&0!==E.offsetHeight,g.removeChild(E)):/^(search|tel)$/.test(o)||(r=/^(url|email)$/.test(o)?E.checkValidity&&E.checkValidity()===!1:E.value!=x)),P[e[i]]=!!r;return P}("search tel url email datetime date month week time datetime-local number range color".split(" "))}var d,f,m="2.8.3",p={},h=!0,g=t.documentElement,v="modernizr",y=t.createElement(v),b=y.style,E=t.createElement("input"),x=":)",w={}.toString,S=" -webkit- -moz- -o- -ms- ".split(" "),C="Webkit Moz O ms",k=C.split(" "),T=C.toLowerCase().split(" "),N={svg:"http://www.w3.org/2000/svg"},M={},P={},j={},$=[],D=$.slice,F=function(e,n,r,o){var a,i,c,s,u=t.createElement("div"),l=t.body,d=l||t.createElement("body");if(parseInt(r,10))for(;r--;)c=t.createElement("div"),c.id=o?o[r]:v+(r+1),u.appendChild(c);return a=["&#173;",'<style id="s',v,'">',e,"</style>"].join(""),u.id=v,(l?u:d).innerHTML+=a,d.appendChild(u),l||(d.style.background="",d.style.overflow="hidden",s=g.style.overflow,g.style.overflow="hidden",g.appendChild(d)),i=n(u,e),l?u.parentNode.removeChild(u):(d.parentNode.removeChild(d),g.style.overflow=s),!!i},z=function(t){var n=e.matchMedia||e.msMatchMedia;if(n)return n(t)&&n(t).matches||!1;var r;return F("@media "+t+" { #"+v+" { position: absolute; } }",function(t){r="absolute"==(e.getComputedStyle?getComputedStyle(t,null):t.currentStyle).position}),r},A=function(){function e(e,o){o=o||t.createElement(r[e]||"div"),e="on"+e;var i=e in o;return i||(o.setAttribute||(o=t.createElement("div")),o.setAttribute&&o.removeAttribute&&(o.setAttribute(e,""),i=a(o[e],"function"),a(o[e],"undefined")||(o[e]=n),o.removeAttribute(e))),o=null,i}var r={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return e}(),L={}.hasOwnProperty;f=a(L,"undefined")||a(L.call,"undefined")?function(e,t){return t in e&&a(e.constructor.prototype[t],"undefined")}:function(e,t){return L.call(e,t)},Function.prototype.bind||(Function.prototype.bind=function(e){var t=this;if("function"!=typeof t)throw new TypeError;var n=D.call(arguments,1),r=function(){if(this instanceof r){var o=function(){};o.prototype=t.prototype;var a=new o,i=t.apply(a,n.concat(D.call(arguments)));return Object(i)===i?i:a}return t.apply(e,n.concat(D.call(arguments)))};return r}),M.flexbox=function(){return u("flexWrap")},M.flexboxlegacy=function(){return u("boxDirection")},M.canvas=function(){var e=t.createElement("canvas");return!(!e.getContext||!e.getContext("2d"))},M.canvastext=function(){return!(!p.canvas||!a(t.createElement("canvas").getContext("2d").fillText,"function"))},M.webgl=function(){return!!e.WebGLRenderingContext},M.touch=function(){var n;return"ontouchstart"in e||e.DocumentTouch&&t instanceof DocumentTouch?n=!0:F(["@media (",S.join("touch-enabled),("),v,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(e){n=9===e.offsetTop}),n},M.geolocation=function(){return"geolocation"in navigator},M.postmessage=function(){return!!e.postMessage},M.websqldatabase=function(){return!!e.openDatabase},M.indexedDB=function(){return!!u("indexedDB",e)},M.hashchange=function(){return A("hashchange",e)&&(t.documentMode===n||t.documentMode>7)},M.history=function(){return!(!e.history||!history.pushState)},M.draganddrop=function(){var e=t.createElement("div");return"draggable"in e||"ondragstart"in e&&"ondrop"in e},M.websockets=function(){return"WebSocket"in e||"MozWebSocket"in e},M.rgba=function(){return r("background-color:rgba(150,255,150,.5)"),i(b.backgroundColor,"rgba")},M.hsla=function(){return r("background-color:hsla(120,40%,100%,.5)"),i(b.backgroundColor,"rgba")||i(b.backgroundColor,"hsla")},M.multiplebgs=function(){return r("background:url(https://),url(https://),red url(https://)"),/(url\s*\(.*?){3}/.test(b.background)},M.backgroundsize=function(){return u("backgroundSize")},M.borderimage=function(){return u("borderImage")},M.borderradius=function(){return u("borderRadius")},M.boxshadow=function(){return u("boxShadow")},M.textshadow=function(){return""===t.createElement("div").style.textShadow},M.opacity=function(){return o("opacity:.55"),/^0.55$/.test(b.opacity)},M.cssanimations=function(){return u("animationName")},M.csscolumns=function(){return u("columnCount")},M.cssgradients=function(){var e="background-image:",t="gradient(linear,left top,right bottom,from(#9f9),to(white));",n="linear-gradient(left top,#9f9, white);";return r((e+"-webkit- ".split(" ").join(t+e)+S.join(n+e)).slice(0,-e.length)),i(b.backgroundImage,"gradient")},M.cssreflections=function(){return u("boxReflect")},M.csstransforms=function(){return!!u("transform")},M.csstransforms3d=function(){var e=!!u("perspective");return e&&"webkitPerspective"in g.style&&F("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(t){e=9===t.offsetLeft&&3===t.offsetHeight}),e},M.csstransitions=function(){return u("transition")},M.fontface=function(){var e;return F('@font-face {font-family:"font";src:url("https://")}',function(n,r){var o=t.getElementById("smodernizr"),a=o.sheet||o.styleSheet,i=a?a.cssRules&&a.cssRules[0]?a.cssRules[0].cssText:a.cssText||"":"";e=/src/i.test(i)&&0===i.indexOf(r.split(" ")[0])}),e},M.generatedcontent=function(){var e;return F(["#",v,"{font:0/0 a}#",v,':after{content:"',x,'";visibility:hidden;font:3px/1 a}'].join(""),function(t){e=t.offsetHeight>=3}),e},M.video=function(){var e=t.createElement("video"),n=!1;try{(n=!!e.canPlayType)&&(n=new Boolean(n),n.ogg=e.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),n.h264=e.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),n.webm=e.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,""))}catch(r){}return n},M.audio=function(){var e=t.createElement("audio"),n=!1;try{(n=!!e.canPlayType)&&(n=new Boolean(n),n.ogg=e.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),n.mp3=e.canPlayType("audio/mpeg;").replace(/^no$/,""),n.wav=e.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),n.m4a=(e.canPlayType("audio/x-m4a;")||e.canPlayType("audio/aac;")).replace(/^no$/,""))}catch(r){}return n},M.localstorage=function(){try{return localStorage.setItem(v,v),localStorage.removeItem(v),!0}catch(e){return!1}},M.sessionstorage=function(){try{return sessionStorage.setItem(v,v),sessionStorage.removeItem(v),!0}catch(e){return!1}},M.webworkers=function(){return!!e.Worker},M.applicationcache=function(){return!!e.applicationCache},M.svg=function(){return!!t.createElementNS&&!!t.createElementNS(N.svg,"svg").createSVGRect},M.inlinesvg=function(){var e=t.createElement("div");return e.innerHTML="<svg/>",(e.firstChild&&e.firstChild.namespaceURI)==N.svg},M.smil=function(){return!!t.createElementNS&&/SVGAnimate/.test(w.call(t.createElementNS(N.svg,"animate")))},M.svgclippaths=function(){return!!t.createElementNS&&/SVGClipPath/.test(w.call(t.createElementNS(N.svg,"clipPath")))};for(var H in M)f(M,H)&&(d=H.toLowerCase(),p[d]=M[H](),$.push((p[d]?"":"no-")+d));return p.input||l(),p.addTest=function(e,t){if("object"==typeof e)for(var r in e)f(e,r)&&p.addTest(r,e[r]);else{if(e=e.toLowerCase(),p[e]!==n)return p;t="function"==typeof t?t():t,"undefined"!=typeof h&&h&&(g.className+=" "+(t?"":"no-")+e),p[e]=t}return p},r(""),y=E=null,function(e,t){function n(e,t){var n=e.createElement("p"),r=e.getElementsByTagName("head")[0]||e.documentElement;return n.innerHTML="x<style>"+t+"</style>",r.insertBefore(n.lastChild,r.firstChild)}function r(){var e=y.elements;return"string"==typeof e?e.split(" "):e}function o(e){var t=v[e[h]];return t||(t={},g++,e[h]=g,v[g]=t),t}function a(e,n,r){if(n||(n=t),l)return n.createElement(e);r||(r=o(n));var a;return a=r.cache[e]?r.cache[e].cloneNode():p.test(e)?(r.cache[e]=r.createElem(e)).cloneNode():r.createElem(e),!a.canHaveChildren||m.test(e)||a.tagUrn?a:r.frag.appendChild(a)}function i(e,n){if(e||(e=t),l)return e.createDocumentFragment();n=n||o(e);for(var a=n.frag.cloneNode(),i=0,c=r(),s=c.length;s>i;i++)a.createElement(c[i]);return a}function c(e,t){t.cache||(t.cache={},t.createElem=e.createElement,t.createFrag=e.createDocumentFragment,t.frag=t.createFrag()),e.createElement=function(n){return y.shivMethods?a(n,e,t):t.createElem(n)},e.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+r().join().replace(/[\w\-]+/g,function(e){return t.createElem(e),t.frag.createElement(e),'c("'+e+'")'})+");return n}")(y,t.frag)}function s(e){e||(e=t);var r=o(e);return!y.shivCSS||u||r.hasCSS||(r.hasCSS=!!n(e,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||c(e,r),e}var u,l,d="3.7.0",f=e.html5||{},m=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,h="_html5shiv",g=0,v={};!function(){try{var e=t.createElement("a");e.innerHTML="<xyz></xyz>",u="hidden"in e,l=1==e.childNodes.length||function(){t.createElement("a");var e=t.createDocumentFragment();return"undefined"==typeof e.cloneNode||"undefined"==typeof e.createDocumentFragment||"undefined"==typeof e.createElement}()}catch(n){u=!0,l=!0}}();var y={elements:f.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:d,shivCSS:f.shivCSS!==!1,supportsUnknownElements:l,shivMethods:f.shivMethods!==!1,type:"default",shivDocument:s,createElement:a,createDocumentFragment:i};e.html5=y,s(t)}(this,t),p._version=m,p._prefixes=S,p._domPrefixes=T,p._cssomPrefixes=k,p.mq=z,p.hasEvent=A,p.testProp=function(e){return c([e])},p.testAllProps=u,p.testStyles=F,p.prefixed=function(e,t,n){return t?u(e,t,n):u(e,"pfx")},g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(h?" js "+$.join(" "):""),p}(this,this.document); \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/js/slick.js b/main/app/sprinkles/core/assets/SiteAssets/js/slick.js
new file mode 100644
index 0000000..c697993
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/js/slick.js
@@ -0,0 +1,556 @@
+!function (i) {
+ "use strict";
+ "function" == typeof define && define.amd ? define(["jquery"], i) : "undefined" != typeof exports ? module.exports = i(require("jquery")) : i(jQuery)
+}(function (i) {
+ "use strict";
+ var e = window.Slick || {};
+ (e = function () {
+ var e = 0;
+ return function (t, o) {
+ var s, n = this;
+ n.defaults = {
+ accessibility: !0,
+ adaptiveHeight: !1,
+ appendArrows: i(t),
+ appendDots: i(t),
+ arrows: !0,
+ asNavFor: null,
+ prevArrow: '<button class="slick-prev" aria-label="Previous" type="button">Previous</button>',
+ nextArrow: '<button class="slick-next" aria-label="Next" type="button">Next</button>',
+ autoplay: !1,
+ autoplaySpeed: 3e3,
+ centerMode: !1,
+ centerPadding: "50px",
+ cssEase: "ease",
+ customPaging: function (e, t) {
+ return i('<button type="button" />').text(t + 1)
+ },
+ dots: !1,
+ dotsClass: "slick-dots",
+ draggable: !0,
+ easing: "linear",
+ edgeFriction: .35,
+ fade: !1,
+ focusOnSelect: !1,
+ focusOnChange: !1,
+ infinite: !0,
+ initialSlide: 0,
+ lazyLoad: "ondemand",
+ mobileFirst: !1,
+ pauseOnHover: !0,
+ pauseOnFocus: !0,
+ pauseOnDotsHover: !1,
+ respondTo: "window",
+ responsive: null,
+ rows: 1,
+ rtl: !1,
+ slide: "",
+ slidesPerRow: 1,
+ slidesToShow: 1,
+ slidesToScroll: 1,
+ speed: 500,
+ swipe: !0,
+ swipeToSlide: !1,
+ touchMove: !0,
+ touchThreshold: 5,
+ useCSS: !0,
+ useTransform: !0,
+ variableWidth: !1,
+ vertical: !1,
+ verticalSwiping: !1,
+ waitForAnimate: !0,
+ zIndex: 1e3
+ }, n.initials = {
+ animating: !1,
+ dragging: !1,
+ autoPlayTimer: null,
+ currentDirection: 0,
+ currentLeft: null,
+ currentSlide: 0,
+ direction: 1,
+ $dots: null,
+ listWidth: null,
+ listHeight: null,
+ loadIndex: 0,
+ $nextArrow: null,
+ $prevArrow: null,
+ scrolling: !1,
+ slideCount: null,
+ slideWidth: null,
+ $slideTrack: null,
+ $slides: null,
+ sliding: !1,
+ slideOffset: 0,
+ swipeLeft: null,
+ swiping: !1,
+ $list: null,
+ touchObject: {},
+ transformsEnabled: !1,
+ unslicked: !1
+ }, i.extend(n, n.initials), n.activeBreakpoint = null, n.animType = null, n.animProp = null, n.breakpoints = [], n.breakpointSettings = [], n.cssTransitions = !1, n.focussed = !1, n.interrupted = !1, n.hidden = "hidden", n.paused = !0, n.positionProp = null, n.respondTo = null, n.rowCount = 1, n.shouldClick = !0, n.$slider = i(t), n.$slidesCache = null, n.transformType = null, n.transitionType = null, n.visibilityChange = "visibilitychange", n.windowWidth = 0, n.windowTimer = null, s = i(t).data("slick") || {}, n.options = i.extend({}, n.defaults, o, s), n.currentSlide = n.options.initialSlide, n.originalSettings = n.options, void 0 !== document.mozHidden ? (n.hidden = "mozHidden", n.visibilityChange = "mozvisibilitychange") : void 0 !== document.webkitHidden && (n.hidden = "webkitHidden", n.visibilityChange = "webkitvisibilitychange"), n.autoPlay = i.proxy(n.autoPlay, n), n.autoPlayClear = i.proxy(n.autoPlayClear, n), n.autoPlayIterator = i.proxy(n.autoPlayIterator, n), n.changeSlide = i.proxy(n.changeSlide, n), n.clickHandler = i.proxy(n.clickHandler, n), n.selectHandler = i.proxy(n.selectHandler, n), n.setPosition = i.proxy(n.setPosition, n), n.swipeHandler = i.proxy(n.swipeHandler, n), n.dragHandler = i.proxy(n.dragHandler, n), n.keyHandler = i.proxy(n.keyHandler, n), n.instanceUid = e++, n.htmlExpr = /^(?:\s*(<[\w\W]+>)[^>]*)$/, n.registerBreakpoints(), n.init(!0)
+ }
+ }()).prototype.activateADA = function () {
+ this.$slideTrack.find(".slick-active").attr({"aria-hidden": "false"}).find("a, input, button, select").attr({tabindex: "0"})
+ }, e.prototype.addSlide = e.prototype.slickAdd = function (e, t, o) {
+ var s = this;
+ if ("boolean" == typeof t) o = t, t = null; else if (t < 0 || t >= s.slideCount) return !1;
+ s.unload(), "number" == typeof t ? 0 === t && 0 === s.$slides.length ? i(e).appendTo(s.$slideTrack) : o ? i(e).insertBefore(s.$slides.eq(t)) : i(e).insertAfter(s.$slides.eq(t)) : !0 === o ? i(e).prependTo(s.$slideTrack) : i(e).appendTo(s.$slideTrack), s.$slides = s.$slideTrack.children(this.options.slide), s.$slideTrack.children(this.options.slide).detach(), s.$slideTrack.append(s.$slides), s.$slides.each(function (e, t) {
+ i(t).attr("data-slick-index", e)
+ }), s.$slidesCache = s.$slides, s.reinit()
+ }, e.prototype.animateHeight = function () {
+ var i = this;
+ if (1 === i.options.slidesToShow && !0 === i.options.adaptiveHeight && !1 === i.options.vertical) {
+ var e = i.$slides.eq(i.currentSlide).outerHeight(!0);
+ i.$list.animate({height: e}, i.options.speed)
+ }
+ }, e.prototype.animateSlide = function (e, t) {
+ var o = {}, s = this;
+ s.animateHeight(), !0 === s.options.rtl && !1 === s.options.vertical && (e = -e), !1 === s.transformsEnabled ? !1 === s.options.vertical ? s.$slideTrack.animate({left: e}, s.options.speed, s.options.easing, t) : s.$slideTrack.animate({top: e}, s.options.speed, s.options.easing, t) : !1 === s.cssTransitions ? (!0 === s.options.rtl && (s.currentLeft = -s.currentLeft), i({animStart: s.currentLeft}).animate({animStart: e}, {
+ duration: s.options.speed,
+ easing: s.options.easing,
+ step: function (i) {
+ i = Math.ceil(i), !1 === s.options.vertical ? (o[s.animType] = "translate(" + i + "px, 0px)", s.$slideTrack.css(o)) : (o[s.animType] = "translate(0px," + i + "px)", s.$slideTrack.css(o))
+ },
+ complete: function () {
+ t && t.call()
+ }
+ })) : (s.applyTransition(), e = Math.ceil(e), !1 === s.options.vertical ? o[s.animType] = "translate3d(" + e + "px, 0px, 0px)" : o[s.animType] = "translate3d(0px," + e + "px, 0px)", s.$slideTrack.css(o), t && setTimeout(function () {
+ s.disableTransition(), t.call()
+ }, s.options.speed))
+ }, e.prototype.getNavTarget = function () {
+ var e = this, t = e.options.asNavFor;
+ return t && null !== t && (t = i(t).not(e.$slider)), t
+ }, e.prototype.asNavFor = function (e) {
+ var t = this.getNavTarget();
+ null !== t && "object" == typeof t && t.each(function () {
+ var t = i(this).slick("getSlick");
+ t.unslicked || t.slideHandler(e, !0)
+ })
+ }, e.prototype.applyTransition = function (i) {
+ var e = this, t = {};
+ !1 === e.options.fade ? t[e.transitionType] = e.transformType + " " + e.options.speed + "ms " + e.options.cssEase : t[e.transitionType] = "opacity " + e.options.speed + "ms " + e.options.cssEase, !1 === e.options.fade ? e.$slideTrack.css(t) : e.$slides.eq(i).css(t)
+ }, e.prototype.autoPlay = function () {
+ var i = this;
+ i.autoPlayClear(), i.slideCount > i.options.slidesToShow && (i.autoPlayTimer = setInterval(i.autoPlayIterator, i.options.autoplaySpeed))
+ }, e.prototype.autoPlayClear = function () {
+ var i = this;
+ i.autoPlayTimer && clearInterval(i.autoPlayTimer)
+ }, e.prototype.autoPlayIterator = function () {
+ var i = this, e = i.currentSlide + i.options.slidesToScroll;
+ i.paused || i.interrupted || i.focussed || (!1 === i.options.infinite && (1 === i.direction && i.currentSlide + 1 === i.slideCount - 1 ? i.direction = 0 : 0 === i.direction && (e = i.currentSlide - i.options.slidesToScroll, i.currentSlide - 1 == 0 && (i.direction = 1))), i.slideHandler(e))
+ }, e.prototype.buildArrows = function () {
+ var e = this;
+ !0 === e.options.arrows && (e.$prevArrow = i(e.options.prevArrow).addClass("slick-arrow"), e.$nextArrow = i(e.options.nextArrow).addClass("slick-arrow"), e.slideCount > e.options.slidesToShow ? (e.$prevArrow.removeClass("slick-hidden").removeAttr("aria-hidden tabindex"), e.$nextArrow.removeClass("slick-hidden").removeAttr("aria-hidden tabindex"), e.htmlExpr.test(e.options.prevArrow) && e.$prevArrow.prependTo(e.options.appendArrows), e.htmlExpr.test(e.options.nextArrow) && e.$nextArrow.appendTo(e.options.appendArrows), !0 !== e.options.infinite && e.$prevArrow.addClass("slick-disabled").attr("aria-disabled", "true")) : e.$prevArrow.add(e.$nextArrow).addClass("slick-hidden").attr({
+ "aria-disabled": "true",
+ tabindex: "-1"
+ }))
+ }, e.prototype.buildDots = function () {
+ var e, t, o = this;
+ if (!0 === o.options.dots) {
+ for (o.$slider.addClass("slick-dotted"), t = i("<ul />").addClass(o.options.dotsClass), e = 0; e <= o.getDotCount(); e += 1) t.append(i("<li />").append(o.options.customPaging.call(this, o, e)));
+ o.$dots = t.appendTo(o.options.appendDots), o.$dots.find("li").first().addClass("slick-active")
+ }
+ }, e.prototype.buildOut = function () {
+ var e = this;
+ e.$slides = e.$slider.children(e.options.slide + ":not(.slick-cloned)").addClass("slick-slide"), e.slideCount = e.$slides.length, e.$slides.each(function (e, t) {
+ i(t).attr("data-slick-index", e).data("originalStyling", i(t).attr("style") || "")
+ }), e.$slider.addClass("slick-slider"), e.$slideTrack = 0 === e.slideCount ? i('<div class="slick-track"/>').appendTo(e.$slider) : e.$slides.wrapAll('<div class="slick-track"/>').parent(), e.$list = e.$slideTrack.wrap('<div class="slick-list"/>').parent(), e.$slideTrack.css("opacity", 0), !0 !== e.options.centerMode && !0 !== e.options.swipeToSlide || (e.options.slidesToScroll = 1), i("img[data-lazy]", e.$slider).not("[src]").addClass("slick-loading"), e.setupInfinite(), e.buildArrows(), e.buildDots(), e.updateDots(), e.setSlideClasses("number" == typeof e.currentSlide ? e.currentSlide : 0), !0 === e.options.draggable && e.$list.addClass("draggable")
+ }, e.prototype.buildRows = function () {
+ var i, e, t, o, s, n, r, l = this;
+ if (o = document.createDocumentFragment(), n = l.$slider.children(), l.options.rows > 1) {
+ for (r = l.options.slidesPerRow * l.options.rows, s = Math.ceil(n.length / r), i = 0; i < s; i++) {
+ var d = document.createElement("div");
+ for (e = 0; e < l.options.rows; e++) {
+ var a = document.createElement("div");
+ for (t = 0; t < l.options.slidesPerRow; t++) {
+ var c = i * r + (e * l.options.slidesPerRow + t);
+ n.get(c) && a.appendChild(n.get(c))
+ }
+ d.appendChild(a)
+ }
+ o.appendChild(d)
+ }
+ l.$slider.empty().append(o), l.$slider.children().children().children().css({
+ width: 100 / l.options.slidesPerRow + "%",
+ display: "inline-block"
+ })
+ }
+ }, e.prototype.checkResponsive = function (e, t) {
+ var o, s, n, r = this, l = !1, d = r.$slider.width(), a = window.innerWidth || i(window).width();
+ if ("window" === r.respondTo ? n = a : "slider" === r.respondTo ? n = d : "min" === r.respondTo && (n = Math.min(a, d)), r.options.responsive && r.options.responsive.length && null !== r.options.responsive) {
+ s = null;
+ for (o in r.breakpoints) r.breakpoints.hasOwnProperty(o) && (!1 === r.originalSettings.mobileFirst ? n < r.breakpoints[o] && (s = r.breakpoints[o]) : n > r.breakpoints[o] && (s = r.breakpoints[o]));
+ null !== s ? null !== r.activeBreakpoint ? (s !== r.activeBreakpoint || t) && (r.activeBreakpoint = s, "unslick" === r.breakpointSettings[s] ? r.unslick(s) : (r.options = i.extend({}, r.originalSettings, r.breakpointSettings[s]), !0 === e && (r.currentSlide = r.options.initialSlide), r.refresh(e)), l = s) : (r.activeBreakpoint = s, "unslick" === r.breakpointSettings[s] ? r.unslick(s) : (r.options = i.extend({}, r.originalSettings, r.breakpointSettings[s]), !0 === e && (r.currentSlide = r.options.initialSlide), r.refresh(e)), l = s) : null !== r.activeBreakpoint && (r.activeBreakpoint = null, r.options = r.originalSettings, !0 === e && (r.currentSlide = r.options.initialSlide), r.refresh(e), l = s), e || !1 === l || r.$slider.trigger("breakpoint", [r, l])
+ }
+ }, e.prototype.changeSlide = function (e, t) {
+ var o, s, n, r = this, l = i(e.currentTarget);
+ switch (l.is("a") && e.preventDefault(), l.is("li") || (l = l.closest("li")), n = r.slideCount % r.options.slidesToScroll != 0, o = n ? 0 : (r.slideCount - r.currentSlide) % r.options.slidesToScroll, e.data.message) {
+ case"previous":
+ s = 0 === o ? r.options.slidesToScroll : r.options.slidesToShow - o, r.slideCount > r.options.slidesToShow && r.slideHandler(r.currentSlide - s, !1, t);
+ break;
+ case"next":
+ s = 0 === o ? r.options.slidesToScroll : o, r.slideCount > r.options.slidesToShow && r.slideHandler(r.currentSlide + s, !1, t);
+ break;
+ case"index":
+ var d = 0 === e.data.index ? 0 : e.data.index || l.index() * r.options.slidesToScroll;
+ r.slideHandler(r.checkNavigable(d), !1, t), l.children().trigger("focus");
+ break;
+ default:
+ return
+ }
+ }, e.prototype.checkNavigable = function (i) {
+ var e, t;
+ if (e = this.getNavigableIndexes(), t = 0, i > e[e.length - 1]) i = e[e.length - 1]; else for (var o in e) {
+ if (i < e[o]) {
+ i = t;
+ break
+ }
+ t = e[o]
+ }
+ return i
+ }, e.prototype.cleanUpEvents = function () {
+ var e = this;
+ e.options.dots && null !== e.$dots && (i("li", e.$dots).off("click.slick", e.changeSlide).off("mouseenter.slick", i.proxy(e.interrupt, e, !0)).off("mouseleave.slick", i.proxy(e.interrupt, e, !1)), !0 === e.options.accessibility && e.$dots.off("keydown.slick", e.keyHandler)), e.$slider.off("focus.slick blur.slick"), !0 === e.options.arrows && e.slideCount > e.options.slidesToShow && (e.$prevArrow && e.$prevArrow.off("click.slick", e.changeSlide), e.$nextArrow && e.$nextArrow.off("click.slick", e.changeSlide), !0 === e.options.accessibility && (e.$prevArrow && e.$prevArrow.off("keydown.slick", e.keyHandler), e.$nextArrow && e.$nextArrow.off("keydown.slick", e.keyHandler))), e.$list.off("touchstart.slick mousedown.slick", e.swipeHandler), e.$list.off("touchmove.slick mousemove.slick", e.swipeHandler), e.$list.off("touchend.slick mouseup.slick", e.swipeHandler), e.$list.off("touchcancel.slick mouseleave.slick", e.swipeHandler), e.$list.off("click.slick", e.clickHandler), i(document).off(e.visibilityChange, e.visibility), e.cleanUpSlideEvents(), !0 === e.options.accessibility && e.$list.off("keydown.slick", e.keyHandler), !0 === e.options.focusOnSelect && i(e.$slideTrack).children().off("click.slick", e.selectHandler), i(window).off("orientationchange.slick.slick-" + e.instanceUid, e.orientationChange), i(window).off("resize.slick.slick-" + e.instanceUid, e.resize), i("[draggable!=true]", e.$slideTrack).off("dragstart", e.preventDefault), i(window).off("load.slick.slick-" + e.instanceUid, e.setPosition)
+ }, e.prototype.cleanUpSlideEvents = function () {
+ var e = this;
+ e.$list.off("mouseenter.slick", i.proxy(e.interrupt, e, !0)), e.$list.off("mouseleave.slick", i.proxy(e.interrupt, e, !1))
+ }, e.prototype.cleanUpRows = function () {
+ var i, e = this;
+ e.options.rows > 1 && ((i = e.$slides.children().children()).removeAttr("style"), e.$slider.empty().append(i))
+ }, e.prototype.clickHandler = function (i) {
+ !1 === this.shouldClick && (i.stopImmediatePropagation(), i.stopPropagation(), i.preventDefault())
+ }, e.prototype.destroy = function (e) {
+ var t = this;
+ t.autoPlayClear(), t.touchObject = {}, t.cleanUpEvents(), i(".slick-cloned", t.$slider).detach(), t.$dots && t.$dots.remove(), t.$prevArrow && t.$prevArrow.length && (t.$prevArrow.removeClass("slick-disabled slick-arrow slick-hidden").removeAttr("aria-hidden aria-disabled tabindex").css("display", ""), t.htmlExpr.test(t.options.prevArrow) && t.$prevArrow.remove()), t.$nextArrow && t.$nextArrow.length && (t.$nextArrow.removeClass("slick-disabled slick-arrow slick-hidden").removeAttr("aria-hidden aria-disabled tabindex").css("display", ""), t.htmlExpr.test(t.options.nextArrow) && t.$nextArrow.remove()), t.$slides && (t.$slides.removeClass("slick-slide slick-active slick-center slick-visible slick-current").removeAttr("aria-hidden").removeAttr("data-slick-index").each(function () {
+ i(this).attr("style", i(this).data("originalStyling"))
+ }), t.$slideTrack.children(this.options.slide).detach(), t.$slideTrack.detach(), t.$list.detach(), t.$slider.append(t.$slides)), t.cleanUpRows(), t.$slider.removeClass("slick-slider"), t.$slider.removeClass("slick-initialized"), t.$slider.removeClass("slick-dotted"), t.unslicked = !0, e || t.$slider.trigger("destroy", [t])
+ }, e.prototype.disableTransition = function (i) {
+ var e = this, t = {};
+ t[e.transitionType] = "", !1 === e.options.fade ? e.$slideTrack.css(t) : e.$slides.eq(i).css(t)
+ }, e.prototype.fadeSlide = function (i, e) {
+ var t = this;
+ !1 === t.cssTransitions ? (t.$slides.eq(i).css({zIndex: t.options.zIndex}), t.$slides.eq(i).animate({opacity: 1}, t.options.speed, t.options.easing, e)) : (t.applyTransition(i), t.$slides.eq(i).css({
+ opacity: 1,
+ zIndex: t.options.zIndex
+ }), e && setTimeout(function () {
+ t.disableTransition(i), e.call()
+ }, t.options.speed))
+ }, e.prototype.fadeSlideOut = function (i) {
+ var e = this;
+ !1 === e.cssTransitions ? e.$slides.eq(i).animate({
+ opacity: 0,
+ zIndex: e.options.zIndex - 2
+ }, e.options.speed, e.options.easing) : (e.applyTransition(i), e.$slides.eq(i).css({
+ opacity: 0,
+ zIndex: e.options.zIndex - 2
+ }))
+ }, e.prototype.filterSlides = e.prototype.slickFilter = function (i) {
+ var e = this;
+ null !== i && (e.$slidesCache = e.$slides, e.unload(), e.$slideTrack.children(this.options.slide).detach(), e.$slidesCache.filter(i).appendTo(e.$slideTrack), e.reinit())
+ }, e.prototype.focusHandler = function () {
+ var e = this;
+ e.$slider.off("focus.slick blur.slick").on("focus.slick blur.slick", "*", function (t) {
+ t.stopImmediatePropagation();
+ var o = i(this);
+ setTimeout(function () {
+ e.options.pauseOnFocus && (e.focussed = o.is(":focus"), e.autoPlay())
+ }, 0)
+ })
+ }, e.prototype.getCurrent = e.prototype.slickCurrentSlide = function () {
+ return this.currentSlide
+ }, e.prototype.getDotCount = function () {
+ var i = this, e = 0, t = 0, o = 0;
+ if (!0 === i.options.infinite) if (i.slideCount <= i.options.slidesToShow) ++o; else for (; e < i.slideCount;) ++o, e = t + i.options.slidesToScroll, t += i.options.slidesToScroll <= i.options.slidesToShow ? i.options.slidesToScroll : i.options.slidesToShow; else if (!0 === i.options.centerMode) o = i.slideCount; else if (i.options.asNavFor) for (; e < i.slideCount;) ++o, e = t + i.options.slidesToScroll, t += i.options.slidesToScroll <= i.options.slidesToShow ? i.options.slidesToScroll : i.options.slidesToShow; else o = 1 + Math.ceil((i.slideCount - i.options.slidesToShow) / i.options.slidesToScroll);
+ return o - 1
+ }, e.prototype.getLeft = function (i) {
+ var e, t, o, s, n = this, r = 0;
+ return n.slideOffset = 0, t = n.$slides.first().outerHeight(!0), !0 === n.options.infinite ? (n.slideCount > n.options.slidesToShow && (n.slideOffset = n.slideWidth * n.options.slidesToShow * -1, s = -1, !0 === n.options.vertical && !0 === n.options.centerMode && (2 === n.options.slidesToShow ? s = -1.5 : 1 === n.options.slidesToShow && (s = -2)), r = t * n.options.slidesToShow * s), n.slideCount % n.options.slidesToScroll != 0 && i + n.options.slidesToScroll > n.slideCount && n.slideCount > n.options.slidesToShow && (i > n.slideCount ? (n.slideOffset = (n.options.slidesToShow - (i - n.slideCount)) * n.slideWidth * -1, r = (n.options.slidesToShow - (i - n.slideCount)) * t * -1) : (n.slideOffset = n.slideCount % n.options.slidesToScroll * n.slideWidth * -1, r = n.slideCount % n.options.slidesToScroll * t * -1))) : i + n.options.slidesToShow > n.slideCount && (n.slideOffset = (i + n.options.slidesToShow - n.slideCount) * n.slideWidth, r = (i + n.options.slidesToShow - n.slideCount) * t), n.slideCount <= n.options.slidesToShow && (n.slideOffset = 0, r = 0), !0 === n.options.centerMode && n.slideCount <= n.options.slidesToShow ? n.slideOffset = n.slideWidth * Math.floor(n.options.slidesToShow) / 2 - n.slideWidth * n.slideCount / 2 : !0 === n.options.centerMode && !0 === n.options.infinite ? n.slideOffset += n.slideWidth * Math.floor(n.options.slidesToShow / 2) - n.slideWidth : !0 === n.options.centerMode && (n.slideOffset = 0, n.slideOffset += n.slideWidth * Math.floor(n.options.slidesToShow / 2)), e = !1 === n.options.vertical ? i * n.slideWidth * -1 + n.slideOffset : i * t * -1 + r, !0 === n.options.variableWidth && (o = n.slideCount <= n.options.slidesToShow || !1 === n.options.infinite ? n.$slideTrack.children(".slick-slide").eq(i) : n.$slideTrack.children(".slick-slide").eq(i + n.options.slidesToShow), e = !0 === n.options.rtl ? o[0] ? -1 * (n.$slideTrack.width() - o[0].offsetLeft - o.width()) : 0 : o[0] ? -1 * o[0].offsetLeft : 0, !0 === n.options.centerMode && (o = n.slideCount <= n.options.slidesToShow || !1 === n.options.infinite ? n.$slideTrack.children(".slick-slide").eq(i) : n.$slideTrack.children(".slick-slide").eq(i + n.options.slidesToShow + 1), e = !0 === n.options.rtl ? o[0] ? -1 * (n.$slideTrack.width() - o[0].offsetLeft - o.width()) : 0 : o[0] ? -1 * o[0].offsetLeft : 0, e += (n.$list.width() - o.outerWidth()) / 2)), e
+ }, e.prototype.getOption = e.prototype.slickGetOption = function (i) {
+ return this.options[i]
+ }, e.prototype.getNavigableIndexes = function () {
+ var i, e = this, t = 0, o = 0, s = [];
+ for (!1 === e.options.infinite ? i = e.slideCount : (t = -1 * e.options.slidesToScroll, o = -1 * e.options.slidesToScroll, i = 2 * e.slideCount); t < i;) s.push(t), t = o + e.options.slidesToScroll, o += e.options.slidesToScroll <= e.options.slidesToShow ? e.options.slidesToScroll : e.options.slidesToShow;
+ return s
+ }, e.prototype.getSlick = function () {
+ return this
+ }, e.prototype.getSlideCount = function () {
+ var e, t, o = this;
+ return t = !0 === o.options.centerMode ? o.slideWidth * Math.floor(o.options.slidesToShow / 2) : 0, !0 === o.options.swipeToSlide ? (o.$slideTrack.find(".slick-slide").each(function (s, n) {
+ if (n.offsetLeft - t + i(n).outerWidth() / 2 > -1 * o.swipeLeft) return e = n, !1
+ }), Math.abs(i(e).attr("data-slick-index") - o.currentSlide) || 1) : o.options.slidesToScroll
+ }, e.prototype.goTo = e.prototype.slickGoTo = function (i, e) {
+ this.changeSlide({data: {message: "index", index: parseInt(i)}}, e)
+ }, e.prototype.init = function (e) {
+ var t = this;
+ i(t.$slider).hasClass("slick-initialized") || (i(t.$slider).addClass("slick-initialized"), t.buildRows(), t.buildOut(), t.setProps(), t.startLoad(), t.loadSlider(), t.initializeEvents(), t.updateArrows(), t.updateDots(), t.checkResponsive(!0), t.focusHandler()), e && t.$slider.trigger("init", [t]), !0 === t.options.accessibility && t.initADA(), t.options.autoplay && (t.paused = !1, t.autoPlay())
+ }, e.prototype.initADA = function () {
+ var e = this, t = Math.ceil(e.slideCount / e.options.slidesToShow),
+ o = e.getNavigableIndexes().filter(function (i) {
+ return i >= 0 && i < e.slideCount
+ });
+ e.$slides.add(e.$slideTrack.find(".slick-cloned")).attr({
+ "aria-hidden": "true",
+ tabindex: "-1"
+ }).find("a, input, button, select").attr({tabindex: "-1"}), null !== e.$dots && (e.$slides.not(e.$slideTrack.find(".slick-cloned")).each(function (t) {
+ var s = o.indexOf(t);
+ i(this).attr({
+ role: "tabpanel",
+ id: "slick-slide" + e.instanceUid + t,
+ tabindex: -1
+ }), -1 !== s && i(this).attr({"aria-describedby": "slick-slide-control" + e.instanceUid + s})
+ }), e.$dots.attr("role", "tablist").find("li").each(function (s) {
+ var n = o[s];
+ i(this).attr({role: "presentation"}), i(this).find("button").first().attr({
+ role: "tab",
+ id: "slick-slide-control" + e.instanceUid + s,
+ "aria-controls": "slick-slide" + e.instanceUid + n,
+ "aria-label": s + 1 + " of " + t,
+ "aria-selected": null,
+ tabindex: "-1"
+ })
+ }).eq(e.currentSlide).find("button").attr({"aria-selected": "true", tabindex: "0"}).end());
+ for (var s = e.currentSlide, n = s + e.options.slidesToShow; s < n; s++) e.$slides.eq(s).attr("tabindex", 0);
+ e.activateADA()
+ }, e.prototype.initArrowEvents = function () {
+ var i = this;
+ !0 === i.options.arrows && i.slideCount > i.options.slidesToShow && (i.$prevArrow.off("click.slick").on("click.slick", {message: "previous"}, i.changeSlide), i.$nextArrow.off("click.slick").on("click.slick", {message: "next"}, i.changeSlide), !0 === i.options.accessibility && (i.$prevArrow.on("keydown.slick", i.keyHandler), i.$nextArrow.on("keydown.slick", i.keyHandler)))
+ }, e.prototype.initDotEvents = function () {
+ var e = this;
+ !0 === e.options.dots && (i("li", e.$dots).on("click.slick", {message: "index"}, e.changeSlide), !0 === e.options.accessibility && e.$dots.on("keydown.slick", e.keyHandler)), !0 === e.options.dots && !0 === e.options.pauseOnDotsHover && i("li", e.$dots).on("mouseenter.slick", i.proxy(e.interrupt, e, !0)).on("mouseleave.slick", i.proxy(e.interrupt, e, !1))
+ }, e.prototype.initSlideEvents = function () {
+ var e = this;
+ e.options.pauseOnHover && (e.$list.on("mouseenter.slick", i.proxy(e.interrupt, e, !0)), e.$list.on("mouseleave.slick", i.proxy(e.interrupt, e, !1)))
+ }, e.prototype.initializeEvents = function () {
+ var e = this;
+ e.initArrowEvents(), e.initDotEvents(), e.initSlideEvents(), e.$list.on("touchstart.slick mousedown.slick", {action: "start"}, e.swipeHandler), e.$list.on("touchmove.slick mousemove.slick", {action: "move"}, e.swipeHandler), e.$list.on("touchend.slick mouseup.slick", {action: "end"}, e.swipeHandler), e.$list.on("touchcancel.slick mouseleave.slick", {action: "end"}, e.swipeHandler), e.$list.on("click.slick", e.clickHandler), i(document).on(e.visibilityChange, i.proxy(e.visibility, e)), !0 === e.options.accessibility && e.$list.on("keydown.slick", e.keyHandler), !0 === e.options.focusOnSelect && i(e.$slideTrack).children().on("click.slick", e.selectHandler), i(window).on("orientationchange.slick.slick-" + e.instanceUid, i.proxy(e.orientationChange, e)), i(window).on("resize.slick.slick-" + e.instanceUid, i.proxy(e.resize, e)), i("[draggable!=true]", e.$slideTrack).on("dragstart", e.preventDefault), i(window).on("load.slick.slick-" + e.instanceUid, e.setPosition), i(e.setPosition)
+ }, e.prototype.initUI = function () {
+ var i = this;
+ !0 === i.options.arrows && i.slideCount > i.options.slidesToShow && (i.$prevArrow.show(), i.$nextArrow.show()), !0 === i.options.dots && i.slideCount > i.options.slidesToShow && i.$dots.show()
+ }, e.prototype.keyHandler = function (i) {
+ var e = this;
+ i.target.tagName.match("TEXTAREA|INPUT|SELECT") || (37 === i.keyCode && !0 === e.options.accessibility ? e.changeSlide({data: {message: !0 === e.options.rtl ? "next" : "previous"}}) : 39 === i.keyCode && !0 === e.options.accessibility && e.changeSlide({data: {message: !0 === e.options.rtl ? "previous" : "next"}}))
+ }, e.prototype.lazyLoad = function () {
+ function e(e) {
+ i("img[data-lazy]", e).each(function () {
+ var e = i(this), t = i(this).attr("data-lazy"), o = i(this).attr("data-srcset"),
+ s = i(this).attr("data-sizes") || n.$slider.attr("data-sizes"), r = document.createElement("img");
+ r.onload = function () {
+ e.animate({opacity: 0}, 100, function () {
+ o && (e.attr("srcset", o), s && e.attr("sizes", s)), e.attr("src", t).animate({opacity: 1}, 200, function () {
+ e.removeAttr("data-lazy data-srcset data-sizes").removeClass("slick-loading")
+ }), n.$slider.trigger("lazyLoaded", [n, e, t])
+ })
+ }, r.onerror = function () {
+ e.removeAttr("data-lazy").removeClass("slick-loading").addClass("slick-lazyload-error"), n.$slider.trigger("lazyLoadError", [n, e, t])
+ }, r.src = t
+ })
+ }
+
+ var t, o, s, n = this;
+ if (!0 === n.options.centerMode ? !0 === n.options.infinite ? s = (o = n.currentSlide + (n.options.slidesToShow / 2 + 1)) + n.options.slidesToShow + 2 : (o = Math.max(0, n.currentSlide - (n.options.slidesToShow / 2 + 1)), s = n.options.slidesToShow / 2 + 1 + 2 + n.currentSlide) : (o = n.options.infinite ? n.options.slidesToShow + n.currentSlide : n.currentSlide, s = Math.ceil(o + n.options.slidesToShow), !0 === n.options.fade && (o > 0 && o--, s <= n.slideCount && s++)), t = n.$slider.find(".slick-slide").slice(o, s), "anticipated" === n.options.lazyLoad) for (var r = o - 1, l = s, d = n.$slider.find(".slick-slide"), a = 0; a < n.options.slidesToScroll; a++) r < 0 && (r = n.slideCount - 1), t = (t = t.add(d.eq(r))).add(d.eq(l)), r--, l++;
+ e(t), n.slideCount <= n.options.slidesToShow ? e(n.$slider.find(".slick-slide")) : n.currentSlide >= n.slideCount - n.options.slidesToShow ? e(n.$slider.find(".slick-cloned").slice(0, n.options.slidesToShow)) : 0 === n.currentSlide && e(n.$slider.find(".slick-cloned").slice(-1 * n.options.slidesToShow))
+ }, e.prototype.loadSlider = function () {
+ var i = this;
+ i.setPosition(), i.$slideTrack.css({opacity: 1}), i.$slider.removeClass("slick-loading"), i.initUI(), "progressive" === i.options.lazyLoad && i.progressiveLazyLoad()
+ }, e.prototype.next = e.prototype.slickNext = function () {
+ this.changeSlide({data: {message: "next"}})
+ }, e.prototype.orientationChange = function () {
+ var i = this;
+ i.checkResponsive(), i.setPosition()
+ }, e.prototype.pause = e.prototype.slickPause = function () {
+ var i = this;
+ i.autoPlayClear(), i.paused = !0
+ }, e.prototype.play = e.prototype.slickPlay = function () {
+ var i = this;
+ i.autoPlay(), i.options.autoplay = !0, i.paused = !1, i.focussed = !1, i.interrupted = !1
+ }, e.prototype.postSlide = function (e) {
+ var t = this;
+ t.unslicked || (t.$slider.trigger("afterChange", [t, e]), t.animating = !1, t.slideCount > t.options.slidesToShow && t.setPosition(), t.swipeLeft = null, t.options.autoplay && t.autoPlay(), !0 === t.options.accessibility && (t.initADA(), t.options.focusOnChange && i(t.$slides.get(t.currentSlide)).attr("tabindex", 0).focus()))
+ }, e.prototype.prev = e.prototype.slickPrev = function () {
+ this.changeSlide({data: {message: "previous"}})
+ }, e.prototype.preventDefault = function (i) {
+ i.preventDefault()
+ }, e.prototype.progressiveLazyLoad = function (e) {
+ e = e || 1;
+ var t, o, s, n, r, l = this, d = i("img[data-lazy]", l.$slider);
+ d.length ? (t = d.first(), o = t.attr("data-lazy"), s = t.attr("data-srcset"), n = t.attr("data-sizes") || l.$slider.attr("data-sizes"), (r = document.createElement("img")).onload = function () {
+ s && (t.attr("srcset", s), n && t.attr("sizes", n)), t.attr("src", o).removeAttr("data-lazy data-srcset data-sizes").removeClass("slick-loading"), !0 === l.options.adaptiveHeight && l.setPosition(), l.$slider.trigger("lazyLoaded", [l, t, o]), l.progressiveLazyLoad()
+ }, r.onerror = function () {
+ e < 3 ? setTimeout(function () {
+ l.progressiveLazyLoad(e + 1)
+ }, 500) : (t.removeAttr("data-lazy").removeClass("slick-loading").addClass("slick-lazyload-error"), l.$slider.trigger("lazyLoadError", [l, t, o]), l.progressiveLazyLoad())
+ }, r.src = o) : l.$slider.trigger("allImagesLoaded", [l])
+ }, e.prototype.refresh = function (e) {
+ var t, o, s = this;
+ o = s.slideCount - s.options.slidesToShow, !s.options.infinite && s.currentSlide > o && (s.currentSlide = o), s.slideCount <= s.options.slidesToShow && (s.currentSlide = 0), t = s.currentSlide, s.destroy(!0), i.extend(s, s.initials, {currentSlide: t}), s.init(), e || s.changeSlide({
+ data: {
+ message: "index",
+ index: t
+ }
+ }, !1)
+ }, e.prototype.registerBreakpoints = function () {
+ var e, t, o, s = this, n = s.options.responsive || null;
+ if ("array" === i.type(n) && n.length) {
+ s.respondTo = s.options.respondTo || "window";
+ for (e in n) if (o = s.breakpoints.length - 1, n.hasOwnProperty(e)) {
+ for (t = n[e].breakpoint; o >= 0;) s.breakpoints[o] && s.breakpoints[o] === t && s.breakpoints.splice(o, 1), o--;
+ s.breakpoints.push(t), s.breakpointSettings[t] = n[e].settings
+ }
+ s.breakpoints.sort(function (i, e) {
+ return s.options.mobileFirst ? i - e : e - i
+ })
+ }
+ }, e.prototype.reinit = function () {
+ var e = this;
+ e.$slides = e.$slideTrack.children(e.options.slide).addClass("slick-slide"), e.slideCount = e.$slides.length, e.currentSlide >= e.slideCount && 0 !== e.currentSlide && (e.currentSlide = e.currentSlide - e.options.slidesToScroll), e.slideCount <= e.options.slidesToShow && (e.currentSlide = 0), e.registerBreakpoints(), e.setProps(), e.setupInfinite(), e.buildArrows(), e.updateArrows(), e.initArrowEvents(), e.buildDots(), e.updateDots(), e.initDotEvents(), e.cleanUpSlideEvents(), e.initSlideEvents(), e.checkResponsive(!1, !0), !0 === e.options.focusOnSelect && i(e.$slideTrack).children().on("click.slick", e.selectHandler), e.setSlideClasses("number" == typeof e.currentSlide ? e.currentSlide : 0), e.setPosition(), e.focusHandler(), e.paused = !e.options.autoplay, e.autoPlay(), e.$slider.trigger("reInit", [e])
+ }, e.prototype.resize = function () {
+ var e = this;
+ i(window).width() !== e.windowWidth && (clearTimeout(e.windowDelay), e.windowDelay = window.setTimeout(function () {
+ e.windowWidth = i(window).width(), e.checkResponsive(), e.unslicked || e.setPosition()
+ }, 50))
+ }, e.prototype.removeSlide = e.prototype.slickRemove = function (i, e, t) {
+ var o = this;
+ if (i = "boolean" == typeof i ? !0 === (e = i) ? 0 : o.slideCount - 1 : !0 === e ? --i : i, o.slideCount < 1 || i < 0 || i > o.slideCount - 1) return !1;
+ o.unload(), !0 === t ? o.$slideTrack.children().remove() : o.$slideTrack.children(this.options.slide).eq(i).remove(), o.$slides = o.$slideTrack.children(this.options.slide), o.$slideTrack.children(this.options.slide).detach(), o.$slideTrack.append(o.$slides), o.$slidesCache = o.$slides, o.reinit()
+ }, e.prototype.setCSS = function (i) {
+ var e, t, o = this, s = {};
+ !0 === o.options.rtl && (i = -i), e = "left" == o.positionProp ? Math.ceil(i) + "px" : "0px", t = "top" == o.positionProp ? Math.ceil(i) + "px" : "0px", s[o.positionProp] = i, !1 === o.transformsEnabled ? o.$slideTrack.css(s) : (s = {}, !1 === o.cssTransitions ? (s[o.animType] = "translate(" + e + ", " + t + ")", o.$slideTrack.css(s)) : (s[o.animType] = "translate3d(" + e + ", " + t + ", 0px)", o.$slideTrack.css(s)))
+ }, e.prototype.setDimensions = function () {
+ var i = this;
+ !1 === i.options.vertical ? !0 === i.options.centerMode && i.$list.css({padding: "0px " + i.options.centerPadding}) : (i.$list.height(i.$slides.first().outerHeight(!0) * i.options.slidesToShow), !0 === i.options.centerMode && i.$list.css({padding: i.options.centerPadding + " 0px"})), i.listWidth = i.$list.width(), i.listHeight = i.$list.height(), !1 === i.options.vertical && !1 === i.options.variableWidth ? (i.slideWidth = Math.ceil(i.listWidth / i.options.slidesToShow), i.$slideTrack.width(Math.ceil(i.slideWidth * i.$slideTrack.children(".slick-slide").length))) : !0 === i.options.variableWidth ? i.$slideTrack.width(5e3 * i.slideCount) : (i.slideWidth = Math.ceil(i.listWidth), i.$slideTrack.height(Math.ceil(i.$slides.first().outerHeight(!0) * i.$slideTrack.children(".slick-slide").length)));
+ var e = i.$slides.first().outerWidth(!0) - i.$slides.first().width();
+ !1 === i.options.variableWidth && i.$slideTrack.children(".slick-slide").width(i.slideWidth - e)
+ }, e.prototype.setFade = function () {
+ var e, t = this;
+ t.$slides.each(function (o, s) {
+ e = t.slideWidth * o * -1, !0 === t.options.rtl ? i(s).css({
+ position: "relative",
+ right: e,
+ top: 0,
+ zIndex: t.options.zIndex - 2,
+ opacity: 0
+ }) : i(s).css({position: "relative", left: e, top: 0, zIndex: t.options.zIndex - 2, opacity: 0})
+ }), t.$slides.eq(t.currentSlide).css({zIndex: t.options.zIndex - 1, opacity: 1})
+ }, e.prototype.setHeight = function () {
+ var i = this;
+ if (1 === i.options.slidesToShow && !0 === i.options.adaptiveHeight && !1 === i.options.vertical) {
+ var e = i.$slides.eq(i.currentSlide).outerHeight(!0);
+ i.$list.css("height", e)
+ }
+ }, e.prototype.setOption = e.prototype.slickSetOption = function () {
+ var e, t, o, s, n, r = this, l = !1;
+ if ("object" === i.type(arguments[0]) ? (o = arguments[0], l = arguments[1], n = "multiple") : "string" === i.type(arguments[0]) && (o = arguments[0], s = arguments[1], l = arguments[2], "responsive" === arguments[0] && "array" === i.type(arguments[1]) ? n = "responsive" : void 0 !== arguments[1] && (n = "single")), "single" === n) r.options[o] = s; else if ("multiple" === n) i.each(o, function (i, e) {
+ r.options[i] = e
+ }); else if ("responsive" === n) for (t in s) if ("array" !== i.type(r.options.responsive)) r.options.responsive = [s[t]]; else {
+ for (e = r.options.responsive.length - 1; e >= 0;) r.options.responsive[e].breakpoint === s[t].breakpoint && r.options.responsive.splice(e, 1), e--;
+ r.options.responsive.push(s[t])
+ }
+ l && (r.unload(), r.reinit())
+ }, e.prototype.setPosition = function () {
+ var i = this;
+ i.setDimensions(), i.setHeight(), !1 === i.options.fade ? i.setCSS(i.getLeft(i.currentSlide)) : i.setFade(), i.$slider.trigger("setPosition", [i])
+ }, e.prototype.setProps = function () {
+ var i = this, e = document.body.style;
+ i.positionProp = !0 === i.options.vertical ? "top" : "left", "top" === i.positionProp ? i.$slider.addClass("slick-vertical") : i.$slider.removeClass("slick-vertical"), void 0 === e.WebkitTransition && void 0 === e.MozTransition && void 0 === e.msTransition || !0 === i.options.useCSS && (i.cssTransitions = !0), i.options.fade && ("number" == typeof i.options.zIndex ? i.options.zIndex < 3 && (i.options.zIndex = 3) : i.options.zIndex = i.defaults.zIndex), void 0 !== e.OTransform && (i.animType = "OTransform", i.transformType = "-o-transform", i.transitionType = "OTransition", void 0 === e.perspectiveProperty && void 0 === e.webkitPerspective && (i.animType = !1)), void 0 !== e.MozTransform && (i.animType = "MozTransform", i.transformType = "-moz-transform", i.transitionType = "MozTransition", void 0 === e.perspectiveProperty && void 0 === e.MozPerspective && (i.animType = !1)), void 0 !== e.webkitTransform && (i.animType = "webkitTransform", i.transformType = "-webkit-transform", i.transitionType = "webkitTransition", void 0 === e.perspectiveProperty && void 0 === e.webkitPerspective && (i.animType = !1)), void 0 !== e.msTransform && (i.animType = "msTransform", i.transformType = "-ms-transform", i.transitionType = "msTransition", void 0 === e.msTransform && (i.animType = !1)), void 0 !== e.transform && !1 !== i.animType && (i.animType = "transform", i.transformType = "transform", i.transitionType = "transition"), i.transformsEnabled = i.options.useTransform && null !== i.animType && !1 !== i.animType
+ }, e.prototype.setSlideClasses = function (i) {
+ var e, t, o, s, n = this;
+ if (t = n.$slider.find(".slick-slide").removeClass("slick-active slick-center slick-current").attr("aria-hidden", "true"), n.$slides.eq(i).addClass("slick-current"), !0 === n.options.centerMode) {
+ var r = n.options.slidesToShow % 2 == 0 ? 1 : 0;
+ e = Math.floor(n.options.slidesToShow / 2), !0 === n.options.infinite && (i >= e && i <= n.slideCount - 1 - e ? n.$slides.slice(i - e + r, i + e + 1).addClass("slick-active").attr("aria-hidden", "false") : (o = n.options.slidesToShow + i, t.slice(o - e + 1 + r, o + e + 2).addClass("slick-active").attr("aria-hidden", "false")), 0 === i ? t.eq(t.length - 1 - n.options.slidesToShow).addClass("slick-center") : i === n.slideCount - 1 && t.eq(n.options.slidesToShow).addClass("slick-center")), n.$slides.eq(i).addClass("slick-center")
+ } else i >= 0 && i <= n.slideCount - n.options.slidesToShow ? n.$slides.slice(i, i + n.options.slidesToShow).addClass("slick-active").attr("aria-hidden", "false") : t.length <= n.options.slidesToShow ? t.addClass("slick-active").attr("aria-hidden", "false") : (s = n.slideCount % n.options.slidesToShow, o = !0 === n.options.infinite ? n.options.slidesToShow + i : i, n.options.slidesToShow == n.options.slidesToScroll && n.slideCount - i < n.options.slidesToShow ? t.slice(o - (n.options.slidesToShow - s), o + s).addClass("slick-active").attr("aria-hidden", "false") : t.slice(o, o + n.options.slidesToShow).addClass("slick-active").attr("aria-hidden", "false"));
+ "ondemand" !== n.options.lazyLoad && "anticipated" !== n.options.lazyLoad || n.lazyLoad()
+ }, e.prototype.setupInfinite = function () {
+ var e, t, o, s = this;
+ if (!0 === s.options.fade && (s.options.centerMode = !1), !0 === s.options.infinite && !1 === s.options.fade && (t = null, s.slideCount > s.options.slidesToShow)) {
+ for (o = !0 === s.options.centerMode ? s.options.slidesToShow + 1 : s.options.slidesToShow, e = s.slideCount; e > s.slideCount - o; e -= 1) t = e - 1, i(s.$slides[t]).clone(!0).attr("id", "").attr("data-slick-index", t - s.slideCount).prependTo(s.$slideTrack).addClass("slick-cloned");
+ for (e = 0; e < o + s.slideCount; e += 1) t = e, i(s.$slides[t]).clone(!0).attr("id", "").attr("data-slick-index", t + s.slideCount).appendTo(s.$slideTrack).addClass("slick-cloned");
+ s.$slideTrack.find(".slick-cloned").find("[id]").each(function () {
+ i(this).attr("id", "")
+ })
+ }
+ }, e.prototype.interrupt = function (i) {
+ var e = this;
+ i || e.autoPlay(), e.interrupted = i
+ }, e.prototype.selectHandler = function (e) {
+ var t = this, o = i(e.target).is(".slick-slide") ? i(e.target) : i(e.target).parents(".slick-slide"),
+ s = parseInt(o.attr("data-slick-index"));
+ s || (s = 0), t.slideCount <= t.options.slidesToShow ? t.slideHandler(s, !1, !0) : t.slideHandler(s)
+ }, e.prototype.slideHandler = function (i, e, t) {
+ var o, s, n, r, l, d = null, a = this;
+ if (e = e || !1, !(!0 === a.animating && !0 === a.options.waitForAnimate || !0 === a.options.fade && a.currentSlide === i)) if (!1 === e && a.asNavFor(i), o = i, d = a.getLeft(o), r = a.getLeft(a.currentSlide), a.currentLeft = null === a.swipeLeft ? r : a.swipeLeft, !1 === a.options.infinite && !1 === a.options.centerMode && (i < 0 || i > a.getDotCount() * a.options.slidesToScroll)) !1 === a.options.fade && (o = a.currentSlide, !0 !== t ? a.animateSlide(r, function () {
+ a.postSlide(o)
+ }) : a.postSlide(o)); else if (!1 === a.options.infinite && !0 === a.options.centerMode && (i < 0 || i > a.slideCount - a.options.slidesToScroll)) !1 === a.options.fade && (o = a.currentSlide, !0 !== t ? a.animateSlide(r, function () {
+ a.postSlide(o)
+ }) : a.postSlide(o)); else {
+ if (a.options.autoplay && clearInterval(a.autoPlayTimer), s = o < 0 ? a.slideCount % a.options.slidesToScroll != 0 ? a.slideCount - a.slideCount % a.options.slidesToScroll : a.slideCount + o : o >= a.slideCount ? a.slideCount % a.options.slidesToScroll != 0 ? 0 : o - a.slideCount : o, a.animating = !0, a.$slider.trigger("beforeChange", [a, a.currentSlide, s]), n = a.currentSlide, a.currentSlide = s, a.setSlideClasses(a.currentSlide), a.options.asNavFor && (l = (l = a.getNavTarget()).slick("getSlick")).slideCount <= l.options.slidesToShow && l.setSlideClasses(a.currentSlide), a.updateDots(), a.updateArrows(), !0 === a.options.fade) return !0 !== t ? (a.fadeSlideOut(n), a.fadeSlide(s, function () {
+ a.postSlide(s)
+ })) : a.postSlide(s), void a.animateHeight();
+ !0 !== t ? a.animateSlide(d, function () {
+ a.postSlide(s)
+ }) : a.postSlide(s)
+ }
+ }, e.prototype.startLoad = function () {
+ var i = this;
+ !0 === i.options.arrows && i.slideCount > i.options.slidesToShow && (i.$prevArrow.hide(), i.$nextArrow.hide()), !0 === i.options.dots && i.slideCount > i.options.slidesToShow && i.$dots.hide(), i.$slider.addClass("slick-loading")
+ }, e.prototype.swipeDirection = function () {
+ var i, e, t, o, s = this;
+ return i = s.touchObject.startX - s.touchObject.curX, e = s.touchObject.startY - s.touchObject.curY, t = Math.atan2(e, i), (o = Math.round(180 * t / Math.PI)) < 0 && (o = 360 - Math.abs(o)), o <= 45 && o >= 0 ? !1 === s.options.rtl ? "left" : "right" : o <= 360 && o >= 315 ? !1 === s.options.rtl ? "left" : "right" : o >= 135 && o <= 225 ? !1 === s.options.rtl ? "right" : "left" : !0 === s.options.verticalSwiping ? o >= 35 && o <= 135 ? "down" : "up" : "vertical"
+ }, e.prototype.swipeEnd = function (i) {
+ var e, t, o = this;
+ if (o.dragging = !1, o.swiping = !1, o.scrolling) return o.scrolling = !1, !1;
+ if (o.interrupted = !1, o.shouldClick = !(o.touchObject.swipeLength > 10), void 0 === o.touchObject.curX) return !1;
+ if (!0 === o.touchObject.edgeHit && o.$slider.trigger("edge", [o, o.swipeDirection()]), o.touchObject.swipeLength >= o.touchObject.minSwipe) {
+ switch (t = o.swipeDirection()) {
+ case"left":
+ case"down":
+ e = o.options.swipeToSlide ? o.checkNavigable(o.currentSlide + o.getSlideCount()) : o.currentSlide + o.getSlideCount(), o.currentDirection = 0;
+ break;
+ case"right":
+ case"up":
+ e = o.options.swipeToSlide ? o.checkNavigable(o.currentSlide - o.getSlideCount()) : o.currentSlide - o.getSlideCount(), o.currentDirection = 1
+ }
+ "vertical" != t && (o.slideHandler(e), o.touchObject = {}, o.$slider.trigger("swipe", [o, t]))
+ } else o.touchObject.startX !== o.touchObject.curX && (o.slideHandler(o.currentSlide), o.touchObject = {})
+ }, e.prototype.swipeHandler = function (i) {
+ var e = this;
+ if (!(!1 === e.options.swipe || "ontouchend" in document && !1 === e.options.swipe || !1 === e.options.draggable && -1 !== i.type.indexOf("mouse"))) switch (e.touchObject.fingerCount = i.originalEvent && void 0 !== i.originalEvent.touches ? i.originalEvent.touches.length : 1, e.touchObject.minSwipe = e.listWidth / e.options.touchThreshold, !0 === e.options.verticalSwiping && (e.touchObject.minSwipe = e.listHeight / e.options.touchThreshold), i.data.action) {
+ case"start":
+ e.swipeStart(i);
+ break;
+ case"move":
+ e.swipeMove(i);
+ break;
+ case"end":
+ e.swipeEnd(i)
+ }
+ }, e.prototype.swipeMove = function (i) {
+ var e, t, o, s, n, r, l = this;
+ return n = void 0 !== i.originalEvent ? i.originalEvent.touches : null, !(!l.dragging || l.scrolling || n && 1 !== n.length) && (e = l.getLeft(l.currentSlide), l.touchObject.curX = void 0 !== n ? n[0].pageX : i.clientX, l.touchObject.curY = void 0 !== n ? n[0].pageY : i.clientY, l.touchObject.swipeLength = Math.round(Math.sqrt(Math.pow(l.touchObject.curX - l.touchObject.startX, 2))), r = Math.round(Math.sqrt(Math.pow(l.touchObject.curY - l.touchObject.startY, 2))), !l.options.verticalSwiping && !l.swiping && r > 4 ? (l.scrolling = !0, !1) : (!0 === l.options.verticalSwiping && (l.touchObject.swipeLength = r), t = l.swipeDirection(), void 0 !== i.originalEvent && l.touchObject.swipeLength > 4 && (l.swiping = !0, i.preventDefault()), s = (!1 === l.options.rtl ? 1 : -1) * (l.touchObject.curX > l.touchObject.startX ? 1 : -1), !0 === l.options.verticalSwiping && (s = l.touchObject.curY > l.touchObject.startY ? 1 : -1), o = l.touchObject.swipeLength, l.touchObject.edgeHit = !1, !1 === l.options.infinite && (0 === l.currentSlide && "right" === t || l.currentSlide >= l.getDotCount() && "left" === t) && (o = l.touchObject.swipeLength * l.options.edgeFriction, l.touchObject.edgeHit = !0), !1 === l.options.vertical ? l.swipeLeft = e + o * s : l.swipeLeft = e + o * (l.$list.height() / l.listWidth) * s, !0 === l.options.verticalSwiping && (l.swipeLeft = e + o * s), !0 !== l.options.fade && !1 !== l.options.touchMove && (!0 === l.animating ? (l.swipeLeft = null, !1) : void l.setCSS(l.swipeLeft))))
+ }, e.prototype.swipeStart = function (i) {
+ var e, t = this;
+ if (t.interrupted = !0, 1 !== t.touchObject.fingerCount || t.slideCount <= t.options.slidesToShow) return t.touchObject = {}, !1;
+ void 0 !== i.originalEvent && void 0 !== i.originalEvent.touches && (e = i.originalEvent.touches[0]), t.touchObject.startX = t.touchObject.curX = void 0 !== e ? e.pageX : i.clientX, t.touchObject.startY = t.touchObject.curY = void 0 !== e ? e.pageY : i.clientY, t.dragging = !0
+ }, e.prototype.unfilterSlides = e.prototype.slickUnfilter = function () {
+ var i = this;
+ null !== i.$slidesCache && (i.unload(), i.$slideTrack.children(this.options.slide).detach(), i.$slidesCache.appendTo(i.$slideTrack), i.reinit())
+ }, e.prototype.unload = function () {
+ var e = this;
+ i(".slick-cloned", e.$slider).remove(), e.$dots && e.$dots.remove(), e.$prevArrow && e.htmlExpr.test(e.options.prevArrow) && e.$prevArrow.remove(), e.$nextArrow && e.htmlExpr.test(e.options.nextArrow) && e.$nextArrow.remove(), e.$slides.removeClass("slick-slide slick-active slick-visible slick-current").attr("aria-hidden", "true").css("width", "")
+ }, e.prototype.unslick = function (i) {
+ var e = this;
+ e.$slider.trigger("unslick", [e, i]), e.destroy()
+ }, e.prototype.updateArrows = function () {
+ var i = this;
+ Math.floor(i.options.slidesToShow / 2), !0 === i.options.arrows && i.slideCount > i.options.slidesToShow && !i.options.infinite && (i.$prevArrow.removeClass("slick-disabled").attr("aria-disabled", "false"), i.$nextArrow.removeClass("slick-disabled").attr("aria-disabled", "false"), 0 === i.currentSlide ? (i.$prevArrow.addClass("slick-disabled").attr("aria-disabled", "true"), i.$nextArrow.removeClass("slick-disabled").attr("aria-disabled", "false")) : i.currentSlide >= i.slideCount - i.options.slidesToShow && !1 === i.options.centerMode ? (i.$nextArrow.addClass("slick-disabled").attr("aria-disabled", "true"), i.$prevArrow.removeClass("slick-disabled").attr("aria-disabled", "false")) : i.currentSlide >= i.slideCount - 1 && !0 === i.options.centerMode && (i.$nextArrow.addClass("slick-disabled").attr("aria-disabled", "true"), i.$prevArrow.removeClass("slick-disabled").attr("aria-disabled", "false")))
+ }, e.prototype.updateDots = function () {
+ var i = this;
+ null !== i.$dots && (i.$dots.find("li").removeClass("slick-active").end(), i.$dots.find("li").eq(Math.floor(i.currentSlide / i.options.slidesToScroll)).addClass("slick-active"))
+ }, e.prototype.visibility = function () {
+ var i = this;
+ i.options.autoplay && (document[i.hidden] ? i.interrupted = !0 : i.interrupted = !1)
+ }, i.fn.slick = function () {
+ var i, t, o = this, s = arguments[0], n = Array.prototype.slice.call(arguments, 1), r = o.length;
+ for (i = 0; i < r; i++) if ("object" == typeof s || void 0 === s ? o[i].slick = new e(o[i], s) : t = o[i].slick[s].apply(o[i].slick, n), void 0 !== t) return t;
+ return o
+ }
+}); \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/languages/ExcelFile.xls b/main/app/sprinkles/core/assets/SiteAssets/languages/ExcelFile.xls
new file mode 100644
index 0000000..ffc5552
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/languages/ExcelFile.xls
Binary files differ
diff --git a/main/app/sprinkles/core/assets/SiteAssets/languages/json/Translations.json b/main/app/sprinkles/core/assets/SiteAssets/languages/json/Translations.json
new file mode 100644
index 0000000..3406ffb
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/languages/json/Translations.json
@@ -0,0 +1,50 @@
+{
+ "en": {
+ "Translator": "Marvin Borner",
+ "you": "you",
+ "Feed": "New",
+ "Explore": "Explore",
+ "Chat": "Chat",
+ "Friends": "Friends",
+ "Personal": "Personal",
+ "joined the group": "joined the group",
+ "You joined the group": "You joined the group",
+ "has disconnected from the server": "has disconnected from the server"
+ },
+ "de": {
+ "Translator": "Marvin Borner",
+ "you": "du",
+ "Feed": "Neues",
+ "Explore": "Entdecken",
+ "Chat": "Nachrichten",
+ "Friends": "Freunde",
+ "Personal": "Persönliche Daten",
+ "joined the group": "ist der Gruppe beigetreten",
+ "You joined the group": "Du bist der Gruppe beigetreten",
+ "has disconnected from the server": "hat sich vom Server getrennt"
+ },
+ "fr": {
+ "Translator": "Marvin Borner (non-french)",
+ "you": "vous",
+ "Feed": "D'actualités",
+ "Explore": "Dépister",
+ "Chat": "Message",
+ "Friends": "Camarades",
+ "Personal": "Personnelles",
+ "joined the group": "s'est joint au groupe",
+ "You joined the group": "Vous avez rejoint le groupe",
+ "has disconnected from the server": "s'est déconnecté du serveur."
+ },
+ "kl": {
+ "Translator": "Marvin Borner (probably needs corrections)",
+ "you": "SoH",
+ "Feed": "De'",
+ "Explore": "Tu'",
+ "Chat": "Qin",
+ "Friends": "Jup",
+ "Personal": "Ghot",
+ "joined the group": "ghom muv",
+ "You joined the group": "Ghom muv SoH",
+ "has disconnected from the server": "disconnected vo' jabwI'"
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/languages/json/de.json b/main/app/sprinkles/core/assets/SiteAssets/languages/json/de.json
new file mode 100644
index 0000000..74d522a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/languages/json/de.json
@@ -0,0 +1,14 @@
+{
+ "de": {
+ "Translator": "Marvin Borner",
+ "you": "du",
+ "Feed": "Neues",
+ "Explore": "Entdecken",
+ "Chat": "Nachrichten",
+ "Friends": "Freunde",
+ "Personal": "Persönliche Daten",
+ "joined the group": "ist der Gruppe beigetreten",
+ "You joined the group": "Du bist der Gruppe beigetreten",
+ "has disconnected from the server": "hat sich vom Server getrennt"
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/languages/json/en.json b/main/app/sprinkles/core/assets/SiteAssets/languages/json/en.json
new file mode 100644
index 0000000..981bb83
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/languages/json/en.json
@@ -0,0 +1,14 @@
+{
+ "en": {
+ "Translator": "Marvin Borner",
+ "you": "you",
+ "Feed": "New",
+ "Explore": "Explore",
+ "Chat": "Chat",
+ "Friends": "Friends",
+ "Personal": "Personal",
+ "joined the group": "joined the group",
+ "You joined the group": "You joined the group",
+ "has disconnected from the server": "has disconnected from the server"
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/languages/json/fr.json b/main/app/sprinkles/core/assets/SiteAssets/languages/json/fr.json
new file mode 100644
index 0000000..5c59619
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/languages/json/fr.json
@@ -0,0 +1,14 @@
+{
+ "fr": {
+ "Translator": "Marvin Borner (non-french)",
+ "you": "vous",
+ "Feed": "D'actualités",
+ "Explore": "Dépister",
+ "Chat": "Message",
+ "Friends": "Camarades",
+ "Personal": "Personnelles",
+ "joined the group": "s'est joint au groupe",
+ "You joined the group": "Vous avez rejoint le groupe",
+ "has disconnected from the server": "s'est déconnecté du serveur."
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/languages/json/kl.json b/main/app/sprinkles/core/assets/SiteAssets/languages/json/kl.json
new file mode 100644
index 0000000..b21768e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/languages/json/kl.json
@@ -0,0 +1,14 @@
+{
+ "kl": {
+ "Translator": "Marvin Borner (probably needs corrections)",
+ "you": "SoH",
+ "Feed": "De'",
+ "Explore": "Tu'",
+ "Chat": "Qin",
+ "Friends": "Jup",
+ "Personal": "Ghot",
+ "joined the group": "ghom muv",
+ "You joined the group": "Ghom muv SoH",
+ "has disconnected from the server": "disconnected vo' jabwI'"
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/Chatserver/bin/WebChatServer.php b/main/app/sprinkles/core/assets/SiteAssets/php/Chatserver/bin/WebChatServer.php
new file mode 100644
index 0000000..15f573b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/Chatserver/bin/WebChatServer.php
@@ -0,0 +1,18 @@
+<?php
+require '../../vendor/autoload.php';
+
+use Ratchet\Server\IoServer;
+use Ratchet\Http\HttpServer;
+use Ratchet\WebSocket\WsServer;
+use Websocket\ChatProcessor;
+
+$server = IoServer::factory(
+ new HttpServer(
+ new WsServer(
+ new ChatProcessor()
+ )
+ ),
+ 1338
+);
+
+$server->run(); \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/Chatserver/src/ChatProcessor.php b/main/app/sprinkles/core/assets/SiteAssets/php/Chatserver/src/ChatProcessor.php
new file mode 100644
index 0000000..da78c9b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/Chatserver/src/ChatProcessor.php
@@ -0,0 +1,118 @@
+<?php
+
+namespace Websocket;
+
+//use Ratchet\MessageComponentInterface;
+use Ratchet\ConnectionInterface;
+use Ratchet\WebSocket\MessageComponentInterface;
+use Ratchet\RFC6455\Messaging\MessageInterface;
+use Nubs\RandomNameGenerator\Alliteration;
+
+class ChatProcessor implements MessageComponentInterface
+{
+ protected $clients;
+ private $subscriptions;
+ private $users;
+ private $connectedUsersNames;
+
+ public function __construct() {
+ $this->clients = new \SplObjectStorage;
+ $this->subscriptions = [];
+ $this->users = [];
+ $this->connectedUsersNames = [];
+ }
+
+ public function onOpen(ConnectionInterface $conn) {
+ $generator = new Alliteration();
+ $this->clients->attach($conn);
+ $this->users[$conn->resourceId] = $conn;
+ $this->connectedUsersNames[$conn->resourceId] = $generator->getName();
+ }
+
+ /*public function onMessage(ConnectionInterface $from, $msg) {
+ $numRecv = count($this->clients) - 1;
+ echo sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n"
+ , $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's');
+
+ foreach ($this->clients as $client) {
+ if ($from === $client) {
+ $client->send("<b>You</b> - " . $msg);
+ } else {
+ $client->send("<b>" . $from->resourceId . "</b> - " . $msg);
+ }
+ }
+ }
+ */
+
+ public function onMessage(ConnectionInterface $conn, MessageInterface $msg) {
+ $data = json_decode($msg);
+ switch ($data->ClientMessageType) {
+ case "Subscribe":
+ $this->subscriptions[$conn->resourceId] = $data->Channel;
+ foreach ($this->subscriptions as $id => $channel) {
+ if ($this->subscriptions[$conn->resourceId] == $channel) {
+ $MessageObject = new \stdClass();
+ $MessageObject->ServerMessage = true;
+ $MessageObject->ServerMessageType = "GroupJoin";
+ $MessageObject->GroupName = $channel;
+ $MessageObject->Username = $this->connectedUsersNames[$conn->resourceId];
+ if ($id === $conn->resourceId) {
+ $MessageObject->WasHimself = true;
+ } else {
+ $MessageObject->WasHimself = false;
+ }
+ $MessageJson = json_encode($MessageObject, true);
+ $this->users[$id]->send($MessageJson);
+ }
+ }
+ break;
+ case "Message":
+ if (isset($this->subscriptions[$conn->resourceId])) {
+ $target = $this->subscriptions[$conn->resourceId];
+ foreach ($this->subscriptions as $id => $channel) {
+ if ($channel == $target) {
+ $MessageObject = new \stdClass();
+ $MessageObject->ServerMessage = false;
+ $MessageObject->Username = $this->connectedUsersNames[$conn->resourceId];
+ $MessageObject->Message = htmlspecialchars($data->Message);
+ if ($id === $conn->resourceId) {
+ $MessageObject->WasHimself = true;
+ } else {
+ $MessageObject->WasHimself = false;
+ }
+ $MessageJson = json_encode($MessageObject, true);
+ $this->users[$id]->send($MessageJson);
+ }
+ }
+ }
+ }
+ }
+
+ public function onClose(ConnectionInterface $conn) {
+ $this->clients->detach($conn);
+ foreach ($this->clients as $client) {
+ if (isset($this->subscriptions[$conn->resourceId])) {
+ $target = $this->subscriptions[$conn->resourceId];
+ foreach ($this->subscriptions as $id => $channel) {
+ if ($channel == $target) {
+ $MessageObject = new \stdClass();
+ $MessageObject->ServerMessage = true;
+ $MessageObject->ServerMessageType = "UserDisconnect";
+ $MessageObject->Username = $this->connectedUsersNames[$conn->resourceId];
+ $MessageJson = json_encode($MessageObject, true);
+ $this->users[$id]->send($MessageJson);
+ }
+ }
+ }
+ }
+ unset($this->users[$conn->resourceId]);
+ unset($this->subscriptions[$conn->resourceId]);
+ unset($this->connectedUsersNames[$conn->resourceId]);
+ }
+
+ public function onError(ConnectionInterface $conn, \Exception $e) {
+ echo "An error has occurred: {$e->getMessage()}\n";
+
+ $conn->close();
+ }
+} \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/SavePublicKey.php b/main/app/sprinkles/core/assets/SiteAssets/php/SavePublicKey.php
new file mode 100644
index 0000000..725a005
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/SavePublicKey.php
@@ -0,0 +1,17 @@
+<?php
+if (isset($_POST["UserID"]) && isset($_POST["PublicKeyString"])) {
+ require "DataBaseConf.php";
+ $CheckIfAlreadySetStmt = $conn->prepare("SELECT count(*) FROM `PublicKeys` WHERE UserID = :UserID");
+ $CheckIfAlreadySetStmt->bindValue(':UserID', $_POST['UserID']);
+ $CheckIfAlreadySetStmt->execute();
+ $CheckIfAlreadySetRes = $CheckIfAlreadySetStmt->fetchColumn();
+ if ($CheckIfAlreadySetRes == 1) {
+ $UpdatePublicKeyStmt = $conn->prepare("UPDATE `PublicKeys` SET PublicKeyString = :PublicKeyString WHERE UserID = :UserID");
+ $UpdatePublicKeyStmt->execute(array('PublicKeyString' => $_POST["PublicKeyString"], 'UserID' => $_POST["UserID"]));
+ } else if ($CheckIfAlreadySetRes == 0) {
+ $InsertPublicKeyStmt = $conn->prepare("INSERT INTO `PublicKeys` (UserID, PublicKeyString) VALUES (:UserID, :PublicKeyString)");
+ $InsertPublicKeyStmt->execute(array('PublicKeyString' => $_POST["PublicKeyString"], 'UserID' => $_POST["UserID"]));
+ }
+} else {
+ http_response_code(400);
+} \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/composer.json b/main/app/sprinkles/core/assets/SiteAssets/php/composer.json
new file mode 100644
index 0000000..8406940
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/composer.json
@@ -0,0 +1,11 @@
+{
+ "autoload": {
+ "psr-4": {
+ "Websocket\\": "Chatserver/src"
+ }
+ },
+ "require": {
+ "cboden/ratchet": "^0.4.1",
+ "nubs/random-name-generator": "^2.1"
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/composer.lock b/main/app/sprinkles/core/assets/SiteAssets/php/composer.lock
new file mode 100644
index 0000000..a852b73
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/composer.lock
@@ -0,0 +1,943 @@
+{
+ "_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#composer-lock-the-lock-file",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "7db98e9dbf466f436f9127ff8289eac0",
+ "packages": [
+ {
+ "name": "cboden/ratchet",
+ "version": "v0.4.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/ratchetphp/Ratchet.git",
+ "reference": "0d31f3a8ad4795fd48397712709e55cd07f51360"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/ratchetphp/Ratchet/zipball/0d31f3a8ad4795fd48397712709e55cd07f51360",
+ "reference": "0d31f3a8ad4795fd48397712709e55cd07f51360",
+ "shasum": ""
+ },
+ "require": {
+ "guzzlehttp/psr7": "^1.0",
+ "php": ">=5.4.2",
+ "ratchet/rfc6455": "^0.2",
+ "react/socket": "^1.0 || ^0.8 || ^0.7 || ^0.6 || ^0.5",
+ "symfony/http-foundation": "^2.6|^3.0|^4.0",
+ "symfony/routing": "^2.6|^3.0|^4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.8"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Ratchet\\": "src/Ratchet"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Chris Boden",
+ "email": "cboden@gmail.com",
+ "role": "Developer"
+ }
+ ],
+ "description": "PHP WebSocket library",
+ "homepage": "http://socketo.me",
+ "keywords": [
+ "Ratchet",
+ "WebSockets",
+ "server",
+ "sockets",
+ "websocket"
+ ],
+ "time": "2017-12-12T00:49:31+00:00"
+ },
+ {
+ "name": "evenement/evenement",
+ "version": "v3.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/igorw/evenement.git",
+ "reference": "531bfb9d15f8aa57454f5f0285b18bec903b8fb7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/igorw/evenement/zipball/531bfb9d15f8aa57454f5f0285b18bec903b8fb7",
+ "reference": "531bfb9d15f8aa57454f5f0285b18bec903b8fb7",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-0": {
+ "Evenement": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Igor Wiedler",
+ "email": "igor@wiedler.ch"
+ }
+ ],
+ "description": "Événement is a very simple event dispatching library for PHP",
+ "keywords": [
+ "event-dispatcher",
+ "event-emitter"
+ ],
+ "time": "2017-07-23T21:35:13+00:00"
+ },
+ {
+ "name": "guzzlehttp/psr7",
+ "version": "1.4.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/psr7.git",
+ "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c",
+ "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4.0",
+ "psr/http-message": "~1.0"
+ },
+ "provide": {
+ "psr/http-message-implementation": "1.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "GuzzleHttp\\Psr7\\": "src/"
+ },
+ "files": [
+ "src/functions_include.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "Tobias Schultze",
+ "homepage": "https://github.com/Tobion"
+ }
+ ],
+ "description": "PSR-7 message implementation that also provides common utility methods",
+ "keywords": [
+ "http",
+ "message",
+ "request",
+ "response",
+ "stream",
+ "uri",
+ "url"
+ ],
+ "time": "2017-03-20T17:10:46+00:00"
+ },
+ {
+ "name": "nubs/random-name-generator",
+ "version": "v2.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/nubs/random-name-generator.git",
+ "reference": "7004eb1724e1c4a154553e44312b7045fe412b77"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/nubs/random-name-generator/zipball/7004eb1724e1c4a154553e44312b7045fe412b77",
+ "reference": "7004eb1724e1c4a154553e44312b7045fe412b77",
+ "shasum": ""
+ },
+ "require": {
+ "php": "~5.6 || ~7.0"
+ },
+ "require-dev": {
+ "cinam/randomizer": ">=1.1.1,<2.0",
+ "phpunit/phpunit": "~5.0",
+ "satooshi/php-coveralls": "~1.0",
+ "squizlabs/php_codesniffer": "~2.3"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Nubs\\RandomNameGenerator\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Spencer Rinehart",
+ "email": "anubis@overthemonkey.com",
+ "role": "Developer"
+ }
+ ],
+ "description": "A library to create interesting, sometimes entertaining, random names.",
+ "keywords": [
+ "alliteration",
+ "generator",
+ "random",
+ "video game"
+ ],
+ "time": "2016-12-04T01:57:19+00:00"
+ },
+ {
+ "name": "paragonie/random_compat",
+ "version": "v2.0.12",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/paragonie/random_compat.git",
+ "reference": "258c89a6b97de7dfaf5b8c7607d0478e236b04fb"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/paragonie/random_compat/zipball/258c89a6b97de7dfaf5b8c7607d0478e236b04fb",
+ "reference": "258c89a6b97de7dfaf5b8c7607d0478e236b04fb",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.2.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.*|5.*"
+ },
+ "suggest": {
+ "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "lib/random.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Paragon Initiative Enterprises",
+ "email": "security@paragonie.com",
+ "homepage": "https://paragonie.com"
+ }
+ ],
+ "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
+ "keywords": [
+ "csprng",
+ "pseudorandom",
+ "random"
+ ],
+ "time": "2018-04-04T21:24:14+00:00"
+ },
+ {
+ "name": "psr/http-message",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-message.git",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Message\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for HTTP messages",
+ "homepage": "https://github.com/php-fig/http-message",
+ "keywords": [
+ "http",
+ "http-message",
+ "psr",
+ "psr-7",
+ "request",
+ "response"
+ ],
+ "time": "2016-08-06T14:39:51+00:00"
+ },
+ {
+ "name": "ratchet/rfc6455",
+ "version": "v0.2.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/ratchetphp/RFC6455.git",
+ "reference": "cc8a1a46a703ce01de10fdb5fab387381b66edc8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/ratchetphp/RFC6455/zipball/cc8a1a46a703ce01de10fdb5fab387381b66edc8",
+ "reference": "cc8a1a46a703ce01de10fdb5fab387381b66edc8",
+ "shasum": ""
+ },
+ "require": {
+ "guzzlehttp/psr7": "^1.0",
+ "php": ">=5.4.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.8.*",
+ "react/http": "^0.4.1",
+ "react/socket-client": "^0.4.3"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Ratchet\\RFC6455\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Chris Boden",
+ "email": "cboden@gmail.com",
+ "role": "Developer"
+ }
+ ],
+ "description": "RFC6455 WebSocket protocol handler",
+ "homepage": "http://socketo.me",
+ "keywords": [
+ "WebSockets",
+ "rfc6455",
+ "websocket"
+ ],
+ "time": "2017-09-13T13:49:42+00:00"
+ },
+ {
+ "name": "react/cache",
+ "version": "v0.4.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/reactphp/cache.git",
+ "reference": "75494f26b4ef089db9bf8c90b63c296246e099e8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/reactphp/cache/zipball/75494f26b4ef089db9bf8c90b63c296246e099e8",
+ "reference": "75494f26b4ef089db9bf8c90b63c296246e099e8",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0",
+ "react/promise": "~2.0|~1.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "React\\Cache\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Async, Promise-based cache interface for ReactPHP",
+ "keywords": [
+ "cache",
+ "caching",
+ "promise",
+ "reactphp"
+ ],
+ "time": "2017-12-20T16:47:13+00:00"
+ },
+ {
+ "name": "react/dns",
+ "version": "v0.4.13",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/reactphp/dns.git",
+ "reference": "7d1e08c300fd7de600810883386ee5e2a64898f4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/reactphp/dns/zipball/7d1e08c300fd7de600810883386ee5e2a64898f4",
+ "reference": "7d1e08c300fd7de600810883386ee5e2a64898f4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0",
+ "react/cache": "~0.4.0|~0.3.0",
+ "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5",
+ "react/promise": "^2.1 || ^1.2.1",
+ "react/promise-timer": "^1.2",
+ "react/stream": "^1.0 || ^0.7 || ^0.6 || ^0.5 || ^0.4.5"
+ },
+ "require-dev": {
+ "clue/block-react": "^1.2",
+ "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "React\\Dns\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Async DNS resolver for ReactPHP",
+ "keywords": [
+ "async",
+ "dns",
+ "dns-resolver",
+ "reactphp"
+ ],
+ "time": "2018-02-27T12:51:22+00:00"
+ },
+ {
+ "name": "react/event-loop",
+ "version": "v0.5.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/reactphp/event-loop.git",
+ "reference": "e1e0647a5c6e2c86013a24e9c8252113df86105a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/reactphp/event-loop/zipball/e1e0647a5c6e2c86013a24e9c8252113df86105a",
+ "reference": "e1e0647a5c6e2c86013a24e9c8252113df86105a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.8.35 || ^5.7 || ^6.4"
+ },
+ "suggest": {
+ "ext-event": "~1.0 for ExtEventLoop",
+ "ext-pcntl": "For signal handling support when using the StreamSelectLoop"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "React\\EventLoop\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "ReactPHP's core reactor event loop that libraries can use for evented I/O.",
+ "keywords": [
+ "asynchronous",
+ "event-loop"
+ ],
+ "time": "2018-04-09T11:59:21+00:00"
+ },
+ {
+ "name": "react/promise",
+ "version": "v2.5.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/reactphp/promise.git",
+ "reference": "62785ae604c8d69725d693eb370e1d67e94c4053"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/reactphp/promise/zipball/62785ae604c8d69725d693eb370e1d67e94c4053",
+ "reference": "62785ae604c8d69725d693eb370e1d67e94c4053",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.8"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "React\\Promise\\": "src/"
+ },
+ "files": [
+ "src/functions_include.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jan Sorgalla",
+ "email": "jsorgalla@gmail.com"
+ }
+ ],
+ "description": "A lightweight implementation of CommonJS Promises/A for PHP",
+ "keywords": [
+ "promise",
+ "promises"
+ ],
+ "time": "2017-03-25T12:08:31+00:00"
+ },
+ {
+ "name": "react/promise-timer",
+ "version": "v1.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/reactphp/promise-timer.git",
+ "reference": "9b4cd9cbe7457e0d87fe8aa7ccceab8a2c830fbd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/reactphp/promise-timer/zipball/9b4cd9cbe7457e0d87fe8aa7ccceab8a2c830fbd",
+ "reference": "9b4cd9cbe7457e0d87fe8aa7ccceab8a2c830fbd",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3",
+ "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5",
+ "react/promise": "~2.1|~1.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "React\\Promise\\Timer\\": "src/"
+ },
+ "files": [
+ "src/functions.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Christian Lück",
+ "email": "christian@lueck.tv"
+ }
+ ],
+ "description": "A trivial implementation of timeouts for Promises, built on top of ReactPHP.",
+ "homepage": "https://github.com/react/promise-timer",
+ "keywords": [
+ "async",
+ "event-loop",
+ "promise",
+ "reactphp",
+ "timeout",
+ "timer"
+ ],
+ "time": "2017-12-22T15:41:41+00:00"
+ },
+ {
+ "name": "react/socket",
+ "version": "v0.8.10",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/reactphp/socket.git",
+ "reference": "d3957313c92b539537fccc80170c05a27ec25796"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/reactphp/socket/zipball/d3957313c92b539537fccc80170c05a27ec25796",
+ "reference": "d3957313c92b539537fccc80170c05a27ec25796",
+ "shasum": ""
+ },
+ "require": {
+ "evenement/evenement": "^3.0 || ^2.0 || ^1.0",
+ "php": ">=5.3.0",
+ "react/dns": "^0.4.13",
+ "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5",
+ "react/promise": "^2.1 || ^1.2",
+ "react/promise-timer": "~1.0",
+ "react/stream": "^1.0 || ^0.7.1"
+ },
+ "require-dev": {
+ "clue/block-react": "^1.2",
+ "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "React\\Socket\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP",
+ "keywords": [
+ "Connection",
+ "Socket",
+ "async",
+ "reactphp",
+ "stream"
+ ],
+ "time": "2018-02-28T09:32:38+00:00"
+ },
+ {
+ "name": "react/stream",
+ "version": "v0.7.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/reactphp/stream.git",
+ "reference": "10100896018fd847a257cd81143b8e1b7be08e40"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/reactphp/stream/zipball/10100896018fd847a257cd81143b8e1b7be08e40",
+ "reference": "10100896018fd847a257cd81143b8e1b7be08e40",
+ "shasum": ""
+ },
+ "require": {
+ "evenement/evenement": "^3.0 || ^2.0 || ^1.0",
+ "php": ">=5.3.8",
+ "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5"
+ },
+ "require-dev": {
+ "clue/stream-filter": "~1.2",
+ "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "React\\Stream\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP",
+ "keywords": [
+ "event-driven",
+ "io",
+ "non-blocking",
+ "pipe",
+ "reactphp",
+ "readable",
+ "stream",
+ "writable"
+ ],
+ "time": "2018-01-19T15:04:38+00:00"
+ },
+ {
+ "name": "symfony/http-foundation",
+ "version": "v3.4.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/http-foundation.git",
+ "reference": "b11e6d165ff4cbf5685d185ab19a90f2f3bb7d1e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/b11e6d165ff4cbf5685d185ab19a90f2f3bb7d1e",
+ "reference": "b11e6d165ff4cbf5685d185ab19a90f2f3bb7d1e",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.5.9|>=7.0.8",
+ "symfony/polyfill-mbstring": "~1.1",
+ "symfony/polyfill-php70": "~1.6"
+ },
+ "require-dev": {
+ "symfony/expression-language": "~2.8|~3.0|~4.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\HttpFoundation\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony HttpFoundation Component",
+ "homepage": "https://symfony.com",
+ "time": "2018-04-03T05:22:50+00:00"
+ },
+ {
+ "name": "symfony/polyfill-mbstring",
+ "version": "v1.7.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
+ "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/78be803ce01e55d3491c1397cf1c64beb9c1b63b",
+ "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "suggest": {
+ "ext-mbstring": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.7-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Mbstring\\": ""
+ },
+ "files": [
+ "bootstrap.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": "Symfony polyfill for the Mbstring extension",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "mbstring",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "time": "2018-01-30T19:27:44+00:00"
+ },
+ {
+ "name": "symfony/polyfill-php70",
+ "version": "v1.7.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php70.git",
+ "reference": "3532bfcd8f933a7816f3a0a59682fc404776600f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/3532bfcd8f933a7816f3a0a59682fc404776600f",
+ "reference": "3532bfcd8f933a7816f3a0a59682fc404776600f",
+ "shasum": ""
+ },
+ "require": {
+ "paragonie/random_compat": "~1.0|~2.0",
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.7-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Php70\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ],
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "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 backporting some PHP 7.0+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "time": "2018-01-30T19:27:44+00:00"
+ },
+ {
+ "name": "symfony/routing",
+ "version": "v3.4.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/routing.git",
+ "reference": "50f333b707bef9f6972ad04e6df3ec8875c9a67c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/routing/zipball/50f333b707bef9f6972ad04e6df3ec8875c9a67c",
+ "reference": "50f333b707bef9f6972ad04e6df3ec8875c9a67c",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.5.9|>=7.0.8"
+ },
+ "conflict": {
+ "symfony/config": "<3.3.1",
+ "symfony/dependency-injection": "<3.3",
+ "symfony/yaml": "<3.4"
+ },
+ "require-dev": {
+ "doctrine/annotations": "~1.0",
+ "doctrine/common": "~2.2",
+ "psr/log": "~1.0",
+ "symfony/config": "^3.3.1|~4.0",
+ "symfony/dependency-injection": "~3.3|~4.0",
+ "symfony/expression-language": "~2.8|~3.0|~4.0",
+ "symfony/http-foundation": "~2.8|~3.0|~4.0",
+ "symfony/yaml": "~3.4|~4.0"
+ },
+ "suggest": {
+ "doctrine/annotations": "For using the annotation loader",
+ "symfony/config": "For using the all-in-one router or any loader",
+ "symfony/dependency-injection": "For loading routes from a service",
+ "symfony/expression-language": "For using expression matching",
+ "symfony/http-foundation": "For using a Symfony Request object",
+ "symfony/yaml": "For using the YAML loader"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Routing\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Routing Component",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "router",
+ "routing",
+ "uri",
+ "url"
+ ],
+ "time": "2018-04-04T13:22:16+00:00"
+ }
+ ],
+ "packages-dev": [],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": [],
+ "platform-dev": []
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/scripts.php b/main/app/sprinkles/core/assets/SiteAssets/php/scripts.php
new file mode 100644
index 0000000..c2a8dbc
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/scripts.php
@@ -0,0 +1,12 @@
+<?php
+require "vendor/autoload.php";
+use MatthiasMullie\Minify;
+$minifier = new Minify\JS('assets/js/jquery.js');
+$minifier->add('assets/js/fontawesome.js');
+$minifier->add('assets/js/modernizr.js');
+$minifier->add('assets/js/language.js');
+$minifier->add('assets/js/encryption.js');
+$minifier->add('assets/js/chat.js');
+$minifier->add('assets/js/slick.js');
+$minifier->add('assets/js/main.js');
+echo $minifier->minify(); \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/stylesheet.php b/main/app/sprinkles/core/assets/SiteAssets/php/stylesheet.php
new file mode 100644
index 0000000..66dbc50
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/stylesheet.php
@@ -0,0 +1,6 @@
+<?php
+require "vendor/autoload.php";
+use MatthiasMullie\Minify;
+$minifier = new Minify\CSS('assets/css/slick.css');
+$minifier->add('assets/css/main.css');
+echo $minifier->minify(); \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/autoload.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/autoload.php
new file mode 100644
index 0000000..fca3b98
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/autoload.php
@@ -0,0 +1,7 @@
+<?php
+
+// autoload.php @generated by Composer
+
+require_once __DIR__ . '/composer/autoload_real.php';
+
+return ComposerAutoloaderInit3c5661e077098f105cbab5a541fd4883::getLoader();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/.gitignore b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/.gitignore
new file mode 100644
index 0000000..793ef58
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/.gitignore
@@ -0,0 +1,5 @@
+phpunit.xml
+reports
+sandbox
+vendor
+composer.lock \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/.travis.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/.travis.yml
new file mode 100644
index 0000000..6c0dc15
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/.travis.yml
@@ -0,0 +1,20 @@
+language: php
+
+php:
+ - 5.4
+ - 5.5
+ - 5.6
+ - 7.0
+ - 7.1
+ - hhvm
+
+dist: trusty
+
+matrix:
+ allow_failures:
+ - php: hhvm
+
+before_script:
+ - sh -c 'if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then echo "session.serialize_handler = php" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi;'
+ - php -m
+ - composer install --dev --prefer-source
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/CHANGELOG.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/CHANGELOG.md
new file mode 100644
index 0000000..5169993
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/CHANGELOG.md
@@ -0,0 +1,135 @@
+CHANGELOG
+=========
+
+### Legend
+
+* "BC": Backwards compatibility break (from public component APIs)
+* "BF": Bug fix
+
+---
+
+* 0.4.1 (2017-12-11)
+ * Only enableKeepAlive in App if no WsServer passed allowing user to set their own timeout duration
+ * Support Symfony 4
+ * BF: Plug NOOP controller in connection from router in case of misbehaving client
+ * BF: Raise error from invalid WAMP payload
+
+* 0.4 (2017-09-14)
+ * BC: $conn->WebSocket->request replaced with $conn->httpRequest which is a PSR-7 object
+ * Binary messages now supported via Ratchet\WebSocket\MessageComponentInterface
+ * Added heartbeat support via ping/pong in WsServer
+ * BC: No longer support old (and insecure) Hixie76 and Hybi protocols
+ * BC: No longer support disabling UTF-8 checks
+ * BC: The Session component implements HttpServerInterface instead of WsServerInterface
+ * BC: PHP 5.3 no longer supported
+ * BC: Update to newer version of react/socket dependency
+ * BC: WAMP topics reduced to 0 subscriptions are deleted, new subs to same name will result in new Topic instance
+ * Significant performance enhancements
+
+* 0.3.6 (2017-01-06)
+ * BF: Keep host and scheme in HTTP request object attatched to connection
+ * BF: Return correct HTTP response (405) when non-GET request made
+
+* 0.3.5 (2016-05-25)
+ * BF: Unmask responding close frame
+ * Added write handler for PHP session serializer
+
+* 0.3.4 (2015-12-23)
+ * BF: Edge case where version check wasn't run on message coalesce
+ * BF: Session didn't start when using pdo_sqlite
+ * BF: WAMP currie prefix check when using '#'
+ * Compatibility with Symfony 3
+
+* 0.3.3 (2015-05-26)
+ * BF: Framing bug on large messages upon TCP fragmentation
+ * BF: Symfony Router query parameter defaults applied to Request
+ * BF: WAMP CURIE on all URIs
+ * OriginCheck rules applied to FlashPolicy
+ * Switched from PSR-0 to PSR-4
+
+* 0.3.2 (2014-06-08)
+ * BF: No messages after closing handshake (fixed rare race condition causing 100% CPU)
+ * BF: Fixed accidental BC break from v0.3.1
+ * Added autoDelete parameter to Topic to destroy when empty of connections
+ * Exposed React Socket on IoServer (allowing FlashPolicy shutdown in App)
+ * Normalized Exceptions in WAMP
+
+* 0.3.1 (2014-05-26)
+ * Added query parameter support to Router, set in HTTP request (ws://server?hello=world)
+ * HHVM compatibility
+ * BF: React/0.4 support; CPU starvation bug fixes
+ * BF: Allow App::route to ignore Host header
+ * Added expected filters to WAMP Topic broadcast method
+ * Resource cleanup in WAMP TopicManager
+
+* 0.3.0 (2013-10-14)
+ * Added the `App` class to help making Ratchet so easy to use it's silly
+ * BC: Require hostname to do HTTP Host header match and do Origin HTTP header check, verify same name by default, helping prevent CSRF attacks
+ * Added Symfony/2.2 based HTTP Router component to allowing for a single Ratchet server to handle multiple apps -> Ratchet\Http\Router
+ * BC: Decoupled HTTP from WebSocket component -> Ratchet\Http\HttpServer
+ * BF: Single sub-protocol selection to conform with RFC6455
+ * BF: Sanity checks on WAMP protocol to prevent errors
+
+* 0.2.8 (2013-09-19)
+ * React 0.3 support
+
+* 0.2.7 (2013-06-09)
+ * BF: Sub-protocol negotation with Guzzle 3.6
+
+* 0.2.6 (2013-06-01)
+ * Guzzle 3.6 support
+
+* 0.2.5 (2013-04-01)
+ * Fixed Hixie-76 handshake bug
+
+* 0.2.4 (2013-03-09)
+ * Support for Symfony 2.2 and Guzzle 2.3
+ * Minor bug fixes when handling errors
+
+* 0.2.3 (2012-11-21)
+ * Bumped dep: Guzzle to v3, React to v0.2.4
+ * More tests
+
+* 0.2.2 (2012-10-20)
+ * Bumped deps to use React v0.2
+
+* 0.2.1 (2012-10-13)
+ * BF: No more UTF-8 warnings in browsers (no longer sending empty sub-protocol string)
+ * Documentation corrections
+ * Using new composer structure
+
+* 0.2 (2012-09-07)
+ * Ratchet passes every non-binary-frame test from the Autobahn Testsuite
+ * Major performance improvements
+ * BC: Renamed "WampServer" to "ServerProtocol"
+ * BC: New "WampServer" component passes Topic container objects of subscribed Connections
+ * Option to turn off UTF-8 checks in order to increase performance
+ * Switched dependency guzzle/guzzle to guzzle/http (no API changes)
+ * mbstring no longer required
+
+* 0.1.5 (2012-07-12)
+ * BF: Error where service wouldn't run on PHP <= 5.3.8
+ * Dependency library updates
+
+* 0.1.4 (2012-06-17)
+ * Fixed dozens of failing AB tests
+ * BF: Proper socket buffer handling
+
+* 0.1.3 (2012-06-15)
+ * Major refactor inside WebSocket protocol handling, more loosley coupled
+ * BF: Proper error handling on failed WebSocket connections
+ * BF: Handle TCP message concatenation
+ * Inclusion of the AutobahnTestSuite checking WebSocket protocol compliance
+ * mb_string now a requirement
+
+* 0.1.2 (2012-05-19)
+ * BC/BF: Updated WAMP API to coincide with the official spec
+ * Tweaks to improve running as a long lived process
+
+* 0.1.1 (2012-05-14)
+ * Separated interfaces allowing WebSockets to support multiple sub protocols
+ * BF: remoteAddress variable on connections returns proper value
+
+* 0.1 (2012-05-11)
+ * First release with components: IoServer, WsServer, SessionProvider, WampServer, FlashPolicy, IpBlackList
+ * I/O now handled by React, making Ratchet fully asynchronous
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/LICENSE b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/LICENSE
new file mode 100644
index 0000000..24abba1
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2011-2017 Chris Boden
+
+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.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/Makefile b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/Makefile
new file mode 100644
index 0000000..a2526c0
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/Makefile
@@ -0,0 +1,42 @@
+# This file is intended to ease the author's development and testing process
+# Users do not need to use `make`; Ratchet does not need to be compiled
+
+test:
+ phpunit
+
+cover:
+ phpunit --coverage-text --coverage-html=reports/coverage
+
+abtests:
+ ulimit -n 2048 && php tests/autobahn/bin/fuzzingserver.php 8001 LibEvent &
+ ulimit -n 2048 && php tests/autobahn/bin/fuzzingserver.php 8002 StreamSelect &
+ ulimit -n 2048 && php tests/autobahn/bin/fuzzingserver.php 8004 LibEv &
+ wstest -m testeeserver -w ws://localhost:8000 &
+ sleep 1
+ wstest -m fuzzingclient -s tests/autobahn/fuzzingclient-all.json
+ killall php wstest
+
+abtest:
+ ulimit -n 2048 && php tests/autobahn/bin/fuzzingserver.php 8000 StreamSelect &
+ sleep 1
+ wstest -m fuzzingclient -s tests/autobahn/fuzzingclient-quick.json
+ killall php
+
+profile:
+ php -d 'xdebug.profiler_enable=1' tests/autobahn/bin/fuzzingserver.php 8000 LibEvent &
+ sleep 1
+ wstest -m fuzzingclient -s tests/autobahn/fuzzingclient-profile.json
+ killall php
+
+apidocs:
+ apigen --title Ratchet -d reports/api \
+ -s src/ \
+ -s vendor/ratchet/rfc6455/src \
+ -s vendor/react/event-loop/src \
+ -s vendor/react/socket/src \
+ -s vendor/react/stream/src \
+ -s vendor/psr/http-message/src \
+ -s vendor/symfony/http-foundation/Session \
+ -s vendor/symfony/routing \
+ -s vendor/evenement/evenement/src/Evenement \
+ --exclude=vendor/symfony/routing/Tests \
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/README.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/README.md
new file mode 100644
index 0000000..3f1a345
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/README.md
@@ -0,0 +1,83 @@
+# Ratchet
+
+[![Build Status](https://secure.travis-ci.org/ratchetphp/Ratchet.png?branch=master)](http://travis-ci.org/ratchetphp/Ratchet)
+[![Autobahn Testsuite](https://img.shields.io/badge/Autobahn-passing-brightgreen.svg)](http://socketo.me/reports/ab/index.html)
+[![Latest Stable Version](https://poser.pugx.org/cboden/ratchet/v/stable.png)](https://packagist.org/packages/cboden/ratchet)
+
+A PHP library for asynchronously serving WebSockets.
+Build up your application through simple interfaces and re-use your application without changing any of its code just by combining different components.
+
+## Requirements
+
+Shell access is required and root access is recommended.
+To avoid proxy/firewall blockage it's recommended WebSockets are requested on port 80 or 443 (SSL), which requires root access.
+In order to do this, along with your sync web stack, you can either use a reverse proxy or two separate machines.
+You can find more details in the [server conf docs](http://socketo.me/docs/deploy#serverconfiguration).
+
+### Documentation
+
+User and API documentation is available on Ratchet's website: http://socketo.me
+
+See https://github.com/cboden/Ratchet-examples for some out-of-the-box working demos using Ratchet.
+
+Need help? Have a question? Want to provide feedback? Write a message on the [Google Groups Mailing List](https://groups.google.com/forum/#!forum/ratchet-php).
+
+---
+
+### A quick example
+
+```php
+<?php
+use Ratchet\MessageComponentInterface;
+use Ratchet\ConnectionInterface;
+
+ // Make sure composer dependencies have been installed
+ require __DIR__ . '/vendor/autoload.php';
+
+/**
+ * chat.php
+ * Send any incoming messages to all connected clients (except sender)
+ */
+class MyChat implements MessageComponentInterface {
+ protected $clients;
+
+ public function __construct() {
+ $this->clients = new \SplObjectStorage;
+ }
+
+ public function onOpen(ConnectionInterface $conn) {
+ $this->clients->attach($conn);
+ }
+
+ public function onMessage(ConnectionInterface $from, $msg) {
+ foreach ($this->clients as $client) {
+ if ($from != $client) {
+ $client->send($msg);
+ }
+ }
+ }
+
+ public function onClose(ConnectionInterface $conn) {
+ $this->clients->detach($conn);
+ }
+
+ public function onError(ConnectionInterface $conn, \Exception $e) {
+ $conn->close();
+ }
+}
+
+ // Run the server application through the WebSocket protocol on port 8080
+ $app = new Ratchet\App('localhost', 8080);
+ $app->route('/chat', new MyChat);
+ $app->route('/echo', new Ratchet\Server\EchoServer, array('*'));
+ $app->run();
+```
+
+ $ php chat.php
+
+```javascript
+ // Then some JavaScript in the browser:
+ var conn = new WebSocket('ws://localhost:8080/echo');
+ conn.onmessage = function(e) { console.log(e.data); };
+ conn.onopen = function(e) { conn.send('Hello Me!'); };
+```
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/composer.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/composer.json
new file mode 100644
index 0000000..9529618
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/composer.json
@@ -0,0 +1,36 @@
+{
+ "name": "cboden/ratchet"
+ , "type": "library"
+ , "description": "PHP WebSocket library"
+ , "keywords": ["WebSockets", "Server", "Ratchet", "Sockets", "WebSocket"]
+ , "homepage": "http://socketo.me"
+ , "license": "MIT"
+ , "authors": [
+ {
+ "name": "Chris Boden"
+ , "email": "cboden@gmail.com"
+ , "role": "Developer"
+ }
+ ]
+ , "support": {
+ "forum": "https://groups.google.com/forum/#!forum/ratchet-php"
+ , "issues": "https://github.com/ratchetphp/Ratchet/issues"
+ , "irc": "irc://irc.freenode.org/reactphp"
+ }
+ , "autoload": {
+ "psr-4": {
+ "Ratchet\\": "src/Ratchet"
+ }
+ }
+ , "require": {
+ "php": ">=5.4.2"
+ , "ratchet/rfc6455": "^0.2"
+ , "react/socket": "^1.0 || ^0.8 || ^0.7 || ^0.6 || ^0.5"
+ , "guzzlehttp/psr7": "^1.0"
+ , "symfony/http-foundation": "^2.6|^3.0|^4.0"
+ , "symfony/routing": "^2.6|^3.0|^4.0"
+ }
+ , "require-dev": {
+ "phpunit/phpunit": "~4.8"
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/phpunit.xml.dist b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/phpunit.xml.dist
new file mode 100644
index 0000000..0cc5451
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/phpunit.xml.dist
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit
+ forceCoversAnnotation="true"
+ mapTestClassNameToCoveredClassName="true"
+ bootstrap="tests/bootstrap.php"
+ colors="true"
+ backupGlobals="false"
+ backupStaticAttributes="false"
+ syntaxCheck="false"
+ stopOnError="false"
+>
+
+ <testsuites>
+ <testsuite name="unit">
+ <directory>./tests/unit/</directory>
+ </testsuite>
+ </testsuites>
+
+ <testsuites>
+ <testsuite name="integration">
+ <directory>./tests/integration/</directory>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist>
+ <directory>./src/</directory>
+ </whitelist>
+ </filter>
+</phpunit> \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/AbstractConnectionDecorator.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/AbstractConnectionDecorator.php
new file mode 100644
index 0000000..9707951
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/AbstractConnectionDecorator.php
@@ -0,0 +1,41 @@
+<?php
+namespace Ratchet;
+
+/**
+ * Wraps ConnectionInterface objects via the decorator pattern but allows
+ * parameters to bubble through with magic methods
+ * @todo It sure would be nice if I could make most of this a trait...
+ */
+abstract class AbstractConnectionDecorator implements ConnectionInterface {
+ /**
+ * @var ConnectionInterface
+ */
+ protected $wrappedConn;
+
+ public function __construct(ConnectionInterface $conn) {
+ $this->wrappedConn = $conn;
+ }
+
+ /**
+ * @return ConnectionInterface
+ */
+ protected function getConnection() {
+ return $this->wrappedConn;
+ }
+
+ public function __set($name, $value) {
+ $this->wrappedConn->$name = $value;
+ }
+
+ public function __get($name) {
+ return $this->wrappedConn->$name;
+ }
+
+ public function __isset($name) {
+ return isset($this->wrappedConn->$name);
+ }
+
+ public function __unset($name) {
+ unset($this->wrappedConn->$name);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/App.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/App.php
new file mode 100644
index 0000000..f378534
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/App.php
@@ -0,0 +1,145 @@
+<?php
+namespace Ratchet;
+use React\EventLoop\LoopInterface;
+use React\EventLoop\Factory as LoopFactory;
+use React\Socket\Server as Reactor;
+use React\Socket\SecureServer as SecureReactor;
+use Ratchet\Http\HttpServerInterface;
+use Ratchet\Http\OriginCheck;
+use Ratchet\Wamp\WampServerInterface;
+use Ratchet\Server\IoServer;
+use Ratchet\Server\FlashPolicy;
+use Ratchet\Http\HttpServer;
+use Ratchet\Http\Router;
+use Ratchet\WebSocket\WsServer;
+use Ratchet\Wamp\WampServer;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RequestContext;
+use Symfony\Component\Routing\Matcher\UrlMatcher;
+
+/**
+ * An opinionated facade class to quickly and easily create a WebSocket server.
+ * A few configuration assumptions are made and some best-practice security conventions are applied by default.
+ */
+class App {
+ /**
+ * @var \Symfony\Component\Routing\RouteCollection
+ */
+ public $routes;
+
+ /**
+ * @var \Ratchet\Server\IoServer
+ */
+ public $flashServer;
+
+ /**
+ * @var \Ratchet\Server\IoServer
+ */
+ protected $_server;
+
+ /**
+ * The Host passed in construct used for same origin policy
+ * @var string
+ */
+ protected $httpHost;
+
+ /***
+ * The port the socket is listening
+ * @var int
+ */
+ protected $port;
+
+ /**
+ * @var int
+ */
+ protected $_routeCounter = 0;
+
+ /**
+ * @param string $httpHost HTTP hostname clients intend to connect to. MUST match JS `new WebSocket('ws://$httpHost');`
+ * @param int $port Port to listen on. If 80, assuming production, Flash on 843 otherwise expecting Flash to be proxied through 8843
+ * @param string $address IP address to bind to. Default is localhost/proxy only. '0.0.0.0' for any machine.
+ * @param LoopInterface $loop Specific React\EventLoop to bind the application to. null will create one for you.
+ */
+ public function __construct($httpHost = 'localhost', $port = 8080, $address = '127.0.0.1', LoopInterface $loop = null) {
+ if (extension_loaded('xdebug')) {
+ trigger_error('XDebug extension detected. Remember to disable this if performance testing or going live!', E_USER_WARNING);
+ }
+
+ if (null === $loop) {
+ $loop = LoopFactory::create();
+ }
+
+ $this->httpHost = $httpHost;
+ $this->port = $port;
+
+ $socket = new Reactor($address . ':' . $port, $loop);
+
+ $this->routes = new RouteCollection;
+ $this->_server = new IoServer(new HttpServer(new Router(new UrlMatcher($this->routes, new RequestContext))), $socket, $loop);
+
+ $policy = new FlashPolicy;
+ $policy->addAllowedAccess($httpHost, 80);
+ $policy->addAllowedAccess($httpHost, $port);
+
+ if (80 == $port) {
+ $flashUri = '0.0.0.0:843';
+ } else {
+ $flashUri = 8843;
+ }
+ $flashSock = new Reactor($flashUri, $loop);
+ $this->flashServer = new IoServer($policy, $flashSock);
+ }
+
+ /**
+ * Add an endpoint/application to the server
+ * @param string $path The URI the client will connect to
+ * @param ComponentInterface $controller Your application to server for the route. If not specified, assumed to be for a WebSocket
+ * @param array $allowedOrigins An array of hosts allowed to connect (same host by default), ['*'] for any
+ * @param string $httpHost Override the $httpHost variable provided in the __construct
+ * @return ComponentInterface|WsServer
+ */
+ public function route($path, ComponentInterface $controller, array $allowedOrigins = array(), $httpHost = null) {
+ if ($controller instanceof HttpServerInterface || $controller instanceof WsServer) {
+ $decorated = $controller;
+ } elseif ($controller instanceof WampServerInterface) {
+ $decorated = new WsServer(new WampServer($controller));
+ $decorated->enableKeepAlive($this->_server->loop);
+ } elseif ($controller instanceof MessageComponentInterface) {
+ $decorated = new WsServer($controller);
+ $decorated->enableKeepAlive($this->_server->loop);
+ } else {
+ $decorated = $controller;
+ }
+
+ if ($httpHost === null) {
+ $httpHost = $this->httpHost;
+ }
+
+ $allowedOrigins = array_values($allowedOrigins);
+ if (0 === count($allowedOrigins)) {
+ $allowedOrigins[] = $httpHost;
+ }
+ if ('*' !== $allowedOrigins[0]) {
+ $decorated = new OriginCheck($decorated, $allowedOrigins);
+ }
+
+ //allow origins in flash policy server
+ if(empty($this->flashServer) === false) {
+ foreach($allowedOrigins as $allowedOrgin) {
+ $this->flashServer->app->addAllowedAccess($allowedOrgin, $this->port);
+ }
+ }
+
+ $this->routes->add('rr-' . ++$this->_routeCounter, new Route($path, array('_controller' => $decorated), array('Origin' => $this->httpHost), array(), $httpHost, array(), array('GET')));
+
+ return $decorated;
+ }
+
+ /**
+ * Run the server by entering the event loop
+ */
+ public function run() {
+ $this->_server->run();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/ComponentInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/ComponentInterface.php
new file mode 100644
index 0000000..37e41b1
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/ComponentInterface.php
@@ -0,0 +1,31 @@
+<?php
+namespace Ratchet;
+
+/**
+ * This is the interface to build a Ratchet application with.
+ * It implements the decorator pattern to build an application stack
+ */
+interface ComponentInterface {
+ /**
+ * When a new connection is opened it will be passed to this method
+ * @param ConnectionInterface $conn The socket/connection that just connected to your application
+ * @throws \Exception
+ */
+ function onOpen(ConnectionInterface $conn);
+
+ /**
+ * This is called before or after a socket is closed (depends on how it's closed). SendMessage to $conn will not result in an error if it has already been closed.
+ * @param ConnectionInterface $conn The socket/connection that is closing/closed
+ * @throws \Exception
+ */
+ function onClose(ConnectionInterface $conn);
+
+ /**
+ * If there is an error with one of the sockets, or somewhere in the application where an Exception is thrown,
+ * the Exception is sent back down the stack, handled by the Server and bubbled back up the application through this method
+ * @param ConnectionInterface $conn
+ * @param \Exception $e
+ * @throws \Exception
+ */
+ function onError(ConnectionInterface $conn, \Exception $e);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/ConnectionInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/ConnectionInterface.php
new file mode 100644
index 0000000..26fb8a4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/ConnectionInterface.php
@@ -0,0 +1,26 @@
+<?php
+namespace Ratchet;
+
+/**
+ * The version of Ratchet being used
+ * @var string
+ */
+const VERSION = 'Ratchet/0.4.1';
+
+/**
+ * A proxy object representing a connection to the application
+ * This acts as a container to store data (in memory) about the connection
+ */
+interface ConnectionInterface {
+ /**
+ * Send data to the connection
+ * @param string $data
+ * @return \Ratchet\ConnectionInterface
+ */
+ function send($data);
+
+ /**
+ * Close the connection
+ */
+ function close();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Http/CloseResponseTrait.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Http/CloseResponseTrait.php
new file mode 100644
index 0000000..abdf5c4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Http/CloseResponseTrait.php
@@ -0,0 +1,22 @@
+<?php
+namespace Ratchet\Http;
+use Ratchet\ConnectionInterface;
+use GuzzleHttp\Psr7 as gPsr;
+use GuzzleHttp\Psr7\Response;
+
+trait CloseResponseTrait {
+ /**
+ * Close a connection with an HTTP response
+ * @param \Ratchet\ConnectionInterface $conn
+ * @param int $code HTTP status code
+ * @return null
+ */
+ private function close(ConnectionInterface $conn, $code = 400, array $additional_headers = []) {
+ $response = new Response($code, array_merge([
+ 'X-Powered-By' => \Ratchet\VERSION
+ ], $additional_headers));
+
+ $conn->send(gPsr\str($response));
+ $conn->close();
+ }
+} \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Http/HttpRequestParser.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Http/HttpRequestParser.php
new file mode 100644
index 0000000..9c44114
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Http/HttpRequestParser.php
@@ -0,0 +1,64 @@
+<?php
+namespace Ratchet\Http;
+use Ratchet\MessageInterface;
+use Ratchet\ConnectionInterface;
+use GuzzleHttp\Psr7 as gPsr;
+
+/**
+ * This class receives streaming data from a client request
+ * and parses HTTP headers, returning a PSR-7 Request object
+ * once it's been buffered
+ */
+class HttpRequestParser implements MessageInterface {
+ const EOM = "\r\n\r\n";
+
+ /**
+ * The maximum number of bytes the request can be
+ * This is a security measure to prevent attacks
+ * @var int
+ */
+ public $maxSize = 4096;
+
+ /**
+ * @param \Ratchet\ConnectionInterface $context
+ * @param string $data Data stream to buffer
+ * @return \Psr\Http\Message\RequestInterface
+ * @throws \OverflowException If the message buffer has become too large
+ */
+ public function onMessage(ConnectionInterface $context, $data) {
+ if (!isset($context->httpBuffer)) {
+ $context->httpBuffer = '';
+ }
+
+ $context->httpBuffer .= $data;
+
+ if (strlen($context->httpBuffer) > (int)$this->maxSize) {
+ throw new \OverflowException("Maximum buffer size of {$this->maxSize} exceeded parsing HTTP header");
+ }
+
+ if ($this->isEom($context->httpBuffer)) {
+ $request = $this->parse($context->httpBuffer);
+
+ unset($context->httpBuffer);
+
+ return $request;
+ }
+ }
+
+ /**
+ * Determine if the message has been buffered as per the HTTP specification
+ * @param string $message
+ * @return boolean
+ */
+ public function isEom($message) {
+ return (boolean)strpos($message, static::EOM);
+ }
+
+ /**
+ * @param string $headers
+ * @return \Psr\Http\Message\RequestInterface
+ */
+ public function parse($headers) {
+ return gPsr\parse_request($headers);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Http/HttpServer.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Http/HttpServer.php
new file mode 100644
index 0000000..bbd8d53
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Http/HttpServer.php
@@ -0,0 +1,76 @@
+<?php
+namespace Ratchet\Http;
+use Ratchet\MessageComponentInterface;
+use Ratchet\ConnectionInterface;
+
+class HttpServer implements MessageComponentInterface {
+ use CloseResponseTrait;
+
+ /**
+ * Buffers incoming HTTP requests returning a Guzzle Request when coalesced
+ * @var HttpRequestParser
+ * @note May not expose this in the future, may do through facade methods
+ */
+ protected $_reqParser;
+
+ /**
+ * @var \Ratchet\Http\HttpServerInterface
+ */
+ protected $_httpServer;
+
+ /**
+ * @param HttpServerInterface
+ */
+ public function __construct(HttpServerInterface $component) {
+ $this->_httpServer = $component;
+ $this->_reqParser = new HttpRequestParser;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onOpen(ConnectionInterface $conn) {
+ $conn->httpHeadersReceived = false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onMessage(ConnectionInterface $from, $msg) {
+ if (true !== $from->httpHeadersReceived) {
+ try {
+ if (null === ($request = $this->_reqParser->onMessage($from, $msg))) {
+ return;
+ }
+ } catch (\OverflowException $oe) {
+ return $this->close($from, 413);
+ }
+
+ $from->httpHeadersReceived = true;
+
+ return $this->_httpServer->onOpen($from, $request);
+ }
+
+ $this->_httpServer->onMessage($from, $msg);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onClose(ConnectionInterface $conn) {
+ if ($conn->httpHeadersReceived) {
+ $this->_httpServer->onClose($conn);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onError(ConnectionInterface $conn, \Exception $e) {
+ if ($conn->httpHeadersReceived) {
+ $this->_httpServer->onError($conn, $e);
+ } else {
+ $this->close($conn, 500);
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Http/HttpServerInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Http/HttpServerInterface.php
new file mode 100644
index 0000000..2c37c49
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Http/HttpServerInterface.php
@@ -0,0 +1,14 @@
+<?php
+namespace Ratchet\Http;
+use Ratchet\MessageComponentInterface;
+use Ratchet\ConnectionInterface;
+use Psr\Http\Message\RequestInterface;
+
+interface HttpServerInterface extends MessageComponentInterface {
+ /**
+ * @param \Ratchet\ConnectionInterface $conn
+ * @param \Psr\Http\Message\RequestInterface $request null is default because PHP won't let me overload; don't pass null!!!
+ * @throws \UnexpectedValueException if a RequestInterface is not passed
+ */
+ public function onOpen(ConnectionInterface $conn, RequestInterface $request = null);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Http/NoOpHttpServerController.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Http/NoOpHttpServerController.php
new file mode 100644
index 0000000..4f72e66
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Http/NoOpHttpServerController.php
@@ -0,0 +1,18 @@
+<?php
+namespace Ratchet\Http;
+use Ratchet\ConnectionInterface;
+use Psr\Http\Message\RequestInterface;
+
+class NoOpHttpServerController implements HttpServerInterface {
+ public function onOpen(ConnectionInterface $conn, RequestInterface $request = null) {
+ }
+
+ public function onMessage(ConnectionInterface $from, $msg) {
+ }
+
+ public function onClose(ConnectionInterface $conn) {
+ }
+
+ public function onError(ConnectionInterface $conn, \Exception $e) {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Http/OriginCheck.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Http/OriginCheck.php
new file mode 100644
index 0000000..2bdc0f7
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Http/OriginCheck.php
@@ -0,0 +1,65 @@
+<?php
+namespace Ratchet\Http;
+use Ratchet\ConnectionInterface;
+use Ratchet\MessageComponentInterface;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * A middleware to ensure JavaScript clients connecting are from the expected domain.
+ * This protects other websites from open WebSocket connections to your application.
+ * Note: This can be spoofed from non-web browser clients
+ */
+class OriginCheck implements HttpServerInterface {
+ use CloseResponseTrait;
+
+ /**
+ * @var \Ratchet\MessageComponentInterface
+ */
+ protected $_component;
+
+ public $allowedOrigins = [];
+
+ /**
+ * @param MessageComponentInterface $component Component/Application to decorate
+ * @param array $allowed An array of allowed domains that are allowed to connect from
+ */
+ public function __construct(MessageComponentInterface $component, array $allowed = []) {
+ $this->_component = $component;
+ $this->allowedOrigins += $allowed;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onOpen(ConnectionInterface $conn, RequestInterface $request = null) {
+ $header = (string)$request->getHeader('Origin')[0];
+ $origin = parse_url($header, PHP_URL_HOST) ?: $header;
+
+ if (!in_array($origin, $this->allowedOrigins)) {
+ return $this->close($conn, 403);
+ }
+
+ return $this->_component->onOpen($conn, $request);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ function onMessage(ConnectionInterface $from, $msg) {
+ return $this->_component->onMessage($from, $msg);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ function onClose(ConnectionInterface $conn) {
+ return $this->_component->onClose($conn);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ function onError(ConnectionInterface $conn, \Exception $e) {
+ return $this->_component->onError($conn, $e);
+ }
+} \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Http/Router.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Http/Router.php
new file mode 100644
index 0000000..df7fe82
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Http/Router.php
@@ -0,0 +1,96 @@
+<?php
+namespace Ratchet\Http;
+use Ratchet\ConnectionInterface;
+use Psr\Http\Message\RequestInterface;
+use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use GuzzleHttp\Psr7 as gPsr;
+
+class Router implements HttpServerInterface {
+ use CloseResponseTrait;
+
+ /**
+ * @var \Symfony\Component\Routing\Matcher\UrlMatcherInterface
+ */
+ protected $_matcher;
+
+ private $_noopController;
+
+ public function __construct(UrlMatcherInterface $matcher) {
+ $this->_matcher = $matcher;
+ $this->_noopController = new NoOpHttpServerController;
+ }
+
+ /**
+ * {@inheritdoc}
+ * @throws \UnexpectedValueException If a controller is not \Ratchet\Http\HttpServerInterface
+ */
+ public function onOpen(ConnectionInterface $conn, RequestInterface $request = null) {
+ if (null === $request) {
+ throw new \UnexpectedValueException('$request can not be null');
+ }
+
+ $conn->controller = $this->_noopController;
+
+ $uri = $request->getUri();
+
+ $context = $this->_matcher->getContext();
+ $context->setMethod($request->getMethod());
+ $context->setHost($uri->getHost());
+
+ try {
+ $route = $this->_matcher->match($uri->getPath());
+ } catch (MethodNotAllowedException $nae) {
+ return $this->close($conn, 405, array('Allow' => $nae->getAllowedMethods()));
+ } catch (ResourceNotFoundException $nfe) {
+ return $this->close($conn, 404);
+ }
+
+ if (is_string($route['_controller']) && class_exists($route['_controller'])) {
+ $route['_controller'] = new $route['_controller'];
+ }
+
+ if (!($route['_controller'] instanceof HttpServerInterface)) {
+ throw new \UnexpectedValueException('All routes must implement Ratchet\Http\HttpServerInterface');
+ }
+
+ $parameters = [];
+ foreach($route as $key => $value) {
+ if ((is_string($key)) && ('_' !== substr($key, 0, 1))) {
+ $parameters[$key] = $value;
+ }
+ }
+ $parameters = array_merge($parameters, gPsr\parse_query($uri->getQuery() ?: ''));
+
+ $request = $request->withUri($uri->withQuery(gPsr\build_query($parameters)));
+
+ $conn->controller = $route['_controller'];
+ $conn->controller->onOpen($conn, $request);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onMessage(ConnectionInterface $from, $msg) {
+ $from->controller->onMessage($from, $msg);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onClose(ConnectionInterface $conn) {
+ if (isset($conn->controller)) {
+ $conn->controller->onClose($conn);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onError(ConnectionInterface $conn, \Exception $e) {
+ if (isset($conn->controller)) {
+ $conn->controller->onError($conn, $e);
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/MessageComponentInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/MessageComponentInterface.php
new file mode 100644
index 0000000..b4a92e2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/MessageComponentInterface.php
@@ -0,0 +1,5 @@
+<?php
+namespace Ratchet;
+
+interface MessageComponentInterface extends ComponentInterface, MessageInterface {
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/MessageInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/MessageInterface.php
new file mode 100644
index 0000000..1486323
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/MessageInterface.php
@@ -0,0 +1,12 @@
+<?php
+namespace Ratchet;
+
+interface MessageInterface {
+ /**
+ * Triggered when a client sends data through the socket
+ * @param \Ratchet\ConnectionInterface $from The socket/connection that sent the message to your application
+ * @param string $msg The message received
+ * @throws \Exception
+ */
+ function onMessage(ConnectionInterface $from, $msg);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Server/EchoServer.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Server/EchoServer.php
new file mode 100644
index 0000000..2918e73
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Server/EchoServer.php
@@ -0,0 +1,23 @@
+<?php
+namespace Ratchet\Server;
+use Ratchet\MessageComponentInterface;
+use Ratchet\ConnectionInterface;
+
+/**
+ * A simple Ratchet application that will reply to all messages with the message it received
+ */
+class EchoServer implements MessageComponentInterface {
+ public function onOpen(ConnectionInterface $conn) {
+ }
+
+ public function onMessage(ConnectionInterface $from, $msg) {
+ $from->send($msg);
+ }
+
+ public function onClose(ConnectionInterface $conn) {
+ }
+
+ public function onError(ConnectionInterface $conn, \Exception $e) {
+ $conn->close();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Server/FlashPolicy.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Server/FlashPolicy.php
new file mode 100644
index 0000000..4a1b8bd
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Server/FlashPolicy.php
@@ -0,0 +1,200 @@
+<?php
+namespace Ratchet\Server;
+use Ratchet\MessageComponentInterface;
+use Ratchet\ConnectionInterface;
+
+/**
+ * An app to go on a server stack to pass a policy file to a Flash socket
+ * Useful if you're using Flash as a WebSocket polyfill on IE
+ * Be sure to run your server instance on port 843
+ * By default this lets accepts everything, make sure you tighten the rules up for production
+ * @final
+ * @link http://www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html
+ * @link http://learn.adobe.com/wiki/download/attachments/64389123/CrossDomain_PolicyFile_Specification.pdf?version=1
+ * @link view-source:http://www.adobe.com/xml/schemas/PolicyFileSocket.xsd
+ */
+class FlashPolicy implements MessageComponentInterface {
+
+ /**
+ * Contains the root policy node
+ * @var string
+ */
+ protected $_policy = '<?xml version="1.0"?><!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd"><cross-domain-policy></cross-domain-policy>';
+
+ /**
+ * Stores an array of allowed domains and their ports
+ * @var array
+ */
+ protected $_access = array();
+
+ /**
+ * @var string
+ */
+ protected $_siteControl = '';
+
+ /**
+ * @var string
+ */
+ protected $_cache = '';
+
+ /**
+ * @var string
+ */
+ protected $_cacheValid = false;
+
+ /**
+ * Add a domain to an allowed access list.
+ *
+ * @param string $domain Specifies a requesting domain to be granted access. Both named domains and IP
+ * addresses are acceptable values. Subdomains are considered different domains. A wildcard (*) can
+ * be used to match all domains when used alone, or multiple domains (subdomains) when used as a
+ * prefix for an explicit, second-level domain name separated with a dot (.)
+ * @param string $ports A comma-separated list of ports or range of ports that a socket connection
+ * is allowed to connect to. A range of ports is specified through a dash (-) between two port numbers.
+ * Ranges can be used with individual ports when separated with a comma. A single wildcard (*) can
+ * be used to allow all ports.
+ * @param bool $secure
+ * @throws \UnexpectedValueException
+ * @return FlashPolicy
+ */
+ public function addAllowedAccess($domain, $ports = '*', $secure = false) {
+ if (!$this->validateDomain($domain)) {
+ throw new \UnexpectedValueException('Invalid domain');
+ }
+
+ if (!$this->validatePorts($ports)) {
+ throw new \UnexpectedValueException('Invalid Port');
+ }
+
+ $this->_access[] = array($domain, $ports, (boolean)$secure);
+ $this->_cacheValid = false;
+
+ return $this;
+ }
+
+ /**
+ * Removes all domains from the allowed access list.
+ *
+ * @return \Ratchet\Server\FlashPolicy
+ */
+ public function clearAllowedAccess() {
+ $this->_access = array();
+ $this->_cacheValid = false;
+
+ return $this;
+ }
+
+ /**
+ * site-control defines the meta-policy for the current domain. A meta-policy specifies acceptable
+ * domain policy files other than the master policy file located in the target domain's root and named
+ * crossdomain.xml.
+ *
+ * @param string $permittedCrossDomainPolicies
+ * @throws \UnexpectedValueException
+ * @return FlashPolicy
+ */
+ public function setSiteControl($permittedCrossDomainPolicies = 'all') {
+ if (!$this->validateSiteControl($permittedCrossDomainPolicies)) {
+ throw new \UnexpectedValueException('Invalid site control set');
+ }
+
+ $this->_siteControl = $permittedCrossDomainPolicies;
+ $this->_cacheValid = false;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onOpen(ConnectionInterface $conn) {
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onMessage(ConnectionInterface $from, $msg) {
+ if (!$this->_cacheValid) {
+ $this->_cache = $this->renderPolicy()->asXML();
+ $this->_cacheValid = true;
+ }
+
+ $from->send($this->_cache . "\0");
+ $from->close();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onClose(ConnectionInterface $conn) {
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onError(ConnectionInterface $conn, \Exception $e) {
+ $conn->close();
+ }
+
+ /**
+ * Builds the crossdomain file based on the template policy
+ *
+ * @throws \UnexpectedValueException
+ * @return \SimpleXMLElement
+ */
+ public function renderPolicy() {
+ $policy = new \SimpleXMLElement($this->_policy);
+
+ $siteControl = $policy->addChild('site-control');
+
+ if ($this->_siteControl == '') {
+ $this->setSiteControl();
+ }
+
+ $siteControl->addAttribute('permitted-cross-domain-policies', $this->_siteControl);
+
+ if (empty($this->_access)) {
+ throw new \UnexpectedValueException('You must add a domain through addAllowedAccess()');
+ }
+
+ foreach ($this->_access as $access) {
+ $tmp = $policy->addChild('allow-access-from');
+ $tmp->addAttribute('domain', $access[0]);
+ $tmp->addAttribute('to-ports', $access[1]);
+ $tmp->addAttribute('secure', ($access[2] === true) ? 'true' : 'false');
+ }
+
+ return $policy;
+ }
+
+ /**
+ * Make sure the proper site control was passed
+ *
+ * @param string $permittedCrossDomainPolicies
+ * @return bool
+ */
+ public function validateSiteControl($permittedCrossDomainPolicies) {
+ //'by-content-type' and 'by-ftp-filename' are not available for sockets
+ return (bool)in_array($permittedCrossDomainPolicies, array('none', 'master-only', 'all'));
+ }
+
+ /**
+ * Validate for proper domains (wildcards allowed)
+ *
+ * @param string $domain
+ * @return bool
+ */
+ public function validateDomain($domain) {
+ return (bool)preg_match("/^((http(s)?:\/\/)?([a-z0-9-_]+\.|\*\.)*([a-z0-9-_\.]+)|\*)$/i", $domain);
+ }
+
+ /**
+ * Make sure valid ports were passed
+ *
+ * @param string $port
+ * @return bool
+ */
+ public function validatePorts($port) {
+ return (bool)preg_match('/^(\*|(\d+[,-]?)*\d+)$/', $port);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Server/IoConnection.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Server/IoConnection.php
new file mode 100644
index 0000000..9f864bb
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Server/IoConnection.php
@@ -0,0 +1,38 @@
+<?php
+namespace Ratchet\Server;
+use Ratchet\ConnectionInterface;
+use React\Socket\ConnectionInterface as ReactConn;
+
+/**
+ * {@inheritdoc}
+ */
+class IoConnection implements ConnectionInterface {
+ /**
+ * @var \React\Socket\ConnectionInterface
+ */
+ protected $conn;
+
+
+ /**
+ * @param \React\Socket\ConnectionInterface $conn
+ */
+ public function __construct(ReactConn $conn) {
+ $this->conn = $conn;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function send($data) {
+ $this->conn->write($data);
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function close() {
+ $this->conn->end();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Server/IoServer.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Server/IoServer.php
new file mode 100644
index 0000000..b3fb7e0
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Server/IoServer.php
@@ -0,0 +1,140 @@
+<?php
+namespace Ratchet\Server;
+use Ratchet\MessageComponentInterface;
+use React\EventLoop\LoopInterface;
+use React\Socket\ServerInterface;
+use React\EventLoop\Factory as LoopFactory;
+use React\Socket\Server as Reactor;
+use React\Socket\SecureServer as SecureReactor;
+
+/**
+ * Creates an open-ended socket to listen on a port for incoming connections.
+ * Events are delegated through this to attached applications
+ */
+class IoServer {
+ /**
+ * @var \React\EventLoop\LoopInterface
+ */
+ public $loop;
+
+ /**
+ * @var \Ratchet\MessageComponentInterface
+ */
+ public $app;
+
+ /**
+ * The socket server the Ratchet Application is run off of
+ * @var \React\Socket\ServerInterface
+ */
+ public $socket;
+
+ /**
+ * @param \Ratchet\MessageComponentInterface $app The Ratchet application stack to host
+ * @param \React\Socket\ServerInterface $socket The React socket server to run the Ratchet application off of
+ * @param \React\EventLoop\LoopInterface|null $loop The React looper to run the Ratchet application off of
+ */
+ public function __construct(MessageComponentInterface $app, ServerInterface $socket, LoopInterface $loop = null) {
+ if (false === strpos(PHP_VERSION, "hiphop")) {
+ gc_enable();
+ }
+
+ set_time_limit(0);
+ ob_implicit_flush();
+
+ $this->loop = $loop;
+ $this->app = $app;
+ $this->socket = $socket;
+
+ $socket->on('connection', array($this, 'handleConnect'));
+ }
+
+ /**
+ * @param \Ratchet\MessageComponentInterface $component The application that I/O will call when events are received
+ * @param int $port The port to server sockets on
+ * @param string $address The address to receive sockets on (0.0.0.0 means receive connections from any)
+ * @return IoServer
+ */
+ public static function factory(MessageComponentInterface $component, $port = 80, $address = '0.0.0.0') {
+ $loop = LoopFactory::create();
+ $socket = new Reactor($address . ':' . $port, $loop);
+
+ return new static($component, $socket, $loop);
+ }
+
+ /**
+ * Run the application by entering the event loop
+ * @throws \RuntimeException If a loop was not previously specified
+ */
+ public function run() {
+ if (null === $this->loop) {
+ throw new \RuntimeException("A React Loop was not provided during instantiation");
+ }
+
+ // @codeCoverageIgnoreStart
+ $this->loop->run();
+ // @codeCoverageIgnoreEnd
+ }
+
+ /**
+ * Triggered when a new connection is received from React
+ * @param \React\Socket\ConnectionInterface $conn
+ */
+ public function handleConnect($conn) {
+ $conn->decor = new IoConnection($conn);
+ $conn->decor->resourceId = (int)$conn->stream;
+
+ $uri = $conn->getRemoteAddress();
+ $conn->decor->remoteAddress = trim(
+ parse_url((strpos($uri, '://') === false ? 'tcp://' : '') . $uri, PHP_URL_HOST),
+ '[]'
+ );
+
+ $this->app->onOpen($conn->decor);
+
+ $conn->on('data', function ($data) use ($conn) {
+ $this->handleData($data, $conn);
+ });
+ $conn->on('close', function () use ($conn) {
+ $this->handleEnd($conn);
+ });
+ $conn->on('error', function (\Exception $e) use ($conn) {
+ $this->handleError($e, $conn);
+ });
+ }
+
+ /**
+ * Data has been received from React
+ * @param string $data
+ * @param \React\Socket\ConnectionInterface $conn
+ */
+ public function handleData($data, $conn) {
+ try {
+ $this->app->onMessage($conn->decor, $data);
+ } catch (\Exception $e) {
+ $this->handleError($e, $conn);
+ }
+ }
+
+ /**
+ * A connection has been closed by React
+ * @param \React\Socket\ConnectionInterface $conn
+ */
+ public function handleEnd($conn) {
+ try {
+ $this->app->onClose($conn->decor);
+ } catch (\Exception $e) {
+ $this->handleError($e, $conn);
+ }
+
+ unset($conn->decor);
+ }
+
+ /**
+ * An error has occurred, let the listening application know
+ * @param \Exception $e
+ * @param \React\Socket\ConnectionInterface $conn
+ */
+ public function handleError(\Exception $e, $conn) {
+ $this->app->onError($conn->decor, $e);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Server/IpBlackList.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Server/IpBlackList.php
new file mode 100644
index 0000000..9342254
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Server/IpBlackList.php
@@ -0,0 +1,111 @@
+<?php
+namespace Ratchet\Server;
+use Ratchet\MessageComponentInterface;
+use Ratchet\ConnectionInterface;
+
+class IpBlackList implements MessageComponentInterface {
+ /**
+ * @var array
+ */
+ protected $_blacklist = array();
+
+ /**
+ * @var \Ratchet\MessageComponentInterface
+ */
+ protected $_decorating;
+
+ /**
+ * @param \Ratchet\MessageComponentInterface $component
+ */
+ public function __construct(MessageComponentInterface $component) {
+ $this->_decorating = $component;
+ }
+
+ /**
+ * Add an address to the blacklist that will not be allowed to connect to your application
+ * @param string $ip IP address to block from connecting to your application
+ * @return IpBlackList
+ */
+ public function blockAddress($ip) {
+ $this->_blacklist[$ip] = true;
+
+ return $this;
+ }
+
+ /**
+ * Unblock an address so they can access your application again
+ * @param string $ip IP address to unblock from connecting to your application
+ * @return IpBlackList
+ */
+ public function unblockAddress($ip) {
+ if (isset($this->_blacklist[$this->filterAddress($ip)])) {
+ unset($this->_blacklist[$this->filterAddress($ip)]);
+ }
+
+ return $this;
+ }
+
+ /**
+ * @param string $address
+ * @return bool
+ */
+ public function isBlocked($address) {
+ return (isset($this->_blacklist[$this->filterAddress($address)]));
+ }
+
+ /**
+ * Get an array of all the addresses blocked
+ * @return array
+ */
+ public function getBlockedAddresses() {
+ return array_keys($this->_blacklist);
+ }
+
+ /**
+ * @param string $address
+ * @return string
+ */
+ public function filterAddress($address) {
+ if (strstr($address, ':') && substr_count($address, '.') == 3) {
+ list($address, $port) = explode(':', $address);
+ }
+
+ return $address;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ function onOpen(ConnectionInterface $conn) {
+ if ($this->isBlocked($conn->remoteAddress)) {
+ return $conn->close();
+ }
+
+ return $this->_decorating->onOpen($conn);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ function onMessage(ConnectionInterface $from, $msg) {
+ return $this->_decorating->onMessage($from, $msg);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ function onClose(ConnectionInterface $conn) {
+ if (!$this->isBlocked($conn->remoteAddress)) {
+ $this->_decorating->onClose($conn);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ function onError(ConnectionInterface $conn, \Exception $e) {
+ if (!$this->isBlocked($conn->remoteAddress)) {
+ $this->_decorating->onError($conn, $e);
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Session/Serialize/HandlerInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Session/Serialize/HandlerInterface.php
new file mode 100644
index 0000000..b83635f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Session/Serialize/HandlerInterface.php
@@ -0,0 +1,16 @@
+<?php
+namespace Ratchet\Session\Serialize;
+
+interface HandlerInterface {
+ /**
+ * @param array
+ * @return string
+ */
+ function serialize(array $data);
+
+ /**
+ * @param string
+ * @return array
+ */
+ function unserialize($raw);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Session/Serialize/PhpBinaryHandler.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Session/Serialize/PhpBinaryHandler.php
new file mode 100644
index 0000000..ba80551
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Session/Serialize/PhpBinaryHandler.php
@@ -0,0 +1,33 @@
+<?php
+namespace Ratchet\Session\Serialize;
+
+class PhpBinaryHandler implements HandlerInterface {
+ /**
+ * {@inheritdoc}
+ */
+ function serialize(array $data) {
+ throw new \RuntimeException("Serialize PhpHandler:serialize code not written yet, write me!");
+ }
+
+ /**
+ * {@inheritdoc}
+ * @link http://ca2.php.net/manual/en/function.session-decode.php#108037 Code from this comment on php.net
+ */
+ public function unserialize($raw) {
+ $returnData = array();
+ $offset = 0;
+
+ while ($offset < strlen($raw)) {
+ $num = ord($raw[$offset]);
+ $offset += 1;
+ $varname = substr($raw, $offset, $num);
+ $offset += $num;
+ $data = unserialize(substr($raw, $offset));
+
+ $returnData[$varname] = $data;
+ $offset += strlen(serialize($data));
+ }
+
+ return $returnData;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Session/Serialize/PhpHandler.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Session/Serialize/PhpHandler.php
new file mode 100644
index 0000000..b1df356
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Session/Serialize/PhpHandler.php
@@ -0,0 +1,49 @@
+<?php
+namespace Ratchet\Session\Serialize;
+
+class PhpHandler implements HandlerInterface {
+ /**
+ * Simply reverse behaviour of unserialize method.
+ * {@inheritdoc}
+ */
+ function serialize(array $data) {
+ $preSerialized = array();
+ $serialized = '';
+
+ if (count($data)) {
+ foreach ($data as $bucket => $bucketData) {
+ $preSerialized[] = $bucket . '|' . serialize($bucketData);
+ }
+ $serialized = implode('', $preSerialized);
+ }
+
+ return $serialized;
+ }
+
+ /**
+ * {@inheritdoc}
+ * @link http://ca2.php.net/manual/en/function.session-decode.php#108037 Code from this comment on php.net
+ * @throws \UnexpectedValueException If there is a problem parsing the data
+ */
+ public function unserialize($raw) {
+ $returnData = array();
+ $offset = 0;
+
+ while ($offset < strlen($raw)) {
+ if (!strstr(substr($raw, $offset), "|")) {
+ throw new \UnexpectedValueException("invalid data, remaining: " . substr($raw, $offset));
+ }
+
+ $pos = strpos($raw, "|", $offset);
+ $num = $pos - $offset;
+ $varname = substr($raw, $offset, $num);
+ $offset += $num + 1;
+ $data = unserialize(substr($raw, $offset));
+
+ $returnData[$varname] = $data;
+ $offset += strlen(serialize($data));
+ }
+
+ return $returnData;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Session/SessionProvider.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Session/SessionProvider.php
new file mode 100644
index 0000000..44276c5
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Session/SessionProvider.php
@@ -0,0 +1,243 @@
+<?php
+namespace Ratchet\Session;
+use Ratchet\ConnectionInterface;
+use Ratchet\Http\HttpServerInterface;
+use Psr\Http\Message\RequestInterface;
+use Ratchet\Session\Storage\VirtualSessionStorage;
+use Ratchet\Session\Serialize\HandlerInterface;
+use Symfony\Component\HttpFoundation\Session\Session;
+use Symfony\Component\HttpFoundation\Session\Storage\Handler\NullSessionHandler;
+
+/**
+ * This component will allow access to session data from your website for each user connected
+ * Symfony HttpFoundation is required for this component to work
+ * Your website must also use Symfony HttpFoundation Sessions to read your sites session data
+ * If your are not using at least PHP 5.4 you must include a SessionHandlerInterface stub (is included in Symfony HttpFoundation, loaded w/ composer)
+ */
+class SessionProvider implements HttpServerInterface {
+ /**
+ * @var \Ratchet\MessageComponentInterface
+ */
+ protected $_app;
+
+ /**
+ * Selected handler storage assigned by the developer
+ * @var \SessionHandlerInterface
+ */
+ protected $_handler;
+
+ /**
+ * Null storage handler if no previous session was found
+ * @var \SessionHandlerInterface
+ */
+ protected $_null;
+
+ /**
+ * @var \Ratchet\Session\Serialize\HandlerInterface
+ */
+ protected $_serializer;
+
+ /**
+ * @param \Ratchet\Http\HttpServerInterface $app
+ * @param \SessionHandlerInterface $handler
+ * @param array $options
+ * @param \Ratchet\Session\Serialize\HandlerInterface $serializer
+ * @throws \RuntimeException
+ */
+ public function __construct(HttpServerInterface $app, \SessionHandlerInterface $handler, array $options = array(), HandlerInterface $serializer = null) {
+ $this->_app = $app;
+ $this->_handler = $handler;
+ $this->_null = new NullSessionHandler;
+
+ ini_set('session.auto_start', 0);
+ ini_set('session.cache_limiter', '');
+ ini_set('session.use_cookies', 0);
+
+ $this->setOptions($options);
+
+ if (null === $serializer) {
+ $serialClass = __NAMESPACE__ . "\\Serialize\\{$this->toClassCase(ini_get('session.serialize_handler'))}Handler"; // awesome/terrible hack, eh?
+ if (!class_exists($serialClass)) {
+ throw new \RuntimeException('Unable to parse session serialize handler');
+ }
+
+ $serializer = new $serialClass;
+ }
+
+ $this->_serializer = $serializer;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onOpen(ConnectionInterface $conn, RequestInterface $request = null) {
+ $sessionName = ini_get('session.name');
+
+ $id = array_reduce($request->getHeader('Cookie'), function($accumulator, $cookie) use ($sessionName) {
+ if ($accumulator) {
+ return $accumulator;
+ }
+
+ $crumbs = $this->parseCookie($cookie);
+
+ return isset($crumbs['cookies'][$sessionName]) ? $crumbs['cookies'][$sessionName] : false;
+ }, false);
+
+ if (null === $request || false === $id) {
+ $saveHandler = $this->_null;
+ $id = '';
+ } else {
+ $saveHandler = $this->_handler;
+ }
+
+ $conn->Session = new Session(new VirtualSessionStorage($saveHandler, $id, $this->_serializer));
+
+ if (ini_get('session.auto_start')) {
+ $conn->Session->start();
+ }
+
+ return $this->_app->onOpen($conn, $request);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ function onMessage(ConnectionInterface $from, $msg) {
+ return $this->_app->onMessage($from, $msg);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ function onClose(ConnectionInterface $conn) {
+ // "close" session for Connection
+
+ return $this->_app->onClose($conn);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ function onError(ConnectionInterface $conn, \Exception $e) {
+ return $this->_app->onError($conn, $e);
+ }
+
+ /**
+ * Set all the php session. ini options
+ * © Symfony
+ * @param array $options
+ * @return array
+ */
+ protected function setOptions(array $options) {
+ $all = array(
+ 'auto_start', 'cache_limiter', 'cookie_domain', 'cookie_httponly',
+ 'cookie_lifetime', 'cookie_path', 'cookie_secure',
+ 'entropy_file', 'entropy_length', 'gc_divisor',
+ 'gc_maxlifetime', 'gc_probability', 'hash_bits_per_character',
+ 'hash_function', 'name', 'referer_check',
+ 'serialize_handler', 'use_cookies',
+ 'use_only_cookies', 'use_trans_sid', 'upload_progress.enabled',
+ 'upload_progress.cleanup', 'upload_progress.prefix', 'upload_progress.name',
+ 'upload_progress.freq', 'upload_progress.min-freq', 'url_rewriter.tags'
+ );
+
+ foreach ($all as $key) {
+ if (!array_key_exists($key, $options)) {
+ $options[$key] = ini_get("session.{$key}");
+ } else {
+ ini_set("session.{$key}", $options[$key]);
+ }
+ }
+
+ return $options;
+ }
+
+ /**
+ * @param string $langDef Input to convert
+ * @return string
+ */
+ protected function toClassCase($langDef) {
+ return str_replace(' ', '', ucwords(str_replace('_', ' ', $langDef)));
+ }
+
+ /**
+ * Taken from Guzzle3
+ */
+ private static $cookieParts = array(
+ 'domain' => 'Domain',
+ 'path' => 'Path',
+ 'max_age' => 'Max-Age',
+ 'expires' => 'Expires',
+ 'version' => 'Version',
+ 'secure' => 'Secure',
+ 'port' => 'Port',
+ 'discard' => 'Discard',
+ 'comment' => 'Comment',
+ 'comment_url' => 'Comment-Url',
+ 'http_only' => 'HttpOnly'
+ );
+
+ /**
+ * Taken from Guzzle3
+ */
+ private function parseCookie($cookie, $host = null, $path = null, $decode = false) {
+ // Explode the cookie string using a series of semicolons
+ $pieces = array_filter(array_map('trim', explode(';', $cookie)));
+
+ // The name of the cookie (first kvp) must include an equal sign.
+ if (empty($pieces) || !strpos($pieces[0], '=')) {
+ return false;
+ }
+
+ // Create the default return array
+ $data = array_merge(array_fill_keys(array_keys(self::$cookieParts), null), array(
+ 'cookies' => array(),
+ 'data' => array(),
+ 'path' => $path ?: '/',
+ 'http_only' => false,
+ 'discard' => false,
+ 'domain' => $host
+ ));
+ $foundNonCookies = 0;
+
+ // Add the cookie pieces into the parsed data array
+ foreach ($pieces as $part) {
+
+ $cookieParts = explode('=', $part, 2);
+ $key = trim($cookieParts[0]);
+
+ if (count($cookieParts) == 1) {
+ // Can be a single value (e.g. secure, httpOnly)
+ $value = true;
+ } else {
+ // Be sure to strip wrapping quotes
+ $value = trim($cookieParts[1], " \n\r\t\0\x0B\"");
+ if ($decode) {
+ $value = urldecode($value);
+ }
+ }
+
+ // Only check for non-cookies when cookies have been found
+ if (!empty($data['cookies'])) {
+ foreach (self::$cookieParts as $mapValue => $search) {
+ if (!strcasecmp($search, $key)) {
+ $data[$mapValue] = $mapValue == 'port' ? array_map('trim', explode(',', $value)) : $value;
+ $foundNonCookies++;
+ continue 2;
+ }
+ }
+ }
+
+ // If cookies have not yet been retrieved, or this value was not found in the pieces array, treat it as a
+ // cookie. IF non-cookies have been parsed, then this isn't a cookie, it's cookie data. Cookies then data.
+ $data[$foundNonCookies ? 'data' : 'cookies'][$key] = $value;
+ }
+
+ // Calculate the expires date
+ if (!$data['expires'] && $data['max_age']) {
+ $data['expires'] = time() + (int) $data['max_age'];
+ }
+
+ return $data;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Session/Storage/Proxy/VirtualProxy.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Session/Storage/Proxy/VirtualProxy.php
new file mode 100644
index 0000000..b478d03
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Session/Storage/Proxy/VirtualProxy.php
@@ -0,0 +1,54 @@
+<?php
+namespace Ratchet\Session\Storage\Proxy;
+use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;
+
+class VirtualProxy extends SessionHandlerProxy {
+ /**
+ * @var string
+ */
+ protected $_sessionId;
+
+ /**
+ * @var string
+ */
+ protected $_sessionName;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function __construct(\SessionHandlerInterface $handler) {
+ parent::__construct($handler);
+
+ $this->saveHandlerName = 'user';
+ $this->_sessionName = ini_get('session.name');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getId() {
+ return $this->_sessionId;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setId($id) {
+ $this->_sessionId = $id;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName() {
+ return $this->_sessionName;
+ }
+
+ /**
+ * DO NOT CALL THIS METHOD
+ * @internal
+ */
+ public function setName($name) {
+ throw new \RuntimeException("Can not change session name in VirtualProxy");
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Session/Storage/VirtualSessionStorage.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Session/Storage/VirtualSessionStorage.php
new file mode 100644
index 0000000..daa10bb
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Session/Storage/VirtualSessionStorage.php
@@ -0,0 +1,88 @@
+<?php
+namespace Ratchet\Session\Storage;
+use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
+use Ratchet\Session\Storage\Proxy\VirtualProxy;
+use Ratchet\Session\Serialize\HandlerInterface;
+
+class VirtualSessionStorage extends NativeSessionStorage {
+ /**
+ * @var \Ratchet\Session\Serialize\HandlerInterface
+ */
+ protected $_serializer;
+
+ /**
+ * @param \SessionHandlerInterface $handler
+ * @param string $sessionId The ID of the session to retrieve
+ * @param \Ratchet\Session\Serialize\HandlerInterface $serializer
+ */
+ public function __construct(\SessionHandlerInterface $handler, $sessionId, HandlerInterface $serializer) {
+ $this->setSaveHandler($handler);
+ $this->saveHandler->setId($sessionId);
+ $this->_serializer = $serializer;
+ $this->setMetadataBag(null);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function start() {
+ if ($this->started && !$this->closed) {
+ return true;
+ }
+
+ // You have to call Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler::open() to use
+ // pdo_sqlite (and possible pdo_*) as session storage, if you are using a DSN string instead of a \PDO object
+ // in the constructor. The method arguments are filled with the values, which are also used by the symfony
+ // framework in this case. This must not be the best choice, but it works.
+ $this->saveHandler->open(session_save_path(), session_name());
+
+ $rawData = $this->saveHandler->read($this->saveHandler->getId());
+ $sessionData = $this->_serializer->unserialize($rawData);
+
+ $this->loadSession($sessionData);
+
+ if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) {
+ $this->saveHandler->setActive(false);
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function regenerate($destroy = false, $lifetime = null) {
+ // .. ?
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function save() {
+ // get the data from the bags?
+ // serialize the data
+ // save the data using the saveHandler
+// $this->saveHandler->write($this->saveHandler->getId(),
+
+ if (!$this->saveHandler->isWrapper() && !$this->getSaveHandler()->isSessionHandlerInterface()) {
+ $this->saveHandler->setActive(false);
+ }
+
+ $this->closed = true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setSaveHandler($saveHandler = null) {
+ if (!($saveHandler instanceof \SessionHandlerInterface)) {
+ throw new \InvalidArgumentException('Handler must be instance of SessionHandlerInterface');
+ }
+
+ if (!($saveHandler instanceof VirtualProxy)) {
+ $saveHandler = new VirtualProxy($saveHandler);
+ }
+
+ $this->saveHandler = $saveHandler;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/Exception.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/Exception.php
new file mode 100644
index 0000000..6c824da
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/Exception.php
@@ -0,0 +1,5 @@
+<?php
+namespace Ratchet\Wamp;
+
+class Exception extends \Exception {
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/JsonException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/JsonException.php
new file mode 100644
index 0000000..8f05d28
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/JsonException.php
@@ -0,0 +1,31 @@
+<?php
+namespace Ratchet\Wamp;
+
+class JsonException extends Exception {
+ public function __construct() {
+ $code = json_last_error();
+
+ switch ($code) {
+ case JSON_ERROR_DEPTH:
+ $msg = 'Maximum stack depth exceeded';
+ break;
+ case JSON_ERROR_STATE_MISMATCH:
+ $msg = 'Underflow or the modes mismatch';
+ break;
+ case JSON_ERROR_CTRL_CHAR:
+ $msg = 'Unexpected control character found';
+ break;
+ case JSON_ERROR_SYNTAX:
+ $msg = 'Syntax error, malformed JSON';
+ break;
+ case JSON_ERROR_UTF8:
+ $msg = 'Malformed UTF-8 characters, possibly incorrectly encoded';
+ break;
+ default:
+ $msg = 'Unknown error';
+ break;
+ }
+
+ parent::__construct($msg, $code);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/ServerProtocol.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/ServerProtocol.php
new file mode 100644
index 0000000..2d6d799
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/ServerProtocol.php
@@ -0,0 +1,161 @@
+<?php
+namespace Ratchet\Wamp;
+use Ratchet\MessageComponentInterface;
+use Ratchet\WebSocket\WsServerInterface;
+use Ratchet\ConnectionInterface;
+
+/**
+ * WebSocket Application Messaging Protocol
+ *
+ * @link http://wamp.ws/spec
+ * @link https://github.com/oberstet/autobahn-js
+ *
+ * +--------------+----+------------------+
+ * | Message Type | ID | DIRECTION |
+ * |--------------+----+------------------+
+ * | WELCOME | 0 | Server-to-Client |
+ * | PREFIX | 1 | Bi-Directional |
+ * | CALL | 2 | Client-to-Server |
+ * | CALL RESULT | 3 | Server-to-Client |
+ * | CALL ERROR | 4 | Server-to-Client |
+ * | SUBSCRIBE | 5 | Client-to-Server |
+ * | UNSUBSCRIBE | 6 | Client-to-Server |
+ * | PUBLISH | 7 | Client-to-Server |
+ * | EVENT | 8 | Server-to-Client |
+ * +--------------+----+------------------+
+ */
+class ServerProtocol implements MessageComponentInterface, WsServerInterface {
+ const MSG_WELCOME = 0;
+ const MSG_PREFIX = 1;
+ const MSG_CALL = 2;
+ const MSG_CALL_RESULT = 3;
+ const MSG_CALL_ERROR = 4;
+ const MSG_SUBSCRIBE = 5;
+ const MSG_UNSUBSCRIBE = 6;
+ const MSG_PUBLISH = 7;
+ const MSG_EVENT = 8;
+
+ /**
+ * @var WampServerInterface
+ */
+ protected $_decorating;
+
+ /**
+ * @var \SplObjectStorage
+ */
+ protected $connections;
+
+ /**
+ * @param WampServerInterface $serverComponent An class to propagate calls through
+ */
+ public function __construct(WampServerInterface $serverComponent) {
+ $this->_decorating = $serverComponent;
+ $this->connections = new \SplObjectStorage;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getSubProtocols() {
+ if ($this->_decorating instanceof WsServerInterface) {
+ $subs = $this->_decorating->getSubProtocols();
+ $subs[] = 'wamp';
+
+ return $subs;
+ }
+
+ return ['wamp'];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onOpen(ConnectionInterface $conn) {
+ $decor = new WampConnection($conn);
+ $this->connections->attach($conn, $decor);
+
+ $this->_decorating->onOpen($decor);
+ }
+
+ /**
+ * {@inheritdoc}
+ * @throws \Ratchet\Wamp\Exception
+ * @throws \Ratchet\Wamp\JsonException
+ */
+ public function onMessage(ConnectionInterface $from, $msg) {
+ $from = $this->connections[$from];
+
+ if (null === ($json = @json_decode($msg, true))) {
+ throw new JsonException;
+ }
+
+ if (!is_array($json) || $json !== array_values($json)) {
+ throw new Exception("Invalid WAMP message format");
+ }
+
+ if (isset($json[1]) && !(is_string($json[1]) || is_numeric($json[1]))) {
+ throw new Exception('Invalid Topic, must be a string');
+ }
+
+ switch ($json[0]) {
+ case static::MSG_PREFIX:
+ $from->WAMP->prefixes[$json[1]] = $json[2];
+ break;
+
+ case static::MSG_CALL:
+ array_shift($json);
+ $callID = array_shift($json);
+ $procURI = array_shift($json);
+
+ if (count($json) == 1 && is_array($json[0])) {
+ $json = $json[0];
+ }
+
+ $this->_decorating->onCall($from, $callID, $from->getUri($procURI), $json);
+ break;
+
+ case static::MSG_SUBSCRIBE:
+ $this->_decorating->onSubscribe($from, $from->getUri($json[1]));
+ break;
+
+ case static::MSG_UNSUBSCRIBE:
+ $this->_decorating->onUnSubscribe($from, $from->getUri($json[1]));
+ break;
+
+ case static::MSG_PUBLISH:
+ $exclude = (array_key_exists(3, $json) ? $json[3] : null);
+ if (!is_array($exclude)) {
+ if (true === (boolean)$exclude) {
+ $exclude = [$from->WAMP->sessionId];
+ } else {
+ $exclude = [];
+ }
+ }
+
+ $eligible = (array_key_exists(4, $json) ? $json[4] : []);
+
+ $this->_decorating->onPublish($from, $from->getUri($json[1]), $json[2], $exclude, $eligible);
+ break;
+
+ default:
+ throw new Exception('Invalid WAMP message type');
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onClose(ConnectionInterface $conn) {
+ $decor = $this->connections[$conn];
+ $this->connections->detach($conn);
+
+ $this->_decorating->onClose($decor);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onError(ConnectionInterface $conn, \Exception $e) {
+ return $this->_decorating->onError($this->connections[$conn], $e);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/Topic.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/Topic.php
new file mode 100644
index 0000000..bca8f67
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/Topic.php
@@ -0,0 +1,99 @@
+<?php
+namespace Ratchet\Wamp;
+use Ratchet\ConnectionInterface;
+
+/**
+ * A topic/channel containing connections that have subscribed to it
+ */
+class Topic implements \IteratorAggregate, \Countable {
+ private $id;
+
+ private $subscribers;
+
+ /**
+ * @param string $topicId Unique ID for this object
+ */
+ public function __construct($topicId) {
+ $this->id = $topicId;
+ $this->subscribers = new \SplObjectStorage;
+ }
+
+ /**
+ * @return string
+ */
+ public function getId() {
+ return $this->id;
+ }
+
+ public function __toString() {
+ return $this->getId();
+ }
+
+ /**
+ * Send a message to all the connections in this topic
+ * @param string|array $msg Payload to publish
+ * @param array $exclude A list of session IDs the message should be excluded from (blacklist)
+ * @param array $eligible A list of session Ids the message should be send to (whitelist)
+ * @return Topic The same Topic object to chain
+ */
+ public function broadcast($msg, array $exclude = array(), array $eligible = array()) {
+ $useEligible = (bool)count($eligible);
+ foreach ($this->subscribers as $client) {
+ if (in_array($client->WAMP->sessionId, $exclude)) {
+ continue;
+ }
+
+ if ($useEligible && !in_array($client->WAMP->sessionId, $eligible)) {
+ continue;
+ }
+
+ $client->event($this->id, $msg);
+ }
+
+ return $this;
+ }
+
+ /**
+ * @param WampConnection $conn
+ * @return boolean
+ */
+ public function has(ConnectionInterface $conn) {
+ return $this->subscribers->contains($conn);
+ }
+
+ /**
+ * @param WampConnection $conn
+ * @return Topic
+ */
+ public function add(ConnectionInterface $conn) {
+ $this->subscribers->attach($conn);
+
+ return $this;
+ }
+
+ /**
+ * @param WampConnection $conn
+ * @return Topic
+ */
+ public function remove(ConnectionInterface $conn) {
+ if ($this->subscribers->contains($conn)) {
+ $this->subscribers->detach($conn);
+ }
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getIterator() {
+ return $this->subscribers;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function count() {
+ return $this->subscribers->count();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/TopicManager.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/TopicManager.php
new file mode 100644
index 0000000..dd06ada
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/TopicManager.php
@@ -0,0 +1,125 @@
+<?php
+namespace Ratchet\Wamp;
+use Ratchet\ConnectionInterface;
+use Ratchet\WebSocket\WsServerInterface;
+
+class TopicManager implements WsServerInterface, WampServerInterface {
+ /**
+ * @var WampServerInterface
+ */
+ protected $app;
+
+ /**
+ * @var array
+ */
+ protected $topicLookup = array();
+
+ public function __construct(WampServerInterface $app) {
+ $this->app = $app;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onOpen(ConnectionInterface $conn) {
+ $conn->WAMP->subscriptions = new \SplObjectStorage;
+ $this->app->onOpen($conn);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onCall(ConnectionInterface $conn, $id, $topic, array $params) {
+ $this->app->onCall($conn, $id, $this->getTopic($topic), $params);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onSubscribe(ConnectionInterface $conn, $topic) {
+ $topicObj = $this->getTopic($topic);
+
+ if ($conn->WAMP->subscriptions->contains($topicObj)) {
+ return;
+ }
+
+ $this->topicLookup[$topic]->add($conn);
+ $conn->WAMP->subscriptions->attach($topicObj);
+ $this->app->onSubscribe($conn, $topicObj);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onUnsubscribe(ConnectionInterface $conn, $topic) {
+ $topicObj = $this->getTopic($topic);
+
+ if (!$conn->WAMP->subscriptions->contains($topicObj)) {
+ return;
+ }
+
+ $this->cleanTopic($topicObj, $conn);
+
+ $this->app->onUnsubscribe($conn, $topicObj);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onPublish(ConnectionInterface $conn, $topic, $event, array $exclude, array $eligible) {
+ $this->app->onPublish($conn, $this->getTopic($topic), $event, $exclude, $eligible);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onClose(ConnectionInterface $conn) {
+ $this->app->onClose($conn);
+
+ foreach ($this->topicLookup as $topic) {
+ $this->cleanTopic($topic, $conn);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onError(ConnectionInterface $conn, \Exception $e) {
+ $this->app->onError($conn, $e);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getSubProtocols() {
+ if ($this->app instanceof WsServerInterface) {
+ return $this->app->getSubProtocols();
+ }
+
+ return array();
+ }
+
+ /**
+ * @param string
+ * @return Topic
+ */
+ protected function getTopic($topic) {
+ if (!array_key_exists($topic, $this->topicLookup)) {
+ $this->topicLookup[$topic] = new Topic($topic);
+ }
+
+ return $this->topicLookup[$topic];
+ }
+
+ protected function cleanTopic(Topic $topic, ConnectionInterface $conn) {
+ if ($conn->WAMP->subscriptions->contains($topic)) {
+ $conn->WAMP->subscriptions->detach($topic);
+ }
+
+ $this->topicLookup[$topic->getId()]->remove($conn);
+
+ if (0 === $topic->count()) {
+ unset($this->topicLookup[$topic->getId()]);
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/WampConnection.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/WampConnection.php
new file mode 100644
index 0000000..dda1e4e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/WampConnection.php
@@ -0,0 +1,115 @@
+<?php
+namespace Ratchet\Wamp;
+use Ratchet\ConnectionInterface;
+use Ratchet\AbstractConnectionDecorator;
+use Ratchet\Wamp\ServerProtocol as WAMP;
+
+/**
+ * A ConnectionInterface object wrapper that is passed to your WAMP application
+ * representing a client. Methods on this Connection are therefore different.
+ * @property \stdClass $WAMP
+ */
+class WampConnection extends AbstractConnectionDecorator {
+ /**
+ * {@inheritdoc}
+ */
+ public function __construct(ConnectionInterface $conn) {
+ parent::__construct($conn);
+
+ $this->WAMP = new \StdClass;
+ $this->WAMP->sessionId = str_replace('.', '', uniqid(mt_rand(), true));
+ $this->WAMP->prefixes = array();
+
+ $this->send(json_encode(array(WAMP::MSG_WELCOME, $this->WAMP->sessionId, 1, \Ratchet\VERSION)));
+ }
+
+ /**
+ * Successfully respond to a call made by the client
+ * @param string $id The unique ID given by the client to respond to
+ * @param array $data an object or array
+ * @return WampConnection
+ */
+ public function callResult($id, $data = array()) {
+ return $this->send(json_encode(array(WAMP::MSG_CALL_RESULT, $id, $data)));
+ }
+
+ /**
+ * Respond with an error to a client call
+ * @param string $id The unique ID given by the client to respond to
+ * @param string $errorUri The URI given to identify the specific error
+ * @param string $desc A developer-oriented description of the error
+ * @param string $details An optional human readable detail message to send back
+ * @return WampConnection
+ */
+ public function callError($id, $errorUri, $desc = '', $details = null) {
+ if ($errorUri instanceof Topic) {
+ $errorUri = (string)$errorUri;
+ }
+
+ $data = array(WAMP::MSG_CALL_ERROR, $id, $errorUri, $desc);
+
+ if (null !== $details) {
+ $data[] = $details;
+ }
+
+ return $this->send(json_encode($data));
+ }
+
+ /**
+ * @param string $topic The topic to broadcast to
+ * @param mixed $msg Data to send with the event. Anything that is json'able
+ * @return WampConnection
+ */
+ public function event($topic, $msg) {
+ return $this->send(json_encode(array(WAMP::MSG_EVENT, (string)$topic, $msg)));
+ }
+
+ /**
+ * @param string $curie
+ * @param string $uri
+ * @return WampConnection
+ */
+ public function prefix($curie, $uri) {
+ $this->WAMP->prefixes[$curie] = (string)$uri;
+
+ return $this->send(json_encode(array(WAMP::MSG_PREFIX, $curie, (string)$uri)));
+ }
+
+ /**
+ * Get the full request URI from the connection object if a prefix has been established for it
+ * @param string $uri
+ * @return string
+ */
+ public function getUri($uri) {
+ $curieSeperator = ':';
+
+ if (preg_match('/http(s*)\:\/\//', $uri) == false) {
+ if (strpos($uri, $curieSeperator) !== false) {
+ list($prefix, $action) = explode($curieSeperator, $uri);
+
+ if(isset($this->WAMP->prefixes[$prefix]) === true){
+ return $this->WAMP->prefixes[$prefix] . '#' . $action;
+ }
+ }
+ }
+
+ return $uri;
+ }
+
+ /**
+ * @internal
+ */
+ public function send($data) {
+ $this->getConnection()->send($data);
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function close($opt = null) {
+ $this->getConnection()->close($opt);
+ }
+
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/WampServer.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/WampServer.php
new file mode 100644
index 0000000..5d710aa
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/WampServer.php
@@ -0,0 +1,67 @@
+<?php
+namespace Ratchet\Wamp;
+use Ratchet\MessageComponentInterface;
+use Ratchet\WebSocket\WsServerInterface;
+use Ratchet\ConnectionInterface;
+
+/**
+ * Enable support for the official WAMP sub-protocol in your application
+ * WAMP allows for Pub/Sub and RPC
+ * @link http://wamp.ws The WAMP specification
+ * @link https://github.com/oberstet/autobahn-js Souce for client side library
+ * @link http://autobahn.s3.amazonaws.com/js/autobahn.min.js Minified client side library
+ */
+class WampServer implements MessageComponentInterface, WsServerInterface {
+ /**
+ * @var ServerProtocol
+ */
+ protected $wampProtocol;
+
+ /**
+ * This class just makes it 1 step easier to use Topic objects in WAMP
+ * If you're looking at the source code, look in the __construct of this
+ * class and use that to make your application instead of using this
+ */
+ public function __construct(WampServerInterface $app) {
+ $this->wampProtocol = new ServerProtocol(new TopicManager($app));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onOpen(ConnectionInterface $conn) {
+ $this->wampProtocol->onOpen($conn);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onMessage(ConnectionInterface $conn, $msg) {
+ try {
+ $this->wampProtocol->onMessage($conn, $msg);
+ } catch (Exception $we) {
+ $conn->close(1007);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onClose(ConnectionInterface $conn) {
+ $this->wampProtocol->onClose($conn);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onError(ConnectionInterface $conn, \Exception $e) {
+ $this->wampProtocol->onError($conn, $e);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getSubProtocols() {
+ return $this->wampProtocol->getSubProtocols();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/WampServerInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/WampServerInterface.php
new file mode 100644
index 0000000..15c521d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/WampServerInterface.php
@@ -0,0 +1,43 @@
+<?php
+namespace Ratchet\Wamp;
+use Ratchet\ComponentInterface;
+use Ratchet\ConnectionInterface;
+
+/**
+ * An extension of Ratchet\ComponentInterface to server a WAMP application
+ * onMessage is replaced by various types of messages for this protocol (pub/sub or rpc)
+ */
+interface WampServerInterface extends ComponentInterface {
+ /**
+ * An RPC call has been received
+ * @param \Ratchet\ConnectionInterface $conn
+ * @param string $id The unique ID of the RPC, required to respond to
+ * @param string|Topic $topic The topic to execute the call against
+ * @param array $params Call parameters received from the client
+ */
+ function onCall(ConnectionInterface $conn, $id, $topic, array $params);
+
+ /**
+ * A request to subscribe to a topic has been made
+ * @param \Ratchet\ConnectionInterface $conn
+ * @param string|Topic $topic The topic to subscribe to
+ */
+ function onSubscribe(ConnectionInterface $conn, $topic);
+
+ /**
+ * A request to unsubscribe from a topic has been made
+ * @param \Ratchet\ConnectionInterface $conn
+ * @param string|Topic $topic The topic to unsubscribe from
+ */
+ function onUnSubscribe(ConnectionInterface $conn, $topic);
+
+ /**
+ * A client is attempting to publish content to a subscribed connections on a URI
+ * @param \Ratchet\ConnectionInterface $conn
+ * @param string|Topic $topic The topic the user has attempted to publish to
+ * @param string $event Payload of the publish
+ * @param array $exclude A list of session IDs the message should be excluded from (blacklist)
+ * @param array $eligible A list of session Ids the message should be send to (whitelist)
+ */
+ function onPublish(ConnectionInterface $conn, $topic, $event, array $exclude, array $eligible);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/ConnContext.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/ConnContext.php
new file mode 100644
index 0000000..2eba782
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/ConnContext.php
@@ -0,0 +1,20 @@
+<?php
+namespace Ratchet\WebSocket;
+use Ratchet\RFC6455\Messaging\MessageBuffer;
+
+class ConnContext {
+ /**
+ * @var \Ratchet\WebSocket\WsConnection
+ */
+ public $connection;
+
+ /**
+ * @var \Ratchet\RFC6455\Messaging\MessageBuffer;
+ */
+ public $buffer;
+
+ public function __construct(WsConnection $conn, MessageBuffer $buffer) {
+ $this->connection = $conn;
+ $this->buffer = $buffer;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/MessageCallableInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/MessageCallableInterface.php
new file mode 100644
index 0000000..b5c094e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/MessageCallableInterface.php
@@ -0,0 +1,8 @@
+<?php
+namespace Ratchet\WebSocket;
+use Ratchet\ConnectionInterface;
+use Ratchet\RFC6455\Messaging\MessageInterface;
+
+interface MessageCallableInterface {
+ public function onMessage(ConnectionInterface $conn, MessageInterface $msg);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/MessageComponentInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/MessageComponentInterface.php
new file mode 100644
index 0000000..fccd4e6
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/MessageComponentInterface.php
@@ -0,0 +1,6 @@
+<?php
+namespace Ratchet\WebSocket;
+use Ratchet\ComponentInterface;
+
+interface MessageComponentInterface extends ComponentInterface, MessageCallableInterface {
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/WsConnection.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/WsConnection.php
new file mode 100644
index 0000000..d2d04ef
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/WsConnection.php
@@ -0,0 +1,45 @@
+<?php
+namespace Ratchet\WebSocket;
+use Ratchet\AbstractConnectionDecorator;
+use Ratchet\RFC6455\Messaging\DataInterface;
+use Ratchet\RFC6455\Messaging\Frame;
+
+/**
+ * {@inheritdoc}
+ * @property \StdClass $WebSocket
+ */
+class WsConnection extends AbstractConnectionDecorator {
+ /**
+ * {@inheritdoc}
+ */
+ public function send($msg) {
+ if (!$this->WebSocket->closing) {
+ if (!($msg instanceof DataInterface)) {
+ $msg = new Frame($msg);
+ }
+
+ $this->getConnection()->send($msg->getContents());
+ }
+
+ return $this;
+ }
+
+ /**
+ * @param int|\Ratchet\RFC6455\Messaging\DataInterface
+ */
+ public function close($code = 1000) {
+ if ($this->WebSocket->closing) {
+ return;
+ }
+
+ if ($code instanceof DataInterface) {
+ $this->send($code);
+ } else {
+ $this->send(new Frame(pack('n', $code), true, Frame::OP_CLOSE));
+ }
+
+ $this->getConnection()->close();
+
+ $this->WebSocket->closing = true;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/WsServer.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/WsServer.php
new file mode 100644
index 0000000..8030604
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/WsServer.php
@@ -0,0 +1,225 @@
+<?php
+namespace Ratchet\WebSocket;
+use Ratchet\ComponentInterface;
+use Ratchet\ConnectionInterface;
+use Ratchet\MessageComponentInterface as DataComponentInterface;
+use Ratchet\Http\HttpServerInterface;
+use Ratchet\Http\CloseResponseTrait;
+use Psr\Http\Message\RequestInterface;
+use Ratchet\RFC6455\Messaging\MessageInterface;
+use Ratchet\RFC6455\Messaging\FrameInterface;
+use Ratchet\RFC6455\Messaging\Frame;
+use Ratchet\RFC6455\Messaging\MessageBuffer;
+use Ratchet\RFC6455\Messaging\CloseFrameChecker;
+use Ratchet\RFC6455\Handshake\ServerNegotiator;
+use Ratchet\RFC6455\Handshake\RequestVerifier;
+use React\EventLoop\LoopInterface;
+use GuzzleHttp\Psr7 as gPsr;
+
+/**
+ * The adapter to handle WebSocket requests/responses
+ * This is a mediator between the Server and your application to handle real-time messaging through a web browser
+ * @link http://ca.php.net/manual/en/ref.http.php
+ * @link http://dev.w3.org/html5/websockets/
+ */
+class WsServer implements HttpServerInterface {
+ use CloseResponseTrait;
+
+ /**
+ * Decorated component
+ * @var \Ratchet\ComponentInterface
+ */
+ private $delegate;
+
+ /**
+ * @var \SplObjectStorage
+ */
+ protected $connections;
+
+ /**
+ * @var \Ratchet\RFC6455\Messaging\CloseFrameChecker
+ */
+ private $closeFrameChecker;
+
+ /**
+ * @var \Ratchet\RFC6455\Handshake\ServerNegotiator
+ */
+ private $handshakeNegotiator;
+
+ /**
+ * @var \Closure
+ */
+ private $ueFlowFactory;
+
+ /**
+ * @var \Closure
+ */
+ private $pongReceiver;
+
+ /**
+ * @var \Closure
+ */
+ private $msgCb;
+
+ /**
+ * @param \Ratchet\WebSocket\MessageComponentInterface|\Ratchet\MessageComponentInterface $component Your application to run with WebSockets
+ * @note If you want to enable sub-protocols have your component implement WsServerInterface as well
+ */
+ public function __construct(ComponentInterface $component) {
+ if ($component instanceof MessageComponentInterface) {
+ $this->msgCb = function(ConnectionInterface $conn, MessageInterface $msg) {
+ $this->delegate->onMessage($conn, $msg);
+ };
+ } elseif ($component instanceof DataComponentInterface) {
+ $this->msgCb = function(ConnectionInterface $conn, MessageInterface $msg) {
+ $this->delegate->onMessage($conn, $msg->getPayload());
+ };
+ } else {
+ throw new \UnexpectedValueException('Expected instance of \Ratchet\WebSocket\MessageComponentInterface or \Ratchet\MessageComponentInterface');
+ }
+
+ if (bin2hex('✓') !== 'e29c93') {
+ throw new \DomainException('Bad encoding, unicode character ✓ did not match expected value. Ensure charset UTF-8 and check ini val mbstring.func_autoload');
+ }
+
+ $this->delegate = $component;
+ $this->connections = new \SplObjectStorage;
+
+ $this->closeFrameChecker = new CloseFrameChecker;
+ $this->handshakeNegotiator = new ServerNegotiator(new RequestVerifier);
+ $this->handshakeNegotiator->setStrictSubProtocolCheck(true);
+
+ if ($component instanceof WsServerInterface) {
+ $this->handshakeNegotiator->setSupportedSubProtocols($component->getSubProtocols());
+ }
+
+ $this->pongReceiver = function() {};
+
+ $reusableUnderflowException = new \UnderflowException;
+ $this->ueFlowFactory = function() use ($reusableUnderflowException) {
+ return $reusableUnderflowException;
+ };
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onOpen(ConnectionInterface $conn, RequestInterface $request = null) {
+ if (null === $request) {
+ throw new \UnexpectedValueException('$request can not be null');
+ }
+
+ $conn->httpRequest = $request;
+
+ $conn->WebSocket = new \StdClass;
+ $conn->WebSocket->closing = false;
+
+ $response = $this->handshakeNegotiator->handshake($request)->withHeader('X-Powered-By', \Ratchet\VERSION);
+
+ $conn->send(gPsr\str($response));
+
+ if (101 !== $response->getStatusCode()) {
+ return $conn->close();
+ }
+
+ $wsConn = new WsConnection($conn);
+
+ $streamer = new MessageBuffer(
+ $this->closeFrameChecker,
+ function(MessageInterface $msg) use ($wsConn) {
+ $cb = $this->msgCb;
+ $cb($wsConn, $msg);
+ },
+ function(FrameInterface $frame) use ($wsConn) {
+ $this->onControlFrame($frame, $wsConn);
+ },
+ true,
+ $this->ueFlowFactory
+ );
+
+ $this->connections->attach($conn, new ConnContext($wsConn, $streamer));
+
+ return $this->delegate->onOpen($wsConn);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onMessage(ConnectionInterface $from, $msg) {
+ if ($from->WebSocket->closing) {
+ return;
+ }
+
+ $this->connections[$from]->buffer->onData($msg);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onClose(ConnectionInterface $conn) {
+ if ($this->connections->contains($conn)) {
+ $context = $this->connections[$conn];
+ $this->connections->detach($conn);
+
+ $this->delegate->onClose($context->connection);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onError(ConnectionInterface $conn, \Exception $e) {
+ if ($this->connections->contains($conn)) {
+ $this->delegate->onError($this->connections[$conn]->connection, $e);
+ } else {
+ $conn->close();
+ }
+ }
+
+ public function onControlFrame(FrameInterface $frame, WsConnection $conn) {
+ switch ($frame->getOpCode()) {
+ case Frame::OP_CLOSE:
+ $conn->close($frame);
+ break;
+ case Frame::OP_PING:
+ $conn->send(new Frame($frame->getPayload(), true, Frame::OP_PONG));
+ break;
+ case Frame::OP_PONG:
+ $pongReceiver = $this->pongReceiver;
+ $pongReceiver($frame, $conn);
+ break;
+ }
+ }
+
+ public function setStrictSubProtocolCheck($enable) {
+ $this->handshakeNegotiator->setStrictSubProtocolCheck($enable);
+ }
+
+ public function enableKeepAlive(LoopInterface $loop, $interval = 30) {
+ $lastPing = new Frame(uniqid(), true, Frame::OP_PING);
+ $pingedConnections = new \SplObjectStorage;
+ $splClearer = new \SplObjectStorage;
+
+ $this->pongReceiver = function(FrameInterface $frame, $wsConn) use ($pingedConnections, &$lastPing) {
+ if ($frame->getPayload() === $lastPing->getPayload()) {
+ $pingedConnections->detach($wsConn);
+ }
+ };
+
+ $loop->addPeriodicTimer((int)$interval, function() use ($pingedConnections, &$lastPing, $splClearer) {
+ foreach ($pingedConnections as $wsConn) {
+ $wsConn->close();
+ }
+ $pingedConnections->removeAllExcept($splClearer);
+
+ $lastPing = new Frame(uniqid(), true, Frame::OP_PING);
+
+ foreach ($this->connections as $key => $conn) {
+ $wsConn = $this->connections[$conn]->connection;
+
+ $wsConn->send($lastPing);
+ $pingedConnections->attach($wsConn);
+ }
+ });
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/WsServerInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/WsServerInterface.php
new file mode 100644
index 0000000..15d1f7b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/WsServerInterface.php
@@ -0,0 +1,14 @@
+<?php
+namespace Ratchet\WebSocket;
+
+/**
+ * WebSocket Server Interface
+ */
+interface WsServerInterface {
+ /**
+ * If any component in a stack supports a WebSocket sub-protocol return each supported in an array
+ * @return array
+ * @todo This method may be removed in future version (note that will not break code, just make some code obsolete)
+ */
+ function getSubProtocols();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/autobahn/bin/fuzzingserver.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/autobahn/bin/fuzzingserver.php
new file mode 100644
index 0000000..66d3704
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/autobahn/bin/fuzzingserver.php
@@ -0,0 +1,36 @@
+<?php
+use Ratchet\ConnectionInterface;
+
+ require dirname(dirname(dirname(__DIR__))) . '/vendor/autoload.php';
+
+class BinaryEcho implements \Ratchet\WebSocket\MessageComponentInterface {
+ public function onMessage(ConnectionInterface $from, \Ratchet\RFC6455\Messaging\MessageInterface $msg) {
+ $from->send($msg);
+ }
+
+ public function onOpen(ConnectionInterface $conn) {
+ }
+
+ public function onClose(ConnectionInterface $conn) {
+ }
+
+ public function onError(ConnectionInterface $conn, \Exception $e) {
+ }
+}
+
+ $port = $argc > 1 ? $argv[1] : 8000;
+ $impl = sprintf('React\EventLoop\%sLoop', $argc > 2 ? $argv[2] : 'StreamSelect');
+
+ $loop = new $impl;
+ $sock = new React\Socket\Server('0.0.0.0:' . $port, $loop);
+
+ $wsServer = new Ratchet\WebSocket\WsServer(new BinaryEcho);
+ // This is enabled to test https://github.com/ratchetphp/Ratchet/issues/430
+ // The time is left at 10 minutes so that it will not try to every ping anything
+ // This causes the Ratchet server to crash on test 2.7
+ $wsServer->enableKeepAlive($loop, 600);
+
+ $app = new Ratchet\Http\HttpServer($wsServer);
+
+ $server = new Ratchet\Server\IoServer($app, $sock, $loop);
+ $server->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/autobahn/fuzzingclient-all.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/autobahn/fuzzingclient-all.json
new file mode 100644
index 0000000..0494cf3
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/autobahn/fuzzingclient-all.json
@@ -0,0 +1,15 @@
+{
+ "options": {"failByDrop": false}
+ , "outdir": "reports/ab"
+
+ , "servers": [
+ {"agent": "Ratchet/0.4 libevent", "url": "ws://localhost:8001", "options": {"version": 18}}
+ , {"agent": "Ratchet/0.4 libev", "url": "ws://localhost:8004", "options": {"version": 18}}
+ , {"agent": "Ratchet/0.4 streams", "url": "ws://localhost:8002", "options": {"version": 18}}
+ , {"agent": "AutobahnTestSuite/0.5.9", "url": "ws://localhost:8000", "options": {"version": 18}}
+ ]
+
+ , "cases": ["*"]
+ , "exclude-cases": []
+ , "exclude-agent-cases": {}
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/autobahn/fuzzingclient-profile.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/autobahn/fuzzingclient-profile.json
new file mode 100644
index 0000000..e81a9fd
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/autobahn/fuzzingclient-profile.json
@@ -0,0 +1,12 @@
+{
+ "options": {"failByDrop": false}
+ , "outdir": "reports/profile"
+
+ , "servers": [
+ {"agent": "Ratchet", "url": "ws://localhost:8000", "options": {"version": 18}}
+ ]
+
+ , "cases": ["9.7.4"]
+ , "exclude-cases": ["1.2.*", "2.3", "2.4", "2.6", "9.2.*", "9.4.*", "9.6.*", "9.8.*"]
+ , "exclude-agent-cases": {}
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/autobahn/fuzzingclient-quick.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/autobahn/fuzzingclient-quick.json
new file mode 100644
index 0000000..c92e805
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/autobahn/fuzzingclient-quick.json
@@ -0,0 +1,12 @@
+{
+ "options": {"failByDrop": false}
+ , "outdir": "reports/rfc"
+
+ , "servers": [
+ {"agent": "Ratchet", "url": "ws://localhost:8000", "options": {"version": 18}}
+ ]
+
+ , "cases": ["*"]
+ , "exclude-cases": []
+ , "exclude-agent-cases": {}
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/bootstrap.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/bootstrap.php
new file mode 100644
index 0000000..40791ba
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/bootstrap.php
@@ -0,0 +1,4 @@
+<?php
+
+ $loader = require __DIR__ . '/../vendor/autoload.php';
+ $loader->addPsr4('Ratchet\\', __DIR__ . '/helpers/Ratchet');
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/AbstractMessageComponentTestCase.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/AbstractMessageComponentTestCase.php
new file mode 100644
index 0000000..8c298e5
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/AbstractMessageComponentTestCase.php
@@ -0,0 +1,50 @@
+<?php
+namespace Ratchet;
+
+abstract class AbstractMessageComponentTestCase extends \PHPUnit_Framework_TestCase {
+ protected $_app;
+ protected $_serv;
+ protected $_conn;
+
+ abstract public function getConnectionClassString();
+ abstract public function getDecoratorClassString();
+ abstract public function getComponentClassString();
+
+ public function setUp() {
+ $this->_app = $this->getMock($this->getComponentClassString());
+ $decorator = $this->getDecoratorClassString();
+ $this->_serv = new $decorator($this->_app);
+ $this->_conn = $this->getMock('\Ratchet\ConnectionInterface');
+
+ $this->doOpen($this->_conn);
+ }
+
+ protected function doOpen($conn) {
+ $this->_serv->onOpen($conn);
+ }
+
+ public function isExpectedConnection() {
+ return new \PHPUnit_Framework_Constraint_IsInstanceOf($this->getConnectionClassString());
+ }
+
+ public function testOpen() {
+ $this->_app->expects($this->once())->method('onOpen')->with($this->isExpectedConnection());
+ $this->doOpen($this->getMock('\Ratchet\ConnectionInterface'));
+ }
+
+ public function testOnClose() {
+ $this->_app->expects($this->once())->method('onClose')->with($this->isExpectedConnection());
+ $this->_serv->onClose($this->_conn);
+ }
+
+ public function testOnError() {
+ $e = new \Exception('Whoops!');
+ $this->_app->expects($this->once())->method('onError')->with($this->isExpectedConnection(), $e);
+ $this->_serv->onError($this->_conn, $e);
+ }
+
+ public function passthroughMessageTest($value) {
+ $this->_app->expects($this->once())->method('onMessage')->with($this->isExpectedConnection(), $value);
+ $this->_serv->onMessage($this->_conn, $value);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/Component.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/Component.php
new file mode 100644
index 0000000..e152988
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/Component.php
@@ -0,0 +1,35 @@
+<?php
+namespace Ratchet\Mock;
+use Ratchet\MessageComponentInterface;
+use Ratchet\WebSocket\WsServerInterface;
+use Ratchet\ConnectionInterface;
+
+class Component implements MessageComponentInterface, WsServerInterface {
+ public $last = array();
+
+ public $protocols = array();
+
+ public function __construct(ComponentInterface $app = null) {
+ $this->last[__FUNCTION__] = func_get_args();
+ }
+
+ public function onOpen(ConnectionInterface $conn) {
+ $this->last[__FUNCTION__] = func_get_args();
+ }
+
+ public function onMessage(ConnectionInterface $from, $msg) {
+ $this->last[__FUNCTION__] = func_get_args();
+ }
+
+ public function onClose(ConnectionInterface $conn) {
+ $this->last[__FUNCTION__] = func_get_args();
+ }
+
+ public function onError(ConnectionInterface $conn, \Exception $e) {
+ $this->last[__FUNCTION__] = func_get_args();
+ }
+
+ public function getSubProtocols() {
+ return $this->protocols;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/Connection.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/Connection.php
new file mode 100644
index 0000000..5918296
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/Connection.php
@@ -0,0 +1,20 @@
+<?php
+namespace Ratchet\Mock;
+use Ratchet\ConnectionInterface;
+
+class Connection implements ConnectionInterface {
+ public $last = array(
+ 'send' => ''
+ , 'close' => false
+ );
+
+ public $remoteAddress = '127.0.0.1';
+
+ public function send($data) {
+ $this->last[__FUNCTION__] = $data;
+ }
+
+ public function close() {
+ $this->last[__FUNCTION__] = true;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/ConnectionDecorator.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/ConnectionDecorator.php
new file mode 100644
index 0000000..5570c07
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/ConnectionDecorator.php
@@ -0,0 +1,22 @@
+<?php
+namespace Ratchet\Mock;
+use Ratchet\AbstractConnectionDecorator;
+
+class ConnectionDecorator extends AbstractConnectionDecorator {
+ public $last = array(
+ 'write' => ''
+ , 'end' => false
+ );
+
+ public function send($data) {
+ $this->last[__FUNCTION__] = $data;
+
+ $this->getConnection()->send($data);
+ }
+
+ public function close() {
+ $this->last[__FUNCTION__] = true;
+
+ $this->getConnection()->close();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/WampComponent.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/WampComponent.php
new file mode 100644
index 0000000..cd526cb
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/WampComponent.php
@@ -0,0 +1,43 @@
+<?php
+namespace Ratchet\Mock;
+use Ratchet\Wamp\WampServerInterface;
+use Ratchet\WebSocket\WsServerInterface;
+use Ratchet\ConnectionInterface;
+
+class WampComponent implements WampServerInterface, WsServerInterface {
+ public $last = array();
+
+ public $protocols = array();
+
+ public function getSubProtocols() {
+ return $this->protocols;
+ }
+
+ public function onCall(ConnectionInterface $conn, $id, $procURI, array $params) {
+ $this->last[__FUNCTION__] = func_get_args();
+ }
+
+ public function onSubscribe(ConnectionInterface $conn, $topic) {
+ $this->last[__FUNCTION__] = func_get_args();
+ }
+
+ public function onUnSubscribe(ConnectionInterface $conn, $topic) {
+ $this->last[__FUNCTION__] = func_get_args();
+ }
+
+ public function onPublish(ConnectionInterface $conn, $topic, $event, array $exclude, array $eligible) {
+ $this->last[__FUNCTION__] = func_get_args();
+ }
+
+ public function onOpen(ConnectionInterface $conn) {
+ $this->last[__FUNCTION__] = func_get_args();
+ }
+
+ public function onClose(ConnectionInterface $conn) {
+ $this->last[__FUNCTION__] = func_get_args();
+ }
+
+ public function onError(ConnectionInterface $conn, \Exception $e) {
+ $this->last[__FUNCTION__] = func_get_args();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/NullComponent.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/NullComponent.php
new file mode 100644
index 0000000..90def21
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/NullComponent.php
@@ -0,0 +1,28 @@
+<?php
+namespace Ratchet;
+use Ratchet\ConnectionInterface;
+use Ratchet\MessageComponentInterface;
+use Ratchet\WebSocket\WsServerInterface;
+use Ratchet\Wamp\WampServerInterface;
+
+class NullComponent implements MessageComponentInterface, WsServerInterface, WampServerInterface {
+ public function onOpen(ConnectionInterface $conn) {}
+
+ public function onMessage(ConnectionInterface $conn, $msg) {}
+
+ public function onClose(ConnectionInterface $conn) {}
+
+ public function onError(ConnectionInterface $conn, \Exception $e) {}
+
+ public function onCall(ConnectionInterface $conn, $id, $topic, array $params) {}
+
+ public function onSubscribe(ConnectionInterface $conn, $topic) {}
+
+ public function onUnSubscribe(ConnectionInterface $conn, $topic) {}
+
+ public function onPublish(ConnectionInterface $conn, $topic, $event, array $exclude = array(), array $eligible = array()) {}
+
+ public function getSubProtocols() {
+ return array();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Wamp/Stub/WsWampServerInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Wamp/Stub/WsWampServerInterface.php
new file mode 100644
index 0000000..197bbd3
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Wamp/Stub/WsWampServerInterface.php
@@ -0,0 +1,7 @@
+<?php
+namespace Ratchet\Wamp\Stub;
+use Ratchet\WebSocket\WsServerInterface;
+use Ratchet\Wamp\WampServerInterface;
+
+interface WsWampServerInterface extends WsServerInterface, WampServerInterface {
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/WebSocket/Stub/WsMessageComponentInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/WebSocket/Stub/WsMessageComponentInterface.php
new file mode 100644
index 0000000..ef88325
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/WebSocket/Stub/WsMessageComponentInterface.php
@@ -0,0 +1,7 @@
+<?php
+namespace Ratchet\WebSocket\Stub;
+use Ratchet\MessageComponentInterface;
+use Ratchet\WebSocket\WsServerInterface;
+
+interface WsMessageComponentInterface extends MessageComponentInterface, WsServerInterface {
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/AbstractConnectionDecoratorTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/AbstractConnectionDecoratorTest.php
new file mode 100644
index 0000000..0887d3e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/AbstractConnectionDecoratorTest.php
@@ -0,0 +1,147 @@
+<?php
+namespace Ratchet;
+use Ratchet\Mock\ConnectionDecorator;
+
+/**
+ * @covers Ratchet\AbstractConnectionDecorator
+ * @covers Ratchet\ConnectionInterface
+ */
+class AbstractConnectionDecoratorTest extends \PHPUnit_Framework_TestCase {
+ protected $mock;
+ protected $l1;
+ protected $l2;
+
+ public function setUp() {
+ $this->mock = $this->getMock('\Ratchet\ConnectionInterface');
+ $this->l1 = new ConnectionDecorator($this->mock);
+ $this->l2 = new ConnectionDecorator($this->l1);
+ }
+
+ public function testGet() {
+ $var = 'hello';
+ $val = 'world';
+
+ $this->mock->$var = $val;
+
+ $this->assertEquals($val, $this->l1->$var);
+ $this->assertEquals($val, $this->l2->$var);
+ }
+
+ public function testSet() {
+ $var = 'Chris';
+ $val = 'Boden';
+
+ $this->l1->$var = $val;
+
+ $this->assertEquals($val, $this->mock->$var);
+ }
+
+ public function testSetLevel2() {
+ $var = 'Try';
+ $val = 'Again';
+
+ $this->l2->$var = $val;
+
+ $this->assertEquals($val, $this->mock->$var);
+ }
+
+ public function testIsSetTrue() {
+ $var = 'PHP';
+ $val = 'Ratchet';
+
+ $this->mock->$var = $val;
+
+ $this->assertTrue(isset($this->l1->$var));
+ $this->assertTrue(isset($this->l2->$var));
+ }
+
+ public function testIsSetFalse() {
+ $var = 'herp';
+ $val = 'derp';
+
+ $this->assertFalse(isset($this->l1->$var));
+ $this->assertFalse(isset($this->l2->$var));
+ }
+
+ public function testUnset() {
+ $var = 'Flying';
+ $val = 'Monkey';
+
+ $this->mock->$var = $val;
+ unset($this->l1->$var);
+
+ $this->assertFalse(isset($this->mock->$var));
+ }
+
+ public function testUnsetLevel2() {
+ $var = 'Flying';
+ $val = 'Monkey';
+
+ $this->mock->$var = $val;
+ unset($this->l2->$var);
+
+ $this->assertFalse(isset($this->mock->$var));
+ }
+
+ public function testGetConnection() {
+ $class = new \ReflectionClass('\\Ratchet\\AbstractConnectionDecorator');
+ $method = $class->getMethod('getConnection');
+ $method->setAccessible(true);
+
+ $conn = $method->invokeArgs($this->l1, array());
+
+ $this->assertSame($this->mock, $conn);
+ }
+
+ public function testGetConnectionLevel2() {
+ $class = new \ReflectionClass('\\Ratchet\\AbstractConnectionDecorator');
+ $method = $class->getMethod('getConnection');
+ $method->setAccessible(true);
+
+ $conn = $method->invokeArgs($this->l2, array());
+
+ $this->assertSame($this->l1, $conn);
+ }
+
+ public function testWrapperCanStoreSelfInDecorator() {
+ $this->mock->decorator = $this->l1;
+
+ $this->assertSame($this->l1, $this->l2->decorator);
+ }
+
+ public function testDecoratorRecursion() {
+ $this->mock->decorator = new \stdClass;
+ $this->mock->decorator->conn = $this->l1;
+
+ $this->assertSame($this->l1, $this->mock->decorator->conn);
+ $this->assertSame($this->l1, $this->l1->decorator->conn);
+ $this->assertSame($this->l1, $this->l2->decorator->conn);
+ }
+
+ public function testDecoratorRecursionLevel2() {
+ $this->mock->decorator = new \stdClass;
+ $this->mock->decorator->conn = $this->l2;
+
+ $this->assertSame($this->l2, $this->mock->decorator->conn);
+ $this->assertSame($this->l2, $this->l1->decorator->conn);
+ $this->assertSame($this->l2, $this->l2->decorator->conn);
+
+ // just for fun
+ $this->assertSame($this->l2, $this->l2->decorator->conn->decorator->conn->decorator->conn);
+ }
+
+ public function testWarningGettingNothing() {
+ $this->setExpectedException('PHPUnit_Framework_Error');
+ $var = $this->mock->nonExistant;
+ }
+
+ public function testWarningGettingNothingLevel1() {
+ $this->setExpectedException('PHPUnit_Framework_Error');
+ $var = $this->l1->nonExistant;
+ }
+
+ public function testWarningGettingNothingLevel2() {
+ $this->setExpectedException('PHPUnit_Framework_Error');
+ $var = $this->l2->nonExistant;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Http/HttpRequestParserTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Http/HttpRequestParserTest.php
new file mode 100644
index 0000000..6af8402
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Http/HttpRequestParserTest.php
@@ -0,0 +1,50 @@
+<?php
+namespace Ratchet\Http;
+
+/**
+ * @covers Ratchet\Http\HttpRequestParser
+ */
+class HttpRequestParserTest extends \PHPUnit_Framework_TestCase {
+ protected $parser;
+
+ public function setUp() {
+ $this->parser = new HttpRequestParser;
+ }
+
+ public function headersProvider() {
+ return array(
+ array(false, "GET / HTTP/1.1\r\nHost: socketo.me\r\n")
+ , array(true, "GET / HTTP/1.1\r\nHost: socketo.me\r\n\r\n")
+ , array(true, "GET / HTTP/1.1\r\nHost: socketo.me\r\n\r\n1")
+ , array(true, "GET / HTTP/1.1\r\nHost: socketo.me\r\n\r\nHixie✖")
+ , array(true, "GET / HTTP/1.1\r\nHost: socketo.me\r\n\r\nHixie✖\r\n\r\n")
+ , array(true, "GET / HTTP/1.1\r\nHost: socketo.me\r\n\r\nHixie\r\n")
+ );
+ }
+
+ /**
+ * @dataProvider headersProvider
+ */
+ public function testIsEom($expected, $message) {
+ $this->assertEquals($expected, $this->parser->isEom($message));
+ }
+
+ public function testBufferOverflowResponse() {
+ $conn = $this->getMock('\Ratchet\ConnectionInterface');
+
+ $this->parser->maxSize = 20;
+
+ $this->assertNull($this->parser->onMessage($conn, "GET / HTTP/1.1\r\n"));
+
+ $this->setExpectedException('OverflowException');
+
+ $this->parser->onMessage($conn, "Header-Is: Too Big");
+ }
+
+ public function testReturnTypeIsRequest() {
+ $conn = $this->getMock('\Ratchet\ConnectionInterface');
+ $return = $this->parser->onMessage($conn, "GET / HTTP/1.1\r\nHost: socketo.me\r\n\r\n");
+
+ $this->assertInstanceOf('\Psr\Http\Message\RequestInterface', $return);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Http/HttpServerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Http/HttpServerTest.php
new file mode 100644
index 0000000..7041d66
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Http/HttpServerTest.php
@@ -0,0 +1,64 @@
+<?php
+namespace Ratchet\Http;
+use Ratchet\AbstractMessageComponentTestCase;
+
+/**
+ * @covers Ratchet\Http\HttpServer
+ */
+class HttpServerTest extends AbstractMessageComponentTestCase {
+ public function setUp() {
+ parent::setUp();
+ $this->_conn->httpHeadersReceived = true;
+ }
+
+ public function getConnectionClassString() {
+ return '\Ratchet\ConnectionInterface';
+ }
+
+ public function getDecoratorClassString() {
+ return '\Ratchet\Http\HttpServer';
+ }
+
+ public function getComponentClassString() {
+ return '\Ratchet\Http\HttpServerInterface';
+ }
+
+ public function testOpen() {
+ $headers = "GET / HTTP/1.1\r\nHost: socketo.me\r\n\r\n";
+
+ $this->_conn->httpHeadersReceived = false;
+ $this->_app->expects($this->once())->method('onOpen')->with($this->isExpectedConnection());
+ $this->_serv->onMessage($this->_conn, $headers);
+ }
+
+ public function testOnMessageAfterHeaders() {
+ $headers = "GET / HTTP/1.1\r\nHost: socketo.me\r\n\r\n";
+ $this->_conn->httpHeadersReceived = false;
+ $this->_serv->onMessage($this->_conn, $headers);
+
+ $message = "Hello World!";
+ $this->_app->expects($this->once())->method('onMessage')->with($this->isExpectedConnection(), $message);
+ $this->_serv->onMessage($this->_conn, $message);
+ }
+
+ public function testBufferOverflow() {
+ $this->_conn->expects($this->once())->method('close');
+ $this->_conn->httpHeadersReceived = false;
+
+ $this->_serv->onMessage($this->_conn, str_repeat('a', 5000));
+ }
+
+ public function testCloseIfNotEstablished() {
+ $this->_conn->httpHeadersReceived = false;
+ $this->_conn->expects($this->once())->method('close');
+ $this->_serv->onError($this->_conn, new \Exception('Whoops!'));
+ }
+
+ public function testBufferHeaders() {
+ $this->_conn->httpHeadersReceived = false;
+ $this->_app->expects($this->never())->method('onOpen');
+ $this->_app->expects($this->never())->method('onMessage');
+
+ $this->_serv->onMessage($this->_conn, "GET / HTTP/1.1");
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Http/OriginCheckTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Http/OriginCheckTest.php
new file mode 100644
index 0000000..c1c4012
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Http/OriginCheckTest.php
@@ -0,0 +1,46 @@
+<?php
+namespace Ratchet\Http;
+use Ratchet\AbstractMessageComponentTestCase;
+
+/**
+ * @covers Ratchet\Http\OriginCheck
+ */
+class OriginCheckTest extends AbstractMessageComponentTestCase {
+ protected $_reqStub;
+
+ public function setUp() {
+ $this->_reqStub = $this->getMock('Psr\Http\Message\RequestInterface');
+ $this->_reqStub->expects($this->any())->method('getHeader')->will($this->returnValue(['localhost']));
+
+ parent::setUp();
+
+ $this->_serv->allowedOrigins[] = 'localhost';
+ }
+
+ protected function doOpen($conn) {
+ $this->_serv->onOpen($conn, $this->_reqStub);
+ }
+
+ public function getConnectionClassString() {
+ return '\Ratchet\ConnectionInterface';
+ }
+
+ public function getDecoratorClassString() {
+ return '\Ratchet\Http\OriginCheck';
+ }
+
+ public function getComponentClassString() {
+ return '\Ratchet\Http\HttpServerInterface';
+ }
+
+ public function testCloseOnNonMatchingOrigin() {
+ $this->_serv->allowedOrigins = ['socketo.me'];
+ $this->_conn->expects($this->once())->method('close');
+
+ $this->_serv->onOpen($this->_conn, $this->_reqStub);
+ }
+
+ public function testOnMessage() {
+ $this->passthroughMessageTest('Hello World!');
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Http/RouterTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Http/RouterTest.php
new file mode 100644
index 0000000..1ca4cbc
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Http/RouterTest.php
@@ -0,0 +1,165 @@
+<?php
+namespace Ratchet\Http;
+use Ratchet\WebSocket\WsServerInterface;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
+use Symfony\Component\Routing\RequestContext;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\Matcher\UrlMatcher;
+
+
+/**
+ * @covers Ratchet\Http\Router
+ */
+class RouterTest extends \PHPUnit_Framework_TestCase {
+ protected $_router;
+ protected $_matcher;
+ protected $_conn;
+ protected $_uri;
+ protected $_req;
+
+ public function setUp() {
+ $this->_conn = $this->getMock('\Ratchet\ConnectionInterface');
+ $this->_uri = $this->getMock('Psr\Http\Message\UriInterface');
+ $this->_req = $this->getMock('\Psr\Http\Message\RequestInterface');
+ $this->_req
+ ->expects($this->any())
+ ->method('getUri')
+ ->will($this->returnValue($this->_uri));
+ $this->_matcher = $this->getMock('Symfony\Component\Routing\Matcher\UrlMatcherInterface');
+ $this->_matcher
+ ->expects($this->any())
+ ->method('getContext')
+ ->will($this->returnValue($this->getMock('Symfony\Component\Routing\RequestContext')));
+ $this->_router = new Router($this->_matcher);
+
+ $this->_uri->expects($this->any())->method('getPath')->will($this->returnValue('ws://doesnt.matter/'));
+ $this->_uri->expects($this->any())->method('withQuery')->with($this->callback(function($val) {
+ $this->setResult($val);
+
+ return true;
+ }))->will($this->returnSelf());
+ $this->_uri->expects($this->any())->method('getQuery')->will($this->returnCallback([$this, 'getResult']));
+ $this->_req->expects($this->any())->method('withUri')->will($this->returnSelf());
+ }
+
+ public function testFourOhFour() {
+ $this->_conn->expects($this->once())->method('close');
+
+ $nope = new ResourceNotFoundException;
+ $this->_matcher->expects($this->any())->method('match')->will($this->throwException($nope));
+
+ $this->_router->onOpen($this->_conn, $this->_req);
+ }
+
+ public function testNullRequest() {
+ $this->setExpectedException('\UnexpectedValueException');
+ $this->_router->onOpen($this->_conn);
+ }
+
+ public function testControllerIsMessageComponentInterface() {
+ $this->setExpectedException('\UnexpectedValueException');
+ $this->_matcher->expects($this->any())->method('match')->will($this->returnValue(array('_controller' => new \StdClass)));
+ $this->_router->onOpen($this->_conn, $this->_req);
+ }
+
+ public function testControllerOnOpen() {
+ $controller = $this->getMockBuilder('\Ratchet\WebSocket\WsServer')->disableOriginalConstructor()->getMock();
+ $this->_matcher->expects($this->any())->method('match')->will($this->returnValue(array('_controller' => $controller)));
+ $this->_router->onOpen($this->_conn, $this->_req);
+
+ $expectedConn = new \PHPUnit_Framework_Constraint_IsInstanceOf('\Ratchet\ConnectionInterface');
+ $controller->expects($this->once())->method('onOpen')->with($expectedConn, $this->_req);
+
+ $this->_matcher->expects($this->any())->method('match')->will($this->returnValue(array('_controller' => $controller)));
+ $this->_router->onOpen($this->_conn, $this->_req);
+ }
+
+ public function testControllerOnMessageBubbles() {
+ $message = "The greatest trick the Devil ever pulled was convincing the world he didn't exist";
+ $controller = $this->getMockBuilder('\Ratchet\WebSocket\WsServer')->disableOriginalConstructor()->getMock();
+ $controller->expects($this->once())->method('onMessage')->with($this->_conn, $message);
+
+ $this->_conn->controller = $controller;
+
+ $this->_router->onMessage($this->_conn, $message);
+ }
+
+ public function testControllerOnCloseBubbles() {
+ $controller = $this->getMockBuilder('\Ratchet\WebSocket\WsServer')->disableOriginalConstructor()->getMock();
+ $controller->expects($this->once())->method('onClose')->with($this->_conn);
+
+ $this->_conn->controller = $controller;
+
+ $this->_router->onClose($this->_conn);
+ }
+
+ public function testControllerOnErrorBubbles() {
+ $e= new \Exception('One cannot be betrayed if one has no exceptions');
+ $controller = $this->getMockBuilder('\Ratchet\WebSocket\WsServer')->disableOriginalConstructor()->getMock();
+ $controller->expects($this->once())->method('onError')->with($this->_conn, $e);
+
+ $this->_conn->controller = $controller;
+
+ $this->_router->onError($this->_conn, $e);
+ }
+
+ public function testRouterGeneratesRouteParameters() {
+ /** @var $controller WsServerInterface */
+ $controller = $this->getMockBuilder('\Ratchet\WebSocket\WsServer')->disableOriginalConstructor()->getMock();
+ /** @var $matcher UrlMatcherInterface */
+ $this->_matcher->expects($this->any())->method('match')->will(
+ $this->returnValue(['_controller' => $controller, 'foo' => 'bar', 'baz' => 'qux'])
+ );
+ $conn = $this->getMock('Ratchet\Mock\Connection');
+
+ $router = new Router($this->_matcher);
+
+ $router->onOpen($conn, $this->_req);
+
+ $this->assertEquals('foo=bar&baz=qux', $this->_req->getUri()->getQuery());
+ }
+
+ public function testQueryParams() {
+ $controller = $this->getMockBuilder('\Ratchet\WebSocket\WsServer')->disableOriginalConstructor()->getMock();
+ $this->_matcher->expects($this->any())->method('match')->will(
+ $this->returnValue(['_controller' => $controller, 'foo' => 'bar', 'baz' => 'qux'])
+ );
+
+ $conn = $this->getMock('Ratchet\Mock\Connection');
+ $request = $this->getMock('Psr\Http\Message\RequestInterface');
+ $uri = new \GuzzleHttp\Psr7\Uri('ws://doesnt.matter/endpoint?hello=world&foo=nope');
+
+ $request->expects($this->any())->method('getUri')->will($this->returnCallback(function() use (&$uri) {
+ return $uri;
+ }));
+ $request->expects($this->any())->method('withUri')->with($this->callback(function($url) use (&$uri) {
+ $uri = $url;
+
+ return true;
+ }))->will($this->returnSelf());
+
+ $router = new Router($this->_matcher);
+ $router->onOpen($conn, $request);
+
+ $this->assertEquals('foo=nope&baz=qux&hello=world', $request->getUri()->getQuery());
+ $this->assertEquals('ws', $request->getUri()->getScheme());
+ $this->assertEquals('doesnt.matter', $request->getUri()->getHost());
+ }
+
+ public function testImpatientClientOverflow() {
+ $this->_conn->expects($this->once())->method('close');
+
+ $header = "GET /nope HTTP/1.1
+Upgrade: websocket
+Connection: upgrade
+Host: localhost
+Origin: http://localhost
+Sec-WebSocket-Version: 13\r\n\r\n";
+
+ $app = new HttpServer(new Router(new UrlMatcher(new RouteCollection, new RequestContext)));
+ $app->onOpen($this->_conn);
+ $app->onMessage($this->_conn, $header);
+ $app->onMessage($this->_conn, 'Silly body');
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Server/EchoServerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Server/EchoServerTest.php
new file mode 100644
index 0000000..47fb0e2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Server/EchoServerTest.php
@@ -0,0 +1,26 @@
+<?php
+namespace Ratchet\Server;
+use Ratchet\Server\EchoServer;
+
+class EchoServerTest extends \PHPUnit_Framework_TestCase {
+ protected $_conn;
+ protected $_comp;
+
+ public function setUp() {
+ $this->_conn = $this->getMock('\Ratchet\ConnectionInterface');
+ $this->_comp = new EchoServer;
+ }
+
+ public function testMessageEchod() {
+ $message = 'Tillsonburg, my back still aches when I hear that word.';
+ $this->_conn->expects($this->once())->method('send')->with($message);
+ $this->_comp->onMessage($this->_conn, $message);
+ }
+
+ public function testErrorClosesConnection() {
+ ob_start();
+ $this->_conn->expects($this->once())->method('close');
+ $this->_comp->onError($this->_conn, new \Exception);
+ ob_end_clean();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Server/FlashPolicyComponentTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Server/FlashPolicyComponentTest.php
new file mode 100644
index 0000000..38fc96a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Server/FlashPolicyComponentTest.php
@@ -0,0 +1,152 @@
+<?php
+namespace Ratchet\Application\Server;
+use Ratchet\Server\FlashPolicy;
+
+/**
+ * @covers Ratchet\Server\FlashPolicy
+ */
+class FlashPolicyTest extends \PHPUnit_Framework_TestCase {
+
+ protected $_policy;
+
+ public function setUp() {
+ $this->_policy = new FlashPolicy();
+ }
+
+ public function testPolicyRender() {
+ $this->_policy->setSiteControl('all');
+ $this->_policy->addAllowedAccess('example.com', '*');
+ $this->_policy->addAllowedAccess('dev.example.com', '*');
+
+ $this->assertInstanceOf('SimpleXMLElement', $this->_policy->renderPolicy());
+ }
+
+ public function testInvalidPolicyReader() {
+ $this->setExpectedException('UnexpectedValueException');
+ $this->_policy->renderPolicy();
+ }
+
+ public function testInvalidDomainPolicyReader() {
+ $this->setExpectedException('UnexpectedValueException');
+ $this->_policy->setSiteControl('all');
+ $this->_policy->addAllowedAccess('dev.example.*', '*');
+ $this->_policy->renderPolicy();
+ }
+
+ /**
+ * @dataProvider siteControl
+ */
+ public function testSiteControlValidation($accept, $permittedCrossDomainPolicies) {
+ $this->assertEquals($accept, $this->_policy->validateSiteControl($permittedCrossDomainPolicies));
+ }
+
+ public static function siteControl() {
+ return array(
+ array(true, 'all')
+ , array(true, 'none')
+ , array(true, 'master-only')
+ , array(false, 'by-content-type')
+ , array(false, 'by-ftp-filename')
+ , array(false, '')
+ , array(false, 'all ')
+ , array(false, 'asdf')
+ , array(false, '@893830')
+ , array(false, '*')
+ );
+ }
+
+ /**
+ * @dataProvider URI
+ */
+ public function testDomainValidation($accept, $domain) {
+ $this->assertEquals($accept, $this->_policy->validateDomain($domain));
+ }
+
+ public static function URI() {
+ return array(
+ array(true, '*')
+ , array(true, 'example.com')
+ , array(true, 'exam-ple.com')
+ , array(true, '*.example.com')
+ , array(true, 'www.example.com')
+ , array(true, 'dev.dev.example.com')
+ , array(true, 'http://example.com')
+ , array(true, 'https://example.com')
+ , array(true, 'http://*.example.com')
+ , array(false, 'exam*ple.com')
+ , array(true, '127.0.255.1')
+ , array(true, 'localhost')
+ , array(false, 'www.example.*')
+ , array(false, 'www.exa*le.com')
+ , array(false, 'www.example.*com')
+ , array(false, '*.example.*')
+ , array(false, 'gasldf*$#a0sdf0a8sdf')
+ );
+ }
+
+ /**
+ * @dataProvider ports
+ */
+ public function testPortValidation($accept, $ports) {
+ $this->assertEquals($accept, $this->_policy->validatePorts($ports));
+ }
+
+ public static function ports() {
+ return array(
+ array(true, '*')
+ , array(true, '80')
+ , array(true, '80,443')
+ , array(true, '507,516-523')
+ , array(true, '507,516-523,333')
+ , array(true, '507,516-523,507,516-523')
+ , array(false, '516-')
+ , array(true, '516-523,11')
+ , array(false, '516,-523,11')
+ , array(false, 'example')
+ , array(false, 'asdf,123')
+ , array(false, '--')
+ , array(false, ',,,')
+ , array(false, '838*')
+ );
+ }
+
+ public function testAddAllowedAccessOnlyAcceptsValidPorts() {
+ $this->setExpectedException('UnexpectedValueException');
+
+ $this->_policy->addAllowedAccess('*', 'nope');
+ }
+
+ public function testSetSiteControlThrowsException() {
+ $this->setExpectedException('UnexpectedValueException');
+
+ $this->_policy->setSiteControl('nope');
+ }
+
+ public function testErrorClosesConnection() {
+ $conn = $this->getMock('\\Ratchet\\ConnectionInterface');
+ $conn->expects($this->once())->method('close');
+
+ $this->_policy->onError($conn, new \Exception);
+ }
+
+ public function testOnMessageSendsString() {
+ $this->_policy->addAllowedAccess('*', '*');
+
+ $conn = $this->getMock('\\Ratchet\\ConnectionInterface');
+ $conn->expects($this->once())->method('send')->with($this->isType('string'));
+
+ $this->_policy->onMessage($conn, ' ');
+ }
+
+ public function testOnOpenExists() {
+ $this->assertTrue(method_exists($this->_policy, 'onOpen'));
+ $conn = $this->getMock('\Ratchet\ConnectionInterface');
+ $this->_policy->onOpen($conn);
+ }
+
+ public function testOnCloseExists() {
+ $this->assertTrue(method_exists($this->_policy, 'onClose'));
+ $conn = $this->getMock('\Ratchet\ConnectionInterface');
+ $this->_policy->onClose($conn);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Server/IoConnectionTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Server/IoConnectionTest.php
new file mode 100644
index 0000000..07130f6
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Server/IoConnectionTest.php
@@ -0,0 +1,32 @@
+<?php
+namespace Ratchet\Application\Server;
+use Ratchet\Server\IoConnection;
+
+/**
+ * @covers Ratchet\Server\IoConnection
+ */
+class IoConnectionTest extends \PHPUnit_Framework_TestCase {
+ protected $sock;
+ protected $conn;
+
+ public function setUp() {
+ $this->sock = $this->getMock('\\React\\Socket\\ConnectionInterface');
+ $this->conn = new IoConnection($this->sock);
+ }
+
+ public function testCloseBubbles() {
+ $this->sock->expects($this->once())->method('end');
+ $this->conn->close();
+ }
+
+ public function testSendBubbles() {
+ $msg = '6 hour rides are productive';
+
+ $this->sock->expects($this->once())->method('write')->with($msg);
+ $this->conn->send($msg);
+ }
+
+ public function testSendReturnsSelf() {
+ $this->assertSame($this->conn, $this->conn->send('fluent interface'));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Server/IoServerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Server/IoServerTest.php
new file mode 100644
index 0000000..284fbde
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Server/IoServerTest.php
@@ -0,0 +1,118 @@
+<?php
+namespace Ratchet\Server;
+use Ratchet\Server\IoServer;
+use React\EventLoop\StreamSelectLoop;
+use React\Socket\Server;
+
+/**
+ * @covers Ratchet\Server\IoServer
+ */
+class IoServerTest extends \PHPUnit_Framework_TestCase {
+ protected $server;
+
+ protected $app;
+
+ protected $port;
+
+ protected $reactor;
+
+ public function setUp() {
+ $this->app = $this->getMock('\\Ratchet\\MessageComponentInterface');
+
+ $loop = new StreamSelectLoop;
+ $this->reactor = new Server(0, $loop);
+
+ $uri = $this->reactor->getAddress();
+ $this->port = parse_url((strpos($uri, '://') === false ? 'tcp://' : '') . $uri, PHP_URL_PORT);
+ $this->server = new IoServer($this->app, $this->reactor, $loop);
+ }
+
+ public function testOnOpen() {
+ $this->app->expects($this->once())->method('onOpen')->with($this->isInstanceOf('\\Ratchet\\ConnectionInterface'));
+
+ $client = stream_socket_client("tcp://localhost:{$this->port}");
+
+ $this->server->loop->tick();
+
+ //$this->assertTrue(is_string($this->app->last['onOpen'][0]->remoteAddress));
+ //$this->assertTrue(is_int($this->app->last['onOpen'][0]->resourceId));
+ }
+
+ public function testOnData() {
+ $msg = 'Hello World!';
+
+ $this->app->expects($this->once())->method('onMessage')->with(
+ $this->isInstanceOf('\\Ratchet\\ConnectionInterface')
+ , $msg
+ );
+
+ $client = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
+ socket_set_option($client, SOL_SOCKET, SO_REUSEADDR, 1);
+ socket_set_option($client, SOL_SOCKET, SO_SNDBUF, 4096);
+ socket_set_block($client);
+ socket_connect($client, 'localhost', $this->port);
+
+ $this->server->loop->tick();
+
+ socket_write($client, $msg);
+ $this->server->loop->tick();
+
+ socket_shutdown($client, 1);
+ socket_shutdown($client, 0);
+ socket_close($client);
+
+ $this->server->loop->tick();
+ }
+
+ public function testOnClose() {
+ $this->app->expects($this->once())->method('onClose')->with($this->isInstanceOf('\\Ratchet\\ConnectionInterface'));
+
+ $client = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
+ socket_set_option($client, SOL_SOCKET, SO_REUSEADDR, 1);
+ socket_set_option($client, SOL_SOCKET, SO_SNDBUF, 4096);
+ socket_set_block($client);
+ socket_connect($client, 'localhost', $this->port);
+
+ $this->server->loop->tick();
+
+ socket_shutdown($client, 1);
+ socket_shutdown($client, 0);
+ socket_close($client);
+
+ $this->server->loop->tick();
+ }
+
+ public function testFactory() {
+ $this->assertInstanceOf('\\Ratchet\\Server\\IoServer', IoServer::factory($this->app, 0));
+ }
+
+ public function testNoLoopProvidedError() {
+ $this->setExpectedException('RuntimeException');
+
+ $io = new IoServer($this->app, $this->reactor);
+ $io->run();
+ }
+
+ public function testOnErrorPassesException() {
+ $conn = $this->getMock('\\React\\Socket\\ConnectionInterface');
+ $conn->decor = $this->getMock('\\Ratchet\\ConnectionInterface');
+ $err = new \Exception("Nope");
+
+ $this->app->expects($this->once())->method('onError')->with($conn->decor, $err);
+
+ $this->server->handleError($err, $conn);
+ }
+
+ public function onErrorCalledWhenExceptionThrown() {
+ $this->markTestIncomplete("Need to learn how to throw an exception from a mock");
+
+ $conn = $this->getMock('\\React\\Socket\\ConnectionInterface');
+ $this->server->handleConnect($conn);
+
+ $e = new \Exception;
+ $this->app->expects($this->once())->method('onMessage')->with($this->isInstanceOf('\\Ratchet\\ConnectionInterface'), 'f')->will($e);
+ $this->app->expects($this->once())->method('onError')->with($this->instanceOf('\\Ratchet\\ConnectionInterface', $e));
+
+ $this->server->handleData('f', $conn);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Server/IpBlackListComponentTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Server/IpBlackListComponentTest.php
new file mode 100644
index 0000000..90f4185
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Server/IpBlackListComponentTest.php
@@ -0,0 +1,125 @@
+<?php
+namespace Ratchet\Server;
+use Ratchet\Server\IpBlackList;
+
+/**
+ * @covers Ratchet\Server\IpBlackList
+ */
+class IpBlackListTest extends \PHPUnit_Framework_TestCase {
+ protected $blocker;
+ protected $mock;
+
+ public function setUp() {
+ $this->mock = $this->getMock('\\Ratchet\\MessageComponentInterface');
+ $this->blocker = new IpBlackList($this->mock);
+ }
+
+ public function testOnOpen() {
+ $this->mock->expects($this->exactly(3))->method('onOpen');
+
+ $conn1 = $this->newConn();
+ $conn2 = $this->newConn();
+ $conn3 = $this->newConn();
+
+ $this->blocker->onOpen($conn1);
+ $this->blocker->onOpen($conn3);
+ $this->blocker->onOpen($conn2);
+ }
+
+ public function testBlockDoesNotTriggerOnOpen() {
+ $conn = $this->newConn();
+
+ $this->blocker->blockAddress($conn->remoteAddress);
+
+ $this->mock->expects($this->never())->method('onOpen');
+
+ $ret = $this->blocker->onOpen($conn);
+ }
+
+ public function testBlockDoesNotTriggerOnClose() {
+ $conn = $this->newConn();
+
+ $this->blocker->blockAddress($conn->remoteAddress);
+
+ $this->mock->expects($this->never())->method('onClose');
+
+ $ret = $this->blocker->onOpen($conn);
+ }
+
+ public function testOnMessageDecoration() {
+ $conn = $this->newConn();
+ $msg = 'Hello not being blocked';
+
+ $this->mock->expects($this->once())->method('onMessage')->with($conn, $msg);
+
+ $this->blocker->onMessage($conn, $msg);
+ }
+
+ public function testOnCloseDecoration() {
+ $conn = $this->newConn();
+
+ $this->mock->expects($this->once())->method('onClose')->with($conn);
+
+ $this->blocker->onClose($conn);
+ }
+
+ public function testBlockClosesConnection() {
+ $conn = $this->newConn();
+ $this->blocker->blockAddress($conn->remoteAddress);
+
+ $conn->expects($this->once())->method('close');
+
+ $this->blocker->onOpen($conn);
+ }
+
+ public function testAddAndRemoveWithFluentInterfaces() {
+ $blockOne = '127.0.0.1';
+ $blockTwo = '192.168.1.1';
+ $unblock = '75.119.207.140';
+
+ $this->blocker
+ ->blockAddress($unblock)
+ ->blockAddress($blockOne)
+ ->unblockAddress($unblock)
+ ->blockAddress($blockTwo)
+ ;
+
+ $this->assertEquals(array($blockOne, $blockTwo), $this->blocker->getBlockedAddresses());
+ }
+
+ public function testDecoratorPassesErrors() {
+ $conn = $this->newConn();
+ $e = new \Exception('I threw an error');
+
+ $this->mock->expects($this->once())->method('onError')->with($conn, $e);
+
+ $this->blocker->onError($conn, $e);
+ }
+
+ public function addressProvider() {
+ return array(
+ array('127.0.0.1', '127.0.0.1')
+ , array('localhost', 'localhost')
+ , array('fe80::1%lo0', 'fe80::1%lo0')
+ , array('127.0.0.1', '127.0.0.1:6392')
+ );
+ }
+
+ /**
+ * @dataProvider addressProvider
+ */
+ public function testFilterAddress($expected, $input) {
+ $this->assertEquals($expected, $this->blocker->filterAddress($input));
+ }
+
+ public function testUnblockingSilentlyFails() {
+ $this->assertInstanceOf('\\Ratchet\\Server\\IpBlackList', $this->blocker->unblockAddress('localhost'));
+ }
+
+ protected function newConn() {
+ $conn = $this->getMock('\\Ratchet\\ConnectionInterface');
+ $conn->remoteAddress = '127.0.0.1';
+
+ return $conn;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Session/Serialize/PhpHandlerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Session/Serialize/PhpHandlerTest.php
new file mode 100644
index 0000000..4acf5bc
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Session/Serialize/PhpHandlerTest.php
@@ -0,0 +1,43 @@
+<?php
+namespace Ratchet\Session\Serialize;
+use Ratchet\Session\Serialize\PhpHandler;
+
+/**
+ * @covers Ratchet\Session\Serialize\PhpHandler
+ */
+class PhpHandlerTest extends \PHPUnit_Framework_TestCase {
+ protected $_handler;
+
+ public function setUp() {
+ $this->_handler = new PhpHandler;
+ }
+
+ public function serializedProvider() {
+ return array(
+ array(
+ '_sf2_attributes|a:2:{s:5:"hello";s:5:"world";s:4:"last";i:1332872102;}_sf2_flashes|a:0:{}'
+ , array(
+ '_sf2_attributes' => array(
+ 'hello' => 'world'
+ , 'last' => 1332872102
+ )
+ , '_sf2_flashes' => array()
+ )
+ )
+ );
+ }
+
+ /**
+ * @dataProvider serializedProvider
+ */
+ public function testUnserialize($in, $expected) {
+ $this->assertEquals($expected, $this->_handler->unserialize($in));
+ }
+
+ /**
+ * @dataProvider serializedProvider
+ */
+ public function testSerialize($serialized, $original) {
+ $this->assertEquals($serialized, $this->_handler->serialize($original));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Session/SessionComponentTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Session/SessionComponentTest.php
new file mode 100644
index 0000000..ebfdde4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Session/SessionComponentTest.php
@@ -0,0 +1,124 @@
+<?php
+namespace Ratchet\Session;
+use Ratchet\AbstractMessageComponentTestCase;
+use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
+use Symfony\Component\HttpFoundation\Session\Storage\Handler\NullSessionHandler;
+
+/**
+ * @covers Ratchet\Session\SessionProvider
+ * @covers Ratchet\Session\Storage\VirtualSessionStorage
+ * @covers Ratchet\Session\Storage\Proxy\VirtualProxy
+ */
+class SessionProviderTest extends AbstractMessageComponentTestCase {
+ public function setUp() {
+ if (!class_exists('Symfony\Component\HttpFoundation\Session\Session')) {
+ return $this->markTestSkipped('Dependency of Symfony HttpFoundation failed');
+ }
+
+ parent::setUp();
+ $this->_serv = new SessionProvider($this->_app, new NullSessionHandler);
+ }
+
+ public function tearDown() {
+ ini_set('session.serialize_handler', 'php');
+ }
+
+ public function getConnectionClassString() {
+ return '\Ratchet\ConnectionInterface';
+ }
+
+ public function getDecoratorClassString() {
+ return '\Ratchet\NullComponent';
+ }
+
+ public function getComponentClassString() {
+ return '\Ratchet\Http\HttpServerInterface';
+ }
+
+ public function classCaseProvider() {
+ return array(
+ array('php', 'Php')
+ , array('php_binary', 'PhpBinary')
+ );
+ }
+
+ /**
+ * @dataProvider classCaseProvider
+ */
+ public function testToClassCase($in, $out) {
+ $ref = new \ReflectionClass('\\Ratchet\\Session\\SessionProvider');
+ $method = $ref->getMethod('toClassCase');
+ $method->setAccessible(true);
+
+ $component = new SessionProvider($this->getMock($this->getComponentClassString()), $this->getMock('\SessionHandlerInterface'));
+ $this->assertEquals($out, $method->invokeArgs($component, array($in)));
+ }
+
+ /**
+ * I think I have severely butchered this test...it's not so much of a unit test as it is a full-fledged component test
+ */
+ public function testConnectionValueFromPdo() {
+ if (!extension_loaded('PDO') || !extension_loaded('pdo_sqlite')) {
+ return $this->markTestSkipped('Session test requires PDO and pdo_sqlite');
+ }
+
+ $sessionId = md5('testSession');
+
+ $dbOptions = array(
+ 'db_table' => 'sessions'
+ , 'db_id_col' => 'sess_id'
+ , 'db_data_col' => 'sess_data'
+ , 'db_time_col' => 'sess_time'
+ , 'db_lifetime_col' => 'sess_lifetime'
+ );
+
+ $pdo = new \PDO("sqlite::memory:");
+ $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+ $pdo->exec(vsprintf("CREATE TABLE %s (%s TEXT NOT NULL PRIMARY KEY, %s BLOB NOT NULL, %s INTEGER NOT NULL, %s INTEGER)", $dbOptions));
+
+ $pdoHandler = new PdoSessionHandler($pdo, $dbOptions);
+ $pdoHandler->write($sessionId, '_sf2_attributes|a:2:{s:5:"hello";s:5:"world";s:4:"last";i:1332872102;}_sf2_flashes|a:0:{}');
+
+ $component = new SessionProvider($this->getMock($this->getComponentClassString()), $pdoHandler, array('auto_start' => 1));
+ $connection = $this->getMock('Ratchet\\ConnectionInterface');
+
+ $headers = $this->getMock('Psr\Http\Message\RequestInterface');
+ $headers->expects($this->once())->method('getHeader')->will($this->returnValue([ini_get('session.name') . "={$sessionId};"]));
+
+ $component->onOpen($connection, $headers);
+
+ $this->assertEquals('world', $connection->Session->get('hello'));
+ }
+
+ protected function newConn() {
+ $conn = $this->getMock('Ratchet\ConnectionInterface');
+
+ $headers = $this->getMock('Psr\Http\Message\Request', array('getCookie'), array('POST', '/', array()));
+ $headers->expects($this->once())->method('getCookie', array(ini_get('session.name')))->will($this->returnValue(null));
+
+ return $conn;
+ }
+
+ public function testOnMessageDecorator() {
+ $message = "Database calls are usually blocking :(";
+ $this->_app->expects($this->once())->method('onMessage')->with($this->isExpectedConnection(), $message);
+ $this->_serv->onMessage($this->_conn, $message);
+ }
+
+ public function testRejectInvalidSeralizers() {
+ if (!function_exists('wddx_serialize_value')) {
+ $this->markTestSkipped();
+ }
+
+ ini_set('session.serialize_handler', 'wddx');
+ $this->setExpectedException('\RuntimeException');
+ new SessionProvider($this->getMock($this->getComponentClassString()), $this->getMock('\SessionHandlerInterface'));
+ }
+
+ protected function doOpen($conn) {
+ $request = $this->getMock('Psr\Http\Message\RequestInterface');
+ $request->expects($this->any())->method('getHeader')->will($this->returnValue([]));
+
+ $this->_serv->onOpen($conn, $request);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Session/Storage/VirtualSessionStoragePDOTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Session/Storage/VirtualSessionStoragePDOTest.php
new file mode 100644
index 0000000..2727484
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Session/Storage/VirtualSessionStoragePDOTest.php
@@ -0,0 +1,53 @@
+<?php
+namespace Ratchet\Session\Storage;
+use Ratchet\Session\Serialize\PhpHandler;
+use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
+use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;
+use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
+
+class VirtualSessionStoragePDOTest extends \PHPUnit_Framework_TestCase {
+ /**
+ * @var VirtualSessionStorage
+ */
+ protected $_virtualSessionStorage;
+
+ protected $_pathToDB;
+
+ public function setUp() {
+ if (!extension_loaded('PDO') || !extension_loaded('pdo_sqlite')) {
+ return $this->markTestSkipped('Session test requires PDO and pdo_sqlite');
+ }
+
+ $schema = <<<SQL
+CREATE TABLE `sessions` (
+ `sess_id` VARBINARY(128) NOT NULL PRIMARY KEY,
+ `sess_data` BLOB NOT NULL,
+ `sess_time` INTEGER UNSIGNED NOT NULL,
+ `sess_lifetime` MEDIUMINT NOT NULL
+);
+SQL;
+ $this->_pathToDB = tempnam(sys_get_temp_dir(), 'SQ3');;
+ $dsn = 'sqlite:' . $this->_pathToDB;
+
+ $pdo = new \PDO($dsn);
+ $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+ $pdo->exec($schema);
+ $pdo = null;
+
+ $sessionHandler = new PdoSessionHandler($dsn);
+ $serializer = new PhpHandler();
+ $this->_virtualSessionStorage = new VirtualSessionStorage($sessionHandler, 'foobar', $serializer);
+ $this->_virtualSessionStorage->registerBag(new FlashBag());
+ $this->_virtualSessionStorage->registerBag(new AttributeBag());
+ }
+
+ public function tearDown() {
+ unlink($this->_pathToDB);
+ }
+
+ public function testStartWithDSN() {
+ $this->_virtualSessionStorage->start();
+
+ $this->assertTrue($this->_virtualSessionStorage->isStarted());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Wamp/ServerProtocolTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Wamp/ServerProtocolTest.php
new file mode 100644
index 0000000..8ff68c2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Wamp/ServerProtocolTest.php
@@ -0,0 +1,295 @@
+<?php
+namespace Ratchet\Wamp;
+use Ratchet\Mock\Connection;
+use Ratchet\Mock\WampComponent as TestComponent;
+
+/**
+ * @covers \Ratchet\Wamp\ServerProtocol
+ * @covers \Ratchet\Wamp\WampServerInterface
+ * @covers \Ratchet\Wamp\WampConnection
+ */
+class ServerProtocolTest extends \PHPUnit_Framework_TestCase {
+ protected $_comp;
+
+ protected $_app;
+
+ public function setUp() {
+ $this->_app = new TestComponent;
+ $this->_comp = new ServerProtocol($this->_app);
+ }
+
+ protected function newConn() {
+ return new Connection;
+ }
+
+ public function invalidMessageProvider() {
+ return [
+ [0]
+ , [3]
+ , [4]
+ , [8]
+ , [9]
+ ];
+ }
+
+ /**
+ * @dataProvider invalidMessageProvider
+ */
+ public function testInvalidMessages($type) {
+ $this->setExpectedException('\Ratchet\Wamp\Exception');
+
+ $conn = $this->newConn();
+ $this->_comp->onOpen($conn);
+ $this->_comp->onMessage($conn, json_encode([$type]));
+ }
+
+ public function testWelcomeMessage() {
+ $conn = $this->newConn();
+
+ $this->_comp->onOpen($conn);
+
+ $message = $conn->last['send'];
+ $json = json_decode($message);
+
+ $this->assertEquals(4, count($json));
+ $this->assertEquals(0, $json[0]);
+ $this->assertTrue(is_string($json[1]));
+ $this->assertEquals(1, $json[2]);
+ }
+
+ public function testSubscribe() {
+ $uri = 'http://example.com';
+ $clientMessage = array(5, $uri);
+
+ $conn = $this->newConn();
+
+ $this->_comp->onOpen($conn);
+ $this->_comp->onMessage($conn, json_encode($clientMessage));
+
+ $this->assertEquals($uri, $this->_app->last['onSubscribe'][1]);
+ }
+
+ public function testUnSubscribe() {
+ $uri = 'http://example.com/endpoint';
+ $clientMessage = array(6, $uri);
+
+ $conn = $this->newConn();
+
+ $this->_comp->onOpen($conn);
+ $this->_comp->onMessage($conn, json_encode($clientMessage));
+
+ $this->assertEquals($uri, $this->_app->last['onUnSubscribe'][1]);
+ }
+
+ public function callProvider() {
+ return [
+ [2, 'a', 'b']
+ , [2, ['a', 'b']]
+ , [1, 'one']
+ , [3, 'one', 'two', 'three']
+ , [3, ['un', 'deux', 'trois']]
+ , [2, 'hi', ['hello', 'world']]
+ , [2, ['hello', 'world'], 'hi']
+ , [2, ['hello' => 'world', 'herp' => 'derp']]
+ ];
+ }
+
+ /**
+ * @dataProvider callProvider
+ */
+ public function testCall() {
+ $args = func_get_args();
+ $paramNum = array_shift($args);
+
+ $uri = 'http://example.com/endpoint/' . rand(1, 100);
+ $id = uniqid('', false);
+ $clientMessage = array_merge(array(2, $id, $uri), $args);
+
+ $conn = $this->newConn();
+
+ $this->_comp->onOpen($conn);
+ $this->_comp->onMessage($conn, json_encode($clientMessage));
+
+ $this->assertEquals($id, $this->_app->last['onCall'][1]);
+ $this->assertEquals($uri, $this->_app->last['onCall'][2]);
+
+ $this->assertEquals($paramNum, count($this->_app->last['onCall'][3]));
+ }
+
+ public function testPublish() {
+ $conn = $this->newConn();
+
+ $topic = 'pubsubhubbub';
+ $event = 'Here I am, publishing data';
+
+ $clientMessage = array(7, $topic, $event);
+
+ $this->_comp->onOpen($conn);
+ $this->_comp->onMessage($conn, json_encode($clientMessage));
+
+ $this->assertEquals($topic, $this->_app->last['onPublish'][1]);
+ $this->assertEquals($event, $this->_app->last['onPublish'][2]);
+ $this->assertEquals(array(), $this->_app->last['onPublish'][3]);
+ $this->assertEquals(array(), $this->_app->last['onPublish'][4]);
+ }
+
+ public function testPublishAndExcludeMe() {
+ $conn = $this->newConn();
+
+ $this->_comp->onOpen($conn);
+ $this->_comp->onMessage($conn, json_encode(array(7, 'topic', 'event', true)));
+
+ $this->assertEquals($conn->WAMP->sessionId, $this->_app->last['onPublish'][3][0]);
+ }
+
+ public function testPublishAndEligible() {
+ $conn = $this->newConn();
+
+ $buddy = uniqid('', false);
+ $friend = uniqid('', false);
+
+ $this->_comp->onOpen($conn);
+ $this->_comp->onMessage($conn, json_encode(array(7, 'topic', 'event', false, array($buddy, $friend))));
+
+ $this->assertEquals(array(), $this->_app->last['onPublish'][3]);
+ $this->assertEquals(2, count($this->_app->last['onPublish'][4]));
+ }
+
+ public function eventProvider() {
+ return array(
+ array('http://example.com', array('one', 'two'))
+ , array('curie', array(array('hello' => 'world', 'herp' => 'derp')))
+ );
+ }
+
+ /**
+ * @dataProvider eventProvider
+ */
+ public function testEvent($topic, $payload) {
+ $conn = new WampConnection($this->newConn());
+ $conn->event($topic, $payload);
+
+ $eventString = $conn->last['send'];
+
+ $this->assertSame(array(8, $topic, $payload), json_decode($eventString, true));
+ }
+
+ public function testOnClosePropagation() {
+ $conn = new Connection;
+
+ $this->_comp->onOpen($conn);
+ $this->_comp->onClose($conn);
+
+ $class = new \ReflectionClass('\\Ratchet\\Wamp\\WampConnection');
+ $method = $class->getMethod('getConnection');
+ $method->setAccessible(true);
+
+ $check = $method->invokeArgs($this->_app->last['onClose'][0], array());
+
+ $this->assertSame($conn, $check);
+ }
+
+ public function testOnErrorPropagation() {
+ $conn = new Connection;
+
+ $e = new \Exception('Nope');
+
+ $this->_comp->onOpen($conn);
+ $this->_comp->onError($conn, $e);
+
+ $class = new \ReflectionClass('\\Ratchet\\Wamp\\WampConnection');
+ $method = $class->getMethod('getConnection');
+ $method->setAccessible(true);
+
+ $check = $method->invokeArgs($this->_app->last['onError'][0], array());
+
+ $this->assertSame($conn, $check);
+ $this->assertSame($e, $this->_app->last['onError'][1]);
+ }
+
+ public function testPrefix() {
+ $conn = new WampConnection($this->newConn());
+ $this->_comp->onOpen($conn);
+
+ $prefix = 'incoming';
+ $fullURI = "http://example.com/$prefix";
+ $method = 'call';
+
+ $this->_comp->onMessage($conn, json_encode(array(1, $prefix, $fullURI)));
+
+ $this->assertEquals($fullURI, $conn->WAMP->prefixes[$prefix]);
+ $this->assertEquals("$fullURI#$method", $conn->getUri("$prefix:$method"));
+ }
+
+ public function testMessageMustBeJson() {
+ $this->setExpectedException('\\Ratchet\\Wamp\\JsonException');
+
+ $conn = new Connection;
+
+ $this->_comp->onOpen($conn);
+ $this->_comp->onMessage($conn, 'Hello World!');
+ }
+
+ public function testGetSubProtocolsReturnsArray() {
+ $this->assertTrue(is_array($this->_comp->getSubProtocols()));
+ }
+
+ public function testGetSubProtocolsGetFromApp() {
+ $this->_app->protocols = array('hello', 'world');
+
+ $this->assertGreaterThanOrEqual(3, count($this->_comp->getSubProtocols()));
+ }
+
+ public function testWampOnMessageApp() {
+ $app = $this->getMock('\\Ratchet\\Wamp\\WampServerInterface');
+ $wamp = new ServerProtocol($app);
+
+ $this->assertContains('wamp', $wamp->getSubProtocols());
+ }
+
+ public function badFormatProvider() {
+ return array(
+ array(json_encode(true))
+ , array('{"valid":"json", "invalid": "message"}')
+ , array('{"0": "fail", "hello": "world"}')
+ );
+ }
+
+ /**
+ * @dataProvider badFormatProvider
+ */
+ public function testValidJsonButInvalidProtocol($message) {
+ $this->setExpectedException('\Ratchet\Wamp\Exception');
+
+ $conn = $this->newConn();
+ $this->_comp->onOpen($conn);
+ $this->_comp->onMessage($conn, $message);
+ }
+
+ public function testBadClientInputFromNonStringTopic() {
+ $this->setExpectedException('\Ratchet\Wamp\Exception');
+
+ $conn = new WampConnection($this->newConn());
+ $this->_comp->onOpen($conn);
+
+ $this->_comp->onMessage($conn, json_encode([5, ['hells', 'nope']]));
+ }
+
+ public function testBadPrefixWithNonStringTopic() {
+ $this->setExpectedException('\Ratchet\Wamp\Exception');
+
+ $conn = new WampConnection($this->newConn());
+ $this->_comp->onOpen($conn);
+
+ $this->_comp->onMessage($conn, json_encode([1, ['hells', 'nope'], ['bad', 'input']]));
+ }
+
+ public function testBadPublishWithNonStringTopic() {
+ $this->setExpectedException('\Ratchet\Wamp\Exception');
+
+ $conn = new WampConnection($this->newConn());
+ $this->_comp->onOpen($conn);
+
+ $this->_comp->onMessage($conn, json_encode([7, ['bad', 'input'], 'Hider']));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Wamp/TopicManagerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Wamp/TopicManagerTest.php
new file mode 100644
index 0000000..b21b6bc
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Wamp/TopicManagerTest.php
@@ -0,0 +1,226 @@
+<?php
+namespace Ratchet\Wamp;
+
+/**
+ * @covers Ratchet\Wamp\TopicManager
+ */
+class TopicManagerTest extends \PHPUnit_Framework_TestCase {
+ private $mock;
+
+ /**
+ * @var \Ratchet\Wamp\TopicManager
+ */
+ private $mngr;
+
+ /**
+ * @var \Ratchet\ConnectionInterface
+ */
+ private $conn;
+
+ public function setUp() {
+ $this->conn = $this->getMock('\Ratchet\ConnectionInterface');
+ $this->mock = $this->getMock('\Ratchet\Wamp\WampServerInterface');
+ $this->mngr = new TopicManager($this->mock);
+
+ $this->conn->WAMP = new \StdClass;
+ $this->mngr->onOpen($this->conn);
+ }
+
+ public function testGetTopicReturnsTopicObject() {
+ $class = new \ReflectionClass('Ratchet\Wamp\TopicManager');
+ $method = $class->getMethod('getTopic');
+ $method->setAccessible(true);
+
+ $topic = $method->invokeArgs($this->mngr, array('The Topic'));
+
+ $this->assertInstanceOf('Ratchet\Wamp\Topic', $topic);
+ }
+
+ public function testGetTopicCreatesTopicWithSameName() {
+ $name = 'The Topic';
+
+ $class = new \ReflectionClass('Ratchet\Wamp\TopicManager');
+ $method = $class->getMethod('getTopic');
+ $method->setAccessible(true);
+
+ $topic = $method->invokeArgs($this->mngr, array($name));
+
+ $this->assertEquals($name, $topic->getId());
+ }
+
+ public function testGetTopicReturnsSameObject() {
+ $class = new \ReflectionClass('Ratchet\Wamp\TopicManager');
+ $method = $class->getMethod('getTopic');
+ $method->setAccessible(true);
+
+ $topic = $method->invokeArgs($this->mngr, array('No copy'));
+ $again = $method->invokeArgs($this->mngr, array('No copy'));
+
+ $this->assertSame($topic, $again);
+ }
+
+ public function testOnOpen() {
+ $this->mock->expects($this->once())->method('onOpen');
+ $this->mngr->onOpen($this->conn);
+ }
+
+ public function testOnCall() {
+ $id = uniqid();
+
+ $this->mock->expects($this->once())->method('onCall')->with(
+ $this->conn
+ , $id
+ , $this->isInstanceOf('Ratchet\Wamp\Topic')
+ , array()
+ );
+
+ $this->mngr->onCall($this->conn, $id, 'new topic', array());
+ }
+
+ public function testOnSubscribeCreatesTopicObject() {
+ $this->mock->expects($this->once())->method('onSubscribe')->with(
+ $this->conn, $this->isInstanceOf('Ratchet\Wamp\Topic')
+ );
+
+ $this->mngr->onSubscribe($this->conn, 'new topic');
+ }
+
+ public function testTopicIsInConnectionOnSubscribe() {
+ $name = 'New Topic';
+
+ $class = new \ReflectionClass('Ratchet\Wamp\TopicManager');
+ $method = $class->getMethod('getTopic');
+ $method->setAccessible(true);
+
+ $topic = $method->invokeArgs($this->mngr, array($name));
+
+ $this->mngr->onSubscribe($this->conn, $name);
+
+ $this->assertTrue($this->conn->WAMP->subscriptions->contains($topic));
+ }
+
+ public function testDoubleSubscriptionFiresOnce() {
+ $this->mock->expects($this->exactly(1))->method('onSubscribe');
+
+ $this->mngr->onSubscribe($this->conn, 'same topic');
+ $this->mngr->onSubscribe($this->conn, 'same topic');
+ }
+
+ public function testUnsubscribeEvent() {
+ $name = 'in and out';
+ $this->mock->expects($this->once())->method('onUnsubscribe')->with(
+ $this->conn, $this->isInstanceOf('Ratchet\Wamp\Topic')
+ );
+
+ $this->mngr->onSubscribe($this->conn, $name);
+ $this->mngr->onUnsubscribe($this->conn, $name);
+ }
+
+ public function testUnsubscribeFiresOnce() {
+ $name = 'getting sleepy';
+ $this->mock->expects($this->exactly(1))->method('onUnsubscribe');
+
+ $this->mngr->onSubscribe($this->conn, $name);
+ $this->mngr->onUnsubscribe($this->conn, $name);
+ $this->mngr->onUnsubscribe($this->conn, $name);
+ }
+
+ public function testUnsubscribeRemovesTopicFromConnection() {
+ $name = 'Bye Bye Topic';
+
+ $class = new \ReflectionClass('Ratchet\Wamp\TopicManager');
+ $method = $class->getMethod('getTopic');
+ $method->setAccessible(true);
+
+ $topic = $method->invokeArgs($this->mngr, array($name));
+
+ $this->mngr->onSubscribe($this->conn, $name);
+ $this->mngr->onUnsubscribe($this->conn, $name);
+
+ $this->assertFalse($this->conn->WAMP->subscriptions->contains($topic));
+ }
+
+ public function testOnPublishBubbles() {
+ $msg = 'Cover all the code!';
+
+ $this->mock->expects($this->once())->method('onPublish')->with(
+ $this->conn
+ , $this->isInstanceOf('Ratchet\Wamp\Topic')
+ , $msg
+ , $this->isType('array')
+ , $this->isType('array')
+ );
+
+ $this->mngr->onPublish($this->conn, 'topic coverage', $msg, array(), array());
+ }
+
+ public function testOnCloseBubbles() {
+ $this->mock->expects($this->once())->method('onClose')->with($this->conn);
+ $this->mngr->onClose($this->conn);
+ }
+
+ protected function topicProvider($name) {
+ $class = new \ReflectionClass('Ratchet\Wamp\TopicManager');
+ $method = $class->getMethod('getTopic');
+ $method->setAccessible(true);
+
+ $attribute = $class->getProperty('topicLookup');
+ $attribute->setAccessible(true);
+
+ $topic = $method->invokeArgs($this->mngr, array($name));
+
+ return array($topic, $attribute);
+ }
+
+ public function testConnIsRemovedFromTopicOnClose() {
+ $name = 'State Testing';
+ list($topic, $attribute) = $this->topicProvider($name);
+
+ $this->assertCount(1, $attribute->getValue($this->mngr));
+
+ $this->mngr->onSubscribe($this->conn, $name);
+ $this->mngr->onClose($this->conn);
+
+ $this->assertFalse($topic->has($this->conn));
+ }
+
+ public static function topicConnExpectationProvider() {
+ return [
+ [ 'onClose', 0]
+ , ['onUnsubscribe', 0]
+ ];
+ }
+
+ /**
+ * @dataProvider topicConnExpectationProvider
+ */
+ public function testTopicRetentionFromLeavingConnections($methodCall, $expectation) {
+ $topicName = 'checkTopic';
+ list($topic, $attribute) = $this->topicProvider($topicName);
+
+ $this->mngr->onSubscribe($this->conn, $topicName);
+ call_user_func_array(array($this->mngr, $methodCall), array($this->conn, $topicName));
+
+ $this->assertCount($expectation, $attribute->getValue($this->mngr));
+ }
+
+ public function testOnErrorBubbles() {
+ $e = new \Exception('All work and no play makes Chris a dull boy');
+ $this->mock->expects($this->once())->method('onError')->with($this->conn, $e);
+
+ $this->mngr->onError($this->conn, $e);
+ }
+
+ public function testGetSubProtocolsReturnsArray() {
+ $this->assertInternalType('array', $this->mngr->getSubProtocols());
+ }
+
+ public function testGetSubProtocolsBubbles() {
+ $subs = array('hello', 'world');
+ $app = $this->getMock('Ratchet\Wamp\Stub\WsWampServerInterface');
+ $app->expects($this->once())->method('getSubProtocols')->will($this->returnValue($subs));
+ $mngr = new TopicManager($app);
+
+ $this->assertEquals($subs, $mngr->getSubProtocols());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Wamp/TopicTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Wamp/TopicTest.php
new file mode 100644
index 0000000..b8685b7
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Wamp/TopicTest.php
@@ -0,0 +1,164 @@
+<?php
+namespace Ratchet\Wamp;
+
+/**
+ * @covers Ratchet\Wamp\Topic
+ */
+class TopicTest extends \PHPUnit_Framework_TestCase {
+ public function testGetId() {
+ $id = uniqid();
+ $topic = new Topic($id);
+
+ $this->assertEquals($id, $topic->getId());
+ }
+
+ public function testAddAndCount() {
+ $topic = new Topic('merp');
+
+ $topic->add($this->newConn());
+ $topic->add($this->newConn());
+ $topic->add($this->newConn());
+
+ $this->assertEquals(3, count($topic));
+ }
+
+ public function testRemove() {
+ $topic = new Topic('boop');
+ $tracked = $this->newConn();
+
+ $topic->add($this->newConn());
+ $topic->add($tracked);
+ $topic->add($this->newConn());
+
+ $topic->remove($tracked);
+
+ $this->assertEquals(2, count($topic));
+ }
+
+ public function testBroadcast() {
+ $msg = 'Hello World!';
+ $name = 'Batman';
+ $protocol = json_encode(array(8, $name, $msg));
+
+ $first = $this->getMock('Ratchet\\Wamp\\WampConnection', array('send'), array($this->getMock('\\Ratchet\\ConnectionInterface')));
+ $second = $this->getMock('Ratchet\\Wamp\\WampConnection', array('send'), array($this->getMock('\\Ratchet\\ConnectionInterface')));
+
+ $first->expects($this->once())
+ ->method('send')
+ ->with($this->equalTo($protocol));
+
+ $second->expects($this->once())
+ ->method('send')
+ ->with($this->equalTo($protocol));
+
+ $topic = new Topic($name);
+ $topic->add($first);
+ $topic->add($second);
+
+ $topic->broadcast($msg);
+ }
+
+ public function testBroadcastWithExclude() {
+ $msg = 'Hello odd numbers';
+ $name = 'Excluding';
+ $protocol = json_encode(array(8, $name, $msg));
+
+ $first = $this->getMock('Ratchet\\Wamp\\WampConnection', array('send'), array($this->getMock('\\Ratchet\\ConnectionInterface')));
+ $second = $this->getMock('Ratchet\\Wamp\\WampConnection', array('send'), array($this->getMock('\\Ratchet\\ConnectionInterface')));
+ $third = $this->getMock('Ratchet\\Wamp\\WampConnection', array('send'), array($this->getMock('\\Ratchet\\ConnectionInterface')));
+
+ $first->expects($this->once())
+ ->method('send')
+ ->with($this->equalTo($protocol));
+
+ $second->expects($this->never())->method('send');
+
+ $third->expects($this->once())
+ ->method('send')
+ ->with($this->equalTo($protocol));
+
+ $topic = new Topic($name);
+ $topic->add($first);
+ $topic->add($second);
+ $topic->add($third);
+
+ $topic->broadcast($msg, array($second->WAMP->sessionId));
+ }
+
+ public function testBroadcastWithEligible() {
+ $msg = 'Hello white list';
+ $name = 'Eligible';
+ $protocol = json_encode(array(8, $name, $msg));
+
+ $first = $this->getMock('Ratchet\\Wamp\\WampConnection', array('send'), array($this->getMock('\\Ratchet\\ConnectionInterface')));
+ $second = $this->getMock('Ratchet\\Wamp\\WampConnection', array('send'), array($this->getMock('\\Ratchet\\ConnectionInterface')));
+ $third = $this->getMock('Ratchet\\Wamp\\WampConnection', array('send'), array($this->getMock('\\Ratchet\\ConnectionInterface')));
+
+ $first->expects($this->once())
+ ->method('send')
+ ->with($this->equalTo($protocol));
+
+ $second->expects($this->never())->method('send');
+
+ $third->expects($this->once())
+ ->method('send')
+ ->with($this->equalTo($protocol));
+
+ $topic = new Topic($name);
+ $topic->add($first);
+ $topic->add($second);
+ $topic->add($third);
+
+ $topic->broadcast($msg, array(), array($first->WAMP->sessionId, $third->WAMP->sessionId));
+ }
+
+ public function testIterator() {
+ $first = $this->newConn();
+ $second = $this->newConn();
+ $third = $this->newConn();
+
+ $topic = new Topic('Joker');
+ $topic->add($first)->add($second)->add($third);
+
+ $check = array($first, $second, $third);
+
+ foreach ($topic as $mock) {
+ $this->assertNotSame(false, array_search($mock, $check));
+ }
+ }
+
+ public function testToString() {
+ $name = 'Bane';
+ $topic = new Topic($name);
+
+ $this->assertEquals($name, (string)$topic);
+ }
+
+ public function testDoesHave() {
+ $conn = $this->newConn();
+ $topic = new Topic('Two Face');
+ $topic->add($conn);
+
+ $this->assertTrue($topic->has($conn));
+ }
+
+ public function testDoesNotHave() {
+ $conn = $this->newConn();
+ $topic = new Topic('Alfred');
+
+ $this->assertFalse($topic->has($conn));
+ }
+
+ public function testDoesNotHaveAfterRemove() {
+ $conn = $this->newConn();
+ $topic = new Topic('Ras');
+
+ $topic->add($conn)->remove($conn);
+
+ $this->assertFalse($topic->has($conn));
+ }
+
+ protected function newConn() {
+ return new WampConnection($this->getMock('\\Ratchet\\ConnectionInterface'));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Wamp/WampConnectionTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Wamp/WampConnectionTest.php
new file mode 100644
index 0000000..adf59d5
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Wamp/WampConnectionTest.php
@@ -0,0 +1,77 @@
+<?php
+namespace Ratchet\Wamp;
+
+/**
+ * @covers Ratchet\Wamp\WampConnection
+ */
+class WampConnectionTest extends \PHPUnit_Framework_TestCase {
+ protected $conn;
+ protected $mock;
+
+ public function setUp() {
+ $this->mock = $this->getMock('\\Ratchet\\ConnectionInterface');
+ $this->conn = new WampConnection($this->mock);
+ }
+
+ public function testCallResult() {
+ $callId = uniqid();
+ $data = array('hello' => 'world', 'herp' => 'derp');
+
+ $this->mock->expects($this->once())->method('send')->with(json_encode(array(3, $callId, $data)));
+
+ $this->conn->callResult($callId, $data);
+ }
+
+ public function testCallError() {
+ $callId = uniqid();
+ $uri = 'http://example.com/end/point';
+
+ $this->mock->expects($this->once())->method('send')->with(json_encode(array(4, $callId, $uri, '')));
+
+ $this->conn->callError($callId, $uri);
+ }
+
+ public function testCallErrorWithTopic() {
+ $callId = uniqid();
+ $uri = 'http://example.com/end/point';
+
+ $this->mock->expects($this->once())->method('send')->with(json_encode(array(4, $callId, $uri, '')));
+
+ $this->conn->callError($callId, new Topic($uri));
+ }
+
+ public function testDetailedCallError() {
+ $callId = uniqid();
+ $uri = 'http://example.com/end/point';
+ $desc = 'beep boop beep';
+ $detail = 'Error: Too much awesome';
+
+ $this->mock->expects($this->once())->method('send')->with(json_encode(array(4, $callId, $uri, $desc, $detail)));
+
+ $this->conn->callError($callId, $uri, $desc, $detail);
+ }
+
+ public function testPrefix() {
+ $shortOut = 'outgoing';
+ $longOut = 'http://example.com/outgoing';
+
+ $this->mock->expects($this->once())->method('send')->with(json_encode(array(1, $shortOut, $longOut)));
+
+ $this->conn->prefix($shortOut, $longOut);
+ }
+
+ public function testGetUriWhenNoCurieGiven() {
+ $uri = 'http://example.com/noshort';
+
+ $this->assertEquals($uri, $this->conn->getUri($uri));
+ }
+
+ public function testClose() {
+ $mock = $this->getMock('\\Ratchet\\ConnectionInterface');
+ $conn = new WampConnection($mock);
+
+ $mock->expects($this->once())->method('close');
+
+ $conn->close();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Wamp/WampServerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Wamp/WampServerTest.php
new file mode 100644
index 0000000..626b1ce
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/tests/unit/Wamp/WampServerTest.php
@@ -0,0 +1,49 @@
+<?php
+namespace Ratchet\Wamp;
+use Ratchet\AbstractMessageComponentTestCase;
+
+/**
+ * @covers Ratchet\Wamp\WampServer
+ */
+class WampServerTest extends AbstractMessageComponentTestCase {
+ public function getConnectionClassString() {
+ return '\Ratchet\Wamp\WampConnection';
+ }
+
+ public function getDecoratorClassString() {
+ return 'Ratchet\Wamp\WampServer';
+ }
+
+ public function getComponentClassString() {
+ return '\Ratchet\Wamp\WampServerInterface';
+ }
+
+ public function testOnMessageToEvent() {
+ $published = 'Client published this message';
+
+ $this->_app->expects($this->once())->method('onPublish')->with(
+ $this->isExpectedConnection()
+ , new \PHPUnit_Framework_Constraint_IsInstanceOf('\Ratchet\Wamp\Topic')
+ , $published
+ , array()
+ , array()
+ );
+
+ $this->_serv->onMessage($this->_conn, json_encode(array(7, 'topic', $published)));
+ }
+
+ public function testGetSubProtocols() {
+ // todo: could expand on this
+ $this->assertInternalType('array', $this->_serv->getSubProtocols());
+ }
+
+ public function testConnectionClosesOnInvalidJson() {
+ $this->_conn->expects($this->once())->method('close');
+ $this->_serv->onMessage($this->_conn, 'invalid json');
+ }
+
+ public function testConnectionClosesOnProtocolError() {
+ $this->_conn->expects($this->once())->method('close');
+ $this->_serv->onMessage($this->_conn, json_encode(array('valid' => 'json', 'invalid' => 'protocol')));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/ClassLoader.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/ClassLoader.php
new file mode 100644
index 0000000..dc02dfb
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/ClassLoader.php
@@ -0,0 +1,445 @@
+<?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 http://www.php-fig.org/psr/psr-0/
+ * @see http://www.php-fig.org/psr/psr-4/
+ */
+class ClassLoader
+{
+ // PSR-4
+ private $prefixLengthsPsr4 = array();
+ private $prefixDirsPsr4 = array();
+ private $fallbackDirsPsr4 = array();
+
+ // PSR-0
+ private $prefixesPsr0 = array();
+ private $fallbackDirsPsr0 = array();
+
+ private $useIncludePath = false;
+ private $classMap = array();
+ private $classMapAuthoritative = false;
+ private $missingClasses = array();
+ private $apcuPrefix;
+
+ public function getPrefixes()
+ {
+ if (!empty($this->prefixesPsr0)) {
+ return call_user_func_array('array_merge', $this->prefixesPsr0);
+ }
+
+ return array();
+ }
+
+ public function getPrefixesPsr4()
+ {
+ return $this->prefixDirsPsr4;
+ }
+
+ public function getFallbackDirs()
+ {
+ return $this->fallbackDirsPsr0;
+ }
+
+ public function getFallbackDirsPsr4()
+ {
+ return $this->fallbackDirsPsr4;
+ }
+
+ public function getClassMap()
+ {
+ return $this->classMap;
+ }
+
+ /**
+ * @param array $classMap Class to filename map
+ */
+ 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 array|string $paths The PSR-0 root directories
+ * @param bool $prepend Whether to prepend the directories
+ */
+ 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 array|string $paths The PSR-4 base directories
+ * @param bool $prepend Whether to prepend the directories
+ *
+ * @throws \InvalidArgumentException
+ */
+ 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 array|string $paths The PSR-0 base directories
+ */
+ 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 array|string $paths The PSR-4 base directories
+ *
+ * @throws \InvalidArgumentException
+ */
+ 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
+ */
+ 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
+ */
+ 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
+ */
+ public function setApcuPrefix($apcuPrefix)
+ {
+ $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $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
+ */
+ public function register($prepend = false)
+ {
+ spl_autoload_register(array($this, 'loadClass'), true, $prepend);
+ }
+
+ /**
+ * Unregisters this instance as an autoloader.
+ */
+ public function unregister()
+ {
+ spl_autoload_unregister(array($this, 'loadClass'));
+ }
+
+ /**
+ * Loads the given class or interface.
+ *
+ * @param string $class The name of the class
+ * @return bool|null True if loaded, null otherwise
+ */
+ public function loadClass($class)
+ {
+ if ($file = $this->findFile($class)) {
+ includeFile($file);
+
+ return true;
+ }
+ }
+
+ /**
+ * 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;
+ }
+
+ 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;
+ }
+}
+
+/**
+ * Scope isolated include.
+ *
+ * Prevents access to $this/self from included files.
+ */
+function includeFile($file)
+{
+ include $file;
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/LICENSE b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/LICENSE
new file mode 100644
index 0000000..f27399a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/LICENSE
@@ -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.
+
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/autoload_classmap.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/autoload_classmap.php
new file mode 100644
index 0000000..a883873
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/autoload_classmap.php
@@ -0,0 +1,84 @@
+<?php
+
+// autoload_classmap.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+ 'ArithmeticError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/ArithmeticError.php',
+ 'AssertionError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/AssertionError.php',
+ 'CssAtCharsetParserPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtCharsetToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtFontFaceDeclarationToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtFontFaceEndToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtFontFaceParserPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtFontFaceStartToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtImportParserPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtImportToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtKeyframesEndToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtKeyframesParserPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtKeyframesRulesetDeclarationToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtKeyframesRulesetEndToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtKeyframesRulesetStartToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtKeyframesStartToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtMediaEndToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtMediaParserPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtMediaStartToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtPageDeclarationToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtPageEndToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtPageParserPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtPageStartToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtVariablesDeclarationToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtVariablesEndToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtVariablesParserPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtVariablesStartToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssCommentParserPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssCommentToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssCompressColorValuesMinifierPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssCompressExpressionValuesMinifierPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssCompressUnitValuesMinifierPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssConvertFontWeightMinifierPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssConvertHslColorsMinifierPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssConvertLevel3AtKeyframesMinifierFilter' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssConvertLevel3PropertiesMinifierFilter' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssConvertNamedColorsMinifierPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssConvertRgbColorsMinifierPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssError' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssExpressionParserPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssImportImportsMinifierFilter' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssMin' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssMinifier' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssNullToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssOtbsFormatter' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssParser' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssRemoveCommentsMinifierFilter' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssRemoveEmptyAtBlocksMinifierFilter' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssRemoveEmptyRulesetsMinifierFilter' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssRemoveLastDelarationSemiColonMinifierFilter' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssRulesetDeclarationToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssRulesetEndToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssRulesetParserPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssRulesetStartToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssSortRulesetPropertiesMinifierFilter' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssStringParserPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssUrlParserPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssVariablesMinifierFilter' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssVariablesMinifierPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'CssWhitesmithsFormatter' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'DivisionByZeroError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/DivisionByZeroError.php',
+ 'Error' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/Error.php',
+ 'ParseError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/ParseError.php',
+ 'SessionUpdateTimestampHandlerInterface' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/SessionUpdateTimestampHandlerInterface.php',
+ 'TypeError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/TypeError.php',
+ 'aCssAtBlockEndToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'aCssAtBlockStartToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'aCssDeclarationToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'aCssFormatter' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'aCssMinifierFilter' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'aCssMinifierPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'aCssParserPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'aCssRulesetEndToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'aCssRulesetStartToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+ 'aCssToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php',
+);
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/autoload_files.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/autoload_files.php
new file mode 100644
index 0000000..295c7b6
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/autoload_files.php
@@ -0,0 +1,15 @@
+<?php
+
+// autoload_files.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+ 'ad155f8f1cf0d418fe49e248db8c661b' => $vendorDir . '/react/promise/src/functions_include.php',
+ '5255c38a0faeba867671b61dfda6d864' => $vendorDir . '/paragonie/random_compat/lib/random.php',
+ '6b06ce8ccf69c43a60a1e48495a034c9' => $vendorDir . '/react/promise-timer/src/functions.php',
+ '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
+ '023d27dca8066ef29e6739335ea73bad' => $vendorDir . '/symfony/polyfill-php70/bootstrap.php',
+ 'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php',
+);
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/autoload_namespaces.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/autoload_namespaces.php
new file mode 100644
index 0000000..02066fb
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/autoload_namespaces.php
@@ -0,0 +1,10 @@
+<?php
+
+// autoload_namespaces.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+ 'Evenement' => array($vendorDir . '/evenement/evenement/src'),
+);
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/autoload_psr4.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/autoload_psr4.php
new file mode 100644
index 0000000..9c1906b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/autoload_psr4.php
@@ -0,0 +1,28 @@
+<?php
+
+// autoload_psr4.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+ 'Websocket\\' => array($baseDir . '/Chatserver/src'),
+ 'Symfony\\Polyfill\\Php70\\' => array($vendorDir . '/symfony/polyfill-php70'),
+ 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
+ 'Symfony\\Component\\Routing\\' => array($vendorDir . '/symfony/routing'),
+ 'Symfony\\Component\\HttpFoundation\\' => array($vendorDir . '/symfony/http-foundation'),
+ 'React\\Stream\\' => array($vendorDir . '/react/stream/src'),
+ 'React\\Socket\\' => array($vendorDir . '/react/socket/src'),
+ 'React\\Promise\\Timer\\' => array($vendorDir . '/react/promise-timer/src'),
+ 'React\\Promise\\' => array($vendorDir . '/react/promise/src'),
+ 'React\\EventLoop\\' => array($vendorDir . '/react/event-loop/src'),
+ 'React\\Dns\\' => array($vendorDir . '/react/dns/src'),
+ 'React\\Cache\\' => array($vendorDir . '/react/cache/src'),
+ 'Ratchet\\RFC6455\\' => array($vendorDir . '/ratchet/rfc6455/src'),
+ 'Ratchet\\' => array($vendorDir . '/cboden/ratchet/src/Ratchet'),
+ 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'),
+ 'Nubs\\RandomNameGenerator\\' => array($vendorDir . '/nubs/random-name-generator/src'),
+ 'MatthiasMullie\\PathConverter\\' => array($vendorDir . '/matthiasmullie/path-converter/src'),
+ 'MatthiasMullie\\Minify\\' => array($vendorDir . '/matthiasmullie/minify/src'),
+ 'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'),
+);
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/autoload_real.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/autoload_real.php
new file mode 100644
index 0000000..8fc42a0
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/autoload_real.php
@@ -0,0 +1,70 @@
+<?php
+
+// autoload_real.php @generated by Composer
+
+class ComposerAutoloaderInit3c5661e077098f105cbab5a541fd4883
+{
+ private static $loader;
+
+ public static function loadClassLoader($class)
+ {
+ if ('Composer\Autoload\ClassLoader' === $class) {
+ require __DIR__ . '/ClassLoader.php';
+ }
+ }
+
+ public static function getLoader()
+ {
+ if (null !== self::$loader) {
+ return self::$loader;
+ }
+
+ spl_autoload_register(array('ComposerAutoloaderInit3c5661e077098f105cbab5a541fd4883', 'loadClassLoader'), true, true);
+ self::$loader = $loader = new \Composer\Autoload\ClassLoader();
+ spl_autoload_unregister(array('ComposerAutoloaderInit3c5661e077098f105cbab5a541fd4883', 'loadClassLoader'));
+
+ $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
+ if ($useStaticLoader) {
+ require_once __DIR__ . '/autoload_static.php';
+
+ call_user_func(\Composer\Autoload\ComposerStaticInit3c5661e077098f105cbab5a541fd4883::getInitializer($loader));
+ } else {
+ $map = require __DIR__ . '/autoload_namespaces.php';
+ foreach ($map as $namespace => $path) {
+ $loader->set($namespace, $path);
+ }
+
+ $map = require __DIR__ . '/autoload_psr4.php';
+ foreach ($map as $namespace => $path) {
+ $loader->setPsr4($namespace, $path);
+ }
+
+ $classMap = require __DIR__ . '/autoload_classmap.php';
+ if ($classMap) {
+ $loader->addClassMap($classMap);
+ }
+ }
+
+ $loader->register(true);
+
+ if ($useStaticLoader) {
+ $includeFiles = Composer\Autoload\ComposerStaticInit3c5661e077098f105cbab5a541fd4883::$files;
+ } else {
+ $includeFiles = require __DIR__ . '/autoload_files.php';
+ }
+ foreach ($includeFiles as $fileIdentifier => $file) {
+ composerRequire3c5661e077098f105cbab5a541fd4883($fileIdentifier, $file);
+ }
+
+ return $loader;
+ }
+}
+
+function composerRequire3c5661e077098f105cbab5a541fd4883($fileIdentifier, $file)
+{
+ if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
+ require $file;
+
+ $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/autoload_static.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/autoload_static.php
new file mode 100644
index 0000000..b5b4c27
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/autoload_static.php
@@ -0,0 +1,238 @@
+<?php
+
+// autoload_static.php @generated by Composer
+
+namespace Composer\Autoload;
+
+class ComposerStaticInit3c5661e077098f105cbab5a541fd4883
+{
+ public static $files = array (
+ 'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php',
+ '5255c38a0faeba867671b61dfda6d864' => __DIR__ . '/..' . '/paragonie/random_compat/lib/random.php',
+ '6b06ce8ccf69c43a60a1e48495a034c9' => __DIR__ . '/..' . '/react/promise-timer/src/functions.php',
+ '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
+ '023d27dca8066ef29e6739335ea73bad' => __DIR__ . '/..' . '/symfony/polyfill-php70/bootstrap.php',
+ 'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php',
+ );
+
+ public static $prefixLengthsPsr4 = array (
+ 'W' =>
+ array (
+ 'Websocket\\' => 10,
+ ),
+ 'S' =>
+ array (
+ 'Symfony\\Polyfill\\Php70\\' => 23,
+ 'Symfony\\Polyfill\\Mbstring\\' => 26,
+ 'Symfony\\Component\\Routing\\' => 26,
+ 'Symfony\\Component\\HttpFoundation\\' => 33,
+ ),
+ 'R' =>
+ array (
+ 'React\\Stream\\' => 13,
+ 'React\\Socket\\' => 13,
+ 'React\\Promise\\Timer\\' => 20,
+ 'React\\Promise\\' => 14,
+ 'React\\EventLoop\\' => 16,
+ 'React\\Dns\\' => 10,
+ 'React\\Cache\\' => 12,
+ 'Ratchet\\RFC6455\\' => 16,
+ 'Ratchet\\' => 8,
+ ),
+ 'P' =>
+ array (
+ 'Psr\\Http\\Message\\' => 17,
+ ),
+ 'N' =>
+ array (
+ 'Nubs\\RandomNameGenerator\\' => 25,
+ ),
+ 'M' =>
+ array (
+ 'MatthiasMullie\\PathConverter\\' => 29,
+ 'MatthiasMullie\\Minify\\' => 22,
+ ),
+ 'G' =>
+ array (
+ 'GuzzleHttp\\Psr7\\' => 16,
+ ),
+ );
+
+ public static $prefixDirsPsr4 = array (
+ 'Websocket\\' =>
+ array (
+ 0 => __DIR__ . '/../..' . '/Chatserver/src',
+ ),
+ 'Symfony\\Polyfill\\Php70\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/symfony/polyfill-php70',
+ ),
+ 'Symfony\\Polyfill\\Mbstring\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
+ ),
+ 'Symfony\\Component\\Routing\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/symfony/routing',
+ ),
+ 'Symfony\\Component\\HttpFoundation\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/symfony/http-foundation',
+ ),
+ 'React\\Stream\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/react/stream/src',
+ ),
+ 'React\\Socket\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/react/socket/src',
+ ),
+ 'React\\Promise\\Timer\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/react/promise-timer/src',
+ ),
+ 'React\\Promise\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/react/promise/src',
+ ),
+ 'React\\EventLoop\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/react/event-loop/src',
+ ),
+ 'React\\Dns\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/react/dns/src',
+ ),
+ 'React\\Cache\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/react/cache/src',
+ ),
+ 'Ratchet\\RFC6455\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/ratchet/rfc6455/src',
+ ),
+ 'Ratchet\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/cboden/ratchet/src/Ratchet',
+ ),
+ 'Psr\\Http\\Message\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/psr/http-message/src',
+ ),
+ 'Nubs\\RandomNameGenerator\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/nubs/random-name-generator/src',
+ ),
+ 'MatthiasMullie\\PathConverter\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/matthiasmullie/path-converter/src',
+ ),
+ 'MatthiasMullie\\Minify\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/matthiasmullie/minify/src',
+ ),
+ 'GuzzleHttp\\Psr7\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/guzzlehttp/psr7/src',
+ ),
+ );
+
+ public static $prefixesPsr0 = array (
+ 'E' =>
+ array (
+ 'Evenement' =>
+ array (
+ 0 => __DIR__ . '/..' . '/evenement/evenement/src',
+ ),
+ ),
+ );
+
+ public static $classMap = array (
+ 'ArithmeticError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/ArithmeticError.php',
+ 'AssertionError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/AssertionError.php',
+ 'CssAtCharsetParserPlugin' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtCharsetToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtFontFaceDeclarationToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtFontFaceEndToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtFontFaceParserPlugin' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtFontFaceStartToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtImportParserPlugin' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtImportToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtKeyframesEndToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtKeyframesParserPlugin' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtKeyframesRulesetDeclarationToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtKeyframesRulesetEndToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtKeyframesRulesetStartToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtKeyframesStartToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtMediaEndToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtMediaParserPlugin' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtMediaStartToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtPageDeclarationToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtPageEndToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtPageParserPlugin' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtPageStartToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtVariablesDeclarationToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtVariablesEndToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtVariablesParserPlugin' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssAtVariablesStartToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssCommentParserPlugin' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssCommentToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssCompressColorValuesMinifierPlugin' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssCompressExpressionValuesMinifierPlugin' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssCompressUnitValuesMinifierPlugin' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssConvertFontWeightMinifierPlugin' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssConvertHslColorsMinifierPlugin' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssConvertLevel3AtKeyframesMinifierFilter' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssConvertLevel3PropertiesMinifierFilter' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssConvertNamedColorsMinifierPlugin' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssConvertRgbColorsMinifierPlugin' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssError' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssExpressionParserPlugin' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssImportImportsMinifierFilter' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssMin' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssMinifier' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssNullToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssOtbsFormatter' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssParser' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssRemoveCommentsMinifierFilter' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssRemoveEmptyAtBlocksMinifierFilter' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssRemoveEmptyRulesetsMinifierFilter' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssRemoveLastDelarationSemiColonMinifierFilter' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssRulesetDeclarationToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssRulesetEndToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssRulesetParserPlugin' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssRulesetStartToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssSortRulesetPropertiesMinifierFilter' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssStringParserPlugin' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssUrlParserPlugin' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssVariablesMinifierFilter' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssVariablesMinifierPlugin' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'CssWhitesmithsFormatter' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'DivisionByZeroError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/DivisionByZeroError.php',
+ 'Error' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/Error.php',
+ 'ParseError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/ParseError.php',
+ 'SessionUpdateTimestampHandlerInterface' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/SessionUpdateTimestampHandlerInterface.php',
+ 'TypeError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/TypeError.php',
+ 'aCssAtBlockEndToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'aCssAtBlockStartToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'aCssDeclarationToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'aCssFormatter' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'aCssMinifierFilter' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'aCssMinifierPlugin' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'aCssParserPlugin' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'aCssRulesetEndToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'aCssRulesetStartToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ 'aCssToken' => __DIR__ . '/..' . '/natxet/CssMin/src/CssMin.php',
+ );
+
+ public static function getInitializer(ClassLoader $loader)
+ {
+ return \Closure::bind(function () use ($loader) {
+ $loader->prefixLengthsPsr4 = ComposerStaticInit3c5661e077098f105cbab5a541fd4883::$prefixLengthsPsr4;
+ $loader->prefixDirsPsr4 = ComposerStaticInit3c5661e077098f105cbab5a541fd4883::$prefixDirsPsr4;
+ $loader->prefixesPsr0 = ComposerStaticInit3c5661e077098f105cbab5a541fd4883::$prefixesPsr0;
+ $loader->classMap = ComposerStaticInit3c5661e077098f105cbab5a541fd4883::$classMap;
+
+ }, null, ClassLoader::class);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/installed.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/installed.json
new file mode 100644
index 0000000..c8ca472
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/composer/installed.json
@@ -0,0 +1,1125 @@
+[
+ {
+ "name": "cboden/ratchet",
+ "version": "v0.4.1",
+ "version_normalized": "0.4.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/ratchetphp/Ratchet.git",
+ "reference": "0d31f3a8ad4795fd48397712709e55cd07f51360"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/ratchetphp/Ratchet/zipball/0d31f3a8ad4795fd48397712709e55cd07f51360",
+ "reference": "0d31f3a8ad4795fd48397712709e55cd07f51360",
+ "shasum": ""
+ },
+ "require": {
+ "guzzlehttp/psr7": "^1.0",
+ "php": ">=5.4.2",
+ "ratchet/rfc6455": "^0.2",
+ "react/socket": "^1.0 || ^0.8 || ^0.7 || ^0.6 || ^0.5",
+ "symfony/http-foundation": "^2.6|^3.0|^4.0",
+ "symfony/routing": "^2.6|^3.0|^4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.8"
+ },
+ "time": "2017-12-12T00:49:31+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Ratchet\\": "src/Ratchet"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Chris Boden",
+ "email": "cboden@gmail.com",
+ "role": "Developer"
+ }
+ ],
+ "description": "PHP WebSocket library",
+ "homepage": "http://socketo.me",
+ "keywords": [
+ "Ratchet",
+ "WebSockets",
+ "server",
+ "sockets",
+ "websocket"
+ ]
+ },
+ {
+ "name": "evenement/evenement",
+ "version": "v3.0.1",
+ "version_normalized": "3.0.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/igorw/evenement.git",
+ "reference": "531bfb9d15f8aa57454f5f0285b18bec903b8fb7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/igorw/evenement/zipball/531bfb9d15f8aa57454f5f0285b18bec903b8fb7",
+ "reference": "531bfb9d15f8aa57454f5f0285b18bec903b8fb7",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.0"
+ },
+ "time": "2017-07-23T21:35:13+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-0": {
+ "Evenement": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Igor Wiedler",
+ "email": "igor@wiedler.ch"
+ }
+ ],
+ "description": "Événement is a very simple event dispatching library for PHP",
+ "keywords": [
+ "event-dispatcher",
+ "event-emitter"
+ ]
+ },
+ {
+ "name": "guzzlehttp/psr7",
+ "version": "1.4.2",
+ "version_normalized": "1.4.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/psr7.git",
+ "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c",
+ "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4.0",
+ "psr/http-message": "~1.0"
+ },
+ "provide": {
+ "psr/http-message-implementation": "1.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.0"
+ },
+ "time": "2017-03-20T17:10:46+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "GuzzleHttp\\Psr7\\": "src/"
+ },
+ "files": [
+ "src/functions_include.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "Tobias Schultze",
+ "homepage": "https://github.com/Tobion"
+ }
+ ],
+ "description": "PSR-7 message implementation that also provides common utility methods",
+ "keywords": [
+ "http",
+ "message",
+ "request",
+ "response",
+ "stream",
+ "uri",
+ "url"
+ ]
+ },
+ {
+ "name": "matthiasmullie/minify",
+ "version": "1.3.59",
+ "version_normalized": "1.3.59.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/matthiasmullie/minify.git",
+ "reference": "62dac3bce06de66f0d71fe6490cf1c508d3c3ff7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/62dac3bce06de66f0d71fe6490cf1c508d3c3ff7",
+ "reference": "62dac3bce06de66f0d71fe6490cf1c508d3c3ff7",
+ "shasum": ""
+ },
+ "require": {
+ "ext-pcre": "*",
+ "matthiasmullie/path-converter": "~1.1",
+ "php": ">=5.3.0"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "~2.0",
+ "matthiasmullie/scrapbook": "~1.0",
+ "phpunit/phpunit": "~4.8"
+ },
+ "suggest": {
+ "psr/cache-implementation": "Cache implementation to use with Minify::cache"
+ },
+ "time": "2018-02-02T12:44:18+00:00",
+ "bin": [
+ "bin/minifycss",
+ "bin/minifyjs"
+ ],
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "MatthiasMullie\\Minify\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Matthias Mullie",
+ "email": "minify@mullie.eu",
+ "homepage": "http://www.mullie.eu",
+ "role": "Developer"
+ }
+ ],
+ "description": "CSS & JavaScript minifier, in PHP. Removes whitespace, strips comments, combines files (incl. @import statements and small assets in CSS files), and optimizes/shortens a few common programming patterns.",
+ "homepage": "http://www.minifier.org",
+ "keywords": [
+ "JS",
+ "css",
+ "javascript",
+ "minifier",
+ "minify"
+ ]
+ },
+ {
+ "name": "matthiasmullie/path-converter",
+ "version": "1.1.1",
+ "version_normalized": "1.1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/matthiasmullie/path-converter.git",
+ "reference": "3082a6838be02b930239a97d38b5c9da4d693aca"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/matthiasmullie/path-converter/zipball/3082a6838be02b930239a97d38b5c9da4d693aca",
+ "reference": "3082a6838be02b930239a97d38b5c9da4d693aca",
+ "shasum": ""
+ },
+ "require": {
+ "ext-pcre": "*",
+ "php": ">=5.3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.8"
+ },
+ "time": "2018-02-02T11:30:10+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "MatthiasMullie\\PathConverter\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Matthias Mullie",
+ "email": "pathconverter@mullie.eu",
+ "homepage": "http://www.mullie.eu",
+ "role": "Developer"
+ }
+ ],
+ "description": "Relative path converter",
+ "homepage": "http://github.com/matthiasmullie/path-converter",
+ "keywords": [
+ "converter",
+ "path",
+ "paths",
+ "relative"
+ ]
+ },
+ {
+ "name": "natxet/CssMin",
+ "version": "v3.0.6",
+ "version_normalized": "3.0.6.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/natxet/CssMin.git",
+ "reference": "d5d9f4c3e5cedb1ae96a95a21731f8790e38f1dd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/natxet/CssMin/zipball/d5d9f4c3e5cedb1ae96a95a21731f8790e38f1dd",
+ "reference": "d5d9f4c3e5cedb1ae96a95a21731f8790e38f1dd",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.0"
+ },
+ "time": "2018-01-09T11:15:01+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Joe Scylla",
+ "email": "joe.scylla@gmail.com",
+ "homepage": "https://profiles.google.com/joe.scylla"
+ }
+ ],
+ "description": "Minifying CSS",
+ "homepage": "http://code.google.com/p/cssmin/",
+ "keywords": [
+ "css",
+ "minify"
+ ]
+ },
+ {
+ "name": "nubs/random-name-generator",
+ "version": "v2.1.0",
+ "version_normalized": "2.1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/nubs/random-name-generator.git",
+ "reference": "7004eb1724e1c4a154553e44312b7045fe412b77"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/nubs/random-name-generator/zipball/7004eb1724e1c4a154553e44312b7045fe412b77",
+ "reference": "7004eb1724e1c4a154553e44312b7045fe412b77",
+ "shasum": ""
+ },
+ "require": {
+ "php": "~5.6 || ~7.0"
+ },
+ "require-dev": {
+ "cinam/randomizer": ">=1.1.1,<2.0",
+ "phpunit/phpunit": "~5.0",
+ "satooshi/php-coveralls": "~1.0",
+ "squizlabs/php_codesniffer": "~2.3"
+ },
+ "time": "2016-12-04T01:57:19+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Nubs\\RandomNameGenerator\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Spencer Rinehart",
+ "email": "anubis@overthemonkey.com",
+ "role": "Developer"
+ }
+ ],
+ "description": "A library to create interesting, sometimes entertaining, random names.",
+ "keywords": [
+ "alliteration",
+ "generator",
+ "random",
+ "video game"
+ ]
+ },
+ {
+ "name": "paragonie/random_compat",
+ "version": "v2.0.12",
+ "version_normalized": "2.0.12.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/paragonie/random_compat.git",
+ "reference": "258c89a6b97de7dfaf5b8c7607d0478e236b04fb"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/paragonie/random_compat/zipball/258c89a6b97de7dfaf5b8c7607d0478e236b04fb",
+ "reference": "258c89a6b97de7dfaf5b8c7607d0478e236b04fb",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.2.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.*|5.*"
+ },
+ "suggest": {
+ "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
+ },
+ "time": "2018-04-04T21:24:14+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "files": [
+ "lib/random.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Paragon Initiative Enterprises",
+ "email": "security@paragonie.com",
+ "homepage": "https://paragonie.com"
+ }
+ ],
+ "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
+ "keywords": [
+ "csprng",
+ "pseudorandom",
+ "random"
+ ]
+ },
+ {
+ "name": "psr/http-message",
+ "version": "1.0.1",
+ "version_normalized": "1.0.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-message.git",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "time": "2016-08-06T14:39:51+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Message\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for HTTP messages",
+ "homepage": "https://github.com/php-fig/http-message",
+ "keywords": [
+ "http",
+ "http-message",
+ "psr",
+ "psr-7",
+ "request",
+ "response"
+ ]
+ },
+ {
+ "name": "ratchet/rfc6455",
+ "version": "v0.2.3",
+ "version_normalized": "0.2.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/ratchetphp/RFC6455.git",
+ "reference": "cc8a1a46a703ce01de10fdb5fab387381b66edc8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/ratchetphp/RFC6455/zipball/cc8a1a46a703ce01de10fdb5fab387381b66edc8",
+ "reference": "cc8a1a46a703ce01de10fdb5fab387381b66edc8",
+ "shasum": ""
+ },
+ "require": {
+ "guzzlehttp/psr7": "^1.0",
+ "php": ">=5.4.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.8.*",
+ "react/http": "^0.4.1",
+ "react/socket-client": "^0.4.3"
+ },
+ "time": "2017-09-13T13:49:42+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Ratchet\\RFC6455\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Chris Boden",
+ "email": "cboden@gmail.com",
+ "role": "Developer"
+ }
+ ],
+ "description": "RFC6455 WebSocket protocol handler",
+ "homepage": "http://socketo.me",
+ "keywords": [
+ "WebSockets",
+ "rfc6455",
+ "websocket"
+ ]
+ },
+ {
+ "name": "react/cache",
+ "version": "v0.4.2",
+ "version_normalized": "0.4.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/reactphp/cache.git",
+ "reference": "75494f26b4ef089db9bf8c90b63c296246e099e8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/reactphp/cache/zipball/75494f26b4ef089db9bf8c90b63c296246e099e8",
+ "reference": "75494f26b4ef089db9bf8c90b63c296246e099e8",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0",
+ "react/promise": "~2.0|~1.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
+ },
+ "time": "2017-12-20T16:47:13+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "React\\Cache\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Async, Promise-based cache interface for ReactPHP",
+ "keywords": [
+ "cache",
+ "caching",
+ "promise",
+ "reactphp"
+ ]
+ },
+ {
+ "name": "react/dns",
+ "version": "v0.4.13",
+ "version_normalized": "0.4.13.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/reactphp/dns.git",
+ "reference": "7d1e08c300fd7de600810883386ee5e2a64898f4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/reactphp/dns/zipball/7d1e08c300fd7de600810883386ee5e2a64898f4",
+ "reference": "7d1e08c300fd7de600810883386ee5e2a64898f4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0",
+ "react/cache": "~0.4.0|~0.3.0",
+ "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5",
+ "react/promise": "^2.1 || ^1.2.1",
+ "react/promise-timer": "^1.2",
+ "react/stream": "^1.0 || ^0.7 || ^0.6 || ^0.5 || ^0.4.5"
+ },
+ "require-dev": {
+ "clue/block-react": "^1.2",
+ "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
+ },
+ "time": "2018-02-27T12:51:22+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "React\\Dns\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Async DNS resolver for ReactPHP",
+ "keywords": [
+ "async",
+ "dns",
+ "dns-resolver",
+ "reactphp"
+ ]
+ },
+ {
+ "name": "react/event-loop",
+ "version": "v0.5.1",
+ "version_normalized": "0.5.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/reactphp/event-loop.git",
+ "reference": "e1e0647a5c6e2c86013a24e9c8252113df86105a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/reactphp/event-loop/zipball/e1e0647a5c6e2c86013a24e9c8252113df86105a",
+ "reference": "e1e0647a5c6e2c86013a24e9c8252113df86105a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.8.35 || ^5.7 || ^6.4"
+ },
+ "suggest": {
+ "ext-event": "~1.0 for ExtEventLoop",
+ "ext-pcntl": "For signal handling support when using the StreamSelectLoop"
+ },
+ "time": "2018-04-09T11:59:21+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "React\\EventLoop\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "ReactPHP's core reactor event loop that libraries can use for evented I/O.",
+ "keywords": [
+ "asynchronous",
+ "event-loop"
+ ]
+ },
+ {
+ "name": "react/promise",
+ "version": "v2.5.1",
+ "version_normalized": "2.5.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/reactphp/promise.git",
+ "reference": "62785ae604c8d69725d693eb370e1d67e94c4053"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/reactphp/promise/zipball/62785ae604c8d69725d693eb370e1d67e94c4053",
+ "reference": "62785ae604c8d69725d693eb370e1d67e94c4053",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.8"
+ },
+ "time": "2017-03-25T12:08:31+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "React\\Promise\\": "src/"
+ },
+ "files": [
+ "src/functions_include.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jan Sorgalla",
+ "email": "jsorgalla@gmail.com"
+ }
+ ],
+ "description": "A lightweight implementation of CommonJS Promises/A for PHP",
+ "keywords": [
+ "promise",
+ "promises"
+ ]
+ },
+ {
+ "name": "react/promise-timer",
+ "version": "v1.2.1",
+ "version_normalized": "1.2.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/reactphp/promise-timer.git",
+ "reference": "9b4cd9cbe7457e0d87fe8aa7ccceab8a2c830fbd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/reactphp/promise-timer/zipball/9b4cd9cbe7457e0d87fe8aa7ccceab8a2c830fbd",
+ "reference": "9b4cd9cbe7457e0d87fe8aa7ccceab8a2c830fbd",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3",
+ "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5",
+ "react/promise": "~2.1|~1.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
+ },
+ "time": "2017-12-22T15:41:41+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "React\\Promise\\Timer\\": "src/"
+ },
+ "files": [
+ "src/functions.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Christian Lück",
+ "email": "christian@lueck.tv"
+ }
+ ],
+ "description": "A trivial implementation of timeouts for Promises, built on top of ReactPHP.",
+ "homepage": "https://github.com/react/promise-timer",
+ "keywords": [
+ "async",
+ "event-loop",
+ "promise",
+ "reactphp",
+ "timeout",
+ "timer"
+ ]
+ },
+ {
+ "name": "react/socket",
+ "version": "v0.8.10",
+ "version_normalized": "0.8.10.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/reactphp/socket.git",
+ "reference": "d3957313c92b539537fccc80170c05a27ec25796"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/reactphp/socket/zipball/d3957313c92b539537fccc80170c05a27ec25796",
+ "reference": "d3957313c92b539537fccc80170c05a27ec25796",
+ "shasum": ""
+ },
+ "require": {
+ "evenement/evenement": "^3.0 || ^2.0 || ^1.0",
+ "php": ">=5.3.0",
+ "react/dns": "^0.4.13",
+ "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5",
+ "react/promise": "^2.1 || ^1.2",
+ "react/promise-timer": "~1.0",
+ "react/stream": "^1.0 || ^0.7.1"
+ },
+ "require-dev": {
+ "clue/block-react": "^1.2",
+ "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
+ },
+ "time": "2018-02-28T09:32:38+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "React\\Socket\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP",
+ "keywords": [
+ "Connection",
+ "Socket",
+ "async",
+ "reactphp",
+ "stream"
+ ]
+ },
+ {
+ "name": "react/stream",
+ "version": "v0.7.7",
+ "version_normalized": "0.7.7.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/reactphp/stream.git",
+ "reference": "10100896018fd847a257cd81143b8e1b7be08e40"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/reactphp/stream/zipball/10100896018fd847a257cd81143b8e1b7be08e40",
+ "reference": "10100896018fd847a257cd81143b8e1b7be08e40",
+ "shasum": ""
+ },
+ "require": {
+ "evenement/evenement": "^3.0 || ^2.0 || ^1.0",
+ "php": ">=5.3.8",
+ "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5"
+ },
+ "require-dev": {
+ "clue/stream-filter": "~1.2",
+ "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
+ },
+ "time": "2018-01-19T15:04:38+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "React\\Stream\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP",
+ "keywords": [
+ "event-driven",
+ "io",
+ "non-blocking",
+ "pipe",
+ "reactphp",
+ "readable",
+ "stream",
+ "writable"
+ ]
+ },
+ {
+ "name": "symfony/http-foundation",
+ "version": "v3.4.8",
+ "version_normalized": "3.4.8.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/http-foundation.git",
+ "reference": "b11e6d165ff4cbf5685d185ab19a90f2f3bb7d1e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/b11e6d165ff4cbf5685d185ab19a90f2f3bb7d1e",
+ "reference": "b11e6d165ff4cbf5685d185ab19a90f2f3bb7d1e",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.5.9|>=7.0.8",
+ "symfony/polyfill-mbstring": "~1.1",
+ "symfony/polyfill-php70": "~1.6"
+ },
+ "require-dev": {
+ "symfony/expression-language": "~2.8|~3.0|~4.0"
+ },
+ "time": "2018-04-03T05:22:50+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.4-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\HttpFoundation\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony HttpFoundation Component",
+ "homepage": "https://symfony.com"
+ },
+ {
+ "name": "symfony/polyfill-mbstring",
+ "version": "v1.7.0",
+ "version_normalized": "1.7.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
+ "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/78be803ce01e55d3491c1397cf1c64beb9c1b63b",
+ "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "suggest": {
+ "ext-mbstring": "For best performance"
+ },
+ "time": "2018-01-30T19:27:44+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.7-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Mbstring\\": ""
+ },
+ "files": [
+ "bootstrap.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": "Symfony polyfill for the Mbstring extension",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "mbstring",
+ "polyfill",
+ "portable",
+ "shim"
+ ]
+ },
+ {
+ "name": "symfony/polyfill-php70",
+ "version": "v1.7.0",
+ "version_normalized": "1.7.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php70.git",
+ "reference": "3532bfcd8f933a7816f3a0a59682fc404776600f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/3532bfcd8f933a7816f3a0a59682fc404776600f",
+ "reference": "3532bfcd8f933a7816f3a0a59682fc404776600f",
+ "shasum": ""
+ },
+ "require": {
+ "paragonie/random_compat": "~1.0|~2.0",
+ "php": ">=5.3.3"
+ },
+ "time": "2018-01-30T19:27:44+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.7-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Php70\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ],
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "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 backporting some PHP 7.0+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ]
+ },
+ {
+ "name": "symfony/routing",
+ "version": "v3.4.8",
+ "version_normalized": "3.4.8.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/routing.git",
+ "reference": "50f333b707bef9f6972ad04e6df3ec8875c9a67c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/routing/zipball/50f333b707bef9f6972ad04e6df3ec8875c9a67c",
+ "reference": "50f333b707bef9f6972ad04e6df3ec8875c9a67c",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.5.9|>=7.0.8"
+ },
+ "conflict": {
+ "symfony/config": "<3.3.1",
+ "symfony/dependency-injection": "<3.3",
+ "symfony/yaml": "<3.4"
+ },
+ "require-dev": {
+ "doctrine/annotations": "~1.0",
+ "doctrine/common": "~2.2",
+ "psr/log": "~1.0",
+ "symfony/config": "^3.3.1|~4.0",
+ "symfony/dependency-injection": "~3.3|~4.0",
+ "symfony/expression-language": "~2.8|~3.0|~4.0",
+ "symfony/http-foundation": "~2.8|~3.0|~4.0",
+ "symfony/yaml": "~3.4|~4.0"
+ },
+ "suggest": {
+ "doctrine/annotations": "For using the annotation loader",
+ "symfony/config": "For using the all-in-one router or any loader",
+ "symfony/dependency-injection": "For loading routes from a service",
+ "symfony/expression-language": "For using expression matching",
+ "symfony/http-foundation": "For using a Symfony Request object",
+ "symfony/yaml": "For using the YAML loader"
+ },
+ "time": "2018-04-04T13:22:16+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.4-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Routing\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Routing Component",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "router",
+ "routing",
+ "uri",
+ "url"
+ ]
+ }
+]
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/.gitignore b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/.gitignore
new file mode 100644
index 0000000..987e2a2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/.gitignore
@@ -0,0 +1,2 @@
+composer.lock
+vendor
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/.travis.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/.travis.yml
new file mode 100644
index 0000000..65ba0ce
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/.travis.yml
@@ -0,0 +1,24 @@
+language: php
+
+php:
+ - 7.0
+ - 7.1
+ - hhvm
+ - nightly
+
+matrix:
+ allow_failures:
+ - php: hhvm
+ - php: nightly
+
+before_script:
+ - wget http://getcomposer.org/composer.phar
+ - php composer.phar install
+
+script:
+ - ./vendor/bin/phpunit --coverage-text
+ - php -n examples/benchmark-emit-no-arguments.php
+ - php -n examples/benchmark-emit-one-argument.php
+ - php -n examples/benchmark-emit.php
+ - php -n examples/benchmark-emit-once.php
+ - php -n examples/benchmark-remove-listener-once.php
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/CHANGELOG.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/CHANGELOG.md
new file mode 100644
index 0000000..568f229
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/CHANGELOG.md
@@ -0,0 +1,35 @@
+CHANGELOG
+=========
+
+
+* v3.0.1 (2017-07-23)
+
+ * Resolved regression introduced in once listeners in v3.0.0 [#49](https://github.com/igorw/evenement/pull/49)
+
+* v3.0.0 (2017-07-23)
+
+ * Passing null as event name throw exception [#46](https://github.com/igorw/evenement/pull/46), and [#47](https://github.com/igorw/evenement/pull/47)
+ * Performance improvements [#39](https://github.com/igorw/evenement/pull/39), and [#45](https://github.com/igorw/evenement/pull/45)
+ * Remove once listeners [#44](https://github.com/igorw/evenement/pull/44), [#45](https://github.com/igorw/evenement/pull/45)
+
+* v2.1.0 (2017-07-17)
+
+ * Chaining for "on" method [#30](https://github.com/igorw/evenement/pull/30)
+ * Unit tests (on Travis) improvements [#33](https://github.com/igorw/evenement/pull/33), [#36](https://github.com/igorw/evenement/pull/36), and [#37](https://github.com/igorw/evenement/pull/37)
+ * Benchmarks added [#35](https://github.com/igorw/evenement/pull/35), and [#40](https://github.com/igorw/evenement/pull/40)
+ * Minor performance improvements [#42](https://github.com/igorw/evenement/pull/42), and [#38](https://github.com/igorw/evenement/pull/38)
+
+* v2.0.0 (2012-11-02)
+
+ * Require PHP >=5.4.0
+ * Added EventEmitterTrait
+ * Removed EventEmitter2
+
+* v1.1.0 (2017-07-17)
+
+ * Chaining for "on" method [#29](https://github.com/igorw/evenement/pull/29)
+ * Minor performance improvements [#43](https://github.com/igorw/evenement/pull/43)
+
+* v1.0.0 (2012-05-30)
+
+ * Inital stable release
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/LICENSE b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/LICENSE
new file mode 100644
index 0000000..d9a37d0
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2011 Igor Wiedler
+
+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.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/README.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/README.md
new file mode 100644
index 0000000..9443011
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/README.md
@@ -0,0 +1,83 @@
+# Événement
+
+Événement is a very simple event dispatching library for PHP.
+
+It has the same design goals as [Silex](http://silex-project.org) and
+[Pimple](http://pimple-project.org), to empower the user while staying concise
+and simple.
+
+It is very strongly inspired by the EventEmitter API found in
+[node.js](http://nodejs.org).
+
+[![Build Status](https://secure.travis-ci.org/igorw/evenement.png?branch=master)](http://travis-ci.org/igorw/evenement)
+
+## Fetch
+
+The recommended way to install Événement is [through composer](http://getcomposer.org).
+
+Just create a composer.json file for your project:
+
+```JSON
+{
+ "require": {
+ "evenement/evenement": "^3.0 || ^2.0"
+ }
+}
+```
+
+**Note:** The `3.x` version of Événement requires PHP 7 and the `2.x` version requires PHP 5.4. If you are
+using PHP 5.3, please use the `1.x` version:
+
+```JSON
+{
+ "require": {
+ "evenement/evenement": "^1.0"
+ }
+}
+```
+
+And run these two commands to install it:
+
+ $ curl -s http://getcomposer.org/installer | php
+ $ php composer.phar install
+
+Now you can add the autoloader, and you will have access to the library:
+
+```php
+<?php
+require 'vendor/autoload.php';
+```
+
+## Usage
+
+### Creating an Emitter
+
+```php
+<?php
+$emitter = new Evenement\EventEmitter();
+```
+
+### Adding Listeners
+
+```php
+<?php
+$emitter->on('user.created', function (User $user) use ($logger) {
+ $logger->log(sprintf("User '%s' was created.", $user->getLogin()));
+});
+```
+
+### Emitting Events
+
+```php
+<?php
+$emitter->emit('user.created', [$user]);
+```
+
+Tests
+-----
+
+ $ ./vendor/bin/phpunit
+
+License
+-------
+MIT, see LICENSE.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/composer.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/composer.json
new file mode 100644
index 0000000..cbb4827
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/composer.json
@@ -0,0 +1,29 @@
+{
+ "name": "evenement/evenement",
+ "description": "Événement is a very simple event dispatching library for PHP",
+ "keywords": ["event-dispatcher", "event-emitter"],
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Igor Wiedler",
+ "email": "igor@wiedler.ch"
+ }
+ ],
+ "require": {
+ "php": ">=7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.0"
+ },
+ "autoload": {
+ "psr-0": {
+ "Evenement": "src"
+ }
+ },
+ "autoload-dev": {
+ "psr-0": {
+ "Evenement": "tests"
+ },
+ "files": ["tests/Evenement/Tests/functions.php"]
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/doc/00-intro.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/doc/00-intro.md
new file mode 100644
index 0000000..6c28a2a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/doc/00-intro.md
@@ -0,0 +1,28 @@
+# Introduction
+
+Événement is is French and means "event". The événement library aims to
+provide a simple way of subscribing to events and notifying those subscribers
+whenever an event occurs.
+
+The API that it exposes is almost a direct port of the EventEmitter API found
+in node.js. It also includes an "EventEmitter". There are some minor
+differences however.
+
+The EventEmitter is an implementation of the publish-subscribe pattern, which
+is a generalized version of the observer pattern. The observer pattern
+specifies an observable subject, which observers can register themselves to.
+Once something interesting happens, the subject notifies its observers.
+
+Pub/sub takes the same idea but encapsulates the observation logic inside a
+separate object which manages all of its subscribers or listeners. Subscribers
+are bound to an event name, and will only receive notifications of the events
+they subscribed to.
+
+**TLDR: What does evenement do, in short? It provides a mapping from event
+names to a list of listener functions and triggers each listener for a given
+event when it is emitted.**
+
+Why do we do this, you ask? To achieve decoupling.
+
+It allows you to design a system where the core will emit events, and modules
+are able to subscribe to these events. And respond to them.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/doc/01-api.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/doc/01-api.md
new file mode 100644
index 0000000..17ba333
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/doc/01-api.md
@@ -0,0 +1,91 @@
+# API
+
+The API that événement exposes is defined by the
+`Evenement\EventEmitterInterface`. The interface is useful if you want to
+define an interface that extends the emitter and implicitly defines certain
+events to be emitted, or if you want to type hint an `EventEmitter` to be
+passed to a method without coupling to the specific implementation.
+
+## on($event, callable $listener)
+
+Allows you to subscribe to an event.
+
+Example:
+
+```php
+$emitter->on('user.created', function (User $user) use ($logger) {
+ $logger->log(sprintf("User '%s' was created.", $user->getLogin()));
+});
+```
+
+Since the listener can be any callable, you could also use an instance method
+instead of the anonymous function:
+
+```php
+$loggerSubscriber = new LoggerSubscriber($logger);
+$emitter->on('user.created', array($loggerSubscriber, 'onUserCreated'));
+```
+
+This has the benefit that listener does not even need to know that the emitter
+exists.
+
+You can also accept more than one parameter for the listener:
+
+```php
+$emitter->on('numbers_added', function ($result, $a, $b) {});
+```
+
+## once($event, callable $listener)
+
+Convenience method that adds a listener which is guaranteed to only be called
+once.
+
+Example:
+
+```php
+$conn->once('connected', function () use ($conn, $data) {
+ $conn->send($data);
+});
+```
+
+## emit($event, array $arguments = [])
+
+Emit an event, which will call all listeners.
+
+Example:
+
+```php
+$conn->emit('data', [$data]);
+```
+
+The second argument to emit is an array of listener arguments. This is how you
+specify more args:
+
+```php
+$result = $a + $b;
+$emitter->emit('numbers_added', [$result, $a, $b]);
+```
+
+## listeners($event)
+
+Allows you to inspect the listeners attached to an event. Particularly useful
+to check if there are any listeners at all.
+
+Example:
+
+```php
+$e = new \RuntimeException('Everything is broken!');
+if (0 === count($emitter->listeners('error'))) {
+ throw $e;
+}
+```
+
+## removeListener($event, callable $listener)
+
+Remove a specific listener for a specific event.
+
+## removeAllListeners($event = null)
+
+Remove all listeners for a specific event or all listeners all together. This
+is useful for long-running processes, where you want to remove listeners in
+order to allow them to get garbage collected.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/doc/02-plugin-system.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/doc/02-plugin-system.md
new file mode 100644
index 0000000..6a08371
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/doc/02-plugin-system.md
@@ -0,0 +1,155 @@
+# Example: Plugin system
+
+In this example I will show you how to create a generic plugin system with
+événement where plugins can alter the behaviour of the app. The app is a blog.
+Boring, I know. By using the EventEmitter it will be easy to extend this blog
+with additional functionality without modifying the core system.
+
+The blog is quite basic. Users are able to create blog posts when they log in.
+The users are stored in a static config file, so there is no sign up process.
+Once logged in they get a "new post" link which gives them a form where they
+can create a new blog post with plain HTML. That will store the post in a
+document database. The index lists all blog post titles by date descending.
+Clicking on the post title will take you to the full post.
+
+## Plugin structure
+
+The goal of the plugin system is to allow features to be added to the blog
+without modifying any core files of the blog.
+
+The plugins are managed through a config file, `plugins.json`. This JSON file
+contains a JSON-encoded list of class-names for plugin classes. This allows
+you to enable and disable plugins in a central location. The initial
+`plugins.json` is just an empty array:
+```json
+[]
+```
+
+A plugin class must implement the `PluginInterface`:
+```php
+interface PluginInterface
+{
+ function attachEvents(EventEmitterInterface $emitter);
+}
+```
+
+The `attachEvents` method allows the plugin to attach any events to the
+emitter. For example:
+```php
+class FooPlugin implements PluginInterface
+{
+ public function attachEvents(EventEmitterInterface $emitter)
+ {
+ $emitter->on('foo', function () {
+ echo 'bar!';
+ });
+ }
+}
+```
+
+The blog system creates an emitter instance and loads the plugins:
+```php
+$emitter = new EventEmitter();
+
+$pluginClasses = json_decode(file_get_contents('plugins.json'), true);
+foreach ($pluginClasses as $pluginClass) {
+ $plugin = new $pluginClass();
+ $pluginClass->attachEvents($emitter);
+}
+```
+
+This is the base system. There are no plugins yet, and there are no events yet
+either. That's because I don't know which extension points will be needed. I
+will add them on demand.
+
+## Feature: Markdown
+
+Writing blog posts in HTML sucks! Wouldn't it be great if I could write them
+in a nice format such as markdown, and have that be converted to HTML for me?
+
+This feature will need two extension points. I need to be able to mark posts
+as markdown, and I need to be able to hook into the rendering of the post body
+and convert it from markdown to HTML. So the blog needs two new events:
+`post.create` and `post.render`.
+
+In the code that creates the post, I'll insert the `post.create` event:
+```php
+class PostEvent
+{
+ public $post;
+
+ public function __construct(array $post)
+ {
+ $this->post = $post;
+ }
+}
+
+$post = createPostFromRequest($_POST);
+
+$event = new PostEvent($post);
+$emitter->emit('post.create', [$event]);
+$post = $event->post;
+
+$db->save('post', $post);
+```
+
+This shows that you can wrap a value in an event object to make it mutable,
+allowing listeners to change it.
+
+The same thing for the `post.render` event:
+```php
+public function renderPostBody(array $post)
+{
+ $emitter = $this->emitter;
+
+ $event = new PostEvent($post);
+ $emitter->emit('post.render', [$event]);
+ $post = $event->post;
+
+ return $post['body'];
+}
+
+<h1><?= $post['title'] %></h1>
+<p><?= renderPostBody($post) %></p>
+```
+
+Ok, the events are in place. It's time to create the first plugin, woohoo! I
+will call this the `MarkdownPlugin`, so here's `plugins.json`:
+```json
+[
+ "MarkdownPlugin"
+]
+```
+
+The `MarkdownPlugin` class will be autoloaded, so I don't have to worry about
+including any files. I just have to worry about implementing the plugin class.
+The `markdown` function represents a markdown to HTML converter.
+```php
+class MarkdownPlugin implements PluginInterface
+{
+ public function attachEvents(EventEmitterInterface $emitter)
+ {
+ $emitter->on('post.create', function (PostEvent $event) {
+ $event->post['format'] = 'markdown';
+ });
+
+ $emitter->on('post.render', function (PostEvent $event) {
+ if (isset($event->post['format']) && 'markdown' === $event->post['format']) {
+ $event->post['body'] = markdown($event->post['body']);
+ }
+ });
+ }
+}
+```
+
+There you go, the blog now renders posts as markdown. But all of the previous
+posts before the addition of the markdown plugin are still rendered correctly
+as raw HTML.
+
+## Feature: Comments
+
+TODO
+
+## Feature: Comment spam control
+
+TODO
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/examples/benchmark-emit-no-arguments.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/examples/benchmark-emit-no-arguments.php
new file mode 100644
index 0000000..53d7f4b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/examples/benchmark-emit-no-arguments.php
@@ -0,0 +1,28 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of Evenement.
+ *
+ * (c) Igor Wiedler <igor@wiedler.ch>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+const ITERATIONS = 10000000;
+
+use Evenement\EventEmitter;
+
+require __DIR__.'/../vendor/autoload.php';
+
+$emitter = new EventEmitter();
+
+$emitter->on('event', function () {});
+
+$start = microtime(true);
+for ($i = 0; $i < ITERATIONS; $i++) {
+ $emitter->emit('event');
+}
+$time = microtime(true) - $start;
+
+echo 'Emitting ', number_format(ITERATIONS), ' events took: ', number_format($time, 2), 's', PHP_EOL;
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/examples/benchmark-emit-once.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/examples/benchmark-emit-once.php
new file mode 100644
index 0000000..74f4d17
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/examples/benchmark-emit-once.php
@@ -0,0 +1,30 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of Evenement.
+ *
+ * (c) Igor Wiedler <igor@wiedler.ch>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+ini_set('memory_limit', '512M');
+
+const ITERATIONS = 100000;
+
+use Evenement\EventEmitter;
+
+require __DIR__.'/../vendor/autoload.php';
+
+$emitter = new EventEmitter();
+
+for ($i = 0; $i < ITERATIONS; $i++) {
+ $emitter->once('event', function ($a, $b, $c) {});
+}
+
+$start = microtime(true);
+$emitter->emit('event', [1, 2, 3]);
+$time = microtime(true) - $start;
+
+echo 'Emitting one event to ', number_format(ITERATIONS), ' once listeners took: ', number_format($time, 2), 's', PHP_EOL;
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/examples/benchmark-emit-one-argument.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/examples/benchmark-emit-one-argument.php
new file mode 100644
index 0000000..39fc4ba
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/examples/benchmark-emit-one-argument.php
@@ -0,0 +1,28 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of Evenement.
+ *
+ * (c) Igor Wiedler <igor@wiedler.ch>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+const ITERATIONS = 10000000;
+
+use Evenement\EventEmitter;
+
+require __DIR__.'/../vendor/autoload.php';
+
+$emitter = new EventEmitter();
+
+$emitter->on('event', function ($a) {});
+
+$start = microtime(true);
+for ($i = 0; $i < ITERATIONS; $i++) {
+ $emitter->emit('event', [1]);
+}
+$time = microtime(true) - $start;
+
+echo 'Emitting ', number_format(ITERATIONS), ' events took: ', number_format($time, 2), 's', PHP_EOL;
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/examples/benchmark-emit.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/examples/benchmark-emit.php
new file mode 100644
index 0000000..3ab639e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/examples/benchmark-emit.php
@@ -0,0 +1,28 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of Evenement.
+ *
+ * (c) Igor Wiedler <igor@wiedler.ch>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+const ITERATIONS = 10000000;
+
+use Evenement\EventEmitter;
+
+require __DIR__.'/../vendor/autoload.php';
+
+$emitter = new EventEmitter();
+
+$emitter->on('event', function ($a, $b, $c) {});
+
+$start = microtime(true);
+for ($i = 0; $i < ITERATIONS; $i++) {
+ $emitter->emit('event', [1, 2, 3]);
+}
+$time = microtime(true) - $start;
+
+echo 'Emitting ', number_format(ITERATIONS), ' events took: ', number_format($time, 2), 's', PHP_EOL;
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/examples/benchmark-remove-listener-once.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/examples/benchmark-remove-listener-once.php
new file mode 100644
index 0000000..414be3b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/examples/benchmark-remove-listener-once.php
@@ -0,0 +1,39 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of Evenement.
+ *
+ * (c) Igor Wiedler <igor@wiedler.ch>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+ini_set('memory_limit', '512M');
+
+const ITERATIONS = 100000;
+
+use Evenement\EventEmitter;
+
+require __DIR__.'/../vendor/autoload.php';
+
+$emitter = new EventEmitter();
+
+$listeners = [];
+for ($i = 0; $i < ITERATIONS; $i++) {
+ $listeners[] = function ($a, $b, $c) {};
+}
+
+$start = microtime(true);
+foreach ($listeners as $listener) {
+ $emitter->once('event', $listener);
+}
+$time = microtime(true) - $start;
+echo 'Adding ', number_format(ITERATIONS), ' once listeners took: ', number_format($time, 2), 's', PHP_EOL;
+
+$start = microtime(true);
+foreach ($listeners as $listener) {
+ $emitter->removeListener('event', $listener);
+}
+$time = microtime(true) - $start;
+echo 'Removing ', number_format(ITERATIONS), ' once listeners took: ', number_format($time, 2), 's', PHP_EOL;
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/phpunit.xml.dist b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/phpunit.xml.dist
new file mode 100644
index 0000000..70bc693
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/phpunit.xml.dist
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit backupGlobals="false"
+ backupStaticAttributes="false"
+ colors="true"
+ convertErrorsToExceptions="true"
+ convertNoticesToExceptions="true"
+ convertWarningsToExceptions="true"
+ processIsolation="false"
+ stopOnFailure="false"
+ syntaxCheck="false"
+>
+ <testsuites>
+ <testsuite name="Evenement Test Suite">
+ <directory>./tests/Evenement/</directory>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist>
+ <directory>./src/</directory>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/src/Evenement/EventEmitter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/src/Evenement/EventEmitter.php
new file mode 100644
index 0000000..db189b9
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/src/Evenement/EventEmitter.php
@@ -0,0 +1,17 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of Evenement.
+ *
+ * (c) Igor Wiedler <igor@wiedler.ch>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Evenement;
+
+class EventEmitter implements EventEmitterInterface
+{
+ use EventEmitterTrait;
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/src/Evenement/EventEmitterInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/src/Evenement/EventEmitterInterface.php
new file mode 100644
index 0000000..310631a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/src/Evenement/EventEmitterInterface.php
@@ -0,0 +1,22 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of Evenement.
+ *
+ * (c) Igor Wiedler <igor@wiedler.ch>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Evenement;
+
+interface EventEmitterInterface
+{
+ public function on($event, callable $listener);
+ public function once($event, callable $listener);
+ public function removeListener($event, callable $listener);
+ public function removeAllListeners($event = null);
+ public function listeners($event = null);
+ public function emit($event, array $arguments = []);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php
new file mode 100644
index 0000000..a78e65c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php
@@ -0,0 +1,135 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of Evenement.
+ *
+ * (c) Igor Wiedler <igor@wiedler.ch>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Evenement;
+
+use InvalidArgumentException;
+
+trait EventEmitterTrait
+{
+ protected $listeners = [];
+ protected $onceListeners = [];
+
+ public function on($event, callable $listener)
+ {
+ if ($event === null) {
+ throw new InvalidArgumentException('event name must not be null');
+ }
+
+ if (!isset($this->listeners[$event])) {
+ $this->listeners[$event] = [];
+ }
+
+ $this->listeners[$event][] = $listener;
+
+ return $this;
+ }
+
+ public function once($event, callable $listener)
+ {
+ if ($event === null) {
+ throw new InvalidArgumentException('event name must not be null');
+ }
+
+ if (!isset($this->onceListeners[$event])) {
+ $this->onceListeners[$event] = [];
+ }
+
+ $this->onceListeners[$event][] = $listener;
+
+ return $this;
+ }
+
+ public function removeListener($event, callable $listener)
+ {
+ if ($event === null) {
+ throw new InvalidArgumentException('event name must not be null');
+ }
+
+ if (isset($this->listeners[$event])) {
+ $index = \array_search($listener, $this->listeners[$event], true);
+ if (false !== $index) {
+ unset($this->listeners[$event][$index]);
+ if (\count($this->listeners[$event]) === 0) {
+ unset($this->listeners[$event]);
+ }
+ }
+ }
+
+ if (isset($this->onceListeners[$event])) {
+ $index = \array_search($listener, $this->onceListeners[$event], true);
+ if (false !== $index) {
+ unset($this->onceListeners[$event][$index]);
+ if (\count($this->onceListeners[$event]) === 0) {
+ unset($this->onceListeners[$event]);
+ }
+ }
+ }
+ }
+
+ public function removeAllListeners($event = null)
+ {
+ if ($event !== null) {
+ unset($this->listeners[$event]);
+ } else {
+ $this->listeners = [];
+ }
+
+ if ($event !== null) {
+ unset($this->onceListeners[$event]);
+ } else {
+ $this->onceListeners = [];
+ }
+ }
+
+ public function listeners($event = null): array
+ {
+ if ($event === null) {
+ $events = [];
+ $eventNames = \array_unique(
+ \array_merge(\array_keys($this->listeners), \array_keys($this->onceListeners))
+ );
+ foreach ($eventNames as $eventName) {
+ $events[$eventName] = \array_merge(
+ isset($this->listeners[$eventName]) ? $this->listeners[$eventName] : [],
+ isset($this->onceListeners[$eventName]) ? $this->onceListeners[$eventName] : []
+ );
+ }
+ return $events;
+ }
+
+ return \array_merge(
+ isset($this->listeners[$event]) ? $this->listeners[$event] : [],
+ isset($this->onceListeners[$event]) ? $this->onceListeners[$event] : []
+ );
+ }
+
+ public function emit($event, array $arguments = [])
+ {
+ if ($event === null) {
+ throw new InvalidArgumentException('event name must not be null');
+ }
+
+ if (isset($this->listeners[$event])) {
+ foreach ($this->listeners[$event] as $listener) {
+ $listener(...$arguments);
+ }
+ }
+
+ if (isset($this->onceListeners[$event])) {
+ $listeners = $this->onceListeners[$event];
+ unset($this->onceListeners[$event]);
+ foreach ($listeners as $listener) {
+ $listener(...$arguments);
+ }
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/tests/Evenement/Tests/EventEmitterTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/tests/Evenement/Tests/EventEmitterTest.php
new file mode 100644
index 0000000..28f3011
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/tests/Evenement/Tests/EventEmitterTest.php
@@ -0,0 +1,438 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of Evenement.
+ *
+ * (c) Igor Wiedler <igor@wiedler.ch>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Evenement\Tests;
+
+use Evenement\EventEmitter;
+use InvalidArgumentException;
+use PHPUnit\Framework\TestCase;
+
+class EventEmitterTest extends TestCase
+{
+ private $emitter;
+
+ public function setUp()
+ {
+ $this->emitter = new EventEmitter();
+ }
+
+ public function testAddListenerWithLambda()
+ {
+ $this->emitter->on('foo', function () {});
+ }
+
+ public function testAddListenerWithMethod()
+ {
+ $listener = new Listener();
+ $this->emitter->on('foo', [$listener, 'onFoo']);
+ }
+
+ public function testAddListenerWithStaticMethod()
+ {
+ $this->emitter->on('bar', ['Evenement\Tests\Listener', 'onBar']);
+ }
+
+ public function testAddListenerWithInvalidListener()
+ {
+ try {
+ $this->emitter->on('foo', 'not a callable');
+ $this->fail();
+ } catch (\Exception $e) {
+ } catch (\TypeError $e) {
+ }
+ }
+
+ public function testOnce()
+ {
+ $listenerCalled = 0;
+
+ $this->emitter->once('foo', function () use (&$listenerCalled) {
+ $listenerCalled++;
+ });
+
+ $this->assertSame(0, $listenerCalled);
+
+ $this->emitter->emit('foo');
+
+ $this->assertSame(1, $listenerCalled);
+
+ $this->emitter->emit('foo');
+
+ $this->assertSame(1, $listenerCalled);
+ }
+
+ public function testOnceWithArguments()
+ {
+ $capturedArgs = [];
+
+ $this->emitter->once('foo', function ($a, $b) use (&$capturedArgs) {
+ $capturedArgs = array($a, $b);
+ });
+
+ $this->emitter->emit('foo', array('a', 'b'));
+
+ $this->assertSame(array('a', 'b'), $capturedArgs);
+ }
+
+ public function testEmitWithoutArguments()
+ {
+ $listenerCalled = false;
+
+ $this->emitter->on('foo', function () use (&$listenerCalled) {
+ $listenerCalled = true;
+ });
+
+ $this->assertSame(false, $listenerCalled);
+ $this->emitter->emit('foo');
+ $this->assertSame(true, $listenerCalled);
+ }
+
+ public function testEmitWithOneArgument()
+ {
+ $test = $this;
+
+ $listenerCalled = false;
+
+ $this->emitter->on('foo', function ($value) use (&$listenerCalled, $test) {
+ $listenerCalled = true;
+
+ $test->assertSame('bar', $value);
+ });
+
+ $this->assertSame(false, $listenerCalled);
+ $this->emitter->emit('foo', ['bar']);
+ $this->assertSame(true, $listenerCalled);
+ }
+
+ public function testEmitWithTwoArguments()
+ {
+ $test = $this;
+
+ $listenerCalled = false;
+
+ $this->emitter->on('foo', function ($arg1, $arg2) use (&$listenerCalled, $test) {
+ $listenerCalled = true;
+
+ $test->assertSame('bar', $arg1);
+ $test->assertSame('baz', $arg2);
+ });
+
+ $this->assertSame(false, $listenerCalled);
+ $this->emitter->emit('foo', ['bar', 'baz']);
+ $this->assertSame(true, $listenerCalled);
+ }
+
+ public function testEmitWithNoListeners()
+ {
+ $this->emitter->emit('foo');
+ $this->emitter->emit('foo', ['bar']);
+ $this->emitter->emit('foo', ['bar', 'baz']);
+ }
+
+ public function testEmitWithTwoListeners()
+ {
+ $listenersCalled = 0;
+
+ $this->emitter->on('foo', function () use (&$listenersCalled) {
+ $listenersCalled++;
+ });
+
+ $this->emitter->on('foo', function () use (&$listenersCalled) {
+ $listenersCalled++;
+ });
+
+ $this->assertSame(0, $listenersCalled);
+ $this->emitter->emit('foo');
+ $this->assertSame(2, $listenersCalled);
+ }
+
+ public function testRemoveListenerMatching()
+ {
+ $listenersCalled = 0;
+
+ $listener = function () use (&$listenersCalled) {
+ $listenersCalled++;
+ };
+
+ $this->emitter->on('foo', $listener);
+ $this->emitter->removeListener('foo', $listener);
+
+ $this->assertSame(0, $listenersCalled);
+ $this->emitter->emit('foo');
+ $this->assertSame(0, $listenersCalled);
+ }
+
+ public function testRemoveListenerNotMatching()
+ {
+ $listenersCalled = 0;
+
+ $listener = function () use (&$listenersCalled) {
+ $listenersCalled++;
+ };
+
+ $this->emitter->on('foo', $listener);
+ $this->emitter->removeListener('bar', $listener);
+
+ $this->assertSame(0, $listenersCalled);
+ $this->emitter->emit('foo');
+ $this->assertSame(1, $listenersCalled);
+ }
+
+ public function testRemoveAllListenersMatching()
+ {
+ $listenersCalled = 0;
+
+ $this->emitter->on('foo', function () use (&$listenersCalled) {
+ $listenersCalled++;
+ });
+
+ $this->emitter->removeAllListeners('foo');
+
+ $this->assertSame(0, $listenersCalled);
+ $this->emitter->emit('foo');
+ $this->assertSame(0, $listenersCalled);
+ }
+
+ public function testRemoveAllListenersNotMatching()
+ {
+ $listenersCalled = 0;
+
+ $this->emitter->on('foo', function () use (&$listenersCalled) {
+ $listenersCalled++;
+ });
+
+ $this->emitter->removeAllListeners('bar');
+
+ $this->assertSame(0, $listenersCalled);
+ $this->emitter->emit('foo');
+ $this->assertSame(1, $listenersCalled);
+ }
+
+ public function testRemoveAllListenersWithoutArguments()
+ {
+ $listenersCalled = 0;
+
+ $this->emitter->on('foo', function () use (&$listenersCalled) {
+ $listenersCalled++;
+ });
+
+ $this->emitter->on('bar', function () use (&$listenersCalled) {
+ $listenersCalled++;
+ });
+
+ $this->emitter->removeAllListeners();
+
+ $this->assertSame(0, $listenersCalled);
+ $this->emitter->emit('foo');
+ $this->emitter->emit('bar');
+ $this->assertSame(0, $listenersCalled);
+ }
+
+ public function testCallablesClosure()
+ {
+ $calledWith = null;
+
+ $this->emitter->on('foo', function ($data) use (&$calledWith) {
+ $calledWith = $data;
+ });
+
+ $this->emitter->emit('foo', ['bar']);
+
+ self::assertSame('bar', $calledWith);
+ }
+
+ public function testCallablesClass()
+ {
+ $listener = new Listener();
+ $this->emitter->on('foo', [$listener, 'onFoo']);
+
+ $this->emitter->emit('foo', ['bar']);
+
+ self::assertSame(['bar'], $listener->getData());
+ }
+
+
+ public function testCallablesClassInvoke()
+ {
+ $listener = new Listener();
+ $this->emitter->on('foo', $listener);
+
+ $this->emitter->emit('foo', ['bar']);
+
+ self::assertSame(['bar'], $listener->getMagicData());
+ }
+
+ public function testCallablesStaticClass()
+ {
+ $this->emitter->on('foo', '\Evenement\Tests\Listener::onBar');
+
+ $this->emitter->emit('foo', ['bar']);
+
+ self::assertSame(['bar'], Listener::getStaticData());
+ }
+
+ public function testCallablesFunction()
+ {
+ $this->emitter->on('foo', '\Evenement\Tests\setGlobalTestData');
+
+ $this->emitter->emit('foo', ['bar']);
+
+ self::assertSame('bar', $GLOBALS['evenement-evenement-test-data']);
+
+ unset($GLOBALS['evenement-evenement-test-data']);
+ }
+
+ public function testListeners()
+ {
+ $onA = function () {};
+ $onB = function () {};
+ $onC = function () {};
+ $onceA = function () {};
+ $onceB = function () {};
+ $onceC = function () {};
+
+ self::assertCount(0, $this->emitter->listeners('event'));
+ $this->emitter->on('event', $onA);
+ self::assertCount(1, $this->emitter->listeners('event'));
+ self::assertSame([$onA], $this->emitter->listeners('event'));
+ $this->emitter->once('event', $onceA);
+ self::assertCount(2, $this->emitter->listeners('event'));
+ self::assertSame([$onA, $onceA], $this->emitter->listeners('event'));
+ $this->emitter->once('event', $onceB);
+ self::assertCount(3, $this->emitter->listeners('event'));
+ self::assertSame([$onA, $onceA, $onceB], $this->emitter->listeners('event'));
+ $this->emitter->on('event', $onB);
+ self::assertCount(4, $this->emitter->listeners('event'));
+ self::assertSame([$onA, $onB, $onceA, $onceB], $this->emitter->listeners('event'));
+ $this->emitter->removeListener('event', $onceA);
+ self::assertCount(3, $this->emitter->listeners('event'));
+ self::assertSame([$onA, $onB, $onceB], $this->emitter->listeners('event'));
+ $this->emitter->once('event', $onceC);
+ self::assertCount(4, $this->emitter->listeners('event'));
+ self::assertSame([$onA, $onB, $onceB, $onceC], $this->emitter->listeners('event'));
+ $this->emitter->on('event', $onC);
+ self::assertCount(5, $this->emitter->listeners('event'));
+ self::assertSame([$onA, $onB, $onC, $onceB, $onceC], $this->emitter->listeners('event'));
+ $this->emitter->once('event', $onceA);
+ self::assertCount(6, $this->emitter->listeners('event'));
+ self::assertSame([$onA, $onB, $onC, $onceB, $onceC, $onceA], $this->emitter->listeners('event'));
+ $this->emitter->removeListener('event', $onB);
+ self::assertCount(5, $this->emitter->listeners('event'));
+ self::assertSame([$onA, $onC, $onceB, $onceC, $onceA], $this->emitter->listeners('event'));
+ $this->emitter->emit('event');
+ self::assertCount(2, $this->emitter->listeners('event'));
+ self::assertSame([$onA, $onC], $this->emitter->listeners('event'));
+ }
+
+ public function testOnceCallIsNotRemovedWhenWorkingOverOnceListeners()
+ {
+ $aCalled = false;
+ $aCallable = function () use (&$aCalled) {
+ $aCalled = true;
+ };
+ $bCalled = false;
+ $bCallable = function () use (&$bCalled, $aCallable) {
+ $bCalled = true;
+ $this->emitter->once('event', $aCallable);
+ };
+ $this->emitter->once('event', $bCallable);
+
+ self::assertFalse($aCalled);
+ self::assertFalse($bCalled);
+ $this->emitter->emit('event');
+
+ self::assertFalse($aCalled);
+ self::assertTrue($bCalled);
+ $this->emitter->emit('event');
+
+ self::assertTrue($aCalled);
+ self::assertTrue($bCalled);
+ }
+
+ public function testEventNameMustBeStringOn()
+ {
+ self::expectException(InvalidArgumentException::class);
+ self::expectExceptionMessage('event name must not be null');
+
+ $this->emitter->on(null, function () {});
+ }
+
+ public function testEventNameMustBeStringOnce()
+ {
+ self::expectException(InvalidArgumentException::class);
+ self::expectExceptionMessage('event name must not be null');
+
+ $this->emitter->once(null, function () {});
+ }
+
+ public function testEventNameMustBeStringRemoveListener()
+ {
+ self::expectException(InvalidArgumentException::class);
+ self::expectExceptionMessage('event name must not be null');
+
+ $this->emitter->removeListener(null, function () {});
+ }
+
+ public function testEventNameMustBeStringEmit()
+ {
+ self::expectException(InvalidArgumentException::class);
+ self::expectExceptionMessage('event name must not be null');
+
+ $this->emitter->emit(null);
+ }
+
+ public function testListenersGetAll()
+ {
+ $a = function () {};
+ $b = function () {};
+ $c = function () {};
+ $d = function () {};
+
+ $this->emitter->once('event2', $c);
+ $this->emitter->on('event', $a);
+ $this->emitter->once('event', $b);
+ $this->emitter->on('event', $c);
+ $this->emitter->once('event', $d);
+
+ self::assertSame(
+ [
+ 'event' => [
+ $a,
+ $c,
+ $b,
+ $d,
+ ],
+ 'event2' => [
+ $c,
+ ],
+ ],
+ $this->emitter->listeners()
+ );
+ }
+
+ public function testOnceNestedCallRegression()
+ {
+ $first = 0;
+ $second = 0;
+
+ $this->emitter->once('event', function () use (&$first, &$second) {
+ $first++;
+ $this->emitter->once('event', function () use (&$second) {
+ $second++;
+ });
+ $this->emitter->emit('event');
+ });
+ $this->emitter->emit('event');
+
+ self::assertSame(1, $first);
+ self::assertSame(1, $second);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/tests/Evenement/Tests/Listener.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/tests/Evenement/Tests/Listener.php
new file mode 100644
index 0000000..df17424
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/tests/Evenement/Tests/Listener.php
@@ -0,0 +1,51 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of Evenement.
+ *
+ * (c) Igor Wiedler <igor@wiedler.ch>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Evenement\Tests;
+
+class Listener
+{
+ private $data = [];
+
+ private $magicData = [];
+
+ private static $staticData = [];
+
+ public function onFoo($data)
+ {
+ $this->data[] = $data;
+ }
+
+ public function __invoke($data)
+ {
+ $this->magicData[] = $data;
+ }
+
+ public static function onBar($data)
+ {
+ self::$staticData[] = $data;
+ }
+
+ public function getData()
+ {
+ return $this->data;
+ }
+
+ public function getMagicData()
+ {
+ return $this->magicData;
+ }
+
+ public static function getStaticData()
+ {
+ return self::$staticData;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/tests/Evenement/Tests/functions.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/tests/Evenement/Tests/functions.php
new file mode 100644
index 0000000..7f11f5b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/evenement/evenement/tests/Evenement/Tests/functions.php
@@ -0,0 +1,17 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of Evenement.
+ *
+ * (c) Igor Wiedler <igor@wiedler.ch>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Evenement\Tests;
+
+function setGlobalTestData($data)
+{
+ $GLOBALS['evenement-evenement-test-data'] = $data;
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/CHANGELOG.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/CHANGELOG.md
new file mode 100644
index 0000000..5c252b3
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/CHANGELOG.md
@@ -0,0 +1,110 @@
+# CHANGELOG
+
+## 1.4.2 - 2017-03-20
+
+* Reverted BC break to `Uri::resolve` and `Uri::removeDotSegments` by removing
+ calls to `trigger_error` when deprecated methods are invoked.
+
+## 1.4.1 - 2017-02-27
+
+* Reverted BC break by reintroducing behavior to automagically fix a URI with a
+ relative path and an authority by adding a leading slash to the path. It's only
+ deprecated now.
+* Added triggering of silenced deprecation warnings.
+
+## 1.4.0 - 2017-02-21
+
+* Fix `Stream::read` when length parameter <= 0.
+* `copy_to_stream` reads bytes in chunks instead of `maxLen` into memory.
+* Fix `ServerRequest::getUriFromGlobals` when `Host` header contains port.
+* Ensure `ServerRequest::getUriFromGlobals` returns a URI in absolute form.
+* Allow `parse_response` to parse a response without delimiting space and reason.
+* Ensure each URI modification results in a valid URI according to PSR-7 discussions.
+ Invalid modifications will throw an exception instead of returning a wrong URI or
+ doing some magic.
+ - `(new Uri)->withPath('foo')->withHost('example.com')` will throw an exception
+ because the path of a URI with an authority must start with a slash "/" or be empty
+ - `(new Uri())->withScheme('http')` will return `'http://localhost'`
+* Fix compatibility of URIs with `file` scheme and empty host.
+* Added common URI utility methods based on RFC 3986 (see documentation in the readme):
+ - `Uri::isDefaultPort`
+ - `Uri::isAbsolute`
+ - `Uri::isNetworkPathReference`
+ - `Uri::isAbsolutePathReference`
+ - `Uri::isRelativePathReference`
+ - `Uri::isSameDocumentReference`
+ - `Uri::composeComponents`
+ - `UriNormalizer::normalize`
+ - `UriNormalizer::isEquivalent`
+ - `UriResolver::relativize`
+* Deprecated `Uri::resolve` in favor of `UriResolver::resolve`
+* Deprecated `Uri::removeDotSegments` in favor of `UriResolver::removeDotSegments`
+
+## 1.3.1 - 2016-06-25
+
+* Fix `Uri::__toString` for network path references, e.g. `//example.org`.
+* Fix missing lowercase normalization for host.
+* Fix handling of URI components in case they are `'0'` in a lot of places,
+ e.g. as a user info password.
+* Fix `Uri::withAddedHeader` to correctly merge headers with different case.
+* Fix trimming of header values in `Uri::withAddedHeader`. Header values may
+ be surrounded by whitespace which should be ignored according to RFC 7230
+ Section 3.2.4. This does not apply to header names.
+* Fix `Uri::withAddedHeader` with an array of header values.
+* Fix `Uri::resolve` when base path has no slash and handling of fragment.
+* Fix handling of encoding in `Uri::with(out)QueryValue` so one can pass the
+ key/value both in encoded as well as decoded form to those methods. This is
+ consistent with withPath, withQuery etc.
+* Fix `ServerRequest::withoutAttribute` when attribute value is null.
+
+## 1.3.0 - 2016-04-13
+
+* Added remaining interfaces needed for full PSR7 compatibility
+ (ServerRequestInterface, UploadedFileInterface, etc.).
+* Added support for stream_for from scalars.
+* Can now extend Uri.
+* Fixed a bug in validating request methods by making it more permissive.
+
+## 1.2.3 - 2016-02-18
+
+* Fixed support in `GuzzleHttp\Psr7\CachingStream` for seeking forward on remote
+ streams, which can sometimes return fewer bytes than requested with `fread`.
+* Fixed handling of gzipped responses with FNAME headers.
+
+## 1.2.2 - 2016-01-22
+
+* Added support for URIs without any authority.
+* Added support for HTTP 451 'Unavailable For Legal Reasons.'
+* Added support for using '0' as a filename.
+* Added support for including non-standard ports in Host headers.
+
+## 1.2.1 - 2015-11-02
+
+* Now supporting negative offsets when seeking to SEEK_END.
+
+## 1.2.0 - 2015-08-15
+
+* Body as `"0"` is now properly added to a response.
+* Now allowing forward seeking in CachingStream.
+* Now properly parsing HTTP requests that contain proxy targets in
+ `parse_request`.
+* functions.php is now conditionally required.
+* user-info is no longer dropped when resolving URIs.
+
+## 1.1.0 - 2015-06-24
+
+* URIs can now be relative.
+* `multipart/form-data` headers are now overridden case-insensitively.
+* URI paths no longer encode the following characters because they are allowed
+ in URIs: "(", ")", "*", "!", "'"
+* A port is no longer added to a URI when the scheme is missing and no port is
+ present.
+
+## 1.0.0 - 2015-05-19
+
+Initial release.
+
+Currently unsupported:
+
+- `Psr\Http\Message\ServerRequestInterface`
+- `Psr\Http\Message\UploadedFileInterface`
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/LICENSE b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/LICENSE
new file mode 100644
index 0000000..581d95f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2015 Michael Dowling, https://github.com/mtdowling <mtdowling@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/README.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/README.md
new file mode 100644
index 0000000..1649935
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/README.md
@@ -0,0 +1,739 @@
+# PSR-7 Message Implementation
+
+This repository contains a full [PSR-7](http://www.php-fig.org/psr/psr-7/)
+message implementation, several stream decorators, and some helpful
+functionality like query string parsing.
+
+
+[![Build Status](https://travis-ci.org/guzzle/psr7.svg?branch=master)](https://travis-ci.org/guzzle/psr7)
+
+
+# Stream implementation
+
+This package comes with a number of stream implementations and stream
+decorators.
+
+
+## AppendStream
+
+`GuzzleHttp\Psr7\AppendStream`
+
+Reads from multiple streams, one after the other.
+
+```php
+use GuzzleHttp\Psr7;
+
+$a = Psr7\stream_for('abc, ');
+$b = Psr7\stream_for('123.');
+$composed = new Psr7\AppendStream([$a, $b]);
+
+$composed->addStream(Psr7\stream_for(' Above all listen to me'));
+
+echo $composed; // abc, 123. Above all listen to me.
+```
+
+
+## BufferStream
+
+`GuzzleHttp\Psr7\BufferStream`
+
+Provides a buffer stream that can be written to fill a buffer, and read
+from to remove bytes from the buffer.
+
+This stream returns a "hwm" metadata value that tells upstream consumers
+what the configured high water mark of the stream is, or the maximum
+preferred size of the buffer.
+
+```php
+use GuzzleHttp\Psr7;
+
+// When more than 1024 bytes are in the buffer, it will begin returning
+// false to writes. This is an indication that writers should slow down.
+$buffer = new Psr7\BufferStream(1024);
+```
+
+
+## CachingStream
+
+The CachingStream is used to allow seeking over previously read bytes on
+non-seekable streams. This can be useful when transferring a non-seekable
+entity body fails due to needing to rewind the stream (for example, resulting
+from a redirect). Data that is read from the remote stream will be buffered in
+a PHP temp stream so that previously read bytes are cached first in memory,
+then on disk.
+
+```php
+use GuzzleHttp\Psr7;
+
+$original = Psr7\stream_for(fopen('http://www.google.com', 'r'));
+$stream = new Psr7\CachingStream($original);
+
+$stream->read(1024);
+echo $stream->tell();
+// 1024
+
+$stream->seek(0);
+echo $stream->tell();
+// 0
+```
+
+
+## DroppingStream
+
+`GuzzleHttp\Psr7\DroppingStream`
+
+Stream decorator that begins dropping data once the size of the underlying
+stream becomes too full.
+
+```php
+use GuzzleHttp\Psr7;
+
+// Create an empty stream
+$stream = Psr7\stream_for();
+
+// Start dropping data when the stream has more than 10 bytes
+$dropping = new Psr7\DroppingStream($stream, 10);
+
+$dropping->write('01234567890123456789');
+echo $stream; // 0123456789
+```
+
+
+## FnStream
+
+`GuzzleHttp\Psr7\FnStream`
+
+Compose stream implementations based on a hash of functions.
+
+Allows for easy testing and extension of a provided stream without needing
+to create a concrete class for a simple extension point.
+
+```php
+
+use GuzzleHttp\Psr7;
+
+$stream = Psr7\stream_for('hi');
+$fnStream = Psr7\FnStream::decorate($stream, [
+ 'rewind' => function () use ($stream) {
+ echo 'About to rewind - ';
+ $stream->rewind();
+ echo 'rewound!';
+ }
+]);
+
+$fnStream->rewind();
+// Outputs: About to rewind - rewound!
+```
+
+
+## InflateStream
+
+`GuzzleHttp\Psr7\InflateStream`
+
+Uses PHP's zlib.inflate filter to inflate deflate or gzipped content.
+
+This stream decorator skips the first 10 bytes of the given stream to remove
+the gzip header, converts the provided stream to a PHP stream resource,
+then appends the zlib.inflate filter. The stream is then converted back
+to a Guzzle stream resource to be used as a Guzzle stream.
+
+
+## LazyOpenStream
+
+`GuzzleHttp\Psr7\LazyOpenStream`
+
+Lazily reads or writes to a file that is opened only after an IO operation
+take place on the stream.
+
+```php
+use GuzzleHttp\Psr7;
+
+$stream = new Psr7\LazyOpenStream('/path/to/file', 'r');
+// The file has not yet been opened...
+
+echo $stream->read(10);
+// The file is opened and read from only when needed.
+```
+
+
+## LimitStream
+
+`GuzzleHttp\Psr7\LimitStream`
+
+LimitStream can be used to read a subset or slice of an existing stream object.
+This can be useful for breaking a large file into smaller pieces to be sent in
+chunks (e.g. Amazon S3's multipart upload API).
+
+```php
+use GuzzleHttp\Psr7;
+
+$original = Psr7\stream_for(fopen('/tmp/test.txt', 'r+'));
+echo $original->getSize();
+// >>> 1048576
+
+// Limit the size of the body to 1024 bytes and start reading from byte 2048
+$stream = new Psr7\LimitStream($original, 1024, 2048);
+echo $stream->getSize();
+// >>> 1024
+echo $stream->tell();
+// >>> 0
+```
+
+
+## MultipartStream
+
+`GuzzleHttp\Psr7\MultipartStream`
+
+Stream that when read returns bytes for a streaming multipart or
+multipart/form-data stream.
+
+
+## NoSeekStream
+
+`GuzzleHttp\Psr7\NoSeekStream`
+
+NoSeekStream wraps a stream and does not allow seeking.
+
+```php
+use GuzzleHttp\Psr7;
+
+$original = Psr7\stream_for('foo');
+$noSeek = new Psr7\NoSeekStream($original);
+
+echo $noSeek->read(3);
+// foo
+var_export($noSeek->isSeekable());
+// false
+$noSeek->seek(0);
+var_export($noSeek->read(3));
+// NULL
+```
+
+
+## PumpStream
+
+`GuzzleHttp\Psr7\PumpStream`
+
+Provides a read only stream that pumps data from a PHP callable.
+
+When invoking the provided callable, the PumpStream will pass the amount of
+data requested to read to the callable. The callable can choose to ignore
+this value and return fewer or more bytes than requested. Any extra data
+returned by the provided callable is buffered internally until drained using
+the read() function of the PumpStream. The provided callable MUST return
+false when there is no more data to read.
+
+
+## Implementing stream decorators
+
+Creating a stream decorator is very easy thanks to the
+`GuzzleHttp\Psr7\StreamDecoratorTrait`. This trait provides methods that
+implement `Psr\Http\Message\StreamInterface` by proxying to an underlying
+stream. Just `use` the `StreamDecoratorTrait` and implement your custom
+methods.
+
+For example, let's say we wanted to call a specific function each time the last
+byte is read from a stream. This could be implemented by overriding the
+`read()` method.
+
+```php
+use Psr\Http\Message\StreamInterface;
+use GuzzleHttp\Psr7\StreamDecoratorTrait;
+
+class EofCallbackStream implements StreamInterface
+{
+ use StreamDecoratorTrait;
+
+ private $callback;
+
+ public function __construct(StreamInterface $stream, callable $cb)
+ {
+ $this->stream = $stream;
+ $this->callback = $cb;
+ }
+
+ public function read($length)
+ {
+ $result = $this->stream->read($length);
+
+ // Invoke the callback when EOF is hit.
+ if ($this->eof()) {
+ call_user_func($this->callback);
+ }
+
+ return $result;
+ }
+}
+```
+
+This decorator could be added to any existing stream and used like so:
+
+```php
+use GuzzleHttp\Psr7;
+
+$original = Psr7\stream_for('foo');
+
+$eofStream = new EofCallbackStream($original, function () {
+ echo 'EOF!';
+});
+
+$eofStream->read(2);
+$eofStream->read(1);
+// echoes "EOF!"
+$eofStream->seek(0);
+$eofStream->read(3);
+// echoes "EOF!"
+```
+
+
+## PHP StreamWrapper
+
+You can use the `GuzzleHttp\Psr7\StreamWrapper` class if you need to use a
+PSR-7 stream as a PHP stream resource.
+
+Use the `GuzzleHttp\Psr7\StreamWrapper::getResource()` method to create a PHP
+stream from a PSR-7 stream.
+
+```php
+use GuzzleHttp\Psr7\StreamWrapper;
+
+$stream = GuzzleHttp\Psr7\stream_for('hello!');
+$resource = StreamWrapper::getResource($stream);
+echo fread($resource, 6); // outputs hello!
+```
+
+
+# Function API
+
+There are various functions available under the `GuzzleHttp\Psr7` namespace.
+
+
+## `function str`
+
+`function str(MessageInterface $message)`
+
+Returns the string representation of an HTTP message.
+
+```php
+$request = new GuzzleHttp\Psr7\Request('GET', 'http://example.com');
+echo GuzzleHttp\Psr7\str($request);
+```
+
+
+## `function uri_for`
+
+`function uri_for($uri)`
+
+This function accepts a string or `Psr\Http\Message\UriInterface` and returns a
+UriInterface for the given value. If the value is already a `UriInterface`, it
+is returned as-is.
+
+```php
+$uri = GuzzleHttp\Psr7\uri_for('http://example.com');
+assert($uri === GuzzleHttp\Psr7\uri_for($uri));
+```
+
+
+## `function stream_for`
+
+`function stream_for($resource = '', array $options = [])`
+
+Create a new stream based on the input type.
+
+Options is an associative array that can contain the following keys:
+
+* - metadata: Array of custom metadata.
+* - size: Size of the stream.
+
+This method accepts the following `$resource` types:
+
+- `Psr\Http\Message\StreamInterface`: Returns the value as-is.
+- `string`: Creates a stream object that uses the given string as the contents.
+- `resource`: Creates a stream object that wraps the given PHP stream resource.
+- `Iterator`: If the provided value implements `Iterator`, then a read-only
+ stream object will be created that wraps the given iterable. Each time the
+ stream is read from, data from the iterator will fill a buffer and will be
+ continuously called until the buffer is equal to the requested read size.
+ Subsequent read calls will first read from the buffer and then call `next`
+ on the underlying iterator until it is exhausted.
+- `object` with `__toString()`: If the object has the `__toString()` method,
+ the object will be cast to a string and then a stream will be returned that
+ uses the string value.
+- `NULL`: When `null` is passed, an empty stream object is returned.
+- `callable` When a callable is passed, a read-only stream object will be
+ created that invokes the given callable. The callable is invoked with the
+ number of suggested bytes to read. The callable can return any number of
+ bytes, but MUST return `false` when there is no more data to return. The
+ stream object that wraps the callable will invoke the callable until the
+ number of requested bytes are available. Any additional bytes will be
+ buffered and used in subsequent reads.
+
+```php
+$stream = GuzzleHttp\Psr7\stream_for('foo');
+$stream = GuzzleHttp\Psr7\stream_for(fopen('/path/to/file', 'r'));
+
+$generator function ($bytes) {
+ for ($i = 0; $i < $bytes; $i++) {
+ yield ' ';
+ }
+}
+
+$stream = GuzzleHttp\Psr7\stream_for($generator(100));
+```
+
+
+## `function parse_header`
+
+`function parse_header($header)`
+
+Parse an array of header values containing ";" separated data into an array of
+associative arrays representing the header key value pair data of the header.
+When a parameter does not contain a value, but just contains a key, this
+function will inject a key with a '' string value.
+
+
+## `function normalize_header`
+
+`function normalize_header($header)`
+
+Converts an array of header values that may contain comma separated headers
+into an array of headers with no comma separated values.
+
+
+## `function modify_request`
+
+`function modify_request(RequestInterface $request, array $changes)`
+
+Clone and modify a request with the given changes. This method is useful for
+reducing the number of clones needed to mutate a message.
+
+The changes can be one of:
+
+- method: (string) Changes the HTTP method.
+- set_headers: (array) Sets the given headers.
+- remove_headers: (array) Remove the given headers.
+- body: (mixed) Sets the given body.
+- uri: (UriInterface) Set the URI.
+- query: (string) Set the query string value of the URI.
+- version: (string) Set the protocol version.
+
+
+## `function rewind_body`
+
+`function rewind_body(MessageInterface $message)`
+
+Attempts to rewind a message body and throws an exception on failure. The body
+of the message will only be rewound if a call to `tell()` returns a value other
+than `0`.
+
+
+## `function try_fopen`
+
+`function try_fopen($filename, $mode)`
+
+Safely opens a PHP stream resource using a filename.
+
+When fopen fails, PHP normally raises a warning. This function adds an error
+handler that checks for errors and throws an exception instead.
+
+
+## `function copy_to_string`
+
+`function copy_to_string(StreamInterface $stream, $maxLen = -1)`
+
+Copy the contents of a stream into a string until the given number of bytes
+have been read.
+
+
+## `function copy_to_stream`
+
+`function copy_to_stream(StreamInterface $source, StreamInterface $dest, $maxLen = -1)`
+
+Copy the contents of a stream into another stream until the given number of
+bytes have been read.
+
+
+## `function hash`
+
+`function hash(StreamInterface $stream, $algo, $rawOutput = false)`
+
+Calculate a hash of a Stream. This method reads the entire stream to calculate
+a rolling hash (based on PHP's hash_init functions).
+
+
+## `function readline`
+
+`function readline(StreamInterface $stream, $maxLength = null)`
+
+Read a line from the stream up to the maximum allowed buffer length.
+
+
+## `function parse_request`
+
+`function parse_request($message)`
+
+Parses a request message string into a request object.
+
+
+## `function parse_response`
+
+`function parse_response($message)`
+
+Parses a response message string into a response object.
+
+
+## `function parse_query`
+
+`function parse_query($str, $urlEncoding = true)`
+
+Parse a query string into an associative array.
+
+If multiple values are found for the same key, the value of that key value pair
+will become an array. This function does not parse nested PHP style arrays into
+an associative array (e.g., `foo[a]=1&foo[b]=2` will be parsed into
+`['foo[a]' => '1', 'foo[b]' => '2']`).
+
+
+## `function build_query`
+
+`function build_query(array $params, $encoding = PHP_QUERY_RFC3986)`
+
+Build a query string from an array of key value pairs.
+
+This function can use the return value of parse_query() to build a query string.
+This function does not modify the provided keys when an array is encountered
+(like http_build_query would).
+
+
+## `function mimetype_from_filename`
+
+`function mimetype_from_filename($filename)`
+
+Determines the mimetype of a file by looking at its extension.
+
+
+## `function mimetype_from_extension`
+
+`function mimetype_from_extension($extension)`
+
+Maps a file extensions to a mimetype.
+
+
+# Additional URI Methods
+
+Aside from the standard `Psr\Http\Message\UriInterface` implementation in form of the `GuzzleHttp\Psr7\Uri` class,
+this library also provides additional functionality when working with URIs as static methods.
+
+## URI Types
+
+An instance of `Psr\Http\Message\UriInterface` can either be an absolute URI or a relative reference.
+An absolute URI has a scheme. A relative reference is used to express a URI relative to another URI,
+the base URI. Relative references can be divided into several forms according to
+[RFC 3986 Section 4.2](https://tools.ietf.org/html/rfc3986#section-4.2):
+
+- network-path references, e.g. `//example.com/path`
+- absolute-path references, e.g. `/path`
+- relative-path references, e.g. `subpath`
+
+The following methods can be used to identify the type of the URI.
+
+### `GuzzleHttp\Psr7\Uri::isAbsolute`
+
+`public static function isAbsolute(UriInterface $uri): bool`
+
+Whether the URI is absolute, i.e. it has a scheme.
+
+### `GuzzleHttp\Psr7\Uri::isNetworkPathReference`
+
+`public static function isNetworkPathReference(UriInterface $uri): bool`
+
+Whether the URI is a network-path reference. A relative reference that begins with two slash characters is
+termed an network-path reference.
+
+### `GuzzleHttp\Psr7\Uri::isAbsolutePathReference`
+
+`public static function isAbsolutePathReference(UriInterface $uri): bool`
+
+Whether the URI is a absolute-path reference. A relative reference that begins with a single slash character is
+termed an absolute-path reference.
+
+### `GuzzleHttp\Psr7\Uri::isRelativePathReference`
+
+`public static function isRelativePathReference(UriInterface $uri): bool`
+
+Whether the URI is a relative-path reference. A relative reference that does not begin with a slash character is
+termed a relative-path reference.
+
+### `GuzzleHttp\Psr7\Uri::isSameDocumentReference`
+
+`public static function isSameDocumentReference(UriInterface $uri, UriInterface $base = null): bool`
+
+Whether the URI is a same-document reference. A same-document reference refers to a URI that is, aside from its
+fragment component, identical to the base URI. When no base URI is given, only an empty URI reference
+(apart from its fragment) is considered a same-document reference.
+
+## URI Components
+
+Additional methods to work with URI components.
+
+### `GuzzleHttp\Psr7\Uri::isDefaultPort`
+
+`public static function isDefaultPort(UriInterface $uri): bool`
+
+Whether the URI has the default port of the current scheme. `Psr\Http\Message\UriInterface::getPort` may return null
+or the standard port. This method can be used independently of the implementation.
+
+### `GuzzleHttp\Psr7\Uri::composeComponents`
+
+`public static function composeComponents($scheme, $authority, $path, $query, $fragment): string`
+
+Composes a URI reference string from its various components according to
+[RFC 3986 Section 5.3](https://tools.ietf.org/html/rfc3986#section-5.3). Usually this method does not need to be called
+manually but instead is used indirectly via `Psr\Http\Message\UriInterface::__toString`.
+
+### `GuzzleHttp\Psr7\Uri::fromParts`
+
+`public static function fromParts(array $parts): UriInterface`
+
+Creates a URI from a hash of [`parse_url`](http://php.net/manual/en/function.parse-url.php) components.
+
+
+### `GuzzleHttp\Psr7\Uri::withQueryValue`
+
+`public static function withQueryValue(UriInterface $uri, $key, $value): UriInterface`
+
+Creates a new URI with a specific query string value. Any existing query string values that exactly match the
+provided key are removed and replaced with the given key value pair. A value of null will set the query string
+key without a value, e.g. "key" instead of "key=value".
+
+
+### `GuzzleHttp\Psr7\Uri::withoutQueryValue`
+
+`public static function withoutQueryValue(UriInterface $uri, $key): UriInterface`
+
+Creates a new URI with a specific query string value removed. Any existing query string values that exactly match the
+provided key are removed.
+
+## Reference Resolution
+
+`GuzzleHttp\Psr7\UriResolver` provides methods to resolve a URI reference in the context of a base URI according
+to [RFC 3986 Section 5](https://tools.ietf.org/html/rfc3986#section-5). This is for example also what web browsers
+do when resolving a link in a website based on the current request URI.
+
+### `GuzzleHttp\Psr7\UriResolver::resolve`
+
+`public static function resolve(UriInterface $base, UriInterface $rel): UriInterface`
+
+Converts the relative URI into a new URI that is resolved against the base URI.
+
+### `GuzzleHttp\Psr7\UriResolver::removeDotSegments`
+
+`public static function removeDotSegments(string $path): string`
+
+Removes dot segments from a path and returns the new path according to
+[RFC 3986 Section 5.2.4](https://tools.ietf.org/html/rfc3986#section-5.2.4).
+
+### `GuzzleHttp\Psr7\UriResolver::relativize`
+
+`public static function relativize(UriInterface $base, UriInterface $target): UriInterface`
+
+Returns the target URI as a relative reference from the base URI. This method is the counterpart to resolve():
+
+```php
+(string) $target === (string) UriResolver::resolve($base, UriResolver::relativize($base, $target))
+```
+
+One use-case is to use the current request URI as base URI and then generate relative links in your documents
+to reduce the document size or offer self-contained downloadable document archives.
+
+```php
+$base = new Uri('http://example.com/a/b/');
+echo UriResolver::relativize($base, new Uri('http://example.com/a/b/c')); // prints 'c'.
+echo UriResolver::relativize($base, new Uri('http://example.com/a/x/y')); // prints '../x/y'.
+echo UriResolver::relativize($base, new Uri('http://example.com/a/b/?q')); // prints '?q'.
+echo UriResolver::relativize($base, new Uri('http://example.org/a/b/')); // prints '//example.org/a/b/'.
+```
+
+## Normalization and Comparison
+
+`GuzzleHttp\Psr7\UriNormalizer` provides methods to normalize and compare URIs according to
+[RFC 3986 Section 6](https://tools.ietf.org/html/rfc3986#section-6).
+
+### `GuzzleHttp\Psr7\UriNormalizer::normalize`
+
+`public static function normalize(UriInterface $uri, $flags = self::PRESERVING_NORMALIZATIONS): UriInterface`
+
+Returns a normalized URI. The scheme and host component are already normalized to lowercase per PSR-7 UriInterface.
+This methods adds additional normalizations that can be configured with the `$flags` parameter which is a bitmask
+of normalizations to apply. The following normalizations are available:
+
+- `UriNormalizer::PRESERVING_NORMALIZATIONS`
+
+ Default normalizations which only include the ones that preserve semantics.
+
+- `UriNormalizer::CAPITALIZE_PERCENT_ENCODING`
+
+ All letters within a percent-encoding triplet (e.g., "%3A") are case-insensitive, and should be capitalized.
+
+ Example: `http://example.org/a%c2%b1b` → `http://example.org/a%C2%B1b`
+
+- `UriNormalizer::DECODE_UNRESERVED_CHARACTERS`
+
+ Decodes percent-encoded octets of unreserved characters. For consistency, percent-encoded octets in the ranges of
+ ALPHA (%41–%5A and %61–%7A), DIGIT (%30–%39), hyphen (%2D), period (%2E), underscore (%5F), or tilde (%7E) should
+ not be created by URI producers and, when found in a URI, should be decoded to their corresponding unreserved
+ characters by URI normalizers.
+
+ Example: `http://example.org/%7Eusern%61me/` → `http://example.org/~username/`
+
+- `UriNormalizer::CONVERT_EMPTY_PATH`
+
+ Converts the empty path to "/" for http and https URIs.
+
+ Example: `http://example.org` → `http://example.org/`
+
+- `UriNormalizer::REMOVE_DEFAULT_HOST`
+
+ Removes the default host of the given URI scheme from the URI. Only the "file" scheme defines the default host
+ "localhost". All of `file:/myfile`, `file:///myfile`, and `file://localhost/myfile` are equivalent according to
+ RFC 3986.
+
+ Example: `file://localhost/myfile` → `file:///myfile`
+
+- `UriNormalizer::REMOVE_DEFAULT_PORT`
+
+ Removes the default port of the given URI scheme from the URI.
+
+ Example: `http://example.org:80/` → `http://example.org/`
+
+- `UriNormalizer::REMOVE_DOT_SEGMENTS`
+
+ Removes unnecessary dot-segments. Dot-segments in relative-path references are not removed as it would
+ change the semantics of the URI reference.
+
+ Example: `http://example.org/../a/b/../c/./d.html` → `http://example.org/a/c/d.html`
+
+- `UriNormalizer::REMOVE_DUPLICATE_SLASHES`
+
+ Paths which include two or more adjacent slashes are converted to one. Webservers usually ignore duplicate slashes
+ and treat those URIs equivalent. But in theory those URIs do not need to be equivalent. So this normalization
+ may change the semantics. Encoded slashes (%2F) are not removed.
+
+ Example: `http://example.org//foo///bar.html` → `http://example.org/foo/bar.html`
+
+- `UriNormalizer::SORT_QUERY_PARAMETERS`
+
+ Sort query parameters with their values in alphabetical order. However, the order of parameters in a URI may be
+ significant (this is not defined by the standard). So this normalization is not safe and may change the semantics
+ of the URI.
+
+ Example: `?lang=en&article=fred` → `?article=fred&lang=en`
+
+### `GuzzleHttp\Psr7\UriNormalizer::isEquivalent`
+
+`public static function isEquivalent(UriInterface $uri1, UriInterface $uri2, $normalizations = self::PRESERVING_NORMALIZATIONS): bool`
+
+Whether two URIs can be considered equivalent. Both URIs are normalized automatically before comparison with the given
+`$normalizations` bitmask. The method also accepts relative URI references and returns true when they are equivalent.
+This of course assumes they will be resolved against the same base URI. If this is not the case, determination of
+equivalence or difference of relative references does not mean anything.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/composer.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/composer.json
new file mode 100644
index 0000000..b1c5a90
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/composer.json
@@ -0,0 +1,39 @@
+{
+ "name": "guzzlehttp/psr7",
+ "type": "library",
+ "description": "PSR-7 message implementation that also provides common utility methods",
+ "keywords": ["request", "response", "message", "stream", "http", "uri", "url"],
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "Tobias Schultze",
+ "homepage": "https://github.com/Tobion"
+ }
+ ],
+ "require": {
+ "php": ">=5.4.0",
+ "psr/http-message": "~1.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.0"
+ },
+ "provide": {
+ "psr/http-message-implementation": "1.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "GuzzleHttp\\Psr7\\": "src/"
+ },
+ "files": ["src/functions_include.php"]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/AppendStream.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/AppendStream.php
new file mode 100644
index 0000000..23039fd
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/AppendStream.php
@@ -0,0 +1,233 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Reads from multiple streams, one after the other.
+ *
+ * This is a read-only stream decorator.
+ */
+class AppendStream implements StreamInterface
+{
+ /** @var StreamInterface[] Streams being decorated */
+ private $streams = [];
+
+ private $seekable = true;
+ private $current = 0;
+ private $pos = 0;
+ private $detached = false;
+
+ /**
+ * @param StreamInterface[] $streams Streams to decorate. Each stream must
+ * be readable.
+ */
+ public function __construct(array $streams = [])
+ {
+ foreach ($streams as $stream) {
+ $this->addStream($stream);
+ }
+ }
+
+ public function __toString()
+ {
+ try {
+ $this->rewind();
+ return $this->getContents();
+ } catch (\Exception $e) {
+ return '';
+ }
+ }
+
+ /**
+ * Add a stream to the AppendStream
+ *
+ * @param StreamInterface $stream Stream to append. Must be readable.
+ *
+ * @throws \InvalidArgumentException if the stream is not readable
+ */
+ public function addStream(StreamInterface $stream)
+ {
+ if (!$stream->isReadable()) {
+ throw new \InvalidArgumentException('Each stream must be readable');
+ }
+
+ // The stream is only seekable if all streams are seekable
+ if (!$stream->isSeekable()) {
+ $this->seekable = false;
+ }
+
+ $this->streams[] = $stream;
+ }
+
+ public function getContents()
+ {
+ return copy_to_string($this);
+ }
+
+ /**
+ * Closes each attached stream.
+ *
+ * {@inheritdoc}
+ */
+ public function close()
+ {
+ $this->pos = $this->current = 0;
+
+ foreach ($this->streams as $stream) {
+ $stream->close();
+ }
+
+ $this->streams = [];
+ }
+
+ /**
+ * Detaches each attached stream
+ *
+ * {@inheritdoc}
+ */
+ public function detach()
+ {
+ $this->close();
+ $this->detached = true;
+ }
+
+ public function tell()
+ {
+ return $this->pos;
+ }
+
+ /**
+ * Tries to calculate the size by adding the size of each stream.
+ *
+ * If any of the streams do not return a valid number, then the size of the
+ * append stream cannot be determined and null is returned.
+ *
+ * {@inheritdoc}
+ */
+ public function getSize()
+ {
+ $size = 0;
+
+ foreach ($this->streams as $stream) {
+ $s = $stream->getSize();
+ if ($s === null) {
+ return null;
+ }
+ $size += $s;
+ }
+
+ return $size;
+ }
+
+ public function eof()
+ {
+ return !$this->streams ||
+ ($this->current >= count($this->streams) - 1 &&
+ $this->streams[$this->current]->eof());
+ }
+
+ public function rewind()
+ {
+ $this->seek(0);
+ }
+
+ /**
+ * Attempts to seek to the given position. Only supports SEEK_SET.
+ *
+ * {@inheritdoc}
+ */
+ public function seek($offset, $whence = SEEK_SET)
+ {
+ if (!$this->seekable) {
+ throw new \RuntimeException('This AppendStream is not seekable');
+ } elseif ($whence !== SEEK_SET) {
+ throw new \RuntimeException('The AppendStream can only seek with SEEK_SET');
+ }
+
+ $this->pos = $this->current = 0;
+
+ // Rewind each stream
+ foreach ($this->streams as $i => $stream) {
+ try {
+ $stream->rewind();
+ } catch (\Exception $e) {
+ throw new \RuntimeException('Unable to seek stream '
+ . $i . ' of the AppendStream', 0, $e);
+ }
+ }
+
+ // Seek to the actual position by reading from each stream
+ while ($this->pos < $offset && !$this->eof()) {
+ $result = $this->read(min(8096, $offset - $this->pos));
+ if ($result === '') {
+ break;
+ }
+ }
+ }
+
+ /**
+ * Reads from all of the appended streams until the length is met or EOF.
+ *
+ * {@inheritdoc}
+ */
+ public function read($length)
+ {
+ $buffer = '';
+ $total = count($this->streams) - 1;
+ $remaining = $length;
+ $progressToNext = false;
+
+ while ($remaining > 0) {
+
+ // Progress to the next stream if needed.
+ if ($progressToNext || $this->streams[$this->current]->eof()) {
+ $progressToNext = false;
+ if ($this->current === $total) {
+ break;
+ }
+ $this->current++;
+ }
+
+ $result = $this->streams[$this->current]->read($remaining);
+
+ // Using a loose comparison here to match on '', false, and null
+ if ($result == null) {
+ $progressToNext = true;
+ continue;
+ }
+
+ $buffer .= $result;
+ $remaining = $length - strlen($buffer);
+ }
+
+ $this->pos += strlen($buffer);
+
+ return $buffer;
+ }
+
+ public function isReadable()
+ {
+ return true;
+ }
+
+ public function isWritable()
+ {
+ return false;
+ }
+
+ public function isSeekable()
+ {
+ return $this->seekable;
+ }
+
+ public function write($string)
+ {
+ throw new \RuntimeException('Cannot write to an AppendStream');
+ }
+
+ public function getMetadata($key = null)
+ {
+ return $key ? null : [];
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/BufferStream.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/BufferStream.php
new file mode 100644
index 0000000..af4d4c2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/BufferStream.php
@@ -0,0 +1,137 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Provides a buffer stream that can be written to to fill a buffer, and read
+ * from to remove bytes from the buffer.
+ *
+ * This stream returns a "hwm" metadata value that tells upstream consumers
+ * what the configured high water mark of the stream is, or the maximum
+ * preferred size of the buffer.
+ */
+class BufferStream implements StreamInterface
+{
+ private $hwm;
+ private $buffer = '';
+
+ /**
+ * @param int $hwm High water mark, representing the preferred maximum
+ * buffer size. If the size of the buffer exceeds the high
+ * water mark, then calls to write will continue to succeed
+ * but will return false to inform writers to slow down
+ * until the buffer has been drained by reading from it.
+ */
+ public function __construct($hwm = 16384)
+ {
+ $this->hwm = $hwm;
+ }
+
+ public function __toString()
+ {
+ return $this->getContents();
+ }
+
+ public function getContents()
+ {
+ $buffer = $this->buffer;
+ $this->buffer = '';
+
+ return $buffer;
+ }
+
+ public function close()
+ {
+ $this->buffer = '';
+ }
+
+ public function detach()
+ {
+ $this->close();
+ }
+
+ public function getSize()
+ {
+ return strlen($this->buffer);
+ }
+
+ public function isReadable()
+ {
+ return true;
+ }
+
+ public function isWritable()
+ {
+ return true;
+ }
+
+ public function isSeekable()
+ {
+ return false;
+ }
+
+ public function rewind()
+ {
+ $this->seek(0);
+ }
+
+ public function seek($offset, $whence = SEEK_SET)
+ {
+ throw new \RuntimeException('Cannot seek a BufferStream');
+ }
+
+ public function eof()
+ {
+ return strlen($this->buffer) === 0;
+ }
+
+ public function tell()
+ {
+ throw new \RuntimeException('Cannot determine the position of a BufferStream');
+ }
+
+ /**
+ * Reads data from the buffer.
+ */
+ public function read($length)
+ {
+ $currentLength = strlen($this->buffer);
+
+ if ($length >= $currentLength) {
+ // No need to slice the buffer because we don't have enough data.
+ $result = $this->buffer;
+ $this->buffer = '';
+ } else {
+ // Slice up the result to provide a subset of the buffer.
+ $result = substr($this->buffer, 0, $length);
+ $this->buffer = substr($this->buffer, $length);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Writes data to the buffer.
+ */
+ public function write($string)
+ {
+ $this->buffer .= $string;
+
+ // TODO: What should happen here?
+ if (strlen($this->buffer) >= $this->hwm) {
+ return false;
+ }
+
+ return strlen($string);
+ }
+
+ public function getMetadata($key = null)
+ {
+ if ($key == 'hwm') {
+ return $this->hwm;
+ }
+
+ return $key ? null : [];
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/CachingStream.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/CachingStream.php
new file mode 100644
index 0000000..ed68f08
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/CachingStream.php
@@ -0,0 +1,138 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Stream decorator that can cache previously read bytes from a sequentially
+ * read stream.
+ */
+class CachingStream implements StreamInterface
+{
+ use StreamDecoratorTrait;
+
+ /** @var StreamInterface Stream being wrapped */
+ private $remoteStream;
+
+ /** @var int Number of bytes to skip reading due to a write on the buffer */
+ private $skipReadBytes = 0;
+
+ /**
+ * We will treat the buffer object as the body of the stream
+ *
+ * @param StreamInterface $stream Stream to cache
+ * @param StreamInterface $target Optionally specify where data is cached
+ */
+ public function __construct(
+ StreamInterface $stream,
+ StreamInterface $target = null
+ ) {
+ $this->remoteStream = $stream;
+ $this->stream = $target ?: new Stream(fopen('php://temp', 'r+'));
+ }
+
+ public function getSize()
+ {
+ return max($this->stream->getSize(), $this->remoteStream->getSize());
+ }
+
+ public function rewind()
+ {
+ $this->seek(0);
+ }
+
+ public function seek($offset, $whence = SEEK_SET)
+ {
+ if ($whence == SEEK_SET) {
+ $byte = $offset;
+ } elseif ($whence == SEEK_CUR) {
+ $byte = $offset + $this->tell();
+ } elseif ($whence == SEEK_END) {
+ $size = $this->remoteStream->getSize();
+ if ($size === null) {
+ $size = $this->cacheEntireStream();
+ }
+ $byte = $size + $offset;
+ } else {
+ throw new \InvalidArgumentException('Invalid whence');
+ }
+
+ $diff = $byte - $this->stream->getSize();
+
+ if ($diff > 0) {
+ // Read the remoteStream until we have read in at least the amount
+ // of bytes requested, or we reach the end of the file.
+ while ($diff > 0 && !$this->remoteStream->eof()) {
+ $this->read($diff);
+ $diff = $byte - $this->stream->getSize();
+ }
+ } else {
+ // We can just do a normal seek since we've already seen this byte.
+ $this->stream->seek($byte);
+ }
+ }
+
+ public function read($length)
+ {
+ // Perform a regular read on any previously read data from the buffer
+ $data = $this->stream->read($length);
+ $remaining = $length - strlen($data);
+
+ // More data was requested so read from the remote stream
+ if ($remaining) {
+ // If data was written to the buffer in a position that would have
+ // been filled from the remote stream, then we must skip bytes on
+ // the remote stream to emulate overwriting bytes from that
+ // position. This mimics the behavior of other PHP stream wrappers.
+ $remoteData = $this->remoteStream->read(
+ $remaining + $this->skipReadBytes
+ );
+
+ if ($this->skipReadBytes) {
+ $len = strlen($remoteData);
+ $remoteData = substr($remoteData, $this->skipReadBytes);
+ $this->skipReadBytes = max(0, $this->skipReadBytes - $len);
+ }
+
+ $data .= $remoteData;
+ $this->stream->write($remoteData);
+ }
+
+ return $data;
+ }
+
+ public function write($string)
+ {
+ // When appending to the end of the currently read stream, you'll want
+ // to skip bytes from being read from the remote stream to emulate
+ // other stream wrappers. Basically replacing bytes of data of a fixed
+ // length.
+ $overflow = (strlen($string) + $this->tell()) - $this->remoteStream->tell();
+ if ($overflow > 0) {
+ $this->skipReadBytes += $overflow;
+ }
+
+ return $this->stream->write($string);
+ }
+
+ public function eof()
+ {
+ return $this->stream->eof() && $this->remoteStream->eof();
+ }
+
+ /**
+ * Close both the remote stream and buffer stream
+ */
+ public function close()
+ {
+ $this->remoteStream->close() && $this->stream->close();
+ }
+
+ private function cacheEntireStream()
+ {
+ $target = new FnStream(['write' => 'strlen']);
+ copy_to_stream($this, $target);
+
+ return $this->tell();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/DroppingStream.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/DroppingStream.php
new file mode 100644
index 0000000..8935c80
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/DroppingStream.php
@@ -0,0 +1,42 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Stream decorator that begins dropping data once the size of the underlying
+ * stream becomes too full.
+ */
+class DroppingStream implements StreamInterface
+{
+ use StreamDecoratorTrait;
+
+ private $maxLength;
+
+ /**
+ * @param StreamInterface $stream Underlying stream to decorate.
+ * @param int $maxLength Maximum size before dropping data.
+ */
+ public function __construct(StreamInterface $stream, $maxLength)
+ {
+ $this->stream = $stream;
+ $this->maxLength = $maxLength;
+ }
+
+ public function write($string)
+ {
+ $diff = $this->maxLength - $this->stream->getSize();
+
+ // Begin returning 0 when the underlying stream is too large.
+ if ($diff <= 0) {
+ return 0;
+ }
+
+ // Write the stream or a subset of the stream if needed.
+ if (strlen($string) < $diff) {
+ return $this->stream->write($string);
+ }
+
+ return $this->stream->write(substr($string, 0, $diff));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/FnStream.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/FnStream.php
new file mode 100644
index 0000000..cc9b445
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/FnStream.php
@@ -0,0 +1,149 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Compose stream implementations based on a hash of functions.
+ *
+ * Allows for easy testing and extension of a provided stream without needing
+ * to create a concrete class for a simple extension point.
+ */
+class FnStream implements StreamInterface
+{
+ /** @var array */
+ private $methods;
+
+ /** @var array Methods that must be implemented in the given array */
+ private static $slots = ['__toString', 'close', 'detach', 'rewind',
+ 'getSize', 'tell', 'eof', 'isSeekable', 'seek', 'isWritable', 'write',
+ 'isReadable', 'read', 'getContents', 'getMetadata'];
+
+ /**
+ * @param array $methods Hash of method name to a callable.
+ */
+ public function __construct(array $methods)
+ {
+ $this->methods = $methods;
+
+ // Create the functions on the class
+ foreach ($methods as $name => $fn) {
+ $this->{'_fn_' . $name} = $fn;
+ }
+ }
+
+ /**
+ * Lazily determine which methods are not implemented.
+ * @throws \BadMethodCallException
+ */
+ public function __get($name)
+ {
+ throw new \BadMethodCallException(str_replace('_fn_', '', $name)
+ . '() is not implemented in the FnStream');
+ }
+
+ /**
+ * The close method is called on the underlying stream only if possible.
+ */
+ public function __destruct()
+ {
+ if (isset($this->_fn_close)) {
+ call_user_func($this->_fn_close);
+ }
+ }
+
+ /**
+ * Adds custom functionality to an underlying stream by intercepting
+ * specific method calls.
+ *
+ * @param StreamInterface $stream Stream to decorate
+ * @param array $methods Hash of method name to a closure
+ *
+ * @return FnStream
+ */
+ public static function decorate(StreamInterface $stream, array $methods)
+ {
+ // If any of the required methods were not provided, then simply
+ // proxy to the decorated stream.
+ foreach (array_diff(self::$slots, array_keys($methods)) as $diff) {
+ $methods[$diff] = [$stream, $diff];
+ }
+
+ return new self($methods);
+ }
+
+ public function __toString()
+ {
+ return call_user_func($this->_fn___toString);
+ }
+
+ public function close()
+ {
+ return call_user_func($this->_fn_close);
+ }
+
+ public function detach()
+ {
+ return call_user_func($this->_fn_detach);
+ }
+
+ public function getSize()
+ {
+ return call_user_func($this->_fn_getSize);
+ }
+
+ public function tell()
+ {
+ return call_user_func($this->_fn_tell);
+ }
+
+ public function eof()
+ {
+ return call_user_func($this->_fn_eof);
+ }
+
+ public function isSeekable()
+ {
+ return call_user_func($this->_fn_isSeekable);
+ }
+
+ public function rewind()
+ {
+ call_user_func($this->_fn_rewind);
+ }
+
+ public function seek($offset, $whence = SEEK_SET)
+ {
+ call_user_func($this->_fn_seek, $offset, $whence);
+ }
+
+ public function isWritable()
+ {
+ return call_user_func($this->_fn_isWritable);
+ }
+
+ public function write($string)
+ {
+ return call_user_func($this->_fn_write, $string);
+ }
+
+ public function isReadable()
+ {
+ return call_user_func($this->_fn_isReadable);
+ }
+
+ public function read($length)
+ {
+ return call_user_func($this->_fn_read, $length);
+ }
+
+ public function getContents()
+ {
+ return call_user_func($this->_fn_getContents);
+ }
+
+ public function getMetadata($key = null)
+ {
+ return call_user_func($this->_fn_getMetadata, $key);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/InflateStream.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/InflateStream.php
new file mode 100644
index 0000000..0051d3f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/InflateStream.php
@@ -0,0 +1,52 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Uses PHP's zlib.inflate filter to inflate deflate or gzipped content.
+ *
+ * This stream decorator skips the first 10 bytes of the given stream to remove
+ * the gzip header, converts the provided stream to a PHP stream resource,
+ * then appends the zlib.inflate filter. The stream is then converted back
+ * to a Guzzle stream resource to be used as a Guzzle stream.
+ *
+ * @link http://tools.ietf.org/html/rfc1952
+ * @link http://php.net/manual/en/filters.compression.php
+ */
+class InflateStream implements StreamInterface
+{
+ use StreamDecoratorTrait;
+
+ public function __construct(StreamInterface $stream)
+ {
+ // read the first 10 bytes, ie. gzip header
+ $header = $stream->read(10);
+ $filenameHeaderLength = $this->getLengthOfPossibleFilenameHeader($stream, $header);
+ // Skip the header, that is 10 + length of filename + 1 (nil) bytes
+ $stream = new LimitStream($stream, -1, 10 + $filenameHeaderLength);
+ $resource = StreamWrapper::getResource($stream);
+ stream_filter_append($resource, 'zlib.inflate', STREAM_FILTER_READ);
+ $this->stream = new Stream($resource);
+ }
+
+ /**
+ * @param StreamInterface $stream
+ * @param $header
+ * @return int
+ */
+ private function getLengthOfPossibleFilenameHeader(StreamInterface $stream, $header)
+ {
+ $filename_header_length = 0;
+
+ if (substr(bin2hex($header), 6, 2) === '08') {
+ // we have a filename, read until nil
+ $filename_header_length = 1;
+ while ($stream->read(1) !== chr(0)) {
+ $filename_header_length++;
+ }
+ }
+
+ return $filename_header_length;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/LazyOpenStream.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/LazyOpenStream.php
new file mode 100644
index 0000000..02cec3a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/LazyOpenStream.php
@@ -0,0 +1,39 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Lazily reads or writes to a file that is opened only after an IO operation
+ * take place on the stream.
+ */
+class LazyOpenStream implements StreamInterface
+{
+ use StreamDecoratorTrait;
+
+ /** @var string File to open */
+ private $filename;
+
+ /** @var string $mode */
+ private $mode;
+
+ /**
+ * @param string $filename File to lazily open
+ * @param string $mode fopen mode to use when opening the stream
+ */
+ public function __construct($filename, $mode)
+ {
+ $this->filename = $filename;
+ $this->mode = $mode;
+ }
+
+ /**
+ * Creates the underlying stream lazily when required.
+ *
+ * @return StreamInterface
+ */
+ protected function createStream()
+ {
+ return stream_for(try_fopen($this->filename, $this->mode));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/LimitStream.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/LimitStream.php
new file mode 100644
index 0000000..3c13d4f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/LimitStream.php
@@ -0,0 +1,155 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+
+/**
+ * Decorator used to return only a subset of a stream
+ */
+class LimitStream implements StreamInterface
+{
+ use StreamDecoratorTrait;
+
+ /** @var int Offset to start reading from */
+ private $offset;
+
+ /** @var int Limit the number of bytes that can be read */
+ private $limit;
+
+ /**
+ * @param StreamInterface $stream Stream to wrap
+ * @param int $limit Total number of bytes to allow to be read
+ * from the stream. Pass -1 for no limit.
+ * @param int $offset Position to seek to before reading (only
+ * works on seekable streams).
+ */
+ public function __construct(
+ StreamInterface $stream,
+ $limit = -1,
+ $offset = 0
+ ) {
+ $this->stream = $stream;
+ $this->setLimit($limit);
+ $this->setOffset($offset);
+ }
+
+ public function eof()
+ {
+ // Always return true if the underlying stream is EOF
+ if ($this->stream->eof()) {
+ return true;
+ }
+
+ // No limit and the underlying stream is not at EOF
+ if ($this->limit == -1) {
+ return false;
+ }
+
+ return $this->stream->tell() >= $this->offset + $this->limit;
+ }
+
+ /**
+ * Returns the size of the limited subset of data
+ * {@inheritdoc}
+ */
+ public function getSize()
+ {
+ if (null === ($length = $this->stream->getSize())) {
+ return null;
+ } elseif ($this->limit == -1) {
+ return $length - $this->offset;
+ } else {
+ return min($this->limit, $length - $this->offset);
+ }
+ }
+
+ /**
+ * Allow for a bounded seek on the read limited stream
+ * {@inheritdoc}
+ */
+ public function seek($offset, $whence = SEEK_SET)
+ {
+ if ($whence !== SEEK_SET || $offset < 0) {
+ throw new \RuntimeException(sprintf(
+ 'Cannot seek to offset % with whence %s',
+ $offset,
+ $whence
+ ));
+ }
+
+ $offset += $this->offset;
+
+ if ($this->limit !== -1) {
+ if ($offset > $this->offset + $this->limit) {
+ $offset = $this->offset + $this->limit;
+ }
+ }
+
+ $this->stream->seek($offset);
+ }
+
+ /**
+ * Give a relative tell()
+ * {@inheritdoc}
+ */
+ public function tell()
+ {
+ return $this->stream->tell() - $this->offset;
+ }
+
+ /**
+ * Set the offset to start limiting from
+ *
+ * @param int $offset Offset to seek to and begin byte limiting from
+ *
+ * @throws \RuntimeException if the stream cannot be seeked.
+ */
+ public function setOffset($offset)
+ {
+ $current = $this->stream->tell();
+
+ if ($current !== $offset) {
+ // If the stream cannot seek to the offset position, then read to it
+ if ($this->stream->isSeekable()) {
+ $this->stream->seek($offset);
+ } elseif ($current > $offset) {
+ throw new \RuntimeException("Could not seek to stream offset $offset");
+ } else {
+ $this->stream->read($offset - $current);
+ }
+ }
+
+ $this->offset = $offset;
+ }
+
+ /**
+ * Set the limit of bytes that the decorator allows to be read from the
+ * stream.
+ *
+ * @param int $limit Number of bytes to allow to be read from the stream.
+ * Use -1 for no limit.
+ */
+ public function setLimit($limit)
+ {
+ $this->limit = $limit;
+ }
+
+ public function read($length)
+ {
+ if ($this->limit == -1) {
+ return $this->stream->read($length);
+ }
+
+ // Check if the current position is less than the total allowed
+ // bytes + original offset
+ $remaining = ($this->offset + $this->limit) - $this->stream->tell();
+ if ($remaining > 0) {
+ // Only return the amount of requested data, ensuring that the byte
+ // limit is not exceeded
+ return $this->stream->read(min($remaining, $length));
+ }
+
+ return '';
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/MessageTrait.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/MessageTrait.php
new file mode 100644
index 0000000..1e4da64
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/MessageTrait.php
@@ -0,0 +1,183 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Trait implementing functionality common to requests and responses.
+ */
+trait MessageTrait
+{
+ /** @var array Map of all registered headers, as original name => array of values */
+ private $headers = [];
+
+ /** @var array Map of lowercase header name => original name at registration */
+ private $headerNames = [];
+
+ /** @var string */
+ private $protocol = '1.1';
+
+ /** @var StreamInterface */
+ private $stream;
+
+ public function getProtocolVersion()
+ {
+ return $this->protocol;
+ }
+
+ public function withProtocolVersion($version)
+ {
+ if ($this->protocol === $version) {
+ return $this;
+ }
+
+ $new = clone $this;
+ $new->protocol = $version;
+ return $new;
+ }
+
+ public function getHeaders()
+ {
+ return $this->headers;
+ }
+
+ public function hasHeader($header)
+ {
+ return isset($this->headerNames[strtolower($header)]);
+ }
+
+ public function getHeader($header)
+ {
+ $header = strtolower($header);
+
+ if (!isset($this->headerNames[$header])) {
+ return [];
+ }
+
+ $header = $this->headerNames[$header];
+
+ return $this->headers[$header];
+ }
+
+ public function getHeaderLine($header)
+ {
+ return implode(', ', $this->getHeader($header));
+ }
+
+ public function withHeader($header, $value)
+ {
+ if (!is_array($value)) {
+ $value = [$value];
+ }
+
+ $value = $this->trimHeaderValues($value);
+ $normalized = strtolower($header);
+
+ $new = clone $this;
+ if (isset($new->headerNames[$normalized])) {
+ unset($new->headers[$new->headerNames[$normalized]]);
+ }
+ $new->headerNames[$normalized] = $header;
+ $new->headers[$header] = $value;
+
+ return $new;
+ }
+
+ public function withAddedHeader($header, $value)
+ {
+ if (!is_array($value)) {
+ $value = [$value];
+ }
+
+ $value = $this->trimHeaderValues($value);
+ $normalized = strtolower($header);
+
+ $new = clone $this;
+ if (isset($new->headerNames[$normalized])) {
+ $header = $this->headerNames[$normalized];
+ $new->headers[$header] = array_merge($this->headers[$header], $value);
+ } else {
+ $new->headerNames[$normalized] = $header;
+ $new->headers[$header] = $value;
+ }
+
+ return $new;
+ }
+
+ public function withoutHeader($header)
+ {
+ $normalized = strtolower($header);
+
+ if (!isset($this->headerNames[$normalized])) {
+ return $this;
+ }
+
+ $header = $this->headerNames[$normalized];
+
+ $new = clone $this;
+ unset($new->headers[$header], $new->headerNames[$normalized]);
+
+ return $new;
+ }
+
+ public function getBody()
+ {
+ if (!$this->stream) {
+ $this->stream = stream_for('');
+ }
+
+ return $this->stream;
+ }
+
+ public function withBody(StreamInterface $body)
+ {
+ if ($body === $this->stream) {
+ return $this;
+ }
+
+ $new = clone $this;
+ $new->stream = $body;
+ return $new;
+ }
+
+ private function setHeaders(array $headers)
+ {
+ $this->headerNames = $this->headers = [];
+ foreach ($headers as $header => $value) {
+ if (!is_array($value)) {
+ $value = [$value];
+ }
+
+ $value = $this->trimHeaderValues($value);
+ $normalized = strtolower($header);
+ if (isset($this->headerNames[$normalized])) {
+ $header = $this->headerNames[$normalized];
+ $this->headers[$header] = array_merge($this->headers[$header], $value);
+ } else {
+ $this->headerNames[$normalized] = $header;
+ $this->headers[$header] = $value;
+ }
+ }
+ }
+
+ /**
+ * Trims whitespace from the header values.
+ *
+ * Spaces and tabs ought to be excluded by parsers when extracting the field value from a header field.
+ *
+ * header-field = field-name ":" OWS field-value OWS
+ * OWS = *( SP / HTAB )
+ *
+ * @param string[] $values Header values
+ *
+ * @return string[] Trimmed header values
+ *
+ * @see https://tools.ietf.org/html/rfc7230#section-3.2.4
+ */
+ private function trimHeaderValues(array $values)
+ {
+ return array_map(function ($value) {
+ return trim($value, " \t");
+ }, $values);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/MultipartStream.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/MultipartStream.php
new file mode 100644
index 0000000..c0fd584
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/MultipartStream.php
@@ -0,0 +1,153 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Stream that when read returns bytes for a streaming multipart or
+ * multipart/form-data stream.
+ */
+class MultipartStream implements StreamInterface
+{
+ use StreamDecoratorTrait;
+
+ private $boundary;
+
+ /**
+ * @param array $elements Array of associative arrays, each containing a
+ * required "name" key mapping to the form field,
+ * name, a required "contents" key mapping to a
+ * StreamInterface/resource/string, an optional
+ * "headers" associative array of custom headers,
+ * and an optional "filename" key mapping to a
+ * string to send as the filename in the part.
+ * @param string $boundary You can optionally provide a specific boundary
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function __construct(array $elements = [], $boundary = null)
+ {
+ $this->boundary = $boundary ?: sha1(uniqid('', true));
+ $this->stream = $this->createStream($elements);
+ }
+
+ /**
+ * Get the boundary
+ *
+ * @return string
+ */
+ public function getBoundary()
+ {
+ return $this->boundary;
+ }
+
+ public function isWritable()
+ {
+ return false;
+ }
+
+ /**
+ * Get the headers needed before transferring the content of a POST file
+ */
+ private function getHeaders(array $headers)
+ {
+ $str = '';
+ foreach ($headers as $key => $value) {
+ $str .= "{$key}: {$value}\r\n";
+ }
+
+ return "--{$this->boundary}\r\n" . trim($str) . "\r\n\r\n";
+ }
+
+ /**
+ * Create the aggregate stream that will be used to upload the POST data
+ */
+ protected function createStream(array $elements)
+ {
+ $stream = new AppendStream();
+
+ foreach ($elements as $element) {
+ $this->addElement($stream, $element);
+ }
+
+ // Add the trailing boundary with CRLF
+ $stream->addStream(stream_for("--{$this->boundary}--\r\n"));
+
+ return $stream;
+ }
+
+ private function addElement(AppendStream $stream, array $element)
+ {
+ foreach (['contents', 'name'] as $key) {
+ if (!array_key_exists($key, $element)) {
+ throw new \InvalidArgumentException("A '{$key}' key is required");
+ }
+ }
+
+ $element['contents'] = stream_for($element['contents']);
+
+ if (empty($element['filename'])) {
+ $uri = $element['contents']->getMetadata('uri');
+ if (substr($uri, 0, 6) !== 'php://') {
+ $element['filename'] = $uri;
+ }
+ }
+
+ list($body, $headers) = $this->createElement(
+ $element['name'],
+ $element['contents'],
+ isset($element['filename']) ? $element['filename'] : null,
+ isset($element['headers']) ? $element['headers'] : []
+ );
+
+ $stream->addStream(stream_for($this->getHeaders($headers)));
+ $stream->addStream($body);
+ $stream->addStream(stream_for("\r\n"));
+ }
+
+ /**
+ * @return array
+ */
+ private function createElement($name, StreamInterface $stream, $filename, array $headers)
+ {
+ // Set a default content-disposition header if one was no provided
+ $disposition = $this->getHeader($headers, 'content-disposition');
+ if (!$disposition) {
+ $headers['Content-Disposition'] = ($filename === '0' || $filename)
+ ? sprintf('form-data; name="%s"; filename="%s"',
+ $name,
+ basename($filename))
+ : "form-data; name=\"{$name}\"";
+ }
+
+ // Set a default content-length header if one was no provided
+ $length = $this->getHeader($headers, 'content-length');
+ if (!$length) {
+ if ($length = $stream->getSize()) {
+ $headers['Content-Length'] = (string) $length;
+ }
+ }
+
+ // Set a default Content-Type if one was not supplied
+ $type = $this->getHeader($headers, 'content-type');
+ if (!$type && ($filename === '0' || $filename)) {
+ if ($type = mimetype_from_filename($filename)) {
+ $headers['Content-Type'] = $type;
+ }
+ }
+
+ return [$stream, $headers];
+ }
+
+ private function getHeader(array $headers, $key)
+ {
+ $lowercaseHeader = strtolower($key);
+ foreach ($headers as $k => $v) {
+ if (strtolower($k) === $lowercaseHeader) {
+ return $v;
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/NoSeekStream.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/NoSeekStream.php
new file mode 100644
index 0000000..2332218
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/NoSeekStream.php
@@ -0,0 +1,22 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Stream decorator that prevents a stream from being seeked
+ */
+class NoSeekStream implements StreamInterface
+{
+ use StreamDecoratorTrait;
+
+ public function seek($offset, $whence = SEEK_SET)
+ {
+ throw new \RuntimeException('Cannot seek a NoSeekStream');
+ }
+
+ public function isSeekable()
+ {
+ return false;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/PumpStream.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/PumpStream.php
new file mode 100644
index 0000000..ffb5440
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/PumpStream.php
@@ -0,0 +1,165 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Provides a read only stream that pumps data from a PHP callable.
+ *
+ * When invoking the provided callable, the PumpStream will pass the amount of
+ * data requested to read to the callable. The callable can choose to ignore
+ * this value and return fewer or more bytes than requested. Any extra data
+ * returned by the provided callable is buffered internally until drained using
+ * the read() function of the PumpStream. The provided callable MUST return
+ * false when there is no more data to read.
+ */
+class PumpStream implements StreamInterface
+{
+ /** @var callable */
+ private $source;
+
+ /** @var int */
+ private $size;
+
+ /** @var int */
+ private $tellPos = 0;
+
+ /** @var array */
+ private $metadata;
+
+ /** @var BufferStream */
+ private $buffer;
+
+ /**
+ * @param callable $source Source of the stream data. The callable MAY
+ * accept an integer argument used to control the
+ * amount of data to return. The callable MUST
+ * return a string when called, or false on error
+ * or EOF.
+ * @param array $options Stream options:
+ * - metadata: Hash of metadata to use with stream.
+ * - size: Size of the stream, if known.
+ */
+ public function __construct(callable $source, array $options = [])
+ {
+ $this->source = $source;
+ $this->size = isset($options['size']) ? $options['size'] : null;
+ $this->metadata = isset($options['metadata']) ? $options['metadata'] : [];
+ $this->buffer = new BufferStream();
+ }
+
+ public function __toString()
+ {
+ try {
+ return copy_to_string($this);
+ } catch (\Exception $e) {
+ return '';
+ }
+ }
+
+ public function close()
+ {
+ $this->detach();
+ }
+
+ public function detach()
+ {
+ $this->tellPos = false;
+ $this->source = null;
+ }
+
+ public function getSize()
+ {
+ return $this->size;
+ }
+
+ public function tell()
+ {
+ return $this->tellPos;
+ }
+
+ public function eof()
+ {
+ return !$this->source;
+ }
+
+ public function isSeekable()
+ {
+ return false;
+ }
+
+ public function rewind()
+ {
+ $this->seek(0);
+ }
+
+ public function seek($offset, $whence = SEEK_SET)
+ {
+ throw new \RuntimeException('Cannot seek a PumpStream');
+ }
+
+ public function isWritable()
+ {
+ return false;
+ }
+
+ public function write($string)
+ {
+ throw new \RuntimeException('Cannot write to a PumpStream');
+ }
+
+ public function isReadable()
+ {
+ return true;
+ }
+
+ public function read($length)
+ {
+ $data = $this->buffer->read($length);
+ $readLen = strlen($data);
+ $this->tellPos += $readLen;
+ $remaining = $length - $readLen;
+
+ if ($remaining) {
+ $this->pump($remaining);
+ $data .= $this->buffer->read($remaining);
+ $this->tellPos += strlen($data) - $readLen;
+ }
+
+ return $data;
+ }
+
+ public function getContents()
+ {
+ $result = '';
+ while (!$this->eof()) {
+ $result .= $this->read(1000000);
+ }
+
+ return $result;
+ }
+
+ public function getMetadata($key = null)
+ {
+ if (!$key) {
+ return $this->metadata;
+ }
+
+ return isset($this->metadata[$key]) ? $this->metadata[$key] : null;
+ }
+
+ private function pump($length)
+ {
+ if ($this->source) {
+ do {
+ $data = call_user_func($this->source, $length);
+ if ($data === false || $data === null) {
+ $this->source = null;
+ return;
+ }
+ $this->buffer->write($data);
+ $length -= strlen($data);
+ } while ($length > 0);
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/Request.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/Request.php
new file mode 100644
index 0000000..0828548
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/Request.php
@@ -0,0 +1,142 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use InvalidArgumentException;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\StreamInterface;
+use Psr\Http\Message\UriInterface;
+
+/**
+ * PSR-7 request implementation.
+ */
+class Request implements RequestInterface
+{
+ use MessageTrait;
+
+ /** @var string */
+ private $method;
+
+ /** @var null|string */
+ private $requestTarget;
+
+ /** @var UriInterface */
+ private $uri;
+
+ /**
+ * @param string $method HTTP method
+ * @param string|UriInterface $uri URI
+ * @param array $headers Request headers
+ * @param string|null|resource|StreamInterface $body Request body
+ * @param string $version Protocol version
+ */
+ public function __construct(
+ $method,
+ $uri,
+ array $headers = [],
+ $body = null,
+ $version = '1.1'
+ ) {
+ if (!($uri instanceof UriInterface)) {
+ $uri = new Uri($uri);
+ }
+
+ $this->method = strtoupper($method);
+ $this->uri = $uri;
+ $this->setHeaders($headers);
+ $this->protocol = $version;
+
+ if (!$this->hasHeader('Host')) {
+ $this->updateHostFromUri();
+ }
+
+ if ($body !== '' && $body !== null) {
+ $this->stream = stream_for($body);
+ }
+ }
+
+ public function getRequestTarget()
+ {
+ if ($this->requestTarget !== null) {
+ return $this->requestTarget;
+ }
+
+ $target = $this->uri->getPath();
+ if ($target == '') {
+ $target = '/';
+ }
+ if ($this->uri->getQuery() != '') {
+ $target .= '?' . $this->uri->getQuery();
+ }
+
+ return $target;
+ }
+
+ public function withRequestTarget($requestTarget)
+ {
+ if (preg_match('#\s#', $requestTarget)) {
+ throw new InvalidArgumentException(
+ 'Invalid request target provided; cannot contain whitespace'
+ );
+ }
+
+ $new = clone $this;
+ $new->requestTarget = $requestTarget;
+ return $new;
+ }
+
+ public function getMethod()
+ {
+ return $this->method;
+ }
+
+ public function withMethod($method)
+ {
+ $new = clone $this;
+ $new->method = strtoupper($method);
+ return $new;
+ }
+
+ public function getUri()
+ {
+ return $this->uri;
+ }
+
+ public function withUri(UriInterface $uri, $preserveHost = false)
+ {
+ if ($uri === $this->uri) {
+ return $this;
+ }
+
+ $new = clone $this;
+ $new->uri = $uri;
+
+ if (!$preserveHost) {
+ $new->updateHostFromUri();
+ }
+
+ return $new;
+ }
+
+ private function updateHostFromUri()
+ {
+ $host = $this->uri->getHost();
+
+ if ($host == '') {
+ return;
+ }
+
+ if (($port = $this->uri->getPort()) !== null) {
+ $host .= ':' . $port;
+ }
+
+ if (isset($this->headerNames['host'])) {
+ $header = $this->headerNames['host'];
+ } else {
+ $header = 'Host';
+ $this->headerNames['host'] = 'Host';
+ }
+ // Ensure Host is the first header.
+ // See: http://tools.ietf.org/html/rfc7230#section-5.4
+ $this->headers = [$header => [$host]] + $this->headers;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/Response.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/Response.php
new file mode 100644
index 0000000..2830c6c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/Response.php
@@ -0,0 +1,132 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * PSR-7 response implementation.
+ */
+class Response implements ResponseInterface
+{
+ use MessageTrait;
+
+ /** @var array Map of standard HTTP status code/reason phrases */
+ private static $phrases = [
+ 100 => 'Continue',
+ 101 => 'Switching Protocols',
+ 102 => 'Processing',
+ 200 => 'OK',
+ 201 => 'Created',
+ 202 => 'Accepted',
+ 203 => 'Non-Authoritative Information',
+ 204 => 'No Content',
+ 205 => 'Reset Content',
+ 206 => 'Partial Content',
+ 207 => 'Multi-status',
+ 208 => 'Already Reported',
+ 300 => 'Multiple Choices',
+ 301 => 'Moved Permanently',
+ 302 => 'Found',
+ 303 => 'See Other',
+ 304 => 'Not Modified',
+ 305 => 'Use Proxy',
+ 306 => 'Switch Proxy',
+ 307 => 'Temporary Redirect',
+ 400 => 'Bad Request',
+ 401 => 'Unauthorized',
+ 402 => 'Payment Required',
+ 403 => 'Forbidden',
+ 404 => 'Not Found',
+ 405 => 'Method Not Allowed',
+ 406 => 'Not Acceptable',
+ 407 => 'Proxy Authentication Required',
+ 408 => 'Request Time-out',
+ 409 => 'Conflict',
+ 410 => 'Gone',
+ 411 => 'Length Required',
+ 412 => 'Precondition Failed',
+ 413 => 'Request Entity Too Large',
+ 414 => 'Request-URI Too Large',
+ 415 => 'Unsupported Media Type',
+ 416 => 'Requested range not satisfiable',
+ 417 => 'Expectation Failed',
+ 418 => 'I\'m a teapot',
+ 422 => 'Unprocessable Entity',
+ 423 => 'Locked',
+ 424 => 'Failed Dependency',
+ 425 => 'Unordered Collection',
+ 426 => 'Upgrade Required',
+ 428 => 'Precondition Required',
+ 429 => 'Too Many Requests',
+ 431 => 'Request Header Fields Too Large',
+ 451 => 'Unavailable For Legal Reasons',
+ 500 => 'Internal Server Error',
+ 501 => 'Not Implemented',
+ 502 => 'Bad Gateway',
+ 503 => 'Service Unavailable',
+ 504 => 'Gateway Time-out',
+ 505 => 'HTTP Version not supported',
+ 506 => 'Variant Also Negotiates',
+ 507 => 'Insufficient Storage',
+ 508 => 'Loop Detected',
+ 511 => 'Network Authentication Required',
+ ];
+
+ /** @var string */
+ private $reasonPhrase = '';
+
+ /** @var int */
+ private $statusCode = 200;
+
+ /**
+ * @param int $status Status code
+ * @param array $headers Response headers
+ * @param string|null|resource|StreamInterface $body Response body
+ * @param string $version Protocol version
+ * @param string|null $reason Reason phrase (when empty a default will be used based on the status code)
+ */
+ public function __construct(
+ $status = 200,
+ array $headers = [],
+ $body = null,
+ $version = '1.1',
+ $reason = null
+ ) {
+ $this->statusCode = (int) $status;
+
+ if ($body !== '' && $body !== null) {
+ $this->stream = stream_for($body);
+ }
+
+ $this->setHeaders($headers);
+ if ($reason == '' && isset(self::$phrases[$this->statusCode])) {
+ $this->reasonPhrase = self::$phrases[$this->statusCode];
+ } else {
+ $this->reasonPhrase = (string) $reason;
+ }
+
+ $this->protocol = $version;
+ }
+
+ public function getStatusCode()
+ {
+ return $this->statusCode;
+ }
+
+ public function getReasonPhrase()
+ {
+ return $this->reasonPhrase;
+ }
+
+ public function withStatus($code, $reasonPhrase = '')
+ {
+ $new = clone $this;
+ $new->statusCode = (int) $code;
+ if ($reasonPhrase == '' && isset(self::$phrases[$new->statusCode])) {
+ $reasonPhrase = self::$phrases[$new->statusCode];
+ }
+ $new->reasonPhrase = $reasonPhrase;
+ return $new;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/ServerRequest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/ServerRequest.php
new file mode 100644
index 0000000..575aab8
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/ServerRequest.php
@@ -0,0 +1,358 @@
+<?php
+
+namespace GuzzleHttp\Psr7;
+
+use InvalidArgumentException;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Message\UriInterface;
+use Psr\Http\Message\StreamInterface;
+use Psr\Http\Message\UploadedFileInterface;
+
+/**
+ * Server-side HTTP request
+ *
+ * Extends the Request definition to add methods for accessing incoming data,
+ * specifically server parameters, cookies, matched path parameters, query
+ * string arguments, body parameters, and upload file information.
+ *
+ * "Attributes" are discovered via decomposing the request (and usually
+ * specifically the URI path), and typically will be injected by the application.
+ *
+ * Requests are considered immutable; all methods that might change state are
+ * implemented such that they retain the internal state of the current
+ * message and return a new instance that contains the changed state.
+ */
+class ServerRequest extends Request implements ServerRequestInterface
+{
+ /**
+ * @var array
+ */
+ private $attributes = [];
+
+ /**
+ * @var array
+ */
+ private $cookieParams = [];
+
+ /**
+ * @var null|array|object
+ */
+ private $parsedBody;
+
+ /**
+ * @var array
+ */
+ private $queryParams = [];
+
+ /**
+ * @var array
+ */
+ private $serverParams;
+
+ /**
+ * @var array
+ */
+ private $uploadedFiles = [];
+
+ /**
+ * @param string $method HTTP method
+ * @param string|UriInterface $uri URI
+ * @param array $headers Request headers
+ * @param string|null|resource|StreamInterface $body Request body
+ * @param string $version Protocol version
+ * @param array $serverParams Typically the $_SERVER superglobal
+ */
+ public function __construct(
+ $method,
+ $uri,
+ array $headers = [],
+ $body = null,
+ $version = '1.1',
+ array $serverParams = []
+ ) {
+ $this->serverParams = $serverParams;
+
+ parent::__construct($method, $uri, $headers, $body, $version);
+ }
+
+ /**
+ * Return an UploadedFile instance array.
+ *
+ * @param array $files A array which respect $_FILES structure
+ * @throws InvalidArgumentException for unrecognized values
+ * @return array
+ */
+ public static function normalizeFiles(array $files)
+ {
+ $normalized = [];
+
+ foreach ($files as $key => $value) {
+ if ($value instanceof UploadedFileInterface) {
+ $normalized[$key] = $value;
+ } elseif (is_array($value) && isset($value['tmp_name'])) {
+ $normalized[$key] = self::createUploadedFileFromSpec($value);
+ } elseif (is_array($value)) {
+ $normalized[$key] = self::normalizeFiles($value);
+ continue;
+ } else {
+ throw new InvalidArgumentException('Invalid value in files specification');
+ }
+ }
+
+ return $normalized;
+ }
+
+ /**
+ * Create and return an UploadedFile instance from a $_FILES specification.
+ *
+ * If the specification represents an array of values, this method will
+ * delegate to normalizeNestedFileSpec() and return that return value.
+ *
+ * @param array $value $_FILES struct
+ * @return array|UploadedFileInterface
+ */
+ private static function createUploadedFileFromSpec(array $value)
+ {
+ if (is_array($value['tmp_name'])) {
+ return self::normalizeNestedFileSpec($value);
+ }
+
+ return new UploadedFile(
+ $value['tmp_name'],
+ (int) $value['size'],
+ (int) $value['error'],
+ $value['name'],
+ $value['type']
+ );
+ }
+
+ /**
+ * Normalize an array of file specifications.
+ *
+ * Loops through all nested files and returns a normalized array of
+ * UploadedFileInterface instances.
+ *
+ * @param array $files
+ * @return UploadedFileInterface[]
+ */
+ private static function normalizeNestedFileSpec(array $files = [])
+ {
+ $normalizedFiles = [];
+
+ foreach (array_keys($files['tmp_name']) as $key) {
+ $spec = [
+ 'tmp_name' => $files['tmp_name'][$key],
+ 'size' => $files['size'][$key],
+ 'error' => $files['error'][$key],
+ 'name' => $files['name'][$key],
+ 'type' => $files['type'][$key],
+ ];
+ $normalizedFiles[$key] = self::createUploadedFileFromSpec($spec);
+ }
+
+ return $normalizedFiles;
+ }
+
+ /**
+ * Return a ServerRequest populated with superglobals:
+ * $_GET
+ * $_POST
+ * $_COOKIE
+ * $_FILES
+ * $_SERVER
+ *
+ * @return ServerRequestInterface
+ */
+ public static function fromGlobals()
+ {
+ $method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET';
+ $headers = function_exists('getallheaders') ? getallheaders() : [];
+ $uri = self::getUriFromGlobals();
+ $body = new LazyOpenStream('php://input', 'r+');
+ $protocol = isset($_SERVER['SERVER_PROTOCOL']) ? str_replace('HTTP/', '', $_SERVER['SERVER_PROTOCOL']) : '1.1';
+
+ $serverRequest = new ServerRequest($method, $uri, $headers, $body, $protocol, $_SERVER);
+
+ return $serverRequest
+ ->withCookieParams($_COOKIE)
+ ->withQueryParams($_GET)
+ ->withParsedBody($_POST)
+ ->withUploadedFiles(self::normalizeFiles($_FILES));
+ }
+
+ /**
+ * Get a Uri populated with values from $_SERVER.
+ *
+ * @return UriInterface
+ */
+ public static function getUriFromGlobals() {
+ $uri = new Uri('');
+
+ $uri = $uri->withScheme(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https' : 'http');
+
+ $hasPort = false;
+ if (isset($_SERVER['HTTP_HOST'])) {
+ $hostHeaderParts = explode(':', $_SERVER['HTTP_HOST']);
+ $uri = $uri->withHost($hostHeaderParts[0]);
+ if (isset($hostHeaderParts[1])) {
+ $hasPort = true;
+ $uri = $uri->withPort($hostHeaderParts[1]);
+ }
+ } elseif (isset($_SERVER['SERVER_NAME'])) {
+ $uri = $uri->withHost($_SERVER['SERVER_NAME']);
+ } elseif (isset($_SERVER['SERVER_ADDR'])) {
+ $uri = $uri->withHost($_SERVER['SERVER_ADDR']);
+ }
+
+ if (!$hasPort && isset($_SERVER['SERVER_PORT'])) {
+ $uri = $uri->withPort($_SERVER['SERVER_PORT']);
+ }
+
+ $hasQuery = false;
+ if (isset($_SERVER['REQUEST_URI'])) {
+ $requestUriParts = explode('?', $_SERVER['REQUEST_URI']);
+ $uri = $uri->withPath($requestUriParts[0]);
+ if (isset($requestUriParts[1])) {
+ $hasQuery = true;
+ $uri = $uri->withQuery($requestUriParts[1]);
+ }
+ }
+
+ if (!$hasQuery && isset($_SERVER['QUERY_STRING'])) {
+ $uri = $uri->withQuery($_SERVER['QUERY_STRING']);
+ }
+
+ return $uri;
+ }
+
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getServerParams()
+ {
+ return $this->serverParams;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getUploadedFiles()
+ {
+ return $this->uploadedFiles;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function withUploadedFiles(array $uploadedFiles)
+ {
+ $new = clone $this;
+ $new->uploadedFiles = $uploadedFiles;
+
+ return $new;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getCookieParams()
+ {
+ return $this->cookieParams;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function withCookieParams(array $cookies)
+ {
+ $new = clone $this;
+ $new->cookieParams = $cookies;
+
+ return $new;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getQueryParams()
+ {
+ return $this->queryParams;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function withQueryParams(array $query)
+ {
+ $new = clone $this;
+ $new->queryParams = $query;
+
+ return $new;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getParsedBody()
+ {
+ return $this->parsedBody;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function withParsedBody($data)
+ {
+ $new = clone $this;
+ $new->parsedBody = $data;
+
+ return $new;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getAttributes()
+ {
+ return $this->attributes;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getAttribute($attribute, $default = null)
+ {
+ if (false === array_key_exists($attribute, $this->attributes)) {
+ return $default;
+ }
+
+ return $this->attributes[$attribute];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function withAttribute($attribute, $value)
+ {
+ $new = clone $this;
+ $new->attributes[$attribute] = $value;
+
+ return $new;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function withoutAttribute($attribute)
+ {
+ if (false === array_key_exists($attribute, $this->attributes)) {
+ return $this;
+ }
+
+ $new = clone $this;
+ unset($new->attributes[$attribute]);
+
+ return $new;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/Stream.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/Stream.php
new file mode 100644
index 0000000..e336628
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/Stream.php
@@ -0,0 +1,257 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * PHP stream implementation.
+ *
+ * @var $stream
+ */
+class Stream implements StreamInterface
+{
+ private $stream;
+ private $size;
+ private $seekable;
+ private $readable;
+ private $writable;
+ private $uri;
+ private $customMetadata;
+
+ /** @var array Hash of readable and writable stream types */
+ private static $readWriteHash = [
+ 'read' => [
+ 'r' => true, 'w+' => true, 'r+' => true, 'x+' => true, 'c+' => true,
+ 'rb' => true, 'w+b' => true, 'r+b' => true, 'x+b' => true,
+ 'c+b' => true, 'rt' => true, 'w+t' => true, 'r+t' => true,
+ 'x+t' => true, 'c+t' => true, 'a+' => true
+ ],
+ 'write' => [
+ 'w' => true, 'w+' => true, 'rw' => true, 'r+' => true, 'x+' => true,
+ 'c+' => true, 'wb' => true, 'w+b' => true, 'r+b' => true,
+ 'x+b' => true, 'c+b' => true, 'w+t' => true, 'r+t' => true,
+ 'x+t' => true, 'c+t' => true, 'a' => true, 'a+' => true
+ ]
+ ];
+
+ /**
+ * This constructor accepts an associative array of options.
+ *
+ * - size: (int) If a read stream would otherwise have an indeterminate
+ * size, but the size is known due to foreknowledge, then you can
+ * provide that size, in bytes.
+ * - metadata: (array) Any additional metadata to return when the metadata
+ * of the stream is accessed.
+ *
+ * @param resource $stream Stream resource to wrap.
+ * @param array $options Associative array of options.
+ *
+ * @throws \InvalidArgumentException if the stream is not a stream resource
+ */
+ public function __construct($stream, $options = [])
+ {
+ if (!is_resource($stream)) {
+ throw new \InvalidArgumentException('Stream must be a resource');
+ }
+
+ if (isset($options['size'])) {
+ $this->size = $options['size'];
+ }
+
+ $this->customMetadata = isset($options['metadata'])
+ ? $options['metadata']
+ : [];
+
+ $this->stream = $stream;
+ $meta = stream_get_meta_data($this->stream);
+ $this->seekable = $meta['seekable'];
+ $this->readable = isset(self::$readWriteHash['read'][$meta['mode']]);
+ $this->writable = isset(self::$readWriteHash['write'][$meta['mode']]);
+ $this->uri = $this->getMetadata('uri');
+ }
+
+ public function __get($name)
+ {
+ if ($name == 'stream') {
+ throw new \RuntimeException('The stream is detached');
+ }
+
+ throw new \BadMethodCallException('No value for ' . $name);
+ }
+
+ /**
+ * Closes the stream when the destructed
+ */
+ public function __destruct()
+ {
+ $this->close();
+ }
+
+ public function __toString()
+ {
+ try {
+ $this->seek(0);
+ return (string) stream_get_contents($this->stream);
+ } catch (\Exception $e) {
+ return '';
+ }
+ }
+
+ public function getContents()
+ {
+ $contents = stream_get_contents($this->stream);
+
+ if ($contents === false) {
+ throw new \RuntimeException('Unable to read stream contents');
+ }
+
+ return $contents;
+ }
+
+ public function close()
+ {
+ if (isset($this->stream)) {
+ if (is_resource($this->stream)) {
+ fclose($this->stream);
+ }
+ $this->detach();
+ }
+ }
+
+ public function detach()
+ {
+ if (!isset($this->stream)) {
+ return null;
+ }
+
+ $result = $this->stream;
+ unset($this->stream);
+ $this->size = $this->uri = null;
+ $this->readable = $this->writable = $this->seekable = false;
+
+ return $result;
+ }
+
+ public function getSize()
+ {
+ if ($this->size !== null) {
+ return $this->size;
+ }
+
+ if (!isset($this->stream)) {
+ return null;
+ }
+
+ // Clear the stat cache if the stream has a URI
+ if ($this->uri) {
+ clearstatcache(true, $this->uri);
+ }
+
+ $stats = fstat($this->stream);
+ if (isset($stats['size'])) {
+ $this->size = $stats['size'];
+ return $this->size;
+ }
+
+ return null;
+ }
+
+ public function isReadable()
+ {
+ return $this->readable;
+ }
+
+ public function isWritable()
+ {
+ return $this->writable;
+ }
+
+ public function isSeekable()
+ {
+ return $this->seekable;
+ }
+
+ public function eof()
+ {
+ return !$this->stream || feof($this->stream);
+ }
+
+ public function tell()
+ {
+ $result = ftell($this->stream);
+
+ if ($result === false) {
+ throw new \RuntimeException('Unable to determine stream position');
+ }
+
+ return $result;
+ }
+
+ public function rewind()
+ {
+ $this->seek(0);
+ }
+
+ public function seek($offset, $whence = SEEK_SET)
+ {
+ if (!$this->seekable) {
+ throw new \RuntimeException('Stream is not seekable');
+ } elseif (fseek($this->stream, $offset, $whence) === -1) {
+ throw new \RuntimeException('Unable to seek to stream position '
+ . $offset . ' with whence ' . var_export($whence, true));
+ }
+ }
+
+ public function read($length)
+ {
+ if (!$this->readable) {
+ throw new \RuntimeException('Cannot read from non-readable stream');
+ }
+ if ($length < 0) {
+ throw new \RuntimeException('Length parameter cannot be negative');
+ }
+
+ if (0 === $length) {
+ return '';
+ }
+
+ $string = fread($this->stream, $length);
+ if (false === $string) {
+ throw new \RuntimeException('Unable to read from stream');
+ }
+
+ return $string;
+ }
+
+ public function write($string)
+ {
+ if (!$this->writable) {
+ throw new \RuntimeException('Cannot write to a non-writable stream');
+ }
+
+ // We can't know the size after writing anything
+ $this->size = null;
+ $result = fwrite($this->stream, $string);
+
+ if ($result === false) {
+ throw new \RuntimeException('Unable to write to stream');
+ }
+
+ return $result;
+ }
+
+ public function getMetadata($key = null)
+ {
+ if (!isset($this->stream)) {
+ return $key ? null : [];
+ } elseif (!$key) {
+ return $this->customMetadata + stream_get_meta_data($this->stream);
+ } elseif (isset($this->customMetadata[$key])) {
+ return $this->customMetadata[$key];
+ }
+
+ $meta = stream_get_meta_data($this->stream);
+
+ return isset($meta[$key]) ? $meta[$key] : null;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/StreamDecoratorTrait.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/StreamDecoratorTrait.php
new file mode 100644
index 0000000..daec6f5
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/StreamDecoratorTrait.php
@@ -0,0 +1,149 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Stream decorator trait
+ * @property StreamInterface stream
+ */
+trait StreamDecoratorTrait
+{
+ /**
+ * @param StreamInterface $stream Stream to decorate
+ */
+ public function __construct(StreamInterface $stream)
+ {
+ $this->stream = $stream;
+ }
+
+ /**
+ * Magic method used to create a new stream if streams are not added in
+ * the constructor of a decorator (e.g., LazyOpenStream).
+ *
+ * @param string $name Name of the property (allows "stream" only).
+ *
+ * @return StreamInterface
+ */
+ public function __get($name)
+ {
+ if ($name == 'stream') {
+ $this->stream = $this->createStream();
+ return $this->stream;
+ }
+
+ throw new \UnexpectedValueException("$name not found on class");
+ }
+
+ public function __toString()
+ {
+ try {
+ if ($this->isSeekable()) {
+ $this->seek(0);
+ }
+ return $this->getContents();
+ } catch (\Exception $e) {
+ // Really, PHP? https://bugs.php.net/bug.php?id=53648
+ trigger_error('StreamDecorator::__toString exception: '
+ . (string) $e, E_USER_ERROR);
+ return '';
+ }
+ }
+
+ public function getContents()
+ {
+ return copy_to_string($this);
+ }
+
+ /**
+ * Allow decorators to implement custom methods
+ *
+ * @param string $method Missing method name
+ * @param array $args Method arguments
+ *
+ * @return mixed
+ */
+ public function __call($method, array $args)
+ {
+ $result = call_user_func_array([$this->stream, $method], $args);
+
+ // Always return the wrapped object if the result is a return $this
+ return $result === $this->stream ? $this : $result;
+ }
+
+ public function close()
+ {
+ $this->stream->close();
+ }
+
+ public function getMetadata($key = null)
+ {
+ return $this->stream->getMetadata($key);
+ }
+
+ public function detach()
+ {
+ return $this->stream->detach();
+ }
+
+ public function getSize()
+ {
+ return $this->stream->getSize();
+ }
+
+ public function eof()
+ {
+ return $this->stream->eof();
+ }
+
+ public function tell()
+ {
+ return $this->stream->tell();
+ }
+
+ public function isReadable()
+ {
+ return $this->stream->isReadable();
+ }
+
+ public function isWritable()
+ {
+ return $this->stream->isWritable();
+ }
+
+ public function isSeekable()
+ {
+ return $this->stream->isSeekable();
+ }
+
+ public function rewind()
+ {
+ $this->seek(0);
+ }
+
+ public function seek($offset, $whence = SEEK_SET)
+ {
+ $this->stream->seek($offset, $whence);
+ }
+
+ public function read($length)
+ {
+ return $this->stream->read($length);
+ }
+
+ public function write($string)
+ {
+ return $this->stream->write($string);
+ }
+
+ /**
+ * Implement in subclasses to dynamically create streams when requested.
+ *
+ * @return StreamInterface
+ * @throws \BadMethodCallException
+ */
+ protected function createStream()
+ {
+ throw new \BadMethodCallException('Not implemented');
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/StreamWrapper.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/StreamWrapper.php
new file mode 100644
index 0000000..cf7b223
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/StreamWrapper.php
@@ -0,0 +1,121 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Converts Guzzle streams into PHP stream resources.
+ */
+class StreamWrapper
+{
+ /** @var resource */
+ public $context;
+
+ /** @var StreamInterface */
+ private $stream;
+
+ /** @var string r, r+, or w */
+ private $mode;
+
+ /**
+ * Returns a resource representing the stream.
+ *
+ * @param StreamInterface $stream The stream to get a resource for
+ *
+ * @return resource
+ * @throws \InvalidArgumentException if stream is not readable or writable
+ */
+ public static function getResource(StreamInterface $stream)
+ {
+ self::register();
+
+ if ($stream->isReadable()) {
+ $mode = $stream->isWritable() ? 'r+' : 'r';
+ } elseif ($stream->isWritable()) {
+ $mode = 'w';
+ } else {
+ throw new \InvalidArgumentException('The stream must be readable, '
+ . 'writable, or both.');
+ }
+
+ return fopen('guzzle://stream', $mode, null, stream_context_create([
+ 'guzzle' => ['stream' => $stream]
+ ]));
+ }
+
+ /**
+ * Registers the stream wrapper if needed
+ */
+ public static function register()
+ {
+ if (!in_array('guzzle', stream_get_wrappers())) {
+ stream_wrapper_register('guzzle', __CLASS__);
+ }
+ }
+
+ public function stream_open($path, $mode, $options, &$opened_path)
+ {
+ $options = stream_context_get_options($this->context);
+
+ if (!isset($options['guzzle']['stream'])) {
+ return false;
+ }
+
+ $this->mode = $mode;
+ $this->stream = $options['guzzle']['stream'];
+
+ return true;
+ }
+
+ public function stream_read($count)
+ {
+ return $this->stream->read($count);
+ }
+
+ public function stream_write($data)
+ {
+ return (int) $this->stream->write($data);
+ }
+
+ public function stream_tell()
+ {
+ return $this->stream->tell();
+ }
+
+ public function stream_eof()
+ {
+ return $this->stream->eof();
+ }
+
+ public function stream_seek($offset, $whence)
+ {
+ $this->stream->seek($offset, $whence);
+
+ return true;
+ }
+
+ public function stream_stat()
+ {
+ static $modeMap = [
+ 'r' => 33060,
+ 'r+' => 33206,
+ 'w' => 33188
+ ];
+
+ return [
+ 'dev' => 0,
+ 'ino' => 0,
+ 'mode' => $modeMap[$this->mode],
+ 'nlink' => 0,
+ 'uid' => 0,
+ 'gid' => 0,
+ 'rdev' => 0,
+ 'size' => $this->stream->getSize() ?: 0,
+ 'atime' => 0,
+ 'mtime' => 0,
+ 'ctime' => 0,
+ 'blksize' => 0,
+ 'blocks' => 0
+ ];
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/UploadedFile.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/UploadedFile.php
new file mode 100644
index 0000000..e62bd5c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/UploadedFile.php
@@ -0,0 +1,316 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use InvalidArgumentException;
+use Psr\Http\Message\StreamInterface;
+use Psr\Http\Message\UploadedFileInterface;
+use RuntimeException;
+
+class UploadedFile implements UploadedFileInterface
+{
+ /**
+ * @var int[]
+ */
+ private static $errors = [
+ UPLOAD_ERR_OK,
+ UPLOAD_ERR_INI_SIZE,
+ UPLOAD_ERR_FORM_SIZE,
+ UPLOAD_ERR_PARTIAL,
+ UPLOAD_ERR_NO_FILE,
+ UPLOAD_ERR_NO_TMP_DIR,
+ UPLOAD_ERR_CANT_WRITE,
+ UPLOAD_ERR_EXTENSION,
+ ];
+
+ /**
+ * @var string
+ */
+ private $clientFilename;
+
+ /**
+ * @var string
+ */
+ private $clientMediaType;
+
+ /**
+ * @var int
+ */
+ private $error;
+
+ /**
+ * @var null|string
+ */
+ private $file;
+
+ /**
+ * @var bool
+ */
+ private $moved = false;
+
+ /**
+ * @var int
+ */
+ private $size;
+
+ /**
+ * @var StreamInterface|null
+ */
+ private $stream;
+
+ /**
+ * @param StreamInterface|string|resource $streamOrFile
+ * @param int $size
+ * @param int $errorStatus
+ * @param string|null $clientFilename
+ * @param string|null $clientMediaType
+ */
+ public function __construct(
+ $streamOrFile,
+ $size,
+ $errorStatus,
+ $clientFilename = null,
+ $clientMediaType = null
+ ) {
+ $this->setError($errorStatus);
+ $this->setSize($size);
+ $this->setClientFilename($clientFilename);
+ $this->setClientMediaType($clientMediaType);
+
+ if ($this->isOk()) {
+ $this->setStreamOrFile($streamOrFile);
+ }
+ }
+
+ /**
+ * Depending on the value set file or stream variable
+ *
+ * @param mixed $streamOrFile
+ * @throws InvalidArgumentException
+ */
+ private function setStreamOrFile($streamOrFile)
+ {
+ if (is_string($streamOrFile)) {
+ $this->file = $streamOrFile;
+ } elseif (is_resource($streamOrFile)) {
+ $this->stream = new Stream($streamOrFile);
+ } elseif ($streamOrFile instanceof StreamInterface) {
+ $this->stream = $streamOrFile;
+ } else {
+ throw new InvalidArgumentException(
+ 'Invalid stream or file provided for UploadedFile'
+ );
+ }
+ }
+
+ /**
+ * @param int $error
+ * @throws InvalidArgumentException
+ */
+ private function setError($error)
+ {
+ if (false === is_int($error)) {
+ throw new InvalidArgumentException(
+ 'Upload file error status must be an integer'
+ );
+ }
+
+ if (false === in_array($error, UploadedFile::$errors)) {
+ throw new InvalidArgumentException(
+ 'Invalid error status for UploadedFile'
+ );
+ }
+
+ $this->error = $error;
+ }
+
+ /**
+ * @param int $size
+ * @throws InvalidArgumentException
+ */
+ private function setSize($size)
+ {
+ if (false === is_int($size)) {
+ throw new InvalidArgumentException(
+ 'Upload file size must be an integer'
+ );
+ }
+
+ $this->size = $size;
+ }
+
+ /**
+ * @param mixed $param
+ * @return boolean
+ */
+ private function isStringOrNull($param)
+ {
+ return in_array(gettype($param), ['string', 'NULL']);
+ }
+
+ /**
+ * @param mixed $param
+ * @return boolean
+ */
+ private function isStringNotEmpty($param)
+ {
+ return is_string($param) && false === empty($param);
+ }
+
+ /**
+ * @param string|null $clientFilename
+ * @throws InvalidArgumentException
+ */
+ private function setClientFilename($clientFilename)
+ {
+ if (false === $this->isStringOrNull($clientFilename)) {
+ throw new InvalidArgumentException(
+ 'Upload file client filename must be a string or null'
+ );
+ }
+
+ $this->clientFilename = $clientFilename;
+ }
+
+ /**
+ * @param string|null $clientMediaType
+ * @throws InvalidArgumentException
+ */
+ private function setClientMediaType($clientMediaType)
+ {
+ if (false === $this->isStringOrNull($clientMediaType)) {
+ throw new InvalidArgumentException(
+ 'Upload file client media type must be a string or null'
+ );
+ }
+
+ $this->clientMediaType = $clientMediaType;
+ }
+
+ /**
+ * Return true if there is no upload error
+ *
+ * @return boolean
+ */
+ private function isOk()
+ {
+ return $this->error === UPLOAD_ERR_OK;
+ }
+
+ /**
+ * @return boolean
+ */
+ public function isMoved()
+ {
+ return $this->moved;
+ }
+
+ /**
+ * @throws RuntimeException if is moved or not ok
+ */
+ private function validateActive()
+ {
+ if (false === $this->isOk()) {
+ throw new RuntimeException('Cannot retrieve stream due to upload error');
+ }
+
+ if ($this->isMoved()) {
+ throw new RuntimeException('Cannot retrieve stream after it has already been moved');
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ * @throws RuntimeException if the upload was not successful.
+ */
+ public function getStream()
+ {
+ $this->validateActive();
+
+ if ($this->stream instanceof StreamInterface) {
+ return $this->stream;
+ }
+
+ return new LazyOpenStream($this->file, 'r+');
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @see http://php.net/is_uploaded_file
+ * @see http://php.net/move_uploaded_file
+ * @param string $targetPath Path to which to move the uploaded file.
+ * @throws RuntimeException if the upload was not successful.
+ * @throws InvalidArgumentException if the $path specified is invalid.
+ * @throws RuntimeException on any error during the move operation, or on
+ * the second or subsequent call to the method.
+ */
+ public function moveTo($targetPath)
+ {
+ $this->validateActive();
+
+ if (false === $this->isStringNotEmpty($targetPath)) {
+ throw new InvalidArgumentException(
+ 'Invalid path provided for move operation; must be a non-empty string'
+ );
+ }
+
+ if ($this->file) {
+ $this->moved = php_sapi_name() == 'cli'
+ ? rename($this->file, $targetPath)
+ : move_uploaded_file($this->file, $targetPath);
+ } else {
+ copy_to_stream(
+ $this->getStream(),
+ new LazyOpenStream($targetPath, 'w')
+ );
+
+ $this->moved = true;
+ }
+
+ if (false === $this->moved) {
+ throw new RuntimeException(
+ sprintf('Uploaded file could not be moved to %s', $targetPath)
+ );
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @return int|null The file size in bytes or null if unknown.
+ */
+ public function getSize()
+ {
+ return $this->size;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @see http://php.net/manual/en/features.file-upload.errors.php
+ * @return int One of PHP's UPLOAD_ERR_XXX constants.
+ */
+ public function getError()
+ {
+ return $this->error;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @return string|null The filename sent by the client or null if none
+ * was provided.
+ */
+ public function getClientFilename()
+ {
+ return $this->clientFilename;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getClientMediaType()
+ {
+ return $this->clientMediaType;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/Uri.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/Uri.php
new file mode 100644
index 0000000..f46c1db
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/Uri.php
@@ -0,0 +1,702 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\UriInterface;
+
+/**
+ * PSR-7 URI implementation.
+ *
+ * @author Michael Dowling
+ * @author Tobias Schultze
+ * @author Matthew Weier O'Phinney
+ */
+class Uri implements UriInterface
+{
+ /**
+ * Absolute http and https URIs require a host per RFC 7230 Section 2.7
+ * but in generic URIs the host can be empty. So for http(s) URIs
+ * we apply this default host when no host is given yet to form a
+ * valid URI.
+ */
+ const HTTP_DEFAULT_HOST = 'localhost';
+
+ private static $defaultPorts = [
+ 'http' => 80,
+ 'https' => 443,
+ 'ftp' => 21,
+ 'gopher' => 70,
+ 'nntp' => 119,
+ 'news' => 119,
+ 'telnet' => 23,
+ 'tn3270' => 23,
+ 'imap' => 143,
+ 'pop' => 110,
+ 'ldap' => 389,
+ ];
+
+ private static $charUnreserved = 'a-zA-Z0-9_\-\.~';
+ private static $charSubDelims = '!\$&\'\(\)\*\+,;=';
+ private static $replaceQuery = ['=' => '%3D', '&' => '%26'];
+
+ /** @var string Uri scheme. */
+ private $scheme = '';
+
+ /** @var string Uri user info. */
+ private $userInfo = '';
+
+ /** @var string Uri host. */
+ private $host = '';
+
+ /** @var int|null Uri port. */
+ private $port;
+
+ /** @var string Uri path. */
+ private $path = '';
+
+ /** @var string Uri query string. */
+ private $query = '';
+
+ /** @var string Uri fragment. */
+ private $fragment = '';
+
+ /**
+ * @param string $uri URI to parse
+ */
+ public function __construct($uri = '')
+ {
+ // weak type check to also accept null until we can add scalar type hints
+ if ($uri != '') {
+ $parts = parse_url($uri);
+ if ($parts === false) {
+ throw new \InvalidArgumentException("Unable to parse URI: $uri");
+ }
+ $this->applyParts($parts);
+ }
+ }
+
+ public function __toString()
+ {
+ return self::composeComponents(
+ $this->scheme,
+ $this->getAuthority(),
+ $this->path,
+ $this->query,
+ $this->fragment
+ );
+ }
+
+ /**
+ * Composes a URI reference string from its various components.
+ *
+ * Usually this method does not need to be called manually but instead is used indirectly via
+ * `Psr\Http\Message\UriInterface::__toString`.
+ *
+ * PSR-7 UriInterface treats an empty component the same as a missing component as
+ * getQuery(), getFragment() etc. always return a string. This explains the slight
+ * difference to RFC 3986 Section 5.3.
+ *
+ * Another adjustment is that the authority separator is added even when the authority is missing/empty
+ * for the "file" scheme. This is because PHP stream functions like `file_get_contents` only work with
+ * `file:///myfile` but not with `file:/myfile` although they are equivalent according to RFC 3986. But
+ * `file:///` is the more common syntax for the file scheme anyway (Chrome for example redirects to
+ * that format).
+ *
+ * @param string $scheme
+ * @param string $authority
+ * @param string $path
+ * @param string $query
+ * @param string $fragment
+ *
+ * @return string
+ *
+ * @link https://tools.ietf.org/html/rfc3986#section-5.3
+ */
+ public static function composeComponents($scheme, $authority, $path, $query, $fragment)
+ {
+ $uri = '';
+
+ // weak type checks to also accept null until we can add scalar type hints
+ if ($scheme != '') {
+ $uri .= $scheme . ':';
+ }
+
+ if ($authority != ''|| $scheme === 'file') {
+ $uri .= '//' . $authority;
+ }
+
+ $uri .= $path;
+
+ if ($query != '') {
+ $uri .= '?' . $query;
+ }
+
+ if ($fragment != '') {
+ $uri .= '#' . $fragment;
+ }
+
+ return $uri;
+ }
+
+ /**
+ * Whether the URI has the default port of the current scheme.
+ *
+ * `Psr\Http\Message\UriInterface::getPort` may return null or the standard port. This method can be used
+ * independently of the implementation.
+ *
+ * @param UriInterface $uri
+ *
+ * @return bool
+ */
+ public static function isDefaultPort(UriInterface $uri)
+ {
+ return $uri->getPort() === null
+ || (isset(self::$defaultPorts[$uri->getScheme()]) && $uri->getPort() === self::$defaultPorts[$uri->getScheme()]);
+ }
+
+ /**
+ * Whether the URI is absolute, i.e. it has a scheme.
+ *
+ * An instance of UriInterface can either be an absolute URI or a relative reference. This method returns true
+ * if it is the former. An absolute URI has a scheme. A relative reference is used to express a URI relative
+ * to another URI, the base URI. Relative references can be divided into several forms:
+ * - network-path references, e.g. '//example.com/path'
+ * - absolute-path references, e.g. '/path'
+ * - relative-path references, e.g. 'subpath'
+ *
+ * @param UriInterface $uri
+ *
+ * @return bool
+ * @see Uri::isNetworkPathReference
+ * @see Uri::isAbsolutePathReference
+ * @see Uri::isRelativePathReference
+ * @link https://tools.ietf.org/html/rfc3986#section-4
+ */
+ public static function isAbsolute(UriInterface $uri)
+ {
+ return $uri->getScheme() !== '';
+ }
+
+ /**
+ * Whether the URI is a network-path reference.
+ *
+ * A relative reference that begins with two slash characters is termed an network-path reference.
+ *
+ * @param UriInterface $uri
+ *
+ * @return bool
+ * @link https://tools.ietf.org/html/rfc3986#section-4.2
+ */
+ public static function isNetworkPathReference(UriInterface $uri)
+ {
+ return $uri->getScheme() === '' && $uri->getAuthority() !== '';
+ }
+
+ /**
+ * Whether the URI is a absolute-path reference.
+ *
+ * A relative reference that begins with a single slash character is termed an absolute-path reference.
+ *
+ * @param UriInterface $uri
+ *
+ * @return bool
+ * @link https://tools.ietf.org/html/rfc3986#section-4.2
+ */
+ public static function isAbsolutePathReference(UriInterface $uri)
+ {
+ return $uri->getScheme() === ''
+ && $uri->getAuthority() === ''
+ && isset($uri->getPath()[0])
+ && $uri->getPath()[0] === '/';
+ }
+
+ /**
+ * Whether the URI is a relative-path reference.
+ *
+ * A relative reference that does not begin with a slash character is termed a relative-path reference.
+ *
+ * @param UriInterface $uri
+ *
+ * @return bool
+ * @link https://tools.ietf.org/html/rfc3986#section-4.2
+ */
+ public static function isRelativePathReference(UriInterface $uri)
+ {
+ return $uri->getScheme() === ''
+ && $uri->getAuthority() === ''
+ && (!isset($uri->getPath()[0]) || $uri->getPath()[0] !== '/');
+ }
+
+ /**
+ * Whether the URI is a same-document reference.
+ *
+ * A same-document reference refers to a URI that is, aside from its fragment
+ * component, identical to the base URI. When no base URI is given, only an empty
+ * URI reference (apart from its fragment) is considered a same-document reference.
+ *
+ * @param UriInterface $uri The URI to check
+ * @param UriInterface|null $base An optional base URI to compare against
+ *
+ * @return bool
+ * @link https://tools.ietf.org/html/rfc3986#section-4.4
+ */
+ public static function isSameDocumentReference(UriInterface $uri, UriInterface $base = null)
+ {
+ if ($base !== null) {
+ $uri = UriResolver::resolve($base, $uri);
+
+ return ($uri->getScheme() === $base->getScheme())
+ && ($uri->getAuthority() === $base->getAuthority())
+ && ($uri->getPath() === $base->getPath())
+ && ($uri->getQuery() === $base->getQuery());
+ }
+
+ return $uri->getScheme() === '' && $uri->getAuthority() === '' && $uri->getPath() === '' && $uri->getQuery() === '';
+ }
+
+ /**
+ * Removes dot segments from a path and returns the new path.
+ *
+ * @param string $path
+ *
+ * @return string
+ *
+ * @deprecated since version 1.4. Use UriResolver::removeDotSegments instead.
+ * @see UriResolver::removeDotSegments
+ */
+ public static function removeDotSegments($path)
+ {
+ return UriResolver::removeDotSegments($path);
+ }
+
+ /**
+ * Converts the relative URI into a new URI that is resolved against the base URI.
+ *
+ * @param UriInterface $base Base URI
+ * @param string|UriInterface $rel Relative URI
+ *
+ * @return UriInterface
+ *
+ * @deprecated since version 1.4. Use UriResolver::resolve instead.
+ * @see UriResolver::resolve
+ */
+ public static function resolve(UriInterface $base, $rel)
+ {
+ if (!($rel instanceof UriInterface)) {
+ $rel = new self($rel);
+ }
+
+ return UriResolver::resolve($base, $rel);
+ }
+
+ /**
+ * Creates a new URI with a specific query string value removed.
+ *
+ * Any existing query string values that exactly match the provided key are
+ * removed.
+ *
+ * @param UriInterface $uri URI to use as a base.
+ * @param string $key Query string key to remove.
+ *
+ * @return UriInterface
+ */
+ public static function withoutQueryValue(UriInterface $uri, $key)
+ {
+ $current = $uri->getQuery();
+ if ($current === '') {
+ return $uri;
+ }
+
+ $decodedKey = rawurldecode($key);
+ $result = array_filter(explode('&', $current), function ($part) use ($decodedKey) {
+ return rawurldecode(explode('=', $part)[0]) !== $decodedKey;
+ });
+
+ return $uri->withQuery(implode('&', $result));
+ }
+
+ /**
+ * Creates a new URI with a specific query string value.
+ *
+ * Any existing query string values that exactly match the provided key are
+ * removed and replaced with the given key value pair.
+ *
+ * A value of null will set the query string key without a value, e.g. "key"
+ * instead of "key=value".
+ *
+ * @param UriInterface $uri URI to use as a base.
+ * @param string $key Key to set.
+ * @param string|null $value Value to set
+ *
+ * @return UriInterface
+ */
+ public static function withQueryValue(UriInterface $uri, $key, $value)
+ {
+ $current = $uri->getQuery();
+
+ if ($current === '') {
+ $result = [];
+ } else {
+ $decodedKey = rawurldecode($key);
+ $result = array_filter(explode('&', $current), function ($part) use ($decodedKey) {
+ return rawurldecode(explode('=', $part)[0]) !== $decodedKey;
+ });
+ }
+
+ // Query string separators ("=", "&") within the key or value need to be encoded
+ // (while preventing double-encoding) before setting the query string. All other
+ // chars that need percent-encoding will be encoded by withQuery().
+ $key = strtr($key, self::$replaceQuery);
+
+ if ($value !== null) {
+ $result[] = $key . '=' . strtr($value, self::$replaceQuery);
+ } else {
+ $result[] = $key;
+ }
+
+ return $uri->withQuery(implode('&', $result));
+ }
+
+ /**
+ * Creates a URI from a hash of `parse_url` components.
+ *
+ * @param array $parts
+ *
+ * @return UriInterface
+ * @link http://php.net/manual/en/function.parse-url.php
+ *
+ * @throws \InvalidArgumentException If the components do not form a valid URI.
+ */
+ public static function fromParts(array $parts)
+ {
+ $uri = new self();
+ $uri->applyParts($parts);
+ $uri->validateState();
+
+ return $uri;
+ }
+
+ public function getScheme()
+ {
+ return $this->scheme;
+ }
+
+ public function getAuthority()
+ {
+ $authority = $this->host;
+ if ($this->userInfo !== '') {
+ $authority = $this->userInfo . '@' . $authority;
+ }
+
+ if ($this->port !== null) {
+ $authority .= ':' . $this->port;
+ }
+
+ return $authority;
+ }
+
+ public function getUserInfo()
+ {
+ return $this->userInfo;
+ }
+
+ public function getHost()
+ {
+ return $this->host;
+ }
+
+ public function getPort()
+ {
+ return $this->port;
+ }
+
+ public function getPath()
+ {
+ return $this->path;
+ }
+
+ public function getQuery()
+ {
+ return $this->query;
+ }
+
+ public function getFragment()
+ {
+ return $this->fragment;
+ }
+
+ public function withScheme($scheme)
+ {
+ $scheme = $this->filterScheme($scheme);
+
+ if ($this->scheme === $scheme) {
+ return $this;
+ }
+
+ $new = clone $this;
+ $new->scheme = $scheme;
+ $new->removeDefaultPort();
+ $new->validateState();
+
+ return $new;
+ }
+
+ public function withUserInfo($user, $password = null)
+ {
+ $info = $user;
+ if ($password != '') {
+ $info .= ':' . $password;
+ }
+
+ if ($this->userInfo === $info) {
+ return $this;
+ }
+
+ $new = clone $this;
+ $new->userInfo = $info;
+ $new->validateState();
+
+ return $new;
+ }
+
+ public function withHost($host)
+ {
+ $host = $this->filterHost($host);
+
+ if ($this->host === $host) {
+ return $this;
+ }
+
+ $new = clone $this;
+ $new->host = $host;
+ $new->validateState();
+
+ return $new;
+ }
+
+ public function withPort($port)
+ {
+ $port = $this->filterPort($port);
+
+ if ($this->port === $port) {
+ return $this;
+ }
+
+ $new = clone $this;
+ $new->port = $port;
+ $new->removeDefaultPort();
+ $new->validateState();
+
+ return $new;
+ }
+
+ public function withPath($path)
+ {
+ $path = $this->filterPath($path);
+
+ if ($this->path === $path) {
+ return $this;
+ }
+
+ $new = clone $this;
+ $new->path = $path;
+ $new->validateState();
+
+ return $new;
+ }
+
+ public function withQuery($query)
+ {
+ $query = $this->filterQueryAndFragment($query);
+
+ if ($this->query === $query) {
+ return $this;
+ }
+
+ $new = clone $this;
+ $new->query = $query;
+
+ return $new;
+ }
+
+ public function withFragment($fragment)
+ {
+ $fragment = $this->filterQueryAndFragment($fragment);
+
+ if ($this->fragment === $fragment) {
+ return $this;
+ }
+
+ $new = clone $this;
+ $new->fragment = $fragment;
+
+ return $new;
+ }
+
+ /**
+ * Apply parse_url parts to a URI.
+ *
+ * @param array $parts Array of parse_url parts to apply.
+ */
+ private function applyParts(array $parts)
+ {
+ $this->scheme = isset($parts['scheme'])
+ ? $this->filterScheme($parts['scheme'])
+ : '';
+ $this->userInfo = isset($parts['user']) ? $parts['user'] : '';
+ $this->host = isset($parts['host'])
+ ? $this->filterHost($parts['host'])
+ : '';
+ $this->port = isset($parts['port'])
+ ? $this->filterPort($parts['port'])
+ : null;
+ $this->path = isset($parts['path'])
+ ? $this->filterPath($parts['path'])
+ : '';
+ $this->query = isset($parts['query'])
+ ? $this->filterQueryAndFragment($parts['query'])
+ : '';
+ $this->fragment = isset($parts['fragment'])
+ ? $this->filterQueryAndFragment($parts['fragment'])
+ : '';
+ if (isset($parts['pass'])) {
+ $this->userInfo .= ':' . $parts['pass'];
+ }
+
+ $this->removeDefaultPort();
+ }
+
+ /**
+ * @param string $scheme
+ *
+ * @return string
+ *
+ * @throws \InvalidArgumentException If the scheme is invalid.
+ */
+ private function filterScheme($scheme)
+ {
+ if (!is_string($scheme)) {
+ throw new \InvalidArgumentException('Scheme must be a string');
+ }
+
+ return strtolower($scheme);
+ }
+
+ /**
+ * @param string $host
+ *
+ * @return string
+ *
+ * @throws \InvalidArgumentException If the host is invalid.
+ */
+ private function filterHost($host)
+ {
+ if (!is_string($host)) {
+ throw new \InvalidArgumentException('Host must be a string');
+ }
+
+ return strtolower($host);
+ }
+
+ /**
+ * @param int|null $port
+ *
+ * @return int|null
+ *
+ * @throws \InvalidArgumentException If the port is invalid.
+ */
+ private function filterPort($port)
+ {
+ if ($port === null) {
+ return null;
+ }
+
+ $port = (int) $port;
+ if (1 > $port || 0xffff < $port) {
+ throw new \InvalidArgumentException(
+ sprintf('Invalid port: %d. Must be between 1 and 65535', $port)
+ );
+ }
+
+ return $port;
+ }
+
+ private function removeDefaultPort()
+ {
+ if ($this->port !== null && self::isDefaultPort($this)) {
+ $this->port = null;
+ }
+ }
+
+ /**
+ * Filters the path of a URI
+ *
+ * @param string $path
+ *
+ * @return string
+ *
+ * @throws \InvalidArgumentException If the path is invalid.
+ */
+ private function filterPath($path)
+ {
+ if (!is_string($path)) {
+ throw new \InvalidArgumentException('Path must be a string');
+ }
+
+ return preg_replace_callback(
+ '/(?:[^' . self::$charUnreserved . self::$charSubDelims . '%:@\/]++|%(?![A-Fa-f0-9]{2}))/',
+ [$this, 'rawurlencodeMatchZero'],
+ $path
+ );
+ }
+
+ /**
+ * Filters the query string or fragment of a URI.
+ *
+ * @param string $str
+ *
+ * @return string
+ *
+ * @throws \InvalidArgumentException If the query or fragment is invalid.
+ */
+ private function filterQueryAndFragment($str)
+ {
+ if (!is_string($str)) {
+ throw new \InvalidArgumentException('Query and fragment must be a string');
+ }
+
+ return preg_replace_callback(
+ '/(?:[^' . self::$charUnreserved . self::$charSubDelims . '%:@\/\?]++|%(?![A-Fa-f0-9]{2}))/',
+ [$this, 'rawurlencodeMatchZero'],
+ $str
+ );
+ }
+
+ private function rawurlencodeMatchZero(array $match)
+ {
+ return rawurlencode($match[0]);
+ }
+
+ private function validateState()
+ {
+ if ($this->host === '' && ($this->scheme === 'http' || $this->scheme === 'https')) {
+ $this->host = self::HTTP_DEFAULT_HOST;
+ }
+
+ if ($this->getAuthority() === '') {
+ if (0 === strpos($this->path, '//')) {
+ throw new \InvalidArgumentException('The path of a URI without an authority must not start with two slashes "//"');
+ }
+ if ($this->scheme === '' && false !== strpos(explode('/', $this->path, 2)[0], ':')) {
+ throw new \InvalidArgumentException('A relative URI must not have a path beginning with a segment containing a colon');
+ }
+ } elseif (isset($this->path[0]) && $this->path[0] !== '/') {
+ @trigger_error(
+ 'The path of a URI with an authority must start with a slash "/" or be empty. Automagically fixing the URI ' .
+ 'by adding a leading slash to the path is deprecated since version 1.4 and will throw an exception instead.',
+ E_USER_DEPRECATED
+ );
+ $this->path = '/'. $this->path;
+ //throw new \InvalidArgumentException('The path of a URI with an authority must start with a slash "/" or be empty');
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/UriNormalizer.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/UriNormalizer.php
new file mode 100644
index 0000000..384c29e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/UriNormalizer.php
@@ -0,0 +1,216 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\UriInterface;
+
+/**
+ * Provides methods to normalize and compare URIs.
+ *
+ * @author Tobias Schultze
+ *
+ * @link https://tools.ietf.org/html/rfc3986#section-6
+ */
+final class UriNormalizer
+{
+ /**
+ * Default normalizations which only include the ones that preserve semantics.
+ *
+ * self::CAPITALIZE_PERCENT_ENCODING | self::DECODE_UNRESERVED_CHARACTERS | self::CONVERT_EMPTY_PATH |
+ * self::REMOVE_DEFAULT_HOST | self::REMOVE_DEFAULT_PORT | self::REMOVE_DOT_SEGMENTS
+ */
+ const PRESERVING_NORMALIZATIONS = 63;
+
+ /**
+ * All letters within a percent-encoding triplet (e.g., "%3A") are case-insensitive, and should be capitalized.
+ *
+ * Example: http://example.org/a%c2%b1b → http://example.org/a%C2%B1b
+ */
+ const CAPITALIZE_PERCENT_ENCODING = 1;
+
+ /**
+ * Decodes percent-encoded octets of unreserved characters.
+ *
+ * For consistency, percent-encoded octets in the ranges of ALPHA (%41–%5A and %61–%7A), DIGIT (%30–%39),
+ * hyphen (%2D), period (%2E), underscore (%5F), or tilde (%7E) should not be created by URI producers and,
+ * when found in a URI, should be decoded to their corresponding unreserved characters by URI normalizers.
+ *
+ * Example: http://example.org/%7Eusern%61me/ → http://example.org/~username/
+ */
+ const DECODE_UNRESERVED_CHARACTERS = 2;
+
+ /**
+ * Converts the empty path to "/" for http and https URIs.
+ *
+ * Example: http://example.org → http://example.org/
+ */
+ const CONVERT_EMPTY_PATH = 4;
+
+ /**
+ * Removes the default host of the given URI scheme from the URI.
+ *
+ * Only the "file" scheme defines the default host "localhost".
+ * All of `file:/myfile`, `file:///myfile`, and `file://localhost/myfile`
+ * are equivalent according to RFC 3986. The first format is not accepted
+ * by PHPs stream functions and thus already normalized implicitly to the
+ * second format in the Uri class. See `GuzzleHttp\Psr7\Uri::composeComponents`.
+ *
+ * Example: file://localhost/myfile → file:///myfile
+ */
+ const REMOVE_DEFAULT_HOST = 8;
+
+ /**
+ * Removes the default port of the given URI scheme from the URI.
+ *
+ * Example: http://example.org:80/ → http://example.org/
+ */
+ const REMOVE_DEFAULT_PORT = 16;
+
+ /**
+ * Removes unnecessary dot-segments.
+ *
+ * Dot-segments in relative-path references are not removed as it would
+ * change the semantics of the URI reference.
+ *
+ * Example: http://example.org/../a/b/../c/./d.html → http://example.org/a/c/d.html
+ */
+ const REMOVE_DOT_SEGMENTS = 32;
+
+ /**
+ * Paths which include two or more adjacent slashes are converted to one.
+ *
+ * Webservers usually ignore duplicate slashes and treat those URIs equivalent.
+ * But in theory those URIs do not need to be equivalent. So this normalization
+ * may change the semantics. Encoded slashes (%2F) are not removed.
+ *
+ * Example: http://example.org//foo///bar.html → http://example.org/foo/bar.html
+ */
+ const REMOVE_DUPLICATE_SLASHES = 64;
+
+ /**
+ * Sort query parameters with their values in alphabetical order.
+ *
+ * However, the order of parameters in a URI may be significant (this is not defined by the standard).
+ * So this normalization is not safe and may change the semantics of the URI.
+ *
+ * Example: ?lang=en&article=fred → ?article=fred&lang=en
+ *
+ * Note: The sorting is neither locale nor Unicode aware (the URI query does not get decoded at all) as the
+ * purpose is to be able to compare URIs in a reproducible way, not to have the params sorted perfectly.
+ */
+ const SORT_QUERY_PARAMETERS = 128;
+
+ /**
+ * Returns a normalized URI.
+ *
+ * The scheme and host component are already normalized to lowercase per PSR-7 UriInterface.
+ * This methods adds additional normalizations that can be configured with the $flags parameter.
+ *
+ * PSR-7 UriInterface cannot distinguish between an empty component and a missing component as
+ * getQuery(), getFragment() etc. always return a string. This means the URIs "/?#" and "/" are
+ * treated equivalent which is not necessarily true according to RFC 3986. But that difference
+ * is highly uncommon in reality. So this potential normalization is implied in PSR-7 as well.
+ *
+ * @param UriInterface $uri The URI to normalize
+ * @param int $flags A bitmask of normalizations to apply, see constants
+ *
+ * @return UriInterface The normalized URI
+ * @link https://tools.ietf.org/html/rfc3986#section-6.2
+ */
+ public static function normalize(UriInterface $uri, $flags = self::PRESERVING_NORMALIZATIONS)
+ {
+ if ($flags & self::CAPITALIZE_PERCENT_ENCODING) {
+ $uri = self::capitalizePercentEncoding($uri);
+ }
+
+ if ($flags & self::DECODE_UNRESERVED_CHARACTERS) {
+ $uri = self::decodeUnreservedCharacters($uri);
+ }
+
+ if ($flags & self::CONVERT_EMPTY_PATH && $uri->getPath() === '' &&
+ ($uri->getScheme() === 'http' || $uri->getScheme() === 'https')
+ ) {
+ $uri = $uri->withPath('/');
+ }
+
+ if ($flags & self::REMOVE_DEFAULT_HOST && $uri->getScheme() === 'file' && $uri->getHost() === 'localhost') {
+ $uri = $uri->withHost('');
+ }
+
+ if ($flags & self::REMOVE_DEFAULT_PORT && $uri->getPort() !== null && Uri::isDefaultPort($uri)) {
+ $uri = $uri->withPort(null);
+ }
+
+ if ($flags & self::REMOVE_DOT_SEGMENTS && !Uri::isRelativePathReference($uri)) {
+ $uri = $uri->withPath(UriResolver::removeDotSegments($uri->getPath()));
+ }
+
+ if ($flags & self::REMOVE_DUPLICATE_SLASHES) {
+ $uri = $uri->withPath(preg_replace('#//++#', '/', $uri->getPath()));
+ }
+
+ if ($flags & self::SORT_QUERY_PARAMETERS && $uri->getQuery() !== '') {
+ $queryKeyValues = explode('&', $uri->getQuery());
+ sort($queryKeyValues);
+ $uri = $uri->withQuery(implode('&', $queryKeyValues));
+ }
+
+ return $uri;
+ }
+
+ /**
+ * Whether two URIs can be considered equivalent.
+ *
+ * Both URIs are normalized automatically before comparison with the given $normalizations bitmask. The method also
+ * accepts relative URI references and returns true when they are equivalent. This of course assumes they will be
+ * resolved against the same base URI. If this is not the case, determination of equivalence or difference of
+ * relative references does not mean anything.
+ *
+ * @param UriInterface $uri1 An URI to compare
+ * @param UriInterface $uri2 An URI to compare
+ * @param int $normalizations A bitmask of normalizations to apply, see constants
+ *
+ * @return bool
+ * @link https://tools.ietf.org/html/rfc3986#section-6.1
+ */
+ public static function isEquivalent(UriInterface $uri1, UriInterface $uri2, $normalizations = self::PRESERVING_NORMALIZATIONS)
+ {
+ return (string) self::normalize($uri1, $normalizations) === (string) self::normalize($uri2, $normalizations);
+ }
+
+ private static function capitalizePercentEncoding(UriInterface $uri)
+ {
+ $regex = '/(?:%[A-Fa-f0-9]{2})++/';
+
+ $callback = function (array $match) {
+ return strtoupper($match[0]);
+ };
+
+ return
+ $uri->withPath(
+ preg_replace_callback($regex, $callback, $uri->getPath())
+ )->withQuery(
+ preg_replace_callback($regex, $callback, $uri->getQuery())
+ );
+ }
+
+ private static function decodeUnreservedCharacters(UriInterface $uri)
+ {
+ $regex = '/%(?:2D|2E|5F|7E|3[0-9]|[46][1-9A-F]|[57][0-9A])/i';
+
+ $callback = function (array $match) {
+ return rawurldecode($match[0]);
+ };
+
+ return
+ $uri->withPath(
+ preg_replace_callback($regex, $callback, $uri->getPath())
+ )->withQuery(
+ preg_replace_callback($regex, $callback, $uri->getQuery())
+ );
+ }
+
+ private function __construct()
+ {
+ // cannot be instantiated
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/UriResolver.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/UriResolver.php
new file mode 100644
index 0000000..c1cb8a2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/UriResolver.php
@@ -0,0 +1,219 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\UriInterface;
+
+/**
+ * Resolves a URI reference in the context of a base URI and the opposite way.
+ *
+ * @author Tobias Schultze
+ *
+ * @link https://tools.ietf.org/html/rfc3986#section-5
+ */
+final class UriResolver
+{
+ /**
+ * Removes dot segments from a path and returns the new path.
+ *
+ * @param string $path
+ *
+ * @return string
+ * @link http://tools.ietf.org/html/rfc3986#section-5.2.4
+ */
+ public static function removeDotSegments($path)
+ {
+ if ($path === '' || $path === '/') {
+ return $path;
+ }
+
+ $results = [];
+ $segments = explode('/', $path);
+ foreach ($segments as $segment) {
+ if ($segment === '..') {
+ array_pop($results);
+ } elseif ($segment !== '.') {
+ $results[] = $segment;
+ }
+ }
+
+ $newPath = implode('/', $results);
+
+ if ($path[0] === '/' && (!isset($newPath[0]) || $newPath[0] !== '/')) {
+ // Re-add the leading slash if necessary for cases like "/.."
+ $newPath = '/' . $newPath;
+ } elseif ($newPath !== '' && ($segment === '.' || $segment === '..')) {
+ // Add the trailing slash if necessary
+ // If newPath is not empty, then $segment must be set and is the last segment from the foreach
+ $newPath .= '/';
+ }
+
+ return $newPath;
+ }
+
+ /**
+ * Converts the relative URI into a new URI that is resolved against the base URI.
+ *
+ * @param UriInterface $base Base URI
+ * @param UriInterface $rel Relative URI
+ *
+ * @return UriInterface
+ * @link http://tools.ietf.org/html/rfc3986#section-5.2
+ */
+ public static function resolve(UriInterface $base, UriInterface $rel)
+ {
+ if ((string) $rel === '') {
+ // we can simply return the same base URI instance for this same-document reference
+ return $base;
+ }
+
+ if ($rel->getScheme() != '') {
+ return $rel->withPath(self::removeDotSegments($rel->getPath()));
+ }
+
+ if ($rel->getAuthority() != '') {
+ $targetAuthority = $rel->getAuthority();
+ $targetPath = self::removeDotSegments($rel->getPath());
+ $targetQuery = $rel->getQuery();
+ } else {
+ $targetAuthority = $base->getAuthority();
+ if ($rel->getPath() === '') {
+ $targetPath = $base->getPath();
+ $targetQuery = $rel->getQuery() != '' ? $rel->getQuery() : $base->getQuery();
+ } else {
+ if ($rel->getPath()[0] === '/') {
+ $targetPath = $rel->getPath();
+ } else {
+ if ($targetAuthority != '' && $base->getPath() === '') {
+ $targetPath = '/' . $rel->getPath();
+ } else {
+ $lastSlashPos = strrpos($base->getPath(), '/');
+ if ($lastSlashPos === false) {
+ $targetPath = $rel->getPath();
+ } else {
+ $targetPath = substr($base->getPath(), 0, $lastSlashPos + 1) . $rel->getPath();
+ }
+ }
+ }
+ $targetPath = self::removeDotSegments($targetPath);
+ $targetQuery = $rel->getQuery();
+ }
+ }
+
+ return new Uri(Uri::composeComponents(
+ $base->getScheme(),
+ $targetAuthority,
+ $targetPath,
+ $targetQuery,
+ $rel->getFragment()
+ ));
+ }
+
+ /**
+ * Returns the target URI as a relative reference from the base URI.
+ *
+ * This method is the counterpart to resolve():
+ *
+ * (string) $target === (string) UriResolver::resolve($base, UriResolver::relativize($base, $target))
+ *
+ * One use-case is to use the current request URI as base URI and then generate relative links in your documents
+ * to reduce the document size or offer self-contained downloadable document archives.
+ *
+ * $base = new Uri('http://example.com/a/b/');
+ * echo UriResolver::relativize($base, new Uri('http://example.com/a/b/c')); // prints 'c'.
+ * echo UriResolver::relativize($base, new Uri('http://example.com/a/x/y')); // prints '../x/y'.
+ * echo UriResolver::relativize($base, new Uri('http://example.com/a/b/?q')); // prints '?q'.
+ * echo UriResolver::relativize($base, new Uri('http://example.org/a/b/')); // prints '//example.org/a/b/'.
+ *
+ * This method also accepts a target that is already relative and will try to relativize it further. Only a
+ * relative-path reference will be returned as-is.
+ *
+ * echo UriResolver::relativize($base, new Uri('/a/b/c')); // prints 'c' as well
+ *
+ * @param UriInterface $base Base URI
+ * @param UriInterface $target Target URI
+ *
+ * @return UriInterface The relative URI reference
+ */
+ public static function relativize(UriInterface $base, UriInterface $target)
+ {
+ if ($target->getScheme() !== '' &&
+ ($base->getScheme() !== $target->getScheme() || $target->getAuthority() === '' && $base->getAuthority() !== '')
+ ) {
+ return $target;
+ }
+
+ if (Uri::isRelativePathReference($target)) {
+ // As the target is already highly relative we return it as-is. It would be possible to resolve
+ // the target with `$target = self::resolve($base, $target);` and then try make it more relative
+ // by removing a duplicate query. But let's not do that automatically.
+ return $target;
+ }
+
+ if ($target->getAuthority() !== '' && $base->getAuthority() !== $target->getAuthority()) {
+ return $target->withScheme('');
+ }
+
+ // We must remove the path before removing the authority because if the path starts with two slashes, the URI
+ // would turn invalid. And we also cannot set a relative path before removing the authority, as that is also
+ // invalid.
+ $emptyPathUri = $target->withScheme('')->withPath('')->withUserInfo('')->withPort(null)->withHost('');
+
+ if ($base->getPath() !== $target->getPath()) {
+ return $emptyPathUri->withPath(self::getRelativePath($base, $target));
+ }
+
+ if ($base->getQuery() === $target->getQuery()) {
+ // Only the target fragment is left. And it must be returned even if base and target fragment are the same.
+ return $emptyPathUri->withQuery('');
+ }
+
+ // If the base URI has a query but the target has none, we cannot return an empty path reference as it would
+ // inherit the base query component when resolving.
+ if ($target->getQuery() === '') {
+ $segments = explode('/', $target->getPath());
+ $lastSegment = end($segments);
+
+ return $emptyPathUri->withPath($lastSegment === '' ? './' : $lastSegment);
+ }
+
+ return $emptyPathUri;
+ }
+
+ private static function getRelativePath(UriInterface $base, UriInterface $target)
+ {
+ $sourceSegments = explode('/', $base->getPath());
+ $targetSegments = explode('/', $target->getPath());
+ array_pop($sourceSegments);
+ $targetLastSegment = array_pop($targetSegments);
+ foreach ($sourceSegments as $i => $segment) {
+ if (isset($targetSegments[$i]) && $segment === $targetSegments[$i]) {
+ unset($sourceSegments[$i], $targetSegments[$i]);
+ } else {
+ break;
+ }
+ }
+ $targetSegments[] = $targetLastSegment;
+ $relativePath = str_repeat('../', count($sourceSegments)) . implode('/', $targetSegments);
+
+ // A reference to am empty last segment or an empty first sub-segment must be prefixed with "./".
+ // This also applies to a segment with a colon character (e.g., "file:colon") that cannot be used
+ // as the first segment of a relative-path reference, as it would be mistaken for a scheme name.
+ if ('' === $relativePath || false !== strpos(explode('/', $relativePath, 2)[0], ':')) {
+ $relativePath = "./$relativePath";
+ } elseif ('/' === $relativePath[0]) {
+ if ($base->getAuthority() != '' && $base->getPath() === '') {
+ // In this case an extra slash is added by resolve() automatically. So we must not add one here.
+ $relativePath = ".$relativePath";
+ } else {
+ $relativePath = "./$relativePath";
+ }
+ }
+
+ return $relativePath;
+ }
+
+ private function __construct()
+ {
+ // cannot be instantiated
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/functions.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/functions.php
new file mode 100644
index 0000000..e40348d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/functions.php
@@ -0,0 +1,828 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\MessageInterface;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Message\StreamInterface;
+use Psr\Http\Message\UriInterface;
+
+/**
+ * Returns the string representation of an HTTP message.
+ *
+ * @param MessageInterface $message Message to convert to a string.
+ *
+ * @return string
+ */
+function str(MessageInterface $message)
+{
+ if ($message instanceof RequestInterface) {
+ $msg = trim($message->getMethod() . ' '
+ . $message->getRequestTarget())
+ . ' HTTP/' . $message->getProtocolVersion();
+ if (!$message->hasHeader('host')) {
+ $msg .= "\r\nHost: " . $message->getUri()->getHost();
+ }
+ } elseif ($message instanceof ResponseInterface) {
+ $msg = 'HTTP/' . $message->getProtocolVersion() . ' '
+ . $message->getStatusCode() . ' '
+ . $message->getReasonPhrase();
+ } else {
+ throw new \InvalidArgumentException('Unknown message type');
+ }
+
+ foreach ($message->getHeaders() as $name => $values) {
+ $msg .= "\r\n{$name}: " . implode(', ', $values);
+ }
+
+ return "{$msg}\r\n\r\n" . $message->getBody();
+}
+
+/**
+ * Returns a UriInterface for the given value.
+ *
+ * This function accepts a string or {@see Psr\Http\Message\UriInterface} and
+ * returns a UriInterface for the given value. If the value is already a
+ * `UriInterface`, it is returned as-is.
+ *
+ * @param string|UriInterface $uri
+ *
+ * @return UriInterface
+ * @throws \InvalidArgumentException
+ */
+function uri_for($uri)
+{
+ if ($uri instanceof UriInterface) {
+ return $uri;
+ } elseif (is_string($uri)) {
+ return new Uri($uri);
+ }
+
+ throw new \InvalidArgumentException('URI must be a string or UriInterface');
+}
+
+/**
+ * Create a new stream based on the input type.
+ *
+ * Options is an associative array that can contain the following keys:
+ * - metadata: Array of custom metadata.
+ * - size: Size of the stream.
+ *
+ * @param resource|string|null|int|float|bool|StreamInterface|callable $resource Entity body data
+ * @param array $options Additional options
+ *
+ * @return Stream
+ * @throws \InvalidArgumentException if the $resource arg is not valid.
+ */
+function stream_for($resource = '', array $options = [])
+{
+ if (is_scalar($resource)) {
+ $stream = fopen('php://temp', 'r+');
+ if ($resource !== '') {
+ fwrite($stream, $resource);
+ fseek($stream, 0);
+ }
+ return new Stream($stream, $options);
+ }
+
+ switch (gettype($resource)) {
+ case 'resource':
+ return new Stream($resource, $options);
+ case 'object':
+ if ($resource instanceof StreamInterface) {
+ return $resource;
+ } elseif ($resource instanceof \Iterator) {
+ return new PumpStream(function () use ($resource) {
+ if (!$resource->valid()) {
+ return false;
+ }
+ $result = $resource->current();
+ $resource->next();
+ return $result;
+ }, $options);
+ } elseif (method_exists($resource, '__toString')) {
+ return stream_for((string) $resource, $options);
+ }
+ break;
+ case 'NULL':
+ return new Stream(fopen('php://temp', 'r+'), $options);
+ }
+
+ if (is_callable($resource)) {
+ return new PumpStream($resource, $options);
+ }
+
+ throw new \InvalidArgumentException('Invalid resource type: ' . gettype($resource));
+}
+
+/**
+ * Parse an array of header values containing ";" separated data into an
+ * array of associative arrays representing the header key value pair
+ * data of the header. When a parameter does not contain a value, but just
+ * contains a key, this function will inject a key with a '' string value.
+ *
+ * @param string|array $header Header to parse into components.
+ *
+ * @return array Returns the parsed header values.
+ */
+function parse_header($header)
+{
+ static $trimmed = "\"' \n\t\r";
+ $params = $matches = [];
+
+ foreach (normalize_header($header) as $val) {
+ $part = [];
+ foreach (preg_split('/;(?=([^"]*"[^"]*")*[^"]*$)/', $val) as $kvp) {
+ if (preg_match_all('/<[^>]+>|[^=]+/', $kvp, $matches)) {
+ $m = $matches[0];
+ if (isset($m[1])) {
+ $part[trim($m[0], $trimmed)] = trim($m[1], $trimmed);
+ } else {
+ $part[] = trim($m[0], $trimmed);
+ }
+ }
+ }
+ if ($part) {
+ $params[] = $part;
+ }
+ }
+
+ return $params;
+}
+
+/**
+ * Converts an array of header values that may contain comma separated
+ * headers into an array of headers with no comma separated values.
+ *
+ * @param string|array $header Header to normalize.
+ *
+ * @return array Returns the normalized header field values.
+ */
+function normalize_header($header)
+{
+ if (!is_array($header)) {
+ return array_map('trim', explode(',', $header));
+ }
+
+ $result = [];
+ foreach ($header as $value) {
+ foreach ((array) $value as $v) {
+ if (strpos($v, ',') === false) {
+ $result[] = $v;
+ continue;
+ }
+ foreach (preg_split('/,(?=([^"]*"[^"]*")*[^"]*$)/', $v) as $vv) {
+ $result[] = trim($vv);
+ }
+ }
+ }
+
+ return $result;
+}
+
+/**
+ * Clone and modify a request with the given changes.
+ *
+ * The changes can be one of:
+ * - method: (string) Changes the HTTP method.
+ * - set_headers: (array) Sets the given headers.
+ * - remove_headers: (array) Remove the given headers.
+ * - body: (mixed) Sets the given body.
+ * - uri: (UriInterface) Set the URI.
+ * - query: (string) Set the query string value of the URI.
+ * - version: (string) Set the protocol version.
+ *
+ * @param RequestInterface $request Request to clone and modify.
+ * @param array $changes Changes to apply.
+ *
+ * @return RequestInterface
+ */
+function modify_request(RequestInterface $request, array $changes)
+{
+ if (!$changes) {
+ return $request;
+ }
+
+ $headers = $request->getHeaders();
+
+ if (!isset($changes['uri'])) {
+ $uri = $request->getUri();
+ } else {
+ // Remove the host header if one is on the URI
+ if ($host = $changes['uri']->getHost()) {
+ $changes['set_headers']['Host'] = $host;
+
+ if ($port = $changes['uri']->getPort()) {
+ $standardPorts = ['http' => 80, 'https' => 443];
+ $scheme = $changes['uri']->getScheme();
+ if (isset($standardPorts[$scheme]) && $port != $standardPorts[$scheme]) {
+ $changes['set_headers']['Host'] .= ':'.$port;
+ }
+ }
+ }
+ $uri = $changes['uri'];
+ }
+
+ if (!empty($changes['remove_headers'])) {
+ $headers = _caseless_remove($changes['remove_headers'], $headers);
+ }
+
+ if (!empty($changes['set_headers'])) {
+ $headers = _caseless_remove(array_keys($changes['set_headers']), $headers);
+ $headers = $changes['set_headers'] + $headers;
+ }
+
+ if (isset($changes['query'])) {
+ $uri = $uri->withQuery($changes['query']);
+ }
+
+ if ($request instanceof ServerRequestInterface) {
+ return new ServerRequest(
+ isset($changes['method']) ? $changes['method'] : $request->getMethod(),
+ $uri,
+ $headers,
+ isset($changes['body']) ? $changes['body'] : $request->getBody(),
+ isset($changes['version'])
+ ? $changes['version']
+ : $request->getProtocolVersion(),
+ $request->getServerParams()
+ );
+ }
+
+ return new Request(
+ isset($changes['method']) ? $changes['method'] : $request->getMethod(),
+ $uri,
+ $headers,
+ isset($changes['body']) ? $changes['body'] : $request->getBody(),
+ isset($changes['version'])
+ ? $changes['version']
+ : $request->getProtocolVersion()
+ );
+}
+
+/**
+ * Attempts to rewind a message body and throws an exception on failure.
+ *
+ * The body of the message will only be rewound if a call to `tell()` returns a
+ * value other than `0`.
+ *
+ * @param MessageInterface $message Message to rewind
+ *
+ * @throws \RuntimeException
+ */
+function rewind_body(MessageInterface $message)
+{
+ $body = $message->getBody();
+
+ if ($body->tell()) {
+ $body->rewind();
+ }
+}
+
+/**
+ * Safely opens a PHP stream resource using a filename.
+ *
+ * When fopen fails, PHP normally raises a warning. This function adds an
+ * error handler that checks for errors and throws an exception instead.
+ *
+ * @param string $filename File to open
+ * @param string $mode Mode used to open the file
+ *
+ * @return resource
+ * @throws \RuntimeException if the file cannot be opened
+ */
+function try_fopen($filename, $mode)
+{
+ $ex = null;
+ set_error_handler(function () use ($filename, $mode, &$ex) {
+ $ex = new \RuntimeException(sprintf(
+ 'Unable to open %s using mode %s: %s',
+ $filename,
+ $mode,
+ func_get_args()[1]
+ ));
+ });
+
+ $handle = fopen($filename, $mode);
+ restore_error_handler();
+
+ if ($ex) {
+ /** @var $ex \RuntimeException */
+ throw $ex;
+ }
+
+ return $handle;
+}
+
+/**
+ * Copy the contents of a stream into a string until the given number of
+ * bytes have been read.
+ *
+ * @param StreamInterface $stream Stream to read
+ * @param int $maxLen Maximum number of bytes to read. Pass -1
+ * to read the entire stream.
+ * @return string
+ * @throws \RuntimeException on error.
+ */
+function copy_to_string(StreamInterface $stream, $maxLen = -1)
+{
+ $buffer = '';
+
+ if ($maxLen === -1) {
+ while (!$stream->eof()) {
+ $buf = $stream->read(1048576);
+ // Using a loose equality here to match on '' and false.
+ if ($buf == null) {
+ break;
+ }
+ $buffer .= $buf;
+ }
+ return $buffer;
+ }
+
+ $len = 0;
+ while (!$stream->eof() && $len < $maxLen) {
+ $buf = $stream->read($maxLen - $len);
+ // Using a loose equality here to match on '' and false.
+ if ($buf == null) {
+ break;
+ }
+ $buffer .= $buf;
+ $len = strlen($buffer);
+ }
+
+ return $buffer;
+}
+
+/**
+ * Copy the contents of a stream into another stream until the given number
+ * of bytes have been read.
+ *
+ * @param StreamInterface $source Stream to read from
+ * @param StreamInterface $dest Stream to write to
+ * @param int $maxLen Maximum number of bytes to read. Pass -1
+ * to read the entire stream.
+ *
+ * @throws \RuntimeException on error.
+ */
+function copy_to_stream(
+ StreamInterface $source,
+ StreamInterface $dest,
+ $maxLen = -1
+) {
+ $bufferSize = 8192;
+
+ if ($maxLen === -1) {
+ while (!$source->eof()) {
+ if (!$dest->write($source->read($bufferSize))) {
+ break;
+ }
+ }
+ } else {
+ $remaining = $maxLen;
+ while ($remaining > 0 && !$source->eof()) {
+ $buf = $source->read(min($bufferSize, $remaining));
+ $len = strlen($buf);
+ if (!$len) {
+ break;
+ }
+ $remaining -= $len;
+ $dest->write($buf);
+ }
+ }
+}
+
+/**
+ * Calculate a hash of a Stream
+ *
+ * @param StreamInterface $stream Stream to calculate the hash for
+ * @param string $algo Hash algorithm (e.g. md5, crc32, etc)
+ * @param bool $rawOutput Whether or not to use raw output
+ *
+ * @return string Returns the hash of the stream
+ * @throws \RuntimeException on error.
+ */
+function hash(
+ StreamInterface $stream,
+ $algo,
+ $rawOutput = false
+) {
+ $pos = $stream->tell();
+
+ if ($pos > 0) {
+ $stream->rewind();
+ }
+
+ $ctx = hash_init($algo);
+ while (!$stream->eof()) {
+ hash_update($ctx, $stream->read(1048576));
+ }
+
+ $out = hash_final($ctx, (bool) $rawOutput);
+ $stream->seek($pos);
+
+ return $out;
+}
+
+/**
+ * Read a line from the stream up to the maximum allowed buffer length
+ *
+ * @param StreamInterface $stream Stream to read from
+ * @param int $maxLength Maximum buffer length
+ *
+ * @return string|bool
+ */
+function readline(StreamInterface $stream, $maxLength = null)
+{
+ $buffer = '';
+ $size = 0;
+
+ while (!$stream->eof()) {
+ // Using a loose equality here to match on '' and false.
+ if (null == ($byte = $stream->read(1))) {
+ return $buffer;
+ }
+ $buffer .= $byte;
+ // Break when a new line is found or the max length - 1 is reached
+ if ($byte === "\n" || ++$size === $maxLength - 1) {
+ break;
+ }
+ }
+
+ return $buffer;
+}
+
+/**
+ * Parses a request message string into a request object.
+ *
+ * @param string $message Request message string.
+ *
+ * @return Request
+ */
+function parse_request($message)
+{
+ $data = _parse_message($message);
+ $matches = [];
+ if (!preg_match('/^[\S]+\s+([a-zA-Z]+:\/\/|\/).*/', $data['start-line'], $matches)) {
+ throw new \InvalidArgumentException('Invalid request string');
+ }
+ $parts = explode(' ', $data['start-line'], 3);
+ $version = isset($parts[2]) ? explode('/', $parts[2])[1] : '1.1';
+
+ $request = new Request(
+ $parts[0],
+ $matches[1] === '/' ? _parse_request_uri($parts[1], $data['headers']) : $parts[1],
+ $data['headers'],
+ $data['body'],
+ $version
+ );
+
+ return $matches[1] === '/' ? $request : $request->withRequestTarget($parts[1]);
+}
+
+/**
+ * Parses a response message string into a response object.
+ *
+ * @param string $message Response message string.
+ *
+ * @return Response
+ */
+function parse_response($message)
+{
+ $data = _parse_message($message);
+ // According to https://tools.ietf.org/html/rfc7230#section-3.1.2 the space
+ // between status-code and reason-phrase is required. But browsers accept
+ // responses without space and reason as well.
+ if (!preg_match('/^HTTP\/.* [0-9]{3}( .*|$)/', $data['start-line'])) {
+ throw new \InvalidArgumentException('Invalid response string');
+ }
+ $parts = explode(' ', $data['start-line'], 3);
+
+ return new Response(
+ $parts[1],
+ $data['headers'],
+ $data['body'],
+ explode('/', $parts[0])[1],
+ isset($parts[2]) ? $parts[2] : null
+ );
+}
+
+/**
+ * Parse a query string into an associative array.
+ *
+ * If multiple values are found for the same key, the value of that key
+ * value pair will become an array. This function does not parse nested
+ * PHP style arrays into an associative array (e.g., foo[a]=1&foo[b]=2 will
+ * be parsed into ['foo[a]' => '1', 'foo[b]' => '2']).
+ *
+ * @param string $str Query string to parse
+ * @param bool|string $urlEncoding How the query string is encoded
+ *
+ * @return array
+ */
+function parse_query($str, $urlEncoding = true)
+{
+ $result = [];
+
+ if ($str === '') {
+ return $result;
+ }
+
+ if ($urlEncoding === true) {
+ $decoder = function ($value) {
+ return rawurldecode(str_replace('+', ' ', $value));
+ };
+ } elseif ($urlEncoding == PHP_QUERY_RFC3986) {
+ $decoder = 'rawurldecode';
+ } elseif ($urlEncoding == PHP_QUERY_RFC1738) {
+ $decoder = 'urldecode';
+ } else {
+ $decoder = function ($str) { return $str; };
+ }
+
+ foreach (explode('&', $str) as $kvp) {
+ $parts = explode('=', $kvp, 2);
+ $key = $decoder($parts[0]);
+ $value = isset($parts[1]) ? $decoder($parts[1]) : null;
+ if (!isset($result[$key])) {
+ $result[$key] = $value;
+ } else {
+ if (!is_array($result[$key])) {
+ $result[$key] = [$result[$key]];
+ }
+ $result[$key][] = $value;
+ }
+ }
+
+ return $result;
+}
+
+/**
+ * Build a query string from an array of key value pairs.
+ *
+ * This function can use the return value of parse_query() to build a query
+ * string. This function does not modify the provided keys when an array is
+ * encountered (like http_build_query would).
+ *
+ * @param array $params Query string parameters.
+ * @param int|false $encoding Set to false to not encode, PHP_QUERY_RFC3986
+ * to encode using RFC3986, or PHP_QUERY_RFC1738
+ * to encode using RFC1738.
+ * @return string
+ */
+function build_query(array $params, $encoding = PHP_QUERY_RFC3986)
+{
+ if (!$params) {
+ return '';
+ }
+
+ if ($encoding === false) {
+ $encoder = function ($str) { return $str; };
+ } elseif ($encoding === PHP_QUERY_RFC3986) {
+ $encoder = 'rawurlencode';
+ } elseif ($encoding === PHP_QUERY_RFC1738) {
+ $encoder = 'urlencode';
+ } else {
+ throw new \InvalidArgumentException('Invalid type');
+ }
+
+ $qs = '';
+ foreach ($params as $k => $v) {
+ $k = $encoder($k);
+ if (!is_array($v)) {
+ $qs .= $k;
+ if ($v !== null) {
+ $qs .= '=' . $encoder($v);
+ }
+ $qs .= '&';
+ } else {
+ foreach ($v as $vv) {
+ $qs .= $k;
+ if ($vv !== null) {
+ $qs .= '=' . $encoder($vv);
+ }
+ $qs .= '&';
+ }
+ }
+ }
+
+ return $qs ? (string) substr($qs, 0, -1) : '';
+}
+
+/**
+ * Determines the mimetype of a file by looking at its extension.
+ *
+ * @param $filename
+ *
+ * @return null|string
+ */
+function mimetype_from_filename($filename)
+{
+ return mimetype_from_extension(pathinfo($filename, PATHINFO_EXTENSION));
+}
+
+/**
+ * Maps a file extensions to a mimetype.
+ *
+ * @param $extension string The file extension.
+ *
+ * @return string|null
+ * @link http://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x/conf/mime.types
+ */
+function mimetype_from_extension($extension)
+{
+ static $mimetypes = [
+ '7z' => 'application/x-7z-compressed',
+ 'aac' => 'audio/x-aac',
+ 'ai' => 'application/postscript',
+ 'aif' => 'audio/x-aiff',
+ 'asc' => 'text/plain',
+ 'asf' => 'video/x-ms-asf',
+ 'atom' => 'application/atom+xml',
+ 'avi' => 'video/x-msvideo',
+ 'bmp' => 'image/bmp',
+ 'bz2' => 'application/x-bzip2',
+ 'cer' => 'application/pkix-cert',
+ 'crl' => 'application/pkix-crl',
+ 'crt' => 'application/x-x509-ca-cert',
+ 'css' => 'text/css',
+ 'csv' => 'text/csv',
+ 'cu' => 'application/cu-seeme',
+ 'deb' => 'application/x-debian-package',
+ 'doc' => 'application/msword',
+ 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+ 'dvi' => 'application/x-dvi',
+ 'eot' => 'application/vnd.ms-fontobject',
+ 'eps' => 'application/postscript',
+ 'epub' => 'application/epub+zip',
+ 'etx' => 'text/x-setext',
+ 'flac' => 'audio/flac',
+ 'flv' => 'video/x-flv',
+ 'gif' => 'image/gif',
+ 'gz' => 'application/gzip',
+ 'htm' => 'text/html',
+ 'html' => 'text/html',
+ 'ico' => 'image/x-icon',
+ 'ics' => 'text/calendar',
+ 'ini' => 'text/plain',
+ 'iso' => 'application/x-iso9660-image',
+ 'jar' => 'application/java-archive',
+ 'jpe' => 'image/jpeg',
+ 'jpeg' => 'image/jpeg',
+ 'jpg' => 'image/jpeg',
+ 'js' => 'text/javascript',
+ 'json' => 'application/json',
+ 'latex' => 'application/x-latex',
+ 'log' => 'text/plain',
+ 'm4a' => 'audio/mp4',
+ 'm4v' => 'video/mp4',
+ 'mid' => 'audio/midi',
+ 'midi' => 'audio/midi',
+ 'mov' => 'video/quicktime',
+ 'mp3' => 'audio/mpeg',
+ 'mp4' => 'video/mp4',
+ 'mp4a' => 'audio/mp4',
+ 'mp4v' => 'video/mp4',
+ 'mpe' => 'video/mpeg',
+ 'mpeg' => 'video/mpeg',
+ 'mpg' => 'video/mpeg',
+ 'mpg4' => 'video/mp4',
+ 'oga' => 'audio/ogg',
+ 'ogg' => 'audio/ogg',
+ 'ogv' => 'video/ogg',
+ 'ogx' => 'application/ogg',
+ 'pbm' => 'image/x-portable-bitmap',
+ 'pdf' => 'application/pdf',
+ 'pgm' => 'image/x-portable-graymap',
+ 'png' => 'image/png',
+ 'pnm' => 'image/x-portable-anymap',
+ 'ppm' => 'image/x-portable-pixmap',
+ 'ppt' => 'application/vnd.ms-powerpoint',
+ 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
+ 'ps' => 'application/postscript',
+ 'qt' => 'video/quicktime',
+ 'rar' => 'application/x-rar-compressed',
+ 'ras' => 'image/x-cmu-raster',
+ 'rss' => 'application/rss+xml',
+ 'rtf' => 'application/rtf',
+ 'sgm' => 'text/sgml',
+ 'sgml' => 'text/sgml',
+ 'svg' => 'image/svg+xml',
+ 'swf' => 'application/x-shockwave-flash',
+ 'tar' => 'application/x-tar',
+ 'tif' => 'image/tiff',
+ 'tiff' => 'image/tiff',
+ 'torrent' => 'application/x-bittorrent',
+ 'ttf' => 'application/x-font-ttf',
+ 'txt' => 'text/plain',
+ 'wav' => 'audio/x-wav',
+ 'webm' => 'video/webm',
+ 'wma' => 'audio/x-ms-wma',
+ 'wmv' => 'video/x-ms-wmv',
+ 'woff' => 'application/x-font-woff',
+ 'wsdl' => 'application/wsdl+xml',
+ 'xbm' => 'image/x-xbitmap',
+ 'xls' => 'application/vnd.ms-excel',
+ 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+ 'xml' => 'application/xml',
+ 'xpm' => 'image/x-xpixmap',
+ 'xwd' => 'image/x-xwindowdump',
+ 'yaml' => 'text/yaml',
+ 'yml' => 'text/yaml',
+ 'zip' => 'application/zip',
+ ];
+
+ $extension = strtolower($extension);
+
+ return isset($mimetypes[$extension])
+ ? $mimetypes[$extension]
+ : null;
+}
+
+/**
+ * Parses an HTTP message into an associative array.
+ *
+ * The array contains the "start-line" key containing the start line of
+ * the message, "headers" key containing an associative array of header
+ * array values, and a "body" key containing the body of the message.
+ *
+ * @param string $message HTTP request or response to parse.
+ *
+ * @return array
+ * @internal
+ */
+function _parse_message($message)
+{
+ if (!$message) {
+ throw new \InvalidArgumentException('Invalid message');
+ }
+
+ // Iterate over each line in the message, accounting for line endings
+ $lines = preg_split('/(\\r?\\n)/', $message, -1, PREG_SPLIT_DELIM_CAPTURE);
+ $result = ['start-line' => array_shift($lines), 'headers' => [], 'body' => ''];
+ array_shift($lines);
+
+ for ($i = 0, $totalLines = count($lines); $i < $totalLines; $i += 2) {
+ $line = $lines[$i];
+ // If two line breaks were encountered, then this is the end of body
+ if (empty($line)) {
+ if ($i < $totalLines - 1) {
+ $result['body'] = implode('', array_slice($lines, $i + 2));
+ }
+ break;
+ }
+ if (strpos($line, ':')) {
+ $parts = explode(':', $line, 2);
+ $key = trim($parts[0]);
+ $value = isset($parts[1]) ? trim($parts[1]) : '';
+ $result['headers'][$key][] = $value;
+ }
+ }
+
+ return $result;
+}
+
+/**
+ * Constructs a URI for an HTTP request message.
+ *
+ * @param string $path Path from the start-line
+ * @param array $headers Array of headers (each value an array).
+ *
+ * @return string
+ * @internal
+ */
+function _parse_request_uri($path, array $headers)
+{
+ $hostKey = array_filter(array_keys($headers), function ($k) {
+ return strtolower($k) === 'host';
+ });
+
+ // If no host is found, then a full URI cannot be constructed.
+ if (!$hostKey) {
+ return $path;
+ }
+
+ $host = $headers[reset($hostKey)][0];
+ $scheme = substr($host, -4) === ':443' ? 'https' : 'http';
+
+ return $scheme . '://' . $host . '/' . ltrim($path, '/');
+}
+
+/** @internal */
+function _caseless_remove($keys, array $data)
+{
+ $result = [];
+
+ foreach ($keys as &$key) {
+ $key = strtolower($key);
+ }
+
+ foreach ($data as $k => $v) {
+ if (!in_array(strtolower($k), $keys)) {
+ $result[$k] = $v;
+ }
+ }
+
+ return $result;
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/functions_include.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/functions_include.php
new file mode 100644
index 0000000..96a4a83
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/guzzlehttp/psr7/src/functions_include.php
@@ -0,0 +1,6 @@
+<?php
+
+// Don't redefine the functions if included multiple times.
+if (!function_exists('GuzzleHttp\Psr7\str')) {
+ require __DIR__ . '/functions.php';
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/CHANGELOG-1.0.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/CHANGELOG-1.0.md
new file mode 100644
index 0000000..f91a7e5
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/CHANGELOG-1.0.md
@@ -0,0 +1,36 @@
+1.0.4 (August 28, 2012)
+-----------------------
+
+ * Fixed the Twig tag to avoid a fatal error when left unclosed
+ * Added the HashableInterface for non-serialiable filters
+ * Fixed a bug for compass on windows
+
+1.0.3 (March 2, 2012)
+---------------------
+
+ * Added "boring" option to Compass filter
+ * Fixed accumulation of load paths in Compass filter
+ * Fixed issues in CssImport and CssRewrite filters
+
+1.0.2 (August 26, 2011)
+-----------------------
+
+ * Twig 1.2 compatibility
+ * Fixed filtering of large LessCSS assets
+ * Fixed escaping of commands on Windows
+ * Misc fixes to Compass filter
+ * Removed default CssEmbed charset
+
+1.0.1 (July 15, 2011)
+---------------------
+
+ * Fixed Twig error handling
+ * Removed use of STDIN
+ * Added inheritance of environment variables
+ * Fixed Compass on Windows
+ * Improved escaping of commands
+
+1.0.0 (July 10, 2011)
+---------------------
+
+ * Initial release
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/CHANGELOG-1.1.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/CHANGELOG-1.1.md
new file mode 100644
index 0000000..8bcf8bb
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/CHANGELOG-1.1.md
@@ -0,0 +1,57 @@
+1.1.2 (July 18, 2013)
+-------------------
+
+ * Fixed deep mtime on asset collections
+ * `CallablesFilter` now implements `DependencyExtractorInterface`
+ * Fixed detection of "partial" children in subfolders in `SassFilter`
+ * Restored `PathUtils` for BC
+
+1.1.1 (June 1, 2013)
+--------------------
+
+ * Fixed cloning of asset collections
+ * Fixed environment var inheritance
+ * Replaced `AssetWriter::getCombinations()` for BC, even though we don't use it
+ * Added support for `@import-once` to Less filters
+
+1.1.0 (May 15, 2013)
+--------------------
+
+ * Added LazyAssetManager::getLastModified() for determining "deep" mtime
+ * Added DartFilter
+ * Added EmberPrecompile
+ * Added GssFilter
+ * Added PhpCssEmbedFilter
+ * Added RooleFilter
+ * Added TypeScriptFilter
+ * Added the possibility to configure additional load paths for less and lessphp
+ * Added the UglifyCssFilter
+ * Fixed the handling of directories in the GlobAsset. #256
+ * Added Handlebars support
+ * Added Scssphp-compass support
+ * Added the CacheBustingWorker
+ * Added the UglifyJs2Filter
+
+1.1.0-alpha1 (August 28, 2012)
+------------------------------
+
+ * Added pure php css embed filter
+ * Added Scssphp support
+ * Added support for Google Closure language option
+ * Added a way to set a specific ruby path for CompassFilter and SassFilter
+ * Ensure uniqueness of temporary files created by the compressor filter. Fixed #61
+ * Added Compass option for generated_images_path (for generated Images/Sprites)
+ * Added PackerFilter
+ * Add the way to contact closure compiler API using curl, if available and allow_url_fopen is off
+ * Added filters for JSMin and JSMinPlus
+ * Added the UglifyJsFilter
+ * Improved the error message in getModifiedTime when a file asset uses an invalid file
+ * added support for asset variables:
+
+ Asset variables allow you to pre-compile your assets for a finite set of known
+ variable values, and then to simply deliver the correct asset version at runtime.
+ For example, this is helpful for assets with language, or browser-specific code.
+ * Removed the copy-paste of the Symfony2 Process component and use the original one
+ * Added ability to pass variables into lessphp filter
+ * Added google closure stylesheets jar filter
+ * Added the support of `--bare` for the CoffeeScriptFilter
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/CHANGELOG-1.2.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/CHANGELOG-1.2.md
new file mode 100644
index 0000000..e80b0ac
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/CHANGELOG-1.2.md
@@ -0,0 +1,49 @@
+1.2.0 (2014-10-14)
+------------------
+
+### New features
+
+* Added the autoprefixer filter
+* Added --no-header option for Coffeescript
+* Implemented the extraction of dependencies for the compass filter
+* Allow custom functions to be registered on the Lessphp filter
+* Added MinifyCssCompressor filter based on `mrclay/minify`
+* Added `setVariables` in the ScssPhpFilter
+* Improved the support of the compress options for UglifyJS2
+* Added CssCacheBustingFilter to apply cache busting on URLs in the CSS
+* Added support for `--relative-assets` option for the compass filter
+
+### Bug fixes
+
+* Allow functions.php to be included many times
+* Updated the ScssPhpFilter for upstream class renaming
+
+1.2.0-alpha1 (2014-07-08)
+-------------------------
+
+### BC breaks
+
+* Added `AssetFactory` instance as second argument for `WorkerInterface::process()`
+* Removed `LazyAssetManager` from `CacheBustingWorker` constructor
+* A new `getSourceDirectory()` method was added on the AssetInterface
+* Removed limit and count arguments from CssUtils functions
+* Removed the deprecated `PathUtils` class
+
+### New features
+
+* added `CssUtils::filterCommentless()`
+* Added `DependencyExtractorInterface` for filters to report other files they import
+* Added the support of nib in the stylus filter
+* Added `registerFunction` and `setFormatter` to the scssphp filter
+* Added the support of flag file for the ClosureCompilerJarFilter
+* Added the JsSqueeze filter
+* Added support of the define option for uglifyjs (1 & 2) filters
+* Added logging for Twig errors in the extractor
+
+### Bug fixes
+
+* Fixed the detection of protocol-relative CSS imports
+* Updated AssetCollection to not add several time the same variable in path
+* Fixed the merging of the environment variables to keep the configuration of the NODE_PATH working
+* Fixed the support of ``{% embed %}`` in the Twig extractor
+* Fixed the support of asset variables in GlobAsset
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/Gemfile b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/Gemfile
new file mode 100644
index 0000000..1c53249
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/Gemfile
@@ -0,0 +1,5 @@
+source "https://rubygems.org"
+
+gem "sprockets", "~> 1.0.0"
+gem "sass"
+gem "compass"
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/LICENSE b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/LICENSE
new file mode 100644
index 0000000..f5dedf4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2010-2015 OpenSky Project 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.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/README.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/README.md
new file mode 100644
index 0000000..7ec0058
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/README.md
@@ -0,0 +1,345 @@
+# Assetic [![Build Status](https://travis-ci.org/kriswallsmith/assetic.png?branch=master)](https://travis-ci.org/kriswallsmith/assetic) ![project status](http://stillmaintained.com/kriswallsmith/assetic.png) #
+
+Assetic is an asset management framework for PHP.
+
+``` php
+<?php
+
+use Assetic\Asset\AssetCollection;
+use Assetic\Asset\FileAsset;
+use Assetic\Asset\GlobAsset;
+
+$js = new AssetCollection(array(
+ new GlobAsset('/path/to/js/*'),
+ new FileAsset('/path/to/another.js'),
+));
+
+// the code is merged when the asset is dumped
+echo $js->dump();
+```
+
+Assets
+------
+
+An Assetic asset is something with filterable content that can be loaded and
+dumped. An asset also includes metadata, some of which can be manipulated and
+some of which is immutable.
+
+| **Property** | **Accessor** | **Mutator** |
+|--------------|-----------------|---------------|
+| content | getContent | setContent |
+| mtime | getLastModified | n/a |
+| source root | getSourceRoot | n/a |
+| source path | getSourcePath | n/a |
+| target path | getTargetPath | setTargetPath |
+
+The "target path" property denotes where an asset (or an collection of assets) should be dumped.
+
+Filters
+-------
+
+Filters can be applied to manipulate assets.
+
+``` php
+<?php
+
+use Assetic\Asset\AssetCollection;
+use Assetic\Asset\FileAsset;
+use Assetic\Asset\GlobAsset;
+use Assetic\Filter\LessFilter;
+use Assetic\Filter\Yui;
+
+$css = new AssetCollection(array(
+ new FileAsset('/path/to/src/styles.less', array(new LessFilter())),
+ new GlobAsset('/path/to/css/*'),
+), array(
+ new Yui\CssCompressorFilter('/path/to/yuicompressor.jar'),
+));
+
+// this will echo CSS compiled by LESS and compressed by YUI
+echo $css->dump();
+```
+
+The filters applied to the collection will cascade to each asset leaf if you
+iterate over it.
+
+``` php
+<?php
+
+foreach ($css as $leaf) {
+ // each leaf is compressed by YUI
+ echo $leaf->dump();
+}
+```
+
+The core provides the following filters in the `Assetic\Filter` namespace:
+
+ * `AutoprefixerFilter`: Parse and update vendor-specific properties using autoprefixer
+ * `CoffeeScriptFilter`: compiles CoffeeScript into Javascript
+ * `CompassFilter`: Compass CSS authoring framework
+ * `CssEmbedFilter`: embeds image data in your stylesheets
+ * `CssImportFilter`: inlines imported stylesheets
+ * `CssMinFilter`: minifies CSS
+ * `CleanCssFilter`: minifies CSS
+ * `CssRewriteFilter`: fixes relative URLs in CSS assets when moving to a new URL
+ * `DartFilter`: compiles Javascript using dart2js
+ * `EmberPrecompileFilter`: precompiles Handlebars templates into Javascript for use in the Ember.js framework
+ * `GoogleClosure\CompilerApiFilter`: compiles Javascript using the Google Closure Compiler API
+ * `GoogleClosure\CompilerJarFilter`: compiles Javascript using the Google Closure Compiler JAR
+ * `GssFilter`: compliles CSS using the Google Closure Stylesheets Compiler
+ * `HandlebarsFilter`: compiles Handlebars templates into Javascript
+ * `JpegoptimFilter`: optimize your JPEGs
+ * `JpegtranFilter`: optimize your JPEGs
+ * `JSMinFilter`: minifies Javascript
+ * `JSMinPlusFilter`: minifies Javascript
+ * `JSqueezeFilter`: compresses Javascript
+ * `LessFilter`: parses LESS into CSS (using less.js with node.js)
+ * `LessphpFilter`: parses LESS into CSS (using lessphp)
+ * `OptiPngFilter`: optimize your PNGs
+ * `PackagerFilter`: parses Javascript for packager tags
+ * `PackerFilter`: compresses Javascript using Dean Edwards's Packer
+ * `PhpCssEmbedFilter`: embeds image data in your stylesheet
+ * `PngoutFilter`: optimize your PNGs
+ * `ReactJsxFilter`: compiles React JSX into JavaScript
+ * `Sass\SassFilter`: parses SASS into CSS
+ * `Sass\ScssFilter`: parses SCSS into CSS
+ * `SassphpFilter`: parses Sass into CSS using the sassphp bindings for Libsass
+ * `ScssphpFilter`: parses SCSS using scssphp
+ * `SeparatorFilter`: inserts a separator between assets to prevent merge failures
+ * `SprocketsFilter`: Sprockets Javascript dependency management
+ * `StylusFilter`: parses STYL into CSS
+ * `TypeScriptFilter`: parses TypeScript into Javascript
+ * `UglifyCssFilter`: minifies CSS
+ * `UglifyJs2Filter`: minifies Javascript
+ * `UglifyJsFilter`: minifies Javascript
+ * `Yui\CssCompressorFilter`: compresses CSS using the YUI compressor
+ * `Yui\JsCompressorFilter`: compresses Javascript using the YUI compressor
+
+Asset Manager
+-------------
+
+An asset manager is provided for organizing assets.
+
+``` php
+<?php
+
+use Assetic\AssetManager;
+use Assetic\Asset\FileAsset;
+use Assetic\Asset\GlobAsset;
+
+$am = new AssetManager();
+$am->set('jquery', new FileAsset('/path/to/jquery.js'));
+$am->set('base_css', new GlobAsset('/path/to/css/*'));
+```
+
+The asset manager can also be used to reference assets to avoid duplication.
+
+``` php
+<?php
+
+use Assetic\Asset\AssetCollection;
+use Assetic\Asset\AssetReference;
+use Assetic\Asset\FileAsset;
+
+$am->set('my_plugin', new AssetCollection(array(
+ new AssetReference($am, 'jquery'),
+ new FileAsset('/path/to/jquery.plugin.js'),
+)));
+```
+
+Filter Manager
+--------------
+
+A filter manager is also provided for organizing filters.
+
+``` php
+<?php
+
+use Assetic\FilterManager;
+use Assetic\Filter\Sass\SassFilter;
+use Assetic\Filter\Yui;
+
+$fm = new FilterManager();
+$fm->set('sass', new SassFilter('/path/to/parser/sass'));
+$fm->set('yui_css', new Yui\CssCompressorFilter('/path/to/yuicompressor.jar'));
+```
+
+Asset Factory
+-------------
+
+If you'd rather not create all these objects by hand, you can use the asset
+factory, which will do most of the work for you.
+
+``` php
+<?php
+
+use Assetic\Factory\AssetFactory;
+
+$factory = new AssetFactory('/path/to/asset/directory/');
+$factory->setAssetManager($am);
+$factory->setFilterManager($fm);
+$factory->setDebug(true);
+
+$css = $factory->createAsset(array(
+ '@reset', // load the asset manager's "reset" asset
+ 'css/src/*.scss', // load every scss files from "/path/to/asset/directory/css/src/"
+), array(
+ 'scss', // filter through the filter manager's "scss" filter
+ '?yui_css', // don't use this filter in debug mode
+));
+
+echo $css->dump();
+```
+
+The `AssetFactory` is constructed with a root directory which is used as the base directory for relative asset paths.
+
+Prefixing a filter name with a question mark, as `yui_css` is here, will cause
+that filter to be omitted when the factory is in debug mode.
+
+You can also register [Workers](src/Assetic/Factory/Worker/WorkerInterface.php) on the factory and all assets created
+by it will be passed to the worker's `process()` method before being returned. See _Cache Busting_ below for an example.
+
+Dumping Assets to static files
+------------------------------
+
+You can dump all the assets an AssetManager holds to files in a directory. This will probably be below your webserver's document root
+so the files can be served statically.
+
+``` php
+<?php
+
+use Assetic\AssetWriter;
+
+$writer = new AssetWriter('/path/to/web');
+$writer->writeManagerAssets($am);
+```
+
+This will make use of the assets' target path.
+
+Cache Busting
+-------------
+
+If you serve your assets from static files as just described, you can use the CacheBustingWorker to rewrite the target
+paths for assets. It will insert an identifier before the filename extension that is unique for a particular version
+of the asset.
+
+This identifier is based on the modification time of the asset and will also take depended-on assets into
+consideration if the applied filters support it.
+
+``` php
+<?php
+
+use Assetic\Factory\AssetFactory;
+use Assetic\Factory\Worker\CacheBustingWorker;
+
+$factory = new AssetFactory('/path/to/asset/directory/');
+$factory->setAssetManager($am);
+$factory->setFilterManager($fm);
+$factory->setDebug(true);
+$factory->addWorker(new CacheBustingWorker());
+
+$css = $factory->createAsset(array(
+ '@reset', // load the asset manager's "reset" asset
+ 'css/src/*.scss', // load every scss files from "/path/to/asset/directory/css/src/"
+), array(
+ 'scss', // filter through the filter manager's "scss" filter
+ '?yui_css', // don't use this filter in debug mode
+));
+
+echo $css->dump();
+```
+
+Internal caching
+-------
+
+A simple caching mechanism is provided to avoid unnecessary work.
+
+``` php
+<?php
+
+use Assetic\Asset\AssetCache;
+use Assetic\Asset\FileAsset;
+use Assetic\Cache\FilesystemCache;
+use Assetic\Filter\Yui;
+
+$yui = new Yui\JsCompressorFilter('/path/to/yuicompressor.jar');
+$js = new AssetCache(
+ new FileAsset('/path/to/some.js', array($yui)),
+ new FilesystemCache('/path/to/cache')
+);
+
+// the YUI compressor will only run on the first call
+$js->dump();
+$js->dump();
+$js->dump();
+```
+
+Twig
+----
+
+To use the Assetic [Twig][3] extension you must register it to your Twig
+environment:
+
+``` php
+<?php
+
+$twig->addExtension(new AsseticExtension($factory));
+```
+
+Once in place, the extension exposes a stylesheets and a javascripts tag with a syntax similar
+to what the asset factory uses:
+
+``` html+jinja
+{% stylesheets '/path/to/sass/main.sass' filter='sass,?yui_css' output='css/all.css' %}
+ <link href="{{ asset_url }}" type="text/css" rel="stylesheet" />
+{% endstylesheets %}
+```
+
+This example will render one `link` element on the page that includes a URL
+where the filtered asset can be found.
+
+When the extension is in debug mode, this same tag will render multiple `link`
+elements, one for each asset referenced by the `css/src/*.sass` glob. The
+specified filters will still be applied, unless they are marked as optional
+using the `?` prefix.
+
+This behavior can also be triggered by setting a `debug` attribute on the tag:
+
+``` html+jinja
+{% stylesheets 'css/*' debug=true %} ... {% stylesheets %}
+```
+
+These assets need to be written to the web directory so these URLs don't
+return 404 errors.
+
+``` php
+<?php
+
+use Assetic\AssetWriter;
+use Assetic\Extension\Twig\TwigFormulaLoader;
+use Assetic\Extension\Twig\TwigResource;
+use Assetic\Factory\LazyAssetManager;
+
+$am = new LazyAssetManager($factory);
+
+// enable loading assets from twig templates
+$am->setLoader('twig', new TwigFormulaLoader($twig));
+
+// loop through all your templates
+foreach ($templates as $template) {
+ $resource = new TwigResource($twigLoader, $template);
+ $am->addResource($resource, 'twig');
+}
+
+$writer = new AssetWriter('/path/to/web');
+$writer->writeManagerAssets($am);
+```
+
+---
+
+Assetic is based on the Python [webassets][1] library (available on
+[GitHub][2]).
+
+[1]: http://elsdoerfer.name/docs/webassets
+[2]: https://github.com/miracle2k/webassets
+[3]: http://twig.sensiolabs.org
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/composer.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/composer.json
new file mode 100644
index 0000000..80755d7
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/composer.json
@@ -0,0 +1,56 @@
+{
+ "name": "kriswallsmith/assetic",
+ "description": "Asset Management for PHP",
+ "keywords": [ "assets", "compression", "minification" ],
+ "homepage": "https://github.com/kriswallsmith/assetic",
+ "type": "library",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Kris Wallsmith",
+ "email": "kris.wallsmith@gmail.com",
+ "homepage": "http://kriswallsmith.net/"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.1",
+ "symfony/process": "~2.1|~3.0"
+ },
+ "conflict": {
+ "twig/twig": "<1.27"
+ },
+ "require-dev": {
+ "leafo/lessphp": "^0.3.7",
+ "leafo/scssphp": "~0.1",
+ "meenie/javascript-packer": "^1.1",
+ "mrclay/minify": "<2.3",
+ "natxet/cssmin": "3.0.4",
+ "patchwork/jsqueeze": "~1.0|~2.0",
+ "phpunit/phpunit": "~4.8 || ^5.6",
+ "psr/log": "~1.0",
+ "ptachoire/cssembed": "~1.0",
+ "symfony/phpunit-bridge": "~2.7|~3.0",
+ "twig/twig": "~1.23|~2.0",
+ "yfix/packager": "dev-master"
+ },
+ "suggest": {
+ "twig/twig": "Assetic provides the integration with the Twig templating engine",
+ "leafo/lessphp": "Assetic provides the integration with the lessphp LESS compiler",
+ "leafo/scssphp": "Assetic provides the integration with the scssphp SCSS compiler",
+ "ptachoire/cssembed": "Assetic provides the integration with phpcssembed to embed data uris",
+ "leafo/scssphp-compass": "Assetic provides the integration with the SCSS compass plugin",
+ "patchwork/jsqueeze": "Assetic provides the integration with the JSqueeze JavaScript compressor"
+ },
+ "autoload": {
+ "psr-0": { "Assetic": "src/" },
+ "files": [ "src/functions.php" ]
+ },
+ "config": {
+ "bin-dir": "bin"
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/package.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/package.json
new file mode 100644
index 0000000..5369739
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/package.json
@@ -0,0 +1,19 @@
+{
+ "devDependencies": {
+ "uglifycss": "*",
+ "coffee-script": "*",
+ "stylus": "*",
+ "nib": "*",
+ "ember-precompile": "*",
+ "typescript": "*",
+ "less": "*",
+ "handlebars": "*",
+ "uglify-js": "*",
+ "autoprefixer": "*",
+ "autoprefixer-5": "^1.x",
+ "autoprefixer-cli": "*",
+ "roole": "*",
+ "react-tools": "*",
+ "clean-css": "*"
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCache.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCache.php
new file mode 100644
index 0000000..7ce62b5
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCache.php
@@ -0,0 +1,174 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Asset;
+
+use Assetic\Cache\CacheInterface;
+use Assetic\Filter\FilterInterface;
+use Assetic\Filter\HashableInterface;
+
+/**
+ * Caches an asset to avoid the cost of loading and dumping.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class AssetCache implements AssetInterface
+{
+ private $asset;
+ private $cache;
+
+ public function __construct(AssetInterface $asset, CacheInterface $cache)
+ {
+ $this->asset = $asset;
+ $this->cache = $cache;
+ }
+
+ public function ensureFilter(FilterInterface $filter)
+ {
+ $this->asset->ensureFilter($filter);
+ }
+
+ public function getFilters()
+ {
+ return $this->asset->getFilters();
+ }
+
+ public function clearFilters()
+ {
+ $this->asset->clearFilters();
+ }
+
+ public function load(FilterInterface $additionalFilter = null)
+ {
+ $cacheKey = self::getCacheKey($this->asset, $additionalFilter, 'load');
+ if ($this->cache->has($cacheKey)) {
+ $this->asset->setContent($this->cache->get($cacheKey));
+
+ return;
+ }
+
+ $this->asset->load($additionalFilter);
+ $this->cache->set($cacheKey, $this->asset->getContent());
+ }
+
+ public function dump(FilterInterface $additionalFilter = null)
+ {
+ $cacheKey = self::getCacheKey($this->asset, $additionalFilter, 'dump');
+ if ($this->cache->has($cacheKey)) {
+ return $this->cache->get($cacheKey);
+ }
+
+ $content = $this->asset->dump($additionalFilter);
+ $this->cache->set($cacheKey, $content);
+
+ return $content;
+ }
+
+ public function getContent()
+ {
+ return $this->asset->getContent();
+ }
+
+ public function setContent($content)
+ {
+ $this->asset->setContent($content);
+ }
+
+ public function getSourceRoot()
+ {
+ return $this->asset->getSourceRoot();
+ }
+
+ public function getSourcePath()
+ {
+ return $this->asset->getSourcePath();
+ }
+
+ public function getSourceDirectory()
+ {
+ return $this->asset->getSourceDirectory();
+ }
+
+ public function getTargetPath()
+ {
+ return $this->asset->getTargetPath();
+ }
+
+ public function setTargetPath($targetPath)
+ {
+ $this->asset->setTargetPath($targetPath);
+ }
+
+ public function getLastModified()
+ {
+ return $this->asset->getLastModified();
+ }
+
+ public function getVars()
+ {
+ return $this->asset->getVars();
+ }
+
+ public function setValues(array $values)
+ {
+ $this->asset->setValues($values);
+ }
+
+ public function getValues()
+ {
+ return $this->asset->getValues();
+ }
+
+ /**
+ * Returns a cache key for the current asset.
+ *
+ * The key is composed of everything but an asset's content:
+ *
+ * * source root
+ * * source path
+ * * target url
+ * * last modified
+ * * filters
+ *
+ * @param AssetInterface $asset The asset
+ * @param FilterInterface $additionalFilter Any additional filter being applied
+ * @param string $salt Salt for the key
+ *
+ * @return string A key for identifying the current asset
+ */
+ private static function getCacheKey(AssetInterface $asset, FilterInterface $additionalFilter = null, $salt = '')
+ {
+ if ($additionalFilter) {
+ $asset = clone $asset;
+ $asset->ensureFilter($additionalFilter);
+ }
+
+ $cacheKey = $asset->getSourceRoot();
+ $cacheKey .= $asset->getSourcePath();
+ $cacheKey .= $asset->getTargetPath();
+ $cacheKey .= $asset->getLastModified();
+
+ foreach ($asset->getFilters() as $filter) {
+ if ($filter instanceof HashableInterface) {
+ $cacheKey .= $filter->hash();
+ } else {
+ $cacheKey .= serialize($filter);
+ }
+ }
+
+ if ($values = $asset->getValues()) {
+ asort($values);
+ $cacheKey .= serialize($values);
+ }
+
+ return md5($cacheKey.$salt);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCollection.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCollection.php
new file mode 100644
index 0000000..3141af5
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCollection.php
@@ -0,0 +1,238 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Asset;
+
+use Assetic\Asset\Iterator\AssetCollectionFilterIterator;
+use Assetic\Asset\Iterator\AssetCollectionIterator;
+use Assetic\Filter\FilterCollection;
+use Assetic\Filter\FilterInterface;
+
+/**
+ * A collection of assets.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class AssetCollection implements \IteratorAggregate, AssetCollectionInterface
+{
+ private $assets;
+ private $filters;
+ private $sourceRoot;
+ private $targetPath;
+ private $content;
+ private $clones;
+ private $vars;
+ private $values;
+
+ /**
+ * Constructor.
+ *
+ * @param array $assets Assets for the current collection
+ * @param array $filters Filters for the current collection
+ * @param string $sourceRoot The root directory
+ * @param array $vars
+ */
+ public function __construct($assets = array(), $filters = array(), $sourceRoot = null, array $vars = array())
+ {
+ $this->assets = array();
+ foreach ($assets as $asset) {
+ $this->add($asset);
+ }
+
+ $this->filters = new FilterCollection($filters);
+ $this->sourceRoot = $sourceRoot;
+ $this->clones = new \SplObjectStorage();
+ $this->vars = $vars;
+ $this->values = array();
+ }
+
+ public function __clone()
+ {
+ $this->filters = clone $this->filters;
+ $this->clones = new \SplObjectStorage();
+ }
+
+ public function all()
+ {
+ return $this->assets;
+ }
+
+ public function add(AssetInterface $asset)
+ {
+ $this->assets[] = $asset;
+ }
+
+ public function removeLeaf(AssetInterface $needle, $graceful = false)
+ {
+ foreach ($this->assets as $i => $asset) {
+ $clone = isset($this->clones[$asset]) ? $this->clones[$asset] : null;
+ if (in_array($needle, array($asset, $clone), true)) {
+ unset($this->clones[$asset], $this->assets[$i]);
+
+ return true;
+ }
+
+ if ($asset instanceof AssetCollectionInterface && $asset->removeLeaf($needle, true)) {
+ return true;
+ }
+ }
+
+ if ($graceful) {
+ return false;
+ }
+
+ throw new \InvalidArgumentException('Leaf not found.');
+ }
+
+ public function replaceLeaf(AssetInterface $needle, AssetInterface $replacement, $graceful = false)
+ {
+ foreach ($this->assets as $i => $asset) {
+ $clone = isset($this->clones[$asset]) ? $this->clones[$asset] : null;
+ if (in_array($needle, array($asset, $clone), true)) {
+ unset($this->clones[$asset]);
+ $this->assets[$i] = $replacement;
+
+ return true;
+ }
+
+ if ($asset instanceof AssetCollectionInterface && $asset->replaceLeaf($needle, $replacement, true)) {
+ return true;
+ }
+ }
+
+ if ($graceful) {
+ return false;
+ }
+
+ throw new \InvalidArgumentException('Leaf not found.');
+ }
+
+ public function ensureFilter(FilterInterface $filter)
+ {
+ $this->filters->ensure($filter);
+ }
+
+ public function getFilters()
+ {
+ return $this->filters->all();
+ }
+
+ public function clearFilters()
+ {
+ $this->filters->clear();
+ $this->clones = new \SplObjectStorage();
+ }
+
+ public function load(FilterInterface $additionalFilter = null)
+ {
+ // loop through leaves and load each asset
+ $parts = array();
+ foreach ($this as $asset) {
+ $asset->load($additionalFilter);
+ $parts[] = $asset->getContent();
+ }
+
+ $this->content = implode("\n", $parts);
+ }
+
+ public function dump(FilterInterface $additionalFilter = null)
+ {
+ // loop through leaves and dump each asset
+ $parts = array();
+ foreach ($this as $asset) {
+ $parts[] = $asset->dump($additionalFilter);
+ }
+
+ return implode("\n", $parts);
+ }
+
+ public function getContent()
+ {
+ return $this->content;
+ }
+
+ public function setContent($content)
+ {
+ $this->content = $content;
+ }
+
+ public function getSourceRoot()
+ {
+ return $this->sourceRoot;
+ }
+
+ public function getSourcePath()
+ {
+ }
+
+ public function getSourceDirectory()
+ {
+ }
+
+ public function getTargetPath()
+ {
+ return $this->targetPath;
+ }
+
+ public function setTargetPath($targetPath)
+ {
+ $this->targetPath = $targetPath;
+ }
+
+ /**
+ * Returns the highest last-modified value of all assets in the current collection.
+ *
+ * @return integer|null A UNIX timestamp
+ */
+ public function getLastModified()
+ {
+ if (!count($this->assets)) {
+ return;
+ }
+
+ $mtime = 0;
+ foreach ($this as $asset) {
+ $assetMtime = $asset->getLastModified();
+ if ($assetMtime > $mtime) {
+ $mtime = $assetMtime;
+ }
+ }
+
+ return $mtime;
+ }
+
+ /**
+ * Returns an iterator for looping recursively over unique leaves.
+ */
+ public function getIterator()
+ {
+ return new \RecursiveIteratorIterator(new AssetCollectionFilterIterator(new AssetCollectionIterator($this, $this->clones)));
+ }
+
+ public function getVars()
+ {
+ return $this->vars;
+ }
+
+ public function setValues(array $values)
+ {
+ $this->values = $values;
+
+ foreach ($this as $asset) {
+ $asset->setValues(array_intersect_key($values, array_flip($asset->getVars())));
+ }
+ }
+
+ public function getValues()
+ {
+ return $this->values;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCollectionInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCollectionInterface.php
new file mode 100644
index 0000000..f029d1b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetCollectionInterface.php
@@ -0,0 +1,59 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Asset;
+
+/**
+ * An asset collection.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+interface AssetCollectionInterface extends AssetInterface, \Traversable
+{
+ /**
+ * Returns all child assets.
+ *
+ * @return array An array of AssetInterface objects
+ */
+ public function all();
+
+ /**
+ * Adds an asset to the current collection.
+ *
+ * @param AssetInterface $asset An asset
+ */
+ public function add(AssetInterface $asset);
+
+ /**
+ * Removes a leaf.
+ *
+ * @param AssetInterface $leaf The leaf to remove
+ * @param Boolean $graceful Whether the failure should return false or throw an exception
+ *
+ * @return Boolean Whether the asset has been found
+ *
+ * @throws \InvalidArgumentException If the asset cannot be found
+ */
+ public function removeLeaf(AssetInterface $leaf, $graceful = false);
+
+ /**
+ * Replaces an existing leaf with a new one.
+ *
+ * @param AssetInterface $needle The current asset to replace
+ * @param AssetInterface $replacement The new asset
+ * @param Boolean $graceful Whether the failure should return false or throw an exception
+ *
+ * @return Boolean Whether the asset has been found
+ *
+ * @throws \InvalidArgumentException If the asset cannot be found
+ */
+ public function replaceLeaf(AssetInterface $needle, AssetInterface $replacement, $graceful = false);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetInterface.php
new file mode 100644
index 0000000..b1d655c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetInterface.php
@@ -0,0 +1,166 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Asset;
+
+use Assetic\Filter\FilterInterface;
+
+/**
+ * An asset has a mutable URL and content and can be loaded and dumped.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+interface AssetInterface
+{
+ /**
+ * Ensures the current asset includes the supplied filter.
+ *
+ * @param FilterInterface $filter A filter
+ */
+ public function ensureFilter(FilterInterface $filter);
+
+ /**
+ * Returns an array of filters currently applied.
+ *
+ * @return array An array of filters
+ */
+ public function getFilters();
+
+ /**
+ * Clears all filters from the current asset.
+ */
+ public function clearFilters();
+
+ /**
+ * Loads the asset into memory and applies load filters.
+ *
+ * You may provide an additional filter to apply during load.
+ *
+ * @param FilterInterface $additionalFilter An additional filter
+ */
+ public function load(FilterInterface $additionalFilter = null);
+
+ /**
+ * Applies dump filters and returns the asset as a string.
+ *
+ * You may provide an additional filter to apply during dump.
+ *
+ * Dumping an asset should not change its state.
+ *
+ * If the current asset has not been loaded yet, it should be
+ * automatically loaded at this time.
+ *
+ * @param FilterInterface $additionalFilter An additional filter
+ *
+ * @return string The filtered content of the current asset
+ */
+ public function dump(FilterInterface $additionalFilter = null);
+
+ /**
+ * Returns the loaded content of the current asset.
+ *
+ * @return string The content
+ */
+ public function getContent();
+
+ /**
+ * Sets the content of the current asset.
+ *
+ * Filters can use this method to change the content of the asset.
+ *
+ * @param string $content The asset content
+ */
+ public function setContent($content);
+
+ /**
+ * Returns an absolute path or URL to the source asset's root directory.
+ *
+ * This value should be an absolute path to a directory in the filesystem,
+ * an absolute URL with no path, or null.
+ *
+ * For example:
+ *
+ * * '/path/to/web'
+ * * 'http://example.com'
+ * * null
+ *
+ * @return string|null The asset's root
+ */
+ public function getSourceRoot();
+
+ /**
+ * Returns the relative path for the source asset.
+ *
+ * This value can be combined with the asset's source root (if both are
+ * non-null) to get something compatible with file_get_contents().
+ *
+ * For example:
+ *
+ * * 'js/main.js'
+ * * 'main.js'
+ * * null
+ *
+ * @return string|null The source asset path
+ */
+ public function getSourcePath();
+
+ /**
+ * Returns the asset's source directory.
+ *
+ * The source directory is the directory the asset was located in
+ * and can be used to resolve references relative to an asset.
+ *
+ * @return string|null The asset's source directory
+ */
+ public function getSourceDirectory();
+
+ /**
+ * Returns the URL for the current asset.
+ *
+ * @return string|null A web URL where the asset will be dumped
+ */
+ public function getTargetPath();
+
+ /**
+ * Sets the URL for the current asset.
+ *
+ * @param string $targetPath A web URL where the asset will be dumped
+ */
+ public function setTargetPath($targetPath);
+
+ /**
+ * Returns the time the current asset was last modified.
+ *
+ * @return integer|null A UNIX timestamp
+ */
+ public function getLastModified();
+
+ /**
+ * Returns an array of variable names for this asset.
+ *
+ * @return array
+ */
+ public function getVars();
+
+ /**
+ * Sets the values for the asset's variables.
+ *
+ * @param array $values
+ */
+ public function setValues(array $values);
+
+ /**
+ * Returns the current values for this asset.
+ *
+ * @return array an array of strings
+ */
+ public function getValues();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetReference.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetReference.php
new file mode 100644
index 0000000..f66b769
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/AssetReference.php
@@ -0,0 +1,164 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Asset;
+
+use Assetic\AssetManager;
+use Assetic\Filter\FilterInterface;
+
+/**
+ * A reference to an asset in the asset manager.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class AssetReference implements AssetInterface
+{
+ private $am;
+ private $name;
+ private $filters = array();
+ private $clone = false;
+ private $asset;
+
+ public function __construct(AssetManager $am, $name)
+ {
+ $this->am = $am;
+ $this->name = $name;
+ }
+
+ public function __clone()
+ {
+ $this->clone = true;
+
+ if ($this->asset) {
+ $this->asset = clone $this->asset;
+ }
+ }
+
+ public function ensureFilter(FilterInterface $filter)
+ {
+ $this->filters[] = $filter;
+ }
+
+ public function getFilters()
+ {
+ $this->flushFilters();
+
+ return $this->callAsset(__FUNCTION__);
+ }
+
+ public function clearFilters()
+ {
+ $this->filters = array();
+ $this->callAsset(__FUNCTION__);
+ }
+
+ public function load(FilterInterface $additionalFilter = null)
+ {
+ $this->flushFilters();
+
+ return $this->callAsset(__FUNCTION__, array($additionalFilter));
+ }
+
+ public function dump(FilterInterface $additionalFilter = null)
+ {
+ $this->flushFilters();
+
+ return $this->callAsset(__FUNCTION__, array($additionalFilter));
+ }
+
+ public function getContent()
+ {
+ return $this->callAsset(__FUNCTION__);
+ }
+
+ public function setContent($content)
+ {
+ $this->callAsset(__FUNCTION__, array($content));
+ }
+
+ public function getSourceRoot()
+ {
+ return $this->callAsset(__FUNCTION__);
+ }
+
+ public function getSourcePath()
+ {
+ return $this->callAsset(__FUNCTION__);
+ }
+
+ public function getSourceDirectory()
+ {
+ return $this->callAsset(__FUNCTION__);
+ }
+
+ public function getTargetPath()
+ {
+ return $this->callAsset(__FUNCTION__);
+ }
+
+ public function setTargetPath($targetPath)
+ {
+ $this->callAsset(__FUNCTION__, array($targetPath));
+ }
+
+ public function getLastModified()
+ {
+ return $this->callAsset(__FUNCTION__);
+ }
+
+ public function getVars()
+ {
+ return $this->callAsset(__FUNCTION__);
+ }
+
+ public function getValues()
+ {
+ return $this->callAsset(__FUNCTION__);
+ }
+
+ public function setValues(array $values)
+ {
+ $this->callAsset(__FUNCTION__, array($values));
+ }
+
+ // private
+
+ private function callAsset($method, $arguments = array())
+ {
+ $asset = $this->resolve();
+
+ return call_user_func_array(array($asset, $method), $arguments);
+ }
+
+ private function flushFilters()
+ {
+ $asset = $this->resolve();
+
+ while ($filter = array_shift($this->filters)) {
+ $asset->ensureFilter($filter);
+ }
+ }
+
+ private function resolve()
+ {
+ if ($this->asset) {
+ return $this->asset;
+ }
+
+ $asset = $this->am->get($this->name);
+
+ if ($this->clone) {
+ $asset = $this->asset = clone $asset;
+ }
+
+ return $asset;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/BaseAsset.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/BaseAsset.php
new file mode 100644
index 0000000..093b92a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/BaseAsset.php
@@ -0,0 +1,181 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Asset;
+
+use Assetic\Filter\FilterCollection;
+use Assetic\Filter\FilterInterface;
+
+/**
+ * A base abstract asset.
+ *
+ * The methods load() and getLastModified() are left undefined, although a
+ * reusable doLoad() method is available to child classes.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+abstract class BaseAsset implements AssetInterface
+{
+ private $filters;
+ private $sourceRoot;
+ private $sourcePath;
+ private $sourceDir;
+ private $targetPath;
+ private $content;
+ private $loaded;
+ private $vars;
+ private $values;
+
+ /**
+ * Constructor.
+ *
+ * @param array $filters Filters for the asset
+ * @param string $sourceRoot The root directory
+ * @param string $sourcePath The asset path
+ * @param array $vars
+ */
+ public function __construct($filters = array(), $sourceRoot = null, $sourcePath = null, array $vars = array())
+ {
+ $this->filters = new FilterCollection($filters);
+ $this->sourceRoot = $sourceRoot;
+ $this->sourcePath = $sourcePath;
+ if ($sourcePath && $sourceRoot) {
+ $this->sourceDir = dirname("$sourceRoot/$sourcePath");
+ }
+ $this->vars = $vars;
+ $this->values = array();
+ $this->loaded = false;
+ }
+
+ public function __clone()
+ {
+ $this->filters = clone $this->filters;
+ }
+
+ public function ensureFilter(FilterInterface $filter)
+ {
+ $this->filters->ensure($filter);
+ }
+
+ public function getFilters()
+ {
+ return $this->filters->all();
+ }
+
+ public function clearFilters()
+ {
+ $this->filters->clear();
+ }
+
+ /**
+ * Encapsulates asset loading logic.
+ *
+ * @param string $content The asset content
+ * @param FilterInterface $additionalFilter An additional filter
+ */
+ protected function doLoad($content, FilterInterface $additionalFilter = null)
+ {
+ $filter = clone $this->filters;
+ if ($additionalFilter) {
+ $filter->ensure($additionalFilter);
+ }
+
+ $asset = clone $this;
+ $asset->setContent($content);
+
+ $filter->filterLoad($asset);
+ $this->content = $asset->getContent();
+
+ $this->loaded = true;
+ }
+
+ public function dump(FilterInterface $additionalFilter = null)
+ {
+ if (!$this->loaded) {
+ $this->load();
+ }
+
+ $filter = clone $this->filters;
+ if ($additionalFilter) {
+ $filter->ensure($additionalFilter);
+ }
+
+ $asset = clone $this;
+ $filter->filterDump($asset);
+
+ return $asset->getContent();
+ }
+
+ public function getContent()
+ {
+ return $this->content;
+ }
+
+ public function setContent($content)
+ {
+ $this->content = $content;
+ }
+
+ public function getSourceRoot()
+ {
+ return $this->sourceRoot;
+ }
+
+ public function getSourcePath()
+ {
+ return $this->sourcePath;
+ }
+
+ public function getSourceDirectory()
+ {
+ return $this->sourceDir;
+ }
+
+ public function getTargetPath()
+ {
+ return $this->targetPath;
+ }
+
+ public function setTargetPath($targetPath)
+ {
+ if ($this->vars) {
+ foreach ($this->vars as $var) {
+ if (false === strpos($targetPath, $var)) {
+ throw new \RuntimeException(sprintf('The asset target path "%s" must contain the variable "{%s}".', $targetPath, $var));
+ }
+ }
+ }
+
+ $this->targetPath = $targetPath;
+ }
+
+ public function getVars()
+ {
+ return $this->vars;
+ }
+
+ public function setValues(array $values)
+ {
+ foreach ($values as $var => $v) {
+ if (!in_array($var, $this->vars, true)) {
+ throw new \InvalidArgumentException(sprintf('The asset with source path "%s" has no variable named "%s".', $this->sourcePath, $var));
+ }
+ }
+
+ $this->values = $values;
+ $this->loaded = false;
+ }
+
+ public function getValues()
+ {
+ return $this->values;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/FileAsset.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/FileAsset.php
new file mode 100644
index 0000000..2a33e08
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/FileAsset.php
@@ -0,0 +1,78 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Asset;
+
+use Assetic\Filter\FilterInterface;
+use Assetic\Util\VarUtils;
+
+/**
+ * Represents an asset loaded from a file.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class FileAsset extends BaseAsset
+{
+ private $source;
+
+ /**
+ * Constructor.
+ *
+ * @param string $source An absolute path
+ * @param array $filters An array of filters
+ * @param string $sourceRoot The source asset root directory
+ * @param string $sourcePath The source asset path
+ * @param array $vars
+ *
+ * @throws \InvalidArgumentException If the supplied root doesn't match the source when guessing the path
+ */
+ public function __construct($source, $filters = array(), $sourceRoot = null, $sourcePath = null, array $vars = array())
+ {
+ if (null === $sourceRoot) {
+ $sourceRoot = dirname($source);
+ if (null === $sourcePath) {
+ $sourcePath = basename($source);
+ }
+ } elseif (null === $sourcePath) {
+ if (0 !== strpos($source, $sourceRoot)) {
+ throw new \InvalidArgumentException(sprintf('The source "%s" is not in the root directory "%s"', $source, $sourceRoot));
+ }
+
+ $sourcePath = substr($source, strlen($sourceRoot) + 1);
+ }
+
+ $this->source = $source;
+
+ parent::__construct($filters, $sourceRoot, $sourcePath, $vars);
+ }
+
+ public function load(FilterInterface $additionalFilter = null)
+ {
+ $source = VarUtils::resolve($this->source, $this->getVars(), $this->getValues());
+
+ if (!is_file($source)) {
+ throw new \RuntimeException(sprintf('The source file "%s" does not exist.', $source));
+ }
+
+ $this->doLoad(file_get_contents($source), $additionalFilter);
+ }
+
+ public function getLastModified()
+ {
+ $source = VarUtils::resolve($this->source, $this->getVars(), $this->getValues());
+
+ if (!is_file($source)) {
+ throw new \RuntimeException(sprintf('The source file "%s" does not exist.', $source));
+ }
+
+ return filemtime($source);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/GlobAsset.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/GlobAsset.php
new file mode 100644
index 0000000..6444e61
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/GlobAsset.php
@@ -0,0 +1,115 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Asset;
+
+use Assetic\Filter\FilterInterface;
+use Assetic\Util\VarUtils;
+
+/**
+ * A collection of assets loaded by glob.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class GlobAsset extends AssetCollection
+{
+ private $globs;
+ private $initialized;
+
+ /**
+ * Constructor.
+ *
+ * @param string|array $globs A single glob path or array of paths
+ * @param array $filters An array of filters
+ * @param string $root The root directory
+ * @param array $vars
+ */
+ public function __construct($globs, $filters = array(), $root = null, array $vars = array())
+ {
+ $this->globs = (array) $globs;
+ $this->initialized = false;
+
+ parent::__construct(array(), $filters, $root, $vars);
+ }
+
+ public function all()
+ {
+ if (!$this->initialized) {
+ $this->initialize();
+ }
+
+ return parent::all();
+ }
+
+ public function load(FilterInterface $additionalFilter = null)
+ {
+ if (!$this->initialized) {
+ $this->initialize();
+ }
+
+ parent::load($additionalFilter);
+ }
+
+ public function dump(FilterInterface $additionalFilter = null)
+ {
+ if (!$this->initialized) {
+ $this->initialize();
+ }
+
+ return parent::dump($additionalFilter);
+ }
+
+ public function getLastModified()
+ {
+ if (!$this->initialized) {
+ $this->initialize();
+ }
+
+ return parent::getLastModified();
+ }
+
+ public function getIterator()
+ {
+ if (!$this->initialized) {
+ $this->initialize();
+ }
+
+ return parent::getIterator();
+ }
+
+ public function setValues(array $values)
+ {
+ parent::setValues($values);
+ $this->initialized = false;
+ }
+
+ /**
+ * Initializes the collection based on the glob(s) passed in.
+ */
+ private function initialize()
+ {
+ foreach ($this->globs as $glob) {
+ $glob = VarUtils::resolve($glob, $this->getVars(), $this->getValues());
+
+ if (false !== $paths = glob($glob)) {
+ foreach ($paths as $path) {
+ if (is_file($path)) {
+ $asset = new FileAsset($path, array(), $this->getSourceRoot(), null, $this->getVars());
+ $asset->setValues($this->getValues());
+ $this->add($asset);
+ }
+ }
+ }
+ }
+
+ $this->initialized = true;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/HttpAsset.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/HttpAsset.php
new file mode 100644
index 0000000..cd56761
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/HttpAsset.php
@@ -0,0 +1,79 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Asset;
+
+use Assetic\Filter\FilterInterface;
+use Assetic\Util\VarUtils;
+
+/**
+ * Represents an asset loaded via an HTTP request.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class HttpAsset extends BaseAsset
+{
+ private $sourceUrl;
+ private $ignoreErrors;
+
+ /**
+ * Constructor.
+ *
+ * @param string $sourceUrl The source URL
+ * @param array $filters An array of filters
+ * @param Boolean $ignoreErrors
+ * @param array $vars
+ *
+ * @throws \InvalidArgumentException If the first argument is not an URL
+ */
+ public function __construct($sourceUrl, $filters = array(), $ignoreErrors = false, array $vars = array())
+ {
+ if (0 === strpos($sourceUrl, '//')) {
+ $sourceUrl = 'http:'.$sourceUrl;
+ } elseif (false === strpos($sourceUrl, '://')) {
+ throw new \InvalidArgumentException(sprintf('"%s" is not a valid URL.', $sourceUrl));
+ }
+
+ $this->sourceUrl = $sourceUrl;
+ $this->ignoreErrors = $ignoreErrors;
+
+ list($scheme, $url) = explode('://', $sourceUrl, 2);
+ list($host, $path) = explode('/', $url, 2);
+
+ parent::__construct($filters, $scheme.'://'.$host, $path, $vars);
+ }
+
+ public function load(FilterInterface $additionalFilter = null)
+ {
+ $content = @file_get_contents(
+ VarUtils::resolve($this->sourceUrl, $this->getVars(), $this->getValues())
+ );
+
+ if (false === $content && !$this->ignoreErrors) {
+ throw new \RuntimeException(sprintf('Unable to load asset from URL "%s"', $this->sourceUrl));
+ }
+
+ $this->doLoad($content, $additionalFilter);
+ }
+
+ public function getLastModified()
+ {
+ if (false !== @file_get_contents($this->sourceUrl, false, stream_context_create(array('http' => array('method' => 'HEAD'))))) {
+ foreach ($http_response_header as $header) {
+ if (0 === stripos($header, 'Last-Modified: ')) {
+ list(, $mtime) = explode(':', $header, 2);
+
+ return strtotime(trim($mtime));
+ }
+ }
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/Iterator/AssetCollectionFilterIterator.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/Iterator/AssetCollectionFilterIterator.php
new file mode 100644
index 0000000..fae5d13
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/Iterator/AssetCollectionFilterIterator.php
@@ -0,0 +1,84 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Asset\Iterator;
+
+/**
+ * Asset collection filter iterator.
+ *
+ * The filter iterator is responsible for de-duplication of leaf assets based
+ * on both strict equality and source URL.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class AssetCollectionFilterIterator extends \RecursiveFilterIterator
+{
+ private $visited;
+ private $sources;
+
+ /**
+ * Constructor.
+ *
+ * @param AssetCollectionIterator $iterator The inner iterator
+ * @param array $visited An array of visited asset objects
+ * @param array $sources An array of visited source strings
+ */
+ public function __construct(AssetCollectionIterator $iterator, array $visited = array(), array $sources = array())
+ {
+ parent::__construct($iterator);
+
+ $this->visited = $visited;
+ $this->sources = $sources;
+ }
+
+ /**
+ * Determines whether the current asset is a duplicate.
+ *
+ * De-duplication is performed based on either strict equality or by
+ * matching sources.
+ *
+ * @return Boolean Returns true if we have not seen this asset yet
+ */
+ public function accept()
+ {
+ $asset = $this->getInnerIterator()->current(true);
+ $duplicate = false;
+
+ // check strict equality
+ if (in_array($asset, $this->visited, true)) {
+ $duplicate = true;
+ } else {
+ $this->visited[] = $asset;
+ }
+
+ // check source
+ $sourceRoot = $asset->getSourceRoot();
+ $sourcePath = $asset->getSourcePath();
+ if ($sourceRoot && $sourcePath) {
+ $source = $sourceRoot.'/'.$sourcePath;
+ if (in_array($source, $this->sources)) {
+ $duplicate = true;
+ } else {
+ $this->sources[] = $source;
+ }
+ }
+
+ return !$duplicate;
+ }
+
+ /**
+ * Passes visited objects and source URLs to the child iterator.
+ */
+ public function getChildren()
+ {
+ return new self($this->getInnerIterator()->getChildren(), $this->visited, $this->sources);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/Iterator/AssetCollectionIterator.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/Iterator/AssetCollectionIterator.php
new file mode 100644
index 0000000..e4cf128
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/Iterator/AssetCollectionIterator.php
@@ -0,0 +1,128 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Asset\Iterator;
+
+use Assetic\Asset\AssetCollectionInterface;
+
+/**
+ * Iterates over an asset collection.
+ *
+ * The iterator is responsible for cascading filters and target URL patterns
+ * from parent to child assets.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class AssetCollectionIterator implements \RecursiveIterator
+{
+ private $assets;
+ private $filters;
+ private $vars;
+ private $output;
+ private $clones;
+
+ public function __construct(AssetCollectionInterface $coll, \SplObjectStorage $clones)
+ {
+ $this->assets = $coll->all();
+ $this->filters = $coll->getFilters();
+ $this->vars = $coll->getVars();
+ $this->output = $coll->getTargetPath();
+ $this->clones = $clones;
+
+ if (false === $pos = strrpos($this->output, '.')) {
+ $this->output .= '_*';
+ } else {
+ $this->output = substr($this->output, 0, $pos).'_*'.substr($this->output, $pos);
+ }
+ }
+
+ /**
+ * Returns a copy of the current asset with filters and a target URL applied.
+ *
+ * @param Boolean $raw Returns the unmodified asset if true
+ *
+ * @return \Assetic\Asset\AssetInterface
+ */
+ public function current($raw = false)
+ {
+ $asset = current($this->assets);
+
+ if ($raw) {
+ return $asset;
+ }
+
+ // clone once
+ if (!isset($this->clones[$asset])) {
+ $clone = $this->clones[$asset] = clone $asset;
+
+ // generate a target path based on asset name
+ $name = sprintf('%s_%d', pathinfo($asset->getSourcePath(), PATHINFO_FILENAME) ?: 'part', $this->key() + 1);
+
+ $name = $this->removeDuplicateVar($name);
+
+ $clone->setTargetPath(str_replace('*', $name, $this->output));
+ } else {
+ $clone = $this->clones[$asset];
+ }
+
+ // cascade filters
+ foreach ($this->filters as $filter) {
+ $clone->ensureFilter($filter);
+ }
+
+ return $clone;
+ }
+
+ public function key()
+ {
+ return key($this->assets);
+ }
+
+ public function next()
+ {
+ return next($this->assets);
+ }
+
+ public function rewind()
+ {
+ return reset($this->assets);
+ }
+
+ public function valid()
+ {
+ return false !== current($this->assets);
+ }
+
+ public function hasChildren()
+ {
+ return current($this->assets) instanceof AssetCollectionInterface;
+ }
+
+ /**
+ * @uses current()
+ */
+ public function getChildren()
+ {
+ return new self($this->current(), $this->clones);
+ }
+
+ private function removeDuplicateVar($name)
+ {
+ foreach ($this->vars as $var) {
+ $var = '{'.$var.'}';
+ if (false !== strpos($name, $var) && false !== strpos($this->output, $var)) {
+ $name = str_replace($var, '', $name);
+ }
+ }
+
+ return $name;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/StringAsset.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/StringAsset.php
new file mode 100644
index 0000000..d9b9a88
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Asset/StringAsset.php
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Asset;
+
+use Assetic\Filter\FilterInterface;
+
+/**
+ * Represents a string asset.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class StringAsset extends BaseAsset
+{
+ private $string;
+ private $lastModified;
+
+ /**
+ * Constructor.
+ *
+ * @param string $content The content of the asset
+ * @param array $filters Filters for the asset
+ * @param string $sourceRoot The source asset root directory
+ * @param string $sourcePath The source asset path
+ */
+ public function __construct($content, $filters = array(), $sourceRoot = null, $sourcePath = null)
+ {
+ $this->string = $content;
+
+ parent::__construct($filters, $sourceRoot, $sourcePath);
+ }
+
+ public function load(FilterInterface $additionalFilter = null)
+ {
+ $this->doLoad($this->string, $additionalFilter);
+ }
+
+ public function setLastModified($lastModified)
+ {
+ $this->lastModified = $lastModified;
+ }
+
+ public function getLastModified()
+ {
+ return $this->lastModified;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/AssetManager.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/AssetManager.php
new file mode 100644
index 0000000..9b8ee12
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/AssetManager.php
@@ -0,0 +1,89 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * Manages assets.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class AssetManager
+{
+ private $assets = array();
+
+ /**
+ * Gets an asset by name.
+ *
+ * @param string $name The asset name
+ *
+ * @return AssetInterface The asset
+ *
+ * @throws \InvalidArgumentException If there is no asset by that name
+ */
+ public function get($name)
+ {
+ if (!isset($this->assets[$name])) {
+ throw new \InvalidArgumentException(sprintf('There is no "%s" asset.', $name));
+ }
+
+ return $this->assets[$name];
+ }
+
+ /**
+ * Checks if the current asset manager has a certain asset.
+ *
+ * @param string $name an asset name
+ *
+ * @return Boolean True if the asset has been set, false if not
+ */
+ public function has($name)
+ {
+ return isset($this->assets[$name]);
+ }
+
+ /**
+ * Registers an asset to the current asset manager.
+ *
+ * @param string $name The asset name
+ * @param AssetInterface $asset The asset
+ *
+ * @throws \InvalidArgumentException If the asset name is invalid
+ */
+ public function set($name, AssetInterface $asset)
+ {
+ if (!ctype_alnum(str_replace('_', '', $name))) {
+ throw new \InvalidArgumentException(sprintf('The name "%s" is invalid.', $name));
+ }
+
+ $this->assets[$name] = $asset;
+ }
+
+ /**
+ * Returns an array of asset names.
+ *
+ * @return array An array of asset names
+ */
+ public function getNames()
+ {
+ return array_keys($this->assets);
+ }
+
+ /**
+ * Clears all assets.
+ */
+ public function clear()
+ {
+ $this->assets = array();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/AssetWriter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/AssetWriter.php
new file mode 100644
index 0000000..4f010a4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/AssetWriter.php
@@ -0,0 +1,94 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Util\VarUtils;
+
+/**
+ * Writes assets to the filesystem.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class AssetWriter
+{
+ private $dir;
+ private $values;
+
+ /**
+ * Constructor.
+ *
+ * @param string $dir The base web directory
+ * @param array $values Variable values
+ *
+ * @throws \InvalidArgumentException if a variable value is not a string
+ */
+ public function __construct($dir, array $values = array())
+ {
+ foreach ($values as $var => $vals) {
+ foreach ($vals as $value) {
+ if (!is_string($value)) {
+ throw new \InvalidArgumentException(sprintf('All variable values must be strings, but got %s for variable "%s".', json_encode($value), $var));
+ }
+ }
+ }
+
+ $this->dir = $dir;
+ $this->values = $values;
+ }
+
+ public function writeManagerAssets(AssetManager $am)
+ {
+ foreach ($am->getNames() as $name) {
+ $this->writeAsset($am->get($name));
+ }
+ }
+
+ public function writeAsset(AssetInterface $asset)
+ {
+ foreach (VarUtils::getCombinations($asset->getVars(), $this->values) as $combination) {
+ $asset->setValues($combination);
+
+ static::write(
+ $this->dir.'/'.VarUtils::resolve(
+ $asset->getTargetPath(),
+ $asset->getVars(),
+ $asset->getValues()
+ ),
+ $asset->dump()
+ );
+ }
+ }
+
+ protected static function write($path, $contents)
+ {
+ if (!is_dir($dir = dirname($path)) && false === @mkdir($dir, 0777, true)) {
+ throw new \RuntimeException('Unable to create directory '.$dir);
+ }
+
+ if (false === @file_put_contents($path, $contents)) {
+ throw new \RuntimeException('Unable to write file '.$path);
+ }
+ }
+
+ /**
+ * Not used.
+ *
+ * This method is provided for backward compatibility with certain versions
+ * of AsseticBundle.
+ */
+ private function getCombinations(array $vars)
+ {
+ return VarUtils::getCombinations($vars, $this->values);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Cache/ApcCache.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Cache/ApcCache.php
new file mode 100644
index 0000000..8c7aa11
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Cache/ApcCache.php
@@ -0,0 +1,66 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Cache;
+
+/**
+ * Uses APC to cache files
+ *
+ * @author André Roaldseth <andre@roaldseth.net>
+ */
+class ApcCache implements CacheInterface
+{
+ public $ttl = 0;
+
+ /**
+ * @see CacheInterface::has()
+ */
+ public function has($key)
+ {
+ return apc_exists($key);
+ }
+
+ /**
+ * @see CacheInterface::get()
+ */
+ public function get($key)
+ {
+ $value = apc_fetch($key, $success);
+
+ if (!$success) {
+ throw new \RuntimeException('There is no cached value for '.$key);
+ }
+
+ return $value;
+ }
+
+ /**
+ * @see CacheInterface::set()
+ */
+ public function set($key, $value)
+ {
+ $store = apc_store($key, $value, $this->ttl);
+
+ if (!$store) {
+ throw new \RuntimeException('Unable to store "'.$key.'" for '.$this->ttl.' seconds.');
+ }
+
+ return $store;
+ }
+
+ /**
+ * @see CacheInterface::remove()
+ */
+ public function remove($key)
+ {
+ return apc_delete($key);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Cache/ArrayCache.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Cache/ArrayCache.php
new file mode 100644
index 0000000..7f357ac
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Cache/ArrayCache.php
@@ -0,0 +1,58 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Cache;
+
+/**
+ * A simple array cache
+ *
+ * @author Michael Mifsud <xzyfer@gmail.com>
+ */
+class ArrayCache implements CacheInterface
+{
+ private $cache = array();
+
+ /**
+ * @see CacheInterface::has()
+ */
+ public function has($key)
+ {
+ return isset($this->cache[$key]);
+ }
+
+ /**
+ * @see CacheInterface::get()
+ */
+ public function get($key)
+ {
+ if (!$this->has($key)) {
+ throw new \RuntimeException('There is no cached value for '.$key);
+ }
+
+ return $this->cache[$key];
+ }
+
+ /**
+ * @see CacheInterface::set()
+ */
+ public function set($key, $value)
+ {
+ $this->cache[$key] = $value;
+ }
+
+ /**
+ * @see CacheInterface::remove()
+ */
+ public function remove($key)
+ {
+ unset($this->cache[$key]);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Cache/CacheInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Cache/CacheInterface.php
new file mode 100644
index 0000000..be13310
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Cache/CacheInterface.php
@@ -0,0 +1,53 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Cache;
+
+/**
+ * Interface for a cache backend.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+interface CacheInterface
+{
+ /**
+ * Checks if the cache has a value for a key.
+ *
+ * @param string $key A unique key
+ *
+ * @return Boolean Whether the cache has a value for this key
+ */
+ public function has($key);
+
+ /**
+ * Returns the value for a key.
+ *
+ * @param string $key A unique key
+ *
+ * @return string|null The value in the cache
+ */
+ public function get($key);
+
+ /**
+ * Sets a value in the cache.
+ *
+ * @param string $key A unique key
+ * @param string $value The value to cache
+ */
+ public function set($key, $value);
+
+ /**
+ * Removes a value from the cache.
+ *
+ * @param string $key A unique key
+ */
+ public function remove($key);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Cache/ConfigCache.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Cache/ConfigCache.php
new file mode 100644
index 0000000..e285e0b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Cache/ConfigCache.php
@@ -0,0 +1,123 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Cache;
+
+/**
+ * A config cache stores values using var_export() and include.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class ConfigCache
+{
+ private $dir;
+
+ /**
+ * Construct.
+ *
+ * @param string $dir The cache directory
+ */
+ public function __construct($dir)
+ {
+ $this->dir = $dir;
+ }
+
+ /**
+ * Checks of the cache has a file.
+ *
+ * @param string $resource A cache key
+ *
+ * @return Boolean True if a file exists
+ */
+ public function has($resource)
+ {
+ return file_exists($this->getSourcePath($resource));
+ }
+
+ /**
+ * Writes a value to a file.
+ *
+ * @param string $resource A cache key
+ * @param mixed $value A value to cache
+ */
+ public function set($resource, $value)
+ {
+ $path = $this->getSourcePath($resource);
+
+ if (!is_dir($dir = dirname($path)) && false === @mkdir($dir, 0777, true)) {
+ // @codeCoverageIgnoreStart
+ throw new \RuntimeException('Unable to create directory '.$dir);
+ // @codeCoverageIgnoreEnd
+ }
+
+ if (false === @file_put_contents($path, sprintf("<?php\n\n// $resource\nreturn %s;\n", var_export($value, true)))) {
+ // @codeCoverageIgnoreStart
+ throw new \RuntimeException('Unable to write file '.$path);
+ // @codeCoverageIgnoreEnd
+ }
+ }
+
+ /**
+ * Loads and returns the value for the supplied cache key.
+ *
+ * @param string $resource A cache key
+ *
+ * @return mixed The cached value
+ */
+ public function get($resource)
+ {
+ $path = $this->getSourcePath($resource);
+
+ if (!file_exists($path)) {
+ throw new \RuntimeException('There is no cached value for '.$resource);
+ }
+
+ return include $path;
+ }
+
+ /**
+ * Returns a timestamp for when the cache was created.
+ *
+ * @param string $resource A cache key
+ *
+ * @return integer A UNIX timestamp
+ */
+ public function getTimestamp($resource)
+ {
+ $path = $this->getSourcePath($resource);
+
+ if (!file_exists($path)) {
+ throw new \RuntimeException('There is no cached value for '.$resource);
+ }
+
+ if (false === $mtime = @filemtime($path)) {
+ // @codeCoverageIgnoreStart
+ throw new \RuntimeException('Unable to determine file mtime for '.$path);
+ // @codeCoverageIgnoreEnd
+ }
+
+ return $mtime;
+ }
+
+ /**
+ * Returns the path where the file corresponding to the supplied cache key can be included from.
+ *
+ * @param string $resource A cache key
+ *
+ * @return string A file path
+ */
+ private function getSourcePath($resource)
+ {
+ $key = md5($resource);
+
+ return $this->dir.'/'.$key[0].'/'.$key.'.php';
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Cache/ExpiringCache.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Cache/ExpiringCache.php
new file mode 100644
index 0000000..46ef85f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Cache/ExpiringCache.php
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Cache;
+
+/**
+ * Adds expiration to a cache backend.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class ExpiringCache implements CacheInterface
+{
+ private $cache;
+ private $lifetime;
+
+ public function __construct(CacheInterface $cache, $lifetime)
+ {
+ $this->cache = $cache;
+ $this->lifetime = $lifetime;
+ }
+
+ public function has($key)
+ {
+ if ($this->cache->has($key)) {
+ if (time() < $this->cache->get($key.'.expires')) {
+ return true;
+ }
+
+ $this->cache->remove($key.'.expires');
+ $this->cache->remove($key);
+ }
+
+ return false;
+ }
+
+ public function get($key)
+ {
+ return $this->cache->get($key);
+ }
+
+ public function set($key, $value)
+ {
+ $this->cache->set($key.'.expires', time() + $this->lifetime);
+ $this->cache->set($key, $value);
+ }
+
+ public function remove($key)
+ {
+ $this->cache->remove($key.'.expires');
+ $this->cache->remove($key);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Cache/FilesystemCache.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Cache/FilesystemCache.php
new file mode 100644
index 0000000..f8eddfd
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Cache/FilesystemCache.php
@@ -0,0 +1,65 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Cache;
+
+/**
+ * A simple filesystem cache.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class FilesystemCache implements CacheInterface
+{
+ private $dir;
+
+ public function __construct($dir)
+ {
+ $this->dir = $dir;
+ }
+
+ public function has($key)
+ {
+ return file_exists($this->dir.'/'.$key);
+ }
+
+ public function get($key)
+ {
+ $path = $this->dir.'/'.$key;
+
+ if (!file_exists($path)) {
+ throw new \RuntimeException('There is no cached value for '.$key);
+ }
+
+ return file_get_contents($path);
+ }
+
+ public function set($key, $value)
+ {
+ if (!is_dir($this->dir) && false === @mkdir($this->dir, 0777, true)) {
+ throw new \RuntimeException('Unable to create directory '.$this->dir);
+ }
+
+ $path = $this->dir.'/'.$key;
+
+ if (false === @file_put_contents($path, $value)) {
+ throw new \RuntimeException('Unable to write file '.$path);
+ }
+ }
+
+ public function remove($key)
+ {
+ $path = $this->dir.'/'.$key;
+
+ if (file_exists($path) && false === @unlink($path)) {
+ throw new \RuntimeException('Unable to remove file '.$path);
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Exception/Exception.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Exception/Exception.php
new file mode 100644
index 0000000..1bd4acc
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Exception/Exception.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Exception;
+
+/**
+ * Marker.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+interface Exception
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Exception/FilterException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Exception/FilterException.php
new file mode 100644
index 0000000..03a230b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Exception/FilterException.php
@@ -0,0 +1,73 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Exception;
+
+use Symfony\Component\Process\Process;
+
+/**
+ * Describes an exception that occurred within a filter.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class FilterException extends \RuntimeException implements Exception
+{
+ private $originalMessage;
+ private $input;
+
+ public static function fromProcess(Process $proc)
+ {
+ $message = sprintf("An error occurred while running:\n%s", $proc->getCommandLine());
+
+ $errorOutput = $proc->getErrorOutput();
+ if (!empty($errorOutput)) {
+ $message .= "\n\nError Output:\n".str_replace("\r", '', $errorOutput);
+ }
+
+ $output = $proc->getOutput();
+ if (!empty($output)) {
+ $message .= "\n\nOutput:\n".str_replace("\r", '', $output);
+ }
+
+ return new self($message);
+ }
+
+ public function __construct($message, $code = 0, \Exception $previous = null)
+ {
+ parent::__construct($message, $code, $previous);
+
+ $this->originalMessage = $message;
+ }
+
+ public function setInput($input)
+ {
+ $this->input = $input;
+ $this->updateMessage();
+
+ return $this;
+ }
+
+ public function getInput()
+ {
+ return $this->input;
+ }
+
+ private function updateMessage()
+ {
+ $message = $this->originalMessage;
+
+ if (!empty($this->input)) {
+ $message .= "\n\nInput:\n".$this->input;
+ }
+
+ $this->message = $message;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticExtension.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticExtension.php
new file mode 100644
index 0000000..951e1c8
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticExtension.php
@@ -0,0 +1,76 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Extension\Twig;
+
+use Assetic\Factory\AssetFactory;
+use Assetic\ValueSupplierInterface;
+
+class AsseticExtension extends \Twig_Extension implements \Twig_Extension_GlobalsInterface
+{
+ protected $factory;
+ protected $functions;
+ protected $valueSupplier;
+
+ public function __construct(AssetFactory $factory, $functions = array(), ValueSupplierInterface $valueSupplier = null)
+ {
+ $this->factory = $factory;
+ $this->functions = array();
+ $this->valueSupplier = $valueSupplier;
+
+ foreach ($functions as $function => $options) {
+ if (is_integer($function) && is_string($options)) {
+ $this->functions[$options] = array('filter' => $options);
+ } else {
+ $this->functions[$function] = $options + array('filter' => $function);
+ }
+ }
+ }
+
+ public function getTokenParsers()
+ {
+ return array(
+ new AsseticTokenParser($this->factory, 'javascripts', 'js/*.js'),
+ new AsseticTokenParser($this->factory, 'stylesheets', 'css/*.css'),
+ new AsseticTokenParser($this->factory, 'image', 'images/*', true),
+ );
+ }
+
+ public function getFunctions()
+ {
+ $functions = array();
+ foreach ($this->functions as $function => $filter) {
+ $functions[] = new AsseticFilterFunction($function);
+ }
+
+ return $functions;
+ }
+
+ public function getGlobals()
+ {
+ return array(
+ 'assetic' => array(
+ 'debug' => $this->factory->isDebug(),
+ 'vars' => null !== $this->valueSupplier ? new ValueContainer($this->valueSupplier) : array(),
+ ),
+ );
+ }
+
+ public function getFilterInvoker($function)
+ {
+ return new AsseticFilterInvoker($this->factory, $this->functions[$function]);
+ }
+
+ public function getName()
+ {
+ return 'assetic';
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterFunction.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterFunction.php
new file mode 100644
index 0000000..2c2b13c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterFunction.php
@@ -0,0 +1,24 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Extension\Twig;
+
+class AsseticFilterFunction extends \Twig_SimpleFunction
+{
+ public function __construct($name, $options = array())
+ {
+ parent::__construct($name, null, array_merge($options, array(
+ 'needs_environment' => false,
+ 'needs_context' => false,
+ 'node_class' => '\Assetic\Extension\Twig\AsseticFilterNode',
+ )));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterInvoker.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterInvoker.php
new file mode 100644
index 0000000..1b70e43
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterInvoker.php
@@ -0,0 +1,59 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Extension\Twig;
+
+/**
+ * Filters a single asset.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class AsseticFilterInvoker
+{
+ private $factory;
+ private $filters;
+ private $options;
+
+ public function __construct($factory, $filter)
+ {
+ $this->factory = $factory;
+
+ if (is_array($filter) && isset($filter['filter'])) {
+ $this->filters = (array) $filter['filter'];
+ $this->options = isset($filter['options']) ? (array) $filter['options'] : array();
+ } else {
+ $this->filters = (array) $filter;
+ $this->options = array();
+ }
+ }
+
+ public function getFactory()
+ {
+ return $this->factory;
+ }
+
+ public function getFilters()
+ {
+ return $this->filters;
+ }
+
+ public function getOptions()
+ {
+ return $this->options;
+ }
+
+ public function invoke($input, array $options = array())
+ {
+ $asset = $this->factory->createAsset($input, $this->filters, $options + $this->options);
+
+ return $asset->getTargetPath();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterNode.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterNode.php
new file mode 100644
index 0000000..3fe05ac
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterNode.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Extension\Twig;
+
+class AsseticFilterNode extends \Twig_Node_Expression_Function
+{
+ protected function compileCallable(\Twig_Compiler $compiler)
+ {
+ $compiler->raw(sprintf('$this->env->getExtension(\'Assetic\\Extension\\Twig\\AsseticExtension\')->getFilterInvoker(\'%s\')->invoke', $this->getAttribute('name')));
+
+ $this->compileArguments($compiler);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticNode.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticNode.php
new file mode 100644
index 0000000..950e46c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticNode.php
@@ -0,0 +1,165 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Extension\Twig;
+
+use Assetic\Asset\AssetInterface;
+
+class AsseticNode extends \Twig_Node
+{
+ /**
+ * Constructor.
+ *
+ * Available attributes:
+ *
+ * * debug: The debug mode
+ * * combine: Whether to combine assets
+ * * var_name: The name of the variable to expose to the body node
+ *
+ * @param AssetInterface $asset The asset
+ * @param \Twig_Node $body The body node
+ * @param array $inputs An array of input strings
+ * @param array $filters An array of filter strings
+ * @param string $name The name of the asset
+ * @param array $attributes An array of attributes
+ * @param integer $lineno The line number
+ * @param string $tag The tag name
+ */
+ public function __construct(AssetInterface $asset, \Twig_Node $body, array $inputs, array $filters, $name, array $attributes = array(), $lineno = 0, $tag = null)
+ {
+ $nodes = array('body' => $body);
+
+ $attributes = array_replace(
+ array('debug' => null, 'combine' => null, 'var_name' => 'asset_url'),
+ $attributes,
+ array('asset' => $asset, 'inputs' => $inputs, 'filters' => $filters, 'name' => $name)
+ );
+
+ parent::__construct($nodes, $attributes, $lineno, $tag);
+ }
+
+ public function compile(\Twig_Compiler $compiler)
+ {
+ $compiler->addDebugInfo($this);
+
+ $combine = $this->getAttribute('combine');
+ $debug = $this->getAttribute('debug');
+
+ if (null === $combine && null !== $debug) {
+ $combine = !$debug;
+ }
+
+ if (null === $combine) {
+ $compiler
+ ->write("if (isset(\$context['assetic']['debug']) && \$context['assetic']['debug']) {\n")
+ ->indent()
+ ;
+
+ $this->compileDebug($compiler);
+
+ $compiler
+ ->outdent()
+ ->write("} else {\n")
+ ->indent()
+ ;
+
+ $this->compileAsset($compiler, $this->getAttribute('asset'), $this->getAttribute('name'));
+
+ $compiler
+ ->outdent()
+ ->write("}\n")
+ ;
+ } elseif ($combine) {
+ $this->compileAsset($compiler, $this->getAttribute('asset'), $this->getAttribute('name'));
+ } else {
+ $this->compileDebug($compiler);
+ }
+
+ $compiler
+ ->write('unset($context[')
+ ->repr($this->getAttribute('var_name'))
+ ->raw("]);\n")
+ ;
+ }
+
+ protected function compileDebug(\Twig_Compiler $compiler)
+ {
+ $i = 0;
+ foreach ($this->getAttribute('asset') as $leaf) {
+ $leafName = $this->getAttribute('name').'_'.$i++;
+ $this->compileAsset($compiler, $leaf, $leafName);
+ }
+ }
+
+ protected function compileAsset(\Twig_Compiler $compiler, AssetInterface $asset, $name)
+ {
+ if ($vars = $asset->getVars()) {
+ $compiler->write("// check variable conditions\n");
+
+ foreach ($vars as $var) {
+ $compiler
+ ->write("if (!isset(\$context['assetic']['vars']['$var'])) {\n")
+ ->indent()
+ ->write("throw new \RuntimeException(sprintf('The asset \"".$name."\" expected variable \"".$var."\" to be set, but got only these vars: %s. Did you set-up a value supplier?', isset(\$context['assetic']['vars']) && \$context['assetic']['vars'] ? implode(', ', \$context['assetic']['vars']) : '# none #'));\n")
+ ->outdent()
+ ->write("}\n")
+ ;
+ }
+
+ $compiler->raw("\n");
+ }
+
+ $compiler
+ ->write("// asset \"$name\"\n")
+ ->write('$context[')
+ ->repr($this->getAttribute('var_name'))
+ ->raw('] = ')
+ ;
+
+ $this->compileAssetUrl($compiler, $asset, $name);
+
+ $compiler
+ ->raw(";\n")
+ ->subcompile($this->getNode('body'))
+ ;
+ }
+
+ protected function compileAssetUrl(\Twig_Compiler $compiler, AssetInterface $asset, $name)
+ {
+ if (!$vars = $asset->getVars()) {
+ $compiler->repr($asset->getTargetPath());
+
+ return;
+ }
+
+ $compiler
+ ->raw("strtr(")
+ ->string($asset->getTargetPath())
+ ->raw(", array(");
+
+ $first = true;
+ foreach ($vars as $var) {
+ if (!$first) {
+ $compiler->raw(", ");
+ }
+ $first = false;
+
+ $compiler
+ ->string("{".$var."}")
+ ->raw(" => \$context['assetic']['vars']['$var']")
+ ;
+ }
+
+ $compiler
+ ->raw("))")
+ ;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticTokenParser.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticTokenParser.php
new file mode 100644
index 0000000..614f567
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticTokenParser.php
@@ -0,0 +1,198 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Extension\Twig;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Factory\AssetFactory;
+
+class AsseticTokenParser extends \Twig_TokenParser
+{
+ private $factory;
+ private $tag;
+ private $output;
+ private $single;
+ private $extensions;
+
+ /**
+ * Constructor.
+ *
+ * Attributes can be added to the tag by passing names as the options
+ * array. These values, if found, will be passed to the factory and node.
+ *
+ * @param AssetFactory $factory The asset factory
+ * @param string $tag The tag name
+ * @param string $output The default output string
+ * @param Boolean $single Whether to force a single asset
+ * @param array $extensions Additional attribute names to look for
+ */
+ public function __construct(AssetFactory $factory, $tag, $output, $single = false, array $extensions = array())
+ {
+ $this->factory = $factory;
+ $this->tag = $tag;
+ $this->output = $output;
+ $this->single = $single;
+ $this->extensions = $extensions;
+ }
+
+ public function parse(\Twig_Token $token)
+ {
+ $inputs = array();
+ $filters = array();
+ $name = null;
+ $attributes = array(
+ 'output' => $this->output,
+ 'var_name' => 'asset_url',
+ 'vars' => array(),
+ );
+
+ $stream = $this->parser->getStream();
+ while (!$stream->test(\Twig_Token::BLOCK_END_TYPE)) {
+ if ($stream->test(\Twig_Token::STRING_TYPE)) {
+ // '@jquery', 'js/src/core/*', 'js/src/extra.js'
+ $inputs[] = $stream->next()->getValue();
+ } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'filter')) {
+ // filter='yui_js'
+ $stream->next();
+ $stream->expect(\Twig_Token::OPERATOR_TYPE, '=');
+ $filters = array_merge($filters, array_filter(array_map('trim', explode(',', $stream->expect(\Twig_Token::STRING_TYPE)->getValue()))));
+ } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'output')) {
+ // output='js/packed/*.js' OR output='js/core.js'
+ $stream->next();
+ $stream->expect(\Twig_Token::OPERATOR_TYPE, '=');
+ $attributes['output'] = $stream->expect(\Twig_Token::STRING_TYPE)->getValue();
+ } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'name')) {
+ // name='core_js'
+ $stream->next();
+ $stream->expect(\Twig_Token::OPERATOR_TYPE, '=');
+ $name = $stream->expect(\Twig_Token::STRING_TYPE)->getValue();
+ } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'as')) {
+ // as='the_url'
+ $stream->next();
+ $stream->expect(\Twig_Token::OPERATOR_TYPE, '=');
+ $attributes['var_name'] = $stream->expect(\Twig_Token::STRING_TYPE)->getValue();
+ } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'debug')) {
+ // debug=true
+ $stream->next();
+ $stream->expect(\Twig_Token::OPERATOR_TYPE, '=');
+ $attributes['debug'] = 'true' == $stream->expect(\Twig_Token::NAME_TYPE, array('true', 'false'))->getValue();
+ } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'combine')) {
+ // combine=true
+ $stream->next();
+ $stream->expect(\Twig_Token::OPERATOR_TYPE, '=');
+ $attributes['combine'] = 'true' == $stream->expect(\Twig_Token::NAME_TYPE, array('true', 'false'))->getValue();
+ } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'vars')) {
+ // vars=['locale','browser']
+ $stream->next();
+ $stream->expect(\Twig_Token::OPERATOR_TYPE, '=');
+ $stream->expect(\Twig_Token::PUNCTUATION_TYPE, '[');
+
+ while ($stream->test(\Twig_Token::STRING_TYPE)) {
+ $attributes['vars'][] = $stream->expect(\Twig_Token::STRING_TYPE)->getValue();
+
+ if (!$stream->test(\Twig_Token::PUNCTUATION_TYPE, ',')) {
+ break;
+ }
+
+ $stream->next();
+ }
+
+ $stream->expect(\Twig_Token::PUNCTUATION_TYPE, ']');
+ } elseif ($stream->test(\Twig_Token::NAME_TYPE, $this->extensions)) {
+ // an arbitrary configured attribute
+ $key = $stream->next()->getValue();
+ $stream->expect(\Twig_Token::OPERATOR_TYPE, '=');
+ $attributes[$key] = $stream->expect(\Twig_Token::STRING_TYPE)->getValue();
+ } else {
+ $token = $stream->getCurrent();
+ throw new \Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s"', \Twig_Token::typeToEnglish($token->getType()), $token->getValue()), $token->getLine(), $stream->getFilename());
+ }
+ }
+
+ $stream->expect(\Twig_Token::BLOCK_END_TYPE);
+
+ $body = $this->parser->subparse(array($this, 'testEndTag'), true);
+
+ $stream->expect(\Twig_Token::BLOCK_END_TYPE);
+
+ if ($this->single && 1 < count($inputs)) {
+ $inputs = array_slice($inputs, -1);
+ }
+
+ if (!$name) {
+ $name = $this->factory->generateAssetName($inputs, $filters, $attributes);
+ }
+
+ $asset = $this->factory->createAsset($inputs, $filters, $attributes + array('name' => $name));
+
+ return $this->createBodyNode($asset, $body, $inputs, $filters, $name, $attributes, $token->getLine(), $this->getTag());
+ }
+
+ public function getTag()
+ {
+ return $this->tag;
+ }
+
+ public function testEndTag(\Twig_Token $token)
+ {
+ return $token->test(array('end'.$this->getTag()));
+ }
+
+ /**
+ * @param AssetInterface $asset
+ * @param \Twig_Node $body
+ * @param array $inputs
+ * @param array $filters
+ * @param string $name
+ * @param array $attributes
+ * @param int $lineno
+ * @param string $tag
+ *
+ * @return \Twig_Node
+ */
+ protected function createBodyNode(AssetInterface $asset, \Twig_Node $body, array $inputs, array $filters, $name, array $attributes = array(), $lineno = 0, $tag = null)
+ {
+ $reflector = new \ReflectionMethod($this, 'createNode');
+
+ if (__CLASS__ !== $reflector->getDeclaringClass()->name) {
+ @trigger_error(sprintf('Overwriting %s::createNode is deprecated since 1.3. Overwrite %s instead.', __CLASS__, __METHOD__), E_USER_DEPRECATED);
+
+ return $this->createNode($asset, $body, $inputs, $filters, $name, $attributes, $lineno, $tag);
+ }
+
+ return new AsseticNode($asset, $body, $inputs, $filters, $name, $attributes, $lineno, $tag);
+ }
+
+ /**
+ * @param AssetInterface $asset
+ * @param \Twig_NodeInterface $body
+ * @param array $inputs
+ * @param array $filters
+ * @param string $name
+ * @param array $attributes
+ * @param int $lineno
+ * @param string $tag
+ *
+ * @return \Twig_Node
+ *
+ * @deprecated since 1.3.0, to be removed in 2.0. Use createBodyNode instead.
+ */
+ protected function createNode(AssetInterface $asset, \Twig_NodeInterface $body, array $inputs, array $filters, $name, array $attributes = array(), $lineno = 0, $tag = null)
+ {
+ @trigger_error(sprintf('The %s method is deprecated since 1.3 and will be removed in 2.0. Use createBodyNode instead.', __METHOD__), E_USER_DEPRECATED);
+
+ if (!$body instanceof \Twig_Node) {
+ throw new \InvalidArgumentException('The body must be a Twig_Node. Custom implementations of Twig_NodeInterface are not supported.');
+ }
+
+ return new AsseticNode($asset, $body, $inputs, $filters, $name, $attributes, $lineno, $tag);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/TwigFormulaLoader.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/TwigFormulaLoader.php
new file mode 100644
index 0000000..2c12d7e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/TwigFormulaLoader.php
@@ -0,0 +1,108 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Extension\Twig;
+
+use Assetic\Factory\Loader\FormulaLoaderInterface;
+use Assetic\Factory\Resource\ResourceInterface;
+use Psr\Log\LoggerInterface;
+
+/**
+ * Loads asset formulae from Twig templates.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class TwigFormulaLoader implements FormulaLoaderInterface
+{
+ private $twig;
+ private $logger;
+
+ public function __construct(\Twig_Environment $twig, LoggerInterface $logger = null)
+ {
+ $this->twig = $twig;
+ $this->logger = $logger;
+ }
+
+ public function load(ResourceInterface $resource)
+ {
+ try {
+ $tokens = $this->twig->tokenize(new \Twig_Source($resource->getContent(), (string) $resource));
+ $nodes = $this->twig->parse($tokens);
+ } catch (\Exception $e) {
+ if ($this->logger) {
+ $this->logger->error(sprintf('The template "%s" contains an error: %s', $resource, $e->getMessage()));
+ }
+
+ return array();
+ }
+
+ return $this->loadNode($nodes);
+ }
+
+ /**
+ * Loads assets from the supplied node.
+ *
+ * @param \Twig_Node $node
+ *
+ * @return array An array of asset formulae indexed by name
+ */
+ private function loadNode(\Twig_Node $node)
+ {
+ $formulae = array();
+
+ if ($node instanceof AsseticNode) {
+ $formulae[$node->getAttribute('name')] = array(
+ $node->getAttribute('inputs'),
+ $node->getAttribute('filters'),
+ array(
+ 'output' => $node->getAttribute('asset')->getTargetPath(),
+ 'name' => $node->getAttribute('name'),
+ 'debug' => $node->getAttribute('debug'),
+ 'combine' => $node->getAttribute('combine'),
+ 'vars' => $node->getAttribute('vars'),
+ ),
+ );
+ } elseif ($node instanceof AsseticFilterNode) {
+ $name = $node->getAttribute('name');
+
+ $arguments = array();
+ foreach ($node->getNode('arguments') as $argument) {
+ $arguments[] = eval('return '.$this->twig->compile($argument).';');
+ }
+
+ $invoker = $this->twig->getExtension('Assetic\Extension\Twig\AsseticExtension')->getFilterInvoker($name);
+
+ $inputs = isset($arguments[0]) ? (array) $arguments[0] : array();
+ $filters = $invoker->getFilters();
+ $options = array_replace($invoker->getOptions(), isset($arguments[1]) ? $arguments[1] : array());
+
+ if (!isset($options['name'])) {
+ $options['name'] = $invoker->getFactory()->generateAssetName($inputs, $filters, $options);
+ }
+
+ $formulae[$options['name']] = array($inputs, $filters, $options);
+ }
+
+ foreach ($node as $child) {
+ if ($child instanceof \Twig_Node) {
+ $formulae += $this->loadNode($child);
+ }
+ }
+
+ if ($node->hasAttribute('embedded_templates')) {
+ foreach ($node->getAttribute('embedded_templates') as $child) {
+ $formulae += $this->loadNode($child);
+ }
+ }
+
+ return $formulae;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/TwigResource.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/TwigResource.php
new file mode 100644
index 0000000..21d040a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/TwigResource.php
@@ -0,0 +1,56 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Extension\Twig;
+
+use Assetic\Factory\Resource\ResourceInterface;
+
+/**
+ * A Twig template resource.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class TwigResource implements ResourceInterface
+{
+ private $loader;
+ private $name;
+
+ public function __construct(\Twig_LoaderInterface $loader, $name)
+ {
+ $this->loader = $loader;
+ $this->name = $name;
+ }
+
+ public function getContent()
+ {
+ try {
+ return method_exists($this->loader, 'getSourceContext')
+ ? $this->loader->getSourceContext($this->name)->getCode()
+ : $this->loader->getSource($this->name);
+ } catch (\Twig_Error_Loader $e) {
+ return '';
+ }
+ }
+
+ public function isFresh($timestamp)
+ {
+ try {
+ return $this->loader->isFresh($this->name, $timestamp);
+ } catch (\Twig_Error_Loader $e) {
+ return false;
+ }
+ }
+
+ public function __toString()
+ {
+ return $this->name;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/ValueContainer.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/ValueContainer.php
new file mode 100644
index 0000000..e197224
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Extension/Twig/ValueContainer.php
@@ -0,0 +1,79 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Extension\Twig;
+
+use Assetic\ValueSupplierInterface;
+
+/**
+ * Container for values initialized lazily from a ValueSupplierInterface.
+ *
+ * @author Christophe Coevoet <stof@notk.org>
+ */
+class ValueContainer implements \ArrayAccess, \IteratorAggregate, \Countable
+{
+ private $values;
+ private $valueSupplier;
+
+ public function __construct(ValueSupplierInterface $valueSupplier)
+ {
+ $this->valueSupplier = $valueSupplier;
+ }
+
+ public function offsetExists($offset)
+ {
+ $this->initialize();
+
+ return array_key_exists($offset, $this->values);
+ }
+
+ public function offsetGet($offset)
+ {
+ $this->initialize();
+
+ if (!array_key_exists($offset, $this->values)) {
+ throw new \OutOfRangeException(sprintf('The variable "%s" does not exist.', $offset));
+ }
+
+ return $this->values[$offset];
+ }
+
+ public function offsetSet($offset, $value)
+ {
+ throw new \BadMethodCallException('The ValueContainer is read-only.');
+ }
+
+ public function offsetUnset($offset)
+ {
+ throw new \BadMethodCallException('The ValueContainer is read-only.');
+ }
+
+ public function getIterator()
+ {
+ $this->initialize();
+
+ return new \ArrayIterator($this->values);
+ }
+
+ public function count()
+ {
+ $this->initialize();
+
+ return count($this->values);
+ }
+
+ private function initialize()
+ {
+ if (null === $this->values) {
+ $this->values = $this->valueSupplier->getValues();
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/AssetFactory.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/AssetFactory.php
new file mode 100644
index 0000000..e267196
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/AssetFactory.php
@@ -0,0 +1,424 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Factory;
+
+use Assetic\Asset\AssetCollection;
+use Assetic\Asset\AssetCollectionInterface;
+use Assetic\Asset\AssetInterface;
+use Assetic\Asset\AssetReference;
+use Assetic\Asset\FileAsset;
+use Assetic\Asset\GlobAsset;
+use Assetic\Asset\HttpAsset;
+use Assetic\AssetManager;
+use Assetic\Factory\Worker\WorkerInterface;
+use Assetic\Filter\DependencyExtractorInterface;
+use Assetic\FilterManager;
+
+/**
+ * The asset factory creates asset objects.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class AssetFactory
+{
+ private $root;
+ private $debug;
+ private $output;
+ private $workers;
+ private $am;
+ private $fm;
+
+ /**
+ * Constructor.
+ *
+ * @param string $root The default root directory
+ * @param Boolean $debug Filters prefixed with a "?" will be omitted in debug mode
+ */
+ public function __construct($root, $debug = false)
+ {
+ $this->root = rtrim($root, '/');
+ $this->debug = $debug;
+ $this->output = 'assetic/*';
+ $this->workers = array();
+ }
+
+ /**
+ * Sets debug mode for the current factory.
+ *
+ * @param Boolean $debug Debug mode
+ */
+ public function setDebug($debug)
+ {
+ $this->debug = $debug;
+ }
+
+ /**
+ * Checks if the factory is in debug mode.
+ *
+ * @return Boolean Debug mode
+ */
+ public function isDebug()
+ {
+ return $this->debug;
+ }
+
+ /**
+ * Sets the default output string.
+ *
+ * @param string $output The default output string
+ */
+ public function setDefaultOutput($output)
+ {
+ $this->output = $output;
+ }
+
+ /**
+ * Adds a factory worker.
+ *
+ * @param WorkerInterface $worker A worker
+ */
+ public function addWorker(WorkerInterface $worker)
+ {
+ $this->workers[] = $worker;
+ }
+
+ /**
+ * Returns the current asset manager.
+ *
+ * @return AssetManager|null The asset manager
+ */
+ public function getAssetManager()
+ {
+ return $this->am;
+ }
+
+ /**
+ * Sets the asset manager to use when creating asset references.
+ *
+ * @param AssetManager $am The asset manager
+ */
+ public function setAssetManager(AssetManager $am)
+ {
+ $this->am = $am;
+ }
+
+ /**
+ * Returns the current filter manager.
+ *
+ * @return FilterManager|null The filter manager
+ */
+ public function getFilterManager()
+ {
+ return $this->fm;
+ }
+
+ /**
+ * Sets the filter manager to use when adding filters.
+ *
+ * @param FilterManager $fm The filter manager
+ */
+ public function setFilterManager(FilterManager $fm)
+ {
+ $this->fm = $fm;
+ }
+
+ /**
+ * Creates a new asset.
+ *
+ * Prefixing a filter name with a question mark will cause it to be
+ * omitted when the factory is in debug mode.
+ *
+ * Available options:
+ *
+ * * output: An output string
+ * * name: An asset name for interpolation in output patterns
+ * * debug: Forces debug mode on or off for this asset
+ * * root: An array or string of more root directories
+ *
+ * @param array|string $inputs An array of input strings
+ * @param array|string $filters An array of filter names
+ * @param array $options An array of options
+ *
+ * @return AssetCollection An asset collection
+ */
+ public function createAsset($inputs = array(), $filters = array(), array $options = array())
+ {
+ if (!is_array($inputs)) {
+ $inputs = array($inputs);
+ }
+
+ if (!is_array($filters)) {
+ $filters = array($filters);
+ }
+
+ if (!isset($options['output'])) {
+ $options['output'] = $this->output;
+ }
+
+ if (!isset($options['vars'])) {
+ $options['vars'] = array();
+ }
+
+ if (!isset($options['debug'])) {
+ $options['debug'] = $this->debug;
+ }
+
+ if (!isset($options['root'])) {
+ $options['root'] = array($this->root);
+ } else {
+ if (!is_array($options['root'])) {
+ $options['root'] = array($options['root']);
+ }
+
+ $options['root'][] = $this->root;
+ }
+
+ if (!isset($options['name'])) {
+ $options['name'] = $this->generateAssetName($inputs, $filters, $options);
+ }
+
+ $asset = $this->createAssetCollection(array(), $options);
+ $extensions = array();
+
+ // inner assets
+ foreach ($inputs as $input) {
+ if (is_array($input)) {
+ // nested formula
+ $asset->add(call_user_func_array(array($this, 'createAsset'), $input));
+ } else {
+ $asset->add($this->parseInput($input, $options));
+ $extensions[pathinfo($input, PATHINFO_EXTENSION)] = true;
+ }
+ }
+
+ // filters
+ foreach ($filters as $filter) {
+ if ('?' != $filter[0]) {
+ $asset->ensureFilter($this->getFilter($filter));
+ } elseif (!$options['debug']) {
+ $asset->ensureFilter($this->getFilter(substr($filter, 1)));
+ }
+ }
+
+ // append variables
+ if (!empty($options['vars'])) {
+ $toAdd = array();
+ foreach ($options['vars'] as $var) {
+ if (false !== strpos($options['output'], '{'.$var.'}')) {
+ continue;
+ }
+
+ $toAdd[] = '{'.$var.'}';
+ }
+
+ if ($toAdd) {
+ $options['output'] = str_replace('*', '*.'.implode('.', $toAdd), $options['output']);
+ }
+ }
+
+ // append consensus extension if missing
+ if (1 == count($extensions) && !pathinfo($options['output'], PATHINFO_EXTENSION) && $extension = key($extensions)) {
+ $options['output'] .= '.'.$extension;
+ }
+
+ // output --> target url
+ $asset->setTargetPath(str_replace('*', $options['name'], $options['output']));
+
+ // apply workers and return
+ return $this->applyWorkers($asset);
+ }
+
+ public function generateAssetName($inputs, $filters, $options = array())
+ {
+ foreach (array_diff(array_keys($options), array('output', 'debug', 'root')) as $key) {
+ unset($options[$key]);
+ }
+
+ ksort($options);
+
+ return substr(sha1(serialize($inputs).serialize($filters).serialize($options)), 0, 7);
+ }
+
+ public function getLastModified(AssetInterface $asset)
+ {
+ $mtime = 0;
+ foreach ($asset instanceof AssetCollectionInterface ? $asset : array($asset) as $leaf) {
+ $mtime = max($mtime, $leaf->getLastModified());
+
+ if (!$filters = $leaf->getFilters()) {
+ continue;
+ }
+
+ $prevFilters = array();
+ foreach ($filters as $filter) {
+ $prevFilters[] = $filter;
+
+ if (!$filter instanceof DependencyExtractorInterface) {
+ continue;
+ }
+
+ // extract children from leaf after running all preceeding filters
+ $clone = clone $leaf;
+ $clone->clearFilters();
+ foreach (array_slice($prevFilters, 0, -1) as $prevFilter) {
+ $clone->ensureFilter($prevFilter);
+ }
+ $clone->load();
+
+ foreach ($filter->getChildren($this, $clone->getContent(), $clone->getSourceDirectory()) as $child) {
+ $mtime = max($mtime, $this->getLastModified($child));
+ }
+ }
+ }
+
+ return $mtime;
+ }
+
+ /**
+ * Parses an input string string into an asset.
+ *
+ * The input string can be one of the following:
+ *
+ * * A reference: If the string starts with an "at" sign it will be interpreted as a reference to an asset in the asset manager
+ * * An absolute URL: If the string contains "://" or starts with "//" it will be interpreted as an HTTP asset
+ * * A glob: If the string contains a "*" it will be interpreted as a glob
+ * * A path: Otherwise the string is interpreted as a filesystem path
+ *
+ * Both globs and paths will be absolutized using the current root directory.
+ *
+ * @param string $input An input string
+ * @param array $options An array of options
+ *
+ * @return AssetInterface An asset
+ */
+ protected function parseInput($input, array $options = array())
+ {
+ if ('@' == $input[0]) {
+ return $this->createAssetReference(substr($input, 1));
+ }
+
+ if (false !== strpos($input, '://') || 0 === strpos($input, '//')) {
+ return $this->createHttpAsset($input, $options['vars']);
+ }
+
+ if (self::isAbsolutePath($input)) {
+ if ($root = self::findRootDir($input, $options['root'])) {
+ $path = ltrim(substr($input, strlen($root)), '/');
+ } else {
+ $path = null;
+ }
+ } else {
+ $root = $this->root;
+ $path = $input;
+ $input = $this->root.'/'.$path;
+ }
+
+ if (false !== strpos($input, '*')) {
+ return $this->createGlobAsset($input, $root, $options['vars']);
+ }
+
+ return $this->createFileAsset($input, $root, $path, $options['vars']);
+ }
+
+ protected function createAssetCollection(array $assets = array(), array $options = array())
+ {
+ return new AssetCollection($assets, array(), null, isset($options['vars']) ? $options['vars'] : array());
+ }
+
+ protected function createAssetReference($name)
+ {
+ if (!$this->am) {
+ throw new \LogicException('There is no asset manager.');
+ }
+
+ return new AssetReference($this->am, $name);
+ }
+
+ protected function createHttpAsset($sourceUrl, $vars)
+ {
+ return new HttpAsset($sourceUrl, array(), false, $vars);
+ }
+
+ protected function createGlobAsset($glob, $root = null, $vars)
+ {
+ return new GlobAsset($glob, array(), $root, $vars);
+ }
+
+ protected function createFileAsset($source, $root = null, $path = null, $vars)
+ {
+ return new FileAsset($source, array(), $root, $path, $vars);
+ }
+
+ protected function getFilter($name)
+ {
+ if (!$this->fm) {
+ throw new \LogicException('There is no filter manager.');
+ }
+
+ return $this->fm->get($name);
+ }
+
+ /**
+ * Filters an asset collection through the factory workers.
+ *
+ * Each leaf asset will be processed first, followed by the asset
+ * collection itself.
+ *
+ * @param AssetCollectionInterface $asset An asset collection
+ *
+ * @return AssetCollectionInterface
+ */
+ private function applyWorkers(AssetCollectionInterface $asset)
+ {
+ foreach ($asset as $leaf) {
+ foreach ($this->workers as $worker) {
+ $retval = $worker->process($leaf, $this);
+
+ if ($retval instanceof AssetInterface && $leaf !== $retval) {
+ $asset->replaceLeaf($leaf, $retval);
+ }
+ }
+ }
+
+ foreach ($this->workers as $worker) {
+ $retval = $worker->process($asset, $this);
+
+ if ($retval instanceof AssetInterface) {
+ $asset = $retval;
+ }
+ }
+
+ return $asset instanceof AssetCollectionInterface ? $asset : $this->createAssetCollection(array($asset));
+ }
+
+ private static function isAbsolutePath($path)
+ {
+ return '/' == $path[0] || '\\' == $path[0] || (3 < strlen($path) && ctype_alpha($path[0]) && $path[1] == ':' && ('\\' == $path[2] || '/' == $path[2]));
+ }
+
+ /**
+ * Loops through the root directories and returns the first match.
+ *
+ * @param string $path An absolute path
+ * @param array $roots An array of root directories
+ *
+ * @return string|null The matching root directory, if found
+ */
+ private static function findRootDir($path, array $roots)
+ {
+ foreach ($roots as $root) {
+ if (0 === strpos($path, $root)) {
+ return $root;
+ }
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/LazyAssetManager.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/LazyAssetManager.php
new file mode 100644
index 0000000..bef72e5
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/LazyAssetManager.php
@@ -0,0 +1,210 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Factory;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\AssetManager;
+use Assetic\Factory\Loader\FormulaLoaderInterface;
+use Assetic\Factory\Resource\ResourceInterface;
+
+/**
+ * A lazy asset manager is a composition of a factory and many formula loaders.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class LazyAssetManager extends AssetManager
+{
+ private $factory;
+ private $loaders;
+ private $resources;
+ private $formulae;
+ private $loaded;
+ private $loading;
+
+ /**
+ * Constructor.
+ *
+ * @param AssetFactory $factory The asset factory
+ * @param array $loaders An array of loaders indexed by alias
+ */
+ public function __construct(AssetFactory $factory, $loaders = array())
+ {
+ $this->factory = $factory;
+ $this->loaders = array();
+ $this->resources = array();
+ $this->formulae = array();
+ $this->loaded = false;
+ $this->loading = false;
+
+ foreach ($loaders as $alias => $loader) {
+ $this->setLoader($alias, $loader);
+ }
+ }
+
+ /**
+ * Adds a loader to the asset manager.
+ *
+ * @param string $alias An alias for the loader
+ * @param FormulaLoaderInterface $loader A loader
+ */
+ public function setLoader($alias, FormulaLoaderInterface $loader)
+ {
+ $this->loaders[$alias] = $loader;
+ $this->loaded = false;
+ }
+
+ /**
+ * Adds a resource to the asset manager.
+ *
+ * @param ResourceInterface $resource A resource
+ * @param string $loader The loader alias for this resource
+ */
+ public function addResource(ResourceInterface $resource, $loader)
+ {
+ $this->resources[$loader][] = $resource;
+ $this->loaded = false;
+ }
+
+ /**
+ * Returns an array of resources.
+ *
+ * @return array An array of resources
+ */
+ public function getResources()
+ {
+ $resources = array();
+ foreach ($this->resources as $r) {
+ $resources = array_merge($resources, $r);
+ }
+
+ return $resources;
+ }
+
+ /**
+ * Checks for an asset formula.
+ *
+ * @param string $name An asset name
+ *
+ * @return Boolean If there is a formula
+ */
+ public function hasFormula($name)
+ {
+ if (!$this->loaded) {
+ $this->load();
+ }
+
+ return isset($this->formulae[$name]);
+ }
+
+ /**
+ * Returns an asset's formula.
+ *
+ * @param string $name An asset name
+ *
+ * @return array The formula
+ *
+ * @throws \InvalidArgumentException If there is no formula by that name
+ */
+ public function getFormula($name)
+ {
+ if (!$this->loaded) {
+ $this->load();
+ }
+
+ if (!isset($this->formulae[$name])) {
+ throw new \InvalidArgumentException(sprintf('There is no "%s" formula.', $name));
+ }
+
+ return $this->formulae[$name];
+ }
+
+ /**
+ * Sets a formula on the asset manager.
+ *
+ * @param string $name An asset name
+ * @param array $formula A formula
+ */
+ public function setFormula($name, array $formula)
+ {
+ $this->formulae[$name] = $formula;
+ }
+
+ /**
+ * Loads formulae from resources.
+ *
+ * @throws \LogicException If a resource has been added to an invalid loader
+ */
+ public function load()
+ {
+ if ($this->loading) {
+ return;
+ }
+
+ if ($diff = array_diff(array_keys($this->resources), array_keys($this->loaders))) {
+ throw new \LogicException('The following loader(s) are not registered: '.implode(', ', $diff));
+ }
+
+ $this->loading = true;
+
+ foreach ($this->resources as $loader => $resources) {
+ foreach ($resources as $resource) {
+ $this->formulae = array_replace($this->formulae, $this->loaders[$loader]->load($resource));
+ }
+ }
+
+ $this->loaded = true;
+ $this->loading = false;
+ }
+
+ public function get($name)
+ {
+ if (!$this->loaded) {
+ $this->load();
+ }
+
+ if (!parent::has($name) && isset($this->formulae[$name])) {
+ list($inputs, $filters, $options) = $this->formulae[$name];
+ $options['name'] = $name;
+ parent::set($name, $this->factory->createAsset($inputs, $filters, $options));
+ }
+
+ return parent::get($name);
+ }
+
+ public function has($name)
+ {
+ if (!$this->loaded) {
+ $this->load();
+ }
+
+ return isset($this->formulae[$name]) || parent::has($name);
+ }
+
+ public function getNames()
+ {
+ if (!$this->loaded) {
+ $this->load();
+ }
+
+ return array_unique(array_merge(parent::getNames(), array_keys($this->formulae)));
+ }
+
+ public function isDebug()
+ {
+ return $this->factory->isDebug();
+ }
+
+ public function getLastModified(AssetInterface $asset)
+ {
+ return $this->factory->getLastModified($asset);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/BasePhpFormulaLoader.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/BasePhpFormulaLoader.php
new file mode 100644
index 0000000..4c747df
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/BasePhpFormulaLoader.php
@@ -0,0 +1,160 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Factory\Loader;
+
+use Assetic\Factory\AssetFactory;
+use Assetic\Factory\Resource\ResourceInterface;
+use Assetic\Util\FilesystemUtils;
+
+/**
+ * Loads asset formulae from PHP files.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+abstract class BasePhpFormulaLoader implements FormulaLoaderInterface
+{
+ protected $factory;
+ protected $prototypes;
+
+ public function __construct(AssetFactory $factory)
+ {
+ $this->factory = $factory;
+ $this->prototypes = array();
+
+ foreach ($this->registerPrototypes() as $prototype => $options) {
+ $this->addPrototype($prototype, $options);
+ }
+ }
+
+ public function addPrototype($prototype, array $options = array())
+ {
+ $tokens = token_get_all('<?php '.$prototype);
+ array_shift($tokens);
+
+ $this->prototypes[$prototype] = array($tokens, $options);
+ }
+
+ public function load(ResourceInterface $resource)
+ {
+ if (!$nbProtos = count($this->prototypes)) {
+ throw new \LogicException('There are no prototypes registered.');
+ }
+
+ $buffers = array_fill(0, $nbProtos, '');
+ $bufferLevels = array_fill(0, $nbProtos, 0);
+ $buffersInWildcard = array();
+
+ $tokens = token_get_all($resource->getContent());
+ $calls = array();
+
+ while ($token = array_shift($tokens)) {
+ $current = self::tokenToString($token);
+ // loop through each prototype (by reference)
+ foreach (array_keys($this->prototypes) as $i) {
+ $prototype = & $this->prototypes[$i][0];
+ $options = $this->prototypes[$i][1];
+ $buffer = & $buffers[$i];
+ $level = & $bufferLevels[$i];
+
+ if (isset($buffersInWildcard[$i])) {
+ switch ($current) {
+ case '(': ++$level; break;
+ case ')': --$level; break;
+ }
+
+ $buffer .= $current;
+
+ if (!$level) {
+ $calls[] = array($buffer.';', $options);
+ $buffer = '';
+ unset($buffersInWildcard[$i]);
+ }
+ } elseif ($current == self::tokenToString(current($prototype))) {
+ $buffer .= $current;
+ if ('*' == self::tokenToString(next($prototype))) {
+ $buffersInWildcard[$i] = true;
+ ++$level;
+ }
+ } else {
+ reset($prototype);
+ unset($buffersInWildcard[$i]);
+ $buffer = '';
+ }
+ }
+ }
+
+ $formulae = array();
+ foreach ($calls as $call) {
+ $formulae += call_user_func_array(array($this, 'processCall'), $call);
+ }
+
+ return $formulae;
+ }
+
+ private function processCall($call, array $protoOptions = array())
+ {
+ $tmp = FilesystemUtils::createTemporaryFile('php_formula_loader');
+ file_put_contents($tmp, implode("\n", array(
+ '<?php',
+ $this->registerSetupCode(),
+ $call,
+ 'echo serialize($_call);',
+ )));
+ $args = unserialize(shell_exec('php '.escapeshellarg($tmp)));
+ unlink($tmp);
+
+ $inputs = isset($args[0]) ? self::argumentToArray($args[0]) : array();
+ $filters = isset($args[1]) ? self::argumentToArray($args[1]) : array();
+ $options = isset($args[2]) ? $args[2] : array();
+
+ if (!isset($options['debug'])) {
+ $options['debug'] = $this->factory->isDebug();
+ }
+
+ if (!is_array($options)) {
+ throw new \RuntimeException('The third argument must be omitted, null or an array.');
+ }
+
+ // apply the prototype options
+ $options += $protoOptions;
+
+ if (!isset($options['name'])) {
+ $options['name'] = $this->factory->generateAssetName($inputs, $filters, $options);
+ }
+
+ return array($options['name'] => array($inputs, $filters, $options));
+ }
+
+ /**
+ * Returns an array of prototypical calls and options.
+ *
+ * @return array Prototypes and options
+ */
+ abstract protected function registerPrototypes();
+
+ /**
+ * Returns setup code for the reflection scriptlet.
+ *
+ * @return string Some PHP setup code
+ */
+ abstract protected function registerSetupCode();
+
+ protected static function tokenToString($token)
+ {
+ return is_array($token) ? $token[1] : $token;
+ }
+
+ protected static function argumentToArray($argument)
+ {
+ return is_array($argument) ? $argument : array_filter(array_map('trim', explode(',', $argument)));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/CachedFormulaLoader.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/CachedFormulaLoader.php
new file mode 100644
index 0000000..9ab002b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/CachedFormulaLoader.php
@@ -0,0 +1,68 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Factory\Loader;
+
+use Assetic\Cache\ConfigCache;
+use Assetic\Factory\Resource\IteratorResourceInterface;
+use Assetic\Factory\Resource\ResourceInterface;
+
+/**
+ * Adds a caching layer to a loader.
+ *
+ * A cached formula loader is a composition of a formula loader and a cache.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class CachedFormulaLoader implements FormulaLoaderInterface
+{
+ private $loader;
+ private $configCache;
+ private $debug;
+
+ /**
+ * Constructor.
+ *
+ * When the loader is in debug mode it will ensure the cached formulae
+ * are fresh before returning them.
+ *
+ * @param FormulaLoaderInterface $loader A formula loader
+ * @param ConfigCache $configCache A config cache
+ * @param Boolean $debug The debug mode
+ */
+ public function __construct(FormulaLoaderInterface $loader, ConfigCache $configCache, $debug = false)
+ {
+ $this->loader = $loader;
+ $this->configCache = $configCache;
+ $this->debug = $debug;
+ }
+
+ public function load(ResourceInterface $resources)
+ {
+ if (!$resources instanceof IteratorResourceInterface) {
+ $resources = array($resources);
+ }
+
+ $formulae = array();
+
+ foreach ($resources as $resource) {
+ $id = (string) $resource;
+ if (!$this->configCache->has($id) || ($this->debug && !$resource->isFresh($this->configCache->getTimestamp($id)))) {
+ $formulae += $this->loader->load($resource);
+ $this->configCache->set($id, $formulae);
+ } else {
+ $formulae += $this->configCache->get($id);
+ }
+ }
+
+ return $formulae;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/FormulaLoaderInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/FormulaLoaderInterface.php
new file mode 100644
index 0000000..fc45e86
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/FormulaLoaderInterface.php
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Factory\Loader;
+
+use Assetic\Factory\Resource\ResourceInterface;
+
+/**
+ * Loads formulae.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+interface FormulaLoaderInterface
+{
+ /**
+ * Loads formulae from a resource.
+ *
+ * Formulae should be loaded the same regardless of the current debug
+ * mode. Debug considerations should happen downstream.
+ *
+ * @param ResourceInterface $resource A resource
+ *
+ * @return array An array of formulae
+ */
+ public function load(ResourceInterface $resource);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/FunctionCallsFormulaLoader.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/FunctionCallsFormulaLoader.php
new file mode 100644
index 0000000..58b56e1
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Loader/FunctionCallsFormulaLoader.php
@@ -0,0 +1,53 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Factory\Loader;
+
+/**
+ * Loads asset formulae from PHP files.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class FunctionCallsFormulaLoader extends BasePhpFormulaLoader
+{
+ protected function registerPrototypes()
+ {
+ return array(
+ 'assetic_javascripts(*)' => array('output' => 'js/*.js'),
+ 'assetic_stylesheets(*)' => array('output' => 'css/*.css'),
+ 'assetic_image(*)' => array('output' => 'images/*'),
+ );
+ }
+
+ protected function registerSetupCode()
+ {
+ return <<<'EOF'
+function assetic_javascripts()
+{
+ global $_call;
+ $_call = func_get_args();
+}
+
+function assetic_stylesheets()
+{
+ global $_call;
+ $_call = func_get_args();
+}
+
+function assetic_image()
+{
+ global $_call;
+ $_call = func_get_args();
+}
+
+EOF;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/CoalescingDirectoryResource.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/CoalescingDirectoryResource.php
new file mode 100644
index 0000000..6c08900
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/CoalescingDirectoryResource.php
@@ -0,0 +1,112 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Factory\Resource;
+
+/**
+ * Coalesces multiple directories together into one merged resource.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class CoalescingDirectoryResource implements IteratorResourceInterface
+{
+ private $directories;
+
+ public function __construct($directories)
+ {
+ $this->directories = array();
+
+ foreach ($directories as $directory) {
+ $this->addDirectory($directory);
+ }
+ }
+
+ public function addDirectory(IteratorResourceInterface $directory)
+ {
+ $this->directories[] = $directory;
+ }
+
+ public function isFresh($timestamp)
+ {
+ foreach ($this->getFileResources() as $file) {
+ if (!$file->isFresh($timestamp)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public function getContent()
+ {
+ $parts = array();
+ foreach ($this->getFileResources() as $file) {
+ $parts[] = $file->getContent();
+ }
+
+ return implode("\n", $parts);
+ }
+
+ /**
+ * Returns a string to uniquely identify the current resource.
+ *
+ * @return string An identifying string
+ */
+ public function __toString()
+ {
+ $parts = array();
+ foreach ($this->directories as $directory) {
+ $parts[] = (string) $directory;
+ }
+
+ return implode(',', $parts);
+ }
+
+ public function getIterator()
+ {
+ return new \ArrayIterator($this->getFileResources());
+ }
+
+ /**
+ * Returns the relative version of a filename.
+ *
+ * @param ResourceInterface $file The file
+ * @param ResourceInterface $directory The directory
+ *
+ * @return string The name to compare with files from other directories
+ */
+ protected function getRelativeName(ResourceInterface $file, ResourceInterface $directory)
+ {
+ return substr((string) $file, strlen((string) $directory));
+ }
+
+ /**
+ * Performs the coalesce.
+ *
+ * @return array An array of file resources
+ */
+ private function getFileResources()
+ {
+ $paths = array();
+
+ foreach ($this->directories as $directory) {
+ foreach ($directory as $file) {
+ $relative = $this->getRelativeName($file, $directory);
+
+ if (!isset($paths[$relative])) {
+ $paths[$relative] = $file;
+ }
+ }
+ }
+
+ return array_values($paths);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/DirectoryResource.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/DirectoryResource.php
new file mode 100644
index 0000000..c823de2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/DirectoryResource.php
@@ -0,0 +1,133 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Factory\Resource;
+
+/**
+ * A resource is something formulae can be loaded from.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class DirectoryResource implements IteratorResourceInterface
+{
+ private $path;
+ private $pattern;
+
+ /**
+ * Constructor.
+ *
+ * @param string $path A directory path
+ * @param string $pattern A filename pattern
+ */
+ public function __construct($path, $pattern = null)
+ {
+ if (DIRECTORY_SEPARATOR != substr($path, -1)) {
+ $path .= DIRECTORY_SEPARATOR;
+ }
+
+ $this->path = $path;
+ $this->pattern = $pattern;
+ }
+
+ public function isFresh($timestamp)
+ {
+ if (!is_dir($this->path) || filemtime($this->path) > $timestamp) {
+ return false;
+ }
+
+ foreach ($this as $resource) {
+ if (!$resource->isFresh($timestamp)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns the combined content of all inner resources.
+ */
+ public function getContent()
+ {
+ $content = array();
+ foreach ($this as $resource) {
+ $content[] = $resource->getContent();
+ }
+
+ return implode("\n", $content);
+ }
+
+ public function __toString()
+ {
+ return $this->path;
+ }
+
+ public function getIterator()
+ {
+ return is_dir($this->path)
+ ? new DirectoryResourceIterator($this->getInnerIterator())
+ : new \EmptyIterator();
+ }
+
+ protected function getInnerIterator()
+ {
+ return new DirectoryResourceFilterIterator(new \RecursiveDirectoryIterator($this->path, \RecursiveDirectoryIterator::FOLLOW_SYMLINKS), $this->pattern);
+ }
+}
+
+/**
+ * An iterator that converts file objects into file resources.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ * @access private
+ */
+class DirectoryResourceIterator extends \RecursiveIteratorIterator
+{
+ public function current()
+ {
+ return new FileResource(parent::current()->getPathname());
+ }
+}
+
+/**
+ * Filters files by a basename pattern.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ * @access private
+ */
+class DirectoryResourceFilterIterator extends \RecursiveFilterIterator
+{
+ protected $pattern;
+
+ public function __construct(\RecursiveDirectoryIterator $iterator, $pattern = null)
+ {
+ parent::__construct($iterator);
+
+ $this->pattern = $pattern;
+ }
+
+ public function accept()
+ {
+ $file = $this->current();
+ $name = $file->getBasename();
+
+ if ($file->isDir()) {
+ return '.' != $name[0];
+ }
+
+ return null === $this->pattern || 0 < preg_match($this->pattern, $name);
+ }
+
+ public function getChildren()
+ {
+ return new self(new \RecursiveDirectoryIterator($this->current()->getPathname(), \RecursiveDirectoryIterator::FOLLOW_SYMLINKS), $this->pattern);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/FileResource.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/FileResource.php
new file mode 100644
index 0000000..b7760e1
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/FileResource.php
@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Factory\Resource;
+
+/**
+ * A resource is something formulae can be loaded from.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class FileResource implements ResourceInterface
+{
+ private $path;
+
+ /**
+ * Constructor.
+ *
+ * @param string $path The path to a file
+ */
+ public function __construct($path)
+ {
+ $this->path = $path;
+ }
+
+ public function isFresh($timestamp)
+ {
+ return file_exists($this->path) && filemtime($this->path) <= $timestamp;
+ }
+
+ public function getContent()
+ {
+ return file_exists($this->path) ? file_get_contents($this->path) : '';
+ }
+
+ public function __toString()
+ {
+ return $this->path;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/IteratorResourceInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/IteratorResourceInterface.php
new file mode 100644
index 0000000..3357332
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/IteratorResourceInterface.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Factory\Resource;
+
+/**
+ * A resource is something formulae can be loaded from.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+interface IteratorResourceInterface extends ResourceInterface, \IteratorAggregate
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/ResourceInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/ResourceInterface.php
new file mode 100644
index 0000000..7eebbd8
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Resource/ResourceInterface.php
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Factory\Resource;
+
+/**
+ * A resource is something formulae can be loaded from.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+interface ResourceInterface
+{
+ /**
+ * Checks if a timestamp represents the latest resource.
+ *
+ * @param integer $timestamp A UNIX timestamp
+ *
+ * @return Boolean True if the timestamp is up to date
+ */
+ public function isFresh($timestamp);
+
+ /**
+ * Returns the content of the resource.
+ *
+ * @return string The content
+ */
+ public function getContent();
+
+ /**
+ * Returns a unique string for the current resource.
+ *
+ * @return string A unique string to identity the current resource
+ */
+ public function __toString();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Worker/CacheBustingWorker.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Worker/CacheBustingWorker.php
new file mode 100644
index 0000000..712c90d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Worker/CacheBustingWorker.php
@@ -0,0 +1,70 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Factory\Worker;
+
+use Assetic\Asset\AssetCollectionInterface;
+use Assetic\Asset\AssetInterface;
+use Assetic\Factory\AssetFactory;
+
+/**
+ * Adds cache busting code
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class CacheBustingWorker implements WorkerInterface
+{
+ private $separator;
+
+ public function __construct($separator = '-')
+ {
+ $this->separator = $separator;
+ }
+
+ public function process(AssetInterface $asset, AssetFactory $factory)
+ {
+ if (!$path = $asset->getTargetPath()) {
+ // no path to work with
+ return;
+ }
+
+ if (!$search = pathinfo($path, PATHINFO_EXTENSION)) {
+ // nothing to replace
+ return;
+ }
+
+ $replace = $this->separator.$this->getHash($asset, $factory).'.'.$search;
+ if (preg_match('/'.preg_quote($replace, '/').'$/', $path)) {
+ // already replaced
+ return;
+ }
+
+ $asset->setTargetPath(
+ preg_replace('/\.'.preg_quote($search, '/').'$/', $replace, $path)
+ );
+ }
+
+ protected function getHash(AssetInterface $asset, AssetFactory $factory)
+ {
+ $hash = hash_init('sha1');
+
+ hash_update($hash, $factory->getLastModified($asset));
+
+ if ($asset instanceof AssetCollectionInterface) {
+ foreach ($asset as $i => $leaf) {
+ $sourcePath = $leaf->getSourcePath();
+ hash_update($hash, $sourcePath ?: $i);
+ }
+ }
+
+ return substr(hash_final($hash), 0, 7);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Worker/EnsureFilterWorker.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Worker/EnsureFilterWorker.php
new file mode 100644
index 0000000..80fd44a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Worker/EnsureFilterWorker.php
@@ -0,0 +1,61 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Factory\Worker;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Factory\AssetFactory;
+use Assetic\Filter\FilterInterface;
+
+/**
+ * Applies a filter to an asset based on a source and/or target path match.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ * @todo A better asset-matcher mechanism
+ */
+class EnsureFilterWorker implements WorkerInterface
+{
+ const CHECK_SOURCE = 1;
+ const CHECK_TARGET = 2;
+
+ private $pattern;
+ private $filter;
+ private $flags;
+
+ /**
+ * Constructor.
+ *
+ * @param string $pattern A regex for checking the asset's target URL
+ * @param FilterInterface $filter A filter to apply if the regex matches
+ * @param integer $flags Flags for what to check
+ */
+ public function __construct($pattern, FilterInterface $filter, $flags = null)
+ {
+ if (null === $flags) {
+ $flags = self::CHECK_SOURCE | self::CHECK_TARGET;
+ }
+
+ $this->pattern = $pattern;
+ $this->filter = $filter;
+ $this->flags = $flags;
+ }
+
+ public function process(AssetInterface $asset, AssetFactory $factory)
+ {
+ if (
+ (self::CHECK_SOURCE === (self::CHECK_SOURCE & $this->flags) && preg_match($this->pattern, $asset->getSourcePath()))
+ ||
+ (self::CHECK_TARGET === (self::CHECK_TARGET & $this->flags) && preg_match($this->pattern, $asset->getTargetPath()))
+ ) {
+ $asset->ensureFilter($this->filter);
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Worker/WorkerInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Worker/WorkerInterface.php
new file mode 100644
index 0000000..e86cc7b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Factory/Worker/WorkerInterface.php
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Factory\Worker;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Factory\AssetFactory;
+
+/**
+ * Assets are passed through factory workers before leaving the factory.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+interface WorkerInterface
+{
+ /**
+ * Processes an asset.
+ *
+ * @param AssetInterface $asset An asset
+ * @param AssetFactory $factory The factory
+ *
+ * @return AssetInterface|null May optionally return a replacement asset
+ */
+ public function process(AssetInterface $asset, AssetFactory $factory);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/AutoprefixerFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/AutoprefixerFilter.php
new file mode 100644
index 0000000..5182161
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/AutoprefixerFilter.php
@@ -0,0 +1,87 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2013 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Assetic\Util\FilesystemUtils;
+
+/**
+ * Parses CSS and adds vendor prefixes to rules using values from the Can I Use website
+ *
+ * @link https://github.com/ai/autoprefixer
+ * @author Alex Vasilenko <aa.vasilenko@gmail.com>
+ */
+class AutoprefixerFilter extends BaseNodeFilter
+{
+ /**
+ * @var string
+ */
+ private $autoprefixerBin;
+
+ /**
+ * @var array
+ */
+ private $browsers = array();
+
+ public function __construct($autoprefixerBin)
+ {
+ $this->autoprefixerBin = $autoprefixerBin;
+ }
+
+ /**
+ * @param array $browsers
+ */
+ public function setBrowsers(array $browsers)
+ {
+ $this->browsers = $browsers;
+ }
+
+ /**
+ * @param string $browser
+ */
+ public function addBrowser($browser)
+ {
+ $this->browsers[] = $browser;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ $input = $asset->getContent();
+ $pb = $this->createProcessBuilder(array($this->autoprefixerBin));
+
+ $pb->setInput($input);
+ if ($this->browsers) {
+ $pb->add('-b')->add(implode(',', $this->browsers));
+ }
+
+ $output = FilesystemUtils::createTemporaryFile('autoprefixer');
+ $pb->add('-o')->add($output);
+
+ $proc = $pb->getProcess();
+ if (0 !== $proc->run()) {
+ throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+ }
+
+ $asset->setContent(file_get_contents($output));
+ unlink($output);
+ }
+
+ /**
+ * Filters an asset just before it's dumped.
+ *
+ * @param AssetInterface $asset An asset
+ */
+ public function filterDump(AssetInterface $asset)
+ {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/BaseCssFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/BaseCssFilter.php
new file mode 100644
index 0000000..8d65271
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/BaseCssFilter.php
@@ -0,0 +1,54 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Util\CssUtils;
+
+/**
+ * An abstract filter for dealing with CSS.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+abstract class BaseCssFilter implements FilterInterface
+{
+ /**
+ * @see CssUtils::filterReferences()
+ */
+ protected function filterReferences($content, $callback, $limit = -1, &$count = 0)
+ {
+ return CssUtils::filterReferences($content, $callback, $limit, $count);
+ }
+
+ /**
+ * @see CssUtils::filterUrls()
+ */
+ protected function filterUrls($content, $callback, $limit = -1, &$count = 0)
+ {
+ return CssUtils::filterUrls($content, $callback, $limit, $count);
+ }
+
+ /**
+ * @see CssUtils::filterImports()
+ */
+ protected function filterImports($content, $callback, $limit = -1, &$count = 0, $includeUrl = true)
+ {
+ return CssUtils::filterImports($content, $callback, $limit, $count, $includeUrl);
+ }
+
+ /**
+ * @see CssUtils::filterIEFilters()
+ */
+ protected function filterIEFilters($content, $callback, $limit = -1, &$count = 0)
+ {
+ return CssUtils::filterIEFilters($content, $callback, $limit, $count);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/BaseNodeFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/BaseNodeFilter.php
new file mode 100644
index 0000000..64e5a13
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/BaseNodeFilter.php
@@ -0,0 +1,44 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+abstract class BaseNodeFilter extends BaseProcessFilter
+{
+ private $nodePaths = array();
+
+ public function getNodePaths()
+ {
+ return $this->nodePaths;
+ }
+
+ public function setNodePaths(array $nodePaths)
+ {
+ $this->nodePaths = $nodePaths;
+ }
+
+ public function addNodePath($nodePath)
+ {
+ $this->nodePaths[] = $nodePath;
+ }
+
+ protected function createProcessBuilder(array $arguments = array())
+ {
+ $pb = parent::createProcessBuilder($arguments);
+
+ if ($this->nodePaths) {
+ $this->mergeEnv($pb);
+ $pb->setEnv('NODE_PATH', implode(PATH_SEPARATOR, $this->nodePaths));
+ }
+
+ return $pb;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/BaseProcessFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/BaseProcessFilter.php
new file mode 100644
index 0000000..642495a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/BaseProcessFilter.php
@@ -0,0 +1,57 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Symfony\Component\Process\ProcessBuilder;
+
+/**
+ * An external process based filter which provides a way to set a timeout on the process.
+ */
+abstract class BaseProcessFilter implements FilterInterface
+{
+ private $timeout;
+
+ /**
+ * Set the process timeout.
+ *
+ * @param int $timeout The timeout for the process
+ */
+ public function setTimeout($timeout)
+ {
+ $this->timeout = $timeout;
+ }
+
+ /**
+ * Creates a new process builder.
+ *
+ * @param array $arguments An optional array of arguments
+ *
+ * @return ProcessBuilder A new process builder
+ */
+ protected function createProcessBuilder(array $arguments = array())
+ {
+ $pb = new ProcessBuilder($arguments);
+
+ if (null !== $this->timeout) {
+ $pb->setTimeout($this->timeout);
+ }
+
+ return $pb;
+ }
+
+ protected function mergeEnv(ProcessBuilder $pb)
+ {
+ foreach (array_filter($_SERVER, 'is_scalar') as $key => $value) {
+ $pb->setEnv($key, $value);
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CallablesFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CallablesFilter.php
new file mode 100644
index 0000000..b81f201
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CallablesFilter.php
@@ -0,0 +1,62 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Factory\AssetFactory;
+
+/**
+ * A filter that wraps callables.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class CallablesFilter implements FilterInterface, DependencyExtractorInterface
+{
+ private $loader;
+ private $dumper;
+ private $extractor;
+
+ /**
+ * @param callable|null $loader
+ * @param callable|null $dumper
+ * @param callable|null $extractor
+ */
+ public function __construct($loader = null, $dumper = null, $extractor = null)
+ {
+ $this->loader = $loader;
+ $this->dumper = $dumper;
+ $this->extractor = $extractor;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ if (null !== $callable = $this->loader) {
+ $callable($asset);
+ }
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ if (null !== $callable = $this->dumper) {
+ $callable($asset);
+ }
+ }
+
+ public function getChildren(AssetFactory $factory, $content, $loadPath = null)
+ {
+ if (null !== $callable = $this->extractor) {
+ return $callable($factory, $content, $loadPath);
+ }
+
+ return array();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CleanCssFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CleanCssFilter.php
new file mode 100644
index 0000000..ada5499
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CleanCssFilter.php
@@ -0,0 +1,343 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+
+/**
+ * CleanCss filter.
+ *
+ * @link https://github.com/jakubpawlowicz/clean-css
+ * @author Jakub Pawlowicz <http://JakubPawlowicz.com>
+ */
+class CleanCssFilter extends BaseNodeFilter
+{
+ private $cleanCssBin;
+ private $nodeBin;
+
+ private $keepLineBreaks;
+ private $compatibility;
+ private $debug;
+ private $rootPath;
+ private $skipImport = true;
+ private $timeout;
+ private $semanticMerging;
+ private $roundingPrecision;
+ private $removeSpecialComments;
+ private $onlyKeepFirstSpecialComment;
+ private $skipAdvanced;
+ private $skipAggresiveMerging;
+ private $skipImportFrom;
+ private $mediaMerging;
+ private $skipRebase;
+ private $skipRestructuring;
+ private $skipShorthandCompacting;
+ private $sourceMap;
+ private $sourceMapInlineSources;
+
+
+ /**
+ * @param string $cleanCssBin Absolute path to the cleancss executable
+ * @param string $nodeBin Absolute path to the folder containg node.js executable
+ */
+ public function __construct($cleanCssBin = '/usr/bin/cleancss', $nodeBin = null)
+ {
+ $this->cleanCssBin = $cleanCssBin;
+ $this->nodeBin = $nodeBin;
+ }
+
+ /**
+ * Keep line breaks
+ * @param bool $keepLineBreaks True to enable
+ */
+ public function setKeepLineBreaks($keepLineBreaks)
+ {
+ $this->keepLineBreaks = $keepLineBreaks;
+ }
+
+ /**
+ * Remove all special comments
+ * @param bool $removeSpecialComments True to enable
+ */ // i.e. /*! comment */
+ public function setRemoveSpecialComments($removeSpecialComments)
+ {
+ $this->removeSpecialComments = $removeSpecialComments;
+ }
+
+ /**
+ * Remove all special comments except the first one
+ * @param bool $onlyKeepFirstSpecialComment True to enable
+ */
+ public function setOnlyKeepFirstSpecialComment($onlyKeepFirstSpecialComment)
+ {
+ $this->onlyKeepFirstSpecialComment = $onlyKeepFirstSpecialComment;
+ }
+ /**
+ * Enables unsafe mode by assuming BEM-like semantic stylesheets (warning, this may break your styling!)
+ * @param bool $semanticMerging True to enable
+ */
+ public function setSemanticMerging($semanticMerging)
+ {
+ $this->semanticMerging = $semanticMerging;
+ }
+
+ /**
+ * A root path to which resolve absolute @import rules
+ * @param string $rootPath
+ */
+ public function setRootPath($rootPath)
+ {
+ $this->rootPath = $rootPath;
+ }
+
+ /**
+ * Disable @import processing
+ * @param bool $skipImport True to enable
+ */
+ public function setSkipImport($skipImport)
+ {
+ $this->skipImport = $skipImport;
+ }
+ /**
+ * Per connection timeout when fetching remote @imports; defaults to 5 seconds
+ * @param int $timeout
+ */
+ public function setTimeout($timeout)
+ {
+ $this->timeout = $timeout;
+ }
+
+ /**
+ * Disable URLs rebasing
+ * @param bool $skipRebase True to enable
+ */
+ public function setSkipRebase($skipRebase)
+ {
+ $this->skipRebase = $skipRebase;
+ }
+
+ /**
+ * Disable restructuring optimizations
+ * @param bool $skipRestructuring True to enable
+ */
+ public function setSkipRestructuring($skipRestructuring)
+ {
+ $this->skipRestructuring = $skipRestructuring;
+ }
+
+ /**
+ * Disable shorthand compacting
+ * @param bool $skipShorthandCompacting True to enable
+ */
+ public function setSkipShorthandCompacting($skipShorthandCompacting)
+ {
+ $this->skipShorthandCompacting = $skipShorthandCompacting;
+ }
+
+ /**
+ * Enables building input's source map
+ * @param bool $sourceMap True to enable
+ */
+ public function setSourceMap($sourceMap)
+ {
+ $this->sourceMap = $sourceMap;
+ }
+
+ /**
+ * Enables inlining sources inside source maps
+ * @param bool $sourceMapInlineSources True to enable
+ */
+ public function setSourceMapInlineSources($sourceMapInlineSources)
+ {
+ $this->sourceMapInlineSources = $sourceMapInlineSources;
+ }
+
+ /**
+ * Disable advanced optimizations - selector & property merging, reduction, etc.
+ * @param bool $skipAdvanced True to enable
+ */
+ public function setSkipAdvanced($skipAdvanced)
+ {
+ $this->skipAdvanced = $skipAdvanced;
+ }
+
+ /**
+ * Disable properties merging based on their order
+ * @param bool $skipAggresiveMerging True to enable
+ */
+ public function setSkipAggresiveMerging($skipAggresiveMerging)
+ {
+ $this->skipAggresiveMerging = $skipAggresiveMerging;
+ }
+
+ /**
+ * Disable @import processing for specified rules
+ * @param string $skipImportFrom
+ */
+ public function setSkipImportFrom($skipImportFrom)
+ {
+ $this->skipImportFrom = $skipImportFrom;
+ }
+
+ /**
+ * Disable @media merging
+ * @param bool $mediaMerging True to enable
+ */
+ public function setMediaMerging($mediaMerging)
+ {
+ $this->mediaMerging = $mediaMerging;
+ }
+
+ /**
+ * Rounds to `N` decimal places. Defaults to 2. -1 disables rounding.
+ * @param int $roundingPrecision
+ */
+ public function setRoundingPrecision($roundingPrecision)
+ {
+ $this->roundingPrecision = $roundingPrecision;
+ }
+
+ /**
+ * Force compatibility mode (see https://github.com/jakubpawlowicz/clean-css/blob/master/README.md#how-to-set-compatibility-mode for advanced examples)
+ * @param string $compatibility
+ */
+ public function setCompatibility($compatibility)
+ {
+ $this->compatibility = $compatibility;
+ }
+
+ /**
+ * Shows debug information (minification time & compression efficiency)
+ * @param bool $debug True to enable
+ */
+ public function setDebug($debug)
+ {
+ $this->debug = $debug;
+ }
+
+
+ /**
+ * @see Assetic\Filter\FilterInterface::filterLoad()
+ */
+ public function filterLoad(AssetInterface $asset)
+ {
+ }
+
+
+ /**
+ * Run the asset through CleanCss
+ *
+ * @see Assetic\Filter\FilterInterface::filterDump()
+ */
+ public function filterDump(AssetInterface $asset)
+ {
+ $pb = $this->createProcessBuilder($this->nodeBin
+ ? array($this->nodeBin, $this->cleanCssBin)
+ : array($this->cleanCssBin));
+
+ if ($this->keepLineBreaks) {
+ $pb->add('--keep-line-breaks');
+ }
+
+ if ($this->compatibility) {
+ $pb->add('--compatibility ' .$this->compatibility);
+ }
+
+ if ($this->debug) {
+ $pb->add('--debug');
+ }
+
+ if ($this->rootPath) {
+ $pb->add('--root ' .$this->rootPath);
+ }
+
+ if ($this->skipImport) {
+ $pb->add('--skip-import');
+ }
+
+ if ($this->timeout) {
+ $pb->add('--timeout ' .$this->timeout);
+ }
+
+ if ($this->roundingPrecision) {
+ $pb->add('--rounding-precision ' .$this->roundingPrecision);
+ }
+
+ if ($this->removeSpecialComments) {
+ $pb->add('--s0');
+ }
+
+ if ($this->onlyKeepFirstSpecialComment) {
+ $pb->add('--s1');
+ }
+
+ if ($this->semanticMerging) {
+ $pb->add('--semantic-merging');
+ }
+
+ if ($this->skipAdvanced) {
+ $pb->add('--skip-advanced');
+ }
+
+ if ($this->skipAggresiveMerging) {
+ $pb->add('--skip-aggressive-merging');
+ }
+
+ if ($this->skipImportFrom) {
+ $pb->add('--skip-import-from ' .$this->skipImportFrom);
+ }
+
+ if ($this->mediaMerging) {
+ $pb->add('--skip-media-merging');
+ }
+
+ if ($this->skipRebase) {
+ $pb->add('--skip-rebase');
+ }
+
+ if ($this->skipRestructuring) {
+ $pb->add('--skip-restructuring');
+ }
+
+ if ($this->skipShorthandCompacting) {
+ $pb->add('--skip-shorthand-compacting');
+ }
+
+ if ($this->sourceMap) {
+ $pb->add('--source-map');
+ }
+
+ if ($this->sourceMapInlineSources) {
+ $pb->add('--source-map-inline-sources');
+ }
+ // input and output files
+ $input = tempnam(sys_get_temp_dir(), 'input');
+
+ file_put_contents($input, $asset->getContent());
+ $pb->add($input);
+
+ $proc = $pb->getProcess();
+ $code = $proc->run();
+ unlink($input);
+
+ if (127 === $code) {
+ throw new \RuntimeException('Path to node executable could not be resolved.');
+ }
+
+ if (0 !== $code) {
+ throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+ }
+
+ $asset->setContent($proc->getOutput());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CoffeeScriptFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CoffeeScriptFilter.php
new file mode 100644
index 0000000..a5cc818
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CoffeeScriptFilter.php
@@ -0,0 +1,83 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Assetic\Util\FilesystemUtils;
+
+/**
+ * Compiles CoffeeScript into Javascript.
+ *
+ * @link http://coffeescript.org/
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class CoffeeScriptFilter extends BaseNodeFilter
+{
+ private $coffeeBin;
+ private $nodeBin;
+
+ // coffee options
+ private $bare;
+ private $noHeader;
+
+ public function __construct($coffeeBin = '/usr/bin/coffee', $nodeBin = null)
+ {
+ $this->coffeeBin = $coffeeBin;
+ $this->nodeBin = $nodeBin;
+ }
+
+ public function setBare($bare)
+ {
+ $this->bare = $bare;
+ }
+
+ public function setNoHeader($noHeader)
+ {
+ $this->noHeader = $noHeader;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ $input = FilesystemUtils::createTemporaryFile('coffee');
+ file_put_contents($input, $asset->getContent());
+
+ $pb = $this->createProcessBuilder($this->nodeBin
+ ? array($this->nodeBin, $this->coffeeBin)
+ : array($this->coffeeBin));
+
+ $pb->add('-cp');
+
+ if ($this->bare) {
+ $pb->add('--bare');
+ }
+
+ if ($this->noHeader) {
+ $pb->add('--no-header');
+ }
+
+ $pb->add($input);
+ $proc = $pb->getProcess();
+ $code = $proc->run();
+ unlink($input);
+
+ if (0 !== $code) {
+ throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+ }
+
+ $asset->setContent($proc->getOutput());
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CompassFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CompassFilter.php
new file mode 100644
index 0000000..d80a1ab
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CompassFilter.php
@@ -0,0 +1,391 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Assetic\Filter\Sass\BaseSassFilter;
+use Assetic\Util\FilesystemUtils;
+
+/**
+ * Loads Compass files.
+ *
+ * @link http://compass-style.org/
+ * @author Maxime Thirouin <maxime.thirouin@gmail.com>
+ */
+class CompassFilter extends BaseSassFilter
+{
+ private $compassPath;
+ private $rubyPath;
+ private $scss;
+
+ // sass options
+ private $unixNewlines;
+ private $debugInfo;
+ private $cacheLocation;
+ private $noCache;
+
+ // compass options
+ private $force;
+ private $style;
+ private $quiet;
+ private $boring;
+ private $noLineComments;
+ private $imagesDir;
+ private $javascriptsDir;
+ private $fontsDir;
+ private $relativeAssets;
+
+ // compass configuration file options
+ private $plugins = array();
+ private $httpPath;
+ private $httpImagesPath;
+ private $httpFontsPath;
+ private $httpGeneratedImagesPath;
+ private $generatedImagesPath;
+ private $httpJavascriptsPath;
+ private $homeEnv = true;
+
+ public function __construct($compassPath = '/usr/bin/compass', $rubyPath = null)
+ {
+ $this->compassPath = $compassPath;
+ $this->rubyPath = $rubyPath;
+ $this->cacheLocation = FilesystemUtils::getTemporaryDirectory();
+
+ if ('cli' !== php_sapi_name()) {
+ $this->boring = true;
+ }
+ }
+
+ public function setScss($scss)
+ {
+ $this->scss = $scss;
+ }
+
+ // sass options setters
+ public function setUnixNewlines($unixNewlines)
+ {
+ $this->unixNewlines = $unixNewlines;
+ }
+
+ public function setDebugInfo($debugInfo)
+ {
+ $this->debugInfo = $debugInfo;
+ }
+
+ public function setCacheLocation($cacheLocation)
+ {
+ $this->cacheLocation = $cacheLocation;
+ }
+
+ public function setNoCache($noCache)
+ {
+ $this->noCache = $noCache;
+ }
+
+ // compass options setters
+ public function setForce($force)
+ {
+ $this->force = $force;
+ }
+
+ public function setStyle($style)
+ {
+ $this->style = $style;
+ }
+
+ public function setQuiet($quiet)
+ {
+ $this->quiet = $quiet;
+ }
+
+ public function setBoring($boring)
+ {
+ $this->boring = $boring;
+ }
+
+ public function setNoLineComments($noLineComments)
+ {
+ $this->noLineComments = $noLineComments;
+ }
+
+ public function setImagesDir($imagesDir)
+ {
+ $this->imagesDir = $imagesDir;
+ }
+
+ public function setJavascriptsDir($javascriptsDir)
+ {
+ $this->javascriptsDir = $javascriptsDir;
+ }
+
+ public function setFontsDir($fontsDir)
+ {
+ $this->fontsDir = $fontsDir;
+ }
+
+ // compass configuration file options setters
+ public function setPlugins(array $plugins)
+ {
+ $this->plugins = $plugins;
+ }
+
+ public function addPlugin($plugin)
+ {
+ $this->plugins[] = $plugin;
+ }
+
+ public function setHttpPath($httpPath)
+ {
+ $this->httpPath = $httpPath;
+ }
+
+ public function setHttpImagesPath($httpImagesPath)
+ {
+ $this->httpImagesPath = $httpImagesPath;
+ }
+
+ public function setHttpFontsPath($httpFontsPath)
+ {
+ $this->httpFontsPath = $httpFontsPath;
+ }
+
+ public function setHttpGeneratedImagesPath($httpGeneratedImagesPath)
+ {
+ $this->httpGeneratedImagesPath = $httpGeneratedImagesPath;
+ }
+
+ public function setGeneratedImagesPath($generatedImagesPath)
+ {
+ $this->generatedImagesPath = $generatedImagesPath;
+ }
+
+ public function setHttpJavascriptsPath($httpJavascriptsPath)
+ {
+ $this->httpJavascriptsPath = $httpJavascriptsPath;
+ }
+
+ public function setHomeEnv($homeEnv)
+ {
+ $this->homeEnv = $homeEnv;
+ }
+
+ public function setRelativeAssets($relativeAssets)
+ {
+ $this->relativeAssets = $relativeAssets;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ $loadPaths = $this->loadPaths;
+ if ($dir = $asset->getSourceDirectory()) {
+ $loadPaths[] = $dir;
+ }
+
+ $tempDir = $this->cacheLocation ? $this->cacheLocation : FilesystemUtils::getTemporaryDirectory();
+
+ $compassProcessArgs = array(
+ $this->compassPath,
+ 'compile',
+ $tempDir,
+ );
+ if (null !== $this->rubyPath) {
+ $compassProcessArgs = array_merge(explode(' ', $this->rubyPath), $compassProcessArgs);
+ }
+
+ $pb = $this->createProcessBuilder($compassProcessArgs);
+
+ if ($this->force) {
+ $pb->add('--force');
+ }
+
+ if ($this->style) {
+ $pb->add('--output-style')->add($this->style);
+ }
+
+ if ($this->quiet) {
+ $pb->add('--quiet');
+ }
+
+ if ($this->boring) {
+ $pb->add('--boring');
+ }
+
+ if ($this->noLineComments) {
+ $pb->add('--no-line-comments');
+ }
+
+ // these three options are not passed into the config file
+ // because like this, compass adapts this to be xxx_dir or xxx_path
+ // whether it's an absolute path or not
+ if ($this->imagesDir) {
+ $pb->add('--images-dir')->add($this->imagesDir);
+ }
+
+ if ($this->relativeAssets) {
+ $pb->add('--relative-assets');
+ }
+
+ if ($this->javascriptsDir) {
+ $pb->add('--javascripts-dir')->add($this->javascriptsDir);
+ }
+
+ if ($this->fontsDir) {
+ $pb->add('--fonts-dir')->add($this->fontsDir);
+ }
+
+ // options in config file
+ $optionsConfig = array();
+
+ if (!empty($loadPaths)) {
+ $optionsConfig['additional_import_paths'] = $loadPaths;
+ }
+
+ if ($this->unixNewlines) {
+ $optionsConfig['sass_options']['unix_newlines'] = true;
+ }
+
+ if ($this->debugInfo) {
+ $optionsConfig['sass_options']['debug_info'] = true;
+ }
+
+ if ($this->cacheLocation) {
+ $optionsConfig['sass_options']['cache_location'] = $this->cacheLocation;
+ }
+
+ if ($this->noCache) {
+ $optionsConfig['sass_options']['no_cache'] = true;
+ }
+
+ if ($this->httpPath) {
+ $optionsConfig['http_path'] = $this->httpPath;
+ }
+
+ if ($this->httpImagesPath) {
+ $optionsConfig['http_images_path'] = $this->httpImagesPath;
+ }
+
+ if ($this->httpFontsPath) {
+ $optionsConfig['http_fonts_path'] = $this->httpFontsPath;
+ }
+
+ if ($this->httpGeneratedImagesPath) {
+ $optionsConfig['http_generated_images_path'] = $this->httpGeneratedImagesPath;
+ }
+
+ if ($this->generatedImagesPath) {
+ $optionsConfig['generated_images_path'] = $this->generatedImagesPath;
+ }
+
+ if ($this->httpJavascriptsPath) {
+ $optionsConfig['http_javascripts_path'] = $this->httpJavascriptsPath;
+ }
+
+ // options in configuration file
+ if (count($optionsConfig)) {
+ $config = array();
+ foreach ($this->plugins as $plugin) {
+ $config[] = sprintf("require '%s'", addcslashes($plugin, '\\'));
+ }
+ foreach ($optionsConfig as $name => $value) {
+ if (!is_array($value)) {
+ $config[] = sprintf('%s = "%s"', $name, addcslashes($value, '\\'));
+ } elseif (!empty($value)) {
+ $config[] = sprintf('%s = %s', $name, $this->formatArrayToRuby($value));
+ }
+ }
+
+ $configFile = tempnam($tempDir, 'assetic_compass');
+ file_put_contents($configFile, implode("\n", $config)."\n");
+ $pb->add('--config')->add($configFile);
+ }
+
+ $pb->add('--sass-dir')->add('')->add('--css-dir')->add('');
+
+ // compass choose the type (sass or scss from the filename)
+ if (null !== $this->scss) {
+ $type = $this->scss ? 'scss' : 'sass';
+ } elseif ($path = $asset->getSourcePath()) {
+ // FIXME: what if the extension is something else?
+ $type = pathinfo($path, PATHINFO_EXTENSION);
+ } else {
+ $type = 'scss';
+ }
+
+ $tempName = tempnam($tempDir, 'assetic_compass');
+ unlink($tempName); // FIXME: don't use tempnam() here
+
+ // input
+ $input = $tempName.'.'.$type;
+
+ // work-around for https://github.com/chriseppstein/compass/issues/748
+ if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
+ $input = str_replace('\\', '/', $input);
+ }
+
+ $pb->add($input);
+ file_put_contents($input, $asset->getContent());
+
+ // output
+ $output = $tempName.'.css';
+
+ if ($this->homeEnv) {
+ // it's not really usefull but... https://github.com/chriseppstein/compass/issues/376
+ $pb->setEnv('HOME', FilesystemUtils::getTemporaryDirectory());
+ $this->mergeEnv($pb);
+ }
+
+ $proc = $pb->getProcess();
+ $code = $proc->run();
+
+ if (0 !== $code) {
+ unlink($input);
+ if (isset($configFile)) {
+ unlink($configFile);
+ }
+
+ throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+ }
+
+ $asset->setContent(file_get_contents($output));
+
+ unlink($input);
+ unlink($output);
+ if (isset($configFile)) {
+ unlink($configFile);
+ }
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ }
+
+ private function formatArrayToRuby($array)
+ {
+ $output = array();
+
+ // does we have an associative array ?
+ if (count(array_filter(array_keys($array), "is_numeric")) != count($array)) {
+ foreach ($array as $name => $value) {
+ $output[] = sprintf(' :%s => "%s"', $name, addcslashes($value, '\\'));
+ }
+ $output = "{\n".implode(",\n", $output)."\n}";
+ } else {
+ foreach ($array as $name => $value) {
+ $output[] = sprintf(' "%s"', addcslashes($value, '\\'));
+ }
+ $output = "[\n".implode(",\n", $output)."\n]";
+ }
+
+ return $output;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssCacheBustingFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssCacheBustingFilter.php
new file mode 100644
index 0000000..5bf8cec
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssCacheBustingFilter.php
@@ -0,0 +1,65 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * Class CssCacheBustingFilter
+ *
+ * @package Assetic\Filter
+ * @author Maximilian Reichel <info@phramz.com>
+ */
+class CssCacheBustingFilter extends BaseCssFilter
+{
+ private $version;
+ private $format = '%s?%s';
+
+ public function setVersion($version)
+ {
+ $this->version = $version;
+ }
+
+ public function setFormat($versionFormat)
+ {
+ $this->format = $versionFormat;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ if (!$this->version) {
+ return;
+ }
+
+ $version = $this->version;
+ $format = $this->format;
+
+ $asset->setContent($this->filterReferences(
+ $asset->getContent(),
+ function ($matches) use ($version, $format) {
+ if (0 === strpos($matches['url'], 'data:')) {
+ return $matches[0];
+ }
+
+ return str_replace(
+ $matches['url'],
+ sprintf($format, $matches['url'], $version),
+ $matches[0]
+ );
+ }
+ ));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssEmbedFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssEmbedFilter.php
new file mode 100644
index 0000000..17970a9
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssEmbedFilter.php
@@ -0,0 +1,143 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Assetic\Factory\AssetFactory;
+use Assetic\Util\FilesystemUtils;
+
+/**
+ * CSSEmbed filter
+ *
+ * @link https://github.com/nzakas/cssembed
+ * @author Maxime Thirouin <maxime.thirouin@gmail.com>
+ */
+class CssEmbedFilter extends BaseProcessFilter implements DependencyExtractorInterface
+{
+ private $jarPath;
+ private $javaPath;
+ private $charset;
+ private $mhtml; // Enable MHTML mode.
+ private $mhtmlRoot; // Use <root> as the MHTML root for the file.
+ private $root; // Prepends <root> to all relative URLs.
+ private $skipMissing; // Don't throw an error for missing image files.
+ private $maxUriLength; // Maximum length for a data URI. Defaults to 32768.
+ private $maxImageSize; // Maximum image size (in bytes) to convert.
+
+ public function __construct($jarPath, $javaPath = '/usr/bin/java')
+ {
+ $this->jarPath = $jarPath;
+ $this->javaPath = $javaPath;
+ }
+
+ public function setCharset($charset)
+ {
+ $this->charset = $charset;
+ }
+
+ public function setMhtml($mhtml)
+ {
+ $this->mhtml = $mhtml;
+ }
+
+ public function setMhtmlRoot($mhtmlRoot)
+ {
+ $this->mhtmlRoot = $mhtmlRoot;
+ }
+
+ public function setRoot($root)
+ {
+ $this->root = $root;
+ }
+
+ public function setSkipMissing($skipMissing)
+ {
+ $this->skipMissing = $skipMissing;
+ }
+
+ public function setMaxUriLength($maxUriLength)
+ {
+ $this->maxUriLength = $maxUriLength;
+ }
+
+ public function setMaxImageSize($maxImageSize)
+ {
+ $this->maxImageSize = $maxImageSize;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ $pb = $this->createProcessBuilder(array(
+ $this->javaPath,
+ '-jar',
+ $this->jarPath,
+ ));
+
+ if (null !== $this->charset) {
+ $pb->add('--charset')->add($this->charset);
+ }
+
+ if ($this->mhtml) {
+ $pb->add('--mhtml');
+ }
+
+ if (null !== $this->mhtmlRoot) {
+ $pb->add('--mhtmlroot')->add($this->mhtmlRoot);
+ }
+
+ // automatically define root if not already defined
+ if (null === $this->root) {
+ if ($dir = $asset->getSourceDirectory()) {
+ $pb->add('--root')->add($dir);
+ }
+ } else {
+ $pb->add('--root')->add($this->root);
+ }
+
+ if ($this->skipMissing) {
+ $pb->add('--skip-missing');
+ }
+
+ if (null !== $this->maxUriLength) {
+ $pb->add('--max-uri-length')->add($this->maxUriLength);
+ }
+
+ if (null !== $this->maxImageSize) {
+ $pb->add('--max-image-size')->add($this->maxImageSize);
+ }
+
+ // input
+ $pb->add($input = FilesystemUtils::createTemporaryFile('cssembed'));
+ file_put_contents($input, $asset->getContent());
+
+ $proc = $pb->getProcess();
+ $code = $proc->run();
+ unlink($input);
+
+ if (0 !== $code) {
+ throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+ }
+
+ $asset->setContent($proc->getOutput());
+ }
+
+ public function getChildren(AssetFactory $factory, $content, $loadPath = null)
+ {
+ // todo
+ return array();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssImportFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssImportFilter.php
new file mode 100644
index 0000000..77ec1c4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssImportFilter.php
@@ -0,0 +1,108 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Asset\FileAsset;
+use Assetic\Asset\HttpAsset;
+use Assetic\Factory\AssetFactory;
+
+/**
+ * Inlines imported stylesheets.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class CssImportFilter extends BaseCssFilter implements DependencyExtractorInterface
+{
+ private $importFilter;
+
+ /**
+ * Constructor.
+ *
+ * @param FilterInterface $importFilter Filter for each imported asset
+ */
+ public function __construct(FilterInterface $importFilter = null)
+ {
+ $this->importFilter = $importFilter ?: new CssRewriteFilter();
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ $importFilter = $this->importFilter;
+ $sourceRoot = $asset->getSourceRoot();
+ $sourcePath = $asset->getSourcePath();
+
+ $callback = function ($matches) use ($importFilter, $sourceRoot, $sourcePath) {
+ if (!$matches['url'] || null === $sourceRoot) {
+ return $matches[0];
+ }
+
+ $importRoot = $sourceRoot;
+
+ if (false !== strpos($matches['url'], '://')) {
+ // absolute
+ list($importScheme, $tmp) = explode('://', $matches['url'], 2);
+ list($importHost, $importPath) = explode('/', $tmp, 2);
+ $importRoot = $importScheme.'://'.$importHost;
+ } elseif (0 === strpos($matches['url'], '//')) {
+ // protocol-relative
+ list($importHost, $importPath) = explode('/', substr($matches['url'], 2), 2);
+ $importRoot = '//'.$importHost;
+ } elseif ('/' == $matches['url'][0]) {
+ // root-relative
+ $importPath = substr($matches['url'], 1);
+ } elseif (null !== $sourcePath) {
+ // document-relative
+ $importPath = $matches['url'];
+ if ('.' != $sourceDir = dirname($sourcePath)) {
+ $importPath = $sourceDir.'/'.$importPath;
+ }
+ } else {
+ return $matches[0];
+ }
+
+ $importSource = $importRoot.'/'.$importPath;
+ if (false !== strpos($importSource, '://') || 0 === strpos($importSource, '//')) {
+ $import = new HttpAsset($importSource, array($importFilter), true);
+ } elseif ('css' != pathinfo($importPath, PATHINFO_EXTENSION) || !file_exists($importSource)) {
+ // ignore non-css and non-existant imports
+ return $matches[0];
+ } else {
+ $import = new FileAsset($importSource, array($importFilter), $importRoot, $importPath);
+ }
+
+ $import->setTargetPath($sourcePath);
+
+ return $import->dump();
+ };
+
+ $content = $asset->getContent();
+ $lastHash = md5($content);
+
+ do {
+ $content = $this->filterImports($content, $callback);
+ $hash = md5($content);
+ } while ($lastHash != $hash && $lastHash = $hash);
+
+ $asset->setContent($content);
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ }
+
+ public function getChildren(AssetFactory $factory, $content, $loadPath = null)
+ {
+ // todo
+ return array();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssMinFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssMinFilter.php
new file mode 100644
index 0000000..6f0b0d2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssMinFilter.php
@@ -0,0 +1,72 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * Filters assets through CssMin.
+ *
+ * @link http://code.google.com/p/cssmin
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class CssMinFilter implements FilterInterface
+{
+ private $filters;
+ private $plugins;
+
+ public function __construct()
+ {
+ $this->filters = array();
+ $this->plugins = array();
+ }
+
+ public function setFilters(array $filters)
+ {
+ $this->filters = $filters;
+ }
+
+ public function setFilter($name, $value)
+ {
+ $this->filters[$name] = $value;
+ }
+
+ public function setPlugins(array $plugins)
+ {
+ $this->plugins = $plugins;
+ }
+
+ public function setPlugin($name, $value)
+ {
+ $this->plugins[$name] = $value;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ $filters = $this->filters;
+ $plugins = $this->plugins;
+
+ if (isset($filters['ImportImports']) && true === $filters['ImportImports']) {
+ if ($dir = $asset->getSourceDirectory()) {
+ $filters['ImportImports'] = array('BasePath' => $dir);
+ } else {
+ unset($filters['ImportImports']);
+ }
+ }
+
+ $asset->setContent(\CssMin::minify($asset->getContent(), $filters, $plugins));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssRewriteFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssRewriteFilter.php
new file mode 100644
index 0000000..c2250c3
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/CssRewriteFilter.php
@@ -0,0 +1,102 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * Fixes relative CSS urls.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class CssRewriteFilter extends BaseCssFilter
+{
+ public function filterLoad(AssetInterface $asset)
+ {
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ $sourceBase = $asset->getSourceRoot();
+ $sourcePath = $asset->getSourcePath();
+ $targetPath = $asset->getTargetPath();
+
+ if (null === $sourcePath || null === $targetPath || $sourcePath == $targetPath) {
+ return;
+ }
+
+ // learn how to get from the target back to the source
+ if (false !== strpos($sourceBase, '://')) {
+ list($scheme, $url) = explode('://', $sourceBase.'/'.$sourcePath, 2);
+ list($host, $path) = explode('/', $url, 2);
+
+ $host = $scheme.'://'.$host.'/';
+ $path = false === strpos($path, '/') ? '' : dirname($path);
+ $path .= '/';
+ } else {
+ // assume source and target are on the same host
+ $host = '';
+
+ // pop entries off the target until it fits in the source
+ if ('.' == dirname($sourcePath)) {
+ $path = str_repeat('../', substr_count($targetPath, '/'));
+ } elseif ('.' == $targetDir = dirname($targetPath)) {
+ $path = dirname($sourcePath).'/';
+ } else {
+ $path = '';
+ while (0 !== strpos($sourcePath, $targetDir)) {
+ if (false !== $pos = strrpos($targetDir, '/')) {
+ $targetDir = substr($targetDir, 0, $pos);
+ $path .= '../';
+ } else {
+ $targetDir = '';
+ $path .= '../';
+ break;
+ }
+ }
+ $path .= ltrim(substr(dirname($sourcePath).'/', strlen($targetDir)), '/');
+ }
+ }
+
+ $content = $this->filterReferences($asset->getContent(), function ($matches) use ($host, $path) {
+ if (false !== strpos($matches['url'], '://') || 0 === strpos($matches['url'], '//') || 0 === strpos($matches['url'], 'data:')) {
+ // absolute or protocol-relative or data uri
+ return $matches[0];
+ }
+
+ if (isset($matches['url'][0]) && '/' == $matches['url'][0]) {
+ // root relative
+ return str_replace($matches['url'], $host.$matches['url'], $matches[0]);
+ }
+
+ // document relative
+ $url = $matches['url'];
+ while (0 === strpos($url, '../') && 2 <= substr_count($path, '/')) {
+ $path = substr($path, 0, strrpos(rtrim($path, '/'), '/') + 1);
+ $url = substr($url, 3);
+ }
+
+ $parts = array();
+ foreach (explode('/', $host.$path.$url) as $part) {
+ if ('..' === $part && count($parts) && '..' !== end($parts)) {
+ array_pop($parts);
+ } else {
+ $parts[] = $part;
+ }
+ }
+
+ return str_replace($matches['url'], implode('/', $parts), $matches[0]);
+ });
+
+ $asset->setContent($content);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/DartFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/DartFilter.php
new file mode 100644
index 0000000..12a3918
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/DartFilter.php
@@ -0,0 +1,73 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Assetic\Util\FilesystemUtils;
+
+/**
+ * Compiles Dart into Javascript.
+ *
+ * @link http://dartlang.org/
+ */
+class DartFilter extends BaseProcessFilter
+{
+ private $dartBin;
+
+ public function __construct($dartBin = '/usr/bin/dart2js')
+ {
+ $this->dartBin = $dartBin;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ $input = FilesystemUtils::createTemporaryFile('dart');
+ $output = FilesystemUtils::createTemporaryFile('dart');
+
+ file_put_contents($input, $asset->getContent());
+
+ $pb = $this->createProcessBuilder()
+ ->add($this->dartBin)
+ ->add('-o'.$output)
+ ->add($input)
+ ;
+
+ $proc = $pb->getProcess();
+ $code = $proc->run();
+ unlink($input);
+
+ if (0 !== $code) {
+ $this->cleanup($output);
+
+ throw FilterException::fromProcess($proc);
+ }
+
+ if (!file_exists($output)) {
+ throw new \RuntimeException('Error creating output file.');
+ }
+
+ $asset->setContent(file_get_contents($output));
+ $this->cleanup($output);
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ }
+
+ private function cleanup($file)
+ {
+ foreach (glob($file.'*') as $related) {
+ unlink($related);
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/DependencyExtractorInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/DependencyExtractorInterface.php
new file mode 100644
index 0000000..6b9a8fb
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/DependencyExtractorInterface.php
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Factory\AssetFactory;
+
+/**
+ * A filter that knows how to extract dependencies.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+interface DependencyExtractorInterface extends FilterInterface
+{
+ /**
+ * Returns child assets.
+ *
+ * @param AssetFactory $factory The asset factory
+ * @param string $content The asset content
+ * @param string $loadPath An optional load path
+ *
+ * @return AssetInterface[] Child assets
+ */
+ public function getChildren(AssetFactory $factory, $content, $loadPath = null);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/EmberPrecompileFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/EmberPrecompileFilter.php
new file mode 100644
index 0000000..313d4a0
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/EmberPrecompileFilter.php
@@ -0,0 +1,87 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Assetic\Util\FilesystemUtils;
+
+/**
+ * Precompiles Handlebars templates for use in the Ember.js framework. This filter
+ * requires that the npm package ember-precompile be installed. You can find this
+ * package at https://github.com/gabrielgrant/node-ember-precompile.
+ *
+ * @link http://www.emberjs.com/
+ * @author Jarrod Nettles <jarrod.nettles@icloud.com>
+ */
+class EmberPrecompileFilter extends BaseNodeFilter
+{
+ private $emberBin;
+ private $nodeBin;
+
+ public function __construct($handlebarsBin = '/usr/bin/ember-precompile', $nodeBin = null)
+ {
+ $this->emberBin = $handlebarsBin;
+ $this->nodeBin = $nodeBin;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ $pb = $this->createProcessBuilder($this->nodeBin
+ ? array($this->nodeBin, $this->emberBin)
+ : array($this->emberBin));
+
+ if ($sourcePath = $asset->getSourcePath()) {
+ $templateName = basename($sourcePath);
+ } else {
+ throw new \LogicException('The embed-precompile filter requires that assets have a source path set');
+ }
+
+ $inputDirPath = FilesystemUtils::createThrowAwayDirectory('ember_in');
+ $inputPath = $inputDirPath.DIRECTORY_SEPARATOR.$templateName;
+ $outputPath = FilesystemUtils::createTemporaryFile('ember_out');
+
+ file_put_contents($inputPath, $asset->getContent());
+
+ $pb->add($inputPath)->add('-f')->add($outputPath);
+
+ $process = $pb->getProcess();
+ $returnCode = $process->run();
+
+ unlink($inputPath);
+ rmdir($inputDirPath);
+
+ if (127 === $returnCode) {
+ throw new \RuntimeException('Path to node executable could not be resolved.');
+ }
+
+ if (0 !== $returnCode) {
+ if (file_exists($outputPath)) {
+ unlink($outputPath);
+ }
+ throw FilterException::fromProcess($process)->setInput($asset->getContent());
+ }
+
+ if (!file_exists($outputPath)) {
+ throw new \RuntimeException('Error creating output file.');
+ }
+
+ $compiledJs = file_get_contents($outputPath);
+ unlink($outputPath);
+
+ $asset->setContent($compiledJs);
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/FilterCollection.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/FilterCollection.php
new file mode 100644
index 0000000..0fcd54e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/FilterCollection.php
@@ -0,0 +1,82 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * A collection of filters.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class FilterCollection implements FilterInterface, \IteratorAggregate, \Countable
+{
+ private $filters = array();
+
+ public function __construct($filters = array())
+ {
+ foreach ($filters as $filter) {
+ $this->ensure($filter);
+ }
+ }
+
+ /**
+ * Checks that the current collection contains the supplied filter.
+ *
+ * If the supplied filter is another filter collection, each of its
+ * filters will be checked.
+ */
+ public function ensure(FilterInterface $filter)
+ {
+ if ($filter instanceof \Traversable) {
+ foreach ($filter as $f) {
+ $this->ensure($f);
+ }
+ } elseif (!in_array($filter, $this->filters, true)) {
+ $this->filters[] = $filter;
+ }
+ }
+
+ public function all()
+ {
+ return $this->filters;
+ }
+
+ public function clear()
+ {
+ $this->filters = array();
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ foreach ($this->filters as $filter) {
+ $filter->filterLoad($asset);
+ }
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ foreach ($this->filters as $filter) {
+ $filter->filterDump($asset);
+ }
+ }
+
+ public function getIterator()
+ {
+ return new \ArrayIterator($this->filters);
+ }
+
+ public function count()
+ {
+ return count($this->filters);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/FilterInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/FilterInterface.php
new file mode 100644
index 0000000..797ac68
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/FilterInterface.php
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * A filter manipulates an asset at load and dump.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+interface FilterInterface
+{
+ /**
+ * Filters an asset after it has been loaded.
+ *
+ * @param AssetInterface $asset An asset
+ */
+ public function filterLoad(AssetInterface $asset);
+
+ /**
+ * Filters an asset just before it's dumped.
+ *
+ * @param AssetInterface $asset An asset
+ */
+ public function filterDump(AssetInterface $asset);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/BaseCompilerFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/BaseCompilerFilter.php
new file mode 100644
index 0000000..2509f4a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/BaseCompilerFilter.php
@@ -0,0 +1,101 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter\GoogleClosure;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Filter\FilterInterface;
+
+/**
+ * Base filter for the Google Closure Compiler implementations.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+abstract class BaseCompilerFilter implements FilterInterface
+{
+ // compilation levels
+ const COMPILE_WHITESPACE_ONLY = 'WHITESPACE_ONLY';
+ const COMPILE_SIMPLE_OPTIMIZATIONS = 'SIMPLE_OPTIMIZATIONS';
+ const COMPILE_ADVANCED_OPTIMIZATIONS = 'ADVANCED_OPTIMIZATIONS';
+
+ // formatting modes
+ const FORMAT_PRETTY_PRINT = 'pretty_print';
+ const FORMAT_PRINT_INPUT_DELIMITER = 'print_input_delimiter';
+
+ // warning levels
+ const LEVEL_QUIET = 'QUIET';
+ const LEVEL_DEFAULT = 'DEFAULT';
+ const LEVEL_VERBOSE = 'VERBOSE';
+
+ // languages
+ const LANGUAGE_ECMASCRIPT3 = 'ECMASCRIPT3';
+ const LANGUAGE_ECMASCRIPT5 = 'ECMASCRIPT5';
+ const LANGUAGE_ECMASCRIPT5_STRICT = 'ECMASCRIPT5_STRICT';
+
+ protected $timeout;
+ protected $compilationLevel;
+ protected $jsExterns;
+ protected $externsUrl;
+ protected $excludeDefaultExterns;
+ protected $formatting;
+ protected $useClosureLibrary;
+ protected $warningLevel;
+ protected $language;
+
+ public function setTimeout($timeout)
+ {
+ $this->timeout = $timeout;
+ }
+
+ public function setCompilationLevel($compilationLevel)
+ {
+ $this->compilationLevel = $compilationLevel;
+ }
+
+ public function setJsExterns($jsExterns)
+ {
+ $this->jsExterns = $jsExterns;
+ }
+
+ public function setExternsUrl($externsUrl)
+ {
+ $this->externsUrl = $externsUrl;
+ }
+
+ public function setExcludeDefaultExterns($excludeDefaultExterns)
+ {
+ $this->excludeDefaultExterns = $excludeDefaultExterns;
+ }
+
+ public function setFormatting($formatting)
+ {
+ $this->formatting = $formatting;
+ }
+
+ public function setUseClosureLibrary($useClosureLibrary)
+ {
+ $this->useClosureLibrary = $useClosureLibrary;
+ }
+
+ public function setWarningLevel($warningLevel)
+ {
+ $this->warningLevel = $warningLevel;
+ }
+
+ public function setLanguage($language)
+ {
+ $this->language = $language;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/CompilerApiFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/CompilerApiFilter.php
new file mode 100644
index 0000000..3478057
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/CompilerApiFilter.php
@@ -0,0 +1,130 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter\GoogleClosure;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * Filter for the Google Closure Compiler API.
+ *
+ * @link https://developers.google.com/closure/compiler/
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class CompilerApiFilter extends BaseCompilerFilter
+{
+ private $proxy;
+ private $proxyFullUri;
+
+ public function setProxy($proxy)
+ {
+ $this->proxy = $proxy;
+ }
+
+ public function setProxyFullUri($proxyFullUri)
+ {
+ $this->proxyFullUri = $proxyFullUri;
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ $query = array(
+ 'js_code' => $asset->getContent(),
+ 'output_format' => 'json',
+ 'output_info' => 'compiled_code',
+ );
+
+ if (null !== $this->compilationLevel) {
+ $query['compilation_level'] = $this->compilationLevel;
+ }
+
+ if (null !== $this->jsExterns) {
+ $query['js_externs'] = $this->jsExterns;
+ }
+
+ if (null !== $this->externsUrl) {
+ $query['externs_url'] = $this->externsUrl;
+ }
+
+ if (null !== $this->excludeDefaultExterns) {
+ $query['exclude_default_externs'] = $this->excludeDefaultExterns ? 'true' : 'false';
+ }
+
+ if (null !== $this->formatting) {
+ $query['formatting'] = $this->formatting;
+ }
+
+ if (null !== $this->useClosureLibrary) {
+ $query['use_closure_library'] = $this->useClosureLibrary ? 'true' : 'false';
+ }
+
+ if (null !== $this->warningLevel) {
+ $query['warning_level'] = $this->warningLevel;
+ }
+
+ if (null !== $this->language) {
+ $query['language'] = $this->language;
+ }
+
+ if (preg_match('/1|yes|on|true/i', ini_get('allow_url_fopen'))) {
+ $contextOptions = array('http' => array(
+ 'method' => 'POST',
+ 'header' => 'Content-Type: application/x-www-form-urlencoded',
+ 'content' => http_build_query($query),
+ ));
+ if (null !== $this->timeout) {
+ $contextOptions['http']['timeout'] = $this->timeout;
+ }
+ if ($this->proxy) {
+ $contextOptions['http']['proxy'] = $this->proxy;
+ $contextOptions['http']['request_fulluri'] = (Boolean) $this->proxyFullUri;
+ }
+ $context = stream_context_create($contextOptions);
+
+ $response = file_get_contents('http://closure-compiler.appspot.com/compile', false, $context);
+ $data = json_decode($response);
+ } elseif (defined('CURLOPT_POST') && !in_array('curl_init', explode(',', ini_get('disable_functions')))) {
+ $ch = curl_init('http://closure-compiler.appspot.com/compile');
+ curl_setopt($ch, CURLOPT_POST, true);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/x-www-form-urlencoded'));
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
+ if (null !== $this->timeout) {
+ curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
+ }
+ if ($this->proxy) {
+ curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, true);
+ curl_setopt($ch, CURLOPT_PROXY, $this->proxy);
+ }
+ $response = curl_exec($ch);
+ curl_close($ch);
+
+ $data = json_decode($response);
+ } else {
+ throw new \RuntimeException("There is no known way to contact closure compiler available");
+ }
+
+ if (isset($data->serverErrors) && 0 < count($data->serverErrors)) {
+ // @codeCoverageIgnoreStart
+ throw new \RuntimeException(sprintf('The Google Closure Compiler API threw some server errors: '.print_r($data->serverErrors, true)));
+ // @codeCoverageIgnoreEnd
+ }
+
+ if (isset($data->errors) && 0 < count($data->errors)) {
+ // @codeCoverageIgnoreStart
+ throw new \RuntimeException(sprintf('The Google Closure Compiler API threw some errors: '.print_r($data->errors, true)));
+ // @codeCoverageIgnoreEnd
+ }
+
+ $asset->setContent($data->compiledCode);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/CompilerJarFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/CompilerJarFilter.php
new file mode 100644
index 0000000..7cd340e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/CompilerJarFilter.php
@@ -0,0 +1,112 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter\GoogleClosure;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Assetic\Util\FilesystemUtils;
+use Symfony\Component\Process\ProcessBuilder;
+
+/**
+ * Filter for the Google Closure Compiler JAR.
+ *
+ * @link https://developers.google.com/closure/compiler/
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class CompilerJarFilter extends BaseCompilerFilter
+{
+ private $jarPath;
+ private $javaPath;
+ private $flagFile;
+
+ public function __construct($jarPath, $javaPath = '/usr/bin/java')
+ {
+ $this->jarPath = $jarPath;
+ $this->javaPath = $javaPath;
+ }
+
+ public function setFlagFile($flagFile)
+ {
+ $this->flagFile = $flagFile;
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ $is64bit = PHP_INT_SIZE === 8;
+ $cleanup = array();
+
+ $pb = new ProcessBuilder(array_merge(
+ array($this->javaPath),
+ $is64bit
+ ? array('-server', '-XX:+TieredCompilation')
+ : array('-client', '-d32'),
+ array('-jar', $this->jarPath)
+ ));
+
+ if (null !== $this->timeout) {
+ $pb->setTimeout($this->timeout);
+ }
+
+ if (null !== $this->compilationLevel) {
+ $pb->add('--compilation_level')->add($this->compilationLevel);
+ }
+
+ if (null !== $this->jsExterns) {
+ $cleanup[] = $externs = FilesystemUtils::createTemporaryFile('google_closure');
+ file_put_contents($externs, $this->jsExterns);
+ $pb->add('--externs')->add($externs);
+ }
+
+ if (null !== $this->externsUrl) {
+ $cleanup[] = $externs = FilesystemUtils::createTemporaryFile('google_closure');
+ file_put_contents($externs, file_get_contents($this->externsUrl));
+ $pb->add('--externs')->add($externs);
+ }
+
+ if (null !== $this->excludeDefaultExterns) {
+ $pb->add('--use_only_custom_externs');
+ }
+
+ if (null !== $this->formatting) {
+ $pb->add('--formatting')->add($this->formatting);
+ }
+
+ if (null !== $this->useClosureLibrary) {
+ $pb->add('--manage_closure_dependencies');
+ }
+
+ if (null !== $this->warningLevel) {
+ $pb->add('--warning_level')->add($this->warningLevel);
+ }
+
+ if (null !== $this->language) {
+ $pb->add('--language_in')->add($this->language);
+ }
+
+ if (null !== $this->flagFile) {
+ $pb->add('--flagfile')->add($this->flagFile);
+ }
+
+ $pb->add('--js')->add($cleanup[] = $input = FilesystemUtils::createTemporaryFile('google_closure'));
+ file_put_contents($input, $asset->getContent());
+
+ $proc = $pb->getProcess();
+ $code = $proc->run();
+ array_map('unlink', $cleanup);
+
+ if (0 !== $code) {
+ throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+ }
+
+ $asset->setContent($proc->getOutput());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/GssFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/GssFilter.php
new file mode 100644
index 0000000..4b55610
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/GssFilter.php
@@ -0,0 +1,142 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Assetic\Util\FilesystemUtils;
+
+/**
+ * Filter for the Google Closure Stylesheets Compiler JAR.
+ *
+ * @link http://code.google.com/p/closure-stylesheets/
+ * @author Matthias Krauser <matthias@krauser.eu>
+ */
+class GssFilter extends BaseProcessFilter
+{
+ private $jarPath;
+ private $javaPath;
+ private $allowUnrecognizedFunctions;
+ private $allowedNonStandardFunctions;
+ private $copyrightNotice;
+ private $define;
+ private $gssFunctionMapProvider;
+ private $inputOrientation;
+ private $outputOrientation;
+ private $prettyPrint;
+
+ public function __construct($jarPath, $javaPath = '/usr/bin/java')
+ {
+ $this->jarPath = $jarPath;
+ $this->javaPath = $javaPath;
+ }
+
+ public function setAllowUnrecognizedFunctions($allowUnrecognizedFunctions)
+ {
+ $this->allowUnrecognizedFunctions = $allowUnrecognizedFunctions;
+ }
+
+ public function setAllowedNonStandardFunctions($allowNonStandardFunctions)
+ {
+ $this->allowedNonStandardFunctions = $allowNonStandardFunctions;
+ }
+
+ public function setCopyrightNotice($copyrightNotice)
+ {
+ $this->copyrightNotice = $copyrightNotice;
+ }
+
+ public function setDefine($define)
+ {
+ $this->define = $define;
+ }
+
+ public function setGssFunctionMapProvider($gssFunctionMapProvider)
+ {
+ $this->gssFunctionMapProvider = $gssFunctionMapProvider;
+ }
+
+ public function setInputOrientation($inputOrientation)
+ {
+ $this->inputOrientation = $inputOrientation;
+ }
+
+ public function setOutputOrientation($outputOrientation)
+ {
+ $this->outputOrientation = $outputOrientation;
+ }
+
+ public function setPrettyPrint($prettyPrint)
+ {
+ $this->prettyPrint = $prettyPrint;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ $cleanup = array();
+
+ $pb = $this->createProcessBuilder(array(
+ $this->javaPath,
+ '-jar',
+ $this->jarPath,
+ ));
+
+ if (null !== $this->allowUnrecognizedFunctions) {
+ $pb->add('--allow-unrecognized-functions');
+ }
+
+ if (null !== $this->allowedNonStandardFunctions) {
+ $pb->add('--allowed_non_standard_functions')->add($this->allowedNonStandardFunctions);
+ }
+
+ if (null !== $this->copyrightNotice) {
+ $pb->add('--copyright-notice')->add($this->copyrightNotice);
+ }
+
+ if (null !== $this->define) {
+ $pb->add('--define')->add($this->define);
+ }
+
+ if (null !== $this->gssFunctionMapProvider) {
+ $pb->add('--gss-function-map-provider')->add($this->gssFunctionMapProvider);
+ }
+
+ if (null !== $this->inputOrientation) {
+ $pb->add('--input-orientation')->add($this->inputOrientation);
+ }
+
+ if (null !== $this->outputOrientation) {
+ $pb->add('--output-orientation')->add($this->outputOrientation);
+ }
+
+ if (null !== $this->prettyPrint) {
+ $pb->add('--pretty-print');
+ }
+
+ $pb->add($cleanup[] = $input = FilesystemUtils::createTemporaryFile('gss'));
+ file_put_contents($input, $asset->getContent());
+
+ $proc = $pb->getProcess();
+ $code = $proc->run();
+ array_map('unlink', $cleanup);
+
+ if (0 !== $code) {
+ throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+ }
+
+ $asset->setContent($proc->getOutput());
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/HandlebarsFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/HandlebarsFilter.php
new file mode 100644
index 0000000..f34927f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/HandlebarsFilter.php
@@ -0,0 +1,106 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Assetic\Util\FilesystemUtils;
+
+/**
+ * Compiles Handlebars templates into Javascript.
+ *
+ * @link http://handlebarsjs.com/
+ * @author Keyvan Akbary <keyvan@funddy.com>
+ */
+class HandlebarsFilter extends BaseNodeFilter
+{
+ private $handlebarsBin;
+ private $nodeBin;
+
+ private $minimize = false;
+ private $simple = false;
+
+ public function __construct($handlebarsBin = '/usr/bin/handlebars', $nodeBin = null)
+ {
+ $this->handlebarsBin = $handlebarsBin;
+ $this->nodeBin = $nodeBin;
+ }
+
+ public function setMinimize($minimize)
+ {
+ $this->minimize = $minimize;
+ }
+
+ public function setSimple($simple)
+ {
+ $this->simple = $simple;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ $pb = $this->createProcessBuilder($this->nodeBin
+ ? array($this->nodeBin, $this->handlebarsBin)
+ : array($this->handlebarsBin));
+
+ if ($sourcePath = $asset->getSourcePath()) {
+ $templateName = basename($sourcePath);
+ } else {
+ throw new \LogicException('The handlebars filter requires that assets have a source path set');
+ }
+
+ $inputDirPath = FilesystemUtils::createThrowAwayDirectory('handlebars_in');
+ $inputPath = $inputDirPath.DIRECTORY_SEPARATOR.$templateName;
+ $outputPath = FilesystemUtils::createTemporaryFile('handlebars_out');
+
+ file_put_contents($inputPath, $asset->getContent());
+
+ $pb->add($inputPath)->add('-f')->add($outputPath);
+
+ if ($this->minimize) {
+ $pb->add('--min');
+ }
+
+ if ($this->simple) {
+ $pb->add('--simple');
+ }
+
+ $process = $pb->getProcess();
+ $returnCode = $process->run();
+
+ unlink($inputPath);
+ rmdir($inputDirPath);
+
+ if (127 === $returnCode) {
+ throw new \RuntimeException('Path to node executable could not be resolved.');
+ }
+
+ if (0 !== $returnCode) {
+ if (file_exists($outputPath)) {
+ unlink($outputPath);
+ }
+ throw FilterException::fromProcess($process)->setInput($asset->getContent());
+ }
+
+ if (!file_exists($outputPath)) {
+ throw new \RuntimeException('Error creating output file.');
+ }
+
+ $compiledJs = file_get_contents($outputPath);
+ unlink($outputPath);
+
+ $asset->setContent($compiledJs);
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/HashableInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/HashableInterface.php
new file mode 100644
index 0000000..cd3ffda
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/HashableInterface.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+/**
+ * A filter can implement a hash function
+ *
+ * @author Francisco Facioni <fran6co@gmail.com>
+ */
+interface HashableInterface
+{
+ /**
+ * Generates a hash for the object
+ *
+ * @return string Object hash
+ */
+ public function hash();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/JSMinFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/JSMinFilter.php
new file mode 100644
index 0000000..884656b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/JSMinFilter.php
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * Filters assets through JsMin.
+ *
+ * All credit for the filter itself is mentioned in the file itself.
+ *
+ * @link https://raw.github.com/mrclay/minify/master/min/lib/JSMin.php
+ * @author Brunoais <brunoaiss@gmail.com>
+ */
+class JSMinFilter implements FilterInterface
+{
+ public function filterLoad(AssetInterface $asset)
+ {
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ $asset->setContent(\JSMin::minify($asset->getContent()));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/JSMinPlusFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/JSMinPlusFilter.php
new file mode 100644
index 0000000..14cd085
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/JSMinPlusFilter.php
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * Filters assets through JSMinPlus.
+ *
+ * All credit for the filter itself is mentioned in the file itself.
+ *
+ * @link https://raw.github.com/mrclay/minify/master/min/lib/JSMinPlus.php
+ * @author Brunoais <brunoaiss@gmail.com>
+ */
+class JSMinPlusFilter implements FilterInterface
+{
+ public function filterLoad(AssetInterface $asset)
+ {
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ $asset->setContent(\JSMinPlus::minify($asset->getContent()));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/JSqueezeFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/JSqueezeFilter.php
new file mode 100644
index 0000000..07c7fd6
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/JSqueezeFilter.php
@@ -0,0 +1,77 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * JSqueeze filter.
+ *
+ * @link https://github.com/nicolas-grekas/JSqueeze
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class JSqueezeFilter implements FilterInterface
+{
+ private $singleLine = true;
+ private $keepImportantComments = true;
+ private $className;
+ private $specialVarRx = false;
+ private $defaultRx;
+
+ public function __construct()
+ {
+ // JSqueeze is namespaced since 2.x, this works with both 1.x and 2.x
+ if (class_exists('\\Patchwork\\JSqueeze')) {
+ $this->className = '\\Patchwork\\JSqueeze';
+ $this->defaultRx = \Patchwork\JSqueeze::SPECIAL_VAR_PACKER;
+ } else {
+ $this->className = '\\JSqueeze';
+ $this->defaultRx = \JSqueeze::SPECIAL_VAR_RX;
+ }
+ }
+
+ public function setSingleLine($bool)
+ {
+ $this->singleLine = (bool) $bool;
+ }
+
+ // call setSpecialVarRx(true) to enable global var/method/property
+ // renaming with the default regex (for 1.x or 2.x)
+ public function setSpecialVarRx($specialVarRx)
+ {
+ if (true === $specialVarRx) {
+ $this->specialVarRx = $this->defaultRx;
+ } else {
+ $this->specialVarRx = $specialVarRx;
+ }
+ }
+
+ public function keepImportantComments($bool)
+ {
+ $this->keepImportantComments = (bool) $bool;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ $parser = new $this->className();
+ $asset->setContent($parser->squeeze(
+ $asset->getContent(),
+ $this->singleLine,
+ $this->keepImportantComments,
+ $this->specialVarRx
+ ));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/JpegoptimFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/JpegoptimFilter.php
new file mode 100644
index 0000000..fcc1489
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/JpegoptimFilter.php
@@ -0,0 +1,81 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Assetic\Util\FilesystemUtils;
+
+/**
+ * Runs assets through Jpegoptim.
+ *
+ * @link http://www.kokkonen.net/tjko/projects.html
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class JpegoptimFilter extends BaseProcessFilter
+{
+ private $jpegoptimBin;
+ private $stripAll;
+ private $max;
+
+ /**
+ * Constructor.
+ *
+ * @param string $jpegoptimBin Path to the jpegoptim binary
+ */
+ public function __construct($jpegoptimBin = '/usr/bin/jpegoptim')
+ {
+ $this->jpegoptimBin = $jpegoptimBin;
+ }
+
+ public function setStripAll($stripAll)
+ {
+ $this->stripAll = $stripAll;
+ }
+
+ public function setMax($max)
+ {
+ $this->max = $max;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ $pb = $this->createProcessBuilder(array($this->jpegoptimBin));
+
+ if ($this->stripAll) {
+ $pb->add('--strip-all');
+ }
+
+ if ($this->max) {
+ $pb->add('--max='.$this->max);
+ }
+
+ $pb->add($input = FilesystemUtils::createTemporaryFile('jpegoptim'));
+ file_put_contents($input, $asset->getContent());
+
+ $proc = $pb->getProcess();
+ $proc->run();
+
+ if (false !== strpos($proc->getOutput(), 'ERROR')) {
+ unlink($input);
+ throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+ }
+
+ $asset->setContent(file_get_contents($input));
+
+ unlink($input);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/JpegtranFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/JpegtranFilter.php
new file mode 100644
index 0000000..7836538
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/JpegtranFilter.php
@@ -0,0 +1,103 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Assetic\Util\FilesystemUtils;
+
+/**
+ * Runs assets through jpegtran.
+ *
+ * @link http://jpegclub.org/jpegtran/
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class JpegtranFilter extends BaseProcessFilter
+{
+ const COPY_NONE = 'none';
+ const COPY_COMMENTS = 'comments';
+ const COPY_ALL = 'all';
+
+ private $jpegtranBin;
+ private $optimize;
+ private $copy;
+ private $progressive;
+ private $restart;
+
+ /**
+ * Constructor.
+ *
+ * @param string $jpegtranBin Path to the jpegtran binary
+ */
+ public function __construct($jpegtranBin = '/usr/bin/jpegtran')
+ {
+ $this->jpegtranBin = $jpegtranBin;
+ }
+
+ public function setOptimize($optimize)
+ {
+ $this->optimize = $optimize;
+ }
+
+ public function setCopy($copy)
+ {
+ $this->copy = $copy;
+ }
+
+ public function setProgressive($progressive)
+ {
+ $this->progressive = $progressive;
+ }
+
+ public function setRestart($restart)
+ {
+ $this->restart = $restart;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ $pb = $this->createProcessBuilder(array($this->jpegtranBin));
+
+ if ($this->optimize) {
+ $pb->add('-optimize');
+ }
+
+ if ($this->copy) {
+ $pb->add('-copy')->add($this->copy);
+ }
+
+ if ($this->progressive) {
+ $pb->add('-progressive');
+ }
+
+ if (null !== $this->restart) {
+ $pb->add('-restart')->add($this->restart);
+ }
+
+ $pb->add($input = FilesystemUtils::createTemporaryFile('jpegtran'));
+ file_put_contents($input, $asset->getContent());
+
+ $proc = $pb->getProcess();
+ $code = $proc->run();
+ unlink($input);
+
+ if (0 !== $code) {
+ throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+ }
+
+ $asset->setContent($proc->getOutput());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/LessFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/LessFilter.php
new file mode 100644
index 0000000..7ca5cd7
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/LessFilter.php
@@ -0,0 +1,206 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Assetic\Factory\AssetFactory;
+use Assetic\Util\FilesystemUtils;
+use Assetic\Util\LessUtils;
+
+/**
+ * Loads LESS files.
+ *
+ * @link http://lesscss.org/
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class LessFilter extends BaseNodeFilter implements DependencyExtractorInterface
+{
+ private $nodeBin;
+
+ /**
+ * @var array
+ */
+ private $treeOptions;
+
+ /**
+ * @var array
+ */
+ private $parserOptions;
+
+ /**
+ * Load Paths
+ *
+ * A list of paths which less will search for includes.
+ *
+ * @var array
+ */
+ protected $loadPaths = array();
+
+ /**
+ * Constructor.
+ *
+ * @param string $nodeBin The path to the node binary
+ * @param array $nodePaths An array of node paths
+ */
+ public function __construct($nodeBin = '/usr/bin/node', array $nodePaths = array())
+ {
+ $this->nodeBin = $nodeBin;
+ $this->setNodePaths($nodePaths);
+ $this->treeOptions = array();
+ $this->parserOptions = array();
+ }
+
+ /**
+ * @param bool $compress
+ */
+ public function setCompress($compress)
+ {
+ $this->addTreeOption('compress', $compress);
+ }
+
+ public function setLoadPaths(array $loadPaths)
+ {
+ $this->loadPaths = $loadPaths;
+ }
+
+ /**
+ * Adds a path where less will search for includes
+ *
+ * @param string $path Load path (absolute)
+ */
+ public function addLoadPath($path)
+ {
+ $this->loadPaths[] = $path;
+ }
+
+ /**
+ * @param string $code
+ * @param string $value
+ */
+ public function addTreeOption($code, $value)
+ {
+ $this->treeOptions[$code] = $value;
+ }
+
+ /**
+ * @param string $code
+ * @param string $value
+ */
+ public function addParserOption($code, $value)
+ {
+ $this->parserOptions[$code] = $value;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ static $format = <<<'EOF'
+var less = require('less');
+var sys = require(process.binding('natives').util ? 'util' : 'sys');
+
+less.render(%s, %s, function(error, css) {
+ if (error) {
+ less.writeError(error);
+ process.exit(2);
+ }
+ try {
+ if (typeof css == 'string') {
+ sys.print(css);
+ } else {
+ sys.print(css.css);
+ }
+ } catch (e) {
+ less.writeError(error);
+ process.exit(3);
+ }
+});
+
+EOF;
+
+ // parser options
+ $parserOptions = $this->parserOptions;
+ if ($dir = $asset->getSourceDirectory()) {
+ $parserOptions['paths'] = array($dir);
+ $parserOptions['filename'] = basename($asset->getSourcePath());
+ }
+
+ foreach ($this->loadPaths as $loadPath) {
+ $parserOptions['paths'][] = $loadPath;
+ }
+
+ $pb = $this->createProcessBuilder();
+
+ $pb->add($this->nodeBin)->add($input = FilesystemUtils::createTemporaryFile('less'));
+ file_put_contents($input, sprintf($format,
+ json_encode($asset->getContent()),
+ json_encode(array_merge($parserOptions, $this->treeOptions))
+ ));
+
+ $proc = $pb->getProcess();
+ $code = $proc->run();
+ unlink($input);
+
+ if (0 !== $code) {
+ throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+ }
+
+ $asset->setContent($proc->getOutput());
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ }
+
+ /**
+ * @todo support for import-once
+ * @todo support for import (less) "lib.css"
+ */
+ public function getChildren(AssetFactory $factory, $content, $loadPath = null)
+ {
+ $loadPaths = $this->loadPaths;
+ if (null !== $loadPath) {
+ $loadPaths[] = $loadPath;
+ }
+
+ if (empty($loadPaths)) {
+ return array();
+ }
+
+ $children = array();
+ foreach (LessUtils::extractImports($content) as $reference) {
+ if ('.css' === substr($reference, -4)) {
+ // skip normal css imports
+ // todo: skip imports with media queries
+ continue;
+ }
+
+ if ('.less' !== substr($reference, -5)) {
+ $reference .= '.less';
+ }
+
+ foreach ($loadPaths as $loadPath) {
+ if (file_exists($file = $loadPath.'/'.$reference)) {
+ $coll = $factory->createAsset($file, array(), array('root' => $loadPath));
+ foreach ($coll as $leaf) {
+ $leaf->ensureFilter($this);
+ $children[] = $leaf;
+ goto next_reference;
+ }
+ }
+ }
+
+ next_reference:
+ }
+
+ return $children;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/LessphpFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/LessphpFilter.php
new file mode 100644
index 0000000..6116f58
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/LessphpFilter.php
@@ -0,0 +1,167 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Factory\AssetFactory;
+use Assetic\Util\LessUtils;
+
+/**
+ * Loads LESS files using the PHP implementation of less, lessphp.
+ *
+ * Less files are mostly compatible, but there are slight differences.
+ *
+ * @link http://leafo.net/lessphp/
+ *
+ * @author David Buchmann <david@liip.ch>
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class LessphpFilter implements DependencyExtractorInterface
+{
+ private $presets = array();
+ private $formatter;
+ private $preserveComments;
+ private $customFunctions = array();
+ private $options = array();
+
+ /**
+ * Lessphp Load Paths
+ *
+ * @var array
+ */
+ protected $loadPaths = array();
+
+ /**
+ * Adds a load path to the paths used by lessphp
+ *
+ * @param string $path Load Path
+ */
+ public function addLoadPath($path)
+ {
+ $this->loadPaths[] = $path;
+ }
+
+ /**
+ * Sets load paths used by lessphp
+ *
+ * @param array $loadPaths Load paths
+ */
+ public function setLoadPaths(array $loadPaths)
+ {
+ $this->loadPaths = $loadPaths;
+ }
+
+ public function setPresets(array $presets)
+ {
+ $this->presets = $presets;
+ }
+
+ public function setOptions(array $options)
+ {
+ $this->options = $options;
+ }
+
+ /**
+ * @param string $formatter One of "lessjs", "compressed", or "classic".
+ */
+ public function setFormatter($formatter)
+ {
+ $this->formatter = $formatter;
+ }
+
+ /**
+ * @param boolean $preserveComments
+ */
+ public function setPreserveComments($preserveComments)
+ {
+ $this->preserveComments = $preserveComments;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ $lc = new \lessc();
+ if ($dir = $asset->getSourceDirectory()) {
+ $lc->importDir = $dir;
+ }
+
+ foreach ($this->loadPaths as $loadPath) {
+ $lc->addImportDir($loadPath);
+ }
+
+ foreach ($this->customFunctions as $name => $callable) {
+ $lc->registerFunction($name, $callable);
+ }
+
+ if ($this->formatter) {
+ $lc->setFormatter($this->formatter);
+ }
+
+ if (null !== $this->preserveComments) {
+ $lc->setPreserveComments($this->preserveComments);
+ }
+
+ if (method_exists($lc, 'setOptions') && count($this->options) > 0 ) {
+ $lc->setOptions($this->options);
+ }
+
+ $asset->setContent($lc->parse($asset->getContent(), $this->presets));
+ }
+
+ public function registerFunction($name, $callable)
+ {
+ $this->customFunctions[$name] = $callable;
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ }
+
+ public function getChildren(AssetFactory $factory, $content, $loadPath = null)
+ {
+ $loadPaths = $this->loadPaths;
+ if (null !== $loadPath) {
+ $loadPaths[] = $loadPath;
+ }
+
+ if (empty($loadPaths)) {
+ return array();
+ }
+
+ $children = array();
+ foreach (LessUtils::extractImports($content) as $reference) {
+ if ('.css' === substr($reference, -4)) {
+ // skip normal css imports
+ // todo: skip imports with media queries
+ continue;
+ }
+
+ if ('.less' !== substr($reference, -5)) {
+ $reference .= '.less';
+ }
+
+ foreach ($loadPaths as $loadPath) {
+ if (file_exists($file = $loadPath.'/'.$reference)) {
+ $coll = $factory->createAsset($file, array(), array('root' => $loadPath));
+ foreach ($coll as $leaf) {
+ $leaf->ensureFilter($this);
+ $children[] = $leaf;
+ goto next_reference;
+ }
+ }
+ }
+
+ next_reference:
+ }
+
+ return $children;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/MinifyCssCompressorFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/MinifyCssCompressorFilter.php
new file mode 100644
index 0000000..180667a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/MinifyCssCompressorFilter.php
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * Filters assets through Minify_CSS_Compressor.
+ *
+ * All credit for the filter itself is mentioned in the file itself.
+ *
+ * @link https://raw.githubusercontent.com/mrclay/minify/master/min/lib/Minify/CSS/Compressor.php
+ * @author Stephen Clay <steve@mrclay.org>
+ * @author http://code.google.com/u/1stvamp/ (Issue 64 patch)
+ */
+class MinifyCssCompressorFilter implements FilterInterface
+{
+ public function filterLoad(AssetInterface $asset)
+ {
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ $asset->setContent(\Minify_CSS_Compressor::process($asset->getContent()));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/OptiPngFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/OptiPngFilter.php
new file mode 100644
index 0000000..5bc1d12
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/OptiPngFilter.php
@@ -0,0 +1,75 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Assetic\Util\FilesystemUtils;
+
+/**
+ * Runs assets through OptiPNG.
+ *
+ * @link http://optipng.sourceforge.net/
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class OptiPngFilter extends BaseProcessFilter
+{
+ private $optipngBin;
+ private $level;
+
+ /**
+ * Constructor.
+ *
+ * @param string $optipngBin Path to the optipng binary
+ */
+ public function __construct($optipngBin = '/usr/bin/optipng')
+ {
+ $this->optipngBin = $optipngBin;
+ }
+
+ public function setLevel($level)
+ {
+ $this->level = $level;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ $pb = $this->createProcessBuilder(array($this->optipngBin));
+
+ if (null !== $this->level) {
+ $pb->add('-o')->add($this->level);
+ }
+
+ $pb->add('-out')->add($output = FilesystemUtils::createTemporaryFile('optipng_out'));
+ unlink($output);
+
+ $pb->add($input = FilesystemUtils::createTemporaryFile('optinpg_in'));
+ file_put_contents($input, $asset->getContent());
+
+ $proc = $pb->getProcess();
+ $code = $proc->run();
+
+ if (0 !== $code) {
+ unlink($input);
+ throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+ }
+
+ $asset->setContent(file_get_contents($output));
+
+ unlink($input);
+ unlink($output);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/PackagerFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/PackagerFilter.php
new file mode 100644
index 0000000..23ceb4e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/PackagerFilter.php
@@ -0,0 +1,65 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Util\FilesystemUtils;
+
+/**
+ * Runs assets through Packager.
+ *
+ * @link https://github.com/kamicane/packager
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class PackagerFilter implements FilterInterface
+{
+ private $packages;
+
+ public function __construct(array $packages = array())
+ {
+ $this->packages = $packages;
+ }
+
+ public function addPackage($package)
+ {
+ $this->packages[] = $package;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ static $manifest = <<<EOF
+name: Application%s
+sources: [source.js]
+
+EOF;
+
+ $hash = substr(sha1(time().rand(11111, 99999)), 0, 7);
+ $package = FilesystemUtils::getTemporaryDirectory().'/assetic_packager_'.$hash;
+
+ mkdir($package);
+ file_put_contents($package.'/package.yml', sprintf($manifest, $hash));
+ file_put_contents($package.'/source.js', $asset->getContent());
+
+ $packager = new \Packager(array_merge(array($package), $this->packages));
+ $content = $packager->build(array(), array(), array('Application'.$hash));
+
+ unlink($package.'/package.yml');
+ unlink($package.'/source.js');
+ rmdir($package);
+
+ $asset->setContent($content);
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/PackerFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/PackerFilter.php
new file mode 100644
index 0000000..6dbe5f3
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/PackerFilter.php
@@ -0,0 +1,56 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * Runs assets through Packager, a JavaScript Compressor/Obfuscator.
+ *
+ * PHP Version of the Dean Edwards's Packer, ported by Nicolas Martin.
+ *
+ * @link http://joliclic.free.fr/php/javascript-packer/en/
+ * @author Maximilian Walter <github@max-walter.net>
+ */
+class PackerFilter implements FilterInterface
+{
+ protected $encoding = 'None';
+
+ protected $fastDecode = true;
+
+ protected $specialChars = false;
+
+ public function setEncoding($encoding)
+ {
+ $this->encoding = $encoding;
+ }
+
+ public function setFastDecode($fastDecode)
+ {
+ $this->fastDecode = (bool) $fastDecode;
+ }
+
+ public function setSpecialChars($specialChars)
+ {
+ $this->specialChars = (bool) $specialChars;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ $packer = new \JavaScriptPacker($asset->getContent(), $this->encoding, $this->fastDecode, $this->specialChars);
+ $asset->setContent($packer->pack());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/PhpCssEmbedFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/PhpCssEmbedFilter.php
new file mode 100644
index 0000000..b1ff33f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/PhpCssEmbedFilter.php
@@ -0,0 +1,52 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Factory\AssetFactory;
+use CssEmbed\CssEmbed;
+
+/**
+ * A filter that embed url directly into css
+ *
+ * @author Pierre Tachoire <pierre.tachoire@gmail.com>
+ * @link https://github.com/krichprollsch/phpCssEmbed
+ */
+class PhpCssEmbedFilter implements DependencyExtractorInterface
+{
+ private $presets = array();
+
+ public function setPresets(array $presets)
+ {
+ $this->presets = $presets;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ $pce = new CssEmbed();
+ if ($dir = $asset->getSourceDirectory()) {
+ $pce->setRootDir($dir);
+ }
+
+ $asset->setContent($pce->embedString($asset->getContent()));
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ }
+
+ public function getChildren(AssetFactory $factory, $content, $loadPath = null)
+ {
+ // todo
+ return array();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/PngoutFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/PngoutFilter.php
new file mode 100644
index 0000000..592ef3a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/PngoutFilter.php
@@ -0,0 +1,128 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Assetic\Util\FilesystemUtils;
+
+/**
+ * Runs assets through pngout.
+ *
+ * @link http://advsys.net/ken/utils.htm#pngout
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class PngoutFilter extends BaseProcessFilter
+{
+ // -c#
+ const COLOR_GREY = '0';
+ const COLOR_RGB = '2';
+ const COLOR_PAL = '3';
+ const COLOR_GRAY_ALPHA = '4';
+ const COLOR_RGB_ALPHA = '6';
+
+ // -f#
+ const FILTER_NONE = '0';
+ const FILTER_X = '1';
+ const FILTER_Y = '2';
+ const FILTER_X_Y = '3';
+ const FILTER_PAETH = '4';
+ const FILTER_MIXED = '5';
+
+ // -s#
+ const STRATEGY_XTREME = '0';
+ const STRATEGY_INTENSE = '1';
+ const STRATEGY_LONGEST_MATCH = '2';
+ const STRATEGY_HUFFMAN_ONLY = '3';
+ const STRATEGY_UNCOMPRESSED = '4';
+
+ private $pngoutBin;
+ private $color;
+ private $filter;
+ private $strategy;
+ private $blockSplitThreshold;
+
+ /**
+ * Constructor.
+ *
+ * @param string $pngoutBin Path to the pngout binary
+ */
+ public function __construct($pngoutBin = '/usr/bin/pngout')
+ {
+ $this->pngoutBin = $pngoutBin;
+ }
+
+ public function setColor($color)
+ {
+ $this->color = $color;
+ }
+
+ public function setFilter($filter)
+ {
+ $this->filter = $filter;
+ }
+
+ public function setStrategy($strategy)
+ {
+ $this->strategy = $strategy;
+ }
+
+ public function setBlockSplitThreshold($blockSplitThreshold)
+ {
+ $this->blockSplitThreshold = $blockSplitThreshold;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ $pb = $this->createProcessBuilder(array($this->pngoutBin));
+
+ if (null !== $this->color) {
+ $pb->add('-c'.$this->color);
+ }
+
+ if (null !== $this->filter) {
+ $pb->add('-f'.$this->filter);
+ }
+
+ if (null !== $this->strategy) {
+ $pb->add('-s'.$this->strategy);
+ }
+
+ if (null !== $this->blockSplitThreshold) {
+ $pb->add('-b'.$this->blockSplitThreshold);
+ }
+
+ $pb->add($input = FilesystemUtils::createTemporaryFile('pngout_in'));
+ file_put_contents($input, $asset->getContent());
+
+ $output = FilesystemUtils::createTemporaryFile('pngout_out');
+ unlink($output);
+ $pb->add($output .= '.png');
+
+ $proc = $pb->getProcess();
+ $code = $proc->run();
+
+ if (0 !== $code) {
+ unlink($input);
+ throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+ }
+
+ $asset->setContent(file_get_contents($output));
+
+ unlink($input);
+ unlink($output);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/ReactJsxFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/ReactJsxFilter.php
new file mode 100644
index 0000000..dc4f218
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/ReactJsxFilter.php
@@ -0,0 +1,75 @@
+<?php
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Assetic\Util\FilesystemUtils;
+
+/**
+ * Compiles JSX (for use with React) into JavaScript.
+ *
+ * @link http://facebook.github.io/react/docs/jsx-in-depth.html
+ * @author Douglas Greenshields <dgreenshields@gmail.com>
+ */
+class ReactJsxFilter extends BaseNodeFilter
+{
+ private $jsxBin;
+ private $nodeBin;
+
+ public function __construct($jsxBin = '/usr/bin/jsx', $nodeBin = null)
+ {
+ $this->jsxBin = $jsxBin;
+ $this->nodeBin = $nodeBin;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ $builder = $this->createProcessBuilder($this->nodeBin
+ ? array($this->nodeBin, $this->jsxBin)
+ : array($this->jsxBin));
+
+ $inputDir = FilesystemUtils::createThrowAwayDirectory('jsx_in');
+ $inputFile = $inputDir.DIRECTORY_SEPARATOR.'asset.js';
+ $outputDir = FilesystemUtils::createThrowAwayDirectory('jsx_out');
+ $outputFile = $outputDir.DIRECTORY_SEPARATOR.'asset.js';
+
+ // create the asset file
+ file_put_contents($inputFile, $asset->getContent());
+
+ $builder
+ ->add($inputDir)
+ ->add($outputDir)
+ ->add('--no-cache-dir')
+ ;
+
+ $proc = $builder->getProcess();
+ $code = $proc->run();
+
+ // remove the input directory and asset file
+ unlink($inputFile);
+ rmdir($inputDir);
+
+ if (0 !== $code) {
+ if (file_exists($outputFile)) {
+ unlink($outputFile);
+ }
+
+ if (file_exists($outputDir)) {
+ rmdir($outputDir);
+ }
+
+ throw FilterException::fromProcess($proc);
+ }
+
+ $asset->setContent(file_get_contents($outputFile));
+
+ // remove the output directory and processed asset file
+ unlink($outputFile);
+ rmdir($outputDir);
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/RooleFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/RooleFilter.php
new file mode 100644
index 0000000..cbcaf4c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/RooleFilter.php
@@ -0,0 +1,84 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Assetic\Factory\AssetFactory;
+use Assetic\Util\FilesystemUtils;
+
+/**
+ * Loads Roole files.
+ *
+ * @link http://roole.org
+ * @author Marcin Chwedziak <tiraeth@gmail.com>
+ */
+class RooleFilter extends BaseNodeFilter implements DependencyExtractorInterface
+{
+ private $rooleBin;
+ private $nodeBin;
+
+ /**
+ * Constructor
+ *
+ * @param string $rooleBin The path to the roole binary
+ * @param string $nodeBin The path to the node binary
+ */
+ public function __construct($rooleBin = '/usr/bin/roole', $nodeBin = null)
+ {
+ $this->rooleBin = $rooleBin;
+ $this->nodeBin = $nodeBin;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ $input = FilesystemUtils::createTemporaryFile('roole');
+ $output = $input.'.css';
+
+ file_put_contents($input, $asset->getContent());
+
+ $pb = $this->createProcessBuilder($this->nodeBin
+ ? array($this->nodeBin, $this->rooleBin)
+ : array($this->rooleBin));
+
+ $pb->add($input);
+
+ $proc = $pb->getProcess();
+ $code = $proc->run();
+ unlink($input);
+
+ if (0 !== $code) {
+ if (file_exists($output)) {
+ unlink($output);
+ }
+
+ throw FilterException::fromProcess($proc);
+ }
+
+ if (!file_exists($output)) {
+ throw new \RuntimeException('Error creating output file.');
+ }
+
+ $asset->setContent(file_get_contents($output));
+ unlink($output);
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ }
+
+ public function getChildren(AssetFactory $factory, $content, $loadPath = null)
+ {
+ // todo
+ return array();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/Sass/BaseSassFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/Sass/BaseSassFilter.php
new file mode 100644
index 0000000..68903f0
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/Sass/BaseSassFilter.php
@@ -0,0 +1,95 @@
+<?php
+
+namespace Assetic\Filter\Sass;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Factory\AssetFactory;
+use Assetic\Filter\BaseProcessFilter;
+use Assetic\Filter\DependencyExtractorInterface;
+use Assetic\Util\SassUtils;
+
+abstract class BaseSassFilter extends BaseProcessFilter implements DependencyExtractorInterface
+{
+ protected $loadPaths = array();
+
+ public function setLoadPaths(array $loadPaths)
+ {
+ $this->loadPaths = $loadPaths;
+ }
+
+ public function addLoadPath($loadPath)
+ {
+ $this->loadPaths[] = $loadPath;
+ }
+
+ public function getChildren(AssetFactory $factory, $content, $loadPath = null)
+ {
+ $loadPaths = $this->loadPaths;
+ if ($loadPath) {
+ array_unshift($loadPaths, $loadPath);
+ }
+
+ if (!$loadPaths) {
+ return array();
+ }
+
+ $children = array();
+ foreach (SassUtils::extractImports($content) as $reference) {
+ if ('.css' === substr($reference, -4)) {
+ // skip normal css imports
+ // todo: skip imports with media queries
+ continue;
+ }
+
+ // the reference may or may not have an extension or be a partial
+ if (pathinfo($reference, PATHINFO_EXTENSION)) {
+ $needles = array(
+ $reference,
+ self::partialize($reference),
+ );
+ } else {
+ $needles = array(
+ $reference.'.scss',
+ $reference.'.sass',
+ self::partialize($reference).'.scss',
+ self::partialize($reference).'.sass',
+ );
+ }
+
+ foreach ($loadPaths as $loadPath) {
+ foreach ($needles as $needle) {
+ if (file_exists($file = $loadPath.'/'.$needle)) {
+ $coll = $factory->createAsset($file, array(), array('root' => $loadPath));
+ foreach ($coll as $leaf) {
+ /** @var $leaf AssetInterface */
+ $leaf->ensureFilter($this);
+ $children[] = $leaf;
+ goto next_reference;
+ }
+ }
+ }
+ }
+
+ next_reference:
+ }
+
+ return $children;
+ }
+
+ private static function partialize($reference)
+ {
+ $parts = pathinfo($reference);
+
+ if ('.' === $parts['dirname']) {
+ $partial = '_'.$parts['filename'];
+ } else {
+ $partial = $parts['dirname'].DIRECTORY_SEPARATOR.'_'.$parts['filename'];
+ }
+
+ if (isset($parts['extension'])) {
+ $partial .= '.'.$parts['extension'];
+ }
+
+ return $partial;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/Sass/SassFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/Sass/SassFilter.php
new file mode 100644
index 0000000..68da116
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/Sass/SassFilter.php
@@ -0,0 +1,186 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter\Sass;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Assetic\Util\FilesystemUtils;
+
+/**
+ * Loads SASS files.
+ *
+ * @link http://sass-lang.com/
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class SassFilter extends BaseSassFilter
+{
+ const STYLE_NESTED = 'nested';
+ const STYLE_EXPANDED = 'expanded';
+ const STYLE_COMPACT = 'compact';
+ const STYLE_COMPRESSED = 'compressed';
+
+ private $sassPath;
+ private $rubyPath;
+ private $unixNewlines;
+ private $scss;
+ private $style;
+ private $precision;
+ private $quiet;
+ private $debugInfo;
+ private $lineNumbers;
+ private $sourceMap;
+ private $cacheLocation;
+ private $noCache;
+ private $compass;
+
+ public function __construct($sassPath = '/usr/bin/sass', $rubyPath = null)
+ {
+ $this->sassPath = $sassPath;
+ $this->rubyPath = $rubyPath;
+ $this->cacheLocation = FilesystemUtils::getTemporaryDirectory();
+ }
+
+ public function setUnixNewlines($unixNewlines)
+ {
+ $this->unixNewlines = $unixNewlines;
+ }
+
+ public function setScss($scss)
+ {
+ $this->scss = $scss;
+ }
+
+ public function setStyle($style)
+ {
+ $this->style = $style;
+ }
+
+ public function setPrecision($precision)
+ {
+ $this->precision = $precision;
+ }
+
+ public function setQuiet($quiet)
+ {
+ $this->quiet = $quiet;
+ }
+
+ public function setDebugInfo($debugInfo)
+ {
+ $this->debugInfo = $debugInfo;
+ }
+
+ public function setLineNumbers($lineNumbers)
+ {
+ $this->lineNumbers = $lineNumbers;
+ }
+
+ public function setSourceMap($sourceMap)
+ {
+ $this->sourceMap = $sourceMap;
+ }
+
+ public function setCacheLocation($cacheLocation)
+ {
+ $this->cacheLocation = $cacheLocation;
+ }
+
+ public function setNoCache($noCache)
+ {
+ $this->noCache = $noCache;
+ }
+
+ public function setCompass($compass)
+ {
+ $this->compass = $compass;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ $sassProcessArgs = array($this->sassPath);
+ if (null !== $this->rubyPath) {
+ $sassProcessArgs = array_merge(explode(' ', $this->rubyPath), $sassProcessArgs);
+ }
+
+ $pb = $this->createProcessBuilder($sassProcessArgs);
+
+ if ($dir = $asset->getSourceDirectory()) {
+ $pb->add('--load-path')->add($dir);
+ }
+
+ if ($this->unixNewlines) {
+ $pb->add('--unix-newlines');
+ }
+
+ if (true === $this->scss || (null === $this->scss && 'scss' == pathinfo($asset->getSourcePath(), PATHINFO_EXTENSION))) {
+ $pb->add('--scss');
+ }
+
+ if ($this->style) {
+ $pb->add('--style')->add($this->style);
+ }
+
+ if ($this->precision) {
+ $pb->add('--precision')->add($this->precision);
+ }
+
+ if ($this->quiet) {
+ $pb->add('--quiet');
+ }
+
+ if ($this->debugInfo) {
+ $pb->add('--debug-info');
+ }
+
+ if ($this->lineNumbers) {
+ $pb->add('--line-numbers');
+ }
+
+ if ($this->sourceMap) {
+ $pb->add('--sourcemap');
+ }
+
+ foreach ($this->loadPaths as $loadPath) {
+ $pb->add('--load-path')->add($loadPath);
+ }
+
+ if ($this->cacheLocation) {
+ $pb->add('--cache-location')->add($this->cacheLocation);
+ }
+
+ if ($this->noCache) {
+ $pb->add('--no-cache');
+ }
+
+ if ($this->compass) {
+ $pb->add('--compass');
+ }
+
+ // input
+ $pb->add($input = FilesystemUtils::createTemporaryFile('sass'));
+ file_put_contents($input, $asset->getContent());
+
+ $proc = $pb->getProcess();
+ $code = $proc->run();
+ unlink($input);
+
+ if (0 !== $code) {
+ throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+ }
+
+ $asset->setContent($proc->getOutput());
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/Sass/ScssFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/Sass/ScssFilter.php
new file mode 100644
index 0000000..f8be046
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/Sass/ScssFilter.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter\Sass;
+
+/**
+ * Loads SCSS files.
+ *
+ * @link http://sass-lang.com/
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class ScssFilter extends SassFilter
+{
+ public function __construct($sassPath = '/usr/bin/sass', $rubyPath = null)
+ {
+ parent::__construct($sassPath, $rubyPath);
+
+ $this->setScss(true);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/SassphpFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/SassphpFilter.php
new file mode 100644
index 0000000..5d4ed1e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/SassphpFilter.php
@@ -0,0 +1,132 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2015 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Factory\AssetFactory;
+use Assetic\Asset\AssetInterface;
+use Assetic\Filter\DependencyExtractorInterface;
+use Assetic\Util\CssUtils;
+
+/**
+ * Compiles Sass to CSS.
+ *
+ * @author Mikey Clarke <mikey.clarke@me.com>
+ */
+class SassphpFilter implements DependencyExtractorInterface
+{
+ private $includePaths = array();
+ private $outputStyle;
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ $sass = new \Sass();
+
+ $includePaths = array_merge(
+ array($asset->getSourceDirectory()),
+ $this->includePaths
+ );
+ $sass->setIncludePath(implode(':', $includePaths));
+
+ if ($this->outputStyle) {
+ $sass->setStyle($this->outputStyle);
+ }
+
+ $css = $sass->compile($asset->getContent());
+
+ $asset->setContent($css);
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ }
+
+ public function setOutputStyle($outputStyle)
+ {
+ $this->outputStyle = $outputStyle;
+ }
+
+ public function setIncludePaths(array $paths)
+ {
+ $this->includePaths = $paths;
+ }
+
+ public function addIncludePath($path)
+ {
+ $this->includePaths[] = $path;
+ }
+
+ public function getChildren(AssetFactory $factory, $content, $loadPath = null)
+ {
+ $children = array();
+
+ $includePaths = $this->includePaths;
+ if (null !== $loadPath && !in_array($loadPath, $includePaths)) {
+ array_unshift($includePaths, $loadPath);
+ }
+
+ if (empty($includePaths)) {
+ return $children;
+ }
+
+ foreach (CssUtils::extractImports($content) as $reference) {
+ if ('.css' === substr($reference, -4)) {
+ continue;
+ }
+
+ // the reference may or may not have an extension or be a partial
+ if (pathinfo($reference, PATHINFO_EXTENSION)) {
+ $needles = array(
+ $reference,
+ $this->partialize($reference),
+ );
+ } else {
+ $needles = array(
+ $reference . '.scss',
+ $this->partialize($reference) . '.scss',
+ );
+ }
+
+ foreach ($includePaths as $includePath) {
+ foreach ($needles as $needle) {
+ if (file_exists($file = $includePath . '/' . $needle)) {
+ $child = $factory->createAsset($file, array(), array('root' => $includePath));
+ $children[] = $child;
+ $child->load();
+ $children = array_merge(
+ $children,
+ $this->getChildren($factory, $child->getContent(), $includePath)
+ );
+ }
+ }
+ }
+ }
+
+ return $children;
+ }
+
+ private function partialize($reference)
+ {
+ $parts = pathinfo($reference);
+
+ if ('.' === $parts['dirname']) {
+ $partial = '_' . $parts['filename'];
+ } else {
+ $partial = $parts['dirname'] . DIRECTORY_SEPARATOR . '_' . $parts['filename'];
+ }
+
+ if (isset($parts['extension'])) {
+ $partial .= '.' . $parts['extension'];
+ }
+
+ return $partial;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/ScssphpFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/ScssphpFilter.php
new file mode 100644
index 0000000..c2252a1
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/ScssphpFilter.php
@@ -0,0 +1,147 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Factory\AssetFactory;
+use Assetic\Util\CssUtils;
+use Leafo\ScssPhp\Compiler;
+
+/**
+ * Loads SCSS files using the PHP implementation of scss, scssphp.
+ *
+ * Scss files are mostly compatible, but there are slight differences.
+ *
+ * @link http://leafo.net/scssphp/
+ *
+ * @author Bart van den Burg <bart@samson-it.nl>
+ */
+class ScssphpFilter implements DependencyExtractorInterface
+{
+ private $compass = false;
+ private $importPaths = array();
+ private $customFunctions = array();
+ private $formatter;
+ private $variables = array();
+
+ public function enableCompass($enable = true)
+ {
+ $this->compass = (Boolean) $enable;
+ }
+
+ public function isCompassEnabled()
+ {
+ return $this->compass;
+ }
+
+ public function setFormatter($formatter)
+ {
+ $legacyFormatters = array(
+ 'scss_formatter' => 'Leafo\ScssPhp\Formatter\Expanded',
+ 'scss_formatter_nested' => 'Leafo\ScssPhp\Formatter\Nested',
+ 'scss_formatter_compressed' => 'Leafo\ScssPhp\Formatter\Compressed',
+ 'scss_formatter_crunched' => 'Leafo\ScssPhp\Formatter\Crunched',
+ );
+
+ if (isset($legacyFormatters[$formatter])) {
+ @trigger_error(sprintf('The scssphp formatter `%s` is deprecated. Use `%s` instead.', $formatter, $legacyFormatters[$formatter]), E_USER_DEPRECATED);
+
+ $formatter = $legacyFormatters[$formatter];
+ }
+
+ $this->formatter = $formatter;
+ }
+
+ public function setVariables(array $variables)
+ {
+ $this->variables = $variables;
+ }
+
+ public function addVariable($variable)
+ {
+ $this->variables[] = $variable;
+ }
+
+ public function setImportPaths(array $paths)
+ {
+ $this->importPaths = $paths;
+ }
+
+ public function addImportPath($path)
+ {
+ $this->importPaths[] = $path;
+ }
+
+ public function registerFunction($name, $callable)
+ {
+ $this->customFunctions[$name] = $callable;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ $sc = new Compiler();
+
+ if ($this->compass) {
+ new \scss_compass($sc);
+ }
+
+ if ($dir = $asset->getSourceDirectory()) {
+ $sc->addImportPath($dir);
+ }
+
+ foreach ($this->importPaths as $path) {
+ $sc->addImportPath($path);
+ }
+
+ foreach ($this->customFunctions as $name => $callable) {
+ $sc->registerFunction($name, $callable);
+ }
+
+ if ($this->formatter) {
+ $sc->setFormatter($this->formatter);
+ }
+
+ if (!empty($this->variables)) {
+ $sc->setVariables($this->variables);
+ }
+
+ $asset->setContent($sc->compile($asset->getContent()));
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ }
+
+ public function getChildren(AssetFactory $factory, $content, $loadPath = null)
+ {
+ $sc = new Compiler();
+ if ($loadPath !== null) {
+ $sc->addImportPath($loadPath);
+ }
+
+ foreach ($this->importPaths as $path) {
+ $sc->addImportPath($path);
+ }
+
+ $children = array();
+ foreach (CssUtils::extractImports($content) as $match) {
+ $file = $sc->findImport($match);
+ if ($file) {
+ $children[] = $child = $factory->createAsset($file, array(), array('root' => $loadPath));
+ $child->load();
+ $children = array_merge($children, $this->getChildren($factory, $child->getContent(), $loadPath));
+ }
+ }
+
+ return $children;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/SeparatorFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/SeparatorFilter.php
new file mode 100644
index 0000000..a2c02ab
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/SeparatorFilter.php
@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * Inserts a separator between assets to prevent merge failures
+ * e.g. missing semicolon at the end of a JS file
+ *
+ * @author Robin McCorkell <rmccorkell@karoshi.org.uk>
+ */
+class SeparatorFilter implements FilterInterface
+{
+ /**
+ * @var string
+ */
+ private $separator;
+
+ /**
+ * Constructor.
+ *
+ * @param string $separator Separator to use between assets
+ */
+ public function __construct($separator = ';')
+ {
+ $this->separator = $separator;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ $asset->setContent($asset->getContent() . $this->separator);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/SprocketsFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/SprocketsFilter.php
new file mode 100644
index 0000000..ed46b0f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/SprocketsFilter.php
@@ -0,0 +1,152 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Assetic\Factory\AssetFactory;
+use Assetic\Util\FilesystemUtils;
+
+/**
+ * Runs assets through Sprockets.
+ *
+ * Requires Sprockets 1.0.x.
+ *
+ * @link http://getsprockets.org/
+ * @link http://github.com/sstephenson/sprockets/tree/1.0.x
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class SprocketsFilter extends BaseProcessFilter implements DependencyExtractorInterface
+{
+ private $sprocketsLib;
+ private $rubyBin;
+ private $includeDirs;
+ private $assetRoot;
+
+ /**
+ * Constructor.
+ *
+ * @param string $sprocketsLib Path to the Sprockets lib/ directory
+ * @param string $rubyBin Path to the ruby binary
+ */
+ public function __construct($sprocketsLib = null, $rubyBin = '/usr/bin/ruby')
+ {
+ $this->sprocketsLib = $sprocketsLib;
+ $this->rubyBin = $rubyBin;
+ $this->includeDirs = array();
+ }
+
+ public function addIncludeDir($directory)
+ {
+ $this->includeDirs[] = $directory;
+ }
+
+ public function setAssetRoot($assetRoot)
+ {
+ $this->assetRoot = $assetRoot;
+ }
+
+ /**
+ * Hack around a bit, get the job done.
+ */
+ public function filterLoad(AssetInterface $asset)
+ {
+ static $format = <<<'EOF'
+#!/usr/bin/env ruby
+
+require %s
+%s
+options = { :load_path => [],
+ :source_files => [%s],
+ :expand_paths => false }
+
+%ssecretary = Sprockets::Secretary.new(options)
+secretary.install_assets if options[:asset_root]
+print secretary.concatenation
+
+EOF;
+
+ $more = '';
+
+ foreach ($this->includeDirs as $directory) {
+ $more .= 'options[:load_path] << '.var_export($directory, true)."\n";
+ }
+
+ if (null !== $this->assetRoot) {
+ $more .= 'options[:asset_root] = '.var_export($this->assetRoot, true)."\n";
+ }
+
+ if ($more) {
+ $more .= "\n";
+ }
+
+ $tmpAsset = FilesystemUtils::createTemporaryFile('sprockets_asset');
+ file_put_contents($tmpAsset, $asset->getContent());
+
+ $input = FilesystemUtils::createTemporaryFile('sprockets_in');
+ file_put_contents($input, sprintf($format,
+ $this->sprocketsLib
+ ? sprintf('File.join(%s, \'sprockets\')', var_export($this->sprocketsLib, true))
+ : '\'sprockets\'',
+ $this->getHack($asset),
+ var_export($tmpAsset, true),
+ $more
+ ));
+
+ $pb = $this->createProcessBuilder(array(
+ $this->rubyBin,
+ $input,
+ ));
+
+ $proc = $pb->getProcess();
+ $code = $proc->run();
+ unlink($tmpAsset);
+ unlink($input);
+
+ if (0 !== $code) {
+ throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+ }
+
+ $asset->setContent($proc->getOutput());
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ }
+
+ public function getChildren(AssetFactory $factory, $content, $loadPath = null)
+ {
+ // todo
+ return array();
+ }
+
+ private function getHack(AssetInterface $asset)
+ {
+ static $format = <<<'EOF'
+
+module Sprockets
+ class Preprocessor
+ protected
+ def pathname_for_relative_require_from(source_line)
+ Sprockets::Pathname.new(@environment, File.join(%s, location_from(source_line)))
+ end
+ end
+end
+
+EOF;
+
+ if ($dir = $asset->getSourceDirectory()) {
+ return sprintf($format, var_export($dir, true));
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/StylusFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/StylusFilter.php
new file mode 100644
index 0000000..aed7861
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/StylusFilter.php
@@ -0,0 +1,126 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Assetic\Factory\AssetFactory;
+use Assetic\Util\FilesystemUtils;
+
+/**
+ * Loads STYL files.
+ *
+ * @link http://learnboost.github.com/stylus/
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class StylusFilter extends BaseNodeFilter implements DependencyExtractorInterface
+{
+ private $nodeBin;
+ private $compress;
+ private $useNib;
+
+ /**
+ * Constructs filter.
+ *
+ * @param string $nodeBin The path to the node binary
+ * @param array $nodePaths An array of node paths
+ */
+ public function __construct($nodeBin = '/usr/bin/node', array $nodePaths = array())
+ {
+ $this->nodeBin = $nodeBin;
+ $this->setNodePaths($nodePaths);
+ }
+
+ /**
+ * Enable output compression.
+ *
+ * @param boolean $compress
+ */
+ public function setCompress($compress)
+ {
+ $this->compress = $compress;
+ }
+
+ /**
+ * Enable the use of Nib
+ *
+ * @param boolean $useNib
+ */
+ public function setUseNib($useNib)
+ {
+ $this->useNib = $useNib;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function filterLoad(AssetInterface $asset)
+ {
+ static $format = <<<'EOF'
+var stylus = require('stylus');
+var sys = require(process.binding('natives').util ? 'util' : 'sys');
+
+stylus(%s, %s)%s.render(function(e, css){
+ if (e) {
+ throw e;
+ }
+
+ sys.print(css);
+ process.exit(0);
+});
+
+EOF;
+
+ // parser options
+ $parserOptions = array();
+ if ($dir = $asset->getSourceDirectory()) {
+ $parserOptions['paths'] = array($dir);
+ $parserOptions['filename'] = basename($asset->getSourcePath());
+ }
+
+ if (null !== $this->compress) {
+ $parserOptions['compress'] = $this->compress;
+ }
+
+ $pb = $this->createProcessBuilder();
+
+ $pb->add($this->nodeBin)->add($input = FilesystemUtils::createTemporaryFile('stylus'));
+ file_put_contents($input, sprintf($format,
+ json_encode($asset->getContent()),
+ json_encode($parserOptions),
+ $this->useNib ? '.use(require(\'nib\')())' : ''
+ ));
+
+ $proc = $pb->getProcess();
+ $code = $proc->run();
+ unlink($input);
+
+ if (0 !== $code) {
+ throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+ }
+
+ $asset->setContent($proc->getOutput());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function filterDump(AssetInterface $asset)
+ {
+ }
+
+ public function getChildren(AssetFactory $factory, $content, $loadPath = null)
+ {
+ // todo
+ return array();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/TypeScriptFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/TypeScriptFilter.php
new file mode 100644
index 0000000..24aee31
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/TypeScriptFilter.php
@@ -0,0 +1,80 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Assetic\Util\FilesystemUtils;
+
+/**
+ * Compiles TypeScript into JavaScript.
+ *
+ * @link http://www.typescriptlang.org/
+ * @author Jarrod Nettles <jarrod.nettles@icloud.com>
+ */
+class TypeScriptFilter extends BaseNodeFilter
+{
+ private $tscBin;
+ private $nodeBin;
+
+ public function __construct($tscBin = '/usr/bin/tsc', $nodeBin = null)
+ {
+ $this->tscBin = $tscBin;
+ $this->nodeBin = $nodeBin;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ $pb = $this->createProcessBuilder($this->nodeBin
+ ? array($this->nodeBin, $this->tscBin)
+ : array($this->tscBin));
+
+ if ($sourcePath = $asset->getSourcePath()) {
+ $templateName = basename($sourcePath);
+ } else {
+ $templateName = 'asset';
+ }
+
+ $inputDirPath = FilesystemUtils::createThrowAwayDirectory('typescript_in');
+ $inputPath = $inputDirPath.DIRECTORY_SEPARATOR.$templateName.'.ts';
+ $outputPath = FilesystemUtils::createTemporaryFile('typescript_out');
+
+ file_put_contents($inputPath, $asset->getContent());
+
+ $pb->add($inputPath)->add('--out')->add($outputPath);
+
+ $proc = $pb->getProcess();
+ $code = $proc->run();
+ unlink($inputPath);
+ rmdir($inputDirPath);
+
+ if (0 !== $code) {
+ if (file_exists($outputPath)) {
+ unlink($outputPath);
+ }
+ throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+ }
+
+ if (!file_exists($outputPath)) {
+ throw new \RuntimeException('Error creating output file.');
+ }
+
+ $compiledJs = file_get_contents($outputPath);
+ unlink($outputPath);
+
+ $asset->setContent($compiledJs);
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/UglifyCssFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/UglifyCssFilter.php
new file mode 100644
index 0000000..d534fa3
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/UglifyCssFilter.php
@@ -0,0 +1,120 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Assetic\Util\FilesystemUtils;
+
+/**
+ * UglifyCss filter.
+ *
+ * @link https://github.com/fmarcia/UglifyCSS
+ * @author Franck Marcia <franck.marcia@gmail.com>
+ */
+class UglifyCssFilter extends BaseNodeFilter
+{
+ private $uglifycssBin;
+ private $nodeBin;
+
+ private $expandVars;
+ private $uglyComments;
+ private $cuteComments;
+
+ /**
+ * @param string $uglifycssBin Absolute path to the uglifycss executable
+ * @param string $nodeBin Absolute path to the folder containg node.js executable
+ */
+ public function __construct($uglifycssBin = '/usr/bin/uglifycss', $nodeBin = null)
+ {
+ $this->uglifycssBin = $uglifycssBin;
+ $this->nodeBin = $nodeBin;
+ }
+
+ /**
+ * Expand variables
+ * @param bool $expandVars True to enable
+ */
+ public function setExpandVars($expandVars)
+ {
+ $this->expandVars = $expandVars;
+ }
+
+ /**
+ * Remove newlines within preserved comments
+ * @param bool $uglyComments True to enable
+ */
+ public function setUglyComments($uglyComments)
+ {
+ $this->uglyComments = $uglyComments;
+ }
+
+ /**
+ * Preserve newlines within and around preserved comments
+ * @param bool $cuteComments True to enable
+ */
+ public function setCuteComments($cuteComments)
+ {
+ $this->cuteComments = $cuteComments;
+ }
+
+ /**
+ * @see Assetic\Filter\FilterInterface::filterLoad()
+ */
+ public function filterLoad(AssetInterface $asset)
+ {
+ }
+
+ /**
+ * Run the asset through UglifyJs
+ *
+ * @see Assetic\Filter\FilterInterface::filterDump()
+ */
+ public function filterDump(AssetInterface $asset)
+ {
+ $pb = $this->createProcessBuilder($this->nodeBin
+ ? array($this->nodeBin, $this->uglifycssBin)
+ : array($this->uglifycssBin));
+
+ if ($this->expandVars) {
+ $pb->add('--expand-vars');
+ }
+
+ if ($this->uglyComments) {
+ $pb->add('--ugly-comments');
+ }
+
+ if ($this->cuteComments) {
+ $pb->add('--cute-comments');
+ }
+
+ // input and output files
+ $input = FilesystemUtils::createTemporaryFile('uglifycss');
+
+ file_put_contents($input, $asset->getContent());
+ $pb->add($input);
+
+ $proc = $pb->getProcess();
+ $code = $proc->run();
+ unlink($input);
+
+ if (127 === $code) {
+ throw new \RuntimeException('Path to node executable could not be resolved.');
+ }
+
+ if (0 !== $code) {
+ throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+ }
+
+ $asset->setContent($proc->getOutput());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/UglifyJs2Filter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/UglifyJs2Filter.php
new file mode 100644
index 0000000..c0441ae
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/UglifyJs2Filter.php
@@ -0,0 +1,152 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Assetic\Util\FilesystemUtils;
+
+/**
+ * UglifyJs2 filter.
+ *
+ * @link http://lisperator.net/uglifyjs
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class UglifyJs2Filter extends BaseNodeFilter
+{
+ private $uglifyjsBin;
+ private $nodeBin;
+ private $compress;
+ private $beautify;
+ private $mangle;
+ private $screwIe8;
+ private $comments;
+ private $wrap;
+ private $defines;
+
+ public function __construct($uglifyjsBin = '/usr/bin/uglifyjs', $nodeBin = null)
+ {
+ $this->uglifyjsBin = $uglifyjsBin;
+ $this->nodeBin = $nodeBin;
+ }
+
+ public function setCompress($compress)
+ {
+ $this->compress = $compress;
+ }
+
+ public function setBeautify($beautify)
+ {
+ $this->beautify = $beautify;
+ }
+
+ public function setMangle($mangle)
+ {
+ $this->mangle = $mangle;
+ }
+
+ public function setScrewIe8($screwIe8)
+ {
+ $this->screwIe8 = $screwIe8;
+ }
+
+ public function setComments($comments)
+ {
+ $this->comments = $comments;
+ }
+
+ public function setWrap($wrap)
+ {
+ $this->wrap = $wrap;
+ }
+
+ public function setDefines(array $defines)
+ {
+ $this->defines = $defines;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ $pb = $this->createProcessBuilder(
+ $this->nodeBin
+ ? array($this->nodeBin, $this->uglifyjsBin)
+ : array($this->uglifyjsBin)
+ );
+
+ if ($this->compress) {
+ $pb->add('--compress');
+
+ if (is_string($this->compress) && !empty($this->compress)) {
+ $pb->add($this->compress);
+ }
+ }
+
+ if ($this->beautify) {
+ $pb->add('--beautify');
+ }
+
+ if ($this->mangle) {
+ $pb->add('--mangle');
+ }
+
+ if ($this->screwIe8) {
+ $pb->add('--screw-ie8');
+ }
+
+ if ($this->comments) {
+ $pb->add('--comments')->add(true === $this->comments ? 'all' : $this->comments);
+ }
+
+ if ($this->wrap) {
+ $pb->add('--wrap')->add($this->wrap);
+ }
+
+ if ($this->defines) {
+ $pb->add('--define')->add(implode(',', $this->defines));
+ }
+
+ // input and output files
+ $input = FilesystemUtils::createTemporaryFile('uglifyjs2_in');
+ $output = FilesystemUtils::createTemporaryFile('uglifyjs2_out');
+
+ file_put_contents($input, $asset->getContent());
+ $pb->add('-o')->add($output)->add($input);
+
+ $proc = $pb->getProcess();
+ $code = $proc->run();
+ unlink($input);
+
+ if (0 !== $code) {
+ if (file_exists($output)) {
+ unlink($output);
+ }
+
+ if (127 === $code) {
+ throw new \RuntimeException('Path to node executable could not be resolved.');
+ }
+
+ throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+ }
+
+ if (!file_exists($output)) {
+ throw new \RuntimeException('Error creating output file.');
+ }
+
+ $asset->setContent(file_get_contents($output));
+
+ unlink($output);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/UglifyJsFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/UglifyJsFilter.php
new file mode 100644
index 0000000..ff9ad66
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/UglifyJsFilter.php
@@ -0,0 +1,160 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Assetic\Util\FilesystemUtils;
+
+/**
+ * UglifyJs filter.
+ *
+ * @link https://github.com/mishoo/UglifyJS
+ * @author André Roaldseth <andre@roaldseth.net>
+ */
+class UglifyJsFilter extends BaseNodeFilter
+{
+ private $uglifyjsBin;
+ private $nodeBin;
+
+ private $noCopyright;
+ private $beautify;
+ private $unsafe;
+ private $mangle;
+ private $defines;
+
+ /**
+ * @param string $uglifyjsBin Absolute path to the uglifyjs executable
+ * @param string $nodeBin Absolute path to the folder containg node.js executable
+ */
+ public function __construct($uglifyjsBin = '/usr/bin/uglifyjs', $nodeBin = null)
+ {
+ $this->uglifyjsBin = $uglifyjsBin;
+ $this->nodeBin = $nodeBin;
+ }
+
+ /**
+ * Removes the first block of comments as well
+ * @param bool $noCopyright True to enable
+ */
+ public function setNoCopyright($noCopyright)
+ {
+ $this->noCopyright = $noCopyright;
+ }
+
+ /**
+ * Output indented code
+ * @param bool $beautify True to enable
+ */
+ public function setBeautify($beautify)
+ {
+ $this->beautify = $beautify;
+ }
+
+ /**
+ * Enable additional optimizations that are known to be unsafe in some situations.
+ * @param bool $unsafe True to enable
+ */
+ public function setUnsafe($unsafe)
+ {
+ $this->unsafe = $unsafe;
+ }
+
+ /**
+ * Safely mangle variable and function names for greater file compress.
+ * @param bool $mangle True to enable
+ */
+ public function setMangle($mangle)
+ {
+ $this->mangle = $mangle;
+ }
+
+ public function setDefines(array $defines)
+ {
+ $this->defines = $defines;
+ }
+
+ /**
+ * @see Assetic\Filter\FilterInterface::filterLoad()
+ */
+ public function filterLoad(AssetInterface $asset)
+ {
+ }
+
+ /**
+ * Run the asset through UglifyJs
+ *
+ * @see Assetic\Filter\FilterInterface::filterDump()
+ */
+ public function filterDump(AssetInterface $asset)
+ {
+ $pb = $this->createProcessBuilder(
+ $this->nodeBin
+ ? array($this->nodeBin, $this->uglifyjsBin)
+ : array($this->uglifyjsBin)
+ );
+
+ if ($this->noCopyright) {
+ $pb->add('--no-copyright');
+ }
+
+ if ($this->beautify) {
+ $pb->add('--beautify');
+ }
+
+ if ($this->unsafe) {
+ $pb->add('--unsafe');
+ }
+
+ if (false === $this->mangle) {
+ $pb->add('--no-mangle');
+ }
+
+ if ($this->defines) {
+ foreach ($this->defines as $define) {
+ $pb->add('-d')->add($define);
+ }
+ }
+
+ // input and output files
+ $input = FilesystemUtils::createTemporaryFile('uglifyjs_in');
+ $output = FilesystemUtils::createTemporaryFile('uglifyjs_out');
+
+ file_put_contents($input, $asset->getContent());
+ $pb->add('-o')->add($output)->add($input);
+
+ $proc = $pb->getProcess();
+ $code = $proc->run();
+ unlink($input);
+
+ if (0 !== $code) {
+ if (file_exists($output)) {
+ unlink($output);
+ }
+
+ if (127 === $code) {
+ throw new \RuntimeException('Path to node executable could not be resolved.');
+ }
+
+ throw FilterException::fromProcess($proc)->setInput($asset->getContent());
+ }
+
+ if (!file_exists($output)) {
+ throw new \RuntimeException('Error creating output file.');
+ }
+
+ $uglifiedJs = file_get_contents($output);
+ unlink($output);
+
+ $asset->setContent($uglifiedJs);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/BaseCompressorFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/BaseCompressorFilter.php
new file mode 100644
index 0000000..b3ec267
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/BaseCompressorFilter.php
@@ -0,0 +1,117 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter\Yui;
+
+use Assetic\Asset\AssetInterface;
+use Assetic\Exception\FilterException;
+use Assetic\Filter\BaseProcessFilter;
+use Assetic\Util\FilesystemUtils;
+
+/**
+ * Base YUI compressor filter.
+ *
+ * @link http://developer.yahoo.com/yui/compressor/
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+abstract class BaseCompressorFilter extends BaseProcessFilter
+{
+ private $jarPath;
+ private $javaPath;
+ private $charset;
+ private $lineBreak;
+ private $stackSize;
+
+ public function __construct($jarPath, $javaPath = '/usr/bin/java')
+ {
+ $this->jarPath = $jarPath;
+ $this->javaPath = $javaPath;
+ }
+
+ public function setCharset($charset)
+ {
+ $this->charset = $charset;
+ }
+
+ public function setLineBreak($lineBreak)
+ {
+ $this->lineBreak = $lineBreak;
+ }
+
+ public function setStackSize($stackSize)
+ {
+ $this->stackSize = $stackSize;
+ }
+
+ public function filterLoad(AssetInterface $asset)
+ {
+ }
+
+ /**
+ * Compresses a string.
+ *
+ * @param string $content The content to compress
+ * @param string $type The type of content, either "js" or "css"
+ * @param array $options An indexed array of additional options
+ *
+ * @return string The compressed content
+ */
+ protected function compress($content, $type, $options = array())
+ {
+ $pb = $this->createProcessBuilder(array($this->javaPath));
+
+ if (null !== $this->stackSize) {
+ $pb->add('-Xss'.$this->stackSize);
+ }
+
+ $pb->add('-jar')->add($this->jarPath);
+
+ foreach ($options as $option) {
+ $pb->add($option);
+ }
+
+ if (null !== $this->charset) {
+ $pb->add('--charset')->add($this->charset);
+ }
+
+ if (null !== $this->lineBreak) {
+ $pb->add('--line-break')->add($this->lineBreak);
+ }
+
+ // input and output files
+ $tempDir = FilesystemUtils::getTemporaryDirectory();
+ $input = tempnam($tempDir, 'assetic_yui_input');
+ $output = tempnam($tempDir, 'assetic_yui_output');
+ file_put_contents($input, $content);
+ $pb->add('-o')->add($output)->add('--type')->add($type)->add($input);
+
+ $proc = $pb->getProcess();
+ $code = $proc->run();
+ unlink($input);
+
+ if (0 !== $code) {
+ if (file_exists($output)) {
+ unlink($output);
+ }
+
+ throw FilterException::fromProcess($proc)->setInput($content);
+ }
+
+ if (!file_exists($output)) {
+ throw new \RuntimeException('Error creating output file.');
+ }
+
+ $retval = file_get_contents($output);
+ unlink($output);
+
+ return $retval;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/CssCompressorFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/CssCompressorFilter.php
new file mode 100644
index 0000000..077c6d5
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/CssCompressorFilter.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter\Yui;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * CSS YUI compressor filter.
+ *
+ * @link http://developer.yahoo.com/yui/compressor/
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class CssCompressorFilter extends BaseCompressorFilter
+{
+ public function filterDump(AssetInterface $asset)
+ {
+ $asset->setContent($this->compress($asset->getContent(), 'css'));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/JsCompressorFilter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/JsCompressorFilter.php
new file mode 100644
index 0000000..b2a59fb
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Filter/Yui/JsCompressorFilter.php
@@ -0,0 +1,61 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Filter\Yui;
+
+use Assetic\Asset\AssetInterface;
+
+/**
+ * Javascript YUI compressor filter.
+ *
+ * @link http://developer.yahoo.com/yui/compressor/
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class JsCompressorFilter extends BaseCompressorFilter
+{
+ private $nomunge;
+ private $preserveSemi;
+ private $disableOptimizations;
+
+ public function setNomunge($nomunge = true)
+ {
+ $this->nomunge = $nomunge;
+ }
+
+ public function setPreserveSemi($preserveSemi)
+ {
+ $this->preserveSemi = $preserveSemi;
+ }
+
+ public function setDisableOptimizations($disableOptimizations)
+ {
+ $this->disableOptimizations = $disableOptimizations;
+ }
+
+ public function filterDump(AssetInterface $asset)
+ {
+ $options = array();
+
+ if ($this->nomunge) {
+ $options[] = '--nomunge';
+ }
+
+ if ($this->preserveSemi) {
+ $options[] = '--preserve-semi';
+ }
+
+ if ($this->disableOptimizations) {
+ $options[] = '--disable-optimizations';
+ }
+
+ $asset->setContent($this->compress($asset->getContent(), 'js', $options));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/FilterManager.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/FilterManager.php
new file mode 100644
index 0000000..e2820d9
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/FilterManager.php
@@ -0,0 +1,64 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic;
+
+use Assetic\Filter\FilterInterface;
+
+/**
+ * Manages the available filters.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class FilterManager
+{
+ private $filters = array();
+
+ public function set($alias, FilterInterface $filter)
+ {
+ $this->checkName($alias);
+
+ $this->filters[$alias] = $filter;
+ }
+
+ public function get($alias)
+ {
+ if (!isset($this->filters[$alias])) {
+ throw new \InvalidArgumentException(sprintf('There is no "%s" filter.', $alias));
+ }
+
+ return $this->filters[$alias];
+ }
+
+ public function has($alias)
+ {
+ return isset($this->filters[$alias]);
+ }
+
+ public function getNames()
+ {
+ return array_keys($this->filters);
+ }
+
+ /**
+ * Checks that a name is valid.
+ *
+ * @param string $name An asset name candidate
+ *
+ * @throws \InvalidArgumentException If the asset name is invalid
+ */
+ protected function checkName($name)
+ {
+ if (!ctype_alnum(str_replace('_', '', $name))) {
+ throw new \InvalidArgumentException(sprintf('The name "%s" is invalid.', $name));
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Util/CssUtils.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Util/CssUtils.php
new file mode 100644
index 0000000..ebc44b0
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Util/CssUtils.php
@@ -0,0 +1,138 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Util;
+
+/**
+ * CSS Utils.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+abstract class CssUtils
+{
+ const REGEX_URLS = '/url\((["\']?)(?P<url>.*?)(\\1)\)/';
+ const REGEX_IMPORTS = '/@import (?:url\()?(\'|"|)(?P<url>[^\'"\)\n\r]*)\1\)?;?/';
+ const REGEX_IMPORTS_NO_URLS = '/@import (?!url\()(\'|"|)(?P<url>[^\'"\)\n\r]*)\1;?/';
+ const REGEX_IE_FILTERS = '/src=(["\']?)(?P<url>.*?)\\1/';
+ const REGEX_COMMENTS = '/(\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)/';
+
+ /**
+ * Filters all references -- url() and "@import" -- through a callable.
+ *
+ * @param string $content The CSS
+ * @param callable $callback A PHP callable
+ *
+ * @return string The filtered CSS
+ */
+ public static function filterReferences($content, $callback)
+ {
+ $content = static::filterUrls($content, $callback);
+ $content = static::filterImports($content, $callback, false);
+ $content = static::filterIEFilters($content, $callback);
+
+ return $content;
+ }
+
+ /**
+ * Filters all CSS url()'s through a callable.
+ *
+ * @param string $content The CSS
+ * @param callable $callback A PHP callable
+ *
+ * @return string The filtered CSS
+ */
+ public static function filterUrls($content, $callback)
+ {
+ $pattern = static::REGEX_URLS;
+
+ return static::filterCommentless($content, function ($part) use (& $callback, $pattern) {
+ return preg_replace_callback($pattern, $callback, $part);
+ });
+ }
+
+ /**
+ * Filters all CSS imports through a callable.
+ *
+ * @param string $content The CSS
+ * @param callable $callback A PHP callable
+ * @param Boolean $includeUrl Whether to include url() in the pattern
+ *
+ * @return string The filtered CSS
+ */
+ public static function filterImports($content, $callback, $includeUrl = true)
+ {
+ $pattern = $includeUrl ? static::REGEX_IMPORTS : static::REGEX_IMPORTS_NO_URLS;
+
+ return static::filterCommentless($content, function ($part) use (& $callback, $pattern) {
+ return preg_replace_callback($pattern, $callback, $part);
+ });
+ }
+
+ /**
+ * Filters all IE filters (AlphaImageLoader filter) through a callable.
+ *
+ * @param string $content The CSS
+ * @param callable $callback A PHP callable
+ *
+ * @return string The filtered CSS
+ */
+ public static function filterIEFilters($content, $callback)
+ {
+ $pattern = static::REGEX_IE_FILTERS;
+
+ return static::filterCommentless($content, function ($part) use (& $callback, $pattern) {
+ return preg_replace_callback($pattern, $callback, $part);
+ });
+ }
+
+ /**
+ * Filters each non-comment part through a callable.
+ *
+ * @param string $content The CSS
+ * @param callable $callback A PHP callable
+ *
+ * @return string The filtered CSS
+ */
+ public static function filterCommentless($content, $callback)
+ {
+ $result = '';
+ foreach (preg_split(static::REGEX_COMMENTS, $content, -1, PREG_SPLIT_DELIM_CAPTURE) as $part) {
+ if (!preg_match(static::REGEX_COMMENTS, $part, $match) || $part != $match[0]) {
+ $part = call_user_func($callback, $part);
+ }
+
+ $result .= $part;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Extracts all references from the supplied CSS content.
+ *
+ * @param string $content The CSS content
+ *
+ * @return array An array of unique URLs
+ */
+ public static function extractImports($content)
+ {
+ $imports = array();
+ static::filterImports($content, function ($matches) use (&$imports) {
+ $imports[] = $matches['url'];
+ });
+
+ return array_unique(array_filter($imports));
+ }
+
+ final private function __construct()
+ {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Util/FilesystemUtils.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Util/FilesystemUtils.php
new file mode 100644
index 0000000..90e6512
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Util/FilesystemUtils.php
@@ -0,0 +1,84 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Util;
+
+/**
+ * Filesystem utilities.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class FilesystemUtils
+{
+ /**
+ * Recursively removes a directory from the filesystem.
+ */
+ public static function removeDirectory($directory)
+ {
+ $inner = new \RecursiveDirectoryIterator($directory, \FilesystemIterator::SKIP_DOTS);
+ $outer = new \RecursiveIteratorIterator($inner, \RecursiveIteratorIterator::SELF_FIRST);
+
+ // remove the files first
+ foreach ($outer as $file) {
+ if ($file->isFile()) {
+ unlink($file);
+ }
+ }
+
+ // remove the sub-directories next
+ $files = iterator_to_array($outer);
+ foreach (array_reverse($files) as $file) {
+ /** @var \SplFileInfo $file */
+ if ($file->isDir()) {
+ rmdir($file);
+ }
+ }
+
+ // finally the directory itself
+ rmdir($directory);
+ }
+
+ /**
+ * Creates a throw-away directory.
+ *
+ * This is not considered a "temporary" directory because it will not be
+ * automatically deleted at the end of the request or process. It must be
+ * deleted manually.
+ *
+ * @param string $prefix A prefix for the directory name
+ *
+ * @return string The directory path
+ */
+ public static function createThrowAwayDirectory($prefix)
+ {
+ $directory = self::getTemporaryDirectory().DIRECTORY_SEPARATOR.uniqid('assetic_'.$prefix);
+ mkdir($directory);
+
+ return $directory;
+ }
+
+ /**
+ * Creates a temporary file.
+ *
+ * @param string $prefix A prefix for the file name
+ *
+ * @return string The file path
+ */
+ public static function createTemporaryFile($prefix)
+ {
+ return tempnam(self::getTemporaryDirectory(), 'assetic_'.$prefix);
+ }
+
+ public static function getTemporaryDirectory()
+ {
+ return realpath(sys_get_temp_dir());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Util/LessUtils.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Util/LessUtils.php
new file mode 100644
index 0000000..1b53f2b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Util/LessUtils.php
@@ -0,0 +1,24 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Util;
+
+/**
+ * Less Utils.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+abstract class LessUtils extends CssUtils
+{
+ const REGEX_IMPORTS = '/@import(?:-once)? (?:\([a-z]*\) )?(?:url\()?(\'|"|)(?P<url>[^\'"\)\n\r]*)\1\)?;?/';
+ const REGEX_IMPORTS_NO_URLS = '/@import(?:-once)? (?:\([a-z]*\) )?(?!url\()(\'|"|)(?P<url>[^\'"\)\n\r]*)\1;?/';
+ const REGEX_COMMENTS = '/((?:\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)|\/\/[^\n]+)/';
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Util/SassUtils.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Util/SassUtils.php
new file mode 100644
index 0000000..9c07615
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Util/SassUtils.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2015 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Util;
+
+/**
+ * Sass Utils.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+abstract class SassUtils extends CssUtils
+{
+ const REGEX_COMMENTS = '/((?:\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)|\/\/[^\n]+)/';
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Util/TraversableString.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Util/TraversableString.php
new file mode 100644
index 0000000..400e97c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Util/TraversableString.php
@@ -0,0 +1,44 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Util;
+
+/**
+ * An object that can be used as either a string or array.
+ *
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
+ */
+class TraversableString implements \IteratorAggregate, \Countable
+{
+ private $one;
+ private $many;
+
+ public function __construct($one, array $many)
+ {
+ $this->one = $one;
+ $this->many = $many;
+ }
+
+ public function getIterator()
+ {
+ return new \ArrayIterator($this->many);
+ }
+
+ public function count()
+ {
+ return count($this->many);
+ }
+
+ public function __toString()
+ {
+ return (string) $this->one;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Util/VarUtils.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Util/VarUtils.php
new file mode 100644
index 0000000..d9464c0
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/Util/VarUtils.php
@@ -0,0 +1,84 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic\Util;
+
+/**
+ * Variable utilities.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+abstract class VarUtils
+{
+ /**
+ * Resolves variable placeholders.
+ *
+ * @param string $template A template string
+ * @param array $vars Variable names
+ * @param array $values Variable values
+ *
+ * @return string The resolved string
+ *
+ * @throws \InvalidArgumentException If there is a variable with no value
+ */
+ public static function resolve($template, array $vars, array $values)
+ {
+ $map = array();
+ foreach ($vars as $var) {
+ if (false === strpos($template, '{'.$var.'}')) {
+ continue;
+ }
+
+ if (!isset($values[$var])) {
+ throw new \InvalidArgumentException(sprintf('The template "%s" contains the variable "%s", but was not given any value for it.', $template, $var));
+ }
+
+ $map['{'.$var.'}'] = $values[$var];
+ }
+
+ return strtr($template, $map);
+ }
+
+ public static function getCombinations(array $vars, array $values)
+ {
+ if (!$vars) {
+ return array(array());
+ }
+
+ $combinations = array();
+ $nbValues = array();
+ foreach ($values as $var => $vals) {
+ if (!in_array($var, $vars, true)) {
+ continue;
+ }
+
+ $nbValues[$var] = count($vals);
+ }
+
+ for ($i = array_product($nbValues), $c = $i * 2; $i < $c; $i++) {
+ $k = $i;
+ $combination = array();
+
+ foreach ($vars as $var) {
+ $combination[$var] = $values[$var][$k % $nbValues[$var]];
+ $k = intval($k / $nbValues[$var]);
+ }
+
+ $combinations[] = $combination;
+ }
+
+ return $combinations;
+ }
+
+ final private function __construct()
+ {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/ValueSupplierInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/ValueSupplierInterface.php
new file mode 100644
index 0000000..a99874e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/Assetic/ValueSupplierInterface.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Assetic;
+
+/**
+ * Value Supplier Interface.
+ *
+ * Implementations determine runtime values for compile-time variables.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+interface ValueSupplierInterface
+{
+ /**
+ * Returns a map of values.
+ *
+ * @return array
+ */
+ public function getValues();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/functions.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/functions.php
new file mode 100644
index 0000000..2af5bde
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/kriswallsmith/assetic/src/functions.php
@@ -0,0 +1,125 @@
+<?php
+
+/*
+ * This file is part of the Assetic package, an OpenSky project.
+ *
+ * (c) 2010-2014 OpenSky Project Inc
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use Assetic\Factory\AssetFactory;
+use Assetic\Util\TraversableString;
+
+if (function_exists('assetic_init')) {
+ return;
+}
+
+/**
+ * Initializes the global Assetic object.
+ *
+ * @param AssetFactory $factory The asset factory
+ */
+function assetic_init(AssetFactory $factory)
+{
+ global $_assetic;
+
+ $_assetic = new stdClass();
+ $_assetic->factory = $factory;
+}
+
+/**
+ * Returns an array of javascript URLs.
+ *
+ * @param array|string $inputs Input strings
+ * @param array|string $filters Filter names
+ * @param array $options An array of options
+ *
+ * @return array An array of javascript URLs
+ */
+function assetic_javascripts($inputs = array(), $filters = array(), array $options = array())
+{
+ if (!isset($options['output'])) {
+ $options['output'] = 'js/*.js';
+ }
+
+ return _assetic_urls($inputs, $filters, $options);
+}
+
+/**
+ * Returns an array of stylesheet URLs.
+ *
+ * @param array|string $inputs Input strings
+ * @param array|string $filters Filter names
+ * @param array $options An array of options
+ *
+ * @return array An array of stylesheet URLs
+ */
+function assetic_stylesheets($inputs = array(), $filters = array(), array $options = array())
+{
+ if (!isset($options['output'])) {
+ $options['output'] = 'css/*.css';
+ }
+
+ return _assetic_urls($inputs, $filters, $options);
+}
+
+/**
+ * Returns an image URL.
+ *
+ * @param string $input An input
+ * @param array|string $filters Filter names
+ * @param array $options An array of options
+ *
+ * @return string An image URL
+ */
+function assetic_image($input, $filters = array(), array $options = array())
+{
+ if (!isset($options['output'])) {
+ $options['output'] = 'images/*';
+ }
+
+ $urls = _assetic_urls($input, $filters, $options);
+
+ return current($urls);
+}
+
+/**
+ * Returns an array of asset urls.
+ *
+ * @param array|string $inputs Input strings
+ * @param array|string $filters Filter names
+ * @param array $options An array of options
+ *
+ * @return array An array of URLs
+ */
+function _assetic_urls($inputs = array(), $filters = array(), array $options = array())
+{
+ global $_assetic;
+
+ if (!is_array($inputs)) {
+ $inputs = array_filter(array_map('trim', explode(',', $inputs)));
+ }
+
+ if (!is_array($filters)) {
+ $filters = array_filter(array_map('trim', explode(',', $filters)));
+ }
+
+ $coll = $_assetic->factory->createAsset($inputs, $filters, $options);
+
+ $debug = isset($options['debug']) ? $options['debug'] : $_assetic->factory->isDebug();
+ $combine = isset($options['combine']) ? $options['combine'] : !$debug;
+
+ $one = $coll->getTargetPath();
+ if ($combine) {
+ $many = array($one);
+ } else {
+ $many = array();
+ foreach ($coll as $leaf) {
+ $many[] = $leaf->getTargetPath();
+ }
+ }
+
+ return new TraversableString($one, $many);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/lmammino/jsmin4assetic/LICENSE b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/lmammino/jsmin4assetic/LICENSE
new file mode 100644
index 0000000..1f2dfac
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/lmammino/jsmin4assetic/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2013 Luciano Mammino
+
+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. \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/lmammino/jsmin4assetic/README.markdown b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/lmammino/jsmin4assetic/README.markdown
new file mode 100644
index 0000000..a910ce6
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/lmammino/jsmin4assetic/README.markdown
@@ -0,0 +1,21 @@
+JSMin4Assetic
+-------------
+
+Slight modified version of [nick4fake/JsMin](https://github.com/nick4fake/JsMin/) that works with [Assetic](https://github.com/kriswallsmith/assetic).
+
+The fastest solution to use JsMin and Assetic if you use [Composer](http://getcomposer.org/).
+
+
+Installation
+============
+
+It's heavily suggested to use
+Add the following lines to your `composer.json`
+
+``` javascript
+{
+ "require": {
+ "lmammino/jsmin4assetic": "1.0.*"
+ }
+}
+``` \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/lmammino/jsmin4assetic/composer.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/lmammino/jsmin4assetic/composer.json
new file mode 100644
index 0000000..d65325d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/lmammino/jsmin4assetic/composer.json
@@ -0,0 +1,26 @@
+{
+ "name": "lmammino/jsmin4assetic",
+ "type": "library",
+ "description":"Library for minifying JavaScript files using jsmin with assetic and composer",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Douglas Crockford",
+ "homepage":"http://www.crockford.com"
+ },
+ {
+ "name": "Bogdan Yurov",
+ "email":"bogdan@yurov.me"
+ },
+ {
+ "name": "Luciano Mammino",
+ "email":"lmammino@oryzone.com"
+ }
+ ],
+ "require": {
+ "php":">=5.3"
+ },
+ "autoload": {
+ "classmap": ["src/"]
+ }
+} \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/lmammino/jsmin4assetic/src/JSMin.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/lmammino/jsmin4assetic/src/JSMin.php
new file mode 100644
index 0000000..a825229
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/lmammino/jsmin4assetic/src/JSMin.php
@@ -0,0 +1,379 @@
+<?php
+/**
+ * JSMin.php - modified PHP implementation of Douglas Crockford's JSMin.
+ *
+ * <code>
+ * $minifiedJs = \JSMin\Minify::minify($js);
+ * </code>
+ *
+ * This is a modified port of jsmin.c. Improvements:
+ *
+ * Does not choke on some regexp literals containing quote characters. E.g. /'/
+ *
+ * Spaces are preserved after some add/sub operators, so they are not mistakenly
+ * converted to post-inc/dec. E.g. a + ++b -> a+ ++b
+ *
+ * Preserves multi-line comments that begin with /*!
+ *
+ * PHP 5 or higher is required.
+ *
+ * Permission is hereby granted to use this version of the library under the
+ * same terms as jsmin.c, which has the following license:
+ *
+ * --
+ * Copyright (c) 2002 Douglas Crockford (www.crockford.com)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * The Software shall be used for Good, not Evil.
+ *
+ * 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.
+ * --
+ *
+ * @package JSMin
+ * @author Ryan Grove <ryan@wonko.com> (PHP port)
+ * @author Steve Clay <steve@mrclay.org> (modifications + cleanup)
+ * @author Andrea Giammarchi <http://www.3site.eu> (spaceBeforeRegExp)
+ * @author Luciano Mammino <lmammino@oryzone.com> (assetic adaptation)
+ * @copyright 2002 Douglas Crockford <douglas@crockford.com> (jsmin.c)
+ * @copyright 2008 Ryan Grove <ryan@wonko.com> (PHP port)
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @link http://code.google.com/p/jsmin-php/
+ */
+class JSMin {
+
+ const ORD_LF = 10;
+ const ORD_SPACE = 32;
+ const ACTION_KEEP_A = 1;
+ const ACTION_DELETE_A = 2;
+ const ACTION_DELETE_A_B = 3;
+
+ protected $a = "\n";
+ protected $b = '';
+ protected $input = '';
+ protected $inputIndex = 0;
+ protected $inputLength = 0;
+ protected $lookAhead = null;
+ protected $output = '';
+ protected $lastByteOut = '';
+
+ /**
+ * Minify Javascript.
+ *
+ * @param string $js Javascript to be minified
+ *
+ * @return string
+ */
+ public static function minify($js) {
+ $jsmin = new static($js);
+ return $jsmin->min();
+ }
+
+ /**
+ * @param string $input
+ */
+ public function __construct($input) {
+ $this->input = $input;
+ }
+
+ /**
+ * Perform minification, return result
+ *
+ * @return string
+ */
+ public function min() {
+ if ($this->output !== '') { // min already run
+ return $this->output;
+ }
+
+ $mbIntEnc = null;
+ if (function_exists('mb_strlen') && ((int)ini_get('mbstring.func_overload') & 2)) {
+ $mbIntEnc = mb_internal_encoding();
+ mb_internal_encoding('8bit');
+ }
+ $this->input = str_replace("\r\n", "\n", $this->input);
+ $this->inputLength = strlen($this->input);
+
+ $this->action(self::ACTION_DELETE_A_B);
+
+ while ($this->a !== null) {
+ // determine next command
+ $command = self::ACTION_KEEP_A; // default
+ if ($this->a === ' ') {
+ if (($this->lastByteOut === '+' || $this->lastByteOut === '-')
+ && ($this->b === $this->lastByteOut)
+ ) {
+ // Don't delete this space. If we do, the addition/subtraction
+ // could be parsed as a post-increment
+ } elseif (!$this->isAlphaNum($this->b)) {
+ $command = self::ACTION_DELETE_A;
+ }
+ } elseif ($this->a === "\n") {
+ if ($this->b === ' ') {
+ $command = self::ACTION_DELETE_A_B;
+ // in case of mbstring.func_overload & 2, must check for null b,
+ // otherwise mb_strpos will give WARNING
+ } elseif ($this->b === null
+ || (false === strpos('{[(+-', $this->b)
+ && !$this->isAlphaNum($this->b))
+ ) {
+ $command = self::ACTION_DELETE_A;
+ }
+ } elseif (!$this->isAlphaNum($this->a)) {
+ if ($this->b === ' '
+ || ($this->b === "\n"
+ && (false === strpos('}])+-"\'', $this->a)))
+ ) {
+ $command = self::ACTION_DELETE_A_B;
+ }
+ }
+ $this->action($command);
+ }
+ $this->output = trim($this->output);
+
+ if ($mbIntEnc !== null) {
+ mb_internal_encoding($mbIntEnc);
+ }
+ return $this->output;
+ }
+
+ /**
+ * ACTION_KEEP_A = Output A. Copy B to A. Get the next B.
+ * ACTION_DELETE_A = Copy B to A. Get the next B.
+ * ACTION_DELETE_A_B = Get the next B.
+ *
+ * @param int $command
+ * @throws JSMinUnterminatedRegExpException|JSMinUnterminatedStringException
+ */
+ protected function action($command) {
+ if ($command === self::ACTION_DELETE_A_B
+ && $this->b === ' '
+ && ($this->a === '+' || $this->a === '-')
+ ) {
+ // Note: we're at an addition/substraction operator; the inputIndex
+ // will certainly be a valid index
+ if ($this->input[$this->inputIndex] === $this->a) {
+ // This is "+ +" or "- -". Don't delete the space.
+ $command = self::ACTION_KEEP_A;
+ }
+ }
+ switch ($command) {
+ case self::ACTION_KEEP_A:
+ $this->output .= $this->a;
+ $this->lastByteOut = $this->a;
+
+ // fallthrough
+ case self::ACTION_DELETE_A:
+ $this->a = $this->b;
+ if ($this->a === "'" || $this->a === '"') { // string literal
+ $str = $this->a; // in case needed for exception
+ while (true) {
+ $this->output .= $this->a;
+ $this->lastByteOut = $this->a;
+
+ $this->a = $this->get();
+ if ($this->a === $this->b) { // end quote
+ break;
+ }
+ if (ord($this->a) <= self::ORD_LF) {
+ throw new JSMinUnterminatedStringException(
+ "JSMin: Unterminated String at byte "
+ . $this->inputIndex . ": {$str}");
+ }
+ $str .= $this->a;
+ if ($this->a === '\\') {
+ $this->output .= $this->a;
+ $this->lastByteOut = $this->a;
+
+ $this->a = $this->get();
+ $str .= $this->a;
+ }
+ }
+ }
+ // fallthrough
+ case self::ACTION_DELETE_A_B:
+ $this->b = $this->next();
+ if ($this->b === '/' && $this->isRegexpLiteral()) { // RegExp literal
+ $this->output .= $this->a . $this->b;
+ $pattern = '/'; // in case needed for exception
+ while (true) {
+ $this->a = $this->get();
+ $pattern .= $this->a;
+ if ($this->a === '/') { // end pattern
+ break; // while (true)
+ } elseif ($this->a === '\\') {
+ $this->output .= $this->a;
+ $this->a = $this->get();
+ $pattern .= $this->a;
+ } elseif (ord($this->a) <= self::ORD_LF) {
+ throw new JSMinUnterminatedRegExpException(
+ "JSMin: Unterminated RegExp at byte "
+ . $this->inputIndex . ": {$pattern}");
+ }
+ $this->output .= $this->a;
+ $this->lastByteOut = $this->a;
+ }
+ $this->b = $this->next();
+ }
+ // end case ACTION_DELETE_A_B
+ }
+ }
+
+ /**
+ * @return bool
+ */
+ protected function isRegexpLiteral() {
+ if (false !== strpos("\n{;(,=:[!&|?", $this->a)) { // we aren't dividing
+ return true;
+ }
+ if (' ' === $this->a) {
+ $length = strlen($this->output);
+ if ($length < 2) { // weird edge case
+ return true;
+ }
+ // you can't divide a keyword
+ if (preg_match('/(?:case|else|in|return|typeof)$/', $this->output, $m)) {
+ if ($this->output === $m[0]) { // odd but could happen
+ return true;
+ }
+ // make sure it's a keyword, not end of an identifier
+ $charBeforeKeyword = substr($this->output, $length - strlen($m[0]) - 1, 1);
+ if (!$this->isAlphaNum($charBeforeKeyword)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Get next char. Convert ctrl char to space.
+ *
+ * @return string
+ */
+ protected function get() {
+ $c = $this->lookAhead;
+ $this->lookAhead = null;
+ if ($c === null) {
+ if ($this->inputIndex < $this->inputLength) {
+ $c = $this->input[$this->inputIndex];
+ $this->inputIndex += 1;
+ } else {
+ return null;
+ }
+ }
+ if ($c === "\r" || $c === "\n") {
+ return "\n";
+ }
+ if (ord($c) < self::ORD_SPACE) { // control char
+ return ' ';
+ }
+ return $c;
+ }
+
+ /**
+ * Get next char. If is ctrl character, translate to a space or newline.
+ *
+ * @return string
+ */
+ protected function peek() {
+ $this->lookAhead = $this->get();
+ return $this->lookAhead;
+ }
+
+ /**
+ * Is $c a letter, digit, underscore, dollar sign, escape, or non-ASCII?
+ *
+ * @param string $c
+ *
+ * @return bool
+ */
+ protected function isAlphaNum($c) {
+ return (preg_match('/^[0-9a-zA-Z_\\$\\\\]$/', $c) || ord($c) > 126);
+ }
+
+ /**
+ * @return string
+ */
+ protected function singleLineComment() {
+ $comment = '';
+ while (true) {
+ $get = $this->get();
+ $comment .= $get;
+ if (ord($get) <= self::ORD_LF) { // EOL reached
+ // if IE conditional comment
+ if (preg_match('/^\\/@(?:cc_on|if|elif|else|end)\\b/', $comment)) {
+ return "/{$comment}";
+ }
+ return $get;
+ }
+ }
+ }
+
+ /**
+ * @return string
+ * @throws JSMinUnterminatedCommentException
+ */
+ protected function multipleLineComment() {
+ $this->get();
+ $comment = '';
+ while (true) {
+ $get = $this->get();
+ if ($get === '*') {
+ if ($this->peek() === '/') { // end of comment reached
+ $this->get();
+ // if comment preserved by YUI Compressor
+ if (0 === strpos($comment, '!')) {
+ return "\n/*!" . substr($comment, 1) . "*/\n";
+ }
+ // if IE conditional comment
+ if (preg_match('/^@(?:cc_on|if|elif|else|end)\\b/', $comment)) {
+ return "/*{$comment}*/";
+ }
+ return ' ';
+ }
+ } elseif ($get === null) {
+ throw new JSMinUnterminatedCommentException(
+ "JSMin: Unterminated comment at byte "
+ . $this->inputIndex . ": /*{$comment}");
+ }
+ $comment .= $get;
+ }
+ }
+
+ /**
+ * Get the next character, skipping over comments.
+ * Some comments may be preserved.
+ *
+ * @return string
+ */
+ protected function next() {
+ $get = $this->get();
+ if ($get !== '/') {
+ return $get;
+ }
+ switch ($this->peek()) {
+ case '/':
+ return $this->singleLineComment();
+ case '*':
+ return $this->multipleLineComment();
+ default:
+ return $get;
+ }
+ }
+
+} \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/lmammino/jsmin4assetic/src/JSMinUnterminatedCommentException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/lmammino/jsmin4assetic/src/JSMinUnterminatedCommentException.php
new file mode 100644
index 0000000..7ffc3b2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/lmammino/jsmin4assetic/src/JSMinUnterminatedCommentException.php
@@ -0,0 +1,5 @@
+<?php
+
+class JSMinUnterminatedCommentException extends \Exception {
+
+} \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/lmammino/jsmin4assetic/src/JSMinUnterminatedRegExpException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/lmammino/jsmin4assetic/src/JSMinUnterminatedRegExpException.php
new file mode 100644
index 0000000..55f1206
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/lmammino/jsmin4assetic/src/JSMinUnterminatedRegExpException.php
@@ -0,0 +1,5 @@
+<?php
+
+class JSMinUnterminatedRegExpException extends \Exception {
+
+} \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/lmammino/jsmin4assetic/src/JSMinUnterminatedStringException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/lmammino/jsmin4assetic/src/JSMinUnterminatedStringException.php
new file mode 100644
index 0000000..53a6af6
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/lmammino/jsmin4assetic/src/JSMinUnterminatedStringException.php
@@ -0,0 +1,5 @@
+<?php
+
+class JSMinUnterminatedStringException extends \Exception {
+
+} \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/CONTRIBUTING.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/CONTRIBUTING.md
new file mode 100644
index 0000000..226cf97
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/CONTRIBUTING.md
@@ -0,0 +1,59 @@
+# How to contribute
+
+
+## Issues
+
+When [filing bugs](https://github.com/matthiasmullie/minify/issues/new),
+try to be as thorough as possible:
+* What version did you use?
+* What did you try to do? ***Please post the relevant parts of your code.***
+* What went wrong? ***Please include error messages, if any.***
+* What was the expected result?
+
+
+## Pull requests
+
+Bug fixes and general improvements to the existing codebase are always welcome.
+New features are also welcome, but will be judged on an individual basis. If
+you'd rather not risk wasting your time implementing a new feature only to see
+it turned down, please start the discussion by
+[opening an issue](https://github.com/matthiasmullie/minify/issues/new).
+
+Don't forget to add your changes to the [changelog](CHANGELOG.md).
+
+
+### Testing
+
+Please include tests for every change or addition to the code.
+To run the complete test suite:
+
+```sh
+vendor/bin/phpunit
+```
+
+When submitting a new pull request, please make sure that that the test suite
+passes (Travis CI will run it & report back on your pull request.)
+
+To run the tests on Windows, run `tests/convert_symlinks_to_windows_style.sh`
+from the command line in order to convert Linux-style test symlinks to
+Windows-style.
+
+
+### Coding standards
+
+All code must follow [PSR-2](http://www.php-fig.org/psr/psr-2/). Just make sure
+to run php-cs-fixer before submitting the code, it'll take care of the
+formatting for you:
+
+```sh
+vendor/bin/php-cs-fixer fix src
+vendor/bin/php-cs-fixer fix tests
+```
+
+Document the code thoroughly!
+
+
+## License
+
+Note that minify is MIT-licensed, which basically allows anyone to do
+anything they like with it, without restriction.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/Dockerfile b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/Dockerfile
new file mode 100644
index 0000000..d17f9d7
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/Dockerfile
@@ -0,0 +1,13 @@
+ARG version=cli
+FROM php:$version
+
+COPY . /var/www
+WORKDIR /var/www
+
+RUN apt-get update
+RUN apt-get install -y zip unzip zlib1g-dev
+RUN docker-php-ext-install zip
+RUN docker-php-ext-install pcntl
+RUN curl -sS https://getcomposer.org/installer | php
+RUN mv composer.phar /usr/local/bin/composer
+RUN composer install
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/LICENSE b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/LICENSE
new file mode 100644
index 0000000..0c0d08a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/LICENSE
@@ -0,0 +1,18 @@
+Copyright (c) 2012 Matthias Mullie
+
+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.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/bin/minifycss b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/bin/minifycss
new file mode 100644
index 0000000..6a681a8
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/bin/minifycss
@@ -0,0 +1,45 @@
+#!/usr/bin/env php
+<?php
+use MatthiasMullie\Minify;
+
+// command line utility to minify CSS
+if (file_exists(__DIR__ . '/../../../autoload.php')) {
+ // if composer install
+ require_once __DIR__ . '/../../../autoload.php';
+} else {
+ require_once __DIR__ . '/../src/Minify.php';
+ require_once __DIR__ . '/../src/CSS.php';
+ require_once __DIR__ . '/../src/Exception.php';
+}
+
+error_reporting(E_ALL);
+// check PHP setup for cli arguments
+if (!isset($_SERVER['argv']) && !isset($argv)) {
+ fwrite(STDERR, 'Please enable the "register_argc_argv" directive in your php.ini' . PHP_EOL);
+ exit(1);
+} elseif (!isset($argv)) {
+ $argv = $_SERVER['argv'];
+}
+// check if path to file given
+if (!isset($argv[1])) {
+ fwrite(STDERR, 'Argument expected: path to file' . PHP_EOL);
+ exit(1);
+}
+// check if script run in cli environment
+if ('cli' !== php_sapi_name()) {
+ fwrite(STDERR, $argv[1] . ' must be run in the command line' . PHP_EOL);
+ exit(1);
+}
+// check if source file exists
+if (!file_exists($argv[1])) {
+ fwrite(STDERR, 'Source file "' . $argv[1] . '" not found' . PHP_EOL);
+ exit(1);
+}
+
+try {
+ $minifier = new Minify\CSS($argv[1]);
+ echo $minifier->minify();
+} catch (Exception $e) {
+ fwrite(STDERR, $e->getMessage(), PHP_EOL);
+ exit(1);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/bin/minifyjs b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/bin/minifyjs
new file mode 100644
index 0000000..4cbe63f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/bin/minifyjs
@@ -0,0 +1,45 @@
+#!/usr/bin/env php
+<?php
+use MatthiasMullie\Minify;
+
+// command line utility to minify JS
+if (file_exists(__DIR__ . '/../../../autoload.php')) {
+ // if composer install
+ require_once __DIR__ . '/../../../autoload.php';
+} else {
+ require_once __DIR__ . '/../src/Minify.php';
+ require_once __DIR__ . '/../src/JS.php';
+ require_once __DIR__ . '/../src/Exception.php';
+}
+
+error_reporting(E_ALL);
+// check PHP setup for cli arguments
+if (!isset($_SERVER['argv']) && !isset($argv)) {
+ fwrite(STDERR, 'Please enable the "register_argc_argv" directive in your php.ini' . PHP_EOL);
+ exit(1);
+} elseif (!isset($argv)) {
+ $argv = $_SERVER['argv'];
+}
+// check if path to file given
+if (!isset($argv[1])) {
+ fwrite(STDERR, 'Argument expected: path to file' . PHP_EOL);
+ exit(1);
+}
+// check if script run in cli environment
+if ('cli' !== php_sapi_name()) {
+ fwrite(STDERR, $argv[1] . ' must be run in the command line' . PHP_EOL);
+ exit(1);
+}
+// check if source file exists
+if (!file_exists($argv[1])) {
+ fwrite(STDERR, 'Source file "' . $argv[1] . '" not found' . PHP_EOL);
+ exit(1);
+}
+
+try {
+ $minifier = new Minify\JS($argv[1]);
+ echo $minifier->minify();
+} catch (Exception $e) {
+ fwrite(STDERR, $e->getMessage(), PHP_EOL);
+ exit(1);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/composer.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/composer.json
new file mode 100644
index 0000000..6d81b4f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/composer.json
@@ -0,0 +1,38 @@
+{
+ "name": "matthiasmullie/minify",
+ "type": "library",
+ "description": "CSS & JavaScript minifier, in PHP. Removes whitespace, strips comments, combines files (incl. @import statements and small assets in CSS files), and optimizes/shortens a few common programming patterns.",
+ "keywords": ["minify", "minifier", "css", "js", "javascript"],
+ "homepage": "http://www.minifier.org",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Matthias Mullie",
+ "homepage": "http://www.mullie.eu",
+ "email": "minify@mullie.eu",
+ "role": "Developer"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.0",
+ "ext-pcre": "*",
+ "matthiasmullie/path-converter": "~1.1"
+ },
+ "require-dev": {
+ "matthiasmullie/scrapbook": "~1.0",
+ "phpunit/phpunit": "~4.8",
+ "friendsofphp/php-cs-fixer": "~2.0"
+ },
+ "suggest": {
+ "psr/cache-implementation": "Cache implementation to use with Minify::cache"
+ },
+ "autoload": {
+ "psr-4": {
+ "MatthiasMullie\\Minify\\": "src/"
+ }
+ },
+ "bin": [
+ "bin/minifycss",
+ "bin/minifyjs"
+ ]
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/data/js/keywords_after.txt b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/data/js/keywords_after.txt
new file mode 100644
index 0000000..5c8cba7
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/data/js/keywords_after.txt
@@ -0,0 +1,7 @@
+in
+public
+extends
+private
+protected
+implements
+instanceof \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/data/js/keywords_before.txt b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/data/js/keywords_before.txt
new file mode 100644
index 0000000..5abf357
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/data/js/keywords_before.txt
@@ -0,0 +1,26 @@
+do
+in
+let
+new
+var
+case
+else
+enum
+void
+with
+class
+const
+yield
+delete
+export
+import
+public
+static
+typeof
+extends
+package
+private
+function
+protected
+implements
+instanceof \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/data/js/keywords_reserved.txt b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/data/js/keywords_reserved.txt
new file mode 100644
index 0000000..2a3ad3c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/data/js/keywords_reserved.txt
@@ -0,0 +1,63 @@
+do
+if
+in
+for
+let
+new
+try
+var
+case
+else
+enum
+eval
+null
+this
+true
+void
+with
+break
+catch
+class
+const
+false
+super
+throw
+while
+yield
+delete
+export
+import
+public
+return
+static
+switch
+typeof
+default
+extends
+finally
+package
+private
+continue
+debugger
+function
+arguments
+interface
+protected
+implements
+instanceof
+abstract
+boolean
+byte
+char
+double
+final
+float
+goto
+int
+long
+native
+short
+synchronized
+throws
+transient
+volatile \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/data/js/operators.txt b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/data/js/operators.txt
new file mode 100644
index 0000000..e66229a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/data/js/operators.txt
@@ -0,0 +1,46 @@
++
+-
+*
+/
+%
+=
++=
+-=
+*=
+/=
+%=
+<<=
+>>=
+>>>=
+&=
+^=
+|=
+&
+|
+^
+~
+<<
+>>
+>>>
+==
+===
+!=
+!==
+>
+<
+>=
+<=
+&&
+||
+!
+.
+[
+]
+?
+:
+,
+;
+(
+)
+{
+} \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/data/js/operators_after.txt b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/data/js/operators_after.txt
new file mode 100644
index 0000000..71a9b70
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/data/js/operators_after.txt
@@ -0,0 +1,43 @@
++
+-
+*
+/
+%
+=
++=
+-=
+*=
+/=
+%=
+<<=
+>>=
+>>>=
+&=
+^=
+|=
+&
+|
+^
+<<
+>>
+>>>
+==
+===
+!=
+!==
+>
+<
+>=
+<=
+&&
+||
+.
+[
+]
+?
+:
+,
+;
+(
+)
+} \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/data/js/operators_before.txt b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/data/js/operators_before.txt
new file mode 100644
index 0000000..ff50d87
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/data/js/operators_before.txt
@@ -0,0 +1,43 @@
++
+-
+*
+/
+%
+=
++=
+-=
+*=
+/=
+%=
+<<=
+>>=
+>>>=
+&=
+^=
+|=
+&
+|
+^
+~
+<<
+>>
+>>>
+==
+===
+!=
+!==
+>
+<
+>=
+<=
+&&
+||
+!
+.
+[
+?
+:
+,
+;
+(
+{
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/docker-compose.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/docker-compose.yml
new file mode 100644
index 0000000..5413e24
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/docker-compose.yml
@@ -0,0 +1,31 @@
+version: '2.1'
+services:
+ php:
+ build:
+ context: .
+ dockerfile: Dockerfile
+ volumes:
+ - ./src:/var/www/src
+ - ./data:/var/www/data
+ - ./tests:/var/www/tests
+ - ./phpunit.xml.dist:/var/www/phpunit.xml.dist
+ '7.2':
+ extends: php
+ build:
+ args:
+ version: 7.2-cli
+ '7.1':
+ extends: php
+ build:
+ args:
+ version: 7.1-cli
+ '7.0':
+ extends: php
+ build:
+ args:
+ version: 7.0-cli
+ '5.6':
+ extends: php
+ build:
+ args:
+ version: 5.6-cli
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/src/CSS.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/src/CSS.php
new file mode 100644
index 0000000..742f043
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/src/CSS.php
@@ -0,0 +1,736 @@
+<?php
+/**
+ * CSS Minifier
+ *
+ * Please report bugs on https://github.com/matthiasmullie/minify/issues
+ *
+ * @author Matthias Mullie <minify@mullie.eu>
+ * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
+ * @license MIT License
+ */
+
+namespace MatthiasMullie\Minify;
+
+use MatthiasMullie\Minify\Exceptions\FileImportException;
+use MatthiasMullie\PathConverter\ConverterInterface;
+use MatthiasMullie\PathConverter\Converter;
+
+/**
+ * CSS minifier
+ *
+ * Please report bugs on https://github.com/matthiasmullie/minify/issues
+ *
+ * @package Minify
+ * @author Matthias Mullie <minify@mullie.eu>
+ * @author Tijs Verkoyen <minify@verkoyen.eu>
+ * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
+ * @license MIT License
+ */
+class CSS extends Minify
+{
+ /**
+ * @var int maximum inport size in kB
+ */
+ protected $maxImportSize = 5;
+
+ /**
+ * @var string[] valid import extensions
+ */
+ protected $importExtensions = array(
+ 'gif' => 'data:image/gif',
+ 'png' => 'data:image/png',
+ 'jpe' => 'data:image/jpeg',
+ 'jpg' => 'data:image/jpeg',
+ 'jpeg' => 'data:image/jpeg',
+ 'svg' => 'data:image/svg+xml',
+ 'woff' => 'data:application/x-font-woff',
+ 'tif' => 'image/tiff',
+ 'tiff' => 'image/tiff',
+ 'xbm' => 'image/x-xbitmap',
+ );
+
+ /**
+ * Set the maximum size if files to be imported.
+ *
+ * Files larger than this size (in kB) will not be imported into the CSS.
+ * Importing files into the CSS as data-uri will save you some connections,
+ * but we should only import relatively small decorative images so that our
+ * CSS file doesn't get too bulky.
+ *
+ * @param int $size Size in kB
+ */
+ public function setMaxImportSize($size)
+ {
+ $this->maxImportSize = $size;
+ }
+
+ /**
+ * Set the type of extensions to be imported into the CSS (to save network
+ * connections).
+ * Keys of the array should be the file extensions & respective values
+ * should be the data type.
+ *
+ * @param string[] $extensions Array of file extensions
+ */
+ public function setImportExtensions(array $extensions)
+ {
+ $this->importExtensions = $extensions;
+ }
+
+ /**
+ * Move any import statements to the top.
+ *
+ * @param string $content Nearly finished CSS content
+ *
+ * @return string
+ */
+ protected function moveImportsToTop($content)
+ {
+ if (preg_match_all('/(;?)(@import (?<url>url\()?(?P<quotes>["\']?).+?(?P=quotes)(?(url)\)))/', $content, $matches)) {
+ // remove from content
+ foreach ($matches[0] as $import) {
+ $content = str_replace($import, '', $content);
+ }
+
+ // add to top
+ $content = implode(';', $matches[2]).';'.trim($content, ';');
+ }
+
+ return $content;
+ }
+
+ /**
+ * Combine CSS from import statements.
+ *
+ * @import's will be loaded and their content merged into the original file,
+ * to save HTTP requests.
+ *
+ * @param string $source The file to combine imports for
+ * @param string $content The CSS content to combine imports for
+ * @param string[] $parents Parent paths, for circular reference checks
+ *
+ * @return string
+ *
+ * @throws FileImportException
+ */
+ protected function combineImports($source, $content, $parents)
+ {
+ $importRegexes = array(
+ // @import url(xxx)
+ '/
+ # import statement
+ @import
+
+ # whitespace
+ \s+
+
+ # open url()
+ url\(
+
+ # (optional) open path enclosure
+ (?P<quotes>["\']?)
+
+ # fetch path
+ (?P<path>.+?)
+
+ # (optional) close path enclosure
+ (?P=quotes)
+
+ # close url()
+ \)
+
+ # (optional) trailing whitespace
+ \s*
+
+ # (optional) media statement(s)
+ (?P<media>[^;]*)
+
+ # (optional) trailing whitespace
+ \s*
+
+ # (optional) closing semi-colon
+ ;?
+
+ /ix',
+
+ // @import 'xxx'
+ '/
+
+ # import statement
+ @import
+
+ # whitespace
+ \s+
+
+ # open path enclosure
+ (?P<quotes>["\'])
+
+ # fetch path
+ (?P<path>.+?)
+
+ # close path enclosure
+ (?P=quotes)
+
+ # (optional) trailing whitespace
+ \s*
+
+ # (optional) media statement(s)
+ (?P<media>[^;]*)
+
+ # (optional) trailing whitespace
+ \s*
+
+ # (optional) closing semi-colon
+ ;?
+
+ /ix',
+ );
+
+ // find all relative imports in css
+ $matches = array();
+ foreach ($importRegexes as $importRegex) {
+ if (preg_match_all($importRegex, $content, $regexMatches, PREG_SET_ORDER)) {
+ $matches = array_merge($matches, $regexMatches);
+ }
+ }
+
+ $search = array();
+ $replace = array();
+
+ // loop the matches
+ foreach ($matches as $match) {
+ // get the path for the file that will be imported
+ $importPath = dirname($source).'/'.$match['path'];
+
+ // only replace the import with the content if we can grab the
+ // content of the file
+ if (!$this->canImportByPath($match['path']) || !$this->canImportFile($importPath)) {
+ continue;
+ }
+
+ // check if current file was not imported previously in the same
+ // import chain.
+ if (in_array($importPath, $parents)) {
+ throw new FileImportException('Failed to import file "'.$importPath.'": circular reference detected.');
+ }
+
+ // grab referenced file & minify it (which may include importing
+ // yet other @import statements recursively)
+ $minifier = new static($importPath);
+ $importContent = $minifier->execute($source, $parents);
+
+ // check if this is only valid for certain media
+ if (!empty($match['media'])) {
+ $importContent = '@media '.$match['media'].'{'.$importContent.'}';
+ }
+
+ // add to replacement array
+ $search[] = $match[0];
+ $replace[] = $importContent;
+ }
+
+ // replace the import statements
+ return str_replace($search, $replace, $content);
+ }
+
+ /**
+ * Import files into the CSS, base64-ized.
+ *
+ * @url(image.jpg) images will be loaded and their content merged into the
+ * original file, to save HTTP requests.
+ *
+ * @param string $source The file to import files for
+ * @param string $content The CSS content to import files for
+ *
+ * @return string
+ */
+ protected function importFiles($source, $content)
+ {
+ $regex = '/url\((["\']?)(.+?)\\1\)/i';
+ if ($this->importExtensions && preg_match_all($regex, $content, $matches, PREG_SET_ORDER)) {
+ $search = array();
+ $replace = array();
+
+ // loop the matches
+ foreach ($matches as $match) {
+ $extension = substr(strrchr($match[2], '.'), 1);
+ if ($extension && !array_key_exists($extension, $this->importExtensions)) {
+ continue;
+ }
+
+ // get the path for the file that will be imported
+ $path = $match[2];
+ $path = dirname($source).'/'.$path;
+
+ // only replace the import with the content if we're able to get
+ // the content of the file, and it's relatively small
+ if ($this->canImportFile($path) && $this->canImportBySize($path)) {
+ // grab content && base64-ize
+ $importContent = $this->load($path);
+ $importContent = base64_encode($importContent);
+
+ // build replacement
+ $search[] = $match[0];
+ $replace[] = 'url('.$this->importExtensions[$extension].';base64,'.$importContent.')';
+ }
+ }
+
+ // replace the import statements
+ $content = str_replace($search, $replace, $content);
+ }
+
+ return $content;
+ }
+
+ /**
+ * Minify the data.
+ * Perform CSS optimizations.
+ *
+ * @param string[optional] $path Path to write the data to
+ * @param string[] $parents Parent paths, for circular reference checks
+ *
+ * @return string The minified data
+ */
+ public function execute($path = null, $parents = array())
+ {
+ $content = '';
+
+ // loop CSS data (raw data and files)
+ foreach ($this->data as $source => $css) {
+ /*
+ * Let's first take out strings & comments, since we can't just
+ * remove whitespace anywhere. If whitespace occurs inside a string,
+ * we should leave it alone. E.g.:
+ * p { content: "a test" }
+ */
+ $this->extractStrings();
+ $this->stripComments();
+ $css = $this->replace($css);
+
+ $css = $this->stripWhitespace($css);
+ $css = $this->shortenHex($css);
+ $css = $this->shortenZeroes($css);
+ $css = $this->shortenFontWeights($css);
+ $css = $this->stripEmptyTags($css);
+
+ // restore the string we've extracted earlier
+ $css = $this->restoreExtractedData($css);
+
+ $source = is_int($source) ? '' : $source;
+ $parents = $source ? array_merge($parents, array($source)) : $parents;
+ $css = $this->combineImports($source, $css, $parents);
+ $css = $this->importFiles($source, $css);
+
+ /*
+ * If we'll save to a new path, we'll have to fix the relative paths
+ * to be relative no longer to the source file, but to the new path.
+ * If we don't write to a file, fall back to same path so no
+ * conversion happens (because we still want it to go through most
+ * of the move code, which also addresses url() & @import syntax...)
+ */
+ $converter = $this->getPathConverter($source, $path ?: $source);
+ $css = $this->move($converter, $css);
+
+ // combine css
+ $content .= $css;
+ }
+
+ $content = $this->moveImportsToTop($content);
+
+ return $content;
+ }
+
+ /**
+ * Moving a css file should update all relative urls.
+ * Relative references (e.g. ../images/image.gif) in a certain css file,
+ * will have to be updated when a file is being saved at another location
+ * (e.g. ../../images/image.gif, if the new CSS file is 1 folder deeper).
+ *
+ * @param ConverterInterface $converter Relative path converter
+ * @param string $content The CSS content to update relative urls for
+ *
+ * @return string
+ */
+ protected function move(ConverterInterface $converter, $content)
+ {
+ /*
+ * Relative path references will usually be enclosed by url(). @import
+ * is an exception, where url() is not necessary around the path (but is
+ * allowed).
+ * This *could* be 1 regular expression, where both regular expressions
+ * in this array are on different sides of a |. But we're using named
+ * patterns in both regexes, the same name on both regexes. This is only
+ * possible with a (?J) modifier, but that only works after a fairly
+ * recent PCRE version. That's why I'm doing 2 separate regular
+ * expressions & combining the matches after executing of both.
+ */
+ $relativeRegexes = array(
+ // url(xxx)
+ '/
+ # open url()
+ url\(
+
+ \s*
+
+ # open path enclosure
+ (?P<quotes>["\'])?
+
+ # fetch path
+ (?P<path>.+?)
+
+ # close path enclosure
+ (?(quotes)(?P=quotes))
+
+ \s*
+
+ # close url()
+ \)
+
+ /ix',
+
+ // @import "xxx"
+ '/
+ # import statement
+ @import
+
+ # whitespace
+ \s+
+
+ # we don\'t have to check for @import url(), because the
+ # condition above will already catch these
+
+ # open path enclosure
+ (?P<quotes>["\'])
+
+ # fetch path
+ (?P<path>.+?)
+
+ # close path enclosure
+ (?P=quotes)
+
+ /ix',
+ );
+
+ // find all relative urls in css
+ $matches = array();
+ foreach ($relativeRegexes as $relativeRegex) {
+ if (preg_match_all($relativeRegex, $content, $regexMatches, PREG_SET_ORDER)) {
+ $matches = array_merge($matches, $regexMatches);
+ }
+ }
+
+ $search = array();
+ $replace = array();
+
+ // loop all urls
+ foreach ($matches as $match) {
+ // determine if it's a url() or an @import match
+ $type = (strpos($match[0], '@import') === 0 ? 'import' : 'url');
+
+ $url = $match['path'];
+ if ($this->canImportByPath($url)) {
+ // attempting to interpret GET-params makes no sense, so let's discard them for awhile
+ $params = strrchr($url, '?');
+ $url = $params ? substr($url, 0, -strlen($params)) : $url;
+
+ // fix relative url
+ $url = $converter->convert($url);
+
+ // now that the path has been converted, re-apply GET-params
+ $url .= $params;
+ }
+
+ /*
+ * Urls with control characters above 0x7e should be quoted.
+ * According to Mozilla's parser, whitespace is only allowed at the
+ * end of unquoted urls.
+ * Urls with `)` (as could happen with data: uris) should also be
+ * quoted to avoid being confused for the url() closing parentheses.
+ * And urls with a # have also been reported to cause issues.
+ * Urls with quotes inside should also remain escaped.
+ *
+ * @see https://developer.mozilla.org/nl/docs/Web/CSS/url#The_url()_functional_notation
+ * @see https://hg.mozilla.org/mozilla-central/rev/14abca4e7378
+ * @see https://github.com/matthiasmullie/minify/issues/193
+ */
+ $url = trim($url);
+ if (preg_match('/[\s\)\'"#\x{7f}-\x{9f}]/u', $url)) {
+ $url = $match['quotes'] . $url . $match['quotes'];
+ }
+
+ // build replacement
+ $search[] = $match[0];
+ if ($type === 'url') {
+ $replace[] = 'url('.$url.')';
+ } elseif ($type === 'import') {
+ $replace[] = '@import "'.$url.'"';
+ }
+ }
+
+ // replace urls
+ return str_replace($search, $replace, $content);
+ }
+
+ /**
+ * Shorthand hex color codes.
+ * #FF0000 -> #F00.
+ *
+ * @param string $content The CSS content to shorten the hex color codes for
+ *
+ * @return string
+ */
+ protected function shortenHex($content)
+ {
+ $content = preg_replace('/(?<=[: ])#([0-9a-z])\\1([0-9a-z])\\2([0-9a-z])\\3(?=[; }])/i', '#$1$2$3', $content);
+
+ // we can shorten some even more by replacing them with their color name
+ $colors = array(
+ '#F0FFFF' => 'azure',
+ '#F5F5DC' => 'beige',
+ '#A52A2A' => 'brown',
+ '#FF7F50' => 'coral',
+ '#FFD700' => 'gold',
+ '#808080' => 'gray',
+ '#008000' => 'green',
+ '#4B0082' => 'indigo',
+ '#FFFFF0' => 'ivory',
+ '#F0E68C' => 'khaki',
+ '#FAF0E6' => 'linen',
+ '#800000' => 'maroon',
+ '#000080' => 'navy',
+ '#808000' => 'olive',
+ '#CD853F' => 'peru',
+ '#FFC0CB' => 'pink',
+ '#DDA0DD' => 'plum',
+ '#800080' => 'purple',
+ '#F00' => 'red',
+ '#FA8072' => 'salmon',
+ '#A0522D' => 'sienna',
+ '#C0C0C0' => 'silver',
+ '#FFFAFA' => 'snow',
+ '#D2B48C' => 'tan',
+ '#FF6347' => 'tomato',
+ '#EE82EE' => 'violet',
+ '#F5DEB3' => 'wheat',
+ );
+
+ return preg_replace_callback(
+ '/(?<=[: ])('.implode(array_keys($colors), '|').')(?=[; }])/i',
+ function ($match) use ($colors) {
+ return $colors[strtoupper($match[0])];
+ },
+ $content
+ );
+ }
+
+ /**
+ * Shorten CSS font weights.
+ *
+ * @param string $content The CSS content to shorten the font weights for
+ *
+ * @return string
+ */
+ protected function shortenFontWeights($content)
+ {
+ $weights = array(
+ 'normal' => 400,
+ 'bold' => 700,
+ );
+
+ $callback = function ($match) use ($weights) {
+ return $match[1].$weights[$match[2]];
+ };
+
+ return preg_replace_callback('/(font-weight\s*:\s*)('.implode('|', array_keys($weights)).')(?=[;}])/', $callback, $content);
+ }
+
+ /**
+ * Shorthand 0 values to plain 0, instead of e.g. -0em.
+ *
+ * @param string $content The CSS content to shorten the zero values for
+ *
+ * @return string
+ */
+ protected function shortenZeroes($content)
+ {
+ // we don't want to strip units in `calc()` expressions:
+ // `5px - 0px` is valid, but `5px - 0` is not
+ // `10px * 0` is valid (equates to 0), and so is `10 * 0px`, but
+ // `10 * 0` is invalid
+ // best to just leave `calc()`s alone, even if they could be optimized
+ // (which is a whole other undertaking, where units & order of
+ // operations all need to be considered...)
+ $calcs = $this->findCalcs($content);
+ $content = str_replace($calcs, array_keys($calcs), $content);
+
+ // reusable bits of code throughout these regexes:
+ // before & after are used to make sure we don't match lose unintended
+ // 0-like values (e.g. in #000, or in http://url/1.0)
+ // units can be stripped from 0 values, or used to recognize non 0
+ // values (where wa may be able to strip a .0 suffix)
+ $before = '(?<=[:(, ])';
+ $after = '(?=[ ,);}])';
+ $units = '(em|ex|%|px|cm|mm|in|pt|pc|ch|rem|vh|vw|vmin|vmax|vm)';
+
+ // strip units after zeroes (0px -> 0)
+ // NOTE: it should be safe to remove all units for a 0 value, but in
+ // practice, Webkit (especially Safari) seems to stumble over at least
+ // 0%, potentially other units as well. Only stripping 'px' for now.
+ // @see https://github.com/matthiasmullie/minify/issues/60
+ $content = preg_replace('/'.$before.'(-?0*(\.0+)?)(?<=0)px'.$after.'/', '\\1', $content);
+
+ // strip 0-digits (.0 -> 0)
+ $content = preg_replace('/'.$before.'\.0+'.$units.'?'.$after.'/', '0\\1', $content);
+ // strip trailing 0: 50.10 -> 50.1, 50.10px -> 50.1px
+ $content = preg_replace('/'.$before.'(-?[0-9]+\.[0-9]+)0+'.$units.'?'.$after.'/', '\\1\\2', $content);
+ // strip trailing 0: 50.00 -> 50, 50.00px -> 50px
+ $content = preg_replace('/'.$before.'(-?[0-9]+)\.0+'.$units.'?'.$after.'/', '\\1\\2', $content);
+ // strip leading 0: 0.1 -> .1, 01.1 -> 1.1
+ $content = preg_replace('/'.$before.'(-?)0+([0-9]*\.[0-9]+)'.$units.'?'.$after.'/', '\\1\\2\\3', $content);
+
+ // strip negative zeroes (-0 -> 0) & truncate zeroes (00 -> 0)
+ $content = preg_replace('/'.$before.'-?0+'.$units.'?'.$after.'/', '0\\1', $content);
+
+ // IE doesn't seem to understand a unitless flex-basis value (correct -
+ // it goes against the spec), so let's add it in again (make it `%`,
+ // which is only 1 char: 0%, 0px, 0 anything, it's all just the same)
+ // @see https://developer.mozilla.org/nl/docs/Web/CSS/flex
+ $content = preg_replace('/flex:([0-9]+\s[0-9]+\s)0([;\}])/', 'flex:${1}0%${2}', $content);
+ $content = preg_replace('/flex-basis:0([;\}])/', 'flex-basis:0%${1}', $content);
+
+ // restore `calc()` expressions
+ $content = str_replace(array_keys($calcs), $calcs, $content);
+
+ return $content;
+ }
+
+ /**
+ * Strip empty tags from source code.
+ *
+ * @param string $content
+ *
+ * @return string
+ */
+ protected function stripEmptyTags($content)
+ {
+ $content = preg_replace('/(?<=^)[^\{\};]+\{\s*\}/', '', $content);
+ $content = preg_replace('/(?<=(\}|;))[^\{\};]+\{\s*\}/', '', $content);
+
+ return $content;
+ }
+
+ /**
+ * Strip comments from source code.
+ */
+ protected function stripComments()
+ {
+ $this->registerPattern('/\/\*.*?\*\//s', '');
+ }
+
+ /**
+ * Strip whitespace.
+ *
+ * @param string $content The CSS content to strip the whitespace for
+ *
+ * @return string
+ */
+ protected function stripWhitespace($content)
+ {
+ // remove leading & trailing whitespace
+ $content = preg_replace('/^\s*/m', '', $content);
+ $content = preg_replace('/\s*$/m', '', $content);
+
+ // replace newlines with a single space
+ $content = preg_replace('/\s+/', ' ', $content);
+
+ // remove whitespace around meta characters
+ // inspired by stackoverflow.com/questions/15195750/minify-compress-css-with-regex
+ $content = preg_replace('/\s*([\*$~^|]?+=|[{};,>~]|!important\b)\s*/', '$1', $content);
+ $content = preg_replace('/([\[(:])\s+/', '$1', $content);
+ $content = preg_replace('/\s+([\]\)])/', '$1', $content);
+ $content = preg_replace('/\s+(:)(?![^\}]*\{)/', '$1', $content);
+
+ // whitespace around + and - can only be stripped inside some pseudo-
+ // classes, like `:nth-child(3+2n)`
+ // not in things like `calc(3px + 2px)`, shorthands like `3px -2px`, or
+ // selectors like `div.weird- p`
+ $pseudos = array('nth-child', 'nth-last-child', 'nth-last-of-type', 'nth-of-type');
+ $content = preg_replace('/:('.implode('|', $pseudos).')\(\s*([+-]?)\s*(.+?)\s*([+-]?)\s*(.*?)\s*\)/', ':$1($2$3$4$5)', $content);
+
+ // remove semicolon/whitespace followed by closing bracket
+ $content = str_replace(';}', '}', $content);
+
+ return trim($content);
+ }
+
+ /**
+ * Find all `calc()` occurrences.
+ *
+ * @param string $content The CSS content to find `calc()`s in.
+ *
+ * @return string[]
+ */
+ protected function findCalcs($content)
+ {
+ $results = array();
+ preg_match_all('/calc(\(.+?)(?=$|;|calc\()/', $content, $matches, PREG_SET_ORDER);
+
+ foreach ($matches as $match) {
+ $length = strlen($match[1]);
+ $expr = '';
+ $opened = 0;
+
+ for ($i = 0; $i < $length; $i++) {
+ $char = $match[1][$i];
+ $expr .= $char;
+ if ($char === '(') {
+ $opened++;
+ } elseif ($char === ')' && --$opened === 0) {
+ break;
+ }
+ }
+
+ $results['calc('.count($results).')'] = 'calc'.$expr;
+ }
+
+ return $results;
+ }
+
+ /**
+ * Check if file is small enough to be imported.
+ *
+ * @param string $path The path to the file
+ *
+ * @return bool
+ */
+ protected function canImportBySize($path)
+ {
+ return ($size = @filesize($path)) && $size <= $this->maxImportSize * 1024;
+ }
+
+ /**
+ * Check if file a file can be imported, going by the path.
+ *
+ * @param string $path
+ *
+ * @return bool
+ */
+ protected function canImportByPath($path)
+ {
+ return preg_match('/^(data:|https?:|\\/)/', $path) === 0;
+ }
+
+ /**
+ * Return a converter to update relative paths to be relative to the new
+ * destination.
+ *
+ * @param string $source
+ * @param string $target
+ *
+ * @return ConverterInterface
+ */
+ protected function getPathConverter($source, $target)
+ {
+ return new Converter($source, $target);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/src/Exception.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/src/Exception.php
new file mode 100644
index 0000000..d03898f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/src/Exception.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Base Exception
+ *
+ * @deprecated Use Exceptions\BasicException instead
+ *
+ * @author Matthias Mullie <minify@mullie.eu>
+ */
+namespace MatthiasMullie\Minify;
+
+/**
+ * Base Exception Class
+ * @deprecated Use Exceptions\BasicException instead
+ *
+ * @package Minify
+ * @author Matthias Mullie <minify@mullie.eu>
+ */
+abstract class Exception extends \Exception
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/src/Exceptions/BasicException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/src/Exceptions/BasicException.php
new file mode 100644
index 0000000..af5e81b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/src/Exceptions/BasicException.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Basic exception
+ *
+ * Please report bugs on https://github.com/matthiasmullie/minify/issues
+ *
+ * @author Matthias Mullie <minify@mullie.eu>
+ * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
+ * @license MIT License
+ */
+namespace MatthiasMullie\Minify\Exceptions;
+
+use MatthiasMullie\Minify\Exception;
+
+/**
+ * Basic Exception Class
+ *
+ * @package Minify\Exception
+ * @author Matthias Mullie <minify@mullie.eu>
+ */
+abstract class BasicException extends Exception
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/src/Exceptions/FileImportException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/src/Exceptions/FileImportException.php
new file mode 100644
index 0000000..912a2c9
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/src/Exceptions/FileImportException.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * File Import Exception
+ *
+ * Please report bugs on https://github.com/matthiasmullie/minify/issues
+ *
+ * @author Matthias Mullie <minify@mullie.eu>
+ * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
+ * @license MIT License
+ */
+namespace MatthiasMullie\Minify\Exceptions;
+
+/**
+ * File Import Exception Class
+ *
+ * @package Minify\Exception
+ * @author Matthias Mullie <minify@mullie.eu>
+ */
+class FileImportException extends BasicException
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/src/Exceptions/IOException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/src/Exceptions/IOException.php
new file mode 100644
index 0000000..b172eb4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/src/Exceptions/IOException.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * IO Exception
+ *
+ * Please report bugs on https://github.com/matthiasmullie/minify/issues
+ *
+ * @author Matthias Mullie <minify@mullie.eu>
+ * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
+ * @license MIT License
+ */
+namespace MatthiasMullie\Minify\Exceptions;
+
+/**
+ * IO Exception Class
+ *
+ * @package Minify\Exception
+ * @author Matthias Mullie <minify@mullie.eu>
+ */
+class IOException extends BasicException
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/src/JS.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/src/JS.php
new file mode 100644
index 0000000..651d8be
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/src/JS.php
@@ -0,0 +1,598 @@
+<?php
+/**
+ * JavaScript minifier
+ *
+ * Please report bugs on https://github.com/matthiasmullie/minify/issues
+ *
+ * @author Matthias Mullie <minify@mullie.eu>
+ * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
+ * @license MIT License
+ */
+namespace MatthiasMullie\Minify;
+
+/**
+ * JavaScript Minifier Class
+ *
+ * Please report bugs on https://github.com/matthiasmullie/minify/issues
+ *
+ * @package Minify
+ * @author Matthias Mullie <minify@mullie.eu>
+ * @author Tijs Verkoyen <minify@verkoyen.eu>
+ * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
+ * @license MIT License
+ */
+class JS extends Minify
+{
+ /**
+ * Var-matching regex based on http://stackoverflow.com/a/9337047/802993.
+ *
+ * Note that regular expressions using that bit must have the PCRE_UTF8
+ * pattern modifier (/u) set.
+ *
+ * @var string
+ */
+ const REGEX_VARIABLE = '\b[$A-Z\_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\x{02c1}\x{02c6}-\x{02d1}\x{02e0}-\x{02e4}\x{02ec}\x{02ee}\x{0370}-\x{0374}\x{0376}\x{0377}\x{037a}-\x{037d}\x{0386}\x{0388}-\x{038a}\x{038c}\x{038e}-\x{03a1}\x{03a3}-\x{03f5}\x{03f7}-\x{0481}\x{048a}-\x{0527}\x{0531}-\x{0556}\x{0559}\x{0561}-\x{0587}\x{05d0}-\x{05ea}\x{05f0}-\x{05f2}\x{0620}-\x{064a}\x{066e}\x{066f}\x{0671}-\x{06d3}\x{06d5}\x{06e5}\x{06e6}\x{06ee}\x{06ef}\x{06fa}-\x{06fc}\x{06ff}\x{0710}\x{0712}-\x{072f}\x{074d}-\x{07a5}\x{07b1}\x{07ca}-\x{07ea}\x{07f4}\x{07f5}\x{07fa}\x{0800}-\x{0815}\x{081a}\x{0824}\x{0828}\x{0840}-\x{0858}\x{08a0}\x{08a2}-\x{08ac}\x{0904}-\x{0939}\x{093d}\x{0950}\x{0958}-\x{0961}\x{0971}-\x{0977}\x{0979}-\x{097f}\x{0985}-\x{098c}\x{098f}\x{0990}\x{0993}-\x{09a8}\x{09aa}-\x{09b0}\x{09b2}\x{09b6}-\x{09b9}\x{09bd}\x{09ce}\x{09dc}\x{09dd}\x{09df}-\x{09e1}\x{09f0}\x{09f1}\x{0a05}-\x{0a0a}\x{0a0f}\x{0a10}\x{0a13}-\x{0a28}\x{0a2a}-\x{0a30}\x{0a32}\x{0a33}\x{0a35}\x{0a36}\x{0a38}\x{0a39}\x{0a59}-\x{0a5c}\x{0a5e}\x{0a72}-\x{0a74}\x{0a85}-\x{0a8d}\x{0a8f}-\x{0a91}\x{0a93}-\x{0aa8}\x{0aaa}-\x{0ab0}\x{0ab2}\x{0ab3}\x{0ab5}-\x{0ab9}\x{0abd}\x{0ad0}\x{0ae0}\x{0ae1}\x{0b05}-\x{0b0c}\x{0b0f}\x{0b10}\x{0b13}-\x{0b28}\x{0b2a}-\x{0b30}\x{0b32}\x{0b33}\x{0b35}-\x{0b39}\x{0b3d}\x{0b5c}\x{0b5d}\x{0b5f}-\x{0b61}\x{0b71}\x{0b83}\x{0b85}-\x{0b8a}\x{0b8e}-\x{0b90}\x{0b92}-\x{0b95}\x{0b99}\x{0b9a}\x{0b9c}\x{0b9e}\x{0b9f}\x{0ba3}\x{0ba4}\x{0ba8}-\x{0baa}\x{0bae}-\x{0bb9}\x{0bd0}\x{0c05}-\x{0c0c}\x{0c0e}-\x{0c10}\x{0c12}-\x{0c28}\x{0c2a}-\x{0c33}\x{0c35}-\x{0c39}\x{0c3d}\x{0c58}\x{0c59}\x{0c60}\x{0c61}\x{0c85}-\x{0c8c}\x{0c8e}-\x{0c90}\x{0c92}-\x{0ca8}\x{0caa}-\x{0cb3}\x{0cb5}-\x{0cb9}\x{0cbd}\x{0cde}\x{0ce0}\x{0ce1}\x{0cf1}\x{0cf2}\x{0d05}-\x{0d0c}\x{0d0e}-\x{0d10}\x{0d12}-\x{0d3a}\x{0d3d}\x{0d4e}\x{0d60}\x{0d61}\x{0d7a}-\x{0d7f}\x{0d85}-\x{0d96}\x{0d9a}-\x{0db1}\x{0db3}-\x{0dbb}\x{0dbd}\x{0dc0}-\x{0dc6}\x{0e01}-\x{0e30}\x{0e32}\x{0e33}\x{0e40}-\x{0e46}\x{0e81}\x{0e82}\x{0e84}\x{0e87}\x{0e88}\x{0e8a}\x{0e8d}\x{0e94}-\x{0e97}\x{0e99}-\x{0e9f}\x{0ea1}-\x{0ea3}\x{0ea5}\x{0ea7}\x{0eaa}\x{0eab}\x{0ead}-\x{0eb0}\x{0eb2}\x{0eb3}\x{0ebd}\x{0ec0}-\x{0ec4}\x{0ec6}\x{0edc}-\x{0edf}\x{0f00}\x{0f40}-\x{0f47}\x{0f49}-\x{0f6c}\x{0f88}-\x{0f8c}\x{1000}-\x{102a}\x{103f}\x{1050}-\x{1055}\x{105a}-\x{105d}\x{1061}\x{1065}\x{1066}\x{106e}-\x{1070}\x{1075}-\x{1081}\x{108e}\x{10a0}-\x{10c5}\x{10c7}\x{10cd}\x{10d0}-\x{10fa}\x{10fc}-\x{1248}\x{124a}-\x{124d}\x{1250}-\x{1256}\x{1258}\x{125a}-\x{125d}\x{1260}-\x{1288}\x{128a}-\x{128d}\x{1290}-\x{12b0}\x{12b2}-\x{12b5}\x{12b8}-\x{12be}\x{12c0}\x{12c2}-\x{12c5}\x{12c8}-\x{12d6}\x{12d8}-\x{1310}\x{1312}-\x{1315}\x{1318}-\x{135a}\x{1380}-\x{138f}\x{13a0}-\x{13f4}\x{1401}-\x{166c}\x{166f}-\x{167f}\x{1681}-\x{169a}\x{16a0}-\x{16ea}\x{16ee}-\x{16f0}\x{1700}-\x{170c}\x{170e}-\x{1711}\x{1720}-\x{1731}\x{1740}-\x{1751}\x{1760}-\x{176c}\x{176e}-\x{1770}\x{1780}-\x{17b3}\x{17d7}\x{17dc}\x{1820}-\x{1877}\x{1880}-\x{18a8}\x{18aa}\x{18b0}-\x{18f5}\x{1900}-\x{191c}\x{1950}-\x{196d}\x{1970}-\x{1974}\x{1980}-\x{19ab}\x{19c1}-\x{19c7}\x{1a00}-\x{1a16}\x{1a20}-\x{1a54}\x{1aa7}\x{1b05}-\x{1b33}\x{1b45}-\x{1b4b}\x{1b83}-\x{1ba0}\x{1bae}\x{1baf}\x{1bba}-\x{1be5}\x{1c00}-\x{1c23}\x{1c4d}-\x{1c4f}\x{1c5a}-\x{1c7d}\x{1ce9}-\x{1cec}\x{1cee}-\x{1cf1}\x{1cf5}\x{1cf6}\x{1d00}-\x{1dbf}\x{1e00}-\x{1f15}\x{1f18}-\x{1f1d}\x{1f20}-\x{1f45}\x{1f48}-\x{1f4d}\x{1f50}-\x{1f57}\x{1f59}\x{1f5b}\x{1f5d}\x{1f5f}-\x{1f7d}\x{1f80}-\x{1fb4}\x{1fb6}-\x{1fbc}\x{1fbe}\x{1fc2}-\x{1fc4}\x{1fc6}-\x{1fcc}\x{1fd0}-\x{1fd3}\x{1fd6}-\x{1fdb}\x{1fe0}-\x{1fec}\x{1ff2}-\x{1ff4}\x{1ff6}-\x{1ffc}\x{2071}\x{207f}\x{2090}-\x{209c}\x{2102}\x{2107}\x{210a}-\x{2113}\x{2115}\x{2119}-\x{211d}\x{2124}\x{2126}\x{2128}\x{212a}-\x{212d}\x{212f}-\x{2139}\x{213c}-\x{213f}\x{2145}-\x{2149}\x{214e}\x{2160}-\x{2188}\x{2c00}-\x{2c2e}\x{2c30}-\x{2c5e}\x{2c60}-\x{2ce4}\x{2ceb}-\x{2cee}\x{2cf2}\x{2cf3}\x{2d00}-\x{2d25}\x{2d27}\x{2d2d}\x{2d30}-\x{2d67}\x{2d6f}\x{2d80}-\x{2d96}\x{2da0}-\x{2da6}\x{2da8}-\x{2dae}\x{2db0}-\x{2db6}\x{2db8}-\x{2dbe}\x{2dc0}-\x{2dc6}\x{2dc8}-\x{2dce}\x{2dd0}-\x{2dd6}\x{2dd8}-\x{2dde}\x{2e2f}\x{3005}-\x{3007}\x{3021}-\x{3029}\x{3031}-\x{3035}\x{3038}-\x{303c}\x{3041}-\x{3096}\x{309d}-\x{309f}\x{30a1}-\x{30fa}\x{30fc}-\x{30ff}\x{3105}-\x{312d}\x{3131}-\x{318e}\x{31a0}-\x{31ba}\x{31f0}-\x{31ff}\x{3400}-\x{4db5}\x{4e00}-\x{9fcc}\x{a000}-\x{a48c}\x{a4d0}-\x{a4fd}\x{a500}-\x{a60c}\x{a610}-\x{a61f}\x{a62a}\x{a62b}\x{a640}-\x{a66e}\x{a67f}-\x{a697}\x{a6a0}-\x{a6ef}\x{a717}-\x{a71f}\x{a722}-\x{a788}\x{a78b}-\x{a78e}\x{a790}-\x{a793}\x{a7a0}-\x{a7aa}\x{a7f8}-\x{a801}\x{a803}-\x{a805}\x{a807}-\x{a80a}\x{a80c}-\x{a822}\x{a840}-\x{a873}\x{a882}-\x{a8b3}\x{a8f2}-\x{a8f7}\x{a8fb}\x{a90a}-\x{a925}\x{a930}-\x{a946}\x{a960}-\x{a97c}\x{a984}-\x{a9b2}\x{a9cf}\x{aa00}-\x{aa28}\x{aa40}-\x{aa42}\x{aa44}-\x{aa4b}\x{aa60}-\x{aa76}\x{aa7a}\x{aa80}-\x{aaaf}\x{aab1}\x{aab5}\x{aab6}\x{aab9}-\x{aabd}\x{aac0}\x{aac2}\x{aadb}-\x{aadd}\x{aae0}-\x{aaea}\x{aaf2}-\x{aaf4}\x{ab01}-\x{ab06}\x{ab09}-\x{ab0e}\x{ab11}-\x{ab16}\x{ab20}-\x{ab26}\x{ab28}-\x{ab2e}\x{abc0}-\x{abe2}\x{ac00}-\x{d7a3}\x{d7b0}-\x{d7c6}\x{d7cb}-\x{d7fb}\x{f900}-\x{fa6d}\x{fa70}-\x{fad9}\x{fb00}-\x{fb06}\x{fb13}-\x{fb17}\x{fb1d}\x{fb1f}-\x{fb28}\x{fb2a}-\x{fb36}\x{fb38}-\x{fb3c}\x{fb3e}\x{fb40}\x{fb41}\x{fb43}\x{fb44}\x{fb46}-\x{fbb1}\x{fbd3}-\x{fd3d}\x{fd50}-\x{fd8f}\x{fd92}-\x{fdc7}\x{fdf0}-\x{fdfb}\x{fe70}-\x{fe74}\x{fe76}-\x{fefc}\x{ff21}-\x{ff3a}\x{ff41}-\x{ff5a}\x{ff66}-\x{ffbe}\x{ffc2}-\x{ffc7}\x{ffca}-\x{ffcf}\x{ffd2}-\x{ffd7}\x{ffda}-\x{ffdc}][$A-Z\_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\x{02c1}\x{02c6}-\x{02d1}\x{02e0}-\x{02e4}\x{02ec}\x{02ee}\x{0370}-\x{0374}\x{0376}\x{0377}\x{037a}-\x{037d}\x{0386}\x{0388}-\x{038a}\x{038c}\x{038e}-\x{03a1}\x{03a3}-\x{03f5}\x{03f7}-\x{0481}\x{048a}-\x{0527}\x{0531}-\x{0556}\x{0559}\x{0561}-\x{0587}\x{05d0}-\x{05ea}\x{05f0}-\x{05f2}\x{0620}-\x{064a}\x{066e}\x{066f}\x{0671}-\x{06d3}\x{06d5}\x{06e5}\x{06e6}\x{06ee}\x{06ef}\x{06fa}-\x{06fc}\x{06ff}\x{0710}\x{0712}-\x{072f}\x{074d}-\x{07a5}\x{07b1}\x{07ca}-\x{07ea}\x{07f4}\x{07f5}\x{07fa}\x{0800}-\x{0815}\x{081a}\x{0824}\x{0828}\x{0840}-\x{0858}\x{08a0}\x{08a2}-\x{08ac}\x{0904}-\x{0939}\x{093d}\x{0950}\x{0958}-\x{0961}\x{0971}-\x{0977}\x{0979}-\x{097f}\x{0985}-\x{098c}\x{098f}\x{0990}\x{0993}-\x{09a8}\x{09aa}-\x{09b0}\x{09b2}\x{09b6}-\x{09b9}\x{09bd}\x{09ce}\x{09dc}\x{09dd}\x{09df}-\x{09e1}\x{09f0}\x{09f1}\x{0a05}-\x{0a0a}\x{0a0f}\x{0a10}\x{0a13}-\x{0a28}\x{0a2a}-\x{0a30}\x{0a32}\x{0a33}\x{0a35}\x{0a36}\x{0a38}\x{0a39}\x{0a59}-\x{0a5c}\x{0a5e}\x{0a72}-\x{0a74}\x{0a85}-\x{0a8d}\x{0a8f}-\x{0a91}\x{0a93}-\x{0aa8}\x{0aaa}-\x{0ab0}\x{0ab2}\x{0ab3}\x{0ab5}-\x{0ab9}\x{0abd}\x{0ad0}\x{0ae0}\x{0ae1}\x{0b05}-\x{0b0c}\x{0b0f}\x{0b10}\x{0b13}-\x{0b28}\x{0b2a}-\x{0b30}\x{0b32}\x{0b33}\x{0b35}-\x{0b39}\x{0b3d}\x{0b5c}\x{0b5d}\x{0b5f}-\x{0b61}\x{0b71}\x{0b83}\x{0b85}-\x{0b8a}\x{0b8e}-\x{0b90}\x{0b92}-\x{0b95}\x{0b99}\x{0b9a}\x{0b9c}\x{0b9e}\x{0b9f}\x{0ba3}\x{0ba4}\x{0ba8}-\x{0baa}\x{0bae}-\x{0bb9}\x{0bd0}\x{0c05}-\x{0c0c}\x{0c0e}-\x{0c10}\x{0c12}-\x{0c28}\x{0c2a}-\x{0c33}\x{0c35}-\x{0c39}\x{0c3d}\x{0c58}\x{0c59}\x{0c60}\x{0c61}\x{0c85}-\x{0c8c}\x{0c8e}-\x{0c90}\x{0c92}-\x{0ca8}\x{0caa}-\x{0cb3}\x{0cb5}-\x{0cb9}\x{0cbd}\x{0cde}\x{0ce0}\x{0ce1}\x{0cf1}\x{0cf2}\x{0d05}-\x{0d0c}\x{0d0e}-\x{0d10}\x{0d12}-\x{0d3a}\x{0d3d}\x{0d4e}\x{0d60}\x{0d61}\x{0d7a}-\x{0d7f}\x{0d85}-\x{0d96}\x{0d9a}-\x{0db1}\x{0db3}-\x{0dbb}\x{0dbd}\x{0dc0}-\x{0dc6}\x{0e01}-\x{0e30}\x{0e32}\x{0e33}\x{0e40}-\x{0e46}\x{0e81}\x{0e82}\x{0e84}\x{0e87}\x{0e88}\x{0e8a}\x{0e8d}\x{0e94}-\x{0e97}\x{0e99}-\x{0e9f}\x{0ea1}-\x{0ea3}\x{0ea5}\x{0ea7}\x{0eaa}\x{0eab}\x{0ead}-\x{0eb0}\x{0eb2}\x{0eb3}\x{0ebd}\x{0ec0}-\x{0ec4}\x{0ec6}\x{0edc}-\x{0edf}\x{0f00}\x{0f40}-\x{0f47}\x{0f49}-\x{0f6c}\x{0f88}-\x{0f8c}\x{1000}-\x{102a}\x{103f}\x{1050}-\x{1055}\x{105a}-\x{105d}\x{1061}\x{1065}\x{1066}\x{106e}-\x{1070}\x{1075}-\x{1081}\x{108e}\x{10a0}-\x{10c5}\x{10c7}\x{10cd}\x{10d0}-\x{10fa}\x{10fc}-\x{1248}\x{124a}-\x{124d}\x{1250}-\x{1256}\x{1258}\x{125a}-\x{125d}\x{1260}-\x{1288}\x{128a}-\x{128d}\x{1290}-\x{12b0}\x{12b2}-\x{12b5}\x{12b8}-\x{12be}\x{12c0}\x{12c2}-\x{12c5}\x{12c8}-\x{12d6}\x{12d8}-\x{1310}\x{1312}-\x{1315}\x{1318}-\x{135a}\x{1380}-\x{138f}\x{13a0}-\x{13f4}\x{1401}-\x{166c}\x{166f}-\x{167f}\x{1681}-\x{169a}\x{16a0}-\x{16ea}\x{16ee}-\x{16f0}\x{1700}-\x{170c}\x{170e}-\x{1711}\x{1720}-\x{1731}\x{1740}-\x{1751}\x{1760}-\x{176c}\x{176e}-\x{1770}\x{1780}-\x{17b3}\x{17d7}\x{17dc}\x{1820}-\x{1877}\x{1880}-\x{18a8}\x{18aa}\x{18b0}-\x{18f5}\x{1900}-\x{191c}\x{1950}-\x{196d}\x{1970}-\x{1974}\x{1980}-\x{19ab}\x{19c1}-\x{19c7}\x{1a00}-\x{1a16}\x{1a20}-\x{1a54}\x{1aa7}\x{1b05}-\x{1b33}\x{1b45}-\x{1b4b}\x{1b83}-\x{1ba0}\x{1bae}\x{1baf}\x{1bba}-\x{1be5}\x{1c00}-\x{1c23}\x{1c4d}-\x{1c4f}\x{1c5a}-\x{1c7d}\x{1ce9}-\x{1cec}\x{1cee}-\x{1cf1}\x{1cf5}\x{1cf6}\x{1d00}-\x{1dbf}\x{1e00}-\x{1f15}\x{1f18}-\x{1f1d}\x{1f20}-\x{1f45}\x{1f48}-\x{1f4d}\x{1f50}-\x{1f57}\x{1f59}\x{1f5b}\x{1f5d}\x{1f5f}-\x{1f7d}\x{1f80}-\x{1fb4}\x{1fb6}-\x{1fbc}\x{1fbe}\x{1fc2}-\x{1fc4}\x{1fc6}-\x{1fcc}\x{1fd0}-\x{1fd3}\x{1fd6}-\x{1fdb}\x{1fe0}-\x{1fec}\x{1ff2}-\x{1ff4}\x{1ff6}-\x{1ffc}\x{2071}\x{207f}\x{2090}-\x{209c}\x{2102}\x{2107}\x{210a}-\x{2113}\x{2115}\x{2119}-\x{211d}\x{2124}\x{2126}\x{2128}\x{212a}-\x{212d}\x{212f}-\x{2139}\x{213c}-\x{213f}\x{2145}-\x{2149}\x{214e}\x{2160}-\x{2188}\x{2c00}-\x{2c2e}\x{2c30}-\x{2c5e}\x{2c60}-\x{2ce4}\x{2ceb}-\x{2cee}\x{2cf2}\x{2cf3}\x{2d00}-\x{2d25}\x{2d27}\x{2d2d}\x{2d30}-\x{2d67}\x{2d6f}\x{2d80}-\x{2d96}\x{2da0}-\x{2da6}\x{2da8}-\x{2dae}\x{2db0}-\x{2db6}\x{2db8}-\x{2dbe}\x{2dc0}-\x{2dc6}\x{2dc8}-\x{2dce}\x{2dd0}-\x{2dd6}\x{2dd8}-\x{2dde}\x{2e2f}\x{3005}-\x{3007}\x{3021}-\x{3029}\x{3031}-\x{3035}\x{3038}-\x{303c}\x{3041}-\x{3096}\x{309d}-\x{309f}\x{30a1}-\x{30fa}\x{30fc}-\x{30ff}\x{3105}-\x{312d}\x{3131}-\x{318e}\x{31a0}-\x{31ba}\x{31f0}-\x{31ff}\x{3400}-\x{4db5}\x{4e00}-\x{9fcc}\x{a000}-\x{a48c}\x{a4d0}-\x{a4fd}\x{a500}-\x{a60c}\x{a610}-\x{a61f}\x{a62a}\x{a62b}\x{a640}-\x{a66e}\x{a67f}-\x{a697}\x{a6a0}-\x{a6ef}\x{a717}-\x{a71f}\x{a722}-\x{a788}\x{a78b}-\x{a78e}\x{a790}-\x{a793}\x{a7a0}-\x{a7aa}\x{a7f8}-\x{a801}\x{a803}-\x{a805}\x{a807}-\x{a80a}\x{a80c}-\x{a822}\x{a840}-\x{a873}\x{a882}-\x{a8b3}\x{a8f2}-\x{a8f7}\x{a8fb}\x{a90a}-\x{a925}\x{a930}-\x{a946}\x{a960}-\x{a97c}\x{a984}-\x{a9b2}\x{a9cf}\x{aa00}-\x{aa28}\x{aa40}-\x{aa42}\x{aa44}-\x{aa4b}\x{aa60}-\x{aa76}\x{aa7a}\x{aa80}-\x{aaaf}\x{aab1}\x{aab5}\x{aab6}\x{aab9}-\x{aabd}\x{aac0}\x{aac2}\x{aadb}-\x{aadd}\x{aae0}-\x{aaea}\x{aaf2}-\x{aaf4}\x{ab01}-\x{ab06}\x{ab09}-\x{ab0e}\x{ab11}-\x{ab16}\x{ab20}-\x{ab26}\x{ab28}-\x{ab2e}\x{abc0}-\x{abe2}\x{ac00}-\x{d7a3}\x{d7b0}-\x{d7c6}\x{d7cb}-\x{d7fb}\x{f900}-\x{fa6d}\x{fa70}-\x{fad9}\x{fb00}-\x{fb06}\x{fb13}-\x{fb17}\x{fb1d}\x{fb1f}-\x{fb28}\x{fb2a}-\x{fb36}\x{fb38}-\x{fb3c}\x{fb3e}\x{fb40}\x{fb41}\x{fb43}\x{fb44}\x{fb46}-\x{fbb1}\x{fbd3}-\x{fd3d}\x{fd50}-\x{fd8f}\x{fd92}-\x{fdc7}\x{fdf0}-\x{fdfb}\x{fe70}-\x{fe74}\x{fe76}-\x{fefc}\x{ff21}-\x{ff3a}\x{ff41}-\x{ff5a}\x{ff66}-\x{ffbe}\x{ffc2}-\x{ffc7}\x{ffca}-\x{ffcf}\x{ffd2}-\x{ffd7}\x{ffda}-\x{ffdc}0-9\x{0300}-\x{036f}\x{0483}-\x{0487}\x{0591}-\x{05bd}\x{05bf}\x{05c1}\x{05c2}\x{05c4}\x{05c5}\x{05c7}\x{0610}-\x{061a}\x{064b}-\x{0669}\x{0670}\x{06d6}-\x{06dc}\x{06df}-\x{06e4}\x{06e7}\x{06e8}\x{06ea}-\x{06ed}\x{06f0}-\x{06f9}\x{0711}\x{0730}-\x{074a}\x{07a6}-\x{07b0}\x{07c0}-\x{07c9}\x{07eb}-\x{07f3}\x{0816}-\x{0819}\x{081b}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082d}\x{0859}-\x{085b}\x{08e4}-\x{08fe}\x{0900}-\x{0903}\x{093a}-\x{093c}\x{093e}-\x{094f}\x{0951}-\x{0957}\x{0962}\x{0963}\x{0966}-\x{096f}\x{0981}-\x{0983}\x{09bc}\x{09be}-\x{09c4}\x{09c7}\x{09c8}\x{09cb}-\x{09cd}\x{09d7}\x{09e2}\x{09e3}\x{09e6}-\x{09ef}\x{0a01}-\x{0a03}\x{0a3c}\x{0a3e}-\x{0a42}\x{0a47}\x{0a48}\x{0a4b}-\x{0a4d}\x{0a51}\x{0a66}-\x{0a71}\x{0a75}\x{0a81}-\x{0a83}\x{0abc}\x{0abe}-\x{0ac5}\x{0ac7}-\x{0ac9}\x{0acb}-\x{0acd}\x{0ae2}\x{0ae3}\x{0ae6}-\x{0aef}\x{0b01}-\x{0b03}\x{0b3c}\x{0b3e}-\x{0b44}\x{0b47}\x{0b48}\x{0b4b}-\x{0b4d}\x{0b56}\x{0b57}\x{0b62}\x{0b63}\x{0b66}-\x{0b6f}\x{0b82}\x{0bbe}-\x{0bc2}\x{0bc6}-\x{0bc8}\x{0bca}-\x{0bcd}\x{0bd7}\x{0be6}-\x{0bef}\x{0c01}-\x{0c03}\x{0c3e}-\x{0c44}\x{0c46}-\x{0c48}\x{0c4a}-\x{0c4d}\x{0c55}\x{0c56}\x{0c62}\x{0c63}\x{0c66}-\x{0c6f}\x{0c82}\x{0c83}\x{0cbc}\x{0cbe}-\x{0cc4}\x{0cc6}-\x{0cc8}\x{0cca}-\x{0ccd}\x{0cd5}\x{0cd6}\x{0ce2}\x{0ce3}\x{0ce6}-\x{0cef}\x{0d02}\x{0d03}\x{0d3e}-\x{0d44}\x{0d46}-\x{0d48}\x{0d4a}-\x{0d4d}\x{0d57}\x{0d62}\x{0d63}\x{0d66}-\x{0d6f}\x{0d82}\x{0d83}\x{0dca}\x{0dcf}-\x{0dd4}\x{0dd6}\x{0dd8}-\x{0ddf}\x{0df2}\x{0df3}\x{0e31}\x{0e34}-\x{0e3a}\x{0e47}-\x{0e4e}\x{0e50}-\x{0e59}\x{0eb1}\x{0eb4}-\x{0eb9}\x{0ebb}\x{0ebc}\x{0ec8}-\x{0ecd}\x{0ed0}-\x{0ed9}\x{0f18}\x{0f19}\x{0f20}-\x{0f29}\x{0f35}\x{0f37}\x{0f39}\x{0f3e}\x{0f3f}\x{0f71}-\x{0f84}\x{0f86}\x{0f87}\x{0f8d}-\x{0f97}\x{0f99}-\x{0fbc}\x{0fc6}\x{102b}-\x{103e}\x{1040}-\x{1049}\x{1056}-\x{1059}\x{105e}-\x{1060}\x{1062}-\x{1064}\x{1067}-\x{106d}\x{1071}-\x{1074}\x{1082}-\x{108d}\x{108f}-\x{109d}\x{135d}-\x{135f}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}\x{1753}\x{1772}\x{1773}\x{17b4}-\x{17d3}\x{17dd}\x{17e0}-\x{17e9}\x{180b}-\x{180d}\x{1810}-\x{1819}\x{18a9}\x{1920}-\x{192b}\x{1930}-\x{193b}\x{1946}-\x{194f}\x{19b0}-\x{19c0}\x{19c8}\x{19c9}\x{19d0}-\x{19d9}\x{1a17}-\x{1a1b}\x{1a55}-\x{1a5e}\x{1a60}-\x{1a7c}\x{1a7f}-\x{1a89}\x{1a90}-\x{1a99}\x{1b00}-\x{1b04}\x{1b34}-\x{1b44}\x{1b50}-\x{1b59}\x{1b6b}-\x{1b73}\x{1b80}-\x{1b82}\x{1ba1}-\x{1bad}\x{1bb0}-\x{1bb9}\x{1be6}-\x{1bf3}\x{1c24}-\x{1c37}\x{1c40}-\x{1c49}\x{1c50}-\x{1c59}\x{1cd0}-\x{1cd2}\x{1cd4}-\x{1ce8}\x{1ced}\x{1cf2}-\x{1cf4}\x{1dc0}-\x{1de6}\x{1dfc}-\x{1dff}\x{200c}\x{200d}\x{203f}\x{2040}\x{2054}\x{20d0}-\x{20dc}\x{20e1}\x{20e5}-\x{20f0}\x{2cef}-\x{2cf1}\x{2d7f}\x{2de0}-\x{2dff}\x{302a}-\x{302f}\x{3099}\x{309a}\x{a620}-\x{a629}\x{a66f}\x{a674}-\x{a67d}\x{a69f}\x{a6f0}\x{a6f1}\x{a802}\x{a806}\x{a80b}\x{a823}-\x{a827}\x{a880}\x{a881}\x{a8b4}-\x{a8c4}\x{a8d0}-\x{a8d9}\x{a8e0}-\x{a8f1}\x{a900}-\x{a909}\x{a926}-\x{a92d}\x{a947}-\x{a953}\x{a980}-\x{a983}\x{a9b3}-\x{a9c0}\x{a9d0}-\x{a9d9}\x{aa29}-\x{aa36}\x{aa43}\x{aa4c}\x{aa4d}\x{aa50}-\x{aa59}\x{aa7b}\x{aab0}\x{aab2}-\x{aab4}\x{aab7}\x{aab8}\x{aabe}\x{aabf}\x{aac1}\x{aaeb}-\x{aaef}\x{aaf5}\x{aaf6}\x{abe3}-\x{abea}\x{abec}\x{abed}\x{abf0}-\x{abf9}\x{fb1e}\x{fe00}-\x{fe0f}\x{fe20}-\x{fe26}\x{fe33}\x{fe34}\x{fe4d}-\x{fe4f}\x{ff10}-\x{ff19}\x{ff3f}]*\b';
+
+ /**
+ * Full list of JavaScript reserved words.
+ * Will be loaded from /data/js/keywords_reserved.txt.
+ *
+ * @see https://mathiasbynens.be/notes/reserved-keywords
+ *
+ * @var string[]
+ */
+ protected $keywordsReserved = array();
+
+ /**
+ * List of JavaScript reserved words that accept a <variable, value, ...>
+ * after them. Some end of lines are not the end of a statement, like with
+ * these keywords.
+ *
+ * E.g.: we shouldn't insert a ; after this else
+ * else
+ * console.log('this is quite fine')
+ *
+ * Will be loaded from /data/js/keywords_before.txt
+ *
+ * @var string[]
+ */
+ protected $keywordsBefore = array();
+
+ /**
+ * List of JavaScript reserved words that accept a <variable, value, ...>
+ * before them. Some end of lines are not the end of a statement, like when
+ * continued by one of these keywords on the newline.
+ *
+ * E.g.: we shouldn't insert a ; before this instanceof
+ * variable
+ * instanceof String
+ *
+ * Will be loaded from /data/js/keywords_after.txt
+ *
+ * @var string[]
+ */
+ protected $keywordsAfter = array();
+
+ /**
+ * List of all JavaScript operators.
+ *
+ * Will be loaded from /data/js/operators.txt
+ *
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators
+ *
+ * @var string[]
+ */
+ protected $operators = array();
+
+ /**
+ * List of JavaScript operators that accept a <variable, value, ...> after
+ * them. Some end of lines are not the end of a statement, like with these
+ * operators.
+ *
+ * Note: Most operators are fine, we've only removed ++ and --.
+ * ++ & -- have to be joined with the value they're in-/decrementing.
+ *
+ * Will be loaded from /data/js/operators_before.txt
+ *
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators
+ *
+ * @var string[]
+ */
+ protected $operatorsBefore = array();
+
+ /**
+ * List of JavaScript operators that accept a <variable, value, ...> before
+ * them. Some end of lines are not the end of a statement, like when
+ * continued by one of these operators on the newline.
+ *
+ * Note: Most operators are fine, we've only removed ), ], ++, --, ! and ~.
+ * There can't be a newline separating ! or ~ and whatever it is negating.
+ * ++ & -- have to be joined with the value they're in-/decrementing.
+ * ) & ] are "special" in that they have lots or usecases. () for example
+ * is used for function calls, for grouping, in if () and for (), ...
+ *
+ * Will be loaded from /data/js/operators_after.txt
+ *
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators
+ *
+ * @var string[]
+ */
+ protected $operatorsAfter = array();
+
+ /**
+ * {@inheritdoc}
+ */
+ public function __construct()
+ {
+ call_user_func_array(array('parent', '__construct'), func_get_args());
+
+ $dataDir = __DIR__.'/../data/js/';
+ $options = FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES;
+ $this->keywordsReserved = file($dataDir.'keywords_reserved.txt', $options);
+ $this->keywordsBefore = file($dataDir.'keywords_before.txt', $options);
+ $this->keywordsAfter = file($dataDir.'keywords_after.txt', $options);
+ $this->operators = file($dataDir.'operators.txt', $options);
+ $this->operatorsBefore = file($dataDir.'operators_before.txt', $options);
+ $this->operatorsAfter = file($dataDir.'operators_after.txt', $options);
+ }
+
+ /**
+ * Minify the data.
+ * Perform JS optimizations.
+ *
+ * @param string[optional] $path Path to write the data to
+ *
+ * @return string The minified data
+ */
+ public function execute($path = null)
+ {
+ $content = '';
+
+ /*
+ * Let's first take out strings, comments and regular expressions.
+ * All of these can contain JS code-like characters, and we should make
+ * sure any further magic ignores anything inside of these.
+ *
+ * Consider this example, where we should not strip any whitespace:
+ * var str = "a test";
+ *
+ * Comments will be removed altogether, strings and regular expressions
+ * will be replaced by placeholder text, which we'll restore later.
+ */
+ $this->extractStrings('\'"`');
+ $this->stripComments();
+ $this->extractRegex();
+
+ // loop files
+ foreach ($this->data as $source => $js) {
+ // take out strings, comments & regex (for which we've registered
+ // the regexes just a few lines earlier)
+ $js = $this->replace($js);
+
+ $js = $this->propertyNotation($js);
+ $js = $this->shortenBools($js);
+ $js = $this->stripWhitespace($js);
+
+ // combine js: separating the scripts by a ;
+ $content .= $js.";";
+ }
+
+ // clean up leftover `;`s from the combination of multiple scripts
+ $content = ltrim($content, ';');
+ $content = (string) substr($content, 0, -1);
+
+ /*
+ * Earlier, we extracted strings & regular expressions and replaced them
+ * with placeholder text. This will restore them.
+ */
+ $content = $this->restoreExtractedData($content);
+
+ return $content;
+ }
+
+ /**
+ * Strip comments from source code.
+ */
+ protected function stripComments()
+ {
+ // single-line comments
+ $this->registerPattern('/\/\/.*$/m', '');
+
+ // multi-line comments
+ $this->registerPattern('/\/\*.*?\*\//s', '');
+ }
+
+ /**
+ * JS can have /-delimited regular expressions, like: /ab+c/.match(string).
+ *
+ * The content inside the regex can contain characters that may be confused
+ * for JS code: e.g. it could contain whitespace it needs to match & we
+ * don't want to strip whitespace in there.
+ *
+ * The regex can be pretty simple: we don't have to care about comments,
+ * (which also use slashes) because stripComments() will have stripped those
+ * already.
+ *
+ * This method will replace all string content with simple REGEX#
+ * placeholder text, so we've rid all regular expressions from characters
+ * that may be misinterpreted. Original regex content will be saved in
+ * $this->extracted and after doing all other minifying, we can restore the
+ * original content via restoreRegex()
+ */
+ protected function extractRegex()
+ {
+ // PHP only supports $this inside anonymous functions since 5.4
+ $minifier = $this;
+ $callback = function ($match) use ($minifier) {
+ $count = count($minifier->extracted);
+ $placeholder = '"'.$count.'"';
+ $minifier->extracted[$placeholder] = $match[0];
+
+ return $placeholder;
+ };
+
+ // match all chars except `/` and `\`
+ // `\` is allowed though, along with whatever char follows (which is the
+ // one being escaped)
+ // this should allow all chars, except for an unescaped `/` (= the one
+ // closing the regex)
+ // then also ignore bare `/` inside `[]`, where they don't need to be
+ // escaped: anything inside `[]` can be ignored safely
+ $pattern = '\\/(?:[^\\[\\/\\\\\n\r]+|(?:\\\\.)+|(?:\\[(?:[^\\]\\\\\n\r]+|(?:\\\\.)+)+\\])+)++\\/[gimy]*';
+
+ // a regular expression can only be followed by a few operators or some
+ // of the RegExp methods (a `\` followed by a variable or value is
+ // likely part of a division, not a regex)
+ $keywords = array('do', 'in', 'new', 'else', 'throw', 'yield', 'delete', 'return', 'typeof');
+ $before = '([=:,;\+\-\*\/\}\(\{\[&\|!]|^|'.implode('|', $keywords).')\s*';
+ $propertiesAndMethods = array(
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#Properties_2
+ 'constructor',
+ 'flags',
+ 'global',
+ 'ignoreCase',
+ 'multiline',
+ 'source',
+ 'sticky',
+ 'unicode',
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#Methods_2
+ 'compile(',
+ 'exec(',
+ 'test(',
+ 'toSource(',
+ 'toString(',
+ );
+ $delimiters = array_fill(0, count($propertiesAndMethods), '/');
+ $propertiesAndMethods = array_map('preg_quote', $propertiesAndMethods, $delimiters);
+ $after = '(?=\s*[\.,;\)\}&\|+]|\/\/|$|\.('.implode('|', $propertiesAndMethods).'))';
+ $this->registerPattern('/'.$before.'\K'.$pattern.$after.'/', $callback);
+
+ // regular expressions following a `)` are rather annoying to detect...
+ // quite often, `/` after `)` is a division operator & if it happens to
+ // be followed by another one (or a comment), it is likely to be
+ // confused for a regular expression
+ // however, it's perfectly possible for a regex to follow a `)`: after
+ // a single-line `if()`, `while()`, ... statement, for example
+ // since, when they occur like that, they're always the start of a
+ // statement, there's only a limited amount of ways they can be useful:
+ // by calling the regex methods directly
+ // if a regex following `)` is not followed by `.<property or method>`,
+ // it's quite likely not a regex
+ $before = '\)\s*';
+ $after = '(?=\s*\.('.implode('|', $propertiesAndMethods).'))';
+ $this->registerPattern('/'.$before.'\K'.$pattern.$after.'/', $callback);
+
+ // 1 more edge case: a regex can be followed by a lot more operators or
+ // keywords if there's a newline (ASI) in between, where the operator
+ // actually starts a new statement
+ // (https://github.com/matthiasmullie/minify/issues/56)
+ $operators = $this->getOperatorsForRegex($this->operatorsBefore, '/');
+ $operators += $this->getOperatorsForRegex($this->keywordsReserved, '/');
+ $after = '(?=\s*\n\s*('.implode('|', $operators).'))';
+ $this->registerPattern('/'.$pattern.$after.'/', $callback);
+ }
+
+ /**
+ * Strip whitespace.
+ *
+ * We won't strip *all* whitespace, but as much as possible. The thing that
+ * we'll preserve are newlines we're unsure about.
+ * JavaScript doesn't require statements to be terminated with a semicolon.
+ * It will automatically fix missing semicolons with ASI (automatic semi-
+ * colon insertion) at the end of line causing errors (without semicolon.)
+ *
+ * Because it's sometimes hard to tell if a newline is part of a statement
+ * that should be terminated or not, we'll just leave some of them alone.
+ *
+ * @param string $content The content to strip the whitespace for
+ *
+ * @return string
+ */
+ protected function stripWhitespace($content)
+ {
+ // uniform line endings, make them all line feed
+ $content = str_replace(array("\r\n", "\r"), "\n", $content);
+
+ // collapse all non-line feed whitespace into a single space
+ $content = preg_replace('/[^\S\n]+/', ' ', $content);
+
+ // strip leading & trailing whitespace
+ $content = str_replace(array(" \n", "\n "), "\n", $content);
+
+ // collapse consecutive line feeds into just 1
+ $content = preg_replace('/\n+/', "\n", $content);
+
+ $operatorsBefore = $this->getOperatorsForRegex($this->operatorsBefore, '/');
+ $operatorsAfter = $this->getOperatorsForRegex($this->operatorsAfter, '/');
+ $operators = $this->getOperatorsForRegex($this->operators, '/');
+ $keywordsBefore = $this->getKeywordsForRegex($this->keywordsBefore, '/');
+ $keywordsAfter = $this->getKeywordsForRegex($this->keywordsAfter, '/');
+
+ // strip whitespace that ends in (or next line begin with) an operator
+ // that allows statements to be broken up over multiple lines
+ unset($operatorsBefore['+'], $operatorsBefore['-'], $operatorsAfter['+'], $operatorsAfter['-']);
+ $content = preg_replace(
+ array(
+ '/('.implode('|', $operatorsBefore).')\s+/',
+ '/\s+('.implode('|', $operatorsAfter).')/',
+ ), '\\1', $content
+ );
+
+ // make sure + and - can't be mistaken for, or joined into ++ and --
+ $content = preg_replace(
+ array(
+ '/(?<![\+\-])\s*([\+\-])(?![\+\-])/',
+ '/(?<![\+\-])([\+\-])\s*(?![\+\-])/',
+ ), '\\1', $content
+ );
+
+ // collapse whitespace around reserved words into single space
+ $content = preg_replace('/(^|[;\}\s])\K('.implode('|', $keywordsBefore).')\s+/', '\\2 ', $content);
+ $content = preg_replace('/\s+('.implode('|', $keywordsAfter).')(?=([;\{\s]|$))/', ' \\1', $content);
+
+ /*
+ * We didn't strip whitespace after a couple of operators because they
+ * could be used in different contexts and we can't be sure it's ok to
+ * strip the newlines. However, we can safely strip any non-line feed
+ * whitespace that follows them.
+ */
+ $operatorsDiffBefore = array_diff($operators, $operatorsBefore);
+ $operatorsDiffAfter = array_diff($operators, $operatorsAfter);
+ $content = preg_replace('/('.implode('|', $operatorsDiffBefore).')[^\S\n]+/', '\\1', $content);
+ $content = preg_replace('/[^\S\n]+('.implode('|', $operatorsDiffAfter).')/', '\\1', $content);
+
+ /*
+ * Whitespace after `return` can be omitted in a few occasions
+ * (such as when followed by a string or regex)
+ * Same for whitespace in between `)` and `{`, or between `{` and some
+ * keywords.
+ */
+ $content = preg_replace('/\breturn\s+(["\'\/\+\-])/', 'return$1', $content);
+ $content = preg_replace('/\)\s+\{/', '){', $content);
+ $content = preg_replace('/}\n(else|catch|finally)\b/', '}$1', $content);
+
+ /*
+ * Get rid of double semicolons, except where they can be used like:
+ * "for(v=1,_=b;;)", "for(v=1;;v++)" or "for(;;ja||(ja=true))".
+ * I'll safeguard these double semicolons inside for-loops by
+ * temporarily replacing them with an invalid condition: they won't have
+ * a double semicolon and will be easy to spot to restore afterwards.
+ */
+ $content = preg_replace('/\bfor\(([^;]*);;([^;]*)\)/', 'for(\\1;-;\\2)', $content);
+ $content = preg_replace('/;+/', ';', $content);
+ $content = preg_replace('/\bfor\(([^;]*);-;([^;]*)\)/', 'for(\\1;;\\2)', $content);
+
+ /*
+ * Next, we'll be removing all semicolons where ASI kicks in.
+ * for-loops however, can have an empty body (ending in only a
+ * semicolon), like: `for(i=1;i<3;i++);`, of `for(i in list);`
+ * Here, nothing happens during the loop; it's just used to keep
+ * increasing `i`. With that ; omitted, the next line would be expected
+ * to be the for-loop's body... Same goes for while loops.
+ * I'm going to double that semicolon (if any) so after the next line,
+ * which strips semicolons here & there, we're still left with this one.
+ */
+ $content = preg_replace('/(for\([^;\{]*;[^;\{]*;[^;\{]*\));(\}|$)/s', '\\1;;\\2', $content);
+ $content = preg_replace('/(for\([^;\{]+\s+in\s+[^;\{]+\));(\}|$)/s', '\\1;;\\2', $content);
+ /*
+ * Below will also keep `;` after a `do{}while();` along with `while();`
+ * While these could be stripped after do-while, detecting this
+ * distinction is cumbersome, so I'll play it safe and make sure `;`
+ * after any kind of `while` is kept.
+ */
+ $content = preg_replace('/(while\([^;\{]+\));(\}|$)/s', '\\1;;\\2', $content);
+
+ /*
+ * We also can't strip empty else-statements. Even though they're
+ * useless and probably shouldn't be in the code in the first place, we
+ * shouldn't be stripping the `;` that follows it as it breaks the code.
+ * We can just remove those useless else-statements completely.
+ *
+ * @see https://github.com/matthiasmullie/minify/issues/91
+ */
+ $content = preg_replace('/else;/s', '', $content);
+
+ /*
+ * We also don't really want to terminate statements followed by closing
+ * curly braces (which we've ignored completely up until now) or end-of-
+ * script: ASI will kick in here & we're all about minifying.
+ * Semicolons at beginning of the file don't make any sense either.
+ */
+ $content = preg_replace('/;(\}|$)/s', '\\1', $content);
+ $content = ltrim($content, ';');
+
+ // get rid of remaining whitespace af beginning/end
+ return trim($content);
+ }
+
+ /**
+ * We'll strip whitespace around certain operators with regular expressions.
+ * This will prepare the given array by escaping all characters.
+ *
+ * @param string[] $operators
+ * @param string $delimiter
+ *
+ * @return string[]
+ */
+ protected function getOperatorsForRegex(array $operators, $delimiter = '/')
+ {
+ // escape operators for use in regex
+ $delimiters = array_fill(0, count($operators), $delimiter);
+ $escaped = array_map('preg_quote', $operators, $delimiters);
+
+ $operators = array_combine($operators, $escaped);
+
+ // ignore + & - for now, they'll get special treatment
+ unset($operators['+'], $operators['-']);
+
+ // dot can not just immediately follow a number; it can be confused for
+ // decimal point, or calling a method on it, e.g. 42 .toString()
+ $operators['.'] = '(?<![0-9]\s)\.';
+
+ // don't confuse = with other assignment shortcuts (e.g. +=)
+ $chars = preg_quote('+-*\=<>%&|', $delimiter);
+ $operators['='] = '(?<!['.$chars.'])\=';
+
+ return $operators;
+ }
+
+ /**
+ * We'll strip whitespace around certain keywords with regular expressions.
+ * This will prepare the given array by escaping all characters.
+ *
+ * @param string[] $keywords
+ * @param string $delimiter
+ *
+ * @return string[]
+ */
+ protected function getKeywordsForRegex(array $keywords, $delimiter = '/')
+ {
+ // escape keywords for use in regex
+ $delimiter = array_fill(0, count($keywords), $delimiter);
+ $escaped = array_map('preg_quote', $keywords, $delimiter);
+
+ // add word boundaries
+ array_walk($keywords, function ($value) {
+ return '\b'.$value.'\b';
+ });
+
+ $keywords = array_combine($keywords, $escaped);
+
+ return $keywords;
+ }
+
+ /**
+ * Replaces all occurrences of array['key'] by array.key.
+ *
+ * @param string $content
+ *
+ * @return string
+ */
+ protected function propertyNotation($content)
+ {
+ // PHP only supports $this inside anonymous functions since 5.4
+ $minifier = $this;
+ $keywords = $this->keywordsReserved;
+ $callback = function ($match) use ($minifier, $keywords) {
+ $property = trim($minifier->extracted[$match[1]], '\'"');
+
+ /*
+ * Check if the property is a reserved keyword. In this context (as
+ * property of an object literal/array) it shouldn't matter, but IE8
+ * freaks out with "Expected identifier".
+ */
+ if (in_array($property, $keywords)) {
+ return $match[0];
+ }
+
+ /*
+ * See if the property is in a variable-like format (e.g.
+ * array['key-here'] can't be replaced by array.key-here since '-'
+ * is not a valid character there.
+ */
+ if (!preg_match('/^'.$minifier::REGEX_VARIABLE.'$/u', $property)) {
+ return $match[0];
+ }
+
+ return '.'.$property;
+ };
+
+ /*
+ * Figure out if previous character is a variable name (of the array
+ * we want to use property notation on) - this is to make sure
+ * standalone ['value'] arrays aren't confused for keys-of-an-array.
+ * We can (and only have to) check the last character, because PHP's
+ * regex implementation doesn't allow unfixed-length look-behind
+ * assertions.
+ */
+ preg_match('/(\[[^\]]+\])[^\]]*$/', static::REGEX_VARIABLE, $previousChar);
+ $previousChar = $previousChar[1];
+
+ /*
+ * Make sure word preceding the ['value'] is not a keyword, e.g.
+ * return['x']. Because -again- PHP's regex implementation doesn't allow
+ * unfixed-length look-behind assertions, I'm just going to do a lot of
+ * separate look-behind assertions, one for each keyword.
+ */
+ $keywords = $this->getKeywordsForRegex($keywords);
+ $keywords = '(?<!'.implode(')(?<!', $keywords).')';
+
+ return preg_replace_callback('/(?<='.$previousChar.'|\])'.$keywords.'\[\s*(([\'"])[0-9]+\\2)\s*\]/u', $callback, $content);
+ }
+
+ /**
+ * Replaces true & false by !0 and !1.
+ *
+ * @param string $content
+ *
+ * @return string
+ */
+ protected function shortenBools($content)
+ {
+ /*
+ * 'true' or 'false' could be used as property names (which may be
+ * followed by whitespace) - we must not replace those!
+ * Since PHP doesn't allow variable-length (to account for the
+ * whitespace) lookbehind assertions, I need to capture the leading
+ * character and check if it's a `.`
+ */
+ $callback = function ($match) {
+ if (trim($match[1]) === '.') {
+ return $match[0];
+ }
+
+ return $match[1].($match[2] === 'true' ? '!0' : '!1');
+ };
+ $content = preg_replace_callback('/(^|.\s*)\b(true|false)\b(?!:)/', $callback, $content);
+
+ // for(;;) is exactly the same as while(true), but shorter :)
+ $content = preg_replace('/\bwhile\(!0\){/', 'for(;;){', $content);
+
+ // now make sure we didn't turn any do ... while(true) into do ... for(;;)
+ preg_match_all('/\bdo\b/', $content, $dos, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
+
+ // go backward to make sure positional offsets aren't altered when $content changes
+ $dos = array_reverse($dos);
+ foreach ($dos as $do) {
+ $offsetDo = $do[0][1];
+
+ // find all `while` (now `for`) following `do`: one of those must be
+ // associated with the `do` and be turned back into `while`
+ preg_match_all('/\bfor\(;;\)/', $content, $whiles, PREG_OFFSET_CAPTURE | PREG_SET_ORDER, $offsetDo);
+ foreach ($whiles as $while) {
+ $offsetWhile = $while[0][1];
+
+ $open = substr_count($content, '{', $offsetDo, $offsetWhile - $offsetDo);
+ $close = substr_count($content, '}', $offsetDo, $offsetWhile - $offsetDo);
+ if ($open === $close) {
+ // only restore `while` if amount of `{` and `}` are the same;
+ // otherwise, that `for` isn't associated with this `do`
+ $content = substr_replace($content, 'while(!0)', $offsetWhile, strlen('for(;;)'));
+ break;
+ }
+ }
+ }
+
+ return $content;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/src/Minify.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/src/Minify.php
new file mode 100644
index 0000000..ac87292
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/minify/src/Minify.php
@@ -0,0 +1,454 @@
+<?php
+/**
+ * Abstract minifier class
+ *
+ * Please report bugs on https://github.com/matthiasmullie/minify/issues
+ *
+ * @author Matthias Mullie <minify@mullie.eu>
+ * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
+ * @license MIT License
+ */
+namespace MatthiasMullie\Minify;
+
+use MatthiasMullie\Minify\Exceptions\IOException;
+use Psr\Cache\CacheItemInterface;
+
+/**
+ * Abstract minifier class.
+ *
+ * Please report bugs on https://github.com/matthiasmullie/minify/issues
+ *
+ * @package Minify
+ * @author Matthias Mullie <minify@mullie.eu>
+ * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
+ * @license MIT License
+ */
+abstract class Minify
+{
+ /**
+ * The data to be minified.
+ *
+ * @var string[]
+ */
+ protected $data = array();
+
+ /**
+ * Array of patterns to match.
+ *
+ * @var string[]
+ */
+ protected $patterns = array();
+
+ /**
+ * This array will hold content of strings and regular expressions that have
+ * been extracted from the JS source code, so we can reliably match "code",
+ * without having to worry about potential "code-like" characters inside.
+ *
+ * @var string[]
+ */
+ public $extracted = array();
+
+ /**
+ * Init the minify class - optionally, code may be passed along already.
+ */
+ public function __construct(/* $data = null, ... */)
+ {
+ // it's possible to add the source through the constructor as well ;)
+ if (func_num_args()) {
+ call_user_func_array(array($this, 'add'), func_get_args());
+ }
+ }
+
+ /**
+ * Add a file or straight-up code to be minified.
+ *
+ * @param string|string[] $data
+ *
+ * @return static
+ */
+ public function add($data /* $data = null, ... */)
+ {
+ // bogus "usage" of parameter $data: scrutinizer warns this variable is
+ // not used (we're using func_get_args instead to support overloading),
+ // but it still needs to be defined because it makes no sense to have
+ // this function without argument :)
+ $args = array($data) + func_get_args();
+
+ // this method can be overloaded
+ foreach ($args as $data) {
+ if (is_array($data)) {
+ call_user_func_array(array($this, 'add'), $data);
+ continue;
+ }
+
+ // redefine var
+ $data = (string) $data;
+
+ // load data
+ $value = $this->load($data);
+ $key = ($data != $value) ? $data : count($this->data);
+
+ // replace CR linefeeds etc.
+ // @see https://github.com/matthiasmullie/minify/pull/139
+ $value = str_replace(array("\r\n", "\r"), "\n", $value);
+
+ // store data
+ $this->data[$key] = $value;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Minify the data & (optionally) saves it to a file.
+ *
+ * @param string[optional] $path Path to write the data to
+ *
+ * @return string The minified data
+ */
+ public function minify($path = null)
+ {
+ $content = $this->execute($path);
+
+ // save to path
+ if ($path !== null) {
+ $this->save($content, $path);
+ }
+
+ return $content;
+ }
+
+ /**
+ * Minify & gzip the data & (optionally) saves it to a file.
+ *
+ * @param string[optional] $path Path to write the data to
+ * @param int[optional] $level Compression level, from 0 to 9
+ *
+ * @return string The minified & gzipped data
+ */
+ public function gzip($path = null, $level = 9)
+ {
+ $content = $this->execute($path);
+ $content = gzencode($content, $level, FORCE_GZIP);
+
+ // save to path
+ if ($path !== null) {
+ $this->save($content, $path);
+ }
+
+ return $content;
+ }
+
+ /**
+ * Minify the data & write it to a CacheItemInterface object.
+ *
+ * @param CacheItemInterface $item Cache item to write the data to
+ *
+ * @return CacheItemInterface Cache item with the minifier data
+ */
+ public function cache(CacheItemInterface $item)
+ {
+ $content = $this->execute();
+ $item->set($content);
+
+ return $item;
+ }
+
+ /**
+ * Minify the data.
+ *
+ * @param string[optional] $path Path to write the data to
+ *
+ * @return string The minified data
+ */
+ abstract public function execute($path = null);
+
+ /**
+ * Load data.
+ *
+ * @param string $data Either a path to a file or the content itself
+ *
+ * @return string
+ */
+ protected function load($data)
+ {
+ // check if the data is a file
+ if ($this->canImportFile($data)) {
+ $data = file_get_contents($data);
+
+ // strip BOM, if any
+ if (substr($data, 0, 3) == "\xef\xbb\xbf") {
+ $data = substr($data, 3);
+ }
+ }
+
+ return $data;
+ }
+
+ /**
+ * Save to file.
+ *
+ * @param string $content The minified data
+ * @param string $path The path to save the minified data to
+ *
+ * @throws IOException
+ */
+ protected function save($content, $path)
+ {
+ $handler = $this->openFileForWriting($path);
+
+ $this->writeToFile($handler, $content);
+
+ @fclose($handler);
+ }
+
+ /**
+ * Register a pattern to execute against the source content.
+ *
+ * @param string $pattern PCRE pattern
+ * @param string|callable $replacement Replacement value for matched pattern
+ */
+ protected function registerPattern($pattern, $replacement = '')
+ {
+ // study the pattern, we'll execute it more than once
+ $pattern .= 'S';
+
+ $this->patterns[] = array($pattern, $replacement);
+ }
+
+ /**
+ * We can't "just" run some regular expressions against JavaScript: it's a
+ * complex language. E.g. having an occurrence of // xyz would be a comment,
+ * unless it's used within a string. Of you could have something that looks
+ * like a 'string', but inside a comment.
+ * The only way to accurately replace these pieces is to traverse the JS one
+ * character at a time and try to find whatever starts first.
+ *
+ * @param string $content The content to replace patterns in
+ *
+ * @return string The (manipulated) content
+ */
+ protected function replace($content)
+ {
+ $processed = '';
+ $positions = array_fill(0, count($this->patterns), -1);
+ $matches = array();
+
+ while ($content) {
+ // find first match for all patterns
+ foreach ($this->patterns as $i => $pattern) {
+ list($pattern, $replacement) = $pattern;
+
+ // no need to re-run matches that are still in the part of the
+ // content that hasn't been processed
+ if ($positions[$i] >= 0) {
+ continue;
+ }
+
+ $match = null;
+ if (preg_match($pattern, $content, $match, PREG_OFFSET_CAPTURE)) {
+ $matches[$i] = $match;
+
+ // we'll store the match position as well; that way, we
+ // don't have to redo all preg_matches after changing only
+ // the first (we'll still know where those others are)
+ $positions[$i] = $match[0][1];
+ } else {
+ // if the pattern couldn't be matched, there's no point in
+ // executing it again in later runs on this same content;
+ // ignore this one until we reach end of content
+ unset($matches[$i]);
+ $positions[$i] = strlen($content);
+ }
+ }
+
+ // no more matches to find: everything's been processed, break out
+ if (!$matches) {
+ $processed .= $content;
+ break;
+ }
+
+ // see which of the patterns actually found the first thing (we'll
+ // only want to execute that one, since we're unsure if what the
+ // other found was not inside what the first found)
+ $discardLength = min($positions);
+ $firstPattern = array_search($discardLength, $positions);
+ $match = $matches[$firstPattern][0][0];
+
+ // execute the pattern that matches earliest in the content string
+ list($pattern, $replacement) = $this->patterns[$firstPattern];
+ $replacement = $this->replacePattern($pattern, $replacement, $content);
+
+ // figure out which part of the string was unmatched; that's the
+ // part we'll execute the patterns on again next
+ $content = (string) substr($content, $discardLength);
+ $unmatched = (string) substr($content, strpos($content, $match) + strlen($match));
+
+ // move the replaced part to $processed and prepare $content to
+ // again match batch of patterns against
+ $processed .= substr($replacement, 0, strlen($replacement) - strlen($unmatched));
+ $content = $unmatched;
+
+ // first match has been replaced & that content is to be left alone,
+ // the next matches will start after this replacement, so we should
+ // fix their offsets
+ foreach ($positions as $i => $position) {
+ $positions[$i] -= $discardLength + strlen($match);
+ }
+ }
+
+ return $processed;
+ }
+
+ /**
+ * This is where a pattern is matched against $content and the matches
+ * are replaced by their respective value.
+ * This function will be called plenty of times, where $content will always
+ * move up 1 character.
+ *
+ * @param string $pattern Pattern to match
+ * @param string|callable $replacement Replacement value
+ * @param string $content Content to match pattern against
+ *
+ * @return string
+ */
+ protected function replacePattern($pattern, $replacement, $content)
+ {
+ if (is_callable($replacement)) {
+ return preg_replace_callback($pattern, $replacement, $content, 1, $count);
+ } else {
+ return preg_replace($pattern, $replacement, $content, 1, $count);
+ }
+ }
+
+ /**
+ * Strings are a pattern we need to match, in order to ignore potential
+ * code-like content inside them, but we just want all of the string
+ * content to remain untouched.
+ *
+ * This method will replace all string content with simple STRING#
+ * placeholder text, so we've rid all strings from characters that may be
+ * misinterpreted. Original string content will be saved in $this->extracted
+ * and after doing all other minifying, we can restore the original content
+ * via restoreStrings().
+ *
+ * @param string[optional] $chars
+ * @param string[optional] $placeholderPrefix
+ */
+ protected function extractStrings($chars = '\'"', $placeholderPrefix = '')
+ {
+ // PHP only supports $this inside anonymous functions since 5.4
+ $minifier = $this;
+ $callback = function ($match) use ($minifier, $placeholderPrefix) {
+ // check the second index here, because the first always contains a quote
+ if ($match[2] === '') {
+ /*
+ * Empty strings need no placeholder; they can't be confused for
+ * anything else anyway.
+ * But we still needed to match them, for the extraction routine
+ * to skip over this particular string.
+ */
+ return $match[0];
+ }
+
+ $count = count($minifier->extracted);
+ $placeholder = $match[1].$placeholderPrefix.$count.$match[1];
+ $minifier->extracted[$placeholder] = $match[1].$match[2].$match[1];
+
+ return $placeholder;
+ };
+
+ /*
+ * The \\ messiness explained:
+ * * Don't count ' or " as end-of-string if it's escaped (has backslash
+ * in front of it)
+ * * Unless... that backslash itself is escaped (another leading slash),
+ * in which case it's no longer escaping the ' or "
+ * * So there can be either no backslash, or an even number
+ * * multiply all of that times 4, to account for the escaping that has
+ * to be done to pass the backslash into the PHP string without it being
+ * considered as escape-char (times 2) and to get it in the regex,
+ * escaped (times 2)
+ */
+ $this->registerPattern('/(['.$chars.'])(.*?(?<!\\\\)(\\\\\\\\)*+)\\1/s', $callback);
+ }
+
+ /**
+ * This method will restore all extracted data (strings, regexes) that were
+ * replaced with placeholder text in extract*(). The original content was
+ * saved in $this->extracted.
+ *
+ * @param string $content
+ *
+ * @return string
+ */
+ protected function restoreExtractedData($content)
+ {
+ if (!$this->extracted) {
+ // nothing was extracted, nothing to restore
+ return $content;
+ }
+
+ $content = strtr($content, $this->extracted);
+
+ $this->extracted = array();
+
+ return $content;
+ }
+
+ /**
+ * Check if the path is a regular file and can be read.
+ *
+ * @param string $path
+ *
+ * @return bool
+ */
+ protected function canImportFile($path)
+ {
+ $parsed = parse_url($path);
+ if (
+ // file is elsewhere
+ isset($parsed['host']) ||
+ // file responds to queries (may change, or need to bypass cache)
+ isset($parsed['query'])
+ ) {
+ return false;
+ }
+
+ return strlen($path) < PHP_MAXPATHLEN && @is_file($path) && is_readable($path);
+ }
+
+ /**
+ * Attempts to open file specified by $path for writing.
+ *
+ * @param string $path The path to the file
+ *
+ * @return resource Specifier for the target file
+ *
+ * @throws IOException
+ */
+ protected function openFileForWriting($path)
+ {
+ if (($handler = @fopen($path, 'w')) === false) {
+ throw new IOException('The file "'.$path.'" could not be opened for writing. Check if PHP has enough permissions.');
+ }
+
+ return $handler;
+ }
+
+ /**
+ * Attempts to write $content to the file specified by $handler. $path is used for printing exceptions.
+ *
+ * @param resource $handler The resource to write to
+ * @param string $content The content to write
+ * @param string $path The path to the file (for exception printing only)
+ *
+ * @throws IOException
+ */
+ protected function writeToFile($handler, $content, $path = '')
+ {
+ if (($result = @fwrite($handler, $content)) === false || ($result < strlen($content))) {
+ throw new IOException('The file "'.$path.'" could not be written to. Check your disk space and file permissions.');
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/path-converter/LICENSE b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/path-converter/LICENSE
new file mode 100644
index 0000000..491295a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/path-converter/LICENSE
@@ -0,0 +1,18 @@
+Copyright (c) 2015 Matthias Mullie
+
+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.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/path-converter/composer.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/path-converter/composer.json
new file mode 100644
index 0000000..1cb6a4c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/path-converter/composer.json
@@ -0,0 +1,28 @@
+{
+ "name": "matthiasmullie/path-converter",
+ "type": "library",
+ "description": "Relative path converter",
+ "keywords": ["relative", "path", "converter", "paths"],
+ "homepage": "http://github.com/matthiasmullie/path-converter",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Matthias Mullie",
+ "homepage": "http://www.mullie.eu",
+ "email": "pathconverter@mullie.eu",
+ "role": "Developer"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.0",
+ "ext-pcre": "*"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.8"
+ },
+ "autoload": {
+ "psr-4": {
+ "MatthiasMullie\\PathConverter\\": "src/"
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/path-converter/src/Converter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/path-converter/src/Converter.php
new file mode 100644
index 0000000..b92b24c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/path-converter/src/Converter.php
@@ -0,0 +1,195 @@
+<?php
+
+namespace MatthiasMullie\PathConverter;
+
+/**
+ * Convert paths relative from 1 file to another.
+ *
+ * E.g.
+ * ../../images/icon.jpg relative to /css/imports/icons.css
+ * becomes
+ * ../images/icon.jpg relative to /css/minified.css
+ *
+ * Please report bugs on https://github.com/matthiasmullie/path-converter/issues
+ *
+ * @author Matthias Mullie <pathconverter@mullie.eu>
+ * @copyright Copyright (c) 2015, Matthias Mullie. All rights reserved
+ * @license MIT License
+ */
+class Converter implements ConverterInterface
+{
+ /**
+ * @var string
+ */
+ protected $from;
+
+ /**
+ * @var string
+ */
+ protected $to;
+
+ /**
+ * @param string $from The original base path (directory, not file!)
+ * @param string $to The new base path (directory, not file!)
+ */
+ public function __construct($from, $to)
+ {
+ $shared = $this->shared($from, $to);
+ if ($shared === '') {
+ // when both paths have nothing in common, one of them is probably
+ // absolute while the other is relative
+ $cwd = getcwd();
+ $from = strpos($from, $cwd) === 0 ? $from : $cwd.'/'.$from;
+ $to = strpos($to, $cwd) === 0 ? $to : $cwd.'/'.$to;
+
+ // or traveling the tree via `..`
+ // attempt to resolve path, or assume it's fine if it doesn't exist
+ $from = @realpath($from) ?: $from;
+ $to = @realpath($to) ?: $to;
+ }
+
+ $from = $this->dirname($from);
+ $to = $this->dirname($to);
+
+ $from = $this->normalize($from);
+ $to = $this->normalize($to);
+
+ $this->from = $from;
+ $this->to = $to;
+ }
+
+ /**
+ * Normalize path.
+ *
+ * @param string $path
+ *
+ * @return string
+ */
+ protected function normalize($path)
+ {
+ // deal with different operating systems' directory structure
+ $path = rtrim(str_replace(DIRECTORY_SEPARATOR, '/', $path), '/');
+
+ /*
+ * Example:
+ * /home/forkcms/frontend/cache/compiled_templates/../../core/layout/css/../images/img.gif
+ * to
+ * /home/forkcms/frontend/core/layout/images/img.gif
+ */
+ do {
+ $path = preg_replace('/[^\/]+(?<!\.\.)\/\.\.\//', '', $path, -1, $count);
+ } while ($count);
+
+ return $path;
+ }
+
+ /**
+ * Figure out the shared path of 2 locations.
+ *
+ * Example:
+ * /home/forkcms/frontend/core/layout/images/img.gif
+ * and
+ * /home/forkcms/frontend/cache/minified_css
+ * share
+ * /home/forkcms/frontend
+ *
+ * @param string $path1
+ * @param string $path2
+ *
+ * @return string
+ */
+ protected function shared($path1, $path2)
+ {
+ // $path could theoretically be empty (e.g. no path is given), in which
+ // case it shouldn't expand to array(''), which would compare to one's
+ // root /
+ $path1 = $path1 ? explode('/', $path1) : array();
+ $path2 = $path2 ? explode('/', $path2) : array();
+
+ $shared = array();
+
+ // compare paths & strip identical ancestors
+ foreach ($path1 as $i => $chunk) {
+ if (isset($path2[$i]) && $path1[$i] == $path2[$i]) {
+ $shared[] = $chunk;
+ } else {
+ break;
+ }
+ }
+
+ return implode('/', $shared);
+ }
+
+ /**
+ * Convert paths relative from 1 file to another.
+ *
+ * E.g.
+ * ../images/img.gif relative to /home/forkcms/frontend/core/layout/css
+ * should become:
+ * ../../core/layout/images/img.gif relative to
+ * /home/forkcms/frontend/cache/minified_css
+ *
+ * @param string $path The relative path that needs to be converted
+ *
+ * @return string The new relative path
+ */
+ public function convert($path)
+ {
+ // quit early if conversion makes no sense
+ if ($this->from === $this->to) {
+ return $path;
+ }
+
+ $path = $this->normalize($path);
+ // if we're not dealing with a relative path, just return absolute
+ if (strpos($path, '/') === 0) {
+ return $path;
+ }
+
+ // normalize paths
+ $path = $this->normalize($this->from.'/'.$path);
+
+ // strip shared ancestor paths
+ $shared = $this->shared($path, $this->to);
+ $path = mb_substr($path, mb_strlen($shared));
+ $to = mb_substr($this->to, mb_strlen($shared));
+
+ // add .. for every directory that needs to be traversed to new path
+ $to = str_repeat('../', mb_substr_count($to, '/'));
+
+ return $to.ltrim($path, '/');
+ }
+
+ /**
+ * Attempt to get the directory name from a path.
+ *
+ * @param string $path
+ *
+ * @return string
+ */
+ protected function dirname($path)
+ {
+ if (@is_file($path)) {
+ return dirname($path);
+ }
+
+ if (@is_dir($path)) {
+ return rtrim($path, '/');
+ }
+
+ // no known file/dir, start making assumptions
+
+ // ends in / = dir
+ if (mb_substr($path, -1) === '/') {
+ return rtrim($path, '/');
+ }
+
+ // has a dot in the name, likely a file
+ if (preg_match('/.*\..*$/', basename($path)) !== 0) {
+ return dirname($path);
+ }
+
+ // you're on your own here!
+ return $path;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/path-converter/src/ConverterInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/path-converter/src/ConverterInterface.php
new file mode 100644
index 0000000..dc1b765
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/path-converter/src/ConverterInterface.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MatthiasMullie\PathConverter;
+
+/**
+ * Convert file paths.
+ *
+ * Please report bugs on https://github.com/matthiasmullie/path-converter/issues
+ *
+ * @author Matthias Mullie <pathconverter@mullie.eu>
+ * @copyright Copyright (c) 2015, Matthias Mullie. All rights reserved
+ * @license MIT License
+ */
+interface ConverterInterface
+{
+ /**
+ * Convert file paths.
+ *
+ * @param string $path The path to be converted
+ *
+ * @return string The new path
+ */
+ public function convert($path);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/path-converter/src/NoConverter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/path-converter/src/NoConverter.php
new file mode 100644
index 0000000..2fcfd0f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/matthiasmullie/path-converter/src/NoConverter.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MatthiasMullie\PathConverter;
+
+/**
+ * Don't convert paths.
+ *
+ * Please report bugs on https://github.com/matthiasmullie/path-converter/issues
+ *
+ * @author Matthias Mullie <pathconverter@mullie.eu>
+ * @copyright Copyright (c) 2015, Matthias Mullie. All rights reserved
+ * @license MIT License
+ */
+class NoConverter implements ConverterInterface
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function convert($path)
+ {
+ return $path;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/natxet/CssMin/README b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/natxet/CssMin/README
new file mode 100644
index 0000000..b93fa4d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/natxet/CssMin/README
@@ -0,0 +1,3 @@
+This is just a copy of the CssMin by Joe Scylla to format it for Composer.
+Composer: http://packagist.org/about-composer
+CssMin: http://code.google.com/p/cssmin/
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/natxet/CssMin/composer.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/natxet/CssMin/composer.json
new file mode 100644
index 0000000..f477e9a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/natxet/CssMin/composer.json
@@ -0,0 +1,26 @@
+{
+ "name": "natxet/cssmin",
+ "description": "Minifying CSS",
+ "type": "library",
+ "keywords": ["css","minify"],
+ "homepage": "http://code.google.com/p/cssmin/",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Joe Scylla",
+ "email": "joe.scylla@gmail.com",
+ "homepage": "https://profiles.google.com/joe.scylla"
+ }
+ ],
+ "require": {
+ "php": ">=5.0"
+ },
+ "autoload": {
+ "classmap": ["src/"]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0-dev"
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/natxet/CssMin/src/CssMin.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/natxet/CssMin/src/CssMin.php
new file mode 100644
index 0000000..835b27a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/natxet/CssMin/src/CssMin.php
@@ -0,0 +1,5155 @@
+<?php
+/**
+ * CssMin - A (simple) css minifier with benefits
+ *
+ * --
+ * Copyright (c) 2011 Joe Scylla <joe.scylla@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ * --
+ *
+ * @package CssMin
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+/**
+ * Abstract definition of a CSS token class.
+ *
+ * Every token has to extend this class.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+abstract class aCssToken
+{
+ /**
+ * Returns the token as string.
+ *
+ * @return string
+ */
+ abstract public function __toString();
+}
+
+/**
+ * Abstract definition of a for a ruleset start token.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+abstract class aCssRulesetStartToken extends aCssToken
+{
+
+}
+
+/**
+ * Abstract definition of a for ruleset end token.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+abstract class aCssRulesetEndToken extends aCssToken
+{
+ /**
+ * Implements {@link aCssToken::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return "}";
+ }
+}
+
+/**
+ * Abstract definition of a parser plugin.
+ *
+ * Every parser plugin have to extend this class. A parser plugin contains the logic to parse one or aspects of a
+ * stylesheet.
+ *
+ * @package CssMin/Parser/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+abstract class aCssParserPlugin
+{
+ /**
+ * Plugin configuration.
+ *
+ * @var array
+ */
+ protected $configuration = array();
+ /**
+ * The CssParser of the plugin.
+ *
+ * @var CssParser
+ */
+ protected $parser = null;
+ /**
+ * Plugin buffer.
+ *
+ * @var string
+ */
+ protected $buffer = "";
+ /**
+ * Constructor.
+ *
+ * @param CssParser $parser The CssParser object of this plugin.
+ * @param array $configuration Plugin configuration [optional]
+ * @return void
+ */
+ public function __construct(CssParser $parser, array $configuration = null)
+ {
+ $this->configuration = $configuration;
+ $this->parser = $parser;
+ }
+ /**
+ * Returns the array of chars triggering the parser plugin.
+ *
+ * @return array
+ */
+ abstract public function getTriggerChars();
+ /**
+ * Returns the array of states triggering the parser plugin or FALSE if every state will trigger the parser plugin.
+ *
+ * @return array
+ */
+ abstract public function getTriggerStates();
+ /**
+ * Parser routine of the plugin.
+ *
+ * @param integer $index Current index
+ * @param string $char Current char
+ * @param string $previousChar Previous char
+ * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
+ */
+ abstract public function parse($index, $char, $previousChar, $state);
+}
+
+/**
+ * Abstract definition of a minifier plugin class.
+ *
+ * Minifier plugin process the parsed tokens one by one to apply changes to the token. Every minifier plugin has to
+ * extend this class.
+ *
+ * @package CssMin/Minifier/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+abstract class aCssMinifierPlugin
+{
+ /**
+ * Plugin configuration.
+ *
+ * @var array
+ */
+ protected $configuration = array();
+ /**
+ * The CssMinifier of the plugin.
+ *
+ * @var CssMinifier
+ */
+ protected $minifier = null;
+ /**
+ * Constructor.
+ *
+ * @param CssMinifier $minifier The CssMinifier object of this plugin.
+ * @param array $configuration Plugin configuration [optional]
+ * @return void
+ */
+ public function __construct(CssMinifier $minifier, array $configuration = array())
+ {
+ $this->configuration = $configuration;
+ $this->minifier = $minifier;
+ }
+ /**
+ * Apply the plugin to the token.
+ *
+ * @param aCssToken $token Token to process
+ * @return boolean Return TRUE to break the processing of this token; FALSE to continue
+ */
+ abstract public function apply(aCssToken &$token);
+ /**
+ * --
+ *
+ * @return array
+ */
+ abstract public function getTriggerTokens();
+}
+
+/**
+ * Abstract definition of a minifier filter class.
+ *
+ * Minifier filters allows a pre-processing of the parsed token to add, edit or delete tokens. Every minifier filter
+ * has to extend this class.
+ *
+ * @package CssMin/Minifier/Filters
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+abstract class aCssMinifierFilter
+{
+ /**
+ * Filter configuration.
+ *
+ * @var array
+ */
+ protected $configuration = array();
+ /**
+ * The CssMinifier of the filter.
+ *
+ * @var CssMinifier
+ */
+ protected $minifier = null;
+ /**
+ * Constructor.
+ *
+ * @param CssMinifier $minifier The CssMinifier object of this plugin.
+ * @param array $configuration Filter configuration [optional]
+ * @return void
+ */
+ public function __construct(CssMinifier $minifier, array $configuration = array())
+ {
+ $this->configuration = $configuration;
+ $this->minifier = $minifier;
+ }
+ /**
+ * Filter the tokens.
+ *
+ * @param array $tokens Array of objects of type aCssToken
+ * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array
+ */
+ abstract public function apply(array &$tokens);
+}
+
+/**
+ * Abstract formatter definition.
+ *
+ * Every formatter have to extend this class.
+ *
+ * @package CssMin/Formatter
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+abstract class aCssFormatter
+{
+ /**
+ * Indent string.
+ *
+ * @var string
+ */
+ protected $indent = " ";
+ /**
+ * Declaration padding.
+ *
+ * @var integer
+ */
+ protected $padding = 0;
+ /**
+ * Tokens.
+ *
+ * @var array
+ */
+ protected $tokens = array();
+ /**
+ * Constructor.
+ *
+ * @param array $tokens Array of CssToken
+ * @param string $indent Indent string [optional]
+ * @param integer $padding Declaration value padding [optional]
+ */
+ public function __construct(array $tokens, $indent = null, $padding = null)
+ {
+ $this->tokens = $tokens;
+ $this->indent = !is_null($indent) ? $indent : $this->indent;
+ $this->padding = !is_null($padding) ? $padding : $this->padding;
+ }
+ /**
+ * Returns the array of aCssToken as formatted string.
+ *
+ * @return string
+ */
+ abstract public function __toString();
+}
+
+/**
+ * Abstract definition of a ruleset declaration token.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+abstract class aCssDeclarationToken extends aCssToken
+{
+ /**
+ * Is the declaration flagged as important?
+ *
+ * @var boolean
+ */
+ public $IsImportant = false;
+ /**
+ * Is the declaration flagged as last one of the ruleset?
+ *
+ * @var boolean
+ */
+ public $IsLast = false;
+ /**
+ * Property name of the declaration.
+ *
+ * @var string
+ */
+ public $Property = "";
+ /**
+ * Value of the declaration.
+ *
+ * @var string
+ */
+ public $Value = "";
+ /**
+ * Set the properties of the @font-face declaration.
+ *
+ * @param string $property Property of the declaration
+ * @param string $value Value of the declaration
+ * @param boolean $isImportant Is the !important flag is set?
+ * @param boolean $IsLast Is the declaration the last one of the block?
+ * @return void
+ */
+ public function __construct($property, $value, $isImportant = false, $isLast = false)
+ {
+ $this->Property = $property;
+ $this->Value = $value;
+ $this->IsImportant = $isImportant;
+ $this->IsLast = $isLast;
+ }
+ /**
+ * Implements {@link aCssToken::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->Property . ":" . $this->Value . ($this->IsImportant ? " !important" : "") . ($this->IsLast ? "" : ";");
+ }
+}
+
+/**
+ * Abstract definition of a for at-rule block start token.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+abstract class aCssAtBlockStartToken extends aCssToken
+{
+
+}
+
+/**
+ * Abstract definition of a for at-rule block end token.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+abstract class aCssAtBlockEndToken extends aCssToken
+{
+ /**
+ * Implements {@link aCssToken::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return "}";
+ }
+}
+
+/**
+ * {@link aCssFromatter Formatter} returning the CSS source in {@link http://goo.gl/etzLs Whitesmiths indent style}.
+ *
+ * @package CssMin/Formatter
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssWhitesmithsFormatter extends aCssFormatter
+{
+ /**
+ * Implements {@link aCssFormatter::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ $r = array();
+ $level = 0;
+ for ($i = 0, $l = count($this->tokens); $i < $l; $i++)
+ {
+ $token = $this->tokens[$i];
+ $class = get_class($token);
+ $indent = str_repeat($this->indent, $level);
+ if ($class === "CssCommentToken")
+ {
+ $lines = array_map("trim", explode("\n", $token->Comment));
+ for ($ii = 0, $ll = count($lines); $ii < $ll; $ii++)
+ {
+ $r[] = $indent . (substr($lines[$ii], 0, 1) == "*" ? " " : "") . $lines[$ii];
+ }
+ }
+ elseif ($class === "CssAtCharsetToken")
+ {
+ $r[] = $indent . "@charset " . $token->Charset . ";";
+ }
+ elseif ($class === "CssAtFontFaceStartToken")
+ {
+ $r[] = $indent . "@font-face";
+ $r[] = $this->indent . $indent . "{";
+ $level++;
+ }
+ elseif ($class === "CssAtImportToken")
+ {
+ $r[] = $indent . "@import " . $token->Import . " " . implode(", ", $token->MediaTypes) . ";";
+ }
+ elseif ($class === "CssAtKeyframesStartToken")
+ {
+ $r[] = $indent . "@keyframes " . $token->Name;
+ $r[] = $this->indent . $indent . "{";
+ $level++;
+ }
+ elseif ($class === "CssAtMediaStartToken")
+ {
+ $r[] = $indent . "@media " . implode(", ", $token->MediaTypes);
+ $r[] = $this->indent . $indent . "{";
+ $level++;
+ }
+ elseif ($class === "CssAtPageStartToken")
+ {
+ $r[] = $indent . "@page";
+ $r[] = $this->indent . $indent . "{";
+ $level++;
+ }
+ elseif ($class === "CssAtVariablesStartToken")
+ {
+ $r[] = $indent . "@variables " . implode(", ", $token->MediaTypes);
+ $r[] = $this->indent . $indent . "{";
+ $level++;
+ }
+ elseif ($class === "CssRulesetStartToken" || $class === "CssAtKeyframesRulesetStartToken")
+ {
+ $r[] = $indent . implode(", ", $token->Selectors);
+ $r[] = $this->indent . $indent . "{";
+ $level++;
+ }
+ elseif ($class === "CssAtFontFaceDeclarationToken"
+ || $class === "CssAtKeyframesRulesetDeclarationToken"
+ || $class === "CssAtPageDeclarationToken"
+ || $class === "CssAtVariablesDeclarationToken"
+ || $class === "CssRulesetDeclarationToken"
+ )
+ {
+ $declaration = $indent . $token->Property . ": ";
+ if ($this->padding)
+ {
+ $declaration = str_pad($declaration, $this->padding, " ", STR_PAD_RIGHT);
+ }
+ $r[] = $declaration . $token->Value . ($token->IsImportant ? " !important" : "") . ";";
+ }
+ elseif ($class === "CssAtFontFaceEndToken"
+ || $class === "CssAtMediaEndToken"
+ || $class === "CssAtKeyframesEndToken"
+ || $class === "CssAtKeyframesRulesetEndToken"
+ || $class === "CssAtPageEndToken"
+ || $class === "CssAtVariablesEndToken"
+ || $class === "CssRulesetEndToken"
+ )
+ {
+ $r[] = $indent . "}";
+ $level--;
+ }
+ }
+ return implode("\n", $r);
+ }
+}
+
+/**
+ * This {@link aCssMinifierPlugin} will process var-statement and sets the declaration value to the variable value.
+ *
+ * This plugin only apply the variable values. The variable values itself will get parsed by the
+ * {@link CssVariablesMinifierFilter}.
+ *
+ * Example:
+ * <code>
+ * @variables
+ * {
+ * defaultColor: black;
+ * }
+ * color: var(defaultColor);
+ * </code>
+ *
+ * Will get converted to:
+ * <code>
+ * color:black;
+ * </code>
+ *
+ * @package CssMin/Minifier/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssVariablesMinifierPlugin extends aCssMinifierPlugin
+{
+ /**
+ * Regular expression matching a value.
+ *
+ * @var string
+ */
+ private $reMatch = "/var\((.+)\)/iSU";
+ /**
+ * Parsed variables.
+ *
+ * @var array
+ */
+ private $variables = null;
+ /**
+ * Returns the variables.
+ *
+ * @return array
+ */
+ public function getVariables()
+ {
+ return $this->variables;
+ }
+ /**
+ * Implements {@link aCssMinifierPlugin::minify()}.
+ *
+ * @param aCssToken $token Token to process
+ * @return boolean Return TRUE to break the processing of this token; FALSE to continue
+ */
+ public function apply(aCssToken &$token)
+ {
+ if (stripos($token->Value, "var") !== false && preg_match_all($this->reMatch, $token->Value, $m))
+ {
+ $mediaTypes = $token->MediaTypes;
+ if (!in_array("all", $mediaTypes))
+ {
+ $mediaTypes[] = "all";
+ }
+ for ($i = 0, $l = count($m[0]); $i < $l; $i++)
+ {
+ $variable = trim($m[1][$i]);
+ foreach ($mediaTypes as $mediaType)
+ {
+ if (isset($this->variables[$mediaType], $this->variables[$mediaType][$variable]))
+ {
+ // Variable value found => set the declaration value to the variable value and return
+ $token->Value = str_replace($m[0][$i], $this->variables[$mediaType][$variable], $token->Value);
+ continue 2;
+ }
+ }
+ // If no value was found trigger an error and replace the token with a CssNullToken
+ CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": No value found for variable <code>" . $variable . "</code> in media types <code>" . implode(", ", $mediaTypes) . "</code>", (string) $token));
+ $token = new CssNullToken();
+ return true;
+ }
+ }
+ return false;
+ }
+ /**
+ * Implements {@link aMinifierPlugin::getTriggerTokens()}
+ *
+ * @return array
+ */
+ public function getTriggerTokens()
+ {
+ return array
+ (
+ "CssAtFontFaceDeclarationToken",
+ "CssAtPageDeclarationToken",
+ "CssRulesetDeclarationToken"
+ );
+ }
+ /**
+ * Sets the variables.
+ *
+ * @param array $variables Variables to set
+ * @return void
+ */
+ public function setVariables(array $variables)
+ {
+ $this->variables = $variables;
+ }
+}
+
+/**
+ * This {@link aCssMinifierFilter minifier filter} will parse the variable declarations out of @variables at-rule
+ * blocks. The variables will get store in the {@link CssVariablesMinifierPlugin} that will apply the variables to
+ * declaration.
+ *
+ * @package CssMin/Minifier/Filters
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssVariablesMinifierFilter extends aCssMinifierFilter
+{
+ /**
+ * Implements {@link aCssMinifierFilter::filter()}.
+ *
+ * @param array $tokens Array of objects of type aCssToken
+ * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array
+ */
+ public function apply(array &$tokens)
+ {
+ $variables = array();
+ $defaultMediaTypes = array("all");
+ $mediaTypes = array();
+ $remove = array();
+ for($i = 0, $l = count($tokens); $i < $l; $i++)
+ {
+ // @variables at-rule block found
+ if (get_class($tokens[$i]) === "CssAtVariablesStartToken")
+ {
+ $remove[] = $i;
+ $mediaTypes = (count($tokens[$i]->MediaTypes) == 0 ? $defaultMediaTypes : $tokens[$i]->MediaTypes);
+ foreach ($mediaTypes as $mediaType)
+ {
+ if (!isset($variables[$mediaType]))
+ {
+ $variables[$mediaType] = array();
+ }
+ }
+ // Read the variable declaration tokens
+ for($i = $i; $i < $l; $i++)
+ {
+ // Found a variable declaration => read the variable values
+ if (get_class($tokens[$i]) === "CssAtVariablesDeclarationToken")
+ {
+ foreach ($mediaTypes as $mediaType)
+ {
+ $variables[$mediaType][$tokens[$i]->Property] = $tokens[$i]->Value;
+ }
+ $remove[] = $i;
+ }
+ // Found the variables end token => break;
+ elseif (get_class($tokens[$i]) === "CssAtVariablesEndToken")
+ {
+ $remove[] = $i;
+ break;
+ }
+ }
+ }
+ }
+ // Variables in @variables at-rule blocks
+ foreach($variables as $mediaType => $null)
+ {
+ foreach($variables[$mediaType] as $variable => $value)
+ {
+ // If a var() statement in a variable value found...
+ if (stripos($value, "var") !== false && preg_match_all("/var\((.+)\)/iSU", $value, $m))
+ {
+ // ... then replace the var() statement with the variable values.
+ for ($i = 0, $l = count($m[0]); $i < $l; $i++)
+ {
+ $variables[$mediaType][$variable] = str_replace($m[0][$i], (isset($variables[$mediaType][$m[1][$i]]) ? $variables[$mediaType][$m[1][$i]] : ""), $variables[$mediaType][$variable]);
+ }
+ }
+ }
+ }
+ // Remove the complete @variables at-rule block
+ foreach ($remove as $i)
+ {
+ $tokens[$i] = null;
+ }
+ if (!($plugin = $this->minifier->getPlugin("CssVariablesMinifierPlugin")))
+ {
+ CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": The plugin <code>CssVariablesMinifierPlugin</code> was not found but is required for <code>" . __CLASS__ . "</code>"));
+ }
+ else
+ {
+ $plugin->setVariables($variables);
+ }
+ return count($remove);
+ }
+}
+
+/**
+ * {@link aCssParserPlugin Parser plugin} for preserve parsing url() values.
+ *
+ * This plugin return no {@link aCssToken CssToken} but ensures that url() values will get parsed properly.
+ *
+ * @package CssMin/Parser/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssUrlParserPlugin extends aCssParserPlugin
+{
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerChars()}.
+ *
+ * @return array
+ */
+ public function getTriggerChars()
+ {
+ return array("(", ")");
+ }
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerStates()}.
+ *
+ * @return array
+ */
+ public function getTriggerStates()
+ {
+ return false;
+ }
+ /**
+ * Implements {@link aCssParserPlugin::parse()}.
+ *
+ * @param integer $index Current index
+ * @param string $char Current char
+ * @param string $previousChar Previous char
+ * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
+ */
+ public function parse($index, $char, $previousChar, $state)
+ {
+ // Start of string
+ if ($char === "(" && strtolower(substr($this->parser->getSource(), $index - 3, 4)) === "url(" && $state !== "T_URL")
+ {
+ $this->parser->pushState("T_URL");
+ $this->parser->setExclusive(__CLASS__);
+ }
+ // Escaped LF in url => remove escape backslash and LF
+ elseif ($char === "\n" && $previousChar === "\\" && $state === "T_URL")
+ {
+ $this->parser->setBuffer(substr($this->parser->getBuffer(), 0, -2));
+ }
+ // Parse error: Unescaped LF in string literal
+ elseif ($char === "\n" && $previousChar !== "\\" && $state === "T_URL")
+ {
+ $line = $this->parser->getBuffer();
+ $this->parser->setBuffer(substr($this->parser->getBuffer(), 0, -1) . ")"); // Replace the LF with the url string delimiter
+ $this->parser->popState();
+ $this->parser->unsetExclusive();
+ CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated string literal", $line . "_"));
+ }
+ // End of string
+ elseif ($char === ")" && $state === "T_URL")
+ {
+ $this->parser->popState();
+ $this->parser->unsetExclusive();
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+ }
+}
+
+/**
+ * {@link aCssParserPlugin Parser plugin} for preserve parsing string values.
+ *
+ * This plugin return no {@link aCssToken CssToken} but ensures that string values will get parsed properly.
+ *
+ * @package CssMin/Parser/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssStringParserPlugin extends aCssParserPlugin
+{
+ /**
+ * Current string delimiter char.
+ *
+ * @var string
+ */
+ private $delimiterChar = null;
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerChars()}.
+ *
+ * @return array
+ */
+ public function getTriggerChars()
+ {
+ return array("\"", "'", "\n");
+ }
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerStates()}.
+ *
+ * @return array
+ */
+ public function getTriggerStates()
+ {
+ return false;
+ }
+ /**
+ * Implements {@link aCssParserPlugin::parse()}.
+ *
+ * @param integer $index Current index
+ * @param string $char Current char
+ * @param string $previousChar Previous char
+ * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
+ */
+ public function parse($index, $char, $previousChar, $state)
+ {
+ // Start of string
+ if (($char === "\"" || $char === "'") && $state !== "T_STRING")
+ {
+ $this->delimiterChar = $char;
+ $this->parser->pushState("T_STRING");
+ $this->parser->setExclusive(__CLASS__);
+ }
+ // Escaped LF in string => remove escape backslash and LF
+ elseif ($char === "\n" && $previousChar === "\\" && $state === "T_STRING")
+ {
+ $this->parser->setBuffer(substr($this->parser->getBuffer(), 0, -2));
+ }
+ // Parse error: Unescaped LF in string literal
+ elseif ($char === "\n" && $previousChar !== "\\" && $state === "T_STRING")
+ {
+ $line = $this->parser->getBuffer();
+ $this->parser->popState();
+ $this->parser->unsetExclusive();
+ $this->parser->setBuffer(substr($this->parser->getBuffer(), 0, -1) . $this->delimiterChar); // Replace the LF with the current string char
+ CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated string literal", $line . "_"));
+ $this->delimiterChar = null;
+ }
+ // End of string
+ elseif ($char === $this->delimiterChar && $state === "T_STRING")
+ {
+ // If the Previous char is a escape char count the amount of the previous escape chars. If the amount of
+ // escape chars is uneven do not end the string
+ if ($previousChar == "\\")
+ {
+ $source = $this->parser->getSource();
+ $c = 1;
+ $i = $index - 2;
+ while (substr($source, $i, 1) === "\\")
+ {
+ $c++; $i--;
+ }
+ if ($c % 2)
+ {
+ return false;
+ }
+ }
+ $this->parser->popState();
+ $this->parser->unsetExclusive();
+ $this->delimiterChar = null;
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+ }
+}
+
+/**
+ * This {@link aCssMinifierFilter minifier filter} sorts the ruleset declarations of a ruleset by name.
+ *
+ * @package CssMin/Minifier/Filters
+ * @link http://code.google.com/p/cssmin/
+ * @author Rowan Beentje <http://assanka.net>
+ * @copyright Rowan Beentje <http://assanka.net>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssSortRulesetPropertiesMinifierFilter extends aCssMinifierFilter
+{
+ /**
+ * Implements {@link aCssMinifierFilter::filter()}.
+ *
+ * @param array $tokens Array of objects of type aCssToken
+ * @return integer Count of added, changed or removed tokens; a return value larger than 0 will rebuild the array
+ */
+ public function apply(array &$tokens)
+ {
+ $r = 0;
+ for ($i = 0, $l = count($tokens); $i < $l; $i++)
+ {
+ // Only look for ruleset start rules
+ if (get_class($tokens[$i]) !== "CssRulesetStartToken") { continue; }
+ // Look for the corresponding ruleset end
+ $endIndex = false;
+ for ($ii = $i + 1; $ii < $l; $ii++)
+ {
+ if (get_class($tokens[$ii]) !== "CssRulesetEndToken") { continue; }
+ $endIndex = $ii;
+ break;
+ }
+ if (!$endIndex) { break; }
+ $startIndex = $i;
+ $i = $endIndex;
+ // Skip if there's only one token in this ruleset
+ if ($endIndex - $startIndex <= 2) { continue; }
+ // Ensure that everything between the start and end is a declaration token, for safety
+ for ($ii = $startIndex + 1; $ii < $endIndex; $ii++)
+ {
+ if (get_class($tokens[$ii]) !== "CssRulesetDeclarationToken") { continue(2); }
+ }
+ $declarations = array_slice($tokens, $startIndex + 1, $endIndex - $startIndex - 1);
+ // Check whether a sort is required
+ $sortRequired = $lastPropertyName = false;
+ foreach ($declarations as $declaration)
+ {
+ if ($lastPropertyName)
+ {
+ if (strcmp($lastPropertyName, $declaration->Property) > 0)
+ {
+ $sortRequired = true;
+ break;
+ }
+ }
+ $lastPropertyName = $declaration->Property;
+ }
+ if (!$sortRequired) { continue; }
+ // Arrange the declarations alphabetically by name
+ usort($declarations, array(__CLASS__, "userDefinedSort1"));
+ // Update "IsLast" property
+ for ($ii = 0, $ll = count($declarations) - 1; $ii <= $ll; $ii++)
+ {
+ if ($ii == $ll)
+ {
+ $declarations[$ii]->IsLast = true;
+ }
+ else
+ {
+ $declarations[$ii]->IsLast = false;
+ }
+ }
+ // Splice back into the array.
+ array_splice($tokens, $startIndex + 1, $endIndex - $startIndex - 1, $declarations);
+ $r += $endIndex - $startIndex - 1;
+ }
+ return $r;
+ }
+ /**
+ * User defined sort function.
+ *
+ * @return integer
+ */
+ public static function userDefinedSort1($a, $b)
+ {
+ return strcmp($a->Property, $b->Property);
+ }
+}
+
+/**
+ * This {@link aCssToken CSS token} represents the start of a ruleset.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssRulesetStartToken extends aCssRulesetStartToken
+{
+ /**
+ * Array of selectors.
+ *
+ * @var array
+ */
+ public $Selectors = array();
+ /**
+ * Set the properties of a ruleset token.
+ *
+ * @param array $selectors Selectors of the ruleset
+ * @return void
+ */
+ public function __construct(array $selectors = array())
+ {
+ $this->Selectors = $selectors;
+ }
+ /**
+ * Implements {@link aCssToken::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return implode(",", $this->Selectors) . "{";
+ }
+}
+
+/**
+ * {@link aCssParserPlugin Parser plugin} for parsing ruleset block with including declarations.
+ *
+ * Found rulesets will add a {@link CssRulesetStartToken} and {@link CssRulesetEndToken} to the
+ * parser; including declarations as {@link CssRulesetDeclarationToken}.
+ *
+ * @package CssMin/Parser/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssRulesetParserPlugin extends aCssParserPlugin
+{
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerChars()}.
+ *
+ * @return array
+ */
+ public function getTriggerChars()
+ {
+ return array(",", "{", "}", ":", ";");
+ }
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerStates()}.
+ *
+ * @return array
+ */
+ public function getTriggerStates()
+ {
+ return array("T_DOCUMENT", "T_AT_MEDIA", "T_RULESET::SELECTORS", "T_RULESET", "T_RULESET_DECLARATION");
+ }
+ /**
+ * Selectors.
+ *
+ * @var array
+ */
+ private $selectors = array();
+ /**
+ * Implements {@link aCssParserPlugin::parse()}.
+ *
+ * @param integer $index Current index
+ * @param string $char Current char
+ * @param string $previousChar Previous char
+ * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
+ */
+ public function parse($index, $char, $previousChar, $state)
+ {
+ // Start of Ruleset and selectors
+ if ($char === "," && ($state === "T_DOCUMENT" || $state === "T_AT_MEDIA" || $state === "T_RULESET::SELECTORS"))
+ {
+ if ($state !== "T_RULESET::SELECTORS")
+ {
+ $this->parser->pushState("T_RULESET::SELECTORS");
+ }
+ $this->selectors[] = $this->parser->getAndClearBuffer(",{");
+ }
+ // End of selectors and start of declarations
+ elseif ($char === "{" && ($state === "T_DOCUMENT" || $state === "T_AT_MEDIA" || $state === "T_RULESET::SELECTORS"))
+ {
+ if ($this->parser->getBuffer() !== "")
+ {
+ $this->selectors[] = $this->parser->getAndClearBuffer(",{");
+ if ($state == "T_RULESET::SELECTORS")
+ {
+ $this->parser->popState();
+ }
+ $this->parser->pushState("T_RULESET");
+ $this->parser->appendToken(new CssRulesetStartToken($this->selectors));
+ $this->selectors = array();
+ }
+ }
+ // Start of declaration
+ elseif ($char === ":" && $state === "T_RULESET")
+ {
+ $this->parser->pushState("T_RULESET_DECLARATION");
+ $this->buffer = $this->parser->getAndClearBuffer(":;", true);
+ }
+ // Unterminated ruleset declaration
+ elseif ($char === ":" && $state === "T_RULESET_DECLARATION")
+ {
+ // Ignore Internet Explorer filter declarations
+ if ($this->buffer === "filter")
+ {
+ return false;
+ }
+ CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated declaration", $this->buffer . ":" . $this->parser->getBuffer() . "_"));
+ }
+ // End of declaration
+ elseif (($char === ";" || $char === "}") && $state === "T_RULESET_DECLARATION")
+ {
+ $value = $this->parser->getAndClearBuffer(";}");
+ if (strtolower(substr($value, -10, 10)) === "!important")
+ {
+ $value = trim(substr($value, 0, -10));
+ $isImportant = true;
+ }
+ else
+ {
+ $isImportant = false;
+ }
+ $this->parser->popState();
+ $this->parser->appendToken(new CssRulesetDeclarationToken($this->buffer, $value, $this->parser->getMediaTypes(), $isImportant));
+ // Declaration ends with a right curly brace; so we have to end the ruleset
+ if ($char === "}")
+ {
+ $this->parser->appendToken(new CssRulesetEndToken());
+ $this->parser->popState();
+ }
+ $this->buffer = "";
+ }
+ // End of ruleset
+ elseif ($char === "}" && $state === "T_RULESET")
+ {
+ $this->parser->popState();
+ $this->parser->clearBuffer();
+ $this->parser->appendToken(new CssRulesetEndToken());
+ $this->buffer = "";
+ $this->selectors = array();
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+ }
+}
+
+/**
+ * This {@link aCssToken CSS token} represents the end of a ruleset.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssRulesetEndToken extends aCssRulesetEndToken
+{
+
+}
+
+/**
+ * This {@link aCssToken CSS token} represents a ruleset declaration.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssRulesetDeclarationToken extends aCssDeclarationToken
+{
+ /**
+ * Media types of the declaration.
+ *
+ * @var array
+ */
+ public $MediaTypes = array("all");
+ /**
+ * Set the properties of a ddocument- or at-rule @media level declaration.
+ *
+ * @param string $property Property of the declaration
+ * @param string $value Value of the declaration
+ * @param mixed $mediaTypes Media types of the declaration
+ * @param boolean $isImportant Is the !important flag is set
+ * @param boolean $isLast Is the declaration the last one of the ruleset
+ * @return void
+ */
+ public function __construct($property, $value, $mediaTypes = null, $isImportant = false, $isLast = false)
+ {
+ parent::__construct($property, $value, $isImportant, $isLast);
+ $this->MediaTypes = $mediaTypes ? $mediaTypes : array("all");
+ }
+}
+
+/**
+ * This {@link aCssMinifierFilter minifier filter} sets the IsLast property of any last declaration in a ruleset,
+ * @font-face at-rule or @page at-rule block. If the property IsLast is TRUE the decrations will get stringified
+ * without tailing semicolon.
+ *
+ * @package CssMin/Minifier/Filters
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssRemoveLastDelarationSemiColonMinifierFilter extends aCssMinifierFilter
+{
+ /**
+ * Implements {@link aCssMinifierFilter::filter()}.
+ *
+ * @param array $tokens Array of objects of type aCssToken
+ * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array
+ */
+ public function apply(array &$tokens)
+ {
+ for ($i = 0, $l = count($tokens); $i < $l; $i++)
+ {
+ $current = get_class($tokens[$i]);
+ $next = isset($tokens[$i+1]) ? get_class($tokens[$i+1]) : false;
+ if (($current === "CssRulesetDeclarationToken" && $next === "CssRulesetEndToken") ||
+ ($current === "CssAtFontFaceDeclarationToken" && $next === "CssAtFontFaceEndToken") ||
+ ($current === "CssAtPageDeclarationToken" && $next === "CssAtPageEndToken"))
+ {
+ $tokens[$i]->IsLast = true;
+ }
+ }
+ return 0;
+ }
+}
+
+/**
+ * This {@link aCssMinifierFilter minifier filter} will remove any empty rulesets (including @keyframes at-rule block
+ * rulesets).
+ *
+ * @package CssMin/Minifier/Filters
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssRemoveEmptyRulesetsMinifierFilter extends aCssMinifierFilter
+{
+ /**
+ * Implements {@link aCssMinifierFilter::filter()}.
+ *
+ * @param array $tokens Array of objects of type aCssToken
+ * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array
+ */
+ public function apply(array &$tokens)
+ {
+ $r = 0;
+ for ($i = 0, $l = count($tokens); $i < $l; $i++)
+ {
+ $current = get_class($tokens[$i]);
+ $next = isset($tokens[$i + 1]) ? get_class($tokens[$i + 1]) : false;
+ if (($current === "CssRulesetStartToken" && $next === "CssRulesetEndToken") ||
+ ($current === "CssAtKeyframesRulesetStartToken" && $next === "CssAtKeyframesRulesetEndToken" && !array_intersect(array("from", "0%", "to", "100%"), array_map("strtolower", $tokens[$i]->Selectors)))
+ )
+ {
+ $tokens[$i] = null;
+ $tokens[$i + 1] = null;
+ $i++;
+ $r = $r + 2;
+ }
+ }
+ return $r;
+ }
+}
+
+/**
+ * This {@link aCssMinifierFilter minifier filter} will remove any empty @font-face, @keyframes, @media and @page
+ * at-rule blocks.
+ *
+ * @package CssMin/Minifier/Filters
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssRemoveEmptyAtBlocksMinifierFilter extends aCssMinifierFilter
+{
+ /**
+ * Implements {@link aCssMinifierFilter::filter()}.
+ *
+ * @param array $tokens Array of objects of type aCssToken
+ * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array
+ */
+ public function apply(array &$tokens)
+ {
+ $r = 0;
+ for ($i = 0, $l = count($tokens); $i < $l; $i++)
+ {
+ $current = get_class($tokens[$i]);
+ $next = isset($tokens[$i + 1]) ? get_class($tokens[$i + 1]) : false;
+ if (($current === "CssAtFontFaceStartToken" && $next === "CssAtFontFaceEndToken") ||
+ ($current === "CssAtKeyframesStartToken" && $next === "CssAtKeyframesEndToken") ||
+ ($current === "CssAtPageStartToken" && $next === "CssAtPageEndToken") ||
+ ($current === "CssAtMediaStartToken" && $next === "CssAtMediaEndToken"))
+ {
+ $tokens[$i] = null;
+ $tokens[$i + 1] = null;
+ $i++;
+ $r = $r + 2;
+ }
+ }
+ return $r;
+ }
+}
+
+/**
+ * This {@link aCssMinifierFilter minifier filter} will remove any comments from the array of parsed tokens.
+ *
+ * @package CssMin/Minifier/Filters
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssRemoveCommentsMinifierFilter extends aCssMinifierFilter
+{
+ /**
+ * Regular expression whitelisting any important comments to preserve.
+ *
+ * @var string
+ */
+ private $whitelistPattern = '/(^\/\*!|@preserve|copyright|license|author|https?:|www\.)/i';
+
+ /**
+ * Implements {@link aCssMinifierFilter::filter()}.
+ *
+ * @param array $tokens Array of objects of type aCssToken
+ * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array
+ */
+ public function apply(array &$tokens)
+ {
+ $r = 0;
+ for ($i = 0, $l = count($tokens); $i < $l; $i++)
+ {
+ if (get_class($tokens[$i]) === "CssCommentToken")
+ {
+ if (!preg_match($this->whitelistPattern, $tokens[$i]->Comment))
+ {
+ $tokens[$i] = null;
+ $r++;
+ }
+ }
+ }
+ return $r;
+ }
+}
+
+/**
+ * CSS Parser.
+ *
+ * @package CssMin/Parser
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssParser
+{
+ /**
+ * Parse buffer.
+ *
+ * @var string
+ */
+ private $buffer = "";
+ /**
+ * {@link aCssParserPlugin Plugins}.
+ *
+ * @var array
+ */
+ private $plugins = array();
+ /**
+ * Source to parse.
+ *
+ * @var string
+ */
+ private $source = "";
+ /**
+ * Current state.
+ *
+ * @var integer
+ */
+ private $state = "T_DOCUMENT";
+ /**
+ * Exclusive state.
+ *
+ * @var string
+ */
+ private $stateExclusive = false;
+ /**
+ * Media types state.
+ *
+ * @var mixed
+ */
+ private $stateMediaTypes = false;
+ /**
+ * State stack.
+ *
+ * @var array
+ */
+ private $states = array("T_DOCUMENT");
+ /**
+ * Parsed tokens.
+ *
+ * @var array
+ */
+ private $tokens = array();
+ /**
+ * Constructer.
+ *
+ * Create instances of the used {@link aCssParserPlugin plugins}.
+ *
+ * @param string $source CSS source [optional]
+ * @param array $plugins Plugin configuration [optional]
+ * @return void
+ */
+ public function __construct($source = null, array $plugins = null)
+ {
+ $plugins = array_merge(array
+ (
+ "Comment" => true,
+ "String" => true,
+ "Url" => true,
+ "Expression" => true,
+ "Ruleset" => true,
+ "AtCharset" => true,
+ "AtFontFace" => true,
+ "AtImport" => true,
+ "AtKeyframes" => true,
+ "AtMedia" => true,
+ "AtPage" => true,
+ "AtVariables" => true
+ ), is_array($plugins) ? $plugins : array());
+ // Create plugin instances
+ foreach ($plugins as $name => $config)
+ {
+ if ($config !== false)
+ {
+ $class = "Css" . $name . "ParserPlugin";
+ $config = is_array($config) ? $config : array();
+ if (class_exists($class))
+ {
+ $this->plugins[] = new $class($this, $config);
+ }
+ else
+ {
+ CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": The plugin <code>" . $name . "</code> with the class name <code>" . $class . "</code> was not found"));
+ }
+ }
+ }
+ if (!is_null($source))
+ {
+ $this->parse($source);
+ }
+ }
+ /**
+ * Append a token to the array of tokens.
+ *
+ * @param aCssToken $token Token to append
+ * @return void
+ */
+ public function appendToken(aCssToken $token)
+ {
+ $this->tokens[] = $token;
+ }
+ /**
+ * Clears the current buffer.
+ *
+ * @return void
+ */
+ public function clearBuffer()
+ {
+ $this->buffer = "";
+ }
+ /**
+ * Returns and clear the current buffer.
+ *
+ * @param string $trim Chars to use to trim the returned buffer
+ * @param boolean $tolower if TRUE the returned buffer will get converted to lower case
+ * @return string
+ */
+ public function getAndClearBuffer($trim = "", $tolower = false)
+ {
+ $r = $this->getBuffer($trim, $tolower);
+ $this->buffer = "";
+ return $r;
+ }
+ /**
+ * Returns the current buffer.
+ *
+ * @param string $trim Chars to use to trim the returned buffer
+ * @param boolean $tolower if TRUE the returned buffer will get converted to lower case
+ * @return string
+ */
+ public function getBuffer($trim = "", $tolower = false)
+ {
+ $r = $this->buffer;
+ if ($trim)
+ {
+ $r = trim($r, " \t\n\r\0\x0B" . $trim);
+ }
+ if ($tolower)
+ {
+ $r = strtolower($r);
+ }
+ return $r;
+ }
+ /**
+ * Returns the current media types state.
+ *
+ * @return array
+ */
+ public function getMediaTypes()
+ {
+ return $this->stateMediaTypes;
+ }
+ /**
+ * Returns the CSS source.
+ *
+ * @return string
+ */
+ public function getSource()
+ {
+ return $this->source;
+ }
+ /**
+ * Returns the current state.
+ *
+ * @return integer The current state
+ */
+ public function getState()
+ {
+ return $this->state;
+ }
+ /**
+ * Returns a plugin by class name.
+ *
+ * @param string $name Class name of the plugin
+ * @return aCssParserPlugin
+ */
+ public function getPlugin($class)
+ {
+ static $index = null;
+ if (is_null($index))
+ {
+ $index = array();
+ for ($i = 0, $l = count($this->plugins); $i < $l; $i++)
+ {
+ $index[get_class($this->plugins[$i])] = $i;
+ }
+ }
+ return isset($index[$class]) ? $this->plugins[$index[$class]] : false;
+ }
+ /**
+ * Returns the parsed tokens.
+ *
+ * @return array
+ */
+ public function getTokens()
+ {
+ return $this->tokens;
+ }
+ /**
+ * Returns if the current state equals the passed state.
+ *
+ * @param integer $state State to compare with the current state
+ * @return boolean TRUE is the state equals to the passed state; FALSE if not
+ */
+ public function isState($state)
+ {
+ return ($this->state == $state);
+ }
+ /**
+ * Parse the CSS source and return a array with parsed tokens.
+ *
+ * @param string $source CSS source
+ * @return array Array with tokens
+ */
+ public function parse($source)
+ {
+ // Reset
+ $this->source = "";
+ $this->tokens = array();
+ // Create a global and plugin lookup table for trigger chars; set array of plugins as local variable and create
+ // several helper variables for plugin handling
+ $globalTriggerChars = "";
+ $plugins = $this->plugins;
+ $pluginCount = count($plugins);
+ $pluginIndex = array();
+ $pluginTriggerStates = array();
+ $pluginTriggerChars = array();
+ for ($i = 0, $l = count($plugins); $i < $l; $i++)
+ {
+ $tPluginClassName = get_class($plugins[$i]);
+ $pluginTriggerChars[$i] = implode("", $plugins[$i]->getTriggerChars());
+ $tPluginTriggerStates = $plugins[$i]->getTriggerStates();
+ $pluginTriggerStates[$i] = $tPluginTriggerStates === false ? false : "|" . implode("|", $tPluginTriggerStates) . "|";
+ $pluginIndex[$tPluginClassName] = $i;
+ for ($ii = 0, $ll = strlen($pluginTriggerChars[$i]); $ii < $ll; $ii++)
+ {
+ $c = substr($pluginTriggerChars[$i], $ii, 1);
+ if (strpos($globalTriggerChars, $c) === false)
+ {
+ $globalTriggerChars .= $c;
+ }
+ }
+ }
+ // Normalise line endings
+ $source = str_replace("\r\n", "\n", $source); // Windows to Unix line endings
+ $source = str_replace("\r", "\n", $source); // Mac to Unix line endings
+ $this->source = $source;
+ // Variables
+ $buffer = &$this->buffer;
+ $exclusive = &$this->stateExclusive;
+ $state = &$this->state;
+ $c = $p = null;
+ // --
+ for ($i = 0, $l = strlen($source); $i < $l; $i++)
+ {
+ // Set the current Char
+ $c = $source[$i]; // Is faster than: $c = substr($source, $i, 1);
+ // Normalize and filter double whitespace characters
+ if ($exclusive === false)
+ {
+ if ($c === "\n" || $c === "\t")
+ {
+ $c = " ";
+ }
+ if ($c === " " && $p === " ")
+ {
+ continue;
+ }
+ }
+ $buffer .= $c;
+
+ // Fix case when value of url() contains parentheses, for example: url("data: ... ()")
+ if ($this->getState() == 'T_URL' && $c == ')') {
+ $trimmedBuffer = trim($buffer);
+ if (preg_match('@url\((\s+)?".+@', $trimmedBuffer)
+ && !preg_match('@url\((\s+)?".+"\)@', $trimmedBuffer)
+ || preg_match('@url\((\s+)?\'.+@', $trimmedBuffer)
+ && !preg_match('@url\((\s+)?\'.+\'\)@', $trimmedBuffer)
+ ) {
+ $p = $c; // Set the parent char
+ continue;
+ }
+ }
+
+ // Extended processing only if the current char is a global trigger char
+ if (strpos($globalTriggerChars, $c) !== false)
+ {
+ // Exclusive state is set; process with the exclusive plugin
+ if ($exclusive)
+ {
+ $tPluginIndex = $pluginIndex[$exclusive];
+ if (strpos($pluginTriggerChars[$tPluginIndex], $c) !== false && ($pluginTriggerStates[$tPluginIndex] === false || strpos($pluginTriggerStates[$tPluginIndex], $state) !== false))
+ {
+ $r = $plugins[$tPluginIndex]->parse($i, $c, $p, $state);
+ // Return value is TRUE => continue with next char
+ if ($r === true)
+ {
+ continue;
+ }
+ // Return value is numeric => set new index and continue with next char
+ elseif ($r !== false && $r != $i)
+ {
+ $i = $r;
+ continue;
+ }
+ }
+ }
+ // Else iterate through the plugins
+ else
+ {
+ $triggerState = "|" . $state . "|";
+ for ($ii = 0, $ll = $pluginCount; $ii < $ll; $ii++)
+ {
+ // Only process if the current char is one of the plugin trigger chars
+ if (strpos($pluginTriggerChars[$ii], $c) !== false && ($pluginTriggerStates[$ii] === false || strpos($pluginTriggerStates[$ii], $triggerState) !== false))
+ {
+ // Process with the plugin
+ $r = $plugins[$ii]->parse($i, $c, $p, $state);
+ // Return value is TRUE => break the plugin loop and and continue with next char
+ if ($r === true)
+ {
+ break;
+ }
+ // Return value is numeric => set new index, break the plugin loop and and continue with next char
+ elseif ($r !== false && $r != $i)
+ {
+ $i = $r;
+ break;
+ }
+ }
+ }
+ }
+ }
+ $p = $c; // Set the parent char
+ }
+ return $this->tokens;
+ }
+ /**
+ * Remove the last state of the state stack and return the removed stack value.
+ *
+ * @return integer Removed state value
+ */
+ public function popState()
+ {
+ $r = array_pop($this->states);
+ $this->state = $this->states[count($this->states) - 1];
+ return $r;
+ }
+ /**
+ * Adds a new state onto the state stack.
+ *
+ * @param integer $state State to add onto the state stack.
+ * @return integer The index of the added state in the state stacks
+ */
+ public function pushState($state)
+ {
+ $r = array_push($this->states, $state);
+ $this->state = $this->states[count($this->states) - 1];
+ return $r;
+ }
+ /**
+ * Sets/restores the buffer.
+ *
+ * @param string $buffer Buffer to set
+ * @return void
+ */
+ public function setBuffer($buffer)
+ {
+ $this->buffer = $buffer;
+ }
+ /**
+ * Set the exclusive state.
+ *
+ * @param string $exclusive Exclusive state
+ * @return void
+ */
+ public function setExclusive($exclusive)
+ {
+ $this->stateExclusive = $exclusive;
+ }
+ /**
+ * Set the media types state.
+ *
+ * @param array $mediaTypes Media types state
+ * @return void
+ */
+ public function setMediaTypes(array $mediaTypes)
+ {
+ $this->stateMediaTypes = $mediaTypes;
+ }
+ /**
+ * Sets the current state in the state stack; equals to {@link CssParser::popState()} + {@link CssParser::pushState()}.
+ *
+ * @param integer $state State to set
+ * @return integer
+ */
+ public function setState($state)
+ {
+ $r = array_pop($this->states);
+ array_push($this->states, $state);
+ $this->state = $this->states[count($this->states) - 1];
+ return $r;
+ }
+ /**
+ * Removes the exclusive state.
+ *
+ * @return void
+ */
+ public function unsetExclusive()
+ {
+ $this->stateExclusive = false;
+ }
+ /**
+ * Removes the media types state.
+ *
+ * @return void
+ */
+ public function unsetMediaTypes()
+ {
+ $this->stateMediaTypes = false;
+ }
+}
+
+/**
+ * {@link aCssFromatter Formatter} returning the CSS source in {@link http://goo.gl/j4XdU OTBS indent style} (The One True Brace Style).
+ *
+ * @package CssMin/Formatter
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssOtbsFormatter extends aCssFormatter
+{
+ /**
+ * Implements {@link aCssFormatter::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ $r = array();
+ $level = 0;
+ for ($i = 0, $l = count($this->tokens); $i < $l; $i++)
+ {
+ $token = $this->tokens[$i];
+ $class = get_class($token);
+ $indent = str_repeat($this->indent, $level);
+ if ($class === "CssCommentToken")
+ {
+ $lines = array_map("trim", explode("\n", $token->Comment));
+ for ($ii = 0, $ll = count($lines); $ii < $ll; $ii++)
+ {
+ $r[] = $indent . (substr($lines[$ii], 0, 1) == "*" ? " " : "") . $lines[$ii];
+ }
+ }
+ elseif ($class === "CssAtCharsetToken")
+ {
+ $r[] = $indent . "@charset " . $token->Charset . ";";
+ }
+ elseif ($class === "CssAtFontFaceStartToken")
+ {
+ $r[] = $indent . "@font-face {";
+ $level++;
+ }
+ elseif ($class === "CssAtImportToken")
+ {
+ $r[] = $indent . "@import " . $token->Import . " " . implode(", ", $token->MediaTypes) . ";";
+ }
+ elseif ($class === "CssAtKeyframesStartToken")
+ {
+ $r[] = $indent . "@keyframes " . $token->Name . " {";
+ $level++;
+ }
+ elseif ($class === "CssAtMediaStartToken")
+ {
+ $r[] = $indent . "@media " . implode(", ", $token->MediaTypes) . " {";
+ $level++;
+ }
+ elseif ($class === "CssAtPageStartToken")
+ {
+ $r[] = $indent . "@page {";
+ $level++;
+ }
+ elseif ($class === "CssAtVariablesStartToken")
+ {
+ $r[] = $indent . "@variables " . implode(", ", $token->MediaTypes) . " {";
+ $level++;
+ }
+ elseif ($class === "CssRulesetStartToken" || $class === "CssAtKeyframesRulesetStartToken")
+ {
+ $r[] = $indent . implode(", ", $token->Selectors) . " {";
+ $level++;
+ }
+ elseif ($class === "CssAtFontFaceDeclarationToken"
+ || $class === "CssAtKeyframesRulesetDeclarationToken"
+ || $class === "CssAtPageDeclarationToken"
+ || $class === "CssAtVariablesDeclarationToken"
+ || $class === "CssRulesetDeclarationToken"
+ )
+ {
+ $declaration = $indent . $token->Property . ": ";
+ if ($this->padding)
+ {
+ $declaration = str_pad($declaration, $this->padding, " ", STR_PAD_RIGHT);
+ }
+ $r[] = $declaration . $token->Value . ($token->IsImportant ? " !important" : "") . ";";
+ }
+ elseif ($class === "CssAtFontFaceEndToken"
+ || $class === "CssAtMediaEndToken"
+ || $class === "CssAtKeyframesEndToken"
+ || $class === "CssAtKeyframesRulesetEndToken"
+ || $class === "CssAtPageEndToken"
+ || $class === "CssAtVariablesEndToken"
+ || $class === "CssRulesetEndToken"
+ )
+ {
+ $level--;
+ $r[] = str_repeat($indent, $level) . "}";
+ }
+ }
+ return implode("\n", $r);
+ }
+}
+
+/**
+ * This {@link aCssToken CSS token} is a utility token that extends {@link aNullToken} and returns only a empty string.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssNullToken extends aCssToken
+{
+ /**
+ * Implements {@link aCssToken::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return "";
+ }
+}
+
+/**
+ * CSS Minifier.
+ *
+ * @package CssMin/Minifier
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssMinifier
+{
+ /**
+ * {@link aCssMinifierFilter Filters}.
+ *
+ * @var array
+ */
+ private $filters = array();
+ /**
+ * {@link aCssMinifierPlugin Plugins}.
+ *
+ * @var array
+ */
+ private $plugins = array();
+ /**
+ * Minified source.
+ *
+ * @var string
+ */
+ private $minified = "";
+ /**
+ * Constructer.
+ *
+ * Creates instances of {@link aCssMinifierFilter filters} and {@link aCssMinifierPlugin plugins}.
+ *
+ * @param string $source CSS source [optional]
+ * @param array $filters Filter configuration [optional]
+ * @param array $plugins Plugin configuration [optional]
+ * @return void
+ */
+ public function __construct($source = null, array $filters = null, array $plugins = null)
+ {
+ $filters = array_merge(array
+ (
+ "ImportImports" => false,
+ "RemoveComments" => true,
+ "RemoveEmptyRulesets" => true,
+ "RemoveEmptyAtBlocks" => true,
+ "ConvertLevel3Properties" => false,
+ "ConvertLevel3AtKeyframes" => false,
+ "Variables" => true,
+ "RemoveLastDelarationSemiColon" => true
+ ), is_array($filters) ? $filters : array());
+ $plugins = array_merge(array
+ (
+ "Variables" => true,
+ "ConvertFontWeight" => false,
+ "ConvertHslColors" => false,
+ "ConvertRgbColors" => false,
+ "ConvertNamedColors" => false,
+ "CompressColorValues" => false,
+ "CompressUnitValues" => false,
+ "CompressExpressionValues" => false
+ ), is_array($plugins) ? $plugins : array());
+ // Filters
+ foreach ($filters as $name => $config)
+ {
+ if ($config !== false)
+ {
+ $class = "Css" . $name . "MinifierFilter";
+ $config = is_array($config) ? $config : array();
+ if (class_exists($class))
+ {
+ $this->filters[] = new $class($this, $config);
+ }
+ else
+ {
+ CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": The filter <code>" . $name . "</code> with the class name <code>" . $class . "</code> was not found"));
+ }
+ }
+ }
+ // Plugins
+ foreach ($plugins as $name => $config)
+ {
+ if ($config !== false)
+ {
+ $class = "Css" . $name . "MinifierPlugin";
+ $config = is_array($config) ? $config : array();
+ if (class_exists($class))
+ {
+ $this->plugins[] = new $class($this, $config);
+ }
+ else
+ {
+ CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": The plugin <code>" . $name . "</code> with the class name <code>" . $class . "</code> was not found"));
+ }
+ }
+ }
+ // --
+ if (!is_null($source))
+ {
+ $this->minify($source);
+ }
+ }
+ /**
+ * Returns the minified Source.
+ *
+ * @return string
+ */
+ public function getMinified()
+ {
+ return $this->minified;
+ }
+ /**
+ * Returns a plugin by class name.
+ *
+ * @param string $name Class name of the plugin
+ * @return aCssMinifierPlugin
+ */
+ public function getPlugin($class)
+ {
+ static $index = null;
+ if (is_null($index))
+ {
+ $index = array();
+ for ($i = 0, $l = count($this->plugins); $i < $l; $i++)
+ {
+ $index[get_class($this->plugins[$i])] = $i;
+ }
+ }
+ return isset($index[$class]) ? $this->plugins[$index[$class]] : false;
+ }
+ /**
+ * Minifies the CSS source.
+ *
+ * @param string $source CSS source
+ * @return string
+ */
+ public function minify($source)
+ {
+ // Variables
+ $r = "";
+ $parser = new CssParser($source);
+ $tokens = $parser->getTokens();
+ $filters = $this->filters;
+ $filterCount = count($this->filters);
+ $plugins = $this->plugins;
+ $pluginCount = count($plugins);
+ $pluginIndex = array();
+ $pluginTriggerTokens = array();
+ $globalTriggerTokens = array();
+ for ($i = 0, $l = count($plugins); $i < $l; $i++)
+ {
+ $tPluginClassName = get_class($plugins[$i]);
+ $pluginTriggerTokens[$i] = $plugins[$i]->getTriggerTokens();
+ foreach ($pluginTriggerTokens[$i] as $v)
+ {
+ if (!in_array($v, $globalTriggerTokens))
+ {
+ $globalTriggerTokens[] = $v;
+ }
+ }
+ $pluginTriggerTokens[$i] = "|" . implode("|", $pluginTriggerTokens[$i]) . "|";
+ $pluginIndex[$tPluginClassName] = $i;
+ }
+ $globalTriggerTokens = "|" . implode("|", $globalTriggerTokens) . "|";
+ /*
+ * Apply filters
+ */
+ for($i = 0; $i < $filterCount; $i++)
+ {
+ // Apply the filter; if the return value is larger than 0...
+ if ($filters[$i]->apply($tokens) > 0)
+ {
+ // ...then filter null values and rebuild the token array
+ $tokens = array_values(array_filter($tokens));
+ }
+ }
+ $tokenCount = count($tokens);
+ /*
+ * Apply plugins
+ */
+ for($i = 0; $i < $tokenCount; $i++)
+ {
+ $triggerToken = "|" . get_class($tokens[$i]) . "|";
+ if (strpos($globalTriggerTokens, $triggerToken) !== false)
+ {
+ for($ii = 0; $ii < $pluginCount; $ii++)
+ {
+ if (strpos($pluginTriggerTokens[$ii], $triggerToken) !== false || $pluginTriggerTokens[$ii] === false)
+ {
+ // Apply the plugin; if the return value is TRUE continue to the next token
+ if ($plugins[$ii]->apply($tokens[$i]) === true)
+ {
+ continue 2;
+ }
+ }
+ }
+ }
+ }
+ // Stringify the tokens
+ for($i = 0; $i < $tokenCount; $i++)
+ {
+ $r .= (string) $tokens[$i];
+ }
+ $this->minified = $r;
+ return $r;
+ }
+}
+
+/**
+ * CssMin - A (simple) css minifier with benefits
+ *
+ * --
+ * Copyright (c) 2011 Joe Scylla <joe.scylla@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ * --
+ *
+ * @package CssMin
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssMin
+{
+ /**
+ * Index of classes
+ *
+ * @var array
+ */
+ private static $classIndex = array();
+ /**
+ * Parse/minify errors
+ *
+ * @var array
+ */
+ private static $errors = array();
+ /**
+ * Verbose output.
+ *
+ * @var boolean
+ */
+ private static $isVerbose = false;
+ /**
+ * {@link http://goo.gl/JrW54 Autoload} function of CssMin.
+ *
+ * @param string $class Name of the class
+ * @return void
+ */
+ public static function autoload($class)
+ {
+ if (isset(self::$classIndex[$class]))
+ {
+ require(self::$classIndex[$class]);
+ }
+ }
+ /**
+ * Return errors
+ *
+ * @return array of {CssError}.
+ */
+ public static function getErrors()
+ {
+ return self::$errors;
+ }
+ /**
+ * Returns if there were errors.
+ *
+ * @return boolean
+ */
+ public static function hasErrors()
+ {
+ return count(self::$errors) > 0;
+ }
+ /**
+ * Initialises CssMin.
+ *
+ * @return void
+ */
+ public static function initialise()
+ {
+ // Create the class index for autoloading or including
+ $paths = array(dirname(__FILE__));
+ for ($i = 0; $i < count($paths); $i++)
+ {
+ $path = $paths[$i];
+ $subDirectorys = glob($path . "*", GLOB_MARK | GLOB_ONLYDIR | GLOB_NOSORT);
+ if (is_array($subDirectorys))
+ {
+ foreach ($subDirectorys as $subDirectory)
+ {
+ $paths[] = $subDirectory;
+ }
+ }
+ $files = glob($path . "*.php", 0);
+ if (is_array($files))
+ {
+ foreach ($files as $file)
+ {
+ $class = substr(basename($file), 0, -4);
+ self::$classIndex[$class] = $file;
+ }
+ }
+ }
+ krsort(self::$classIndex);
+ // Only use autoloading if spl_autoload_register() is available and no __autoload() is defined (because
+ // __autoload() breaks if spl_autoload_register() is used.
+ if (function_exists("spl_autoload_register") && !is_callable("__autoload"))
+ {
+ spl_autoload_register(array(__CLASS__, "autoload"));
+ }
+ // Otherwise include all class files
+ else
+ {
+ foreach (self::$classIndex as $class => $file)
+ {
+ if (!class_exists($class))
+ {
+ require_once($file);
+ }
+ }
+ }
+ }
+ /**
+ * Minifies CSS source.
+ *
+ * @param string $source CSS source
+ * @param array $filters Filter configuration [optional]
+ * @param array $plugins Plugin configuration [optional]
+ * @return string Minified CSS
+ */
+ public static function minify($source, array $filters = null, array $plugins = null)
+ {
+ self::$errors = array();
+ $minifier = new CssMinifier($source, $filters, $plugins);
+ return $minifier->getMinified();
+ }
+ /**
+ * Parse the CSS source.
+ *
+ * @param string $source CSS source
+ * @param array $plugins Plugin configuration [optional]
+ * @return array Array of aCssToken
+ */
+ public static function parse($source, array $plugins = null)
+ {
+ self::$errors = array();
+ $parser = new CssParser($source, $plugins);
+ return $parser->getTokens();
+ }
+ /**
+ * --
+ *
+ * @param boolean $to
+ * @return boolean
+ */
+ public static function setVerbose($to)
+ {
+ self::$isVerbose = (boolean) $to;
+ return self::$isVerbose;
+ }
+ /**
+ * --
+ *
+ * @param CssError $error
+ * @return void
+ */
+ public static function triggerError(CssError $error)
+ {
+ self::$errors[] = $error;
+ if (self::$isVerbose)
+ {
+ trigger_error((string) $error, E_USER_WARNING);
+ }
+ }
+}
+// Initialises CssMin
+CssMin::initialise();
+
+/**
+ * This {@link aCssMinifierFilter minifier filter} import external css files defined with the @import at-rule into the
+ * current stylesheet.
+ *
+ * @package CssMin/Minifier/Filters
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssImportImportsMinifierFilter extends aCssMinifierFilter
+{
+ /**
+ * Array with already imported external stylesheets.
+ *
+ * @var array
+ */
+ private $imported = array();
+ /**
+ * Implements {@link aCssMinifierFilter::filter()}.
+ *
+ * @param array $tokens Array of objects of type aCssToken
+ * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array
+ */
+ public function apply(array &$tokens)
+ {
+ if (!isset($this->configuration["BasePath"]) || !is_dir($this->configuration["BasePath"]))
+ {
+ CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Base path <code>" . ($this->configuration["BasePath"] ? $this->configuration["BasePath"] : "null"). "</code> is not a directory"));
+ return 0;
+ }
+ for ($i = 0, $l = count($tokens); $i < $l; $i++)
+ {
+ if (get_class($tokens[$i]) === "CssAtImportToken")
+ {
+ $import = $this->configuration["BasePath"] . "/" . $tokens[$i]->Import;
+ // Import file was not found/is not a file
+ if (!is_file($import))
+ {
+ CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Import file <code>" . $import. "</code> was not found.", (string) $tokens[$i]));
+ }
+ // Import file already imported; remove this @import at-rule to prevent recursions
+ elseif (in_array($import, $this->imported))
+ {
+ CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Import file <code>" . $import. "</code> was already imported.", (string) $tokens[$i]));
+ $tokens[$i] = null;
+ }
+ else
+ {
+ $this->imported[] = $import;
+ $parser = new CssParser(file_get_contents($import));
+ $import = $parser->getTokens();
+ // The @import at-rule has media types defined requiring special handling
+ if (count($tokens[$i]->MediaTypes) > 0 && !(count($tokens[$i]->MediaTypes) == 1 && $tokens[$i]->MediaTypes[0] == "all"))
+ {
+ $blocks = array();
+ /*
+ * Filter or set media types of @import at-rule or remove the @import at-rule if no media type is matching the parent @import at-rule
+ */
+ for($ii = 0, $ll = count($import); $ii < $ll; $ii++)
+ {
+ if (get_class($import[$ii]) === "CssAtImportToken")
+ {
+ // @import at-rule defines no media type or only the "all" media type; set the media types to the one defined in the parent @import at-rule
+ if (count($import[$ii]->MediaTypes) == 0 || (count($import[$ii]->MediaTypes) == 1 && $import[$ii]->MediaTypes[0] == "all"))
+ {
+ $import[$ii]->MediaTypes = $tokens[$i]->MediaTypes;
+ }
+ // @import at-rule defineds one or more media types; filter out media types not matching with the parent @import at-rule
+ elseif (count($import[$ii]->MediaTypes) > 0)
+ {
+ foreach ($import[$ii]->MediaTypes as $index => $mediaType)
+ {
+ if (!in_array($mediaType, $tokens[$i]->MediaTypes))
+ {
+ unset($import[$ii]->MediaTypes[$index]);
+ }
+ }
+ $import[$ii]->MediaTypes = array_values($import[$ii]->MediaTypes);
+ // If there are no media types left in the @import at-rule remove the @import at-rule
+ if (count($import[$ii]->MediaTypes) == 0)
+ {
+ $import[$ii] = null;
+ }
+ }
+ }
+ }
+ /*
+ * Remove media types of @media at-rule block not defined in the @import at-rule
+ */
+ for($ii = 0, $ll = count($import); $ii < $ll; $ii++)
+ {
+ if (get_class($import[$ii]) === "CssAtMediaStartToken")
+ {
+ foreach ($import[$ii]->MediaTypes as $index => $mediaType)
+ {
+ if (!in_array($mediaType, $tokens[$i]->MediaTypes))
+ {
+ unset($import[$ii]->MediaTypes[$index]);
+ }
+ $import[$ii]->MediaTypes = array_values($import[$ii]->MediaTypes);
+ }
+ }
+ }
+ /*
+ * If no media types left of the @media at-rule block remove the complete block
+ */
+ for($ii = 0, $ll = count($import); $ii < $ll; $ii++)
+ {
+ if (get_class($import[$ii]) === "CssAtMediaStartToken")
+ {
+ if (count($import[$ii]->MediaTypes) === 0)
+ {
+ for ($iii = $ii; $iii < $ll; $iii++)
+ {
+ if (get_class($import[$iii]) === "CssAtMediaEndToken")
+ {
+ break;
+ }
+ }
+ if (get_class($import[$iii]) === "CssAtMediaEndToken")
+ {
+ array_splice($import, $ii, $iii - $ii + 1, array());
+ $ll = count($import);
+ }
+ }
+ }
+ }
+ /*
+ * If the media types of the @media at-rule equals the media types defined in the @import
+ * at-rule remove the CssAtMediaStartToken and CssAtMediaEndToken token
+ */
+ for($ii = 0, $ll = count($import); $ii < $ll; $ii++)
+ {
+ if (get_class($import[$ii]) === "CssAtMediaStartToken" && count(array_diff($tokens[$i]->MediaTypes, $import[$ii]->MediaTypes)) === 0)
+ {
+ for ($iii = $ii; $iii < $ll; $iii++)
+ {
+ if (get_class($import[$iii]) == "CssAtMediaEndToken")
+ {
+ break;
+ }
+ }
+ if (get_class($import[$iii]) == "CssAtMediaEndToken")
+ {
+ unset($import[$ii]);
+ unset($import[$iii]);
+ $import = array_values($import);
+ $ll = count($import);
+ }
+ }
+ }
+ /**
+ * Extract CssAtImportToken and CssAtCharsetToken tokens
+ */
+ for($ii = 0, $ll = count($import); $ii < $ll; $ii++)
+ {
+ $class = get_class($import[$ii]);
+ if ($class === "CssAtImportToken" || $class === "CssAtCharsetToken")
+ {
+ $blocks = array_merge($blocks, array_splice($import, $ii, 1, array()));
+ $ll = count($import);
+ }
+ }
+ /*
+ * Extract the @font-face, @media and @page at-rule block
+ */
+ for($ii = 0, $ll = count($import); $ii < $ll; $ii++)
+ {
+ $class = get_class($import[$ii]);
+ if ($class === "CssAtFontFaceStartToken" || $class === "CssAtMediaStartToken" || $class === "CssAtPageStartToken" || $class === "CssAtVariablesStartToken")
+ {
+ for ($iii = $ii; $iii < $ll; $iii++)
+ {
+ $class = get_class($import[$iii]);
+ if ($class === "CssAtFontFaceEndToken" || $class === "CssAtMediaEndToken" || $class === "CssAtPageEndToken" || $class === "CssAtVariablesEndToken")
+ {
+ break;
+ }
+ }
+ $class = get_class($import[$iii]);
+ if (isset($import[$iii]) && ($class === "CssAtFontFaceEndToken" || $class === "CssAtMediaEndToken" || $class === "CssAtPageEndToken" || $class === "CssAtVariablesEndToken"))
+ {
+ $blocks = array_merge($blocks, array_splice($import, $ii, $iii - $ii + 1, array()));
+ $ll = count($import);
+ }
+ }
+ }
+ // Create the import array with extracted tokens and the rulesets wrapped into a @media at-rule block
+ $import = array_merge($blocks, array(new CssAtMediaStartToken($tokens[$i]->MediaTypes)), $import, array(new CssAtMediaEndToken()));
+ }
+ // Insert the imported tokens
+ array_splice($tokens, $i, 1, $import);
+ // Modify parameters of the for-loop
+ $i--;
+ $l = count($tokens);
+ }
+ }
+ }
+ }
+}
+
+/**
+ * {@link aCssParserPlugin Parser plugin} for preserve parsing expression() declaration values.
+ *
+ * This plugin return no {@link aCssToken CssToken} but ensures that expression() declaration values will get parsed
+ * properly.
+ *
+ * @package CssMin/Parser/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssExpressionParserPlugin extends aCssParserPlugin
+{
+ /**
+ * Count of left braces.
+ *
+ * @var integer
+ */
+ private $leftBraces = 0;
+ /**
+ * Count of right braces.
+ *
+ * @var integer
+ */
+ private $rightBraces = 0;
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerChars()}.
+ *
+ * @return array
+ */
+ public function getTriggerChars()
+ {
+ return array("(", ")", ";", "}");
+ }
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerStates()}.
+ *
+ * @return array
+ */
+ public function getTriggerStates()
+ {
+ return false;
+ }
+ /**
+ * Implements {@link aCssParserPlugin::parse()}.
+ *
+ * @param integer $index Current index
+ * @param string $char Current char
+ * @param string $previousChar Previous char
+ * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
+ */
+ public function parse($index, $char, $previousChar, $state)
+ {
+ // Start of expression
+ if ($char === "(" && strtolower(substr($this->parser->getSource(), $index - 10, 11)) === "expression(" && $state !== "T_EXPRESSION")
+ {
+ $this->parser->pushState("T_EXPRESSION");
+ $this->leftBraces++;
+ }
+ // Count left braces
+ elseif ($char === "(" && $state === "T_EXPRESSION")
+ {
+ $this->leftBraces++;
+ }
+ // Count right braces
+ elseif ($char === ")" && $state === "T_EXPRESSION")
+ {
+ $this->rightBraces++;
+ }
+ // Possible end of expression; if left and right braces are equal the expressen ends
+ elseif (($char === ";" || $char === "}") && $state === "T_EXPRESSION" && $this->leftBraces === $this->rightBraces)
+ {
+ $this->leftBraces = $this->rightBraces = 0;
+ $this->parser->popState();
+ return $index - 1;
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+ }
+}
+
+/**
+ * CSS Error.
+ *
+ * @package CssMin
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssError
+{
+ /**
+ * File.
+ *
+ * @var string
+ */
+ public $File = "";
+ /**
+ * Line.
+ *
+ * @var integer
+ */
+ public $Line = 0;
+ /**
+ * Error message.
+ *
+ * @var string
+ */
+ public $Message = "";
+ /**
+ * Source.
+ *
+ * @var string
+ */
+ public $Source = "";
+ /**
+ * Constructor triggering the error.
+ *
+ * @param string $message Error message
+ * @param string $source Corresponding line [optional]
+ * @return void
+ */
+ public function __construct($file, $line, $message, $source = "")
+ {
+ $this->File = $file;
+ $this->Line = $line;
+ $this->Message = $message;
+ $this->Source = $source;
+ }
+ /**
+ * Returns the error as formatted string.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->Message . ($this->Source ? ": <br /><code>" . $this->Source . "</code>": "") . "<br />in file " . $this->File . " at line " . $this->Line;
+ }
+}
+
+/**
+ * This {@link aCssMinifierPlugin} will convert a color value in rgb notation to hexadecimal notation.
+ *
+ * Example:
+ * <code>
+ * color: rgb(200,60%,5);
+ * </code>
+ *
+ * Will get converted to:
+ * <code>
+ * color:#c89905;
+ * </code>
+ *
+ * @package CssMin/Minifier/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssConvertRgbColorsMinifierPlugin extends aCssMinifierPlugin
+{
+ /**
+ * Regular expression matching the value.
+ *
+ * @var string
+ */
+ private $reMatch = "/rgb\s*\(\s*([0-9%]+)\s*,\s*([0-9%]+)\s*,\s*([0-9%]+)\s*\)/iS";
+ /**
+ * Implements {@link aCssMinifierPlugin::minify()}.
+ *
+ * @param aCssToken $token Token to process
+ * @return boolean Return TRUE to break the processing of this token; FALSE to continue
+ */
+ public function apply(aCssToken &$token)
+ {
+ if (stripos($token->Value, "rgb") !== false && preg_match($this->reMatch, $token->Value, $m))
+ {
+ for ($i = 1, $l = count($m); $i < $l; $i++)
+ {
+ if (strpos("%", $m[$i]) !== false)
+ {
+ $m[$i] = substr($m[$i], 0, -1);
+ $m[$i] = (int) (256 * ($m[$i] / 100));
+ }
+ $m[$i] = str_pad(dechex($m[$i]), 2, "0", STR_PAD_LEFT);
+ }
+ $token->Value = str_replace($m[0], "#" . $m[1] . $m[2] . $m[3], $token->Value);
+ }
+ return false;
+ }
+ /**
+ * Implements {@link aMinifierPlugin::getTriggerTokens()}
+ *
+ * @return array
+ */
+ public function getTriggerTokens()
+ {
+ return array
+ (
+ "CssAtFontFaceDeclarationToken",
+ "CssAtPageDeclarationToken",
+ "CssRulesetDeclarationToken"
+ );
+ }
+}
+
+/**
+ * This {@link aCssMinifierPlugin} will convert named color values to hexadecimal notation.
+ *
+ * Example:
+ * <code>
+ * color: black;
+ * border: 1px solid indigo;
+ * </code>
+ *
+ * Will get converted to:
+ * <code>
+ * color:#000;
+ * border:1px solid #4b0082;
+ * </code>
+ *
+ * @package CssMin/Minifier/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssConvertNamedColorsMinifierPlugin extends aCssMinifierPlugin
+{
+
+ /**
+ * Regular expression matching the value.
+ *
+ * @var string
+ */
+ private $reMatch = null;
+ /**
+ * Transformation table used by the {@link CssConvertNamedColorsMinifierPlugin::reReplace() replacement method}.
+ *
+ * @var array
+ */
+ private $transformation = array
+ (
+ "aliceblue" => "#f0f8ff",
+ "antiquewhite" => "#faebd7",
+ "aqua" => "#0ff",
+ "aquamarine" => "#7fffd4",
+ "azure" => "#f0ffff",
+ "beige" => "#f5f5dc",
+ "black" => "#000",
+ "blue" => "#00f",
+ "blueviolet" => "#8a2be2",
+ "brown" => "#a52a2a",
+ "burlywood" => "#deb887",
+ "cadetblue" => "#5f9ea0",
+ "chartreuse" => "#7fff00",
+ "chocolate" => "#d2691e",
+ "coral" => "#ff7f50",
+ "cornflowerblue" => "#6495ed",
+ "cornsilk" => "#fff8dc",
+ "crimson" => "#dc143c",
+ "darkblue" => "#00008b",
+ "darkcyan" => "#008b8b",
+ "darkgoldenrod" => "#b8860b",
+ "darkgray" => "#a9a9a9",
+ "darkgreen" => "#006400",
+ "darkkhaki" => "#bdb76b",
+ "darkmagenta" => "#8b008b",
+ "darkolivegreen" => "#556b2f",
+ "darkorange" => "#ff8c00",
+ "darkorchid" => "#9932cc",
+ "darkred" => "#8b0000",
+ "darksalmon" => "#e9967a",
+ "darkseagreen" => "#8fbc8f",
+ "darkslateblue" => "#483d8b",
+ "darkslategray" => "#2f4f4f",
+ "darkturquoise" => "#00ced1",
+ "darkviolet" => "#9400d3",
+ "deeppink" => "#ff1493",
+ "deepskyblue" => "#00bfff",
+ "dimgray" => "#696969",
+ "dodgerblue" => "#1e90ff",
+ "firebrick" => "#b22222",
+ "floralwhite" => "#fffaf0",
+ "forestgreen" => "#228b22",
+ "fuchsia" => "#f0f",
+ "gainsboro" => "#dcdcdc",
+ "ghostwhite" => "#f8f8ff",
+ "gold" => "#ffd700",
+ "goldenrod" => "#daa520",
+ "gray" => "#808080",
+ "green" => "#008000",
+ "greenyellow" => "#adff2f",
+ "honeydew" => "#f0fff0",
+ "hotpink" => "#ff69b4",
+ "indianred" => "#cd5c5c",
+ "indigo" => "#4b0082",
+ "ivory" => "#fffff0",
+ "khaki" => "#f0e68c",
+ "lavender" => "#e6e6fa",
+ "lavenderblush" => "#fff0f5",
+ "lawngreen" => "#7cfc00",
+ "lemonchiffon" => "#fffacd",
+ "lightblue" => "#add8e6",
+ "lightcoral" => "#f08080",
+ "lightcyan" => "#e0ffff",
+ "lightgoldenrodyellow" => "#fafad2",
+ "lightgreen" => "#90ee90",
+ "lightgrey" => "#d3d3d3",
+ "lightpink" => "#ffb6c1",
+ "lightsalmon" => "#ffa07a",
+ "lightseagreen" => "#20b2aa",
+ "lightskyblue" => "#87cefa",
+ "lightslategray" => "#789",
+ "lightsteelblue" => "#b0c4de",
+ "lightyellow" => "#ffffe0",
+ "lime" => "#0f0",
+ "limegreen" => "#32cd32",
+ "linen" => "#faf0e6",
+ "maroon" => "#800000",
+ "mediumaquamarine" => "#66cdaa",
+ "mediumblue" => "#0000cd",
+ "mediumorchid" => "#ba55d3",
+ "mediumpurple" => "#9370db",
+ "mediumseagreen" => "#3cb371",
+ "mediumslateblue" => "#7b68ee",
+ "mediumspringgreen" => "#00fa9a",
+ "mediumturquoise" => "#48d1cc",
+ "mediumvioletred" => "#c71585",
+ "midnightblue" => "#191970",
+ "mintcream" => "#f5fffa",
+ "mistyrose" => "#ffe4e1",
+ "moccasin" => "#ffe4b5",
+ "navajowhite" => "#ffdead",
+ "navy" => "#000080",
+ "oldlace" => "#fdf5e6",
+ "olive" => "#808000",
+ "olivedrab" => "#6b8e23",
+ "orange" => "#ffa500",
+ "orangered" => "#ff4500",
+ "orchid" => "#da70d6",
+ "palegoldenrod" => "#eee8aa",
+ "palegreen" => "#98fb98",
+ "paleturquoise" => "#afeeee",
+ "palevioletred" => "#db7093",
+ "papayawhip" => "#ffefd5",
+ "peachpuff" => "#ffdab9",
+ "peru" => "#cd853f",
+ "pink" => "#ffc0cb",
+ "plum" => "#dda0dd",
+ "powderblue" => "#b0e0e6",
+ "purple" => "#800080",
+ "red" => "#f00",
+ "rosybrown" => "#bc8f8f",
+ "royalblue" => "#4169e1",
+ "saddlebrown" => "#8b4513",
+ "salmon" => "#fa8072",
+ "sandybrown" => "#f4a460",
+ "seagreen" => "#2e8b57",
+ "seashell" => "#fff5ee",
+ "sienna" => "#a0522d",
+ "silver" => "#c0c0c0",
+ "skyblue" => "#87ceeb",
+ "slateblue" => "#6a5acd",
+ "slategray" => "#708090",
+ "snow" => "#fffafa",
+ "springgreen" => "#00ff7f",
+ "steelblue" => "#4682b4",
+ "tan" => "#d2b48c",
+ "teal" => "#008080",
+ "thistle" => "#d8bfd8",
+ "tomato" => "#ff6347",
+ "turquoise" => "#40e0d0",
+ "violet" => "#ee82ee",
+ "wheat" => "#f5deb3",
+ "white" => "#fff",
+ "whitesmoke" => "#f5f5f5",
+ "yellow" => "#ff0",
+ "yellowgreen" => "#9acd32"
+ );
+ /**
+ * Overwrites {@link aCssMinifierPlugin::__construct()}.
+ *
+ * The constructor will create the {@link CssConvertNamedColorsMinifierPlugin::$reMatch replace regular expression}
+ * based on the {@link CssConvertNamedColorsMinifierPlugin::$transformation transformation table}.
+ *
+ * @param CssMinifier $minifier The CssMinifier object of this plugin.
+ * @param array $configuration Plugin configuration [optional]
+ * @return void
+ */
+ public function __construct(CssMinifier $minifier, array $configuration = array())
+ {
+ $this->reMatch = "/(^|\s)+(" . implode("|", array_keys($this->transformation)) . ")(\s|$)+/iS";
+ parent::__construct($minifier, $configuration);
+ }
+ /**
+ * Implements {@link aCssMinifierPlugin::minify()}.
+ *
+ * @param aCssToken $token Token to process
+ * @return boolean Return TRUE to break the processing of this token; FALSE to continue
+ */
+ public function apply(aCssToken &$token)
+ {
+ $lcValue = strtolower($token->Value);
+ // Declaration value equals a value in the transformation table => simple replace
+ if (isset($this->transformation[$lcValue]))
+ {
+ $token->Value = $this->transformation[$lcValue];
+ }
+ // Declaration value contains a value in the transformation table => regular expression replace
+ elseif (preg_match($this->reMatch, $token->Value))
+ {
+ $token->Value = preg_replace_callback($this->reMatch, array($this, 'reReplace'), $token->Value);
+ }
+ return false;
+ }
+ /**
+ * Callback for replacement value.
+ *
+ * @param array $match
+ * @return string
+ */
+ private function reReplace($match)
+ {
+ return $match[1] . $this->transformation[strtolower($match[2])] . $match[3];
+ }
+ /**
+ * Implements {@link aMinifierPlugin::getTriggerTokens()}
+ *
+ * @return array
+ */
+ public function getTriggerTokens()
+ {
+ return array
+ (
+ "CssAtFontFaceDeclarationToken",
+ "CssAtPageDeclarationToken",
+ "CssRulesetDeclarationToken"
+ );
+ }
+}
+
+/**
+ * This {@link aCssMinifierFilter minifier filter} triggers on CSS Level 3 properties and will add declaration tokens
+ * with browser-specific properties.
+ *
+ * @package CssMin/Minifier/Filters
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssConvertLevel3PropertiesMinifierFilter extends aCssMinifierFilter
+{
+ /**
+ * Css property transformations table. Used to convert CSS3 and proprietary properties to the browser-specific
+ * counterparts.
+ *
+ * @var array
+ */
+ private $transformations = array
+ (
+ // Property Array(Mozilla, Webkit, Opera, Internet Explorer); NULL values are placeholders and will get ignored
+ "animation" => array(null, "-webkit-animation", null, null),
+ "animation-delay" => array(null, "-webkit-animation-delay", null, null),
+ "animation-direction" => array(null, "-webkit-animation-direction", null, null),
+ "animation-duration" => array(null, "-webkit-animation-duration", null, null),
+ "animation-fill-mode" => array(null, "-webkit-animation-fill-mode", null, null),
+ "animation-iteration-count" => array(null, "-webkit-animation-iteration-count", null, null),
+ "animation-name" => array(null, "-webkit-animation-name", null, null),
+ "animation-play-state" => array(null, "-webkit-animation-play-state", null, null),
+ "animation-timing-function" => array(null, "-webkit-animation-timing-function", null, null),
+ "appearance" => array("-moz-appearance", "-webkit-appearance", null, null),
+ "backface-visibility" => array(null, "-webkit-backface-visibility", null, null),
+ "background-clip" => array(null, "-webkit-background-clip", null, null),
+ "background-composite" => array(null, "-webkit-background-composite", null, null),
+ "background-inline-policy" => array("-moz-background-inline-policy", null, null, null),
+ "background-origin" => array(null, "-webkit-background-origin", null, null),
+ "background-position-x" => array(null, null, null, "-ms-background-position-x"),
+ "background-position-y" => array(null, null, null, "-ms-background-position-y"),
+ "background-size" => array(null, "-webkit-background-size", null, null),
+ "behavior" => array(null, null, null, "-ms-behavior"),
+ "binding" => array("-moz-binding", null, null, null),
+ "border-after" => array(null, "-webkit-border-after", null, null),
+ "border-after-color" => array(null, "-webkit-border-after-color", null, null),
+ "border-after-style" => array(null, "-webkit-border-after-style", null, null),
+ "border-after-width" => array(null, "-webkit-border-after-width", null, null),
+ "border-before" => array(null, "-webkit-border-before", null, null),
+ "border-before-color" => array(null, "-webkit-border-before-color", null, null),
+ "border-before-style" => array(null, "-webkit-border-before-style", null, null),
+ "border-before-width" => array(null, "-webkit-border-before-width", null, null),
+ "border-border-bottom-colors" => array("-moz-border-bottom-colors", null, null, null),
+ "border-bottom-left-radius" => array("-moz-border-radius-bottomleft", "-webkit-border-bottom-left-radius", null, null),
+ "border-bottom-right-radius" => array("-moz-border-radius-bottomright", "-webkit-border-bottom-right-radius", null, null),
+ "border-end" => array("-moz-border-end", "-webkit-border-end", null, null),
+ "border-end-color" => array("-moz-border-end-color", "-webkit-border-end-color", null, null),
+ "border-end-style" => array("-moz-border-end-style", "-webkit-border-end-style", null, null),
+ "border-end-width" => array("-moz-border-end-width", "-webkit-border-end-width", null, null),
+ "border-fit" => array(null, "-webkit-border-fit", null, null),
+ "border-horizontal-spacing" => array(null, "-webkit-border-horizontal-spacing", null, null),
+ "border-image" => array("-moz-border-image", "-webkit-border-image", null, null),
+ "border-left-colors" => array("-moz-border-left-colors", null, null, null),
+ "border-radius" => array("-moz-border-radius", "-webkit-border-radius", null, null),
+ "border-border-right-colors" => array("-moz-border-right-colors", null, null, null),
+ "border-start" => array("-moz-border-start", "-webkit-border-start", null, null),
+ "border-start-color" => array("-moz-border-start-color", "-webkit-border-start-color", null, null),
+ "border-start-style" => array("-moz-border-start-style", "-webkit-border-start-style", null, null),
+ "border-start-width" => array("-moz-border-start-width", "-webkit-border-start-width", null, null),
+ "border-top-colors" => array("-moz-border-top-colors", null, null, null),
+ "border-top-left-radius" => array("-moz-border-radius-topleft", "-webkit-border-top-left-radius", null, null),
+ "border-top-right-radius" => array("-moz-border-radius-topright", "-webkit-border-top-right-radius", null, null),
+ "border-vertical-spacing" => array(null, "-webkit-border-vertical-spacing", null, null),
+ "box-align" => array("-moz-box-align", "-webkit-box-align", null, null),
+ "box-direction" => array("-moz-box-direction", "-webkit-box-direction", null, null),
+ "box-flex" => array("-moz-box-flex", "-webkit-box-flex", null, null),
+ "box-flex-group" => array(null, "-webkit-box-flex-group", null, null),
+ "box-flex-lines" => array(null, "-webkit-box-flex-lines", null, null),
+ "box-ordinal-group" => array("-moz-box-ordinal-group", "-webkit-box-ordinal-group", null, null),
+ "box-orient" => array("-moz-box-orient", "-webkit-box-orient", null, null),
+ "box-pack" => array("-moz-box-pack", "-webkit-box-pack", null, null),
+ "box-reflect" => array(null, "-webkit-box-reflect", null, null),
+ "box-shadow" => array("-moz-box-shadow", "-webkit-box-shadow", null, null),
+ "box-sizing" => array("-moz-box-sizing", null, null, null),
+ "color-correction" => array(null, "-webkit-color-correction", null, null),
+ "column-break-after" => array(null, "-webkit-column-break-after", null, null),
+ "column-break-before" => array(null, "-webkit-column-break-before", null, null),
+ "column-break-inside" => array(null, "-webkit-column-break-inside", null, null),
+ "column-count" => array("-moz-column-count", "-webkit-column-count", null, null),
+ "column-gap" => array("-moz-column-gap", "-webkit-column-gap", null, null),
+ "column-rule" => array("-moz-column-rule", "-webkit-column-rule", null, null),
+ "column-rule-color" => array("-moz-column-rule-color", "-webkit-column-rule-color", null, null),
+ "column-rule-style" => array("-moz-column-rule-style", "-webkit-column-rule-style", null, null),
+ "column-rule-width" => array("-moz-column-rule-width", "-webkit-column-rule-width", null, null),
+ "column-span" => array(null, "-webkit-column-span", null, null),
+ "column-width" => array("-moz-column-width", "-webkit-column-width", null, null),
+ "columns" => array(null, "-webkit-columns", null, null),
+ "filter" => array(__CLASS__, "filter"),
+ "float-edge" => array("-moz-float-edge", null, null, null),
+ "font-feature-settings" => array("-moz-font-feature-settings", null, null, null),
+ "font-language-override" => array("-moz-font-language-override", null, null, null),
+ "font-size-delta" => array(null, "-webkit-font-size-delta", null, null),
+ "font-smoothing" => array(null, "-webkit-font-smoothing", null, null),
+ "force-broken-image-icon" => array("-moz-force-broken-image-icon", null, null, null),
+ "highlight" => array(null, "-webkit-highlight", null, null),
+ "hyphenate-character" => array(null, "-webkit-hyphenate-character", null, null),
+ "hyphenate-locale" => array(null, "-webkit-hyphenate-locale", null, null),
+ "hyphens" => array(null, "-webkit-hyphens", null, null),
+ "force-broken-image-icon" => array("-moz-image-region", null, null, null),
+ "ime-mode" => array(null, null, null, "-ms-ime-mode"),
+ "interpolation-mode" => array(null, null, null, "-ms-interpolation-mode"),
+ "layout-flow" => array(null, null, null, "-ms-layout-flow"),
+ "layout-grid" => array(null, null, null, "-ms-layout-grid"),
+ "layout-grid-char" => array(null, null, null, "-ms-layout-grid-char"),
+ "layout-grid-line" => array(null, null, null, "-ms-layout-grid-line"),
+ "layout-grid-mode" => array(null, null, null, "-ms-layout-grid-mode"),
+ "layout-grid-type" => array(null, null, null, "-ms-layout-grid-type"),
+ "line-break" => array(null, "-webkit-line-break", null, "-ms-line-break"),
+ "line-clamp" => array(null, "-webkit-line-clamp", null, null),
+ "line-grid-mode" => array(null, null, null, "-ms-line-grid-mode"),
+ "logical-height" => array(null, "-webkit-logical-height", null, null),
+ "logical-width" => array(null, "-webkit-logical-width", null, null),
+ "margin-after" => array(null, "-webkit-margin-after", null, null),
+ "margin-after-collapse" => array(null, "-webkit-margin-after-collapse", null, null),
+ "margin-before" => array(null, "-webkit-margin-before", null, null),
+ "margin-before-collapse" => array(null, "-webkit-margin-before-collapse", null, null),
+ "margin-bottom-collapse" => array(null, "-webkit-margin-bottom-collapse", null, null),
+ "margin-collapse" => array(null, "-webkit-margin-collapse", null, null),
+ "margin-end" => array("-moz-margin-end", "-webkit-margin-end", null, null),
+ "margin-start" => array("-moz-margin-start", "-webkit-margin-start", null, null),
+ "margin-top-collapse" => array(null, "-webkit-margin-top-collapse", null, null),
+ "marquee " => array(null, "-webkit-marquee", null, null),
+ "marquee-direction" => array(null, "-webkit-marquee-direction", null, null),
+ "marquee-increment" => array(null, "-webkit-marquee-increment", null, null),
+ "marquee-repetition" => array(null, "-webkit-marquee-repetition", null, null),
+ "marquee-speed" => array(null, "-webkit-marquee-speed", null, null),
+ "marquee-style" => array(null, "-webkit-marquee-style", null, null),
+ "mask" => array(null, "-webkit-mask", null, null),
+ "mask-attachment" => array(null, "-webkit-mask-attachment", null, null),
+ "mask-box-image" => array(null, "-webkit-mask-box-image", null, null),
+ "mask-clip" => array(null, "-webkit-mask-clip", null, null),
+ "mask-composite" => array(null, "-webkit-mask-composite", null, null),
+ "mask-image" => array(null, "-webkit-mask-image", null, null),
+ "mask-origin" => array(null, "-webkit-mask-origin", null, null),
+ "mask-position" => array(null, "-webkit-mask-position", null, null),
+ "mask-position-x" => array(null, "-webkit-mask-position-x", null, null),
+ "mask-position-y" => array(null, "-webkit-mask-position-y", null, null),
+ "mask-repeat" => array(null, "-webkit-mask-repeat", null, null),
+ "mask-repeat-x" => array(null, "-webkit-mask-repeat-x", null, null),
+ "mask-repeat-y" => array(null, "-webkit-mask-repeat-y", null, null),
+ "mask-size" => array(null, "-webkit-mask-size", null, null),
+ "match-nearest-mail-blockquote-color" => array(null, "-webkit-match-nearest-mail-blockquote-color", null, null),
+ "max-logical-height" => array(null, "-webkit-max-logical-height", null, null),
+ "max-logical-width" => array(null, "-webkit-max-logical-width", null, null),
+ "min-logical-height" => array(null, "-webkit-min-logical-height", null, null),
+ "min-logical-width" => array(null, "-webkit-min-logical-width", null, null),
+ "object-fit" => array(null, null, "-o-object-fit", null),
+ "object-position" => array(null, null, "-o-object-position", null),
+ "opacity" => array(__CLASS__, "opacity"),
+ "outline-radius" => array("-moz-outline-radius", null, null, null),
+ "outline-bottom-left-radius" => array("-moz-outline-radius-bottomleft", null, null, null),
+ "outline-bottom-right-radius" => array("-moz-outline-radius-bottomright", null, null, null),
+ "outline-top-left-radius" => array("-moz-outline-radius-topleft", null, null, null),
+ "outline-top-right-radius" => array("-moz-outline-radius-topright", null, null, null),
+ "padding-after" => array(null, "-webkit-padding-after", null, null),
+ "padding-before" => array(null, "-webkit-padding-before", null, null),
+ "padding-end" => array("-moz-padding-end", "-webkit-padding-end", null, null),
+ "padding-start" => array("-moz-padding-start", "-webkit-padding-start", null, null),
+ "perspective" => array(null, "-webkit-perspective", null, null),
+ "perspective-origin" => array(null, "-webkit-perspective-origin", null, null),
+ "perspective-origin-x" => array(null, "-webkit-perspective-origin-x", null, null),
+ "perspective-origin-y" => array(null, "-webkit-perspective-origin-y", null, null),
+ "rtl-ordering" => array(null, "-webkit-rtl-ordering", null, null),
+ "scrollbar-3dlight-color" => array(null, null, null, "-ms-scrollbar-3dlight-color"),
+ "scrollbar-arrow-color" => array(null, null, null, "-ms-scrollbar-arrow-color"),
+ "scrollbar-base-color" => array(null, null, null, "-ms-scrollbar-base-color"),
+ "scrollbar-darkshadow-color" => array(null, null, null, "-ms-scrollbar-darkshadow-color"),
+ "scrollbar-face-color" => array(null, null, null, "-ms-scrollbar-face-color"),
+ "scrollbar-highlight-color" => array(null, null, null, "-ms-scrollbar-highlight-color"),
+ "scrollbar-shadow-color" => array(null, null, null, "-ms-scrollbar-shadow-color"),
+ "scrollbar-track-color" => array(null, null, null, "-ms-scrollbar-track-color"),
+ "stack-sizing" => array("-moz-stack-sizing", null, null, null),
+ "svg-shadow" => array(null, "-webkit-svg-shadow", null, null),
+ "tab-size" => array("-moz-tab-size", null, "-o-tab-size", null),
+ "table-baseline" => array(null, null, "-o-table-baseline", null),
+ "text-align-last" => array(null, null, null, "-ms-text-align-last"),
+ "text-autospace" => array(null, null, null, "-ms-text-autospace"),
+ "text-combine" => array(null, "-webkit-text-combine", null, null),
+ "text-decorations-in-effect" => array(null, "-webkit-text-decorations-in-effect", null, null),
+ "text-emphasis" => array(null, "-webkit-text-emphasis", null, null),
+ "text-emphasis-color" => array(null, "-webkit-text-emphasis-color", null, null),
+ "text-emphasis-position" => array(null, "-webkit-text-emphasis-position", null, null),
+ "text-emphasis-style" => array(null, "-webkit-text-emphasis-style", null, null),
+ "text-fill-color" => array(null, "-webkit-text-fill-color", null, null),
+ "text-justify" => array(null, null, null, "-ms-text-justify"),
+ "text-kashida-space" => array(null, null, null, "-ms-text-kashida-space"),
+ "text-overflow" => array(null, null, "-o-text-overflow", "-ms-text-overflow"),
+ "text-security" => array(null, "-webkit-text-security", null, null),
+ "text-size-adjust" => array(null, "-webkit-text-size-adjust", null, "-ms-text-size-adjust"),
+ "text-stroke" => array(null, "-webkit-text-stroke", null, null),
+ "text-stroke-color" => array(null, "-webkit-text-stroke-color", null, null),
+ "text-stroke-width" => array(null, "-webkit-text-stroke-width", null, null),
+ "text-underline-position" => array(null, null, null, "-ms-text-underline-position"),
+ "transform" => array("-moz-transform", "-webkit-transform", "-o-transform", null),
+ "transform-origin" => array("-moz-transform-origin", "-webkit-transform-origin", "-o-transform-origin", null),
+ "transform-origin-x" => array(null, "-webkit-transform-origin-x", null, null),
+ "transform-origin-y" => array(null, "-webkit-transform-origin-y", null, null),
+ "transform-origin-z" => array(null, "-webkit-transform-origin-z", null, null),
+ "transform-style" => array(null, "-webkit-transform-style", null, null),
+ "transition" => array("-moz-transition", "-webkit-transition", "-o-transition", null),
+ "transition-delay" => array("-moz-transition-delay", "-webkit-transition-delay", "-o-transition-delay", null),
+ "transition-duration" => array("-moz-transition-duration", "-webkit-transition-duration", "-o-transition-duration", null),
+ "transition-property" => array("-moz-transition-property", "-webkit-transition-property", "-o-transition-property", null),
+ "transition-timing-function" => array("-moz-transition-timing-function", "-webkit-transition-timing-function", "-o-transition-timing-function", null),
+ "user-drag" => array(null, "-webkit-user-drag", null, null),
+ "user-focus" => array("-moz-user-focus", null, null, null),
+ "user-input" => array("-moz-user-input", null, null, null),
+ "user-modify" => array("-moz-user-modify", "-webkit-user-modify", null, null),
+ "user-select" => array("-moz-user-select", "-webkit-user-select", null, null),
+ "white-space" => array(__CLASS__, "whiteSpace"),
+ "window-shadow" => array("-moz-window-shadow", null, null, null),
+ "word-break" => array(null, null, null, "-ms-word-break"),
+ "word-wrap" => array(null, null, null, "-ms-word-wrap"),
+ "writing-mode" => array(null, "-webkit-writing-mode", null, "-ms-writing-mode"),
+ "zoom" => array(null, null, null, "-ms-zoom")
+ );
+ /**
+ * Implements {@link aCssMinifierFilter::filter()}.
+ *
+ * @param array $tokens Array of objects of type aCssToken
+ * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array
+ */
+ public function apply(array &$tokens)
+ {
+ $r = 0;
+ $transformations = &$this->transformations;
+ for ($i = 0, $l = count($tokens); $i < $l; $i++)
+ {
+ if (get_class($tokens[$i]) === "CssRulesetDeclarationToken")
+ {
+ $tProperty = $tokens[$i]->Property;
+ if (isset($transformations[$tProperty]))
+ {
+ $result = array();
+ if (is_callable($transformations[$tProperty]))
+ {
+ $result = call_user_func_array($transformations[$tProperty], array($tokens[$i]));
+ if (!is_array($result) && is_object($result))
+ {
+ $result = array($result);
+ }
+ }
+ else
+ {
+ $tValue = $tokens[$i]->Value;
+ $tMediaTypes = $tokens[$i]->MediaTypes;
+ foreach ($transformations[$tProperty] as $property)
+ {
+ if ($property !== null)
+ {
+ $result[] = new CssRulesetDeclarationToken($property, $tValue, $tMediaTypes);
+ }
+ }
+ }
+ if (count($result) > 0)
+ {
+ array_splice($tokens, $i + 1, 0, $result);
+ $i += count($result);
+ $l += count($result);
+ }
+ }
+ }
+ }
+ return $r;
+ }
+ /**
+ * Transforms the Internet Explorer specific declaration property "filter" to Internet Explorer 8+ compatible
+ * declaratiopn property "-ms-filter".
+ *
+ * @param aCssToken $token
+ * @return array
+ */
+ private static function filter($token)
+ {
+ $r = array
+ (
+ new CssRulesetDeclarationToken("-ms-filter", "\"" . $token->Value . "\"", $token->MediaTypes),
+ );
+ return $r;
+ }
+ /**
+ * Transforms "opacity: {value}" into browser specific counterparts.
+ *
+ * @param aCssToken $token
+ * @return array
+ */
+ private static function opacity($token)
+ {
+ // Calculate the value for Internet Explorer filter statement
+ $ieValue = (int) ((float) $token->Value * 100);
+ $r = array
+ (
+ // Internet Explorer >= 8
+ new CssRulesetDeclarationToken("-ms-filter", "\"alpha(opacity=" . $ieValue . ")\"", $token->MediaTypes),
+ // Internet Explorer >= 4 <= 7
+ new CssRulesetDeclarationToken("filter", "alpha(opacity=" . $ieValue . ")", $token->MediaTypes),
+ new CssRulesetDeclarationToken("zoom", "1", $token->MediaTypes)
+ );
+ return $r;
+ }
+ /**
+ * Transforms "white-space: pre-wrap" into browser specific counterparts.
+ *
+ * @param aCssToken $token
+ * @return array
+ */
+ private static function whiteSpace($token)
+ {
+ if (strtolower($token->Value) === "pre-wrap")
+ {
+ $r = array
+ (
+ // Firefox < 3
+ new CssRulesetDeclarationToken("white-space", "-moz-pre-wrap", $token->MediaTypes),
+ // Webkit
+ new CssRulesetDeclarationToken("white-space", "-webkit-pre-wrap", $token->MediaTypes),
+ // Opera >= 4 <= 6
+ new CssRulesetDeclarationToken("white-space", "-pre-wrap", $token->MediaTypes),
+ // Opera >= 7
+ new CssRulesetDeclarationToken("white-space", "-o-pre-wrap", $token->MediaTypes),
+ // Internet Explorer >= 5.5
+ new CssRulesetDeclarationToken("word-wrap", "break-word", $token->MediaTypes)
+ );
+ return $r;
+ }
+ else
+ {
+ return array();
+ }
+ }
+}
+
+/**
+ * This {@link aCssMinifierFilter minifier filter} will convert @keyframes at-rule block to browser specific counterparts.
+ *
+ * @package CssMin/Minifier/Filters
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssConvertLevel3AtKeyframesMinifierFilter extends aCssMinifierFilter
+{
+ /**
+ * Implements {@link aCssMinifierFilter::filter()}.
+ *
+ * @param array $tokens Array of objects of type aCssToken
+ * @return integer Count of added, changed or removed tokens; a return value larger than 0 will rebuild the array
+ */
+ public function apply(array &$tokens)
+ {
+ $r = 0;
+ $transformations = array("-moz-keyframes", "-webkit-keyframes");
+ for ($i = 0, $l = count($tokens); $i < $l; $i++)
+ {
+ if (get_class($tokens[$i]) === "CssAtKeyframesStartToken")
+ {
+ for ($ii = $i; $ii < $l; $ii++)
+ {
+ if (get_class($tokens[$ii]) === "CssAtKeyframesEndToken")
+ {
+ break;
+ }
+ }
+ if (get_class($tokens[$ii]) === "CssAtKeyframesEndToken")
+ {
+ $add = array();
+ $source = array();
+ for ($iii = $i; $iii <= $ii; $iii++)
+ {
+ $source[] = clone($tokens[$iii]);
+ }
+ foreach ($transformations as $transformation)
+ {
+ $t = array();
+ foreach ($source as $token)
+ {
+ $t[] = clone($token);
+ }
+ $t[0]->AtRuleName = $transformation;
+ $add = array_merge($add, $t);
+ }
+ if (isset($this->configuration["RemoveSource"]) && $this->configuration["RemoveSource"] === true)
+ {
+ array_splice($tokens, $i, $ii - $i + 1, $add);
+ }
+ else
+ {
+ array_splice($tokens, $ii + 1, 0, $add);
+ }
+ $l = count($tokens);
+ $i = $ii + count($add);
+ $r += count($add);
+ }
+ }
+ }
+ return $r;
+ }
+}
+
+/**
+ * This {@link aCssMinifierPlugin} will convert a color value in hsl notation to hexadecimal notation.
+ *
+ * Example:
+ * <code>
+ * color: hsl(232,36%,48%);
+ * </code>
+ *
+ * Will get converted to:
+ * <code>
+ * color:#4e5aa7;
+ * </code>
+ *
+ * @package CssMin/Minifier/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssConvertHslColorsMinifierPlugin extends aCssMinifierPlugin
+{
+ /**
+ * Regular expression matching the value.
+ *
+ * @var string
+ */
+ private $reMatch = "/^hsl\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*%\s*,\s*([0-9]+)\s*%\s*\)/iS";
+ /**
+ * Implements {@link aCssMinifierPlugin::minify()}.
+ *
+ * @param aCssToken $token Token to process
+ * @return boolean Return TRUE to break the processing of this token; FALSE to continue
+ */
+ public function apply(aCssToken &$token)
+ {
+ if (stripos($token->Value, "hsl") !== false && preg_match($this->reMatch, $token->Value, $m))
+ {
+ $token->Value = str_replace($m[0], $this->hsl2hex($m[1], $m[2], $m[3]), $token->Value);
+ }
+ return false;
+ }
+ /**
+ * Implements {@link aMinifierPlugin::getTriggerTokens()}
+ *
+ * @return array
+ */
+ public function getTriggerTokens()
+ {
+ return array
+ (
+ "CssAtFontFaceDeclarationToken",
+ "CssAtPageDeclarationToken",
+ "CssRulesetDeclarationToken"
+ );
+ }
+ /**
+ * Convert a HSL value to hexadecimal notation.
+ *
+ * Based on: {@link http://www.easyrgb.com/index.php?X=MATH&H=19#text19}.
+ *
+ * @param integer $hue Hue
+ * @param integer $saturation Saturation
+ * @param integer $lightness Lightnesss
+ * @return string
+ */
+ private function hsl2hex($hue, $saturation, $lightness)
+ {
+ $hue = $hue / 360;
+ $saturation = $saturation / 100;
+ $lightness = $lightness / 100;
+ if ($saturation == 0)
+ {
+ $red = $lightness * 255;
+ $green = $lightness * 255;
+ $blue = $lightness * 255;
+ }
+ else
+ {
+ if ($lightness < 0.5 )
+ {
+ $v2 = $lightness * (1 + $saturation);
+ }
+ else
+ {
+ $v2 = ($lightness + $saturation) - ($saturation * $lightness);
+ }
+ $v1 = 2 * $lightness - $v2;
+ $red = 255 * self::hue2rgb($v1, $v2, $hue + (1 / 3));
+ $green = 255 * self::hue2rgb($v1, $v2, $hue);
+ $blue = 255 * self::hue2rgb($v1, $v2, $hue - (1 / 3));
+ }
+ return "#" . str_pad(dechex(round($red)), 2, "0", STR_PAD_LEFT) . str_pad(dechex(round($green)), 2, "0", STR_PAD_LEFT) . str_pad(dechex(round($blue)), 2, "0", STR_PAD_LEFT);
+ }
+ /**
+ * Apply hue to a rgb color value.
+ *
+ * @param integer $v1 Value 1
+ * @param integer $v2 Value 2
+ * @param integer $hue Hue
+ * @return integer
+ */
+ private function hue2rgb($v1, $v2, $hue)
+ {
+ if ($hue < 0)
+ {
+ $hue += 1;
+ }
+ if ($hue > 1)
+ {
+ $hue -= 1;
+ }
+ if ((6 * $hue) < 1)
+ {
+ return ($v1 + ($v2 - $v1) * 6 * $hue);
+ }
+ if ((2 * $hue) < 1)
+ {
+ return ($v2);
+ }
+ if ((3 * $hue) < 2)
+ {
+ return ($v1 + ($v2 - $v1) * (( 2 / 3) - $hue) * 6);
+ }
+ return $v1;
+ }
+}
+
+/**
+ * This {@link aCssMinifierPlugin} will convert the font-weight values normal and bold to their numeric notation.
+ *
+ * Example:
+ * <code>
+ * font-weight: normal;
+ * font: bold 11px monospace;
+ * </code>
+ *
+ * Will get converted to:
+ * <code>
+ * font-weight:400;
+ * font:700 11px monospace;
+ * </code>
+ *
+ * @package CssMin/Minifier/Pluginsn
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssConvertFontWeightMinifierPlugin extends aCssMinifierPlugin
+{
+ /**
+ * Array of included declaration properties this plugin will process; others declaration properties will get
+ * ignored.
+ *
+ * @var array
+ */
+ private $include = array
+ (
+ "font",
+ "font-weight"
+ );
+ /**
+ * Regular expression matching the value.
+ *
+ * @var string
+ */
+ private $reMatch = null;
+ /**
+ * Transformation table used by the {@link CssConvertFontWeightMinifierPlugin::reReplace() replacement method}.
+ *
+ * @var array
+ */
+ private $transformation = array
+ (
+ "normal" => "400",
+ "bold" => "700"
+ );
+ /**
+ * Overwrites {@link aCssMinifierPlugin::__construct()}.
+ *
+ * The constructor will create the {@link CssConvertFontWeightMinifierPlugin::$reMatch replace regular expression}
+ * based on the {@link CssConvertFontWeightMinifierPlugin::$transformation transformation table}.
+ *
+ * @param CssMinifier $minifier The CssMinifier object of this plugin.
+ * @return void
+ */
+ public function __construct(CssMinifier $minifier)
+ {
+ $this->reMatch = "/(^|\s)+(" . implode("|", array_keys($this->transformation)). ")(\s|$)+/iS";
+ parent::__construct($minifier);
+ }
+ /**
+ * Implements {@link aCssMinifierPlugin::minify()}.
+ *
+ * @param aCssToken $token Token to process
+ * @return boolean Return TRUE to break the processing of this token; FALSE to continue
+ */
+ public function apply(aCssToken &$token)
+ {
+ if (in_array($token->Property, $this->include) && preg_match($this->reMatch, $token->Value, $m))
+ {
+ $token->Value = preg_replace_callback($this->reMatch, array($this, 'reReplace'), $token->Value);
+ }
+ return false;
+ }
+ /**
+ * Callback for replacement value.
+ *
+ * @param array $match
+ * @return string
+ */
+ private function reReplace($match)
+ {
+ return $match[1] . $this->transformation[strtolower($match[2])] . $match[3];
+ }
+ /**
+ * Implements {@link aMinifierPlugin::getTriggerTokens()}
+ *
+ * @return array
+ */
+ public function getTriggerTokens()
+ {
+ return array
+ (
+ "CssAtFontFaceDeclarationToken",
+ "CssAtPageDeclarationToken",
+ "CssRulesetDeclarationToken"
+ );
+ }
+}
+
+/**
+ * This {@link aCssMinifierPlugin} will compress several unit values to their short notations. Examples:
+ *
+ * <code>
+ * padding: 0.5em;
+ * border: 0px;
+ * margin: 0 0 0 0;
+ * </code>
+ *
+ * Will get compressed to:
+ *
+ * <code>
+ * padding:.5px;
+ * border:0;
+ * margin:0;
+ * </code>
+ *
+ * --
+ *
+ * @package CssMin/Minifier/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssCompressUnitValuesMinifierPlugin extends aCssMinifierPlugin
+{
+ /**
+ * Regular expression used for matching and replacing unit values.
+ *
+ * @var array
+ */
+ private $re = array
+ (
+ "/(^| |-)0\.([0-9]+?)(0+)?(%|em|ex|px|in|cm|mm|pt|pc)/iS" => "\${1}.\${2}\${4}",
+ "/(^| )-?(\.?)0(%|em|ex|px|in|cm|mm|pt|pc)/iS" => "\${1}0",
+ );
+ /**
+ * Regular expression used for matching and replacing unit values only for non-blacklisted declarations.
+ *
+ * @var array
+ */
+ private $reBlacklisted = array(
+ "/(^0\s0\s0\s0)|(^0\s0\s0$)|(^0\s0$)/iS" => "0",
+ );
+ /**
+ * Blacklisted properties for the above regular expression.
+ *
+ * @var array
+ */
+ private $propertiesBlacklist = array('background-position');
+ /**
+ * Regular expression matching the value.
+ *
+ * @var string
+ */
+ private $reMatch = "/(^| |-)0\.([0-9]+?)(0+)?(%|em|ex|px|in|cm|mm|pt|pc)|(^| )-?(\.?)0(%|em|ex|px|in|cm|mm|pt|pc)|(^0\s0\s0\s0$)|(^0\s0\s0$)|(^0\s0$)/iS";
+ /**
+ * Implements {@link aCssMinifierPlugin::minify()}.
+ *
+ * @param aCssToken $token Token to process
+ * @return boolean Return TRUE to break the processing of this token; FALSE to continue
+ */
+ public function apply(aCssToken &$token)
+ {
+ if (preg_match($this->reMatch, $token->Value))
+ {
+ foreach ($this->re as $reMatch => $reReplace)
+ {
+ $token->Value = preg_replace($reMatch, $reReplace, $token->Value);
+ }
+ if (!in_array($token->Property, $this->propertiesBlacklist))
+ {
+ foreach ($this->reBlacklisted as $reMatch => $reReplace)
+ {
+ $token->Value = preg_replace($reMatch, $reReplace, $token->Value);
+ }
+ }
+ }
+ return false;
+ }
+ /**
+ * Implements {@link aMinifierPlugin::getTriggerTokens()}
+ *
+ * @return array
+ */
+ public function getTriggerTokens()
+ {
+ return array
+ (
+ "CssAtFontFaceDeclarationToken",
+ "CssAtPageDeclarationToken",
+ "CssRulesetDeclarationToken"
+ );
+ }
+}
+
+/**
+ * This {@link aCssMinifierPlugin} compress the content of expresssion() declaration values.
+ *
+ * For compression of expressions {@link https://github.com/rgrove/jsmin-php/ JSMin} will get used. JSMin have to be
+ * already included or loadable via {@link http://goo.gl/JrW54 PHP autoloading}.
+ *
+ * @package CssMin/Minifier/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssCompressExpressionValuesMinifierPlugin extends aCssMinifierPlugin
+{
+ /**
+ * Implements {@link aCssMinifierPlugin::minify()}.
+ *
+ * @param aCssToken $token Token to process
+ * @return boolean Return TRUE to break the processing of this token; FALSE to continue
+ */
+ public function apply(aCssToken &$token)
+ {
+ if (class_exists("JSMin") && stripos($token->Value, "expression(") !== false)
+ {
+ $value = $token->Value;
+ $value = substr($token->Value, stripos($token->Value, "expression(") + 10);
+ $value = trim(JSMin::minify($value));
+ $token->Value = "expression(" . $value . ")";
+ }
+ return false;
+ }
+ /**
+ * Implements {@link aMinifierPlugin::getTriggerTokens()}
+ *
+ * @return array
+ */
+ public function getTriggerTokens()
+ {
+ return array
+ (
+ "CssAtFontFaceDeclarationToken",
+ "CssAtPageDeclarationToken",
+ "CssRulesetDeclarationToken"
+ );
+ }
+}
+
+/**
+ * This {@link aCssMinifierPlugin} will convert hexadecimal color value with 6 chars to their 3 char hexadecimal
+ * notation (if possible).
+ *
+ * Example:
+ * <code>
+ * color: #aabbcc;
+ * </code>
+ *
+ * Will get converted to:
+ * <code>
+ * color:#abc;
+ * </code>
+ *
+ * @package CssMin/Minifier/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssCompressColorValuesMinifierPlugin extends aCssMinifierPlugin
+{
+ /**
+ * Regular expression matching 6 char hexadecimal color values.
+ *
+ * @var string
+ */
+ private $reMatch = "/\#([0-9a-f]{6})/iS";
+ /**
+ * Implements {@link aCssMinifierPlugin::minify()}.
+ *
+ * @param aCssToken $token Token to process
+ * @return boolean Return TRUE to break the processing of this token; FALSE to continue
+ */
+ public function apply(aCssToken &$token)
+ {
+ if (strpos($token->Value, "#") !== false && preg_match($this->reMatch, $token->Value, $m))
+ {
+ $value = strtolower($m[1]);
+ if ($value[0] == $value[1] && $value[2] == $value[3] && $value[4] == $value[5])
+ {
+ $token->Value = str_replace($m[0], "#" . $value[0] . $value[2] . $value[4], $token->Value);
+ }
+ }
+ return false;
+ }
+ /**
+ * Implements {@link aMinifierPlugin::getTriggerTokens()}
+ *
+ * @return array
+ */
+ public function getTriggerTokens()
+ {
+ return array
+ (
+ "CssAtFontFaceDeclarationToken",
+ "CssAtPageDeclarationToken",
+ "CssRulesetDeclarationToken"
+ );
+ }
+}
+
+/**
+ * This {@link aCssToken CSS token} represents a CSS comment.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssCommentToken extends aCssToken
+{
+ /**
+ * Comment as Text.
+ *
+ * @var string
+ */
+ public $Comment = "";
+ /**
+ * Set the properties of a comment token.
+ *
+ * @param string $comment Comment including comment delimiters
+ * @return void
+ */
+ public function __construct($comment)
+ {
+ $this->Comment = $comment;
+ }
+ /**
+ * Implements {@link aCssToken::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->Comment;
+ }
+}
+
+/**
+ * {@link aCssParserPlugin Parser plugin} for parsing comments.
+ *
+ * Adds a {@link CssCommentToken} to the parser if a comment was found.
+ *
+ * @package CssMin/Parser/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssCommentParserPlugin extends aCssParserPlugin
+{
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerChars()}.
+ *
+ * @return array
+ */
+ public function getTriggerChars()
+ {
+ return array("*", "/");
+ }
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerStates()}.
+ *
+ * @return array
+ */
+ public function getTriggerStates()
+ {
+ return false;
+ }
+ /**
+ * Stored buffer for restore.
+ *
+ * @var string
+ */
+ private $restoreBuffer = "";
+ /**
+ * Implements {@link aCssParserPlugin::parse()}.
+ *
+ * @param integer $index Current index
+ * @param string $char Current char
+ * @param string $previousChar Previous char
+ * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
+ */
+ public function parse($index, $char, $previousChar, $state)
+ {
+ if ($char === "*" && $previousChar === "/" && $state !== "T_COMMENT")
+ {
+ $this->parser->pushState("T_COMMENT");
+ $this->parser->setExclusive(__CLASS__);
+ $this->restoreBuffer = substr($this->parser->getAndClearBuffer(), 0, -2);
+ }
+ elseif ($char === "/" && $previousChar === "*" && $state === "T_COMMENT")
+ {
+ $this->parser->popState();
+ $this->parser->unsetExclusive();
+ $this->parser->appendToken(new CssCommentToken("/*" . $this->parser->getAndClearBuffer()));
+ $this->parser->setBuffer($this->restoreBuffer);
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+ }
+}
+
+/**
+ * This {@link aCssToken CSS token} represents the start of a @variables at-rule block.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtVariablesStartToken extends aCssAtBlockStartToken
+{
+ /**
+ * Media types of the @variables at-rule block.
+ *
+ * @var array
+ */
+ public $MediaTypes = array();
+ /**
+ * Set the properties of a @variables at-rule token.
+ *
+ * @param array $mediaTypes Media types
+ * @return void
+ */
+ public function __construct($mediaTypes = null)
+ {
+ $this->MediaTypes = $mediaTypes ? $mediaTypes : array("all");
+ }
+ /**
+ * Implements {@link aCssToken::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return "";
+ }
+}
+
+/**
+ * {@link aCssParserPlugin Parser plugin} for parsing @variables at-rule block with including declarations.
+ *
+ * Found @variables at-rule blocks will add a {@link CssAtVariablesStartToken} and {@link CssAtVariablesEndToken} to the
+ * parser; including declarations as {@link CssAtVariablesDeclarationToken}.
+ *
+ * @package CssMin/Parser/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtVariablesParserPlugin extends aCssParserPlugin
+{
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerChars()}.
+ *
+ * @return array
+ */
+ public function getTriggerChars()
+ {
+ return array("@", "{", "}", ":", ";");
+ }
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerStates()}.
+ *
+ * @return array
+ */
+ public function getTriggerStates()
+ {
+ return array("T_DOCUMENT", "T_AT_VARIABLES::PREPARE", "T_AT_VARIABLES", "T_AT_VARIABLES_DECLARATION");
+ }
+ /**
+ * Implements {@link aCssParserPlugin::parse()}.
+ *
+ * @param integer $index Current index
+ * @param string $char Current char
+ * @param string $previousChar Previous char
+ * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
+ */
+ public function parse($index, $char, $previousChar, $state)
+ {
+ // Start of @variables at-rule block
+ if ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 10)) === "@variables")
+ {
+ $this->parser->pushState("T_AT_VARIABLES::PREPARE");
+ $this->parser->clearBuffer();
+ return $index + 10;
+ }
+ // Start of @variables declarations
+ elseif ($char === "{" && $state === "T_AT_VARIABLES::PREPARE")
+ {
+ $this->parser->setState("T_AT_VARIABLES");
+ $mediaTypes = array_filter(array_map("trim", explode(",", $this->parser->getAndClearBuffer("{"))));
+ $this->parser->appendToken(new CssAtVariablesStartToken($mediaTypes));
+ }
+ // Start of @variables declaration
+ if ($char === ":" && $state === "T_AT_VARIABLES")
+ {
+ $this->buffer = $this->parser->getAndClearBuffer(":");
+ $this->parser->pushState("T_AT_VARIABLES_DECLARATION");
+ }
+ // Unterminated @variables declaration
+ elseif ($char === ":" && $state === "T_AT_VARIABLES_DECLARATION")
+ {
+ // Ignore Internet Explorer filter declarations
+ if ($this->buffer === "filter")
+ {
+ return false;
+ }
+ CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated @variables declaration", $this->buffer . ":" . $this->parser->getBuffer() . "_"));
+ }
+ // End of @variables declaration
+ elseif (($char === ";" || $char === "}") && $state === "T_AT_VARIABLES_DECLARATION")
+ {
+ $value = $this->parser->getAndClearBuffer(";}");
+ if (strtolower(substr($value, -10, 10)) === "!important")
+ {
+ $value = trim(substr($value, 0, -10));
+ $isImportant = true;
+ }
+ else
+ {
+ $isImportant = false;
+ }
+ $this->parser->popState();
+ $this->parser->appendToken(new CssAtVariablesDeclarationToken($this->buffer, $value, $isImportant));
+ $this->buffer = "";
+ }
+ // End of @variables at-rule block
+ elseif ($char === "}" && $state === "T_AT_VARIABLES")
+ {
+ $this->parser->popState();
+ $this->parser->clearBuffer();
+ $this->parser->appendToken(new CssAtVariablesEndToken());
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+ }
+}
+
+/**
+ * This {@link aCssToken CSS token} represents the end of a @variables at-rule block.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtVariablesEndToken extends aCssAtBlockEndToken
+{
+ /**
+ * Implements {@link aCssToken::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return "";
+ }
+}
+
+/**
+ * This {@link aCssToken CSS token} represents a declaration of a @variables at-rule block.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtVariablesDeclarationToken extends aCssDeclarationToken
+{
+ /**
+ * Implements {@link aCssToken::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return "";
+ }
+}
+
+/**
+ * This {@link aCssToken CSS token} represents the start of a @page at-rule block.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtPageStartToken extends aCssAtBlockStartToken
+{
+ /**
+ * Selector.
+ *
+ * @var string
+ */
+ public $Selector = "";
+ /**
+ * Sets the properties of the @page at-rule.
+ *
+ * @param string $selector Selector
+ * @return void
+ */
+ public function __construct($selector = "")
+ {
+ $this->Selector = $selector;
+ }
+ /**
+ * Implements {@link aCssToken::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return "@page" . ($this->Selector ? " " . $this->Selector : "") . "{";
+ }
+}
+
+/**
+ * {@link aCssParserPlugin Parser plugin} for parsing @page at-rule block with including declarations.
+ *
+ * Found @page at-rule blocks will add a {@link CssAtPageStartToken} and {@link CssAtPageEndToken} to the
+ * parser; including declarations as {@link CssAtPageDeclarationToken}.
+ *
+ * @package CssMin/Parser/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtPageParserPlugin extends aCssParserPlugin
+{
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerChars()}.
+ *
+ * @return array
+ */
+ public function getTriggerChars()
+ {
+ return array("@", "{", "}", ":", ";");
+ }
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerStates()}.
+ *
+ * @return array
+ */
+ public function getTriggerStates()
+ {
+ return array("T_DOCUMENT", "T_AT_PAGE::SELECTOR", "T_AT_PAGE", "T_AT_PAGE_DECLARATION");
+ }
+ /**
+ * Implements {@link aCssParserPlugin::parse()}.
+ *
+ * @param integer $index Current index
+ * @param string $char Current char
+ * @param string $previousChar Previous char
+ * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
+ */
+ public function parse($index, $char, $previousChar, $state)
+ {
+ // Start of @page at-rule block
+ if ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 5)) === "@page")
+ {
+ $this->parser->pushState("T_AT_PAGE::SELECTOR");
+ $this->parser->clearBuffer();
+ return $index + 5;
+ }
+ // Start of @page declarations
+ elseif ($char === "{" && $state === "T_AT_PAGE::SELECTOR")
+ {
+ $selector = $this->parser->getAndClearBuffer("{");
+ $this->parser->setState("T_AT_PAGE");
+ $this->parser->clearBuffer();
+ $this->parser->appendToken(new CssAtPageStartToken($selector));
+ }
+ // Start of @page declaration
+ elseif ($char === ":" && $state === "T_AT_PAGE")
+ {
+ $this->parser->pushState("T_AT_PAGE_DECLARATION");
+ $this->buffer = $this->parser->getAndClearBuffer(":", true);
+ }
+ // Unterminated @font-face declaration
+ elseif ($char === ":" && $state === "T_AT_PAGE_DECLARATION")
+ {
+ // Ignore Internet Explorer filter declarations
+ if ($this->buffer === "filter")
+ {
+ return false;
+ }
+ CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated @page declaration", $this->buffer . ":" . $this->parser->getBuffer() . "_"));
+ }
+ // End of @page declaration
+ elseif (($char === ";" || $char === "}") && $state == "T_AT_PAGE_DECLARATION")
+ {
+ $value = $this->parser->getAndClearBuffer(";}");
+ if (strtolower(substr($value, -10, 10)) == "!important")
+ {
+ $value = trim(substr($value, 0, -10));
+ $isImportant = true;
+ }
+ else
+ {
+ $isImportant = false;
+ }
+ $this->parser->popState();
+ $this->parser->appendToken(new CssAtPageDeclarationToken($this->buffer, $value, $isImportant));
+ // --
+ if ($char === "}")
+ {
+ $this->parser->popState();
+ $this->parser->appendToken(new CssAtPageEndToken());
+ }
+ $this->buffer = "";
+ }
+ // End of @page at-rule block
+ elseif ($char === "}" && $state === "T_AT_PAGE")
+ {
+ $this->parser->popState();
+ $this->parser->clearBuffer();
+ $this->parser->appendToken(new CssAtPageEndToken());
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+ }
+}
+
+/**
+ * This {@link aCssToken CSS token} represents the end of a @page at-rule block.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtPageEndToken extends aCssAtBlockEndToken
+{
+
+}
+
+/**
+ * This {@link aCssToken CSS token} represents a declaration of a @page at-rule block.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtPageDeclarationToken extends aCssDeclarationToken
+{
+
+}
+
+/**
+ * This {@link aCssToken CSS token} represents the start of a @media at-rule block.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtMediaStartToken extends aCssAtBlockStartToken
+{
+ /**
+ * Sets the properties of the @media at-rule.
+ *
+ * @param array $mediaTypes Media types
+ * @return void
+ */
+ public function __construct(array $mediaTypes = array())
+ {
+ $this->MediaTypes = $mediaTypes;
+ }
+ /**
+ * Implements {@link aCssToken::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return "@media " . implode(",", $this->MediaTypes) . "{";
+ }
+}
+
+/**
+ * {@link aCssParserPlugin Parser plugin} for parsing @media at-rule block.
+ *
+ * Found @media at-rule blocks will add a {@link CssAtMediaStartToken} and {@link CssAtMediaEndToken} to the parser.
+ * This plugin will also set the the current media types using {@link CssParser::setMediaTypes()} and
+ * {@link CssParser::unsetMediaTypes()}.
+ *
+ * @package CssMin/Parser/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtMediaParserPlugin extends aCssParserPlugin
+{
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerChars()}.
+ *
+ * @return array
+ */
+ public function getTriggerChars()
+ {
+ return array("@", "{", "}");
+ }
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerStates()}.
+ *
+ * @return array
+ */
+ public function getTriggerStates()
+ {
+ return array("T_DOCUMENT", "T_AT_MEDIA::PREPARE", "T_AT_MEDIA");
+ }
+ /**
+ * Implements {@link aCssParserPlugin::parse()}.
+ *
+ * @param integer $index Current index
+ * @param string $char Current char
+ * @param string $previousChar Previous char
+ * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
+ */
+ public function parse($index, $char, $previousChar, $state)
+ {
+ if ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 6)) === "@media")
+ {
+ $this->parser->pushState("T_AT_MEDIA::PREPARE");
+ $this->parser->clearBuffer();
+ return $index + 6;
+ }
+ elseif ($char === "{" && $state === "T_AT_MEDIA::PREPARE")
+ {
+ $mediaTypes = array_filter(array_map("trim", explode(",", $this->parser->getAndClearBuffer("{"))));
+ $this->parser->setMediaTypes($mediaTypes);
+ $this->parser->setState("T_AT_MEDIA");
+ $this->parser->appendToken(new CssAtMediaStartToken($mediaTypes));
+ }
+ elseif ($char === "}" && $state === "T_AT_MEDIA")
+ {
+ $this->parser->appendToken(new CssAtMediaEndToken());
+ $this->parser->clearBuffer();
+ $this->parser->unsetMediaTypes();
+ $this->parser->popState();
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+ }
+}
+
+/**
+ * This {@link aCssToken CSS token} represents the end of a @media at-rule block.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtMediaEndToken extends aCssAtBlockEndToken
+{
+
+}
+
+/**
+ * This {@link aCssToken CSS token} represents the start of a @keyframes at-rule block.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtKeyframesStartToken extends aCssAtBlockStartToken
+{
+ /**
+ * Name of the at-rule.
+ *
+ * @var string
+ */
+ public $AtRuleName = "keyframes";
+ /**
+ * Name
+ *
+ * @var string
+ */
+ public $Name = "";
+ /**
+ * Sets the properties of the @page at-rule.
+ *
+ * @param string $selector Selector
+ * @return void
+ */
+ public function __construct($name, $atRuleName = null)
+ {
+ $this->Name = $name;
+ if (!is_null($atRuleName))
+ {
+ $this->AtRuleName = $atRuleName;
+ }
+ }
+ /**
+ * Implements {@link aCssToken::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ if ($this->AtRuleName === "-moz-keyframes")
+ {
+ return "@-moz-keyframes " . $this->Name . " {";
+ }
+ return "@" . $this->AtRuleName . " " . $this->Name . "{";
+ }
+}
+
+/**
+ * This {@link aCssToken CSS token} represents the start of a ruleset of a @keyframes at-rule block.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtKeyframesRulesetStartToken extends aCssRulesetStartToken
+{
+ /**
+ * Array of selectors.
+ *
+ * @var array
+ */
+ public $Selectors = array();
+ /**
+ * Set the properties of a ruleset token.
+ *
+ * @param array $selectors Selectors of the ruleset
+ * @return void
+ */
+ public function __construct(array $selectors = array())
+ {
+ $this->Selectors = $selectors;
+ }
+ /**
+ * Implements {@link aCssToken::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return implode(",", $this->Selectors) . "{";
+ }
+}
+
+/**
+ * This {@link aCssToken CSS token} represents the end of a ruleset of a @keyframes at-rule block.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtKeyframesRulesetEndToken extends aCssRulesetEndToken
+{
+
+}
+
+/**
+ * This {@link aCssToken CSS token} represents a ruleset declaration of a @keyframes at-rule block.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtKeyframesRulesetDeclarationToken extends aCssDeclarationToken
+{
+
+}
+
+/**
+ * {@link aCssParserPlugin Parser plugin} for parsing @keyframes at-rule blocks, rulesets and declarations.
+ *
+ * @package CssMin/Parser/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtKeyframesParserPlugin extends aCssParserPlugin
+{
+ /**
+ * @var string Keyword
+ */
+ private $atRuleName = "";
+ /**
+ * Selectors.
+ *
+ * @var array
+ */
+ private $selectors = array();
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerChars()}.
+ *
+ * @return array
+ */
+ public function getTriggerChars()
+ {
+ return array("@", "{", "}", ":", ",", ";");
+ }
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerStates()}.
+ *
+ * @return array
+ */
+ public function getTriggerStates()
+ {
+ return array("T_DOCUMENT", "T_AT_KEYFRAMES::NAME", "T_AT_KEYFRAMES", "T_AT_KEYFRAMES_RULESETS", "T_AT_KEYFRAMES_RULESET", "T_AT_KEYFRAMES_RULESET_DECLARATION");
+ }
+ /**
+ * Implements {@link aCssParserPlugin::parse()}.
+ *
+ * @param integer $index Current index
+ * @param string $char Current char
+ * @param string $previousChar Previous char
+ * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
+ */
+ public function parse($index, $char, $previousChar, $state)
+ {
+ // Start of @keyframes at-rule block
+ if ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 10)) === "@keyframes")
+ {
+ $this->atRuleName = "keyframes";
+ $this->parser->pushState("T_AT_KEYFRAMES::NAME");
+ $this->parser->clearBuffer();
+ return $index + 10;
+ }
+ // Start of @keyframes at-rule block (@-moz-keyframes)
+ elseif ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 15)) === "@-moz-keyframes")
+ {
+ $this->atRuleName = "-moz-keyframes";
+ $this->parser->pushState("T_AT_KEYFRAMES::NAME");
+ $this->parser->clearBuffer();
+ return $index + 15;
+ }
+ // Start of @keyframes at-rule block (@-webkit-keyframes)
+ elseif ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 18)) === "@-webkit-keyframes")
+ {
+ $this->atRuleName = "-webkit-keyframes";
+ $this->parser->pushState("T_AT_KEYFRAMES::NAME");
+ $this->parser->clearBuffer();
+ return $index + 18;
+ }
+ // Start of @keyframes at-rule block (@-o-keyframes)
+ elseif ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 13)) === "@-o-keyframes")
+ {
+ $this->atRuleName = "-o-keyframes";
+ $this->parser->pushState("T_AT_KEYFRAMES::NAME");
+ $this->parser->clearBuffer();
+ return $index + 13;
+ }
+ // Start of @keyframes at-rule block (@-ms-keyframes)
+ elseif ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 14)) === "@-ms-keyframes")
+ {
+ $this->atRuleName = "-ms-keyframes";
+ $this->parser->pushState("T_AT_KEYFRAMES::NAME");
+ $this->parser->clearBuffer();
+ return $index + 14;
+ }
+ // Start of @keyframes rulesets
+ elseif ($char === "{" && $state === "T_AT_KEYFRAMES::NAME")
+ {
+ $name = $this->parser->getAndClearBuffer("{\"'");
+ $this->parser->setState("T_AT_KEYFRAMES_RULESETS");
+ $this->parser->clearBuffer();
+ $this->parser->appendToken(new CssAtKeyframesStartToken($name, $this->atRuleName));
+ }
+ // Start of @keyframe ruleset and selectors
+ if ($char === "," && $state === "T_AT_KEYFRAMES_RULESETS")
+ {
+ $this->selectors[] = $this->parser->getAndClearBuffer(",{");
+ }
+ // Start of a @keyframes ruleset
+ elseif ($char === "{" && $state === "T_AT_KEYFRAMES_RULESETS")
+ {
+ if ($this->parser->getBuffer() !== "")
+ {
+ $this->selectors[] = $this->parser->getAndClearBuffer(",{");
+ $this->parser->pushState("T_AT_KEYFRAMES_RULESET");
+ $this->parser->appendToken(new CssAtKeyframesRulesetStartToken($this->selectors));
+ $this->selectors = array();
+ }
+ }
+ // Start of @keyframes ruleset declaration
+ elseif ($char === ":" && $state === "T_AT_KEYFRAMES_RULESET")
+ {
+ $this->parser->pushState("T_AT_KEYFRAMES_RULESET_DECLARATION");
+ $this->buffer = $this->parser->getAndClearBuffer(":;", true);
+ }
+ // Unterminated @keyframes ruleset declaration
+ elseif ($char === ":" && $state === "T_AT_KEYFRAMES_RULESET_DECLARATION")
+ {
+ // Ignore Internet Explorer filter declarations
+ if ($this->buffer === "filter")
+ {
+ return false;
+ }
+ CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated @keyframes ruleset declaration", $this->buffer . ":" . $this->parser->getBuffer() . "_"));
+ }
+ // End of declaration
+ elseif (($char === ";" || $char === "}") && $state === "T_AT_KEYFRAMES_RULESET_DECLARATION")
+ {
+ $value = $this->parser->getAndClearBuffer(";}");
+ if (strtolower(substr($value, -10, 10)) === "!important")
+ {
+ $value = trim(substr($value, 0, -10));
+ $isImportant = true;
+ }
+ else
+ {
+ $isImportant = false;
+ }
+ $this->parser->popState();
+ $this->parser->appendToken(new CssAtKeyframesRulesetDeclarationToken($this->buffer, $value, $isImportant));
+ // Declaration ends with a right curly brace; so we have to end the ruleset
+ if ($char === "}")
+ {
+ $this->parser->appendToken(new CssAtKeyframesRulesetEndToken());
+ $this->parser->popState();
+ }
+ $this->buffer = "";
+ }
+ // End of @keyframes ruleset
+ elseif ($char === "}" && $state === "T_AT_KEYFRAMES_RULESET")
+ {
+ $this->parser->clearBuffer();
+
+ $this->parser->popState();
+ $this->parser->appendToken(new CssAtKeyframesRulesetEndToken());
+ }
+ // End of @keyframes rulesets
+ elseif ($char === "}" && $state === "T_AT_KEYFRAMES_RULESETS")
+ {
+ $this->parser->clearBuffer();
+ $this->parser->popState();
+ $this->parser->appendToken(new CssAtKeyframesEndToken());
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+ }
+}
+
+/**
+ * This {@link aCssToken CSS token} represents the end of a @keyframes at-rule block.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtKeyframesEndToken extends aCssAtBlockEndToken
+{
+
+}
+
+/**
+ * This {@link aCssToken CSS token} represents a @import at-rule.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1.b1 (2001-02-22)
+ */
+class CssAtImportToken extends aCssToken
+{
+ /**
+ * Import path of the @import at-rule.
+ *
+ * @var string
+ */
+ public $Import = "";
+ /**
+ * Media types of the @import at-rule.
+ *
+ * @var array
+ */
+ public $MediaTypes = array();
+ /**
+ * Set the properties of a @import at-rule token.
+ *
+ * @param string $import Import path
+ * @param array $mediaTypes Media types
+ * @return void
+ */
+ public function __construct($import, $mediaTypes)
+ {
+ $this->Import = $import;
+ $this->MediaTypes = $mediaTypes ? $mediaTypes : array();
+ }
+ /**
+ * Implements {@link aCssToken::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return "@import \"" . $this->Import . "\"" . (count($this->MediaTypes) > 0 ? " " . implode(",", $this->MediaTypes) : ""). ";";
+ }
+}
+
+/**
+ * {@link aCssParserPlugin Parser plugin} for parsing @import at-rule.
+ *
+ * If a @import at-rule was found this plugin will add a {@link CssAtImportToken} to the parser.
+ *
+ * @package CssMin/Parser/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtImportParserPlugin extends aCssParserPlugin
+{
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerChars()}.
+ *
+ * @return array
+ */
+ public function getTriggerChars()
+ {
+ return array("@", ";", ",", "\n");
+ }
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerStates()}.
+ *
+ * @return array
+ */
+ public function getTriggerStates()
+ {
+ return array("T_DOCUMENT", "T_AT_IMPORT");
+ }
+ /**
+ * Implements {@link aCssParserPlugin::parse()}.
+ *
+ * @param integer $index Current index
+ * @param string $char Current char
+ * @param string $previousChar Previous char
+ * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
+ */
+ public function parse($index, $char, $previousChar, $state)
+ {
+ if ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 7)) === "@import")
+ {
+ $this->parser->pushState("T_AT_IMPORT");
+ $this->parser->clearBuffer();
+ return $index + 7;
+ }
+ elseif (($char === ";" || $char === "\n") && $state === "T_AT_IMPORT")
+ {
+ $this->buffer = $this->parser->getAndClearBuffer(";");
+ $pos = false;
+ foreach (array(")", "\"", "'") as $needle)
+ {
+ if (($pos = strrpos($this->buffer, $needle)) !== false)
+ {
+ break;
+ }
+ }
+ $import = substr($this->buffer, 0, $pos + 1);
+ if (stripos($import, "url(") === 0)
+ {
+ $import = substr($import, 4, -1);
+ }
+ $import = trim($import, " \t\n\r\0\x0B'\"");
+ $mediaTypes = array_filter(array_map("trim", explode(",", trim(substr($this->buffer, $pos + 1), " \t\n\r\0\x0B{"))));
+ if ($pos)
+ {
+ $this->parser->appendToken(new CssAtImportToken($import, $mediaTypes));
+ }
+ else
+ {
+ CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Invalid @import at-rule syntax", $this->buffer));
+ }
+ $this->parser->popState();
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+ }
+}
+
+/**
+ * This {@link aCssToken CSS token} represents the start of a @font-face at-rule block.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtFontFaceStartToken extends aCssAtBlockStartToken
+{
+ /**
+ * Implements {@link aCssToken::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return "@font-face{";
+ }
+}
+
+/**
+ * {@link aCssParserPlugin Parser plugin} for parsing @font-face at-rule block with including declarations.
+ *
+ * Found @font-face at-rule blocks will add a {@link CssAtFontFaceStartToken} and {@link CssAtFontFaceEndToken} to the
+ * parser; including declarations as {@link CssAtFontFaceDeclarationToken}.
+ *
+ * @package CssMin/Parser/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtFontFaceParserPlugin extends aCssParserPlugin
+{
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerChars()}.
+ *
+ * @return array
+ */
+ public function getTriggerChars()
+ {
+ return array("@", "{", "}", ":", ";");
+ }
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerStates()}.
+ *
+ * @return array
+ */
+ public function getTriggerStates()
+ {
+ return array("T_DOCUMENT", "T_AT_FONT_FACE::PREPARE", "T_AT_FONT_FACE", "T_AT_FONT_FACE_DECLARATION");
+ }
+ /**
+ * Implements {@link aCssParserPlugin::parse()}.
+ *
+ * @param integer $index Current index
+ * @param string $char Current char
+ * @param string $previousChar Previous char
+ * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
+ */
+ public function parse($index, $char, $previousChar, $state)
+ {
+ // Start of @font-face at-rule block
+ if ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 10)) === "@font-face")
+ {
+ $this->parser->pushState("T_AT_FONT_FACE::PREPARE");
+ $this->parser->clearBuffer();
+ return $index + 10 - 1;
+ }
+ // Start of @font-face declarations
+ elseif ($char === "{" && $state === "T_AT_FONT_FACE::PREPARE")
+ {
+ $this->parser->setState("T_AT_FONT_FACE");
+ $this->parser->clearBuffer();
+ $this->parser->appendToken(new CssAtFontFaceStartToken());
+ }
+ // Start of @font-face declaration
+ elseif ($char === ":" && $state === "T_AT_FONT_FACE")
+ {
+ $this->parser->pushState("T_AT_FONT_FACE_DECLARATION");
+ $this->buffer = $this->parser->getAndClearBuffer(":", true);
+ }
+ // Unterminated @font-face declaration
+ elseif ($char === ":" && $state === "T_AT_FONT_FACE_DECLARATION")
+ {
+ // Ignore Internet Explorer filter declarations
+ if ($this->buffer === "filter")
+ {
+ return false;
+ }
+ CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated @font-face declaration", $this->buffer . ":" . $this->parser->getBuffer() . "_"));
+ }
+ // End of @font-face declaration
+ elseif (($char === ";" || $char === "}") && $state === "T_AT_FONT_FACE_DECLARATION")
+ {
+ $value = $this->parser->getAndClearBuffer(";}");
+ if (strtolower(substr($value, -10, 10)) === "!important")
+ {
+ $value = trim(substr($value, 0, -10));
+ $isImportant = true;
+ }
+ else
+ {
+ $isImportant = false;
+ }
+ $this->parser->popState();
+ $this->parser->appendToken(new CssAtFontFaceDeclarationToken($this->buffer, $value, $isImportant));
+ $this->buffer = "";
+ // --
+ if ($char === "}")
+ {
+ $this->parser->appendToken(new CssAtFontFaceEndToken());
+ $this->parser->popState();
+ }
+ }
+ // End of @font-face at-rule block
+ elseif ($char === "}" && $state === "T_AT_FONT_FACE")
+ {
+ $this->parser->appendToken(new CssAtFontFaceEndToken());
+ $this->parser->clearBuffer();
+ $this->parser->popState();
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+ }
+}
+
+/**
+ * This {@link aCssToken CSS token} represents the end of a @font-face at-rule block.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtFontFaceEndToken extends aCssAtBlockEndToken
+{
+
+}
+
+/**
+ * This {@link aCssToken CSS token} represents a declaration of a @font-face at-rule block.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtFontFaceDeclarationToken extends aCssDeclarationToken
+{
+
+}
+
+/**
+ * This {@link aCssToken CSS token} represents a @charset at-rule.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtCharsetToken extends aCssToken
+{
+ /**
+ * Charset of the @charset at-rule.
+ *
+ * @var string
+ */
+ public $Charset = "";
+ /**
+ * Set the properties of @charset at-rule token.
+ *
+ * @param string $charset Charset of the @charset at-rule token
+ * @return void
+ */
+ public function __construct($charset)
+ {
+ $this->Charset = $charset;
+ }
+ /**
+ * Implements {@link aCssToken::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return "@charset " . $this->Charset . ";";
+ }
+}
+
+/**
+ * {@link aCssParserPlugin Parser plugin} for parsing @charset at-rule.
+ *
+ * If a @charset at-rule was found this plugin will add a {@link CssAtCharsetToken} to the parser.
+ *
+ * @package CssMin/Parser/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla <joe.scylla@gmail.com>
+ * @copyright 2008 - 2011 Joe Scylla <joe.scylla@gmail.com>
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtCharsetParserPlugin extends aCssParserPlugin
+{
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerChars()}.
+ *
+ * @return array
+ */
+ public function getTriggerChars()
+ {
+ return array("@", ";", "\n");
+ }
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerStates()}.
+ *
+ * @return array
+ */
+ public function getTriggerStates()
+ {
+ return array("T_DOCUMENT", "T_AT_CHARSET");
+ }
+ /**
+ * Implements {@link aCssParserPlugin::parse()}.
+ *
+ * @param integer $index Current index
+ * @param string $char Current char
+ * @param string $previousChar Previous char
+ * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
+ */
+ public function parse($index, $char, $previousChar, $state)
+ {
+ if ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 8)) === "@charset")
+ {
+ $this->parser->pushState("T_AT_CHARSET");
+ $this->parser->clearBuffer();
+ return $index + 8;
+ }
+ elseif (($char === ";" || $char === "\n") && $state === "T_AT_CHARSET")
+ {
+ $charset = $this->parser->getAndClearBuffer(";");
+ $this->parser->popState();
+ $this->parser->appendToken(new CssAtCharsetToken($charset));
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+ }
+}
+
+?>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/.coveralls.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/.coveralls.yml
new file mode 100644
index 0000000..4eecff5
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/.coveralls.yml
@@ -0,0 +1,3 @@
+service_name: travis-ci
+coverage_clover: clover.xml
+json_path: coveralls-upload.json
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/.gitignore b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/.gitignore
new file mode 100644
index 0000000..c98f719
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/.gitignore
@@ -0,0 +1,2 @@
+/coverage/
+/vendor/
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/.scrutinizer.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/.scrutinizer.yml
new file mode 100644
index 0000000..4efaf59
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/.scrutinizer.yml
@@ -0,0 +1,19 @@
+filter:
+ excluded_paths:
+ - 'vendor/*'
+ - 'tests/*'
+before_commands:
+ - 'composer install'
+tools:
+ php_analyzer: true
+ php_mess_detector: true
+ php_code_sniffer:
+ config:
+ standard: PSR1
+ sensiolabs_security_checker: true
+ php_loc:
+ excluded_dirs:
+ - vendor
+ - tests
+ php_pdepend: true
+ php_sim: true
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/.travis.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/.travis.yml
new file mode 100644
index 0000000..eca1932
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/.travis.yml
@@ -0,0 +1,9 @@
+language: php
+sudo: false
+php:
+ - 5.6
+ - 7.0
+ - hhvm
+install: composer install
+script: ./vendor/bin/phpunit --coverage-clover clover.xml
+after_success: sh -c 'if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then ./vendor/bin/coveralls -v; fi'
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/CONTRIBUTING.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/CONTRIBUTING.md
new file mode 100644
index 0000000..478fae4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/CONTRIBUTING.md
@@ -0,0 +1,38 @@
+# Contribution Guidelines
+This project is wide open to contributions. You can use GitHub to [report
+issues][issues] or [submit pull requests][pull-requests]. When opening pull
+requests, it is recommended to follow these guidelines in order to grease the
+wheels, so to speak.
+
+Please include as many details as you can in any issues and pull requests.
+Understanding how you are using the library and exactly what problems you are
+having can also help make things move quickly.
+
+## Building
+There is an included [build script][build-script] that you can execute locally
+to run the code through the [PSR-1 coding standard][psr-1] and the
+[PHPUnit][phpunit] test suite. Code coverage is kept at 100% according to
+PHPUnit's code coverage report. This is inforced using
+[coveralls][coveralls].
+
+Alternatively, you can use [Docker][docker] and/or [Docker
+Compose][docker-compose] to execute the build:
+```bash
+docker-compose run build
+```
+
+## Automated builds
+Pull requests will automatically have a build kicked off on [Travis
+CI][travis-ci] and [Scrutinizer CI][scrutinizer-ci]. The results of these
+builds are monitored closely for all pull requests.
+
+[issues]: https://github.com/nubs/random-name-generator/issues
+[pull-requests]: https://github.com/nubs/random-name-generator/pulls
+[build-script]: https://github.com/nubs/random-name-generator/blob/master/build.php
+[psr-1]: http://www.php-fig.org/psr/psr-1/ "PSR-1 - Basic Coding Standard"
+[phpunit]: http://phpunit.de/ "PHPUnit - The PHP Testing Framework"
+[travis-ci]: https://travis-ci.org/nubs/random-name-generator
+[scrutinizer-ci]: https://scrutinizer-ci.com/g/nubs/random-name-generator/
+[coveralls]: https://coveralls.io/github/nubs/random-name-generator
+[docker]: https://docker.com/ "Docker - Build, Ship, and Run Any App, Anywhere"
+[docker-compose]: https://www.docker.com/docker-compose
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/Dockerfile.tests b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/Dockerfile.tests
new file mode 100644
index 0000000..50b01c1
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/Dockerfile.tests
@@ -0,0 +1,5 @@
+FROM nubs/phpunit
+
+MAINTAINER Spencer Rinehart <anubis@overthemonkey.com>
+
+CMD ["./build.php"]
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/LICENSE b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/LICENSE
new file mode 100644
index 0000000..4efa9e9
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014-2016 Spencer Rinehart
+
+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.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/README.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/README.md
new file mode 100644
index 0000000..70d76cf
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/README.md
@@ -0,0 +1,91 @@
+# Random Name Generator
+A PHP library to create interesting, sometimes entertaining, random names.
+
+[![Build Status](http://img.shields.io/travis/nubs/random-name-generator.svg?style=flat)](https://travis-ci.org/nubs/random-name-generator)
+[![Scrutinizer Code Quality](http://img.shields.io/scrutinizer/g/nubs/random-name-generator.svg?style=flat)](https://scrutinizer-ci.com/g/nubs/random-name-generator/)
+[![Coverage Status](https://coveralls.io/repos/nubs/random-name-generator/badge.svg?branch=master&service=github)](https://coveralls.io/github/nubs/random-name-generator?branch=master)
+
+[![Latest Stable Version](http://img.shields.io/packagist/v/nubs/random-name-generator.svg?style=flat)](https://packagist.org/packages/nubs/random-name-generator)
+[![Total Downloads](http://img.shields.io/packagist/dt/nubs/random-name-generator.svg?style=flat)](https://packagist.org/packages/nubs/random-name-generator)
+[![License](http://img.shields.io/packagist/l/nubs/random-name-generator.svg?style=flat)](https://packagist.org/packages/nubs/random-name-generator)
+
+[![Dependency Status](https://www.versioneye.com/user/projects/537d561814c15855aa000019/badge.svg?style=flat)](https://www.versioneye.com/user/projects/537d561814c15855aa000019)
+
+## Requirements
+This library requires PHP 5.6, or newer.
+
+## Installation
+This package uses [composer](https://getcomposer.org) so you can just add
+`nubs/random-name-generator` as a dependency to your `composer.json` file or
+execute the following command:
+
+```bash
+composer require nubs/random-name-generator
+```
+
+## Generators
+
+### All
+The "all" generator will utilize all other configured generators to generate
+random names. It will select from the list of generators randomly and then
+use them to generate a random name using their functionality.
+
+#### Usage
+```php
+$generator = \Nubs\RandomNameGenerator\All::create();
+echo $generator->getName();
+```
+
+Alternatively, if you want to configure/build the generators to use instead of
+using all of the available generators, you can construct them yourself:
+
+```php
+$generator = new \Nubs\RandomNameGenerator\All(
+ [
+ new \Nubs\RandomNameGenerator\Alliteration(),
+ new \Nubs\RandomNameGenerator\Vgng()
+ ]
+);
+```
+
+### Video Game Names
+The video game name generator is based off of [prior](http://videogamena.me/)
+[art](https://github.com/nullpuppy/vgng). It will generate unique names based
+off of "typical" video games.
+
+#### Examples
+* *Kamikaze Bubblegum Warrior*
+* *Rockin' Valkyrie Gaiden*
+* *Neurotic Jackhammer Detective*
+* *My Little Mountain Climber Conflict*
+* *Small-Time Princess vs. The Space Mutants*
+
+You can also use [this web example](http://sam.sbat.com/) to see more example
+video game names generated by this library.
+
+#### Usage
+```php
+$generator = new \Nubs\RandomNameGenerator\Vgng();
+echo $generator->getName();
+```
+
+## Alliterative Names
+The alliteration name generator is based off of a list of
+[adjectives](http://grammar.yourdictionary.com/parts-of-speech/adjectives/list-of-adjective-words.html)
+and a list of [animals](https://animalcorner.co.uk/animals/).
+
+#### Examples
+* *Agreeable Anaconda*
+* *Disturbed Duck*
+* *Misty Meerkat*
+* *Prickly Pig*
+
+#### Usage
+```php
+$generator = new \Nubs\RandomNameGenerator\Alliteration();
+echo $generator->getName();
+```
+
+## License
+random-name-generator is licensed under the MIT license. See
+[LICENSE](LICENSE) for the full license text.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/build.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/build.php
new file mode 100644
index 0000000..f285d55
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/build.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+<?php
+require 'vendor/autoload.php';
+
+$phpcsCLI = new PHP_CodeSniffer_CLI();
+$phpcsViolations = $phpcsCLI->process(['standard' => ['PSR1'], 'files' => ['src', 'tests', 'build.php']]);
+if ($phpcsViolations > 0) {
+ exit(1);
+}
+
+$phpunitConfiguration = PHPUnit_Util_Configuration::getInstance(__DIR__ . '/phpunit.xml');
+$phpunitArguments = ['coverageHtml' => __DIR__ . '/coverage', 'configuration' => $phpunitConfiguration];
+$testRunner = new PHPUnit_TextUI_TestRunner();
+$result = $testRunner->doRun($phpunitConfiguration->getTestSuiteConfiguration(), $phpunitArguments, false);
+if (!$result->wasSuccessful()) {
+ exit(1);
+}
+
+$coverageReport = $result->getCodeCoverage()->getReport();
+if ($coverageReport->getNumExecutedLines() !== $coverageReport->getNumExecutableLines()) {
+ file_put_contents('php://stderr', "Code coverage was NOT 100%\n");
+ exit(1);
+}
+
+file_put_contents('php://stderr', "Code coverage was 100%\n");
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/composer.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/composer.json
new file mode 100644
index 0000000..d91fbff
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/composer.json
@@ -0,0 +1,30 @@
+{
+ "name": "nubs/random-name-generator",
+ "description": "A library to create interesting, sometimes entertaining, random names.",
+ "keywords": ["random", "generator", "video game", "alliteration"],
+ "authors": [
+ {
+ "name": "Spencer Rinehart",
+ "email": "anubis@overthemonkey.com",
+ "role": "Developer"
+ }
+ ],
+ "license": "MIT",
+ "require": {
+ "php": "~5.6 || ~7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~5.0",
+ "satooshi/php-coveralls": "~1.0",
+ "cinam/randomizer": ">=1.1.1,<2.0",
+ "squizlabs/php_codesniffer": "~2.3"
+ },
+ "autoload": {
+ "psr-4": {
+ "Nubs\\RandomNameGenerator\\": "src"
+ }
+ },
+ "scripts": {
+ "test": "./build.php"
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/composer.lock b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/composer.lock
new file mode 100644
index 0000000..77d0fdb
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/composer.lock
@@ -0,0 +1,1963 @@
+{
+ "_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#composer-lock-the-lock-file",
+ "This file is @generated automatically"
+ ],
+ "hash": "4b2c771eec058567f987575b9b3199a2",
+ "content-hash": "826850e9b398ef46a5bc5fec486788f6",
+ "packages": [],
+ "packages-dev": [
+ {
+ "name": "cinam/randomizer",
+ "version": "1.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/cinam/randomizer.git",
+ "reference": "beca7e3ad5b93cebdb897cd47247b19a109b970f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/cinam/randomizer/zipball/beca7e3ad5b93cebdb897cd47247b19a109b970f",
+ "reference": "beca7e3ad5b93cebdb897cd47247b19a109b970f",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "3.7.*"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Cinam\\Randomizer\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "cinam",
+ "email": "cinam@hotmail.com"
+ }
+ ],
+ "description": "Tools for generating random values.",
+ "homepage": "http://github.com/cinam/randomizer",
+ "keywords": [
+ "random",
+ "random numbers",
+ "random values"
+ ],
+ "time": "2014-06-01 07:27:32"
+ },
+ {
+ "name": "doctrine/instantiator",
+ "version": "1.0.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/instantiator.git",
+ "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d",
+ "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3,<8.0-DEV"
+ },
+ "require-dev": {
+ "athletic/athletic": "~0.1.8",
+ "ext-pdo": "*",
+ "ext-phar": "*",
+ "phpunit/phpunit": "~4.0",
+ "squizlabs/php_codesniffer": "~2.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com",
+ "homepage": "http://ocramius.github.com/"
+ }
+ ],
+ "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
+ "homepage": "https://github.com/doctrine/instantiator",
+ "keywords": [
+ "constructor",
+ "instantiate"
+ ],
+ "time": "2015-06-14 21:17:01"
+ },
+ {
+ "name": "guzzle/guzzle",
+ "version": "v3.9.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/guzzle3.git",
+ "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/guzzle3/zipball/0645b70d953bc1c067bbc8d5bc53194706b628d9",
+ "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9",
+ "shasum": ""
+ },
+ "require": {
+ "ext-curl": "*",
+ "php": ">=5.3.3",
+ "symfony/event-dispatcher": "~2.1"
+ },
+ "replace": {
+ "guzzle/batch": "self.version",
+ "guzzle/cache": "self.version",
+ "guzzle/common": "self.version",
+ "guzzle/http": "self.version",
+ "guzzle/inflection": "self.version",
+ "guzzle/iterator": "self.version",
+ "guzzle/log": "self.version",
+ "guzzle/parser": "self.version",
+ "guzzle/plugin": "self.version",
+ "guzzle/plugin-async": "self.version",
+ "guzzle/plugin-backoff": "self.version",
+ "guzzle/plugin-cache": "self.version",
+ "guzzle/plugin-cookie": "self.version",
+ "guzzle/plugin-curlauth": "self.version",
+ "guzzle/plugin-error-response": "self.version",
+ "guzzle/plugin-history": "self.version",
+ "guzzle/plugin-log": "self.version",
+ "guzzle/plugin-md5": "self.version",
+ "guzzle/plugin-mock": "self.version",
+ "guzzle/plugin-oauth": "self.version",
+ "guzzle/service": "self.version",
+ "guzzle/stream": "self.version"
+ },
+ "require-dev": {
+ "doctrine/cache": "~1.3",
+ "monolog/monolog": "~1.0",
+ "phpunit/phpunit": "3.7.*",
+ "psr/log": "~1.0",
+ "symfony/class-loader": "~2.1",
+ "zendframework/zend-cache": "2.*,<2.3",
+ "zendframework/zend-log": "2.*,<2.3"
+ },
+ "suggest": {
+ "guzzlehttp/guzzle": "Guzzle 5 has moved to a new package name. The package you have installed, Guzzle 3, is deprecated."
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.9-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Guzzle": "src/",
+ "Guzzle\\Tests": "tests/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "Guzzle Community",
+ "homepage": "https://github.com/guzzle/guzzle/contributors"
+ }
+ ],
+ "description": "PHP HTTP client. This library is deprecated in favor of https://packagist.org/packages/guzzlehttp/guzzle",
+ "homepage": "http://guzzlephp.org/",
+ "keywords": [
+ "client",
+ "curl",
+ "framework",
+ "http",
+ "http client",
+ "rest",
+ "web service"
+ ],
+ "abandoned": "guzzlehttp/guzzle",
+ "time": "2015-03-18 18:23:50"
+ },
+ {
+ "name": "myclabs/deep-copy",
+ "version": "1.5.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/myclabs/DeepCopy.git",
+ "reference": "a8773992b362b58498eed24bf85005f363c34771"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/a8773992b362b58498eed24bf85005f363c34771",
+ "reference": "a8773992b362b58498eed24bf85005f363c34771",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4.0"
+ },
+ "require-dev": {
+ "doctrine/collections": "1.*",
+ "phpunit/phpunit": "~4.1"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "DeepCopy\\": "src/DeepCopy/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Create deep copies (clones) of your objects",
+ "homepage": "https://github.com/myclabs/DeepCopy",
+ "keywords": [
+ "clone",
+ "copy",
+ "duplicate",
+ "object",
+ "object graph"
+ ],
+ "time": "2015-11-20 12:04:31"
+ },
+ {
+ "name": "phpdocumentor/reflection-common",
+ "version": "1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
+ "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
+ "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.6"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": [
+ "src"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jaap van Otterdijk",
+ "email": "opensource@ijaap.nl"
+ }
+ ],
+ "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
+ "homepage": "http://www.phpdoc.org",
+ "keywords": [
+ "FQSEN",
+ "phpDocumentor",
+ "phpdoc",
+ "reflection",
+ "static analysis"
+ ],
+ "time": "2015-12-27 11:43:31"
+ },
+ {
+ "name": "phpdocumentor/reflection-docblock",
+ "version": "3.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
+ "reference": "9270140b940ff02e58ec577c237274e92cd40cdd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/9270140b940ff02e58ec577c237274e92cd40cdd",
+ "reference": "9270140b940ff02e58ec577c237274e92cd40cdd",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5",
+ "phpdocumentor/reflection-common": "^1.0@dev",
+ "phpdocumentor/type-resolver": "^0.2.0",
+ "webmozart/assert": "^1.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "^0.9.4",
+ "phpunit/phpunit": "^4.4"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": [
+ "src/"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mike van Riel",
+ "email": "me@mikevanriel.com"
+ }
+ ],
+ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
+ "time": "2016-06-10 09:48:41"
+ },
+ {
+ "name": "phpdocumentor/type-resolver",
+ "version": "0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/TypeResolver.git",
+ "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/b39c7a5b194f9ed7bd0dd345c751007a41862443",
+ "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5",
+ "phpdocumentor/reflection-common": "^1.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "^0.9.4",
+ "phpunit/phpunit": "^5.2||^4.8.24"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": [
+ "src/"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mike van Riel",
+ "email": "me@mikevanriel.com"
+ }
+ ],
+ "time": "2016-06-10 07:14:17"
+ },
+ {
+ "name": "phpspec/prophecy",
+ "version": "v1.6.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpspec/prophecy.git",
+ "reference": "58a8137754bc24b25740d4281399a4a3596058e0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/58a8137754bc24b25740d4281399a4a3596058e0",
+ "reference": "58a8137754bc24b25740d4281399a4a3596058e0",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/instantiator": "^1.0.2",
+ "php": "^5.3|^7.0",
+ "phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
+ "sebastian/comparator": "^1.1",
+ "sebastian/recursion-context": "^1.0"
+ },
+ "require-dev": {
+ "phpspec/phpspec": "^2.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.6.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Prophecy\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Konstantin Kudryashov",
+ "email": "ever.zet@gmail.com",
+ "homepage": "http://everzet.com"
+ },
+ {
+ "name": "Marcello Duarte",
+ "email": "marcello.duarte@gmail.com"
+ }
+ ],
+ "description": "Highly opinionated mocking framework for PHP 5.3+",
+ "homepage": "https://github.com/phpspec/prophecy",
+ "keywords": [
+ "Double",
+ "Dummy",
+ "fake",
+ "mock",
+ "spy",
+ "stub"
+ ],
+ "time": "2016-06-07 08:13:47"
+ },
+ {
+ "name": "phpunit/php-code-coverage",
+ "version": "4.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+ "reference": "5f3f7e736d6319d5f1fc402aff8b026da26709a3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/5f3f7e736d6319d5f1fc402aff8b026da26709a3",
+ "reference": "5f3f7e736d6319d5f1fc402aff8b026da26709a3",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.6 || ^7.0",
+ "phpunit/php-file-iterator": "~1.3",
+ "phpunit/php-text-template": "~1.2",
+ "phpunit/php-token-stream": "^1.4.2",
+ "sebastian/code-unit-reverse-lookup": "~1.0",
+ "sebastian/environment": "^1.3.2 || ^2.0",
+ "sebastian/version": "~1.0|~2.0"
+ },
+ "require-dev": {
+ "ext-xdebug": ">=2.1.4",
+ "phpunit/phpunit": "^5.4"
+ },
+ "suggest": {
+ "ext-dom": "*",
+ "ext-xdebug": ">=2.4.0",
+ "ext-xmlwriter": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
+ "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
+ "keywords": [
+ "coverage",
+ "testing",
+ "xunit"
+ ],
+ "time": "2016-07-26 14:39:29"
+ },
+ {
+ "name": "phpunit/php-file-iterator",
+ "version": "1.4.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
+ "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
+ "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "FilterIterator implementation that filters files based on a list of suffixes.",
+ "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
+ "keywords": [
+ "filesystem",
+ "iterator"
+ ],
+ "time": "2015-06-21 13:08:43"
+ },
+ {
+ "name": "phpunit/php-text-template",
+ "version": "1.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-text-template.git",
+ "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
+ "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Simple template engine.",
+ "homepage": "https://github.com/sebastianbergmann/php-text-template/",
+ "keywords": [
+ "template"
+ ],
+ "time": "2015-06-21 13:50:34"
+ },
+ {
+ "name": "phpunit/php-timer",
+ "version": "1.0.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-timer.git",
+ "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260",
+ "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4|~5"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Utility class for timing",
+ "homepage": "https://github.com/sebastianbergmann/php-timer/",
+ "keywords": [
+ "timer"
+ ],
+ "time": "2016-05-12 18:03:57"
+ },
+ {
+ "name": "phpunit/php-token-stream",
+ "version": "1.4.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-token-stream.git",
+ "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
+ "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
+ "shasum": ""
+ },
+ "require": {
+ "ext-tokenizer": "*",
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.2"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Wrapper around PHP's tokenizer extension.",
+ "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
+ "keywords": [
+ "tokenizer"
+ ],
+ "time": "2015-09-15 10:49:45"
+ },
+ {
+ "name": "phpunit/phpunit",
+ "version": "5.5.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
+ "reference": "46ec2d1522ae8c9a12aca6b7650e0be78bbb0502"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/46ec2d1522ae8c9a12aca6b7650e0be78bbb0502",
+ "reference": "46ec2d1522ae8c9a12aca6b7650e0be78bbb0502",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-json": "*",
+ "ext-pcre": "*",
+ "ext-reflection": "*",
+ "ext-spl": "*",
+ "myclabs/deep-copy": "~1.3",
+ "php": "^5.6 || ^7.0",
+ "phpspec/prophecy": "^1.3.1",
+ "phpunit/php-code-coverage": "^4.0.1",
+ "phpunit/php-file-iterator": "~1.4",
+ "phpunit/php-text-template": "~1.2",
+ "phpunit/php-timer": "^1.0.6",
+ "phpunit/phpunit-mock-objects": "^3.2",
+ "sebastian/comparator": "~1.1",
+ "sebastian/diff": "~1.2",
+ "sebastian/environment": "^1.3 || ^2.0",
+ "sebastian/exporter": "~1.2",
+ "sebastian/global-state": "~1.0",
+ "sebastian/object-enumerator": "~1.0",
+ "sebastian/resource-operations": "~1.0",
+ "sebastian/version": "~1.0|~2.0",
+ "symfony/yaml": "~2.1|~3.0"
+ },
+ "conflict": {
+ "phpdocumentor/reflection-docblock": "3.0.2"
+ },
+ "suggest": {
+ "phpunit/php-invoker": "~1.1"
+ },
+ "bin": [
+ "phpunit"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.5.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "The PHP Unit Testing framework.",
+ "homepage": "https://phpunit.de/",
+ "keywords": [
+ "phpunit",
+ "testing",
+ "xunit"
+ ],
+ "time": "2016-08-18 11:10:44"
+ },
+ {
+ "name": "phpunit/phpunit-mock-objects",
+ "version": "3.2.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
+ "reference": "4e83390f64e7ce04fcaec2ce95cd72823b431d19"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/4e83390f64e7ce04fcaec2ce95cd72823b431d19",
+ "reference": "4e83390f64e7ce04fcaec2ce95cd72823b431d19",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/instantiator": "^1.0.2",
+ "php": "^5.6 || ^7.0",
+ "phpunit/php-text-template": "^1.2",
+ "sebastian/exporter": "^1.2"
+ },
+ "conflict": {
+ "phpunit/phpunit": "<5.4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.4"
+ },
+ "suggest": {
+ "ext-soap": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Mock Object library for PHPUnit",
+ "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
+ "keywords": [
+ "mock",
+ "xunit"
+ ],
+ "time": "2016-08-17 09:33:51"
+ },
+ {
+ "name": "psr/log",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b",
+ "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b",
+ "shasum": ""
+ },
+ "type": "library",
+ "autoload": {
+ "psr-0": {
+ "Psr\\Log\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for logging libraries",
+ "keywords": [
+ "log",
+ "psr",
+ "psr-3"
+ ],
+ "time": "2012-12-21 11:40:51"
+ },
+ {
+ "name": "satooshi/php-coveralls",
+ "version": "v1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/satooshi/php-coveralls.git",
+ "reference": "da51d304fe8622bf9a6da39a8446e7afd432115c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/satooshi/php-coveralls/zipball/da51d304fe8622bf9a6da39a8446e7afd432115c",
+ "reference": "da51d304fe8622bf9a6da39a8446e7afd432115c",
+ "shasum": ""
+ },
+ "require": {
+ "ext-json": "*",
+ "ext-simplexml": "*",
+ "guzzle/guzzle": "^2.8|^3.0",
+ "php": ">=5.3.3",
+ "psr/log": "^1.0",
+ "symfony/config": "^2.1|^3.0",
+ "symfony/console": "^2.1|^3.0",
+ "symfony/stopwatch": "^2.0|^3.0",
+ "symfony/yaml": "^2.0|^3.0"
+ },
+ "suggest": {
+ "symfony/http-kernel": "Allows Symfony integration"
+ },
+ "bin": [
+ "bin/coveralls"
+ ],
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Satooshi\\": "src/Satooshi/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Kitamura Satoshi",
+ "email": "with.no.parachute@gmail.com",
+ "homepage": "https://www.facebook.com/satooshi.jp"
+ }
+ ],
+ "description": "PHP client library for Coveralls API",
+ "homepage": "https://github.com/satooshi/php-coveralls",
+ "keywords": [
+ "ci",
+ "coverage",
+ "github",
+ "test"
+ ],
+ "time": "2016-01-20 17:35:46"
+ },
+ {
+ "name": "sebastian/code-unit-reverse-lookup",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
+ "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/c36f5e7cfce482fde5bf8d10d41a53591e0198fe",
+ "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Looks up which function or method a line of code belongs to",
+ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
+ "time": "2016-02-13 06:45:14"
+ },
+ {
+ "name": "sebastian/comparator",
+ "version": "1.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/comparator.git",
+ "reference": "937efb279bd37a375bcadf584dec0726f84dbf22"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22",
+ "reference": "937efb279bd37a375bcadf584dec0726f84dbf22",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "sebastian/diff": "~1.2",
+ "sebastian/exporter": "~1.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@2bepublished.at"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides the functionality to compare PHP values for equality",
+ "homepage": "http://www.github.com/sebastianbergmann/comparator",
+ "keywords": [
+ "comparator",
+ "compare",
+ "equality"
+ ],
+ "time": "2015-07-26 15:48:44"
+ },
+ {
+ "name": "sebastian/diff",
+ "version": "1.4.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/diff.git",
+ "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e",
+ "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.8"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kore Nordmann",
+ "email": "mail@kore-nordmann.de"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Diff implementation",
+ "homepage": "https://github.com/sebastianbergmann/diff",
+ "keywords": [
+ "diff"
+ ],
+ "time": "2015-12-08 07:14:41"
+ },
+ {
+ "name": "sebastian/environment",
+ "version": "1.3.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/environment.git",
+ "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea",
+ "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.3 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8 || ^5.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.3.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides functionality to handle HHVM/PHP environments",
+ "homepage": "http://www.github.com/sebastianbergmann/environment",
+ "keywords": [
+ "Xdebug",
+ "environment",
+ "hhvm"
+ ],
+ "time": "2016-08-18 05:49:44"
+ },
+ {
+ "name": "sebastian/exporter",
+ "version": "1.2.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/exporter.git",
+ "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4",
+ "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "sebastian/recursion-context": "~1.0"
+ },
+ "require-dev": {
+ "ext-mbstring": "*",
+ "phpunit/phpunit": "~4.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.3.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@2bepublished.at"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ }
+ ],
+ "description": "Provides the functionality to export PHP variables for visualization",
+ "homepage": "http://www.github.com/sebastianbergmann/exporter",
+ "keywords": [
+ "export",
+ "exporter"
+ ],
+ "time": "2016-06-17 09:04:28"
+ },
+ {
+ "name": "sebastian/global-state",
+ "version": "1.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/global-state.git",
+ "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4",
+ "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.2"
+ },
+ "suggest": {
+ "ext-uopz": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Snapshotting of global state",
+ "homepage": "http://www.github.com/sebastianbergmann/global-state",
+ "keywords": [
+ "global state"
+ ],
+ "time": "2015-10-12 03:26:01"
+ },
+ {
+ "name": "sebastian/object-enumerator",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/object-enumerator.git",
+ "reference": "d4ca2fb70344987502567bc50081c03e6192fb26"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/d4ca2fb70344987502567bc50081c03e6192fb26",
+ "reference": "d4ca2fb70344987502567bc50081c03e6192fb26",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6",
+ "sebastian/recursion-context": "~1.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Traverses array structures and object graphs to enumerate all referenced objects",
+ "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
+ "time": "2016-01-28 13:25:10"
+ },
+ {
+ "name": "sebastian/recursion-context",
+ "version": "1.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/recursion-context.git",
+ "reference": "913401df809e99e4f47b27cdd781f4a258d58791"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791",
+ "reference": "913401df809e99e4f47b27cdd781f4a258d58791",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ }
+ ],
+ "description": "Provides functionality to recursively process PHP variables",
+ "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
+ "time": "2015-11-11 19:50:13"
+ },
+ {
+ "name": "sebastian/resource-operations",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/resource-operations.git",
+ "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
+ "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides a list of PHP built-in functions that operate on resources",
+ "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
+ "time": "2015-07-28 20:34:47"
+ },
+ {
+ "name": "sebastian/version",
+ "version": "2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/version.git",
+ "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5",
+ "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library that helps with managing the version number of Git-hosted PHP projects",
+ "homepage": "https://github.com/sebastianbergmann/version",
+ "time": "2016-02-04 12:56:52"
+ },
+ {
+ "name": "squizlabs/php_codesniffer",
+ "version": "2.6.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
+ "reference": "4edb770cb853def6e60c93abb088ad5ac2010c83"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/4edb770cb853def6e60c93abb088ad5ac2010c83",
+ "reference": "4edb770cb853def6e60c93abb088ad5ac2010c83",
+ "shasum": ""
+ },
+ "require": {
+ "ext-simplexml": "*",
+ "ext-tokenizer": "*",
+ "ext-xmlwriter": "*",
+ "php": ">=5.1.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.0"
+ },
+ "bin": [
+ "scripts/phpcs",
+ "scripts/phpcbf"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "CodeSniffer.php",
+ "CodeSniffer/CLI.php",
+ "CodeSniffer/Exception.php",
+ "CodeSniffer/File.php",
+ "CodeSniffer/Fixer.php",
+ "CodeSniffer/Report.php",
+ "CodeSniffer/Reporting.php",
+ "CodeSniffer/Sniff.php",
+ "CodeSniffer/Tokens.php",
+ "CodeSniffer/Reports/",
+ "CodeSniffer/Tokenizers/",
+ "CodeSniffer/DocGenerators/",
+ "CodeSniffer/Standards/AbstractPatternSniff.php",
+ "CodeSniffer/Standards/AbstractScopeSniff.php",
+ "CodeSniffer/Standards/AbstractVariableSniff.php",
+ "CodeSniffer/Standards/IncorrectPatternException.php",
+ "CodeSniffer/Standards/Generic/Sniffs/",
+ "CodeSniffer/Standards/MySource/Sniffs/",
+ "CodeSniffer/Standards/PEAR/Sniffs/",
+ "CodeSniffer/Standards/PSR1/Sniffs/",
+ "CodeSniffer/Standards/PSR2/Sniffs/",
+ "CodeSniffer/Standards/Squiz/Sniffs/",
+ "CodeSniffer/Standards/Zend/Sniffs/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Greg Sherwood",
+ "role": "lead"
+ }
+ ],
+ "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
+ "homepage": "http://www.squizlabs.com/php-codesniffer",
+ "keywords": [
+ "phpcs",
+ "standards"
+ ],
+ "time": "2016-07-13 23:29:13"
+ },
+ {
+ "name": "symfony/config",
+ "version": "v3.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/config.git",
+ "reference": "a7630397b91be09cdd2fe57fd13612e258700598"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/config/zipball/a7630397b91be09cdd2fe57fd13612e258700598",
+ "reference": "a7630397b91be09cdd2fe57fd13612e258700598",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9",
+ "symfony/filesystem": "~2.8|~3.0"
+ },
+ "suggest": {
+ "symfony/yaml": "To use the yaml reference dumper"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.1-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Config\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Config Component",
+ "homepage": "https://symfony.com",
+ "time": "2016-07-26 08:04:17"
+ },
+ {
+ "name": "symfony/console",
+ "version": "v3.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/console.git",
+ "reference": "f9e638e8149e9e41b570ff092f8007c477ef0ce5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/console/zipball/f9e638e8149e9e41b570ff092f8007c477ef0ce5",
+ "reference": "f9e638e8149e9e41b570ff092f8007c477ef0ce5",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9",
+ "symfony/polyfill-mbstring": "~1.0"
+ },
+ "require-dev": {
+ "psr/log": "~1.0",
+ "symfony/event-dispatcher": "~2.8|~3.0",
+ "symfony/process": "~2.8|~3.0"
+ },
+ "suggest": {
+ "psr/log": "For using the console logger",
+ "symfony/event-dispatcher": "",
+ "symfony/process": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.1-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Console\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Console Component",
+ "homepage": "https://symfony.com",
+ "time": "2016-07-26 08:04:17"
+ },
+ {
+ "name": "symfony/event-dispatcher",
+ "version": "v2.8.9",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/event-dispatcher.git",
+ "reference": "889983a79a043dfda68f38c38b6dba092dd49cd8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/889983a79a043dfda68f38c38b6dba092dd49cd8",
+ "reference": "889983a79a043dfda68f38c38b6dba092dd49cd8",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.9"
+ },
+ "require-dev": {
+ "psr/log": "~1.0",
+ "symfony/config": "~2.0,>=2.0.5|~3.0.0",
+ "symfony/dependency-injection": "~2.6|~3.0.0",
+ "symfony/expression-language": "~2.6|~3.0.0",
+ "symfony/stopwatch": "~2.3|~3.0.0"
+ },
+ "suggest": {
+ "symfony/dependency-injection": "",
+ "symfony/http-kernel": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.8-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\EventDispatcher\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony EventDispatcher Component",
+ "homepage": "https://symfony.com",
+ "time": "2016-07-28 16:56:28"
+ },
+ {
+ "name": "symfony/filesystem",
+ "version": "v3.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/filesystem.git",
+ "reference": "bb29adceb552d202b6416ede373529338136e84f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/bb29adceb552d202b6416ede373529338136e84f",
+ "reference": "bb29adceb552d202b6416ede373529338136e84f",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.1-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Filesystem\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Filesystem Component",
+ "homepage": "https://symfony.com",
+ "time": "2016-07-20 05:44:26"
+ },
+ {
+ "name": "symfony/polyfill-mbstring",
+ "version": "v1.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
+ "reference": "dff51f72b0706335131b00a7f49606168c582594"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/dff51f72b0706335131b00a7f49606168c582594",
+ "reference": "dff51f72b0706335131b00a7f49606168c582594",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "suggest": {
+ "ext-mbstring": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Mbstring\\": ""
+ },
+ "files": [
+ "bootstrap.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": "Symfony polyfill for the Mbstring extension",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "mbstring",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "time": "2016-05-18 14:26:46"
+ },
+ {
+ "name": "symfony/stopwatch",
+ "version": "v3.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/stopwatch.git",
+ "reference": "bb42806b12c5f89db4ebf64af6741afe6d8457e1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/stopwatch/zipball/bb42806b12c5f89db4ebf64af6741afe6d8457e1",
+ "reference": "bb42806b12c5f89db4ebf64af6741afe6d8457e1",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.1-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Stopwatch\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Stopwatch Component",
+ "homepage": "https://symfony.com",
+ "time": "2016-06-29 05:41:56"
+ },
+ {
+ "name": "symfony/yaml",
+ "version": "v3.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/yaml.git",
+ "reference": "1819adf2066880c7967df7180f4f662b6f0567ac"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/1819adf2066880c7967df7180f4f662b6f0567ac",
+ "reference": "1819adf2066880c7967df7180f4f662b6f0567ac",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.1-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Yaml\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Yaml Component",
+ "homepage": "https://symfony.com",
+ "time": "2016-07-17 14:02:08"
+ },
+ {
+ "name": "webmozart/assert",
+ "version": "1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/webmozart/assert.git",
+ "reference": "bb2d123231c095735130cc8f6d31385a44c7b308"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/webmozart/assert/zipball/bb2d123231c095735130cc8f6d31385a44c7b308",
+ "reference": "bb2d123231c095735130cc8f6d31385a44c7b308",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.3|^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.6",
+ "sebastian/version": "^1.0.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Webmozart\\Assert\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@gmail.com"
+ }
+ ],
+ "description": "Assertions to validate method input/output with nice error messages.",
+ "keywords": [
+ "assert",
+ "check",
+ "validate"
+ ],
+ "time": "2016-08-09 15:02:57"
+ }
+ ],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": {
+ "php": "~5.6 || ~7.0"
+ },
+ "platform-dev": []
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/docker-compose.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/docker-compose.yml
new file mode 100644
index 0000000..e52fe45
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/docker-compose.yml
@@ -0,0 +1,8 @@
+version: "2"
+services:
+ build:
+ build:
+ context: .
+ dockerfile: Dockerfile.tests
+ volumes:
+ - .:/code
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/phpunit.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/phpunit.xml
new file mode 100644
index 0000000..dc845da
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/phpunit.xml
@@ -0,0 +1,10 @@
+<phpunit colors="true" forceCoversAnnotation="true" strict="true">
+ <testsuite name="Unit Tests">
+ <directory>./tests</directory>
+ </testsuite>
+ <filter>
+ <whitelist>
+ <directory>src</directory>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/AbstractGenerator.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/AbstractGenerator.php
new file mode 100644
index 0000000..abfae12
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/AbstractGenerator.php
@@ -0,0 +1,19 @@
+<?php
+namespace Nubs\RandomNameGenerator;
+
+abstract class AbstractGenerator implements Generator
+{
+ /**
+ * Alias for getName so that the generator can be directly stringified.
+ *
+ * Note that this will return a different name everytime it is cast to a
+ * string.
+ *
+ * @api
+ * @return string A random name.
+ */
+ public function __toString()
+ {
+ return $this->getName();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/All.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/All.php
new file mode 100644
index 0000000..d044c74
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/All.php
@@ -0,0 +1,62 @@
+<?php
+namespace Nubs\RandomNameGenerator;
+
+use Cinam\Randomizer\Randomizer;
+
+/**
+ * A generator that uses all of the other generators randomly.
+ */
+class All extends AbstractGenerator implements Generator
+{
+ /** @type array The other generators to use. */
+ protected $_generators;
+
+ /** @type Cinam\Randomizer\Randomizer The random number generator. */
+ protected $_randomizer;
+
+ /**
+ * Initializes the All Generator with the list of generators to choose from.
+ *
+ * @api
+ * @param array $generators The random generators to use.
+ * @param \Cinam\Randomizer\Randomizer $randomizer The random number generator.
+ */
+ public function __construct(array $generators, Randomizer $randomizer = null)
+ {
+ $this->_generators = $generators;
+ $this->_randomizer = $randomizer;
+ }
+
+ /**
+ * Constructs an All Generator using the default list of generators.
+ *
+ * @api
+ * @param \Cinam\Randomizer\Randomizer $randomizer The random number generator.
+ * @return \Nubs\RandomNameGenerator\All The constructed generator.
+ */
+ public static function create(Randomizer $randomizer = null)
+ {
+ return new self([new Alliteration($randomizer), new Vgng($randomizer)], $randomizer);
+ }
+
+ /**
+ * Gets a randomly generated name using the configured generators.
+ *
+ * @api
+ * @return string A random name.
+ */
+ public function getName()
+ {
+ return $this->_getRandomGenerator()->getName();
+ }
+
+ /**
+ * Get a random generator from the list of generators.
+ *
+ * @return \Nubs\RandomNameGenerator\Generator A random generator.
+ */
+ protected function _getRandomGenerator()
+ {
+ return $this->_randomizer ? $this->_randomizer->getArrayValue($this->_generators) : $this->_generators[array_rand($this->_generators)];
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/Alliteration.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/Alliteration.php
new file mode 100644
index 0000000..68ef3a2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/Alliteration.php
@@ -0,0 +1,59 @@
+<?php
+namespace Nubs\RandomNameGenerator;
+
+use Cinam\Randomizer\Randomizer;
+
+/**
+ * Defines an alliterative name generator.
+ */
+class Alliteration extends AbstractGenerator implements Generator
+{
+ /** @type array The definition of the potential adjectives. */
+ protected $_adjectives;
+
+ /** @type array The definition of the potential nouns. */
+ protected $_nouns;
+
+ /** @type Cinam\Randomizer\Randomizer The random number generator. */
+ protected $_randomizer;
+
+ /**
+ * Initializes the Alliteration Generator with the default word lists.
+ *
+ * @api
+ * @param \Cinam\Randomizer\Randomizer $randomizer The random number generator.
+ */
+ public function __construct(Randomizer $randomizer = null)
+ {
+ $this->_randomizer = $randomizer;
+ $this->_adjectives = file(__DIR__ . '/adjectives.txt', FILE_IGNORE_NEW_LINES);
+ $this->_nouns = file(__DIR__ . '/nouns.txt', FILE_IGNORE_NEW_LINES);
+ }
+
+ /**
+ * Gets a randomly generated alliterative name.
+ *
+ * @api
+ * @return string A random alliterative name.
+ */
+ public function getName()
+ {
+ $adjective = $this->_getRandomWord($this->_adjectives);
+ $noun = $this->_getRandomWord($this->_nouns, $adjective[0]);
+
+ return ucwords("{$adjective} {$noun}");
+ }
+
+ /**
+ * Get a random word from the list of words, optionally filtering by starting letter.
+ *
+ * @param array $words An array of words to choose from.
+ * @param string $startingLetter The desired starting letter of the word.
+ * @return string The random word.
+ */
+ protected function _getRandomWord(array $words, $startingLetter = null)
+ {
+ $wordsToSearch = $startingLetter === null ? $words : preg_grep("/^{$startingLetter}/", $words);
+ return $this->_randomizer ? $this->_randomizer->getArrayValue($wordsToSearch) : $wordsToSearch[array_rand($wordsToSearch)];
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/Generator.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/Generator.php
new file mode 100644
index 0000000..572c990
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/Generator.php
@@ -0,0 +1,16 @@
+<?php
+namespace Nubs\RandomNameGenerator;
+
+/**
+ * Defines the standard interface for all the random name generators.
+ */
+interface Generator
+{
+ /**
+ * Gets a randomly generated name.
+ *
+ * @api
+ * @return string A random name.
+ */
+ public function getName();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/Vgng.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/Vgng.php
new file mode 100644
index 0000000..2c43224
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/Vgng.php
@@ -0,0 +1,138 @@
+<?php
+namespace Nubs\RandomNameGenerator;
+
+use Cinam\Randomizer\Randomizer;
+
+/**
+ * Defines a video game name generator based off of
+ * https://github.com/nullpuppy/vgng which in turn is based off of
+ * http://videogamena.me/vgng.js.
+ */
+class Vgng extends AbstractGenerator implements Generator
+{
+ /** @type array The definition of the potential names. */
+ protected $_definitionSets;
+
+ /** @type Cinam\Randomizer\Randomizer The random number generator. */
+ protected $_randomizer;
+
+ /**
+ * Initializes the Video Game Name Generator from the default word list.
+ *
+ * @api
+ * @param \Cinam\Randomizer\Randomizer $randomizer The random number generator.
+ */
+ public function __construct(Randomizer $randomizer = null)
+ {
+ $this->_randomizer = $randomizer;
+ $this->_definitionSets = array_map(
+ [$this, '_parseSection'],
+ $this->_getSections($this->_getFileContents())
+ );
+ }
+
+ /**
+ * Gets a randomly generated video game name.
+ *
+ * @api
+ * @return string A random video game name.
+ */
+ public function getName()
+ {
+ $similarWords = [];
+ $words = [];
+
+ foreach ($this->_definitionSets as $definitionSet) {
+ $word = $this->_getUniqueWord($definitionSet, $similarWords);
+ $words[] = $word['word'];
+ $similarWords[] = $word['word'];
+ $similarWords = array_merge($similarWords, $word['similarWords']);
+ }
+
+ return implode(' ', $words);
+ }
+
+ /**
+ * Get a definition from the definitions that does not exist already.
+ *
+ * @param array $definitions The word list to pick from.
+ * @param array $existingWords The already-chosen words to avoid.
+ * @return array The definition of a previously unchosen word.
+ */
+ protected function _getUniqueWord(array $definitions, array $existingWords)
+ {
+ $definition = $this->_randomizer ? $this->_randomizer->getArrayValue($definitions) : $definitions[array_rand($definitions)];
+
+ if (array_search($definition['word'], $existingWords) === false) {
+ return $definition;
+ }
+
+ return $this->_getUniqueWord($definitions, $existingWords);
+ }
+
+ /**
+ * Gets the file contents of the video_game_names.txt file.
+ *
+ * @return string The video_game_names.txt contents.
+ */
+ protected function _getFileContents()
+ {
+ return file_get_contents(__DIR__ . '/video_game_names.txt');
+ }
+
+ /**
+ * Separates the contents into each of the word list sections.
+ *
+ * This builder operates by picking a random word from each of a consecutive
+ * list of word lists. These separate lists are separated by a line
+ * consisting of four hyphens in the file.
+ *
+ * @param string $contents The file contents.
+ * @return array Each section split into its own string.
+ */
+ protected function _getSections($contents)
+ {
+ return array_map('trim', explode('----', $contents));
+ }
+
+ /**
+ * Parses the given section into the final definitions.
+ *
+ * @param string $section The newline-separated list of words in a section.
+ * @return array The parsed section into its final form.
+ */
+ protected function _parseSection($section)
+ {
+ return array_map(
+ [$this, '_parseDefinition'],
+ $this->_getDefinitionsFromSection($section)
+ );
+ }
+
+ /**
+ * Gets the separate definitions from the given section.
+ *
+ * @param string $section The newline-separated list of words in a section.
+ * @return array Each word split out, but unparsed.
+ */
+ protected function _getDefinitionsFromSection($section)
+ {
+ return array_map('trim', explode("\n", $section));
+ }
+
+ /**
+ * Parses a single definition into its component pieces.
+ *
+ * The format of a definition in a file is word[^similarWord|...].
+ *
+ * @param string $definition The definition.
+ * @return array The formatted definition.
+ */
+ protected function _parseDefinition($definition)
+ {
+ $word = strtok($definition, '^');
+ $similarWords = array_filter(explode('|', strtok('^')));
+
+ return ['word' => $word, 'similarWords' => $similarWords];
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/adjectives.txt b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/adjectives.txt
new file mode 100644
index 0000000..f8d3247
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/adjectives.txt
@@ -0,0 +1,233 @@
+adorable
+adventurous
+aggressive
+agreeable
+alert
+alive
+amused
+angry
+annoyed
+annoying
+anxious
+arrogant
+ashamed
+attractive
+average
+awful
+bad
+beautiful
+better
+bewildered
+black
+bloody
+blue
+blue-eyed
+blushing
+bored
+brainy
+brave
+breakable
+bright
+busy
+calm
+careful
+cautious
+charming
+cheerful
+clean
+clear
+clever
+cloudy
+clumsy
+colorful
+combative
+comfortable
+concerned
+condemned
+confused
+cooperative
+courageous
+crazy
+creepy
+crowded
+cruel
+curious
+cute
+dangerous
+dark
+dead
+defeated
+defiant
+delightful
+depressed
+determined
+different
+difficult
+disgusted
+distinct
+disturbed
+dizzy
+doubtful
+drab
+dull
+eager
+easy
+elated
+elegant
+embarrassed
+enchanting
+encouraging
+energetic
+enthusiastic
+envious
+evil
+excited
+expensive
+exuberant
+fair
+faithful
+famous
+fancy
+fantastic
+fierce
+filthy
+fine
+foolish
+fragile
+frail
+frantic
+friendly
+frightened
+funny
+gentle
+gifted
+glamorous
+gleaming
+glorious
+good
+gorgeous
+graceful
+grieving
+grotesque
+grumpy
+handsome
+happy
+healthy
+helpful
+helpless
+hilarious
+homeless
+homely
+horrible
+hungry
+hurt
+ill
+important
+impossible
+inexpensive
+innocent
+inquisitive
+itchy
+jealous
+jittery
+jolly
+joyous
+kind
+lazy
+light
+lively
+lonely
+long
+lovely
+lucky
+magnificent
+misty
+modern
+motionless
+muddy
+mushy
+mysterious
+nasty
+naughty
+nervous
+nice
+nutty
+obedient
+obnoxious
+odd
+old-fashioned
+open
+outrageous
+outstanding
+panicky
+perfect
+plain
+pleasant
+poised
+poor
+powerful
+precious
+prickly
+proud
+puzzled
+quaint
+real
+relieved
+repulsive
+rich
+scary
+selfish
+shiny
+shy
+silly
+sleepy
+smiling
+smoggy
+sore
+sparkling
+splendid
+spotless
+stormy
+strange
+stupid
+successful
+super
+talented
+tame
+tender
+tense
+terrible
+testy
+thankful
+thoughtful
+thoughtless
+tired
+tough
+troubled
+ugliest
+ugly
+uninterested
+unsightly
+unusual
+upset
+uptight
+vast
+victorious
+vivacious
+wandering
+weary
+wicked
+wide-eyed
+wild
+witty
+worrisome
+worried
+wrong
+xenophobic
+xanthous
+xerothermic
+yawning
+yellowed
+yucky
+zany
+zealous
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/nouns.txt b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/nouns.txt
new file mode 100644
index 0000000..4e4adc2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/nouns.txt
@@ -0,0 +1,313 @@
+aardvark
+addax
+albatross
+alligator
+alpaca
+anaconda
+angelfish
+anteater
+antelope
+ant
+ape
+armadillo
+baboon
+badger
+barracuda
+bat
+batfish
+bear
+beaver
+bee
+beetle
+bird
+bison
+boar
+booby
+buffalo
+bug
+butterfly
+buzzard
+caiman
+camel
+capuchin
+capybara
+caracal
+cardinal
+caribou
+cassowary
+cat
+caterpillar
+centipede
+chamois
+cheetah
+chicken
+chimpanzee
+chinchilla
+chipmunk
+cicada
+civet
+cobra
+cockroach
+cod
+constrictor
+copperhead
+cormorant
+corncrake
+cottonmouth
+cowfish
+cow
+coyote
+crab
+crane
+crayfish
+crocodile
+crossbill
+curlew
+deer
+dingo
+dog
+dogfish
+dolphin
+donkey
+dormouse
+dotterel
+dove
+dragonfly
+duck
+dugong
+dunlin
+eagle
+earthworm
+echidna
+eel
+eland
+elephant
+elk
+emu
+falcon
+ferret
+finch
+fish
+flamingo
+flatworm
+fly
+fowl
+fox
+frog
+gannet
+gaur
+gazelle
+gecko
+gemsbok
+gentoo
+gerbil
+gerenuk
+gharial
+gibbon
+giraffe
+gnat
+gnu
+goat
+goldfinch
+goosander
+goose
+gorilla
+goshawk
+grasshopper
+grebe
+grivet
+grouse
+guanaco
+gull
+hamerkop
+hamster
+hare
+hawk
+hedgehog
+heron
+herring
+hippopotamus
+hoopoe
+hornet
+horse
+hummingbird
+hyena
+ibex
+ibis
+iguana
+impala
+jackal
+jaguar
+jay
+jellyfish
+kangaroo
+katipo
+kea
+kestrel
+kingfisher
+kinkajou
+kitten
+koala
+kookaburra
+kouprey
+kudu
+ladybird
+lapwing
+lark
+lemur
+leopard
+lion
+lizard
+llama
+lobster
+locust
+loris
+louse
+lynx
+lyrebird
+macaque
+macaw
+magpie
+mallard
+mamba
+manatee
+mandrill
+mantis
+manx
+markhor
+marten
+meerkat
+millipede
+mink
+mockingbird
+mole
+mongoose
+monkey
+moose
+mosquito
+moth
+mouse
+narwhal
+newt
+nightingale
+ocelot
+octopus
+okapi
+opossum
+orangutan
+oryx
+osprey
+ostrich
+otter
+owl
+ox
+oyster
+oystercatcher
+panda
+panther
+parrot
+partridge
+peacock
+peafowl
+peccary
+pelican
+penguin
+petrel
+pheasant
+pig
+pigeon
+pintail
+piranha
+platypus
+plover
+polecat
+pollan
+pony
+porcupine
+porpoise
+puffin
+puma
+pygmy
+quagga
+quail
+quelea
+quetzal
+quoll
+rabbit
+raccoon
+rat
+ratel
+rattlesnake
+raven
+ray
+reindeer
+rhinoceros
+rook
+sable
+salamander
+salmon
+sandpiper
+sardine
+scarab
+seahorse
+seal
+serval
+shark
+sheep
+shrew
+shrike
+skimmer
+skipper
+skunk
+skylark
+sloth
+snail
+snake
+spider
+squirrel
+stag
+starling
+stoat
+stork
+swan
+swiftlet
+tamarin
+tapir
+tarantula
+tarsier
+teira
+termite
+tern
+thrush
+tiger
+toad
+tortoise
+toucan
+trout
+tuatara
+turkey
+turtle
+unicorn
+vendace
+vicuña
+vole
+vulture
+wallaby
+walrus
+warbler
+wasp
+weasel
+weevil
+whale
+wildebeest
+willet
+wolf
+wolverine
+wombat
+worm
+wren
+wryneck
+xenomorph
+yacare
+yak
+zebra
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/video_game_names.txt b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/video_game_names.txt
new file mode 100644
index 0000000..a2bcaa2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/src/video_game_names.txt
@@ -0,0 +1,1276 @@
+3D
+8-Bit
+A Boy and His
+Action
+Advanced^Advance
+Adventures of the^Adventure
+Aero
+African^in Africa
+Alcoholic
+Alien
+Allied
+All-American
+All-Night
+All-Star^Star|Starring Mickey Mouse|Stars|Superstar
+Almighty
+Amateur
+Amazing
+Amazon
+American
+Amish
+Amphibious
+Ancient
+Android^Cyborg
+Angry
+Apathetic
+Aquatic
+Arcane
+Armored
+Art of
+Asian
+Astral
+Attack of the^Attack
+Atomic^Nuclear
+Australian
+Awesome
+Barbie's
+Battle^Battleship|Battalion
+Battlefield:^Battle|Battleship|Battalion
+Beautiful^Beautician
+Bewildering
+Biblical
+Big^Big Game Hunter
+Big Bird's^Big Game Hunter
+Big-Time^Big Game Hunter
+Bionic
+Bizarre
+Bizarro
+Black
+Blasphemous
+Blazing
+Bling Bling
+Blissful
+Blocky
+Bloody^Blood|Bloodbath|of the Blood God
+Bonk's
+Boring
+Bouncin'
+Brain-Damaged
+British
+Britney Spears'
+BudgetSoft Presents:
+Caesar's
+Canadian
+Cantankerous
+Caribbean
+Catholic
+Celebrity
+Celtic
+Charlie Brown's
+Children of the
+Chillin'
+Chinese
+Chocolate
+Christian
+Claustrophobic
+College
+Colonial
+Combat
+Communist
+Confusing
+Cool
+Corporate
+Cosmic
+Crazy
+Create Your Own^Creator
+Creepy
+Cthulhu's
+Curse of the
+Custom
+Cyber
+Cybernetic
+Cyborg^Android
+Dance Dance^Breakdancing|Dance|Dance Mix|Dance Party|Dancers|Square Dancing
+Dangerous
+Darkest
+Day of the
+Dead or Alive^Death|Deathmatch|of Death|of the Dead
+Deadly^Death|Deathmatch|of Death|of the Dead
+Death-Defying^Death|Deathmatch|of Death|of the Dead
+Deep Space^of the Deep
+Def Jam
+Demonic
+Depressing
+Deranged
+Derek Smart's
+Dirty
+Disney's
+Distinguished
+Disturbing
+Divine
+Donkey Kong's
+Double
+Downtown
+Dr.
+Dracula's
+Drug-Induced
+Drunken
+Duke Nukem:
+Dwarven^Dwarf|Gnome|Midget
+Dynamite
+Ebony
+Eco-Friendly
+Educational
+Elderly
+Electric
+Elegant
+Elite
+Elmo's
+Emo
+Endless
+Enormous
+Enraged
+Epic
+Erotic
+Escape from the
+Eternal
+European
+Everybody Hates the
+Everybody Loves the
+Exciting
+Excruciating
+Explosive^Explosion
+Exquisite
+Extreme^X-Treme
+Fabulous
+Fancy
+Fantastic
+Fantasy
+Fatal
+Feverish
+Fiery
+Final
+Final Fantasy^Fantasy
+First-Person
+Fisher Price
+Flamboyant
+Fluffy
+Flying
+Forbidden
+Forgotten
+Frankenstein's
+French
+Frisky
+Fruity
+Full Metal
+Funky^Funk
+Furry
+Future
+Galactic
+Generic
+Geriatric
+German
+Ghetto
+Giant
+Glowing
+Go Go
+God of
+Golden
+Gothic^Goth
+Grand
+Great
+Grimy
+Guitar
+Happy
+Hardcore
+Haunted
+Hazardous
+Heavy
+Heavy Metal^Metal
+Heinous
+Helicopter
+Heroic^Hero|Heroes
+Hidden
+Hideous
+High-Speed^Speed
+Hillbilly
+Hindu
+Hip-Hop^Hippo
+History of the
+Hitler's^Nazi
+Ho-Hum
+Holy
+Horrifying
+Hyper
+Imperial
+Impossible
+In Search of
+In Search of the
+In the Lost Kingdom of
+In Your Face
+Inappropriate
+Inbred
+Incomprehensible
+Incredible
+Indian
+Indiana Jones and the
+Inept
+Infinite
+Ingenious
+Insane
+Intellectual
+Intelligent
+Intense
+Interactive
+International
+Internet
+Interstellar
+Invisible
+Irish
+Iron
+Irresistible
+Irritating
+Islamic
+Italian
+It's a Mad, Mad^Madness
+Jackie Chan's
+Jamaican
+Japanese
+Jedi
+Jewish
+Johnny Turbo's
+John Romero's
+Kabuki
+Kamikaze
+Kermit's
+Killer
+Kinect
+King of^King|Kingdom
+Kinky
+Kirby's
+Kosher
+Kung-fu
+Jack Thompson's
+Lair of the
+Latino
+Lazy
+Legacy of
+Legend of^Legend|Legends
+Legend of the^Legend|Legends
+Legendary^Legend|Legends
+Leisure Suit
+Lethal
+Little
+Looney Tunes
+Lord of the^Lord
+Lost
+Lovely^Love|of Love|Romance
+Low G
+Lucky
+Luigi's
+M.C. Escher's
+Madden
+Magic^of Magic|of Might and Magic
+Magical^Magic|of Magic|of Might and Magic
+Magnetic
+Major
+Manic^Mania|Maniac
+Maniac^Mania
+Mario's
+Mary Kate and Ashley's
+Master Chief's^Master
+Masters of^Master
+Masters of the^Master
+Maximum
+Mechanized
+Medieval
+Mega
+Mega Man's
+Merciless
+Metal
+Mexican
+Michael Jackson's
+Mickey's
+Micro
+Middle-Eastern^in the Middle East
+Mighty
+Mind-Bending
+Miniature^Dwarf|Gnome|Midget
+Miracle
+Monster^Monster Truck
+Monty Python's
+Morbid
+Morbidly Obese
+Mr.
+MTV's
+Muppet
+Musical^DJ|Music
+My First
+My Little
+My Very Own
+Mysterious^of Mystery
+Mystery^of Mystery
+Mystic^of Mystery
+Mystical^of Mystery
+Mythical
+Narcoleptic
+Nasty
+National Lampoon's
+Naughty
+NBA
+NCAA
+Nerf
+Neo
+Neon
+Neurotic
+New
+Night of the^Knights|Night|Nightmare
+Nighttime^Knights|Night|Nightmare
+Nihilistic
+Ninja
+No One Can Stop the
+Nostalgic
+Nuclear^Atomic
+Nudist
+Obsessive-Compulsive
+Occult
+Olympic
+Omega
+Orbital
+Pagan
+Panzer
+Papal
+Paranoid
+Pathetic
+Peaceful
+Perfect
+Perverted
+Phoenix Wright:
+Pixellated
+Planet of the^Planet
+Political
+Post-Apocalyptic
+Prehistoric
+Preschool
+Presidential
+Primal
+Pro
+Profane
+Professional^Pro
+Psychedelic
+Psycho
+Queen of the^Princess
+Quiet
+Rad
+Radical
+Radioactive
+Raging^Rage
+Real
+Red Hot
+Regal
+Relentless
+Religious
+Remote
+Renegade
+Retarded
+Retro
+Return of^Returns|Strikes Again|Strikes Back
+Return of the^Returns|Strikes Again|Strikes Back
+Revenge of^Revenge|- The Revenge
+Revenge of the^Revenge|- The Revenge
+Rise of the
+Robot
+Robotic^Robot
+Rock 'n' Roll
+Rocket-Powered
+Rockin'
+Rogue
+Romantic
+Royal
+Rural
+Rushing^Rush
+Russian
+Samba de
+Samurai
+Satan's
+Savage
+Save Yourself from the
+Scandinavian
+Scooby Doo and the
+Scottish
+Screaming
+Search for the
+Secret of the
+Sensual^Sex
+Sexy^Sex
+Shadow of the^Shadow
+Shady
+Shameful
+Shrunken^Midget
+Sid Meier's
+Silent
+Silly
+Sim^Simulator
+Sinister
+Sleazy
+Sleepy
+Small-Time
+Sonic's
+Soviet
+Space
+Special^Special Edition
+Spectacular
+Spectral^Ghost
+Spirit of the
+Spooky
+Spunky
+Star^All-Stars|Starring Mickey Mouse|Stars|Superstar
+Star Trek^All-Stars|Star|Starring Mickey Mouse|Stars|Superstar
+Star Wars^All-Stars|Star|Starring Mickey Mouse|Stars|Superstar
+Stealth
+Stoic
+Strategic
+Street
+Stupendous
+Stylish
+Subatomic
+Subterranean^Underground|Underworld
+Summer
+Super
+Super Sexy^Sex|Superstar
+Supreme
+Surprise
+Tactical^Tactics
+Tasteless
+Team
+Teenage
+Telekinetic
+Terrible
+The
+The Care Bears'
+The Castle of
+The Castle of the
+The Glory of
+The Great
+The Harlem Globetrotters:
+The Hunt For the
+The Incredible
+The Infernal
+The Last
+The Muppets^Muppets
+The Quest for the^Quest
+The Secret Weapon of the
+The Simpsons'
+The Sims:
+The Six Million Dollar
+Third-World
+Throbbing
+Tiger Woods'
+Tiny^Midget
+Tom Clancy's
+Tony Hawk's
+Topsy-Turvy
+Toxic
+Transvestite
+Trendy
+Tribal
+Tropical
+True Crime:
+Turbo
+Twin
+Twisted
+Ultimate
+Ultra
+Ultraviolent^Ultra
+Unbelievable
+Undead
+Undercover^Under Fire|Underwear|Underground|Underworld
+Underground^Under Fire|Underwear|Underground|Underworld
+Underwater^Under Fire|Underwear|Underground|Underworld
+Unforgettable
+Unholy
+Unpleasant
+Unreal
+Unremarkable
+Unstoppable
+Urban
+Vampire
+Vegetarian
+Viking
+Violent
+Virtua
+Virtual
+Wacky
+Wandering
+War of the^Warfare|Warrior|Wars|- Total War
+We Love
+Weary
+Wild^Gone Wild
+Wonderous
+Wooden
+World^World Cup|World Tour
+World of^World|World Cup|World Tour
+Wrath of the
+WWII^Warfare|Warrior|Wars|World|World Cup|World Tour|- Total War
+Ye Olde
+Yoshi's
+Zany
+Zombie^Zombies
+----
+3D
+Acid
+Aerobics
+Afro
+Alien
+Alligator
+Amish
+Android
+Animal
+Arcade
+Architecture
+Army
+Assault
+Axe
+Badminton^Baseball|Basketball|Boxing|Football|Paintbrawl|Pinball|Polo
+Baking
+Ballet
+Balloon
+Banana
+Bandicoot
+Banjo
+Barbarian
+Barcode
+Baseball^Base|Baseball|Basketball|Boxing|Football|Paintbrawl|Pinball|Polo
+Basketball^Baseball|Basketball|Boxing|Football|Paintbrawl|Pinball|Polo
+Bass
+Batman
+Battle^Battalion
+Battleship^Battle|Battalion
+Bazooka
+Beach
+Beast
+Beat
+Beautician
+Bedtime
+Bible
+Big Game Hunter^Hunt|Hunter
+Bimbo
+Bingo
+Biplane
+Blade
+Blimp
+Blood^Bloodbath|of the Blood God
+BMX
+Bobsled
+Bomb
+Bomberman
+Bong
+Bongo
+Booty
+Bow Hunter^Hunt|Hunter
+Bowling^Baseball|Basketball|Boxing|Football|Paintbrawl|Pinball|Polo
+Boxing^Baseball|Basketball|Boxing|Football|Paintbrawl|Pinball|Polo
+Breakdancing^Dance Mix|Dance Party|Dancers
+Bubble
+Bubblegum
+Buddhist
+Bungie
+Burger
+Business
+Cannibal
+Car
+Cardboard
+Carnival
+Casino
+Castlevania
+Catapult
+Caveman^Man
+Chainsaw
+Chase
+Cheese
+Chef
+Chess
+Chicken
+Chipmunk
+Chocobo
+Circus
+City
+College
+Combat
+Computer
+Conga
+Cookie
+Cooking
+Cowboy
+Cricket^Baseball|Basketball|Boxing|Football|Paintbrawl|Pinball|Polo
+Croquet^Baseball|Basketball|Boxing|Football|Paintbrawl|Pinball|Polo
+Crowbar
+Crystal
+Cyborg
+Dance^Dance Mix|Dance Party|Dancers
+Dating
+Death^Deathmatch|of Death|of the Dead
+Deer Hunter
+Demon
+Dentist
+Desert^in the Desert
+Devil
+Dinosaur
+Disco
+Dodgeball^Baseball|Basketball|Boxing|Football|Paintbrawl|Pinball|Polo
+Dog
+Donkey
+Dragon
+Driving
+Drug-Dealing
+Duck
+Dungeon
+Dwarf
+Elevator
+Equestrian
+Fashion
+Fantasy
+Farm^Farmer
+Fencing
+Fighter^Fight|Fight Club
+Fire
+Fishing^Baseball|Basketball|Boxing|Football|Paintbrawl|Pinball|Polo
+Flatulence
+Florist
+Football^Baseball|Basketball|Boxing|Football|Paintbrawl|Pinball|Polo
+Forklift
+Frisbee
+Frog
+Fun
+Fun Noodle
+Funk
+Furry
+Ghost
+Gimp
+Gnome
+Go-Kart
+Goblin
+Godzilla
+Golf
+Gopher
+Goth
+Graveyard
+Grizzly Bear
+Guitar
+Gun
+Hair Salon
+Hammer
+Hamster
+Handgun
+Hang Glider
+Hardware
+Harpoon
+Harvest
+Helicopter
+Hillbilly
+Hippo
+Hitman^Man
+Hobo
+Hockey
+Hoedown^Beatdown|Showdown|Smackdown|Takedown
+Hovercraft
+Horse Racing^Baseball|Basketball|Boxing|Football|Paintbrawl|Pinball|Polo
+Ice
+Ice Cream
+Indian
+Insect
+Internet
+Jackhammer
+Janitor
+Jazz
+Jetpack
+Jetski
+Juggalo
+Jungle
+Kabuki
+Kangaroo
+Karaoke
+Karate
+Kart
+Katana
+Kitchen
+Kung-fu
+Lacrosse^Baseball|Basketball|Boxing|Football|Paintbrawl|Pinball|Polo
+Landmine
+Laser
+Lawnmower
+Lego
+Leisure Suit
+Lightning
+Limbo
+Lizard
+Llama
+Love^of Love|Romance
+Lowrider
+Mafia
+Magic^of Magic|of Might and Magic
+Mahjong
+Makeout
+Makeover
+Mall
+Manlove
+Matador
+Math
+Maze
+Mech
+Metal
+Midget
+Military
+Mind Control
+Monkey
+Monster
+Monster Truck
+Moon
+Moped
+Motorcycle
+Motocross
+Mountain Climber
+Mummy
+Mushroom
+Music^DJ
+Mutant
+NASCAR
+Nazi
+Night^Knights|Nightmare
+Ninja
+Nuclear
+Nudist
+Octopus
+Office
+Ostrich
+Outlaw
+Pachinko
+Paintball^Baseball|Basketball|Boxing|Football|Paintbrawl|Pinball|Polo
+Penguin
+Piano
+Pinball^Baseball|Basketball|Boxing|Football|Paintbrawl|Pinball|Polo
+Ping Pong^Baseball|Basketball|Boxing|Football|Paintbrawl|Pinball|Polo
+Pirate
+Platypus
+Plumber
+Plunger
+Pogo
+Pokemon
+Police
+Polka
+Pony
+Porn
+Princess
+Prison
+Programming
+Punching
+Puppy
+Puzzle
+Quantum
+Quiz
+Rabbit
+Raccoon
+Racing^Racer
+Railroad
+Rainbow
+River
+Robot
+Rocket
+Rodeo
+Rollerball^Baseball|Basketball|Boxing|Football|Paintbrawl|Pinball|Polo
+Rugby^Baseball|Basketball|Boxing|Football|Paintbrawl|Pinball|Polo
+Sailboat
+Sailor
+Samurai
+Sandwich
+Scooter
+Scorched Earth
+Sewer
+Sex
+Shadow
+Shark
+Shaving
+Shock
+Shopping
+Shotgun
+Skate
+Skydiving
+Sloth
+Sniper
+Snowboard
+Soccer
+Software
+Spatula
+Speed
+Spelling
+Spelunking
+Spider
+Spork
+Square Dancing^Dance Mix|Dance Party|Dancers
+Squirrel
+Stapler
+STD
+Stick
+Stunt
+Submarine
+Sumo
+Sudoku
+Sunshine
+Surf
+Surgery
+Sushi
+Sword
+Tank
+Techno
+Tennis
+Terrorist
+Tetris
+Theme Park^Park
+Thief
+Thunder
+Toon
+Trailer Park^Park
+Train
+Trampoline
+Transvestite
+Tricycle
+Turtle
+Typing
+UFO
+Underwear^Under Fire|Underground|Underworld
+Unicorn
+Unicycle
+Valkyrie
+Vampire
+Vegetarian
+Vigilante
+Viking
+Vocabulary
+Volleyball^Baseball|Basketball|Boxing|Football|Paintbrawl|Pinball|Polo
+Wagon
+Walrus
+Wedding
+Weight Loss
+Werewolf
+Whale
+Wheelchair
+Wizard
+Workout
+Worm
+Wrestling
+Writing
+WWE
+WWII^Warfare|Warrior|Wars|World|World Cup|World Tour|- Total War
+Yak
+Yeti
+Yoga
+Zamboni
+Zombie^Zombies
+----
+- 2nd Impact
+- 3rd Strike
+1942
+25th Anniversary Edition
+2K
+2000
+3000
+3D
+64
+95
+Academy
+Advance
+Adventure
+Agent
+All-Stars
+Alpha
+Anarchy
+Annihilation
+Anthology
+Apocalypse
+Arena
+Armada
+Armageddon
+Assassins
+Assault
+at the Olympics
+Attack
+Babies
+Bandit
+Bandits
+Bastards
+Battle
+Battalion
+Base
+Baseball
+Basketball
+Beatdown
+Beta
+Blast
+Blaster
+Bloodbath
+Boxing
+Boy
+Brawl
+Brothers
+Camp
+Caper
+Carnage
+Castle
+CD
+Challenge
+Championship
+Chase
+Choreographer
+Chronicles
+City
+Co-Op
+Collection
+- Collector's Edition
+College
+Colosseum
+Combat
+Commander
+Commando
+Competition
+Conflict
+Connection
+Conquest
+Conspiracy
+Conundrum
+Corps
+Country
+Creator
+Crime Scene Investigation
+Crisis
+Crusade
+Crusader
+Dance Mix
+Dance Party
+Dancers
+Daredevils
+Dash
+Deathmatch
+Deluxe
+Demolition
+Derby
+Desperadoes
+Destruction
+Detective
+Diesel
+Disaster
+DJ
+Domination
+Dreamland
+DS
+Dudes
+Dungeon
+DX
+Dynasty
+Dystopia
+Empire
+Encounter
+Enforcer
+Epidemic
+Espionage
+EX
+Exhibition
+Experience
+Expert
+Explorer
+Explosion
+Express
+Extra
+Extravaganza
+Factory
+Family
+Fandango
+Fantasy
+Farmer
+Fest
+Feud
+Fever
+Fiasco
+Fiesta
+Fight
+Fight Club
+Fighter
+Football
+For Kids
+Force
+Forever
+Fortress
+Freak
+Frenzy
+from Hell
+from Mars
+from Outer Space
+from Planet X
+Fun
+Gaiden
+Gang
+Girl
+Gold
+Gone Wild
+Gladiator
+Groove
+GT
+Havoc
+Hell
+Hero
+Heroes
+Hoedown
+Hop-A-Bout
+Horde
+Horror
+Hospital
+- Hot Pursuit
+House
+Hunt
+Hunter
+II
+III
+Ignition
+in Africa
+in Busytown
+in Crazyland
+in Middle-Earth
+in My Pocket
+in Space
+in the Bayou
+in the Dark
+in the Desert
+in the Hood
+in the Magic Kingdom
+in the Middle East
+in the Outback
+in the Salad Kingdom
+in the Sky
+in Toyland
+in Vegas
+Incident
+Inferno
+Insanity
+Inspector
+Insurrection
+Interactive
+Interceptor
+Invaders
+Invasion
+Island
+Jam
+Jamboree
+Jihad
+Joe
+Journey
+Jr.
+Kid
+Kids
+King
+Kingdom
+Knights
+Kombat
+Legend
+Legends
+- Limited Edition
+Live
+Lord
+Machine
+Madness
+Man
+Mania
+Maniac
+Mansion
+Marines
+Massacre
+Master
+Maxx
+Mayhem
+Melee
+Mission
+Munchers
+Nation
+Nightmare
+Nitro
+Odyssey
+of Death
+of Doom
+of Fury
+of Love
+of Magic
+of Might and Magic
+of Mystery
+of the Blood God
+of the Damned
+of the Dead
+of the Deep
+of the Third Reich
+on the Oregon Trail
+Offensive
+Omega
+on the High Seas
+On The Road
+on Wheels
+Online
+Onslaught
+Operation
+Operatives
+Oppression
+Orchestra
+Over Normandy
+Overdrive
+Overload
+Overlords
+Paintbrawl
+Palace
+Panic
+Paratroopers
+Park
+Party
+Patrol
+Phonics
+Pimps
+Pinball
+Pioneer
+Planet
+Playhouse
+Plus
+Police
+Polo
+Posse
+Power
+Preacher
+Princess
+Pro
+Project
+Prophecy
+Psychiatrist
+Punch-Out!!
+Punishment
+Quest
+Quiz
+Racer
+Rage
+Raider
+Rally
+Rampage
+Rangers
+Ransom
+Rave
+Rebellion
+Reloaded
+Remix
+Rescue
+Restaurant
+Returns
+Revenge
+Revisited
+Revolution
+Rider
+Riders
+Rocket
+Romance
+Romp
+Roundup
+Runner
+Rush
+Safari
+Saga
+Saloon
+Scam
+Scandal
+School
+Shack
+Shoot
+Shootout
+Showdown
+Siege
+Simulator
+Sisters
+Slam
+Slaughter
+Slayer
+Smackdown
+Smash
+Smuggler
+Solid
+Soldier
+Special Edition
+Spectacular
+Spies
+Spree
+Squadron
+Stadium
+Starring Mickey Mouse
+Stars
+Story
+Strike Force
+Strikes Again
+Strikes Back
+Struggle
+Studio
+Summit
+Summoner
+Superstar
+Symphony
+Syndicate
+Syndrome
+Tactics
+Takedown
+Tale
+Task Force
+Temple
+Terror
+Thieves
+- The Card Game
+- The Dark Project
+- The Gathering Storm
+- The Lost Levels
+- The Movie
+- The Next Generation
+- The Quickening
+- The Resistance
+- The Revenge
+Through Time
+Throwdown
+- Total War
+Tournament
+Trader
+Train
+Trainer
+Training
+Tribe
+Trilogy
+Trivia
+Troopers
+Turbo
+Tycoon
+Ultra
+Unit
+Uncensored
+Underground
+Underworld
+Universe
+Unleashed
+Uprising
+Vengeance
+Voyage
+vs. Capcom
+vs. Street Fighter
+vs. The Space Mutants
+Warfare
+Warrior
+Wars
+Wasteland
+with Friends
+World
+World Cup
+World Tour
+Wranglers
+X
+XP
+XXX
+X-treme
+Yoga
+Z
+Zombies
+Zone
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/tests/AllTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/tests/AllTest.php
new file mode 100644
index 0000000..8049ab7
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/tests/AllTest.php
@@ -0,0 +1,72 @@
+<?php
+namespace Nubs\RandomNameGenerator;
+
+use PHPUnit_Framework_TestCase;
+use Cinam\Randomizer\Randomizer;
+
+/**
+ * @coversDefaultClass \Nubs\RandomNameGenerator\All
+ * @covers ::<protected>
+ */
+class AllTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * Verify basic behavior of getName().
+ *
+ * @test
+ * @covers ::__construct
+ * @covers ::create
+ * @covers ::getName
+ * @uses \Nubs\RandomNameGenerator\Alliteration
+ * @uses \Nubs\RandomNameGenerator\Vgng
+ *
+ * @return void
+ */
+ public function getNameBasic()
+ {
+ $generator = All::create();
+ $name = $generator->getName();
+ $this->assertRegexp('/.+/', $name);
+ }
+
+ /**
+ * Verify basic behavior of getName() with a forced random generator.
+ *
+ * @test
+ * @covers ::__construct
+ * @covers ::create
+ * @covers ::getName
+ * @uses \Nubs\RandomNameGenerator\Alliteration
+ *
+ * @return void
+ */
+ public function getNameForced()
+ {
+ $numberGenerator = $this->createMock('\Cinam\Randomizer\NumberGenerator');
+ $numberGenerator->expects($this->exactly(2))->method('getInt')->will($this->onConsecutiveCalls(20, 5));
+ $randomizer = new Randomizer($numberGenerator);
+
+ $generator = new All([new Alliteration($randomizer)]);
+ $this->assertSame('Black Bear', $generator->getName());
+ }
+
+ /**
+ * Verify basic behavior of __toString().
+ *
+ * @test
+ * @covers ::__construct
+ * @covers ::create
+ * @covers ::__toString
+ * @covers ::getName
+ * @uses \Nubs\RandomNameGenerator\Alliteration
+ * @uses \Nubs\RandomNameGenerator\Vgng
+ *
+ * @return void
+ */
+ public function toStringBasic()
+ {
+ $generator = All::create();
+ $name = (string)$generator;
+ $this->assertRegexp('/.+/', $name);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/tests/AlliterationTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/tests/AlliterationTest.php
new file mode 100644
index 0000000..0b47343
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/tests/AlliterationTest.php
@@ -0,0 +1,66 @@
+<?php
+namespace Nubs\RandomNameGenerator;
+
+use PHPUnit_Framework_TestCase;
+use Cinam\Randomizer\Randomizer;
+
+/**
+ * @coversDefaultClass \Nubs\RandomNameGenerator\Alliteration
+ * @covers ::<protected>
+ */
+class AlliterationTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * Verify basic behavior of getName().
+ *
+ * @test
+ * @covers ::__construct
+ * @covers ::getName
+ *
+ * @return void
+ */
+ public function getNameBasic()
+ {
+ $generator = new Alliteration();
+ $parts = explode(' ', $generator->getName());
+ $this->assertSame(2, count($parts));
+ $this->assertSame($parts[0][0], $parts[1][0]);
+ }
+
+ /**
+ * Verify basic behavior of getName() with a forced random generator.
+ *
+ * @test
+ * @covers ::__construct
+ * @covers ::getName
+ *
+ * @return void
+ */
+ public function getNameForced()
+ {
+ $numberGenerator = $this->createMock('\Cinam\Randomizer\NumberGenerator');
+ $numberGenerator->expects($this->exactly(2))->method('getInt')->will($this->onConsecutiveCalls(20, 5));
+ $randomizer = new Randomizer($numberGenerator);
+
+ $generator = new Alliteration($randomizer);
+ $this->assertSame('Black Bear', $generator->getName());
+ }
+
+ /**
+ * Verify basic behavior of __toString().
+ *
+ * @test
+ * @covers ::__construct
+ * @covers ::__toString
+ * @covers ::getName
+ *
+ * @return void
+ */
+ public function toStringBasic()
+ {
+ $generator = new Alliteration();
+ $parts = explode(' ', (string)$generator);
+ $this->assertSame(2, count($parts));
+ $this->assertSame($parts[0][0], $parts[1][0]);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/tests/VgngTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/tests/VgngTest.php
new file mode 100644
index 0000000..a301b81
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/nubs/random-name-generator/tests/VgngTest.php
@@ -0,0 +1,67 @@
+<?php
+namespace Nubs\RandomNameGenerator;
+
+use PHPUnit_Framework_TestCase;
+use Cinam\Randomizer\Randomizer;
+
+/**
+ * @coversDefaultClass \Nubs\RandomNameGenerator\Vgng
+ * @covers ::<protected>
+ */
+class VgngTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * Verify that getName returns the expected name.
+ *
+ * @test
+ * @covers ::__construct
+ * @covers ::getName
+ */
+ public function getNameBasic()
+ {
+ $numberGenerator = $this->createMock('\Cinam\Randomizer\NumberGenerator');
+ $numberGenerator->expects($this->exactly(3))->method('getInt')->will($this->returnValue(1));
+ $randomizer = new Randomizer($numberGenerator);
+
+ $vgng = new Vgng($randomizer);
+
+ $this->assertSame('8-Bit Acid - 3rd Strike', $vgng->getName());
+ }
+
+ /**
+ * Verify that getName returns a name without similar strings.
+ *
+ * @test
+ * @covers ::__construct
+ * @covers ::getName
+ */
+ public function getNameSimilarName()
+ {
+ $numberGenerator = $this->createMock('\Cinam\Randomizer\NumberGenerator');
+ $numberGenerator->expects($this->exactly(4))->method('getInt')->will($this->onConsecutiveCalls(0, 0, 2, 10));
+ $randomizer = new Randomizer($numberGenerator);
+
+ $vgng = new Vgng($randomizer);
+
+ $this->assertSame('3D Aerobics Academy', $vgng->getName());
+ }
+
+ /**
+ * Verify that toString returns the expected name.
+ *
+ * @test
+ * @covers ::__construct
+ * @covers ::__toString
+ * @covers ::getName
+ */
+ public function toStringBasic()
+ {
+ $numberGenerator = $this->createMock('\Cinam\Randomizer\NumberGenerator');
+ $numberGenerator->expects($this->exactly(3))->method('getInt')->will($this->returnValue(1));
+ $randomizer = new Randomizer($numberGenerator);
+
+ $vgng = new Vgng($randomizer);
+
+ $this->assertSame('8-Bit Acid - 3rd Strike', (string)$vgng);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/LICENSE b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/LICENSE
new file mode 100644
index 0000000..45c7017
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Paragon Initiative Enterprises
+
+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.
+
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/build-phar.sh b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/build-phar.sh
new file mode 100644
index 0000000..b4a5ba3
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/build-phar.sh
@@ -0,0 +1,5 @@
+#!/usr/bin/env bash
+
+basedir=$( dirname $( readlink -f ${BASH_SOURCE[0]} ) )
+
+php -dphar.readonly=0 "$basedir/other/build_phar.php" $* \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/composer.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/composer.json
new file mode 100644
index 0000000..1c5978c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/composer.json
@@ -0,0 +1,37 @@
+{
+ "name": "paragonie/random_compat",
+ "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
+ "keywords": [
+ "csprng",
+ "random",
+ "pseudorandom"
+ ],
+ "license": "MIT",
+ "type": "library",
+ "authors": [
+ {
+ "name": "Paragon Initiative Enterprises",
+ "email": "security@paragonie.com",
+ "homepage": "https://paragonie.com"
+ }
+ ],
+ "support": {
+ "issues": "https://github.com/paragonie/random_compat/issues",
+ "email": "info@paragonie.com",
+ "source": "https://github.com/paragonie/random_compat"
+ },
+ "require": {
+ "php": ">=5.2.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.*|5.*"
+ },
+ "suggest": {
+ "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
+ },
+ "autoload": {
+ "files": [
+ "lib/random.php"
+ ]
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey
new file mode 100644
index 0000000..eb50ebf
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey
@@ -0,0 +1,5 @@
+-----BEGIN PUBLIC KEY-----
+MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEEd+wCqJDrx5B4OldM0dQE0ZMX+lx1ZWm
+pui0SUqD4G29L3NGsz9UhJ/0HjBdbnkhIK5xviT0X5vtjacF6ajgcCArbTB+ds+p
++h7Q084NuSuIpNb6YPfoUFgC/CL9kAoc
+-----END PUBLIC KEY-----
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc
new file mode 100644
index 0000000..6a1d7f3
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc
@@ -0,0 +1,11 @@
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v2.0.22 (MingW32)
+
+iQEcBAABAgAGBQJWtW1hAAoJEGuXocKCZATaJf0H+wbZGgskK1dcRTsuVJl9IWip
+QwGw/qIKI280SD6/ckoUMxKDCJiFuPR14zmqnS36k7N5UNPnpdTJTS8T11jttSpg
+1LCmgpbEIpgaTah+cELDqFCav99fS+bEiAL5lWDAHBTE/XPjGVCqeehyPYref4IW
+NDBIEsvnHPHPLsn6X5jq4+Yj5oUixgxaMPiR+bcO4Sh+RzOVB6i2D0upWfRXBFXA
+NNnsg9/zjvoC7ZW73y9uSH+dPJTt/Vgfeiv52/v41XliyzbUyLalf02GNPY+9goV
+JHG1ulEEBJOCiUD9cE1PUIJwHA/HqyhHIvV350YoEFiHl8iSwm7SiZu5kPjaq74=
+=B6+8
+-----END PGP SIGNATURE-----
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/byte_safe_strings.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/byte_safe_strings.php
new file mode 100644
index 0000000..3de86b2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/byte_safe_strings.php
@@ -0,0 +1,181 @@
+<?php
+/**
+ * Random_* Compatibility Library
+ * for using the new PHP 7 random_* API in PHP 5 projects
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
+ *
+ * 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.
+ */
+
+if (!is_callable('RandomCompat_strlen')) {
+ if (
+ defined('MB_OVERLOAD_STRING') &&
+ ini_get('mbstring.func_overload') & MB_OVERLOAD_STRING
+ ) {
+ /**
+ * strlen() implementation that isn't brittle to mbstring.func_overload
+ *
+ * This version uses mb_strlen() in '8bit' mode to treat strings as raw
+ * binary rather than UTF-8, ISO-8859-1, etc
+ *
+ * @param string $binary_string
+ *
+ * @throws TypeError
+ *
+ * @return int
+ */
+ function RandomCompat_strlen($binary_string)
+ {
+ if (!is_string($binary_string)) {
+ throw new TypeError(
+ 'RandomCompat_strlen() expects a string'
+ );
+ }
+
+ return (int) mb_strlen($binary_string, '8bit');
+ }
+
+ } else {
+ /**
+ * strlen() implementation that isn't brittle to mbstring.func_overload
+ *
+ * This version just used the default strlen()
+ *
+ * @param string $binary_string
+ *
+ * @throws TypeError
+ *
+ * @return int
+ */
+ function RandomCompat_strlen($binary_string)
+ {
+ if (!is_string($binary_string)) {
+ throw new TypeError(
+ 'RandomCompat_strlen() expects a string'
+ );
+ }
+ return (int) strlen($binary_string);
+ }
+ }
+}
+
+if (!is_callable('RandomCompat_substr')) {
+
+ if (
+ defined('MB_OVERLOAD_STRING')
+ &&
+ ini_get('mbstring.func_overload') & MB_OVERLOAD_STRING
+ ) {
+ /**
+ * substr() implementation that isn't brittle to mbstring.func_overload
+ *
+ * This version uses mb_substr() in '8bit' mode to treat strings as raw
+ * binary rather than UTF-8, ISO-8859-1, etc
+ *
+ * @param string $binary_string
+ * @param int $start
+ * @param int $length (optional)
+ *
+ * @throws TypeError
+ *
+ * @return string
+ */
+ function RandomCompat_substr($binary_string, $start, $length = null)
+ {
+ if (!is_string($binary_string)) {
+ throw new TypeError(
+ 'RandomCompat_substr(): First argument should be a string'
+ );
+ }
+
+ if (!is_int($start)) {
+ throw new TypeError(
+ 'RandomCompat_substr(): Second argument should be an integer'
+ );
+ }
+
+ if ($length === null) {
+ /**
+ * mb_substr($str, 0, NULL, '8bit') returns an empty string on
+ * PHP 5.3, so we have to find the length ourselves.
+ */
+ $length = RandomCompat_strlen($binary_string) - $start;
+ } elseif (!is_int($length)) {
+ throw new TypeError(
+ 'RandomCompat_substr(): Third argument should be an integer, or omitted'
+ );
+ }
+
+ // Consistency with PHP's behavior
+ if ($start === RandomCompat_strlen($binary_string) && $length === 0) {
+ return '';
+ }
+ if ($start > RandomCompat_strlen($binary_string)) {
+ return '';
+ }
+
+ return (string) mb_substr($binary_string, $start, $length, '8bit');
+ }
+
+ } else {
+
+ /**
+ * substr() implementation that isn't brittle to mbstring.func_overload
+ *
+ * This version just uses the default substr()
+ *
+ * @param string $binary_string
+ * @param int $start
+ * @param int $length (optional)
+ *
+ * @throws TypeError
+ *
+ * @return string
+ */
+ function RandomCompat_substr($binary_string, $start, $length = null)
+ {
+ if (!is_string($binary_string)) {
+ throw new TypeError(
+ 'RandomCompat_substr(): First argument should be a string'
+ );
+ }
+
+ if (!is_int($start)) {
+ throw new TypeError(
+ 'RandomCompat_substr(): Second argument should be an integer'
+ );
+ }
+
+ if ($length !== null) {
+ if (!is_int($length)) {
+ throw new TypeError(
+ 'RandomCompat_substr(): Third argument should be an integer, or omitted'
+ );
+ }
+
+ return (string) substr($binary_string, $start, $length);
+ }
+
+ return (string) substr($binary_string, $start);
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/cast_to_int.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/cast_to_int.php
new file mode 100644
index 0000000..9a4fab9
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/cast_to_int.php
@@ -0,0 +1,75 @@
+<?php
+/**
+ * Random_* Compatibility Library
+ * for using the new PHP 7 random_* API in PHP 5 projects
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
+ *
+ * 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.
+ */
+
+if (!is_callable('RandomCompat_intval')) {
+
+ /**
+ * Cast to an integer if we can, safely.
+ *
+ * If you pass it a float in the range (~PHP_INT_MAX, PHP_INT_MAX)
+ * (non-inclusive), it will sanely cast it to an int. If you it's equal to
+ * ~PHP_INT_MAX or PHP_INT_MAX, we let it fail as not an integer. Floats
+ * lose precision, so the <= and => operators might accidentally let a float
+ * through.
+ *
+ * @param int|float $number The number we want to convert to an int
+ * @param bool $fail_open Set to true to not throw an exception
+ *
+ * @return float|int
+ * @psalm-suppress InvalidReturnType
+ *
+ * @throws TypeError
+ */
+ function RandomCompat_intval($number, $fail_open = false)
+ {
+ if (is_int($number) || is_float($number)) {
+ $number += 0;
+ } elseif (is_numeric($number)) {
+ $number += 0;
+ }
+
+ if (
+ is_float($number)
+ &&
+ $number > ~PHP_INT_MAX
+ &&
+ $number < PHP_INT_MAX
+ ) {
+ $number = (int) $number;
+ }
+
+ if (is_int($number)) {
+ return (int) $number;
+ } elseif (!$fail_open) {
+ throw new TypeError(
+ 'Expected an integer.'
+ );
+ }
+ return $number;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/error_polyfill.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/error_polyfill.php
new file mode 100644
index 0000000..6a91990
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/error_polyfill.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Random_* Compatibility Library
+ * for using the new PHP 7 random_* API in PHP 5 projects
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
+ *
+ * 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.
+ */
+
+if (!class_exists('Error', false)) {
+ // We can't really avoid making this extend Exception in PHP 5.
+ class Error extends Exception
+ {
+
+ }
+}
+
+if (!class_exists('TypeError', false)) {
+ if (is_subclass_of('Error', 'Exception')) {
+ class TypeError extends Error
+ {
+
+ }
+ } else {
+ class TypeError extends Exception
+ {
+
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/random.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/random.php
new file mode 100644
index 0000000..080b87c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/random.php
@@ -0,0 +1,225 @@
+<?php
+/**
+ * Random_* Compatibility Library
+ * for using the new PHP 7 random_* API in PHP 5 projects
+ *
+ * @version 2.0.10
+ * @released 2017-03-13
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
+ *
+ * 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.
+ */
+
+if (!defined('PHP_VERSION_ID')) {
+ // This constant was introduced in PHP 5.2.7
+ $RandomCompatversion = array_map('intval', explode('.', PHP_VERSION));
+ define(
+ 'PHP_VERSION_ID',
+ $RandomCompatversion[0] * 10000
+ + $RandomCompatversion[1] * 100
+ + $RandomCompatversion[2]
+ );
+ $RandomCompatversion = null;
+}
+
+/**
+ * PHP 7.0.0 and newer have these functions natively.
+ */
+if (PHP_VERSION_ID >= 70000) {
+ return;
+}
+
+if (!defined('RANDOM_COMPAT_READ_BUFFER')) {
+ define('RANDOM_COMPAT_READ_BUFFER', 8);
+}
+
+$RandomCompatDIR = dirname(__FILE__);
+
+require_once $RandomCompatDIR . '/byte_safe_strings.php';
+require_once $RandomCompatDIR . '/cast_to_int.php';
+require_once $RandomCompatDIR . '/error_polyfill.php';
+
+if (!is_callable('random_bytes')) {
+ /**
+ * PHP 5.2.0 - 5.6.x way to implement random_bytes()
+ *
+ * We use conditional statements here to define the function in accordance
+ * to the operating environment. It's a micro-optimization.
+ *
+ * In order of preference:
+ * 1. Use libsodium if available.
+ * 2. fread() /dev/urandom if available (never on Windows)
+ * 3. mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM)
+ * 4. COM('CAPICOM.Utilities.1')->GetRandom()
+ *
+ * See RATIONALE.md for our reasoning behind this particular order
+ */
+ if (extension_loaded('libsodium')) {
+ // See random_bytes_libsodium.php
+ if (PHP_VERSION_ID >= 50300 && is_callable('\\Sodium\\randombytes_buf')) {
+ require_once $RandomCompatDIR . '/random_bytes_libsodium.php';
+ } elseif (method_exists('Sodium', 'randombytes_buf')) {
+ require_once $RandomCompatDIR . '/random_bytes_libsodium_legacy.php';
+ }
+ }
+
+ /**
+ * Reading directly from /dev/urandom:
+ */
+ if (DIRECTORY_SEPARATOR === '/') {
+ // DIRECTORY_SEPARATOR === '/' on Unix-like OSes -- this is a fast
+ // way to exclude Windows.
+ $RandomCompatUrandom = true;
+ $RandomCompat_basedir = ini_get('open_basedir');
+
+ if (!empty($RandomCompat_basedir)) {
+ $RandomCompat_open_basedir = explode(
+ PATH_SEPARATOR,
+ strtolower($RandomCompat_basedir)
+ );
+ $RandomCompatUrandom = (array() !== array_intersect(
+ array('/dev', '/dev/', '/dev/urandom'),
+ $RandomCompat_open_basedir
+ ));
+ $RandomCompat_open_basedir = null;
+ }
+
+ if (
+ !is_callable('random_bytes')
+ &&
+ $RandomCompatUrandom
+ &&
+ @is_readable('/dev/urandom')
+ ) {
+ // Error suppression on is_readable() in case of an open_basedir
+ // or safe_mode failure. All we care about is whether or not we
+ // can read it at this point. If the PHP environment is going to
+ // panic over trying to see if the file can be read in the first
+ // place, that is not helpful to us here.
+
+ // See random_bytes_dev_urandom.php
+ require_once $RandomCompatDIR . '/random_bytes_dev_urandom.php';
+ }
+ // Unset variables after use
+ $RandomCompat_basedir = null;
+ } else {
+ $RandomCompatUrandom = false;
+ }
+
+ /**
+ * mcrypt_create_iv()
+ *
+ * We only want to use mcypt_create_iv() if:
+ *
+ * - random_bytes() hasn't already been defined
+ * - the mcrypt extensions is loaded
+ * - One of these two conditions is true:
+ * - We're on Windows (DIRECTORY_SEPARATOR !== '/')
+ * - We're not on Windows and /dev/urandom is readabale
+ * (i.e. we're not in a chroot jail)
+ * - Special case:
+ * - If we're not on Windows, but the PHP version is between
+ * 5.6.10 and 5.6.12, we don't want to use mcrypt. It will
+ * hang indefinitely. This is bad.
+ * - If we're on Windows, we want to use PHP >= 5.3.7 or else
+ * we get insufficient entropy errors.
+ */
+ if (
+ !is_callable('random_bytes')
+ &&
+ // Windows on PHP < 5.3.7 is broken, but non-Windows is not known to be.
+ (DIRECTORY_SEPARATOR === '/' || PHP_VERSION_ID >= 50307)
+ &&
+ // Prevent this code from hanging indefinitely on non-Windows;
+ // see https://bugs.php.net/bug.php?id=69833
+ (
+ DIRECTORY_SEPARATOR !== '/' ||
+ (PHP_VERSION_ID <= 50609 || PHP_VERSION_ID >= 50613)
+ )
+ &&
+ extension_loaded('mcrypt')
+ ) {
+ // See random_bytes_mcrypt.php
+ require_once $RandomCompatDIR . '/random_bytes_mcrypt.php';
+ }
+ $RandomCompatUrandom = null;
+
+ /**
+ * This is a Windows-specific fallback, for when the mcrypt extension
+ * isn't loaded.
+ */
+ if (
+ !is_callable('random_bytes')
+ &&
+ extension_loaded('com_dotnet')
+ &&
+ class_exists('COM')
+ ) {
+ $RandomCompat_disabled_classes = preg_split(
+ '#\s*,\s*#',
+ strtolower(ini_get('disable_classes'))
+ );
+
+ if (!in_array('com', $RandomCompat_disabled_classes)) {
+ try {
+ $RandomCompatCOMtest = new COM('CAPICOM.Utilities.1');
+ if (method_exists($RandomCompatCOMtest, 'GetRandom')) {
+ // See random_bytes_com_dotnet.php
+ require_once $RandomCompatDIR . '/random_bytes_com_dotnet.php';
+ }
+ } catch (com_exception $e) {
+ // Don't try to use it.
+ }
+ }
+ $RandomCompat_disabled_classes = null;
+ $RandomCompatCOMtest = null;
+ }
+
+ /**
+ * throw new Exception
+ */
+ if (!is_callable('random_bytes')) {
+ /**
+ * We don't have any more options, so let's throw an exception right now
+ * and hope the developer won't let it fail silently.
+ *
+ * @param mixed $length
+ * @psalm-suppress MissingReturnType
+ * @throws Exception
+ * @return string
+ */
+ function random_bytes($length)
+ {
+ unset($length); // Suppress "variable not used" warnings.
+ throw new Exception(
+ 'There is no suitable CSPRNG installed on your system'
+ );
+ return '';
+ }
+ }
+}
+
+if (!is_callable('random_int')) {
+ require_once $RandomCompatDIR . '/random_int.php';
+}
+
+$RandomCompatDIR = null;
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/random_bytes_com_dotnet.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/random_bytes_com_dotnet.php
new file mode 100644
index 0000000..fc1926e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/random_bytes_com_dotnet.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * Random_* Compatibility Library
+ * for using the new PHP 7 random_* API in PHP 5 projects
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
+ *
+ * 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.
+ */
+
+if (!is_callable('random_bytes')) {
+ /**
+ * Windows with PHP < 5.3.0 will not have the function
+ * openssl_random_pseudo_bytes() available, so let's use
+ * CAPICOM to work around this deficiency.
+ *
+ * @param int $bytes
+ *
+ * @throws Exception
+ *
+ * @return string
+ */
+ function random_bytes($bytes)
+ {
+ try {
+ $bytes = RandomCompat_intval($bytes);
+ } catch (TypeError $ex) {
+ throw new TypeError(
+ 'random_bytes(): $bytes must be an integer'
+ );
+ }
+
+ if ($bytes < 1) {
+ throw new Error(
+ 'Length must be greater than 0'
+ );
+ }
+
+ $buf = '';
+ if (!class_exists('COM')) {
+ throw new Error(
+ 'COM does not exist'
+ );
+ }
+ $util = new COM('CAPICOM.Utilities.1');
+ $execCount = 0;
+
+ /**
+ * Let's not let it loop forever. If we run N times and fail to
+ * get N bytes of random data, then CAPICOM has failed us.
+ */
+ do {
+ $buf .= base64_decode($util->GetRandom($bytes, 0));
+ if (RandomCompat_strlen($buf) >= $bytes) {
+ /**
+ * Return our random entropy buffer here:
+ */
+ return RandomCompat_substr($buf, 0, $bytes);
+ }
+ ++$execCount;
+ } while ($execCount < $bytes);
+
+ /**
+ * If we reach here, PHP has failed us.
+ */
+ throw new Exception(
+ 'Could not gather sufficient random data'
+ );
+ }
+} \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/random_bytes_dev_urandom.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/random_bytes_dev_urandom.php
new file mode 100644
index 0000000..df5b915
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/random_bytes_dev_urandom.php
@@ -0,0 +1,167 @@
+<?php
+/**
+ * Random_* Compatibility Library
+ * for using the new PHP 7 random_* API in PHP 5 projects
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
+ *
+ * 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.
+ */
+
+if (!defined('RANDOM_COMPAT_READ_BUFFER')) {
+ define('RANDOM_COMPAT_READ_BUFFER', 8);
+}
+
+if (!is_callable('random_bytes')) {
+ /**
+ * Unless open_basedir is enabled, use /dev/urandom for
+ * random numbers in accordance with best practices
+ *
+ * Why we use /dev/urandom and not /dev/random
+ * @ref http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers
+ *
+ * @param int $bytes
+ *
+ * @throws Exception
+ *
+ * @return string
+ */
+ function random_bytes($bytes)
+ {
+ static $fp = null;
+ /**
+ * This block should only be run once
+ */
+ if (empty($fp)) {
+ /**
+ * We use /dev/urandom if it is a char device.
+ * We never fall back to /dev/random
+ */
+ $fp = fopen('/dev/urandom', 'rb');
+ if (!empty($fp)) {
+ $st = fstat($fp);
+ if (($st['mode'] & 0170000) !== 020000) {
+ fclose($fp);
+ $fp = false;
+ }
+ }
+
+ if (!empty($fp)) {
+ /**
+ * stream_set_read_buffer() does not exist in HHVM
+ *
+ * If we don't set the stream's read buffer to 0, PHP will
+ * internally buffer 8192 bytes, which can waste entropy
+ *
+ * stream_set_read_buffer returns 0 on success
+ */
+ if (is_callable('stream_set_read_buffer')) {
+ stream_set_read_buffer($fp, RANDOM_COMPAT_READ_BUFFER);
+ }
+ if (is_callable('stream_set_chunk_size')) {
+ stream_set_chunk_size($fp, RANDOM_COMPAT_READ_BUFFER);
+ }
+ }
+ }
+
+ try {
+ $bytes = RandomCompat_intval($bytes);
+ } catch (TypeError $ex) {
+ throw new TypeError(
+ 'random_bytes(): $bytes must be an integer'
+ );
+ }
+
+ if ($bytes < 1) {
+ throw new Error(
+ 'Length must be greater than 0'
+ );
+ }
+
+ /**
+ * This if() block only runs if we managed to open a file handle
+ *
+ * It does not belong in an else {} block, because the above
+ * if (empty($fp)) line is logic that should only be run once per
+ * page load.
+ */
+ if (!empty($fp)) {
+ /**
+ * @var int
+ */
+ $remaining = $bytes;
+
+ /**
+ * @var string|bool
+ */
+ $buf = '';
+
+ /**
+ * We use fread() in a loop to protect against partial reads
+ */
+ do {
+ /**
+ * @var string|bool
+ */
+ $read = fread($fp, $remaining);
+ if (!is_string($read)) {
+ if ($read === false) {
+ /**
+ * We cannot safely read from the file. Exit the
+ * do-while loop and trigger the exception condition
+ *
+ * @var string|bool
+ */
+ $buf = false;
+ break;
+ }
+ }
+ /**
+ * Decrease the number of bytes returned from remaining
+ */
+ $remaining -= RandomCompat_strlen($read);
+ /**
+ * @var string|bool
+ */
+ $buf = $buf . $read;
+ } while ($remaining > 0);
+
+ /**
+ * Is our result valid?
+ */
+ if (is_string($buf)) {
+ if (RandomCompat_strlen($buf) === $bytes) {
+ /**
+ * Return our random entropy buffer here:
+ */
+ return $buf;
+ }
+ }
+ }
+
+ /**
+ * If we reach here, PHP has failed us.
+ */
+ throw new Exception(
+ 'Error reading from source device'
+ );
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/random_bytes_libsodium.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/random_bytes_libsodium.php
new file mode 100644
index 0000000..4af1a24
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/random_bytes_libsodium.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * Random_* Compatibility Library
+ * for using the new PHP 7 random_* API in PHP 5 projects
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
+ *
+ * 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.
+ */
+
+if (!is_callable('random_bytes')) {
+ /**
+ * If the libsodium PHP extension is loaded, we'll use it above any other
+ * solution.
+ *
+ * libsodium-php project:
+ * @ref https://github.com/jedisct1/libsodium-php
+ *
+ * @param int $bytes
+ *
+ * @throws Exception
+ *
+ * @return string
+ */
+ function random_bytes($bytes)
+ {
+ try {
+ $bytes = RandomCompat_intval($bytes);
+ } catch (TypeError $ex) {
+ throw new TypeError(
+ 'random_bytes(): $bytes must be an integer'
+ );
+ }
+
+ if ($bytes < 1) {
+ throw new Error(
+ 'Length must be greater than 0'
+ );
+ }
+
+ /**
+ * \Sodium\randombytes_buf() doesn't allow more than 2147483647 bytes to be
+ * generated in one invocation.
+ */
+ if ($bytes > 2147483647) {
+ $buf = '';
+ for ($i = 0; $i < $bytes; $i += 1073741824) {
+ $n = ($bytes - $i) > 1073741824
+ ? 1073741824
+ : $bytes - $i;
+ $buf .= \Sodium\randombytes_buf($n);
+ }
+ } else {
+ $buf = \Sodium\randombytes_buf($bytes);
+ }
+
+ if ($buf !== false) {
+ if (RandomCompat_strlen($buf) === $bytes) {
+ return $buf;
+ }
+ }
+
+ /**
+ * If we reach here, PHP has failed us.
+ */
+ throw new Exception(
+ 'Could not gather sufficient random data'
+ );
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/random_bytes_libsodium_legacy.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/random_bytes_libsodium_legacy.php
new file mode 100644
index 0000000..705af52
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/random_bytes_libsodium_legacy.php
@@ -0,0 +1,92 @@
+<?php
+/**
+ * Random_* Compatibility Library
+ * for using the new PHP 7 random_* API in PHP 5 projects
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
+ *
+ * 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.
+ */
+
+if (!is_callable('random_bytes')) {
+ /**
+ * If the libsodium PHP extension is loaded, we'll use it above any other
+ * solution.
+ *
+ * libsodium-php project:
+ * @ref https://github.com/jedisct1/libsodium-php
+ *
+ * @param int $bytes
+ *
+ * @throws Exception
+ *
+ * @return string
+ */
+ function random_bytes($bytes)
+ {
+ try {
+ $bytes = RandomCompat_intval($bytes);
+ } catch (TypeError $ex) {
+ throw new TypeError(
+ 'random_bytes(): $bytes must be an integer'
+ );
+ }
+
+ if ($bytes < 1) {
+ throw new Error(
+ 'Length must be greater than 0'
+ );
+ }
+
+ /**
+ * @var string
+ */
+ $buf = '';
+
+ /**
+ * \Sodium\randombytes_buf() doesn't allow more than 2147483647 bytes to be
+ * generated in one invocation.
+ */
+ if ($bytes > 2147483647) {
+ for ($i = 0; $i < $bytes; $i += 1073741824) {
+ $n = ($bytes - $i) > 1073741824
+ ? 1073741824
+ : $bytes - $i;
+ $buf .= Sodium::randombytes_buf((int) $n);
+ }
+ } else {
+ $buf .= Sodium::randombytes_buf((int) $bytes);
+ }
+
+ if (is_string($buf)) {
+ if (RandomCompat_strlen($buf) === $bytes) {
+ return $buf;
+ }
+ }
+
+ /**
+ * If we reach here, PHP has failed us.
+ */
+ throw new Exception(
+ 'Could not gather sufficient random data'
+ );
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/random_bytes_mcrypt.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/random_bytes_mcrypt.php
new file mode 100644
index 0000000..aac9c01
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/random_bytes_mcrypt.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Random_* Compatibility Library
+ * for using the new PHP 7 random_* API in PHP 5 projects
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
+ *
+ * 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.
+ */
+
+if (!is_callable('random_bytes')) {
+ /**
+ * Powered by ext/mcrypt (and thankfully NOT libmcrypt)
+ *
+ * @ref https://bugs.php.net/bug.php?id=55169
+ * @ref https://github.com/php/php-src/blob/c568ffe5171d942161fc8dda066bce844bdef676/ext/mcrypt/mcrypt.c#L1321-L1386
+ *
+ * @param int $bytes
+ *
+ * @throws Exception
+ *
+ * @return string
+ */
+ function random_bytes($bytes)
+ {
+ try {
+ $bytes = RandomCompat_intval($bytes);
+ } catch (TypeError $ex) {
+ throw new TypeError(
+ 'random_bytes(): $bytes must be an integer'
+ );
+ }
+
+ if ($bytes < 1) {
+ throw new Error(
+ 'Length must be greater than 0'
+ );
+ }
+
+ $buf = @mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM);
+ if (
+ $buf !== false
+ &&
+ RandomCompat_strlen($buf) === $bytes
+ ) {
+ /**
+ * Return our random entropy buffer here:
+ */
+ return $buf;
+ }
+
+ /**
+ * If we reach here, PHP has failed us.
+ */
+ throw new Exception(
+ 'Could not gather sufficient random data'
+ );
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/random_int.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/random_int.php
new file mode 100644
index 0000000..5b2143a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/lib/random_int.php
@@ -0,0 +1,190 @@
+<?php
+
+if (!is_callable('random_int')) {
+ /**
+ * Random_* Compatibility Library
+ * for using the new PHP 7 random_* API in PHP 5 projects
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
+ *
+ * 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.
+ */
+
+ /**
+ * Fetch a random integer between $min and $max inclusive
+ *
+ * @param int $min
+ * @param int $max
+ *
+ * @throws Exception
+ *
+ * @return int
+ */
+ function random_int($min, $max)
+ {
+ /**
+ * Type and input logic checks
+ *
+ * If you pass it a float in the range (~PHP_INT_MAX, PHP_INT_MAX)
+ * (non-inclusive), it will sanely cast it to an int. If you it's equal to
+ * ~PHP_INT_MAX or PHP_INT_MAX, we let it fail as not an integer. Floats
+ * lose precision, so the <= and => operators might accidentally let a float
+ * through.
+ */
+
+ try {
+ $min = RandomCompat_intval($min);
+ } catch (TypeError $ex) {
+ throw new TypeError(
+ 'random_int(): $min must be an integer'
+ );
+ }
+
+ try {
+ $max = RandomCompat_intval($max);
+ } catch (TypeError $ex) {
+ throw new TypeError(
+ 'random_int(): $max must be an integer'
+ );
+ }
+
+ /**
+ * Now that we've verified our weak typing system has given us an integer,
+ * let's validate the logic then we can move forward with generating random
+ * integers along a given range.
+ */
+ if ($min > $max) {
+ throw new Error(
+ 'Minimum value must be less than or equal to the maximum value'
+ );
+ }
+
+ if ($max === $min) {
+ return (int) $min;
+ }
+
+ /**
+ * Initialize variables to 0
+ *
+ * We want to store:
+ * $bytes => the number of random bytes we need
+ * $mask => an integer bitmask (for use with the &) operator
+ * so we can minimize the number of discards
+ */
+ $attempts = $bits = $bytes = $mask = $valueShift = 0;
+
+ /**
+ * At this point, $range is a positive number greater than 0. It might
+ * overflow, however, if $max - $min > PHP_INT_MAX. PHP will cast it to
+ * a float and we will lose some precision.
+ */
+ $range = $max - $min;
+
+ /**
+ * Test for integer overflow:
+ */
+ if (!is_int($range)) {
+
+ /**
+ * Still safely calculate wider ranges.
+ * Provided by @CodesInChaos, @oittaa
+ *
+ * @ref https://gist.github.com/CodesInChaos/03f9ea0b58e8b2b8d435
+ *
+ * We use ~0 as a mask in this case because it generates all 1s
+ *
+ * @ref https://eval.in/400356 (32-bit)
+ * @ref http://3v4l.org/XX9r5 (64-bit)
+ */
+ $bytes = PHP_INT_SIZE;
+ $mask = ~0;
+
+ } else {
+
+ /**
+ * $bits is effectively ceil(log($range, 2)) without dealing with
+ * type juggling
+ */
+ while ($range > 0) {
+ if ($bits % 8 === 0) {
+ ++$bytes;
+ }
+ ++$bits;
+ $range >>= 1;
+ $mask = $mask << 1 | 1;
+ }
+ $valueShift = $min;
+ }
+
+ $val = 0;
+ /**
+ * Now that we have our parameters set up, let's begin generating
+ * random integers until one falls between $min and $max
+ */
+ do {
+ /**
+ * The rejection probability is at most 0.5, so this corresponds
+ * to a failure probability of 2^-128 for a working RNG
+ */
+ if ($attempts > 128) {
+ throw new Exception(
+ 'random_int: RNG is broken - too many rejections'
+ );
+ }
+
+ /**
+ * Let's grab the necessary number of random bytes
+ */
+ $randomByteString = random_bytes($bytes);
+
+ /**
+ * Let's turn $randomByteString into an integer
+ *
+ * This uses bitwise operators (<< and |) to build an integer
+ * out of the values extracted from ord()
+ *
+ * Example: [9F] | [6D] | [32] | [0C] =>
+ * 159 + 27904 + 3276800 + 201326592 =>
+ * 204631455
+ */
+ $val &= 0;
+ for ($i = 0; $i < $bytes; ++$i) {
+ $val |= ord($randomByteString[$i]) << ($i * 8);
+ }
+
+ /**
+ * Apply mask
+ */
+ $val &= $mask;
+ $val += $valueShift;
+
+ ++$attempts;
+ /**
+ * If $val overflows to a floating point number,
+ * ... or is larger than $max,
+ * ... or smaller than $min,
+ * then try again.
+ */
+ } while (!is_int($val) || $val > $max || $val < $min);
+
+ return (int) $val;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/other/build_phar.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/other/build_phar.php
new file mode 100644
index 0000000..70ef4b2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/other/build_phar.php
@@ -0,0 +1,57 @@
+<?php
+$dist = dirname(__DIR__).'/dist';
+if (!is_dir($dist)) {
+ mkdir($dist, 0755);
+}
+if (file_exists($dist.'/random_compat.phar')) {
+ unlink($dist.'/random_compat.phar');
+}
+$phar = new Phar(
+ $dist.'/random_compat.phar',
+ FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::KEY_AS_FILENAME,
+ 'random_compat.phar'
+);
+rename(
+ dirname(__DIR__).'/lib/random.php',
+ dirname(__DIR__).'/lib/index.php'
+);
+$phar->buildFromDirectory(dirname(__DIR__).'/lib');
+rename(
+ dirname(__DIR__).'/lib/index.php',
+ dirname(__DIR__).'/lib/random.php'
+);
+
+/**
+ * If we pass an (optional) path to a private key as a second argument, we will
+ * sign the Phar with OpenSSL.
+ *
+ * If you leave this out, it will produce an unsigned .phar!
+ */
+if ($argc > 1) {
+ if (!@is_readable($argv[1])) {
+ echo 'Could not read the private key file:', $argv[1], "\n";
+ exit(255);
+ }
+ $pkeyFile = file_get_contents($argv[1]);
+
+ $private = openssl_get_privatekey($pkeyFile);
+ if ($private !== false) {
+ $pkey = '';
+ openssl_pkey_export($private, $pkey);
+ $phar->setSignatureAlgorithm(Phar::OPENSSL, $pkey);
+
+ /**
+ * Save the corresponding public key to the file
+ */
+ if (!@is_readable($dist.'/random_compat.phar.pubkey')) {
+ $details = openssl_pkey_get_details($private);
+ file_put_contents(
+ $dist.'/random_compat.phar.pubkey',
+ $details['key']
+ );
+ }
+ } else {
+ echo 'An error occurred reading the private key from OpenSSL.', "\n";
+ exit(255);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/psalm-autoload.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/psalm-autoload.php
new file mode 100644
index 0000000..d71d1b8
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/psalm-autoload.php
@@ -0,0 +1,9 @@
+<?php
+
+require_once 'lib/byte_safe_strings.php';
+require_once 'lib/cast_to_int.php';
+require_once 'lib/error_polyfill.php';
+require_once 'other/ide_stubs/libsodium.php';
+require_once 'lib/random.php';
+
+$int = random_int(0, 65536);
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/psalm.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/psalm.xml
new file mode 100644
index 0000000..ee072a9
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/paragonie/random_compat/psalm.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<psalm
+ autoloader="psalm-autoload.php"
+ stopOnFirstError="false"
+ useDocblockTypes="true"
+>
+ <projectFiles>
+ <directory name="lib" />
+ </projectFiles>
+ <issueHandlers>
+ <RedundantConditionGivenDocblockType errorLevel="info" />
+ <UnresolvableInclude errorLevel="info" />
+ <DuplicateClass errorLevel="info" />
+ <InvalidOperand errorLevel="info" />
+ <UndefinedConstant errorLevel="info" />
+ <MissingReturnType errorLevel="info" />
+ </issueHandlers>
+</psalm>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/CHANGELOG.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/CHANGELOG.md
new file mode 100644
index 0000000..74b1ef9
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/CHANGELOG.md
@@ -0,0 +1,36 @@
+# Changelog
+
+All notable changes to this project will be documented in this file, in reverse chronological order by release.
+
+## 1.0.1 - 2016-08-06
+
+### Added
+
+- Nothing.
+
+### Deprecated
+
+- Nothing.
+
+### Removed
+
+- Nothing.
+
+### Fixed
+
+- Updated all `@return self` annotation references in interfaces to use
+ `@return static`, which more closelly follows the semantics of the
+ specification.
+- Updated the `MessageInterface::getHeaders()` return annotation to use the
+ value `string[][]`, indicating the format is a nested array of strings.
+- Updated the `@link` annotation for `RequestInterface::withRequestTarget()`
+ to point to the correct section of RFC 7230.
+- Updated the `ServerRequestInterface::withUploadedFiles()` parameter annotation
+ to add the parameter name (`$uploadedFiles`).
+- Updated a `@throws` annotation for the `UploadedFileInterface::moveTo()`
+ method to correctly reference the method parameter (it was referencing an
+ incorrect parameter name previously).
+
+## 1.0.0 - 2016-05-18
+
+Initial stable release; reflects accepted PSR-7 specification.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/LICENSE b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/LICENSE
new file mode 100644
index 0000000..c2d8e45
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2014 PHP Framework Interoperability Group
+
+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.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/README.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/README.md
new file mode 100644
index 0000000..2818533
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/README.md
@@ -0,0 +1,13 @@
+PSR Http Message
+================
+
+This repository holds all interfaces/classes/traits related to
+[PSR-7](http://www.php-fig.org/psr/psr-7/).
+
+Note that this is not a HTTP message implementation of its own. It is merely an
+interface that describes a HTTP message. See the specification for more details.
+
+Usage
+-----
+
+We'll certainly need some stuff in here. \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/composer.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/composer.json
new file mode 100644
index 0000000..b0d2937
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/composer.json
@@ -0,0 +1,26 @@
+{
+ "name": "psr/http-message",
+ "description": "Common interface for HTTP messages",
+ "keywords": ["psr", "psr-7", "http", "http-message", "request", "response"],
+ "homepage": "https://github.com/php-fig/http-message",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Message\\": "src/"
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/src/MessageInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/src/MessageInterface.php
new file mode 100644
index 0000000..dd46e5e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/src/MessageInterface.php
@@ -0,0 +1,187 @@
+<?php
+
+namespace Psr\Http\Message;
+
+/**
+ * HTTP messages consist of requests from a client to a server and responses
+ * from a server to a client. This interface defines the methods common to
+ * each.
+ *
+ * Messages are considered immutable; all methods that might change state MUST
+ * be implemented such that they retain the internal state of the current
+ * message and return an instance that contains the changed state.
+ *
+ * @link http://www.ietf.org/rfc/rfc7230.txt
+ * @link http://www.ietf.org/rfc/rfc7231.txt
+ */
+interface MessageInterface
+{
+ /**
+ * Retrieves the HTTP protocol version as a string.
+ *
+ * The string MUST contain only the HTTP version number (e.g., "1.1", "1.0").
+ *
+ * @return string HTTP protocol version.
+ */
+ public function getProtocolVersion();
+
+ /**
+ * Return an instance with the specified HTTP protocol version.
+ *
+ * The version string MUST contain only the HTTP version number (e.g.,
+ * "1.1", "1.0").
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * new protocol version.
+ *
+ * @param string $version HTTP protocol version
+ * @return static
+ */
+ public function withProtocolVersion($version);
+
+ /**
+ * Retrieves all message header values.
+ *
+ * The keys represent the header name as it will be sent over the wire, and
+ * each value is an array of strings associated with the header.
+ *
+ * // Represent the headers as a string
+ * foreach ($message->getHeaders() as $name => $values) {
+ * echo $name . ": " . implode(", ", $values);
+ * }
+ *
+ * // Emit headers iteratively:
+ * foreach ($message->getHeaders() as $name => $values) {
+ * foreach ($values as $value) {
+ * header(sprintf('%s: %s', $name, $value), false);
+ * }
+ * }
+ *
+ * While header names are not case-sensitive, getHeaders() will preserve the
+ * exact case in which headers were originally specified.
+ *
+ * @return string[][] Returns an associative array of the message's headers. Each
+ * key MUST be a header name, and each value MUST be an array of strings
+ * for that header.
+ */
+ public function getHeaders();
+
+ /**
+ * Checks if a header exists by the given case-insensitive name.
+ *
+ * @param string $name Case-insensitive header field name.
+ * @return bool Returns true if any header names match the given header
+ * name using a case-insensitive string comparison. Returns false if
+ * no matching header name is found in the message.
+ */
+ public function hasHeader($name);
+
+ /**
+ * Retrieves a message header value by the given case-insensitive name.
+ *
+ * This method returns an array of all the header values of the given
+ * case-insensitive header name.
+ *
+ * If the header does not appear in the message, this method MUST return an
+ * empty array.
+ *
+ * @param string $name Case-insensitive header field name.
+ * @return string[] An array of string values as provided for the given
+ * header. If the header does not appear in the message, this method MUST
+ * return an empty array.
+ */
+ public function getHeader($name);
+
+ /**
+ * Retrieves a comma-separated string of the values for a single header.
+ *
+ * This method returns all of the header values of the given
+ * case-insensitive header name as a string concatenated together using
+ * a comma.
+ *
+ * NOTE: Not all header values may be appropriately represented using
+ * comma concatenation. For such headers, use getHeader() instead
+ * and supply your own delimiter when concatenating.
+ *
+ * If the header does not appear in the message, this method MUST return
+ * an empty string.
+ *
+ * @param string $name Case-insensitive header field name.
+ * @return string A string of values as provided for the given header
+ * concatenated together using a comma. If the header does not appear in
+ * the message, this method MUST return an empty string.
+ */
+ public function getHeaderLine($name);
+
+ /**
+ * Return an instance with the provided value replacing the specified header.
+ *
+ * While header names are case-insensitive, the casing of the header will
+ * be preserved by this function, and returned from getHeaders().
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * new and/or updated header and value.
+ *
+ * @param string $name Case-insensitive header field name.
+ * @param string|string[] $value Header value(s).
+ * @return static
+ * @throws \InvalidArgumentException for invalid header names or values.
+ */
+ public function withHeader($name, $value);
+
+ /**
+ * Return an instance with the specified header appended with the given value.
+ *
+ * Existing values for the specified header will be maintained. The new
+ * value(s) will be appended to the existing list. If the header did not
+ * exist previously, it will be added.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * new header and/or value.
+ *
+ * @param string $name Case-insensitive header field name to add.
+ * @param string|string[] $value Header value(s).
+ * @return static
+ * @throws \InvalidArgumentException for invalid header names or values.
+ */
+ public function withAddedHeader($name, $value);
+
+ /**
+ * Return an instance without the specified header.
+ *
+ * Header resolution MUST be done without case-sensitivity.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that removes
+ * the named header.
+ *
+ * @param string $name Case-insensitive header field name to remove.
+ * @return static
+ */
+ public function withoutHeader($name);
+
+ /**
+ * Gets the body of the message.
+ *
+ * @return StreamInterface Returns the body as a stream.
+ */
+ public function getBody();
+
+ /**
+ * Return an instance with the specified message body.
+ *
+ * The body MUST be a StreamInterface object.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return a new instance that has the
+ * new body stream.
+ *
+ * @param StreamInterface $body Body.
+ * @return static
+ * @throws \InvalidArgumentException When the body is not valid.
+ */
+ public function withBody(StreamInterface $body);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/src/RequestInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/src/RequestInterface.php
new file mode 100644
index 0000000..a96d4fd
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/src/RequestInterface.php
@@ -0,0 +1,129 @@
+<?php
+
+namespace Psr\Http\Message;
+
+/**
+ * Representation of an outgoing, client-side request.
+ *
+ * Per the HTTP specification, this interface includes properties for
+ * each of the following:
+ *
+ * - Protocol version
+ * - HTTP method
+ * - URI
+ * - Headers
+ * - Message body
+ *
+ * During construction, implementations MUST attempt to set the Host header from
+ * a provided URI if no Host header is provided.
+ *
+ * Requests are considered immutable; all methods that might change state MUST
+ * be implemented such that they retain the internal state of the current
+ * message and return an instance that contains the changed state.
+ */
+interface RequestInterface extends MessageInterface
+{
+ /**
+ * Retrieves the message's request target.
+ *
+ * Retrieves the message's request-target either as it will appear (for
+ * clients), as it appeared at request (for servers), or as it was
+ * specified for the instance (see withRequestTarget()).
+ *
+ * In most cases, this will be the origin-form of the composed URI,
+ * unless a value was provided to the concrete implementation (see
+ * withRequestTarget() below).
+ *
+ * If no URI is available, and no request-target has been specifically
+ * provided, this method MUST return the string "/".
+ *
+ * @return string
+ */
+ public function getRequestTarget();
+
+ /**
+ * Return an instance with the specific request-target.
+ *
+ * If the request needs a non-origin-form request-target — e.g., for
+ * specifying an absolute-form, authority-form, or asterisk-form —
+ * this method may be used to create an instance with the specified
+ * request-target, verbatim.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * changed request target.
+ *
+ * @link http://tools.ietf.org/html/rfc7230#section-5.3 (for the various
+ * request-target forms allowed in request messages)
+ * @param mixed $requestTarget
+ * @return static
+ */
+ public function withRequestTarget($requestTarget);
+
+ /**
+ * Retrieves the HTTP method of the request.
+ *
+ * @return string Returns the request method.
+ */
+ public function getMethod();
+
+ /**
+ * Return an instance with the provided HTTP method.
+ *
+ * While HTTP method names are typically all uppercase characters, HTTP
+ * method names are case-sensitive and thus implementations SHOULD NOT
+ * modify the given string.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * changed request method.
+ *
+ * @param string $method Case-sensitive method.
+ * @return static
+ * @throws \InvalidArgumentException for invalid HTTP methods.
+ */
+ public function withMethod($method);
+
+ /**
+ * Retrieves the URI instance.
+ *
+ * This method MUST return a UriInterface instance.
+ *
+ * @link http://tools.ietf.org/html/rfc3986#section-4.3
+ * @return UriInterface Returns a UriInterface instance
+ * representing the URI of the request.
+ */
+ public function getUri();
+
+ /**
+ * Returns an instance with the provided URI.
+ *
+ * This method MUST update the Host header of the returned request by
+ * default if the URI contains a host component. If the URI does not
+ * contain a host component, any pre-existing Host header MUST be carried
+ * over to the returned request.
+ *
+ * You can opt-in to preserving the original state of the Host header by
+ * setting `$preserveHost` to `true`. When `$preserveHost` is set to
+ * `true`, this method interacts with the Host header in the following ways:
+ *
+ * - If the Host header is missing or empty, and the new URI contains
+ * a host component, this method MUST update the Host header in the returned
+ * request.
+ * - If the Host header is missing or empty, and the new URI does not contain a
+ * host component, this method MUST NOT update the Host header in the returned
+ * request.
+ * - If a Host header is present and non-empty, this method MUST NOT update
+ * the Host header in the returned request.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * new UriInterface instance.
+ *
+ * @link http://tools.ietf.org/html/rfc3986#section-4.3
+ * @param UriInterface $uri New request URI to use.
+ * @param bool $preserveHost Preserve the original state of the Host header.
+ * @return static
+ */
+ public function withUri(UriInterface $uri, $preserveHost = false);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/src/ResponseInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/src/ResponseInterface.php
new file mode 100644
index 0000000..c306514
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/src/ResponseInterface.php
@@ -0,0 +1,68 @@
+<?php
+
+namespace Psr\Http\Message;
+
+/**
+ * Representation of an outgoing, server-side response.
+ *
+ * Per the HTTP specification, this interface includes properties for
+ * each of the following:
+ *
+ * - Protocol version
+ * - Status code and reason phrase
+ * - Headers
+ * - Message body
+ *
+ * Responses are considered immutable; all methods that might change state MUST
+ * be implemented such that they retain the internal state of the current
+ * message and return an instance that contains the changed state.
+ */
+interface ResponseInterface extends MessageInterface
+{
+ /**
+ * Gets the response status code.
+ *
+ * The status code is a 3-digit integer result code of the server's attempt
+ * to understand and satisfy the request.
+ *
+ * @return int Status code.
+ */
+ public function getStatusCode();
+
+ /**
+ * Return an instance with the specified status code and, optionally, reason phrase.
+ *
+ * If no reason phrase is specified, implementations MAY choose to default
+ * to the RFC 7231 or IANA recommended reason phrase for the response's
+ * status code.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * updated status and reason phrase.
+ *
+ * @link http://tools.ietf.org/html/rfc7231#section-6
+ * @link http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
+ * @param int $code The 3-digit integer result code to set.
+ * @param string $reasonPhrase The reason phrase to use with the
+ * provided status code; if none is provided, implementations MAY
+ * use the defaults as suggested in the HTTP specification.
+ * @return static
+ * @throws \InvalidArgumentException For invalid status code arguments.
+ */
+ public function withStatus($code, $reasonPhrase = '');
+
+ /**
+ * Gets the response reason phrase associated with the status code.
+ *
+ * Because a reason phrase is not a required element in a response
+ * status line, the reason phrase value MAY be null. Implementations MAY
+ * choose to return the default RFC 7231 recommended reason phrase (or those
+ * listed in the IANA HTTP Status Code Registry) for the response's
+ * status code.
+ *
+ * @link http://tools.ietf.org/html/rfc7231#section-6
+ * @link http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
+ * @return string Reason phrase; must return an empty string if none present.
+ */
+ public function getReasonPhrase();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/src/ServerRequestInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/src/ServerRequestInterface.php
new file mode 100644
index 0000000..0251234
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/src/ServerRequestInterface.php
@@ -0,0 +1,261 @@
+<?php
+
+namespace Psr\Http\Message;
+
+/**
+ * Representation of an incoming, server-side HTTP request.
+ *
+ * Per the HTTP specification, this interface includes properties for
+ * each of the following:
+ *
+ * - Protocol version
+ * - HTTP method
+ * - URI
+ * - Headers
+ * - Message body
+ *
+ * Additionally, it encapsulates all data as it has arrived to the
+ * application from the CGI and/or PHP environment, including:
+ *
+ * - The values represented in $_SERVER.
+ * - Any cookies provided (generally via $_COOKIE)
+ * - Query string arguments (generally via $_GET, or as parsed via parse_str())
+ * - Upload files, if any (as represented by $_FILES)
+ * - Deserialized body parameters (generally from $_POST)
+ *
+ * $_SERVER values MUST be treated as immutable, as they represent application
+ * state at the time of request; as such, no methods are provided to allow
+ * modification of those values. The other values provide such methods, as they
+ * can be restored from $_SERVER or the request body, and may need treatment
+ * during the application (e.g., body parameters may be deserialized based on
+ * content type).
+ *
+ * Additionally, this interface recognizes the utility of introspecting a
+ * request to derive and match additional parameters (e.g., via URI path
+ * matching, decrypting cookie values, deserializing non-form-encoded body
+ * content, matching authorization headers to users, etc). These parameters
+ * are stored in an "attributes" property.
+ *
+ * Requests are considered immutable; all methods that might change state MUST
+ * be implemented such that they retain the internal state of the current
+ * message and return an instance that contains the changed state.
+ */
+interface ServerRequestInterface extends RequestInterface
+{
+ /**
+ * Retrieve server parameters.
+ *
+ * Retrieves data related to the incoming request environment,
+ * typically derived from PHP's $_SERVER superglobal. The data IS NOT
+ * REQUIRED to originate from $_SERVER.
+ *
+ * @return array
+ */
+ public function getServerParams();
+
+ /**
+ * Retrieve cookies.
+ *
+ * Retrieves cookies sent by the client to the server.
+ *
+ * The data MUST be compatible with the structure of the $_COOKIE
+ * superglobal.
+ *
+ * @return array
+ */
+ public function getCookieParams();
+
+ /**
+ * Return an instance with the specified cookies.
+ *
+ * The data IS NOT REQUIRED to come from the $_COOKIE superglobal, but MUST
+ * be compatible with the structure of $_COOKIE. Typically, this data will
+ * be injected at instantiation.
+ *
+ * This method MUST NOT update the related Cookie header of the request
+ * instance, nor related values in the server params.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * updated cookie values.
+ *
+ * @param array $cookies Array of key/value pairs representing cookies.
+ * @return static
+ */
+ public function withCookieParams(array $cookies);
+
+ /**
+ * Retrieve query string arguments.
+ *
+ * Retrieves the deserialized query string arguments, if any.
+ *
+ * Note: the query params might not be in sync with the URI or server
+ * params. If you need to ensure you are only getting the original
+ * values, you may need to parse the query string from `getUri()->getQuery()`
+ * or from the `QUERY_STRING` server param.
+ *
+ * @return array
+ */
+ public function getQueryParams();
+
+ /**
+ * Return an instance with the specified query string arguments.
+ *
+ * These values SHOULD remain immutable over the course of the incoming
+ * request. They MAY be injected during instantiation, such as from PHP's
+ * $_GET superglobal, or MAY be derived from some other value such as the
+ * URI. In cases where the arguments are parsed from the URI, the data
+ * MUST be compatible with what PHP's parse_str() would return for
+ * purposes of how duplicate query parameters are handled, and how nested
+ * sets are handled.
+ *
+ * Setting query string arguments MUST NOT change the URI stored by the
+ * request, nor the values in the server params.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * updated query string arguments.
+ *
+ * @param array $query Array of query string arguments, typically from
+ * $_GET.
+ * @return static
+ */
+ public function withQueryParams(array $query);
+
+ /**
+ * Retrieve normalized file upload data.
+ *
+ * This method returns upload metadata in a normalized tree, with each leaf
+ * an instance of Psr\Http\Message\UploadedFileInterface.
+ *
+ * These values MAY be prepared from $_FILES or the message body during
+ * instantiation, or MAY be injected via withUploadedFiles().
+ *
+ * @return array An array tree of UploadedFileInterface instances; an empty
+ * array MUST be returned if no data is present.
+ */
+ public function getUploadedFiles();
+
+ /**
+ * Create a new instance with the specified uploaded files.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * updated body parameters.
+ *
+ * @param array $uploadedFiles An array tree of UploadedFileInterface instances.
+ * @return static
+ * @throws \InvalidArgumentException if an invalid structure is provided.
+ */
+ public function withUploadedFiles(array $uploadedFiles);
+
+ /**
+ * Retrieve any parameters provided in the request body.
+ *
+ * If the request Content-Type is either application/x-www-form-urlencoded
+ * or multipart/form-data, and the request method is POST, this method MUST
+ * return the contents of $_POST.
+ *
+ * Otherwise, this method may return any results of deserializing
+ * the request body content; as parsing returns structured content, the
+ * potential types MUST be arrays or objects only. A null value indicates
+ * the absence of body content.
+ *
+ * @return null|array|object The deserialized body parameters, if any.
+ * These will typically be an array or object.
+ */
+ public function getParsedBody();
+
+ /**
+ * Return an instance with the specified body parameters.
+ *
+ * These MAY be injected during instantiation.
+ *
+ * If the request Content-Type is either application/x-www-form-urlencoded
+ * or multipart/form-data, and the request method is POST, use this method
+ * ONLY to inject the contents of $_POST.
+ *
+ * The data IS NOT REQUIRED to come from $_POST, but MUST be the results of
+ * deserializing the request body content. Deserialization/parsing returns
+ * structured data, and, as such, this method ONLY accepts arrays or objects,
+ * or a null value if nothing was available to parse.
+ *
+ * As an example, if content negotiation determines that the request data
+ * is a JSON payload, this method could be used to create a request
+ * instance with the deserialized parameters.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * updated body parameters.
+ *
+ * @param null|array|object $data The deserialized body data. This will
+ * typically be in an array or object.
+ * @return static
+ * @throws \InvalidArgumentException if an unsupported argument type is
+ * provided.
+ */
+ public function withParsedBody($data);
+
+ /**
+ * Retrieve attributes derived from the request.
+ *
+ * The request "attributes" may be used to allow injection of any
+ * parameters derived from the request: e.g., the results of path
+ * match operations; the results of decrypting cookies; the results of
+ * deserializing non-form-encoded message bodies; etc. Attributes
+ * will be application and request specific, and CAN be mutable.
+ *
+ * @return array Attributes derived from the request.
+ */
+ public function getAttributes();
+
+ /**
+ * Retrieve a single derived request attribute.
+ *
+ * Retrieves a single derived request attribute as described in
+ * getAttributes(). If the attribute has not been previously set, returns
+ * the default value as provided.
+ *
+ * This method obviates the need for a hasAttribute() method, as it allows
+ * specifying a default value to return if the attribute is not found.
+ *
+ * @see getAttributes()
+ * @param string $name The attribute name.
+ * @param mixed $default Default value to return if the attribute does not exist.
+ * @return mixed
+ */
+ public function getAttribute($name, $default = null);
+
+ /**
+ * Return an instance with the specified derived request attribute.
+ *
+ * This method allows setting a single derived request attribute as
+ * described in getAttributes().
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * updated attribute.
+ *
+ * @see getAttributes()
+ * @param string $name The attribute name.
+ * @param mixed $value The value of the attribute.
+ * @return static
+ */
+ public function withAttribute($name, $value);
+
+ /**
+ * Return an instance that removes the specified derived request attribute.
+ *
+ * This method allows removing a single derived request attribute as
+ * described in getAttributes().
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that removes
+ * the attribute.
+ *
+ * @see getAttributes()
+ * @param string $name The attribute name.
+ * @return static
+ */
+ public function withoutAttribute($name);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/src/StreamInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/src/StreamInterface.php
new file mode 100644
index 0000000..f68f391
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/src/StreamInterface.php
@@ -0,0 +1,158 @@
+<?php
+
+namespace Psr\Http\Message;
+
+/**
+ * Describes a data stream.
+ *
+ * Typically, an instance will wrap a PHP stream; this interface provides
+ * a wrapper around the most common operations, including serialization of
+ * the entire stream to a string.
+ */
+interface StreamInterface
+{
+ /**
+ * Reads all data from the stream into a string, from the beginning to end.
+ *
+ * This method MUST attempt to seek to the beginning of the stream before
+ * reading data and read the stream until the end is reached.
+ *
+ * Warning: This could attempt to load a large amount of data into memory.
+ *
+ * This method MUST NOT raise an exception in order to conform with PHP's
+ * string casting operations.
+ *
+ * @see http://php.net/manual/en/language.oop5.magic.php#object.tostring
+ * @return string
+ */
+ public function __toString();
+
+ /**
+ * Closes the stream and any underlying resources.
+ *
+ * @return void
+ */
+ public function close();
+
+ /**
+ * Separates any underlying resources from the stream.
+ *
+ * After the stream has been detached, the stream is in an unusable state.
+ *
+ * @return resource|null Underlying PHP stream, if any
+ */
+ public function detach();
+
+ /**
+ * Get the size of the stream if known.
+ *
+ * @return int|null Returns the size in bytes if known, or null if unknown.
+ */
+ public function getSize();
+
+ /**
+ * Returns the current position of the file read/write pointer
+ *
+ * @return int Position of the file pointer
+ * @throws \RuntimeException on error.
+ */
+ public function tell();
+
+ /**
+ * Returns true if the stream is at the end of the stream.
+ *
+ * @return bool
+ */
+ public function eof();
+
+ /**
+ * Returns whether or not the stream is seekable.
+ *
+ * @return bool
+ */
+ public function isSeekable();
+
+ /**
+ * Seek to a position in the stream.
+ *
+ * @link http://www.php.net/manual/en/function.fseek.php
+ * @param int $offset Stream offset
+ * @param int $whence Specifies how the cursor position will be calculated
+ * based on the seek offset. Valid values are identical to the built-in
+ * PHP $whence values for `fseek()`. SEEK_SET: Set position equal to
+ * offset bytes SEEK_CUR: Set position to current location plus offset
+ * SEEK_END: Set position to end-of-stream plus offset.
+ * @throws \RuntimeException on failure.
+ */
+ public function seek($offset, $whence = SEEK_SET);
+
+ /**
+ * Seek to the beginning of the stream.
+ *
+ * If the stream is not seekable, this method will raise an exception;
+ * otherwise, it will perform a seek(0).
+ *
+ * @see seek()
+ * @link http://www.php.net/manual/en/function.fseek.php
+ * @throws \RuntimeException on failure.
+ */
+ public function rewind();
+
+ /**
+ * Returns whether or not the stream is writable.
+ *
+ * @return bool
+ */
+ public function isWritable();
+
+ /**
+ * Write data to the stream.
+ *
+ * @param string $string The string that is to be written.
+ * @return int Returns the number of bytes written to the stream.
+ * @throws \RuntimeException on failure.
+ */
+ public function write($string);
+
+ /**
+ * Returns whether or not the stream is readable.
+ *
+ * @return bool
+ */
+ public function isReadable();
+
+ /**
+ * Read data from the stream.
+ *
+ * @param int $length Read up to $length bytes from the object and return
+ * them. Fewer than $length bytes may be returned if underlying stream
+ * call returns fewer bytes.
+ * @return string Returns the data read from the stream, or an empty string
+ * if no bytes are available.
+ * @throws \RuntimeException if an error occurs.
+ */
+ public function read($length);
+
+ /**
+ * Returns the remaining contents in a string
+ *
+ * @return string
+ * @throws \RuntimeException if unable to read or an error occurs while
+ * reading.
+ */
+ public function getContents();
+
+ /**
+ * Get stream metadata as an associative array or retrieve a specific key.
+ *
+ * The keys returned are identical to the keys returned from PHP's
+ * stream_get_meta_data() function.
+ *
+ * @link http://php.net/manual/en/function.stream-get-meta-data.php
+ * @param string $key Specific metadata to retrieve.
+ * @return array|mixed|null Returns an associative array if no key is
+ * provided. Returns a specific key value if a key is provided and the
+ * value is found, or null if the key is not found.
+ */
+ public function getMetadata($key = null);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/src/UploadedFileInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/src/UploadedFileInterface.php
new file mode 100644
index 0000000..f8a6901
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/src/UploadedFileInterface.php
@@ -0,0 +1,123 @@
+<?php
+
+namespace Psr\Http\Message;
+
+/**
+ * Value object representing a file uploaded through an HTTP request.
+ *
+ * Instances of this interface are considered immutable; all methods that
+ * might change state MUST be implemented such that they retain the internal
+ * state of the current instance and return an instance that contains the
+ * changed state.
+ */
+interface UploadedFileInterface
+{
+ /**
+ * Retrieve a stream representing the uploaded file.
+ *
+ * This method MUST return a StreamInterface instance, representing the
+ * uploaded file. The purpose of this method is to allow utilizing native PHP
+ * stream functionality to manipulate the file upload, such as
+ * stream_copy_to_stream() (though the result will need to be decorated in a
+ * native PHP stream wrapper to work with such functions).
+ *
+ * If the moveTo() method has been called previously, this method MUST raise
+ * an exception.
+ *
+ * @return StreamInterface Stream representation of the uploaded file.
+ * @throws \RuntimeException in cases when no stream is available or can be
+ * created.
+ */
+ public function getStream();
+
+ /**
+ * Move the uploaded file to a new location.
+ *
+ * Use this method as an alternative to move_uploaded_file(). This method is
+ * guaranteed to work in both SAPI and non-SAPI environments.
+ * Implementations must determine which environment they are in, and use the
+ * appropriate method (move_uploaded_file(), rename(), or a stream
+ * operation) to perform the operation.
+ *
+ * $targetPath may be an absolute path, or a relative path. If it is a
+ * relative path, resolution should be the same as used by PHP's rename()
+ * function.
+ *
+ * The original file or stream MUST be removed on completion.
+ *
+ * If this method is called more than once, any subsequent calls MUST raise
+ * an exception.
+ *
+ * When used in an SAPI environment where $_FILES is populated, when writing
+ * files via moveTo(), is_uploaded_file() and move_uploaded_file() SHOULD be
+ * used to ensure permissions and upload status are verified correctly.
+ *
+ * If you wish to move to a stream, use getStream(), as SAPI operations
+ * cannot guarantee writing to stream destinations.
+ *
+ * @see http://php.net/is_uploaded_file
+ * @see http://php.net/move_uploaded_file
+ * @param string $targetPath Path to which to move the uploaded file.
+ * @throws \InvalidArgumentException if the $targetPath specified is invalid.
+ * @throws \RuntimeException on any error during the move operation, or on
+ * the second or subsequent call to the method.
+ */
+ public function moveTo($targetPath);
+
+ /**
+ * Retrieve the file size.
+ *
+ * Implementations SHOULD return the value stored in the "size" key of
+ * the file in the $_FILES array if available, as PHP calculates this based
+ * on the actual size transmitted.
+ *
+ * @return int|null The file size in bytes or null if unknown.
+ */
+ public function getSize();
+
+ /**
+ * Retrieve the error associated with the uploaded file.
+ *
+ * The return value MUST be one of PHP's UPLOAD_ERR_XXX constants.
+ *
+ * If the file was uploaded successfully, this method MUST return
+ * UPLOAD_ERR_OK.
+ *
+ * Implementations SHOULD return the value stored in the "error" key of
+ * the file in the $_FILES array.
+ *
+ * @see http://php.net/manual/en/features.file-upload.errors.php
+ * @return int One of PHP's UPLOAD_ERR_XXX constants.
+ */
+ public function getError();
+
+ /**
+ * Retrieve the filename sent by the client.
+ *
+ * Do not trust the value returned by this method. A client could send
+ * a malicious filename with the intention to corrupt or hack your
+ * application.
+ *
+ * Implementations SHOULD return the value stored in the "name" key of
+ * the file in the $_FILES array.
+ *
+ * @return string|null The filename sent by the client or null if none
+ * was provided.
+ */
+ public function getClientFilename();
+
+ /**
+ * Retrieve the media type sent by the client.
+ *
+ * Do not trust the value returned by this method. A client could send
+ * a malicious media type with the intention to corrupt or hack your
+ * application.
+ *
+ * Implementations SHOULD return the value stored in the "type" key of
+ * the file in the $_FILES array.
+ *
+ * @return string|null The media type sent by the client or null if none
+ * was provided.
+ */
+ public function getClientMediaType();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/src/UriInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/src/UriInterface.php
new file mode 100644
index 0000000..9d7ab9e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/psr/http-message/src/UriInterface.php
@@ -0,0 +1,323 @@
+<?php
+namespace Psr\Http\Message;
+
+/**
+ * Value object representing a URI.
+ *
+ * This interface is meant to represent URIs according to RFC 3986 and to
+ * provide methods for most common operations. Additional functionality for
+ * working with URIs can be provided on top of the interface or externally.
+ * Its primary use is for HTTP requests, but may also be used in other
+ * contexts.
+ *
+ * Instances of this interface are considered immutable; all methods that
+ * might change state MUST be implemented such that they retain the internal
+ * state of the current instance and return an instance that contains the
+ * changed state.
+ *
+ * Typically the Host header will be also be present in the request message.
+ * For server-side requests, the scheme will typically be discoverable in the
+ * server parameters.
+ *
+ * @link http://tools.ietf.org/html/rfc3986 (the URI specification)
+ */
+interface UriInterface
+{
+ /**
+ * Retrieve the scheme component of the URI.
+ *
+ * If no scheme is present, this method MUST return an empty string.
+ *
+ * The value returned MUST be normalized to lowercase, per RFC 3986
+ * Section 3.1.
+ *
+ * The trailing ":" character is not part of the scheme and MUST NOT be
+ * added.
+ *
+ * @see https://tools.ietf.org/html/rfc3986#section-3.1
+ * @return string The URI scheme.
+ */
+ public function getScheme();
+
+ /**
+ * Retrieve the authority component of the URI.
+ *
+ * If no authority information is present, this method MUST return an empty
+ * string.
+ *
+ * The authority syntax of the URI is:
+ *
+ * <pre>
+ * [user-info@]host[:port]
+ * </pre>
+ *
+ * If the port component is not set or is the standard port for the current
+ * scheme, it SHOULD NOT be included.
+ *
+ * @see https://tools.ietf.org/html/rfc3986#section-3.2
+ * @return string The URI authority, in "[user-info@]host[:port]" format.
+ */
+ public function getAuthority();
+
+ /**
+ * Retrieve the user information component of the URI.
+ *
+ * If no user information is present, this method MUST return an empty
+ * string.
+ *
+ * If a user is present in the URI, this will return that value;
+ * additionally, if the password is also present, it will be appended to the
+ * user value, with a colon (":") separating the values.
+ *
+ * The trailing "@" character is not part of the user information and MUST
+ * NOT be added.
+ *
+ * @return string The URI user information, in "username[:password]" format.
+ */
+ public function getUserInfo();
+
+ /**
+ * Retrieve the host component of the URI.
+ *
+ * If no host is present, this method MUST return an empty string.
+ *
+ * The value returned MUST be normalized to lowercase, per RFC 3986
+ * Section 3.2.2.
+ *
+ * @see http://tools.ietf.org/html/rfc3986#section-3.2.2
+ * @return string The URI host.
+ */
+ public function getHost();
+
+ /**
+ * Retrieve the port component of the URI.
+ *
+ * If a port is present, and it is non-standard for the current scheme,
+ * this method MUST return it as an integer. If the port is the standard port
+ * used with the current scheme, this method SHOULD return null.
+ *
+ * If no port is present, and no scheme is present, this method MUST return
+ * a null value.
+ *
+ * If no port is present, but a scheme is present, this method MAY return
+ * the standard port for that scheme, but SHOULD return null.
+ *
+ * @return null|int The URI port.
+ */
+ public function getPort();
+
+ /**
+ * Retrieve the path component of the URI.
+ *
+ * The path can either be empty or absolute (starting with a slash) or
+ * rootless (not starting with a slash). Implementations MUST support all
+ * three syntaxes.
+ *
+ * Normally, the empty path "" and absolute path "/" are considered equal as
+ * defined in RFC 7230 Section 2.7.3. But this method MUST NOT automatically
+ * do this normalization because in contexts with a trimmed base path, e.g.
+ * the front controller, this difference becomes significant. It's the task
+ * of the user to handle both "" and "/".
+ *
+ * The value returned MUST be percent-encoded, but MUST NOT double-encode
+ * any characters. To determine what characters to encode, please refer to
+ * RFC 3986, Sections 2 and 3.3.
+ *
+ * As an example, if the value should include a slash ("/") not intended as
+ * delimiter between path segments, that value MUST be passed in encoded
+ * form (e.g., "%2F") to the instance.
+ *
+ * @see https://tools.ietf.org/html/rfc3986#section-2
+ * @see https://tools.ietf.org/html/rfc3986#section-3.3
+ * @return string The URI path.
+ */
+ public function getPath();
+
+ /**
+ * Retrieve the query string of the URI.
+ *
+ * If no query string is present, this method MUST return an empty string.
+ *
+ * The leading "?" character is not part of the query and MUST NOT be
+ * added.
+ *
+ * The value returned MUST be percent-encoded, but MUST NOT double-encode
+ * any characters. To determine what characters to encode, please refer to
+ * RFC 3986, Sections 2 and 3.4.
+ *
+ * As an example, if a value in a key/value pair of the query string should
+ * include an ampersand ("&") not intended as a delimiter between values,
+ * that value MUST be passed in encoded form (e.g., "%26") to the instance.
+ *
+ * @see https://tools.ietf.org/html/rfc3986#section-2
+ * @see https://tools.ietf.org/html/rfc3986#section-3.4
+ * @return string The URI query string.
+ */
+ public function getQuery();
+
+ /**
+ * Retrieve the fragment component of the URI.
+ *
+ * If no fragment is present, this method MUST return an empty string.
+ *
+ * The leading "#" character is not part of the fragment and MUST NOT be
+ * added.
+ *
+ * The value returned MUST be percent-encoded, but MUST NOT double-encode
+ * any characters. To determine what characters to encode, please refer to
+ * RFC 3986, Sections 2 and 3.5.
+ *
+ * @see https://tools.ietf.org/html/rfc3986#section-2
+ * @see https://tools.ietf.org/html/rfc3986#section-3.5
+ * @return string The URI fragment.
+ */
+ public function getFragment();
+
+ /**
+ * Return an instance with the specified scheme.
+ *
+ * This method MUST retain the state of the current instance, and return
+ * an instance that contains the specified scheme.
+ *
+ * Implementations MUST support the schemes "http" and "https" case
+ * insensitively, and MAY accommodate other schemes if required.
+ *
+ * An empty scheme is equivalent to removing the scheme.
+ *
+ * @param string $scheme The scheme to use with the new instance.
+ * @return static A new instance with the specified scheme.
+ * @throws \InvalidArgumentException for invalid or unsupported schemes.
+ */
+ public function withScheme($scheme);
+
+ /**
+ * Return an instance with the specified user information.
+ *
+ * This method MUST retain the state of the current instance, and return
+ * an instance that contains the specified user information.
+ *
+ * Password is optional, but the user information MUST include the
+ * user; an empty string for the user is equivalent to removing user
+ * information.
+ *
+ * @param string $user The user name to use for authority.
+ * @param null|string $password The password associated with $user.
+ * @return static A new instance with the specified user information.
+ */
+ public function withUserInfo($user, $password = null);
+
+ /**
+ * Return an instance with the specified host.
+ *
+ * This method MUST retain the state of the current instance, and return
+ * an instance that contains the specified host.
+ *
+ * An empty host value is equivalent to removing the host.
+ *
+ * @param string $host The hostname to use with the new instance.
+ * @return static A new instance with the specified host.
+ * @throws \InvalidArgumentException for invalid hostnames.
+ */
+ public function withHost($host);
+
+ /**
+ * Return an instance with the specified port.
+ *
+ * This method MUST retain the state of the current instance, and return
+ * an instance that contains the specified port.
+ *
+ * Implementations MUST raise an exception for ports outside the
+ * established TCP and UDP port ranges.
+ *
+ * A null value provided for the port is equivalent to removing the port
+ * information.
+ *
+ * @param null|int $port The port to use with the new instance; a null value
+ * removes the port information.
+ * @return static A new instance with the specified port.
+ * @throws \InvalidArgumentException for invalid ports.
+ */
+ public function withPort($port);
+
+ /**
+ * Return an instance with the specified path.
+ *
+ * This method MUST retain the state of the current instance, and return
+ * an instance that contains the specified path.
+ *
+ * The path can either be empty or absolute (starting with a slash) or
+ * rootless (not starting with a slash). Implementations MUST support all
+ * three syntaxes.
+ *
+ * If the path is intended to be domain-relative rather than path relative then
+ * it must begin with a slash ("/"). Paths not starting with a slash ("/")
+ * are assumed to be relative to some base path known to the application or
+ * consumer.
+ *
+ * Users can provide both encoded and decoded path characters.
+ * Implementations ensure the correct encoding as outlined in getPath().
+ *
+ * @param string $path The path to use with the new instance.
+ * @return static A new instance with the specified path.
+ * @throws \InvalidArgumentException for invalid paths.
+ */
+ public function withPath($path);
+
+ /**
+ * Return an instance with the specified query string.
+ *
+ * This method MUST retain the state of the current instance, and return
+ * an instance that contains the specified query string.
+ *
+ * Users can provide both encoded and decoded query characters.
+ * Implementations ensure the correct encoding as outlined in getQuery().
+ *
+ * An empty query string value is equivalent to removing the query string.
+ *
+ * @param string $query The query string to use with the new instance.
+ * @return static A new instance with the specified query string.
+ * @throws \InvalidArgumentException for invalid query strings.
+ */
+ public function withQuery($query);
+
+ /**
+ * Return an instance with the specified URI fragment.
+ *
+ * This method MUST retain the state of the current instance, and return
+ * an instance that contains the specified URI fragment.
+ *
+ * Users can provide both encoded and decoded fragment characters.
+ * Implementations ensure the correct encoding as outlined in getFragment().
+ *
+ * An empty fragment value is equivalent to removing the fragment.
+ *
+ * @param string $fragment The fragment to use with the new instance.
+ * @return static A new instance with the specified fragment.
+ */
+ public function withFragment($fragment);
+
+ /**
+ * Return the string representation as a URI reference.
+ *
+ * Depending on which components of the URI are present, the resulting
+ * string is either a full URI or relative reference according to RFC 3986,
+ * Section 4.1. The method concatenates the various components of the URI,
+ * using the appropriate delimiters:
+ *
+ * - If a scheme is present, it MUST be suffixed by ":".
+ * - If an authority is present, it MUST be prefixed by "//".
+ * - The path can be concatenated without delimiters. But there are two
+ * cases where the path has to be adjusted to make the URI reference
+ * valid as PHP does not allow to throw an exception in __toString():
+ * - If the path is rootless and an authority is present, the path MUST
+ * be prefixed by "/".
+ * - If the path is starting with more than one "/" and no authority is
+ * present, the starting slashes MUST be reduced to one.
+ * - If a query is present, it MUST be prefixed by "?".
+ * - If a fragment is present, it MUST be prefixed by "#".
+ *
+ * @see http://tools.ietf.org/html/rfc3986#section-4.1
+ * @return string
+ */
+ public function __toString();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/.gitignore b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/.gitignore
new file mode 100644
index 0000000..42ab5d5
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/.gitignore
@@ -0,0 +1,4 @@
+composer.lock
+vendor
+tests/ab/reports
+reports
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/.travis.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/.travis.yml
new file mode 100644
index 0000000..11d51b4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/.travis.yml
@@ -0,0 +1,20 @@
+language: php
+
+php:
+ - 5.4
+ - 5.5
+ - 5.6
+ - 7
+ - hhvm
+
+before_install:
+ - export PATH=$HOME/.local/bin:$PATH
+ - pip install --user autobahntestsuite
+ - pip list --user autobahntestsuite
+
+before_script:
+ - composer install
+ - sh tests/ab/run_ab_tests.sh
+
+script:
+ - vendor/bin/phpunit
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/LICENSE b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/LICENSE
new file mode 100644
index 0000000..7f8c128
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2011-2016 Chris Boden
+
+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.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/README.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/README.md
new file mode 100644
index 0000000..7c09148
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/README.md
@@ -0,0 +1,13 @@
+# RFC6455 - The WebSocket Protocol
+
+[![Build Status](https://travis-ci.org/ratchetphp/RFC6455.svg?branch=master)](https://travis-ci.org/ratchetphp/RFC6455)
+![Autobahn Testsuite](https://img.shields.io/badge/Autobahn-passing-brightgreen.svg)
+
+This library a protocol handler for the RFC6455 specification.
+It contains components for both server and client side handshake and messaging protocol negotation.
+
+Aspects that are left open to interpertation in the specification are also left open in this library.
+It is up to the implementation to determine how those interpertations are to be dealt with.
+
+This library is independent, framework agnostic, and does not deal with any I/O.
+HTTP upgrade negotiation integration points are handled with PSR-7 interfaces.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/composer.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/composer.json
new file mode 100644
index 0000000..224066b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/composer.json
@@ -0,0 +1,32 @@
+{
+ "name": "ratchet/rfc6455",
+ "type": "library",
+ "description": "RFC6455 WebSocket protocol handler",
+ "keywords": ["WebSockets", "websocket", "RFC6455"],
+ "homepage": "http://socketo.me",
+ "license": "MIT",
+ "authors": [{
+ "name": "Chris Boden"
+ , "email": "cboden@gmail.com"
+ , "role": "Developer"
+ }],
+ "support": {
+ "forum": "https://groups.google.com/forum/#!forum/ratchet-php"
+ , "issues": "https://github.com/ratchetphp/RFC6455/issues"
+ , "irc": "irc://irc.freenode.org/reactphp"
+ },
+ "autoload": {
+ "psr-4": {
+ "Ratchet\\RFC6455\\": "src"
+ }
+ },
+ "require": {
+ "php": ">=5.4.2",
+ "guzzlehttp/psr7": "^1.0"
+ },
+ "require-dev": {
+ "react/http": "^0.4.1",
+ "react/socket-client": "^0.4.3",
+ "phpunit/phpunit": "4.8.*"
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/phpunit.xml.dist b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/phpunit.xml.dist
new file mode 100644
index 0000000..8f2e7d1
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/phpunit.xml.dist
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit
+ forceCoversAnnotation="true"
+ mapTestClassNameToCoveredClassName="true"
+ bootstrap="tests/bootstrap.php"
+ colors="true"
+ backupGlobals="false"
+ backupStaticAttributes="false"
+ syntaxCheck="false"
+ stopOnError="false"
+ >
+
+ <testsuites>
+ <testsuite name="tests">
+ <directory>tests</directory>
+ <exclude>
+ <directory>test/ab</directory>
+ </exclude>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist>
+ <directory>./src/</directory>
+ </whitelist>
+ </filter>
+</phpunit> \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Handshake/ClientNegotiator.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Handshake/ClientNegotiator.php
new file mode 100644
index 0000000..70856df
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Handshake/ClientNegotiator.php
@@ -0,0 +1,53 @@
+<?php
+namespace Ratchet\RFC6455\Handshake;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\UriInterface;
+use GuzzleHttp\Psr7\Request;
+
+class ClientNegotiator {
+ /**
+ * @var ResponseVerifier
+ */
+ private $verifier;
+
+ /**
+ * @var \Psr\Http\Message\RequestInterface
+ */
+ private $defaultHeader;
+
+ function __construct() {
+ $this->verifier = new ResponseVerifier;
+
+ $this->defaultHeader = new Request('GET', '', [
+ 'Connection' => 'Upgrade'
+ , 'Upgrade' => 'websocket'
+ , 'Sec-WebSocket-Version' => $this->getVersion()
+ , 'User-Agent' => "Ratchet"
+ ]);
+ }
+
+ public function generateRequest(UriInterface $uri) {
+ return $this->defaultHeader->withUri($uri)
+ ->withHeader("Sec-WebSocket-Key", $this->generateKey());
+ }
+
+ public function validateResponse(RequestInterface $request, ResponseInterface $response) {
+ return $this->verifier->verifyAll($request, $response);
+ }
+
+ public function generateKey() {
+ $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwzyz1234567890+/=';
+ $charRange = strlen($chars) - 1;
+ $key = '';
+ for ($i = 0; $i < 16; $i++) {
+ $key .= $chars[mt_rand(0, $charRange)];
+ }
+
+ return base64_encode($key);
+ }
+
+ public function getVersion() {
+ return 13;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Handshake/NegotiatorInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Handshake/NegotiatorInterface.php
new file mode 100644
index 0000000..c152eca
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Handshake/NegotiatorInterface.php
@@ -0,0 +1,47 @@
+<?php
+namespace Ratchet\RFC6455\Handshake;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * A standard interface for interacting with the various version of the WebSocket protocol
+ * @todo Look in to extension support
+ */
+interface NegotiatorInterface {
+ const GUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
+
+ /**
+ * Given an HTTP header, determine if this version should handle the protocol
+ * @param RequestInterface $request
+ * @return bool
+ */
+ function isProtocol(RequestInterface $request);
+
+ /**
+ * Although the version has a name associated with it the integer returned is the proper identification
+ * @return int
+ */
+ function getVersionNumber();
+
+ /**
+ * Perform the handshake and return the response headers
+ * @param RequestInterface $request
+ * @return \Psr\Http\Message\ResponseInterface
+ */
+ function handshake(RequestInterface $request);
+
+ /**
+ * Add supported protocols. If the request has any matching the response will include one
+ * @param array $protocols
+ */
+ function setSupportedSubProtocols(array $protocols);
+
+ /**
+ * If enabled and support for a subprotocol has been added handshake
+ * will not upgrade if a match between request and supported subprotocols
+ * @param boolean $enable
+ * @todo Consider extending this interface and moving this there.
+ * The spec does says the server can fail for this reason, but
+ * it is not a requirement. This is an implementation detail.
+ */
+ function setStrictSubProtocolCheck($enable);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Handshake/RequestVerifier.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Handshake/RequestVerifier.php
new file mode 100644
index 0000000..1ace489
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Handshake/RequestVerifier.php
@@ -0,0 +1,140 @@
+<?php
+namespace Ratchet\RFC6455\Handshake;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * These are checks to ensure the client requested handshake are valid
+ * Verification rules come from section 4.2.1 of the RFC6455 document
+ * @todo Currently just returning invalid - should consider returning appropriate HTTP status code error #s
+ */
+class RequestVerifier {
+ const VERSION = 13;
+
+ /**
+ * Given an array of the headers this method will run through all verification methods
+ * @param RequestInterface $request
+ * @return bool TRUE if all headers are valid, FALSE if 1 or more were invalid
+ */
+ public function verifyAll(RequestInterface $request) {
+ $passes = 0;
+
+ $passes += (int)$this->verifyMethod($request->getMethod());
+ $passes += (int)$this->verifyHTTPVersion($request->getProtocolVersion());
+ $passes += (int)$this->verifyRequestURI($request->getUri()->getPath());
+ $passes += (int)$this->verifyHost($request->getHeader('Host'));
+ $passes += (int)$this->verifyUpgradeRequest($request->getHeader('Upgrade'));
+ $passes += (int)$this->verifyConnection($request->getHeader('Connection'));
+ $passes += (int)$this->verifyKey($request->getHeader('Sec-WebSocket-Key'));
+ $passes += (int)$this->verifyVersion($request->getHeader('Sec-WebSocket-Version'));
+
+ return (8 === $passes);
+ }
+
+ /**
+ * Test the HTTP method. MUST be "GET"
+ * @param string
+ * @return bool
+ */
+ public function verifyMethod($val) {
+ return ('get' === strtolower($val));
+ }
+
+ /**
+ * Test the HTTP version passed. MUST be 1.1 or greater
+ * @param string|int
+ * @return bool
+ */
+ public function verifyHTTPVersion($val) {
+ return (1.1 <= (double)$val);
+ }
+
+ /**
+ * @param string
+ * @return bool
+ */
+ public function verifyRequestURI($val) {
+ if ($val[0] !== '/') {
+ return false;
+ }
+
+ if (false !== strstr($val, '#')) {
+ return false;
+ }
+
+ if (!extension_loaded('mbstring')) {
+ return true;
+ }
+
+ return mb_check_encoding($val, 'US-ASCII');
+ }
+
+ /**
+ * @param array $hostHeader
+ * @return bool
+ * @todo Once I fix HTTP::getHeaders just verify this isn't NULL or empty...or maybe need to verify it's a valid domain??? Or should it equal $_SERVER['HOST'] ?
+ */
+ public function verifyHost(array $hostHeader) {
+ return (1 === count($hostHeader));
+ }
+
+ /**
+ * Verify the Upgrade request to WebSockets.
+ * @param array $upgradeHeader MUST equal "websocket"
+ * @return bool
+ */
+ public function verifyUpgradeRequest(array $upgradeHeader) {
+ return (1 === count($upgradeHeader) && 'websocket' === strtolower($upgradeHeader[0]));
+ }
+
+ /**
+ * Verify the Connection header
+ * @param array $connectionHeader MUST include "Upgrade"
+ * @return bool
+ */
+ public function verifyConnection(array $connectionHeader) {
+ foreach ($connectionHeader as $l) {
+ $upgrades = array_filter(
+ array_map('trim', array_map('strtolower', explode(',', $l))),
+ function ($x) {
+ return 'upgrade' === $x;
+ }
+ );
+ if (count($upgrades) > 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * This function verifies the nonce is valid (64 big encoded, 16 bytes random string)
+ * @param array $keyHeader
+ * @return bool
+ * @todo The spec says we don't need to base64_decode - can I just check if the length is 24 and not decode?
+ * @todo Check the spec to see what the encoding of the key could be
+ */
+ public function verifyKey(array $keyHeader) {
+ return (1 === count($keyHeader) && 16 === strlen(base64_decode($keyHeader[0])));
+ }
+
+ /**
+ * Verify the version passed matches this RFC
+ * @param string|int $versionHeader MUST equal 13|"13"
+ * @return bool
+ */
+ public function verifyVersion($versionHeader) {
+ return (1 === count($versionHeader) && static::VERSION === (int)$versionHeader[0]);
+ }
+
+ /**
+ * @todo Write logic for this method. See section 4.2.1.8
+ */
+ public function verifyProtocol($val) {
+ }
+
+ /**
+ * @todo Write logic for this method. See section 4.2.1.9
+ */
+ public function verifyExtensions($val) {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Handshake/ResponseVerifier.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Handshake/ResponseVerifier.php
new file mode 100644
index 0000000..de03f53
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Handshake/ResponseVerifier.php
@@ -0,0 +1,52 @@
+<?php
+namespace Ratchet\RFC6455\Handshake;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
+class ResponseVerifier {
+ public function verifyAll(RequestInterface $request, ResponseInterface $response) {
+ $passes = 0;
+
+ $passes += (int)$this->verifyStatus($response->getStatusCode());
+ $passes += (int)$this->verifyUpgrade($response->getHeader('Upgrade'));
+ $passes += (int)$this->verifyConnection($response->getHeader('Connection'));
+ $passes += (int)$this->verifySecWebSocketAccept(
+ $response->getHeader('Sec-WebSocket-Accept')
+ , $request->getHeader('Sec-WebSocket-Key')
+ );
+ $passes += (int)$this->verifySubProtocol(
+ $request->getHeader('Sec-WebSocket-Protocol')
+ , $response->getHeader('Sec-WebSocket-Protocol')
+ );
+
+ return (5 === $passes);
+ }
+
+ public function verifyStatus($status) {
+ return ((int)$status === 101);
+ }
+
+ public function verifyUpgrade(array $upgrade) {
+ return (in_array('websocket', array_map('strtolower', $upgrade)));
+ }
+
+ public function verifyConnection(array $connection) {
+ return (in_array('upgrade', array_map('strtolower', $connection)));
+ }
+
+ public function verifySecWebSocketAccept($swa, $key) {
+ return (
+ 1 === count($swa) &&
+ 1 === count($key) &&
+ $swa[0] === $this->sign($key[0])
+ );
+ }
+
+ public function sign($key) {
+ return base64_encode(sha1($key . NegotiatorInterface::GUID, true));
+ }
+
+ public function verifySubProtocol(array $requestHeader, array $responseHeader) {
+ return 0 === count($responseHeader) || count(array_intersect($responseHeader, $requestHeader)) > 0;
+ }
+} \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Handshake/ServerNegotiator.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Handshake/ServerNegotiator.php
new file mode 100644
index 0000000..5a0073b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Handshake/ServerNegotiator.php
@@ -0,0 +1,136 @@
+<?php
+namespace Ratchet\RFC6455\Handshake;
+use Psr\Http\Message\RequestInterface;
+use GuzzleHttp\Psr7\Response;
+
+/**
+ * The latest version of the WebSocket protocol
+ * @todo Unicode: return mb_convert_encoding(pack("N",$u), mb_internal_encoding(), 'UCS-4BE');
+ */
+class ServerNegotiator implements NegotiatorInterface {
+ /**
+ * @var \Ratchet\RFC6455\Handshake\RequestVerifier
+ */
+ private $verifier;
+
+ private $_supportedSubProtocols = [];
+
+ private $_strictSubProtocols = false;
+
+ public function __construct(RequestVerifier $requestVerifier) {
+ $this->verifier = $requestVerifier;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isProtocol(RequestInterface $request) {
+ return $this->verifier->verifyVersion($request->getHeader('Sec-WebSocket-Version'));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getVersionNumber() {
+ return RequestVerifier::VERSION;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function handshake(RequestInterface $request) {
+ if (true !== $this->verifier->verifyMethod($request->getMethod())) {
+ return new Response(405, ['Allow' => 'GET']);
+ }
+
+ if (true !== $this->verifier->verifyHTTPVersion($request->getProtocolVersion())) {
+ return new Response(505);
+ }
+
+ if (true !== $this->verifier->verifyRequestURI($request->getUri()->getPath())) {
+ return new Response(400);
+ }
+
+ if (true !== $this->verifier->verifyHost($request->getHeader('Host'))) {
+ return new Response(400);
+ }
+
+ $upgradeSuggestion = [
+ 'Connection' => 'Upgrade',
+ 'Upgrade' => 'websocket',
+ 'Sec-WebSocket-Version' => $this->getVersionNumber()
+ ];
+ if (count($this->_supportedSubProtocols) > 0) {
+ $upgradeSuggestion['Sec-WebSocket-Protocol'] = implode(', ', $this->_supportedSubProtocols);
+ }
+ if (true !== $this->verifier->verifyUpgradeRequest($request->getHeader('Upgrade'))) {
+ return new Response(426, $upgradeSuggestion, null, '1.1', 'Upgrade header MUST be provided');
+ }
+
+ if (true !== $this->verifier->verifyConnection($request->getHeader('Connection'))) {
+ return new Response(400, [], null, '1.1', 'Connection Upgrade MUST be requested');
+ }
+
+ if (true !== $this->verifier->verifyKey($request->getHeader('Sec-WebSocket-Key'))) {
+ return new Response(400, [], null, '1.1', 'Invalid Sec-WebSocket-Key');
+ }
+
+ if (true !== $this->verifier->verifyVersion($request->getHeader('Sec-WebSocket-Version'))) {
+ return new Response(426, $upgradeSuggestion);
+ }
+
+ $headers = [];
+ $subProtocols = $request->getHeader('Sec-WebSocket-Protocol');
+ if (count($subProtocols) > 0 || (count($this->_supportedSubProtocols) > 0 && $this->_strictSubProtocols)) {
+ $subProtocols = array_map('trim', explode(',', implode(',', $subProtocols)));
+
+ $match = array_reduce($subProtocols, function($accumulator, $protocol) {
+ return $accumulator ?: (isset($this->_supportedSubProtocols[$protocol]) ? $protocol : null);
+ }, null);
+
+ if ($this->_strictSubProtocols && null === $match) {
+ return new Response(426, $upgradeSuggestion, null, '1.1', 'No Sec-WebSocket-Protocols requested supported');
+ }
+
+ if (null !== $match) {
+ $headers['Sec-WebSocket-Protocol'] = $match;
+ }
+ }
+
+ return new Response(101, array_merge($headers, [
+ 'Upgrade' => 'websocket'
+ , 'Connection' => 'Upgrade'
+ , 'Sec-WebSocket-Accept' => $this->sign((string)$request->getHeader('Sec-WebSocket-Key')[0])
+ , 'X-Powered-By' => 'Ratchet'
+ ]));
+ }
+
+ /**
+ * Used when doing the handshake to encode the key, verifying client/server are speaking the same language
+ * @param string $key
+ * @return string
+ * @internal
+ */
+ public function sign($key) {
+ return base64_encode(sha1($key . static::GUID, true));
+ }
+
+ /**
+ * @param array $protocols
+ */
+ function setSupportedSubProtocols(array $protocols) {
+ $this->_supportedSubProtocols = array_flip($protocols);
+ }
+
+ /**
+ * If enabled and support for a subprotocol has been added handshake
+ * will not upgrade if a match between request and supported subprotocols
+ * @param boolean $enable
+ * @todo Consider extending this interface and moving this there.
+ * The spec does says the server can fail for this reason, but
+ * it is not a requirement. This is an implementation detail.
+ */
+ function setStrictSubProtocolCheck($enable) {
+ $this->_strictSubProtocols = (boolean)$enable;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Messaging/CloseFrameChecker.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Messaging/CloseFrameChecker.php
new file mode 100644
index 0000000..3d800e5
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Messaging/CloseFrameChecker.php
@@ -0,0 +1,24 @@
+<?php
+namespace Ratchet\RFC6455\Messaging;
+
+class CloseFrameChecker {
+ private $validCloseCodes = [];
+
+ public function __construct() {
+ $this->validCloseCodes = [
+ Frame::CLOSE_NORMAL,
+ Frame::CLOSE_GOING_AWAY,
+ Frame::CLOSE_PROTOCOL,
+ Frame::CLOSE_BAD_DATA,
+ Frame::CLOSE_BAD_PAYLOAD,
+ Frame::CLOSE_POLICY,
+ Frame::CLOSE_TOO_BIG,
+ Frame::CLOSE_MAND_EXT,
+ Frame::CLOSE_SRV_ERR,
+ ];
+ }
+
+ public function __invoke($val) {
+ return ($val >= 3000 && $val <= 4999) || in_array($val, $this->validCloseCodes);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Messaging/DataInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Messaging/DataInterface.php
new file mode 100644
index 0000000..18aa2e3
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Messaging/DataInterface.php
@@ -0,0 +1,34 @@
+<?php
+namespace Ratchet\RFC6455\Messaging;
+
+interface DataInterface {
+ /**
+ * Determine if the message is complete or still fragmented
+ * @return bool
+ */
+ function isCoalesced();
+
+ /**
+ * Get the number of bytes the payload is set to be
+ * @return int
+ */
+ function getPayloadLength();
+
+ /**
+ * Get the payload (message) sent from peer
+ * @return string
+ */
+ function getPayload();
+
+ /**
+ * Get raw contents of the message
+ * @return string
+ */
+ function getContents();
+
+ /**
+ * Should return the unmasked payload received from peer
+ * @return string
+ */
+ function __toString();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Messaging/Frame.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Messaging/Frame.php
new file mode 100644
index 0000000..40f9eb2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Messaging/Frame.php
@@ -0,0 +1,473 @@
+<?php
+namespace Ratchet\RFC6455\Messaging;
+
+class Frame implements FrameInterface {
+ const OP_CONTINUE = 0;
+ const OP_TEXT = 1;
+ const OP_BINARY = 2;
+ const OP_CLOSE = 8;
+ const OP_PING = 9;
+ const OP_PONG = 10;
+
+ const CLOSE_NORMAL = 1000;
+ const CLOSE_GOING_AWAY = 1001;
+ const CLOSE_PROTOCOL = 1002;
+ const CLOSE_BAD_DATA = 1003;
+ const CLOSE_NO_STATUS = 1005;
+ const CLOSE_ABNORMAL = 1006;
+ const CLOSE_BAD_PAYLOAD = 1007;
+ const CLOSE_POLICY = 1008;
+ const CLOSE_TOO_BIG = 1009;
+ const CLOSE_MAND_EXT = 1010;
+ const CLOSE_SRV_ERR = 1011;
+ const CLOSE_TLS = 1015;
+
+ const MASK_LENGTH = 4;
+
+ /**
+ * The contents of the frame
+ * @var string
+ */
+ protected $data = '';
+
+ /**
+ * Number of bytes received from the frame
+ * @var int
+ */
+ public $bytesRecvd = 0;
+
+ /**
+ * Number of bytes in the payload (as per framing protocol)
+ * @var int
+ */
+ protected $defPayLen = -1;
+
+ /**
+ * If the frame is coalesced this is true
+ * This is to prevent doing math every time ::isCoalesced is called
+ * @var boolean
+ */
+ private $isCoalesced = false;
+
+ /**
+ * The unpacked first byte of the frame
+ * @var int
+ */
+ protected $firstByte = -1;
+
+ /**
+ * The unpacked second byte of the frame
+ * @var int
+ */
+ protected $secondByte = -1;
+
+ /**
+ * @var callable
+ * @returns \UnderflowException
+ */
+ private $ufeg;
+
+ /**
+ * @param string|null $payload
+ * @param bool $final
+ * @param int $opcode
+ * @param callable<\UnderflowException> $ufExceptionFactory
+ */
+ public function __construct($payload = null, $final = true, $opcode = 1, callable $ufExceptionFactory = null) {
+ $this->ufeg = $ufExceptionFactory ?: function($msg = '') {
+ return new \UnderflowException($msg);
+ };
+
+ if (null === $payload) {
+ return;
+ }
+
+ $this->defPayLen = strlen($payload);
+ $this->firstByte = ($final ? 128 : 0) + $opcode;
+ $this->secondByte = $this->defPayLen;
+ $this->isCoalesced = true;
+
+ $ext = '';
+ if ($this->defPayLen > 65535) {
+ $ext = pack('NN', 0, $this->defPayLen);
+ $this->secondByte = 127;
+ } elseif ($this->defPayLen > 125) {
+ $ext = pack('n', $this->defPayLen);
+ $this->secondByte = 126;
+ }
+
+ $this->data = chr($this->firstByte) . chr($this->secondByte) . $ext . $payload;
+ $this->bytesRecvd = 2 + strlen($ext) + $this->defPayLen;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isCoalesced() {
+ if (true === $this->isCoalesced) {
+ return true;
+ }
+
+ try {
+ $payload_length = $this->getPayloadLength();
+ $payload_start = $this->getPayloadStartingByte();
+ } catch (\UnderflowException $e) {
+ return false;
+ }
+
+ $this->isCoalesced = $this->bytesRecvd >= $payload_length + $payload_start;
+
+ return $this->isCoalesced;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addBuffer($buf) {
+ $len = strlen($buf);
+
+ $this->data .= $buf;
+ $this->bytesRecvd += $len;
+
+ if ($this->firstByte === -1 && $this->bytesRecvd !== 0) {
+ $this->firstByte = ord($this->data[0]);
+ }
+
+ if ($this->secondByte === -1 && $this->bytesRecvd >= 2) {
+ $this->secondByte = ord($this->data[1]);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isFinal() {
+ if (-1 === $this->firstByte) {
+ throw call_user_func($this->ufeg, 'Not enough bytes received to determine if this is the final frame in message');
+ }
+
+ return 128 === ($this->firstByte & 128);
+ }
+
+ /**
+ * @return boolean
+ * @throws \UnderflowException
+ */
+ public function getRsv1() {
+ if (-1 === $this->firstByte) {
+ throw call_user_func($this->ufeg, 'Not enough bytes received to determine reserved bit');
+ }
+
+ return 64 === ($this->firstByte & 64);
+ }
+
+ /**
+ * @return boolean
+ * @throws \UnderflowException
+ */
+ public function getRsv2() {
+ if (-1 === $this->firstByte) {
+ throw call_user_func($this->ufeg, 'Not enough bytes received to determine reserved bit');
+ }
+
+ return 32 === ($this->firstByte & 32);
+ }
+
+ /**
+ * @return boolean
+ * @throws \UnderflowException
+ */
+ public function getRsv3() {
+ if (-1 === $this->firstByte) {
+ throw call_user_func($this->ufeg, 'Not enough bytes received to determine reserved bit');
+ }
+
+ return 16 === ($this->firstByte & 16);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isMasked() {
+ if (-1 === $this->secondByte) {
+ throw call_user_func($this->ufeg, "Not enough bytes received ({$this->bytesRecvd}) to determine if mask is set");
+ }
+
+ return 128 === ($this->secondByte & 128);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMaskingKey() {
+ if (!$this->isMasked()) {
+ return '';
+ }
+
+ $start = 1 + $this->getNumPayloadBytes();
+
+ if ($this->bytesRecvd < $start + static::MASK_LENGTH) {
+ throw call_user_func($this->ufeg, 'Not enough data buffered to calculate the masking key');
+ }
+
+ return substr($this->data, $start, static::MASK_LENGTH);
+ }
+
+ /**
+ * Create a 4 byte masking key
+ * @return string
+ */
+ public function generateMaskingKey() {
+ $mask = '';
+
+ for ($i = 1; $i <= static::MASK_LENGTH; $i++) {
+ $mask .= chr(rand(32, 126));
+ }
+
+ return $mask;
+ }
+
+ /**
+ * Apply a mask to the payload
+ * @param string|null If NULL is passed a masking key will be generated
+ * @throws \OutOfBoundsException
+ * @throws \InvalidArgumentException If there is an issue with the given masking key
+ * @return Frame
+ */
+ public function maskPayload($maskingKey = null) {
+ if (null === $maskingKey) {
+ $maskingKey = $this->generateMaskingKey();
+ }
+
+ if (static::MASK_LENGTH !== strlen($maskingKey)) {
+ throw new \InvalidArgumentException("Masking key must be " . static::MASK_LENGTH ." characters");
+ }
+
+ if (extension_loaded('mbstring') && true !== mb_check_encoding($maskingKey, 'US-ASCII')) {
+ throw new \OutOfBoundsException("Masking key MUST be ASCII");
+ }
+
+ $this->unMaskPayload();
+
+ $this->secondByte = $this->secondByte | 128;
+ $this->data[1] = chr($this->secondByte);
+
+ $this->data = substr_replace($this->data, $maskingKey, $this->getNumPayloadBytes() + 1, 0);
+
+ $this->bytesRecvd += static::MASK_LENGTH;
+ $this->data = substr_replace($this->data, $this->applyMask($maskingKey), $this->getPayloadStartingByte(), $this->getPayloadLength());
+
+ return $this;
+ }
+
+ /**
+ * Remove a mask from the payload
+ * @throws \UnderFlowException If the frame is not coalesced
+ * @return Frame
+ */
+ public function unMaskPayload() {
+ if (!$this->isCoalesced()) {
+ throw call_user_func($this->ufeg, 'Frame must be coalesced before applying mask');
+ }
+
+ if (!$this->isMasked()) {
+ return $this;
+ }
+
+ $maskingKey = $this->getMaskingKey();
+
+ $this->secondByte = $this->secondByte & ~128;
+ $this->data[1] = chr($this->secondByte);
+
+ $this->data = substr_replace($this->data, '', $this->getNumPayloadBytes() + 1, static::MASK_LENGTH);
+
+ $this->bytesRecvd -= static::MASK_LENGTH;
+ $this->data = substr_replace($this->data, $this->applyMask($maskingKey), $this->getPayloadStartingByte(), $this->getPayloadLength());
+
+ return $this;
+ }
+
+ /**
+ * Apply a mask to a string or the payload of the instance
+ * @param string $maskingKey The 4 character masking key to be applied
+ * @param string|null $payload A string to mask or null to use the payload
+ * @throws \UnderflowException If using the payload but enough hasn't been buffered
+ * @return string The masked string
+ */
+ public function applyMask($maskingKey, $payload = null) {
+ if (null === $payload) {
+ if (!$this->isCoalesced()) {
+ throw call_user_func($this->ufeg, 'Frame must be coalesced to apply a mask');
+ }
+
+ $payload = substr($this->data, $this->getPayloadStartingByte(), $this->getPayloadLength());
+ }
+
+ $len = strlen($payload);
+
+ if (0 === $len) {
+ return '';
+ }
+
+ return $payload ^ str_pad('', $len, $maskingKey, STR_PAD_RIGHT);
+
+ // TODO: Remove this before publish - keeping methods here to compare performance (above is faster but need control against v0.3.3)
+
+ $applied = '';
+ for ($i = 0, $len = strlen($payload); $i < $len; $i++) {
+ $applied .= $payload[$i] ^ $maskingKey[$i % static::MASK_LENGTH];
+ }
+
+ return $applied;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getOpcode() {
+ if (-1 === $this->firstByte) {
+ throw call_user_func($this->ufeg, 'Not enough bytes received to determine opcode');
+ }
+
+ return ($this->firstByte & ~240);
+ }
+
+ /**
+ * Gets the decimal value of bits 9 (10th) through 15 inclusive
+ * @return int
+ * @throws \UnderflowException If the buffer doesn't have enough data to determine this
+ */
+ protected function getFirstPayloadVal() {
+ if (-1 === $this->secondByte) {
+ throw call_user_func($this->ufeg, 'Not enough bytes received');
+ }
+
+ return $this->secondByte & 127;
+ }
+
+ /**
+ * @return int (7|23|71) Number of bits defined for the payload length in the fame
+ * @throws \UnderflowException
+ */
+ protected function getNumPayloadBits() {
+ if (-1 === $this->secondByte) {
+ throw call_user_func($this->ufeg, 'Not enough bytes received');
+ }
+
+ // By default 7 bits are used to describe the payload length
+ // These are bits 9 (10th) through 15 inclusive
+ $bits = 7;
+
+ // Get the value of those bits
+ $check = $this->getFirstPayloadVal();
+
+ // If the value is 126 the 7 bits plus the next 16 are used to describe the payload length
+ if ($check >= 126) {
+ $bits += 16;
+ }
+
+ // If the value of the initial payload length are is 127 an additional 48 bits are used to describe length
+ // Note: The documentation specifies the length is to be 63 bits, but I think that's a typo and is 64 (16+48)
+ if ($check === 127) {
+ $bits += 48;
+ }
+
+ return $bits;
+ }
+
+ /**
+ * This just returns the number of bytes used in the frame to describe the payload length (as opposed to # of bits)
+ * @see getNumPayloadBits
+ */
+ protected function getNumPayloadBytes() {
+ return (1 + $this->getNumPayloadBits()) / 8;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getPayloadLength() {
+ if ($this->defPayLen !== -1) {
+ return $this->defPayLen;
+ }
+
+ $this->defPayLen = $this->getFirstPayloadVal();
+ if ($this->defPayLen <= 125) {
+ return $this->getPayloadLength();
+ }
+
+ $byte_length = $this->getNumPayloadBytes();
+ if ($this->bytesRecvd < 1 + $byte_length) {
+ $this->defPayLen = -1;
+ throw call_user_func($this->ufeg, 'Not enough data buffered to determine payload length');
+ }
+
+ $len = 0;
+ for ($i = 2; $i <= $byte_length; $i++) {
+ $len <<= 8;
+ $len += ord($this->data[$i]);
+ }
+
+ $this->defPayLen = $len;
+
+ return $this->getPayloadLength();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getPayloadStartingByte() {
+ return 1 + $this->getNumPayloadBytes() + ($this->isMasked() ? static::MASK_LENGTH : 0);
+ }
+
+ /**
+ * {@inheritdoc}
+ * @todo Consider not checking mask, always returning the payload, masked or not
+ */
+ public function getPayload() {
+ if (!$this->isCoalesced()) {
+ throw call_user_func($this->ufeg, 'Can not return partial message');
+ }
+
+ return $this->__toString();
+ }
+
+ /**
+ * Get the raw contents of the frame
+ * @todo This is untested, make sure the substr is right - trying to return the frame w/o the overflow
+ */
+ public function getContents() {
+ return substr($this->data, 0, $this->getPayloadStartingByte() + $this->getPayloadLength());
+ }
+
+ public function __toString() {
+ $payload = (string)substr($this->data, $this->getPayloadStartingByte(), $this->getPayloadLength());
+
+ if ($this->isMasked()) {
+ $payload = $this->applyMask($this->getMaskingKey(), $payload);
+ }
+
+ return $payload;
+ }
+
+ /**
+ * Sometimes clients will concatenate more than one frame over the wire
+ * This method will take the extra bytes off the end and return them
+ * @return string
+ */
+ public function extractOverflow() {
+ if ($this->isCoalesced()) {
+ $endPoint = $this->getPayloadLength();
+ $endPoint += $this->getPayloadStartingByte();
+
+ if ($this->bytesRecvd > $endPoint) {
+ $overflow = substr($this->data, $endPoint);
+ $this->data = substr($this->data, 0, $endPoint);
+
+ return $overflow;
+ }
+ }
+
+ return '';
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Messaging/FrameInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Messaging/FrameInterface.php
new file mode 100644
index 0000000..dc24091
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Messaging/FrameInterface.php
@@ -0,0 +1,38 @@
+<?php
+namespace Ratchet\RFC6455\Messaging;
+
+interface FrameInterface extends DataInterface {
+ /**
+ * Add incoming data to the frame from peer
+ * @param string
+ */
+ function addBuffer($buf);
+
+ /**
+ * Is this the final frame in a fragmented message?
+ * @return bool
+ */
+ function isFinal();
+
+ /**
+ * Is the payload masked?
+ * @return bool
+ */
+ function isMasked();
+
+ /**
+ * @return int
+ */
+ function getOpcode();
+
+ /**
+ * @return int
+ */
+ //function getReceivedPayloadLength();
+
+ /**
+ * 32-big string
+ * @return string
+ */
+ function getMaskingKey();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Messaging/Message.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Messaging/Message.php
new file mode 100644
index 0000000..4f3b014
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Messaging/Message.php
@@ -0,0 +1,123 @@
+<?php
+namespace Ratchet\RFC6455\Messaging;
+
+class Message implements \IteratorAggregate, MessageInterface {
+ /**
+ * @var \SplDoublyLinkedList
+ */
+ private $_frames;
+
+ public function __construct() {
+ $this->_frames = new \SplDoublyLinkedList;
+ }
+
+ public function getIterator() {
+ return $this->_frames;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function count() {
+ return count($this->_frames);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isCoalesced() {
+ if (count($this->_frames) == 0) {
+ return false;
+ }
+
+ $last = $this->_frames->top();
+
+ return ($last->isCoalesced() && $last->isFinal());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addFrame(FrameInterface $fragment) {
+ $this->_frames->push($fragment);
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getOpcode() {
+ if (count($this->_frames) == 0) {
+ throw new \UnderflowException('No frames have been added to this message');
+ }
+
+ return $this->_frames->bottom()->getOpcode();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getPayloadLength() {
+ $len = 0;
+
+ foreach ($this->_frames as $frame) {
+ try {
+ $len += $frame->getPayloadLength();
+ } catch (\UnderflowException $e) {
+ // Not an error, want the current amount buffered
+ }
+ }
+
+ return $len;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getPayload() {
+ if (!$this->isCoalesced()) {
+ throw new \UnderflowException('Message has not been put back together yet');
+ }
+
+ return $this->__toString();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getContents() {
+ if (!$this->isCoalesced()) {
+ throw new \UnderflowException("Message has not been put back together yet");
+ }
+
+ $buffer = '';
+
+ foreach ($this->_frames as $frame) {
+ $buffer .= $frame->getContents();
+ }
+
+ return $buffer;
+ }
+
+ public function __toString() {
+ $buffer = '';
+
+ foreach ($this->_frames as $frame) {
+ $buffer .= $frame->getPayload();
+ }
+
+ return $buffer;
+ }
+
+ /**
+ * @return boolean
+ */
+ public function isBinary() {
+ if ($this->_frames->isEmpty()) {
+ throw new \UnderflowException('Not enough data has been received to determine if message is binary');
+ }
+
+ return Frame::OP_BINARY === $this->_frames->bottom()->getOpcode();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Messaging/MessageBuffer.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Messaging/MessageBuffer.php
new file mode 100644
index 0000000..07ff4f1
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Messaging/MessageBuffer.php
@@ -0,0 +1,231 @@
+<?php
+namespace Ratchet\RFC6455\Messaging;
+
+class MessageBuffer {
+ /**
+ * @var \Ratchet\RFC6455\Messaging\CloseFrameChecker
+ */
+ private $closeFrameChecker;
+
+ /**
+ * @var callable
+ */
+ private $exceptionFactory;
+
+ /**
+ * @var \Ratchet\RFC6455\Messaging\Message
+ */
+ private $messageBuffer;
+
+ /**
+ * @var \Ratchet\RFC6455\Messaging\Frame
+ */
+ private $frameBuffer;
+
+ /**
+ * @var callable
+ */
+ private $onMessage;
+
+ /**
+ * @var callable
+ */
+ private $onControl;
+
+ /**
+ * @var bool
+ */
+ private $checkForMask;
+
+ function __construct(
+ CloseFrameChecker $frameChecker,
+ callable $onMessage,
+ callable $onControl = null,
+ $expectMask = true,
+ $exceptionFactory = null
+ ) {
+ $this->closeFrameChecker = $frameChecker;
+ $this->checkForMask = (bool)$expectMask;
+
+ $this->exceptionFactory ?: $this->exceptionFactory = function($msg) {
+ return new \UnderflowException($msg);
+ };
+
+ $this->onMessage = $onMessage;
+ $this->onControl = $onControl ?: function() {};
+ }
+
+ public function onData($data) {
+ while (strlen($data) > 0) {
+ $data = $this->processData($data);
+ }
+ }
+
+ /**
+ * @param string $data
+ * @return null
+ */
+ private function processData($data) {
+ $this->messageBuffer ?: $this->messageBuffer = $this->newMessage();
+ $this->frameBuffer ?: $this->frameBuffer = $this->newFrame();
+
+ $this->frameBuffer->addBuffer($data);
+ if (!$this->frameBuffer->isCoalesced()) {
+ return '';
+ }
+
+ $onMessage = $this->onMessage;
+ $onControl = $this->onControl;
+
+ $this->frameBuffer = $this->frameCheck($this->frameBuffer);
+
+ $overflow = $this->frameBuffer->extractOverflow();
+ $this->frameBuffer->unMaskPayload();
+
+ $opcode = $this->frameBuffer->getOpcode();
+
+ if ($opcode > 2) {
+ $onControl($this->frameBuffer);
+
+ if (Frame::OP_CLOSE === $opcode) {
+ return '';
+ }
+ } else {
+ $this->messageBuffer->addFrame($this->frameBuffer);
+ }
+
+ $this->frameBuffer = null;
+
+ if ($this->messageBuffer->isCoalesced()) {
+ $msgCheck = $this->checkMessage($this->messageBuffer);
+ if (true !== $msgCheck) {
+ $onControl($this->newCloseFrame($msgCheck, 'Ratchet detected an invalid UTF-8 payload'));
+ } else {
+ $onMessage($this->messageBuffer);
+ }
+
+ $this->messageBuffer = null;
+ }
+
+ return $overflow;
+ }
+
+ /**
+ * Check a frame to be added to the current message buffer
+ * @param \Ratchet\RFC6455\Messaging\FrameInterface|FrameInterface $frame
+ * @return \Ratchet\RFC6455\Messaging\FrameInterface|FrameInterface
+ */
+ public function frameCheck(FrameInterface $frame) {
+ if (false !== $frame->getRsv1() ||
+ false !== $frame->getRsv2() ||
+ false !== $frame->getRsv3()
+ ) {
+ return $this->newCloseFrame(Frame::CLOSE_PROTOCOL, 'Ratchet detected an invalid reserve code');
+ }
+
+ if ($this->checkForMask && !$frame->isMasked()) {
+ return $this->newCloseFrame(Frame::CLOSE_PROTOCOL, 'Ratchet detected an incorrect frame mask');
+ }
+
+ $opcode = $frame->getOpcode();
+
+ if ($opcode > 2) {
+ if ($frame->getPayloadLength() > 125 || !$frame->isFinal()) {
+ return $this->newCloseFrame(Frame::CLOSE_PROTOCOL, 'Ratchet detected a mismatch between final bit and indicated payload length');
+ }
+
+ switch ($opcode) {
+ case Frame::OP_CLOSE:
+ $closeCode = 0;
+
+ $bin = $frame->getPayload();
+
+ if (empty($bin)) {
+ return $this->newCloseFrame(Frame::CLOSE_NORMAL);
+ }
+
+ if (strlen($bin) === 1) {
+ return $this->newCloseFrame(Frame::CLOSE_PROTOCOL, 'Ratchet detected an invalid close code');
+ }
+
+ if (strlen($bin) >= 2) {
+ list($closeCode) = array_merge(unpack('n*', substr($bin, 0, 2)));
+ }
+
+ $checker = $this->closeFrameChecker;
+ if (!$checker($closeCode)) {
+ return $this->newCloseFrame(Frame::CLOSE_PROTOCOL, 'Ratchet detected an invalid close code');
+ }
+
+ if (!$this->checkUtf8(substr($bin, 2))) {
+ return $this->newCloseFrame(Frame::CLOSE_BAD_PAYLOAD, 'Ratchet detected an invalid UTF-8 payload in the close reason');
+ }
+
+ return $frame;
+ break;
+ case Frame::OP_PING:
+ case Frame::OP_PONG:
+ break;
+ default:
+ return $this->newCloseFrame(Frame::CLOSE_PROTOCOL, 'Ratchet detected an invalid OP code');
+ break;
+ }
+
+ return $frame;
+ }
+
+ if (Frame::OP_CONTINUE === $frame->getOpcode() && 0 === count($this->messageBuffer)) {
+ return $this->newCloseFrame(Frame::CLOSE_PROTOCOL, 'Ratchet detected the first frame of a message was a continue');
+ }
+
+ if (count($this->messageBuffer) > 0 && Frame::OP_CONTINUE !== $frame->getOpcode()) {
+ return $this->newCloseFrame(Frame::CLOSE_PROTOCOL, 'Ratchet detected invalid OP code when expecting continue frame');
+ }
+
+ return $frame;
+ }
+
+ /**
+ * Determine if a message is valid
+ * @param \Ratchet\RFC6455\Messaging\MessageInterface
+ * @return bool|int true if valid - false if incomplete - int of recommended close code
+ */
+ public function checkMessage(MessageInterface $message) {
+ if (!$message->isBinary()) {
+ if (!$this->checkUtf8($message->getPayload())) {
+ return Frame::CLOSE_BAD_PAYLOAD;
+ }
+ }
+
+ return true;
+ }
+
+ private function checkUtf8($string) {
+ if (extension_loaded('mbstring')) {
+ return mb_check_encoding($string, 'UTF-8');
+ }
+
+ return preg_match('//u', $string);
+ }
+
+ /**
+ * @return \Ratchet\RFC6455\Messaging\MessageInterface
+ */
+ public function newMessage() {
+ return new Message;
+ }
+
+ /**
+ * @param string|null $payload
+ * @param bool|null $final
+ * @param int|null $opcode
+ * @return \Ratchet\RFC6455\Messaging\FrameInterface
+ */
+ public function newFrame($payload = null, $final = null, $opcode = null) {
+ return new Frame($payload, $final, $opcode, $this->exceptionFactory);
+ }
+
+ public function newCloseFrame($code, $reason = '') {
+ return $this->newFrame(pack('n', $code) . $reason, true, Frame::OP_CLOSE);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Messaging/MessageInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Messaging/MessageInterface.php
new file mode 100644
index 0000000..fd7212e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/src/Messaging/MessageInterface.php
@@ -0,0 +1,20 @@
+<?php
+namespace Ratchet\RFC6455\Messaging;
+
+interface MessageInterface extends DataInterface, \Traversable, \Countable {
+ /**
+ * @param FrameInterface $fragment
+ * @return MessageInterface
+ */
+ function addFrame(FrameInterface $fragment);
+
+ /**
+ * @return int
+ */
+ function getOpcode();
+
+ /**
+ * @return bool
+ */
+ function isBinary();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/AbResultsTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/AbResultsTest.php
new file mode 100644
index 0000000..9bc502d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/AbResultsTest.php
@@ -0,0 +1,30 @@
+<?php
+namespace Ratchet\RFC6455\Test;
+
+class AbResultsTest extends \PHPUnit_Framework_TestCase {
+ private function verifyAutobahnResults($fileName) {
+ if (!file_exists($fileName)) {
+ return $this->markTestSkipped('Autobahn TestSuite results not found');
+ }
+
+ $resultsJson = file_get_contents($fileName);
+ $results = json_decode($resultsJson);
+ $agentName = array_keys(get_object_vars($results))[0];
+
+ foreach ($results->$agentName as $name => $result) {
+ if ($result->behavior === "INFORMATIONAL") {
+ continue;
+ }
+
+ $this->assertTrue(in_array($result->behavior, ["OK", "NON-STRICT"]), "Autobahn test case " . $name . " in " . $fileName);
+ }
+ }
+
+ public function testAutobahnClientResults() {
+ $this->verifyAutobahnResults(__DIR__ . '/ab/reports/clients/index.json');
+ }
+
+ public function testAutobahnServerResults() {
+ $this->verifyAutobahnResults(__DIR__ . '/ab/reports/servers/index.json');
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/ab/clientRunner.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/ab/clientRunner.php
new file mode 100644
index 0000000..0c5578a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/ab/clientRunner.php
@@ -0,0 +1,228 @@
+<?php
+use GuzzleHttp\Psr7\Uri;
+use React\Promise\Deferred;
+use Ratchet\RFC6455\Messaging\Frame;
+
+require __DIR__ . '/../bootstrap.php';
+
+define('AGENT', 'RatchetRFC/0.0.0');
+
+$testServer = "127.0.0.1";
+
+$loop = React\EventLoop\Factory::create();
+
+$dnsResolverFactory = new React\Dns\Resolver\Factory();
+$dnsResolver = $dnsResolverFactory->createCached('8.8.8.8', $loop);
+
+$factory = new \React\SocketClient\Connector($loop, $dnsResolver);
+
+function echoStreamerFactory($conn)
+{
+ return new \Ratchet\RFC6455\Messaging\MessageBuffer(
+ new \Ratchet\RFC6455\Messaging\CloseFrameChecker,
+ function (\Ratchet\RFC6455\Messaging\MessageInterface $msg) use ($conn) {
+ /** @var Frame $frame */
+ foreach ($msg as $frame) {
+ $frame->maskPayload();
+ }
+ $conn->write($msg->getContents());
+ },
+ function (\Ratchet\RFC6455\Messaging\FrameInterface $frame) use ($conn) {
+ switch ($frame->getOpcode()) {
+ case Frame::OP_PING:
+ return $conn->write((new Frame($frame->getPayload(), true, Frame::OP_PONG))->maskPayload()->getContents());
+ break;
+ case Frame::OP_CLOSE:
+ return $conn->end((new Frame($frame->getPayload(), true, Frame::OP_CLOSE))->maskPayload()->getContents());
+ break;
+ }
+ },
+ false
+ );
+}
+
+function getTestCases() {
+ global $factory;
+ global $testServer;
+
+ $deferred = new Deferred();
+
+ $factory->create($testServer, 9001)->then(function (\React\Stream\Stream $stream) use ($deferred) {
+ $cn = new \Ratchet\RFC6455\Handshake\ClientNegotiator();
+ $cnRequest = $cn->generateRequest(new Uri('ws://127.0.0.1:9001/getCaseCount'));
+
+ $rawResponse = "";
+ $response = null;
+
+ /** @var \Ratchet\RFC6455\Messaging\Streaming\MessageBuffer $ms */
+ $ms = null;
+
+ $stream->on('data', function ($data) use ($stream, &$rawResponse, &$response, &$ms, $cn, $deferred, &$context, $cnRequest) {
+ if ($response === null) {
+ $rawResponse .= $data;
+ $pos = strpos($rawResponse, "\r\n\r\n");
+ if ($pos) {
+ $data = substr($rawResponse, $pos + 4);
+ $rawResponse = substr($rawResponse, 0, $pos + 4);
+ $response = \GuzzleHttp\Psr7\parse_response($rawResponse);
+
+ if (!$cn->validateResponse($cnRequest, $response)) {
+ $stream->end();
+ $deferred->reject();
+ } else {
+ $ms = new \Ratchet\RFC6455\Messaging\MessageBuffer(
+ new \Ratchet\RFC6455\Messaging\CloseFrameChecker,
+ function (\Ratchet\RFC6455\Messaging\MessageInterface $msg) use ($deferred, $stream) {
+ $deferred->resolve($msg->getPayload());
+ $stream->close();
+ },
+ null,
+ false
+ );
+ }
+ }
+ }
+
+ // feed the message streamer
+ if ($ms) {
+ $ms->onData($data);
+ }
+ });
+
+ $stream->write(\GuzzleHttp\Psr7\str($cnRequest));
+ });
+
+ return $deferred->promise();
+}
+
+function runTest($case)
+{
+ global $factory;
+ global $testServer;
+
+ $casePath = "/runCase?case={$case}&agent=" . AGENT;
+
+ $deferred = new Deferred();
+
+ $factory->create($testServer, 9001)->then(function (\React\Stream\Stream $stream) use ($deferred, $casePath, $case) {
+ $cn = new \Ratchet\RFC6455\Handshake\ClientNegotiator();
+ $cnRequest = $cn->generateRequest(new Uri('ws://127.0.0.1:9001' . $casePath));
+
+ $rawResponse = "";
+ $response = null;
+
+ $ms = null;
+
+ $stream->on('data', function ($data) use ($stream, &$rawResponse, &$response, &$ms, $cn, $deferred, &$context, $cnRequest) {
+ if ($response === null) {
+ $rawResponse .= $data;
+ $pos = strpos($rawResponse, "\r\n\r\n");
+ if ($pos) {
+ $data = substr($rawResponse, $pos + 4);
+ $rawResponse = substr($rawResponse, 0, $pos + 4);
+ $response = \GuzzleHttp\Psr7\parse_response($rawResponse);
+
+ if (!$cn->validateResponse($cnRequest, $response)) {
+ $stream->end();
+ $deferred->reject();
+ } else {
+ $ms = echoStreamerFactory($stream);
+ }
+ }
+ }
+
+ // feed the message streamer
+ if ($ms) {
+ $ms->onData($data);
+ }
+ });
+
+ $stream->on('close', function () use ($deferred) {
+ $deferred->resolve();
+ });
+
+ $stream->write(\GuzzleHttp\Psr7\str($cnRequest));
+ });
+
+ return $deferred->promise();
+}
+
+function createReport() {
+ global $factory;
+ global $testServer;
+
+ $deferred = new Deferred();
+
+ $factory->create($testServer, 9001)->then(function (\React\Stream\Stream $stream) use ($deferred) {
+ $reportPath = "/updateReports?agent=" . AGENT . "&shutdownOnComplete=true";
+ $cn = new \Ratchet\RFC6455\Handshake\ClientNegotiator();
+ $cnRequest = $cn->generateRequest(new Uri('ws://127.0.0.1:9001' . $reportPath));
+
+ $rawResponse = "";
+ $response = null;
+
+ /** @var \Ratchet\RFC6455\Messaging\MessageBuffer $ms */
+ $ms = null;
+
+ $stream->on('data', function ($data) use ($stream, &$rawResponse, &$response, &$ms, $cn, $deferred, &$context, $cnRequest) {
+ if ($response === null) {
+ $rawResponse .= $data;
+ $pos = strpos($rawResponse, "\r\n\r\n");
+ if ($pos) {
+ $data = substr($rawResponse, $pos + 4);
+ $rawResponse = substr($rawResponse, 0, $pos + 4);
+ $response = \GuzzleHttp\Psr7\parse_response($rawResponse);
+
+ if (!$cn->validateResponse($cnRequest, $response)) {
+ $stream->end();
+ $deferred->reject();
+ } else {
+ $ms = new \Ratchet\RFC6455\Messaging\MessageBuffer(
+ new \Ratchet\RFC6455\Messaging\CloseFrameChecker,
+ function (\Ratchet\RFC6455\Messaging\MessageInterface $msg) use ($deferred, $stream) {
+ $deferred->resolve($msg->getPayload());
+ $stream->close();
+ },
+ null,
+ false
+ );
+ }
+ }
+ }
+
+ // feed the message streamer
+ if ($ms) {
+ $ms->onData($data);
+ }
+ });
+
+ $stream->write(\GuzzleHttp\Psr7\str($cnRequest));
+ });
+
+ return $deferred->promise();
+}
+
+
+$testPromises = [];
+
+getTestCases()->then(function ($count) use ($loop) {
+ $allDeferred = new Deferred();
+
+ $runNextCase = function () use (&$i, &$runNextCase, $count, $allDeferred) {
+ $i++;
+ if ($i > $count) {
+ $allDeferred->resolve();
+ return;
+ }
+ runTest($i)->then($runNextCase);
+ };
+
+ $i = 0;
+ $runNextCase();
+
+ $allDeferred->promise()->then(function () {
+ createReport();
+ });
+});
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/ab/fuzzingclient.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/ab/fuzzingclient.json
new file mode 100644
index 0000000..d2fd0d0
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/ab/fuzzingclient.json
@@ -0,0 +1,14 @@
+{
+ "options": {
+ "failByDrop": false
+ }
+ , "outdir": "./reports/servers"
+ , "servers": [{
+ "agent": "RatchetRFC/0.1.0"
+ , "url": "ws://localhost:9001"
+ , "options": {"version": 18}
+ }]
+ , "cases": ["*"]
+ , "exclude-cases": ["6.4.*", "12.*","13.*"]
+ , "exclude-agent-cases": {}
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/ab/fuzzingserver.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/ab/fuzzingserver.json
new file mode 100644
index 0000000..0422560
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/ab/fuzzingserver.json
@@ -0,0 +1,10 @@
+{
+ "url": "ws://127.0.0.1:9001"
+ , "options": {
+ "failByDrop": false
+ }
+ , "outdir": "./reports/clients"
+ , "cases": ["*"]
+ , "exclude-cases": ["6.4.*", "12.*", "13.*"]
+ , "exclude-agent-cases": {}
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/ab/run_ab_tests.sh b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/ab/run_ab_tests.sh
new file mode 100644
index 0000000..8fa9ced
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/ab/run_ab_tests.sh
@@ -0,0 +1,11 @@
+cd tests/ab
+
+wstest -m fuzzingserver -s fuzzingserver.json &
+sleep 5
+php clientRunner.php
+
+sleep 2
+
+php startServer.php &
+sleep 3
+wstest -m fuzzingclient -s fuzzingclient.json
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/ab/startServer.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/ab/startServer.php
new file mode 100644
index 0000000..b256ec2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/ab/startServer.php
@@ -0,0 +1,55 @@
+<?php
+use Ratchet\RFC6455\Messaging\MessageInterface;
+use Ratchet\RFC6455\Messaging\FrameInterface;
+use Ratchet\RFC6455\Messaging\Frame;
+
+require_once __DIR__ . "/../bootstrap.php";
+
+$loop = \React\EventLoop\Factory::create();
+
+$socket = new \React\Socket\Server($loop);
+$server = new \React\Http\Server($socket);
+
+$closeFrameChecker = new \Ratchet\RFC6455\Messaging\CloseFrameChecker;
+$negotiator = new \Ratchet\RFC6455\Handshake\ServerNegotiator(new \Ratchet\RFC6455\Handshake\RequestVerifier);
+
+$uException = new \UnderflowException;
+
+$server->on('request', function (\React\Http\Request $request, \React\Http\Response $response) use ($negotiator, $closeFrameChecker, $uException) {
+ $psrRequest = new \GuzzleHttp\Psr7\Request($request->getMethod(), $request->getPath(), $request->getHeaders());
+
+ $negotiatorResponse = $negotiator->handshake($psrRequest);
+
+ $response->writeHead(
+ $negotiatorResponse->getStatusCode(),
+ array_merge(
+ $negotiatorResponse->getHeaders(),
+ ["Content-Length" => "0"]
+ )
+ );
+
+ if ($negotiatorResponse->getStatusCode() !== 101) {
+ $response->end();
+ return;
+ }
+
+ $parser = new \Ratchet\RFC6455\Messaging\MessageBuffer($closeFrameChecker, function(MessageInterface $message) use ($response) {
+ $response->write($message->getContents());
+ }, function(FrameInterface $frame) use ($response, &$parser) {
+ switch ($frame->getOpCode()) {
+ case Frame::OP_CLOSE:
+ $response->end($frame->getContents());
+ break;
+ case Frame::OP_PING:
+ $response->write($parser->newFrame($frame->getPayload(), true, Frame::OP_PONG)->getContents());
+ break;
+ }
+ }, true, function() use ($uException) {
+ return $uException;
+ });
+
+ $request->on('data', [$parser, 'onData']);
+});
+
+$socket->listen(9001, '0.0.0.0');
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/bootstrap.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/bootstrap.php
new file mode 100644
index 0000000..511b041
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/bootstrap.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * Find the auto loader file
+ */
+$files = [
+ __DIR__ . '/../vendor/autoload.php',
+ __DIR__ . '/../../vendor/autoload.php',
+ __DIR__ . '/../../../vendor/autoload.php',
+ __DIR__ . '/../../../../vendor/autoload.php',
+];
+
+foreach ($files as $file) {
+ if (file_exists($file)) {
+ $loader = require $file;
+ $loader->addPsr4('Ratchet\\RFC6455\\Test\\', __DIR__);
+ break;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/unit/Handshake/RequestVerifierTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/unit/Handshake/RequestVerifierTest.php
new file mode 100644
index 0000000..239de33
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/unit/Handshake/RequestVerifierTest.php
@@ -0,0 +1,177 @@
+<?php
+namespace Ratchet\RFC6455\Test\Unit\Handshake;
+use Ratchet\RFC6455\Handshake\RequestVerifier;
+
+/**
+ * @covers Ratchet\RFC6455\Handshake\RequestVerifier
+ */
+class RequestVerifierTest extends \PHPUnit_Framework_TestCase {
+ /**
+ * @var RequestVerifier
+ */
+ protected $_v;
+
+ public function setUp() {
+ $this->_v = new RequestVerifier();
+ }
+
+ public static function methodProvider() {
+ return array(
+ array(true, 'GET'),
+ array(true, 'get'),
+ array(true, 'Get'),
+ array(false, 'POST'),
+ array(false, 'DELETE'),
+ array(false, 'PUT'),
+ array(false, 'PATCH')
+ );
+ }
+ /**
+ * @dataProvider methodProvider
+ */
+ public function testMethodMustBeGet($result, $in) {
+ $this->assertEquals($result, $this->_v->verifyMethod($in));
+ }
+
+ public static function httpVersionProvider() {
+ return array(
+ array(true, 1.1),
+ array(true, '1.1'),
+ array(true, 1.2),
+ array(true, '1.2'),
+ array(true, 2),
+ array(true, '2'),
+ array(true, '2.0'),
+ array(false, '1.0'),
+ array(false, 1),
+ array(false, '0.9'),
+ array(false, ''),
+ array(false, 'hello')
+ );
+ }
+
+ /**
+ * @dataProvider httpVersionProvider
+ */
+ public function testHttpVersionIsAtLeast1Point1($expected, $in) {
+ $this->assertEquals($expected, $this->_v->verifyHTTPVersion($in));
+ }
+
+ public static function uRIProvider() {
+ return array(
+ array(true, '/chat'),
+ array(true, '/hello/world?key=val'),
+ array(false, '/chat#bad'),
+ array(false, 'nope'),
+ array(false, '/ ಠ_ಠ '),
+ array(false, '/✖')
+ );
+ }
+
+ /**
+ * @dataProvider URIProvider
+ */
+ public function testRequestUri($expected, $in) {
+ $this->assertEquals($expected, $this->_v->verifyRequestURI($in));
+ }
+
+ public static function hostProvider() {
+ return array(
+ array(true, ['server.example.com']),
+ array(false, [])
+ );
+ }
+
+ /**
+ * @dataProvider HostProvider
+ */
+ public function testVerifyHostIsSet($expected, $in) {
+ $this->assertEquals($expected, $this->_v->verifyHost($in));
+ }
+
+ public static function upgradeProvider() {
+ return array(
+ array(true, ['websocket']),
+ array(true, ['Websocket']),
+ array(true, ['webSocket']),
+ array(false, []),
+ array(false, [''])
+ );
+ }
+
+ /**
+ * @dataProvider upgradeProvider
+ */
+ public function testVerifyUpgradeIsWebSocket($expected, $val) {
+ $this->assertEquals($expected, $this->_v->verifyUpgradeRequest($val));
+ }
+
+ public static function connectionProvider() {
+ return array(
+ array(true, ['Upgrade']),
+ array(true, ['upgrade']),
+ array(true, ['keep-alive', 'Upgrade']),
+ array(true, ['Upgrade', 'keep-alive']),
+ array(true, ['keep-alive', 'Upgrade', 'something']),
+ // as seen in Firefox 47.0.1 - see https://github.com/ratchetphp/RFC6455/issues/14
+ array(true, ['keep-alive, Upgrade']),
+ array(true, ['Upgrade, keep-alive']),
+ array(true, ['keep-alive, Upgrade, something']),
+ array(true, ['keep-alive, Upgrade', 'something']),
+ array(false, ['']),
+ array(false, [])
+ );
+ }
+
+ /**
+ * @dataProvider connectionProvider
+ */
+ public function testConnectionHeaderVerification($expected, $val) {
+ $this->assertEquals($expected, $this->_v->verifyConnection($val));
+ }
+
+ public static function keyProvider() {
+ return array(
+ array(true, ['hkfa1L7uwN6DCo4IS3iWAw==']),
+ array(true, ['765vVoQpKSGJwPzJIMM2GA==']),
+ array(true, ['AQIDBAUGBwgJCgsMDQ4PEC==']),
+ array(true, ['axa2B/Yz2CdpfQAY2Q5P7w==']),
+ array(false, [0]),
+ array(false, ['Hello World']),
+ array(false, ['1234567890123456']),
+ array(false, ['123456789012345678901234']),
+ array(true, [base64_encode('UTF8allthngs+✓')]),
+ array(true, ['dGhlIHNhbXBsZSBub25jZQ==']),
+ array(false, []),
+ array(false, ['dGhlIHNhbXBsZSBub25jZQ==', 'Some other value']),
+ array(false, ['Some other value', 'dGhlIHNhbXBsZSBub25jZQ=='])
+ );
+ }
+
+ /**
+ * @dataProvider keyProvider
+ */
+ public function testKeyIsBase64Encoded16BitNonce($expected, $val) {
+ $this->assertEquals($expected, $this->_v->verifyKey($val));
+ }
+
+ public static function versionProvider() {
+ return array(
+ array(true, [13]),
+ array(true, ['13']),
+ array(false, [12]),
+ array(false, [14]),
+ array(false, ['14']),
+ array(false, ['hi']),
+ array(false, ['']),
+ array(false, [])
+ );
+ }
+
+ /**
+ * @dataProvider versionProvider
+ */
+ public function testVersionEquals13($expected, $in) {
+ $this->assertEquals($expected, $this->_v->verifyVersion($in));
+ }
+} \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/unit/Handshake/ResponseVerifierTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/unit/Handshake/ResponseVerifierTest.php
new file mode 100644
index 0000000..312930e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/unit/Handshake/ResponseVerifierTest.php
@@ -0,0 +1,34 @@
+<?php
+namespace Ratchet\RFC6455\Test\Unit\Handshake;
+use Ratchet\RFC6455\Handshake\ResponseVerifier;
+
+/**
+ * @covers Ratchet\RFC6455\Handshake\ResponseVerifier
+ */
+class ResponseVerifierTest extends \PHPUnit_Framework_TestCase {
+ /**
+ * @var ResponseVerifier
+ */
+ protected $_v;
+
+ public function setUp() {
+ $this->_v = new ResponseVerifier;
+ }
+
+ public static function subProtocolsProvider() {
+ return [
+ [true, ['a'], ['a']]
+ , [true, ['b', 'a'], ['c', 'd', 'a']]
+ , [false, ['a', 'b', 'c'], ['d']]
+ , [true, [], []]
+ , [true, ['a', 'b'], []]
+ ];
+ }
+
+ /**
+ * @dataProvider subProtocolsProvider
+ */
+ public function testVerifySubProtocol($expected, $response, $request) {
+ $this->assertEquals($expected, $this->_v->verifySubProtocol($response, $request));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/unit/Handshake/ServerNegotiatorTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/unit/Handshake/ServerNegotiatorTest.php
new file mode 100644
index 0000000..9c9aa8d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/unit/Handshake/ServerNegotiatorTest.php
@@ -0,0 +1,175 @@
+<?php
+
+namespace Ratchet\RFC6455\Test\Unit\Handshake;
+
+use Ratchet\RFC6455\Handshake\RequestVerifier;
+use Ratchet\RFC6455\Handshake\ServerNegotiator;
+
+class ServerNegotiatorTest extends \PHPUnit_Framework_TestCase
+{
+ public function testNoUpgradeRequested() {
+ $negotiator = new ServerNegotiator(new RequestVerifier());
+
+ $requestText = 'GET / HTTP/1.1
+Host: 127.0.0.1:6789
+Connection: keep-alive
+Pragma: no-cache
+Cache-Control: no-cache
+Upgrade-Insecure-Requests: 1
+User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
+Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
+Accept-Encoding: gzip, deflate, sdch, br
+Accept-Language: en-US,en;q=0.8';
+
+ $request = \GuzzleHttp\Psr7\parse_request($requestText);
+
+ $response = $negotiator->handshake($request);
+
+ $this->assertEquals('1.1', $response->getProtocolVersion());
+ $this->assertEquals(426, $response->getStatusCode());
+ $this->assertEquals('Upgrade header MUST be provided', $response->getReasonPhrase());
+ $this->assertEquals('Upgrade', $response->getHeaderLine('Connection'));
+ $this->assertEquals('websocket', $response->getHeaderLine('Upgrade'));
+ $this->assertEquals('13', $response->getHeaderLine('Sec-WebSocket-Version'));
+ }
+
+ public function testNoConnectionUpgradeRequested() {
+ $negotiator = new ServerNegotiator(new RequestVerifier());
+
+ $requestText = 'GET / HTTP/1.1
+Host: 127.0.0.1:6789
+Connection: keep-alive
+Pragma: no-cache
+Cache-Control: no-cache
+Upgrade: websocket
+Upgrade-Insecure-Requests: 1
+User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
+Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
+Accept-Encoding: gzip, deflate, sdch, br
+Accept-Language: en-US,en;q=0.8';
+
+ $request = \GuzzleHttp\Psr7\parse_request($requestText);
+
+ $response = $negotiator->handshake($request);
+
+ $this->assertEquals('1.1', $response->getProtocolVersion());
+ $this->assertEquals(400, $response->getStatusCode());
+ $this->assertEquals('Connection Upgrade MUST be requested', $response->getReasonPhrase());
+ }
+
+ public function testInvalidSecWebsocketKey() {
+ $negotiator = new ServerNegotiator(new RequestVerifier());
+
+ $requestText = 'GET / HTTP/1.1
+Host: 127.0.0.1:6789
+Connection: Upgrade
+Pragma: no-cache
+Cache-Control: no-cache
+Upgrade: websocket
+Sec-WebSocket-Key: 12345
+Upgrade-Insecure-Requests: 1
+User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
+Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
+Accept-Encoding: gzip, deflate, sdch, br
+Accept-Language: en-US,en;q=0.8';
+
+ $request = \GuzzleHttp\Psr7\parse_request($requestText);
+
+ $response = $negotiator->handshake($request);
+
+ $this->assertEquals('1.1', $response->getProtocolVersion());
+ $this->assertEquals(400, $response->getStatusCode());
+ $this->assertEquals('Invalid Sec-WebSocket-Key', $response->getReasonPhrase());
+ }
+
+ public function testInvalidSecWebsocketVersion() {
+ $negotiator = new ServerNegotiator(new RequestVerifier());
+
+ $requestText = 'GET / HTTP/1.1
+Host: 127.0.0.1:6789
+Connection: Upgrade
+Pragma: no-cache
+Cache-Control: no-cache
+Upgrade: websocket
+Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
+Upgrade-Insecure-Requests: 1
+User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
+Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
+Accept-Encoding: gzip, deflate, sdch, br
+Accept-Language: en-US,en;q=0.8';
+
+ $request = \GuzzleHttp\Psr7\parse_request($requestText);
+
+ $response = $negotiator->handshake($request);
+
+ $this->assertEquals('1.1', $response->getProtocolVersion());
+ $this->assertEquals(426, $response->getStatusCode());
+ $this->assertEquals('Upgrade Required', $response->getReasonPhrase());
+ $this->assertEquals('Upgrade', $response->getHeaderLine('Connection'));
+ $this->assertEquals('websocket', $response->getHeaderLine('Upgrade'));
+ $this->assertEquals('13', $response->getHeaderLine('Sec-WebSocket-Version'));
+ }
+
+ public function testBadSubprotocolResponse() {
+ $negotiator = new ServerNegotiator(new RequestVerifier());
+ $negotiator->setStrictSubProtocolCheck(true);
+ $negotiator->setSupportedSubProtocols([]);
+
+ $requestText = 'GET / HTTP/1.1
+Host: 127.0.0.1:6789
+Connection: Upgrade
+Pragma: no-cache
+Cache-Control: no-cache
+Upgrade: websocket
+Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
+Sec-WebSocket-Version: 13
+Sec-WebSocket-Protocol: someprotocol
+Upgrade-Insecure-Requests: 1
+User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
+Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
+Accept-Encoding: gzip, deflate, sdch, br
+Accept-Language: en-US,en;q=0.8';
+
+ $request = \GuzzleHttp\Psr7\parse_request($requestText);
+
+ $response = $negotiator->handshake($request);
+
+ $this->assertEquals('1.1', $response->getProtocolVersion());
+ $this->assertEquals(426, $response->getStatusCode());
+ $this->assertEquals('No Sec-WebSocket-Protocols requested supported', $response->getReasonPhrase());
+ $this->assertEquals('Upgrade', $response->getHeaderLine('Connection'));
+ $this->assertEquals('websocket', $response->getHeaderLine('Upgrade'));
+ $this->assertEquals('13', $response->getHeaderLine('Sec-WebSocket-Version'));
+ }
+
+ public function testNonStrictSubprotocolDoesNotIncludeHeaderWhenNoneAgreedOn() {
+ $negotiator = new ServerNegotiator(new RequestVerifier());
+ $negotiator->setStrictSubProtocolCheck(false);
+ $negotiator->setSupportedSubProtocols(['someproto']);
+
+ $requestText = 'GET / HTTP/1.1
+Host: 127.0.0.1:6789
+Connection: Upgrade
+Pragma: no-cache
+Cache-Control: no-cache
+Upgrade: websocket
+Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
+Sec-WebSocket-Version: 13
+Sec-WebSocket-Protocol: someotherproto
+Upgrade-Insecure-Requests: 1
+User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
+Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
+Accept-Encoding: gzip, deflate, sdch, br
+Accept-Language: en-US,en;q=0.8';
+
+ $request = \GuzzleHttp\Psr7\parse_request($requestText);
+
+ $response = $negotiator->handshake($request);
+
+ $this->assertEquals('1.1', $response->getProtocolVersion());
+ $this->assertEquals(101, $response->getStatusCode());
+ $this->assertEquals('Upgrade', $response->getHeaderLine('Connection'));
+ $this->assertEquals('websocket', $response->getHeaderLine('Upgrade'));
+ $this->assertFalse($response->hasHeader('Sec-WebSocket-Protocol'));
+ }
+} \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/unit/Messaging/FrameTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/unit/Messaging/FrameTest.php
new file mode 100644
index 0000000..b73f600
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/unit/Messaging/FrameTest.php
@@ -0,0 +1,501 @@
+<?php
+namespace Ratchet\RFC6455\Test\Unit\Messaging;
+use Ratchet\RFC6455\Messaging\Frame;
+
+/**
+ * @covers Ratchet\RFC6455\Messaging\Frame
+ * @todo getMaskingKey, getPayloadStartingByte don't have tests yet
+ * @todo Could use some clean up in general, I had to rush to fix a bug for a deadline, sorry.
+ */
+class FrameTest extends \PHPUnit_Framework_TestCase {
+ protected $_firstByteFinText = '10000001';
+
+ protected $_secondByteMaskedSPL = '11111101';
+
+ /** @var Frame */
+ protected $_frame;
+
+ protected $_packer;
+
+ public function setUp() {
+ $this->_frame = new Frame;
+ }
+
+ /**
+ * Encode the fake binary string to send over the wire
+ * @param string of 1's and 0's
+ * @return string
+ */
+ public static function encode($in) {
+ if (strlen($in) > 8) {
+ $out = '';
+ while (strlen($in) >= 8) {
+ $out .= static::encode(substr($in, 0, 8));
+ $in = substr($in, 8);
+ }
+ return $out;
+ }
+ return chr(bindec($in));
+ }
+
+ /**
+ * This is a data provider
+ * param string The UTF8 message
+ * param string The WebSocket framed message, then base64_encoded
+ */
+ public static function UnframeMessageProvider() {
+ return array(
+ array('Hello World!', 'gYydAIfa1WXrtvIg0LXvbOP7'),
+ array('!@#$%^&*()-=_+[]{}\|/.,<>`~', 'gZv+h96r38f9j9vZ+IHWrvOWoayF9oX6gtfRqfKXwOeg'),
+ array('ಠ_ಠ', 'gYfnSpu5B/g75gf4Ow=='),
+ array(
+ "The quick brown fox jumps over the lazy dog. All work and no play makes Chris a dull boy. I'm trying to get past 128 characters for a unit test here...",
+ 'gf4Amahb14P8M7Kj2S6+4MN7tfHHLLmjzjSvo8IuuvPbe7j1zSn398A+9+/JIa6jzDSwrYh7lu/Ee6Ds2jD34sY/9+3He6fvySL37skwsvCIGL/xwSj34og/ou/Ee7Xs0XX3o+F8uqPcKa7qxjz398d7sObce6fi2y/3sppj9+DAOqXiyy+y8dt7sezae7aj3TW+94gvsvDce7/m2j75rYY='
+ )
+ );
+ }
+
+ public static function underflowProvider() {
+ return array(
+ array('isFinal', ''),
+ array('getRsv1', ''),
+ array('getRsv2', ''),
+ array('getRsv3', ''),
+ array('getOpcode', ''),
+ array('isMasked', '10000001'),
+ array('getPayloadLength', '10000001'),
+ array('getPayloadLength', '1000000111111110'),
+ array('getMaskingKey', '1000000110000111'),
+ array('getPayload', '100000011000000100011100101010101001100111110100')
+ );
+ }
+
+ /**
+ * @dataProvider underflowProvider
+ *
+ * @covers Ratchet\RFC6455\Messaging\Frame::isFinal
+ * @covers Ratchet\RFC6455\Messaging\Frame::getRsv1
+ * @covers Ratchet\RFC6455\Messaging\Frame::getRsv2
+ * @covers Ratchet\RFC6455\Messaging\Frame::getRsv3
+ * @covers Ratchet\RFC6455\Messaging\Frame::getOpcode
+ * @covers Ratchet\RFC6455\Messaging\Frame::isMasked
+ * @covers Ratchet\RFC6455\Messaging\Frame::getPayloadLength
+ * @covers Ratchet\RFC6455\Messaging\Frame::getMaskingKey
+ * @covers Ratchet\RFC6455\Messaging\Frame::getPayload
+ */
+ public function testUnderflowExceptionFromAllTheMethodsMimickingBuffering($method, $bin) {
+ $this->setExpectedException('\UnderflowException');
+ if (!empty($bin)) {
+ $this->_frame->addBuffer(static::encode($bin));
+ }
+ call_user_func(array($this->_frame, $method));
+ }
+
+ /**
+ * A data provider for testing the first byte of a WebSocket frame
+ * param bool Given, is the byte indicate this is the final frame
+ * param int Given, what is the expected opcode
+ * param string of 0|1 Each character represents a bit in the byte
+ */
+ public static function firstByteProvider() {
+ return array(
+ array(false, false, false, true, 8, '00011000'),
+ array(true, false, true, false, 10, '10101010'),
+ array(false, false, false, false, 15, '00001111'),
+ array(true, false, false, false, 1, '10000001'),
+ array(true, true, true, true, 15, '11111111'),
+ array(true, true, false, false, 7, '11000111')
+ );
+ }
+
+ /**
+ * @dataProvider firstByteProvider
+ * covers Ratchet\RFC6455\Messaging\Frame::isFinal
+ */
+ public function testFinCodeFromBits($fin, $rsv1, $rsv2, $rsv3, $opcode, $bin) {
+ $this->_frame->addBuffer(static::encode($bin));
+ $this->assertEquals($fin, $this->_frame->isFinal());
+ }
+
+ /**
+ * @dataProvider firstByteProvider
+ * covers Ratchet\RFC6455\Messaging\Frame::getRsv1
+ * covers Ratchet\RFC6455\Messaging\Frame::getRsv2
+ * covers Ratchet\RFC6455\Messaging\Frame::getRsv3
+ */
+ public function testGetRsvFromBits($fin, $rsv1, $rsv2, $rsv3, $opcode, $bin) {
+ $this->_frame->addBuffer(static::encode($bin));
+ $this->assertEquals($rsv1, $this->_frame->getRsv1());
+ $this->assertEquals($rsv2, $this->_frame->getRsv2());
+ $this->assertEquals($rsv3, $this->_frame->getRsv3());
+ }
+
+ /**
+ * @dataProvider firstByteProvider
+ * covers Ratchet\RFC6455\Messaging\Frame::getOpcode
+ */
+ public function testOpcodeFromBits($fin, $rsv1, $rsv2, $rsv3, $opcode, $bin) {
+ $this->_frame->addBuffer(static::encode($bin));
+ $this->assertEquals($opcode, $this->_frame->getOpcode());
+ }
+
+ /**
+ * @dataProvider UnframeMessageProvider
+ * covers Ratchet\RFC6455\Messaging\Frame::isFinal
+ */
+ public function testFinCodeFromFullMessage($msg, $encoded) {
+ $this->_frame->addBuffer(base64_decode($encoded));
+ $this->assertTrue($this->_frame->isFinal());
+ }
+
+ /**
+ * @dataProvider UnframeMessageProvider
+ * covers Ratchet\RFC6455\Messaging\Frame::getOpcode
+ */
+ public function testOpcodeFromFullMessage($msg, $encoded) {
+ $this->_frame->addBuffer(base64_decode($encoded));
+ $this->assertEquals(1, $this->_frame->getOpcode());
+ }
+
+ public static function payloadLengthDescriptionProvider() {
+ return array(
+ array(7, '01110101'),
+ array(7, '01111101'),
+ array(23, '01111110'),
+ array(71, '01111111'),
+ array(7, '00000000'), // Should this throw an exception? Can a payload be empty?
+ array(7, '00000001')
+ );
+ }
+
+ /**
+ * @dataProvider payloadLengthDescriptionProvider
+ * covers Ratchet\RFC6455\Messaging\Frame::addBuffer
+ * covers Ratchet\RFC6455\Messaging\Frame::getFirstPayloadVal
+ */
+ public function testFirstPayloadDesignationValue($bits, $bin) {
+ $this->_frame->addBuffer(static::encode($this->_firstByteFinText));
+ $this->_frame->addBuffer(static::encode($bin));
+ $ref = new \ReflectionClass($this->_frame);
+ $cb = $ref->getMethod('getFirstPayloadVal');
+ $cb->setAccessible(true);
+ $this->assertEquals(bindec($bin), $cb->invoke($this->_frame));
+ }
+
+ /**
+ * covers Ratchet\RFC6455\Messaging\Frame::getFirstPayloadVal
+ */
+ public function testFirstPayloadValUnderflow() {
+ $ref = new \ReflectionClass($this->_frame);
+ $cb = $ref->getMethod('getFirstPayloadVal');
+ $cb->setAccessible(true);
+ $this->setExpectedException('UnderflowException');
+ $cb->invoke($this->_frame);
+ }
+
+ /**
+ * @dataProvider payloadLengthDescriptionProvider
+ * covers Ratchet\RFC6455\Messaging\Frame::getNumPayloadBits
+ */
+ public function testDetermineHowManyBitsAreUsedToDescribePayload($expected_bits, $bin) {
+ $this->_frame->addBuffer(static::encode($this->_firstByteFinText));
+ $this->_frame->addBuffer(static::encode($bin));
+ $ref = new \ReflectionClass($this->_frame);
+ $cb = $ref->getMethod('getNumPayloadBits');
+ $cb->setAccessible(true);
+ $this->assertEquals($expected_bits, $cb->invoke($this->_frame));
+ }
+
+ /**
+ * covers Ratchet\RFC6455\Messaging\Frame::getNumPayloadBits
+ */
+ public function testgetNumPayloadBitsUnderflow() {
+ $ref = new \ReflectionClass($this->_frame);
+ $cb = $ref->getMethod('getNumPayloadBits');
+ $cb->setAccessible(true);
+ $this->setExpectedException('UnderflowException');
+ $cb->invoke($this->_frame);
+ }
+
+ public function secondByteProvider() {
+ return array(
+ array(true, 1, '10000001'),
+ array(false, 1, '00000001'),
+ array(true, 125, $this->_secondByteMaskedSPL)
+ );
+ }
+ /**
+ * @dataProvider secondByteProvider
+ * covers Ratchet\RFC6455\Messaging\Frame::isMasked
+ */
+ public function testIsMaskedReturnsExpectedValue($masked, $payload_length, $bin) {
+ $this->_frame->addBuffer(static::encode($this->_firstByteFinText));
+ $this->_frame->addBuffer(static::encode($bin));
+ $this->assertEquals($masked, $this->_frame->isMasked());
+ }
+
+ /**
+ * @dataProvider UnframeMessageProvider
+ * covers Ratchet\RFC6455\Messaging\Frame::isMasked
+ */
+ public function testIsMaskedFromFullMessage($msg, $encoded) {
+ $this->_frame->addBuffer(base64_decode($encoded));
+ $this->assertTrue($this->_frame->isMasked());
+ }
+
+ /**
+ * @dataProvider secondByteProvider
+ * covers Ratchet\RFC6455\Messaging\Frame::getPayloadLength
+ */
+ public function testGetPayloadLengthWhenOnlyFirstFrameIsUsed($masked, $payload_length, $bin) {
+ $this->_frame->addBuffer(static::encode($this->_firstByteFinText));
+ $this->_frame->addBuffer(static::encode($bin));
+ $this->assertEquals($payload_length, $this->_frame->getPayloadLength());
+ }
+
+ /**
+ * @dataProvider UnframeMessageProvider
+ * covers Ratchet\RFC6455\Messaging\Frame::getPayloadLength
+ * @todo Not yet testing when second additional payload length descriptor
+ */
+ public function testGetPayloadLengthFromFullMessage($msg, $encoded) {
+ $this->_frame->addBuffer(base64_decode($encoded));
+ $this->assertEquals(strlen($msg), $this->_frame->getPayloadLength());
+ }
+
+ public function maskingKeyProvider() {
+ $frame = new Frame;
+ return array(
+ array($frame->generateMaskingKey()),
+ array($frame->generateMaskingKey()),
+ array($frame->generateMaskingKey())
+ );
+ }
+
+ /**
+ * @dataProvider maskingKeyProvider
+ * covers Ratchet\RFC6455\Messaging\Frame::getMaskingKey
+ * @todo I I wrote the dataProvider incorrectly, skipping for now
+ */
+ public function testGetMaskingKey($mask) {
+ $this->_frame->addBuffer(static::encode($this->_firstByteFinText));
+ $this->_frame->addBuffer(static::encode($this->_secondByteMaskedSPL));
+ $this->_frame->addBuffer($mask);
+ $this->assertEquals($mask, $this->_frame->getMaskingKey());
+ }
+
+ /**
+ * covers Ratchet\RFC6455\Messaging\Frame::getMaskingKey
+ */
+ public function testGetMaskingKeyOnUnmaskedPayload() {
+ $frame = new Frame('Hello World!');
+ $this->assertEquals('', $frame->getMaskingKey());
+ }
+
+ /**
+ * @dataProvider UnframeMessageProvider
+ * covers Ratchet\RFC6455\Messaging\Frame::getPayload
+ * @todo Move this test to bottom as it requires all methods of the class
+ */
+ public function testUnframeFullMessage($unframed, $base_framed) {
+ $this->_frame->addBuffer(base64_decode($base_framed));
+ $this->assertEquals($unframed, $this->_frame->getPayload());
+ }
+
+ public static function messageFragmentProvider() {
+ return array(
+ array(false, '', '', '', '', '')
+ );
+ }
+
+ /**
+ * @dataProvider UnframeMessageProvider
+ * covers Ratchet\RFC6455\Messaging\Frame::getPayload
+ */
+ public function testCheckPiecingTogetherMessage($msg, $encoded) {
+ $framed = base64_decode($encoded);
+ for ($i = 0, $len = strlen($framed);$i < $len; $i++) {
+ $this->_frame->addBuffer(substr($framed, $i, 1));
+ }
+ $this->assertEquals($msg, $this->_frame->getPayload());
+ }
+
+ /**
+ * covers Ratchet\RFC6455\Messaging\Frame::__construct
+ * covers Ratchet\RFC6455\Messaging\Frame::getPayloadLength
+ * covers Ratchet\RFC6455\Messaging\Frame::getPayload
+ */
+ public function testLongCreate() {
+ $len = 65525;
+ $pl = $this->generateRandomString($len);
+ $frame = new Frame($pl, true, Frame::OP_PING);
+ $this->assertTrue($frame->isFinal());
+ $this->assertEquals(Frame::OP_PING, $frame->getOpcode());
+ $this->assertFalse($frame->isMasked());
+ $this->assertEquals($len, $frame->getPayloadLength());
+ $this->assertEquals($pl, $frame->getPayload());
+ }
+
+ /**
+ * covers Ratchet\RFC6455\Messaging\Frame::__construct
+ * covers Ratchet\RFC6455\Messaging\Frame::getPayloadLength
+ */
+ public function testReallyLongCreate() {
+ $len = 65575;
+ $frame = new Frame($this->generateRandomString($len));
+ $this->assertEquals($len, $frame->getPayloadLength());
+ }
+ /**
+ * covers Ratchet\RFC6455\Messaging\Frame::__construct
+ * covers Ratchet\RFC6455\Messaging\Frame::extractOverflow
+ */
+ public function testExtractOverflow() {
+ $string1 = $this->generateRandomString();
+ $frame1 = new Frame($string1);
+ $string2 = $this->generateRandomString();
+ $frame2 = new Frame($string2);
+ $cat = new Frame;
+ $cat->addBuffer($frame1->getContents() . $frame2->getContents());
+ $this->assertEquals($frame1->getContents(), $cat->getContents());
+ $this->assertEquals($string1, $cat->getPayload());
+ $uncat = new Frame;
+ $uncat->addBuffer($cat->extractOverflow());
+ $this->assertEquals($string1, $cat->getPayload());
+ $this->assertEquals($string2, $uncat->getPayload());
+ }
+
+ /**
+ * covers Ratchet\RFC6455\Messaging\Frame::extractOverflow
+ */
+ public function testEmptyExtractOverflow() {
+ $string = $this->generateRandomString();
+ $frame = new Frame($string);
+ $this->assertEquals($string, $frame->getPayload());
+ $this->assertEquals('', $frame->extractOverflow());
+ $this->assertEquals($string, $frame->getPayload());
+ }
+
+ /**
+ * covers Ratchet\RFC6455\Messaging\Frame::getContents
+ */
+ public function testGetContents() {
+ $msg = 'The quick brown fox jumps over the lazy dog.';
+ $frame1 = new Frame($msg);
+ $frame2 = new Frame($msg);
+ $frame2->maskPayload();
+ $this->assertNotEquals($frame1->getContents(), $frame2->getContents());
+ $this->assertEquals(strlen($frame1->getContents()) + 4, strlen($frame2->getContents()));
+ }
+
+ /**
+ * covers Ratchet\RFC6455\Messaging\Frame::maskPayload
+ */
+ public function testMasking() {
+ $msg = 'The quick brown fox jumps over the lazy dog.';
+ $frame = new Frame($msg);
+ $frame->maskPayload();
+ $this->assertTrue($frame->isMasked());
+ $this->assertEquals($msg, $frame->getPayload());
+ }
+
+ /**
+ * covers Ratchet\RFC6455\Messaging\Frame::unMaskPayload
+ */
+ public function testUnMaskPayload() {
+ $string = $this->generateRandomString();
+ $frame = new Frame($string);
+ $frame->maskPayload()->unMaskPayload();
+ $this->assertFalse($frame->isMasked());
+ $this->assertEquals($string, $frame->getPayload());
+ }
+
+ /**
+ * covers Ratchet\RFC6455\Messaging\Frame::generateMaskingKey
+ */
+ public function testGenerateMaskingKey() {
+ $dupe = false;
+ $done = array();
+ for ($i = 0; $i < 10; $i++) {
+ $new = $this->_frame->generateMaskingKey();
+ if (in_array($new, $done)) {
+ $dupe = true;
+ }
+ $done[] = $new;
+ }
+ $this->assertEquals(4, strlen($new));
+ $this->assertFalse($dupe);
+ }
+
+ /**
+ * covers Ratchet\RFC6455\Messaging\Frame::maskPayload
+ */
+ public function testGivenMaskIsValid() {
+ $this->setExpectedException('InvalidArgumentException');
+ $this->_frame->maskPayload('hello world');
+ }
+
+ /**
+ * covers Ratchet\RFC6455\Messaging\Frame::maskPayload
+ */
+ public function testGivenMaskIsValidAscii() {
+ if (!extension_loaded('mbstring')) {
+ $this->markTestSkipped("mbstring required for this test");
+ return;
+ }
+ $this->setExpectedException('OutOfBoundsException');
+ $this->_frame->maskPayload('x✖');
+ }
+
+ protected function generateRandomString($length = 10, $addSpaces = true, $addNumbers = true) {
+ $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"$%&/()=[]{}'; // ยง
+ $useChars = array();
+ for($i = 0; $i < $length; $i++) {
+ $useChars[] = $characters[mt_rand(0, strlen($characters) - 1)];
+ }
+ if($addSpaces === true) {
+ array_push($useChars, ' ', ' ', ' ', ' ', ' ', ' ');
+ }
+ if($addNumbers === true) {
+ array_push($useChars, rand(0, 9), rand(0, 9), rand(0, 9));
+ }
+ shuffle($useChars);
+ $randomString = trim(implode('', $useChars));
+ $randomString = substr($randomString, 0, $length);
+ return $randomString;
+ }
+
+ /**
+ * There was a frame boundary issue when the first 3 bytes of a frame with a payload greater than
+ * 126 was added to the frame buffer and then Frame::getPayloadLength was called. It would cause the frame
+ * to set the payload length to 126 and then not recalculate it once the full length information was available.
+ *
+ * This is fixed by setting the defPayLen back to -1 before the underflow exception is thrown.
+ *
+ * covers Ratchet\RFC6455\Messaging\Frame::getPayloadLength
+ * covers Ratchet\RFC6455\Messaging\Frame::extractOverflow
+ */
+ public function testFrameDeliveredOneByteAtATime() {
+ $startHeader = "\x01\x7e\x01\x00"; // header for a text frame of 256 - non-final
+ $framePayload = str_repeat("*", 256);
+ $rawOverflow = "xyz";
+ $rawFrame = $startHeader . $framePayload . $rawOverflow;
+ $frame = new Frame();
+ $payloadLen = 256;
+ for ($i = 0; $i < strlen($rawFrame); $i++) {
+ $frame->addBuffer($rawFrame[$i]);
+ try {
+ // payloadLen will
+ $payloadLen = $frame->getPayloadLength();
+ } catch (\UnderflowException $e) {
+ if ($i > 2) { // we should get an underflow on 0,1,2
+ $this->fail("Underflow exception when the frame length should be available");
+ }
+ }
+ if ($payloadLen !== 256) {
+ $this->fail("Payload length of " . $payloadLen . " should have been 256.");
+ }
+ }
+ // make sure the overflow is good
+ $this->assertEquals($rawOverflow, $frame->extractOverflow());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/unit/Messaging/MessageBufferTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/unit/Messaging/MessageBufferTest.php
new file mode 100644
index 0000000..c33ff0c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/unit/Messaging/MessageBufferTest.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Ratchet\RFC6455\Test\Unit\Messaging;
+
+use Ratchet\RFC6455\Messaging\CloseFrameChecker;
+use Ratchet\RFC6455\Messaging\Frame;
+use Ratchet\RFC6455\Messaging\Message;
+use Ratchet\RFC6455\Messaging\MessageBuffer;
+
+class MessageBufferTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * This is to test that MessageBuffer can handle a large receive
+ * buffer with many many frames without blowing the stack (pre-v0.4 issue)
+ */
+ public function testProcessingLotsOfFramesInASingleChunk() {
+ $frame = new Frame('a', true, Frame::OP_TEXT);
+
+ $frameRaw = $frame->getContents();
+
+ $data = str_repeat($frameRaw, 1000);
+
+ $messageCount = 0;
+
+ $messageBuffer = new MessageBuffer(
+ new CloseFrameChecker(),
+ function (Message $message) use (&$messageCount) {
+ $messageCount++;
+ $this->assertEquals('a', $message->getPayload());
+ },
+ null,
+ false
+ );
+
+ $messageBuffer->onData($data);
+
+ $this->assertEquals(1000, $messageCount);
+ }
+} \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/unit/Messaging/MessageTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/unit/Messaging/MessageTest.php
new file mode 100644
index 0000000..1f7eab5
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/ratchet/rfc6455/tests/unit/Messaging/MessageTest.php
@@ -0,0 +1,58 @@
+<?php
+namespace Ratchet\RFC6455\Test\Unit\Messaging;
+use Ratchet\RFC6455\Messaging\Frame;
+use Ratchet\RFC6455\Messaging\Message;
+
+/**
+ * @covers Ratchet\RFC6455\Messaging\Message
+ */
+class MessageTest extends \PHPUnit_Framework_TestCase {
+ /** @var Message */
+ protected $message;
+
+ public function setUp() {
+ $this->message = new Message;
+ }
+
+ public function testNoFrames() {
+ $this->assertFalse($this->message->isCoalesced());
+ }
+
+ public function testNoFramesOpCode() {
+ $this->setExpectedException('UnderflowException');
+ $this->message->getOpCode();
+ }
+
+ public function testFragmentationPayload() {
+ $a = 'Hello ';
+ $b = 'World!';
+ $f1 = new Frame($a, false);
+ $f2 = new Frame($b, true, Frame::OP_CONTINUE);
+ $this->message->addFrame($f1)->addFrame($f2);
+ $this->assertEquals(strlen($a . $b), $this->message->getPayloadLength());
+ $this->assertEquals($a . $b, $this->message->getPayload());
+ }
+
+ public function testUnbufferedFragment() {
+ $this->message->addFrame(new Frame('The quick brow', false));
+ $this->setExpectedException('UnderflowException');
+ $this->message->getPayload();
+ }
+
+ public function testGetOpCode() {
+ $this->message
+ ->addFrame(new Frame('The quick brow', false, Frame::OP_TEXT))
+ ->addFrame(new Frame('n fox jumps ov', false, Frame::OP_CONTINUE))
+ ->addFrame(new Frame('er the lazy dog', true, Frame::OP_CONTINUE))
+ ;
+ $this->assertEquals(Frame::OP_TEXT, $this->message->getOpCode());
+ }
+
+ public function testGetUnBufferedPayloadLength() {
+ $this->message
+ ->addFrame(new Frame('The quick brow', false, Frame::OP_TEXT))
+ ->addFrame(new Frame('n fox jumps ov', false, Frame::OP_CONTINUE))
+ ;
+ $this->assertEquals(28, $this->message->getPayloadLength());
+ }
+} \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/.gitignore b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/.gitignore
new file mode 100644
index 0000000..987e2a2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/.gitignore
@@ -0,0 +1,2 @@
+composer.lock
+vendor
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/.travis.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/.travis.yml
new file mode 100644
index 0000000..290df75
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/.travis.yml
@@ -0,0 +1,25 @@
+language: php
+
+php:
+# - 5.3 # requires old distro, see below
+ - 5.4
+ - 5.5
+ - 5.6
+ - 7
+ - hhvm
+
+# lock distro so new future defaults will not break the build
+dist: trusty
+
+matrix:
+ include:
+ - php: 5.3
+ dist: precise
+
+sudo: false
+
+install:
+ - composer install --no-interaction
+
+script:
+ - ./vendor/bin/phpunit --coverage-text
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/CHANGELOG.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/CHANGELOG.md
new file mode 100644
index 0000000..19d1801
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/CHANGELOG.md
@@ -0,0 +1,35 @@
+# Changelog
+
+## 0.4.2 (2017-12-20)
+
+* Improve documentation with usage and installation instructions
+ (#10 by @clue)
+
+* Improve test suite by adding PHPUnit to `require-dev` and
+ add forward compatibility with PHPUnit 5 and PHPUnit 6 and
+ sanitize Composer autoload paths
+ (#14 by @shaunbramley and #12 and #18 by @clue)
+
+## 0.4.1 (2016-02-25)
+
+* Repository maintenance, split off from main repo, improve test suite and documentation
+* First class support for PHP7 and HHVM (#9 by @clue)
+* Adjust compatibility to 5.3 (#7 by @clue)
+
+## 0.4.0 (2014-02-02)
+
+* BC break: Bump minimum PHP version to PHP 5.4, remove 5.3 specific hacks
+* BC break: Update to React/Promise 2.0
+* Dependency: Autoloading and filesystem structure now PSR-4 instead of PSR-0
+
+## 0.3.2 (2013-05-10)
+
+* Version bump
+
+## 0.3.0 (2013-04-14)
+
+* Version bump
+
+## 0.2.6 (2012-12-26)
+
+* Feature: New cache component, used by DNS
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/LICENSE b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/LICENSE
new file mode 100644
index 0000000..a808108
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2012 Igor Wiedler, Chris Boden
+
+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.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/README.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/README.md
new file mode 100644
index 0000000..70ad40a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/README.md
@@ -0,0 +1,171 @@
+# Cache Component
+
+[![Build Status](https://secure.travis-ci.org/reactphp/cache.png?branch=master)](http://travis-ci.org/reactphp/cache) [![Code Climate](https://codeclimate.com/github/reactphp/cache/badges/gpa.svg)](https://codeclimate.com/github/reactphp/cache)
+
+Async, [Promise](https://github.com/reactphp/promise)-based cache interface
+for [ReactPHP](https://reactphp.org/).
+
+The cache component provides a
+[Promise](https://github.com/reactphp/promise)-based
+[`CacheInterface`](#cacheinterface) and an in-memory [`ArrayCache`](#arraycache)
+implementation of that.
+This allows consumers to type hint against the interface and third parties to
+provide alternate implementations.
+
+**Table of Contents**
+
+* [Usage](#usage)
+ * [CacheInterface](#cacheinterface)
+ * [get()](#get)
+ * [set()](#set)
+ * [remove()](#remove)
+ * [ArrayCache](#arraycache)
+* [Common usage](#common-usage)
+ * [Fallback get](#fallback-get)
+ * [Fallback-get-and-set](#fallback-get-and-set)
+* [Install](#install)
+* [Tests](#tests)
+* [License](#license)
+
+## Usage
+
+### CacheInterface
+
+The `CacheInterface` describes the main interface of this component.
+This allows consumers to type hint against the interface and third parties to
+provide alternate implementations.
+
+#### get()
+
+```php
+$cache
+ ->get('foo')
+ ->then('var_dump');
+```
+
+This example fetches the value of the key `foo` and passes it to the
+`var_dump` function. You can use any of the composition provided by
+[promises](https://github.com/reactphp/promise).
+
+If the key `foo` does not exist, the promise will be rejected.
+
+#### set()
+
+```php
+$cache->set('foo', 'bar');
+```
+
+This example eventually sets the value of the key `foo` to `bar`. If it
+already exists, it is overridden. No guarantees are made as to when the cache
+value is set. If the cache implementation has to go over the network to store
+it, it may take a while.
+
+#### remove()
+
+```php
+$cache->remove('foo');
+```
+
+This example eventually removes the key `foo` from the cache. As with `set`,
+this may not happen instantly.
+
+### ArrayCache
+
+The `ArrayCache` provides an in-memory implementation of the
+[`CacheInterface`](#cacheinterface).
+
+```php
+$cache = new ArrayCache();
+
+$cache->set('foo', 'bar');
+```
+
+## Common usage
+
+### Fallback get
+
+A common use case of caches is to attempt fetching a cached value and as a
+fallback retrieve it from the original data source if not found. Here is an
+example of that:
+
+```php
+$cache
+ ->get('foo')
+ ->then(null, 'getFooFromDb')
+ ->then('var_dump');
+```
+
+First an attempt is made to retrieve the value of `foo`. A promise rejection
+handler of the function `getFooFromDb` is registered. `getFooFromDb` is a
+function (can be any PHP callable) that will be called if the key does not
+exist in the cache.
+
+`getFooFromDb` can handle the missing key by returning a promise for the
+actual value from the database (or any other data source). As a result, this
+chain will correctly fall back, and provide the value in both cases.
+
+### Fallback get and set
+
+To expand on the fallback get example, often you want to set the value on the
+cache after fetching it from the data source.
+
+```php
+$cache
+ ->get('foo')
+ ->then(null, array($this, 'getAndCacheFooFromDb'))
+ ->then('var_dump');
+
+public function getAndCacheFooFromDb()
+{
+ return $this->db
+ ->get('foo')
+ ->then(array($this, 'cacheFooFromDb'));
+}
+
+public function cacheFooFromDb($foo)
+{
+ $this->cache->set('foo', $foo);
+
+ return $foo;
+}
+```
+
+By using chaining you can easily conditionally cache the value if it is
+fetched from the database.
+
+## Install
+
+The recommended way to install this library is [through Composer](https://getcomposer.org).
+[New to Composer?](https://getcomposer.org/doc/00-intro.md)
+
+This will install the latest supported version:
+
+```bash
+$ composer require react/cache:^0.4.2
+```
+
+See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades.
+
+This project aims to run on any platform and thus does not require any PHP
+extensions and supports running on legacy PHP 5.3 through current PHP 7+ and
+HHVM.
+It's *highly recommended to use PHP 7+* for this project.
+
+## Tests
+
+To run the test suite, you first need to clone this repo and then install all
+dependencies [through Composer](https://getcomposer.org):
+
+```bash
+$ composer install
+```
+
+To run the test suite, go to the project root and run:
+
+```bash
+$ php vendor/bin/phpunit
+```
+
+## License
+
+MIT, see [LICENSE file](LICENSE).
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/composer.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/composer.json
new file mode 100644
index 0000000..51573b6
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/composer.json
@@ -0,0 +1,19 @@
+{
+ "name": "react/cache",
+ "description": "Async, Promise-based cache interface for ReactPHP",
+ "keywords": ["cache", "caching", "promise", "ReactPHP"],
+ "license": "MIT",
+ "require": {
+ "php": ">=5.3.0",
+ "react/promise": "~2.0|~1.1"
+ },
+ "autoload": {
+ "psr-4": { "React\\Cache\\": "src/" }
+ },
+ "autoload-dev": {
+ "psr-4": { "React\\Tests\\Cache\\": "tests/" }
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/phpunit.xml.dist b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/phpunit.xml.dist
new file mode 100644
index 0000000..d02182f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/phpunit.xml.dist
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit colors="true"
+ convertErrorsToExceptions="true"
+ convertNoticesToExceptions="true"
+ convertWarningsToExceptions="true"
+ bootstrap="vendor/autoload.php"
+>
+ <testsuites>
+ <testsuite name="React Test Suite">
+ <directory>./tests/</directory>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist>
+ <directory>./src/</directory>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/src/ArrayCache.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/src/ArrayCache.php
new file mode 100644
index 0000000..03dcc15
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/src/ArrayCache.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace React\Cache;
+
+use React\Promise;
+
+class ArrayCache implements CacheInterface
+{
+ private $data = array();
+
+ public function get($key)
+ {
+ if (!isset($this->data[$key])) {
+ return Promise\reject();
+ }
+
+ return Promise\resolve($this->data[$key]);
+ }
+
+ public function set($key, $value)
+ {
+ $this->data[$key] = $value;
+ }
+
+ public function remove($key)
+ {
+ unset($this->data[$key]);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/src/CacheInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/src/CacheInterface.php
new file mode 100644
index 0000000..fd5f2d5
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/src/CacheInterface.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace React\Cache;
+
+interface CacheInterface
+{
+ // @return React\Promise\PromiseInterface
+ public function get($key);
+
+ public function set($key, $value);
+
+ public function remove($key);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/tests/ArrayCacheTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/tests/ArrayCacheTest.php
new file mode 100644
index 0000000..eec3739
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/tests/ArrayCacheTest.php
@@ -0,0 +1,60 @@
+<?php
+
+namespace React\Tests\Cache;
+
+use React\Cache\ArrayCache;
+
+class ArrayCacheTest extends TestCase
+{
+ private $cache;
+
+ public function setUp()
+ {
+ $this->cache = new ArrayCache();
+ }
+
+ /** @test */
+ public function getShouldRejectPromiseForNonExistentKey()
+ {
+ $this->cache
+ ->get('foo')
+ ->then(
+ $this->expectCallableNever(),
+ $this->expectCallableOnce()
+ );
+ }
+
+ /** @test */
+ public function setShouldSetKey()
+ {
+ $this->cache
+ ->set('foo', 'bar');
+
+ $success = $this->createCallableMock();
+ $success
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with('bar');
+
+ $this->cache
+ ->get('foo')
+ ->then($success);
+ }
+
+ /** @test */
+ public function removeShouldRemoveKey()
+ {
+ $this->cache
+ ->set('foo', 'bar');
+
+ $this->cache
+ ->remove('foo');
+
+ $this->cache
+ ->get('foo')
+ ->then(
+ $this->expectCallableNever(),
+ $this->expectCallableOnce()
+ );
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/tests/CallableStub.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/tests/CallableStub.php
new file mode 100644
index 0000000..2f547cd
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/tests/CallableStub.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace React\Tests\Cache;
+
+class CallableStub
+{
+ public function __invoke()
+ {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/tests/TestCase.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/tests/TestCase.php
new file mode 100644
index 0000000..aa449f2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/cache/tests/TestCase.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace React\Tests\Cache;
+
+use PHPUnit\Framework\TestCase as BaseTestCase;
+
+class TestCase extends BaseTestCase
+{
+ protected function expectCallableExactly($amount)
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->exactly($amount))
+ ->method('__invoke');
+
+ return $mock;
+ }
+
+ protected function expectCallableOnce()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke');
+
+ return $mock;
+ }
+
+ protected function expectCallableNever()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->never())
+ ->method('__invoke');
+
+ return $mock;
+ }
+
+ protected function createCallableMock()
+ {
+ return $this->getMockBuilder('React\Tests\Cache\CallableStub')->getMock();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/.gitignore b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/.gitignore
new file mode 100644
index 0000000..19982ea
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/.gitignore
@@ -0,0 +1,2 @@
+composer.lock
+vendor \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/.travis.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/.travis.yml
new file mode 100644
index 0000000..41921e3
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/.travis.yml
@@ -0,0 +1,29 @@
+language: php
+
+php:
+# - 5.3 # requires old distro, see below
+ - 5.4
+ - 5.5
+ - 5.6
+ - 7.0
+ - 7.1
+ - 7.2
+ - hhvm # ignore errors, see below
+
+# lock distro so new future defaults will not break the build
+dist: trusty
+
+matrix:
+ include:
+ - php: 5.3
+ dist: precise
+ allow_failures:
+ - php: hhvm
+
+sudo: false
+
+install:
+ - composer install --no-interaction
+
+script:
+ - vendor/bin/phpunit --coverage-text
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/CHANGELOG.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/CHANGELOG.md
new file mode 100644
index 0000000..adad0a7
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/CHANGELOG.md
@@ -0,0 +1,179 @@
+# Changelog
+
+## 0.4.13 (2018-02-27)
+
+* Add `Config::loadSystemConfigBlocking()` to load default system config
+ and support parsing DNS config on all supported platforms
+ (`/etc/resolv.conf` on Unix/Linux/Mac and WMIC on Windows)
+ (#92, #93, #94 and #95 by @clue)
+
+ ```php
+ $config = Config::loadSystemConfigBlocking();
+ $server = $config->nameservers ? reset($config->nameservers) : '8.8.8.8';
+ ```
+
+* Remove unneeded cyclic dependency on react/socket
+ (#96 by @clue)
+
+## 0.4.12 (2018-01-14)
+
+* Improve test suite by adding forward compatibility with PHPUnit 6,
+ test against PHP 7.2, fix forward compatibility with upcoming EventLoop releases,
+ add test group to skip integration tests relying on internet connection
+ and add minor documentation improvements.
+ (#85 and #87 by @carusogabriel, #88 and #89 by @clue and #83 by @jsor)
+
+## 0.4.11 (2017-08-25)
+
+* Feature: Support resolving from default hosts file
+ (#75, #76 and #77 by @clue)
+
+ This means that resolving hosts such as `localhost` will now work as
+ expected across all platforms with no changes required:
+
+ ```php
+ $resolver->resolve('localhost')->then(function ($ip) {
+ echo 'IP: ' . $ip;
+ });
+ ```
+
+ The new `HostsExecutor` exists for advanced usage and is otherwise used
+ internally for this feature.
+
+## 0.4.10 (2017-08-10)
+
+* Feature: Forward compatibility with EventLoop v1.0 and v0.5 and
+ lock minimum dependencies and work around circular dependency for tests
+ (#70 and #71 by @clue)
+
+* Fix: Work around DNS timeout issues for Windows users
+ (#74 by @clue)
+
+* Documentation and examples for advanced usage
+ (#66 by @WyriHaximus)
+
+* Remove broken TCP code, do not retry with invalid TCP query
+ (#73 by @clue)
+
+* Improve test suite by fixing HHVM build for now again and ignore future HHVM build errors and
+ lock Travis distro so new defaults will not break the build and
+ fix failing tests for PHP 7.1
+ (#68 by @WyriHaximus and #69 and #72 by @clue)
+
+## 0.4.9 (2017-05-01)
+
+* Feature: Forward compatibility with upcoming Socket v1.0 and v0.8
+ (#61 by @clue)
+
+## 0.4.8 (2017-04-16)
+
+* Feature: Add support for the AAAA record type to the protocol parser
+ (#58 by @othillo)
+
+* Feature: Add support for the PTR record type to the protocol parser
+ (#59 by @othillo)
+
+## 0.4.7 (2017-03-31)
+
+* Feature: Forward compatibility with upcoming Socket v0.6 and v0.7 component
+ (#57 by @clue)
+
+## 0.4.6 (2017-03-11)
+
+* Fix: Fix DNS timeout issues for Windows users and add forward compatibility
+ with Stream v0.5 and upcoming v0.6
+ (#53 by @clue)
+
+* Improve test suite by adding PHPUnit to `require-dev`
+ (#54 by @clue)
+
+## 0.4.5 (2017-03-02)
+
+* Fix: Ensure we ignore the case of the answer
+ (#51 by @WyriHaximus)
+
+* Feature: Add `TimeoutExecutor` and simplify internal APIs to allow internal
+ code re-use for upcoming versions.
+ (#48 and #49 by @clue)
+
+## 0.4.4 (2017-02-13)
+
+* Fix: Fix handling connection and stream errors
+ (#45 by @clue)
+
+* Feature: Add examples and forward compatibility with upcoming Socket v0.5 component
+ (#46 and #47 by @clue)
+
+## 0.4.3 (2016-07-31)
+
+* Feature: Allow for cache adapter injection (#38 by @WyriHaximus)
+
+ ```php
+ $factory = new React\Dns\Resolver\Factory();
+
+ $cache = new MyCustomCacheInstance();
+ $resolver = $factory->createCached('8.8.8.8', $loop, $cache);
+ ```
+
+* Feature: Support Promise cancellation (#35 by @clue)
+
+ ```php
+ $promise = $resolver->resolve('reactphp.org');
+
+ $promise->cancel();
+ ```
+
+## 0.4.2 (2016-02-24)
+
+* Repository maintenance, split off from main repo, improve test suite and documentation
+* First class support for PHP7 and HHVM (#34 by @clue)
+* Adjust compatibility to 5.3 (#30 by @clue)
+
+## 0.4.1 (2014-04-13)
+
+* Bug fix: Fixed PSR-4 autoload path (@marcj/WyriHaximus)
+
+## 0.4.0 (2014-02-02)
+
+* BC break: Bump minimum PHP version to PHP 5.4, remove 5.3 specific hacks
+* BC break: Update to React/Promise 2.0
+* Bug fix: Properly resolve CNAME aliases
+* Dependency: Autoloading and filesystem structure now PSR-4 instead of PSR-0
+* Bump React dependencies to v0.4
+
+## 0.3.2 (2013-05-10)
+
+* Feature: Support default port for IPv6 addresses (@clue)
+
+## 0.3.0 (2013-04-14)
+
+* Bump React dependencies to v0.3
+
+## 0.2.6 (2012-12-26)
+
+* Feature: New cache component, used by DNS
+
+## 0.2.5 (2012-11-26)
+
+* Version bump
+
+## 0.2.4 (2012-11-18)
+
+* Feature: Change to promise-based API (@jsor)
+
+## 0.2.3 (2012-11-14)
+
+* Version bump
+
+## 0.2.2 (2012-10-28)
+
+* Feature: DNS executor timeout handling (@arnaud-lb)
+* Feature: DNS retry executor (@arnaud-lb)
+
+## 0.2.1 (2012-10-14)
+
+* Minor adjustments to DNS parser
+
+## 0.2.0 (2012-09-10)
+
+* Feature: DNS resolver
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/LICENSE b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/LICENSE
new file mode 100644
index 0000000..a808108
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2012 Igor Wiedler, Chris Boden
+
+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.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/README.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/README.md
new file mode 100644
index 0000000..ed86667
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/README.md
@@ -0,0 +1,209 @@
+# Dns
+
+[![Build Status](https://travis-ci.org/reactphp/dns.svg?branch=master)](https://travis-ci.org/reactphp/dns)
+
+Async DNS resolver for [ReactPHP](https://reactphp.org/).
+
+The main point of the DNS component is to provide async DNS resolution.
+However, it is really a toolkit for working with DNS messages, and could
+easily be used to create a DNS server.
+
+**Table of contents**
+
+* [Basic usage](#basic-usage)
+* [Caching](#caching)
+ * [Custom cache adapter](#custom-cache-adapter)
+* [Advanced usage](#advanced-usage)
+ * [HostsFileExecutor](#hostsfileexecutor)
+* [Install](#install)
+* [Tests](#tests)
+* [License](#license)
+* [References](#references)
+
+## Basic usage
+
+The most basic usage is to just create a resolver through the resolver
+factory. All you need to give it is a nameserver, then you can start resolving
+names, baby!
+
+```php
+$loop = React\EventLoop\Factory::create();
+
+$config = React\Dns\Config\Config::loadSystemConfigBlocking();
+$server = $config->nameservers ? reset($config->nameservers) : '8.8.8.8';
+
+$factory = new React\Dns\Resolver\Factory();
+$dns = $factory->create($server, $loop);
+
+$dns->resolve('igor.io')->then(function ($ip) {
+ echo "Host: $ip\n";
+});
+
+$loop->run();
+```
+
+See also the [first example](examples).
+
+The `Config` class can be used to load the system default config. This is an
+operation that may access the filesystem and block. Ideally, this method should
+thus be executed only once before the loop starts and not repeatedly while it is
+running.
+Note that this class may return an *empty* configuration if the system config
+can not be loaded. As such, you'll likely want to apply a default nameserver
+as above if none can be found.
+
+> Note that the factory loads the hosts file from the filesystem once when
+ creating the resolver instance.
+ Ideally, this method should thus be executed only once before the loop starts
+ and not repeatedly while it is running.
+
+Pending DNS queries can be cancelled by cancelling its pending promise like so:
+
+```php
+$promise = $resolver->resolve('reactphp.org');
+
+$promise->cancel();
+```
+
+But there's more.
+
+## Caching
+
+You can cache results by configuring the resolver to use a `CachedExecutor`:
+
+```php
+$loop = React\EventLoop\Factory::create();
+
+$config = React\Dns\Config\Config::loadSystemConfigBlocking();
+$server = $config->nameservers ? reset($config->nameservers) : '8.8.8.8';
+
+$factory = new React\Dns\Resolver\Factory();
+$dns = $factory->createCached($server, $loop);
+
+$dns->resolve('igor.io')->then(function ($ip) {
+ echo "Host: $ip\n";
+});
+
+...
+
+$dns->resolve('igor.io')->then(function ($ip) {
+ echo "Host: $ip\n";
+});
+
+$loop->run();
+```
+
+If the first call returns before the second, only one query will be executed.
+The second result will be served from an in memory cache.
+This is particularly useful for long running scripts where the same hostnames
+have to be looked up multiple times.
+
+See also the [third example](examples).
+
+### Custom cache adapter
+
+By default, the above will use an in memory cache.
+
+You can also specify a custom cache implementing [`CacheInterface`](https://github.com/reactphp/cache) to handle the record cache instead:
+
+```php
+$cache = new React\Cache\ArrayCache();
+$loop = React\EventLoop\Factory::create();
+$factory = new React\Dns\Resolver\Factory();
+$dns = $factory->createCached('8.8.8.8', $loop, $cache);
+```
+
+See also the wiki for possible [cache implementations](https://github.com/reactphp/react/wiki/Users#cache-implementations).
+
+## Advanced Usage
+
+For more advanced usages one can utilize the `React\Dns\Query\Executor` directly.
+The following example looks up the `IPv6` address for `igor.io`.
+
+```php
+$loop = Factory::create();
+
+$executor = new Executor($loop, new Parser(), new BinaryDumper(), null);
+
+$executor->query(
+ '8.8.8.8:53',
+ new Query($name, Message::TYPE_AAAA, Message::CLASS_IN, time())
+)->done(function (Message $message) {
+ foreach ($message->answers as $answer) {
+ echo 'IPv6: ' . $answer->data . PHP_EOL;
+ }
+}, 'printf');
+
+$loop->run();
+
+```
+
+See also the [fourth example](examples).
+
+### HostsFileExecutor
+
+Note that the above `Executor` class always performs an actual DNS query.
+If you also want to take entries from your hosts file into account, you may
+use this code:
+
+```php
+$hosts = \React\Dns\Config\HostsFile::loadFromPathBlocking();
+
+$executor = new Executor($loop, new Parser(), new BinaryDumper(), null);
+$executor = new HostsFileExecutor($hosts, $executor);
+
+$executor->query(
+ '8.8.8.8:53',
+ new Query('localhost', Message::TYPE_A, Message::CLASS_IN, time())
+);
+```
+
+## Install
+
+The recommended way to install this library is [through Composer](https://getcomposer.org).
+[New to Composer?](https://getcomposer.org/doc/00-intro.md)
+
+This will install the latest supported version:
+
+```bash
+$ composer require react/dns:^0.4.13
+```
+
+See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades.
+
+This project aims to run on any platform and thus does not require any PHP
+extensions and supports running on legacy PHP 5.3 through current PHP 7+ and
+HHVM.
+It's *highly recommended to use PHP 7+* for this project.
+
+## Tests
+
+To run the test suite, you first need to clone this repo and then install all
+dependencies [through Composer](https://getcomposer.org):
+
+```bash
+$ composer install
+```
+
+To run the test suite, go to the project root and run:
+
+```bash
+$ php vendor/bin/phpunit
+```
+
+The test suite also contains a number of functional integration tests that rely
+on a stable internet connection.
+If you do not want to run these, they can simply be skipped like this:
+
+```bash
+$ php vendor/bin/phpunit --exclude-group internet
+```
+
+## License
+
+MIT, see [LICENSE file](LICENSE).
+
+## References
+
+* [RFC 1034](https://tools.ietf.org/html/rfc1034) Domain Names - Concepts and Facilities
+* [RFC 1035](https://tools.ietf.org/html/rfc1035) Domain Names - Implementation and Specification
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/composer.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/composer.json
new file mode 100644
index 0000000..510a43c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/composer.json
@@ -0,0 +1,24 @@
+{
+ "name": "react/dns",
+ "description": "Async DNS resolver for ReactPHP",
+ "keywords": ["dns", "dns-resolver", "ReactPHP", "async"],
+ "license": "MIT",
+ "require": {
+ "php": ">=5.3.0",
+ "react/cache": "~0.4.0|~0.3.0",
+ "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5",
+ "react/promise": "^2.1 || ^1.2.1",
+ "react/promise-timer": "^1.2",
+ "react/stream": "^1.0 || ^0.7 || ^0.6 || ^0.5 || ^0.4.5"
+ },
+ "require-dev": {
+ "clue/block-react": "^1.2",
+ "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
+ },
+ "autoload": {
+ "psr-4": { "React\\Dns\\": "src" }
+ },
+ "autoload-dev": {
+ "psr-4": { "React\\Tests\\Dns\\": "tests" }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/examples/01-one.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/examples/01-one.php
new file mode 100644
index 0000000..5db164f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/examples/01-one.php
@@ -0,0 +1,22 @@
+<?php
+
+use React\Dns\Config\Config;
+use React\Dns\Resolver\Factory;
+
+require __DIR__ . '/../vendor/autoload.php';
+
+$loop = React\EventLoop\Factory::create();
+
+$config = Config::loadSystemConfigBlocking();
+$server = $config->nameservers ? reset($config->nameservers) : '8.8.8.8';
+
+$factory = new Factory();
+$resolver = $factory->create($server, $loop);
+
+$name = isset($argv[1]) ? $argv[1] : 'www.google.com';
+
+$resolver->resolve($name)->then(function ($ip) use ($name) {
+ echo 'IP for ' . $name . ': ' . $ip . PHP_EOL;
+}, 'printf');
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/examples/02-concurrent.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/examples/02-concurrent.php
new file mode 100644
index 0000000..87e3f5c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/examples/02-concurrent.php
@@ -0,0 +1,27 @@
+<?php
+
+use React\Dns\Config\Config;
+use React\Dns\Resolver\Factory;
+
+require __DIR__ . '/../vendor/autoload.php';
+
+$loop = React\EventLoop\Factory::create();
+
+$config = Config::loadSystemConfigBlocking();
+$server = $config->nameservers ? reset($config->nameservers) : '8.8.8.8';
+
+$factory = new Factory();
+$resolver = $factory->create($server, $loop);
+
+$names = array_slice($argv, 1);
+if (!$names) {
+ $names = array('google.com', 'www.google.com', 'gmail.com');
+}
+
+foreach ($names as $name) {
+ $resolver->resolve($name)->then(function ($ip) use ($name) {
+ echo 'IP for ' . $name . ': ' . $ip . PHP_EOL;
+ }, 'printf');
+}
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/examples/03-cached.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/examples/03-cached.php
new file mode 100644
index 0000000..e76a27c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/examples/03-cached.php
@@ -0,0 +1,40 @@
+<?php
+
+use React\Dns\Config\Config;
+use React\Dns\Resolver\Factory;
+
+require __DIR__ . '/../vendor/autoload.php';
+
+$loop = React\EventLoop\Factory::create();
+
+$config = Config::loadSystemConfigBlocking();
+$server = $config->nameservers ? reset($config->nameservers) : '8.8.8.8';
+
+$factory = new Factory();
+$resolver = $factory->createCached($server, $loop);
+
+$name = isset($argv[1]) ? $argv[1] : 'www.google.com';
+
+$resolver->resolve($name)->then(function ($ip) use ($name) {
+ echo 'IP for ' . $name . ': ' . $ip . PHP_EOL;
+}, 'printf');
+
+$loop->addTimer(1.0, function() use ($name, $resolver) {
+ $resolver->resolve($name)->then(function ($ip) use ($name) {
+ echo 'IP for ' . $name . ': ' . $ip . PHP_EOL;
+ }, 'printf');
+});
+
+$loop->addTimer(2.0, function() use ($name, $resolver) {
+ $resolver->resolve($name)->then(function ($ip) use ($name) {
+ echo 'IP for ' . $name . ': ' . $ip . PHP_EOL;
+ }, 'printf');
+});
+
+$loop->addTimer(3.0, function() use ($name, $resolver) {
+ $resolver->resolve($name)->then(function ($ip) use ($name) {
+ echo 'IP for ' . $name . ': ' . $ip . PHP_EOL;
+ }, 'printf');
+});
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/examples/04-query-a-and-aaaa.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/examples/04-query-a-and-aaaa.php
new file mode 100644
index 0000000..6c46bbf
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/examples/04-query-a-and-aaaa.php
@@ -0,0 +1,32 @@
+<?php
+
+use React\Dns\Model\Message;
+use React\Dns\Protocol\BinaryDumper;
+use React\Dns\Protocol\Parser;
+use React\Dns\Query\Executor;
+use React\Dns\Query\Query;
+use React\EventLoop\Factory;
+
+require __DIR__ . '/../vendor/autoload.php';
+
+$loop = Factory::create();
+
+$executor = new Executor($loop, new Parser(), new BinaryDumper(), null);
+
+$name = isset($argv[1]) ? $argv[1] : 'www.google.com';
+
+$ipv4Query = new Query($name, Message::TYPE_A, Message::CLASS_IN, time());
+$ipv6Query = new Query($name, Message::TYPE_AAAA, Message::CLASS_IN, time());
+
+$executor->query('8.8.8.8:53', $ipv4Query)->done(function (Message $message) {
+ foreach ($message->answers as $answer) {
+ echo 'IPv4: ' . $answer->data . PHP_EOL;
+ }
+}, 'printf');
+$executor->query('8.8.8.8:53', $ipv6Query)->done(function (Message $message) {
+ foreach ($message->answers as $answer) {
+ echo 'IPv6: ' . $answer->data . PHP_EOL;
+ }
+}, 'printf');
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/phpunit.xml.dist b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/phpunit.xml.dist
new file mode 100644
index 0000000..13d3fab
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/phpunit.xml.dist
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit backupGlobals="false"
+ backupStaticAttributes="false"
+ colors="true"
+ convertErrorsToExceptions="true"
+ convertNoticesToExceptions="true"
+ convertWarningsToExceptions="true"
+ processIsolation="false"
+ stopOnFailure="false"
+ syntaxCheck="false"
+ bootstrap="vendor/autoload.php"
+>
+ <testsuites>
+ <testsuite name="React Test Suite">
+ <directory>./tests/</directory>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist>
+ <directory>./src/</directory>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/BadServerException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/BadServerException.php
new file mode 100644
index 0000000..3bf50f1
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/BadServerException.php
@@ -0,0 +1,7 @@
+<?php
+
+namespace React\Dns;
+
+class BadServerException extends \Exception
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Config/Config.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Config/Config.php
new file mode 100644
index 0000000..c82635d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Config/Config.php
@@ -0,0 +1,127 @@
+<?php
+
+namespace React\Dns\Config;
+
+use RuntimeException;
+
+class Config
+{
+ /**
+ * Loads the system DNS configuration
+ *
+ * Note that this method may block while loading its internal files and/or
+ * commands and should thus be used with care! While this should be
+ * relatively fast for most systems, it remains unknown if this may block
+ * under certain circumstances. In particular, this method should only be
+ * executed before the loop starts, not while it is running.
+ *
+ * Note that this method will try to access its files and/or commands and
+ * try to parse its output. Currently, this will only parse valid nameserver
+ * entries from its output and will ignore all other output without
+ * complaining.
+ *
+ * Note that the previous section implies that this may return an empty
+ * `Config` object if no valid nameserver entries can be found.
+ *
+ * @return self
+ * @codeCoverageIgnore
+ */
+ public static function loadSystemConfigBlocking()
+ {
+ // Use WMIC output on Windows
+ if (DIRECTORY_SEPARATOR === '\\') {
+ return self::loadWmicBlocking();
+ }
+
+ // otherwise (try to) load from resolv.conf
+ try {
+ return self::loadResolvConfBlocking();
+ } catch (RuntimeException $ignored) {
+ // return empty config if parsing fails (file not found)
+ return new self();
+ }
+ }
+
+ /**
+ * Loads a resolv.conf file (from the given path or default location)
+ *
+ * Note that this method blocks while loading the given path and should
+ * thus be used with care! While this should be relatively fast for normal
+ * resolv.conf files, this may be an issue if this file is located on a slow
+ * device or contains an excessive number of entries. In particular, this
+ * method should only be executed before the loop starts, not while it is
+ * running.
+ *
+ * Note that this method will throw if the given file can not be loaded,
+ * such as if it is not readable or does not exist. In particular, this file
+ * is not available on Windows.
+ *
+ * Currently, this will only parse valid "nameserver X" lines from the
+ * given file contents. Lines can be commented out with "#" and ";" and
+ * invalid lines will be ignored without complaining. See also
+ * `man resolv.conf` for more details.
+ *
+ * Note that the previous section implies that this may return an empty
+ * `Config` object if no valid "nameserver X" lines can be found. See also
+ * `man resolv.conf` which suggests that the DNS server on the localhost
+ * should be used in this case. This is left up to higher level consumers
+ * of this API.
+ *
+ * @param ?string $path (optional) path to resolv.conf file or null=load default location
+ * @return self
+ * @throws RuntimeException if the path can not be loaded (does not exist)
+ */
+ public static function loadResolvConfBlocking($path = null)
+ {
+ if ($path === null) {
+ $path = '/etc/resolv.conf';
+ }
+
+ $contents = @file_get_contents($path);
+ if ($contents === false) {
+ throw new RuntimeException('Unable to load resolv.conf file "' . $path . '"');
+ }
+
+ preg_match_all('/^nameserver\s+(\S+)\s*$/m', $contents, $matches);
+
+ $config = new self();
+ $config->nameservers = $matches[1];
+
+ return $config;
+ }
+
+ /**
+ * Loads the DNS configurations from Windows's WMIC (from the given command or default command)
+ *
+ * Note that this method blocks while loading the given command and should
+ * thus be used with care! While this should be relatively fast for normal
+ * WMIC commands, it remains unknown if this may block under certain
+ * circumstances. In particular, this method should only be executed before
+ * the loop starts, not while it is running.
+ *
+ * Note that this method will only try to execute the given command try to
+ * parse its output, irrespective of whether this command exists. In
+ * particular, this command is only available on Windows. Currently, this
+ * will only parse valid nameserver entries from the command output and will
+ * ignore all other output without complaining.
+ *
+ * Note that the previous section implies that this may return an empty
+ * `Config` object if no valid nameserver entries can be found.
+ *
+ * @param ?string $command (advanced) should not be given (NULL) unless you know what you're doing
+ * @return self
+ * @link https://ss64.com/nt/wmic.html
+ */
+ public static function loadWmicBlocking($command = null)
+ {
+ $contents = shell_exec($command === null ? 'wmic NICCONFIG get "DNSServerSearchOrder" /format:CSV' : $command);
+ preg_match_all('/(?<=[{;,"])([\da-f.:]{4,})(?=[};,"])/i', $contents, $matches);
+
+ $config = new self();
+ $config->nameservers = $matches[1];
+
+ return $config;
+ }
+
+ public $nameservers = array();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Config/FilesystemFactory.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Config/FilesystemFactory.php
new file mode 100644
index 0000000..68cec3e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Config/FilesystemFactory.php
@@ -0,0 +1,73 @@
+<?php
+
+namespace React\Dns\Config;
+
+use React\EventLoop\LoopInterface;
+use React\Promise;
+use React\Promise\Deferred;
+use React\Stream\ReadableResourceStream;
+use React\Stream\Stream;
+
+/**
+ * @deprecated
+ * @see Config see Config class instead.
+ */
+class FilesystemFactory
+{
+ private $loop;
+
+ public function __construct(LoopInterface $loop)
+ {
+ $this->loop = $loop;
+ }
+
+ public function create($filename)
+ {
+ return $this
+ ->loadEtcResolvConf($filename)
+ ->then(array($this, 'parseEtcResolvConf'));
+ }
+
+ /**
+ * @param string $contents
+ * @return Promise
+ * @deprecated see Config instead
+ */
+ public function parseEtcResolvConf($contents)
+ {
+ return Promise\resolve(Config::loadResolvConfBlocking(
+ 'data://text/plain;base64,' . base64_encode($contents)
+ ));
+ }
+
+ public function loadEtcResolvConf($filename)
+ {
+ if (!file_exists($filename)) {
+ return Promise\reject(new \InvalidArgumentException("The filename for /etc/resolv.conf given does not exist: $filename"));
+ }
+
+ try {
+ $deferred = new Deferred();
+
+ $fd = fopen($filename, 'r');
+ stream_set_blocking($fd, 0);
+
+ $contents = '';
+
+ $stream = class_exists('React\Stream\ReadableResourceStream') ? new ReadableResourceStream($fd, $this->loop) : new Stream($fd, $this->loop);
+ $stream->on('data', function ($data) use (&$contents) {
+ $contents .= $data;
+ });
+ $stream->on('end', function () use (&$contents, $deferred) {
+ $deferred->resolve($contents);
+ });
+ $stream->on('error', function ($error) use ($deferred) {
+ $deferred->reject($error);
+ });
+
+ return $deferred->promise();
+ } catch (\Exception $e) {
+ return Promise\reject($e);
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Config/HostsFile.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Config/HostsFile.php
new file mode 100644
index 0000000..5b6277e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Config/HostsFile.php
@@ -0,0 +1,151 @@
+<?php
+
+namespace React\Dns\Config;
+
+use RuntimeException;
+
+/**
+ * Represents a static hosts file which maps hostnames to IPs
+ *
+ * Hosts files are used on most systems to avoid actually hitting the DNS for
+ * certain common hostnames.
+ *
+ * Most notably, this file usually contains an entry to map "localhost" to the
+ * local IP. Windows is a notable exception here, as Windows does not actually
+ * include "localhost" in this file by default. To compensate for this, this
+ * class may explicitly be wrapped in another HostsFile instance which
+ * hard-codes these entries for Windows (see also Factory).
+ *
+ * This class mostly exists to abstract the parsing/extraction process so this
+ * can be replaced with a faster alternative in the future.
+ */
+class HostsFile
+{
+ /**
+ * Returns the default path for the hosts file on this system
+ *
+ * @return string
+ * @codeCoverageIgnore
+ */
+ public static function getDefaultPath()
+ {
+ // use static path for all Unix-based systems
+ if (DIRECTORY_SEPARATOR !== '\\') {
+ return '/etc/hosts';
+ }
+
+ // Windows actually stores the path in the registry under
+ // \HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DataBasePath
+ $path = '%SystemRoot%\\system32\drivers\etc\hosts';
+
+ $base = getenv('SystemRoot');
+ if ($base === false) {
+ $base = 'C:\\Windows';
+ }
+
+ return str_replace('%SystemRoot%', $base, $path);
+ }
+
+ /**
+ * Loads a hosts file (from the given path or default location)
+ *
+ * Note that this method blocks while loading the given path and should
+ * thus be used with care! While this should be relatively fast for normal
+ * hosts file, this may be an issue if this file is located on a slow device
+ * or contains an excessive number of entries. In particular, this method
+ * should only be executed before the loop starts, not while it is running.
+ *
+ * @param ?string $path (optional) path to hosts file or null=load default location
+ * @return self
+ * @throws RuntimeException if the path can not be loaded (does not exist)
+ */
+ public static function loadFromPathBlocking($path = null)
+ {
+ if ($path === null) {
+ $path = self::getDefaultPath();
+ }
+
+ $contents = @file_get_contents($path);
+ if ($contents === false) {
+ throw new RuntimeException('Unable to load hosts file "' . $path . '"');
+ }
+
+ return new self($contents);
+ }
+
+ /**
+ * Instantiate new hosts file with the given hosts file contents
+ *
+ * @param string $contents
+ */
+ public function __construct($contents)
+ {
+ // remove all comments from the contents
+ $contents = preg_replace('/[ \t]*#.*/', '', strtolower($contents));
+
+ $this->contents = $contents;
+ }
+
+ /**
+ * Returns all IPs for the given hostname
+ *
+ * @param string $name
+ * @return string[]
+ */
+ public function getIpsForHost($name)
+ {
+ $name = strtolower($name);
+
+ $ips = array();
+ foreach (preg_split('/\r?\n/', $this->contents) as $line) {
+ $parts = preg_split('/\s+/', $line);
+ $ip = array_shift($parts);
+ if ($parts && array_search($name, $parts) !== false) {
+ // remove IPv6 zone ID (`fe80::1%lo0` => `fe80:1`)
+ if (strpos($ip, ':') !== false && ($pos = strpos($ip, '%')) !== false) {
+ $ip = substr($ip, 0, $pos);
+ }
+
+ if (@inet_pton($ip) !== false) {
+ $ips[] = $ip;
+ }
+ }
+ }
+
+ return $ips;
+ }
+
+ /**
+ * Returns all hostnames for the given IPv4 or IPv6 address
+ *
+ * @param string $ip
+ * @return string[]
+ */
+ public function getHostsForIp($ip)
+ {
+ // check binary representation of IP to avoid string case and short notation
+ $ip = @inet_pton($ip);
+ if ($ip === false) {
+ return array();
+ }
+
+ $names = array();
+ foreach (preg_split('/\r?\n/', $this->contents) as $line) {
+ $parts = preg_split('/\s+/', $line, null, PREG_SPLIT_NO_EMPTY);
+ $addr = array_shift($parts);
+
+ // remove IPv6 zone ID (`fe80::1%lo0` => `fe80:1`)
+ if (strpos($addr, ':') !== false && ($pos = strpos($addr, '%')) !== false) {
+ $addr = substr($addr, 0, $pos);
+ }
+
+ if (@inet_pton($addr) === $ip) {
+ foreach ($parts as $part) {
+ $names[] = $part;
+ }
+ }
+ }
+
+ return $names;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Model/HeaderBag.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Model/HeaderBag.php
new file mode 100644
index 0000000..193e65c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Model/HeaderBag.php
@@ -0,0 +1,56 @@
+<?php
+
+namespace React\Dns\Model;
+
+class HeaderBag
+{
+ public $data = '';
+
+ public $attributes = array(
+ 'qdCount' => 0,
+ 'anCount' => 0,
+ 'nsCount' => 0,
+ 'arCount' => 0,
+ 'qr' => 0,
+ 'opcode' => Message::OPCODE_QUERY,
+ 'aa' => 0,
+ 'tc' => 0,
+ 'rd' => 0,
+ 'ra' => 0,
+ 'z' => 0,
+ 'rcode' => Message::RCODE_OK,
+ );
+
+ public function get($name)
+ {
+ return isset($this->attributes[$name]) ? $this->attributes[$name] : null;
+ }
+
+ public function set($name, $value)
+ {
+ $this->attributes[$name] = $value;
+ }
+
+ public function isQuery()
+ {
+ return 0 === $this->attributes['qr'];
+ }
+
+ public function isResponse()
+ {
+ return 1 === $this->attributes['qr'];
+ }
+
+ public function isTruncated()
+ {
+ return 1 === $this->attributes['tc'];
+ }
+
+ public function populateCounts(Message $message)
+ {
+ $this->attributes['qdCount'] = count($message->questions);
+ $this->attributes['anCount'] = count($message->answers);
+ $this->attributes['nsCount'] = count($message->authority);
+ $this->attributes['arCount'] = count($message->additional);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Model/Message.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Model/Message.php
new file mode 100644
index 0000000..715cb1f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Model/Message.php
@@ -0,0 +1,100 @@
+<?php
+
+namespace React\Dns\Model;
+
+use React\Dns\Query\Query;
+use React\Dns\Model\Record;
+
+class Message
+{
+ const TYPE_A = 1;
+ const TYPE_NS = 2;
+ const TYPE_CNAME = 5;
+ const TYPE_SOA = 6;
+ const TYPE_PTR = 12;
+ const TYPE_MX = 15;
+ const TYPE_TXT = 16;
+ const TYPE_AAAA = 28;
+
+ const CLASS_IN = 1;
+
+ const OPCODE_QUERY = 0;
+ const OPCODE_IQUERY = 1; // inverse query
+ const OPCODE_STATUS = 2;
+
+ const RCODE_OK = 0;
+ const RCODE_FORMAT_ERROR = 1;
+ const RCODE_SERVER_FAILURE = 2;
+ const RCODE_NAME_ERROR = 3;
+ const RCODE_NOT_IMPLEMENTED = 4;
+ const RCODE_REFUSED = 5;
+
+ /**
+ * Creates a new request message for the given query
+ *
+ * @param Query $query
+ * @return self
+ */
+ public static function createRequestForQuery(Query $query)
+ {
+ $request = new Message();
+ $request->header->set('id', self::generateId());
+ $request->header->set('rd', 1);
+ $request->questions[] = (array) $query;
+ $request->prepare();
+
+ return $request;
+ }
+
+ /**
+ * Creates a new response message for the given query with the given answer records
+ *
+ * @param Query $query
+ * @param Record[] $answers
+ * @return self
+ */
+ public static function createResponseWithAnswersForQuery(Query $query, array $answers)
+ {
+ $response = new Message();
+ $response->header->set('id', self::generateId());
+ $response->header->set('qr', 1);
+ $response->header->set('opcode', Message::OPCODE_QUERY);
+ $response->header->set('rd', 1);
+ $response->header->set('rcode', Message::RCODE_OK);
+
+ $response->questions[] = (array) $query;
+
+ foreach ($answers as $record) {
+ $response->answers[] = $record;
+ }
+
+ $response->prepare();
+
+ return $response;
+ }
+
+ private static function generateId()
+ {
+ return mt_rand(0, 0xffff);
+ }
+
+ public $data = '';
+
+ public $header;
+ public $questions = array();
+ public $answers = array();
+ public $authority = array();
+ public $additional = array();
+
+ public $consumed = 0;
+
+ public function __construct()
+ {
+ $this->header = new HeaderBag();
+ }
+
+ public function prepare()
+ {
+ $this->header->populateCounts($this);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Model/Record.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Model/Record.php
new file mode 100644
index 0000000..029d232
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Model/Record.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace React\Dns\Model;
+
+class Record
+{
+ public $name;
+ public $type;
+ public $class;
+ public $ttl;
+ public $data;
+
+ public function __construct($name, $type, $class, $ttl = 0, $data = null)
+ {
+ $this->name = $name;
+ $this->type = $type;
+ $this->class = $class;
+ $this->ttl = $ttl;
+ $this->data = $data;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Protocol/BinaryDumper.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Protocol/BinaryDumper.php
new file mode 100644
index 0000000..35d6ae6
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Protocol/BinaryDumper.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace React\Dns\Protocol;
+
+use React\Dns\Model\Message;
+use React\Dns\Model\HeaderBag;
+
+class BinaryDumper
+{
+ public function toBinary(Message $message)
+ {
+ $data = '';
+
+ $data .= $this->headerToBinary($message->header);
+ $data .= $this->questionToBinary($message->questions);
+
+ return $data;
+ }
+
+ private function headerToBinary(HeaderBag $header)
+ {
+ $data = '';
+
+ $data .= pack('n', $header->get('id'));
+
+ $flags = 0x00;
+ $flags = ($flags << 1) | $header->get('qr');
+ $flags = ($flags << 4) | $header->get('opcode');
+ $flags = ($flags << 1) | $header->get('aa');
+ $flags = ($flags << 1) | $header->get('tc');
+ $flags = ($flags << 1) | $header->get('rd');
+ $flags = ($flags << 1) | $header->get('ra');
+ $flags = ($flags << 3) | $header->get('z');
+ $flags = ($flags << 4) | $header->get('rcode');
+
+ $data .= pack('n', $flags);
+
+ $data .= pack('n', $header->get('qdCount'));
+ $data .= pack('n', $header->get('anCount'));
+ $data .= pack('n', $header->get('nsCount'));
+ $data .= pack('n', $header->get('arCount'));
+
+ return $data;
+ }
+
+ private function questionToBinary(array $questions)
+ {
+ $data = '';
+
+ foreach ($questions as $question) {
+ $labels = explode('.', $question['name']);
+ foreach ($labels as $label) {
+ $data .= chr(strlen($label)).$label;
+ }
+ $data .= "\x00";
+
+ $data .= pack('n*', $question['type'], $question['class']);
+ }
+
+ return $data;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Protocol/Parser.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Protocol/Parser.php
new file mode 100644
index 0000000..1191cd3
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Protocol/Parser.php
@@ -0,0 +1,254 @@
+<?php
+
+namespace React\Dns\Protocol;
+
+use React\Dns\Model\Message;
+use React\Dns\Model\Record;
+use InvalidArgumentException;
+
+/**
+ * DNS protocol parser
+ *
+ * Obsolete and uncommon types and classes are not implemented.
+ */
+class Parser
+{
+ /**
+ * Parses the given raw binary message into a Message object
+ *
+ * @param string $data
+ * @throws InvalidArgumentException
+ * @return Message
+ */
+ public function parseMessage($data)
+ {
+ $message = new Message();
+ if ($this->parse($data, $message) !== $message) {
+ throw new InvalidArgumentException('Unable to parse binary message');
+ }
+
+ return $message;
+ }
+
+ /**
+ * @deprecated unused, exists for BC only
+ */
+ public function parseChunk($data, Message $message)
+ {
+ return $this->parse($data, $message);
+ }
+
+ private function parse($data, Message $message)
+ {
+ $message->data .= $data;
+
+ if (!$message->header->get('id')) {
+ if (!$this->parseHeader($message)) {
+ return;
+ }
+ }
+
+ if ($message->header->get('qdCount') != count($message->questions)) {
+ if (!$this->parseQuestion($message)) {
+ return;
+ }
+ }
+
+ if ($message->header->get('anCount') != count($message->answers)) {
+ if (!$this->parseAnswer($message)) {
+ return;
+ }
+ }
+
+ return $message;
+ }
+
+ public function parseHeader(Message $message)
+ {
+ if (strlen($message->data) < 12) {
+ return;
+ }
+
+ $header = substr($message->data, 0, 12);
+ $message->consumed += 12;
+
+ list($id, $fields, $qdCount, $anCount, $nsCount, $arCount) = array_values(unpack('n*', $header));
+
+ $rcode = $fields & bindec('1111');
+ $z = ($fields >> 4) & bindec('111');
+ $ra = ($fields >> 7) & 1;
+ $rd = ($fields >> 8) & 1;
+ $tc = ($fields >> 9) & 1;
+ $aa = ($fields >> 10) & 1;
+ $opcode = ($fields >> 11) & bindec('1111');
+ $qr = ($fields >> 15) & 1;
+
+ $vars = compact('id', 'qdCount', 'anCount', 'nsCount', 'arCount',
+ 'qr', 'opcode', 'aa', 'tc', 'rd', 'ra', 'z', 'rcode');
+
+
+ foreach ($vars as $name => $value) {
+ $message->header->set($name, $value);
+ }
+
+ return $message;
+ }
+
+ public function parseQuestion(Message $message)
+ {
+ if (strlen($message->data) < 2) {
+ return;
+ }
+
+ $consumed = $message->consumed;
+
+ list($labels, $consumed) = $this->readLabels($message->data, $consumed);
+
+ if (null === $labels) {
+ return;
+ }
+
+ if (strlen($message->data) - $consumed < 4) {
+ return;
+ }
+
+ list($type, $class) = array_values(unpack('n*', substr($message->data, $consumed, 4)));
+ $consumed += 4;
+
+ $message->consumed = $consumed;
+
+ $message->questions[] = array(
+ 'name' => implode('.', $labels),
+ 'type' => $type,
+ 'class' => $class,
+ );
+
+ if ($message->header->get('qdCount') != count($message->questions)) {
+ return $this->parseQuestion($message);
+ }
+
+ return $message;
+ }
+
+ public function parseAnswer(Message $message)
+ {
+ if (strlen($message->data) < 2) {
+ return;
+ }
+
+ $consumed = $message->consumed;
+
+ list($labels, $consumed) = $this->readLabels($message->data, $consumed);
+
+ if (null === $labels) {
+ return;
+ }
+
+ if (strlen($message->data) - $consumed < 10) {
+ return;
+ }
+
+ list($type, $class) = array_values(unpack('n*', substr($message->data, $consumed, 4)));
+ $consumed += 4;
+
+ list($ttl) = array_values(unpack('N', substr($message->data, $consumed, 4)));
+ $consumed += 4;
+
+ list($rdLength) = array_values(unpack('n', substr($message->data, $consumed, 2)));
+ $consumed += 2;
+
+ $rdata = null;
+
+ if (Message::TYPE_A === $type || Message::TYPE_AAAA === $type) {
+ $ip = substr($message->data, $consumed, $rdLength);
+ $consumed += $rdLength;
+
+ $rdata = inet_ntop($ip);
+ }
+
+ if (Message::TYPE_CNAME === $type || Message::TYPE_PTR === $type) {
+ list($bodyLabels, $consumed) = $this->readLabels($message->data, $consumed);
+
+ $rdata = implode('.', $bodyLabels);
+ }
+
+ $message->consumed = $consumed;
+
+ $name = implode('.', $labels);
+ $ttl = $this->signedLongToUnsignedLong($ttl);
+ $record = new Record($name, $type, $class, $ttl, $rdata);
+
+ $message->answers[] = $record;
+
+ if ($message->header->get('anCount') != count($message->answers)) {
+ return $this->parseAnswer($message);
+ }
+
+ return $message;
+ }
+
+ private function readLabels($data, $consumed)
+ {
+ $labels = array();
+
+ while (true) {
+ if ($this->isEndOfLabels($data, $consumed)) {
+ $consumed += 1;
+ break;
+ }
+
+ if ($this->isCompressedLabel($data, $consumed)) {
+ list($newLabels, $consumed) = $this->getCompressedLabel($data, $consumed);
+ $labels = array_merge($labels, $newLabels);
+ break;
+ }
+
+ $length = ord(substr($data, $consumed, 1));
+ $consumed += 1;
+
+ if (strlen($data) - $consumed < $length) {
+ return array(null, null);
+ }
+
+ $labels[] = substr($data, $consumed, $length);
+ $consumed += $length;
+ }
+
+ return array($labels, $consumed);
+ }
+
+ public function isEndOfLabels($data, $consumed)
+ {
+ $length = ord(substr($data, $consumed, 1));
+ return 0 === $length;
+ }
+
+ public function getCompressedLabel($data, $consumed)
+ {
+ list($nameOffset, $consumed) = $this->getCompressedLabelOffset($data, $consumed);
+ list($labels) = $this->readLabels($data, $nameOffset);
+
+ return array($labels, $consumed);
+ }
+
+ public function isCompressedLabel($data, $consumed)
+ {
+ $mask = 0xc000; // 1100000000000000
+ list($peek) = array_values(unpack('n', substr($data, $consumed, 2)));
+
+ return (bool) ($peek & $mask);
+ }
+
+ public function getCompressedLabelOffset($data, $consumed)
+ {
+ $mask = 0x3fff; // 0011111111111111
+ list($peek) = array_values(unpack('n', substr($data, $consumed, 2)));
+
+ return array($peek & $mask, $consumed + 2);
+ }
+
+ public function signedLongToUnsignedLong($i)
+ {
+ return $i & 0x80000000 ? $i - 0xffffffff : $i;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/CachedExecutor.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/CachedExecutor.php
new file mode 100644
index 0000000..285936d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/CachedExecutor.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace React\Dns\Query;
+
+use React\Dns\Model\Message;
+
+class CachedExecutor implements ExecutorInterface
+{
+ private $executor;
+ private $cache;
+
+ public function __construct(ExecutorInterface $executor, RecordCache $cache)
+ {
+ $this->executor = $executor;
+ $this->cache = $cache;
+ }
+
+ public function query($nameserver, Query $query)
+ {
+ $executor = $this->executor;
+ $cache = $this->cache;
+
+ return $this->cache
+ ->lookup($query)
+ ->then(
+ function ($cachedRecords) use ($query) {
+ return Message::createResponseWithAnswersForQuery($query, $cachedRecords);
+ },
+ function () use ($executor, $cache, $nameserver, $query) {
+ return $executor
+ ->query($nameserver, $query)
+ ->then(function ($response) use ($cache, $query) {
+ $cache->storeResponseMessage($query->currentTime, $response);
+ return $response;
+ });
+ }
+ );
+ }
+
+ /**
+ * @deprecated unused, exists for BC only
+ */
+ public function buildResponse(Query $query, array $cachedRecords)
+ {
+ return Message::createResponseWithAnswersForQuery($query, $cachedRecords);
+ }
+
+ /**
+ * @deprecated unused, exists for BC only
+ */
+ protected function generateId()
+ {
+ return mt_rand(0, 0xffff);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/CancellationException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/CancellationException.php
new file mode 100644
index 0000000..ac30f4c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/CancellationException.php
@@ -0,0 +1,7 @@
+<?php
+
+namespace React\Dns\Query;
+
+class CancellationException extends \RuntimeException
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/Executor.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/Executor.php
new file mode 100644
index 0000000..4c51f2b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/Executor.php
@@ -0,0 +1,156 @@
+<?php
+
+namespace React\Dns\Query;
+
+use React\Dns\Model\Message;
+use React\Dns\Protocol\Parser;
+use React\Dns\Protocol\BinaryDumper;
+use React\EventLoop\LoopInterface;
+use React\Promise\Deferred;
+use React\Promise;
+use React\Stream\DuplexResourceStream;
+use React\Stream\Stream;
+
+class Executor implements ExecutorInterface
+{
+ private $loop;
+ private $parser;
+ private $dumper;
+ private $timeout;
+
+ /**
+ *
+ * Note that albeit supported, the $timeout parameter is deprecated!
+ * You should pass a `null` value here instead. If you need timeout handling,
+ * use the `TimeoutConnector` instead.
+ *
+ * @param LoopInterface $loop
+ * @param Parser $parser
+ * @param BinaryDumper $dumper
+ * @param null|float $timeout DEPRECATED: timeout for DNS query or NULL=no timeout
+ */
+ public function __construct(LoopInterface $loop, Parser $parser, BinaryDumper $dumper, $timeout = 5)
+ {
+ $this->loop = $loop;
+ $this->parser = $parser;
+ $this->dumper = $dumper;
+ $this->timeout = $timeout;
+ }
+
+ public function query($nameserver, Query $query)
+ {
+ $request = Message::createRequestForQuery($query);
+
+ $queryData = $this->dumper->toBinary($request);
+ $transport = strlen($queryData) > 512 ? 'tcp' : 'udp';
+
+ return $this->doQuery($nameserver, $transport, $queryData, $query->name);
+ }
+
+ /**
+ * @deprecated unused, exists for BC only
+ */
+ public function prepareRequest(Query $query)
+ {
+ return Message::createRequestForQuery($query);
+ }
+
+ public function doQuery($nameserver, $transport, $queryData, $name)
+ {
+ // we only support UDP right now
+ if ($transport !== 'udp') {
+ return Promise\reject(new \RuntimeException(
+ 'DNS query for ' . $name . ' failed: Requested transport "' . $transport . '" not available, only UDP is supported in this version'
+ ));
+ }
+
+ $that = $this;
+ $parser = $this->parser;
+ $loop = $this->loop;
+
+ // UDP connections are instant, so try this without a timer
+ try {
+ $conn = $this->createConnection($nameserver, $transport);
+ } catch (\Exception $e) {
+ return Promise\reject(new \RuntimeException('DNS query for ' . $name . ' failed: ' . $e->getMessage(), 0, $e));
+ }
+
+ $deferred = new Deferred(function ($resolve, $reject) use (&$timer, $loop, &$conn, $name) {
+ $reject(new CancellationException(sprintf('DNS query for %s has been cancelled', $name)));
+
+ if ($timer !== null) {
+ $loop->cancelTimer($timer);
+ }
+ $conn->close();
+ });
+
+ $timer = null;
+ if ($this->timeout !== null) {
+ $timer = $this->loop->addTimer($this->timeout, function () use (&$conn, $name, $deferred) {
+ $conn->close();
+ $deferred->reject(new TimeoutException(sprintf("DNS query for %s timed out", $name)));
+ });
+ }
+
+ $conn->on('data', function ($data) use ($conn, $parser, $deferred, $timer, $loop, $name) {
+ $conn->end();
+ if ($timer !== null) {
+ $loop->cancelTimer($timer);
+ }
+
+ try {
+ $response = $parser->parseMessage($data);
+ } catch (\Exception $e) {
+ $deferred->reject($e);
+ return;
+ }
+
+ if ($response->header->isTruncated()) {
+ $deferred->reject(new \RuntimeException('DNS query for ' . $name . ' failed: The server returned a truncated result for a UDP query, but retrying via TCP is currently not supported'));
+ return;
+ }
+
+ $deferred->resolve($response);
+ });
+ $conn->write($queryData);
+
+ return $deferred->promise();
+ }
+
+ /**
+ * @deprecated unused, exists for BC only
+ */
+ protected function generateId()
+ {
+ return mt_rand(0, 0xffff);
+ }
+
+ /**
+ * @param string $nameserver
+ * @param string $transport
+ * @return \React\Stream\DuplexStreamInterface
+ */
+ protected function createConnection($nameserver, $transport)
+ {
+ $fd = @stream_socket_client("$transport://$nameserver", $errno, $errstr, 0, STREAM_CLIENT_CONNECT | STREAM_CLIENT_ASYNC_CONNECT);
+ if ($fd === false) {
+ throw new \RuntimeException('Unable to connect to DNS server: ' . $errstr, $errno);
+ }
+
+ // Instantiate stream instance around this stream resource.
+ // This ought to be replaced with a datagram socket in the future.
+ // Temporary work around for Windows 10: buffer whole UDP response
+ // @coverageIgnoreStart
+ if (!class_exists('React\Stream\Stream')) {
+ // prefer DuplexResourceStream as of react/stream v0.7.0
+ $conn = new DuplexResourceStream($fd, $this->loop, -1);
+ } else {
+ // use legacy Stream class for react/stream < v0.7.0
+ $conn = new Stream($fd, $this->loop);
+ $conn->bufferSize = null;
+ }
+ // @coverageIgnoreEnd
+
+ return $conn;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/ExecutorInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/ExecutorInterface.php
new file mode 100644
index 0000000..2f7a635
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/ExecutorInterface.php
@@ -0,0 +1,8 @@
+<?php
+
+namespace React\Dns\Query;
+
+interface ExecutorInterface
+{
+ public function query($nameserver, Query $query);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/HostsFileExecutor.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/HostsFileExecutor.php
new file mode 100644
index 0000000..0ca58be
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/HostsFileExecutor.php
@@ -0,0 +1,89 @@
+<?php
+
+namespace React\Dns\Query;
+
+use React\Dns\Config\HostsFile;
+use React\Dns\Model\Message;
+use React\Dns\Model\Record;
+use React\Promise;
+
+/**
+ * Resolves hosts from the givne HostsFile or falls back to another executor
+ *
+ * If the host is found in the hosts file, it will not be passed to the actual
+ * DNS executor. If the host is not found in the hosts file, it will be passed
+ * to the DNS executor as a fallback.
+ */
+class HostsFileExecutor implements ExecutorInterface
+{
+ private $hosts;
+ private $fallback;
+
+ public function __construct(HostsFile $hosts, ExecutorInterface $fallback)
+ {
+ $this->hosts = $hosts;
+ $this->fallback = $fallback;
+ }
+
+ public function query($nameserver, Query $query)
+ {
+ if ($query->class === Message::CLASS_IN && ($query->type === Message::TYPE_A || $query->type === Message::TYPE_AAAA)) {
+ // forward lookup for type A or AAAA
+ $records = array();
+ $expectsColon = $query->type === Message::TYPE_AAAA;
+ foreach ($this->hosts->getIpsForHost($query->name) as $ip) {
+ // ensure this is an IPv4/IPV6 address according to query type
+ if ((strpos($ip, ':') !== false) === $expectsColon) {
+ $records[] = new Record($query->name, $query->type, $query->class, 0, $ip);
+ }
+ }
+
+ if ($records) {
+ return Promise\resolve(
+ Message::createResponseWithAnswersForQuery($query, $records)
+ );
+ }
+ } elseif ($query->class === Message::CLASS_IN && $query->type === Message::TYPE_PTR) {
+ // reverse lookup: extract IPv4 or IPv6 from special `.arpa` domain
+ $ip = $this->getIpFromHost($query->name);
+
+ if ($ip !== null) {
+ $records = array();
+ foreach ($this->hosts->getHostsForIp($ip) as $host) {
+ $records[] = new Record($query->name, $query->type, $query->class, 0, $host);
+ }
+
+ if ($records) {
+ return Promise\resolve(
+ Message::createResponseWithAnswersForQuery($query, $records)
+ );
+ }
+ }
+ }
+
+ return $this->fallback->query($nameserver, $query);
+ }
+
+ private function getIpFromHost($host)
+ {
+ if (substr($host, -13) === '.in-addr.arpa') {
+ // IPv4: read as IP and reverse bytes
+ $ip = @inet_pton(substr($host, 0, -13));
+ if ($ip === false || isset($ip[4])) {
+ return null;
+ }
+
+ return inet_ntop(strrev($ip));
+ } elseif (substr($host, -9) === '.ip6.arpa') {
+ // IPv6: replace dots, reverse nibbles and interpret as hexadecimal string
+ $ip = @inet_ntop(pack('H*', strrev(str_replace('.', '', substr($host, 0, -9)))));
+ if ($ip === false) {
+ return null;
+ }
+
+ return $ip;
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/Query.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/Query.php
new file mode 100644
index 0000000..aef6e05
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/Query.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace React\Dns\Query;
+
+class Query
+{
+ public $name;
+ public $type;
+ public $class;
+ public $currentTime;
+
+ public function __construct($name, $type, $class, $currentTime)
+ {
+ $this->name = $name;
+ $this->type = $type;
+ $this->class = $class;
+ $this->currentTime = $currentTime;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/RecordBag.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/RecordBag.php
new file mode 100644
index 0000000..358cf5d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/RecordBag.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace React\Dns\Query;
+
+use React\Dns\Model\Message;
+use React\Dns\Model\Record;
+
+class RecordBag
+{
+ private $records = array();
+
+ public function set($currentTime, Record $record)
+ {
+ $this->records[$record->data] = array($currentTime + $record->ttl, $record);
+ }
+
+ public function all()
+ {
+ return array_values(array_map(
+ function ($value) {
+ list($expiresAt, $record) = $value;
+ return $record;
+ },
+ $this->records
+ ));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/RecordCache.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/RecordCache.php
new file mode 100644
index 0000000..b8142d3
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/RecordCache.php
@@ -0,0 +1,82 @@
+<?php
+
+namespace React\Dns\Query;
+
+use React\Cache\CacheInterface;
+use React\Dns\Model\Message;
+use React\Dns\Model\Record;
+use React\Promise;
+
+class RecordCache
+{
+ private $cache;
+ private $expiredAt;
+
+ public function __construct(CacheInterface $cache)
+ {
+ $this->cache = $cache;
+ }
+
+ public function lookup(Query $query)
+ {
+ $id = $this->serializeQueryToIdentity($query);
+
+ $expiredAt = $this->expiredAt;
+
+ return $this->cache
+ ->get($id)
+ ->then(function ($value) use ($query, $expiredAt) {
+ $recordBag = unserialize($value);
+
+ if (null !== $expiredAt && $expiredAt <= $query->currentTime) {
+ return Promise\reject();
+ }
+
+ return $recordBag->all();
+ });
+ }
+
+ public function storeResponseMessage($currentTime, Message $message)
+ {
+ foreach ($message->answers as $record) {
+ $this->storeRecord($currentTime, $record);
+ }
+ }
+
+ public function storeRecord($currentTime, Record $record)
+ {
+ $id = $this->serializeRecordToIdentity($record);
+
+ $cache = $this->cache;
+
+ $this->cache
+ ->get($id)
+ ->then(
+ function ($value) {
+ return unserialize($value);
+ },
+ function ($e) {
+ return new RecordBag();
+ }
+ )
+ ->then(function ($recordBag) use ($id, $currentTime, $record, $cache) {
+ $recordBag->set($currentTime, $record);
+ $cache->set($id, serialize($recordBag));
+ });
+ }
+
+ public function expire($currentTime)
+ {
+ $this->expiredAt = $currentTime;
+ }
+
+ public function serializeQueryToIdentity(Query $query)
+ {
+ return sprintf('%s:%s:%s', $query->name, $query->type, $query->class);
+ }
+
+ public function serializeRecordToIdentity(Record $record)
+ {
+ return sprintf('%s:%s:%s', $record->name, $record->type, $record->class);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/RetryExecutor.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/RetryExecutor.php
new file mode 100644
index 0000000..90353e5
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/RetryExecutor.php
@@ -0,0 +1,44 @@
+<?php
+
+namespace React\Dns\Query;
+
+use React\Promise\Deferred;
+
+class RetryExecutor implements ExecutorInterface
+{
+ private $executor;
+ private $retries;
+
+ public function __construct(ExecutorInterface $executor, $retries = 2)
+ {
+ $this->executor = $executor;
+ $this->retries = $retries;
+ }
+
+ public function query($nameserver, Query $query)
+ {
+ return $this->tryQuery($nameserver, $query, $this->retries);
+ }
+
+ public function tryQuery($nameserver, Query $query, $retries)
+ {
+ $that = $this;
+ $errorback = function ($error) use ($nameserver, $query, $retries, $that) {
+ if (!$error instanceof TimeoutException) {
+ throw $error;
+ }
+ if (0 >= $retries) {
+ throw new \RuntimeException(
+ sprintf("DNS query for %s failed: too many retries", $query->name),
+ 0,
+ $error
+ );
+ }
+ return $that->tryQuery($nameserver, $query, $retries-1);
+ };
+
+ return $this->executor
+ ->query($nameserver, $query)
+ ->then(null, $errorback);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/TimeoutException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/TimeoutException.php
new file mode 100644
index 0000000..90bf806
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/TimeoutException.php
@@ -0,0 +1,7 @@
+<?php
+
+namespace React\Dns\Query;
+
+class TimeoutException extends \Exception
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/TimeoutExecutor.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/TimeoutExecutor.php
new file mode 100644
index 0000000..6a44888
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Query/TimeoutExecutor.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace React\Dns\Query;
+
+use React\EventLoop\LoopInterface;
+use React\Promise\Deferred;
+use React\Promise\CancellablePromiseInterface;
+use React\Promise\Timer;
+
+class TimeoutExecutor implements ExecutorInterface
+{
+ private $executor;
+ private $loop;
+ private $timeout;
+
+ public function __construct(ExecutorInterface $executor, $timeout, LoopInterface $loop)
+ {
+ $this->executor = $executor;
+ $this->loop = $loop;
+ $this->timeout = $timeout;
+ }
+
+ public function query($nameserver, Query $query)
+ {
+ return Timer\timeout($this->executor->query($nameserver, $query), $this->timeout, $this->loop)->then(null, function ($e) use ($query) {
+ if ($e instanceof Timer\TimeoutException) {
+ $e = new TimeoutException(sprintf("DNS query for %s timed out", $query->name), 0, $e);
+ }
+ throw $e;
+ });
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/RecordNotFoundException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/RecordNotFoundException.php
new file mode 100644
index 0000000..0028413
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/RecordNotFoundException.php
@@ -0,0 +1,7 @@
+<?php
+
+namespace React\Dns;
+
+class RecordNotFoundException extends \Exception
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Resolver/Factory.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Resolver/Factory.php
new file mode 100644
index 0000000..12a912f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Resolver/Factory.php
@@ -0,0 +1,103 @@
+<?php
+
+namespace React\Dns\Resolver;
+
+use React\Cache\ArrayCache;
+use React\Cache\CacheInterface;
+use React\Dns\Config\HostsFile;
+use React\Dns\Protocol\Parser;
+use React\Dns\Protocol\BinaryDumper;
+use React\Dns\Query\CachedExecutor;
+use React\Dns\Query\Executor;
+use React\Dns\Query\ExecutorInterface;
+use React\Dns\Query\HostsFileExecutor;
+use React\Dns\Query\RecordCache;
+use React\Dns\Query\RetryExecutor;
+use React\Dns\Query\TimeoutExecutor;
+use React\EventLoop\LoopInterface;
+
+class Factory
+{
+ public function create($nameserver, LoopInterface $loop)
+ {
+ $nameserver = $this->addPortToServerIfMissing($nameserver);
+ $executor = $this->decorateHostsFileExecutor($this->createRetryExecutor($loop));
+
+ return new Resolver($nameserver, $executor);
+ }
+
+ public function createCached($nameserver, LoopInterface $loop, CacheInterface $cache = null)
+ {
+ if (!($cache instanceof CacheInterface)) {
+ $cache = new ArrayCache();
+ }
+
+ $nameserver = $this->addPortToServerIfMissing($nameserver);
+ $executor = $this->decorateHostsFileExecutor($this->createCachedExecutor($loop, $cache));
+
+ return new Resolver($nameserver, $executor);
+ }
+
+ /**
+ * Tries to load the hosts file and decorates the given executor on success
+ *
+ * @param ExecutorInterface $executor
+ * @return ExecutorInterface
+ * @codeCoverageIgnore
+ */
+ private function decorateHostsFileExecutor(ExecutorInterface $executor)
+ {
+ try {
+ $executor = new HostsFileExecutor(
+ HostsFile::loadFromPathBlocking(),
+ $executor
+ );
+ } catch (\RuntimeException $e) {
+ // ignore this file if it can not be loaded
+ }
+
+ // Windows does not store localhost in hosts file by default but handles this internally
+ // To compensate for this, we explicitly use hard-coded defaults for localhost
+ if (DIRECTORY_SEPARATOR === '\\') {
+ $executor = new HostsFileExecutor(
+ new HostsFile("127.0.0.1 localhost\n::1 localhost"),
+ $executor
+ );
+ }
+
+ return $executor;
+ }
+
+ protected function createExecutor(LoopInterface $loop)
+ {
+ return new TimeoutExecutor(
+ new Executor($loop, new Parser(), new BinaryDumper(), null),
+ 5.0,
+ $loop
+ );
+ }
+
+ protected function createRetryExecutor(LoopInterface $loop)
+ {
+ return new RetryExecutor($this->createExecutor($loop));
+ }
+
+ protected function createCachedExecutor(LoopInterface $loop, CacheInterface $cache)
+ {
+ return new CachedExecutor($this->createRetryExecutor($loop), new RecordCache($cache));
+ }
+
+ protected function addPortToServerIfMissing($nameserver)
+ {
+ if (strpos($nameserver, '[') === false && substr_count($nameserver, ':') >= 2) {
+ // several colons, but not enclosed in square brackets => enclose IPv6 address in square brackets
+ $nameserver = '[' . $nameserver . ']';
+ }
+ // assume a dummy scheme when checking for the port, otherwise parse_url() fails
+ if (parse_url('dummy://' . $nameserver, PHP_URL_PORT) === null) {
+ $nameserver .= ':53';
+ }
+
+ return $nameserver;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Resolver/Resolver.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Resolver/Resolver.php
new file mode 100644
index 0000000..4a4983a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/src/Resolver/Resolver.php
@@ -0,0 +1,100 @@
+<?php
+
+namespace React\Dns\Resolver;
+
+use React\Dns\Query\ExecutorInterface;
+use React\Dns\Query\Query;
+use React\Dns\RecordNotFoundException;
+use React\Dns\Model\Message;
+
+class Resolver
+{
+ private $nameserver;
+ private $executor;
+
+ public function __construct($nameserver, ExecutorInterface $executor)
+ {
+ $this->nameserver = $nameserver;
+ $this->executor = $executor;
+ }
+
+ public function resolve($domain)
+ {
+ $query = new Query($domain, Message::TYPE_A, Message::CLASS_IN, time());
+ $that = $this;
+
+ return $this->executor
+ ->query($this->nameserver, $query)
+ ->then(function (Message $response) use ($query, $that) {
+ return $that->extractAddress($query, $response);
+ });
+ }
+
+ public function extractAddress(Query $query, Message $response)
+ {
+ $answers = $response->answers;
+
+ $addresses = $this->resolveAliases($answers, $query->name);
+
+ if (0 === count($addresses)) {
+ $message = 'DNS Request did not return valid answer.';
+ throw new RecordNotFoundException($message);
+ }
+
+ $address = $addresses[array_rand($addresses)];
+ return $address;
+ }
+
+ public function resolveAliases(array $answers, $name)
+ {
+ $named = $this->filterByName($answers, $name);
+ $aRecords = $this->filterByType($named, Message::TYPE_A);
+ $cnameRecords = $this->filterByType($named, Message::TYPE_CNAME);
+
+ if ($aRecords) {
+ return $this->mapRecordData($aRecords);
+ }
+
+ if ($cnameRecords) {
+ $aRecords = array();
+
+ $cnames = $this->mapRecordData($cnameRecords);
+ foreach ($cnames as $cname) {
+ $targets = $this->filterByName($answers, $cname);
+ $aRecords = array_merge(
+ $aRecords,
+ $this->resolveAliases($answers, $cname)
+ );
+ }
+
+ return $aRecords;
+ }
+
+ return array();
+ }
+
+ private function filterByName(array $answers, $name)
+ {
+ return $this->filterByField($answers, 'name', $name);
+ }
+
+ private function filterByType(array $answers, $type)
+ {
+ return $this->filterByField($answers, 'type', $type);
+ }
+
+ private function filterByField(array $answers, $field, $value)
+ {
+ $value = strtolower($value);
+ return array_filter($answers, function ($answer) use ($field, $value) {
+ return $value === strtolower($answer->$field);
+ });
+ }
+
+ private function mapRecordData(array $records)
+ {
+ return array_map(function ($record) {
+ return $record->data;
+ }, $records);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/CallableStub.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/CallableStub.php
new file mode 100644
index 0000000..a34a263
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/CallableStub.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace React\Tests\Dns;
+
+class CallableStub
+{
+ public function __invoke()
+ {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Config/ConfigTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Config/ConfigTest.php
new file mode 100644
index 0000000..8020408
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Config/ConfigTest.php
@@ -0,0 +1,189 @@
+<?php
+
+namespace React\Tests\Dns\Config;
+
+use React\Tests\Dns\TestCase;
+use React\Dns\Config\Config;
+
+class ConfigTest extends TestCase
+{
+ public function testLoadsSystemDefault()
+ {
+ $config = Config::loadSystemConfigBlocking();
+
+ $this->assertInstanceOf('React\Dns\Config\Config', $config);
+ }
+
+ public function testLoadsDefaultPath()
+ {
+ if (DIRECTORY_SEPARATOR === '\\') {
+ $this->markTestSkipped('Not supported on Windows');
+ }
+
+ $config = Config::loadResolvConfBlocking();
+
+ $this->assertInstanceOf('React\Dns\Config\Config', $config);
+ }
+
+ public function testLoadsFromExplicitPath()
+ {
+ $config = Config::loadResolvConfBlocking(__DIR__ . '/../Fixtures/etc/resolv.conf');
+
+ $this->assertEquals(array('8.8.8.8'), $config->nameservers);
+ }
+
+ /**
+ * @expectedException RuntimeException
+ */
+ public function testLoadThrowsWhenPathIsInvalid()
+ {
+ Config::loadResolvConfBlocking(__DIR__ . '/invalid.conf');
+ }
+
+ public function testParsesSingleEntryFile()
+ {
+ $contents = 'nameserver 8.8.8.8';
+ $expected = array('8.8.8.8');
+
+ $config = Config::loadResolvConfBlocking('data://text/plain;base64,' . base64_encode($contents));
+ $this->assertEquals($expected, $config->nameservers);
+ }
+
+ public function testParsesNameserverEntriesFromAverageFileCorrectly()
+ {
+ $contents = '#
+# Mac OS X Notice
+#
+# This file is not used by the host name and address resolution
+# or the DNS query routing mechanisms used by most processes on
+# this Mac OS X system.
+#
+# This file is automatically generated.
+#
+domain v.cablecom.net
+nameserver 127.0.0.1
+nameserver ::1
+';
+ $expected = array('127.0.0.1', '::1');
+
+ $config = Config::loadResolvConfBlocking('data://text/plain;base64,' . base64_encode($contents));
+ $this->assertEquals($expected, $config->nameservers);
+ }
+
+ public function testParsesEmptyFileWithoutNameserverEntries()
+ {
+ $contents = '';
+ $expected = array();
+
+ $config = Config::loadResolvConfBlocking('data://text/plain;base64,');
+ $this->assertEquals($expected, $config->nameservers);
+ }
+
+ public function testParsesFileAndIgnoresCommentsAndInvalidNameserverEntries()
+ {
+ $contents = '
+# nameserver 1.2.3.4
+; nameserver 2.3.4.5
+
+nameserver 3.4.5.6 # nope
+nameserver 4.5.6.7 5.6.7.8
+ nameserver 6.7.8.9
+NameServer 7.8.9.10
+';
+ $expected = array();
+
+ $config = Config::loadResolvConfBlocking('data://text/plain;base64,' . base64_encode($contents));
+ $this->assertEquals($expected, $config->nameservers);
+ }
+
+ public function testLoadsFromWmicOnWindows()
+ {
+ if (DIRECTORY_SEPARATOR !== '\\') {
+ $this->markTestSkipped('Only on Windows');
+ }
+
+ $config = Config::loadWmicBlocking();
+
+ $this->assertInstanceOf('React\Dns\Config\Config', $config);
+ }
+
+ public function testLoadsSingleEntryFromWmicOutput()
+ {
+ $contents = '
+Node,DNSServerSearchOrder
+ACE,
+ACE,{192.168.2.1}
+ACE,
+';
+ $expected = array('192.168.2.1');
+
+ $config = Config::loadWmicBlocking($this->echoCommand($contents));
+
+ $this->assertEquals($expected, $config->nameservers);
+ }
+
+ public function testLoadsEmptyListFromWmicOutput()
+ {
+ $contents = '
+Node,DNSServerSearchOrder
+ACE,
+';
+ $expected = array();
+
+ $config = Config::loadWmicBlocking($this->echoCommand($contents));
+
+ $this->assertEquals($expected, $config->nameservers);
+ }
+
+ public function testLoadsSingleEntryForMultipleNicsFromWmicOutput()
+ {
+ $contents = '
+Node,DNSServerSearchOrder
+ACE,
+ACE,{192.168.2.1}
+ACE,
+ACE,{192.168.2.2}
+ACE,
+';
+ $expected = array('192.168.2.1', '192.168.2.2');
+
+ $config = Config::loadWmicBlocking($this->echoCommand($contents));
+
+ $this->assertEquals($expected, $config->nameservers);
+ }
+
+ public function testLoadsMultipleEntriesForSingleNicWithSemicolonFromWmicOutput()
+ {
+ $contents = '
+Node,DNSServerSearchOrder
+ACE,
+ACE,{192.168.2.1;192.168.2.2}
+ACE,
+';
+ $expected = array('192.168.2.1', '192.168.2.2');
+
+ $config = Config::loadWmicBlocking($this->echoCommand($contents));
+
+ $this->assertEquals($expected, $config->nameservers);
+ }
+
+ public function testLoadsMultipleEntriesForSingleNicWithQuotesFromWmicOutput()
+ {
+ $contents = '
+Node,DNSServerSearchOrder
+ACE,
+ACE,{"192.168.2.1","192.168.2.2"}
+ACE,
+';
+ $expected = array('192.168.2.1', '192.168.2.2');
+
+ $config = Config::loadWmicBlocking($this->echoCommand($contents));
+
+ $this->assertEquals($expected, $config->nameservers);
+ }
+
+ private function echoCommand($output)
+ {
+ return 'echo ' . escapeshellarg($output);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Config/FilesystemFactoryTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Config/FilesystemFactoryTest.php
new file mode 100644
index 0000000..bb9eac7
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Config/FilesystemFactoryTest.php
@@ -0,0 +1,70 @@
+<?php
+
+namespace React\Test\Dns\Config;
+
+use PHPUnit\Framework\TestCase;
+use React\Dns\Config\FilesystemFactory;
+
+class FilesystemFactoryTest extends TestCase
+{
+ /** @test */
+ public function parseEtcResolvConfShouldParseCorrectly()
+ {
+ $contents = '#
+# Mac OS X Notice
+#
+# This file is not used by the host name and address resolution
+# or the DNS query routing mechanisms used by most processes on
+# this Mac OS X system.
+#
+# This file is automatically generated.
+#
+domain v.cablecom.net
+nameserver 127.0.0.1
+nameserver 8.8.8.8
+';
+ $expected = array('127.0.0.1', '8.8.8.8');
+
+ $capturedConfig = null;
+
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ $factory = new FilesystemFactory($loop);
+ $factory->parseEtcResolvConf($contents)->then(function ($config) use (&$capturedConfig) {
+ $capturedConfig = $config;
+ });
+
+ $this->assertNotNull($capturedConfig);
+ $this->assertSame($expected, $capturedConfig->nameservers);
+ }
+
+ /** @test */
+ public function createShouldLoadStuffFromFilesystem()
+ {
+ $this->markTestIncomplete('Filesystem API is incomplete');
+
+ $expected = array('8.8.8.8');
+
+ $triggerListener = null;
+ $capturedConfig = null;
+
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ $loop
+ ->expects($this->once())
+ ->method('addReadStream')
+ ->will($this->returnCallback(function ($stream, $listener) use (&$triggerListener) {
+ $triggerListener = function () use ($stream, $listener) {
+ call_user_func($listener, $stream);
+ };
+ }));
+
+ $factory = new FilesystemFactory($loop);
+ $factory->create(__DIR__.'/../Fixtures/etc/resolv.conf')->then(function ($config) use (&$capturedConfig) {
+ $capturedConfig = $config;
+ });
+
+ $triggerListener();
+
+ $this->assertNotNull($capturedConfig);
+ $this->assertSame($expected, $capturedConfig->nameservers);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Config/HostsFileTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Config/HostsFileTest.php
new file mode 100644
index 0000000..ff74ad2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Config/HostsFileTest.php
@@ -0,0 +1,170 @@
+<?php
+
+namespace React\Tests\Dns\Config;
+
+use React\Tests\Dns\TestCase;
+use React\Dns\Config\HostsFile;
+
+class HostsFileTest extends TestCase
+{
+ public function testLoadsFromDefaultPath()
+ {
+ $hosts = HostsFile::loadFromPathBlocking();
+
+ $this->assertInstanceOf('React\Dns\Config\HostsFile', $hosts);
+ }
+
+ public function testDefaultShouldHaveLocalhostMapped()
+ {
+ if (DIRECTORY_SEPARATOR === '\\') {
+ $this->markTestSkipped('Not supported on Windows');
+ }
+
+ $hosts = HostsFile::loadFromPathBlocking();
+
+ $this->assertContains('127.0.0.1', $hosts->getIpsForHost('localhost'));
+ }
+
+ /**
+ * @expectedException RuntimeException
+ */
+ public function testLoadThrowsForInvalidPath()
+ {
+ HostsFile::loadFromPathBlocking('does/not/exist');
+ }
+
+ public function testContainsSingleLocalhostEntry()
+ {
+ $hosts = new HostsFile('127.0.0.1 localhost');
+
+ $this->assertEquals(array('127.0.0.1'), $hosts->getIpsForHost('localhost'));
+ $this->assertEquals(array(), $hosts->getIpsForHost('example.com'));
+ }
+
+ public function testNonIpReturnsNothingForInvalidHosts()
+ {
+ $hosts = new HostsFile('a b');
+
+ $this->assertEquals(array(), $hosts->getIpsForHost('a'));
+ $this->assertEquals(array(), $hosts->getIpsForHost('b'));
+ }
+
+ public function testIgnoresIpv6ZoneId()
+ {
+ $hosts = new HostsFile('fe80::1%lo0 localhost');
+
+ $this->assertEquals(array('fe80::1'), $hosts->getIpsForHost('localhost'));
+ }
+
+ public function testSkipsComments()
+ {
+ $hosts = new HostsFile('# start' . PHP_EOL .'#127.0.0.1 localhost' . PHP_EOL . '127.0.0.2 localhost # example.com');
+
+ $this->assertEquals(array('127.0.0.2'), $hosts->getIpsForHost('localhost'));
+ $this->assertEquals(array(), $hosts->getIpsForHost('example.com'));
+ }
+
+ public function testContainsSingleLocalhostEntryWithCaseIgnored()
+ {
+ $hosts = new HostsFile('127.0.0.1 LocalHost');
+
+ $this->assertEquals(array('127.0.0.1'), $hosts->getIpsForHost('LOCALHOST'));
+ }
+
+ public function testEmptyFileContainsNothing()
+ {
+ $hosts = new HostsFile('');
+
+ $this->assertEquals(array(), $hosts->getIpsForHost('example.com'));
+ }
+
+ public function testSingleEntryWithMultipleNames()
+ {
+ $hosts = new HostsFile('127.0.0.1 localhost example.com');
+
+ $this->assertEquals(array('127.0.0.1'), $hosts->getIpsForHost('example.com'));
+ $this->assertEquals(array('127.0.0.1'), $hosts->getIpsForHost('localhost'));
+ }
+
+ public function testMergesEntriesOverMultipleLines()
+ {
+ $hosts = new HostsFile("127.0.0.1 localhost\n127.0.0.2 localhost\n127.0.0.3 a localhost b\n127.0.0.4 a localhost");
+
+ $this->assertEquals(array('127.0.0.1', '127.0.0.2', '127.0.0.3', '127.0.0.4'), $hosts->getIpsForHost('localhost'));
+ }
+
+ public function testMergesIpv4AndIpv6EntriesOverMultipleLines()
+ {
+ $hosts = new HostsFile("127.0.0.1 localhost\n::1 localhost");
+
+ $this->assertEquals(array('127.0.0.1', '::1'), $hosts->getIpsForHost('localhost'));
+ }
+
+ public function testReverseLookup()
+ {
+ $hosts = new HostsFile('127.0.0.1 localhost');
+
+ $this->assertEquals(array('localhost'), $hosts->getHostsForIp('127.0.0.1'));
+ $this->assertEquals(array(), $hosts->getHostsForIp('192.168.1.1'));
+ }
+
+ public function testReverseSkipsComments()
+ {
+ $hosts = new HostsFile("# start\n#127.0.0.1 localhosted\n127.0.0.2\tlocalhost\t# example.com\n\t127.0.0.3\t\texample.org\t\t");
+
+ $this->assertEquals(array(), $hosts->getHostsForIp('127.0.0.1'));
+ $this->assertEquals(array('localhost'), $hosts->getHostsForIp('127.0.0.2'));
+ $this->assertEquals(array('example.org'), $hosts->getHostsForIp('127.0.0.3'));
+ }
+
+ public function testReverseNonIpReturnsNothing()
+ {
+ $hosts = new HostsFile('127.0.0.1 localhost');
+
+ $this->assertEquals(array(), $hosts->getHostsForIp('localhost'));
+ $this->assertEquals(array(), $hosts->getHostsForIp('127.0.0.1.1'));
+ }
+
+ public function testReverseNonIpReturnsNothingForInvalidHosts()
+ {
+ $hosts = new HostsFile('a b');
+
+ $this->assertEquals(array(), $hosts->getHostsForIp('a'));
+ $this->assertEquals(array(), $hosts->getHostsForIp('b'));
+ }
+
+ public function testReverseLookupReturnsLowerCaseHost()
+ {
+ $hosts = new HostsFile('127.0.0.1 LocalHost');
+
+ $this->assertEquals(array('localhost'), $hosts->getHostsForIp('127.0.0.1'));
+ }
+
+ public function testReverseLookupChecksNormalizedIpv6()
+ {
+ $hosts = new HostsFile('FE80::00a1 localhost');
+
+ $this->assertEquals(array('localhost'), $hosts->getHostsForIp('fe80::A1'));
+ }
+
+ public function testReverseLookupIgnoresIpv6ZoneId()
+ {
+ $hosts = new HostsFile('fe80::1%lo0 localhost');
+
+ $this->assertEquals(array('localhost'), $hosts->getHostsForIp('fe80::1'));
+ }
+
+ public function testReverseLookupReturnsMultipleHostsOverSingleLine()
+ {
+ $hosts = new HostsFile("::1 ip6-localhost ip6-loopback");
+
+ $this->assertEquals(array('ip6-localhost', 'ip6-loopback'), $hosts->getHostsForIp('::1'));
+ }
+
+ public function testReverseLookupReturnsMultipleHostsOverMultipleLines()
+ {
+ $hosts = new HostsFile("::1 ip6-localhost\n::1 ip6-loopback");
+
+ $this->assertEquals(array('ip6-localhost', 'ip6-loopback'), $hosts->getHostsForIp('::1'));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Fixtures/etc/resolv.conf b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Fixtures/etc/resolv.conf
new file mode 100644
index 0000000..cae093a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Fixtures/etc/resolv.conf
@@ -0,0 +1 @@
+nameserver 8.8.8.8
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/FunctionalResolverTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/FunctionalResolverTest.php
new file mode 100644
index 0000000..0807e86
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/FunctionalResolverTest.php
@@ -0,0 +1,71 @@
+<?php
+
+namespace React\Tests\Dns;
+
+use React\Tests\Dns\TestCase;
+use React\EventLoop\Factory as LoopFactory;
+use React\Dns\Resolver\Resolver;
+use React\Dns\Resolver\Factory;
+
+class FunctionalTest extends TestCase
+{
+ public function setUp()
+ {
+ $this->loop = LoopFactory::create();
+
+ $factory = new Factory();
+ $this->resolver = $factory->create('8.8.8.8', $this->loop);
+ }
+
+ public function testResolveLocalhostResolves()
+ {
+ $promise = $this->resolver->resolve('localhost');
+ $promise->then($this->expectCallableOnce(), $this->expectCallableNever());
+
+ $this->loop->run();
+ }
+
+ /**
+ * @group internet
+ */
+ public function testResolveGoogleResolves()
+ {
+ $promise = $this->resolver->resolve('google.com');
+ $promise->then($this->expectCallableOnce(), $this->expectCallableNever());
+
+ $this->loop->run();
+ }
+
+ /**
+ * @group internet
+ */
+ public function testResolveInvalidRejects()
+ {
+ $promise = $this->resolver->resolve('example.invalid');
+ $promise->then($this->expectCallableNever(), $this->expectCallableOnce());
+
+ $this->loop->run();
+ }
+
+ public function testResolveCancelledRejectsImmediately()
+ {
+ $promise = $this->resolver->resolve('google.com');
+ $promise->then($this->expectCallableNever(), $this->expectCallableOnce());
+ $promise->cancel();
+
+ $time = microtime(true);
+ $this->loop->run();
+ $time = microtime(true) - $time;
+
+ $this->assertLessThan(0.1, $time);
+ }
+
+ public function testInvalidResolverDoesNotResolveGoogle()
+ {
+ $factory = new Factory();
+ $this->resolver = $factory->create('255.255.255.255', $this->loop);
+
+ $promise = $this->resolver->resolve('google.com');
+ $promise->then($this->expectCallableNever(), $this->expectCallableOnce());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Model/MessageTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Model/MessageTest.php
new file mode 100644
index 0000000..53d6b28
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Model/MessageTest.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace React\Tests\Dns\Model;
+
+use PHPUnit\Framework\TestCase;
+use React\Dns\Query\Query;
+use React\Dns\Model\Message;
+
+class MessageTest extends TestCase
+{
+ public function testCreateRequestDesiresRecusion()
+ {
+ $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN, 1345656451);
+ $request = Message::createRequestForQuery($query);
+
+ $this->assertTrue($request->header->isQuery());
+ $this->assertSame(1, $request->header->get('rd'));
+ }
+
+ public function testCreateResponseWithNoAnswers()
+ {
+ $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN, 1345656451);
+ $answers = array();
+ $request = Message::createResponseWithAnswersForQuery($query, $answers);
+
+ $this->assertFalse($request->header->isQuery());
+ $this->assertTrue($request->header->isResponse());
+ $this->assertEquals(0, $request->header->get('anCount'));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Protocol/BinaryDumperTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Protocol/BinaryDumperTest.php
new file mode 100644
index 0000000..bf60ca9
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Protocol/BinaryDumperTest.php
@@ -0,0 +1,48 @@
+<?php
+
+namespace React\Tests\Dns\Protocol;
+
+use PHPUnit\Framework\TestCase;
+use React\Dns\Protocol\BinaryDumper;
+use React\Dns\Model\Message;
+
+class BinaryDumperTest extends TestCase
+{
+ public function testRequestToBinary()
+ {
+ $data = "";
+ $data .= "72 62 01 00 00 01 00 00 00 00 00 00"; // header
+ $data .= "04 69 67 6f 72 02 69 6f 00"; // question: igor.io
+ $data .= "00 01 00 01"; // question: type A, class IN
+
+ $expected = $this->formatHexDump(str_replace(' ', '', $data), 2);
+
+ $request = new Message();
+ $request->header->set('id', 0x7262);
+ $request->header->set('rd', 1);
+
+ $request->questions[] = array(
+ 'name' => 'igor.io',
+ 'type' => Message::TYPE_A,
+ 'class' => Message::CLASS_IN,
+ );
+
+ $request->prepare();
+
+ $dumper = new BinaryDumper();
+ $data = $dumper->toBinary($request);
+ $data = $this->convertBinaryToHexDump($data);
+
+ $this->assertSame($expected, $data);
+ }
+
+ private function convertBinaryToHexDump($input)
+ {
+ return $this->formatHexDump(implode('', unpack('H*', $input)));
+ }
+
+ private function formatHexDump($input)
+ {
+ return implode(' ', str_split($input, 2));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Protocol/ParserTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Protocol/ParserTest.php
new file mode 100644
index 0000000..195fad2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Protocol/ParserTest.php
@@ -0,0 +1,343 @@
+<?php
+
+namespace React\Tests\Dns\Protocol;
+
+use PHPUnit\Framework\TestCase;
+use React\Dns\Protocol\Parser;
+use React\Dns\Model\Message;
+
+class ParserTest extends TestCase
+{
+ public function setUp()
+ {
+ $this->parser = new Parser();
+ }
+
+ /**
+ * @dataProvider provideConvertTcpDumpToBinary
+ */
+ public function testConvertTcpDumpToBinary($expected, $data)
+ {
+ $this->assertSame($expected, $this->convertTcpDumpToBinary($data));
+ }
+
+ public function provideConvertTcpDumpToBinary()
+ {
+ return array(
+ array(chr(0x72).chr(0x62), "72 62"),
+ array(chr(0x72).chr(0x62).chr(0x01).chr(0x00), "72 62 01 00"),
+ array(chr(0x72).chr(0x62).chr(0x01).chr(0x00).chr(0x00).chr(0x01), "72 62 01 00 00 01"),
+ array(chr(0x01).chr(0x00).chr(0x01), "01 00 01"),
+ );
+ }
+
+ public function testParseRequest()
+ {
+ $data = "";
+ $data .= "72 62 01 00 00 01 00 00 00 00 00 00"; // header
+ $data .= "04 69 67 6f 72 02 69 6f 00"; // question: igor.io
+ $data .= "00 01 00 01"; // question: type A, class IN
+
+ $data = $this->convertTcpDumpToBinary($data);
+
+ $request = $this->parser->parseMessage($data);
+
+ $header = $request->header;
+ $this->assertSame(0x7262, $header->get('id'));
+ $this->assertSame(1, $header->get('qdCount'));
+ $this->assertSame(0, $header->get('anCount'));
+ $this->assertSame(0, $header->get('nsCount'));
+ $this->assertSame(0, $header->get('arCount'));
+ $this->assertSame(0, $header->get('qr'));
+ $this->assertSame(Message::OPCODE_QUERY, $header->get('opcode'));
+ $this->assertSame(0, $header->get('aa'));
+ $this->assertSame(0, $header->get('tc'));
+ $this->assertSame(1, $header->get('rd'));
+ $this->assertSame(0, $header->get('ra'));
+ $this->assertSame(0, $header->get('z'));
+ $this->assertSame(Message::RCODE_OK, $header->get('rcode'));
+
+ $this->assertCount(1, $request->questions);
+ $this->assertSame('igor.io', $request->questions[0]['name']);
+ $this->assertSame(Message::TYPE_A, $request->questions[0]['type']);
+ $this->assertSame(Message::CLASS_IN, $request->questions[0]['class']);
+ }
+
+ public function testParseResponse()
+ {
+ $data = "";
+ $data .= "72 62 81 80 00 01 00 01 00 00 00 00"; // header
+ $data .= "04 69 67 6f 72 02 69 6f 00"; // question: igor.io
+ $data .= "00 01 00 01"; // question: type A, class IN
+ $data .= "c0 0c"; // answer: offset pointer to igor.io
+ $data .= "00 01 00 01"; // answer: type A, class IN
+ $data .= "00 01 51 80"; // answer: ttl 86400
+ $data .= "00 04"; // answer: rdlength 4
+ $data .= "b2 4f a9 83"; // answer: rdata 178.79.169.131
+
+ $data = $this->convertTcpDumpToBinary($data);
+
+ $response = $this->parser->parseMessage($data);
+
+ $header = $response->header;
+ $this->assertSame(0x7262, $header->get('id'));
+ $this->assertSame(1, $header->get('qdCount'));
+ $this->assertSame(1, $header->get('anCount'));
+ $this->assertSame(0, $header->get('nsCount'));
+ $this->assertSame(0, $header->get('arCount'));
+ $this->assertSame(1, $header->get('qr'));
+ $this->assertSame(Message::OPCODE_QUERY, $header->get('opcode'));
+ $this->assertSame(0, $header->get('aa'));
+ $this->assertSame(0, $header->get('tc'));
+ $this->assertSame(1, $header->get('rd'));
+ $this->assertSame(1, $header->get('ra'));
+ $this->assertSame(0, $header->get('z'));
+ $this->assertSame(Message::RCODE_OK, $header->get('rcode'));
+
+ $this->assertCount(1, $response->questions);
+ $this->assertSame('igor.io', $response->questions[0]['name']);
+ $this->assertSame(Message::TYPE_A, $response->questions[0]['type']);
+ $this->assertSame(Message::CLASS_IN, $response->questions[0]['class']);
+
+ $this->assertCount(1, $response->answers);
+ $this->assertSame('igor.io', $response->answers[0]->name);
+ $this->assertSame(Message::TYPE_A, $response->answers[0]->type);
+ $this->assertSame(Message::CLASS_IN, $response->answers[0]->class);
+ $this->assertSame(86400, $response->answers[0]->ttl);
+ $this->assertSame('178.79.169.131', $response->answers[0]->data);
+ }
+
+ public function testParseQuestionWithTwoQuestions()
+ {
+ $data = "";
+ $data .= "04 69 67 6f 72 02 69 6f 00"; // question: igor.io
+ $data .= "00 01 00 01"; // question: type A, class IN
+ $data .= "03 77 77 77 04 69 67 6f 72 02 69 6f 00"; // question: www.igor.io
+ $data .= "00 01 00 01"; // question: type A, class IN
+
+ $data = $this->convertTcpDumpToBinary($data);
+
+ $request = new Message();
+ $request->header->set('qdCount', 2);
+ $request->data = $data;
+
+ $this->parser->parseQuestion($request);
+
+ $this->assertCount(2, $request->questions);
+ $this->assertSame('igor.io', $request->questions[0]['name']);
+ $this->assertSame(Message::TYPE_A, $request->questions[0]['type']);
+ $this->assertSame(Message::CLASS_IN, $request->questions[0]['class']);
+ $this->assertSame('www.igor.io', $request->questions[1]['name']);
+ $this->assertSame(Message::TYPE_A, $request->questions[1]['type']);
+ $this->assertSame(Message::CLASS_IN, $request->questions[1]['class']);
+ }
+
+ public function testParseAnswerWithInlineData()
+ {
+ $data = "";
+ $data .= "04 69 67 6f 72 02 69 6f 00"; // answer: igor.io
+ $data .= "00 01 00 01"; // answer: type A, class IN
+ $data .= "00 01 51 80"; // answer: ttl 86400
+ $data .= "00 04"; // answer: rdlength 4
+ $data .= "b2 4f a9 83"; // answer: rdata 178.79.169.131
+
+ $data = $this->convertTcpDumpToBinary($data);
+
+ $response = new Message();
+ $response->header->set('anCount', 1);
+ $response->data = $data;
+
+ $this->parser->parseAnswer($response);
+
+ $this->assertCount(1, $response->answers);
+ $this->assertSame('igor.io', $response->answers[0]->name);
+ $this->assertSame(Message::TYPE_A, $response->answers[0]->type);
+ $this->assertSame(Message::CLASS_IN, $response->answers[0]->class);
+ $this->assertSame(86400, $response->answers[0]->ttl);
+ $this->assertSame('178.79.169.131', $response->answers[0]->data);
+ }
+
+ public function testParseResponseWithCnameAndOffsetPointers()
+ {
+ $data = "";
+ $data .= "9e 8d 81 80 00 01 00 01 00 00 00 00"; // header
+ $data .= "04 6d 61 69 6c 06 67 6f 6f 67 6c 65 03 63 6f 6d 00"; // question: mail.google.com
+ $data .= "00 05 00 01"; // question: type CNAME, class IN
+ $data .= "c0 0c"; // answer: offset pointer to mail.google.com
+ $data .= "00 05 00 01"; // answer: type CNAME, class IN
+ $data .= "00 00 a8 9c"; // answer: ttl 43164
+ $data .= "00 0f"; // answer: rdlength 15
+ $data .= "0a 67 6f 6f 67 6c 65 6d 61 69 6c 01 6c"; // answer: rdata googlemail.l.
+ $data .= "c0 11"; // answer: rdata offset pointer to google.com
+
+ $data = $this->convertTcpDumpToBinary($data);
+
+ $response = $this->parser->parseMessage($data);
+
+ $this->assertCount(1, $response->questions);
+ $this->assertSame('mail.google.com', $response->questions[0]['name']);
+ $this->assertSame(Message::TYPE_CNAME, $response->questions[0]['type']);
+ $this->assertSame(Message::CLASS_IN, $response->questions[0]['class']);
+
+ $this->assertCount(1, $response->answers);
+ $this->assertSame('mail.google.com', $response->answers[0]->name);
+ $this->assertSame(Message::TYPE_CNAME, $response->answers[0]->type);
+ $this->assertSame(Message::CLASS_IN, $response->answers[0]->class);
+ $this->assertSame(43164, $response->answers[0]->ttl);
+ $this->assertSame('googlemail.l.google.com', $response->answers[0]->data);
+ }
+
+ public function testParseAAAAResponse()
+ {
+ $data = "";
+ $data .= "cd 72 81 80 00 01 00 01 00 00 00 00 06"; // header
+ $data .= "67 6f 6f 67 6c 65 03 63 6f 6d 00"; // question: google.com
+ $data .= "00 1c 00 01"; // question: type AAAA, class IN
+ $data .= "c0 0c"; // answer: offset pointer to google.com
+ $data .= "00 1c 00 01"; // answer: type AAAA, class IN
+ $data .= "00 00 01 2b"; // answer: ttl 299
+ $data .= "00 10"; // answer: rdlength 16
+ $data .= "2a 00 14 50 40 09 08 09 00 00 00 00 00 00 20 0e"; // answer: 2a00:1450:4009:809::200e
+
+ $data = $this->convertTcpDumpToBinary($data);
+
+ $response = $this->parser->parseMessage($data);
+
+ $header = $response->header;
+ $this->assertSame(0xcd72, $header->get('id'));
+ $this->assertSame(1, $header->get('qdCount'));
+ $this->assertSame(1, $header->get('anCount'));
+ $this->assertSame(0, $header->get('nsCount'));
+ $this->assertSame(0, $header->get('arCount'));
+ $this->assertSame(1, $header->get('qr'));
+ $this->assertSame(Message::OPCODE_QUERY, $header->get('opcode'));
+ $this->assertSame(0, $header->get('aa'));
+ $this->assertSame(0, $header->get('tc'));
+ $this->assertSame(1, $header->get('rd'));
+ $this->assertSame(1, $header->get('ra'));
+ $this->assertSame(0, $header->get('z'));
+ $this->assertSame(Message::RCODE_OK, $header->get('rcode'));
+
+ $this->assertCount(1, $response->questions);
+ $this->assertSame('google.com', $response->questions[0]['name']);
+ $this->assertSame(Message::TYPE_AAAA, $response->questions[0]['type']);
+ $this->assertSame(Message::CLASS_IN, $response->questions[0]['class']);
+
+ $this->assertCount(1, $response->answers);
+ $this->assertSame('google.com', $response->answers[0]->name);
+ $this->assertSame(Message::TYPE_AAAA, $response->answers[0]->type);
+ $this->assertSame(Message::CLASS_IN, $response->answers[0]->class);
+ $this->assertSame(299, $response->answers[0]->ttl);
+ $this->assertSame('2a00:1450:4009:809::200e', $response->answers[0]->data);
+ }
+
+ public function testParseResponseWithTwoAnswers()
+ {
+ $data = "";
+ $data .= "bc 73 81 80 00 01 00 02 00 00 00 00"; // header
+ $data .= "02 69 6f 0d 77 68 6f 69 73 2d 73 65 72 76 65 72 73 03 6e 65 74 00";
+ // question: io.whois-servers.net
+ $data .= "00 01 00 01"; // question: type A, class IN
+ $data .= "c0 0c"; // answer: offset pointer to io.whois-servers.net
+ $data .= "00 05 00 01"; // answer: type CNAME, class IN
+ $data .= "00 00 00 29"; // answer: ttl 41
+ $data .= "00 0e"; // answer: rdlength 14
+ $data .= "05 77 68 6f 69 73 03 6e 69 63 02 69 6f 00"; // answer: rdata whois.nic.io
+ $data .= "c0 32"; // answer: offset pointer to whois.nic.io
+ $data .= "00 01 00 01"; // answer: type CNAME, class IN
+ $data .= "00 00 0d f7"; // answer: ttl 3575
+ $data .= "00 04"; // answer: rdlength 4
+ $data .= "c1 df 4e 98"; // answer: rdata 193.223.78.152
+
+ $data = $this->convertTcpDumpToBinary($data);
+
+ $response = $this->parser->parseMessage($data);
+
+ $this->assertCount(1, $response->questions);
+ $this->assertSame('io.whois-servers.net', $response->questions[0]['name']);
+ $this->assertSame(Message::TYPE_A, $response->questions[0]['type']);
+ $this->assertSame(Message::CLASS_IN, $response->questions[0]['class']);
+
+ $this->assertCount(2, $response->answers);
+
+ $this->assertSame('io.whois-servers.net', $response->answers[0]->name);
+ $this->assertSame(Message::TYPE_CNAME, $response->answers[0]->type);
+ $this->assertSame(Message::CLASS_IN, $response->answers[0]->class);
+ $this->assertSame(41, $response->answers[0]->ttl);
+ $this->assertSame('whois.nic.io', $response->answers[0]->data);
+
+ $this->assertSame('whois.nic.io', $response->answers[1]->name);
+ $this->assertSame(Message::TYPE_A, $response->answers[1]->type);
+ $this->assertSame(Message::CLASS_IN, $response->answers[1]->class);
+ $this->assertSame(3575, $response->answers[1]->ttl);
+ $this->assertSame('193.223.78.152', $response->answers[1]->data);
+ }
+
+ public function testParsePTRResponse()
+ {
+ $data = "";
+ $data .= "5d d8 81 80 00 01 00 01 00 00 00 00"; // header
+ $data .= "01 34 01 34 01 38 01 38 07 69 6e"; // question: 4.4.8.8.in-addr.arpa
+ $data .= "2d 61 64 64 72 04 61 72 70 61 00"; // question (continued)
+ $data .= "00 0c 00 01"; // question: type PTR, class IN
+ $data .= "c0 0c"; // answer: offset pointer to rdata
+ $data .= "00 0c 00 01"; // answer: type PTR, class IN
+ $data .= "00 01 51 7f"; // answer: ttl 86399
+ $data .= "00 20"; // answer: rdlength 32
+ $data .= "13 67 6f 6f 67 6c 65 2d 70 75 62 6c 69 63 2d 64"; // answer: rdata google-public-dns-b.google.com.
+ $data .= "6e 73 2d 62 06 67 6f 6f 67 6c 65 03 63 6f 6d 00";
+
+ $data = $this->convertTcpDumpToBinary($data);
+
+ $response = $this->parser->parseMessage($data);
+
+ $header = $response->header;
+ $this->assertSame(0x5dd8, $header->get('id'));
+ $this->assertSame(1, $header->get('qdCount'));
+ $this->assertSame(1, $header->get('anCount'));
+ $this->assertSame(0, $header->get('nsCount'));
+ $this->assertSame(0, $header->get('arCount'));
+ $this->assertSame(1, $header->get('qr'));
+ $this->assertSame(Message::OPCODE_QUERY, $header->get('opcode'));
+ $this->assertSame(0, $header->get('aa'));
+ $this->assertSame(0, $header->get('tc'));
+ $this->assertSame(1, $header->get('rd'));
+ $this->assertSame(1, $header->get('ra'));
+ $this->assertSame(0, $header->get('z'));
+ $this->assertSame(Message::RCODE_OK, $header->get('rcode'));
+
+ $this->assertCount(1, $response->questions);
+ $this->assertSame('4.4.8.8.in-addr.arpa', $response->questions[0]['name']);
+ $this->assertSame(Message::TYPE_PTR, $response->questions[0]['type']);
+ $this->assertSame(Message::CLASS_IN, $response->questions[0]['class']);
+
+ $this->assertCount(1, $response->answers);
+ $this->assertSame('4.4.8.8.in-addr.arpa', $response->answers[0]->name);
+ $this->assertSame(Message::TYPE_PTR, $response->answers[0]->type);
+ $this->assertSame(Message::CLASS_IN, $response->answers[0]->class);
+ $this->assertSame(86399, $response->answers[0]->ttl);
+ $this->assertSame('google-public-dns-b.google.com', $response->answers[0]->data);
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ public function testParseIncomplete()
+ {
+ $data = "";
+ $data .= "72 62 01 00 00 01 00 00 00 00 00 00"; // header
+ $data .= "04 69 67 6f 72 02 69 6f 00"; // question: igor.io
+ //$data .= "00 01 00 01"; // question: type A, class IN
+
+ $data = $this->convertTcpDumpToBinary($data);
+
+ $this->parser->parseMessage($data);
+ }
+
+ private function convertTcpDumpToBinary($input)
+ {
+ // sudo ngrep -d en1 -x port 53
+
+ return pack('H*', str_replace(' ', '', $input));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Query/CachedExecutorTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Query/CachedExecutorTest.php
new file mode 100644
index 0000000..d08ed05
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Query/CachedExecutorTest.php
@@ -0,0 +1,100 @@
+<?php
+
+namespace React\Tests\Dns\Query;
+
+use React\Tests\Dns\TestCase;
+use React\Dns\Query\CachedExecutor;
+use React\Dns\Query\Query;
+use React\Dns\Model\Message;
+use React\Dns\Model\Record;
+use React\Promise;
+
+class CachedExecutorTest extends TestCase
+{
+ /**
+ * @covers React\Dns\Query\CachedExecutor
+ * @test
+ */
+ public function queryShouldDelegateToDecoratedExecutor()
+ {
+ $executor = $this->createExecutorMock();
+ $executor
+ ->expects($this->once())
+ ->method('query')
+ ->with('8.8.8.8', $this->isInstanceOf('React\Dns\Query\Query'))
+ ->will($this->returnValue($this->createPromiseMock()));
+
+ $cache = $this->getMockBuilder('React\Dns\Query\RecordCache')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $cache
+ ->expects($this->once())
+ ->method('lookup')
+ ->will($this->returnValue(Promise\reject()));
+ $cachedExecutor = new CachedExecutor($executor, $cache);
+
+ $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN, 1345656451);
+ $cachedExecutor->query('8.8.8.8', $query);
+ }
+
+ /**
+ * @covers React\Dns\Query\CachedExecutor
+ * @test
+ */
+ public function callingQueryTwiceShouldUseCachedResult()
+ {
+ $cachedRecords = array(new Record('igor.io', Message::TYPE_A, Message::CLASS_IN));
+
+ $executor = $this->createExecutorMock();
+ $executor
+ ->expects($this->once())
+ ->method('query')
+ ->will($this->callQueryCallbackWithAddress('178.79.169.131'));
+
+ $cache = $this->getMockBuilder('React\Dns\Query\RecordCache')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $cache
+ ->expects($this->at(0))
+ ->method('lookup')
+ ->with($this->isInstanceOf('React\Dns\Query\Query'))
+ ->will($this->returnValue(Promise\reject()));
+ $cache
+ ->expects($this->at(1))
+ ->method('storeResponseMessage')
+ ->with($this->isType('integer'), $this->isInstanceOf('React\Dns\Model\Message'));
+ $cache
+ ->expects($this->at(2))
+ ->method('lookup')
+ ->with($this->isInstanceOf('React\Dns\Query\Query'))
+ ->will($this->returnValue(Promise\resolve($cachedRecords)));
+
+ $cachedExecutor = new CachedExecutor($executor, $cache);
+
+ $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN, 1345656451);
+ $cachedExecutor->query('8.8.8.8', $query, function () {}, function () {});
+ $cachedExecutor->query('8.8.8.8', $query, function () {}, function () {});
+ }
+
+ private function callQueryCallbackWithAddress($address)
+ {
+ return $this->returnCallback(function ($nameserver, $query) use ($address) {
+ $response = new Message();
+ $response->header->set('qr', 1);
+ $response->questions[] = new Record($query->name, $query->type, $query->class);
+ $response->answers[] = new Record($query->name, $query->type, $query->class, 3600, $address);
+
+ return Promise\resolve($response);
+ });
+ }
+
+ private function createExecutorMock()
+ {
+ return $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock();
+ }
+
+ private function createPromiseMock()
+ {
+ return $this->getMockBuilder('React\Promise\PromiseInterface')->getMock();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Query/ExecutorTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Query/ExecutorTest.php
new file mode 100644
index 0000000..0d7ac1d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Query/ExecutorTest.php
@@ -0,0 +1,308 @@
+<?php
+
+namespace React\Tests\Dns\Query;
+
+use Clue\React\Block;
+use React\Dns\Query\Executor;
+use React\Dns\Query\Query;
+use React\Dns\Model\Message;
+use React\Dns\Model\Record;
+use React\Dns\Protocol\BinaryDumper;
+use React\Tests\Dns\TestCase;
+
+class ExecutorTest extends TestCase
+{
+ private $loop;
+ private $parser;
+ private $dumper;
+ private $executor;
+
+ public function setUp()
+ {
+ $this->loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ $this->parser = $this->getMockBuilder('React\Dns\Protocol\Parser')->getMock();
+ $this->dumper = new BinaryDumper();
+
+ $this->executor = new Executor($this->loop, $this->parser, $this->dumper);
+ }
+
+ /** @test */
+ public function queryShouldCreateUdpRequest()
+ {
+ $timer = $this->createTimerMock();
+ $this->loop
+ ->expects($this->any())
+ ->method('addTimer')
+ ->will($this->returnValue($timer));
+
+ $this->executor = $this->createExecutorMock();
+ $this->executor
+ ->expects($this->once())
+ ->method('createConnection')
+ ->with('8.8.8.8:53', 'udp')
+ ->will($this->returnNewConnectionMock(false));
+
+ $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN, 1345656451);
+ $this->executor->query('8.8.8.8:53', $query);
+ }
+
+ /** @test */
+ public function resolveShouldRejectIfRequestIsLargerThan512Bytes()
+ {
+ $query = new Query(str_repeat('a', 512).'.igor.io', Message::TYPE_A, Message::CLASS_IN, 1345656451);
+ $promise = $this->executor->query('8.8.8.8:53', $query);
+
+ $this->setExpectedException('RuntimeException', 'DNS query for ' . $query->name . ' failed: Requested transport "tcp" not available, only UDP is supported in this version');
+ Block\await($promise, $this->loop);
+ }
+
+ /** @test */
+ public function resolveShouldCloseConnectionWhenCancelled()
+ {
+ $conn = $this->createConnectionMock(false);
+ $conn->expects($this->once())->method('close');
+
+ $timer = $this->createTimerMock();
+ $this->loop
+ ->expects($this->any())
+ ->method('addTimer')
+ ->will($this->returnValue($timer));
+
+ $this->executor = $this->createExecutorMock();
+ $this->executor
+ ->expects($this->once())
+ ->method('createConnection')
+ ->with('8.8.8.8:53', 'udp')
+ ->will($this->returnValue($conn));
+
+ $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN, 1345656451);
+ $promise = $this->executor->query('8.8.8.8:53', $query);
+
+ $promise->cancel();
+
+ $this->setExpectedException('React\Dns\Query\CancellationException', 'DNS query for igor.io has been cancelled');
+ Block\await($promise, $this->loop);
+ }
+
+ /** @test */
+ public function resolveShouldNotStartOrCancelTimerWhenCancelledWithTimeoutIsNull()
+ {
+ $this->loop
+ ->expects($this->never())
+ ->method('addTimer');
+
+ $this->executor = new Executor($this->loop, $this->parser, $this->dumper, null);
+
+ $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN, 1345656451);
+ $promise = $this->executor->query('127.0.0.1:53', $query);
+
+ $promise->cancel();
+
+ $this->setExpectedException('React\Dns\Query\CancellationException', 'DNS query for igor.io has been cancelled');
+ Block\await($promise, $this->loop);
+ }
+
+ /** @test */
+ public function resolveShouldRejectIfResponseIsTruncated()
+ {
+ $timer = $this->createTimerMock();
+
+ $this->loop
+ ->expects($this->any())
+ ->method('addTimer')
+ ->will($this->returnValue($timer));
+
+ $this->parser
+ ->expects($this->once())
+ ->method('parseMessage')
+ ->will($this->returnTruncatedResponse());
+
+ $this->executor = $this->createExecutorMock();
+ $this->executor
+ ->expects($this->once())
+ ->method('createConnection')
+ ->with('8.8.8.8:53', 'udp')
+ ->will($this->returnNewConnectionMock());
+
+ $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN, 1345656451);
+ $this->executor->query('8.8.8.8:53', $query);
+ }
+
+ /** @test */
+ public function resolveShouldFailIfUdpThrow()
+ {
+ $this->loop
+ ->expects($this->never())
+ ->method('addTimer');
+
+ $this->parser
+ ->expects($this->never())
+ ->method('parseMessage');
+
+ $this->executor = $this->createExecutorMock();
+ $this->executor
+ ->expects($this->once())
+ ->method('createConnection')
+ ->with('8.8.8.8:53', 'udp')
+ ->will($this->throwException(new \Exception('Nope')));
+
+ $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN, 1345656451);
+ $promise = $this->executor->query('8.8.8.8:53', $query);
+
+ $this->setExpectedException('RuntimeException', 'DNS query for igor.io failed: Nope');
+ Block\await($promise, $this->loop);
+ }
+
+ /** @test */
+ public function resolveShouldCancelTimerWhenFullResponseIsReceived()
+ {
+ $conn = $this->createConnectionMock();
+
+ $this->parser
+ ->expects($this->once())
+ ->method('parseMessage')
+ ->will($this->returnStandardResponse());
+
+ $this->executor = $this->createExecutorMock();
+ $this->executor
+ ->expects($this->at(0))
+ ->method('createConnection')
+ ->with('8.8.8.8:53', 'udp')
+ ->will($this->returnNewConnectionMock());
+
+
+ $timer = $this->createTimerMock();
+
+ $this->loop
+ ->expects($this->once())
+ ->method('addTimer')
+ ->with(5, $this->isInstanceOf('Closure'))
+ ->will($this->returnValue($timer));
+
+ $this->loop
+ ->expects($this->once())
+ ->method('cancelTimer')
+ ->with($timer);
+
+ $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN, 1345656451);
+ $this->executor->query('8.8.8.8:53', $query);
+ }
+
+ /** @test */
+ public function resolveShouldCloseConnectionOnTimeout()
+ {
+ $this->executor = $this->createExecutorMock();
+ $this->executor
+ ->expects($this->at(0))
+ ->method('createConnection')
+ ->with('8.8.8.8:53', 'udp')
+ ->will($this->returnNewConnectionMock(false));
+
+ $timer = $this->createTimerMock();
+
+ $this->loop
+ ->expects($this->never())
+ ->method('cancelTimer');
+
+ $this->loop
+ ->expects($this->once())
+ ->method('addTimer')
+ ->with(5, $this->isInstanceOf('Closure'))
+ ->will($this->returnCallback(function ($time, $callback) use (&$timerCallback, $timer) {
+ $timerCallback = $callback;
+ return $timer;
+ }));
+
+ $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN, 1345656451);
+ $promise = $this->executor->query('8.8.8.8:53', $query);
+
+ $this->assertNotNull($timerCallback);
+ $timerCallback();
+
+ $this->setExpectedException('React\Dns\Query\TimeoutException', 'DNS query for igor.io timed out');
+ Block\await($promise, $this->loop);
+ }
+
+ private function returnStandardResponse()
+ {
+ $that = $this;
+ $callback = function ($data) use ($that) {
+ $response = new Message();
+ $that->convertMessageToStandardResponse($response);
+ return $response;
+ };
+
+ return $this->returnCallback($callback);
+ }
+
+ private function returnTruncatedResponse()
+ {
+ $that = $this;
+ $callback = function ($data) use ($that) {
+ $response = new Message();
+ $that->convertMessageToTruncatedResponse($response);
+ return $response;
+ };
+
+ return $this->returnCallback($callback);
+ }
+
+ public function convertMessageToStandardResponse(Message $response)
+ {
+ $response->header->set('qr', 1);
+ $response->questions[] = new Record('igor.io', Message::TYPE_A, Message::CLASS_IN);
+ $response->answers[] = new Record('igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131');
+ $response->prepare();
+
+ return $response;
+ }
+
+ public function convertMessageToTruncatedResponse(Message $response)
+ {
+ $this->convertMessageToStandardResponse($response);
+ $response->header->set('tc', 1);
+ $response->prepare();
+
+ return $response;
+ }
+
+ private function returnNewConnectionMock($emitData = true)
+ {
+ $conn = $this->createConnectionMock($emitData);
+
+ $callback = function () use ($conn) {
+ return $conn;
+ };
+
+ return $this->returnCallback($callback);
+ }
+
+ private function createConnectionMock($emitData = true)
+ {
+ $conn = $this->getMockBuilder('React\Stream\DuplexStreamInterface')->getMock();
+ $conn
+ ->expects($this->any())
+ ->method('on')
+ ->with('data', $this->isInstanceOf('Closure'))
+ ->will($this->returnCallback(function ($name, $callback) use ($emitData) {
+ $emitData && $callback(null);
+ }));
+
+ return $conn;
+ }
+
+ private function createTimerMock()
+ {
+ return $this->getMockBuilder(
+ interface_exists('React\EventLoop\TimerInterface') ? 'React\EventLoop\TimerInterface' : 'React\EventLoop\Timer\TimerInterface'
+ )->getMock();
+ }
+
+ private function createExecutorMock()
+ {
+ return $this->getMockBuilder('React\Dns\Query\Executor')
+ ->setConstructorArgs(array($this->loop, $this->parser, $this->dumper))
+ ->setMethods(array('createConnection'))
+ ->getMock();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Query/HostsFileExecutorTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Query/HostsFileExecutorTest.php
new file mode 100644
index 0000000..70d877e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Query/HostsFileExecutorTest.php
@@ -0,0 +1,126 @@
+<?php
+
+namespace React\Tests\Dns\Query;
+
+use React\Tests\Dns\TestCase;
+use React\Dns\Query\HostsFileExecutor;
+use React\Dns\Query\Query;
+use React\Dns\Model\Message;
+
+class HostsFileExecutorTest extends TestCase
+{
+ private $hosts;
+ private $fallback;
+ private $executor;
+
+ public function setUp()
+ {
+ $this->hosts = $this->getMockBuilder('React\Dns\Config\HostsFile')->disableOriginalConstructor()->getMock();
+ $this->fallback = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock();
+ $this->executor = new HostsFileExecutor($this->hosts, $this->fallback);
+ }
+
+ public function testDoesNotTryToGetIpsForMxQuery()
+ {
+ $this->hosts->expects($this->never())->method('getIpsForHost');
+ $this->fallback->expects($this->once())->method('query');
+
+ $this->executor->query('8.8.8.8', new Query('google.com', Message::TYPE_MX, Message::CLASS_IN, 0));
+ }
+
+ public function testFallsBackIfNoIpsWereFound()
+ {
+ $this->hosts->expects($this->once())->method('getIpsForHost')->willReturn(array());
+ $this->fallback->expects($this->once())->method('query');
+
+ $this->executor->query('8.8.8.8', new Query('google.com', Message::TYPE_A, Message::CLASS_IN, 0));
+ }
+
+ public function testReturnsResponseMessageIfIpsWereFound()
+ {
+ $this->hosts->expects($this->once())->method('getIpsForHost')->willReturn(array('127.0.0.1'));
+ $this->fallback->expects($this->never())->method('query');
+
+ $ret = $this->executor->query('8.8.8.8', new Query('google.com', Message::TYPE_A, Message::CLASS_IN, 0));
+ }
+
+ public function testFallsBackIfNoIpv4Matches()
+ {
+ $this->hosts->expects($this->once())->method('getIpsForHost')->willReturn(array('::1'));
+ $this->fallback->expects($this->once())->method('query');
+
+ $ret = $this->executor->query('8.8.8.8', new Query('google.com', Message::TYPE_A, Message::CLASS_IN, 0));
+ }
+
+ public function testReturnsResponseMessageIfIpv6AddressesWereFound()
+ {
+ $this->hosts->expects($this->once())->method('getIpsForHost')->willReturn(array('::1'));
+ $this->fallback->expects($this->never())->method('query');
+
+ $ret = $this->executor->query('8.8.8.8', new Query('google.com', Message::TYPE_AAAA, Message::CLASS_IN, 0));
+ }
+
+ public function testFallsBackIfNoIpv6Matches()
+ {
+ $this->hosts->expects($this->once())->method('getIpsForHost')->willReturn(array('127.0.0.1'));
+ $this->fallback->expects($this->once())->method('query');
+
+ $ret = $this->executor->query('8.8.8.8', new Query('google.com', Message::TYPE_AAAA, Message::CLASS_IN, 0));
+ }
+
+ public function testDoesReturnReverseIpv4Lookup()
+ {
+ $this->hosts->expects($this->once())->method('getHostsForIp')->with('127.0.0.1')->willReturn(array('localhost'));
+ $this->fallback->expects($this->never())->method('query');
+
+ $this->executor->query('8.8.8.8', new Query('1.0.0.127.in-addr.arpa', Message::TYPE_PTR, Message::CLASS_IN, 0));
+ }
+
+ public function testFallsBackIfNoReverseIpv4Matches()
+ {
+ $this->hosts->expects($this->once())->method('getHostsForIp')->with('127.0.0.1')->willReturn(array());
+ $this->fallback->expects($this->once())->method('query');
+
+ $this->executor->query('8.8.8.8', new Query('1.0.0.127.in-addr.arpa', Message::TYPE_PTR, Message::CLASS_IN, 0));
+ }
+
+ public function testDoesReturnReverseIpv6Lookup()
+ {
+ $this->hosts->expects($this->once())->method('getHostsForIp')->with('2a02:2e0:3fe:100::6')->willReturn(array('ip6-localhost'));
+ $this->fallback->expects($this->never())->method('query');
+
+ $this->executor->query('8.8.8.8', new Query('6.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.e.f.3.0.0.e.2.0.2.0.a.2.ip6.arpa', Message::TYPE_PTR, Message::CLASS_IN, 0));
+ }
+
+ public function testFallsBackForInvalidAddress()
+ {
+ $this->hosts->expects($this->never())->method('getHostsForIp');
+ $this->fallback->expects($this->once())->method('query');
+
+ $this->executor->query('8.8.8.8', new Query('example.com', Message::TYPE_PTR, Message::CLASS_IN, 0));
+ }
+
+ public function testReverseFallsBackForInvalidIpv4Address()
+ {
+ $this->hosts->expects($this->never())->method('getHostsForIp');
+ $this->fallback->expects($this->once())->method('query');
+
+ $this->executor->query('8.8.8.8', new Query('::1.in-addr.arpa', Message::TYPE_PTR, Message::CLASS_IN, 0));
+ }
+
+ public function testReverseFallsBackForInvalidLengthIpv6Address()
+ {
+ $this->hosts->expects($this->never())->method('getHostsForIp');
+ $this->fallback->expects($this->once())->method('query');
+
+ $this->executor->query('8.8.8.8', new Query('abcd.ip6.arpa', Message::TYPE_PTR, Message::CLASS_IN, 0));
+ }
+
+ public function testReverseFallsBackForInvalidHexIpv6Address()
+ {
+ $this->hosts->expects($this->never())->method('getHostsForIp');
+ $this->fallback->expects($this->once())->method('query');
+
+ $this->executor->query('8.8.8.8', new Query('zZz.ip6.arpa', Message::TYPE_PTR, Message::CLASS_IN, 0));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Query/RecordBagTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Query/RecordBagTest.php
new file mode 100644
index 0000000..83b8934
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Query/RecordBagTest.php
@@ -0,0 +1,64 @@
+<?php
+
+namespace React\Tests\Dns\Query;
+
+use PHPUnit\Framework\TestCase;
+use React\Dns\Query\RecordBag;
+use React\Dns\Model\Message;
+use React\Dns\Model\Record;
+
+class RecordBagTest extends TestCase
+{
+ /**
+ * @covers React\Dns\Query\RecordBag
+ * @test
+ */
+ public function emptyBagShouldBeEmpty()
+ {
+ $recordBag = new RecordBag();
+
+ $this->assertSame(array(), $recordBag->all());
+ }
+
+ /**
+ * @covers React\Dns\Query\RecordBag
+ * @test
+ */
+ public function setShouldSetTheValue()
+ {
+ $currentTime = 1345656451;
+
+ $recordBag = new RecordBag();
+ $recordBag->set($currentTime, new Record('igor.io', Message::TYPE_A, Message::CLASS_IN, 3600));
+
+ $records = $recordBag->all();
+ $this->assertCount(1, $records);
+ $this->assertSame('igor.io', $records[0]->name);
+ $this->assertSame(Message::TYPE_A, $records[0]->type);
+ $this->assertSame(Message::CLASS_IN, $records[0]->class);
+ }
+
+ /**
+ * @covers React\Dns\Query\RecordBag
+ * @test
+ */
+ public function setShouldSetManyValues()
+ {
+ $currentTime = 1345656451;
+
+ $recordBag = new RecordBag();
+ $recordBag->set($currentTime, new Record('igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131'));
+ $recordBag->set($currentTime, new Record('igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.132'));
+
+ $records = $recordBag->all();
+ $this->assertCount(2, $records);
+ $this->assertSame('igor.io', $records[0]->name);
+ $this->assertSame(Message::TYPE_A, $records[0]->type);
+ $this->assertSame(Message::CLASS_IN, $records[0]->class);
+ $this->assertSame('178.79.169.131', $records[0]->data);
+ $this->assertSame('igor.io', $records[1]->name);
+ $this->assertSame(Message::TYPE_A, $records[1]->type);
+ $this->assertSame(Message::CLASS_IN, $records[1]->class);
+ $this->assertSame('178.79.169.132', $records[1]->data);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Query/RecordCacheTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Query/RecordCacheTest.php
new file mode 100644
index 0000000..399fbe8
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Query/RecordCacheTest.php
@@ -0,0 +1,123 @@
+<?php
+
+namespace React\Tests\Dns\Query;
+
+use PHPUnit\Framework\TestCase;
+use React\Cache\ArrayCache;
+use React\Dns\Model\Message;
+use React\Dns\Model\Record;
+use React\Dns\Query\RecordCache;
+use React\Dns\Query\Query;
+use React\Promise\PromiseInterface;
+
+class RecordCacheTest extends TestCase
+{
+ /**
+ * @covers React\Dns\Query\RecordCache
+ * @test
+ */
+ public function lookupOnEmptyCacheShouldReturnNull()
+ {
+ $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN, 1345656451);
+
+ $cache = new RecordCache(new ArrayCache());
+ $promise = $cache->lookup($query);
+
+ $this->assertInstanceOf('React\Promise\RejectedPromise', $promise);
+ }
+
+ /**
+ * @covers React\Dns\Query\RecordCache
+ * @test
+ */
+ public function storeRecordShouldMakeLookupSucceed()
+ {
+ $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN, 1345656451);
+
+ $cache = new RecordCache(new ArrayCache());
+ $cache->storeRecord($query->currentTime, new Record('igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131'));
+ $promise = $cache->lookup($query);
+
+ $this->assertInstanceOf('React\Promise\FulfilledPromise', $promise);
+ $cachedRecords = $this->getPromiseValue($promise);
+
+ $this->assertCount(1, $cachedRecords);
+ $this->assertSame('178.79.169.131', $cachedRecords[0]->data);
+ }
+
+ /**
+ * @covers React\Dns\Query\RecordCache
+ * @test
+ */
+ public function storeTwoRecordsShouldReturnBoth()
+ {
+ $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN, 1345656451);
+
+ $cache = new RecordCache(new ArrayCache());
+ $cache->storeRecord($query->currentTime, new Record('igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131'));
+ $cache->storeRecord($query->currentTime, new Record('igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.132'));
+ $promise = $cache->lookup($query);
+
+ $this->assertInstanceOf('React\Promise\FulfilledPromise', $promise);
+ $cachedRecords = $this->getPromiseValue($promise);
+
+ $this->assertCount(2, $cachedRecords);
+ $this->assertSame('178.79.169.131', $cachedRecords[0]->data);
+ $this->assertSame('178.79.169.132', $cachedRecords[1]->data);
+ }
+
+ /**
+ * @covers React\Dns\Query\RecordCache
+ * @test
+ */
+ public function storeResponseMessageShouldStoreAllAnswerValues()
+ {
+ $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN, 1345656451);
+
+ $response = new Message();
+ $response->answers[] = new Record('igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131');
+ $response->answers[] = new Record('igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.132');
+ $response->prepare();
+
+ $cache = new RecordCache(new ArrayCache());
+ $cache->storeResponseMessage($query->currentTime, $response);
+ $promise = $cache->lookup($query);
+
+ $this->assertInstanceOf('React\Promise\FulfilledPromise', $promise);
+ $cachedRecords = $this->getPromiseValue($promise);
+
+ $this->assertCount(2, $cachedRecords);
+ $this->assertSame('178.79.169.131', $cachedRecords[0]->data);
+ $this->assertSame('178.79.169.132', $cachedRecords[1]->data);
+ }
+
+ /**
+ * @covers React\Dns\Query\RecordCache
+ * @test
+ */
+ public function expireShouldExpireDeadRecords()
+ {
+ $cachedTime = 1345656451;
+ $currentTime = $cachedTime + 3605;
+
+ $cache = new RecordCache(new ArrayCache());
+ $cache->storeRecord($cachedTime, new Record('igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131'));
+ $cache->expire($currentTime);
+
+ $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN, $currentTime);
+ $promise = $cache->lookup($query);
+
+ $this->assertInstanceOf('React\Promise\RejectedPromise', $promise);
+ }
+
+ private function getPromiseValue(PromiseInterface $promise)
+ {
+ $capturedValue = null;
+
+ $promise->then(function ($value) use (&$capturedValue) {
+ $capturedValue = $value;
+ });
+
+ return $capturedValue;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Query/RetryExecutorTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Query/RetryExecutorTest.php
new file mode 100644
index 0000000..8950f84
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Query/RetryExecutorTest.php
@@ -0,0 +1,197 @@
+<?php
+
+namespace React\Tests\Dns\Query;
+
+use React\Tests\Dns\TestCase;
+use React\Dns\Query\RetryExecutor;
+use React\Dns\Query\Query;
+use React\Dns\Model\Message;
+use React\Dns\Query\TimeoutException;
+use React\Dns\Model\Record;
+use React\Promise;
+use React\Promise\Deferred;
+use React\Dns\Query\CancellationException;
+
+class RetryExecutorTest extends TestCase
+{
+ /**
+ * @covers React\Dns\Query\RetryExecutor
+ * @test
+ */
+ public function queryShouldDelegateToDecoratedExecutor()
+ {
+ $executor = $this->createExecutorMock();
+ $executor
+ ->expects($this->once())
+ ->method('query')
+ ->with('8.8.8.8', $this->isInstanceOf('React\Dns\Query\Query'))
+ ->will($this->returnValue($this->expectPromiseOnce()));
+
+ $retryExecutor = new RetryExecutor($executor, 2);
+
+ $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN, 1345656451);
+ $retryExecutor->query('8.8.8.8', $query);
+ }
+
+ /**
+ * @covers React\Dns\Query\RetryExecutor
+ * @test
+ */
+ public function queryShouldRetryQueryOnTimeout()
+ {
+ $response = $this->createStandardResponse();
+
+ $executor = $this->createExecutorMock();
+ $executor
+ ->expects($this->exactly(2))
+ ->method('query')
+ ->with('8.8.8.8', $this->isInstanceOf('React\Dns\Query\Query'))
+ ->will($this->onConsecutiveCalls(
+ $this->returnCallback(function ($domain, $query) {
+ return Promise\reject(new TimeoutException("timeout"));
+ }),
+ $this->returnCallback(function ($domain, $query) use ($response) {
+ return Promise\resolve($response);
+ })
+ ));
+
+ $callback = $this->createCallableMock();
+ $callback
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->isInstanceOf('React\Dns\Model\Message'));
+
+ $errorback = $this->expectCallableNever();
+
+ $retryExecutor = new RetryExecutor($executor, 2);
+
+ $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN, 1345656451);
+ $retryExecutor->query('8.8.8.8', $query)->then($callback, $errorback);
+ }
+
+ /**
+ * @covers React\Dns\Query\RetryExecutor
+ * @test
+ */
+ public function queryShouldStopRetryingAfterSomeAttempts()
+ {
+ $executor = $this->createExecutorMock();
+ $executor
+ ->expects($this->exactly(3))
+ ->method('query')
+ ->with('8.8.8.8', $this->isInstanceOf('React\Dns\Query\Query'))
+ ->will($this->returnCallback(function ($domain, $query) {
+ return Promise\reject(new TimeoutException("timeout"));
+ }));
+
+ $callback = $this->expectCallableNever();
+
+ $errorback = $this->createCallableMock();
+ $errorback
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->isInstanceOf('RuntimeException'));
+
+ $retryExecutor = new RetryExecutor($executor, 2);
+
+ $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN, 1345656451);
+ $retryExecutor->query('8.8.8.8', $query)->then($callback, $errorback);
+ }
+
+ /**
+ * @covers React\Dns\Query\RetryExecutor
+ * @test
+ */
+ public function queryShouldForwardNonTimeoutErrors()
+ {
+ $executor = $this->createExecutorMock();
+ $executor
+ ->expects($this->once())
+ ->method('query')
+ ->with('8.8.8.8', $this->isInstanceOf('React\Dns\Query\Query'))
+ ->will($this->returnCallback(function ($domain, $query) {
+ return Promise\reject(new \Exception);
+ }));
+
+ $callback = $this->expectCallableNever();
+
+ $errorback = $this->createCallableMock();
+ $errorback
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->isInstanceOf('Exception'));
+
+ $retryExecutor = new RetryExecutor($executor, 2);
+
+ $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN, 1345656451);
+ $retryExecutor->query('8.8.8.8', $query)->then($callback, $errorback);
+ }
+
+ /**
+ * @covers React\Dns\Query\RetryExecutor
+ * @test
+ */
+ public function queryShouldCancelQueryOnCancel()
+ {
+ $cancelled = 0;
+
+ $executor = $this->createExecutorMock();
+ $executor
+ ->expects($this->once())
+ ->method('query')
+ ->with('8.8.8.8', $this->isInstanceOf('React\Dns\Query\Query'))
+ ->will($this->returnCallback(function ($domain, $query) use (&$cancelled) {
+ $deferred = new Deferred(function ($resolve, $reject) use (&$cancelled) {
+ ++$cancelled;
+ $reject(new CancellationException('Cancelled'));
+ });
+
+ return $deferred->promise();
+ })
+ );
+
+ $retryExecutor = new RetryExecutor($executor, 2);
+
+ $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN, 1345656451);
+ $promise = $retryExecutor->query('8.8.8.8', $query);
+
+ $promise->then($this->expectCallableNever(), $this->expectCallableOnce());
+
+ $this->assertEquals(0, $cancelled);
+ $promise->cancel();
+ $this->assertEquals(1, $cancelled);
+ }
+
+ protected function expectPromiseOnce($return = null)
+ {
+ $mock = $this->createPromiseMock();
+ $mock
+ ->expects($this->once())
+ ->method('then')
+ ->will($this->returnValue($return));
+
+ return $mock;
+ }
+
+ protected function createExecutorMock()
+ {
+ return $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock();
+ }
+
+ protected function createPromiseMock()
+ {
+ return $this->getMockBuilder('React\Promise\PromiseInterface')->getMock();
+ }
+
+ protected function createStandardResponse()
+ {
+ $response = new Message();
+ $response->header->set('qr', 1);
+ $response->questions[] = new Record('igor.io', Message::TYPE_A, Message::CLASS_IN);
+ $response->answers[] = new Record('igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131');
+ $response->prepare();
+
+ return $response;
+ }
+}
+
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Query/TimeoutExecutorTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Query/TimeoutExecutorTest.php
new file mode 100644
index 0000000..0d37fb4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Query/TimeoutExecutorTest.php
@@ -0,0 +1,115 @@
+<?php
+
+namespace React\Tests\Dns\Query;
+
+use React\Dns\Query\TimeoutExecutor;
+use React\Dns\Query\Query;
+use React\Dns\Model\Message;
+use React\Promise\Deferred;
+use React\Dns\Query\CancellationException;
+use React\Tests\Dns\TestCase;
+use React\EventLoop\Factory;
+use React\Promise;
+
+class TimeoutExecutorTest extends TestCase
+{
+ public function setUp()
+ {
+ $this->loop = Factory::create();
+
+ $this->wrapped = $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock();
+
+ $this->executor = new TimeoutExecutor($this->wrapped, 5.0, $this->loop);
+ }
+
+ public function testCancellingPromiseWillCancelWrapped()
+ {
+ $cancelled = 0;
+
+ $this->wrapped
+ ->expects($this->once())
+ ->method('query')
+ ->will($this->returnCallback(function ($domain, $query) use (&$cancelled) {
+ $deferred = new Deferred(function ($resolve, $reject) use (&$cancelled) {
+ ++$cancelled;
+ $reject(new CancellationException('Cancelled'));
+ });
+
+ return $deferred->promise();
+ }));
+
+ $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN, 1345656451);
+ $promise = $this->executor->query('8.8.8.8:53', $query);
+
+ $this->assertEquals(0, $cancelled);
+ $promise->cancel();
+ $this->assertEquals(1, $cancelled);
+
+ $promise->then($this->expectCallableNever(), $this->expectCallableOnce());
+ }
+
+ public function testResolvesPromiseWhenWrappedResolves()
+ {
+ $this->wrapped
+ ->expects($this->once())
+ ->method('query')
+ ->willReturn(Promise\resolve('0.0.0.0'));
+
+ $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN, 1345656451);
+ $promise = $this->executor->query('8.8.8.8:53', $query);
+
+ $promise->then($this->expectCallableOnce(), $this->expectCallableNever());
+ }
+
+ public function testRejectsPromiseWhenWrappedRejects()
+ {
+ $this->wrapped
+ ->expects($this->once())
+ ->method('query')
+ ->willReturn(Promise\reject(new \RuntimeException()));
+
+ $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN, 1345656451);
+ $promise = $this->executor->query('8.8.8.8:53', $query);
+
+ $promise->then($this->expectCallableNever(), $this->expectCallableOnceWith(new \RuntimeException()));
+ }
+
+ public function testWrappedWillBeCancelledOnTimeout()
+ {
+ $this->executor = new TimeoutExecutor($this->wrapped, 0, $this->loop);
+
+ $cancelled = 0;
+
+ $this->wrapped
+ ->expects($this->once())
+ ->method('query')
+ ->will($this->returnCallback(function ($domain, $query) use (&$cancelled) {
+ $deferred = new Deferred(function ($resolve, $reject) use (&$cancelled) {
+ ++$cancelled;
+ $reject(new CancellationException('Cancelled'));
+ });
+
+ return $deferred->promise();
+ }));
+
+ $callback = $this->expectCallableNever();
+
+ $errorback = $this->createCallableMock();
+ $errorback
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->logicalAnd(
+ $this->isInstanceOf('React\Dns\Query\TimeoutException'),
+ $this->attribute($this->equalTo('DNS query for igor.io timed out'), 'message')
+ ));
+
+ $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN, 1345656451);
+ $this->executor->query('8.8.8.8:53', $query)->then($callback, $errorback);
+
+ $this->assertEquals(0, $cancelled);
+
+ $this->loop->run();
+
+ $this->assertEquals(1, $cancelled);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Resolver/FactoryTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Resolver/FactoryTest.php
new file mode 100644
index 0000000..acaeac0
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Resolver/FactoryTest.php
@@ -0,0 +1,131 @@
+<?php
+
+namespace React\Tests\Dns\Resolver;
+
+use React\Dns\Resolver\Factory;
+use React\Tests\Dns\TestCase;
+use React\Dns\Query\HostsFileExecutor;
+
+class FactoryTest extends TestCase
+{
+ /** @test */
+ public function createShouldCreateResolver()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+
+ $factory = new Factory();
+ $resolver = $factory->create('8.8.8.8:53', $loop);
+
+ $this->assertInstanceOf('React\Dns\Resolver\Resolver', $resolver);
+ }
+
+ /** @test */
+ public function createWithoutPortShouldCreateResolverWithDefaultPort()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+
+ $factory = new Factory();
+ $resolver = $factory->create('8.8.8.8', $loop);
+
+ $this->assertInstanceOf('React\Dns\Resolver\Resolver', $resolver);
+ $this->assertSame('8.8.8.8:53', $this->getResolverPrivateMemberValue($resolver, 'nameserver'));
+ }
+
+ /** @test */
+ public function createCachedShouldCreateResolverWithCachedExecutor()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+
+ $factory = new Factory();
+ $resolver = $factory->createCached('8.8.8.8:53', $loop);
+
+ $this->assertInstanceOf('React\Dns\Resolver\Resolver', $resolver);
+ $executor = $this->getResolverPrivateExecutor($resolver);
+ $this->assertInstanceOf('React\Dns\Query\CachedExecutor', $executor);
+ $recordCache = $this->getCachedExecutorPrivateMemberValue($executor, 'cache');
+ $recordCacheCache = $this->getRecordCachePrivateMemberValue($recordCache, 'cache');
+ $this->assertInstanceOf('React\Cache\CacheInterface', $recordCacheCache);
+ $this->assertInstanceOf('React\Cache\ArrayCache', $recordCacheCache);
+ }
+
+ /** @test */
+ public function createCachedShouldCreateResolverWithCachedExecutorWithCustomCache()
+ {
+ $cache = $this->getMockBuilder('React\Cache\CacheInterface')->getMock();
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+
+ $factory = new Factory();
+ $resolver = $factory->createCached('8.8.8.8:53', $loop, $cache);
+
+ $this->assertInstanceOf('React\Dns\Resolver\Resolver', $resolver);
+ $executor = $this->getResolverPrivateExecutor($resolver);
+ $this->assertInstanceOf('React\Dns\Query\CachedExecutor', $executor);
+ $recordCache = $this->getCachedExecutorPrivateMemberValue($executor, 'cache');
+ $recordCacheCache = $this->getRecordCachePrivateMemberValue($recordCache, 'cache');
+ $this->assertInstanceOf('React\Cache\CacheInterface', $recordCacheCache);
+ $this->assertSame($cache, $recordCacheCache);
+ }
+
+ /**
+ * @test
+ * @dataProvider factoryShouldAddDefaultPortProvider
+ */
+ public function factoryShouldAddDefaultPort($input, $expected)
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+
+ $factory = new Factory();
+ $resolver = $factory->create($input, $loop);
+
+ $this->assertInstanceOf('React\Dns\Resolver\Resolver', $resolver);
+ $this->assertSame($expected, $this->getResolverPrivateMemberValue($resolver, 'nameserver'));
+ }
+
+ public static function factoryShouldAddDefaultPortProvider()
+ {
+ return array(
+ array('8.8.8.8', '8.8.8.8:53'),
+ array('1.2.3.4:5', '1.2.3.4:5'),
+ array('localhost', 'localhost:53'),
+ array('localhost:1234', 'localhost:1234'),
+ array('::1', '[::1]:53'),
+ array('[::1]:53', '[::1]:53')
+ );
+ }
+
+ private function getResolverPrivateExecutor($resolver)
+ {
+ $executor = $this->getResolverPrivateMemberValue($resolver, 'executor');
+
+ // extract underlying executor that may be wrapped in multiple layers of hosts file executors
+ while ($executor instanceof HostsFileExecutor) {
+ $reflector = new \ReflectionProperty('React\Dns\Query\HostsFileExecutor', 'fallback');
+ $reflector->setAccessible(true);
+
+ $executor = $reflector->getValue($executor);
+ }
+
+ return $executor;
+ }
+
+ private function getResolverPrivateMemberValue($resolver, $field)
+ {
+ $reflector = new \ReflectionProperty('React\Dns\Resolver\Resolver', $field);
+ $reflector->setAccessible(true);
+ return $reflector->getValue($resolver);
+ }
+
+ private function getCachedExecutorPrivateMemberValue($resolver, $field)
+ {
+ $reflector = new \ReflectionProperty('React\Dns\Query\CachedExecutor', $field);
+ $reflector->setAccessible(true);
+ return $reflector->getValue($resolver);
+ }
+
+ private function getRecordCachePrivateMemberValue($resolver, $field)
+ {
+ $reflector = new \ReflectionProperty('React\Dns\Query\RecordCache', $field);
+ $reflector->setAccessible(true);
+ return $reflector->getValue($resolver);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Resolver/ResolveAliasesTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Resolver/ResolveAliasesTest.php
new file mode 100644
index 0000000..b5175e3
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Resolver/ResolveAliasesTest.php
@@ -0,0 +1,100 @@
+<?php
+
+namespace React\Tests\Dns\Resolver;
+
+use PHPUnit\Framework\TestCase;
+use React\Dns\Resolver\Resolver;
+use React\Dns\Query\Query;
+use React\Dns\Model\Message;
+use React\Dns\Model\Record;
+
+class ResolveAliasesTest extends TestCase
+{
+ /**
+ * @covers React\Dns\Resolver\Resolver::resolveAliases
+ * @dataProvider provideAliasedAnswers
+ */
+ public function testResolveAliases(array $expectedAnswers, array $answers, $name)
+ {
+ $executor = $this->createExecutorMock();
+ $resolver = new Resolver('8.8.8.8:53', $executor);
+
+ $answers = $resolver->resolveAliases($answers, $name);
+
+ $this->assertEquals($expectedAnswers, $answers);
+ }
+
+ public function provideAliasedAnswers()
+ {
+ return array(
+ array(
+ array('178.79.169.131'),
+ array(
+ new Record('igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131'),
+ ),
+ 'igor.io',
+ ),
+ array(
+ array('178.79.169.131', '178.79.169.132', '178.79.169.133'),
+ array(
+ new Record('igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131'),
+ new Record('igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.132'),
+ new Record('igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.133'),
+ ),
+ 'igor.io',
+ ),
+ array(
+ array('178.79.169.131'),
+ array(
+ new Record('igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131'),
+ new Record('foo.igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131'),
+ new Record('bar.igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131'),
+ ),
+ 'igor.io',
+ ),
+ array(
+ array(),
+ array(
+ new Record('foo.igor.io', Message::TYPE_A, Message::CLASS_IN),
+ new Record('bar.igor.io', Message::TYPE_A, Message::CLASS_IN),
+ ),
+ 'igor.io',
+ ),
+ array(
+ array('178.79.169.131'),
+ array(
+ new Record('igor.io', Message::TYPE_CNAME, Message::CLASS_IN, 3600, 'foo.igor.io'),
+ new Record('foo.igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131'),
+ ),
+ 'igor.io',
+ ),
+ array(
+ array('178.79.169.131'),
+ array(
+ new Record('igor.io', Message::TYPE_CNAME, Message::CLASS_IN, 3600, 'foo.igor.io'),
+ new Record('foo.igor.io', Message::TYPE_CNAME, Message::CLASS_IN, 3600, 'bar.igor.io'),
+ new Record('bar.igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131'),
+ ),
+ 'igor.io',
+ ),
+ array(
+ array('178.79.169.131', '178.79.169.132', '178.79.169.133'),
+ array(
+ new Record('igor.io', Message::TYPE_CNAME, Message::CLASS_IN, 3600, 'foo.igor.io'),
+ new Record('foo.igor.io', Message::TYPE_CNAME, Message::CLASS_IN, 3600, 'bar.igor.io'),
+ new Record('bar.igor.io', Message::TYPE_CNAME, Message::CLASS_IN, 3600, 'baz.igor.io'),
+ new Record('bar.igor.io', Message::TYPE_CNAME, Message::CLASS_IN, 3600, 'qux.igor.io'),
+ new Record('baz.igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.131'),
+ new Record('baz.igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.132'),
+ new Record('qux.igor.io', Message::TYPE_A, Message::CLASS_IN, 3600, '178.79.169.133'),
+ ),
+ 'igor.io',
+ ),
+ );
+ }
+
+ private function createExecutorMock()
+ {
+ return $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Resolver/ResolverTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Resolver/ResolverTest.php
new file mode 100644
index 0000000..e11509b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/Resolver/ResolverTest.php
@@ -0,0 +1,129 @@
+<?php
+
+namespace React\Tests\Dns\Resolver;
+
+use React\Dns\Resolver\Resolver;
+use React\Dns\Query\Query;
+use React\Dns\Model\Message;
+use React\Dns\Model\Record;
+use React\Promise;
+use React\Tests\Dns\TestCase;
+
+class ResolverTest extends TestCase
+{
+ /** @test */
+ public function resolveShouldQueryARecords()
+ {
+ $executor = $this->createExecutorMock();
+ $executor
+ ->expects($this->once())
+ ->method('query')
+ ->with($this->anything(), $this->isInstanceOf('React\Dns\Query\Query'))
+ ->will($this->returnCallback(function ($nameserver, $query) {
+ $response = new Message();
+ $response->header->set('qr', 1);
+ $response->questions[] = new Record($query->name, $query->type, $query->class);
+ $response->answers[] = new Record($query->name, $query->type, $query->class, 3600, '178.79.169.131');
+
+ return Promise\resolve($response);
+ }));
+
+ $resolver = new Resolver('8.8.8.8:53', $executor);
+ $resolver->resolve('igor.io')->then($this->expectCallableOnceWith('178.79.169.131'));
+ }
+
+ /** @test */
+ public function resolveShouldQueryARecordsAndIgnoreCase()
+ {
+ $executor = $this->createExecutorMock();
+ $executor
+ ->expects($this->once())
+ ->method('query')
+ ->with($this->anything(), $this->isInstanceOf('React\Dns\Query\Query'))
+ ->will($this->returnCallback(function ($nameserver, $query) {
+ $response = new Message();
+ $response->header->set('qr', 1);
+ $response->questions[] = new Record('Blog.wyrihaximus.net', $query->type, $query->class);
+ $response->answers[] = new Record('Blog.wyrihaximus.net', $query->type, $query->class, 3600, '178.79.169.131');
+
+ return Promise\resolve($response);
+ }));
+
+ $resolver = new Resolver('8.8.8.8:53', $executor);
+ $resolver->resolve('blog.wyrihaximus.net')->then($this->expectCallableOnceWith('178.79.169.131'));
+ }
+
+ /** @test */
+ public function resolveShouldFilterByName()
+ {
+ $executor = $this->createExecutorMock();
+ $executor
+ ->expects($this->once())
+ ->method('query')
+ ->with($this->anything(), $this->isInstanceOf('React\Dns\Query\Query'))
+ ->will($this->returnCallback(function ($nameserver, $query) {
+ $response = new Message();
+ $response->header->set('qr', 1);
+ $response->questions[] = new Record($query->name, $query->type, $query->class);
+ $response->answers[] = new Record('foo.bar', $query->type, $query->class, 3600, '178.79.169.131');
+
+ return Promise\resolve($response);
+ }));
+
+ $errback = $this->expectCallableOnceWith($this->isInstanceOf('React\Dns\RecordNotFoundException'));
+
+ $resolver = new Resolver('8.8.8.8:53', $executor);
+ $resolver->resolve('igor.io')->then($this->expectCallableNever(), $errback);
+ }
+
+ /** @test */
+ public function resolveWithNoAnswersShouldThrowException()
+ {
+ $executor = $this->createExecutorMock();
+ $executor
+ ->expects($this->once())
+ ->method('query')
+ ->with($this->anything(), $this->isInstanceOf('React\Dns\Query\Query'))
+ ->will($this->returnCallback(function ($nameserver, $query) {
+ $response = new Message();
+ $response->header->set('qr', 1);
+ $response->questions[] = new Record($query->name, $query->type, $query->class);
+
+ return Promise\resolve($response);
+ }));
+
+ $errback = $this->expectCallableOnceWith($this->isInstanceOf('React\Dns\RecordNotFoundException'));
+
+ $resolver = new Resolver('8.8.8.8:53', $executor);
+ $resolver->resolve('igor.io')->then($this->expectCallableNever(), $errback);
+ }
+
+ /**
+ * @test
+ */
+ public function resolveWithNoAnswersShouldCallErrbackIfGiven()
+ {
+ $executor = $this->createExecutorMock();
+ $executor
+ ->expects($this->once())
+ ->method('query')
+ ->with($this->anything(), $this->isInstanceOf('React\Dns\Query\Query'))
+ ->will($this->returnCallback(function ($nameserver, $query) {
+ $response = new Message();
+ $response->header->set('qr', 1);
+ $response->questions[] = new Record($query->name, $query->type, $query->class);
+
+ return Promise\resolve($response);
+ }));
+
+ $errback = $this->expectCallableOnceWith($this->isInstanceOf('React\Dns\RecordNotFoundException'));
+
+ $resolver = new Resolver('8.8.8.8:53', $executor);
+ $resolver->resolve('igor.io')->then($this->expectCallableNever(), $errback);
+ }
+
+ private function createExecutorMock()
+ {
+ return $this->getMockBuilder('React\Dns\Query\ExecutorInterface')->getMock();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/TestCase.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/TestCase.php
new file mode 100644
index 0000000..a5a22bf
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/dns/tests/TestCase.php
@@ -0,0 +1,61 @@
+<?php
+
+namespace React\Tests\Dns;
+
+use PHPUnit\Framework\TestCase as BaseTestCase;
+
+abstract class TestCase extends BaseTestCase
+{
+ protected function expectCallableOnce()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke');
+
+ return $mock;
+ }
+
+ protected function expectCallableOnceWith($value)
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($value);
+
+ return $mock;
+ }
+
+ protected function expectCallableNever()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->never())
+ ->method('__invoke');
+
+ return $mock;
+ }
+
+ protected function createCallableMock()
+ {
+ return $this->getMockBuilder('React\Tests\Dns\CallableStub')->getMock();
+ }
+
+ public function setExpectedException($exception, $exceptionMessage = '', $exceptionCode = null)
+ {
+ if (method_exists($this, 'expectException')) {
+ // PHPUnit 5
+ $this->expectException($exception);
+ if ($exceptionMessage !== '') {
+ $this->expectExceptionMessage($exceptionMessage);
+ }
+ if ($exceptionCode !== null) {
+ $this->expectExceptionCode($exceptionCode);
+ }
+ } else {
+ // legacy PHPUnit 4
+ parent::setExpectedException($exception, $exceptionMessage, $exceptionCode);
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/.gitignore b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/.gitignore
new file mode 100644
index 0000000..81b9258
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/.gitignore
@@ -0,0 +1,3 @@
+composer.lock
+phpunit.xml
+vendor
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/.travis.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/.travis.yml
new file mode 100644
index 0000000..7af713a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/.travis.yml
@@ -0,0 +1,39 @@
+language: php
+
+php:
+# - 5.3 # requires old distro, see below
+ - 5.4
+ - 5.5
+ - 5.6
+ - 7.0
+ - 7.1
+ - 7.2
+ - hhvm # ignore errors, see below
+
+# lock distro so new future defaults will not break the build
+dist: trusty
+
+matrix:
+ include:
+ - php: 5.3
+ dist: precise
+ allow_failures:
+ - php: hhvm
+
+sudo: false
+
+addons:
+ apt:
+ packages:
+ - libevent-dev # Used by 'event' and 'libevent' PHP extensions
+
+cache:
+ directories:
+ - $HOME/.composer/cache/files
+
+install:
+ - ./travis-init.sh
+ - composer install
+
+script:
+ - ./vendor/bin/phpunit --coverage-text
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/CHANGELOG.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/CHANGELOG.md
new file mode 100644
index 0000000..c291840
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/CHANGELOG.md
@@ -0,0 +1,316 @@
+# Changelog
+
+## 0.5.1 (2018-04-09)
+
+* New loop: ExtEvLoop (PECL ext-ev) (#148 by @kaduev13)
+
+## 0.5.0 (2018-04-05)
+
+A major feature release with a significant documentation overhaul and long overdue API cleanup!
+
+This update involves a number of BC breaks due to dropped support for deprecated
+functionality. We've tried hard to avoid BC breaks where possible and minimize
+impact otherwise. We expect that most consumers of this package will actually
+not be affected by any BC breaks, see below for more details.
+
+We realize that the changes listed below may seem overwhelming, but we've tried
+to be very clear about any possible BC breaks. Don't worry: In fact, all ReactPHP
+components are already compatible and support both this new release as well as
+providing backwards compatibility with the last release.
+
+* Feature / BC break: Add support for signal handling via new
+ `LoopInterface::addSignal()` and `LoopInterface::removeSignal()` methods.
+ (#104 by @WyriHaximus and #111 and #150 by @clue)
+
+ ```php
+ $loop->addSignal(SIGINT, function () {
+ echo 'CTRL-C';
+ });
+ ```
+
+* Feature: Significant documentation updates for `LoopInterface` and `Factory`.
+ (#100, #119, #126, #127, #159 and #160 by @clue, #113 by @WyriHaximus and #81 and #91 by @jsor)
+
+* Feature: Add examples to ease getting started
+ (#99, #100 and #125 by @clue, #59 by @WyriHaximus and #143 by @jsor)
+
+* Feature: Documentation for advanced timer concepts, such as monotonic time source vs wall-clock time
+ and high precision timers with millisecond accuracy or below.
+ (#130 and #157 by @clue)
+
+* Feature: Documentation for advanced stream concepts, such as edge-triggered event listeners
+ and stream buffers and allow throwing Exception if stream resource is not supported.
+ (#129 and #158 by @clue)
+
+* Feature: Throw `BadMethodCallException` on manual loop creation when required extension isn't installed.
+ (#153 by @WyriHaximus)
+
+* Feature / BC break: First class support for legacy PHP 5.3 through PHP 7.2 and HHVM
+ and remove all `callable` type hints for consistency reasons.
+ (#141 and #151 by @clue)
+
+* BC break: Documentation for timer API and clean up unneeded timer API.
+ (#102 by @clue)
+
+ Remove `TimerInterface::cancel()`, use `LoopInterface::cancelTimer()` instead:
+
+ ```php
+ // old (method invoked on timer instance)
+ $timer->cancel();
+
+ // already supported before: invoke method on loop instance
+ $loop->cancelTimer($timer);
+ ```
+
+ Remove unneeded `TimerInterface::setData()` and `TimerInterface::getData()`,
+ use closure binding to add arbitrary data to timer instead:
+
+ ```php
+ // old (limited setData() and getData() only allows single variable)
+ $name = 'Tester';
+ $timer = $loop->addTimer(1.0, function ($timer) {
+ echo 'Hello ' . $timer->getData() . PHP_EOL;
+ });
+ $timer->setData($name);
+
+ // already supported before: closure binding allows any number of variables
+ $name = 'Tester';
+ $loop->addTimer(1.0, function () use ($name) {
+ echo 'Hello ' . $name . PHP_EOL;
+ });
+ ```
+
+ Remove unneeded `TimerInterface::getLoop()`, use closure binding instead:
+
+ ```php
+ // old (getLoop() called on timer instance)
+ $loop->addTimer(0.1, function ($timer) {
+ $timer->getLoop()->stop();
+ });
+
+ // already supported before: use closure binding as usual
+ $loop->addTimer(0.1, function () use ($loop) {
+ $loop->stop();
+ });
+ ```
+
+* BC break: Remove unneeded `LoopInterface::isTimerActive()` and
+ `TimerInterface::isActive()` to reduce API surface.
+ (#133 by @clue)
+
+ ```php
+ // old (method on timer instance or on loop instance)
+ $timer->isActive();
+ $loop->isTimerActive($timer);
+ ```
+
+* BC break: Move `TimerInterface` one level up to `React\EventLoop\TimerInterface`.
+ (#138 by @WyriHaximus)
+
+ ```php
+ // old (notice obsolete "Timer" namespace)
+ assert($timer instanceof React\EventLoop\Timer\TimerInterface);
+
+ // new
+ assert($timer instanceof React\EventLoop\TimerInterface);
+ ```
+
+* BC break: Remove unneeded `LoopInterface::nextTick()` (and internal `NextTickQueue`),
+ use `LoopInterface::futureTick()` instead.
+ (#30 by @clue)
+
+ ```php
+ // old (removed)
+ $loop->nextTick(function () {
+ echo 'tick';
+ });
+
+ // already supported before
+ $loop->futureTick(function () {
+ echo 'tick';
+ });
+ ```
+
+* BC break: Remove unneeded `$loop` argument for `LoopInterface::futureTick()`
+ (and fix internal cyclic dependency).
+ (#103 by @clue)
+
+ ```php
+ // old ($loop gets passed by default)
+ $loop->futureTick(function ($loop) {
+ $loop->stop();
+ });
+
+ // already supported before: use closure binding as usual
+ $loop->futureTick(function () use ($loop) {
+ $loop->stop();
+ });
+ ```
+
+* BC break: Remove unneeded `LoopInterface::tick()`.
+ (#72 by @jsor)
+
+ ```php
+ // old (removed)
+ $loop->tick();
+
+ // suggested work around for testing purposes only
+ $loop->futureTick(function () use ($loop) {
+ $loop->stop();
+ });
+ ```
+
+* BC break: Documentation for advanced stream API and clean up unneeded stream API.
+ (#110 by @clue)
+
+ Remove unneeded `$loop` argument for `LoopInterface::addReadStream()`
+ and `LoopInterface::addWriteStream()`, use closure binding instead:
+
+ ```php
+ // old ($loop gets passed by default)
+ $loop->addReadStream($stream, function ($stream, $loop) {
+ $loop->removeReadStream($stream);
+ });
+
+ // already supported before: use closure binding as usual
+ $loop->addReadStream($stream, function ($stream) use ($loop) {
+ $loop->removeReadStream($stream);
+ });
+ ```
+
+* BC break: Remove unneeded `LoopInterface::removeStream()` method,
+ use `LoopInterface::removeReadStream()` and `LoopInterface::removeWriteStream()` instead.
+ (#118 by @clue)
+
+ ```php
+ // old
+ $loop->removeStream($stream);
+
+ // already supported before
+ $loop->removeReadStream($stream);
+ $loop->removeWriteStream($stream);
+ ```
+
+* BC break: Rename `LibEventLoop` to `ExtLibeventLoop` and `LibEvLoop` to `ExtLibevLoop`
+ for consistent naming for event loop implementations.
+ (#128 by @clue)
+
+* BC break: Remove optional `EventBaseConfig` argument from `ExtEventLoop`
+ and make its `FEATURE_FDS` enabled by default.
+ (#156 by @WyriHaximus)
+
+* BC break: Mark all classes as final to discourage inheritance.
+ (#131 by @clue)
+
+* Fix: Fix `ExtEventLoop` to keep track of stream resources (refcount)
+ (#123 by @clue)
+
+* Fix: Ensure large timer interval does not overflow on 32bit systems
+ (#132 by @clue)
+
+* Fix: Fix separately removing readable and writable side of stream when closing
+ (#139 by @clue)
+
+* Fix: Properly clean up event watchers for `ext-event` and `ext-libev`
+ (#149 by @clue)
+
+* Fix: Minor code cleanup and remove unneeded references
+ (#145 by @seregazhuk)
+
+* Fix: Discourage outdated `ext-libevent` on PHP 7
+ (#62 by @cboden)
+
+* Improve test suite by adding forward compatibility with PHPUnit 6 and PHPUnit 5,
+ lock Travis distro so new defaults will not break the build,
+ improve test suite to be less fragile and increase test timeouts,
+ test against PHP 7.2 and reduce fwrite() call length to one chunk.
+ (#106 and #144 by @clue, #120 and #124 by @carusogabriel, #147 by nawarian and #92 by @kelunik)
+
+* A number of changes were originally planned for this release but have been backported
+ to the last `v0.4.3` already: #74, #76, #79, #81 (refs #65, #66, #67), #88 and #93
+
+## 0.4.3 (2017-04-27)
+
+* Bug fix: Bugfix in the usage sample code #57 (@dandelionred)
+* Improvement: Remove branch-alias definition #53 (@WyriHaximus)
+* Improvement: StreamSelectLoop: Use fresh time so Timers added during stream events are accurate #51 (@andrewminerd)
+* Improvement: Avoid deprecation warnings in test suite due to deprecation of getMock() in PHPUnit #68 (@martinschroeder)
+* Improvement: Add PHPUnit 4.8 to require-dev #69 (@shaunbramley)
+* Improvement: Increase test timeouts for HHVM and unify timeout handling #70 (@clue)
+* Improvement: Travis improvements (backported from #74) #75 (@clue)
+* Improvement: Test suite now uses socket pairs instead of memory streams #66 (@martinschroeder)
+* Improvement: StreamSelectLoop: Test suite uses signal constant names in data provider #67 (@martinschroeder)
+* Improvement: ExtEventLoop: No longer suppress all errors #65 (@mamciek)
+* Improvement: Readme cleanup #89 (@jsor)
+* Improvement: Restructure and improve README #90 (@jsor)
+* Bug fix: StreamSelectLoop: Fix erroneous zero-time sleep (backport to 0.4) #94 (@jsor)
+
+## 0.4.2 (2016-03-07)
+
+* Bug fix: No longer error when signals sent to StreamSelectLoop
+* Support HHVM and PHP7 (@ondrejmirtes, @cebe)
+* Feature: Added support for EventConfig for ExtEventLoop (@steverhoades)
+* Bug fix: Fixed an issue loading loop extension libs via autoloader (@czarpino)
+
+## 0.4.1 (2014-04-13)
+
+* Bug fix: null timeout in StreamSelectLoop causing 100% CPU usage (@clue)
+* Bug fix: v0.3.4 changes merged for v0.4.1
+
+## 0.4.0 (2014-02-02)
+
+* Feature: Added `EventLoopInterface::nextTick()`, implemented in all event loops (@jmalloc)
+* Feature: Added `EventLoopInterface::futureTick()`, implemented in all event loops (@jmalloc)
+* Feature: Added `ExtEventLoop` implementation using pecl/event (@jmalloc)
+* BC break: Bump minimum PHP version to PHP 5.4, remove 5.3 specific hacks
+* BC break: New method: `EventLoopInterface::nextTick()`
+* BC break: New method: `EventLoopInterface::futureTick()`
+* Dependency: Autoloading and filesystem structure now PSR-4 instead of PSR-0
+
+## 0.3.5 (2016-12-28)
+
+This is a compatibility release that eases upgrading to the v0.4 release branch.
+You should consider upgrading to the v0.4 release branch.
+
+* Feature: Cap min timer interval at 1µs, thus improving compatibility with v0.4
+ (#47 by @clue)
+
+## 0.3.4 (2014-03-30)
+
+* Bug fix: Changed StreamSelectLoop to use non-blocking behavior on tick() (@astephens25)
+
+## 0.3.3 (2013-07-08)
+
+* Bug fix: No error on removing non-existent streams (@clue)
+* Bug fix: Do not silently remove feof listeners in `LibEvLoop`
+
+## 0.3.0 (2013-04-14)
+
+* BC break: New timers API (@nrk)
+* BC break: Remove check on return value from stream callbacks (@nrk)
+
+## 0.2.7 (2013-01-05)
+
+* Bug fix: Fix libevent timers with PHP 5.3
+* Bug fix: Fix libevent timer cancellation (@nrk)
+
+## 0.2.6 (2012-12-26)
+
+* Bug fix: Plug memory issue in libevent timers (@cameronjacobson)
+* Bug fix: Correctly pause LibEvLoop on stop()
+
+## 0.2.3 (2012-11-14)
+
+* Feature: LibEvLoop, integration of `php-libev`
+
+## 0.2.0 (2012-09-10)
+
+* Version bump
+
+## 0.1.1 (2012-07-12)
+
+* Version bump
+
+## 0.1.0 (2012-07-11)
+
+* First tagged release
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/LICENSE b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/LICENSE
new file mode 100644
index 0000000..a808108
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2012 Igor Wiedler, Chris Boden
+
+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.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/README.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/README.md
new file mode 100644
index 0000000..207e7f4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/README.md
@@ -0,0 +1,702 @@
+# EventLoop Component
+
+[![Build Status](https://travis-ci.org/reactphp/event-loop.svg?branch=master)](https://travis-ci.org/reactphp/event-loop)
+
+[ReactPHP](https://reactphp.org/)'s core reactor event loop that libraries can use for evented I/O.
+
+In order for async based libraries to be interoperable, they need to use the
+same event loop. This component provides a common `LoopInterface` that any
+library can target. This allows them to be used in the same loop, with one
+single [`run()`](#run) call that is controlled by the user.
+
+**Table of Contents**
+
+* [Quickstart example](#quickstart-example)
+* [Usage](#usage)
+ * [Factory](#factory)
+ * [create()](#create)
+ * [Loop implementations](#loop-implementations)
+ * [StreamSelectLoop](#streamselectloop)
+ * [ExtEventLoop](#exteventloop)
+ * [ExtLibeventLoop](#extlibeventloop)
+ * [ExtLibevLoop](#extlibevloop)
+ * [ExtEvLoop](#extevloop)
+ * [LoopInterface](#loopinterface)
+ * [run()](#run)
+ * [stop()](#stop)
+ * [addTimer()](#addtimer)
+ * [addPeriodicTimer()](#addperiodictimer)
+ * [cancelTimer()](#canceltimer)
+ * [futureTick()](#futuretick)
+ * [addSignal()](#addsignal)
+ * [removeSignal()](#removesignal)
+ * [addReadStream()](#addreadstream)
+ * [addWriteStream()](#addwritestream)
+ * [removeReadStream()](#removereadstream)
+ * [removeWriteStream()](#removewritestream)
+* [Install](#install)
+* [Tests](#tests)
+* [License](#license)
+* [More](#more)
+
+## Quickstart example
+
+Here is an async HTTP server built with just the event loop.
+
+```php
+$loop = React\EventLoop\Factory::create();
+
+$server = stream_socket_server('tcp://127.0.0.1:8080');
+stream_set_blocking($server, false);
+
+$loop->addReadStream($server, function ($server) use ($loop) {
+ $conn = stream_socket_accept($server);
+ $data = "HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nHi\n";
+ $loop->addWriteStream($conn, function ($conn) use (&$data, $loop) {
+ $written = fwrite($conn, $data);
+ if ($written === strlen($data)) {
+ fclose($conn);
+ $loop->removeWriteStream($conn);
+ } else {
+ $data = substr($data, $written);
+ }
+ });
+});
+
+$loop->addPeriodicTimer(5, function () {
+ $memory = memory_get_usage() / 1024;
+ $formatted = number_format($memory, 3).'K';
+ echo "Current memory usage: {$formatted}\n";
+});
+
+$loop->run();
+```
+
+See also the [examples](examples).
+
+## Usage
+
+Typical applications use a single event loop which is created at the beginning
+and run at the end of the program.
+
+```php
+// [1]
+$loop = React\EventLoop\Factory::create();
+
+// [2]
+$loop->addPeriodicTimer(1, function () {
+ echo "Tick\n";
+});
+
+$stream = new React\Stream\ReadableResourceStream(
+ fopen('file.txt', 'r'),
+ $loop
+);
+
+// [3]
+$loop->run();
+```
+
+1. The loop instance is created at the beginning of the program. A convenience
+ factory [`React\EventLoop\Factory::create()`](#create) is provided by this library which
+ picks the best available [loop implementation](#loop-implementations).
+2. The loop instance is used directly or passed to library and application code.
+ In this example, a periodic timer is registered with the event loop which
+ simply outputs `Tick` every second and a
+ [readable stream](https://github.com/reactphp/stream#readableresourcestream)
+ is created by using ReactPHP's
+ [stream component](https://github.com/reactphp/stream) for demonstration
+ purposes.
+3. The loop is run with a single [`$loop->run()`](#run) call at the end of the program.
+
+### Factory
+
+The `Factory` class exists as a convenient way to pick the best available
+[event loop implementation](#loop-implementations).
+
+#### create()
+
+The `create(): LoopInterface` method can be used to create a new event loop
+instance:
+
+```php
+$loop = React\EventLoop\Factory::create();
+```
+
+This method always returns an instance implementing [`LoopInterface`](#loopinterface),
+the actual [event loop implementation](#loop-implementations) is an implementation detail.
+
+This method should usually only be called once at the beginning of the program.
+
+### Loop implementations
+
+In addition to the [`LoopInterface`](#loopinterface), there are a number of
+event loop implementations provided.
+
+All of the event loops support these features:
+
+* File descriptor polling
+* One-off timers
+* Periodic timers
+* Deferred execution on future loop tick
+
+For most consumers of this package, the underlying event loop implementation is
+an implementation detail.
+You should use the [`Factory`](#factory) to automatically create a new instance.
+
+Advanced! If you explicitly need a certain event loop implementation, you can
+manually instantiate one of the following classes.
+Note that you may have to install the required PHP extensions for the respective
+event loop implementation first or they will throw a `BadMethodCallException` on creation.
+
+#### StreamSelectLoop
+
+A `stream_select()` based event loop.
+
+This uses the [`stream_select()`](http://php.net/manual/en/function.stream-select.php)
+function and is the only implementation which works out of the box with PHP.
+
+This event loop works out of the box on PHP 5.3 through PHP 7+ and HHVM.
+This means that no installation is required and this library works on all
+platforms and supported PHP versions.
+Accordingly, the [`Factory`](#factory) will use this event loop by default if
+you do not install any of the event loop extensions listed below.
+
+Under the hood, it does a simple `select` system call.
+This system call is limited to the maximum file descriptor number of
+`FD_SETSIZE` (platform dependent, commonly 1024) and scales with `O(m)`
+(`m` being the maximum file descriptor number passed).
+This means that you may run into issues when handling thousands of streams
+concurrently and you may want to look into using one of the alternative
+event loop implementations listed below in this case.
+If your use case is among the many common use cases that involve handling only
+dozens or a few hundred streams at once, then this event loop implementation
+performs really well.
+
+If you want to use signal handling (see also [`addSignal()`](#addsignal) below),
+this event loop implementation requires `ext-pcntl`.
+This extension is only available for Unix-like platforms and does not support
+Windows.
+It is commonly installed as part of many PHP distributions.
+If this extension is missing (or you're running on Windows), signal handling is
+not supported and throws a `BadMethodCallException` instead.
+
+This event loop is known to rely on wall-clock time to schedule future
+timers, because a monotonic time source is not available in PHP by default.
+While this does not affect many common use cases, this is an important
+distinction for programs that rely on a high time precision or on systems
+that are subject to discontinuous time adjustments (time jumps).
+This means that if you schedule a timer to trigger in 30s and then adjust
+your system time forward by 20s, the timer may trigger in 10s.
+See also [`addTimer()`](#addtimer) for more details.
+
+#### ExtEventLoop
+
+An `ext-event` based event loop.
+
+This uses the [`event` PECL extension](https://pecl.php.net/package/event).
+It supports the same backends as libevent.
+
+This loop is known to work with PHP 5.4 through PHP 7+.
+
+#### ExtEvLoop
+
+An `ext-ev` based event loop.
+
+This loop uses the [`ev` PECL extension](https://pecl.php.net/package/ev), that
+provides an interface to `libev` library.
+
+This loop is known to work with PHP 5.4 through PHP 7+.
+
+
+#### ExtLibeventLoop
+
+An `ext-libevent` based event loop.
+
+This uses the [`libevent` PECL extension](https://pecl.php.net/package/libevent).
+`libevent` itself supports a number of system-specific backends (epoll, kqueue).
+
+This event loop does only work with PHP 5.
+An [unofficial update](https://github.com/php/pecl-event-libevent/pull/2) for
+PHP 7 does exist, but it is known to cause regular crashes due to `SEGFAULT`s.
+To reiterate: Using this event loop on PHP 7 is not recommended.
+Accordingly, the [`Factory`](#factory) will not try to use this event loop on
+PHP 7.
+
+This event loop is known to trigger a readable listener only if
+the stream *becomes* readable (edge-triggered) and may not trigger if the
+stream has already been readable from the beginning.
+This also implies that a stream may not be recognized as readable when data
+is still left in PHP's internal stream buffers.
+As such, it's recommended to use `stream_set_read_buffer($stream, 0);`
+to disable PHP's internal read buffer in this case.
+See also [`addReadStream()`](#addreadstream) for more details.
+
+#### ExtLibevLoop
+
+An `ext-libev` based event loop.
+
+This uses an [unofficial `libev` extension](https://github.com/m4rw3r/php-libev).
+It supports the same backends as libevent.
+
+This loop does only work with PHP 5.
+An update for PHP 7 is [unlikely](https://github.com/m4rw3r/php-libev/issues/8)
+to happen any time soon.
+
+### LoopInterface
+
+#### run()
+
+The `run(): void` method can be used to
+run the event loop until there are no more tasks to perform.
+
+For many applications, this method is the only directly visible
+invocation on the event loop.
+As a rule of thumb, it is usally recommended to attach everything to the
+same loop instance and then run the loop once at the bottom end of the
+application.
+
+```php
+$loop->run();
+```
+
+This method will keep the loop running until there are no more tasks
+to perform. In other words: This method will block until the last
+timer, stream and/or signal has been removed.
+
+Likewise, it is imperative to ensure the application actually invokes
+this method once. Adding listeners to the loop and missing to actually
+run it will result in the application exiting without actually waiting
+for any of the attached listeners.
+
+This method MUST NOT be called while the loop is already running.
+This method MAY be called more than once after it has explicity been
+[`stop()`ped](#stop) or after it automatically stopped because it
+previously did no longer have anything to do.
+
+#### stop()
+
+The `stop(): void` method can be used to
+instruct a running event loop to stop.
+
+This method is considered advanced usage and should be used with care.
+As a rule of thumb, it is usually recommended to let the loop stop
+only automatically when it no longer has anything to do.
+
+This method can be used to explicitly instruct the event loop to stop:
+
+```php
+$loop->addTimer(3.0, function () use ($loop) {
+ $loop->stop();
+});
+```
+
+Calling this method on a loop instance that is not currently running or
+on a loop instance that has already been stopped has no effect.
+
+#### addTimer()
+
+The `addTimer(float $interval, callable $callback): TimerInterface` method can be used to
+enqueue a callback to be invoked once after the given interval.
+
+The timer callback function MUST be able to accept a single parameter,
+the timer instance as also returned by this method or you MAY use a
+function which has no parameters at all.
+
+The timer callback function MUST NOT throw an `Exception`.
+The return value of the timer callback function will be ignored and has
+no effect, so for performance reasons you're recommended to not return
+any excessive data structures.
+
+Unlike [`addPeriodicTimer()`](#addperiodictimer), this method will ensure
+the callback will be invoked only once after the given interval.
+You can invoke [`cancelTimer`](#canceltimer) to cancel a pending timer.
+
+```php
+$loop->addTimer(0.8, function () {
+ echo 'world!' . PHP_EOL;
+});
+
+$loop->addTimer(0.3, function () {
+ echo 'hello ';
+});
+```
+
+See also [example #1](examples).
+
+If you want to access any variables within your callback function, you
+can bind arbitrary data to a callback closure like this:
+
+```php
+function hello($name, LoopInterface $loop)
+{
+ $loop->addTimer(1.0, function () use ($name) {
+ echo "hello $name\n";
+ });
+}
+
+hello('Tester', $loop);
+```
+
+This interface does not enforce any particular timer resolution, so
+special care may have to be taken if you rely on very high precision with
+millisecond accuracy or below. Event loop implementations SHOULD work on
+a best effort basis and SHOULD provide at least millisecond accuracy
+unless otherwise noted. Many existing event loop implementations are
+known to provide microsecond accuracy, but it's generally not recommended
+to rely on this high precision.
+
+Similarly, the execution order of timers scheduled to execute at the
+same time (within its possible accuracy) is not guaranteed.
+
+This interface suggests that event loop implementations SHOULD use a
+monotonic time source if available. Given that a monotonic time source is
+not available on PHP by default, event loop implementations MAY fall back
+to using wall-clock time.
+While this does not affect many common use cases, this is an important
+distinction for programs that rely on a high time precision or on systems
+that are subject to discontinuous time adjustments (time jumps).
+This means that if you schedule a timer to trigger in 30s and then adjust
+your system time forward by 20s, the timer SHOULD still trigger in 30s.
+See also [event loop implementations](#loop-implementations) for more details.
+
+#### addPeriodicTimer()
+
+The `addPeriodicTimer(float $interval, callable $callback): TimerInterface` method can be used to
+enqueue a callback to be invoked repeatedly after the given interval.
+
+The timer callback function MUST be able to accept a single parameter,
+the timer instance as also returned by this method or you MAY use a
+function which has no parameters at all.
+
+The timer callback function MUST NOT throw an `Exception`.
+The return value of the timer callback function will be ignored and has
+no effect, so for performance reasons you're recommended to not return
+any excessive data structures.
+
+Unlike [`addTimer()`](#addtimer), this method will ensure the the
+callback will be invoked infinitely after the given interval or until you
+invoke [`cancelTimer`](#canceltimer).
+
+```php
+$timer = $loop->addPeriodicTimer(0.1, function () {
+ echo 'tick!' . PHP_EOL;
+});
+
+$loop->addTimer(1.0, function () use ($loop, $timer) {
+ $loop->cancelTimer($timer);
+ echo 'Done' . PHP_EOL;
+});
+```
+
+See also [example #2](examples).
+
+If you want to limit the number of executions, you can bind
+arbitrary data to a callback closure like this:
+
+```php
+function hello($name, LoopInterface $loop)
+{
+ $n = 3;
+ $loop->addPeriodicTimer(1.0, function ($timer) use ($name, $loop, &$n) {
+ if ($n > 0) {
+ --$n;
+ echo "hello $name\n";
+ } else {
+ $loop->cancelTimer($timer);
+ }
+ });
+}
+
+hello('Tester', $loop);
+```
+
+This interface does not enforce any particular timer resolution, so
+special care may have to be taken if you rely on very high precision with
+millisecond accuracy or below. Event loop implementations SHOULD work on
+a best effort basis and SHOULD provide at least millisecond accuracy
+unless otherwise noted. Many existing event loop implementations are
+known to provide microsecond accuracy, but it's generally not recommended
+to rely on this high precision.
+
+Similarly, the execution order of timers scheduled to execute at the
+same time (within its possible accuracy) is not guaranteed.
+
+This interface suggests that event loop implementations SHOULD use a
+monotonic time source if available. Given that a monotonic time source is
+not available on PHP by default, event loop implementations MAY fall back
+to using wall-clock time.
+While this does not affect many common use cases, this is an important
+distinction for programs that rely on a high time precision or on systems
+that are subject to discontinuous time adjustments (time jumps).
+This means that if you schedule a timer to trigger in 30s and then adjust
+your system time forward by 20s, the timer SHOULD still trigger in 30s.
+See also [event loop implementations](#loop-implementations) for more details.
+
+Additionally, periodic timers may be subject to timer drift due to
+re-scheduling after each invocation. As such, it's generally not
+recommended to rely on this for high precision intervals with millisecond
+accuracy or below.
+
+#### cancelTimer()
+
+The `cancelTimer(TimerInterface $timer): void` method can be used to
+cancel a pending timer.
+
+See also [`addPeriodicTimer()`](#addperiodictimer) and [example #2](examples).
+
+Calling this method on a timer instance that has not been added to this
+loop instance or on a timer that has already been cancelled has no effect.
+
+#### futureTick()
+
+The `futureTick(callable $listener): void` method can be used to
+schedule a callback to be invoked on a future tick of the event loop.
+
+This works very much similar to timers with an interval of zero seconds,
+but does not require the overhead of scheduling a timer queue.
+
+The tick callback function MUST be able to accept zero parameters.
+
+The tick callback function MUST NOT throw an `Exception`.
+The return value of the tick callback function will be ignored and has
+no effect, so for performance reasons you're recommended to not return
+any excessive data structures.
+
+If you want to access any variables within your callback function, you
+can bind arbitrary data to a callback closure like this:
+
+```php
+function hello($name, LoopInterface $loop)
+{
+ $loop->futureTick(function () use ($name) {
+ echo "hello $name\n";
+ });
+}
+
+hello('Tester', $loop);
+```
+
+Unlike timers, tick callbacks are guaranteed to be executed in the order
+they are enqueued.
+Also, once a callback is enqueued, there's no way to cancel this operation.
+
+This is often used to break down bigger tasks into smaller steps (a form
+of cooperative multitasking).
+
+```php
+$loop->futureTick(function () {
+ echo 'b';
+});
+$loop->futureTick(function () {
+ echo 'c';
+});
+echo 'a';
+```
+
+See also [example #3](examples).
+
+#### addSignal()
+
+The `addSignal(int $signal, callable $listener): void` method can be used to
+register a listener to be notified when a signal has been caught by this process.
+
+This is useful to catch user interrupt signals or shutdown signals from
+tools like `supervisor` or `systemd`.
+
+The listener callback function MUST be able to accept a single parameter,
+the signal added by this method or you MAY use a function which
+has no parameters at all.
+
+The listener callback function MUST NOT throw an `Exception`.
+The return value of the listener callback function will be ignored and has
+no effect, so for performance reasons you're recommended to not return
+any excessive data structures.
+
+```php
+$loop->addSignal(SIGINT, function (int $signal) {
+ echo 'Caught user interrupt signal' . PHP_EOL;
+});
+```
+
+See also [example #4](examples).
+
+Signaling is only available on Unix-like platform, Windows isn't
+supported due to operating system limitations.
+This method may throw a `BadMethodCallException` if signals aren't
+supported on this platform, for example when required extensions are
+missing.
+
+**Note: A listener can only be added once to the same signal, any
+attempts to add it more then once will be ignored.**
+
+#### removeSignal()
+
+The `removeSignal(int $signal, callable $listener): void` method can be used to
+remove a previously added signal listener.
+
+```php
+$loop->removeSignal(SIGINT, $listener);
+```
+
+Any attempts to remove listeners that aren't registered will be ignored.
+
+#### addReadStream()
+
+> Advanced! Note that this low-level API is considered advanced usage.
+ Most use cases should probably use the higher-level
+ [readable Stream API](https://github.com/reactphp/stream#readablestreaminterface)
+ instead.
+
+The `addReadStream(resource $stream, callable $callback): void` method can be used to
+register a listener to be notified when a stream is ready to read.
+
+The first parameter MUST be a valid stream resource that supports
+checking whether it is ready to read by this loop implementation.
+A single stream resource MUST NOT be added more than once.
+Instead, either call [`removeReadStream()`](#removereadstream) first or
+react to this event with a single listener and then dispatch from this
+listener. This method MAY throw an `Exception` if the given resource type
+is not supported by this loop implementation.
+
+The listener callback function MUST be able to accept a single parameter,
+the stream resource added by this method or you MAY use a function which
+has no parameters at all.
+
+The listener callback function MUST NOT throw an `Exception`.
+The return value of the listener callback function will be ignored and has
+no effect, so for performance reasons you're recommended to not return
+any excessive data structures.
+
+If you want to access any variables within your callback function, you
+can bind arbitrary data to a callback closure like this:
+
+```php
+$loop->addReadStream($stream, function ($stream) use ($name) {
+ echo $name . ' said: ' . fread($stream);
+});
+```
+
+See also [example #11](examples).
+
+You can invoke [`removeReadStream()`](#removereadstream) to remove the
+read event listener for this stream.
+
+The execution order of listeners when multiple streams become ready at
+the same time is not guaranteed.
+
+Some event loop implementations are known to only trigger the listener if
+the stream *becomes* readable (edge-triggered) and may not trigger if the
+stream has already been readable from the beginning.
+This also implies that a stream may not be recognized as readable when data
+is still left in PHP's internal stream buffers.
+As such, it's recommended to use `stream_set_read_buffer($stream, 0);`
+to disable PHP's internal read buffer in this case.
+
+#### addWriteStream()
+
+> Advanced! Note that this low-level API is considered advanced usage.
+ Most use cases should probably use the higher-level
+ [writable Stream API](https://github.com/reactphp/stream#writablestreaminterface)
+ instead.
+
+The `addWriteStream(resource $stream, callable $callback): void` method can be used to
+register a listener to be notified when a stream is ready to write.
+
+The first parameter MUST be a valid stream resource that supports
+checking whether it is ready to write by this loop implementation.
+A single stream resource MUST NOT be added more than once.
+Instead, either call [`removeWriteStream()`](#removewritestream) first or
+react to this event with a single listener and then dispatch from this
+listener. This method MAY throw an `Exception` if the given resource type
+is not supported by this loop implementation.
+
+The listener callback function MUST be able to accept a single parameter,
+the stream resource added by this method or you MAY use a function which
+has no parameters at all.
+
+The listener callback function MUST NOT throw an `Exception`.
+The return value of the listener callback function will be ignored and has
+no effect, so for performance reasons you're recommended to not return
+any excessive data structures.
+
+If you want to access any variables within your callback function, you
+can bind arbitrary data to a callback closure like this:
+
+```php
+$loop->addWriteStream($stream, function ($stream) use ($name) {
+ fwrite($stream, 'Hello ' . $name);
+});
+```
+
+See also [example #12](examples).
+
+You can invoke [`removeWriteStream()`](#removewritestream) to remove the
+write event listener for this stream.
+
+The execution order of listeners when multiple streams become ready at
+the same time is not guaranteed.
+
+#### removeReadStream()
+
+The `removeReadStream(resource $stream): void` method can be used to
+remove the read event listener for the given stream.
+
+Removing a stream from the loop that has already been removed or trying
+to remove a stream that was never added or is invalid has no effect.
+
+#### removeWriteStream()
+
+The `removeWriteStream(resource $stream): void` method can be used to
+remove the write event listener for the given stream.
+
+Removing a stream from the loop that has already been removed or trying
+to remove a stream that was never added or is invalid has no effect.
+
+## Install
+
+The recommended way to install this library is [through Composer](https://getcomposer.org).
+[New to Composer?](https://getcomposer.org/doc/00-intro.md)
+
+This will install the latest supported version:
+
+```bash
+$ composer require react/event-loop:^0.5.1
+```
+
+See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades.
+
+This project aims to run on any platform and thus does not require any PHP
+extensions and supports running on legacy PHP 5.3 through current PHP 7+ and
+HHVM.
+It's *highly recommended to use PHP 7+* for this project.
+
+Installing any of the event loop extensions is suggested, but entirely optional.
+See also [event loop implementations](#loop-implementations) for more details.
+
+## Tests
+
+To run the test suite, you first need to clone this repo and then install all
+dependencies [through Composer](https://getcomposer.org):
+
+```bash
+$ composer install
+```
+
+To run the test suite, go to the project root and run:
+
+```bash
+$ php vendor/bin/phpunit
+```
+
+## License
+
+MIT, see [LICENSE file](LICENSE).
+
+## More
+
+* See our [Stream component](https://github.com/reactphp/stream) for more
+ information on how streams are used in real-world applications.
+* See our [users wiki](https://github.com/reactphp/react/wiki/Users) and the
+ [dependents on Packagist](https://packagist.org/packages/react/event-loop/dependents)
+ for a list of packages that use the EventLoop in real-world applications.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/composer.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/composer.json
new file mode 100644
index 0000000..24974ec
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/composer.json
@@ -0,0 +1,21 @@
+{
+ "name": "react/event-loop",
+ "description": "ReactPHP's core reactor event loop that libraries can use for evented I/O.",
+ "keywords": ["event-loop", "asynchronous"],
+ "license": "MIT",
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.8.35 || ^5.7 || ^6.4"
+ },
+ "suggest": {
+ "ext-event": "~1.0 for ExtEventLoop",
+ "ext-pcntl": "For signal handling support when using the StreamSelectLoop"
+ },
+ "autoload": {
+ "psr-4": {
+ "React\\EventLoop\\": "src"
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/01-timers.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/01-timers.php
new file mode 100644
index 0000000..e6107e4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/01-timers.php
@@ -0,0 +1,15 @@
+<?php
+
+require __DIR__ . '/../vendor/autoload.php';
+
+$loop = React\EventLoop\Factory::create();
+
+$loop->addTimer(0.8, function () {
+ echo 'world!' . PHP_EOL;
+});
+
+$loop->addTimer(0.3, function () {
+ echo 'hello ';
+});
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/02-periodic.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/02-periodic.php
new file mode 100644
index 0000000..5e138a6
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/02-periodic.php
@@ -0,0 +1,16 @@
+<?php
+
+require __DIR__ . '/../vendor/autoload.php';
+
+$loop = React\EventLoop\Factory::create();
+
+$timer = $loop->addPeriodicTimer(0.1, function () {
+ echo 'tick!' . PHP_EOL;
+});
+
+$loop->addTimer(1.0, function () use ($loop, $timer) {
+ $loop->cancelTimer($timer);
+ echo 'Done' . PHP_EOL;
+});
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/03-ticks.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/03-ticks.php
new file mode 100644
index 0000000..3f36c6d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/03-ticks.php
@@ -0,0 +1,15 @@
+<?php
+
+require __DIR__ . '/../vendor/autoload.php';
+
+$loop = React\EventLoop\Factory::create();
+
+$loop->futureTick(function () {
+ echo 'b';
+});
+$loop->futureTick(function () {
+ echo 'c';
+});
+echo 'a';
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/04-signals.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/04-signals.php
new file mode 100644
index 0000000..90b6898
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/04-signals.php
@@ -0,0 +1,19 @@
+<?php
+
+require __DIR__ . '/../vendor/autoload.php';
+
+if (!defined('SIGINT')) {
+ fwrite(STDERR, 'Not supported on your platform (ext-pcntl missing or Windows?)' . PHP_EOL);
+ exit(1);
+}
+
+$loop = React\EventLoop\Factory::create();
+
+$loop->addSignal(SIGINT, $func = function ($signal) use ($loop, &$func) {
+ echo 'Signal: ', (string)$signal, PHP_EOL;
+ $loop->removeSignal(SIGINT, $func);
+});
+
+echo 'Listening for SIGINT. Use "kill -SIGINT ' . getmypid() . '" or CTRL+C' . PHP_EOL;
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/11-consume-stdin.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/11-consume-stdin.php
new file mode 100644
index 0000000..2a77245
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/11-consume-stdin.php
@@ -0,0 +1,30 @@
+<?php
+
+use React\EventLoop\Factory;
+
+require __DIR__ . '/../vendor/autoload.php';
+
+if (!defined('STDIN') || stream_set_blocking(STDIN, false) !== true) {
+ fwrite(STDERR, 'ERROR: Unable to set STDIN non-blocking (not CLI or Windows?)' . PHP_EOL);
+ exit(1);
+}
+
+$loop = Factory::create();
+
+// read everything from STDIN and report number of bytes
+// for illustration purposes only, should use react/stream instead
+$loop->addReadStream(STDIN, function ($stream) use ($loop) {
+ $chunk = fread($stream, 64 * 1024);
+
+ // reading nothing means we reached EOF
+ if ($chunk === '') {
+ $loop->removeReadStream($stream);
+ stream_set_blocking($stream, true);
+ fclose($stream);
+ return;
+ }
+
+ echo strlen($chunk) . ' bytes' . PHP_EOL;
+});
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/12-generate-yes.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/12-generate-yes.php
new file mode 100644
index 0000000..ebc2beb
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/12-generate-yes.php
@@ -0,0 +1,41 @@
+<?php
+
+require __DIR__ . '/../vendor/autoload.php';
+
+// data can be given as first argument or defaults to "y"
+$data = (isset($argv[1]) ? $argv[1] : 'y') . "\n";
+
+// repeat data X times in order to fill around 200 KB
+$data = str_repeat($data, round(200000 / strlen($data)));
+
+$loop = React\EventLoop\Factory::create();
+
+if (!defined('STDOUT') || stream_set_blocking(STDOUT, false) !== true) {
+ fwrite(STDERR, 'ERROR: Unable to set STDOUT non-blocking (not CLI or Windows?)' . PHP_EOL);
+ exit(1);
+}
+
+// write data to STDOUT whenever its write buffer accepts data
+// for illustrations purpose only, should use react/stream instead
+$loop->addWriteStream(STDOUT, function ($stdout) use ($loop, &$data) {
+ // try to write data
+ $r = fwrite($stdout, $data);
+
+ // nothing could be written despite being writable => closed
+ if ($r === 0) {
+ $loop->removeWriteStream($stdout);
+ fclose($stdout);
+ stream_set_blocking($stdout, true);
+ fwrite(STDERR, 'Stopped because STDOUT closed' . PHP_EOL);
+
+ return;
+ }
+
+ // implement a very simple ring buffer, unless everything has been written at once:
+ // everything written in this iteration will be appended for next iteration
+ if (isset($data[$r])) {
+ $data = substr($data, $r) . substr($data, 0, $r);
+ }
+});
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/13-http-client-blocking.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/13-http-client-blocking.php
new file mode 100644
index 0000000..a2dde55
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/13-http-client-blocking.php
@@ -0,0 +1,35 @@
+<?php
+
+use React\EventLoop\Factory;
+
+require __DIR__ . '/../vendor/autoload.php';
+
+$loop = Factory::create();
+
+// connect to www.google.com:80 (blocking call!)
+// for illustration purposes only, should use react/socket instead
+$stream = stream_socket_client('tcp://www.google.com:80');
+if (!$stream) {
+ exit(1);
+}
+stream_set_blocking($stream, false);
+
+// send HTTP request
+fwrite($stream, "GET / HTTP/1.1\r\nHost: www.google.com\r\nConnection: close\r\n\r\n");
+
+// wait for HTTP response
+$loop->addReadStream($stream, function ($stream) use ($loop) {
+ $chunk = fread($stream, 64 * 1024);
+
+ // reading nothing means we reached EOF
+ if ($chunk === '') {
+ echo '[END]' . PHP_EOL;
+ $loop->removeReadStream($stream);
+ fclose($stream);
+ return;
+ }
+
+ echo $chunk;
+});
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/14-http-client-async.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/14-http-client-async.php
new file mode 100644
index 0000000..c82c988
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/14-http-client-async.php
@@ -0,0 +1,63 @@
+<?php
+
+use React\EventLoop\Factory;
+
+require __DIR__ . '/../vendor/autoload.php';
+
+$loop = Factory::create();
+
+// resolve hostname before establishing TCP/IP connection (resolving DNS is still blocking here)
+// for illustration purposes only, should use react/socket or react/dns instead!
+$ip = gethostbyname('www.google.com');
+if (ip2long($ip) === false) {
+ echo 'Unable to resolve hostname' . PHP_EOL;
+ exit(1);
+}
+
+// establish TCP/IP connection (non-blocking)
+// for illustraction purposes only, should use react/socket instead!
+$stream = stream_socket_client('tcp://' . $ip . ':80', $errno, $errstr, null, STREAM_CLIENT_CONNECT | STREAM_CLIENT_ASYNC_CONNECT);
+if (!$stream) {
+ exit(1);
+}
+stream_set_blocking($stream, false);
+
+// print progress every 10ms
+echo 'Connecting';
+$timer = $loop->addPeriodicTimer(0.01, function () {
+ echo '.';
+});
+
+// wait for connection success/error
+$loop->addWriteStream($stream, function ($stream) use ($loop, $timer) {
+ $loop->removeWriteStream($stream);
+ $loop->cancelTimer($timer);
+
+ // check for socket error (connection rejected)
+ if (stream_socket_get_name($stream, true) === false) {
+ echo '[unable to connect]' . PHP_EOL;
+ exit(1);
+ } else {
+ echo '[connected]' . PHP_EOL;
+ }
+
+ // send HTTP request
+ fwrite($stream, "GET / HTTP/1.1\r\nHost: www.google.com\r\nConnection: close\r\n\r\n");
+
+ // wait for HTTP response
+ $loop->addReadStream($stream, function ($stream) use ($loop) {
+ $chunk = fread($stream, 64 * 1024);
+
+ // reading nothing means we reached EOF
+ if ($chunk === '') {
+ echo '[END]' . PHP_EOL;
+ $loop->removeReadStream($stream);
+ fclose($stream);
+ return;
+ }
+
+ echo $chunk;
+ });
+});
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/21-http-server.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/21-http-server.php
new file mode 100644
index 0000000..89520ce
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/21-http-server.php
@@ -0,0 +1,36 @@
+<?php
+
+require __DIR__ . '/../vendor/autoload.php';
+
+$loop = React\EventLoop\Factory::create();
+
+// start TCP/IP server on localhost:8080
+// for illustration purposes only, should use react/socket instead
+$server = stream_socket_server('tcp://127.0.0.1:8080');
+if (!$server) {
+ exit(1);
+}
+stream_set_blocking($server, false);
+
+// wait for incoming connections on server socket
+$loop->addReadStream($server, function ($server) use ($loop) {
+ $conn = stream_socket_accept($server);
+ $data = "HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nHi\n";
+ $loop->addWriteStream($conn, function ($conn) use (&$data, $loop) {
+ $written = fwrite($conn, $data);
+ if ($written === strlen($data)) {
+ fclose($conn);
+ $loop->removeWriteStream($conn);
+ } else {
+ $data = substr($data, $written);
+ }
+ });
+});
+
+$loop->addPeriodicTimer(5, function () {
+ $memory = memory_get_usage() / 1024;
+ $formatted = number_format($memory, 3).'K';
+ echo "Current memory usage: {$formatted}\n";
+});
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/91-benchmark-ticks.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/91-benchmark-ticks.php
new file mode 100644
index 0000000..3f4690b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/91-benchmark-ticks.php
@@ -0,0 +1,15 @@
+<?php
+
+use React\EventLoop\Factory;
+
+require __DIR__ . '/../vendor/autoload.php';
+
+$loop = Factory::create();
+
+$n = isset($argv[1]) ? (int)$argv[1] : 1000 * 100;
+
+for ($i = 0; $i < $n; ++$i) {
+ $loop->futureTick(function () { });
+}
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/92-benchmark-timers.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/92-benchmark-timers.php
new file mode 100644
index 0000000..e2e02e4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/92-benchmark-timers.php
@@ -0,0 +1,15 @@
+<?php
+
+use React\EventLoop\Factory;
+
+require __DIR__ . '/../vendor/autoload.php';
+
+$loop = Factory::create();
+
+$n = isset($argv[1]) ? (int)$argv[1] : 1000 * 100;
+
+for ($i = 0; $i < $n; ++$i) {
+ $loop->addTimer(0, function () { });
+}
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/93-benchmark-ticks-delay.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/93-benchmark-ticks-delay.php
new file mode 100644
index 0000000..95ee78c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/93-benchmark-ticks-delay.php
@@ -0,0 +1,22 @@
+<?php
+
+use React\EventLoop\Factory;
+
+require __DIR__ . '/../vendor/autoload.php';
+
+$loop = Factory::create();
+
+$ticks = isset($argv[1]) ? (int)$argv[1] : 1000 * 100;
+$tick = function () use (&$tick, &$ticks, $loop) {
+ if ($ticks > 0) {
+ --$ticks;
+ //$loop->addTimer(0, $tick);
+ $loop->futureTick($tick);
+ } else {
+ echo 'done';
+ }
+};
+
+$tick();
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/94-benchmark-timers-delay.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/94-benchmark-timers-delay.php
new file mode 100644
index 0000000..2d6cfa2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/94-benchmark-timers-delay.php
@@ -0,0 +1,22 @@
+<?php
+
+use React\EventLoop\Factory;
+
+require __DIR__ . '/../vendor/autoload.php';
+
+$loop = Factory::create();
+
+$ticks = isset($argv[1]) ? (int)$argv[1] : 1000 * 100;
+$tick = function () use (&$tick, &$ticks, $loop) {
+ if ($ticks > 0) {
+ --$ticks;
+ //$loop->futureTick($tick);
+ $loop->addTimer(0, $tick);
+ } else {
+ echo 'done';
+ }
+};
+
+$tick();
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/95-benchmark-memory.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/95-benchmark-memory.php
new file mode 100644
index 0000000..084c404
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/examples/95-benchmark-memory.php
@@ -0,0 +1,67 @@
+<?php
+
+/**
+ * Run the script indefinitely seconds with the loop from the factory and report every 2 seconds:
+ * php 95-benchmark-memory.php
+ * Run the script for 30 seconds with the stream_select loop and report every 10 seconds:
+ * php 95-benchmark-memory.php -t 30 -l StreamSelect -r 10
+ */
+
+use React\EventLoop\Factory;
+use React\EventLoop\LoopInterface;
+use React\EventLoop\TimerInterface;
+
+require __DIR__ . '/../vendor/autoload.php';
+
+$args = getopt('t:l:r:');
+$t = isset($args['t']) ? (int)$args['t'] : 0;
+$loop = isset($args['l']) && class_exists('React\EventLoop\\' . $args['l'] . 'Loop') ? 'React\EventLoop\\' . $args['l'] . 'Loop' : Factory::create();
+
+if (!($loop instanceof LoopInterface)) {
+ $loop = new $loop();
+}
+
+$r = isset($args['r']) ? (int)$args['r'] : 2;
+
+$runs = 0;
+
+if (5 < $t) {
+ $loop->addTimer($t, function () use ($loop) {
+ $loop->stop();
+ });
+
+}
+
+$loop->addPeriodicTimer(0.001, function () use (&$runs, $loop) {
+ $runs++;
+
+ $loop->addPeriodicTimer(1, function (TimerInterface $timer) use ($loop) {
+ $loop->cancelTimer($timer);
+ });
+});
+
+$loop->addPeriodicTimer($r, function () use (&$runs) {
+ $kmem = round(memory_get_usage() / 1024);
+ $kmemReal = round(memory_get_usage(true) / 1024);
+ echo "Runs:\t\t\t$runs\n";
+ echo "Memory (internal):\t$kmem KiB\n";
+ echo "Memory (real):\t\t$kmemReal KiB\n";
+ echo str_repeat('-', 50), "\n";
+});
+
+echo "PHP Version:\t\t", phpversion(), "\n";
+echo "Loop\t\t\t", get_class($loop), "\n";
+echo "Time\t\t\t", date('r'), "\n";
+
+echo str_repeat('-', 50), "\n";
+
+$beginTime = time();
+$loop->run();
+$endTime = time();
+$timeTaken = $endTime - $beginTime;
+
+echo "PHP Version:\t\t", phpversion(), "\n";
+echo "Loop\t\t\t", get_class($loop), "\n";
+echo "Time\t\t\t", date('r'), "\n";
+echo "Time taken\t\t", $timeTaken, " seconds\n";
+echo "Runs per second\t\t", round($runs / $timeTaken), "\n";
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/phpunit.xml.dist b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/phpunit.xml.dist
new file mode 100644
index 0000000..cba6d4d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/phpunit.xml.dist
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit backupGlobals="false"
+ backupStaticAttributes="false"
+ colors="true"
+ convertErrorsToExceptions="true"
+ convertNoticesToExceptions="true"
+ convertWarningsToExceptions="true"
+ processIsolation="false"
+ stopOnFailure="false"
+ syntaxCheck="false"
+ bootstrap="tests/bootstrap.php"
+>
+ <testsuites>
+ <testsuite name="React Test Suite">
+ <directory>./tests/</directory>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist>
+ <directory>./src/</directory>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/ExtEvLoop.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/ExtEvLoop.php
new file mode 100644
index 0000000..74db6d0
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/ExtEvLoop.php
@@ -0,0 +1,252 @@
+<?php
+
+namespace React\EventLoop;
+
+use Ev;
+use EvIo;
+use EvLoop;
+use React\EventLoop\Tick\FutureTickQueue;
+use React\EventLoop\Timer\Timer;
+use SplObjectStorage;
+
+/**
+ * An `ext-ev` based event loop.
+ *
+ * This loop uses the [`ev` PECL extension](https://pecl.php.net/package/ev),
+ * that provides an interface to `libev` library.
+ *
+ * This loop is known to work with PHP 5.4 through PHP 7+.
+ *
+ * @see http://php.net/manual/en/book.ev.php
+ * @see https://bitbucket.org/osmanov/pecl-ev/overview
+ */
+class ExtEvLoop implements LoopInterface
+{
+ /**
+ * @var EvLoop
+ */
+ private $loop;
+
+ /**
+ * @var FutureTickQueue
+ */
+ private $futureTickQueue;
+
+ /**
+ * @var SplObjectStorage
+ */
+ private $timers;
+
+ /**
+ * @var EvIo[]
+ */
+ private $readStreams = [];
+
+ /**
+ * @var EvIo[]
+ */
+ private $writeStreams = [];
+
+ /**
+ * @var bool
+ */
+ private $running;
+
+ /**
+ * @var SignalsHandler
+ */
+ private $signals;
+
+ /**
+ * @var \EvSignal[]
+ */
+ private $signalEvents = [];
+
+ public function __construct()
+ {
+ $this->loop = new EvLoop();
+ $this->futureTickQueue = new FutureTickQueue();
+ $this->timers = new SplObjectStorage();
+ $this->signals = new SignalsHandler();
+ }
+
+ public function addReadStream($stream, $listener)
+ {
+ $key = (int)$stream;
+
+ if (isset($this->readStreams[$key])) {
+ return;
+ }
+
+ $callback = $this->getStreamListenerClosure($stream, $listener);
+ $event = $this->loop->io($stream, Ev::READ, $callback);
+ $this->readStreams[$key] = $event;
+ }
+
+ /**
+ * @param resource $stream
+ * @param callable $listener
+ *
+ * @return \Closure
+ */
+ private function getStreamListenerClosure($stream, $listener)
+ {
+ return function () use ($stream, $listener) {
+ call_user_func($listener, $stream);
+ };
+ }
+
+ public function addWriteStream($stream, $listener)
+ {
+ $key = (int)$stream;
+
+ if (isset($this->writeStreams[$key])) {
+ return;
+ }
+
+ $callback = $this->getStreamListenerClosure($stream, $listener);
+ $event = $this->loop->io($stream, Ev::WRITE, $callback);
+ $this->writeStreams[$key] = $event;
+ }
+
+ public function removeReadStream($stream)
+ {
+ $key = (int)$stream;
+
+ if (!isset($this->readStreams[$key])) {
+ return;
+ }
+
+ $this->readStreams[$key]->stop();
+ unset($this->readStreams[$key]);
+ }
+
+ public function removeWriteStream($stream)
+ {
+ $key = (int)$stream;
+
+ if (!isset($this->writeStreams[$key])) {
+ return;
+ }
+
+ $this->writeStreams[$key]->stop();
+ unset($this->writeStreams[$key]);
+ }
+
+ public function addTimer($interval, $callback)
+ {
+ $timer = new Timer($interval, $callback, false);
+
+ $that = $this;
+ $timers = $this->timers;
+ $callback = function () use ($timer, $timers, $that) {
+ call_user_func($timer->getCallback(), $timer);
+
+ if ($timers->contains($timer)) {
+ $that->cancelTimer($timer);
+ }
+ };
+
+ $event = $this->loop->timer($timer->getInterval(), 0.0, $callback);
+ $this->timers->attach($timer, $event);
+
+ return $timer;
+ }
+
+ public function addPeriodicTimer($interval, $callback)
+ {
+ $timer = new Timer($interval, $callback, true);
+
+ $callback = function () use ($timer) {
+ call_user_func($timer->getCallback(), $timer);
+ };
+
+ $event = $this->loop->timer($interval, $interval, $callback);
+ $this->timers->attach($timer, $event);
+
+ return $timer;
+ }
+
+ public function cancelTimer(TimerInterface $timer)
+ {
+ if (!isset($this->timers[$timer])) {
+ return;
+ }
+
+ $event = $this->timers[$timer];
+ $event->stop();
+ $this->timers->detach($timer);
+ }
+
+ public function futureTick($listener)
+ {
+ $this->futureTickQueue->add($listener);
+ }
+
+ public function run()
+ {
+ $this->running = true;
+
+ while ($this->running) {
+ $this->futureTickQueue->tick();
+
+ $hasPendingCallbacks = !$this->futureTickQueue->isEmpty();
+ $wasJustStopped = !$this->running;
+ $nothingLeftToDo = !$this->readStreams
+ && !$this->writeStreams
+ && !$this->timers->count()
+ && $this->signals->isEmpty();
+
+ $flags = Ev::RUN_ONCE;
+ if ($wasJustStopped || $hasPendingCallbacks) {
+ $flags |= Ev::RUN_NOWAIT;
+ } elseif ($nothingLeftToDo) {
+ break;
+ }
+
+ $this->loop->run($flags);
+ }
+ }
+
+ public function stop()
+ {
+ $this->running = false;
+ }
+
+ public function __destruct()
+ {
+ /** @var TimerInterface $timer */
+ foreach ($this->timers as $timer) {
+ $this->cancelTimer($timer);
+ }
+
+ foreach ($this->readStreams as $key => $stream) {
+ $this->removeReadStream($key);
+ }
+
+ foreach ($this->writeStreams as $key => $stream) {
+ $this->removeWriteStream($key);
+ }
+ }
+
+ public function addSignal($signal, $listener)
+ {
+ $this->signals->add($signal, $listener);
+
+ if (!isset($this->signalEvents[$signal])) {
+ $this->signalEvents[$signal] = $this->loop->signal($signal, function() use ($signal) {
+ $this->signals->call($signal);
+ });
+ }
+ }
+
+ public function removeSignal($signal, $listener)
+ {
+ $this->signals->remove($signal, $listener);
+
+ if (isset($this->signalEvents[$signal])) {
+ $this->signalEvents[$signal]->stop();
+ unset($this->signalEvents[$signal]);
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/ExtEventLoop.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/ExtEventLoop.php
new file mode 100644
index 0000000..622dd47
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/ExtEventLoop.php
@@ -0,0 +1,259 @@
+<?php
+
+namespace React\EventLoop;
+
+use BadMethodCallException;
+use Event;
+use EventBase;
+use EventConfig as EventBaseConfig;
+use React\EventLoop\Tick\FutureTickQueue;
+use React\EventLoop\Timer\Timer;
+use SplObjectStorage;
+
+/**
+ * An `ext-event` based event loop.
+ *
+ * This uses the [`event` PECL extension](https://pecl.php.net/package/event).
+ * It supports the same backends as libevent.
+ *
+ * This loop is known to work with PHP 5.4 through PHP 7+.
+ *
+ * @link https://pecl.php.net/package/event
+ */
+final class ExtEventLoop implements LoopInterface
+{
+ private $eventBase;
+ private $futureTickQueue;
+ private $timerCallback;
+ private $timerEvents;
+ private $streamCallback;
+ private $readEvents = array();
+ private $writeEvents = array();
+ private $readListeners = array();
+ private $writeListeners = array();
+ private $readRefs = array();
+ private $writeRefs = array();
+ private $running;
+ private $signals;
+ private $signalEvents = array();
+
+ public function __construct()
+ {
+ if (!class_exists('EventBase', false)) {
+ throw new BadMethodCallException('Cannot create ExtEventLoop, ext-event extension missing');
+ }
+
+ $config = new EventBaseConfig();
+ $config->requireFeatures(EventBaseConfig::FEATURE_FDS);
+
+ $this->eventBase = new EventBase($config);
+ $this->futureTickQueue = new FutureTickQueue();
+ $this->timerEvents = new SplObjectStorage();
+ $this->signals = new SignalsHandler();
+
+ $this->createTimerCallback();
+ $this->createStreamCallback();
+ }
+
+ public function addReadStream($stream, $listener)
+ {
+ $key = (int) $stream;
+ if (isset($this->readListeners[$key])) {
+ return;
+ }
+
+ $event = new Event($this->eventBase, $stream, Event::PERSIST | Event::READ, $this->streamCallback);
+ $event->add();
+ $this->readEvents[$key] = $event;
+ $this->readListeners[$key] = $listener;
+
+ // ext-event does not increase refcount on stream resources for PHP 7+
+ // manually keep track of stream resource to prevent premature garbage collection
+ if (PHP_VERSION_ID >= 70000) {
+ $this->readRefs[$key] = $stream;
+ }
+ }
+
+ public function addWriteStream($stream, $listener)
+ {
+ $key = (int) $stream;
+ if (isset($this->writeListeners[$key])) {
+ return;
+ }
+
+ $event = new Event($this->eventBase, $stream, Event::PERSIST | Event::WRITE, $this->streamCallback);
+ $event->add();
+ $this->writeEvents[$key] = $event;
+ $this->writeListeners[$key] = $listener;
+
+ // ext-event does not increase refcount on stream resources for PHP 7+
+ // manually keep track of stream resource to prevent premature garbage collection
+ if (PHP_VERSION_ID >= 70000) {
+ $this->writeRefs[$key] = $stream;
+ }
+ }
+
+ public function removeReadStream($stream)
+ {
+ $key = (int) $stream;
+
+ if (isset($this->readEvents[$key])) {
+ $this->readEvents[$key]->free();
+ unset(
+ $this->readEvents[$key],
+ $this->readListeners[$key],
+ $this->readRefs[$key]
+ );
+ }
+ }
+
+ public function removeWriteStream($stream)
+ {
+ $key = (int) $stream;
+
+ if (isset($this->writeEvents[$key])) {
+ $this->writeEvents[$key]->free();
+ unset(
+ $this->writeEvents[$key],
+ $this->writeListeners[$key],
+ $this->writeRefs[$key]
+ );
+ }
+ }
+
+ public function addTimer($interval, $callback)
+ {
+ $timer = new Timer($interval, $callback, false);
+
+ $this->scheduleTimer($timer);
+
+ return $timer;
+ }
+
+ public function addPeriodicTimer($interval, $callback)
+ {
+ $timer = new Timer($interval, $callback, true);
+
+ $this->scheduleTimer($timer);
+
+ return $timer;
+ }
+
+ public function cancelTimer(TimerInterface $timer)
+ {
+ if ($this->timerEvents->contains($timer)) {
+ $this->timerEvents[$timer]->free();
+ $this->timerEvents->detach($timer);
+ }
+ }
+
+ public function futureTick($listener)
+ {
+ $this->futureTickQueue->add($listener);
+ }
+
+ public function addSignal($signal, $listener)
+ {
+ $this->signals->add($signal, $listener);
+
+ if (!isset($this->signalEvents[$signal])) {
+ $this->signalEvents[$signal] = Event::signal($this->eventBase, $signal, array($this->signals, 'call'));
+ $this->signalEvents[$signal]->add();
+ }
+ }
+
+ public function removeSignal($signal, $listener)
+ {
+ $this->signals->remove($signal, $listener);
+
+ if (isset($this->signalEvents[$signal]) && $this->signals->count($signal) === 0) {
+ $this->signalEvents[$signal]->free();
+ unset($this->signalEvents[$signal]);
+ }
+ }
+
+ public function run()
+ {
+ $this->running = true;
+
+ while ($this->running) {
+ $this->futureTickQueue->tick();
+
+ $flags = EventBase::LOOP_ONCE;
+ if (!$this->running || !$this->futureTickQueue->isEmpty()) {
+ $flags |= EventBase::LOOP_NONBLOCK;
+ } elseif (!$this->readEvents && !$this->writeEvents && !$this->timerEvents->count() && $this->signals->isEmpty()) {
+ break;
+ }
+
+ $this->eventBase->loop($flags);
+ }
+ }
+
+ public function stop()
+ {
+ $this->running = false;
+ }
+
+ /**
+ * Schedule a timer for execution.
+ *
+ * @param TimerInterface $timer
+ */
+ private function scheduleTimer(TimerInterface $timer)
+ {
+ $flags = Event::TIMEOUT;
+
+ if ($timer->isPeriodic()) {
+ $flags |= Event::PERSIST;
+ }
+
+ $event = new Event($this->eventBase, -1, $flags, $this->timerCallback, $timer);
+ $this->timerEvents[$timer] = $event;
+
+ $event->add($timer->getInterval());
+ }
+
+ /**
+ * Create a callback used as the target of timer events.
+ *
+ * A reference is kept to the callback for the lifetime of the loop
+ * to prevent "Cannot destroy active lambda function" fatal error from
+ * the event extension.
+ */
+ private function createTimerCallback()
+ {
+ $timers = $this->timerEvents;
+ $this->timerCallback = function ($_, $__, $timer) use ($timers) {
+ call_user_func($timer->getCallback(), $timer);
+
+ if (!$timer->isPeriodic() && $timers->contains($timer)) {
+ $this->cancelTimer($timer);
+ }
+ };
+ }
+
+ /**
+ * Create a callback used as the target of stream events.
+ *
+ * A reference is kept to the callback for the lifetime of the loop
+ * to prevent "Cannot destroy active lambda function" fatal error from
+ * the event extension.
+ */
+ private function createStreamCallback()
+ {
+ $read =& $this->readListeners;
+ $write =& $this->writeListeners;
+ $this->streamCallback = function ($stream, $flags) use (&$read, &$write) {
+ $key = (int) $stream;
+
+ if (Event::READ === (Event::READ & $flags) && isset($read[$key])) {
+ call_user_func($read[$key], $stream);
+ }
+
+ if (Event::WRITE === (Event::WRITE & $flags) && isset($write[$key])) {
+ call_user_func($write[$key], $stream);
+ }
+ };
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/ExtLibevLoop.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/ExtLibevLoop.php
new file mode 100644
index 0000000..d3b0df8
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/ExtLibevLoop.php
@@ -0,0 +1,199 @@
+<?php
+
+namespace React\EventLoop;
+
+use BadMethodCallException;
+use libev\EventLoop;
+use libev\IOEvent;
+use libev\SignalEvent;
+use libev\TimerEvent;
+use React\EventLoop\Tick\FutureTickQueue;
+use React\EventLoop\Timer\Timer;
+use SplObjectStorage;
+
+/**
+ * An `ext-libev` based event loop.
+ *
+ * This uses an [unofficial `libev` extension](https://github.com/m4rw3r/php-libev).
+ * It supports the same backends as libevent.
+ *
+ * This loop does only work with PHP 5.
+ * An update for PHP 7 is [unlikely](https://github.com/m4rw3r/php-libev/issues/8)
+ * to happen any time soon.
+ *
+ * @see https://github.com/m4rw3r/php-libev
+ * @see https://gist.github.com/1688204
+ */
+final class ExtLibevLoop implements LoopInterface
+{
+ private $loop;
+ private $futureTickQueue;
+ private $timerEvents;
+ private $readEvents = array();
+ private $writeEvents = array();
+ private $running;
+ private $signals;
+ private $signalEvents = array();
+
+ public function __construct()
+ {
+ if (!class_exists('libev\EventLoop', false)) {
+ throw new BadMethodCallException('Cannot create ExtLibevLoop, ext-libev extension missing');
+ }
+
+ $this->loop = new EventLoop();
+ $this->futureTickQueue = new FutureTickQueue();
+ $this->timerEvents = new SplObjectStorage();
+ $this->signals = new SignalsHandler();
+ }
+
+ public function addReadStream($stream, $listener)
+ {
+ if (isset($this->readEvents[(int) $stream])) {
+ return;
+ }
+
+ $callback = function () use ($stream, $listener) {
+ call_user_func($listener, $stream);
+ };
+
+ $event = new IOEvent($callback, $stream, IOEvent::READ);
+ $this->loop->add($event);
+
+ $this->readEvents[(int) $stream] = $event;
+ }
+
+ public function addWriteStream($stream, $listener)
+ {
+ if (isset($this->writeEvents[(int) $stream])) {
+ return;
+ }
+
+ $callback = function () use ($stream, $listener) {
+ call_user_func($listener, $stream);
+ };
+
+ $event = new IOEvent($callback, $stream, IOEvent::WRITE);
+ $this->loop->add($event);
+
+ $this->writeEvents[(int) $stream] = $event;
+ }
+
+ public function removeReadStream($stream)
+ {
+ $key = (int) $stream;
+
+ if (isset($this->readEvents[$key])) {
+ $this->readEvents[$key]->stop();
+ $this->loop->remove($this->readEvents[$key]);
+ unset($this->readEvents[$key]);
+ }
+ }
+
+ public function removeWriteStream($stream)
+ {
+ $key = (int) $stream;
+
+ if (isset($this->writeEvents[$key])) {
+ $this->writeEvents[$key]->stop();
+ $this->loop->remove($this->writeEvents[$key]);
+ unset($this->writeEvents[$key]);
+ }
+ }
+
+ public function addTimer($interval, $callback)
+ {
+ $timer = new Timer( $interval, $callback, false);
+
+ $that = $this;
+ $timers = $this->timerEvents;
+ $callback = function () use ($timer, $timers, $that) {
+ call_user_func($timer->getCallback(), $timer);
+
+ if ($timers->contains($timer)) {
+ $that->cancelTimer($timer);
+ }
+ };
+
+ $event = new TimerEvent($callback, $timer->getInterval());
+ $this->timerEvents->attach($timer, $event);
+ $this->loop->add($event);
+
+ return $timer;
+ }
+
+ public function addPeriodicTimer($interval, $callback)
+ {
+ $timer = new Timer($interval, $callback, true);
+
+ $callback = function () use ($timer) {
+ call_user_func($timer->getCallback(), $timer);
+ };
+
+ $event = new TimerEvent($callback, $interval, $interval);
+ $this->timerEvents->attach($timer, $event);
+ $this->loop->add($event);
+
+ return $timer;
+ }
+
+ public function cancelTimer(TimerInterface $timer)
+ {
+ if (isset($this->timerEvents[$timer])) {
+ $this->loop->remove($this->timerEvents[$timer]);
+ $this->timerEvents->detach($timer);
+ }
+ }
+
+ public function futureTick($listener)
+ {
+ $this->futureTickQueue->add($listener);
+ }
+
+ public function addSignal($signal, $listener)
+ {
+ $this->signals->add($signal, $listener);
+
+ if (!isset($this->signalEvents[$signal])) {
+ $signals = $this->signals;
+ $this->signalEvents[$signal] = new SignalEvent(function () use ($signals, $signal) {
+ $signals->call($signal);
+ }, $signal);
+ $this->loop->add($this->signalEvents[$signal]);
+ }
+ }
+
+ public function removeSignal($signal, $listener)
+ {
+ $this->signals->remove($signal, $listener);
+
+ if (isset($this->signalEvents[$signal]) && $this->signals->count($signal) === 0) {
+ $this->signalEvents[$signal]->stop();
+ $this->loop->remove($this->signalEvents[$signal]);
+ unset($this->signalEvents[$signal]);
+ }
+ }
+
+ public function run()
+ {
+ $this->running = true;
+
+ while ($this->running) {
+ $this->futureTickQueue->tick();
+
+ $flags = EventLoop::RUN_ONCE;
+ if (!$this->running || !$this->futureTickQueue->isEmpty()) {
+ $flags |= EventLoop::RUN_NOWAIT;
+ } elseif (!$this->readEvents && !$this->writeEvents && !$this->timerEvents->count() && $this->signals->isEmpty()) {
+ break;
+ }
+
+ $this->loop->run($flags);
+ }
+ }
+
+ public function stop()
+ {
+ $this->running = false;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/ExtLibeventLoop.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/ExtLibeventLoop.php
new file mode 100644
index 0000000..427f8db
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/ExtLibeventLoop.php
@@ -0,0 +1,283 @@
+<?php
+
+namespace React\EventLoop;
+
+use BadMethodCallException;
+use Event;
+use EventBase;
+use React\EventLoop\Tick\FutureTickQueue;
+use React\EventLoop\Timer\Timer;
+use SplObjectStorage;
+
+/**
+ * An `ext-libevent` based event loop.
+ *
+ * This uses the [`libevent` PECL extension](https://pecl.php.net/package/libevent).
+ * `libevent` itself supports a number of system-specific backends (epoll, kqueue).
+ *
+ * This event loop does only work with PHP 5.
+ * An [unofficial update](https://github.com/php/pecl-event-libevent/pull/2) for
+ * PHP 7 does exist, but it is known to cause regular crashes due to `SEGFAULT`s.
+ * To reiterate: Using this event loop on PHP 7 is not recommended.
+ * Accordingly, the [`Factory`](#factory) will not try to use this event loop on
+ * PHP 7.
+ *
+ * This event loop is known to trigger a readable listener only if
+ * the stream *becomes* readable (edge-triggered) and may not trigger if the
+ * stream has already been readable from the beginning.
+ * This also implies that a stream may not be recognized as readable when data
+ * is still left in PHP's internal stream buffers.
+ * As such, it's recommended to use `stream_set_read_buffer($stream, 0);`
+ * to disable PHP's internal read buffer in this case.
+ * See also [`addReadStream()`](#addreadstream) for more details.
+ *
+ * @link https://pecl.php.net/package/libevent
+ */
+final class ExtLibeventLoop implements LoopInterface
+{
+ /** @internal */
+ const MICROSECONDS_PER_SECOND = 1000000;
+
+ private $eventBase;
+ private $futureTickQueue;
+ private $timerCallback;
+ private $timerEvents;
+ private $streamCallback;
+ private $readEvents = array();
+ private $writeEvents = array();
+ private $readListeners = array();
+ private $writeListeners = array();
+ private $running;
+ private $signals;
+ private $signalEvents = array();
+
+ public function __construct()
+ {
+ if (!function_exists('event_base_new')) {
+ throw new BadMethodCallException('Cannot create ExtLibeventLoop, ext-libevent extension missing');
+ }
+
+ $this->eventBase = event_base_new();
+ $this->futureTickQueue = new FutureTickQueue();
+ $this->timerEvents = new SplObjectStorage();
+ $this->signals = new SignalsHandler();
+
+ $this->createTimerCallback();
+ $this->createStreamCallback();
+ }
+
+ public function addReadStream($stream, $listener)
+ {
+ $key = (int) $stream;
+ if (isset($this->readListeners[$key])) {
+ return;
+ }
+
+ $event = event_new();
+ event_set($event, $stream, EV_PERSIST | EV_READ, $this->streamCallback);
+ event_base_set($event, $this->eventBase);
+ event_add($event);
+
+ $this->readEvents[$key] = $event;
+ $this->readListeners[$key] = $listener;
+ }
+
+ public function addWriteStream($stream, $listener)
+ {
+ $key = (int) $stream;
+ if (isset($this->writeListeners[$key])) {
+ return;
+ }
+
+ $event = event_new();
+ event_set($event, $stream, EV_PERSIST | EV_WRITE, $this->streamCallback);
+ event_base_set($event, $this->eventBase);
+ event_add($event);
+
+ $this->writeEvents[$key] = $event;
+ $this->writeListeners[$key] = $listener;
+ }
+
+ public function removeReadStream($stream)
+ {
+ $key = (int) $stream;
+
+ if (isset($this->readListeners[$key])) {
+ $event = $this->readEvents[$key];
+ event_del($event);
+ event_free($event);
+
+ unset(
+ $this->readEvents[$key],
+ $this->readListeners[$key]
+ );
+ }
+ }
+
+ public function removeWriteStream($stream)
+ {
+ $key = (int) $stream;
+
+ if (isset($this->writeListeners[$key])) {
+ $event = $this->writeEvents[$key];
+ event_del($event);
+ event_free($event);
+
+ unset(
+ $this->writeEvents[$key],
+ $this->writeListeners[$key]
+ );
+ }
+ }
+
+ public function addTimer($interval, $callback)
+ {
+ $timer = new Timer($interval, $callback, false);
+
+ $this->scheduleTimer($timer);
+
+ return $timer;
+ }
+
+ public function addPeriodicTimer($interval, $callback)
+ {
+ $timer = new Timer($interval, $callback, true);
+
+ $this->scheduleTimer($timer);
+
+ return $timer;
+ }
+
+ public function cancelTimer(TimerInterface $timer)
+ {
+ if ($this->timerEvents->contains($timer)) {
+ $event = $this->timerEvents[$timer];
+ event_del($event);
+ event_free($event);
+
+ $this->timerEvents->detach($timer);
+ }
+ }
+
+ public function futureTick($listener)
+ {
+ $this->futureTickQueue->add($listener);
+ }
+
+ public function addSignal($signal, $listener)
+ {
+ $this->signals->add($signal, $listener);
+
+ if (!isset($this->signalEvents[$signal])) {
+ $this->signalEvents[$signal] = event_new();
+ event_set($this->signalEvents[$signal], $signal, EV_PERSIST | EV_SIGNAL, array($this->signals, 'call'));
+ event_base_set($this->signalEvents[$signal], $this->eventBase);
+ event_add($this->signalEvents[$signal]);
+ }
+ }
+
+ public function removeSignal($signal, $listener)
+ {
+ $this->signals->remove($signal, $listener);
+
+ if (isset($this->signalEvents[$signal]) && $this->signals->count($signal) === 0) {
+ event_del($this->signalEvents[$signal]);
+ event_free($this->signalEvents[$signal]);
+ unset($this->signalEvents[$signal]);
+ }
+ }
+
+ public function run()
+ {
+ $this->running = true;
+
+ while ($this->running) {
+ $this->futureTickQueue->tick();
+
+ $flags = EVLOOP_ONCE;
+ if (!$this->running || !$this->futureTickQueue->isEmpty()) {
+ $flags |= EVLOOP_NONBLOCK;
+ } elseif (!$this->readEvents && !$this->writeEvents && !$this->timerEvents->count() && $this->signals->isEmpty()) {
+ break;
+ }
+
+ event_base_loop($this->eventBase, $flags);
+ }
+ }
+
+ public function stop()
+ {
+ $this->running = false;
+ }
+
+ /**
+ * Schedule a timer for execution.
+ *
+ * @param TimerInterface $timer
+ */
+ private function scheduleTimer(TimerInterface $timer)
+ {
+ $this->timerEvents[$timer] = $event = event_timer_new();
+
+ event_timer_set($event, $this->timerCallback, $timer);
+ event_base_set($event, $this->eventBase);
+ event_add($event, $timer->getInterval() * self::MICROSECONDS_PER_SECOND);
+ }
+
+ /**
+ * Create a callback used as the target of timer events.
+ *
+ * A reference is kept to the callback for the lifetime of the loop
+ * to prevent "Cannot destroy active lambda function" fatal error from
+ * the event extension.
+ */
+ private function createTimerCallback()
+ {
+ $that = $this;
+ $timers = $this->timerEvents;
+ $this->timerCallback = function ($_, $__, $timer) use ($timers, $that) {
+ call_user_func($timer->getCallback(), $timer);
+
+ // Timer already cancelled ...
+ if (!$timers->contains($timer)) {
+ return;
+ }
+
+ // Reschedule periodic timers ...
+ if ($timer->isPeriodic()) {
+ event_add(
+ $timers[$timer],
+ $timer->getInterval() * ExtLibeventLoop::MICROSECONDS_PER_SECOND
+ );
+
+ // Clean-up one shot timers ...
+ } else {
+ $that->cancelTimer($timer);
+ }
+ };
+ }
+
+ /**
+ * Create a callback used as the target of stream events.
+ *
+ * A reference is kept to the callback for the lifetime of the loop
+ * to prevent "Cannot destroy active lambda function" fatal error from
+ * the event extension.
+ */
+ private function createStreamCallback()
+ {
+ $read =& $this->readListeners;
+ $write =& $this->writeListeners;
+ $this->streamCallback = function ($stream, $flags) use (&$read, &$write) {
+ $key = (int) $stream;
+
+ if (EV_READ === (EV_READ & $flags) && isset($read[$key])) {
+ call_user_func($read[$key], $stream);
+ }
+
+ if (EV_WRITE === (EV_WRITE & $flags) && isset($write[$key])) {
+ call_user_func($write[$key], $stream);
+ }
+ };
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/Factory.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/Factory.php
new file mode 100644
index 0000000..b46fc07
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/Factory.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace React\EventLoop;
+
+/**
+ * The `Factory` class exists as a convenient way to pick the best available event loop implementation.
+ */
+final class Factory
+{
+ /**
+ * Creates a new event loop instance
+ *
+ * ```php
+ * $loop = React\EventLoop\Factory::create();
+ * ```
+ *
+ * This method always returns an instance implementing `LoopInterface`,
+ * the actual event loop implementation is an implementation detail.
+ *
+ * This method should usually only be called once at the beginning of the program.
+ *
+ * @return LoopInterface
+ */
+ public static function create()
+ {
+ // @codeCoverageIgnoreStart
+ if (class_exists('libev\EventLoop', false)) {
+ return new ExtLibevLoop();
+ } elseif (class_exists('EvLoop', false)) {
+ return new ExtEvLoop();
+ } elseif (class_exists('EventBase', false)) {
+ return new ExtEventLoop();
+ } elseif (function_exists('event_base_new') && PHP_VERSION_ID < 70000) {
+ // only use ext-libevent on PHP < 7 for now
+ return new ExtLibeventLoop();
+ }
+
+ return new StreamSelectLoop();
+ // @codeCoverageIgnoreEnd
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/LoopInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/LoopInterface.php
new file mode 100644
index 0000000..1cc8640
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/LoopInterface.php
@@ -0,0 +1,463 @@
+<?php
+
+namespace React\EventLoop;
+
+interface LoopInterface
+{
+ /**
+ * [Advanced] Register a listener to be notified when a stream is ready to read.
+ *
+ * Note that this low-level API is considered advanced usage.
+ * Most use cases should probably use the higher-level
+ * [readable Stream API](https://github.com/reactphp/stream#readablestreaminterface)
+ * instead.
+ *
+ * The first parameter MUST be a valid stream resource that supports
+ * checking whether it is ready to read by this loop implementation.
+ * A single stream resource MUST NOT be added more than once.
+ * Instead, either call [`removeReadStream()`](#removereadstream) first or
+ * react to this event with a single listener and then dispatch from this
+ * listener. This method MAY throw an `Exception` if the given resource type
+ * is not supported by this loop implementation.
+ *
+ * The listener callback function MUST be able to accept a single parameter,
+ * the stream resource added by this method or you MAY use a function which
+ * has no parameters at all.
+ *
+ * The listener callback function MUST NOT throw an `Exception`.
+ * The return value of the listener callback function will be ignored and has
+ * no effect, so for performance reasons you're recommended to not return
+ * any excessive data structures.
+ *
+ * If you want to access any variables within your callback function, you
+ * can bind arbitrary data to a callback closure like this:
+ *
+ * ```php
+ * $loop->addReadStream($stream, function ($stream) use ($name) {
+ * echo $name . ' said: ' . fread($stream);
+ * });
+ * ```
+ *
+ * See also [example #11](examples).
+ *
+ * You can invoke [`removeReadStream()`](#removereadstream) to remove the
+ * read event listener for this stream.
+ *
+ * The execution order of listeners when multiple streams become ready at
+ * the same time is not guaranteed.
+ *
+ * @param resource $stream The PHP stream resource to check.
+ * @param callable $listener Invoked when the stream is ready.
+ * @throws \Exception if the given resource type is not supported by this loop implementation
+ * @see self::removeReadStream()
+ */
+ public function addReadStream($stream, $listener);
+
+ /**
+ * [Advanced] Register a listener to be notified when a stream is ready to write.
+ *
+ * Note that this low-level API is considered advanced usage.
+ * Most use cases should probably use the higher-level
+ * [writable Stream API](https://github.com/reactphp/stream#writablestreaminterface)
+ * instead.
+ *
+ * The first parameter MUST be a valid stream resource that supports
+ * checking whether it is ready to write by this loop implementation.
+ * A single stream resource MUST NOT be added more than once.
+ * Instead, either call [`removeWriteStream()`](#removewritestream) first or
+ * react to this event with a single listener and then dispatch from this
+ * listener. This method MAY throw an `Exception` if the given resource type
+ * is not supported by this loop implementation.
+ *
+ * The listener callback function MUST be able to accept a single parameter,
+ * the stream resource added by this method or you MAY use a function which
+ * has no parameters at all.
+ *
+ * The listener callback function MUST NOT throw an `Exception`.
+ * The return value of the listener callback function will be ignored and has
+ * no effect, so for performance reasons you're recommended to not return
+ * any excessive data structures.
+ *
+ * If you want to access any variables within your callback function, you
+ * can bind arbitrary data to a callback closure like this:
+ *
+ * ```php
+ * $loop->addWriteStream($stream, function ($stream) use ($name) {
+ * fwrite($stream, 'Hello ' . $name);
+ * });
+ * ```
+ *
+ * See also [example #12](examples).
+ *
+ * You can invoke [`removeWriteStream()`](#removewritestream) to remove the
+ * write event listener for this stream.
+ *
+ * The execution order of listeners when multiple streams become ready at
+ * the same time is not guaranteed.
+ *
+ * Some event loop implementations are known to only trigger the listener if
+ * the stream *becomes* readable (edge-triggered) and may not trigger if the
+ * stream has already been readable from the beginning.
+ * This also implies that a stream may not be recognized as readable when data
+ * is still left in PHP's internal stream buffers.
+ * As such, it's recommended to use `stream_set_read_buffer($stream, 0);`
+ * to disable PHP's internal read buffer in this case.
+ *
+ * @param resource $stream The PHP stream resource to check.
+ * @param callable $listener Invoked when the stream is ready.
+ * @throws \Exception if the given resource type is not supported by this loop implementation
+ * @see self::removeWriteStream()
+ */
+ public function addWriteStream($stream, $listener);
+
+ /**
+ * Remove the read event listener for the given stream.
+ *
+ * Removing a stream from the loop that has already been removed or trying
+ * to remove a stream that was never added or is invalid has no effect.
+ *
+ * @param resource $stream The PHP stream resource.
+ */
+ public function removeReadStream($stream);
+
+ /**
+ * Remove the write event listener for the given stream.
+ *
+ * Removing a stream from the loop that has already been removed or trying
+ * to remove a stream that was never added or is invalid has no effect.
+ *
+ * @param resource $stream The PHP stream resource.
+ */
+ public function removeWriteStream($stream);
+
+ /**
+ * Enqueue a callback to be invoked once after the given interval.
+ *
+ * The timer callback function MUST be able to accept a single parameter,
+ * the timer instance as also returned by this method or you MAY use a
+ * function which has no parameters at all.
+ *
+ * The timer callback function MUST NOT throw an `Exception`.
+ * The return value of the timer callback function will be ignored and has
+ * no effect, so for performance reasons you're recommended to not return
+ * any excessive data structures.
+ *
+ * Unlike [`addPeriodicTimer()`](#addperiodictimer), this method will ensure
+ * the callback will be invoked only once after the given interval.
+ * You can invoke [`cancelTimer`](#canceltimer) to cancel a pending timer.
+ *
+ * ```php
+ * $loop->addTimer(0.8, function () {
+ * echo 'world!' . PHP_EOL;
+ * });
+ *
+ * $loop->addTimer(0.3, function () {
+ * echo 'hello ';
+ * });
+ * ```
+ *
+ * See also [example #1](examples).
+ *
+ * If you want to access any variables within your callback function, you
+ * can bind arbitrary data to a callback closure like this:
+ *
+ * ```php
+ * function hello($name, LoopInterface $loop)
+ * {
+ * $loop->addTimer(1.0, function () use ($name) {
+ * echo "hello $name\n";
+ * });
+ * }
+ *
+ * hello('Tester', $loop);
+ * ```
+ *
+ * This interface does not enforce any particular timer resolution, so
+ * special care may have to be taken if you rely on very high precision with
+ * millisecond accuracy or below. Event loop implementations SHOULD work on
+ * a best effort basis and SHOULD provide at least millisecond accuracy
+ * unless otherwise noted. Many existing event loop implementations are
+ * known to provide microsecond accuracy, but it's generally not recommended
+ * to rely on this high precision.
+ *
+ * Similarly, the execution order of timers scheduled to execute at the
+ * same time (within its possible accuracy) is not guaranteed.
+ *
+ * This interface suggests that event loop implementations SHOULD use a
+ * monotonic time source if available. Given that a monotonic time source is
+ * not available on PHP by default, event loop implementations MAY fall back
+ * to using wall-clock time.
+ * While this does not affect many common use cases, this is an important
+ * distinction for programs that rely on a high time precision or on systems
+ * that are subject to discontinuous time adjustments (time jumps).
+ * This means that if you schedule a timer to trigger in 30s and then adjust
+ * your system time forward by 20s, the timer SHOULD still trigger in 30s.
+ * See also [event loop implementations](#loop-implementations) for more details.
+ *
+ * @param int|float $interval The number of seconds to wait before execution.
+ * @param callable $callback The callback to invoke.
+ *
+ * @return TimerInterface
+ */
+ public function addTimer($interval, $callback);
+
+ /**
+ * Enqueue a callback to be invoked repeatedly after the given interval.
+ *
+ * The timer callback function MUST be able to accept a single parameter,
+ * the timer instance as also returned by this method or you MAY use a
+ * function which has no parameters at all.
+ *
+ * The timer callback function MUST NOT throw an `Exception`.
+ * The return value of the timer callback function will be ignored and has
+ * no effect, so for performance reasons you're recommended to not return
+ * any excessive data structures.
+ *
+ * Unlike [`addTimer()`](#addtimer), this method will ensure the the
+ * callback will be invoked infinitely after the given interval or until you
+ * invoke [`cancelTimer`](#canceltimer).
+ *
+ * ```php
+ * $timer = $loop->addPeriodicTimer(0.1, function () {
+ * echo 'tick!' . PHP_EOL;
+ * });
+ *
+ * $loop->addTimer(1.0, function () use ($loop, $timer) {
+ * $loop->cancelTimer($timer);
+ * echo 'Done' . PHP_EOL;
+ * });
+ * ```
+ *
+ * See also [example #2](examples).
+ *
+ * If you want to limit the number of executions, you can bind
+ * arbitrary data to a callback closure like this:
+ *
+ * ```php
+ * function hello($name, LoopInterface $loop)
+ * {
+ * $n = 3;
+ * $loop->addPeriodicTimer(1.0, function ($timer) use ($name, $loop, &$n) {
+ * if ($n > 0) {
+ * --$n;
+ * echo "hello $name\n";
+ * } else {
+ * $loop->cancelTimer($timer);
+ * }
+ * });
+ * }
+ *
+ * hello('Tester', $loop);
+ * ```
+ *
+ * This interface does not enforce any particular timer resolution, so
+ * special care may have to be taken if you rely on very high precision with
+ * millisecond accuracy or below. Event loop implementations SHOULD work on
+ * a best effort basis and SHOULD provide at least millisecond accuracy
+ * unless otherwise noted. Many existing event loop implementations are
+ * known to provide microsecond accuracy, but it's generally not recommended
+ * to rely on this high precision.
+ *
+ * Similarly, the execution order of timers scheduled to execute at the
+ * same time (within its possible accuracy) is not guaranteed.
+ *
+ * This interface suggests that event loop implementations SHOULD use a
+ * monotonic time source if available. Given that a monotonic time source is
+ * not available on PHP by default, event loop implementations MAY fall back
+ * to using wall-clock time.
+ * While this does not affect many common use cases, this is an important
+ * distinction for programs that rely on a high time precision or on systems
+ * that are subject to discontinuous time adjustments (time jumps).
+ * This means that if you schedule a timer to trigger in 30s and then adjust
+ * your system time forward by 20s, the timer SHOULD still trigger in 30s.
+ * See also [event loop implementations](#loop-implementations) for more details.
+ *
+ * Additionally, periodic timers may be subject to timer drift due to
+ * re-scheduling after each invocation. As such, it's generally not
+ * recommended to rely on this for high precision intervals with millisecond
+ * accuracy or below.
+ *
+ * @param int|float $interval The number of seconds to wait before execution.
+ * @param callable $callback The callback to invoke.
+ *
+ * @return TimerInterface
+ */
+ public function addPeriodicTimer($interval, $callback);
+
+ /**
+ * Cancel a pending timer.
+ *
+ * See also [`addPeriodicTimer()`](#addperiodictimer) and [example #2](examples).
+ *
+ * Calling this method on a timer instance that has not been added to this
+ * loop instance or on a timer that has already been cancelled has no effect.
+ *
+ * @param TimerInterface $timer The timer to cancel.
+ *
+ * @return void
+ */
+ public function cancelTimer(TimerInterface $timer);
+
+ /**
+ * Schedule a callback to be invoked on a future tick of the event loop.
+ *
+ * This works very much similar to timers with an interval of zero seconds,
+ * but does not require the overhead of scheduling a timer queue.
+ *
+ * The tick callback function MUST be able to accept zero parameters.
+ *
+ * The tick callback function MUST NOT throw an `Exception`.
+ * The return value of the tick callback function will be ignored and has
+ * no effect, so for performance reasons you're recommended to not return
+ * any excessive data structures.
+ *
+ * If you want to access any variables within your callback function, you
+ * can bind arbitrary data to a callback closure like this:
+ *
+ * ```php
+ * function hello($name, LoopInterface $loop)
+ * {
+ * $loop->futureTick(function () use ($name) {
+ * echo "hello $name\n";
+ * });
+ * }
+ *
+ * hello('Tester', $loop);
+ * ```
+ *
+ * Unlike timers, tick callbacks are guaranteed to be executed in the order
+ * they are enqueued.
+ * Also, once a callback is enqueued, there's no way to cancel this operation.
+ *
+ * This is often used to break down bigger tasks into smaller steps (a form
+ * of cooperative multitasking).
+ *
+ * ```php
+ * $loop->futureTick(function () {
+ * echo 'b';
+ * });
+ * $loop->futureTick(function () {
+ * echo 'c';
+ * });
+ * echo 'a';
+ * ```
+ *
+ * See also [example #3](examples).
+ *
+ * @param callable $listener The callback to invoke.
+ *
+ * @return void
+ */
+ public function futureTick($listener);
+
+ /**
+ * Register a listener to be notified when a signal has been caught by this process.
+ *
+ * This is useful to catch user interrupt signals or shutdown signals from
+ * tools like `supervisor` or `systemd`.
+ *
+ * The listener callback function MUST be able to accept a single parameter,
+ * the signal added by this method or you MAY use a function which
+ * has no parameters at all.
+ *
+ * The listener callback function MUST NOT throw an `Exception`.
+ * The return value of the listener callback function will be ignored and has
+ * no effect, so for performance reasons you're recommended to not return
+ * any excessive data structures.
+ *
+ * ```php
+ * $loop->addSignal(SIGINT, function (int $signal) {
+ * echo 'Caught user interrupt signal' . PHP_EOL;
+ * });
+ * ```
+ *
+ * See also [example #4](examples).
+ *
+ * Signaling is only available on Unix-like platform, Windows isn't
+ * supported due to operating system limitations.
+ * This method may throw a `BadMethodCallException` if signals aren't
+ * supported on this platform, for example when required extensions are
+ * missing.
+ *
+ * **Note: A listener can only be added once to the same signal, any
+ * attempts to add it more then once will be ignored.**
+ *
+ * @param int $signal
+ * @param callable $listener
+ *
+ * @throws \BadMethodCallException when signals aren't supported on this
+ * platform, for example when required extensions are missing.
+ *
+ * @return void
+ */
+ public function addSignal($signal, $listener);
+
+ /**
+ * Removes a previously added signal listener.
+ *
+ * ```php
+ * $loop->removeSignal(SIGINT, $listener);
+ * ```
+ *
+ * Any attempts to remove listeners that aren't registered will be ignored.
+ *
+ * @param int $signal
+ * @param callable $listener
+ *
+ * @return void
+ */
+ public function removeSignal($signal, $listener);
+
+ /**
+ * Run the event loop until there are no more tasks to perform.
+ *
+ * For many applications, this method is the only directly visible
+ * invocation on the event loop.
+ * As a rule of thumb, it is usally recommended to attach everything to the
+ * same loop instance and then run the loop once at the bottom end of the
+ * application.
+ *
+ * ```php
+ * $loop->run();
+ * ```
+ *
+ * This method will keep the loop running until there are no more tasks
+ * to perform. In other words: This method will block until the last
+ * timer, stream and/or signal has been removed.
+ *
+ * Likewise, it is imperative to ensure the application actually invokes
+ * this method once. Adding listeners to the loop and missing to actually
+ * run it will result in the application exiting without actually waiting
+ * for any of the attached listeners.
+ *
+ * This method MUST NOT be called while the loop is already running.
+ * This method MAY be called more than once after it has explicity been
+ * [`stop()`ped](#stop) or after it automatically stopped because it
+ * previously did no longer have anything to do.
+ *
+ * @return void
+ */
+ public function run();
+
+ /**
+ * Instruct a running event loop to stop.
+ *
+ * This method is considered advanced usage and should be used with care.
+ * As a rule of thumb, it is usually recommended to let the loop stop
+ * only automatically when it no longer has anything to do.
+ *
+ * This method can be used to explicitly instruct the event loop to stop:
+ *
+ * ```php
+ * $loop->addTimer(3.0, function () use ($loop) {
+ * $loop->stop();
+ * });
+ * ```
+ *
+ * Calling this method on a loop instance that is not currently running or
+ * on a loop instance that has already been stopped has no effect.
+ *
+ * @return void
+ */
+ public function stop();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/SignalsHandler.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/SignalsHandler.php
new file mode 100644
index 0000000..523e1ca
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/SignalsHandler.php
@@ -0,0 +1,63 @@
+<?php
+
+namespace React\EventLoop;
+
+/**
+ * @internal
+ */
+final class SignalsHandler
+{
+ private $signals = array();
+
+ public function add($signal, $listener)
+ {
+ if (!isset($this->signals[$signal])) {
+ $this->signals[$signal] = array();
+ }
+
+ if (in_array($listener, $this->signals[$signal])) {
+ return;
+ }
+
+ $this->signals[$signal][] = $listener;
+ }
+
+ public function remove($signal, $listener)
+ {
+ if (!isset($this->signals[$signal])) {
+ return;
+ }
+
+ $index = \array_search($listener, $this->signals[$signal], true);
+ unset($this->signals[$signal][$index]);
+
+ if (isset($this->signals[$signal]) && \count($this->signals[$signal]) === 0) {
+ unset($this->signals[$signal]);
+ }
+ }
+
+ public function call($signal)
+ {
+ if (!isset($this->signals[$signal])) {
+ return;
+ }
+
+ foreach ($this->signals[$signal] as $listener) {
+ \call_user_func($listener, $signal);
+ }
+ }
+
+ public function count($signal)
+ {
+ if (!isset($this->signals[$signal])) {
+ return 0;
+ }
+
+ return \count($this->signals[$signal]);
+ }
+
+ public function isEmpty()
+ {
+ return !$this->signals;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/StreamSelectLoop.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/StreamSelectLoop.php
new file mode 100644
index 0000000..e82e9e4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/StreamSelectLoop.php
@@ -0,0 +1,275 @@
+<?php
+
+namespace React\EventLoop;
+
+use React\EventLoop\Signal\Pcntl;
+use React\EventLoop\Tick\FutureTickQueue;
+use React\EventLoop\Timer\Timer;
+use React\EventLoop\Timer\Timers;
+
+/**
+ * A `stream_select()` based event loop.
+ *
+ * This uses the [`stream_select()`](http://php.net/manual/en/function.stream-select.php)
+ * function and is the only implementation which works out of the box with PHP.
+ *
+ * This event loop works out of the box on PHP 5.4 through PHP 7+ and HHVM.
+ * This means that no installation is required and this library works on all
+ * platforms and supported PHP versions.
+ * Accordingly, the [`Factory`](#factory) will use this event loop by default if
+ * you do not install any of the event loop extensions listed below.
+ *
+ * Under the hood, it does a simple `select` system call.
+ * This system call is limited to the maximum file descriptor number of
+ * `FD_SETSIZE` (platform dependent, commonly 1024) and scales with `O(m)`
+ * (`m` being the maximum file descriptor number passed).
+ * This means that you may run into issues when handling thousands of streams
+ * concurrently and you may want to look into using one of the alternative
+ * event loop implementations listed below in this case.
+ * If your use case is among the many common use cases that involve handling only
+ * dozens or a few hundred streams at once, then this event loop implementation
+ * performs really well.
+ *
+ * If you want to use signal handling (see also [`addSignal()`](#addsignal) below),
+ * this event loop implementation requires `ext-pcntl`.
+ * This extension is only available for Unix-like platforms and does not support
+ * Windows.
+ * It is commonly installed as part of many PHP distributions.
+ * If this extension is missing (or you're running on Windows), signal handling is
+ * not supported and throws a `BadMethodCallException` instead.
+ *
+ * This event loop is known to rely on wall-clock time to schedule future
+ * timers, because a monotonic time source is not available in PHP by default.
+ * While this does not affect many common use cases, this is an important
+ * distinction for programs that rely on a high time precision or on systems
+ * that are subject to discontinuous time adjustments (time jumps).
+ * This means that if you schedule a timer to trigger in 30s and then adjust
+ * your system time forward by 20s, the timer may trigger in 10s.
+ * See also [`addTimer()`](#addtimer) for more details.
+ *
+ * @link http://php.net/manual/en/function.stream-select.php
+ */
+final class StreamSelectLoop implements LoopInterface
+{
+ /** @internal */
+ const MICROSECONDS_PER_SECOND = 1000000;
+
+ private $futureTickQueue;
+ private $timers;
+ private $readStreams = array();
+ private $readListeners = array();
+ private $writeStreams = array();
+ private $writeListeners = array();
+ private $running;
+ private $pcntl = false;
+ private $signals;
+
+ public function __construct()
+ {
+ $this->futureTickQueue = new FutureTickQueue();
+ $this->timers = new Timers();
+ $this->pcntl = extension_loaded('pcntl');
+ $this->signals = new SignalsHandler();
+ }
+
+ public function addReadStream($stream, $listener)
+ {
+ $key = (int) $stream;
+
+ if (!isset($this->readStreams[$key])) {
+ $this->readStreams[$key] = $stream;
+ $this->readListeners[$key] = $listener;
+ }
+ }
+
+ public function addWriteStream($stream, $listener)
+ {
+ $key = (int) $stream;
+
+ if (!isset($this->writeStreams[$key])) {
+ $this->writeStreams[$key] = $stream;
+ $this->writeListeners[$key] = $listener;
+ }
+ }
+
+ public function removeReadStream($stream)
+ {
+ $key = (int) $stream;
+
+ unset(
+ $this->readStreams[$key],
+ $this->readListeners[$key]
+ );
+ }
+
+ public function removeWriteStream($stream)
+ {
+ $key = (int) $stream;
+
+ unset(
+ $this->writeStreams[$key],
+ $this->writeListeners[$key]
+ );
+ }
+
+ public function addTimer($interval, $callback)
+ {
+ $timer = new Timer($interval, $callback, false);
+
+ $this->timers->add($timer);
+
+ return $timer;
+ }
+
+ public function addPeriodicTimer($interval, $callback)
+ {
+ $timer = new Timer($interval, $callback, true);
+
+ $this->timers->add($timer);
+
+ return $timer;
+ }
+
+ public function cancelTimer(TimerInterface $timer)
+ {
+ $this->timers->cancel($timer);
+ }
+
+ public function futureTick($listener)
+ {
+ $this->futureTickQueue->add($listener);
+ }
+
+ public function addSignal($signal, $listener)
+ {
+ if ($this->pcntl === false) {
+ throw new \BadMethodCallException('Event loop feature "signals" isn\'t supported by the "StreamSelectLoop"');
+ }
+
+ $first = $this->signals->count($signal) === 0;
+ $this->signals->add($signal, $listener);
+
+ if ($first) {
+ \pcntl_signal($signal, array($this->signals, 'call'));
+ }
+ }
+
+ public function removeSignal($signal, $listener)
+ {
+ if (!$this->signals->count($signal)) {
+ return;
+ }
+
+ $this->signals->remove($signal, $listener);
+
+ if ($this->signals->count($signal) === 0) {
+ \pcntl_signal($signal, SIG_DFL);
+ }
+ }
+
+ public function run()
+ {
+ $this->running = true;
+
+ while ($this->running) {
+ $this->futureTickQueue->tick();
+
+ $this->timers->tick();
+
+ // Future-tick queue has pending callbacks ...
+ if (!$this->running || !$this->futureTickQueue->isEmpty()) {
+ $timeout = 0;
+
+ // There is a pending timer, only block until it is due ...
+ } elseif ($scheduledAt = $this->timers->getFirst()) {
+ $timeout = $scheduledAt - $this->timers->getTime();
+ if ($timeout < 0) {
+ $timeout = 0;
+ } else {
+ // Convert float seconds to int microseconds.
+ // Ensure we do not exceed maximum integer size, which may
+ // cause the loop to tick once every ~35min on 32bit systems.
+ $timeout *= self::MICROSECONDS_PER_SECOND;
+ $timeout = $timeout > PHP_INT_MAX ? PHP_INT_MAX : (int)$timeout;
+ }
+
+ // The only possible event is stream or signal activity, so wait forever ...
+ } elseif ($this->readStreams || $this->writeStreams || !$this->signals->isEmpty()) {
+ $timeout = null;
+
+ // There's nothing left to do ...
+ } else {
+ break;
+ }
+
+ $this->waitForStreamActivity($timeout);
+ }
+ }
+
+ public function stop()
+ {
+ $this->running = false;
+ }
+
+ /**
+ * Wait/check for stream activity, or until the next timer is due.
+ *
+ * @param integer|null $timeout Activity timeout in microseconds, or null to wait forever.
+ */
+ private function waitForStreamActivity($timeout)
+ {
+ $read = $this->readStreams;
+ $write = $this->writeStreams;
+
+ $available = $this->streamSelect($read, $write, $timeout);
+ if ($this->pcntl) {
+ \pcntl_signal_dispatch();
+ }
+ if (false === $available) {
+ // if a system call has been interrupted,
+ // we cannot rely on it's outcome
+ return;
+ }
+
+ foreach ($read as $stream) {
+ $key = (int) $stream;
+
+ if (isset($this->readListeners[$key])) {
+ call_user_func($this->readListeners[$key], $stream);
+ }
+ }
+
+ foreach ($write as $stream) {
+ $key = (int) $stream;
+
+ if (isset($this->writeListeners[$key])) {
+ call_user_func($this->writeListeners[$key], $stream);
+ }
+ }
+ }
+
+ /**
+ * Emulate a stream_select() implementation that does not break when passed
+ * empty stream arrays.
+ *
+ * @param array &$read An array of read streams to select upon.
+ * @param array &$write An array of write streams to select upon.
+ * @param integer|null $timeout Activity timeout in microseconds, or null to wait forever.
+ *
+ * @return integer|false The total number of streams that are ready for read/write.
+ * Can return false if stream_select() is interrupted by a signal.
+ */
+ private function streamSelect(array &$read, array &$write, $timeout)
+ {
+ if ($read || $write) {
+ $except = null;
+
+ // suppress warnings that occur, when stream_select is interrupted by a signal
+ return @stream_select($read, $write, $except, $timeout === null ? null : 0, $timeout);
+ }
+
+ $timeout && usleep($timeout);
+
+ return 0;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/Tick/FutureTickQueue.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/Tick/FutureTickQueue.php
new file mode 100644
index 0000000..c79afc5
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/Tick/FutureTickQueue.php
@@ -0,0 +1,60 @@
+<?php
+
+namespace React\EventLoop\Tick;
+
+use SplQueue;
+
+/**
+ * A tick queue implementation that can hold multiple callback functions
+ *
+ * This class should only be used internally, see LoopInterface instead.
+ *
+ * @see LoopInterface
+ * @internal
+ */
+final class FutureTickQueue
+{
+ private $queue;
+
+ public function __construct()
+ {
+ $this->queue = new SplQueue();
+ }
+
+ /**
+ * Add a callback to be invoked on a future tick of the event loop.
+ *
+ * Callbacks are guaranteed to be executed in the order they are enqueued.
+ *
+ * @param callable $listener The callback to invoke.
+ */
+ public function add($listener)
+ {
+ $this->queue->enqueue($listener);
+ }
+
+ /**
+ * Flush the callback queue.
+ */
+ public function tick()
+ {
+ // Only invoke as many callbacks as were on the queue when tick() was called.
+ $count = $this->queue->count();
+
+ while ($count--) {
+ call_user_func(
+ $this->queue->dequeue()
+ );
+ }
+ }
+
+ /**
+ * Check if the next tick queue is empty.
+ *
+ * @return boolean
+ */
+ public function isEmpty()
+ {
+ return $this->queue->isEmpty();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/Timer/Timer.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/Timer/Timer.php
new file mode 100644
index 0000000..da3602a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/Timer/Timer.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace React\EventLoop\Timer;
+
+use React\EventLoop\TimerInterface;
+
+/**
+ * The actual connection implementation for TimerInterface
+ *
+ * This class should only be used internally, see TimerInterface instead.
+ *
+ * @see TimerInterface
+ * @internal
+ */
+final class Timer implements TimerInterface
+{
+ const MIN_INTERVAL = 0.000001;
+
+ private $interval;
+ private $callback;
+ private $periodic;
+
+ /**
+ * Constructor initializes the fields of the Timer
+ *
+ * @param float $interval The interval after which this timer will execute, in seconds
+ * @param callable $callback The callback that will be executed when this timer elapses
+ * @param bool $periodic Whether the time is periodic
+ */
+ public function __construct($interval, $callback, $periodic = false)
+ {
+ if ($interval < self::MIN_INTERVAL) {
+ $interval = self::MIN_INTERVAL;
+ }
+
+ $this->interval = (float) $interval;
+ $this->callback = $callback;
+ $this->periodic = (bool) $periodic;
+ }
+
+ public function getInterval()
+ {
+ return $this->interval;
+ }
+
+ public function getCallback()
+ {
+ return $this->callback;
+ }
+
+ public function isPeriodic()
+ {
+ return $this->periodic;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/Timer/Timers.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/Timer/Timers.php
new file mode 100644
index 0000000..17bbdac
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/Timer/Timers.php
@@ -0,0 +1,109 @@
+<?php
+
+namespace React\EventLoop\Timer;
+
+use React\EventLoop\TimerInterface;
+use SplObjectStorage;
+use SplPriorityQueue;
+
+/**
+ * A scheduler implementation that can hold multiple timer instances
+ *
+ * This class should only be used internally, see TimerInterface instead.
+ *
+ * @see TimerInterface
+ * @internal
+ */
+final class Timers
+{
+ private $time;
+ private $timers;
+ private $scheduler;
+
+ public function __construct()
+ {
+ $this->timers = new SplObjectStorage();
+ $this->scheduler = new SplPriorityQueue();
+ }
+
+ public function updateTime()
+ {
+ return $this->time = microtime(true);
+ }
+
+ public function getTime()
+ {
+ return $this->time ?: $this->updateTime();
+ }
+
+ public function add(TimerInterface $timer)
+ {
+ $interval = $timer->getInterval();
+ $scheduledAt = $interval + microtime(true);
+
+ $this->timers->attach($timer, $scheduledAt);
+ $this->scheduler->insert($timer, -$scheduledAt);
+ }
+
+ public function contains(TimerInterface $timer)
+ {
+ return $this->timers->contains($timer);
+ }
+
+ public function cancel(TimerInterface $timer)
+ {
+ $this->timers->detach($timer);
+ }
+
+ public function getFirst()
+ {
+ while ($this->scheduler->count()) {
+ $timer = $this->scheduler->top();
+
+ if ($this->timers->contains($timer)) {
+ return $this->timers[$timer];
+ }
+
+ $this->scheduler->extract();
+ }
+
+ return null;
+ }
+
+ public function isEmpty()
+ {
+ return count($this->timers) === 0;
+ }
+
+ public function tick()
+ {
+ $time = $this->updateTime();
+ $timers = $this->timers;
+ $scheduler = $this->scheduler;
+
+ while (!$scheduler->isEmpty()) {
+ $timer = $scheduler->top();
+
+ if (!isset($timers[$timer])) {
+ $scheduler->extract();
+ $timers->detach($timer);
+
+ continue;
+ }
+
+ if ($timers[$timer] >= $time) {
+ break;
+ }
+
+ $scheduler->extract();
+ call_user_func($timer->getCallback(), $timer);
+
+ if ($timer->isPeriodic() && isset($timers[$timer])) {
+ $timers[$timer] = $scheduledAt = $timer->getInterval() + $time;
+ $scheduler->insert($timer, -$scheduledAt);
+ } else {
+ $timers->detach($timer);
+ }
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/TimerInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/TimerInterface.php
new file mode 100644
index 0000000..cdcf773
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/src/TimerInterface.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace React\EventLoop;
+
+interface TimerInterface
+{
+ /**
+ * Get the interval after which this timer will execute, in seconds
+ *
+ * @return float
+ */
+ public function getInterval();
+
+ /**
+ * Get the callback that will be executed when this timer elapses
+ *
+ * @return callable
+ */
+ public function getCallback();
+
+ /**
+ * Determine whether the time is periodic
+ *
+ * @return bool
+ */
+ public function isPeriodic();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/AbstractLoopTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/AbstractLoopTest.php
new file mode 100644
index 0000000..dbfc91e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/AbstractLoopTest.php
@@ -0,0 +1,621 @@
+<?php
+
+namespace React\Tests\EventLoop;
+
+abstract class AbstractLoopTest extends TestCase
+{
+ /**
+ * @var \React\EventLoop\LoopInterface
+ */
+ protected $loop;
+
+ private $tickTimeout;
+
+ const PHP_DEFAULT_CHUNK_SIZE = 8192;
+
+ public function setUp()
+ {
+ // It's a timeout, don't set it too low. Travis and other CI systems are slow.
+ $this->tickTimeout = 0.02;
+ $this->loop = $this->createLoop();
+ }
+
+ abstract public function createLoop();
+
+ public function createSocketPair()
+ {
+ $domain = (DIRECTORY_SEPARATOR === '\\') ? STREAM_PF_INET : STREAM_PF_UNIX;
+ $sockets = stream_socket_pair($domain, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
+
+ foreach ($sockets as $socket) {
+ if (function_exists('stream_set_read_buffer')) {
+ stream_set_read_buffer($socket, 0);
+ }
+ }
+
+ return $sockets;
+ }
+
+ public function testAddReadStream()
+ {
+ list ($input, $output) = $this->createSocketPair();
+
+ $this->loop->addReadStream($input, $this->expectCallableExactly(2));
+
+ fwrite($output, "foo\n");
+ $this->tickLoop($this->loop);
+
+ fwrite($output, "bar\n");
+ $this->tickLoop($this->loop);
+ }
+
+ public function testAddReadStreamIgnoresSecondCallable()
+ {
+ list ($input, $output) = $this->createSocketPair();
+
+ $this->loop->addReadStream($input, $this->expectCallableExactly(2));
+ $this->loop->addReadStream($input, $this->expectCallableNever());
+
+ fwrite($output, "foo\n");
+ $this->tickLoop($this->loop);
+
+ fwrite($output, "bar\n");
+ $this->tickLoop($this->loop);
+ }
+
+ public function testAddReadStreamReceivesDataFromStreamReference()
+ {
+ $this->received = '';
+ $this->subAddReadStreamReceivesDataFromStreamReference();
+ $this->assertEquals('', $this->received);
+
+ $this->assertRunFasterThan($this->tickTimeout * 2);
+ $this->assertEquals('[hello]X', $this->received);
+ }
+
+ /**
+ * Helper for above test. This happens in another helper method to verify
+ * the loop keeps track of assigned stream resources (refcount).
+ */
+ private function subAddReadStreamReceivesDataFromStreamReference()
+ {
+ list ($input, $output) = $this->createSocketPair();
+
+ fwrite($input, 'hello');
+ fclose($input);
+
+ $loop = $this->loop;
+ $received =& $this->received;
+ $loop->addReadStream($output, function ($output) use ($loop, &$received) {
+ $chunk = fread($output, 1024);
+ if ($chunk === '') {
+ $received .= 'X';
+ $loop->removeReadStream($output);
+ fclose($output);
+ } else {
+ $received .= '[' . $chunk . ']';
+ }
+ });
+ }
+
+ public function testAddWriteStream()
+ {
+ list ($input) = $this->createSocketPair();
+
+ $this->loop->addWriteStream($input, $this->expectCallableExactly(2));
+ $this->tickLoop($this->loop);
+ $this->tickLoop($this->loop);
+ }
+
+ public function testAddWriteStreamIgnoresSecondCallable()
+ {
+ list ($input) = $this->createSocketPair();
+
+ $this->loop->addWriteStream($input, $this->expectCallableExactly(2));
+ $this->loop->addWriteStream($input, $this->expectCallableNever());
+ $this->tickLoop($this->loop);
+ $this->tickLoop($this->loop);
+ }
+
+ public function testRemoveReadStreamInstantly()
+ {
+ list ($input, $output) = $this->createSocketPair();
+
+ $this->loop->addReadStream($input, $this->expectCallableNever());
+ $this->loop->removeReadStream($input);
+
+ fwrite($output, "bar\n");
+ $this->tickLoop($this->loop);
+ }
+
+ public function testRemoveReadStreamAfterReading()
+ {
+ list ($input, $output) = $this->createSocketPair();
+
+ $this->loop->addReadStream($input, $this->expectCallableOnce());
+
+ fwrite($output, "foo\n");
+ $this->tickLoop($this->loop);
+
+ $this->loop->removeReadStream($input);
+
+ fwrite($output, "bar\n");
+ $this->tickLoop($this->loop);
+ }
+
+ public function testRemoveWriteStreamInstantly()
+ {
+ list ($input) = $this->createSocketPair();
+
+ $this->loop->addWriteStream($input, $this->expectCallableNever());
+ $this->loop->removeWriteStream($input);
+ $this->tickLoop($this->loop);
+ }
+
+ public function testRemoveWriteStreamAfterWriting()
+ {
+ list ($input) = $this->createSocketPair();
+
+ $this->loop->addWriteStream($input, $this->expectCallableOnce());
+ $this->tickLoop($this->loop);
+
+ $this->loop->removeWriteStream($input);
+ $this->tickLoop($this->loop);
+ }
+
+ public function testRemoveStreamForReadOnly()
+ {
+ list ($input, $output) = $this->createSocketPair();
+
+ $this->loop->addReadStream($input, $this->expectCallableNever());
+ $this->loop->addWriteStream($output, $this->expectCallableOnce());
+ $this->loop->removeReadStream($input);
+
+ fwrite($output, "foo\n");
+ $this->tickLoop($this->loop);
+ }
+
+ public function testRemoveStreamForWriteOnly()
+ {
+ list ($input, $output) = $this->createSocketPair();
+
+ fwrite($output, "foo\n");
+
+ $this->loop->addReadStream($input, $this->expectCallableOnce());
+ $this->loop->addWriteStream($output, $this->expectCallableNever());
+ $this->loop->removeWriteStream($output);
+
+ $this->tickLoop($this->loop);
+ }
+
+ public function testRemoveReadAndWriteStreamFromLoopOnceResourceClosesEndsLoop()
+ {
+ list($stream, $other) = $this->createSocketPair();
+ stream_set_blocking($stream, false);
+ stream_set_blocking($other, false);
+
+ // dummy writable handler
+ $this->loop->addWriteStream($stream, function () { });
+
+ // remove stream when the stream is readable (closes)
+ $loop = $this->loop;
+ $loop->addReadStream($stream, function ($stream) use ($loop) {
+ $loop->removeReadStream($stream);
+ $loop->removeWriteStream($stream);
+ fclose($stream);
+ });
+
+ // close other side
+ fclose($other);
+
+ $this->assertRunFasterThan($this->tickTimeout);
+ }
+
+ public function testRemoveReadAndWriteStreamFromLoopOnceResourceClosesOnEndOfFileEndsLoop()
+ {
+ list($stream, $other) = $this->createSocketPair();
+ stream_set_blocking($stream, false);
+ stream_set_blocking($other, false);
+
+ // dummy writable handler
+ $this->loop->addWriteStream($stream, function () { });
+
+ // remove stream when the stream is readable (closes)
+ $loop = $this->loop;
+ $loop->addReadStream($stream, function ($stream) use ($loop) {
+ $data = fread($stream, 1024);
+ if ($data !== '') {
+ return;
+ }
+
+ $loop->removeReadStream($stream);
+ $loop->removeWriteStream($stream);
+ fclose($stream);
+ });
+
+ // send data and close stream
+ fwrite($other, str_repeat('.', static::PHP_DEFAULT_CHUNK_SIZE));
+ $this->loop->addTimer(0.01, function () use ($other) {
+ fclose($other);
+ });
+
+ $this->assertRunFasterThan(0.1);
+ }
+
+ public function testRemoveReadAndWriteStreamFromLoopWithClosingResourceEndsLoop()
+ {
+ // get only one part of the pair to ensure the other side will close immediately
+ list($stream) = $this->createSocketPair();
+ stream_set_blocking($stream, false);
+
+ // dummy writable handler
+ $this->loop->addWriteStream($stream, function () { });
+
+ // remove stream when the stream is readable (closes)
+ $loop = $this->loop;
+ $loop->addReadStream($stream, function ($stream) use ($loop) {
+ $loop->removeReadStream($stream);
+ $loop->removeWriteStream($stream);
+ fclose($stream);
+ });
+
+ $this->assertRunFasterThan($this->tickTimeout);
+ }
+
+ public function testRemoveInvalid()
+ {
+ list ($stream) = $this->createSocketPair();
+
+ // remove a valid stream from the event loop that was never added in the first place
+ $this->loop->removeReadStream($stream);
+ $this->loop->removeWriteStream($stream);
+
+ $this->assertTrue(true);
+ }
+
+ /** @test */
+ public function emptyRunShouldSimplyReturn()
+ {
+ $this->assertRunFasterThan($this->tickTimeout);
+ }
+
+ /** @test */
+ public function runShouldReturnWhenNoMoreFds()
+ {
+ list ($input, $output) = $this->createSocketPair();
+
+ $loop = $this->loop;
+ $this->loop->addReadStream($input, function ($stream) use ($loop) {
+ $loop->removeReadStream($stream);
+ });
+
+ fwrite($output, "foo\n");
+
+ $this->assertRunFasterThan($this->tickTimeout * 2);
+ }
+
+ /** @test */
+ public function stopShouldStopRunningLoop()
+ {
+ list ($input, $output) = $this->createSocketPair();
+
+ $loop = $this->loop;
+ $this->loop->addReadStream($input, function ($stream) use ($loop) {
+ $loop->stop();
+ });
+
+ fwrite($output, "foo\n");
+
+ $this->assertRunFasterThan($this->tickTimeout * 2);
+ }
+
+ public function testStopShouldPreventRunFromBlocking()
+ {
+ $that = $this;
+ $this->loop->addTimer(
+ 1,
+ function () use ($that) {
+ $that->fail('Timer was executed.');
+ }
+ );
+
+ $loop = $this->loop;
+ $this->loop->futureTick(
+ function () use ($loop) {
+ $loop->stop();
+ }
+ );
+
+ $this->assertRunFasterThan($this->tickTimeout * 2);
+ }
+
+ public function testIgnoreRemovedCallback()
+ {
+ // two independent streams, both should be readable right away
+ list ($input1, $output1) = $this->createSocketPair();
+ list ($input2, $output2) = $this->createSocketPair();
+
+ $called = false;
+
+ $loop = $this->loop;
+ $loop->addReadStream($input1, function ($stream) use (& $called, $loop, $input2) {
+ // stream1 is readable, remove stream2 as well => this will invalidate its callback
+ $loop->removeReadStream($stream);
+ $loop->removeReadStream($input2);
+
+ $called = true;
+ });
+
+ // this callback would have to be called as well, but the first stream already removed us
+ $that = $this;
+ $loop->addReadStream($input2, function () use (& $called, $that) {
+ if ($called) {
+ $that->fail('Callback 2 must not be called after callback 1 was called');
+ }
+ });
+
+ fwrite($output1, "foo\n");
+ fwrite($output2, "foo\n");
+
+ $loop->run();
+
+ $this->assertTrue($called);
+ }
+
+ public function testFutureTickEventGeneratedByFutureTick()
+ {
+ $loop = $this->loop;
+ $this->loop->futureTick(
+ function () use ($loop) {
+ $loop->futureTick(
+ function () {
+ echo 'future-tick' . PHP_EOL;
+ }
+ );
+ }
+ );
+
+ $this->expectOutputString('future-tick' . PHP_EOL);
+
+ $this->loop->run();
+ }
+
+ public function testFutureTick()
+ {
+ $called = false;
+
+ $callback = function () use (&$called) {
+ $called = true;
+ };
+
+ $this->loop->futureTick($callback);
+
+ $this->assertFalse($called);
+
+ $this->tickLoop($this->loop);
+
+ $this->assertTrue($called);
+ }
+
+ public function testFutureTickFiresBeforeIO()
+ {
+ list ($stream) = $this->createSocketPair();
+
+ $this->loop->addWriteStream(
+ $stream,
+ function () {
+ echo 'stream' . PHP_EOL;
+ }
+ );
+
+ $this->loop->futureTick(
+ function () {
+ echo 'future-tick' . PHP_EOL;
+ }
+ );
+
+ $this->expectOutputString('future-tick' . PHP_EOL . 'stream' . PHP_EOL);
+
+ $this->tickLoop($this->loop);
+ }
+
+ public function testRecursiveFutureTick()
+ {
+ list ($stream) = $this->createSocketPair();
+
+ $loop = $this->loop;
+ $this->loop->addWriteStream(
+ $stream,
+ function () use ($stream, $loop) {
+ echo 'stream' . PHP_EOL;
+ $loop->removeWriteStream($stream);
+ }
+ );
+
+ $this->loop->futureTick(
+ function () use ($loop) {
+ echo 'future-tick-1' . PHP_EOL;
+ $loop->futureTick(
+ function () {
+ echo 'future-tick-2' . PHP_EOL;
+ }
+ );
+ }
+ );
+
+ $this->expectOutputString('future-tick-1' . PHP_EOL . 'stream' . PHP_EOL . 'future-tick-2' . PHP_EOL);
+
+ $this->loop->run();
+ }
+
+ public function testRunWaitsForFutureTickEvents()
+ {
+ list ($stream) = $this->createSocketPair();
+
+ $loop = $this->loop;
+ $this->loop->addWriteStream(
+ $stream,
+ function () use ($stream, $loop) {
+ $loop->removeWriteStream($stream);
+ $loop->futureTick(
+ function () {
+ echo 'future-tick' . PHP_EOL;
+ }
+ );
+ }
+ );
+
+ $this->expectOutputString('future-tick' . PHP_EOL);
+
+ $this->loop->run();
+ }
+
+ public function testFutureTickEventGeneratedByTimer()
+ {
+ $loop = $this->loop;
+ $this->loop->addTimer(
+ 0.001,
+ function () use ($loop) {
+ $loop->futureTick(
+ function () {
+ echo 'future-tick' . PHP_EOL;
+ }
+ );
+ }
+ );
+
+ $this->expectOutputString('future-tick' . PHP_EOL);
+
+ $this->loop->run();
+ }
+
+ public function testRemoveSignalNotRegisteredIsNoOp()
+ {
+ $this->loop->removeSignal(SIGINT, function () { });
+ $this->assertTrue(true);
+ }
+
+ public function testSignal()
+ {
+ if (!function_exists('posix_kill') || !function_exists('posix_getpid')) {
+ $this->markTestSkipped('Signal test skipped because functions "posix_kill" and "posix_getpid" are missing.');
+ }
+
+ $called = false;
+ $calledShouldNot = true;
+
+ $timer = $this->loop->addPeriodicTimer(1, function () {});
+
+ $this->loop->addSignal(SIGUSR2, $func2 = function () use (&$calledShouldNot) {
+ $calledShouldNot = false;
+ });
+
+ $loop = $this->loop;
+ $this->loop->addSignal(SIGUSR1, $func1 = function () use (&$func1, &$func2, &$called, $timer, $loop) {
+ $called = true;
+ $loop->removeSignal(SIGUSR1, $func1);
+ $loop->removeSignal(SIGUSR2, $func2);
+ $loop->cancelTimer($timer);
+ });
+
+ $this->loop->futureTick(function () {
+ posix_kill(posix_getpid(), SIGUSR1);
+ });
+
+ $this->loop->run();
+
+ $this->assertTrue($called);
+ $this->assertTrue($calledShouldNot);
+ }
+
+ public function testSignalMultipleUsagesForTheSameListener()
+ {
+ $funcCallCount = 0;
+ $func = function () use (&$funcCallCount) {
+ $funcCallCount++;
+ };
+ $this->loop->addTimer(1, function () {});
+
+ $this->loop->addSignal(SIGUSR1, $func);
+ $this->loop->addSignal(SIGUSR1, $func);
+
+ $this->loop->addTimer(0.4, function () {
+ posix_kill(posix_getpid(), SIGUSR1);
+ });
+ $loop = $this->loop;
+ $this->loop->addTimer(0.9, function () use (&$func, $loop) {
+ $loop->removeSignal(SIGUSR1, $func);
+ });
+
+ $this->loop->run();
+
+ $this->assertSame(1, $funcCallCount);
+ }
+
+ public function testSignalsKeepTheLoopRunning()
+ {
+ $loop = $this->loop;
+ $function = function () {};
+ $this->loop->addSignal(SIGUSR1, $function);
+ $this->loop->addTimer(1.5, function () use ($function, $loop) {
+ $loop->removeSignal(SIGUSR1, $function);
+ $loop->stop();
+ });
+
+ $this->assertRunSlowerThan(1.5);
+ }
+
+ public function testSignalsKeepTheLoopRunningAndRemovingItStopsTheLoop()
+ {
+ $loop = $this->loop;
+ $function = function () {};
+ $this->loop->addSignal(SIGUSR1, $function);
+ $this->loop->addTimer(1.5, function () use ($function, $loop) {
+ $loop->removeSignal(SIGUSR1, $function);
+ });
+
+ $this->assertRunFasterThan(1.6);
+ }
+
+ public function testTimerIntervalCanBeFarInFuture()
+ {
+ // get only one part of the pair to ensure the other side will close immediately
+ list($stream) = $this->createSocketPair();
+
+ // start a timer very far in the future
+ $timer = $this->loop->addTimer(PHP_INT_MAX, function () { });
+
+ // remove stream and timer when the stream is readable (closes)
+ $loop = $this->loop;
+ $this->loop->addReadStream($stream, function ($stream) use ($timer, $loop) {
+ $loop->removeReadStream($stream);
+ $loop->cancelTimer($timer);
+ });
+
+ $this->assertRunFasterThan($this->tickTimeout);
+ }
+
+ private function assertRunSlowerThan($minInterval)
+ {
+ $start = microtime(true);
+
+ $this->loop->run();
+
+ $end = microtime(true);
+ $interval = $end - $start;
+
+ $this->assertLessThan($interval, $minInterval);
+ }
+
+ private function assertRunFasterThan($maxInterval)
+ {
+ $start = microtime(true);
+
+ $this->loop->run();
+
+ $end = microtime(true);
+ $interval = $end - $start;
+
+ $this->assertLessThan($maxInterval, $interval);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/CallableStub.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/CallableStub.php
new file mode 100644
index 0000000..913d403
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/CallableStub.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace React\Tests\EventLoop;
+
+class CallableStub
+{
+ public function __invoke()
+ {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/ExtEvLoopTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/ExtEvLoopTest.php
new file mode 100644
index 0000000..ab41c9f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/ExtEvLoopTest.php
@@ -0,0 +1,17 @@
+<?php
+
+namespace React\Tests\EventLoop;
+
+use React\EventLoop\ExtEvLoop;
+
+class ExtEvLoopTest extends AbstractLoopTest
+{
+ public function createLoop()
+ {
+ if (!class_exists('EvLoop')) {
+ $this->markTestSkipped('ExtEvLoop tests skipped because ext-ev extension is not installed.');
+ }
+
+ return new ExtEvLoop();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/ExtEventLoopTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/ExtEventLoopTest.php
new file mode 100644
index 0000000..2f88d18
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/ExtEventLoopTest.php
@@ -0,0 +1,84 @@
+<?php
+
+namespace React\Tests\EventLoop;
+
+use React\EventLoop\ExtEventLoop;
+
+class ExtEventLoopTest extends AbstractLoopTest
+{
+ public function createLoop($readStreamCompatible = false)
+ {
+ if ('Linux' === PHP_OS && !extension_loaded('posix')) {
+ $this->markTestSkipped('libevent tests skipped on linux due to linux epoll issues.');
+ }
+
+ if (!extension_loaded('event')) {
+ $this->markTestSkipped('ext-event tests skipped because ext-event is not installed.');
+ }
+
+ return new ExtEventLoop();
+ }
+
+ public function createStream()
+ {
+ // Use a FIFO on linux to get around lack of support for disk-based file
+ // descriptors when using the EPOLL back-end.
+ if ('Linux' === PHP_OS) {
+ $this->fifoPath = tempnam(sys_get_temp_dir(), 'react-');
+
+ unlink($this->fifoPath);
+
+ posix_mkfifo($this->fifoPath, 0600);
+
+ $stream = fopen($this->fifoPath, 'r+');
+
+ // ext-event (as of 1.8.1) does not yet support in-memory temporary
+ // streams. Setting maxmemory:0 and performing a write forces PHP to
+ // back this temporary stream with a real file.
+ //
+ // This problem is mentioned at https://bugs.php.net/bug.php?id=64652&edit=3
+ // but remains unresolved (despite that issue being closed).
+ } else {
+ $stream = fopen('php://temp/maxmemory:0', 'r+');
+
+ fwrite($stream, 'x');
+ ftruncate($stream, 0);
+ }
+
+ return $stream;
+ }
+
+ public function writeToStream($stream, $content)
+ {
+ if ('Linux' !== PHP_OS) {
+ return parent::writeToStream($stream, $content);
+ }
+
+ fwrite($stream, $content);
+ }
+
+ /**
+ * @group epoll-readable-error
+ */
+ public function testCanUseReadableStreamWithFeatureFds()
+ {
+ if (PHP_VERSION_ID > 70000) {
+ $this->markTestSkipped('Memory stream not supported');
+ }
+
+ $this->loop = $this->createLoop(true);
+
+ $input = fopen('php://temp/maxmemory:0', 'r+');
+
+ fwrite($input, 'x');
+ ftruncate($input, 0);
+
+ $this->loop->addReadStream($input, $this->expectCallableExactly(2));
+
+ fwrite($input, "foo\n");
+ $this->tickLoop($this->loop);
+
+ fwrite($input, "bar\n");
+ $this->tickLoop($this->loop);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/ExtLibevLoopTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/ExtLibevLoopTest.php
new file mode 100644
index 0000000..19a5e87
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/ExtLibevLoopTest.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace React\Tests\EventLoop;
+
+use React\EventLoop\ExtLibevLoop;
+
+class ExtLibevLoopTest extends AbstractLoopTest
+{
+ public function createLoop()
+ {
+ if (!class_exists('libev\EventLoop')) {
+ $this->markTestSkipped('libev tests skipped because ext-libev is not installed.');
+ }
+
+ return new ExtLibevLoop();
+ }
+
+ public function testLibEvConstructor()
+ {
+ $loop = new ExtLibevLoop();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/ExtLibeventLoopTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/ExtLibeventLoopTest.php
new file mode 100644
index 0000000..8497065
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/ExtLibeventLoopTest.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace React\Tests\EventLoop;
+
+use React\EventLoop\ExtLibeventLoop;
+
+class ExtLibeventLoopTest extends AbstractLoopTest
+{
+ private $fifoPath;
+
+ public function createLoop()
+ {
+ if ('Linux' === PHP_OS && !extension_loaded('posix')) {
+ $this->markTestSkipped('libevent tests skipped on linux due to linux epoll issues.');
+ }
+
+ if (!function_exists('event_base_new')) {
+ $this->markTestSkipped('libevent tests skipped because ext-libevent is not installed.');
+ }
+
+ return new ExtLibeventLoop();
+ }
+
+ public function tearDown()
+ {
+ if (file_exists($this->fifoPath)) {
+ unlink($this->fifoPath);
+ }
+ }
+
+ public function createStream()
+ {
+ if ('Linux' !== PHP_OS) {
+ return parent::createStream();
+ }
+
+ $this->fifoPath = tempnam(sys_get_temp_dir(), 'react-');
+
+ unlink($this->fifoPath);
+
+ // Use a FIFO on linux to get around lack of support for disk-based file
+ // descriptors when using the EPOLL back-end.
+ posix_mkfifo($this->fifoPath, 0600);
+
+ $stream = fopen($this->fifoPath, 'r+');
+
+ return $stream;
+ }
+
+ public function writeToStream($stream, $content)
+ {
+ if ('Linux' !== PHP_OS) {
+ return parent::writeToStream($stream, $content);
+ }
+
+ fwrite($stream, $content);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/SignalsHandlerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/SignalsHandlerTest.php
new file mode 100644
index 0000000..f8b7df3
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/SignalsHandlerTest.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace React\Tests\EventLoop;
+
+use React\EventLoop\SignalsHandler;
+
+final class SignalsHandlerTest extends TestCase
+{
+ public function testEmittedEventsAndCallHandling()
+ {
+ $callCount = 0;
+ $func = function () use (&$callCount) {
+ $callCount++;
+ };
+ $signals = new SignalsHandler();
+
+ $this->assertSame(0, $callCount);
+
+ $signals->add(SIGUSR1, $func);
+ $this->assertSame(0, $callCount);
+
+ $signals->add(SIGUSR1, $func);
+ $this->assertSame(0, $callCount);
+
+ $signals->add(SIGUSR1, $func);
+ $this->assertSame(0, $callCount);
+
+ $signals->call(SIGUSR1);
+ $this->assertSame(1, $callCount);
+
+ $signals->add(SIGUSR2, $func);
+ $this->assertSame(1, $callCount);
+
+ $signals->add(SIGUSR2, $func);
+ $this->assertSame(1, $callCount);
+
+ $signals->call(SIGUSR2);
+ $this->assertSame(2, $callCount);
+
+ $signals->remove(SIGUSR2, $func);
+ $this->assertSame(2, $callCount);
+
+ $signals->remove(SIGUSR2, $func);
+ $this->assertSame(2, $callCount);
+
+ $signals->call(SIGUSR2);
+ $this->assertSame(2, $callCount);
+
+ $signals->remove(SIGUSR1, $func);
+ $this->assertSame(2, $callCount);
+
+ $signals->call(SIGUSR1);
+ $this->assertSame(2, $callCount);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/StreamSelectLoopTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/StreamSelectLoopTest.php
new file mode 100644
index 0000000..bd19e1c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/StreamSelectLoopTest.php
@@ -0,0 +1,148 @@
+<?php
+
+namespace React\Tests\EventLoop;
+
+use React\EventLoop\LoopInterface;
+use React\EventLoop\StreamSelectLoop;
+
+class StreamSelectLoopTest extends AbstractLoopTest
+{
+ protected function tearDown()
+ {
+ parent::tearDown();
+ if (strncmp($this->getName(false), 'testSignal', 10) === 0 && extension_loaded('pcntl')) {
+ $this->resetSignalHandlers();
+ }
+ }
+
+ public function createLoop()
+ {
+ return new StreamSelectLoop();
+ }
+
+ public function testStreamSelectTimeoutEmulation()
+ {
+ $this->loop->addTimer(
+ 0.05,
+ $this->expectCallableOnce()
+ );
+
+ $start = microtime(true);
+
+ $this->loop->run();
+
+ $end = microtime(true);
+ $interval = $end - $start;
+
+ $this->assertGreaterThan(0.04, $interval);
+ }
+
+ public function signalProvider()
+ {
+ return array(
+ array('SIGUSR1'),
+ array('SIGHUP'),
+ array('SIGTERM'),
+ );
+ }
+
+ /**
+ * Test signal interrupt when no stream is attached to the loop
+ * @dataProvider signalProvider
+ */
+ public function testSignalInterruptNoStream($signal)
+ {
+ if (!extension_loaded('pcntl')) {
+ $this->markTestSkipped('"pcntl" extension is required to run this test.');
+ }
+
+ // dispatch signal handler every 10ms for 0.1s
+ $check = $this->loop->addPeriodicTimer(0.01, function() {
+ pcntl_signal_dispatch();
+ });
+ $loop = $this->loop;
+ $loop->addTimer(0.1, function () use ($check, $loop) {
+ $loop->cancelTimer($check);
+ });
+
+ $handled = false;
+ $this->assertTrue(pcntl_signal(constant($signal), function () use (&$handled) {
+ $handled = true;
+ }));
+
+ // spawn external process to send signal to current process id
+ $this->forkSendSignal($signal);
+
+ $this->loop->run();
+ $this->assertTrue($handled);
+ }
+
+ /**
+ * Test signal interrupt when a stream is attached to the loop
+ * @dataProvider signalProvider
+ */
+ public function testSignalInterruptWithStream($signal)
+ {
+ if (!extension_loaded('pcntl')) {
+ $this->markTestSkipped('"pcntl" extension is required to run this test.');
+ }
+
+ // dispatch signal handler every 10ms
+ $this->loop->addPeriodicTimer(0.01, function() {
+ pcntl_signal_dispatch();
+ });
+
+ // add stream to the loop
+ $loop = $this->loop;
+ list($writeStream, $readStream) = $this->createSocketPair();
+ $loop->addReadStream($readStream, function ($stream) use ($loop) {
+ /** @var $loop LoopInterface */
+ $read = fgets($stream);
+ if ($read === "end loop\n") {
+ $loop->stop();
+ }
+ });
+ $this->loop->addTimer(0.1, function() use ($writeStream) {
+ fwrite($writeStream, "end loop\n");
+ });
+
+ $handled = false;
+ $this->assertTrue(pcntl_signal(constant($signal), function () use (&$handled) {
+ $handled = true;
+ }));
+
+ // spawn external process to send signal to current process id
+ $this->forkSendSignal($signal);
+
+ $this->loop->run();
+
+ $this->assertTrue($handled);
+ }
+
+ /**
+ * reset all signal handlers to default
+ */
+ protected function resetSignalHandlers()
+ {
+ foreach($this->signalProvider() as $signal) {
+ pcntl_signal(constant($signal[0]), SIG_DFL);
+ }
+ }
+
+ /**
+ * fork child process to send signal to current process id
+ */
+ protected function forkSendSignal($signal)
+ {
+ $currentPid = posix_getpid();
+ $childPid = pcntl_fork();
+ if ($childPid == -1) {
+ $this->fail("Failed to fork child process!");
+ } else if ($childPid === 0) {
+ // this is executed in the child process
+ usleep(20000);
+ posix_kill($currentPid, constant($signal));
+ die();
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/TestCase.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/TestCase.php
new file mode 100644
index 0000000..dbdd54c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/TestCase.php
@@ -0,0 +1,53 @@
+<?php
+
+namespace React\Tests\EventLoop;
+
+use PHPUnit\Framework\TestCase as BaseTestCase;
+use React\EventLoop\LoopInterface;
+
+class TestCase extends BaseTestCase
+{
+ protected function expectCallableExactly($amount)
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->exactly($amount))
+ ->method('__invoke');
+
+ return $mock;
+ }
+
+ protected function expectCallableOnce()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke');
+
+ return $mock;
+ }
+
+ protected function expectCallableNever()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->never())
+ ->method('__invoke');
+
+ return $mock;
+ }
+
+ protected function createCallableMock()
+ {
+ return $this->getMockBuilder('React\Tests\EventLoop\CallableStub')->getMock();
+ }
+
+ protected function tickLoop(LoopInterface $loop)
+ {
+ $loop->futureTick(function () use ($loop) {
+ $loop->stop();
+ });
+
+ $loop->run();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/Timer/AbstractTimerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/Timer/AbstractTimerTest.php
new file mode 100644
index 0000000..294e683
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/Timer/AbstractTimerTest.php
@@ -0,0 +1,122 @@
+<?php
+
+namespace React\Tests\EventLoop\Timer;
+
+use React\EventLoop\LoopInterface;
+use React\Tests\EventLoop\TestCase;
+
+abstract class AbstractTimerTest extends TestCase
+{
+ /**
+ * @return LoopInterface
+ */
+ abstract public function createLoop();
+
+ public function testAddTimerReturnsNonPeriodicTimerInstance()
+ {
+ $loop = $this->createLoop();
+
+ $timer = $loop->addTimer(0.001, $this->expectCallableNever());
+
+ $this->assertInstanceOf('React\EventLoop\TimerInterface', $timer);
+ $this->assertFalse($timer->isPeriodic());
+ }
+
+ public function testAddTimerWillBeInvokedOnceAndBlocksLoopWhenRunning()
+ {
+ $loop = $this->createLoop();
+
+ $loop->addTimer(0.001, $this->expectCallableOnce());
+
+ $start = microtime(true);
+ $loop->run();
+ $end = microtime(true);
+
+ // make no strict assumptions about actual time interval.
+ // must be at least 0.001s (1ms) and should not take longer than 0.1s
+ $this->assertGreaterThanOrEqual(0.001, $end - $start);
+ $this->assertLessThan(0.1, $end - $start);
+ }
+
+ public function testAddPeriodicTimerReturnsPeriodicTimerInstance()
+ {
+ $loop = $this->createLoop();
+
+ $periodic = $loop->addPeriodicTimer(0.1, $this->expectCallableNever());
+
+ $this->assertInstanceOf('React\EventLoop\TimerInterface', $periodic);
+ $this->assertTrue($periodic->isPeriodic());
+ }
+
+ public function testAddPeriodicTimerWillBeInvokedUntilItIsCancelled()
+ {
+ $loop = $this->createLoop();
+
+ $periodic = $loop->addPeriodicTimer(0.1, $this->expectCallableExactly(3));
+
+ // make no strict assumptions about actual time interval.
+ // leave some room to ensure this ticks exactly 3 times.
+ $loop->addTimer(0.399, function () use ($loop, $periodic) {
+ $loop->cancelTimer($periodic);
+ });
+
+ $loop->run();
+ }
+
+ public function testAddPeriodicTimerWillBeInvokedWithMaximumAccuracyUntilItIsCancelled()
+ {
+ $loop = $this->createLoop();
+
+ $i = 0;
+ $periodic = $loop->addPeriodicTimer(0.001, function () use (&$i) {
+ ++$i;
+ });
+
+ $loop->addTimer(0.02, function () use ($loop, $periodic) {
+ $loop->cancelTimer($periodic);
+ });
+
+ $loop->run();
+
+ // make no strict assumptions about number of invocations.
+ // we know it must be no more than 20 times and should at least be
+ // invoked twice for really slow loops
+ $this->assertLessThanOrEqual(20, $i);
+ $this->assertGreaterThan(2, $i);
+ }
+
+ public function testAddPeriodicTimerCancelsItself()
+ {
+ $loop = $this->createLoop();
+
+ $i = 0;
+ $loop->addPeriodicTimer(0.001, function ($timer) use (&$i, $loop) {
+ $i++;
+
+ if ($i === 5) {
+ $loop->cancelTimer($timer);
+ }
+ });
+
+ $start = microtime(true);
+ $loop->run();
+ $end = microtime(true);
+
+ $this->assertEquals(5, $i);
+
+ // make no strict assumptions about time interval.
+ // 5 invocations must take at least 0.005s (5ms) and should not take
+ // longer than 0.1s for slower loops.
+ $this->assertGreaterThanOrEqual(0.005, $end - $start);
+ $this->assertLessThan(0.1, $end - $start);
+ }
+
+ public function testMinimumIntervalOneMicrosecond()
+ {
+ $loop = $this->createLoop();
+
+ $timer = $loop->addTimer(0, function () {});
+
+ $this->assertEquals(0.000001, $timer->getInterval());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/Timer/ExtEvTimerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/Timer/ExtEvTimerTest.php
new file mode 100644
index 0000000..bfa9186
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/Timer/ExtEvTimerTest.php
@@ -0,0 +1,17 @@
+<?php
+
+namespace React\Tests\EventLoop\Timer;
+
+use React\EventLoop\ExtEvLoop;
+
+class ExtEvTimerTest extends AbstractTimerTest
+{
+ public function createLoop()
+ {
+ if (!class_exists('EvLoop')) {
+ $this->markTestSkipped('ExtEvLoop tests skipped because ext-ev extension is not installed.');
+ }
+
+ return new ExtEvLoop();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/Timer/ExtEventTimerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/Timer/ExtEventTimerTest.php
new file mode 100644
index 0000000..a7a6d00
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/Timer/ExtEventTimerTest.php
@@ -0,0 +1,17 @@
+<?php
+
+namespace React\Tests\EventLoop\Timer;
+
+use React\EventLoop\ExtEventLoop;
+
+class ExtEventTimerTest extends AbstractTimerTest
+{
+ public function createLoop()
+ {
+ if (!extension_loaded('event')) {
+ $this->markTestSkipped('ext-event tests skipped because ext-event is not installed.');
+ }
+
+ return new ExtEventLoop();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/Timer/ExtLibevTimerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/Timer/ExtLibevTimerTest.php
new file mode 100644
index 0000000..65e82be
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/Timer/ExtLibevTimerTest.php
@@ -0,0 +1,17 @@
+<?php
+
+namespace React\Tests\EventLoop\Timer;
+
+use React\EventLoop\ExtLibevLoop;
+
+class ExtLibevTimerTest extends AbstractTimerTest
+{
+ public function createLoop()
+ {
+ if (!class_exists('libev\EventLoop')) {
+ $this->markTestSkipped('libev tests skipped because ext-libev is not installed.');
+ }
+
+ return new ExtLibevLoop();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/Timer/ExtLibeventTimerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/Timer/ExtLibeventTimerTest.php
new file mode 100644
index 0000000..9089b9a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/Timer/ExtLibeventTimerTest.php
@@ -0,0 +1,17 @@
+<?php
+
+namespace React\Tests\EventLoop\Timer;
+
+use React\EventLoop\ExtLibeventLoop;
+
+class ExtLibeventTimerTest extends AbstractTimerTest
+{
+ public function createLoop()
+ {
+ if (!function_exists('event_base_new')) {
+ $this->markTestSkipped('libevent tests skipped because ext-libevent is not installed.');
+ }
+
+ return new ExtLibeventLoop();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/Timer/StreamSelectTimerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/Timer/StreamSelectTimerTest.php
new file mode 100644
index 0000000..cfe1d7d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/Timer/StreamSelectTimerTest.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace React\Tests\EventLoop\Timer;
+
+use React\EventLoop\StreamSelectLoop;
+
+class StreamSelectTimerTest extends AbstractTimerTest
+{
+ public function createLoop()
+ {
+ return new StreamSelectLoop();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/Timer/TimersTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/Timer/TimersTest.php
new file mode 100644
index 0000000..b279478
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/Timer/TimersTest.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace React\Tests\EventLoop\Timer;
+
+use React\Tests\EventLoop\TestCase;
+use React\EventLoop\Timer\Timer;
+use React\EventLoop\Timer\Timers;
+
+class TimersTest extends TestCase
+{
+ public function testBlockedTimer()
+ {
+ $timers = new Timers();
+ $timers->tick();
+
+ // simulate a bunch of processing on stream events,
+ // part of which schedules a future timer...
+ sleep(1);
+ $timers->add(new Timer(0.5, function () {
+ $this->fail("Timer shouldn't be called");
+ }));
+
+ $timers->tick();
+
+ $this->assertTrue(true);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/bootstrap.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/bootstrap.php
new file mode 100644
index 0000000..ea7dd4c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/tests/bootstrap.php
@@ -0,0 +1,15 @@
+<?php
+
+$loader = @include __DIR__ . '/../vendor/autoload.php';
+if (!$loader) {
+ $loader = require __DIR__ . '/../../../../vendor/autoload.php';
+}
+$loader->addPsr4('React\\Tests\\EventLoop\\', __DIR__);
+
+if (!defined('SIGUSR1')) {
+ define('SIGUSR1', 1);
+}
+
+if (!defined('SIGUSR2')) {
+ define('SIGUSR2', 2);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/travis-init.sh b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/travis-init.sh
new file mode 100644
index 0000000..29ce884
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/event-loop/travis-init.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+set -e
+set -o pipefail
+
+if [[ "$TRAVIS_PHP_VERSION" != "hhvm" &&
+ "$TRAVIS_PHP_VERSION" != "hhvm-nightly" ]]; then
+
+ # install 'event' and 'ev' PHP extension
+ if [[ "$TRAVIS_PHP_VERSION" != "5.3" ]]; then
+ echo "yes" | pecl install event
+ echo "yes" | pecl install ev
+ fi
+
+ # install 'libevent' PHP extension (does not support php 7)
+ if [[ "$TRAVIS_PHP_VERSION" != "7.0" &&
+ "$TRAVIS_PHP_VERSION" != "7.1" &&
+ "$TRAVIS_PHP_VERSION" != "7.2" ]]; then
+ curl http://pecl.php.net/get/libevent-0.1.0.tgz | tar -xz
+ pushd libevent-0.1.0
+ phpize
+ ./configure
+ make
+ make install
+ popd
+ echo "extension=libevent.so" >> "$(php -r 'echo php_ini_loaded_file();')"
+ fi
+
+ # install 'libev' PHP extension (does not support php 7)
+ if [[ "$TRAVIS_PHP_VERSION" != "7.0" &&
+ "$TRAVIS_PHP_VERSION" != "7.1" &&
+ "$TRAVIS_PHP_VERSION" != "7.2" ]]; then
+ git clone --recursive https://github.com/m4rw3r/php-libev
+ pushd php-libev
+ phpize
+ ./configure --with-libev
+ make
+ make install
+ popd
+ echo "extension=libev.so" >> "$(php -r 'echo php_ini_loaded_file();')"
+ fi
+
+fi
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/.gitignore b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/.gitignore
new file mode 100644
index 0000000..de4a392
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/.gitignore
@@ -0,0 +1,2 @@
+/vendor
+/composer.lock
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/.travis.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/.travis.yml
new file mode 100644
index 0000000..a71864a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/.travis.yml
@@ -0,0 +1,26 @@
+language: php
+
+php:
+# - 5.3 # requires old distro, see below
+ - 5.4
+ - 5.5
+ - 5.6
+ - 7.0
+ - 7.1
+ - hhvm # ignore errors, see below
+
+# lock distro so new future defaults will not break the build
+dist: trusty
+
+matrix:
+ include:
+ - php: 5.3
+ dist: precise
+ allow_failures:
+ - php: hhvm
+
+install:
+ - composer install --no-interaction
+
+script:
+ - vendor/bin/phpunit --coverage-text
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/CHANGELOG.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/CHANGELOG.md
new file mode 100644
index 0000000..0a21244
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/CHANGELOG.md
@@ -0,0 +1,40 @@
+# Changelog
+
+## 1.2.1 (2017-12-22)
+
+* README improvements
+ (#28 by @jsor)
+
+* Improve test suite by adding forward compatiblity with PHPUnit 6 and
+ fix test suite forward compatibility with upcoming EventLoop releases
+ (#30 and #31 by @clue)
+
+## 1.2.0 (2017-08-08)
+
+* Feature: Only start timers if input Promise is still pending and
+ return a settled output promise if the input is already settled.
+ (#25 by @clue)
+
+* Feature: Cap minimum timer interval at 1µs across all versions
+ (#23 by @clue)
+
+* Feature: Forward compatibility with EventLoop v1.0 and v0.5
+ (#27 by @clue)
+
+* Improve test suite by adding PHPUnit to require-dev and
+ lock Travis distro so new defaults will not break the build
+ (#24 and #26 by @clue)
+
+## 1.1.1 (2016-12-27)
+
+* Improve test suite to use PSR-4 autoloader and proper namespaces.
+ (#21 by @clue)
+
+## 1.1.0 (2016-02-29)
+
+* Feature: Support promise cancellation for all timer primitives
+ (#18 by @clue)
+
+## 1.0.0 (2015-09-29)
+
+* First tagged release
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/LICENSE b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/LICENSE
new file mode 100644
index 0000000..dc09d1e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Christian Lück
+
+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.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/README.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/README.md
new file mode 100644
index 0000000..2ea94fa
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/README.md
@@ -0,0 +1,372 @@
+# PromiseTimer
+
+[![Build Status](https://travis-ci.org/reactphp/promise-timer.svg?branch=master)](https://travis-ci.org/reactphp/promise-timer)
+
+A trivial implementation of timeouts for `Promise`s, built on top of [ReactPHP](https://reactphp.org/).
+
+**Table of contents**
+
+* [Usage](#usage)
+ * [timeout()](#timeout)
+ * [Timeout cancellation](#timeout-cancellation)
+ * [Cancellation handler](#cancellation-handler)
+ * [Input cancellation](#input-cancellation)
+ * [Output cancellation](#output-cancellation)
+ * [Collections](#collections)
+ * [resolve()](#resolve)
+ * [Resolve cancellation](#resolve-cancellation)
+ * [reject()](#reject)
+ * [Reject cancellation](#reject-cancellation)
+ * [TimeoutException](#timeoutexception)
+* [Install](#install)
+* [Tests](#tests)
+* [License](#license)
+
+## Usage
+
+This lightweight library consists only of a few simple functions.
+All functions reside under the `React\Promise\Timer` namespace.
+
+The below examples assume you use an import statement similar to this:
+
+```php
+use React\Promise\Timer;
+
+Timer\timeout(…);
+```
+
+Alternatively, you can also refer to them with their fully-qualified name:
+
+```php
+\React\Promise\Timer\timeout(…);
+```
+
+### timeout()
+
+The `timeout(PromiseInterface $promise, $time, LoopInterface $loop)` function
+can be used to *cancel* operations that take *too long*.
+You need to pass in an input `$promise` that represents a pending operation and timeout parameters.
+It returns a new `Promise` with the following resolution behavior:
+
+* If the input `$promise` resolves before `$time` seconds, resolve the resulting promise with its fulfillment value.
+* If the input `$promise` rejects before `$time` seconds, reject the resulting promise with its rejection value.
+* If the input `$promise` does not settle before `$time` seconds, *cancel* the operation and reject the resulting promise with a [`TimeoutException`](#timeoutexception).
+
+Internally, the given `$time` value will be used to start a timer that will
+*cancel* the pending operation once it triggers.
+This implies that if you pass a really small (or negative) value, it will still
+start a timer and will thus trigger at the earliest possible time in the future.
+
+If the input `$promise` is already settled, then the resulting promise will
+resolve or reject immediately without starting a timer at all.
+
+A common use case for handling only resolved values looks like this:
+
+```php
+$promise = accessSomeRemoteResource();
+Timer\timeout($promise, 10.0, $loop)->then(function ($value) {
+ // the operation finished within 10.0 seconds
+});
+```
+
+A more complete example could look like this:
+
+```php
+$promise = accessSomeRemoteResource();
+Timer\timeout($promise, 10.0, $loop)->then(
+ function ($value) {
+ // the operation finished within 10.0 seconds
+ },
+ function ($error) {
+ if ($error instanceof Timer\TimeoutException) {
+ // the operation has failed due to a timeout
+ } else {
+ // the input operation has failed due to some other error
+ }
+ }
+);
+```
+
+Or if you're using [react/promise v2.2.0](https://github.com/reactphp/promise) or up:
+
+```php
+Timer\timeout($promise, 10.0, $loop)
+ ->then(function ($value) {
+ // the operation finished within 10.0 seconds
+ })
+ ->otherwise(function (Timer\TimeoutException $error) {
+ // the operation has failed due to a timeout
+ })
+ ->otherwise(function ($error) {
+ // the input operation has failed due to some other error
+ })
+;
+```
+
+#### Timeout cancellation
+
+As discussed above, the [`timeout()`](#timeout) function will *cancel* the
+underlying operation if it takes *too long*.
+This means that you can be sure the resulting promise will then be rejected
+with a [`TimeoutException`](#timeoutexception).
+
+However, what happens to the underlying input `$promise` is a bit more tricky:
+Once the timer fires, we will try to call
+[`$promise->cancel()`](https://github.com/reactphp/promise#cancellablepromiseinterfacecancel)
+on the input `$promise` which in turn invokes its [cancellation handler](#cancellation-handler).
+
+This means that it's actually up the input `$promise` to handle
+[cancellation support](https://github.com/reactphp/promise#cancellablepromiseinterface).
+
+* A common use case involves cleaning up any resources like open network sockets or
+ file handles or terminating external processes or timers.
+
+* If the given input `$promise` does not support cancellation, then this is a NO-OP.
+ This means that while the resulting promise will still be rejected, the underlying
+ input `$promise` may still be pending and can hence continue consuming resources.
+
+See the following chapter for more details on the cancellation handler.
+
+#### Cancellation handler
+
+For example, an implementation for the above operation could look like this:
+
+```php
+function accessSomeRemoteResource()
+{
+ return new Promise(
+ function ($resolve, $reject) use (&$socket) {
+ // this will be called once the promise is created
+ // a common use case involves opening any resources and eventually resolving
+ $socket = createSocket();
+ $socket->on('data', function ($data) use ($resolve) {
+ $resolve($data);
+ });
+ },
+ function ($resolve, $reject) use (&$socket) {
+ // this will be called once calling `cancel()` on this promise
+ // a common use case involves cleaning any resources and then rejecting
+ $socket->close();
+ $reject(new \RuntimeException('Operation cancelled'));
+ }
+ );
+}
+```
+
+In this example, calling `$promise->cancel()` will invoke the registered cancellation
+handler which then closes the network socket and rejects the `Promise` instance.
+
+If no cancellation handler is passed to the `Promise` constructor, then invoking
+its `cancel()` method it is effectively a NO-OP.
+This means that it may still be pending and can hence continue consuming resources.
+
+For more details on the promise cancellation, please refer to the
+[Promise documentation](https://github.com/reactphp/promise#cancellablepromiseinterface).
+
+#### Input cancellation
+
+Irrespective of the timout handling, you can also explicitly `cancel()` the
+input `$promise` at any time.
+This means that the `timeout()` handling does not affect cancellation of the
+input `$promise`, as demonstrated in the following example:
+
+```php
+$promise = accessSomeRemoteResource();
+$timeout = Timer\timeout($promise, 10.0, $loop);
+
+$promise->cancel();
+```
+
+The registered [cancellation handler](#cancellation-handler) is responsible for
+handling the `cancel()` call:
+
+* A described above, a common use involves resource cleanup and will then *reject*
+ the `Promise`.
+ If the input `$promise` is being rejected, then the timeout will be aborted
+ and the resulting promise will also be rejected.
+* If the input `$promise` is still pending, then the timout will continue
+ running until the timer expires.
+ The same happens if the input `$promise` does not register a
+ [cancellation handler](#cancellation-handler).
+
+#### Output cancellation
+
+Similarily, you can also explicitly `cancel()` the resulting promise like this:
+
+```php
+$promise = accessSomeRemoteResource();
+$timeout = Timer\timeout($promise, 10.0, $loop);
+
+$timeout->cancel();
+```
+
+Note how this looks very similar to the above [input cancellation](#input-cancellation)
+example. Accordingly, it also behaves very similar.
+
+Calling `cancel()` on the resulting promise will merely try
+to `cancel()` the input `$promise`.
+This means that we do not take over responsibility of the outcome and it's
+entirely up to the input `$promise` to handle cancellation support.
+
+The registered [cancellation handler](#cancellation-handler) is responsible for
+handling the `cancel()` call:
+
+* As described above, a common use involves resource cleanup and will then *reject*
+ the `Promise`.
+ If the input `$promise` is being rejected, then the timeout will be aborted
+ and the resulting promise will also be rejected.
+* If the input `$promise` is still pending, then the timout will continue
+ running until the timer expires.
+ The same happens if the input `$promise` does not register a
+ [cancellation handler](#cancellation-handler).
+
+To re-iterate, note that calling `cancel()` on the resulting promise will merely
+try to cancel the input `$promise` only.
+It is then up to the cancellation handler of the input promise to settle the promise.
+If the input promise is still pending when the timeout occurs, then the normal
+[timeout cancellation](#timeout-cancellation) handling will trigger, effectively rejecting
+the output promise with a [`TimeoutException`](#timeoutexception).
+
+This is done for consistency with the [timeout cancellation](#timeout-cancellation)
+handling and also because it is assumed this is often used like this:
+
+```php
+$timeout = Timer\timeout(accessSomeRemoteResource(), 10.0, $loop);
+
+$timeout->cancel();
+```
+
+As described above, this example works as expected and cleans up any resources
+allocated for the input `$promise`.
+
+Note that if the given input `$promise` does not support cancellation, then this
+is a NO-OP.
+This means that while the resulting promise will still be rejected after the
+timeout, the underlying input `$promise` may still be pending and can hence
+continue consuming resources.
+
+#### Collections
+
+If you want to wait for multiple promises to resolve, you can use the normal promise primitives like this:
+
+```php
+$promises = array(
+ accessSomeRemoteResource(),
+ accessSomeRemoteResource(),
+ accessSomeRemoteResource()
+);
+
+$promise = \React\Promise\all($promises);
+
+Timer\timeout($promise, 10, $loop)->then(function ($values) {
+ // *all* promises resolved
+});
+```
+
+The applies to all promise collection primitives alike, i.e. `all()`, `race()`, `any()`, `some()` etc.
+
+For more details on the promise primitives, please refer to the
+[Promise documentation](https://github.com/reactphp/promise#functions).
+
+### resolve()
+
+The `resolve($time, LoopInterface $loop)` function can be used to create a new Promise that
+resolves in `$time` seconds with the `$time` as the fulfillment value.
+
+```php
+Timer\resolve(1.5, $loop)->then(function ($time) {
+ echo 'Thanks for waiting ' . $time . ' seconds' . PHP_EOL;
+});
+```
+
+Internally, the given `$time` value will be used to start a timer that will
+resolve the promise once it triggers.
+This implies that if you pass a really small (or negative) value, it will still
+start a timer and will thus trigger at the earliest possible time in the future.
+
+#### Resolve cancellation
+
+You can explicitly `cancel()` the resulting timer promise at any time:
+
+```php
+$timer = Timer\resolve(2.0, $loop);
+
+$timer->cancel();
+```
+
+This will abort the timer and *reject* with a `RuntimeException`.
+
+### reject()
+
+The `reject($time, LoopInterface $loop)` function can be used to create a new Promise
+which rejects in `$time` seconds with a `TimeoutException`.
+
+```php
+Timer\reject(2.0, $loop)->then(null, function (TimeoutException $e) {
+ echo 'Rejected after ' . $e->getTimeout() . ' seconds ' . PHP_EOL;
+});
+```
+
+Internally, the given `$time` value will be used to start a timer that will
+reject the promise once it triggers.
+This implies that if you pass a really small (or negative) value, it will still
+start a timer and will thus trigger at the earliest possible time in the future.
+
+This function complements the [`resolve()`](#resolve) function
+and can be used as a basic building block for higher-level promise consumers.
+
+#### Reject cancellation
+
+You can explicitly `cancel()` the resulting timer promise at any time:
+
+```php
+$timer = Timer\reject(2.0, $loop);
+
+$timer->cancel();
+```
+
+This will abort the timer and *reject* with a `RuntimeException`.
+
+### TimeoutException
+
+The `TimeoutException` extends PHP's built-in `RuntimeException`.
+
+The `getTimeout()` method can be used to get the timeout value in seconds.
+
+## Install
+
+The recommended way to install this library is [through Composer](https://getcomposer.org).
+[New to Composer?](https://getcomposer.org/doc/00-intro.md)
+
+This project follows [SemVer](http://semver.org/).
+This will install the latest supported version:
+
+```bash
+$ composer require react/promise-timer:^1.2.1
+```
+
+See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades.
+
+This project aims to run on any platform and thus does not require any PHP
+extensions and supports running on legacy PHP 5.3 through current PHP 7+ and
+HHVM.
+It's *highly recommended to use PHP 7+* for this project.
+
+## Tests
+
+To run the test suite, you first need to clone this repo and then install all
+dependencies [through Composer](https://getcomposer.org):
+
+```bash
+$ composer install
+```
+
+To run the test suite, go to the project root and run:
+
+```bash
+$ php vendor/bin/phpunit
+```
+
+## License
+
+MIT, see [LICENSE file](LICENSE).
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/composer.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/composer.json
new file mode 100644
index 0000000..e425dc6
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/composer.json
@@ -0,0 +1,28 @@
+{
+ "name": "react/promise-timer",
+ "description": "A trivial implementation of timeouts for Promises, built on top of ReactPHP.",
+ "keywords": ["Promise", "timeout", "timer", "event-loop", "ReactPHP", "async"],
+ "homepage": "https://github.com/react/promise-timer",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Christian Lück",
+ "email": "christian@lueck.tv"
+ }
+ ],
+ "autoload": {
+ "psr-4": { "React\\Promise\\Timer\\": "src/" },
+ "files": [ "src/functions.php" ]
+ },
+ "autoload-dev": {
+ "psr-4": { "React\\Tests\\Promise\\Timer\\": "tests/" }
+ },
+ "require": {
+ "php": ">=5.3",
+ "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5",
+ "react/promise": "~2.1|~1.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/phpunit.xml.dist b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/phpunit.xml.dist
new file mode 100644
index 0000000..bb79fba
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/phpunit.xml.dist
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit bootstrap="vendor/autoload.php"
+ colors="true"
+ convertErrorsToExceptions="true"
+ convertNoticesToExceptions="true"
+ convertWarningsToExceptions="true"
+>
+ <testsuites>
+ <testsuite name="Promise Timer Test Suite">
+ <directory>./tests/</directory>
+ </testsuite>
+ </testsuites>
+ <filter>
+ <whitelist>
+ <directory>./src/</directory>
+ </whitelist>
+ </filter>
+</phpunit> \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/src/TimeoutException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/src/TimeoutException.php
new file mode 100644
index 0000000..18ea72f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/src/TimeoutException.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace React\Promise\Timer;
+
+use RuntimeException;
+
+class TimeoutException extends RuntimeException
+{
+ private $timeout;
+
+ public function __construct($timeout, $message = null, $code = null, $previous = null)
+ {
+ parent::__construct($message, $code, $previous);
+
+ $this->timeout = $timeout;
+ }
+
+ public function getTimeout()
+ {
+ return $this->timeout;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/src/functions.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/src/functions.php
new file mode 100644
index 0000000..6ad9867
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/src/functions.php
@@ -0,0 +1,70 @@
+<?php
+
+namespace React\Promise\Timer;
+
+use React\Promise\CancellablePromiseInterface;
+use React\EventLoop\LoopInterface;
+use React\Promise\PromiseInterface;
+use React\Promise\Promise;
+
+function timeout(PromiseInterface $promise, $time, LoopInterface $loop)
+{
+ // cancelling this promise will only try to cancel the input promise,
+ // thus leaving responsibility to the input promise.
+ $canceller = null;
+ if ($promise instanceof CancellablePromiseInterface) {
+ $canceller = array($promise, 'cancel');
+ }
+
+ return new Promise(function ($resolve, $reject) use ($loop, $time, $promise) {
+ $timer = null;
+ $promise->then(function ($v) use (&$timer, $loop, $resolve) {
+ if ($timer) {
+ $loop->cancelTimer($timer);
+ }
+ $timer = false;
+ $resolve($v);
+ }, function ($v) use (&$timer, $loop, $reject) {
+ if ($timer) {
+ $loop->cancelTimer($timer);
+ }
+ $timer = false;
+ $reject($v);
+ });
+
+ // promise already resolved => no need to start timer
+ if ($timer === false) {
+ return;
+ }
+
+ // start timeout timer which will cancel the input promise
+ $timer = $loop->addTimer($time, function () use ($time, $promise, $reject) {
+ $reject(new TimeoutException($time, 'Timed out after ' . $time . ' seconds'));
+
+ if ($promise instanceof CancellablePromiseInterface) {
+ $promise->cancel();
+ }
+ });
+ }, $canceller);
+}
+
+function resolve($time, LoopInterface $loop)
+{
+ return new Promise(function ($resolve) use ($loop, $time, &$timer) {
+ // resolve the promise when the timer fires in $time seconds
+ $timer = $loop->addTimer($time, function () use ($time, $resolve) {
+ $resolve($time);
+ });
+ }, function ($resolveUnused, $reject) use (&$timer, $loop) {
+ // cancelling this promise will cancel the timer and reject
+ $loop->cancelTimer($timer);
+ $reject(new \RuntimeException('Timer cancelled'));
+ });
+}
+
+function reject($time, LoopInterface $loop)
+{
+ return resolve($time, $loop)->then(function ($time) {
+ throw new TimeoutException($time, 'Timer expired after ' . $time . ' seconds');
+ });
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/tests/CallableStub.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/tests/CallableStub.php
new file mode 100644
index 0000000..a391aa5
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/tests/CallableStub.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace React\Tests\Promise\Timer;
+
+class CallableStub
+{
+ public function __invoke()
+ {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/tests/FunctionRejectTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/tests/FunctionRejectTest.php
new file mode 100644
index 0000000..6153fcc
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/tests/FunctionRejectTest.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace React\Tests\Promise\Timer;
+
+use React\Promise\Timer;
+
+class FunctionRejectTest extends TestCase
+{
+ public function testPromiseIsPendingWithoutRunningLoop()
+ {
+ $promise = Timer\reject(0.01, $this->loop);
+
+ $this->expectPromisePending($promise);
+ }
+
+ public function testPromiseExpiredIsPendingWithoutRunningLoop()
+ {
+ $promise = Timer\reject(-1, $this->loop);
+
+ $this->expectPromisePending($promise);
+ }
+
+ public function testPromiseWillBeRejectedOnTimeout()
+ {
+ $promise = Timer\reject(0.01, $this->loop);
+
+ $this->loop->run();
+
+ $this->expectPromiseRejected($promise);
+ }
+
+ public function testPromiseExpiredWillBeRejectedOnTimeout()
+ {
+ $promise = Timer\reject(-1, $this->loop);
+
+ $this->loop->run();
+
+ $this->expectPromiseRejected($promise);
+ }
+
+ public function testCancelingPromiseWillRejectTimer()
+ {
+ $promise = Timer\reject(0.01, $this->loop);
+
+ $promise->cancel();
+
+ $this->expectPromiseRejected($promise);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/tests/FunctionResolveTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/tests/FunctionResolveTest.php
new file mode 100644
index 0000000..0bfdc21
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/tests/FunctionResolveTest.php
@@ -0,0 +1,71 @@
+<?php
+
+namespace React\Tests\Promise\Timer;
+
+use React\Promise\Timer;
+
+class FunctionResolveTest extends TestCase
+{
+ public function testPromiseIsPendingWithoutRunningLoop()
+ {
+ $promise = Timer\resolve(0.01, $this->loop);
+
+ $this->expectPromisePending($promise);
+ }
+
+ public function testPromiseExpiredIsPendingWithoutRunningLoop()
+ {
+ $promise = Timer\resolve(-1, $this->loop);
+
+ $this->expectPromisePending($promise);
+ }
+
+ public function testPromiseWillBeResolvedOnTimeout()
+ {
+ $promise = Timer\resolve(0.01, $this->loop);
+
+ $this->loop->run();
+
+ $this->expectPromiseResolved($promise);
+ }
+
+ public function testPromiseExpiredWillBeResolvedOnTimeout()
+ {
+ $promise = Timer\resolve(-1, $this->loop);
+
+ $this->loop->run();
+
+ $this->expectPromiseResolved($promise);
+ }
+
+ public function testWillStartLoopTimer()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ $loop->expects($this->once())->method('addTimer')->with($this->equalTo(0.01));
+
+ Timer\resolve(0.01, $loop);
+ }
+
+ public function testCancellingPromiseWillCancelLoopTimer()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+
+ $timer = $this->getMockBuilder(interface_exists('React\EventLoop\TimerInterface') ? 'React\EventLoop\TimerInterface' : 'React\EventLoop\Timer\TimerInterface')->getMock();
+ $loop->expects($this->once())->method('addTimer')->will($this->returnValue($timer));
+
+ $promise = Timer\resolve(0.01, $loop);
+
+ $loop->expects($this->once())->method('cancelTimer')->with($this->equalTo($timer));
+
+ $promise->cancel();
+ }
+
+ public function testCancelingPromiseWillRejectTimer()
+ {
+ $promise = Timer\resolve(0.01, $this->loop);
+
+ $promise->cancel();
+
+ $this->expectPromiseRejected($promise);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/tests/FunctionTimeoutTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/tests/FunctionTimeoutTest.php
new file mode 100644
index 0000000..aaca2da
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/tests/FunctionTimeoutTest.php
@@ -0,0 +1,169 @@
+<?php
+
+namespace React\Tests\Promise\Timer;
+
+use React\Promise\Timer;
+use React\Promise;
+
+class FunctionTimerTest extends TestCase
+{
+ public function testResolvedWillResolveRightAway()
+ {
+ $promise = Promise\resolve();
+
+ $promise = Timer\timeout($promise, 3, $this->loop);
+
+ $this->expectPromiseResolved($promise);
+ }
+
+ public function testResolvedExpiredWillResolveRightAway()
+ {
+ $promise = Promise\resolve();
+
+ $promise = Timer\timeout($promise, -1, $this->loop);
+
+ $this->expectPromiseResolved($promise);
+ }
+
+ public function testResolvedWillNotStartTimer()
+ {
+ $promise = Promise\resolve();
+
+ Timer\timeout($promise, 3, $this->loop);
+
+ $time = microtime(true);
+ $this->loop->run();
+ $time = microtime(true) - $time;
+
+ $this->assertLessThan(0.5, $time);
+ }
+
+ public function testRejectedWillRejectRightAway()
+ {
+ $promise = Promise\reject();
+
+ $promise = Timer\timeout($promise, 3, $this->loop);
+
+ $this->expectPromiseRejected($promise);
+ }
+
+ public function testRejectedWillNotStartTimer()
+ {
+ $promise = Promise\reject();
+
+ Timer\timeout($promise, 3, $this->loop);
+
+ $time = microtime(true);
+ $this->loop->run();
+ $time = microtime(true) - $time;
+
+ $this->assertLessThan(0.5, $time);
+ }
+
+ public function testPendingWillRejectOnTimeout()
+ {
+ $promise = $this->getMockBuilder('React\Promise\PromiseInterface')->getMock();
+
+ $promise = Timer\timeout($promise, 0.01, $this->loop);
+
+ $this->loop->run();
+
+ $this->expectPromiseRejected($promise);
+ }
+
+ public function testPendingCancellableWillBeCancelledOnTimeout()
+ {
+ $promise = $this->getMockBuilder('React\Promise\CancellablePromiseInterface')->getMock();
+ $promise->expects($this->once())->method('cancel');
+
+ Timer\timeout($promise, 0.01, $this->loop);
+
+ $this->loop->run();
+ }
+
+ public function testCancelTimeoutWithoutCancellationhandlerWillNotCancelTimerAndWillNotReject()
+ {
+ $promise = new \React\Promise\Promise(function () { });
+
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+
+ $timer = $this->getMockBuilder('React\EventLoop\Timer\TimerInterface')->getMock();
+ $loop->expects($this->once())->method('addTimer')->will($this->returnValue($timer));
+ $loop->expects($this->never())->method('cancelTimer');
+
+ $timeout = Timer\timeout($promise, 0.01, $loop);
+
+ $timeout->cancel();
+
+ $this->expectPromisePending($timeout);
+ }
+
+ public function testResolvedPromiseWillNotStartTimer()
+ {
+ $promise = new \React\Promise\Promise(function ($resolve) { $resolve(true); });
+
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ $loop->expects($this->never())->method('addTimer');
+
+ $timeout = Timer\timeout($promise, 0.01, $loop);
+
+ $this->expectPromiseResolved($timeout);
+ }
+
+ public function testRejectedPromiseWillNotStartTimer()
+ {
+ $promise = Promise\reject(new \RuntimeException());
+
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ $loop->expects($this->never())->method('addTimer');
+
+ $timeout = Timer\timeout($promise, 0.01, $loop);
+
+ $this->expectPromiseRejected($timeout);
+ }
+
+ public function testCancelTimeoutWillCancelGivenPromise()
+ {
+ $promise = new \React\Promise\Promise(function () { }, $this->expectCallableOnce());
+
+ $timeout = Timer\timeout($promise, 0.01, $this->loop);
+
+ $timeout->cancel();
+ }
+
+ public function testCancelGivenPromiseWillReject()
+ {
+ $promise = new \React\Promise\Promise(function () { }, function ($resolve, $reject) { $reject(); });
+
+ $timeout = Timer\timeout($promise, 0.01, $this->loop);
+
+ $promise->cancel();
+
+ $this->expectPromiseRejected($promise);
+ $this->expectPromiseRejected($timeout);
+ }
+
+ public function testCancelTimeoutWillRejectIfGivenPromiseWillReject()
+ {
+ $promise = new \React\Promise\Promise(function () { }, function ($resolve, $reject) { $reject(); });
+
+ $timeout = Timer\timeout($promise, 0.01, $this->loop);
+
+ $timeout->cancel();
+
+ $this->expectPromiseRejected($promise);
+ $this->expectPromiseRejected($timeout);
+ }
+
+ public function testCancelTimeoutWillResolveIfGivenPromiseWillResolve()
+ {
+ $promise = new \React\Promise\Promise(function () { }, function ($resolve, $reject) { $resolve(); });
+
+ $timeout = Timer\timeout($promise, 0.01, $this->loop);
+
+ $timeout->cancel();
+
+ $this->expectPromiseResolved($promise);
+ $this->expectPromiseResolved($timeout);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/tests/TestCase.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/tests/TestCase.php
new file mode 100644
index 0000000..9d8d49a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/tests/TestCase.php
@@ -0,0 +1,61 @@
+<?php
+
+namespace React\Tests\Promise\Timer;
+
+use PHPUnit\Framework\TestCase as BaseTestCase;
+use React\EventLoop\Factory;
+
+class TestCase extends BaseTestCase
+{
+ protected $loop;
+
+ public function setUp()
+ {
+ $this->loop = Factory::create();
+ }
+
+ protected function expectCallableOnce()
+ {
+ $mock = $this->createCallableMock();
+
+ $mock
+ ->expects($this->once())
+ ->method('__invoke');
+
+ return $mock;
+ }
+
+ protected function expectCallableNever()
+ {
+ $mock = $this->createCallableMock();
+
+ $mock
+ ->expects($this->never())
+ ->method('__invoke');
+
+ return $mock;
+ }
+
+ /**
+ * @link https://github.com/reactphp/react/blob/master/tests/React/Tests/Socket/TestCase.php (taken from reactphp/react)
+ */
+ protected function createCallableMock()
+ {
+ return $this->getMockBuilder('React\Tests\Promise\Timer\CallableStub')->getMock();
+ }
+
+ protected function expectPromiseRejected($promise)
+ {
+ return $promise->then($this->expectCallableNever(), $this->expectCallableOnce());
+ }
+
+ protected function expectPromiseResolved($promise)
+ {
+ return $promise->then($this->expectCallableOnce(), $this->expectCallableNever());
+ }
+
+ protected function expectPromisePending($promise)
+ {
+ return $promise->then($this->expectCallableNever(), $this->expectCallableNever());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/tests/TimeoutExceptionTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/tests/TimeoutExceptionTest.php
new file mode 100644
index 0000000..e9bedd9
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise-timer/tests/TimeoutExceptionTest.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace React\Tests\Promise\Timer;
+
+use React\Promise\Timer\TimeoutException;
+
+class TimeoutExceptionTest extends TestCase
+{
+ public function testAccessTimeout()
+ {
+ $e = new TimeoutException(10);
+
+ $this->assertEquals(10, $e->getTimeout());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/.gitignore b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/.gitignore
new file mode 100644
index 0000000..5241c60
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/.gitignore
@@ -0,0 +1,5 @@
+composer.lock
+composer.phar
+phpunit.xml
+build/
+vendor/
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/.travis.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/.travis.yml
new file mode 100644
index 0000000..5d0c6ab
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/.travis.yml
@@ -0,0 +1,22 @@
+language: php
+
+php:
+ - 5.4
+ - 5.5
+ - 5.6
+ - 7.0
+ - nightly
+ - hhvm
+
+before_install:
+ - composer self-update
+
+install:
+ - composer install
+
+script:
+ - ./vendor/bin/phpunit -v --coverage-text --coverage-clover=./build/logs/clover.xml
+
+after_script:
+ - if [ -f ./build/logs/clover.xml ]; then travis_retry composer require satooshi/php-coveralls --no-interaction --update-with-dependencies; fi
+ - if [ -f ./build/logs/clover.xml ]; then php vendor/bin/coveralls -v; fi
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/CHANGELOG.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/CHANGELOG.md
new file mode 100644
index 0000000..484e542
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/CHANGELOG.md
@@ -0,0 +1,96 @@
+CHANGELOG for 2.x
+=================
+
+* 2.5.1 (2017-03-25)
+
+ * Fix circular references when resolving with a promise which follows
+ itself (#94).
+
+* 2.5.0 (2016-12-22)
+
+ * Revert automatic cancellation of pending collection promises once the
+ output promise resolves. This was introduced in 42d86b7 (PR #36, released
+ in [v2.3.0](https://github.com/reactphp/promise/releases/tag/v2.3.0)) and
+ was both unintended and backward incompatible.
+
+ If you need automatic cancellation, you can use something like:
+
+ ```php
+ function allAndCancel(array $promises)
+ {
+ return \React\Promise\all($promises)
+ ->always(function() use ($promises) {
+ foreach ($promises as $promise) {
+ if ($promise instanceof \React\Promise\CancellablePromiseInterface) {
+ $promise->cancel();
+ }
+ }
+ });
+ }
+ ```
+ * `all()` and `map()` functions now preserve the order of the array (#77).
+ * Fix circular references when resolving a promise with itself (#71).
+
+* 2.4.1 (2016-05-03)
+
+ * Fix `some()` not cancelling pending promises when too much input promises
+ reject (16ff799).
+
+* 2.4.0 (2016-03-31)
+
+ * Support foreign thenables in `resolve()`.
+ Any object that provides a `then()` method is now assimilated to a trusted
+ promise that follows the state of this thenable (#52).
+ * Fix `some()` and `any()` for input arrays containing not enough items
+ (#34).
+
+* 2.3.0 (2016-03-24)
+
+ * Allow cancellation of promises returned by functions working on promise
+ collections (#36).
+ * Handle `\Throwable` in the same way as `\Exception` (#51 by @joshdifabio).
+
+* 2.2.2 (2016-02-26)
+
+ * Fix cancellation handlers called multiple times (#47 by @clue).
+
+* 2.2.1 (2015-07-03)
+
+ * Fix stack error when resolving a promise in its own fulfillment or
+ rejection handlers.
+
+* 2.2.0 (2014-12-30)
+
+ * Introduce new `ExtendedPromiseInterface` implemented by all promises.
+ * Add new `done()` method (part of the `ExtendedPromiseInterface`).
+ * Add new `otherwise()` method (part of the `ExtendedPromiseInterface`).
+ * Add new `always()` method (part of the `ExtendedPromiseInterface`).
+ * Add new `progress()` method (part of the `ExtendedPromiseInterface`).
+ * Rename `Deferred::progress` to `Deferred::notify` to avoid confusion with
+ `ExtendedPromiseInterface::progress` (a `Deferred::progress` alias is
+ still available for backward compatibility)
+ * `resolve()` now always returns a `ExtendedPromiseInterface`.
+
+* 2.1.0 (2014-10-15)
+
+ * Introduce new `CancellablePromiseInterface` implemented by all promises.
+ * Add new `cancel()` method (part of the `CancellablePromiseInterface`).
+
+* 2.0.0 (2013-12-10)
+
+ New major release. The goal is to streamline the API and to make it more
+ compliant with other promise libraries and especially with the new upcoming
+ [ES6 promises specification](https://github.com/domenic/promises-unwrapping/).
+
+ * Add standalone Promise class.
+ * Add new `race()` function.
+ * BC break: Bump minimum PHP version to PHP 5.4.
+ * BC break: Remove `ResolverInterface` and `PromiseInterface` from
+ `Deferred`.
+ * BC break: Change signature of `PromiseInterface`.
+ * BC break: Remove `When` and `Util` classes and move static methods to
+ functions.
+ * BC break: `FulfilledPromise` and `RejectedPromise` now throw an exception
+ when initialized with a promise instead of a value/reason.
+ * BC break: `Deferred::resolve()` and `Deferred::reject()` no longer return
+ a promise.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/LICENSE b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/LICENSE
new file mode 100644
index 0000000..5919d20
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2012-2016 Jan Sorgalla
+
+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.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/README.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/README.md
new file mode 100644
index 0000000..9c0558c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/README.md
@@ -0,0 +1,840 @@
+React/Promise
+=============
+
+A lightweight implementation of
+[CommonJS Promises/A](http://wiki.commonjs.org/wiki/Promises/A) for PHP.
+
+[![Build Status](https://travis-ci.org/reactphp/promise.svg?branch=master)](http://travis-ci.org/reactphp/promise)
+[![Coverage Status](https://coveralls.io/repos/github/reactphp/promise/badge.svg?branch=master)](https://coveralls.io/github/reactphp/promise?branch=master)
+
+Table of Contents
+-----------------
+
+1. [Introduction](#introduction)
+2. [Concepts](#concepts)
+ * [Deferred](#deferred)
+ * [Promise](#promise)
+3. [API](#api)
+ * [Deferred](#deferred-1)
+ * [Deferred::promise()](#deferredpromise)
+ * [Deferred::resolve()](#deferredresolve)
+ * [Deferred::reject()](#deferredreject)
+ * [Deferred::notify()](#deferrednotify)
+ * [PromiseInterface](#promiseinterface)
+ * [PromiseInterface::then()](#promiseinterfacethen)
+ * [ExtendedPromiseInterface](#extendedpromiseinterface)
+ * [ExtendedPromiseInterface::done()](#extendedpromiseinterfacedone)
+ * [ExtendedPromiseInterface::otherwise()](#extendedpromiseinterfaceotherwise)
+ * [ExtendedPromiseInterface::always()](#extendedpromiseinterfacealways)
+ * [ExtendedPromiseInterface::progress()](#extendedpromiseinterfaceprogress)
+ * [CancellablePromiseInterface](#cancellablepromiseinterface)
+ * [CancellablePromiseInterface::cancel()](#cancellablepromiseinterfacecancel)
+ * [Promise](#promise-1)
+ * [FulfilledPromise](#fulfilledpromise)
+ * [RejectedPromise](#rejectedpromise)
+ * [LazyPromise](#lazypromise)
+ * [Functions](#functions)
+ * [resolve()](#resolve)
+ * [reject()](#reject)
+ * [all()](#all)
+ * [race()](#race)
+ * [any()](#any)
+ * [some()](#some)
+ * [map()](#map)
+ * [reduce()](#reduce)
+ * [PromisorInterface](#promisorinterface)
+4. [Examples](#examples)
+ * [How to use Deferred](#how-to-use-deferred)
+ * [How promise forwarding works](#how-promise-forwarding-works)
+ * [Resolution forwarding](#resolution-forwarding)
+ * [Rejection forwarding](#rejection-forwarding)
+ * [Mixed resolution and rejection forwarding](#mixed-resolution-and-rejection-forwarding)
+ * [Progress event forwarding](#progress-event-forwarding)
+ * [done() vs. then()](#done-vs-then)
+5. [Credits](#credits)
+6. [License](#license)
+
+Introduction
+------------
+
+React/Promise is a library implementing
+[CommonJS Promises/A](http://wiki.commonjs.org/wiki/Promises/A) for PHP.
+
+It also provides several other useful promise-related concepts, such as joining
+multiple promises and mapping and reducing collections of promises.
+
+If you've never heard about promises before,
+[read this first](https://gist.github.com/3889970).
+
+Concepts
+--------
+
+### Deferred
+
+A **Deferred** represents a computation or unit of work that may not have
+completed yet. Typically (but not always), that computation will be something
+that executes asynchronously and completes at some point in the future.
+
+### Promise
+
+While a deferred represents the computation itself, a **Promise** represents
+the result of that computation. Thus, each deferred has a promise that acts as
+a placeholder for its actual result.
+
+API
+---
+
+### Deferred
+
+A deferred represents an operation whose resolution is pending. It has separate
+promise and resolver parts.
+
+```php
+$deferred = new React\Promise\Deferred();
+
+$promise = $deferred->promise();
+
+$deferred->resolve(mixed $value = null);
+$deferred->reject(mixed $reason = null);
+$deferred->notify(mixed $update = null);
+```
+
+The `promise` method returns the promise of the deferred.
+
+The `resolve` and `reject` methods control the state of the deferred.
+
+The `notify` method is for progress notification.
+
+The constructor of the `Deferred` accepts an optional `$canceller` argument.
+See [Promise](#promise-1) for more information.
+
+#### Deferred::promise()
+
+```php
+$promise = $deferred->promise();
+```
+
+Returns the promise of the deferred, which you can hand out to others while
+keeping the authority to modify its state to yourself.
+
+#### Deferred::resolve()
+
+```php
+$deferred->resolve(mixed $value = null);
+```
+
+Resolves the promise returned by `promise()`. All consumers are notified by
+having `$onFulfilled` (which they registered via `$promise->then()`) called with
+`$value`.
+
+If `$value` itself is a promise, the promise will transition to the state of
+this promise once it is resolved.
+
+#### Deferred::reject()
+
+```php
+$deferred->reject(mixed $reason = null);
+```
+
+Rejects the promise returned by `promise()`, signalling that the deferred's
+computation failed.
+All consumers are notified by having `$onRejected` (which they registered via
+`$promise->then()`) called with `$reason`.
+
+If `$reason` itself is a promise, the promise will be rejected with the outcome
+of this promise regardless whether it fulfills or rejects.
+
+#### Deferred::notify()
+
+```php
+$deferred->notify(mixed $update = null);
+```
+
+Triggers progress notifications, to indicate to consumers that the computation
+is making progress toward its result.
+
+All consumers are notified by having `$onProgress` (which they registered via
+`$promise->then()`) called with `$update`.
+
+### PromiseInterface
+
+The promise interface provides the common interface for all promise
+implementations.
+
+A promise represents an eventual outcome, which is either fulfillment (success)
+and an associated value, or rejection (failure) and an associated reason.
+
+Once in the fulfilled or rejected state, a promise becomes immutable.
+Neither its state nor its result (or error) can be modified.
+
+#### Implementations
+
+* [Promise](#promise-1)
+* [FulfilledPromise](#fulfilledpromise)
+* [RejectedPromise](#rejectedpromise)
+* [LazyPromise](#lazypromise)
+
+#### PromiseInterface::then()
+
+```php
+$transformedPromise = $promise->then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null);
+```
+
+Transforms a promise's value by applying a function to the promise's fulfillment
+or rejection value. Returns a new promise for the transformed result.
+
+The `then()` method registers new fulfilled, rejection and progress handlers
+with a promise (all parameters are optional):
+
+ * `$onFulfilled` will be invoked once the promise is fulfilled and passed
+ the result as the first argument.
+ * `$onRejected` will be invoked once the promise is rejected and passed the
+ reason as the first argument.
+ * `$onProgress` will be invoked whenever the producer of the promise
+ triggers progress notifications and passed a single argument (whatever it
+ wants) to indicate progress.
+
+It returns a new promise that will fulfill with the return value of either
+`$onFulfilled` or `$onRejected`, whichever is called, or will reject with
+the thrown exception if either throws.
+
+A promise makes the following guarantees about handlers registered in
+the same call to `then()`:
+
+ 1. Only one of `$onFulfilled` or `$onRejected` will be called,
+ never both.
+ 2. `$onFulfilled` and `$onRejected` will never be called more
+ than once.
+ 3. `$onProgress` may be called multiple times.
+
+#### See also
+
+* [resolve()](#resolve) - Creating a resolved promise
+* [reject()](#reject) - Creating a rejected promise
+* [ExtendedPromiseInterface::done()](#extendedpromiseinterfacedone)
+* [done() vs. then()](#done-vs-then)
+
+### ExtendedPromiseInterface
+
+The ExtendedPromiseInterface extends the PromiseInterface with useful shortcut
+and utility methods which are not part of the Promises/A specification.
+
+#### Implementations
+
+* [Promise](#promise-1)
+* [FulfilledPromise](#fulfilledpromise)
+* [RejectedPromise](#rejectedpromise)
+* [LazyPromise](#lazypromise)
+
+#### ExtendedPromiseInterface::done()
+
+```php
+$promise->done(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null);
+```
+
+Consumes the promise's ultimate value if the promise fulfills, or handles the
+ultimate error.
+
+It will cause a fatal error if either `$onFulfilled` or `$onRejected` throw or
+return a rejected promise.
+
+Since the purpose of `done()` is consumption rather than transformation,
+`done()` always returns `null`.
+
+#### See also
+
+* [PromiseInterface::then()](#promiseinterfacethen)
+* [done() vs. then()](#done-vs-then)
+
+#### ExtendedPromiseInterface::otherwise()
+
+```php
+$promise->otherwise(callable $onRejected);
+```
+
+Registers a rejection handler for promise. It is a shortcut for:
+
+```php
+$promise->then(null, $onRejected);
+```
+
+Additionally, you can type hint the `$reason` argument of `$onRejected` to catch
+only specific errors.
+
+```php
+$promise
+ ->otherwise(function (\RuntimeException $reason) {
+ // Only catch \RuntimeException instances
+ // All other types of errors will propagate automatically
+ })
+ ->otherwise(function ($reason) {
+ // Catch other errors
+ )};
+```
+
+#### ExtendedPromiseInterface::always()
+
+```php
+$newPromise = $promise->always(callable $onFulfilledOrRejected);
+```
+
+Allows you to execute "cleanup" type tasks in a promise chain.
+
+It arranges for `$onFulfilledOrRejected` to be called, with no arguments,
+when the promise is either fulfilled or rejected.
+
+* If `$promise` fulfills, and `$onFulfilledOrRejected` returns successfully,
+ `$newPromise` will fulfill with the same value as `$promise`.
+* If `$promise` fulfills, and `$onFulfilledOrRejected` throws or returns a
+ rejected promise, `$newPromise` will reject with the thrown exception or
+ rejected promise's reason.
+* If `$promise` rejects, and `$onFulfilledOrRejected` returns successfully,
+ `$newPromise` will reject with the same reason as `$promise`.
+* If `$promise` rejects, and `$onFulfilledOrRejected` throws or returns a
+ rejected promise, `$newPromise` will reject with the thrown exception or
+ rejected promise's reason.
+
+`always()` behaves similarly to the synchronous finally statement. When combined
+with `otherwise()`, `always()` allows you to write code that is similar to the familiar
+synchronous catch/finally pair.
+
+Consider the following synchronous code:
+
+```php
+try {
+ return doSomething();
+} catch(\Exception $e) {
+ return handleError($e);
+} finally {
+ cleanup();
+}
+```
+
+Similar asynchronous code (with `doSomething()` that returns a promise) can be
+written:
+
+```php
+return doSomething()
+ ->otherwise('handleError')
+ ->always('cleanup');
+```
+
+#### ExtendedPromiseInterface::progress()
+
+```php
+$promise->progress(callable $onProgress);
+```
+
+Registers a handler for progress updates from promise. It is a shortcut for:
+
+```php
+$promise->then(null, null, $onProgress);
+```
+
+### CancellablePromiseInterface
+
+A cancellable promise provides a mechanism for consumers to notify the creator
+of the promise that they are not longer interested in the result of an
+operation.
+
+#### CancellablePromiseInterface::cancel()
+
+``` php
+$promise->cancel();
+```
+
+The `cancel()` method notifies the creator of the promise that there is no
+further interest in the results of the operation.
+
+Once a promise is settled (either fulfilled or rejected), calling `cancel()` on
+a promise has no effect.
+
+#### Implementations
+
+* [Promise](#promise-1)
+* [FulfilledPromise](#fulfilledpromise)
+* [RejectedPromise](#rejectedpromise)
+* [LazyPromise](#lazypromise)
+
+### Promise
+
+Creates a promise whose state is controlled by the functions passed to
+`$resolver`.
+
+```php
+$resolver = function (callable $resolve, callable $reject, callable $notify) {
+ // Do some work, possibly asynchronously, and then
+ // resolve or reject. You can notify of progress events
+ // along the way if you want/need.
+
+ $resolve($awesomeResult);
+ // or $resolve($anotherPromise);
+ // or $reject($nastyError);
+ // or $notify($progressNotification);
+};
+
+$canceller = function (callable $resolve, callable $reject, callable $progress) {
+ // Cancel/abort any running operations like network connections, streams etc.
+
+ $reject(new \Exception('Promise cancelled'));
+};
+
+$promise = new React\Promise\Promise($resolver, $canceller);
+```
+
+The promise constructor receives a resolver function and an optional canceller
+function which both will be called with 3 arguments:
+
+ * `$resolve($value)` - Primary function that seals the fate of the
+ returned promise. Accepts either a non-promise value, or another promise.
+ When called with a non-promise value, fulfills promise with that value.
+ When called with another promise, e.g. `$resolve($otherPromise)`, promise's
+ fate will be equivalent to that of `$otherPromise`.
+ * `$reject($reason)` - Function that rejects the promise.
+ * `$notify($update)` - Function that issues progress events for the promise.
+
+If the resolver or canceller throw an exception, the promise will be rejected
+with that thrown exception as the rejection reason.
+
+The resolver function will be called immediately, the canceller function only
+once all consumers called the `cancel()` method of the promise.
+
+### FulfilledPromise
+
+Creates a already fulfilled promise.
+
+```php
+$promise = React\Promise\FulfilledPromise($value);
+```
+
+Note, that `$value` **cannot** be a promise. It's recommended to use
+[resolve()](#resolve) for creating resolved promises.
+
+### RejectedPromise
+
+Creates a already rejected promise.
+
+```php
+$promise = React\Promise\RejectedPromise($reason);
+```
+
+Note, that `$reason` **cannot** be a promise. It's recommended to use
+[reject()](#reject) for creating rejected promises.
+
+### LazyPromise
+
+Creates a promise which will be lazily initialized by `$factory` once a consumer
+calls the `then()` method.
+
+```php
+$factory = function () {
+ $deferred = new React\Promise\Deferred();
+
+ // Do some heavy stuff here and resolve the deferred once completed
+
+ return $deferred->promise();
+};
+
+$promise = React\Promise\LazyPromise($factory);
+
+// $factory will only be executed once we call then()
+$promise->then(function ($value) {
+});
+```
+
+### Functions
+
+Useful functions for creating, joining, mapping and reducing collections of
+promises.
+
+All functions working on promise collections (like `all()`, `race()`, `some()`
+etc.) support cancellation. This means, if you call `cancel()` on the returned
+promise, all promises in the collection are cancelled. If the collection itself
+is a promise which resolves to an array, this promise is also cancelled.
+
+#### resolve()
+
+```php
+$promise = React\Promise\resolve(mixed $promiseOrValue);
+```
+
+Creates a promise for the supplied `$promiseOrValue`.
+
+If `$promiseOrValue` is a value, it will be the resolution value of the
+returned promise.
+
+If `$promiseOrValue` is a thenable (any object that provides a `then()` method),
+a trusted promise that follows the state of the thenable is returned.
+
+If `$promiseOrValue` is a promise, it will be returned as is.
+
+Note: The promise returned is always a promise implementing
+[ExtendedPromiseInterface](#extendedpromiseinterface). If you pass in a custom
+promise which only implements [PromiseInterface](#promiseinterface), this
+promise will be assimilated to a extended promise following `$promiseOrValue`.
+
+#### reject()
+
+```php
+$promise = React\Promise\reject(mixed $promiseOrValue);
+```
+
+Creates a rejected promise for the supplied `$promiseOrValue`.
+
+If `$promiseOrValue` is a value, it will be the rejection value of the
+returned promise.
+
+If `$promiseOrValue` is a promise, its completion value will be the rejected
+value of the returned promise.
+
+This can be useful in situations where you need to reject a promise without
+throwing an exception. For example, it allows you to propagate a rejection with
+the value of another promise.
+
+#### all()
+
+```php
+$promise = React\Promise\all(array|React\Promise\PromiseInterface $promisesOrValues);
+```
+
+Returns a promise that will resolve only once all the items in
+`$promisesOrValues` have resolved. The resolution value of the returned promise
+will be an array containing the resolution values of each of the items in
+`$promisesOrValues`.
+
+#### race()
+
+```php
+$promise = React\Promise\race(array|React\Promise\PromiseInterface $promisesOrValues);
+```
+
+Initiates a competitive race that allows one winner. Returns a promise which is
+resolved in the same way the first settled promise resolves.
+
+#### any()
+
+```php
+$promise = React\Promise\any(array|React\Promise\PromiseInterface $promisesOrValues);
+```
+
+Returns a promise that will resolve when any one of the items in
+`$promisesOrValues` resolves. The resolution value of the returned promise
+will be the resolution value of the triggering item.
+
+The returned promise will only reject if *all* items in `$promisesOrValues` are
+rejected. The rejection value will be an array of all rejection reasons.
+
+The returned promise will also reject with a `React\Promise\Exception\LengthException`
+if `$promisesOrValues` contains 0 items.
+
+#### some()
+
+```php
+$promise = React\Promise\some(array|React\Promise\PromiseInterface $promisesOrValues, integer $howMany);
+```
+
+Returns a promise that will resolve when `$howMany` of the supplied items in
+`$promisesOrValues` resolve. The resolution value of the returned promise
+will be an array of length `$howMany` containing the resolution values of the
+triggering items.
+
+The returned promise will reject if it becomes impossible for `$howMany` items
+to resolve (that is, when `(count($promisesOrValues) - $howMany) + 1` items
+reject). The rejection value will be an array of
+`(count($promisesOrValues) - $howMany) + 1` rejection reasons.
+
+The returned promise will also reject with a `React\Promise\Exception\LengthException`
+if `$promisesOrValues` contains less items than `$howMany`.
+
+#### map()
+
+```php
+$promise = React\Promise\map(array|React\Promise\PromiseInterface $promisesOrValues, callable $mapFunc);
+```
+
+Traditional map function, similar to `array_map()`, but allows input to contain
+promises and/or values, and `$mapFunc` may return either a value or a promise.
+
+The map function receives each item as argument, where item is a fully resolved
+value of a promise or value in `$promisesOrValues`.
+
+#### reduce()
+
+```php
+$promise = React\Promise\reduce(array|React\Promise\PromiseInterface $promisesOrValues, callable $reduceFunc , $initialValue = null);
+```
+
+Traditional reduce function, similar to `array_reduce()`, but input may contain
+promises and/or values, and `$reduceFunc` may return either a value or a
+promise, *and* `$initialValue` may be a promise or a value for the starting
+value.
+
+### PromisorInterface
+
+The `React\Promise\PromisorInterface` provides a common interface for objects
+that provide a promise. `React\Promise\Deferred` implements it, but since it
+is part of the public API anyone can implement it.
+
+Examples
+--------
+
+### How to use Deferred
+
+```php
+function getAwesomeResultPromise()
+{
+ $deferred = new React\Promise\Deferred();
+
+ // Execute a Node.js-style function using the callback pattern
+ computeAwesomeResultAsynchronously(function ($error, $result) use ($deferred) {
+ if ($error) {
+ $deferred->reject($error);
+ } else {
+ $deferred->resolve($result);
+ }
+ });
+
+ // Return the promise
+ return $deferred->promise();
+}
+
+getAwesomeResultPromise()
+ ->then(
+ function ($value) {
+ // Deferred resolved, do something with $value
+ },
+ function ($reason) {
+ // Deferred rejected, do something with $reason
+ },
+ function ($update) {
+ // Progress notification triggered, do something with $update
+ }
+ );
+```
+
+### How promise forwarding works
+
+A few simple examples to show how the mechanics of Promises/A forwarding works.
+These examples are contrived, of course, and in real usage, promise chains will
+typically be spread across several function calls, or even several levels of
+your application architecture.
+
+#### Resolution forwarding
+
+Resolved promises forward resolution values to the next promise.
+The first promise, `$deferred->promise()`, will resolve with the value passed
+to `$deferred->resolve()` below.
+
+Each call to `then()` returns a new promise that will resolve with the return
+value of the previous handler. This creates a promise "pipeline".
+
+```php
+$deferred = new React\Promise\Deferred();
+
+$deferred->promise()
+ ->then(function ($x) {
+ // $x will be the value passed to $deferred->resolve() below
+ // and returns a *new promise* for $x + 1
+ return $x + 1;
+ })
+ ->then(function ($x) {
+ // $x === 2
+ // This handler receives the return value of the
+ // previous handler.
+ return $x + 1;
+ })
+ ->then(function ($x) {
+ // $x === 3
+ // This handler receives the return value of the
+ // previous handler.
+ return $x + 1;
+ })
+ ->then(function ($x) {
+ // $x === 4
+ // This handler receives the return value of the
+ // previous handler.
+ echo 'Resolve ' . $x;
+ });
+
+$deferred->resolve(1); // Prints "Resolve 4"
+```
+
+#### Rejection forwarding
+
+Rejected promises behave similarly, and also work similarly to try/catch:
+When you catch an exception, you must rethrow for it to propagate.
+
+Similarly, when you handle a rejected promise, to propagate the rejection,
+"rethrow" it by either returning a rejected promise, or actually throwing
+(since promise translates thrown exceptions into rejections)
+
+```php
+$deferred = new React\Promise\Deferred();
+
+$deferred->promise()
+ ->then(function ($x) {
+ throw new \Exception($x + 1);
+ })
+ ->otherwise(function (\Exception $x) {
+ // Propagate the rejection
+ throw $x;
+ })
+ ->otherwise(function (\Exception $x) {
+ // Can also propagate by returning another rejection
+ return React\Promise\reject(
+ new \Exception($x->getMessage() + 1)
+ );
+ })
+ ->otherwise(function ($x) {
+ echo 'Reject ' . $x->getMessage(); // 3
+ });
+
+$deferred->resolve(1); // Prints "Reject 3"
+```
+
+#### Mixed resolution and rejection forwarding
+
+Just like try/catch, you can choose to propagate or not. Mixing resolutions and
+rejections will still forward handler results in a predictable way.
+
+```php
+$deferred = new React\Promise\Deferred();
+
+$deferred->promise()
+ ->then(function ($x) {
+ return $x + 1;
+ })
+ ->then(function ($x) {
+ throw new \Exception($x + 1);
+ })
+ ->otherwise(function (\Exception $x) {
+ // Handle the rejection, and don't propagate.
+ // This is like catch without a rethrow
+ return $x->getMessage() + 1;
+ })
+ ->then(function ($x) {
+ echo 'Mixed ' . $x; // 4
+ });
+
+$deferred->resolve(1); // Prints "Mixed 4"
+```
+
+#### Progress event forwarding
+
+In the same way as resolution and rejection handlers, your progress handler
+**MUST** return a progress event to be propagated to the next link in the chain.
+If you return nothing, `null` will be propagated.
+
+Also in the same way as resolutions and rejections, if you don't register a
+progress handler, the update will be propagated through.
+
+If your progress handler throws an exception, the exception will be propagated
+to the next link in the chain. The best thing to do is to ensure your progress
+handlers do not throw exceptions.
+
+This gives you the opportunity to transform progress events at each step in the
+chain so that they are meaningful to the next step. It also allows you to choose
+not to transform them, and simply let them propagate untransformed, by not
+registering a progress handler.
+
+```php
+$deferred = new React\Promise\Deferred();
+
+$deferred->promise()
+ ->progress(function ($update) {
+ return $update + 1;
+ })
+ ->progress(function ($update) {
+ echo 'Progress ' . $update; // 2
+ });
+
+$deferred->notify(1); // Prints "Progress 2"
+```
+
+### done() vs. then()
+
+The golden rule is:
+
+ Either return your promise, or call done() on it.
+
+At a first glance, `then()` and `done()` seem very similar. However, there are
+important distinctions.
+
+The intent of `then()` is to transform a promise's value and to pass or return
+a new promise for the transformed value along to other parts of your code.
+
+The intent of `done()` is to consume a promise's value, transferring
+responsibility for the value to your code.
+
+In addition to transforming a value, `then()` allows you to recover from, or
+propagate intermediate errors. Any errors that are not handled will be caught
+by the promise machinery and used to reject the promise returned by `then()`.
+
+Calling `done()` transfers all responsibility for errors to your code. If an
+error (either a thrown exception or returned rejection) escapes the
+`$onFulfilled` or `$onRejected` callbacks you provide to done, it will be
+rethrown in an uncatchable way causing a fatal error.
+
+```php
+function getJsonResult()
+{
+ return queryApi()
+ ->then(
+ // Transform API results to an object
+ function ($jsonResultString) {
+ return json_decode($jsonResultString);
+ },
+ // Transform API errors to an exception
+ function ($jsonErrorString) {
+ $object = json_decode($jsonErrorString);
+ throw new ApiErrorException($object->errorMessage);
+ }
+ );
+}
+
+// Here we provide no rejection handler. If the promise returned has been
+// rejected, the ApiErrorException will be thrown
+getJsonResult()
+ ->done(
+ // Consume transformed object
+ function ($jsonResultObject) {
+ // Do something with $jsonResultObject
+ }
+ );
+
+// Here we provide a rejection handler which will either throw while debugging
+// or log the exception
+getJsonResult()
+ ->done(
+ function ($jsonResultObject) {
+ // Do something with $jsonResultObject
+ },
+ function (ApiErrorException $exception) {
+ if (isDebug()) {
+ throw $exception;
+ } else {
+ logException($exception);
+ }
+ }
+ );
+```
+
+Note that if a rejection value is not an instance of `\Exception`, it will be
+wrapped in an exception of the type `React\Promise\UnhandledRejectionException`.
+
+You can get the original rejection reason by calling `$exception->getReason()`.
+
+Credits
+-------
+
+React/Promise is a port of [when.js](https://github.com/cujojs/when)
+by [Brian Cavalier](https://github.com/briancavalier).
+
+Also, large parts of the documentation have been ported from the when.js
+[Wiki](https://github.com/cujojs/when/wiki) and the
+[API docs](https://github.com/cujojs/when/blob/master/docs/api.md).
+
+License
+-------
+
+React/Promise is released under the [MIT](https://github.com/reactphp/promise/blob/master/LICENSE) license.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/composer.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/composer.json
new file mode 100644
index 0000000..2fc4809
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/composer.json
@@ -0,0 +1,29 @@
+{
+ "name": "react/promise",
+ "description": "A lightweight implementation of CommonJS Promises/A for PHP",
+ "license": "MIT",
+ "authors": [
+ {"name": "Jan Sorgalla", "email": "jsorgalla@gmail.com"}
+ ],
+ "require": {
+ "php": ">=5.4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.8"
+ },
+ "autoload": {
+ "psr-4": {
+ "React\\Promise\\": "src/"
+ },
+ "files": ["src/functions_include.php"]
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "React\\Promise\\": "tests/fixtures"
+ }
+ },
+ "keywords": [
+ "promise",
+ "promises"
+ ]
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/phpunit.xml.dist b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/phpunit.xml.dist
new file mode 100644
index 0000000..b9a689d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/phpunit.xml.dist
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit backupGlobals="false"
+ backupStaticAttributes="false"
+ colors="true"
+ convertErrorsToExceptions="true"
+ convertNoticesToExceptions="true"
+ convertWarningsToExceptions="true"
+ processIsolation="false"
+ stopOnFailure="false"
+ syntaxCheck="false"
+ bootstrap="tests/bootstrap.php"
+>
+ <testsuites>
+ <testsuite name="Promise Test Suite">
+ <directory>./tests/</directory>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist>
+ <directory>./src/</directory>
+ <exclude>
+ <file>./src/functions_include.php</file>
+ </exclude>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/CancellablePromiseInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/CancellablePromiseInterface.php
new file mode 100644
index 0000000..896db2d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/CancellablePromiseInterface.php
@@ -0,0 +1,11 @@
+<?php
+
+namespace React\Promise;
+
+interface CancellablePromiseInterface extends PromiseInterface
+{
+ /**
+ * @return void
+ */
+ public function cancel();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/CancellationQueue.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/CancellationQueue.php
new file mode 100644
index 0000000..a366994
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/CancellationQueue.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace React\Promise;
+
+class CancellationQueue
+{
+ private $started = false;
+ private $queue = [];
+
+ public function __invoke()
+ {
+ if ($this->started) {
+ return;
+ }
+
+ $this->started = true;
+ $this->drain();
+ }
+
+ public function enqueue($cancellable)
+ {
+ if (!method_exists($cancellable, 'then') || !method_exists($cancellable, 'cancel')) {
+ return;
+ }
+
+ $length = array_push($this->queue, $cancellable);
+
+ if ($this->started && 1 === $length) {
+ $this->drain();
+ }
+ }
+
+ private function drain()
+ {
+ for ($i = key($this->queue); isset($this->queue[$i]); $i++) {
+ $cancellable = $this->queue[$i];
+
+ $exception = null;
+
+ try {
+ $cancellable->cancel();
+ } catch (\Throwable $exception) {
+ } catch (\Exception $exception) {
+ }
+
+ unset($this->queue[$i]);
+
+ if ($exception) {
+ throw $exception;
+ }
+ }
+
+ $this->queue = [];
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/Deferred.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/Deferred.php
new file mode 100644
index 0000000..f23980c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/Deferred.php
@@ -0,0 +1,60 @@
+<?php
+
+namespace React\Promise;
+
+class Deferred implements PromisorInterface
+{
+ private $promise;
+ private $resolveCallback;
+ private $rejectCallback;
+ private $notifyCallback;
+ private $canceller;
+
+ public function __construct(callable $canceller = null)
+ {
+ $this->canceller = $canceller;
+ }
+
+ public function promise()
+ {
+ if (null === $this->promise) {
+ $this->promise = new Promise(function ($resolve, $reject, $notify) {
+ $this->resolveCallback = $resolve;
+ $this->rejectCallback = $reject;
+ $this->notifyCallback = $notify;
+ }, $this->canceller);
+ }
+
+ return $this->promise;
+ }
+
+ public function resolve($value = null)
+ {
+ $this->promise();
+
+ call_user_func($this->resolveCallback, $value);
+ }
+
+ public function reject($reason = null)
+ {
+ $this->promise();
+
+ call_user_func($this->rejectCallback, $reason);
+ }
+
+ public function notify($update = null)
+ {
+ $this->promise();
+
+ call_user_func($this->notifyCallback, $update);
+ }
+
+ /**
+ * @deprecated 2.2.0
+ * @see Deferred::notify()
+ */
+ public function progress($update = null)
+ {
+ $this->notify($update);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/Exception/LengthException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/Exception/LengthException.php
new file mode 100644
index 0000000..775c48d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/Exception/LengthException.php
@@ -0,0 +1,7 @@
+<?php
+
+namespace React\Promise\Exception;
+
+class LengthException extends \LengthException
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/ExtendedPromiseInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/ExtendedPromiseInterface.php
new file mode 100644
index 0000000..9cb6435
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/ExtendedPromiseInterface.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace React\Promise;
+
+interface ExtendedPromiseInterface extends PromiseInterface
+{
+ /**
+ * @return void
+ */
+ public function done(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null);
+
+ /**
+ * @return ExtendedPromiseInterface
+ */
+ public function otherwise(callable $onRejected);
+
+ /**
+ * @return ExtendedPromiseInterface
+ */
+ public function always(callable $onFulfilledOrRejected);
+
+ /**
+ * @return ExtendedPromiseInterface
+ */
+ public function progress(callable $onProgress);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/FulfilledPromise.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/FulfilledPromise.php
new file mode 100644
index 0000000..914bb5c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/FulfilledPromise.php
@@ -0,0 +1,68 @@
+<?php
+
+namespace React\Promise;
+
+class FulfilledPromise implements ExtendedPromiseInterface, CancellablePromiseInterface
+{
+ private $value;
+
+ public function __construct($value = null)
+ {
+ if ($value instanceof PromiseInterface) {
+ throw new \InvalidArgumentException('You cannot create React\Promise\FulfilledPromise with a promise. Use React\Promise\resolve($promiseOrValue) instead.');
+ }
+
+ $this->value = $value;
+ }
+
+ public function then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null)
+ {
+ if (null === $onFulfilled) {
+ return $this;
+ }
+
+ try {
+ return resolve($onFulfilled($this->value));
+ } catch (\Throwable $exception) {
+ return new RejectedPromise($exception);
+ } catch (\Exception $exception) {
+ return new RejectedPromise($exception);
+ }
+ }
+
+ public function done(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null)
+ {
+ if (null === $onFulfilled) {
+ return;
+ }
+
+ $result = $onFulfilled($this->value);
+
+ if ($result instanceof ExtendedPromiseInterface) {
+ $result->done();
+ }
+ }
+
+ public function otherwise(callable $onRejected)
+ {
+ return $this;
+ }
+
+ public function always(callable $onFulfilledOrRejected)
+ {
+ return $this->then(function ($value) use ($onFulfilledOrRejected) {
+ return resolve($onFulfilledOrRejected())->then(function () use ($value) {
+ return $value;
+ });
+ });
+ }
+
+ public function progress(callable $onProgress)
+ {
+ return $this;
+ }
+
+ public function cancel()
+ {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/LazyPromise.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/LazyPromise.php
new file mode 100644
index 0000000..7e3a3d3
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/LazyPromise.php
@@ -0,0 +1,63 @@
+<?php
+
+namespace React\Promise;
+
+class LazyPromise implements ExtendedPromiseInterface, CancellablePromiseInterface
+{
+ private $factory;
+ private $promise;
+
+ public function __construct(callable $factory)
+ {
+ $this->factory = $factory;
+ }
+
+ public function then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null)
+ {
+ return $this->promise()->then($onFulfilled, $onRejected, $onProgress);
+ }
+
+ public function done(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null)
+ {
+ return $this->promise()->done($onFulfilled, $onRejected, $onProgress);
+ }
+
+ public function otherwise(callable $onRejected)
+ {
+ return $this->promise()->otherwise($onRejected);
+ }
+
+ public function always(callable $onFulfilledOrRejected)
+ {
+ return $this->promise()->always($onFulfilledOrRejected);
+ }
+
+ public function progress(callable $onProgress)
+ {
+ return $this->promise()->progress($onProgress);
+ }
+
+ public function cancel()
+ {
+ return $this->promise()->cancel();
+ }
+
+ /**
+ * @internal
+ * @see Promise::settle()
+ */
+ public function promise()
+ {
+ if (null === $this->promise) {
+ try {
+ $this->promise = resolve(call_user_func($this->factory));
+ } catch (\Throwable $exception) {
+ $this->promise = new RejectedPromise($exception);
+ } catch (\Exception $exception) {
+ $this->promise = new RejectedPromise($exception);
+ }
+ }
+
+ return $this->promise;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/Promise.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/Promise.php
new file mode 100644
index 0000000..0261eb3
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/Promise.php
@@ -0,0 +1,216 @@
+<?php
+
+namespace React\Promise;
+
+class Promise implements ExtendedPromiseInterface, CancellablePromiseInterface
+{
+ private $canceller;
+ private $result;
+
+ private $handlers = [];
+ private $progressHandlers = [];
+
+ private $requiredCancelRequests = 0;
+ private $cancelRequests = 0;
+
+ public function __construct(callable $resolver, callable $canceller = null)
+ {
+ $this->canceller = $canceller;
+ $this->call($resolver);
+ }
+
+ public function then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null)
+ {
+ if (null !== $this->result) {
+ return $this->result->then($onFulfilled, $onRejected, $onProgress);
+ }
+
+ if (null === $this->canceller) {
+ return new static($this->resolver($onFulfilled, $onRejected, $onProgress));
+ }
+
+ $this->requiredCancelRequests++;
+
+ return new static($this->resolver($onFulfilled, $onRejected, $onProgress), function () {
+ if (++$this->cancelRequests < $this->requiredCancelRequests) {
+ return;
+ }
+
+ $this->cancel();
+ });
+ }
+
+ public function done(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null)
+ {
+ if (null !== $this->result) {
+ return $this->result->done($onFulfilled, $onRejected, $onProgress);
+ }
+
+ $this->handlers[] = function (ExtendedPromiseInterface $promise) use ($onFulfilled, $onRejected) {
+ $promise
+ ->done($onFulfilled, $onRejected);
+ };
+
+ if ($onProgress) {
+ $this->progressHandlers[] = $onProgress;
+ }
+ }
+
+ public function otherwise(callable $onRejected)
+ {
+ return $this->then(null, function ($reason) use ($onRejected) {
+ if (!_checkTypehint($onRejected, $reason)) {
+ return new RejectedPromise($reason);
+ }
+
+ return $onRejected($reason);
+ });
+ }
+
+ public function always(callable $onFulfilledOrRejected)
+ {
+ return $this->then(function ($value) use ($onFulfilledOrRejected) {
+ return resolve($onFulfilledOrRejected())->then(function () use ($value) {
+ return $value;
+ });
+ }, function ($reason) use ($onFulfilledOrRejected) {
+ return resolve($onFulfilledOrRejected())->then(function () use ($reason) {
+ return new RejectedPromise($reason);
+ });
+ });
+ }
+
+ public function progress(callable $onProgress)
+ {
+ return $this->then(null, null, $onProgress);
+ }
+
+ public function cancel()
+ {
+ if (null === $this->canceller || null !== $this->result) {
+ return;
+ }
+
+ $canceller = $this->canceller;
+ $this->canceller = null;
+
+ $this->call($canceller);
+ }
+
+ private function resolver(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null)
+ {
+ return function ($resolve, $reject, $notify) use ($onFulfilled, $onRejected, $onProgress) {
+ if ($onProgress) {
+ $progressHandler = function ($update) use ($notify, $onProgress) {
+ try {
+ $notify($onProgress($update));
+ } catch (\Throwable $e) {
+ $notify($e);
+ } catch (\Exception $e) {
+ $notify($e);
+ }
+ };
+ } else {
+ $progressHandler = $notify;
+ }
+
+ $this->handlers[] = function (ExtendedPromiseInterface $promise) use ($onFulfilled, $onRejected, $resolve, $reject, $progressHandler) {
+ $promise
+ ->then($onFulfilled, $onRejected)
+ ->done($resolve, $reject, $progressHandler);
+ };
+
+ $this->progressHandlers[] = $progressHandler;
+ };
+ }
+
+ private function resolve($value = null)
+ {
+ if (null !== $this->result) {
+ return;
+ }
+
+ $this->settle(resolve($value));
+ }
+
+ private function reject($reason = null)
+ {
+ if (null !== $this->result) {
+ return;
+ }
+
+ $this->settle(reject($reason));
+ }
+
+ private function notify($update = null)
+ {
+ if (null !== $this->result) {
+ return;
+ }
+
+ foreach ($this->progressHandlers as $handler) {
+ $handler($update);
+ }
+ }
+
+ private function settle(ExtendedPromiseInterface $promise)
+ {
+ $promise = $this->unwrap($promise);
+
+ $handlers = $this->handlers;
+
+ $this->progressHandlers = $this->handlers = [];
+ $this->result = $promise;
+
+ foreach ($handlers as $handler) {
+ $handler($promise);
+ }
+ }
+
+ private function unwrap($promise)
+ {
+ $promise = $this->extract($promise);
+
+ while ($promise instanceof self && null !== $promise->result) {
+ $promise = $this->extract($promise->result);
+ }
+
+ return $promise;
+ }
+
+ private function extract($promise)
+ {
+ if ($promise instanceof LazyPromise) {
+ $promise = $promise->promise();
+ }
+
+ if ($promise === $this) {
+ return new RejectedPromise(
+ new \LogicException('Cannot resolve a promise with itself.')
+ );
+ }
+
+ return $promise;
+ }
+
+ private function call(callable $callback)
+ {
+ try {
+ $callback(
+ function ($value = null) {
+ $this->resolve($value);
+ },
+ function ($reason = null) {
+ $this->reject($reason);
+ },
+ function ($update = null) {
+ $this->notify($update);
+ }
+ );
+ } catch (\Throwable $e) {
+ $this->reject($e);
+ } catch (\Exception $e) {
+ $this->reject($e);
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/PromiseInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/PromiseInterface.php
new file mode 100644
index 0000000..d80d114
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/PromiseInterface.php
@@ -0,0 +1,11 @@
+<?php
+
+namespace React\Promise;
+
+interface PromiseInterface
+{
+ /**
+ * @return PromiseInterface
+ */
+ public function then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/PromisorInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/PromisorInterface.php
new file mode 100644
index 0000000..9341a4f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/PromisorInterface.php
@@ -0,0 +1,11 @@
+<?php
+
+namespace React\Promise;
+
+interface PromisorInterface
+{
+ /**
+ * @return PromiseInterface
+ */
+ public function promise();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/RejectedPromise.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/RejectedPromise.php
new file mode 100644
index 0000000..479a746
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/RejectedPromise.php
@@ -0,0 +1,76 @@
+<?php
+
+namespace React\Promise;
+
+class RejectedPromise implements ExtendedPromiseInterface, CancellablePromiseInterface
+{
+ private $reason;
+
+ public function __construct($reason = null)
+ {
+ if ($reason instanceof PromiseInterface) {
+ throw new \InvalidArgumentException('You cannot create React\Promise\RejectedPromise with a promise. Use React\Promise\reject($promiseOrValue) instead.');
+ }
+
+ $this->reason = $reason;
+ }
+
+ public function then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null)
+ {
+ if (null === $onRejected) {
+ return $this;
+ }
+
+ try {
+ return resolve($onRejected($this->reason));
+ } catch (\Throwable $exception) {
+ return new RejectedPromise($exception);
+ } catch (\Exception $exception) {
+ return new RejectedPromise($exception);
+ }
+ }
+
+ public function done(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null)
+ {
+ if (null === $onRejected) {
+ throw UnhandledRejectionException::resolve($this->reason);
+ }
+
+ $result = $onRejected($this->reason);
+
+ if ($result instanceof self) {
+ throw UnhandledRejectionException::resolve($result->reason);
+ }
+
+ if ($result instanceof ExtendedPromiseInterface) {
+ $result->done();
+ }
+ }
+
+ public function otherwise(callable $onRejected)
+ {
+ if (!_checkTypehint($onRejected, $this->reason)) {
+ return $this;
+ }
+
+ return $this->then(null, $onRejected);
+ }
+
+ public function always(callable $onFulfilledOrRejected)
+ {
+ return $this->then(null, function ($reason) use ($onFulfilledOrRejected) {
+ return resolve($onFulfilledOrRejected())->then(function () use ($reason) {
+ return new RejectedPromise($reason);
+ });
+ });
+ }
+
+ public function progress(callable $onProgress)
+ {
+ return $this;
+ }
+
+ public function cancel()
+ {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/UnhandledRejectionException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/UnhandledRejectionException.php
new file mode 100644
index 0000000..a44b7a1
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/UnhandledRejectionException.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace React\Promise;
+
+class UnhandledRejectionException extends \RuntimeException
+{
+ private $reason;
+
+ public static function resolve($reason)
+ {
+ if ($reason instanceof \Exception || $reason instanceof \Throwable) {
+ return $reason;
+ }
+
+ return new static($reason);
+ }
+
+ public function __construct($reason)
+ {
+ $this->reason = $reason;
+
+ $message = sprintf('Unhandled Rejection: %s', json_encode($reason));
+
+ parent::__construct($message, 0);
+ }
+
+ public function getReason()
+ {
+ return $this->reason;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/functions.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/functions.php
new file mode 100644
index 0000000..70c0eb7
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/functions.php
@@ -0,0 +1,244 @@
+<?php
+
+namespace React\Promise;
+
+function resolve($promiseOrValue = null)
+{
+ if ($promiseOrValue instanceof ExtendedPromiseInterface) {
+ return $promiseOrValue;
+ }
+
+ if (method_exists($promiseOrValue, 'then')) {
+ $canceller = null;
+
+ if (method_exists($promiseOrValue, 'cancel')) {
+ $canceller = [$promiseOrValue, 'cancel'];
+ }
+
+ return new Promise(function ($resolve, $reject, $notify) use ($promiseOrValue) {
+ $promiseOrValue->then($resolve, $reject, $notify);
+ }, $canceller);
+ }
+
+ return new FulfilledPromise($promiseOrValue);
+}
+
+function reject($promiseOrValue = null)
+{
+ if ($promiseOrValue instanceof PromiseInterface) {
+ return resolve($promiseOrValue)->then(function ($value) {
+ return new RejectedPromise($value);
+ });
+ }
+
+ return new RejectedPromise($promiseOrValue);
+}
+
+function all($promisesOrValues)
+{
+ return map($promisesOrValues, function ($val) {
+ return $val;
+ });
+}
+
+function race($promisesOrValues)
+{
+ $cancellationQueue = new CancellationQueue();
+ $cancellationQueue->enqueue($promisesOrValues);
+
+ return new Promise(function ($resolve, $reject, $notify) use ($promisesOrValues, $cancellationQueue) {
+ resolve($promisesOrValues)
+ ->done(function ($array) use ($cancellationQueue, $resolve, $reject, $notify) {
+ if (!is_array($array) || !$array) {
+ $resolve();
+ return;
+ }
+
+ foreach ($array as $promiseOrValue) {
+ $cancellationQueue->enqueue($promiseOrValue);
+
+ resolve($promiseOrValue)
+ ->done($resolve, $reject, $notify);
+ }
+ }, $reject, $notify);
+ }, $cancellationQueue);
+}
+
+function any($promisesOrValues)
+{
+ return some($promisesOrValues, 1)
+ ->then(function ($val) {
+ return array_shift($val);
+ });
+}
+
+function some($promisesOrValues, $howMany)
+{
+ $cancellationQueue = new CancellationQueue();
+ $cancellationQueue->enqueue($promisesOrValues);
+
+ return new Promise(function ($resolve, $reject, $notify) use ($promisesOrValues, $howMany, $cancellationQueue) {
+ resolve($promisesOrValues)
+ ->done(function ($array) use ($howMany, $cancellationQueue, $resolve, $reject, $notify) {
+ if (!is_array($array) || $howMany < 1) {
+ $resolve([]);
+ return;
+ }
+
+ $len = count($array);
+
+ if ($len < $howMany) {
+ throw new Exception\LengthException(
+ sprintf(
+ 'Input array must contain at least %d item%s but contains only %s item%s.',
+ $howMany,
+ 1 === $howMany ? '' : 's',
+ $len,
+ 1 === $len ? '' : 's'
+ )
+ );
+ }
+
+ $toResolve = $howMany;
+ $toReject = ($len - $toResolve) + 1;
+ $values = [];
+ $reasons = [];
+
+ foreach ($array as $i => $promiseOrValue) {
+ $fulfiller = function ($val) use ($i, &$values, &$toResolve, $toReject, $resolve) {
+ if ($toResolve < 1 || $toReject < 1) {
+ return;
+ }
+
+ $values[$i] = $val;
+
+ if (0 === --$toResolve) {
+ $resolve($values);
+ }
+ };
+
+ $rejecter = function ($reason) use ($i, &$reasons, &$toReject, $toResolve, $reject) {
+ if ($toResolve < 1 || $toReject < 1) {
+ return;
+ }
+
+ $reasons[$i] = $reason;
+
+ if (0 === --$toReject) {
+ $reject($reasons);
+ }
+ };
+
+ $cancellationQueue->enqueue($promiseOrValue);
+
+ resolve($promiseOrValue)
+ ->done($fulfiller, $rejecter, $notify);
+ }
+ }, $reject, $notify);
+ }, $cancellationQueue);
+}
+
+function map($promisesOrValues, callable $mapFunc)
+{
+ $cancellationQueue = new CancellationQueue();
+ $cancellationQueue->enqueue($promisesOrValues);
+
+ return new Promise(function ($resolve, $reject, $notify) use ($promisesOrValues, $mapFunc, $cancellationQueue) {
+ resolve($promisesOrValues)
+ ->done(function ($array) use ($mapFunc, $cancellationQueue, $resolve, $reject, $notify) {
+ if (!is_array($array) || !$array) {
+ $resolve([]);
+ return;
+ }
+
+ $toResolve = count($array);
+ $values = [];
+
+ foreach ($array as $i => $promiseOrValue) {
+ $cancellationQueue->enqueue($promiseOrValue);
+ $values[$i] = null;
+
+ resolve($promiseOrValue)
+ ->then($mapFunc)
+ ->done(
+ function ($mapped) use ($i, &$values, &$toResolve, $resolve) {
+ $values[$i] = $mapped;
+
+ if (0 === --$toResolve) {
+ $resolve($values);
+ }
+ },
+ $reject,
+ $notify
+ );
+ }
+ }, $reject, $notify);
+ }, $cancellationQueue);
+}
+
+function reduce($promisesOrValues, callable $reduceFunc, $initialValue = null)
+{
+ $cancellationQueue = new CancellationQueue();
+ $cancellationQueue->enqueue($promisesOrValues);
+
+ return new Promise(function ($resolve, $reject, $notify) use ($promisesOrValues, $reduceFunc, $initialValue, $cancellationQueue) {
+ resolve($promisesOrValues)
+ ->done(function ($array) use ($reduceFunc, $initialValue, $cancellationQueue, $resolve, $reject, $notify) {
+ if (!is_array($array)) {
+ $array = [];
+ }
+
+ $total = count($array);
+ $i = 0;
+
+ // Wrap the supplied $reduceFunc with one that handles promises and then
+ // delegates to the supplied.
+ $wrappedReduceFunc = function ($current, $val) use ($reduceFunc, $cancellationQueue, $total, &$i) {
+ $cancellationQueue->enqueue($val);
+
+ return $current
+ ->then(function ($c) use ($reduceFunc, $total, &$i, $val) {
+ return resolve($val)
+ ->then(function ($value) use ($reduceFunc, $total, &$i, $c) {
+ return $reduceFunc($c, $value, $i++, $total);
+ });
+ });
+ };
+
+ $cancellationQueue->enqueue($initialValue);
+
+ array_reduce($array, $wrappedReduceFunc, resolve($initialValue))
+ ->done($resolve, $reject, $notify);
+ }, $reject, $notify);
+ }, $cancellationQueue);
+}
+
+// Internal functions
+function _checkTypehint(callable $callback, $object)
+{
+ if (!is_object($object)) {
+ return true;
+ }
+
+ if (is_array($callback)) {
+ $callbackReflection = new \ReflectionMethod($callback[0], $callback[1]);
+ } elseif (is_object($callback) && !$callback instanceof \Closure) {
+ $callbackReflection = new \ReflectionMethod($callback, '__invoke');
+ } else {
+ $callbackReflection = new \ReflectionFunction($callback);
+ }
+
+ $parameters = $callbackReflection->getParameters();
+
+ if (!isset($parameters[0])) {
+ return true;
+ }
+
+ $expectedException = $parameters[0];
+
+ if (!$expectedException->getClass()) {
+ return true;
+ }
+
+ return $expectedException->getClass()->isInstance($object);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/functions_include.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/functions_include.php
new file mode 100644
index 0000000..c71decb
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/src/functions_include.php
@@ -0,0 +1,5 @@
+<?php
+
+if (!function_exists('React\Promise\resolve')) {
+ require __DIR__.'/functions.php';
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/CancellationQueueTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/CancellationQueueTest.php
new file mode 100644
index 0000000..32cedf4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/CancellationQueueTest.php
@@ -0,0 +1,100 @@
+<?php
+
+namespace React\Promise;
+
+class CancellationQueueTest extends TestCase
+{
+ /** @test */
+ public function acceptsSimpleCancellableThenable()
+ {
+ $p = new SimpleTestCancellableThenable();
+
+ $cancellationQueue = new CancellationQueue();
+ $cancellationQueue->enqueue($p);
+
+ $cancellationQueue();
+
+ $this->assertTrue($p->cancelCalled);
+ }
+
+ /** @test */
+ public function ignoresSimpleCancellable()
+ {
+ $p = new SimpleTestCancellable();
+
+ $cancellationQueue = new CancellationQueue();
+ $cancellationQueue->enqueue($p);
+
+ $cancellationQueue();
+
+ $this->assertFalse($p->cancelCalled);
+ }
+
+ /** @test */
+ public function callsCancelOnPromisesEnqueuedBeforeStart()
+ {
+ $d1 = $this->getCancellableDeferred();
+ $d2 = $this->getCancellableDeferred();
+
+ $cancellationQueue = new CancellationQueue();
+ $cancellationQueue->enqueue($d1->promise());
+ $cancellationQueue->enqueue($d2->promise());
+
+ $cancellationQueue();
+ }
+
+ /** @test */
+ public function callsCancelOnPromisesEnqueuedAfterStart()
+ {
+ $d1 = $this->getCancellableDeferred();
+ $d2 = $this->getCancellableDeferred();
+
+ $cancellationQueue = new CancellationQueue();
+
+ $cancellationQueue();
+
+ $cancellationQueue->enqueue($d2->promise());
+ $cancellationQueue->enqueue($d1->promise());
+ }
+
+ /** @test */
+ public function doesNotCallCancelTwiceWhenStartedTwice()
+ {
+ $d = $this->getCancellableDeferred();
+
+ $cancellationQueue = new CancellationQueue();
+ $cancellationQueue->enqueue($d->promise());
+
+ $cancellationQueue();
+ $cancellationQueue();
+ }
+
+ /** @test */
+ public function rethrowsExceptionsThrownFromCancel()
+ {
+ $this->setExpectedException('\Exception', 'test');
+
+ $mock = $this
+ ->getMockBuilder('React\Promise\CancellablePromiseInterface')
+ ->getMock();
+ $mock
+ ->expects($this->once())
+ ->method('cancel')
+ ->will($this->throwException(new \Exception('test')));
+
+ $cancellationQueue = new CancellationQueue();
+ $cancellationQueue->enqueue($mock);
+
+ $cancellationQueue();
+ }
+
+ private function getCancellableDeferred()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke');
+
+ return new Deferred($mock);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/DeferredTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/DeferredTest.php
new file mode 100644
index 0000000..16212e9
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/DeferredTest.php
@@ -0,0 +1,42 @@
+<?php
+
+namespace React\Promise;
+
+use React\Promise\PromiseAdapter\CallbackPromiseAdapter;
+
+class DeferredTest extends TestCase
+{
+ use PromiseTest\FullTestTrait;
+
+ public function getPromiseTestAdapter(callable $canceller = null)
+ {
+ $d = new Deferred($canceller);
+
+ return new CallbackPromiseAdapter([
+ 'promise' => [$d, 'promise'],
+ 'resolve' => [$d, 'resolve'],
+ 'reject' => [$d, 'reject'],
+ 'notify' => [$d, 'progress'],
+ 'settle' => [$d, 'resolve'],
+ ]);
+ }
+
+ /** @test */
+ public function progressIsAnAliasForNotify()
+ {
+ $deferred = new Deferred();
+
+ $sentinel = new \stdClass();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($sentinel);
+
+ $deferred->promise()
+ ->then($this->expectCallableNever(), $this->expectCallableNever(), $mock);
+
+ $deferred->progress($sentinel);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FulfilledPromiseTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FulfilledPromiseTest.php
new file mode 100644
index 0000000..97fc8f6
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FulfilledPromiseTest.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace React\Promise;
+
+use React\Promise\PromiseAdapter\CallbackPromiseAdapter;
+
+class FulfilledPromiseTest extends TestCase
+{
+ use PromiseTest\PromiseSettledTestTrait,
+ PromiseTest\PromiseFulfilledTestTrait;
+
+ public function getPromiseTestAdapter(callable $canceller = null)
+ {
+ $promise = null;
+
+ return new CallbackPromiseAdapter([
+ 'promise' => function () use (&$promise) {
+ if (!$promise) {
+ throw new \LogicException('FulfilledPromise must be resolved before obtaining the promise');
+ }
+
+ return $promise;
+ },
+ 'resolve' => function ($value = null) use (&$promise) {
+ if (!$promise) {
+ $promise = new FulfilledPromise($value);
+ }
+ },
+ 'reject' => function () {
+ throw new \LogicException('You cannot call reject() for React\Promise\FulfilledPromise');
+ },
+ 'notify' => function () {
+ // no-op
+ },
+ 'settle' => function ($value = null) use (&$promise) {
+ if (!$promise) {
+ $promise = new FulfilledPromise($value);
+ }
+ },
+ ]);
+ }
+
+ /** @test */
+ public function shouldThrowExceptionIfConstructedWithAPromise()
+ {
+ $this->setExpectedException('\InvalidArgumentException');
+
+ return new FulfilledPromise(new FulfilledPromise());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionAllTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionAllTest.php
new file mode 100644
index 0000000..74c1d7c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionAllTest.php
@@ -0,0 +1,114 @@
+<?php
+
+namespace React\Promise;
+
+class FunctionAllTest extends TestCase
+{
+ /** @test */
+ public function shouldResolveEmptyInput()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo([]));
+
+ all([])
+ ->then($mock);
+ }
+
+ /** @test */
+ public function shouldResolveValuesArray()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo([1, 2, 3]));
+
+ all([1, 2, 3])
+ ->then($mock);
+ }
+
+ /** @test */
+ public function shouldResolvePromisesArray()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo([1, 2, 3]));
+
+ all([resolve(1), resolve(2), resolve(3)])
+ ->then($mock);
+ }
+
+ /** @test */
+ public function shouldResolveSparseArrayInput()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo([null, 1, null, 1, 1]));
+
+ all([null, 1, null, 1, 1])
+ ->then($mock);
+ }
+
+ /** @test */
+ public function shouldRejectIfAnyInputPromiseRejects()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(2));
+
+ all([resolve(1), reject(2), resolve(3)])
+ ->then($this->expectCallableNever(), $mock);
+ }
+
+ /** @test */
+ public function shouldAcceptAPromiseForAnArray()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo([1, 2, 3]));
+
+ all(resolve([1, 2, 3]))
+ ->then($mock);
+ }
+
+ /** @test */
+ public function shouldResolveToEmptyArrayWhenInputPromiseDoesNotResolveToArray()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo([]));
+
+ all(resolve(1))
+ ->then($mock);
+ }
+
+ /** @test */
+ public function shouldPreserveTheOrderOfArrayWhenResolvingAsyncPromises()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo([1, 2, 3]));
+
+ $deferred = new Deferred();
+
+ all([resolve(1), $deferred->promise(), resolve(3)])
+ ->then($mock);
+
+ $deferred->resolve(2);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionAnyTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionAnyTest.php
new file mode 100644
index 0000000..140b551
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionAnyTest.php
@@ -0,0 +1,204 @@
+<?php
+
+namespace React\Promise;
+
+use React\Promise\Exception\LengthException;
+
+class FunctionAnyTest extends TestCase
+{
+ /** @test */
+ public function shouldRejectWithLengthExceptionWithEmptyInputArray()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with(
+ $this->callback(function($exception){
+ return $exception instanceof LengthException &&
+ 'Input array must contain at least 1 item but contains only 0 items.' === $exception->getMessage();
+ })
+ );
+
+ any([])
+ ->then($this->expectCallableNever(), $mock);
+ }
+
+ /** @test */
+ public function shouldResolveToNullWithNonArrayInput()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(null));
+
+ any(null)
+ ->then($mock);
+ }
+
+ /** @test */
+ public function shouldResolveWithAnInputValue()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ any([1, 2, 3])
+ ->then($mock);
+ }
+
+ /** @test */
+ public function shouldResolveWithAPromisedInputValue()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ any([resolve(1), resolve(2), resolve(3)])
+ ->then($mock);
+ }
+
+ /** @test */
+ public function shouldRejectWithAllRejectedInputValuesIfAllInputsAreRejected()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo([0 => 1, 1 => 2, 2 => 3]));
+
+ any([reject(1), reject(2), reject(3)])
+ ->then($this->expectCallableNever(), $mock);
+ }
+
+ /** @test */
+ public function shouldResolveWhenFirstInputPromiseResolves()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ any([resolve(1), reject(2), reject(3)])
+ ->then($mock);
+ }
+
+ /** @test */
+ public function shouldAcceptAPromiseForAnArray()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ any(resolve([1, 2, 3]))
+ ->then($mock);
+ }
+
+ /** @test */
+ public function shouldResolveToNullArrayWhenInputPromiseDoesNotResolveToArray()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(null));
+
+ any(resolve(1))
+ ->then($mock);
+ }
+
+ /** @test */
+ public function shouldNotRelyOnArryIndexesWhenUnwrappingToASingleResolutionValue()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(2));
+
+ $d1 = new Deferred();
+ $d2 = new Deferred();
+
+ any(['abc' => $d1->promise(), 1 => $d2->promise()])
+ ->then($mock);
+
+ $d2->resolve(2);
+ $d1->resolve(1);
+ }
+
+ /** @test */
+ public function shouldRejectWhenInputPromiseRejects()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(null));
+
+ any(reject())
+ ->then($this->expectCallableNever(), $mock);
+ }
+
+ /** @test */
+ public function shouldCancelInputPromise()
+ {
+ $mock = $this
+ ->getMockBuilder('React\Promise\CancellablePromiseInterface')
+ ->getMock();
+ $mock
+ ->expects($this->once())
+ ->method('cancel');
+
+ any($mock)->cancel();
+ }
+
+ /** @test */
+ public function shouldCancelInputArrayPromises()
+ {
+ $mock1 = $this
+ ->getMockBuilder('React\Promise\CancellablePromiseInterface')
+ ->getMock();
+ $mock1
+ ->expects($this->once())
+ ->method('cancel');
+
+ $mock2 = $this
+ ->getMockBuilder('React\Promise\CancellablePromiseInterface')
+ ->getMock();
+ $mock2
+ ->expects($this->once())
+ ->method('cancel');
+
+ any([$mock1, $mock2])->cancel();
+ }
+
+ /** @test */
+ public function shouldNotCancelOtherPendingInputArrayPromisesIfOnePromiseFulfills()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->never())
+ ->method('__invoke');
+
+
+ $deferred = New Deferred($mock);
+ $deferred->resolve();
+
+ $mock2 = $this
+ ->getMockBuilder('React\Promise\CancellablePromiseInterface')
+ ->getMock();
+ $mock2
+ ->expects($this->never())
+ ->method('cancel');
+
+ some([$deferred->promise(), $mock2], 1)->cancel();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionCheckTypehintTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionCheckTypehintTest.php
new file mode 100644
index 0000000..8449bc1
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionCheckTypehintTest.php
@@ -0,0 +1,118 @@
+<?php
+
+namespace React\Promise;
+
+class FunctionCheckTypehintTest extends TestCase
+{
+ /** @test */
+ public function shouldAcceptClosureCallbackWithTypehint()
+ {
+ $this->assertTrue(_checkTypehint(function (\InvalidArgumentException $e) {
+ }, new \InvalidArgumentException()));
+ $this->assertfalse(_checkTypehint(function (\InvalidArgumentException $e) {
+ }, new \Exception()));
+ }
+
+ /** @test */
+ public function shouldAcceptFunctionStringCallbackWithTypehint()
+ {
+ $this->assertTrue(_checkTypehint('React\Promise\testCallbackWithTypehint', new \InvalidArgumentException()));
+ $this->assertfalse(_checkTypehint('React\Promise\testCallbackWithTypehint', new \Exception()));
+ }
+
+ /** @test */
+ public function shouldAcceptInvokableObjectCallbackWithTypehint()
+ {
+ $this->assertTrue(_checkTypehint(new TestCallbackWithTypehintClass(), new \InvalidArgumentException()));
+ $this->assertfalse(_checkTypehint(new TestCallbackWithTypehintClass(), new \Exception()));
+ }
+
+ /** @test */
+ public function shouldAcceptObjectMethodCallbackWithTypehint()
+ {
+ $this->assertTrue(_checkTypehint([new TestCallbackWithTypehintClass(), 'testCallback'], new \InvalidArgumentException()));
+ $this->assertfalse(_checkTypehint([new TestCallbackWithTypehintClass(), 'testCallback'], new \Exception()));
+ }
+
+ /** @test */
+ public function shouldAcceptStaticClassCallbackWithTypehint()
+ {
+ $this->assertTrue(_checkTypehint(['React\Promise\TestCallbackWithTypehintClass', 'testCallbackStatic'], new \InvalidArgumentException()));
+ $this->assertfalse(_checkTypehint(['React\Promise\TestCallbackWithTypehintClass', 'testCallbackStatic'], new \Exception()));
+ }
+
+ /** @test */
+ public function shouldAcceptClosureCallbackWithoutTypehint()
+ {
+ $this->assertTrue(_checkTypehint(function (\InvalidArgumentException $e) {
+ }, new \InvalidArgumentException()));
+ }
+
+ /** @test */
+ public function shouldAcceptFunctionStringCallbackWithoutTypehint()
+ {
+ $this->assertTrue(_checkTypehint('React\Promise\testCallbackWithoutTypehint', new \InvalidArgumentException()));
+ }
+
+ /** @test */
+ public function shouldAcceptInvokableObjectCallbackWithoutTypehint()
+ {
+ $this->assertTrue(_checkTypehint(new TestCallbackWithoutTypehintClass(), new \InvalidArgumentException()));
+ }
+
+ /** @test */
+ public function shouldAcceptObjectMethodCallbackWithoutTypehint()
+ {
+ $this->assertTrue(_checkTypehint([new TestCallbackWithoutTypehintClass(), 'testCallback'], new \InvalidArgumentException()));
+ }
+
+ /** @test */
+ public function shouldAcceptStaticClassCallbackWithoutTypehint()
+ {
+ $this->assertTrue(_checkTypehint(['React\Promise\TestCallbackWithoutTypehintClass', 'testCallbackStatic'], new \InvalidArgumentException()));
+ }
+}
+
+function testCallbackWithTypehint(\InvalidArgumentException $e)
+{
+}
+
+function testCallbackWithoutTypehint()
+{
+}
+
+class TestCallbackWithTypehintClass
+{
+ public function __invoke(\InvalidArgumentException $e)
+ {
+
+ }
+
+ public function testCallback(\InvalidArgumentException $e)
+ {
+
+ }
+
+ public static function testCallbackStatic(\InvalidArgumentException $e)
+ {
+
+ }
+}
+
+class TestCallbackWithoutTypehintClass
+{
+ public function __invoke()
+ {
+
+ }
+
+ public function testCallback()
+ {
+
+ }
+
+ public static function testCallbackStatic()
+ {
+
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionMapTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionMapTest.php
new file mode 100644
index 0000000..1ea560a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionMapTest.php
@@ -0,0 +1,198 @@
+<?php
+
+namespace React\Promise;
+
+class FunctionMapTest extends TestCase
+{
+ protected function mapper()
+ {
+ return function ($val) {
+ return $val * 2;
+ };
+ }
+
+ protected function promiseMapper()
+ {
+ return function ($val) {
+ return resolve($val * 2);
+ };
+ }
+
+ /** @test */
+ public function shouldMapInputValuesArray()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo([2, 4, 6]));
+
+ map(
+ [1, 2, 3],
+ $this->mapper()
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldMapInputPromisesArray()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo([2, 4, 6]));
+
+ map(
+ [resolve(1), resolve(2), resolve(3)],
+ $this->mapper()
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldMapMixedInputArray()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo([2, 4, 6]));
+
+ map(
+ [1, resolve(2), 3],
+ $this->mapper()
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldMapInputWhenMapperReturnsAPromise()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo([2, 4, 6]));
+
+ map(
+ [1, 2, 3],
+ $this->promiseMapper()
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldAcceptAPromiseForAnArray()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo([2, 4, 6]));
+
+ map(
+ resolve([1, resolve(2), 3]),
+ $this->mapper()
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldResolveToEmptyArrayWhenInputPromiseDoesNotResolveToArray()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo([]));
+
+ map(
+ resolve(1),
+ $this->mapper()
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldPreserveTheOrderOfArrayWhenResolvingAsyncPromises()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo([2, 4, 6]));
+
+ $deferred = new Deferred();
+
+ map(
+ [resolve(1), $deferred->promise(), resolve(3)],
+ $this->mapper()
+ )->then($mock);
+
+ $deferred->resolve(2);
+ }
+
+ /** @test */
+ public function shouldRejectWhenInputContainsRejection()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(2));
+
+ map(
+ [resolve(1), reject(2), resolve(3)],
+ $this->mapper()
+ )->then($this->expectCallableNever(), $mock);
+ }
+
+ /** @test */
+ public function shouldRejectWhenInputPromiseRejects()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(null));
+
+ map(
+ reject(),
+ $this->mapper()
+ )->then($this->expectCallableNever(), $mock);
+ }
+
+ /** @test */
+ public function shouldCancelInputPromise()
+ {
+ $mock = $this
+ ->getMockBuilder('React\Promise\CancellablePromiseInterface')
+ ->getMock();
+ $mock
+ ->expects($this->once())
+ ->method('cancel');
+
+ map(
+ $mock,
+ $this->mapper()
+ )->cancel();
+ }
+
+ /** @test */
+ public function shouldCancelInputArrayPromises()
+ {
+ $mock1 = $this
+ ->getMockBuilder('React\Promise\CancellablePromiseInterface')
+ ->getMock();
+ $mock1
+ ->expects($this->once())
+ ->method('cancel');
+
+ $mock2 = $this
+ ->getMockBuilder('React\Promise\CancellablePromiseInterface')
+ ->getMock();
+ $mock2
+ ->expects($this->once())
+ ->method('cancel');
+
+ map(
+ [$mock1, $mock2],
+ $this->mapper()
+ )->cancel();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionRaceTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionRaceTest.php
new file mode 100644
index 0000000..83770ec
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionRaceTest.php
@@ -0,0 +1,211 @@
+<?php
+
+namespace React\Promise;
+
+class FunctionRaceTest extends TestCase
+{
+ /** @test */
+ public function shouldResolveEmptyInput()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(null));
+
+ race(
+ []
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldResolveValuesArray()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ race(
+ [1, 2, 3]
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldResolvePromisesArray()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(2));
+
+ $d1 = new Deferred();
+ $d2 = new Deferred();
+ $d3 = new Deferred();
+
+ race(
+ [$d1->promise(), $d2->promise(), $d3->promise()]
+ )->then($mock);
+
+ $d2->resolve(2);
+
+ $d1->resolve(1);
+ $d3->resolve(3);
+ }
+
+ /** @test */
+ public function shouldResolveSparseArrayInput()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(null));
+
+ race(
+ [null, 1, null, 2, 3]
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldRejectIfFirstSettledPromiseRejects()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(2));
+
+ $d1 = new Deferred();
+ $d2 = new Deferred();
+ $d3 = new Deferred();
+
+ race(
+ [$d1->promise(), $d2->promise(), $d3->promise()]
+ )->then($this->expectCallableNever(), $mock);
+
+ $d2->reject(2);
+
+ $d1->resolve(1);
+ $d3->resolve(3);
+ }
+
+ /** @test */
+ public function shouldAcceptAPromiseForAnArray()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ race(
+ resolve([1, 2, 3])
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldResolveToNullWhenInputPromiseDoesNotResolveToArray()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(null));
+
+ race(
+ resolve(1)
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldRejectWhenInputPromiseRejects()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(null));
+
+ race(
+ reject()
+ )->then($this->expectCallableNever(), $mock);
+ }
+
+ /** @test */
+ public function shouldCancelInputPromise()
+ {
+ $mock = $this
+ ->getMockBuilder('React\Promise\CancellablePromiseInterface')
+ ->getMock();
+ $mock
+ ->expects($this->once())
+ ->method('cancel');
+
+ race($mock)->cancel();
+ }
+
+ /** @test */
+ public function shouldCancelInputArrayPromises()
+ {
+ $mock1 = $this
+ ->getMockBuilder('React\Promise\CancellablePromiseInterface')
+ ->getMock();
+ $mock1
+ ->expects($this->once())
+ ->method('cancel');
+
+ $mock2 = $this
+ ->getMockBuilder('React\Promise\CancellablePromiseInterface')
+ ->getMock();
+ $mock2
+ ->expects($this->once())
+ ->method('cancel');
+
+ race([$mock1, $mock2])->cancel();
+ }
+
+ /** @test */
+ public function shouldNotCancelOtherPendingInputArrayPromisesIfOnePromiseFulfills()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->never())
+ ->method('__invoke');
+
+ $deferred = New Deferred($mock);
+ $deferred->resolve();
+
+ $mock2 = $this
+ ->getMockBuilder('React\Promise\CancellablePromiseInterface')
+ ->getMock();
+ $mock2
+ ->expects($this->never())
+ ->method('cancel');
+
+ race([$deferred->promise(), $mock2])->cancel();
+ }
+
+ /** @test */
+ public function shouldNotCancelOtherPendingInputArrayPromisesIfOnePromiseRejects()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->never())
+ ->method('__invoke');
+
+ $deferred = New Deferred($mock);
+ $deferred->reject();
+
+ $mock2 = $this
+ ->getMockBuilder('React\Promise\CancellablePromiseInterface')
+ ->getMock();
+ $mock2
+ ->expects($this->never())
+ ->method('cancel');
+
+ race([$deferred->promise(), $mock2])->cancel();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionReduceTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionReduceTest.php
new file mode 100644
index 0000000..8b43a87
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionReduceTest.php
@@ -0,0 +1,347 @@
+<?php
+
+namespace React\Promise;
+
+class FunctionReduceTest extends TestCase
+{
+ protected function plus()
+ {
+ return function ($sum, $val) {
+ return $sum + $val;
+ };
+ }
+
+ protected function append()
+ {
+ return function ($sum, $val) {
+ return $sum . $val;
+ };
+ }
+
+ /** @test */
+ public function shouldReduceValuesWithoutInitialValue()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(6));
+
+ reduce(
+ [1, 2, 3],
+ $this->plus()
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldReduceValuesWithInitialValue()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(7));
+
+ reduce(
+ [1, 2, 3],
+ $this->plus(),
+ 1
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldReduceValuesWithInitialPromise()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(7));
+
+ reduce(
+ [1, 2, 3],
+ $this->plus(),
+ resolve(1)
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldReducePromisedValuesWithoutInitialValue()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(6));
+
+ reduce(
+ [resolve(1), resolve(2), resolve(3)],
+ $this->plus()
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldReducePromisedValuesWithInitialValue()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(7));
+
+ reduce(
+ [resolve(1), resolve(2), resolve(3)],
+ $this->plus(),
+ 1
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldReducePromisedValuesWithInitialPromise()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(7));
+
+ reduce(
+ [resolve(1), resolve(2), resolve(3)],
+ $this->plus(),
+ resolve(1)
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldReduceEmptyInputWithInitialValue()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ reduce(
+ [],
+ $this->plus(),
+ 1
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldReduceEmptyInputWithInitialPromise()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ reduce(
+ [],
+ $this->plus(),
+ resolve(1)
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldRejectWhenInputContainsRejection()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(2));
+
+ reduce(
+ [resolve(1), reject(2), resolve(3)],
+ $this->plus(),
+ resolve(1)
+ )->then($this->expectCallableNever(), $mock);
+ }
+
+ /** @test */
+ public function shouldResolveWithNullWhenInputIsEmptyAndNoInitialValueOrPromiseProvided()
+ {
+ // Note: this is different from when.js's behavior!
+ // In when.reduce(), this rejects with a TypeError exception (following
+ // JavaScript's [].reduce behavior.
+ // We're following PHP's array_reduce behavior and resolve with NULL.
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(null));
+
+ reduce(
+ [],
+ $this->plus()
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldAllowSparseArrayInputWithoutInitialValue()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(3));
+
+ reduce(
+ [null, null, 1, null, 1, 1],
+ $this->plus()
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldAllowSparseArrayInputWithInitialValue()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(4));
+
+ reduce(
+ [null, null, 1, null, 1, 1],
+ $this->plus(),
+ 1
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldReduceInInputOrder()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo('123'));
+
+ reduce(
+ [1, 2, 3],
+ $this->append(),
+ ''
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldAcceptAPromiseForAnArray()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo('123'));
+
+ reduce(
+ resolve([1, 2, 3]),
+ $this->append(),
+ ''
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldResolveToInitialValueWhenInputPromiseDoesNotResolveToAnArray()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ reduce(
+ resolve(1),
+ $this->plus(),
+ 1
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldProvideCorrectBasisValue()
+ {
+ $insertIntoArray = function ($arr, $val, $i) {
+ $arr[$i] = $val;
+
+ return $arr;
+ };
+
+ $d1 = new Deferred();
+ $d2 = new Deferred();
+ $d3 = new Deferred();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo([1, 2, 3]));
+
+ reduce(
+ [$d1->promise(), $d2->promise(), $d3->promise()],
+ $insertIntoArray,
+ []
+ )->then($mock);
+
+ $d3->resolve(3);
+ $d1->resolve(1);
+ $d2->resolve(2);
+ }
+
+ /** @test */
+ public function shouldRejectWhenInputPromiseRejects()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(null));
+
+ reduce(
+ reject(),
+ $this->plus(),
+ 1
+ )->then($this->expectCallableNever(), $mock);
+ }
+
+ /** @test */
+ public function shouldCancelInputPromise()
+ {
+ $mock = $this
+ ->getMockBuilder('React\Promise\CancellablePromiseInterface')
+ ->getMock();
+ $mock
+ ->expects($this->once())
+ ->method('cancel');
+
+ reduce(
+ $mock,
+ $this->plus(),
+ 1
+ )->cancel();
+ }
+
+ /** @test */
+ public function shouldCancelInputArrayPromises()
+ {
+ $mock1 = $this
+ ->getMockBuilder('React\Promise\CancellablePromiseInterface')
+ ->getMock();
+ $mock1
+ ->expects($this->once())
+ ->method('cancel');
+
+ $mock2 = $this
+ ->getMockBuilder('React\Promise\CancellablePromiseInterface')
+ ->getMock();
+ $mock2
+ ->expects($this->once())
+ ->method('cancel');
+
+ reduce(
+ [$mock1, $mock2],
+ $this->plus(),
+ 1
+ )->cancel();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionRejectTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionRejectTest.php
new file mode 100644
index 0000000..84b8ec6
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionRejectTest.php
@@ -0,0 +1,64 @@
+<?php
+
+namespace React\Promise;
+
+class FunctionRejectTest extends TestCase
+{
+ /** @test */
+ public function shouldRejectAnImmediateValue()
+ {
+ $expected = 123;
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($expected));
+
+ reject($expected)
+ ->then(
+ $this->expectCallableNever(),
+ $mock
+ );
+ }
+
+ /** @test */
+ public function shouldRejectAFulfilledPromise()
+ {
+ $expected = 123;
+
+ $resolved = new FulfilledPromise($expected);
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($expected));
+
+ reject($resolved)
+ ->then(
+ $this->expectCallableNever(),
+ $mock
+ );
+ }
+
+ /** @test */
+ public function shouldRejectARejectedPromise()
+ {
+ $expected = 123;
+
+ $resolved = new RejectedPromise($expected);
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($expected));
+
+ reject($resolved)
+ ->then(
+ $this->expectCallableNever(),
+ $mock
+ );
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionResolveTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionResolveTest.php
new file mode 100644
index 0000000..53126bc
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionResolveTest.php
@@ -0,0 +1,171 @@
+<?php
+
+namespace React\Promise;
+
+class FunctionResolveTest extends TestCase
+{
+ /** @test */
+ public function shouldResolveAnImmediateValue()
+ {
+ $expected = 123;
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($expected));
+
+ resolve($expected)
+ ->then(
+ $mock,
+ $this->expectCallableNever()
+ );
+ }
+
+ /** @test */
+ public function shouldResolveAFulfilledPromise()
+ {
+ $expected = 123;
+
+ $resolved = new FulfilledPromise($expected);
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($expected));
+
+ resolve($resolved)
+ ->then(
+ $mock,
+ $this->expectCallableNever()
+ );
+ }
+
+ /** @test */
+ public function shouldResolveAThenable()
+ {
+ $thenable = new SimpleFulfilledTestThenable();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo('foo'));
+
+ resolve($thenable)
+ ->then(
+ $mock,
+ $this->expectCallableNever()
+ );
+ }
+
+ /** @test */
+ public function shouldResolveACancellableThenable()
+ {
+ $thenable = new SimpleTestCancellableThenable();
+
+ $promise = resolve($thenable);
+ $promise->cancel();
+
+ $this->assertTrue($thenable->cancelCalled);
+ }
+
+ /** @test */
+ public function shouldRejectARejectedPromise()
+ {
+ $expected = 123;
+
+ $resolved = new RejectedPromise($expected);
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($expected));
+
+ resolve($resolved)
+ ->then(
+ $this->expectCallableNever(),
+ $mock
+ );
+ }
+
+ /** @test */
+ public function shouldSupportDeepNestingInPromiseChains()
+ {
+ $d = new Deferred();
+ $d->resolve(false);
+
+ $result = resolve(resolve($d->promise()->then(function ($val) {
+ $d = new Deferred();
+ $d->resolve($val);
+
+ $identity = function ($val) {
+ return $val;
+ };
+
+ return resolve($d->promise()->then($identity))->then(
+ function ($val) {
+ return !$val;
+ }
+ );
+ })));
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(true));
+
+ $result->then($mock);
+ }
+
+ /** @test */
+ public function shouldSupportVeryDeepNestedPromises()
+ {
+ $deferreds = [];
+
+ // @TODO Increase count once global-queue is merged
+ for ($i = 0; $i < 10; $i++) {
+ $deferreds[] = $d = new Deferred();
+ $p = $d->promise();
+
+ $last = $p;
+ for ($j = 0; $j < 10; $j++) {
+ $last = $last->then(function($result) {
+ return $result;
+ });
+ }
+ }
+
+ $p = null;
+ foreach ($deferreds as $d) {
+ if ($p) {
+ $d->resolve($p);
+ }
+
+ $p = $d->promise();
+ }
+
+ $deferreds[0]->resolve(true);
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(true));
+
+ $deferreds[0]->promise()->then($mock);
+ }
+
+ /** @test */
+ public function returnsExtendePromiseForSimplePromise()
+ {
+ $promise = $this
+ ->getMockBuilder('React\Promise\PromiseInterface')
+ ->getMock();
+
+ $this->assertInstanceOf('React\Promise\ExtendedPromiseInterface', resolve($promise));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionSomeTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionSomeTest.php
new file mode 100644
index 0000000..276b54b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/FunctionSomeTest.php
@@ -0,0 +1,258 @@
+<?php
+
+namespace React\Promise;
+
+use React\Promise\Exception\LengthException;
+
+class FunctionSomeTest extends TestCase
+{
+ /** @test */
+ public function shouldRejectWithLengthExceptionWithEmptyInputArray()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with(
+ $this->callback(function($exception){
+ return $exception instanceof LengthException &&
+ 'Input array must contain at least 1 item but contains only 0 items.' === $exception->getMessage();
+ })
+ );
+
+ some(
+ [],
+ 1
+ )->then($this->expectCallableNever(), $mock);
+ }
+
+ /** @test */
+ public function shouldRejectWithLengthExceptionWithInputArrayContainingNotEnoughItems()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with(
+ $this->callback(function($exception){
+ return $exception instanceof LengthException &&
+ 'Input array must contain at least 4 items but contains only 3 items.' === $exception->getMessage();
+ })
+ );
+
+ some(
+ [1, 2, 3],
+ 4
+ )->then($this->expectCallableNever(), $mock);
+ }
+
+ /** @test */
+ public function shouldResolveToEmptyArrayWithNonArrayInput()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo([]));
+
+ some(
+ null,
+ 1
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldResolveValuesArray()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo([1, 2]));
+
+ some(
+ [1, 2, 3],
+ 2
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldResolvePromisesArray()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo([1, 2]));
+
+ some(
+ [resolve(1), resolve(2), resolve(3)],
+ 2
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldResolveSparseArrayInput()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo([null, 1]));
+
+ some(
+ [null, 1, null, 2, 3],
+ 2
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldRejectIfAnyInputPromiseRejectsBeforeDesiredNumberOfInputsAreResolved()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo([1 => 2, 2 => 3]));
+
+ some(
+ [resolve(1), reject(2), reject(3)],
+ 2
+ )->then($this->expectCallableNever(), $mock);
+ }
+
+ /** @test */
+ public function shouldAcceptAPromiseForAnArray()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo([1, 2]));
+
+ some(
+ resolve([1, 2, 3]),
+ 2
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldResolveWithEmptyArrayIfHowManyIsLessThanOne()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo([]));
+
+ some(
+ [1],
+ 0
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldResolveToEmptyArrayWhenInputPromiseDoesNotResolveToArray()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo([]));
+
+ some(
+ resolve(1),
+ 1
+ )->then($mock);
+ }
+
+ /** @test */
+ public function shouldRejectWhenInputPromiseRejects()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(null));
+
+ some(
+ reject(),
+ 1
+ )->then($this->expectCallableNever(), $mock);
+ }
+
+ /** @test */
+ public function shouldCancelInputPromise()
+ {
+ $mock = $this
+ ->getMockBuilder('React\Promise\CancellablePromiseInterface')
+ ->getMock();
+ $mock
+ ->expects($this->once())
+ ->method('cancel');
+
+ some($mock, 1)->cancel();
+ }
+
+ /** @test */
+ public function shouldCancelInputArrayPromises()
+ {
+ $mock1 = $this
+ ->getMockBuilder('React\Promise\CancellablePromiseInterface')
+ ->getMock();
+ $mock1
+ ->expects($this->once())
+ ->method('cancel');
+
+ $mock2 = $this
+ ->getMockBuilder('React\Promise\CancellablePromiseInterface')
+ ->getMock();
+ $mock2
+ ->expects($this->once())
+ ->method('cancel');
+
+ some([$mock1, $mock2], 1)->cancel();
+ }
+
+ /** @test */
+ public function shouldNotCancelOtherPendingInputArrayPromisesIfEnoughPromisesFulfill()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->never())
+ ->method('__invoke');
+
+ $deferred = New Deferred($mock);
+ $deferred->resolve();
+
+ $mock2 = $this
+ ->getMockBuilder('React\Promise\CancellablePromiseInterface')
+ ->getMock();
+ $mock2
+ ->expects($this->never())
+ ->method('cancel');
+
+ some([$deferred->promise(), $mock2], 1);
+ }
+
+ /** @test */
+ public function shouldNotCancelOtherPendingInputArrayPromisesIfEnoughPromisesReject()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->never())
+ ->method('__invoke');
+
+ $deferred = New Deferred($mock);
+ $deferred->reject();
+
+ $mock2 = $this
+ ->getMockBuilder('React\Promise\CancellablePromiseInterface')
+ ->getMock();
+ $mock2
+ ->expects($this->never())
+ ->method('cancel');
+
+ some([$deferred->promise(), $mock2], 2);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/LazyPromiseTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/LazyPromiseTest.php
new file mode 100644
index 0000000..b630881
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/LazyPromiseTest.php
@@ -0,0 +1,107 @@
+<?php
+
+namespace React\Promise;
+
+use React\Promise\PromiseAdapter\CallbackPromiseAdapter;
+
+class LazyPromiseTest extends TestCase
+{
+ use PromiseTest\FullTestTrait;
+
+ public function getPromiseTestAdapter(callable $canceller = null)
+ {
+ $d = new Deferred($canceller);
+
+ $factory = function () use ($d) {
+ return $d->promise();
+ };
+
+ return new CallbackPromiseAdapter([
+ 'promise' => function () use ($factory) {
+ return new LazyPromise($factory);
+ },
+ 'resolve' => [$d, 'resolve'],
+ 'reject' => [$d, 'reject'],
+ 'notify' => [$d, 'progress'],
+ 'settle' => [$d, 'resolve'],
+ ]);
+ }
+
+ /** @test */
+ public function shouldNotCallFactoryIfThenIsNotInvoked()
+ {
+ $factory = $this->createCallableMock();
+ $factory
+ ->expects($this->never())
+ ->method('__invoke');
+
+ new LazyPromise($factory);
+ }
+
+ /** @test */
+ public function shouldCallFactoryIfThenIsInvoked()
+ {
+ $factory = $this->createCallableMock();
+ $factory
+ ->expects($this->once())
+ ->method('__invoke');
+
+ $p = new LazyPromise($factory);
+ $p->then();
+ }
+
+ /** @test */
+ public function shouldReturnPromiseFromFactory()
+ {
+ $factory = $this->createCallableMock();
+ $factory
+ ->expects($this->once())
+ ->method('__invoke')
+ ->will($this->returnValue(new FulfilledPromise(1)));
+
+ $onFulfilled = $this->createCallableMock();
+ $onFulfilled
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ $p = new LazyPromise($factory);
+
+ $p->then($onFulfilled);
+ }
+
+ /** @test */
+ public function shouldReturnPromiseIfFactoryReturnsNull()
+ {
+ $factory = $this->createCallableMock();
+ $factory
+ ->expects($this->once())
+ ->method('__invoke')
+ ->will($this->returnValue(null));
+
+ $p = new LazyPromise($factory);
+ $this->assertInstanceOf('React\\Promise\\PromiseInterface', $p->then());
+ }
+
+ /** @test */
+ public function shouldReturnRejectedPromiseIfFactoryThrowsException()
+ {
+ $exception = new \Exception();
+
+ $factory = $this->createCallableMock();
+ $factory
+ ->expects($this->once())
+ ->method('__invoke')
+ ->will($this->throwException($exception));
+
+ $onRejected = $this->createCallableMock();
+ $onRejected
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($exception));
+
+ $p = new LazyPromise($factory);
+
+ $p->then($this->expectCallableNever(), $onRejected);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseAdapter/CallbackPromiseAdapter.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseAdapter/CallbackPromiseAdapter.php
new file mode 100644
index 0000000..bdedf46
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseAdapter/CallbackPromiseAdapter.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace React\Promise\PromiseAdapter;
+
+use React\Promise;
+
+class CallbackPromiseAdapter implements PromiseAdapterInterface
+{
+ private $callbacks;
+
+ public function __construct(array $callbacks)
+ {
+ $this->callbacks = $callbacks;
+ }
+
+ public function promise()
+ {
+ return call_user_func_array($this->callbacks['promise'], func_get_args());
+ }
+
+ public function resolve()
+ {
+ return call_user_func_array($this->callbacks['resolve'], func_get_args());
+ }
+
+ public function reject()
+ {
+ return call_user_func_array($this->callbacks['reject'], func_get_args());
+ }
+
+ public function notify()
+ {
+ return call_user_func_array($this->callbacks['notify'], func_get_args());
+ }
+
+ public function settle()
+ {
+ return call_user_func_array($this->callbacks['settle'], func_get_args());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseAdapter/PromiseAdapterInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseAdapter/PromiseAdapterInterface.php
new file mode 100644
index 0000000..9157cd4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseAdapter/PromiseAdapterInterface.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace React\Promise\PromiseAdapter;
+
+use React\Promise;
+
+interface PromiseAdapterInterface
+{
+ public function promise();
+ public function resolve();
+ public function reject();
+ public function notify();
+ public function settle();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest.php
new file mode 100644
index 0000000..dc7b733
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest.php
@@ -0,0 +1,84 @@
+<?php
+
+namespace React\Promise;
+
+use React\Promise\PromiseAdapter\CallbackPromiseAdapter;
+
+class PromiseTest extends TestCase
+{
+ use PromiseTest\FullTestTrait;
+
+ public function getPromiseTestAdapter(callable $canceller = null)
+ {
+ $resolveCallback = $rejectCallback = $progressCallback = null;
+
+ $promise = new Promise(function ($resolve, $reject, $progress) use (&$resolveCallback, &$rejectCallback, &$progressCallback) {
+ $resolveCallback = $resolve;
+ $rejectCallback = $reject;
+ $progressCallback = $progress;
+ }, $canceller);
+
+ return new CallbackPromiseAdapter([
+ 'promise' => function () use ($promise) {
+ return $promise;
+ },
+ 'resolve' => $resolveCallback,
+ 'reject' => $rejectCallback,
+ 'notify' => $progressCallback,
+ 'settle' => $resolveCallback,
+ ]);
+ }
+
+ /** @test */
+ public function shouldRejectIfResolverThrowsException()
+ {
+ $exception = new \Exception('foo');
+
+ $promise = new Promise(function () use ($exception) {
+ throw $exception;
+ });
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($exception));
+
+ $promise
+ ->then($this->expectCallableNever(), $mock);
+ }
+
+ /** @test */
+ public function shouldFulfillIfFullfilledWithSimplePromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo('foo'));
+
+ $adapter->promise()
+ ->then($mock);
+
+ $adapter->resolve(new SimpleFulfilledTestPromise());
+ }
+
+ /** @test */
+ public function shouldRejectIfRejectedWithSimplePromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo('foo'));
+
+ $adapter->promise()
+ ->then($this->expectCallableNever(), $mock);
+
+ $adapter->resolve(new SimpleRejectedTestPromise());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/CancelTestTrait.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/CancelTestTrait.php
new file mode 100644
index 0000000..d722d75
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/CancelTestTrait.php
@@ -0,0 +1,231 @@
+<?php
+
+namespace React\Promise\PromiseTest;
+
+use React\Promise;
+
+trait CancelTestTrait
+{
+ /**
+ * @return \React\Promise\PromiseAdapter\PromiseAdapterInterface
+ */
+ abstract public function getPromiseTestAdapter(callable $canceller = null);
+
+ /** @test */
+ public function cancelShouldCallCancellerWithResolverArguments()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->isType('callable'), $this->isType('callable'), $this->isType('callable'));
+
+ $adapter = $this->getPromiseTestAdapter($mock);
+
+ $adapter->promise()->cancel();
+ }
+
+ /** @test */
+ public function cancelShouldFulfillPromiseIfCancellerFulfills()
+ {
+ $adapter = $this->getPromiseTestAdapter(function ($resolve) {
+ $resolve(1);
+ });
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ $adapter->promise()
+ ->then($mock, $this->expectCallableNever());
+
+ $adapter->promise()->cancel();
+ }
+
+ /** @test */
+ public function cancelShouldRejectPromiseIfCancellerRejects()
+ {
+ $adapter = $this->getPromiseTestAdapter(function ($resolve, $reject) {
+ $reject(1);
+ });
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ $adapter->promise()
+ ->then($this->expectCallableNever(), $mock);
+
+ $adapter->promise()->cancel();
+ }
+
+ /** @test */
+ public function cancelShouldRejectPromiseWithExceptionIfCancellerThrows()
+ {
+ $e = new \Exception();
+
+ $adapter = $this->getPromiseTestAdapter(function () use ($e) {
+ throw $e;
+ });
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($e));
+
+ $adapter->promise()
+ ->then($this->expectCallableNever(), $mock);
+
+ $adapter->promise()->cancel();
+ }
+
+ /** @test */
+ public function cancelShouldProgressPromiseIfCancellerNotifies()
+ {
+ $adapter = $this->getPromiseTestAdapter(function ($resolve, $reject, $progress) {
+ $progress(1);
+ });
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ $adapter->promise()
+ ->then($this->expectCallableNever(), $this->expectCallableNever(), $mock);
+
+ $adapter->promise()->cancel();
+ }
+
+ /** @test */
+ public function cancelShouldCallCancellerOnlyOnceIfCancellerResolves()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->will($this->returnCallback(function ($resolve) {
+ $resolve();
+ }));
+
+ $adapter = $this->getPromiseTestAdapter($mock);
+
+ $adapter->promise()->cancel();
+ $adapter->promise()->cancel();
+ }
+
+ /** @test */
+ public function cancelShouldHaveNoEffectIfCancellerDoesNothing()
+ {
+ $adapter = $this->getPromiseTestAdapter(function () {});
+
+ $adapter->promise()
+ ->then($this->expectCallableNever(), $this->expectCallableNever());
+
+ $adapter->promise()->cancel();
+ $adapter->promise()->cancel();
+ }
+
+ /** @test */
+ public function cancelShouldCallCancellerFromDeepNestedPromiseChain()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke');
+
+ $adapter = $this->getPromiseTestAdapter($mock);
+
+ $promise = $adapter->promise()
+ ->then(function () {
+ return new Promise\Promise(function () {});
+ })
+ ->then(function () {
+ $d = new Promise\Deferred();
+
+ return $d->promise();
+ })
+ ->then(function () {
+ return new Promise\Promise(function () {});
+ });
+
+ $promise->cancel();
+ }
+
+ /** @test */
+ public function cancelCalledOnChildrenSouldOnlyCancelWhenAllChildrenCancelled()
+ {
+ $adapter = $this->getPromiseTestAdapter($this->expectCallableNever());
+
+ $child1 = $adapter->promise()
+ ->then()
+ ->then();
+
+ $adapter->promise()
+ ->then();
+
+ $child1->cancel();
+ }
+
+ /** @test */
+ public function cancelShouldTriggerCancellerWhenAllChildrenCancel()
+ {
+ $adapter = $this->getPromiseTestAdapter($this->expectCallableOnce());
+
+ $child1 = $adapter->promise()
+ ->then()
+ ->then();
+
+ $child2 = $adapter->promise()
+ ->then();
+
+ $child1->cancel();
+ $child2->cancel();
+ }
+
+ /** @test */
+ public function cancelShouldNotTriggerCancellerWhenCancellingOneChildrenMultipleTimes()
+ {
+ $adapter = $this->getPromiseTestAdapter($this->expectCallableNever());
+
+ $child1 = $adapter->promise()
+ ->then()
+ ->then();
+
+ $child2 = $adapter->promise()
+ ->then();
+
+ $child1->cancel();
+ $child1->cancel();
+ }
+
+ /** @test */
+ public function cancelShouldTriggerCancellerOnlyOnceWhenCancellingMultipleTimes()
+ {
+ $adapter = $this->getPromiseTestAdapter($this->expectCallableOnce());
+
+ $adapter->promise()->cancel();
+ $adapter->promise()->cancel();
+ }
+
+ /** @test */
+ public function cancelShouldAlwaysTriggerCancellerWhenCalledOnRootPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter($this->expectCallableOnce());
+
+ $adapter->promise()
+ ->then()
+ ->then();
+
+ $adapter->promise()
+ ->then();
+
+ $adapter->promise()->cancel();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/FullTestTrait.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/FullTestTrait.php
new file mode 100644
index 0000000..3ce45d6
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/FullTestTrait.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace React\Promise\PromiseTest;
+
+trait FullTestTrait
+{
+ use PromisePendingTestTrait,
+ PromiseSettledTestTrait,
+ PromiseFulfilledTestTrait,
+ PromiseRejectedTestTrait,
+ ResolveTestTrait,
+ RejectTestTrait,
+ NotifyTestTrait,
+ CancelTestTrait;
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/NotifyTestTrait.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/NotifyTestTrait.php
new file mode 100644
index 0000000..4501df6
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/NotifyTestTrait.php
@@ -0,0 +1,336 @@
+<?php
+
+namespace React\Promise\PromiseTest;
+
+trait NotifyTestTrait
+{
+ /**
+ * @return \React\Promise\PromiseAdapter\PromiseAdapterInterface
+ */
+ abstract public function getPromiseTestAdapter(callable $canceller = null);
+
+ /** @test */
+ public function notifyShouldProgress()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $sentinel = new \stdClass();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($sentinel);
+
+ $adapter->promise()
+ ->then($this->expectCallableNever(), $this->expectCallableNever(), $mock);
+
+ $adapter->notify($sentinel);
+ }
+
+ /** @test */
+ public function notifyShouldPropagateProgressToDownstreamPromises()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $sentinel = new \stdClass();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->will($this->returnArgument(0));
+
+ $mock2 = $this->createCallableMock();
+ $mock2
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($sentinel);
+
+ $adapter->promise()
+ ->then(
+ $this->expectCallableNever(),
+ $this->expectCallableNever(),
+ $mock
+ )
+ ->then(
+ $this->expectCallableNever(),
+ $this->expectCallableNever(),
+ $mock2
+ );
+
+ $adapter->notify($sentinel);
+ }
+
+ /** @test */
+ public function notifyShouldPropagateTransformedProgressToDownstreamPromises()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $sentinel = new \stdClass();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->will($this->returnValue($sentinel));
+
+ $mock2 = $this->createCallableMock();
+ $mock2
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($sentinel);
+
+ $adapter->promise()
+ ->then(
+ $this->expectCallableNever(),
+ $this->expectCallableNever(),
+ $mock
+ )
+ ->then(
+ $this->expectCallableNever(),
+ $this->expectCallableNever(),
+ $mock2
+ );
+
+ $adapter->notify(1);
+ }
+
+ /** @test */
+ public function notifyShouldPropagateCaughtExceptionValueAsProgress()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $exception = new \Exception();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->will($this->throwException($exception));
+
+ $mock2 = $this->createCallableMock();
+ $mock2
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($exception));
+
+ $adapter->promise()
+ ->then(
+ $this->expectCallableNever(),
+ $this->expectCallableNever(),
+ $mock
+ )
+ ->then(
+ $this->expectCallableNever(),
+ $this->expectCallableNever(),
+ $mock2
+ );
+
+ $adapter->notify(1);
+ }
+
+ /** @test */
+ public function notifyShouldForwardProgressEventsWhenIntermediaryCallbackTiedToAResolvedPromiseReturnsAPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+ $adapter2 = $this->getPromiseTestAdapter();
+
+ $promise2 = $adapter2->promise();
+
+ $sentinel = new \stdClass();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($sentinel);
+
+ // resolve BEFORE attaching progress handler
+ $adapter->resolve();
+
+ $adapter->promise()
+ ->then(function () use ($promise2) {
+ return $promise2;
+ })
+ ->then(
+ $this->expectCallableNever(),
+ $this->expectCallableNever(),
+ $mock
+ );
+
+ $adapter2->notify($sentinel);
+ }
+
+ /** @test */
+ public function notifyShouldForwardProgressEventsWhenIntermediaryCallbackTiedToAnUnresolvedPromiseReturnsAPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+ $adapter2 = $this->getPromiseTestAdapter();
+
+ $promise2 = $adapter2->promise();
+
+ $sentinel = new \stdClass();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($sentinel);
+
+ $adapter->promise()
+ ->then(function () use ($promise2) {
+ return $promise2;
+ })
+ ->then(
+ $this->expectCallableNever(),
+ $this->expectCallableNever(),
+ $mock
+ );
+
+ // resolve AFTER attaching progress handler
+ $adapter->resolve();
+ $adapter2->notify($sentinel);
+ }
+
+ /** @test */
+ public function notifyShouldForwardProgressWhenResolvedWithAnotherPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+ $adapter2 = $this->getPromiseTestAdapter();
+
+ $sentinel = new \stdClass();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->will($this->returnValue($sentinel));
+
+ $mock2 = $this->createCallableMock();
+ $mock2
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($sentinel);
+
+ $adapter->promise()
+ ->then(
+ $this->expectCallableNever(),
+ $this->expectCallableNever(),
+ $mock
+ )
+ ->then(
+ $this->expectCallableNever(),
+ $this->expectCallableNever(),
+ $mock2
+ );
+
+ $adapter->resolve($adapter2->promise());
+ $adapter2->notify($sentinel);
+ }
+
+ /** @test */
+ public function notifyShouldAllowResolveAfterProgress()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->at(0))
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+ $mock
+ ->expects($this->at(1))
+ ->method('__invoke')
+ ->with($this->identicalTo(2));
+
+ $adapter->promise()
+ ->then(
+ $mock,
+ $this->expectCallableNever(),
+ $mock
+ );
+
+ $adapter->notify(1);
+ $adapter->resolve(2);
+ }
+
+ /** @test */
+ public function notifyShouldAllowRejectAfterProgress()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->at(0))
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+ $mock
+ ->expects($this->at(1))
+ ->method('__invoke')
+ ->with($this->identicalTo(2));
+
+ $adapter->promise()
+ ->then(
+ $this->expectCallableNever(),
+ $mock,
+ $mock
+ );
+
+ $adapter->notify(1);
+ $adapter->reject(2);
+ }
+
+ /** @test */
+ public function notifyShouldReturnSilentlyOnProgressWhenAlreadyRejected()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $adapter->reject(1);
+
+ $this->assertNull($adapter->notify());
+ }
+
+ /** @test */
+ public function notifyShouldInvokeProgressHandler()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ $adapter->promise()->progress($mock);
+ $adapter->notify(1);
+ }
+
+ /** @test */
+ public function notifyShouldInvokeProgressHandlerFromDone()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ $this->assertNull($adapter->promise()->done(null, null, $mock));
+ $adapter->notify(1);
+ }
+
+ /** @test */
+ public function notifyShouldThrowExceptionThrownProgressHandlerFromDone()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $this->setExpectedException('\Exception', 'UnhandledRejectionException');
+
+ $this->assertNull($adapter->promise()->done(null, null, function () {
+ throw new \Exception('UnhandledRejectionException');
+ }));
+ $adapter->notify(1);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/PromiseFulfilledTestTrait.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/PromiseFulfilledTestTrait.php
new file mode 100644
index 0000000..428230b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/PromiseFulfilledTestTrait.php
@@ -0,0 +1,351 @@
+<?php
+
+namespace React\Promise\PromiseTest;
+
+trait PromiseFulfilledTestTrait
+{
+ /**
+ * @return \React\Promise\PromiseAdapter\PromiseAdapterInterface
+ */
+ abstract public function getPromiseTestAdapter(callable $canceller = null);
+
+ /** @test */
+ public function fulfilledPromiseShouldBeImmutable()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ $adapter->resolve(1);
+ $adapter->resolve(2);
+
+ $adapter->promise()
+ ->then(
+ $mock,
+ $this->expectCallableNever()
+ );
+ }
+
+ /** @test */
+ public function fulfilledPromiseShouldInvokeNewlyAddedCallback()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $adapter->resolve(1);
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ $adapter->promise()
+ ->then($mock, $this->expectCallableNever());
+ }
+
+ /** @test */
+ public function thenShouldForwardResultWhenCallbackIsNull()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ $adapter->resolve(1);
+ $adapter->promise()
+ ->then(
+ null,
+ $this->expectCallableNever()
+ )
+ ->then(
+ $mock,
+ $this->expectCallableNever()
+ );
+ }
+
+ /** @test */
+ public function thenShouldForwardCallbackResultToNextCallback()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(2));
+
+ $adapter->resolve(1);
+ $adapter->promise()
+ ->then(
+ function ($val) {
+ return $val + 1;
+ },
+ $this->expectCallableNever()
+ )
+ ->then(
+ $mock,
+ $this->expectCallableNever()
+ );
+ }
+
+ /** @test */
+ public function thenShouldForwardPromisedCallbackResultValueToNextCallback()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(2));
+
+ $adapter->resolve(1);
+ $adapter->promise()
+ ->then(
+ function ($val) {
+ return \React\Promise\resolve($val + 1);
+ },
+ $this->expectCallableNever()
+ )
+ ->then(
+ $mock,
+ $this->expectCallableNever()
+ );
+ }
+
+ /** @test */
+ public function thenShouldSwitchFromCallbacksToErrbacksWhenCallbackReturnsARejection()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(2));
+
+ $adapter->resolve(1);
+ $adapter->promise()
+ ->then(
+ function ($val) {
+ return \React\Promise\reject($val + 1);
+ },
+ $this->expectCallableNever()
+ )
+ ->then(
+ $this->expectCallableNever(),
+ $mock
+ );
+ }
+
+ /** @test */
+ public function thenShouldSwitchFromCallbacksToErrbacksWhenCallbackThrows()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $exception = new \Exception();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->will($this->throwException($exception));
+
+ $mock2 = $this->createCallableMock();
+ $mock2
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($exception));
+
+ $adapter->resolve(1);
+ $adapter->promise()
+ ->then(
+ $mock,
+ $this->expectCallableNever()
+ )
+ ->then(
+ $this->expectCallableNever(),
+ $mock2
+ );
+ }
+
+ /** @test */
+ public function cancelShouldReturnNullForFulfilledPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $adapter->resolve();
+
+ $this->assertNull($adapter->promise()->cancel());
+ }
+
+ /** @test */
+ public function cancelShouldHaveNoEffectForFulfilledPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter($this->expectCallableNever());
+
+ $adapter->resolve();
+
+ $adapter->promise()->cancel();
+ }
+
+ /** @test */
+ public function doneShouldInvokeFulfillmentHandlerForFulfilledPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ $adapter->resolve(1);
+ $this->assertNull($adapter->promise()->done($mock));
+ }
+
+ /** @test */
+ public function doneShouldThrowExceptionThrownFulfillmentHandlerForFulfilledPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $this->setExpectedException('\Exception', 'UnhandledRejectionException');
+
+ $adapter->resolve(1);
+ $this->assertNull($adapter->promise()->done(function () {
+ throw new \Exception('UnhandledRejectionException');
+ }));
+ }
+
+ /** @test */
+ public function doneShouldThrowUnhandledRejectionExceptionWhenFulfillmentHandlerRejectsForFulfilledPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $this->setExpectedException('React\\Promise\\UnhandledRejectionException');
+
+ $adapter->resolve(1);
+ $this->assertNull($adapter->promise()->done(function () {
+ return \React\Promise\reject();
+ }));
+ }
+
+ /** @test */
+ public function otherwiseShouldNotInvokeRejectionHandlerForFulfilledPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $adapter->resolve(1);
+ $adapter->promise()->otherwise($this->expectCallableNever());
+ }
+
+ /** @test */
+ public function alwaysShouldNotSuppressValueForFulfilledPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $value = new \stdClass();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($value));
+
+ $adapter->resolve($value);
+ $adapter->promise()
+ ->always(function () {})
+ ->then($mock);
+ }
+
+ /** @test */
+ public function alwaysShouldNotSuppressValueWhenHandlerReturnsANonPromiseForFulfilledPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $value = new \stdClass();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($value));
+
+ $adapter->resolve($value);
+ $adapter->promise()
+ ->always(function () {
+ return 1;
+ })
+ ->then($mock);
+ }
+
+ /** @test */
+ public function alwaysShouldNotSuppressValueWhenHandlerReturnsAPromiseForFulfilledPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $value = new \stdClass();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($value));
+
+ $adapter->resolve($value);
+ $adapter->promise()
+ ->always(function () {
+ return \React\Promise\resolve(1);
+ })
+ ->then($mock);
+ }
+
+ /** @test */
+ public function alwaysShouldRejectWhenHandlerThrowsForFulfilledPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $exception = new \Exception();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($exception));
+
+ $adapter->resolve(1);
+ $adapter->promise()
+ ->always(function () use ($exception) {
+ throw $exception;
+ })
+ ->then(null, $mock);
+ }
+
+ /** @test */
+ public function alwaysShouldRejectWhenHandlerRejectsForFulfilledPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $exception = new \Exception();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($exception));
+
+ $adapter->resolve(1);
+ $adapter->promise()
+ ->always(function () use ($exception) {
+ return \React\Promise\reject($exception);
+ })
+ ->then(null, $mock);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/PromisePendingTestTrait.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/PromisePendingTestTrait.php
new file mode 100644
index 0000000..a4f48ee
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/PromisePendingTestTrait.php
@@ -0,0 +1,68 @@
+<?php
+
+namespace React\Promise\PromiseTest;
+
+trait PromisePendingTestTrait
+{
+ /**
+ * @return \React\Promise\PromiseAdapter\PromiseAdapterInterface
+ */
+ abstract public function getPromiseTestAdapter(callable $canceller = null);
+
+ /** @test */
+ public function thenShouldReturnAPromiseForPendingPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $this->assertInstanceOf('React\\Promise\\PromiseInterface', $adapter->promise()->then());
+ }
+
+ /** @test */
+ public function thenShouldReturnAllowNullForPendingPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $this->assertInstanceOf('React\\Promise\\PromiseInterface', $adapter->promise()->then(null, null, null));
+ }
+
+ /** @test */
+ public function cancelShouldReturnNullForPendingPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $this->assertNull($adapter->promise()->cancel());
+ }
+
+ /** @test */
+ public function doneShouldReturnNullForPendingPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $this->assertNull($adapter->promise()->done());
+ }
+
+ /** @test */
+ public function doneShouldReturnAllowNullForPendingPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $this->assertNull($adapter->promise()->done(null, null, null));
+ }
+
+ /** @test */
+ public function otherwiseShouldNotInvokeRejectionHandlerForPendingPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $adapter->settle();
+ $adapter->promise()->otherwise($this->expectCallableNever());
+ }
+
+ /** @test */
+ public function alwaysShouldReturnAPromiseForPendingPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $this->assertInstanceOf('React\\Promise\\PromiseInterface', $adapter->promise()->always(function () {}));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/PromiseRejectedTestTrait.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/PromiseRejectedTestTrait.php
new file mode 100644
index 0000000..98d1dcf
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/PromiseRejectedTestTrait.php
@@ -0,0 +1,512 @@
+<?php
+
+namespace React\Promise\PromiseTest;
+
+use React\Promise\Deferred;
+use React\Promise\UnhandledRejectionException;
+
+trait PromiseRejectedTestTrait
+{
+ /**
+ * @return \React\Promise\PromiseAdapter\PromiseAdapterInterface
+ */
+ abstract public function getPromiseTestAdapter(callable $canceller = null);
+
+ /** @test */
+ public function rejectedPromiseShouldBeImmutable()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ $adapter->reject(1);
+ $adapter->reject(2);
+
+ $adapter->promise()
+ ->then(
+ $this->expectCallableNever(),
+ $mock
+ );
+ }
+
+ /** @test */
+ public function rejectedPromiseShouldInvokeNewlyAddedCallback()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $adapter->reject(1);
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ $adapter->promise()
+ ->then($this->expectCallableNever(), $mock);
+ }
+
+ /** @test */
+ public function shouldForwardUndefinedRejectionValue()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with(null);
+
+ $adapter->reject(1);
+ $adapter->promise()
+ ->then(
+ $this->expectCallableNever(),
+ function () {
+ // Presence of rejection handler is enough to switch back
+ // to resolve mode, even though it returns undefined.
+ // The ONLY way to propagate a rejection is to re-throw or
+ // return a rejected promise;
+ }
+ )
+ ->then(
+ $mock,
+ $this->expectCallableNever()
+ );
+ }
+
+ /** @test */
+ public function shouldSwitchFromErrbacksToCallbacksWhenErrbackDoesNotExplicitlyPropagate()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(2));
+
+ $adapter->reject(1);
+ $adapter->promise()
+ ->then(
+ $this->expectCallableNever(),
+ function ($val) {
+ return $val + 1;
+ }
+ )
+ ->then(
+ $mock,
+ $this->expectCallableNever()
+ );
+ }
+
+ /** @test */
+ public function shouldSwitchFromErrbacksToCallbacksWhenErrbackReturnsAResolution()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(2));
+
+ $adapter->reject(1);
+ $adapter->promise()
+ ->then(
+ $this->expectCallableNever(),
+ function ($val) {
+ return \React\Promise\resolve($val + 1);
+ }
+ )
+ ->then(
+ $mock,
+ $this->expectCallableNever()
+ );
+ }
+
+ /** @test */
+ public function shouldPropagateRejectionsWhenErrbackThrows()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $exception = new \Exception();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->will($this->throwException($exception));
+
+ $mock2 = $this->createCallableMock();
+ $mock2
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($exception));
+
+ $adapter->reject(1);
+ $adapter->promise()
+ ->then(
+ $this->expectCallableNever(),
+ $mock
+ )
+ ->then(
+ $this->expectCallableNever(),
+ $mock2
+ );
+ }
+
+ /** @test */
+ public function shouldPropagateRejectionsWhenErrbackReturnsARejection()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(2));
+
+ $adapter->reject(1);
+ $adapter->promise()
+ ->then(
+ $this->expectCallableNever(),
+ function ($val) {
+ return \React\Promise\reject($val + 1);
+ }
+ )
+ ->then(
+ $this->expectCallableNever(),
+ $mock
+ );
+ }
+
+ /** @test */
+ public function doneShouldInvokeRejectionHandlerForRejectedPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ $adapter->reject(1);
+ $this->assertNull($adapter->promise()->done(null, $mock));
+ }
+
+ /** @test */
+ public function doneShouldThrowExceptionThrownByRejectionHandlerForRejectedPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $this->setExpectedException('\Exception', 'UnhandledRejectionException');
+
+ $adapter->reject(1);
+ $this->assertNull($adapter->promise()->done(null, function () {
+ throw new \Exception('UnhandledRejectionException');
+ }));
+ }
+
+ /** @test */
+ public function doneShouldThrowUnhandledRejectionExceptionWhenRejectedWithNonExceptionForRejectedPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $this->setExpectedException('React\\Promise\\UnhandledRejectionException');
+
+ $adapter->reject(1);
+ $this->assertNull($adapter->promise()->done());
+ }
+
+ /** @test */
+ public function unhandledRejectionExceptionThrownByDoneHoldsRejectionValue()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $expected = new \stdClass();
+
+ $adapter->reject($expected);
+
+ try {
+ $adapter->promise()->done();
+ } catch (UnhandledRejectionException $e) {
+ $this->assertSame($expected, $e->getReason());
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /** @test */
+ public function doneShouldThrowUnhandledRejectionExceptionWhenRejectionHandlerRejectsForRejectedPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $this->setExpectedException('React\\Promise\\UnhandledRejectionException');
+
+ $adapter->reject(1);
+ $this->assertNull($adapter->promise()->done(null, function () {
+ return \React\Promise\reject();
+ }));
+ }
+
+ /** @test */
+ public function doneShouldThrowRejectionExceptionWhenRejectionHandlerRejectsWithExceptionForRejectedPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $this->setExpectedException('\Exception', 'UnhandledRejectionException');
+
+ $adapter->reject(1);
+ $this->assertNull($adapter->promise()->done(null, function () {
+ return \React\Promise\reject(new \Exception('UnhandledRejectionException'));
+ }));
+ }
+
+ /** @test */
+ public function doneShouldThrowExceptionProvidedAsRejectionValueForRejectedPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $this->setExpectedException('\Exception', 'UnhandledRejectionException');
+
+ $adapter->reject(new \Exception('UnhandledRejectionException'));
+ $this->assertNull($adapter->promise()->done());
+ }
+
+ /** @test */
+ public function doneShouldThrowWithDeepNestingPromiseChainsForRejectedPromise()
+ {
+ $this->setExpectedException('\Exception', 'UnhandledRejectionException');
+
+ $exception = new \Exception('UnhandledRejectionException');
+
+ $d = new Deferred();
+ $d->resolve();
+
+ $result = \React\Promise\resolve(\React\Promise\resolve($d->promise()->then(function () use ($exception) {
+ $d = new Deferred();
+ $d->resolve();
+
+ return \React\Promise\resolve($d->promise()->then(function () {}))->then(
+ function () use ($exception) {
+ throw $exception;
+ }
+ );
+ })));
+
+ $result->done();
+ }
+
+ /** @test */
+ public function doneShouldRecoverWhenRejectionHandlerCatchesExceptionForRejectedPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $adapter->reject(new \Exception('UnhandledRejectionException'));
+ $this->assertNull($adapter->promise()->done(null, function (\Exception $e) {
+
+ }));
+ }
+
+ /** @test */
+ public function otherwiseShouldInvokeRejectionHandlerForRejectedPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ $adapter->reject(1);
+ $adapter->promise()->otherwise($mock);
+ }
+
+ /** @test */
+ public function otherwiseShouldInvokeNonTypeHintedRejectionHandlerIfReasonIsAnExceptionForRejectedPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $exception = new \Exception();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($exception));
+
+ $adapter->reject($exception);
+ $adapter->promise()
+ ->otherwise(function ($reason) use ($mock) {
+ $mock($reason);
+ });
+ }
+
+ /** @test */
+ public function otherwiseShouldInvokeRejectionHandlerIfReasonMatchesTypehintForRejectedPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $exception = new \InvalidArgumentException();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($exception));
+
+ $adapter->reject($exception);
+ $adapter->promise()
+ ->otherwise(function (\InvalidArgumentException $reason) use ($mock) {
+ $mock($reason);
+ });
+ }
+
+ /** @test */
+ public function otherwiseShouldNotInvokeRejectionHandlerIfReaonsDoesNotMatchTypehintForRejectedPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $exception = new \Exception();
+
+ $mock = $this->expectCallableNever();
+
+ $adapter->reject($exception);
+ $adapter->promise()
+ ->otherwise(function (\InvalidArgumentException $reason) use ($mock) {
+ $mock($reason);
+ });
+ }
+
+ /** @test */
+ public function alwaysShouldNotSuppressRejectionForRejectedPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $exception = new \Exception();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($exception));
+
+ $adapter->reject($exception);
+ $adapter->promise()
+ ->always(function () {})
+ ->then(null, $mock);
+ }
+
+ /** @test */
+ public function alwaysShouldNotSuppressRejectionWhenHandlerReturnsANonPromiseForRejectedPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $exception = new \Exception();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($exception));
+
+ $adapter->reject($exception);
+ $adapter->promise()
+ ->always(function () {
+ return 1;
+ })
+ ->then(null, $mock);
+ }
+
+ /** @test */
+ public function alwaysShouldNotSuppressRejectionWhenHandlerReturnsAPromiseForRejectedPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $exception = new \Exception();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($exception));
+
+ $adapter->reject($exception);
+ $adapter->promise()
+ ->always(function () {
+ return \React\Promise\resolve(1);
+ })
+ ->then(null, $mock);
+ }
+
+ /** @test */
+ public function alwaysShouldRejectWhenHandlerThrowsForRejectedPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $exception1 = new \Exception();
+ $exception2 = new \Exception();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($exception2));
+
+ $adapter->reject($exception1);
+ $adapter->promise()
+ ->always(function () use ($exception2) {
+ throw $exception2;
+ })
+ ->then(null, $mock);
+ }
+
+ /** @test */
+ public function alwaysShouldRejectWhenHandlerRejectsForRejectedPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $exception1 = new \Exception();
+ $exception2 = new \Exception();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($exception2));
+
+ $adapter->reject($exception1);
+ $adapter->promise()
+ ->always(function () use ($exception2) {
+ return \React\Promise\reject($exception2);
+ })
+ ->then(null, $mock);
+ }
+
+ /** @test */
+ public function cancelShouldReturnNullForRejectedPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $adapter->reject();
+
+ $this->assertNull($adapter->promise()->cancel());
+ }
+
+ /** @test */
+ public function cancelShouldHaveNoEffectForRejectedPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter($this->expectCallableNever());
+
+ $adapter->reject();
+
+ $adapter->promise()->cancel();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/PromiseSettledTestTrait.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/PromiseSettledTestTrait.php
new file mode 100644
index 0000000..e363b6d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/PromiseSettledTestTrait.php
@@ -0,0 +1,86 @@
+<?php
+
+namespace React\Promise\PromiseTest;
+
+trait PromiseSettledTestTrait
+{
+ /**
+ * @return \React\Promise\PromiseAdapter\PromiseAdapterInterface
+ */
+ abstract public function getPromiseTestAdapter(callable $canceller = null);
+
+ /** @test */
+ public function thenShouldReturnAPromiseForSettledPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $adapter->settle();
+ $this->assertInstanceOf('React\\Promise\\PromiseInterface', $adapter->promise()->then());
+ }
+
+ /** @test */
+ public function thenShouldReturnAllowNullForSettledPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $adapter->settle();
+ $this->assertInstanceOf('React\\Promise\\PromiseInterface', $adapter->promise()->then(null, null, null));
+ }
+
+ /** @test */
+ public function cancelShouldReturnNullForSettledPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $adapter->settle();
+
+ $this->assertNull($adapter->promise()->cancel());
+ }
+
+ /** @test */
+ public function cancelShouldHaveNoEffectForSettledPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter($this->expectCallableNever());
+
+ $adapter->settle();
+
+ $adapter->promise()->cancel();
+ }
+
+ /** @test */
+ public function doneShouldReturnNullForSettledPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $adapter->settle();
+ $this->assertNull($adapter->promise()->done(null, function () {}));
+ }
+
+ /** @test */
+ public function doneShouldReturnAllowNullForSettledPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $adapter->settle();
+ $this->assertNull($adapter->promise()->done(null, function () {}, null));
+ }
+
+ /** @test */
+ public function progressShouldNotInvokeProgressHandlerForSettledPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $adapter->settle();
+ $adapter->promise()->progress($this->expectCallableNever());
+ $adapter->notify();
+ }
+
+ /** @test */
+ public function alwaysShouldReturnAPromiseForSettledPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $adapter->settle();
+ $this->assertInstanceOf('React\\Promise\\PromiseInterface', $adapter->promise()->always(function () {}));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/RejectTestTrait.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/RejectTestTrait.php
new file mode 100644
index 0000000..063f178
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/RejectTestTrait.php
@@ -0,0 +1,368 @@
+<?php
+
+namespace React\Promise\PromiseTest;
+
+use React\Promise;
+use React\Promise\Deferred;
+
+trait RejectTestTrait
+{
+ /**
+ * @return \React\Promise\PromiseAdapter\PromiseAdapterInterface
+ */
+ abstract public function getPromiseTestAdapter(callable $canceller = null);
+
+ /** @test */
+ public function rejectShouldRejectWithAnImmediateValue()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ $adapter->promise()
+ ->then($this->expectCallableNever(), $mock);
+
+ $adapter->reject(1);
+ }
+
+ /** @test */
+ public function rejectShouldRejectWithFulfilledPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ $adapter->promise()
+ ->then($this->expectCallableNever(), $mock);
+
+ $adapter->reject(Promise\resolve(1));
+ }
+
+ /** @test */
+ public function rejectShouldRejectWithRejectedPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ $adapter->promise()
+ ->then($this->expectCallableNever(), $mock);
+
+ $adapter->reject(Promise\reject(1));
+ }
+
+ /** @test */
+ public function rejectShouldForwardReasonWhenCallbackIsNull()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ $adapter->promise()
+ ->then(
+ $this->expectCallableNever()
+ )
+ ->then(
+ $this->expectCallableNever(),
+ $mock
+ );
+
+ $adapter->reject(1);
+ }
+
+ /** @test */
+ public function rejectShouldMakePromiseImmutable()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ $adapter->promise()
+ ->then(null, function ($value) use ($adapter) {
+ $adapter->reject(3);
+
+ return Promise\reject($value);
+ })
+ ->then(
+ $this->expectCallableNever(),
+ $mock
+ );
+
+ $adapter->reject(1);
+ $adapter->reject(2);
+ }
+
+ /** @test */
+ public function notifyShouldInvokeOtherwiseHandler()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ $adapter->promise()
+ ->otherwise($mock);
+
+ $adapter->reject(1);
+ }
+
+ /** @test */
+ public function doneShouldInvokeRejectionHandler()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ $this->assertNull($adapter->promise()->done(null, $mock));
+ $adapter->reject(1);
+ }
+
+ /** @test */
+ public function doneShouldThrowExceptionThrownByRejectionHandler()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $this->setExpectedException('\Exception', 'UnhandledRejectionException');
+
+ $this->assertNull($adapter->promise()->done(null, function () {
+ throw new \Exception('UnhandledRejectionException');
+ }));
+ $adapter->reject(1);
+ }
+
+ /** @test */
+ public function doneShouldThrowUnhandledRejectionExceptionWhenRejectedWithNonException()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $this->setExpectedException('React\\Promise\\UnhandledRejectionException');
+
+ $this->assertNull($adapter->promise()->done());
+ $adapter->reject(1);
+ }
+
+ /** @test */
+ public function doneShouldThrowUnhandledRejectionExceptionWhenRejectionHandlerRejects()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $this->setExpectedException('React\\Promise\\UnhandledRejectionException');
+
+ $this->assertNull($adapter->promise()->done(null, function () {
+ return \React\Promise\reject();
+ }));
+ $adapter->reject(1);
+ }
+
+ /** @test */
+ public function doneShouldThrowRejectionExceptionWhenRejectionHandlerRejectsWithException()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $this->setExpectedException('\Exception', 'UnhandledRejectionException');
+
+ $this->assertNull($adapter->promise()->done(null, function () {
+ return \React\Promise\reject(new \Exception('UnhandledRejectionException'));
+ }));
+ $adapter->reject(1);
+ }
+
+ /** @test */
+ public function doneShouldThrowUnhandledRejectionExceptionWhenRejectionHandlerRetunsPendingPromiseWhichRejectsLater()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $this->setExpectedException('React\\Promise\\UnhandledRejectionException');
+
+ $d = new Deferred();
+ $promise = $d->promise();
+
+ $this->assertNull($adapter->promise()->done(null, function () use ($promise) {
+ return $promise;
+ }));
+ $adapter->reject(1);
+ $d->reject(1);
+ }
+
+ /** @test */
+ public function doneShouldThrowExceptionProvidedAsRejectionValue()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $this->setExpectedException('\Exception', 'UnhandledRejectionException');
+
+ $this->assertNull($adapter->promise()->done());
+ $adapter->reject(new \Exception('UnhandledRejectionException'));
+ }
+
+ /** @test */
+ public function doneShouldThrowWithDeepNestingPromiseChains()
+ {
+ $this->setExpectedException('\Exception', 'UnhandledRejectionException');
+
+ $exception = new \Exception('UnhandledRejectionException');
+
+ $d = new Deferred();
+
+ $result = \React\Promise\resolve(\React\Promise\resolve($d->promise()->then(function () use ($exception) {
+ $d = new Deferred();
+ $d->resolve();
+
+ return \React\Promise\resolve($d->promise()->then(function () {}))->then(
+ function () use ($exception) {
+ throw $exception;
+ }
+ );
+ })));
+
+ $result->done();
+
+ $d->resolve();
+ }
+
+ /** @test */
+ public function doneShouldRecoverWhenRejectionHandlerCatchesException()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $this->assertNull($adapter->promise()->done(null, function (\Exception $e) {
+
+ }));
+ $adapter->reject(new \Exception('UnhandledRejectionException'));
+ }
+
+ /** @test */
+ public function alwaysShouldNotSuppressRejection()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $exception = new \Exception();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($exception));
+
+ $adapter->promise()
+ ->always(function () {})
+ ->then(null, $mock);
+
+ $adapter->reject($exception);
+ }
+
+ /** @test */
+ public function alwaysShouldNotSuppressRejectionWhenHandlerReturnsANonPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $exception = new \Exception();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($exception));
+
+ $adapter->promise()
+ ->always(function () {
+ return 1;
+ })
+ ->then(null, $mock);
+
+ $adapter->reject($exception);
+ }
+
+ /** @test */
+ public function alwaysShouldNotSuppressRejectionWhenHandlerReturnsAPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $exception = new \Exception();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($exception));
+
+ $adapter->promise()
+ ->always(function () {
+ return \React\Promise\resolve(1);
+ })
+ ->then(null, $mock);
+
+ $adapter->reject($exception);
+ }
+
+ /** @test */
+ public function alwaysShouldRejectWhenHandlerThrowsForRejection()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $exception = new \Exception();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($exception));
+
+ $adapter->promise()
+ ->always(function () use ($exception) {
+ throw $exception;
+ })
+ ->then(null, $mock);
+
+ $adapter->reject($exception);
+ }
+
+ /** @test */
+ public function alwaysShouldRejectWhenHandlerRejectsForRejection()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $exception = new \Exception();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($exception));
+
+ $adapter->promise()
+ ->always(function () use ($exception) {
+ return \React\Promise\reject($exception);
+ })
+ ->then(null, $mock);
+
+ $adapter->reject($exception);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/ResolveTestTrait.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/ResolveTestTrait.php
new file mode 100644
index 0000000..0736d35
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/PromiseTest/ResolveTestTrait.php
@@ -0,0 +1,312 @@
+<?php
+
+namespace React\Promise\PromiseTest;
+
+use React\Promise;
+
+trait ResolveTestTrait
+{
+ /**
+ * @return \React\Promise\PromiseAdapter\PromiseAdapterInterface
+ */
+ abstract public function getPromiseTestAdapter(callable $canceller = null);
+
+ /** @test */
+ public function resolveShouldResolve()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ $adapter->promise()
+ ->then($mock);
+
+ $adapter->resolve(1);
+ }
+
+ /** @test */
+ public function resolveShouldResolveWithPromisedValue()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ $adapter->promise()
+ ->then($mock);
+
+ $adapter->resolve(Promise\resolve(1));
+ }
+
+ /** @test */
+ public function resolveShouldRejectWhenResolvedWithRejectedPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ $adapter->promise()
+ ->then($this->expectCallableNever(), $mock);
+
+ $adapter->resolve(Promise\reject(1));
+ }
+
+ /** @test */
+ public function resolveShouldForwardValueWhenCallbackIsNull()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ $adapter->promise()
+ ->then(
+ null,
+ $this->expectCallableNever()
+ )
+ ->then(
+ $mock,
+ $this->expectCallableNever()
+ );
+
+ $adapter->resolve(1);
+ }
+
+ /** @test */
+ public function resolveShouldMakePromiseImmutable()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ $adapter->promise()
+ ->then(function ($value) use ($adapter) {
+ $adapter->resolve(3);
+
+ return $value;
+ })
+ ->then(
+ $mock,
+ $this->expectCallableNever()
+ );
+
+ $adapter->resolve(1);
+ $adapter->resolve(2);
+ }
+
+ /**
+ * @test
+ */
+ public function resolveShouldRejectWhenResolvedWithItself()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with(new \LogicException('Cannot resolve a promise with itself.'));
+
+ $adapter->promise()
+ ->then(
+ $this->expectCallableNever(),
+ $mock
+ );
+
+ $adapter->resolve($adapter->promise());
+ }
+
+ /**
+ * @test
+ */
+ public function resolveShouldRejectWhenResolvedWithAPromiseWhichFollowsItself()
+ {
+ $adapter1 = $this->getPromiseTestAdapter();
+ $adapter2 = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with(new \LogicException('Cannot resolve a promise with itself.'));
+
+ $promise1 = $adapter1->promise();
+
+ $promise2 = $adapter2->promise();
+
+ $promise2->then(
+ $this->expectCallableNever(),
+ $mock
+ );
+
+ $adapter1->resolve($promise2);
+ $adapter2->resolve($promise1);
+ }
+
+ /** @test */
+ public function doneShouldInvokeFulfillmentHandler()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo(1));
+
+ $this->assertNull($adapter->promise()->done($mock));
+ $adapter->resolve(1);
+ }
+
+ /** @test */
+ public function doneShouldThrowExceptionThrownFulfillmentHandler()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $this->setExpectedException('\Exception', 'UnhandledRejectionException');
+
+ $this->assertNull($adapter->promise()->done(function () {
+ throw new \Exception('UnhandledRejectionException');
+ }));
+ $adapter->resolve(1);
+ }
+
+ /** @test */
+ public function doneShouldThrowUnhandledRejectionExceptionWhenFulfillmentHandlerRejects()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $this->setExpectedException('React\\Promise\\UnhandledRejectionException');
+
+ $this->assertNull($adapter->promise()->done(function () {
+ return \React\Promise\reject();
+ }));
+ $adapter->resolve(1);
+ }
+
+ /** @test */
+ public function alwaysShouldNotSuppressValue()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $value = new \stdClass();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($value));
+
+ $adapter->promise()
+ ->always(function () {})
+ ->then($mock);
+
+ $adapter->resolve($value);
+ }
+
+ /** @test */
+ public function alwaysShouldNotSuppressValueWhenHandlerReturnsANonPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $value = new \stdClass();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($value));
+
+ $adapter->promise()
+ ->always(function () {
+ return 1;
+ })
+ ->then($mock);
+
+ $adapter->resolve($value);
+ }
+
+ /** @test */
+ public function alwaysShouldNotSuppressValueWhenHandlerReturnsAPromise()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $value = new \stdClass();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($value));
+
+ $adapter->promise()
+ ->always(function () {
+ return \React\Promise\resolve(1);
+ })
+ ->then($mock);
+
+ $adapter->resolve($value);
+ }
+
+ /** @test */
+ public function alwaysShouldRejectWhenHandlerThrowsForFulfillment()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $exception = new \Exception();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($exception));
+
+ $adapter->promise()
+ ->always(function () use ($exception) {
+ throw $exception;
+ })
+ ->then(null, $mock);
+
+ $adapter->resolve(1);
+ }
+
+ /** @test */
+ public function alwaysShouldRejectWhenHandlerRejectsForFulfillment()
+ {
+ $adapter = $this->getPromiseTestAdapter();
+
+ $exception = new \Exception();
+
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($this->identicalTo($exception));
+
+ $adapter->promise()
+ ->always(function () use ($exception) {
+ return \React\Promise\reject($exception);
+ })
+ ->then(null, $mock);
+
+ $adapter->resolve(1);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/RejectedPromiseTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/RejectedPromiseTest.php
new file mode 100644
index 0000000..c886b00
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/RejectedPromiseTest.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace React\Promise;
+
+use React\Promise\PromiseAdapter\CallbackPromiseAdapter;
+
+class RejectedPromiseTest extends TestCase
+{
+ use PromiseTest\PromiseSettledTestTrait,
+ PromiseTest\PromiseRejectedTestTrait;
+
+ public function getPromiseTestAdapter(callable $canceller = null)
+ {
+ $promise = null;
+
+ return new CallbackPromiseAdapter([
+ 'promise' => function () use (&$promise) {
+ if (!$promise) {
+ throw new \LogicException('RejectedPromise must be rejected before obtaining the promise');
+ }
+
+ return $promise;
+ },
+ 'resolve' => function () {
+ throw new \LogicException('You cannot call resolve() for React\Promise\RejectedPromise');
+ },
+ 'reject' => function ($reason = null) use (&$promise) {
+ if (!$promise) {
+ $promise = new RejectedPromise($reason);
+ }
+ },
+ 'notify' => function () {
+ // no-op
+ },
+ 'settle' => function ($reason = null) use (&$promise) {
+ if (!$promise) {
+ $promise = new RejectedPromise($reason);
+ }
+ },
+ ]);
+ }
+
+ /** @test */
+ public function shouldThrowExceptionIfConstructedWithAPromise()
+ {
+ $this->setExpectedException('\InvalidArgumentException');
+
+ return new RejectedPromise(new RejectedPromise());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/Stub/CallableStub.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/Stub/CallableStub.php
new file mode 100644
index 0000000..0120893
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/Stub/CallableStub.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace React\Promise\Stub;
+
+class CallableStub
+{
+ public function __invoke()
+ {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/TestCase.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/TestCase.php
new file mode 100644
index 0000000..c9274f4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/TestCase.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace React\Promise;
+
+class TestCase extends \PHPUnit_Framework_TestCase
+{
+ public function expectCallableExactly($amount)
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->exactly($amount))
+ ->method('__invoke');
+
+ return $mock;
+ }
+
+ public function expectCallableOnce()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke');
+
+ return $mock;
+ }
+
+ public function expectCallableNever()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->never())
+ ->method('__invoke');
+
+ return $mock;
+ }
+
+ public function createCallableMock()
+ {
+ return $this
+ ->getMockBuilder('React\\Promise\Stub\CallableStub')
+ ->getMock();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/bootstrap.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/bootstrap.php
new file mode 100644
index 0000000..9b7f872
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/bootstrap.php
@@ -0,0 +1,7 @@
+<?php
+
+$loader = @include __DIR__.'/../vendor/autoload.php';
+if (!$loader) {
+ $loader = require __DIR__.'/../../../../vendor/autoload.php';
+}
+$loader->addPsr4('React\\Promise\\', __DIR__);
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/fixtures/SimpleFulfilledTestPromise.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/fixtures/SimpleFulfilledTestPromise.php
new file mode 100644
index 0000000..ef4d530
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/fixtures/SimpleFulfilledTestPromise.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace React\Promise;
+
+class SimpleFulfilledTestPromise implements PromiseInterface
+{
+ public function then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null)
+ {
+ try {
+ if ($onFulfilled) {
+ $onFulfilled('foo');
+ }
+
+ return new self();
+ } catch (\Throwable $exception) {
+ return new RejectedPromise($exception);
+ } catch (\Exception $exception) {
+ return new RejectedPromise($exception);
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/fixtures/SimpleFulfilledTestThenable.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/fixtures/SimpleFulfilledTestThenable.php
new file mode 100644
index 0000000..3f66f63
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/fixtures/SimpleFulfilledTestThenable.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace React\Promise;
+
+class SimpleFulfilledTestThenable
+{
+ public function then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null)
+ {
+ try {
+ if ($onFulfilled) {
+ $onFulfilled('foo');
+ }
+
+ return new self();
+ } catch (\Throwable $exception) {
+ return new RejectedPromise($exception);
+ } catch (\Exception $exception) {
+ return new RejectedPromise($exception);
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/fixtures/SimpleRejectedTestPromise.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/fixtures/SimpleRejectedTestPromise.php
new file mode 100644
index 0000000..b30a226
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/fixtures/SimpleRejectedTestPromise.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace React\Promise;
+
+class SimpleRejectedTestPromise implements PromiseInterface
+{
+ public function then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null)
+ {
+ try {
+ if ($onRejected) {
+ $onRejected('foo');
+ }
+
+ return new self();
+ } catch (\Throwable $exception) {
+ return new RejectedPromise($exception);
+ } catch (\Exception $exception) {
+ return new RejectedPromise($exception);
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/fixtures/SimpleTestCancellable.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/fixtures/SimpleTestCancellable.php
new file mode 100644
index 0000000..f232a68
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/fixtures/SimpleTestCancellable.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace React\Promise;
+
+class SimpleTestCancellable
+{
+ public $cancelCalled = false;
+
+ public function cancel()
+ {
+ $this->cancelCalled = true;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/fixtures/SimpleTestCancellableThenable.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/fixtures/SimpleTestCancellableThenable.php
new file mode 100644
index 0000000..c0f1593
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/promise/tests/fixtures/SimpleTestCancellableThenable.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace React\Promise;
+
+class SimpleTestCancellableThenable
+{
+ public $cancelCalled = false;
+
+ public function then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null)
+ {
+ return new self();
+ }
+
+ public function cancel()
+ {
+ $this->cancelCalled = true;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/.gitignore b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/.gitignore
new file mode 100644
index 0000000..987e2a2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/.gitignore
@@ -0,0 +1,2 @@
+composer.lock
+vendor
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/.travis.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/.travis.yml
new file mode 100644
index 0000000..917dc0c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/.travis.yml
@@ -0,0 +1,49 @@
+language: php
+
+php:
+# - 5.3 # requires old distro, see below
+ - 5.4
+ - 5.5
+ - 5.6
+ - 7.0
+ - 7.1
+ - 7.2
+# - 7.0 # Mac OS X, ignore errors, see below
+ - hhvm # ignore errors, see below
+
+# lock distro so new future defaults will not break the build
+dist: trusty
+
+matrix:
+ include:
+ - php: 5.3
+ dist: precise
+ include:
+ - os: osx
+ language: generic
+ php: 7.0 # just to look right on travis
+ env:
+ - PACKAGE: php70
+ allow_failures:
+ - php: hhvm
+ - os: osx
+
+sudo: false
+
+install:
+ # OSX install inspired by https://github.com/kiler129/TravisCI-OSX-PHP
+ - |
+ if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
+ brew tap homebrew/homebrew-php
+ echo "Installing PHP ..."
+ brew install "${PACKAGE}"
+ brew install "${PACKAGE}"-xdebug
+ brew link "${PACKAGE}"
+ echo "Installing composer ..."
+ curl -s http://getcomposer.org/installer | php
+ mv composer.phar /usr/local/bin/composer
+ fi
+ - composer install --no-interaction
+
+script:
+ - ./vendor/bin/phpunit --coverage-text
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/CHANGELOG.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/CHANGELOG.md
new file mode 100644
index 0000000..03c2eec
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/CHANGELOG.md
@@ -0,0 +1,451 @@
+# Changelog
+
+## 0.8.10 (2018-02-28)
+
+* Feature: Update DNS dependency to support loading system default DNS
+ nameserver config on all supported platforms
+ (`/etc/resolv.conf` on Unix/Linux/Mac/Docker/WSL and WMIC on Windows)
+ (#152 by @clue)
+
+ This means that connecting to hosts that are managed by a local DNS server,
+ such as a corporate DNS server or when using Docker containers, will now
+ work as expected across all platforms with no changes required:
+
+ ```php
+ $connector = new Connector($loop);
+ $connector->connect('intranet.example:80')->then(function ($connection) {
+ // …
+ });
+ ```
+
+## 0.8.9 (2018-01-18)
+
+* Feature: Support explicitly choosing TLS version to negotiate with remote side
+ by respecting `crypto_method` context parameter for all classes.
+ (#149 by @clue)
+
+ By default, all connector and server classes support TLSv1.0+ and exclude
+ support for legacy SSLv2/SSLv3. As of PHP 5.6+ you can also explicitly
+ choose the TLS version you want to negotiate with the remote side:
+
+ ```php
+ // new: now supports 'crypto_method` context parameter for all classes
+ $connector = new Connector($loop, array(
+ 'tls' => array(
+ 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
+ )
+ ));
+ ```
+
+* Minor internal clean up to unify class imports
+ (#148 by @clue)
+
+## 0.8.8 (2018-01-06)
+
+* Improve test suite by adding test group to skip integration tests relying on
+ internet connection and fix minor documentation typo.
+ (#146 by @clue and #145 by @cn007b)
+
+## 0.8.7 (2017-12-24)
+
+* Fix: Fix closing socket resource before removing from loop
+ (#141 by @clue)
+
+ This fixes the root cause of an uncaught `Exception` that only manifested
+ itself after the recent Stream v0.7.4 component update and only if you're
+ using `ext-event` (`ExtEventLoop`).
+
+* Improve test suite by testing against PHP 7.2
+ (#140 by @carusogabriel)
+
+## 0.8.6 (2017-11-18)
+
+* Feature: Add Unix domain socket (UDS) support to `Server` with `unix://` URI scheme
+ and add advanced `UnixServer` class.
+ (#120 by @andig)
+
+ ```php
+ // new: Server now supports "unix://" scheme
+ $server = new Server('unix:///tmp/server.sock', $loop);
+
+ // new: advanced usage
+ $server = new UnixServer('/tmp/server.sock', $loop);
+ ```
+
+* Restructure examples to ease getting started
+ (#136 by @clue)
+
+* Improve test suite by adding forward compatibility with PHPUnit 6 and
+ ignore Mac OS X test failures for now until Travis tests work again
+ (#133 by @gabriel-caruso and #134 by @clue)
+
+## 0.8.5 (2017-10-23)
+
+* Fix: Work around PHP bug with Unix domain socket (UDS) paths for Mac OS X
+ (#123 by @andig)
+
+* Fix: Fix `SecureServer` to return `null` URI if server socket is already closed
+ (#129 by @clue)
+
+* Improve test suite by adding forward compatibility with PHPUnit v5 and
+ forward compatibility with upcoming EventLoop releases in tests and
+ test Mac OS X on Travis
+ (#122 by @andig and #125, #127 and #130 by @clue)
+
+* Readme improvements
+ (#118 by @jsor)
+
+## 0.8.4 (2017-09-16)
+
+* Feature: Add `FixedUriConnector` decorator to use fixed, preconfigured URI instead
+ (#117 by @clue)
+
+ This can be useful for consumers that do not support certain URIs, such as
+ when you want to explicitly connect to a Unix domain socket (UDS) path
+ instead of connecting to a default address assumed by an higher-level API:
+
+ ```php
+ $connector = new FixedUriConnector(
+ 'unix:///var/run/docker.sock',
+ new UnixConnector($loop)
+ );
+
+ // destination will be ignored, actually connects to Unix domain socket
+ $promise = $connector->connect('localhost:80');
+ ```
+
+## 0.8.3 (2017-09-08)
+
+* Feature: Reduce memory consumption for failed connections
+ (#113 by @valga)
+
+* Fix: Work around write chunk size for TLS streams for PHP < 7.1.14
+ (#114 by @clue)
+
+## 0.8.2 (2017-08-25)
+
+* Feature: Update DNS dependency to support hosts file on all platforms
+ (#112 by @clue)
+
+ This means that connecting to hosts such as `localhost` will now work as
+ expected across all platforms with no changes required:
+
+ ```php
+ $connector = new Connector($loop);
+ $connector->connect('localhost:8080')->then(function ($connection) {
+ // …
+ });
+ ```
+
+## 0.8.1 (2017-08-15)
+
+* Feature: Forward compatibility with upcoming EventLoop v1.0 and v0.5 and
+ target evenement 3.0 a long side 2.0 and 1.0
+ (#104 by @clue and #111 by @WyriHaximus)
+
+* Improve test suite by locking Travis distro so new defaults will not break the build and
+ fix HHVM build for now again and ignore future HHVM build errors
+ (#109 and #110 by @clue)
+
+* Minor documentation fixes
+ (#103 by @christiaan and #108 by @hansott)
+
+## 0.8.0 (2017-05-09)
+
+* Feature: New `Server` class now acts as a facade for existing server classes
+ and renamed old `Server` to `TcpServer` for advanced usage.
+ (#96 and #97 by @clue)
+
+ The `Server` class is now the main class in this package that implements the
+ `ServerInterface` and allows you to accept incoming streaming connections,
+ such as plaintext TCP/IP or secure TLS connection streams.
+
+ > This is not a BC break and consumer code does not have to be updated.
+
+* Feature / BC break: All addresses are now URIs that include the URI scheme
+ (#98 by @clue)
+
+ ```diff
+ - $parts = parse_url('tcp://' . $conn->getRemoteAddress());
+ + $parts = parse_url($conn->getRemoteAddress());
+ ```
+
+* Fix: Fix `unix://` addresses for Unix domain socket (UDS) paths
+ (#100 by @clue)
+
+* Feature: Forward compatibility with Stream v1.0 and v0.7
+ (#99 by @clue)
+
+## 0.7.2 (2017-04-24)
+
+* Fix: Work around latest PHP 7.0.18 and 7.1.4 no longer accepting full URIs
+ (#94 by @clue)
+
+## 0.7.1 (2017-04-10)
+
+* Fix: Ignore HHVM errors when closing connection that is already closing
+ (#91 by @clue)
+
+## 0.7.0 (2017-04-10)
+
+* Feature: Merge SocketClient component into this component
+ (#87 by @clue)
+
+ This means that this package now provides async, streaming plaintext TCP/IP
+ and secure TLS socket server and client connections for ReactPHP.
+
+ ```
+ $connector = new React\Socket\Connector($loop);
+ $connector->connect('google.com:80')->then(function (ConnectionInterface $conn) {
+ $connection->write('…');
+ });
+ ```
+
+ Accordingly, the `ConnectionInterface` is now used to represent both incoming
+ server side connections as well as outgoing client side connections.
+
+ If you've previously used the SocketClient component to establish outgoing
+ client connections, upgrading should take no longer than a few minutes.
+ All classes have been merged as-is from the latest `v0.7.0` release with no
+ other changes, so you can simply update your code to use the updated namespace
+ like this:
+
+ ```php
+ // old from SocketClient component and namespace
+ $connector = new React\SocketClient\Connector($loop);
+ $connector->connect('google.com:80')->then(function (ConnectionInterface $conn) {
+ $connection->write('…');
+ });
+
+ // new
+ $connector = new React\Socket\Connector($loop);
+ $connector->connect('google.com:80')->then(function (ConnectionInterface $conn) {
+ $connection->write('…');
+ });
+ ```
+
+## 0.6.0 (2017-04-04)
+
+* Feature: Add `LimitingServer` to limit and keep track of open connections
+ (#86 by @clue)
+
+ ```php
+ $server = new Server(0, $loop);
+ $server = new LimitingServer($server, 100);
+
+ $server->on('connection', function (ConnectionInterface $connection) {
+ $connection->write('hello there!' . PHP_EOL);
+ …
+ });
+ ```
+
+* Feature / BC break: Add `pause()` and `resume()` methods to limit active
+ connections
+ (#84 by @clue)
+
+ ```php
+ $server = new Server(0, $loop);
+ $server->pause();
+
+ $loop->addTimer(1.0, function() use ($server) {
+ $server->resume();
+ });
+ ```
+
+## 0.5.1 (2017-03-09)
+
+* Feature: Forward compatibility with Stream v0.5 and upcoming v0.6
+ (#79 by @clue)
+
+## 0.5.0 (2017-02-14)
+
+* Feature / BC break: Replace `listen()` call with URIs passed to constructor
+ and reject listening on hostnames with `InvalidArgumentException`
+ and replace `ConnectionException` with `RuntimeException` for consistency
+ (#61, #66 and #72 by @clue)
+
+ ```php
+ // old
+ $server = new Server($loop);
+ $server->listen(8080);
+
+ // new
+ $server = new Server(8080, $loop);
+ ```
+
+ Similarly, you can now pass a full listening URI to the constructor to change
+ the listening host:
+
+ ```php
+ // old
+ $server = new Server($loop);
+ $server->listen(8080, '127.0.0.1');
+
+ // new
+ $server = new Server('127.0.0.1:8080', $loop);
+ ```
+
+ Trying to start listening on (DNS) host names will now throw an
+ `InvalidArgumentException`, use IP addresses instead:
+
+ ```php
+ // old
+ $server = new Server($loop);
+ $server->listen(8080, 'localhost');
+
+ // new
+ $server = new Server('127.0.0.1:8080', $loop);
+ ```
+
+ If trying to listen fails (such as if port is already in use or port below
+ 1024 may require root access etc.), it will now throw a `RuntimeException`,
+ the `ConnectionException` class has been removed:
+
+ ```php
+ // old: throws React\Socket\ConnectionException
+ $server = new Server($loop);
+ $server->listen(80);
+
+ // new: throws RuntimeException
+ $server = new Server(80, $loop);
+ ```
+
+* Feature / BC break: Rename `shutdown()` to `close()` for consistency throughout React
+ (#62 by @clue)
+
+ ```php
+ // old
+ $server->shutdown();
+
+ // new
+ $server->close();
+ ```
+
+* Feature / BC break: Replace `getPort()` with `getAddress()`
+ (#67 by @clue)
+
+ ```php
+ // old
+ echo $server->getPort(); // 8080
+
+ // new
+ echo $server->getAddress(); // 127.0.0.1:8080
+ ```
+
+* Feature / BC break: `getRemoteAddress()` returns full address instead of only IP
+ (#65 by @clue)
+
+ ```php
+ // old
+ echo $connection->getRemoteAddress(); // 192.168.0.1
+
+ // new
+ echo $connection->getRemoteAddress(); // 192.168.0.1:51743
+ ```
+
+* Feature / BC break: Add `getLocalAddress()` method
+ (#68 by @clue)
+
+ ```php
+ echo $connection->getLocalAddress(); // 127.0.0.1:8080
+ ```
+
+* BC break: The `Server` and `SecureServer` class are now marked `final`
+ and you can no longer `extend` them
+ (which was never documented or recommended anyway).
+ Public properties and event handlers are now internal only.
+ Please use composition instead of extension.
+ (#71, #70 and #69 by @clue)
+
+## 0.4.6 (2017-01-26)
+
+* Feature: Support socket context options passed to `Server`
+ (#64 by @clue)
+
+* Fix: Properly return `null` for unknown addresses
+ (#63 by @clue)
+
+* Improve documentation for `ServerInterface` and lock test suite requirements
+ (#60 by @clue, #57 by @shaunbramley)
+
+## 0.4.5 (2017-01-08)
+
+* Feature: Add `SecureServer` for secure TLS connections
+ (#55 by @clue)
+
+* Add functional integration tests
+ (#54 by @clue)
+
+## 0.4.4 (2016-12-19)
+
+* Feature / Fix: `ConnectionInterface` should extend `DuplexStreamInterface` + documentation
+ (#50 by @clue)
+
+* Feature / Fix: Improve test suite and switch to normal stream handler
+ (#51 by @clue)
+
+* Feature: Add examples
+ (#49 by @clue)
+
+## 0.4.3 (2016-03-01)
+
+* Bug fix: Suppress errors on stream_socket_accept to prevent PHP from crashing
+* Support for PHP7 and HHVM
+* Support PHP 5.3 again
+
+## 0.4.2 (2014-05-25)
+
+* Verify stream is a valid resource in Connection
+
+## 0.4.1 (2014-04-13)
+
+* Bug fix: Check read buffer for data before shutdown signal and end emit (@ArtyDev)
+* Bug fix: v0.3.4 changes merged for v0.4.1
+
+## 0.3.4 (2014-03-30)
+
+* Bug fix: Reset socket to non-blocking after shutting down (PHP bug)
+
+## 0.4.0 (2014-02-02)
+
+* BC break: Bump minimum PHP version to PHP 5.4, remove 5.3 specific hacks
+* BC break: Update to React/Promise 2.0
+* BC break: Update to Evenement 2.0
+* Dependency: Autoloading and filesystem structure now PSR-4 instead of PSR-0
+* Bump React dependencies to v0.4
+
+## 0.3.3 (2013-07-08)
+
+* Version bump
+
+## 0.3.2 (2013-05-10)
+
+* Version bump
+
+## 0.3.1 (2013-04-21)
+
+* Feature: Support binding to IPv6 addresses (@clue)
+
+## 0.3.0 (2013-04-14)
+
+* Bump React dependencies to v0.3
+
+## 0.2.6 (2012-12-26)
+
+* Version bump
+
+## 0.2.3 (2012-11-14)
+
+* Version bump
+
+## 0.2.0 (2012-09-10)
+
+* Bump React dependencies to v0.2
+
+## 0.1.1 (2012-07-12)
+
+* Version bump
+
+## 0.1.0 (2012-07-11)
+
+* First tagged release
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/LICENSE b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/LICENSE
new file mode 100644
index 0000000..a808108
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2012 Igor Wiedler, Chris Boden
+
+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.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/README.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/README.md
new file mode 100644
index 0000000..e8b53a0
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/README.md
@@ -0,0 +1,1419 @@
+# Socket
+
+[![Build Status](https://travis-ci.org/reactphp/socket.svg?branch=master)](https://travis-ci.org/reactphp/socket)
+
+Async, streaming plaintext TCP/IP and secure TLS socket server and client
+connections for [ReactPHP](https://reactphp.org/).
+
+The socket library provides re-usable interfaces for a socket-layer
+server and client based on the [`EventLoop`](https://github.com/reactphp/event-loop)
+and [`Stream`](https://github.com/reactphp/stream) components.
+Its server component allows you to build networking servers that accept incoming
+connections from networking clients (such as an HTTP server).
+Its client component allows you to build networking clients that establish
+outgoing connections to networking servers (such as an HTTP or database client).
+This library provides async, streaming means for all of this, so you can
+handle multiple concurrent connections without blocking.
+
+**Table of Contents**
+
+* [Quickstart example](#quickstart-example)
+* [Connection usage](#connection-usage)
+ * [ConnectionInterface](#connectioninterface)
+ * [getRemoteAddress()](#getremoteaddress)
+ * [getLocalAddress()](#getlocaladdress)
+* [Server usage](#server-usage)
+ * [ServerInterface](#serverinterface)
+ * [connection event](#connection-event)
+ * [error event](#error-event)
+ * [getAddress()](#getaddress)
+ * [pause()](#pause)
+ * [resume()](#resume)
+ * [close()](#close)
+ * [Server](#server)
+ * [Advanced server usage](#advanced-server-usage)
+ * [TcpServer](#tcpserver)
+ * [SecureServer](#secureserver)
+ * [UnixServer](#unixserver)
+ * [LimitingServer](#limitingserver)
+ * [getConnections()](#getconnections)
+* [Client usage](#client-usage)
+ * [ConnectorInterface](#connectorinterface)
+ * [connect()](#connect)
+ * [Connector](#connector)
+ * [Advanced client usage](#advanced-client-usage)
+ * [TcpConnector](#tcpconnector)
+ * [DnsConnector](#dnsconnector)
+ * [SecureConnector](#secureconnector)
+ * [TimeoutConnector](#timeoutconnector)
+ * [UnixConnector](#unixconnector)
+ * [FixUriConnector](#fixeduriconnector)
+* [Install](#install)
+* [Tests](#tests)
+* [License](#license)
+
+## Quickstart example
+
+Here is a server that closes the connection if you send it anything:
+
+```php
+$loop = React\EventLoop\Factory::create();
+$socket = new React\Socket\Server('127.0.0.1:8080', $loop);
+
+$socket->on('connection', function (ConnectionInterface $conn) {
+ $conn->write("Hello " . $conn->getRemoteAddress() . "!\n");
+ $conn->write("Welcome to this amazing server!\n");
+ $conn->write("Here's a tip: don't say anything.\n");
+
+ $conn->on('data', function ($data) use ($conn) {
+ $conn->close();
+ });
+});
+
+$loop->run();
+```
+
+See also the [examples](examples).
+
+Here's a client that outputs the output of said server and then attempts to
+send it a string:
+
+```php
+$loop = React\EventLoop\Factory::create();
+$connector = new React\Socket\Connector($loop);
+
+$connector->connect('127.0.0.1:8080')->then(function (ConnectionInterface $conn) use ($loop) {
+ $conn->pipe(new React\Stream\WritableResourceStream(STDOUT, $loop));
+ $conn->write("Hello World!\n");
+});
+
+$loop->run();
+```
+
+## Connection usage
+
+### ConnectionInterface
+
+The `ConnectionInterface` is used to represent any incoming and outgoing
+connection, such as a normal TCP/IP connection.
+
+An incoming or outgoing connection is a duplex stream (both readable and
+writable) that implements React's
+[`DuplexStreamInterface`](https://github.com/reactphp/stream#duplexstreaminterface).
+It contains additional properties for the local and remote address (client IP)
+where this connection has been established to/from.
+
+Most commonly, instances implementing this `ConnectionInterface` are emitted
+by all classes implementing the [`ServerInterface`](#serverinterface) and
+used by all classes implementing the [`ConnectorInterface`](#connectorinterface).
+
+Because the `ConnectionInterface` implements the underlying
+[`DuplexStreamInterface`](https://github.com/reactphp/stream#duplexstreaminterface)
+you can use any of its events and methods as usual:
+
+```php
+$connection->on('data', function ($chunk) {
+ echo $chunk;
+});
+
+$connection->on('end', function () {
+ echo 'ended';
+});
+
+$connection->on('error', function (Exception $e) {
+ echo 'error: ' . $e->getMessage();
+});
+
+$connection->on('close', function () {
+ echo 'closed';
+});
+
+$connection->write($data);
+$connection->end($data = null);
+$connection->close();
+// …
+```
+
+For more details, see the
+[`DuplexStreamInterface`](https://github.com/reactphp/stream#duplexstreaminterface).
+
+#### getRemoteAddress()
+
+The `getRemoteAddress(): ?string` method returns the full remote address
+(URI) where this connection has been established with.
+
+```php
+$address = $connection->getRemoteAddress();
+echo 'Connection with ' . $address . PHP_EOL;
+```
+
+If the remote address can not be determined or is unknown at this time (such as
+after the connection has been closed), it MAY return a `NULL` value instead.
+
+Otherwise, it will return the full address (URI) as a string value, such
+as `tcp://127.0.0.1:8080`, `tcp://[::1]:80`, `tls://127.0.0.1:443`,
+`unix://example.sock` or `unix:///path/to/example.sock`.
+Note that individual URI components are application specific and depend
+on the underlying transport protocol.
+
+If this is a TCP/IP based connection and you only want the remote IP, you may
+use something like this:
+
+```php
+$address = $connection->getRemoteAddress();
+$ip = trim(parse_url($address, PHP_URL_HOST), '[]');
+echo 'Connection with ' . $ip . PHP_EOL;
+```
+
+#### getLocalAddress()
+
+The `getLocalAddress(): ?string` method returns the full local address
+(URI) where this connection has been established with.
+
+```php
+$address = $connection->getLocalAddress();
+echo 'Connection with ' . $address . PHP_EOL;
+```
+
+If the local address can not be determined or is unknown at this time (such as
+after the connection has been closed), it MAY return a `NULL` value instead.
+
+Otherwise, it will return the full address (URI) as a string value, such
+as `tcp://127.0.0.1:8080`, `tcp://[::1]:80`, `tls://127.0.0.1:443`,
+`unix://example.sock` or `unix:///path/to/example.sock`.
+Note that individual URI components are application specific and depend
+on the underlying transport protocol.
+
+This method complements the [`getRemoteAddress()`](#getremoteaddress) method,
+so they should not be confused.
+
+If your `TcpServer` instance is listening on multiple interfaces (e.g. using
+the address `0.0.0.0`), you can use this method to find out which interface
+actually accepted this connection (such as a public or local interface).
+
+If your system has multiple interfaces (e.g. a WAN and a LAN interface),
+you can use this method to find out which interface was actually
+used for this connection.
+
+## Server usage
+
+### ServerInterface
+
+The `ServerInterface` is responsible for providing an interface for accepting
+incoming streaming connections, such as a normal TCP/IP connection.
+
+Most higher-level components (such as a HTTP server) accept an instance
+implementing this interface to accept incoming streaming connections.
+This is usually done via dependency injection, so it's fairly simple to actually
+swap this implementation against any other implementation of this interface.
+This means that you SHOULD typehint against this interface instead of a concrete
+implementation of this interface.
+
+Besides defining a few methods, this interface also implements the
+[`EventEmitterInterface`](https://github.com/igorw/evenement)
+which allows you to react to certain events.
+
+#### connection event
+
+The `connection` event will be emitted whenever a new connection has been
+established, i.e. a new client connects to this server socket:
+
+```php
+$server->on('connection', function (ConnectionInterface $connection) {
+ echo 'new connection' . PHP_EOL;
+});
+```
+
+See also the [`ConnectionInterface`](#connectioninterface) for more details
+about handling the incoming connection.
+
+#### error event
+
+The `error` event will be emitted whenever there's an error accepting a new
+connection from a client.
+
+```php
+$server->on('error', function (Exception $e) {
+ echo 'error: ' . $e->getMessage() . PHP_EOL;
+});
+```
+
+Note that this is not a fatal error event, i.e. the server keeps listening for
+new connections even after this event.
+
+
+#### getAddress()
+
+The `getAddress(): ?string` method can be used to
+return the full address (URI) this server is currently listening on.
+
+```php
+$address = $server->getAddress();
+echo 'Server listening on ' . $address . PHP_EOL;
+```
+
+If the address can not be determined or is unknown at this time (such as
+after the socket has been closed), it MAY return a `NULL` value instead.
+
+Otherwise, it will return the full address (URI) as a string value, such
+as `tcp://127.0.0.1:8080`, `tcp://[::1]:80`, `tls://127.0.0.1:443`
+`unix://example.sock` or `unix:///path/to/example.sock`.
+Note that individual URI components are application specific and depend
+on the underlying transport protocol.
+
+If this is a TCP/IP based server and you only want the local port, you may
+use something like this:
+
+```php
+$address = $server->getAddress();
+$port = parse_url($address, PHP_URL_PORT);
+echo 'Server listening on port ' . $port . PHP_EOL;
+```
+
+#### pause()
+
+The `pause(): void` method can be used to
+pause accepting new incoming connections.
+
+Removes the socket resource from the EventLoop and thus stop accepting
+new connections. Note that the listening socket stays active and is not
+closed.
+
+This means that new incoming connections will stay pending in the
+operating system backlog until its configurable backlog is filled.
+Once the backlog is filled, the operating system may reject further
+incoming connections until the backlog is drained again by resuming
+to accept new connections.
+
+Once the server is paused, no futher `connection` events SHOULD
+be emitted.
+
+```php
+$server->pause();
+
+$server->on('connection', assertShouldNeverCalled());
+```
+
+This method is advisory-only, though generally not recommended, the
+server MAY continue emitting `connection` events.
+
+Unless otherwise noted, a successfully opened server SHOULD NOT start
+in paused state.
+
+You can continue processing events by calling `resume()` again.
+
+Note that both methods can be called any number of times, in particular
+calling `pause()` more than once SHOULD NOT have any effect.
+Similarly, calling this after `close()` is a NO-OP.
+
+#### resume()
+
+The `resume(): void` method can be used to
+resume accepting new incoming connections.
+
+Re-attach the socket resource to the EventLoop after a previous `pause()`.
+
+```php
+$server->pause();
+
+$loop->addTimer(1.0, function () use ($server) {
+ $server->resume();
+});
+```
+
+Note that both methods can be called any number of times, in particular
+calling `resume()` without a prior `pause()` SHOULD NOT have any effect.
+Similarly, calling this after `close()` is a NO-OP.
+
+#### close()
+
+The `close(): void` method can be used to
+shut down this listening socket.
+
+This will stop listening for new incoming connections on this socket.
+
+```php
+echo 'Shutting down server socket' . PHP_EOL;
+$server->close();
+```
+
+Calling this method more than once on the same instance is a NO-OP.
+
+### Server
+
+The `Server` class is the main class in this package that implements the
+[`ServerInterface`](#serverinterface) and allows you to accept incoming
+streaming connections, such as plaintext TCP/IP or secure TLS connection streams.
+Connections can also be accepted on Unix domain sockets.
+
+```php
+$server = new Server(8080, $loop);
+```
+
+As above, the `$uri` parameter can consist of only a port, in which case the
+server will default to listening on the localhost address `127.0.0.1`,
+which means it will not be reachable from outside of this system.
+
+In order to use a random port assignment, you can use the port `0`:
+
+```php
+$server = new Server(0, $loop);
+$address = $server->getAddress();
+```
+
+In order to change the host the socket is listening on, you can provide an IP
+address through the first parameter provided to the constructor, optionally
+preceded by the `tcp://` scheme:
+
+```php
+$server = new Server('192.168.0.1:8080', $loop);
+```
+
+If you want to listen on an IPv6 address, you MUST enclose the host in square
+brackets:
+
+```php
+$server = new Server('[::1]:8080', $loop);
+```
+
+To listen on a Unix domain socket (UDS) path, you MUST prefix the URI with the
+`unix://` scheme:
+
+```php
+$server = new Server('unix:///tmp/server.sock', $loop);
+```
+
+If the given URI is invalid, does not contain a port, any other scheme or if it
+contains a hostname, it will throw an `InvalidArgumentException`:
+
+```php
+// throws InvalidArgumentException due to missing port
+$server = new Server('127.0.0.1', $loop);
+```
+
+If the given URI appears to be valid, but listening on it fails (such as if port
+is already in use or port below 1024 may require root access etc.), it will
+throw a `RuntimeException`:
+
+```php
+$first = new Server(8080, $loop);
+
+// throws RuntimeException because port is already in use
+$second = new Server(8080, $loop);
+```
+
+> Note that these error conditions may vary depending on your system and/or
+ configuration.
+ See the exception message and code for more details about the actual error
+ condition.
+
+Optionally, you can specify [TCP socket context options](http://php.net/manual/en/context.socket.php)
+for the underlying stream socket resource like this:
+
+```php
+$server = new Server('[::1]:8080', $loop, array(
+ 'tcp' => array(
+ 'backlog' => 200,
+ 'so_reuseport' => true,
+ 'ipv6_v6only' => true
+ )
+));
+```
+
+> Note that available [socket context options](http://php.net/manual/en/context.socket.php),
+ their defaults and effects of changing these may vary depending on your system
+ and/or PHP version.
+ Passing unknown context options has no effect.
+ For BC reasons, you can also pass the TCP socket context options as a simple
+ array without wrapping this in another array under the `tcp` key.
+
+You can start a secure TLS (formerly known as SSL) server by simply prepending
+the `tls://` URI scheme.
+Internally, it will wait for plaintext TCP/IP connections and then performs a
+TLS handshake for each connection.
+It thus requires valid [TLS context options](http://php.net/manual/en/context.ssl.php),
+which in its most basic form may look something like this if you're using a
+PEM encoded certificate file:
+
+```php
+$server = new Server('tls://127.0.0.1:8080', $loop, array(
+ 'tls' => array(
+ 'local_cert' => 'server.pem'
+ )
+));
+```
+
+> Note that the certificate file will not be loaded on instantiation but when an
+ incoming connection initializes its TLS context.
+ This implies that any invalid certificate file paths or contents will only cause
+ an `error` event at a later time.
+
+If your private key is encrypted with a passphrase, you have to specify it
+like this:
+
+```php
+$server = new Server('tls://127.0.0.1:8000', $loop, array(
+ 'tls' => array(
+ 'local_cert' => 'server.pem',
+ 'passphrase' => 'secret'
+ )
+));
+```
+
+By default, this server supports TLSv1.0+ and excludes support for legacy
+SSLv2/SSLv3. As of PHP 5.6+ you can also explicitly choose the TLS version you
+want to negotiate with the remote side:
+
+```php
+$server = new Server('tls://127.0.0.1:8000', $loop, array(
+ 'tls' => array(
+ 'local_cert' => 'server.pem',
+ 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER
+ )
+));
+```
+
+> Note that available [TLS context options](http://php.net/manual/en/context.ssl.php),
+ their defaults and effects of changing these may vary depending on your system
+ and/or PHP version.
+ The outer context array allows you to also use `tcp` (and possibly more)
+ context options at the same time.
+ Passing unknown context options has no effect.
+ If you do not use the `tls://` scheme, then passing `tls` context options
+ has no effect.
+
+Whenever a client connects, it will emit a `connection` event with a connection
+instance implementing [`ConnectionInterface`](#connectioninterface):
+
+```php
+$server->on('connection', function (ConnectionInterface $connection) {
+ echo 'Plaintext connection from ' . $connection->getRemoteAddress() . PHP_EOL;
+
+ $connection->write('hello there!' . PHP_EOL);
+ …
+});
+```
+
+See also the [`ServerInterface`](#serverinterface) for more details.
+
+> Note that the `Server` class is a concrete implementation for TCP/IP sockets.
+ If you want to typehint in your higher-level protocol implementation, you SHOULD
+ use the generic [`ServerInterface`](#serverinterface) instead.
+
+### Advanced server usage
+
+#### TcpServer
+
+The `TcpServer` class implements the [`ServerInterface`](#serverinterface) and
+is responsible for accepting plaintext TCP/IP connections.
+
+```php
+$server = new TcpServer(8080, $loop);
+```
+
+As above, the `$uri` parameter can consist of only a port, in which case the
+server will default to listening on the localhost address `127.0.0.1`,
+which means it will not be reachable from outside of this system.
+
+In order to use a random port assignment, you can use the port `0`:
+
+```php
+$server = new TcpServer(0, $loop);
+$address = $server->getAddress();
+```
+
+In order to change the host the socket is listening on, you can provide an IP
+address through the first parameter provided to the constructor, optionally
+preceded by the `tcp://` scheme:
+
+```php
+$server = new TcpServer('192.168.0.1:8080', $loop);
+```
+
+If you want to listen on an IPv6 address, you MUST enclose the host in square
+brackets:
+
+```php
+$server = new TcpServer('[::1]:8080', $loop);
+```
+
+If the given URI is invalid, does not contain a port, any other scheme or if it
+contains a hostname, it will throw an `InvalidArgumentException`:
+
+```php
+// throws InvalidArgumentException due to missing port
+$server = new TcpServer('127.0.0.1', $loop);
+```
+
+If the given URI appears to be valid, but listening on it fails (such as if port
+is already in use or port below 1024 may require root access etc.), it will
+throw a `RuntimeException`:
+
+```php
+$first = new TcpServer(8080, $loop);
+
+// throws RuntimeException because port is already in use
+$second = new TcpServer(8080, $loop);
+```
+
+> Note that these error conditions may vary depending on your system and/or
+configuration.
+See the exception message and code for more details about the actual error
+condition.
+
+Optionally, you can specify [socket context options](http://php.net/manual/en/context.socket.php)
+for the underlying stream socket resource like this:
+
+```php
+$server = new TcpServer('[::1]:8080', $loop, array(
+ 'backlog' => 200,
+ 'so_reuseport' => true,
+ 'ipv6_v6only' => true
+));
+```
+
+> Note that available [socket context options](http://php.net/manual/en/context.socket.php),
+their defaults and effects of changing these may vary depending on your system
+and/or PHP version.
+Passing unknown context options has no effect.
+
+Whenever a client connects, it will emit a `connection` event with a connection
+instance implementing [`ConnectionInterface`](#connectioninterface):
+
+```php
+$server->on('connection', function (ConnectionInterface $connection) {
+ echo 'Plaintext connection from ' . $connection->getRemoteAddress() . PHP_EOL;
+
+ $connection->write('hello there!' . PHP_EOL);
+ …
+});
+```
+
+See also the [`ServerInterface`](#serverinterface) for more details.
+
+#### SecureServer
+
+The `SecureServer` class implements the [`ServerInterface`](#serverinterface)
+and is responsible for providing a secure TLS (formerly known as SSL) server.
+
+It does so by wrapping a [`TcpServer`](#tcpserver) instance which waits for plaintext
+TCP/IP connections and then performs a TLS handshake for each connection.
+It thus requires valid [TLS context options](http://php.net/manual/en/context.ssl.php),
+which in its most basic form may look something like this if you're using a
+PEM encoded certificate file:
+
+```php
+$server = new TcpServer(8000, $loop);
+$server = new SecureServer($server, $loop, array(
+ 'local_cert' => 'server.pem'
+));
+```
+
+> Note that the certificate file will not be loaded on instantiation but when an
+incoming connection initializes its TLS context.
+This implies that any invalid certificate file paths or contents will only cause
+an `error` event at a later time.
+
+If your private key is encrypted with a passphrase, you have to specify it
+like this:
+
+```php
+$server = new TcpServer(8000, $loop);
+$server = new SecureServer($server, $loop, array(
+ 'local_cert' => 'server.pem',
+ 'passphrase' => 'secret'
+));
+```
+
+By default, this server supports TLSv1.0+ and excludes support for legacy
+SSLv2/SSLv3. As of PHP 5.6+ you can also explicitly choose the TLS version you
+want to negotiate with the remote side:
+
+```php
+$server = new TcpServer(8000, $loop);
+$server = new SecureServer($server, $loop, array(
+ 'local_cert' => 'server.pem',
+ 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER
+));
+```
+
+> Note that available [TLS context options](http://php.net/manual/en/context.ssl.php),
+their defaults and effects of changing these may vary depending on your system
+and/or PHP version.
+Passing unknown context options has no effect.
+
+Whenever a client completes the TLS handshake, it will emit a `connection` event
+with a connection instance implementing [`ConnectionInterface`](#connectioninterface):
+
+```php
+$server->on('connection', function (ConnectionInterface $connection) {
+ echo 'Secure connection from' . $connection->getRemoteAddress() . PHP_EOL;
+
+ $connection->write('hello there!' . PHP_EOL);
+ …
+});
+```
+
+Whenever a client fails to perform a successful TLS handshake, it will emit an
+`error` event and then close the underlying TCP/IP connection:
+
+```php
+$server->on('error', function (Exception $e) {
+ echo 'Error' . $e->getMessage() . PHP_EOL;
+});
+```
+
+See also the [`ServerInterface`](#serverinterface) for more details.
+
+Note that the `SecureServer` class is a concrete implementation for TLS sockets.
+If you want to typehint in your higher-level protocol implementation, you SHOULD
+use the generic [`ServerInterface`](#serverinterface) instead.
+
+> Advanced usage: Despite allowing any `ServerInterface` as first parameter,
+you SHOULD pass a `TcpServer` instance as first parameter, unless you
+know what you're doing.
+Internally, the `SecureServer` has to set the required TLS context options on
+the underlying stream resources.
+These resources are not exposed through any of the interfaces defined in this
+package, but only through the internal `Connection` class.
+The `TcpServer` class is guaranteed to emit connections that implement
+the `ConnectionInterface` and uses the internal `Connection` class in order to
+expose these underlying resources.
+If you use a custom `ServerInterface` and its `connection` event does not
+meet this requirement, the `SecureServer` will emit an `error` event and
+then close the underlying connection.
+
+#### UnixServer
+
+The `UnixServer` class implements the [`ServerInterface`](#serverinterface) and
+is responsible for accepting connections on Unix domain sockets (UDS).
+
+```php
+$server = new UnixServer('/tmp/server.sock', $loop);
+```
+
+As above, the `$uri` parameter can consist of only a socket path or socket path
+prefixed by the `unix://` scheme.
+
+If the given URI appears to be valid, but listening on it fails (such as if the
+socket is already in use or the file not accessible etc.), it will throw a
+`RuntimeException`:
+
+```php
+$first = new UnixServer('/tmp/same.sock', $loop);
+
+// throws RuntimeException because socket is already in use
+$second = new UnixServer('/tmp/same.sock', $loop);
+```
+
+Whenever a client connects, it will emit a `connection` event with a connection
+instance implementing [`ConnectionInterface`](#connectioninterface):
+
+```php
+$server->on('connection', function (ConnectionInterface $connection) {
+ echo 'New connection' . PHP_EOL;
+
+ $connection->write('hello there!' . PHP_EOL);
+ …
+});
+```
+
+See also the [`ServerInterface`](#serverinterface) for more details.
+
+#### LimitingServer
+
+The `LimitingServer` decorator wraps a given `ServerInterface` and is responsible
+for limiting and keeping track of open connections to this server instance.
+
+Whenever the underlying server emits a `connection` event, it will check its
+limits and then either
+ - keep track of this connection by adding it to the list of
+ open connections and then forward the `connection` event
+ - or reject (close) the connection when its limits are exceeded and will
+ forward an `error` event instead.
+
+Whenever a connection closes, it will remove this connection from the list of
+open connections.
+
+```php
+$server = new LimitingServer($server, 100);
+$server->on('connection', function (ConnectionInterface $connection) {
+ $connection->write('hello there!' . PHP_EOL);
+ …
+});
+```
+
+See also the [second example](examples) for more details.
+
+You have to pass a maximum number of open connections to ensure
+the server will automatically reject (close) connections once this limit
+is exceeded. In this case, it will emit an `error` event to inform about
+this and no `connection` event will be emitted.
+
+```php
+$server = new LimitingServer($server, 100);
+$server->on('connection', function (ConnectionInterface $connection) {
+ $connection->write('hello there!' . PHP_EOL);
+ …
+});
+```
+
+You MAY pass a `null` limit in order to put no limit on the number of
+open connections and keep accepting new connection until you run out of
+operating system resources (such as open file handles). This may be
+useful if you do not want to take care of applying a limit but still want
+to use the `getConnections()` method.
+
+You can optionally configure the server to pause accepting new
+connections once the connection limit is reached. In this case, it will
+pause the underlying server and no longer process any new connections at
+all, thus also no longer closing any excessive connections.
+The underlying operating system is responsible for keeping a backlog of
+pending connections until its limit is reached, at which point it will
+start rejecting further connections.
+Once the server is below the connection limit, it will continue consuming
+connections from the backlog and will process any outstanding data on
+each connection.
+This mode may be useful for some protocols that are designed to wait for
+a response message (such as HTTP), but may be less useful for other
+protocols that demand immediate responses (such as a "welcome" message in
+an interactive chat).
+
+```php
+$server = new LimitingServer($server, 100, true);
+$server->on('connection', function (ConnectionInterface $connection) {
+ $connection->write('hello there!' . PHP_EOL);
+ …
+});
+```
+
+##### getConnections()
+
+The `getConnections(): ConnectionInterface[]` method can be used to
+return an array with all currently active connections.
+
+```php
+foreach ($server->getConnection() as $connection) {
+ $connection->write('Hi!');
+}
+```
+
+## Client usage
+
+### ConnectorInterface
+
+The `ConnectorInterface` is responsible for providing an interface for
+establishing streaming connections, such as a normal TCP/IP connection.
+
+This is the main interface defined in this package and it is used throughout
+React's vast ecosystem.
+
+Most higher-level components (such as HTTP, database or other networking
+service clients) accept an instance implementing this interface to create their
+TCP/IP connection to the underlying networking service.
+This is usually done via dependency injection, so it's fairly simple to actually
+swap this implementation against any other implementation of this interface.
+
+The interface only offers a single method:
+
+#### connect()
+
+The `connect(string $uri): PromiseInterface<ConnectionInterface, Exception>` method
+can be used to create a streaming connection to the given remote address.
+
+It returns a [Promise](https://github.com/reactphp/promise) which either
+fulfills with a stream implementing [`ConnectionInterface`](#connectioninterface)
+on success or rejects with an `Exception` if the connection is not successful:
+
+```php
+$connector->connect('google.com:443')->then(
+ function (ConnectionInterface $connection) {
+ // connection successfully established
+ },
+ function (Exception $error) {
+ // failed to connect due to $error
+ }
+);
+```
+
+See also [`ConnectionInterface`](#connectioninterface) for more details.
+
+The returned Promise MUST be implemented in such a way that it can be
+cancelled when it is still pending. Cancelling a pending promise MUST
+reject its value with an `Exception`. It SHOULD clean up any underlying
+resources and references as applicable:
+
+```php
+$promise = $connector->connect($uri);
+
+$promise->cancel();
+```
+
+### Connector
+
+The `Connector` class is the main class in this package that implements the
+[`ConnectorInterface`](#connectorinterface) and allows you to create streaming connections.
+
+You can use this connector to create any kind of streaming connections, such
+as plaintext TCP/IP, secure TLS or local Unix connection streams.
+
+It binds to the main event loop and can be used like this:
+
+```php
+$loop = React\EventLoop\Factory::create();
+$connector = new Connector($loop);
+
+$connector->connect($uri)->then(function (ConnectionInterface $connection) {
+ $connection->write('...');
+ $connection->end();
+});
+
+$loop->run();
+```
+
+In order to create a plaintext TCP/IP connection, you can simply pass a host
+and port combination like this:
+
+```php
+$connector->connect('www.google.com:80')->then(function (ConnectionInterface $connection) {
+ $connection->write('...');
+ $connection->end();
+});
+```
+
+> If you do no specify a URI scheme in the destination URI, it will assume
+ `tcp://` as a default and establish a plaintext TCP/IP connection.
+ Note that TCP/IP connections require a host and port part in the destination
+ URI like above, all other URI components are optional.
+
+In order to create a secure TLS connection, you can use the `tls://` URI scheme
+like this:
+
+```php
+$connector->connect('tls://www.google.com:443')->then(function (ConnectionInterface $connection) {
+ $connection->write('...');
+ $connection->end();
+});
+```
+
+In order to create a local Unix domain socket connection, you can use the
+`unix://` URI scheme like this:
+
+```php
+$connector->connect('unix:///tmp/demo.sock')->then(function (ConnectionInterface $connection) {
+ $connection->write('...');
+ $connection->end();
+});
+```
+
+> The [`getRemoteAddress()`](#getremoteaddress) method will return the target
+ Unix domain socket (UDS) path as given to the `connect()` method, including
+ the `unix://` scheme, for example `unix:///tmp/demo.sock`.
+ The [`getLocalAddress()`](#getlocaladdress) method will most likely return a
+ `null` value as this value is not applicable to UDS connections here.
+
+Under the hood, the `Connector` is implemented as a *higher-level facade*
+for the lower-level connectors implemented in this package. This means it
+also shares all of their features and implementation details.
+If you want to typehint in your higher-level protocol implementation, you SHOULD
+use the generic [`ConnectorInterface`](#connectorinterface) instead.
+
+The `Connector` class will try to detect your system DNS settings (and uses
+Google's public DNS server `8.8.8.8` as a fallback if unable to determine your
+system settings) to resolve all public hostnames into underlying IP addresses by
+default.
+If you explicitly want to use a custom DNS server (such as a local DNS relay or
+a company wide DNS server), you can set up the `Connector` like this:
+
+```php
+$connector = new Connector($loop, array(
+ 'dns' => '127.0.1.1'
+));
+
+$connector->connect('localhost:80')->then(function (ConnectionInterface $connection) {
+ $connection->write('...');
+ $connection->end();
+});
+```
+
+If you do not want to use a DNS resolver at all and want to connect to IP
+addresses only, you can also set up your `Connector` like this:
+
+```php
+$connector = new Connector($loop, array(
+ 'dns' => false
+));
+
+$connector->connect('127.0.0.1:80')->then(function (ConnectionInterface $connection) {
+ $connection->write('...');
+ $connection->end();
+});
+```
+
+Advanced: If you need a custom DNS `Resolver` instance, you can also set up
+your `Connector` like this:
+
+```php
+$dnsResolverFactory = new React\Dns\Resolver\Factory();
+$resolver = $dnsResolverFactory->createCached('127.0.1.1', $loop);
+
+$connector = new Connector($loop, array(
+ 'dns' => $resolver
+));
+
+$connector->connect('localhost:80')->then(function (ConnectionInterface $connection) {
+ $connection->write('...');
+ $connection->end();
+});
+```
+
+By default, the `tcp://` and `tls://` URI schemes will use timeout value that
+repects your `default_socket_timeout` ini setting (which defaults to 60s).
+If you want a custom timeout value, you can simply pass this like this:
+
+```php
+$connector = new Connector($loop, array(
+ 'timeout' => 10.0
+));
+```
+
+Similarly, if you do not want to apply a timeout at all and let the operating
+system handle this, you can pass a boolean flag like this:
+
+```php
+$connector = new Connector($loop, array(
+ 'timeout' => false
+));
+```
+
+By default, the `Connector` supports the `tcp://`, `tls://` and `unix://`
+URI schemes. If you want to explicitly prohibit any of these, you can simply
+pass boolean flags like this:
+
+```php
+// only allow secure TLS connections
+$connector = new Connector($loop, array(
+ 'tcp' => false,
+ 'tls' => true,
+ 'unix' => false,
+));
+
+$connector->connect('tls://google.com:443')->then(function (ConnectionInterface $connection) {
+ $connection->write('...');
+ $connection->end();
+});
+```
+
+The `tcp://` and `tls://` also accept additional context options passed to
+the underlying connectors.
+If you want to explicitly pass additional context options, you can simply
+pass arrays of context options like this:
+
+```php
+// allow insecure TLS connections
+$connector = new Connector($loop, array(
+ 'tcp' => array(
+ 'bindto' => '192.168.0.1:0'
+ ),
+ 'tls' => array(
+ 'verify_peer' => false,
+ 'verify_peer_name' => false
+ ),
+));
+
+$connector->connect('tls://localhost:443')->then(function (ConnectionInterface $connection) {
+ $connection->write('...');
+ $connection->end();
+});
+```
+
+By default, this connector supports TLSv1.0+ and excludes support for legacy
+SSLv2/SSLv3. As of PHP 5.6+ you can also explicitly choose the TLS version you
+want to negotiate with the remote side:
+
+```php
+$connector = new Connector($loop, array(
+ 'tls' => array(
+ 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
+ )
+));
+```
+
+> For more details about context options, please refer to the PHP documentation
+ about [socket context options](http://php.net/manual/en/context.socket.php)
+ and [SSL context options](http://php.net/manual/en/context.ssl.php).
+
+Advanced: By default, the `Connector` supports the `tcp://`, `tls://` and
+`unix://` URI schemes.
+For this, it sets up the required connector classes automatically.
+If you want to explicitly pass custom connectors for any of these, you can simply
+pass an instance implementing the `ConnectorInterface` like this:
+
+```php
+$dnsResolverFactory = new React\Dns\Resolver\Factory();
+$resolver = $dnsResolverFactory->createCached('127.0.1.1', $loop);
+$tcp = new DnsConnector(new TcpConnector($loop), $resolver);
+
+$tls = new SecureConnector($tcp, $loop);
+
+$unix = new UnixConnector($loop);
+
+$connector = new Connector($loop, array(
+ 'tcp' => $tcp,
+ 'tls' => $tls,
+ 'unix' => $unix,
+
+ 'dns' => false,
+ 'timeout' => false,
+));
+
+$connector->connect('google.com:80')->then(function (ConnectionInterface $connection) {
+ $connection->write('...');
+ $connection->end();
+});
+```
+
+> Internally, the `tcp://` connector will always be wrapped by the DNS resolver,
+ unless you disable DNS like in the above example. In this case, the `tcp://`
+ connector receives the actual hostname instead of only the resolved IP address
+ and is thus responsible for performing the lookup.
+ Internally, the automatically created `tls://` connector will always wrap the
+ underlying `tcp://` connector for establishing the underlying plaintext
+ TCP/IP connection before enabling secure TLS mode. If you want to use a custom
+ underlying `tcp://` connector for secure TLS connections only, you may
+ explicitly pass a `tls://` connector like above instead.
+ Internally, the `tcp://` and `tls://` connectors will always be wrapped by
+ `TimeoutConnector`, unless you disable timeouts like in the above example.
+
+### Advanced client usage
+
+#### TcpConnector
+
+The `React\Socket\TcpConnector` class implements the
+[`ConnectorInterface`](#connectorinterface) and allows you to create plaintext
+TCP/IP connections to any IP-port-combination:
+
+```php
+$tcpConnector = new React\Socket\TcpConnector($loop);
+
+$tcpConnector->connect('127.0.0.1:80')->then(function (ConnectionInterface $connection) {
+ $connection->write('...');
+ $connection->end();
+});
+
+$loop->run();
+```
+
+See also the [examples](examples).
+
+Pending connection attempts can be cancelled by cancelling its pending promise like so:
+
+```php
+$promise = $tcpConnector->connect('127.0.0.1:80');
+
+$promise->cancel();
+```
+
+Calling `cancel()` on a pending promise will close the underlying socket
+resource, thus cancelling the pending TCP/IP connection, and reject the
+resulting promise.
+
+You can optionally pass additional
+[socket context options](http://php.net/manual/en/context.socket.php)
+to the constructor like this:
+
+```php
+$tcpConnector = new React\Socket\TcpConnector($loop, array(
+ 'bindto' => '192.168.0.1:0'
+));
+```
+
+Note that this class only allows you to connect to IP-port-combinations.
+If the given URI is invalid, does not contain a valid IP address and port
+or contains any other scheme, it will reject with an
+`InvalidArgumentException`:
+
+If the given URI appears to be valid, but connecting to it fails (such as if
+the remote host rejects the connection etc.), it will reject with a
+`RuntimeException`.
+
+If you want to connect to hostname-port-combinations, see also the following chapter.
+
+> Advanced usage: Internally, the `TcpConnector` allocates an empty *context*
+resource for each stream resource.
+If the destination URI contains a `hostname` query parameter, its value will
+be used to set up the TLS peer name.
+This is used by the `SecureConnector` and `DnsConnector` to verify the peer
+name and can also be used if you want a custom TLS peer name.
+
+#### DnsConnector
+
+The `DnsConnector` class implements the
+[`ConnectorInterface`](#connectorinterface) and allows you to create plaintext
+TCP/IP connections to any hostname-port-combination.
+
+It does so by decorating a given `TcpConnector` instance so that it first
+looks up the given domain name via DNS (if applicable) and then establishes the
+underlying TCP/IP connection to the resolved target IP address.
+
+Make sure to set up your DNS resolver and underlying TCP connector like this:
+
+```php
+$dnsResolverFactory = new React\Dns\Resolver\Factory();
+$dns = $dnsResolverFactory->createCached('8.8.8.8', $loop);
+
+$dnsConnector = new React\Socket\DnsConnector($tcpConnector, $dns);
+
+$dnsConnector->connect('www.google.com:80')->then(function (ConnectionInterface $connection) {
+ $connection->write('...');
+ $connection->end();
+});
+
+$loop->run();
+```
+
+See also the [examples](examples).
+
+Pending connection attempts can be cancelled by cancelling its pending promise like so:
+
+```php
+$promise = $dnsConnector->connect('www.google.com:80');
+
+$promise->cancel();
+```
+
+Calling `cancel()` on a pending promise will cancel the underlying DNS lookup
+and/or the underlying TCP/IP connection and reject the resulting promise.
+
+> Advanced usage: Internally, the `DnsConnector` relies on a `Resolver` to
+look up the IP address for the given hostname.
+It will then replace the hostname in the destination URI with this IP and
+append a `hostname` query parameter and pass this updated URI to the underlying
+connector.
+The underlying connector is thus responsible for creating a connection to the
+target IP address, while this query parameter can be used to check the original
+hostname and is used by the `TcpConnector` to set up the TLS peer name.
+If a `hostname` is given explicitly, this query parameter will not be modified,
+which can be useful if you want a custom TLS peer name.
+
+#### SecureConnector
+
+The `SecureConnector` class implements the
+[`ConnectorInterface`](#connectorinterface) and allows you to create secure
+TLS (formerly known as SSL) connections to any hostname-port-combination.
+
+It does so by decorating a given `DnsConnector` instance so that it first
+creates a plaintext TCP/IP connection and then enables TLS encryption on this
+stream.
+
+```php
+$secureConnector = new React\Socket\SecureConnector($dnsConnector, $loop);
+
+$secureConnector->connect('www.google.com:443')->then(function (ConnectionInterface $connection) {
+ $connection->write("GET / HTTP/1.0\r\nHost: www.google.com\r\n\r\n");
+ ...
+});
+
+$loop->run();
+```
+
+See also the [examples](examples).
+
+Pending connection attempts can be cancelled by cancelling its pending promise like so:
+
+```php
+$promise = $secureConnector->connect('www.google.com:443');
+
+$promise->cancel();
+```
+
+Calling `cancel()` on a pending promise will cancel the underlying TCP/IP
+connection and/or the SSL/TLS negotiation and reject the resulting promise.
+
+You can optionally pass additional
+[SSL context options](http://php.net/manual/en/context.ssl.php)
+to the constructor like this:
+
+```php
+$secureConnector = new React\Socket\SecureConnector($dnsConnector, $loop, array(
+ 'verify_peer' => false,
+ 'verify_peer_name' => false
+));
+```
+
+By default, this connector supports TLSv1.0+ and excludes support for legacy
+SSLv2/SSLv3. As of PHP 5.6+ you can also explicitly choose the TLS version you
+want to negotiate with the remote side:
+
+```php
+$secureConnector = new React\Socket\SecureConnector($dnsConnector, $loop, array(
+ 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
+));
+```
+
+> Advanced usage: Internally, the `SecureConnector` relies on setting up the
+required *context options* on the underlying stream resource.
+It should therefor be used with a `TcpConnector` somewhere in the connector
+stack so that it can allocate an empty *context* resource for each stream
+resource and verify the peer name.
+Failing to do so may result in a TLS peer name mismatch error or some hard to
+trace race conditions, because all stream resources will use a single, shared
+*default context* resource otherwise.
+
+#### TimeoutConnector
+
+The `TimeoutConnector` class implements the
+[`ConnectorInterface`](#connectorinterface) and allows you to add timeout
+handling to any existing connector instance.
+
+It does so by decorating any given [`ConnectorInterface`](#connectorinterface)
+instance and starting a timer that will automatically reject and abort any
+underlying connection attempt if it takes too long.
+
+```php
+$timeoutConnector = new React\Socket\TimeoutConnector($connector, 3.0, $loop);
+
+$timeoutConnector->connect('google.com:80')->then(function (ConnectionInterface $connection) {
+ // connection succeeded within 3.0 seconds
+});
+```
+
+See also any of the [examples](examples).
+
+Pending connection attempts can be cancelled by cancelling its pending promise like so:
+
+```php
+$promise = $timeoutConnector->connect('google.com:80');
+
+$promise->cancel();
+```
+
+Calling `cancel()` on a pending promise will cancel the underlying connection
+attempt, abort the timer and reject the resulting promise.
+
+#### UnixConnector
+
+The `UnixConnector` class implements the
+[`ConnectorInterface`](#connectorinterface) and allows you to connect to
+Unix domain socket (UDS) paths like this:
+
+```php
+$connector = new React\Socket\UnixConnector($loop);
+
+$connector->connect('/tmp/demo.sock')->then(function (ConnectionInterface $connection) {
+ $connection->write("HELLO\n");
+});
+
+$loop->run();
+```
+
+Connecting to Unix domain sockets is an atomic operation, i.e. its promise will
+settle (either resolve or reject) immediately.
+As such, calling `cancel()` on the resulting promise has no effect.
+
+> The [`getRemoteAddress()`](#getremoteaddress) method will return the target
+ Unix domain socket (UDS) path as given to the `connect()` method, prepended
+ with the `unix://` scheme, for example `unix:///tmp/demo.sock`.
+ The [`getLocalAddress()`](#getlocaladdress) method will most likely return a
+ `null` value as this value is not applicable to UDS connections here.
+
+#### FixedUriConnector
+
+The `FixedUriConnector` class implements the
+[`ConnectorInterface`](#connectorinterface) and decorates an existing Connector
+to always use a fixed, preconfigured URI.
+
+This can be useful for consumers that do not support certain URIs, such as
+when you want to explicitly connect to a Unix domain socket (UDS) path
+instead of connecting to a default address assumed by an higher-level API:
+
+```php
+$connector = new FixedUriConnector(
+ 'unix:///var/run/docker.sock',
+ new UnixConnector($loop)
+);
+
+// destination will be ignored, actually connects to Unix domain socket
+$promise = $connector->connect('localhost:80');
+```
+
+## Install
+
+The recommended way to install this library is [through Composer](https://getcomposer.org).
+[New to Composer?](https://getcomposer.org/doc/00-intro.md)
+
+This will install the latest supported version:
+
+```bash
+$ composer require react/socket:^0.8.10
+```
+
+See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades.
+
+This project aims to run on any platform and thus does not require any PHP
+extensions and supports running on legacy PHP 5.3 through current PHP 7+ and HHVM.
+It's *highly recommended to use PHP 7+* for this project, partly due to its vast
+performance improvements and partly because legacy PHP versions require several
+workarounds as described below.
+
+Secure TLS connections received some major upgrades starting with PHP 5.6, with
+the defaults now being more secure, while older versions required explicit
+context options.
+This library does not take responsibility over these context options, so it's
+up to consumers of this library to take care of setting appropriate context
+options as described above.
+
+All versions of PHP prior to 5.6.8 suffered from a buffering issue where reading
+from a streaming TLS connection could be one `data` event behind.
+This library implements a work-around to try to flush the complete incoming
+data buffers on these legacy PHP versions, which has a penalty of around 10% of
+throughput on all connections.
+With this work-around, we have not been able to reproduce this issue anymore,
+but we have seen reports of people saying this could still affect some of the
+older PHP versions (`5.5.23`, `5.6.7`, and `5.6.8`).
+Note that this only affects *some* higher-level streaming protocols, such as
+IRC over TLS, but should not affect HTTP over TLS (HTTPS).
+Further investigation of this issue is needed.
+For more insights, this issue is also covered by our test suite.
+
+PHP < 7.1.4 (and PHP < 7.0.18) suffers from a bug when writing big
+chunks of data over TLS streams at once.
+We try to work around this by limiting the write chunk size to 8192
+bytes for older PHP versions only.
+This is only a work-around and has a noticable performance penalty on
+affected versions.
+
+This project also supports running on HHVM.
+Note that really old HHVM < 3.8 does not support secure TLS connections, as it
+lacks the required `stream_socket_enable_crypto()` function.
+As such, trying to create a secure TLS connections on affected versions will
+return a rejected promise instead.
+This issue is also covered by our test suite, which will skip related tests
+on affected versions.
+
+## Tests
+
+To run the test suite, you first need to clone this repo and then install all
+dependencies [through Composer](https://getcomposer.org):
+
+```bash
+$ composer install
+```
+
+To run the test suite, go to the project root and run:
+
+```bash
+$ php vendor/bin/phpunit
+```
+
+The test suite also contains a number of functional integration tests that rely
+on a stable internet connection.
+If you do not want to run these, they can simply be skipped like this:
+
+```bash
+$ php vendor/bin/phpunit --exclude-group internet
+```
+
+## License
+
+MIT, see [LICENSE file](LICENSE).
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/composer.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/composer.json
new file mode 100644
index 0000000..bc85aab
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/composer.json
@@ -0,0 +1,29 @@
+{
+ "name": "react/socket",
+ "description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP",
+ "keywords": ["async", "socket", "stream", "connection", "ReactPHP"],
+ "license": "MIT",
+ "require": {
+ "php": ">=5.3.0",
+ "evenement/evenement": "^3.0 || ^2.0 || ^1.0",
+ "react/dns": "^0.4.13",
+ "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5",
+ "react/stream": "^1.0 || ^0.7.1",
+ "react/promise": "^2.1 || ^1.2",
+ "react/promise-timer": "~1.0"
+ },
+ "require-dev": {
+ "clue/block-react": "^1.2",
+ "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
+ },
+ "autoload": {
+ "psr-4": {
+ "React\\Socket\\": "src"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "React\\Tests\\Socket\\": "tests"
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/01-echo-server.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/01-echo-server.php
new file mode 100644
index 0000000..2c0be57
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/01-echo-server.php
@@ -0,0 +1,42 @@
+<?php
+
+// Just start this server and connect to it. Everything you send to it will be
+// sent back to you.
+//
+// $ php examples/01-echo-server.php 8000
+// $ telnet localhost 8000
+//
+// You can also run a secure TLS echo server like this:
+//
+// $ php examples/01-echo-server.php tls://127.0.0.1:8000 examples/localhost.pem
+// $ openssl s_client -connect localhost:8000
+//
+// You can also run a Unix domain socket (UDS) server like this:
+//
+// $ php examples/01-echo-server.php unix:///tmp/server.sock
+// $ nc -U /tmp/server.sock
+
+use React\EventLoop\Factory;
+use React\Socket\Server;
+use React\Socket\ConnectionInterface;
+
+require __DIR__ . '/../vendor/autoload.php';
+
+$loop = Factory::create();
+
+$server = new Server(isset($argv[1]) ? $argv[1] : 0, $loop, array(
+ 'tls' => array(
+ 'local_cert' => isset($argv[2]) ? $argv[2] : (__DIR__ . '/localhost.pem')
+ )
+));
+
+$server->on('connection', function (ConnectionInterface $conn) {
+ echo '[' . $conn->getRemoteAddress() . ' connected]' . PHP_EOL;
+ $conn->pipe($conn);
+});
+
+$server->on('error', 'printf');
+
+echo 'Listening on ' . $server->getAddress() . PHP_EOL;
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/02-chat-server.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/02-chat-server.php
new file mode 100644
index 0000000..46439e0
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/02-chat-server.php
@@ -0,0 +1,59 @@
+<?php
+
+// Just start this server and connect with any number of clients to it.
+// Everything a client sends will be broadcasted to all connected clients.
+//
+// $ php examples/02-chat-server.php 8000
+// $ telnet localhost 8000
+//
+// You can also run a secure TLS chat server like this:
+//
+// $ php examples/02-chat-server.php tls://127.0.0.1:8000 examples/localhost.pem
+// $ openssl s_client -connect localhost:8000
+//
+// You can also run a Unix domain socket (UDS) server like this:
+//
+// $ php examples/02-chat-server.php unix:///tmp/server.sock
+// $ nc -U /tmp/server.sock
+
+use React\EventLoop\Factory;
+use React\Socket\Server;
+use React\Socket\ConnectionInterface;
+use React\Socket\LimitingServer;
+
+require __DIR__ . '/../vendor/autoload.php';
+
+$loop = Factory::create();
+
+$server = new Server(isset($argv[1]) ? $argv[1] : 0, $loop, array(
+ 'tls' => array(
+ 'local_cert' => isset($argv[2]) ? $argv[2] : (__DIR__ . '/localhost.pem')
+ )
+));
+
+$server = new LimitingServer($server, null);
+
+$server->on('connection', function (ConnectionInterface $client) use ($server) {
+ // whenever a new message comes in
+ $client->on('data', function ($data) use ($client, $server) {
+ // remove any non-word characters (just for the demo)
+ $data = trim(preg_replace('/[^\w\d \.\,\-\!\?]/u', '', $data));
+
+ // ignore empty messages
+ if ($data === '') {
+ return;
+ }
+
+ // prefix with client IP and broadcast to all connected clients
+ $data = trim(parse_url($client->getRemoteAddress(), PHP_URL_HOST), '[]') . ': ' . $data . PHP_EOL;
+ foreach ($server->getConnections() as $connection) {
+ $connection->write($data);
+ }
+ });
+});
+
+$server->on('error', 'printf');
+
+echo 'Listening on ' . $server->getAddress() . PHP_EOL;
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/03-http-server.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/03-http-server.php
new file mode 100644
index 0000000..eb6d454
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/03-http-server.php
@@ -0,0 +1,57 @@
+<?php
+
+// Simple HTTP server example (for illustration purposes only).
+// This shows how a plaintext TCP/IP connection is accepted to then receive an
+// application level protocol message (HTTP request) and reply with an
+// application level protocol message (HTTP response) in return.
+//
+// This example exists for illustraion purposes only. It does not actually
+// parse incoming HTTP requests, so you can actually send *anything* and will
+// still respond with a valid HTTP response.
+// Real applications should use react/http instead!
+//
+// Just start this server and send a request to it:
+//
+// $ php examples/03-http-server.php 8000
+// $ curl -v http://localhost:8000/
+// $ ab -n1000 -c10 http://localhost:8000/
+// $ docker run -it --rm --net=host jordi/ab ab -n1000 -c10 http://localhost:8000/
+//
+// You can also run a secure HTTPS echo server like this:
+//
+// $ php examples/03-http-server.php tls://127.0.0.1:8000 examples/localhost.pem
+// $ curl -v --insecure https://localhost:8000/
+// $ ab -n1000 -c10 https://localhost:8000/
+// $ docker run -it --rm --net=host jordi/ab ab -n1000 -c10 https://localhost:8000/
+//
+// You can also run a Unix domain socket (UDS) server like this:
+//
+// $ php examples/03-http-server.php unix:///tmp/server.sock
+// $ nc -U /tmp/server.sock
+
+use React\EventLoop\Factory;
+use React\Socket\Server;
+use React\Socket\ConnectionInterface;
+
+require __DIR__ . '/../vendor/autoload.php';
+
+$loop = Factory::create();
+
+$server = new Server(isset($argv[1]) ? $argv[1] : 0, $loop, array(
+ 'tls' => array(
+ 'local_cert' => isset($argv[2]) ? $argv[2] : (__DIR__ . '/localhost.pem')
+ )
+));
+
+$server->on('connection', function (ConnectionInterface $conn) {
+ $conn->once('data', function () use ($conn) {
+ $body = "<html><h1>Hello world!</h1></html>\r\n";
+ $conn->end("HTTP/1.1 200 OK\r\nContent-Length: " . strlen($body) . "\r\nConnection: close\r\n\r\n" . $body);
+ });
+});
+
+$server->on('error', 'printf');
+
+echo 'Listening on ' . strtr($server->getAddress(), array('tcp:' => 'http:', 'tls:' => 'https:')) . PHP_EOL;
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/11-http-client.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/11-http-client.php
new file mode 100644
index 0000000..2b64a43
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/11-http-client.php
@@ -0,0 +1,36 @@
+<?php
+
+// Simple plaintext HTTP client example (for illustration purposes only).
+// This shows how a plaintext TCP/IP connection is established to then send an
+// application level protocol message (HTTP).
+// Real applications should use react/http-client instead!
+//
+// This simple example only accepts an optional host parameter to send the
+// request to. See also example #22 for proper URI parsing.
+//
+// $ php examples/11-http-client.php
+// $ php examples/11-http-client.php reactphp.org
+
+use React\EventLoop\Factory;
+use React\Socket\Connector;
+use React\Socket\ConnectionInterface;
+
+$host = isset($argv[1]) ? $argv[1] : 'www.google.com';
+
+require __DIR__ . '/../vendor/autoload.php';
+
+$loop = Factory::create();
+$connector = new Connector($loop);
+
+$connector->connect($host. ':80')->then(function (ConnectionInterface $connection) use ($host) {
+ $connection->on('data', function ($data) {
+ echo $data;
+ });
+ $connection->on('close', function () {
+ echo '[CLOSED]' . PHP_EOL;
+ });
+
+ $connection->write("GET / HTTP/1.0\r\nHost: $host\r\n\r\n");
+}, 'printf');
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/12-https-client.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/12-https-client.php
new file mode 100644
index 0000000..6e3f279
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/12-https-client.php
@@ -0,0 +1,36 @@
+<?php
+
+// Simple secure HTTPS client example (for illustration purposes only).
+// This shows how a secure TLS connection is established to then send an
+// application level protocol message (HTTP).
+// Real applications should use react/http-client instead
+//
+// This simple example only accepts an optional host parameter to send the
+// request to. See also example #22 for proper URI parsing.
+//
+// $ php examples/12-https-client.php
+// $ php examples/12-https-client.php reactphp.org
+
+use React\EventLoop\Factory;
+use React\Socket\Connector;
+use React\Socket\ConnectionInterface;
+
+$host = isset($argv[1]) ? $argv[1] : 'www.google.com';
+
+require __DIR__ . '/../vendor/autoload.php';
+
+$loop = Factory::create();
+$connector = new Connector($loop);
+
+$connector->connect('tls://' . $host . ':443')->then(function (ConnectionInterface $connection) use ($host) {
+ $connection->on('data', function ($data) {
+ echo $data;
+ });
+ $connection->on('close', function () {
+ echo '[CLOSED]' . PHP_EOL;
+ });
+
+ $connection->write("GET / HTTP/1.0\r\nHost: $host\r\n\r\n");
+}, 'printf');
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/21-netcat-client.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/21-netcat-client.php
new file mode 100644
index 0000000..9140e2c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/21-netcat-client.php
@@ -0,0 +1,68 @@
+<?php
+
+// Simple plaintext TCP/IP and secure TLS client example that pipes console I/O.
+// This shows how a plaintext TCP/IP or secure TLS connection is established and
+// then everything you type on STDIN will be sent and everything the server
+// sends will be piped to your STDOUT.
+//
+// $ php examples/21-netcat-client.php www.google.com:80
+// $ php examples/21-netcat-client.php tls://www.google.com:443
+
+use React\EventLoop\Factory;
+use React\Socket\Connector;
+use React\Socket\ConnectionInterface;
+use React\Stream\ReadableResourceStream;
+use React\Stream\WritableResourceStream;
+
+require __DIR__ . '/../vendor/autoload.php';
+
+if (!defined('STDIN')) {
+ echo 'STDIO streams require CLI SAPI' . PHP_EOL;
+ exit(1);
+}
+
+if (DIRECTORY_SEPARATOR === '\\') {
+ fwrite(STDERR, 'Non-blocking console I/O not supported on Microsoft Windows' . PHP_EOL);
+ exit(1);
+}
+
+if (!isset($argv[1])) {
+ fwrite(STDERR, 'Usage error: required argument <host:port>' . PHP_EOL);
+ exit(1);
+}
+
+$loop = Factory::create();
+$connector = new Connector($loop);
+
+$stdin = new ReadableResourceStream(STDIN, $loop);
+$stdin->pause();
+$stdout = new WritableResourceStream(STDOUT, $loop);
+$stderr = new WritableResourceStream(STDERR, $loop);
+
+$stderr->write('Connecting' . PHP_EOL);
+
+$connector->connect($argv[1])->then(function (ConnectionInterface $connection) use ($stdin, $stdout, $stderr) {
+ // pipe everything from STDIN into connection
+ $stdin->resume();
+ $stdin->pipe($connection);
+
+ // pipe everything from connection to STDOUT
+ $connection->pipe($stdout);
+
+ // report errors to STDERR
+ $connection->on('error', function ($error) use ($stderr) {
+ $stderr->write('Stream ERROR: ' . $error . PHP_EOL);
+ });
+
+ // report closing and stop reading from input
+ $connection->on('close', function () use ($stderr, $stdin) {
+ $stderr->write('[CLOSED]' . PHP_EOL);
+ $stdin->close();
+ });
+
+ $stderr->write('Connected' . PHP_EOL);
+}, function ($error) use ($stderr) {
+ $stderr->write('Connection ERROR: ' . $error . PHP_EOL);
+});
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/22-http-client.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/22-http-client.php
new file mode 100644
index 0000000..fcb8107
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/22-http-client.php
@@ -0,0 +1,60 @@
+<?php
+
+// Simple plaintext HTTP and secure HTTPS client example (for illustration purposes only).
+// This shows how an URI parameter can parsed to decide whether to establish
+// a plaintext TCP/IP or secure TLS connection and then send an
+// application level protocol message (HTTP).
+// Real applications should use react/http-client instead!
+//
+// Unlike examples #11 and #12, this example will actually take an optional URI
+// parameter and parse it to connect to the correct default port and use the
+// correct transport protocol.
+//
+// $ php examples/22-http-client.php
+// $ php examples/22-http-client.php https://reactphp.org/
+
+use React\EventLoop\Factory;
+use React\Socket\ConnectionInterface;
+use React\Socket\Connector;
+use React\Stream\WritableResourceStream;
+
+require __DIR__ . '/../vendor/autoload.php';
+
+$uri = isset($argv[1]) ? $argv[1] : 'www.google.com';
+
+if (strpos($uri, '://') === false) {
+ $uri = 'http://' . $uri;
+}
+$parts = parse_url($uri);
+
+if (!$parts || !isset($parts['scheme'], $parts['host'])) {
+ fwrite(STDERR, 'Usage error: required argument <host:port>' . PHP_EOL);
+ exit(1);
+}
+
+$loop = Factory::create();
+$connector = new Connector($loop);
+
+if (!isset($parts['port'])) {
+ $parts['port'] = $parts['scheme'] === 'https' ? 443 : 80;
+}
+
+$host = $parts['host'];
+if (($parts['scheme'] === 'http' && $parts['port'] !== 80) || ($parts['scheme'] === 'https' && $parts['port'] !== 443)) {
+ $host .= ':' . $parts['port'];
+}
+$target = ($parts['scheme'] === 'https' ? 'tls' : 'tcp') . '://' . $parts['host'] . ':' . $parts['port'];
+$resource = isset($parts['path']) ? $parts['path'] : '/';
+if (isset($parts['query'])) {
+ $resource .= '?' . $parts['query'];
+}
+
+$stdout = new WritableResourceStream(STDOUT, $loop);
+
+$connector->connect($target)->then(function (ConnectionInterface $connection) use ($resource, $host, $stdout) {
+ $connection->pipe($stdout);
+
+ $connection->write("GET $resource HTTP/1.0\r\nHost: $host\r\n\r\n");
+}, 'printf');
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/91-benchmark-server.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/91-benchmark-server.php
new file mode 100644
index 0000000..420d474
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/91-benchmark-server.php
@@ -0,0 +1,60 @@
+<?php
+
+// Just start the server and connect to it. It will count the number of bytes
+// sent for each connection and will print the average throughput once the
+// connection closes.
+//
+// $ php examples/91-benchmark-server.php 8000
+// $ telnet localhost 8000
+// $ echo hello world | nc -N localhost 8000
+// $ dd if=/dev/zero bs=1M count=1000 | nc -N localhost 8000
+//
+// You can also run a secure TLS benchmarking server like this:
+//
+// $ php examples/91-benchmark-server.php tls://127.0.0.1:8000 examples/localhost.pem
+// $ openssl s_client -connect localhost:8000
+// $ echo hello world | openssl s_client -connect localhost:8000
+// $ dd if=/dev/zero bs=1M count=1000 | openssl s_client -connect localhost:8000
+//
+// You can also run a Unix domain socket (UDS) server benchmark like this:
+//
+// $ php examples/91-benchmark-server.php unix:///tmp/server.sock
+// $ nc -N -U /tmp/server.sock
+// $ dd if=/dev/zero bs=1M count=1000 | nc -N -U /tmp/server.sock
+
+use React\EventLoop\Factory;
+use React\Socket\Server;
+use React\Socket\ConnectionInterface;
+
+require __DIR__ . '/../vendor/autoload.php';
+
+$loop = Factory::create();
+
+$server = new Server(isset($argv[1]) ? $argv[1] : 0, $loop, array(
+ 'tls' => array(
+ 'local_cert' => isset($argv[2]) ? $argv[2] : (__DIR__ . '/localhost.pem')
+ )
+));
+
+$server->on('connection', function (ConnectionInterface $conn) use ($loop) {
+ echo '[connected]' . PHP_EOL;
+
+ // count the number of bytes received from this connection
+ $bytes = 0;
+ $conn->on('data', function ($chunk) use (&$bytes) {
+ $bytes += strlen($chunk);
+ });
+
+ // report average throughput once client disconnects
+ $t = microtime(true);
+ $conn->on('close', function () use ($conn, $t, &$bytes) {
+ $t = microtime(true) - $t;
+ echo '[disconnected after receiving ' . $bytes . ' bytes in ' . round($t, 3) . 's => ' . round($bytes / $t / 1024 / 1024, 1) . ' MiB/s]' . PHP_EOL;
+ });
+});
+
+$server->on('error', 'printf');
+
+echo 'Listening on ' . $server->getAddress() . PHP_EOL;
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/99-generate-self-signed.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/99-generate-self-signed.php
new file mode 100644
index 0000000..00f9314
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/99-generate-self-signed.php
@@ -0,0 +1,31 @@
+<?php
+
+// A very simple helper script used to generate self-signed certificates.
+// Accepts the CN and an optional passphrase to encrypt the private key.
+//
+// $ php 10-generate-self-signed.php localhost swordfish > secret.pem
+
+// certificate details (Distinguished Name)
+// (OpenSSL applies defaults to missing fields)
+$dn = array(
+ "commonName" => isset($argv[1]) ? $argv[1] : "localhost",
+// "countryName" => "AU",
+// "stateOrProvinceName" => "Some-State",
+// "localityName" => "London",
+// "organizationName" => "Internet Widgits Pty Ltd",
+// "organizationalUnitName" => "R&D",
+// "emailAddress" => "admin@example.com"
+);
+
+// create certificate which is valid for ~10 years
+$privkey = openssl_pkey_new();
+$cert = openssl_csr_new($dn, $privkey);
+$cert = openssl_csr_sign($cert, null, $privkey, 3650);
+
+// export public and (optionally encrypted) private key in PEM format
+openssl_x509_export($cert, $out);
+echo $out;
+
+$passphrase = isset($argv[2]) ? $argv[2] : null;
+openssl_pkey_export($privkey, $out, $passphrase);
+echo $out;
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/localhost.pem b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/localhost.pem
new file mode 100644
index 0000000..be69279
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/localhost.pem
@@ -0,0 +1,49 @@
+-----BEGIN CERTIFICATE-----
+MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBZMRIwEAYDVQQDDAkxMjcu
+MC4wLjExCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQK
+DBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTYxMjMwMTQ1OTA2WhcNMjYx
+MjI4MTQ1OTA2WjBZMRIwEAYDVQQDDAkxMjcuMC4wLjExCzAJBgNVBAYTAkFVMRMw
+EQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0
+eSBMdGQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC8SZWNS+Ktg0Py
+W8dx5uXZ+ZUawd3wnzLMHW7EhoUpIrIdp3kDU9NezF68dOhPMJY/Kh+6btRCxWXN
+2OVTqS5Xi826j3TSE07iF83JRLeveW0PcodjUBd+RzdwCWWo2pfMJz4v7x1wu1c9
+zNi6JxxpDAXTFSB4GiWsI4tFu2XmMRhfm6LRK4WPfsZIJKokdiG5fKSPDn7nrVj0
+UUXr2eBsEAzdwL14U9+mwbLdaAkz3qK3fqi8sEC09lEWm95gKMOhkQf5qvXODtT4
+wdVrrKDTyehLv0xaItnUDnXzrkMBU5QS9TQzzqSW6ZaBsSxtONEFUiXiN9dtyXsY
+YCUE54G/AgMBAAGjUDBOMB0GA1UdDgQWBBQ2GRz3QsQzdXaTMnPVCKfpigA10DAf
+BgNVHSMEGDAWgBQ2GRz3QsQzdXaTMnPVCKfpigA10DAMBgNVHRMEBTADAQH/MA0G
+CSqGSIb3DQEBBQUAA4IBAQA77iZ4KrpPY18Ezjt0mngYAuAxunKddXYdLZ2khywN
+0uI/VzYnkFVtrsC7y2jLHSxlmE2/viPPGZDUplENV2acN6JNW+tlt7/bsrQHDQw3
+7VCF27EWiDxHsaghhLkqC+kcop5YR5c0oDQTdEWEKSbow2zayUXDYbRRs76SClTe
+824Yul+Ts8Mka+AX2PXDg47iZ84fJRN/nKavcJUTJ2iS1uYw0GNnFMge/uwsfMR3
+V47qN0X5emky8fcq99FlMCbcy0gHAeSWAjClgr2dd2i0LDatUbj7YmdmFcskOgII
+IwGfvuWR2yPevYGAE0QgFeLHniN3RW8zmpnX/XtrJ4a7
+-----END CERTIFICATE-----
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC8SZWNS+Ktg0Py
+W8dx5uXZ+ZUawd3wnzLMHW7EhoUpIrIdp3kDU9NezF68dOhPMJY/Kh+6btRCxWXN
+2OVTqS5Xi826j3TSE07iF83JRLeveW0PcodjUBd+RzdwCWWo2pfMJz4v7x1wu1c9
+zNi6JxxpDAXTFSB4GiWsI4tFu2XmMRhfm6LRK4WPfsZIJKokdiG5fKSPDn7nrVj0
+UUXr2eBsEAzdwL14U9+mwbLdaAkz3qK3fqi8sEC09lEWm95gKMOhkQf5qvXODtT4
+wdVrrKDTyehLv0xaItnUDnXzrkMBU5QS9TQzzqSW6ZaBsSxtONEFUiXiN9dtyXsY
+YCUE54G/AgMBAAECggEBAKiO/3FE1CMddkCLZVtUp8ShqJgRokx9WI5ecwFApAkV
+ZHsjqDQQYRNmxhDUX/w0tOzLGyhde2xjJyZG29YviKsbHwu6zYwbeOzy/mkGOaK/
+g6DmmMmRs9Z6juifoQCu4GIFZ6il2adIL2vF7OeJh+eKudQj/7NFRSB7mXzNrQWK
+tZY3eux5zXWmio7pgZrx1HFZQiiL9NVLwT9J7oBnaoO3fREiu5J2xBpljG9Cr0j1
+LLiVLhukWJYRlHDtGt1CzI9w8iKo44PCRzpKyxpbsOrQxeSyEWUYQRv9VHA59LC7
+tVAJTbnTX1BNHkGZkOkoOpoZLwBaM2XbbDtcOGCAZMECgYEA+mTURFQ85/pxawvk
+9ndqZ+5He1u/bMLYIJDp0hdB/vgD+vw3gb2UyRwp0I6Wc6Si4FEEnbY7L0pzWsiR
+43CpLs+cyLfnD9NycuIasxs5fKb/1s1nGTkRAp7x9x/ZTtEf8v4YTmmMXFHzdo7V
+pv+czO89ppEDkxEtMf/b5SifhO8CgYEAwIDIUvXLduGhL+RPDwjc2SKdydXGV6om
+OEdt/V8oS801Z7k8l3gHXFm7zL/MpHmh9cag+F9dHK42kw2RSjDGsBlXXiAO1Z0I
+2A34OdPw/kow8fmIKWTMu3+28Kca+3RmUqeyaq0vazQ/bWMO9px+Ud3YfLo1Tn5I
+li0MecAx8DECgYEAvsLceKYYtL83c09fg2oc1ctSCCgw4WJcGAtvJ9DyRZacKbXH
+b/+H/+OF8879zmKqd+0hcCnqUzAMTCisBLPLIM+o6b45ufPkqKObpcJi/JWaKgLY
+vf2c+Psw6o4IF6T5Cz4MNIjzF06UBknxecYZpoPJ20F1kLCwVvxPgfl99l8CgYAb
+XfOcv67WTstgiJ+oroTfJamy+P5ClkDqvVTosW+EHz9ZaJ8xlXHOcj9do2LPey9I
+Rp250azmF+pQS5x9JKQKgv/FtN8HBVUtigbhCb14GUoODICMCfWFLmnumoMefnTR
+iV+3BLn6Dqp5vZxx+NuIffZ5/Or5JsDhALSGVomC8QKBgAi3Z/dNQrDHfkXMNn/L
++EAoLuAbFgLs76r9VGgNaRQ/q5gex2bZEGoBj4Sxvs95NUIcfD9wKT7FF8HdxARv
+y3o6Bfc8Xp9So9SlFXrje+gkdEJ0rQR67d+XBuJZh86bXJHVrMwpoNL+ahLGdVSe
+81oh1uCH1YPLM29hPyaohxL8
+-----END PRIVATE KEY-----
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/localhost_swordfish.pem b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/localhost_swordfish.pem
new file mode 100644
index 0000000..7d1ee80
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/examples/localhost_swordfish.pem
@@ -0,0 +1,51 @@
+-----BEGIN CERTIFICATE-----
+MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBZMRIwEAYDVQQDDAkxMjcu
+MC4wLjExCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQK
+DBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTYxMjMwMTQxMDQzWhcNMjYx
+MjI4MTQxMDQzWjBZMRIwEAYDVQQDDAkxMjcuMC4wLjExCzAJBgNVBAYTAkFVMRMw
+EQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0
+eSBMdGQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRXt83SrKIHr/i
+3lc8O8pz6NHE1DNHJa4xg2xalXWzCEV6m1qLd9VdaLT9cJD1afNmEMBgY6RblNL/
+paJWVoR9MOUeIoYl2PrhUCxsf7h6MRtezQQe3e+n+/0XunF0JUQIZuJqbxfRk5WT
+XmYnphqOZKEcistAYvFBjzl/D+Cl/nYsreADc+t9l5Vni89oTWEuqIrsM4WUZqqB
+VMAakd2nZJLWIrMxq9hbW1XNukOQfcmZVFTC6CUnLq8qzGbtfZYBuMBACnL1k/E/
+yPaAgR46l14VAcndDUJBtMeL2qYuNwvXQhg3KuBmpTUpH+yzxU+4T3lmv0xXmPqu
+ySH3xvW3AgMBAAGjUDBOMB0GA1UdDgQWBBRu68WTI4pVeTB7wuG9QGI3Ie441TAf
+BgNVHSMEGDAWgBRu68WTI4pVeTB7wuG9QGI3Ie441TAMBgNVHRMEBTADAQH/MA0G
+CSqGSIb3DQEBBQUAA4IBAQCc4pEjEHO47VRJkbHgC+c2gAVgxekkaA1czBA1uAvh
+ILRda0NLlvyftbjaG0zZp2ABUCfRfksl/Pf/PzWLUMEuH/9kEW2rgP43z6YgiL6k
+kBPlmAU607UjD726RPGkw8QPSXS/dWiNJ5CBpPWLpxC45pokqItYbY0ijQ5Piq09
+TchYlCX044oSRnPiP394PQ3HVdaGhJB2DnjDq3in5dVivFf8EdgzQSvp/wXy3WQs
+uFSVonSnrZGY/4AgT3psGaQ6fqKb4SBoqtf5bFQvp1XNNRkuEJnS/0dygEya0c+c
+aCe/1gXC2wDjx0/TekY5m1Nyw5SY6z7stOqL/ekwgejt
+-----END CERTIFICATE-----
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIG7idPRLgiHkCAggA
+MBQGCCqGSIb3DQMHBAg+MLPdepHWSwSCBMgVW9LseCjfTAmF9U1qRnKsq3kIwEnW
+6aERBqs/mnmEhrXgZYgcvRRK7kD12TdHt/Nz46Ymu0h+Lrvuwtl1fHQUARTk/gFh
+onLhc9kjMUhLRIR007vJe3HvWOb/v+SBSDB38OpUxUwJmBVBuSaYLWVuPR6J5kUj
+xOgBS049lN3E9cfrHvb3bF/epIQrU0OgfyyxEvIi5n30y+tlRn3y68PY6Qd46t4Y
+UN5VZUwvJBgoRy9TGxSkiSRjhxC2PWpLYq/HMzDbcRcFF5dVAIioUd/VZ7fdgBfA
+uMW4SFfpFLDUX0aaYe+ZdA5tM0Bc0cOtG8Z0sc9JYDNNcvjmSiGCi646h8F0D3O6
+JKAQMMxQGWiyQeJ979LVjtq4lJESXA8VEKz9rV03y5xunmFCLy6dGt+6GJwXgabn
+OH7nvEv4GqAOqKc6E9je4JM+AF/oUazrfPse1KEEtsPKarazjCB/SKYtHyDJaavD
+GGjtiU9zWwGMOgIDyNmXe3ga7/TWoGOAg5YlTr6Hbq2Y/5ycgjAgPFjuXtvnoT0+
+mF5TnNfMAqTgQsE2gjhonK1pdlOen0lN5FtoUXp3CXU0dOq0J70GiX+1YA7VDn30
+n5WNAgfOXX3l3E95jGN370pHXyli5RUNW0NZVHV+22jlNWCVtQHUh+DVswQZg+i5
++DqaIHz2jUetMo7gWtqGn/wwSopOs87VM1rcALhZL4EsJ+Zy81I/hA32RNnGbuol
+NAiZh+0KrtTcc/fPunpd8vRtOwGphM11dKucozUufuiPG2inR3aEqt5yNx54ec/f
+J6nryWRYiHEA/rCU9MSBM9cqKFtEmy9/8oxV41/SPxhXjHwDlABWTtFuJ3pf2sOF
+ILSYYFwB0ZGvdjE5yAJFBr9efno/L9fafmGk7a3vmVgK2AmUC9VNB5XHw1GjF8OP
+aQAXe4md9Bh0jk/D/iyp7e7IWNssul/7XejhabidWgFj6EXc9YxE59+FlhDqyMhn
+V6houc+QeUXuwsAKgRJJhJtpv/QSZ5BI3esxHHUt3ayGnvhFElpAc0t7C/EiXKIv
+DAFYP2jksBqijM8YtEgPWYzEP5buYxZnf/LK7FDocLsNcdF38UaKBbeF90e7bR8j
+SHspG9aJWICu8Yawnh8zuy/vQv+h9gWyGodd2p9lQzlbRXrutbwfmPf7xP6nzT9i
+9GcugJxTaZgkCfhhHxFk/nRHS2NAzagKVib1xkUlZJg2hX0fIFUdYteL1GGTvOx5
+m3mTOino4T19z9SEdZYb2OHYh29e/T74bJiLCYdXwevSYHxfZc8pYAf0jp4UnMT2
+f7B0ctX1iXuQ2uZVuxh+U1Mcu+v0gDla1jWh7AhcePSi4xBNUCak0kQip6r5e6Oi
+r4MIyMRk/Pc5pzEKo8G6nk26rNvX3aRvECoVfmK7IVdsqZ6IXlt9kOmWx3IeKzrO
+J5DxpzW+9oIRZJgPTkc4/XRb0tFmFQYTiChiQ1AJUEiCX0GpkFf7cq61aLGYtWyn
+vL2lmQhljzjrDo15hKErvk7eBZW7GW/6j/m/PfRdcBI4ceuP9zWQXnDOd9zmaE4b
+q3bJ+IbbyVZA2WwyzN7umCKWghsiPMAolxEnYM9JRf8BcqeqQiwVZlfO5KFuN6Ze
+le4=
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/phpunit.xml.dist b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/phpunit.xml.dist
new file mode 100644
index 0000000..13d3fab
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/phpunit.xml.dist
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit backupGlobals="false"
+ backupStaticAttributes="false"
+ colors="true"
+ convertErrorsToExceptions="true"
+ convertNoticesToExceptions="true"
+ convertWarningsToExceptions="true"
+ processIsolation="false"
+ stopOnFailure="false"
+ syntaxCheck="false"
+ bootstrap="vendor/autoload.php"
+>
+ <testsuites>
+ <testsuite name="React Test Suite">
+ <directory>./tests/</directory>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist>
+ <directory>./src/</directory>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/Connection.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/Connection.php
new file mode 100644
index 0000000..c6267cc
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/Connection.php
@@ -0,0 +1,178 @@
+<?php
+
+namespace React\Socket;
+
+use Evenement\EventEmitter;
+use React\EventLoop\LoopInterface;
+use React\Stream\DuplexResourceStream;
+use React\Stream\Util;
+use React\Stream\WritableResourceStream;
+use React\Stream\WritableStreamInterface;
+
+/**
+ * The actual connection implementation for ConnectionInterface
+ *
+ * This class should only be used internally, see ConnectionInterface instead.
+ *
+ * @see ConnectionInterface
+ * @internal
+ */
+class Connection extends EventEmitter implements ConnectionInterface
+{
+ /**
+ * Internal flag whether this is a Unix domain socket (UDS) connection
+ *
+ * @internal
+ */
+ public $unix = false;
+
+ /**
+ * Internal flag whether encryption has been enabled on this connection
+ *
+ * Mostly used by internal StreamEncryption so that connection returns
+ * `tls://` scheme for encrypted connections instead of `tcp://`.
+ *
+ * @internal
+ */
+ public $encryptionEnabled = false;
+
+ /** @internal */
+ public $stream;
+
+ private $input;
+
+ public function __construct($resource, LoopInterface $loop)
+ {
+ // PHP < 5.6.8 suffers from a buffer indicator bug on secure TLS connections
+ // as a work-around we always read the complete buffer until its end.
+ // The buffer size is limited due to TCP/IP buffers anyway, so this
+ // should not affect usage otherwise.
+ // See https://bugs.php.net/bug.php?id=65137
+ // https://bugs.php.net/bug.php?id=41631
+ // https://github.com/reactphp/socket-client/issues/24
+ $clearCompleteBuffer = PHP_VERSION_ID < 50608;
+
+ // PHP < 7.1.4 (and PHP < 7.0.18) suffers from a bug when writing big
+ // chunks of data over TLS streams at once.
+ // We try to work around this by limiting the write chunk size to 8192
+ // bytes for older PHP versions only.
+ // This is only a work-around and has a noticable performance penalty on
+ // affected versions. Please update your PHP version.
+ // This applies to all streams because TLS may be enabled later on.
+ // See https://github.com/reactphp/socket/issues/105
+ $limitWriteChunks = (PHP_VERSION_ID < 70018 || (PHP_VERSION_ID >= 70100 && PHP_VERSION_ID < 70104));
+
+ $this->input = new DuplexResourceStream(
+ $resource,
+ $loop,
+ $clearCompleteBuffer ? -1 : null,
+ new WritableResourceStream($resource, $loop, null, $limitWriteChunks ? 8192 : null)
+ );
+
+ $this->stream = $resource;
+
+ Util::forwardEvents($this->input, $this, array('data', 'end', 'error', 'close', 'pipe', 'drain'));
+
+ $this->input->on('close', array($this, 'close'));
+ }
+
+ public function isReadable()
+ {
+ return $this->input->isReadable();
+ }
+
+ public function isWritable()
+ {
+ return $this->input->isWritable();
+ }
+
+ public function pause()
+ {
+ $this->input->pause();
+ }
+
+ public function resume()
+ {
+ $this->input->resume();
+ }
+
+ public function pipe(WritableStreamInterface $dest, array $options = array())
+ {
+ return $this->input->pipe($dest, $options);
+ }
+
+ public function write($data)
+ {
+ return $this->input->write($data);
+ }
+
+ public function end($data = null)
+ {
+ $this->input->end($data);
+ }
+
+ public function close()
+ {
+ $this->input->close();
+ $this->handleClose();
+ $this->removeAllListeners();
+ }
+
+ public function handleClose()
+ {
+ if (!is_resource($this->stream)) {
+ return;
+ }
+
+ // Try to cleanly shut down socket and ignore any errors in case other
+ // side already closed. Shutting down may return to blocking mode on
+ // some legacy versions, so reset to non-blocking just in case before
+ // continuing to close the socket resource.
+ // Underlying Stream implementation will take care of closing file
+ // handle, so we otherwise keep this open here.
+ @stream_socket_shutdown($this->stream, STREAM_SHUT_RDWR);
+ stream_set_blocking($this->stream, false);
+ }
+
+ public function getRemoteAddress()
+ {
+ return $this->parseAddress(@stream_socket_get_name($this->stream, true));
+ }
+
+ public function getLocalAddress()
+ {
+ return $this->parseAddress(@stream_socket_get_name($this->stream, false));
+ }
+
+ private function parseAddress($address)
+ {
+ if ($address === false) {
+ return null;
+ }
+
+ if ($this->unix) {
+ // remove trailing colon from address for HHVM < 3.19: https://3v4l.org/5C1lo
+ // note that technically ":" is a valid address, so keep this in place otherwise
+ if (substr($address, -1) === ':' && defined('HHVM_VERSION_ID') && HHVM_VERSION_ID < 31900) {
+ $address = (string)substr($address, 0, -1);
+ }
+
+ // work around unknown addresses should return null value: https://3v4l.org/5C1lo and https://bugs.php.net/bug.php?id=74556
+ // PHP uses "\0" string and HHVM uses empty string (colon removed above)
+ if ($address === '' || $address[0] === "\x00" ) {
+ return null;
+ }
+
+ return 'unix://' . $address;
+ }
+
+ // check if this is an IPv6 address which includes multiple colons but no square brackets
+ $pos = strrpos($address, ':');
+ if ($pos !== false && strpos($address, ':') < $pos && substr($address, 0, 1) !== '[') {
+ $port = substr($address, $pos + 1);
+ $address = '[' . substr($address, 0, $pos) . ']:' . $port;
+ }
+
+ return ($this->encryptionEnabled ? 'tls' : 'tcp') . '://' . $address;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/ConnectionInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/ConnectionInterface.php
new file mode 100644
index 0000000..64613b5
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/ConnectionInterface.php
@@ -0,0 +1,119 @@
+<?php
+
+namespace React\Socket;
+
+use React\Stream\DuplexStreamInterface;
+
+/**
+ * Any incoming and outgoing connection is represented by this interface,
+ * such as a normal TCP/IP connection.
+ *
+ * An incoming or outgoing connection is a duplex stream (both readable and
+ * writable) that implements React's
+ * [`DuplexStreamInterface`](https://github.com/reactphp/stream#duplexstreaminterface).
+ * It contains additional properties for the local and remote address (client IP)
+ * where this connection has been established to/from.
+ *
+ * Most commonly, instances implementing this `ConnectionInterface` are emitted
+ * by all classes implementing the [`ServerInterface`](#serverinterface) and
+ * used by all classes implementing the [`ConnectorInterface`](#connectorinterface).
+ *
+ * Because the `ConnectionInterface` implements the underlying
+ * [`DuplexStreamInterface`](https://github.com/reactphp/stream#duplexstreaminterface)
+ * you can use any of its events and methods as usual:
+ *
+ * ```php
+ * $connection->on('data', function ($chunk) {
+ * echo $chunk;
+ * });
+ *
+ * $connection->on('end', function () {
+ * echo 'ended';
+ * });
+ *
+ * $connection->on('error', function (Exception $e) {
+ * echo 'error: ' . $e->getMessage();
+ * });
+ *
+ * $connection->on('close', function () {
+ * echo 'closed';
+ * });
+ *
+ * $connection->write($data);
+ * $connection->end($data = null);
+ * $connection->close();
+ * // …
+ * ```
+ *
+ * For more details, see the
+ * [`DuplexStreamInterface`](https://github.com/reactphp/stream#duplexstreaminterface).
+ *
+ * @see DuplexStreamInterface
+ * @see ServerInterface
+ * @see ConnectorInterface
+ */
+interface ConnectionInterface extends DuplexStreamInterface
+{
+ /**
+ * Returns the full remote address (URI) where this connection has been established with
+ *
+ * ```php
+ * $address = $connection->getRemoteAddress();
+ * echo 'Connection with ' . $address . PHP_EOL;
+ * ```
+ *
+ * If the remote address can not be determined or is unknown at this time (such as
+ * after the connection has been closed), it MAY return a `NULL` value instead.
+ *
+ * Otherwise, it will return the full address (URI) as a string value, such
+ * as `tcp://127.0.0.1:8080`, `tcp://[::1]:80`, `tls://127.0.0.1:443`,
+ * `unix://example.sock` or `unix:///path/to/example.sock`.
+ * Note that individual URI components are application specific and depend
+ * on the underlying transport protocol.
+ *
+ * If this is a TCP/IP based connection and you only want the remote IP, you may
+ * use something like this:
+ *
+ * ```php
+ * $address = $connection->getRemoteAddress();
+ * $ip = trim(parse_url($address, PHP_URL_HOST), '[]');
+ * echo 'Connection with ' . $ip . PHP_EOL;
+ * ```
+ *
+ * @return ?string remote address (URI) or null if unknown
+ */
+ public function getRemoteAddress();
+
+ /**
+ * Returns the full local address (full URI with scheme, IP and port) where this connection has been established with
+ *
+ * ```php
+ * $address = $connection->getLocalAddress();
+ * echo 'Connection with ' . $address . PHP_EOL;
+ * ```
+ *
+ * If the local address can not be determined or is unknown at this time (such as
+ * after the connection has been closed), it MAY return a `NULL` value instead.
+ *
+ * Otherwise, it will return the full address (URI) as a string value, such
+ * as `tcp://127.0.0.1:8080`, `tcp://[::1]:80`, `tls://127.0.0.1:443`,
+ * `unix://example.sock` or `unix:///path/to/example.sock`.
+ * Note that individual URI components are application specific and depend
+ * on the underlying transport protocol.
+ *
+ * This method complements the [`getRemoteAddress()`](#getremoteaddress) method,
+ * so they should not be confused.
+ *
+ * If your `TcpServer` instance is listening on multiple interfaces (e.g. using
+ * the address `0.0.0.0`), you can use this method to find out which interface
+ * actually accepted this connection (such as a public or local interface).
+ *
+ * If your system has multiple interfaces (e.g. a WAN and a LAN interface),
+ * you can use this method to find out which interface was actually
+ * used for this connection.
+ *
+ * @return ?string local address (URI) or null if unknown
+ * @see self::getRemoteAddress()
+ */
+ public function getLocalAddress();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/Connector.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/Connector.php
new file mode 100644
index 0000000..75276bc
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/Connector.php
@@ -0,0 +1,136 @@
+<?php
+
+namespace React\Socket;
+
+use React\Dns\Config\Config;
+use React\Dns\Resolver\Factory;
+use React\Dns\Resolver\Resolver;
+use React\EventLoop\LoopInterface;
+use React\Promise;
+use RuntimeException;
+
+/**
+ * The `Connector` class is the main class in this package that implements the
+ * `ConnectorInterface` and allows you to create streaming connections.
+ *
+ * You can use this connector to create any kind of streaming connections, such
+ * as plaintext TCP/IP, secure TLS or local Unix connection streams.
+ *
+ * Under the hood, the `Connector` is implemented as a *higher-level facade*
+ * or the lower-level connectors implemented in this package. This means it
+ * also shares all of their features and implementation details.
+ * If you want to typehint in your higher-level protocol implementation, you SHOULD
+ * use the generic [`ConnectorInterface`](#connectorinterface) instead.
+ *
+ * @see ConnectorInterface for the base interface
+ */
+final class Connector implements ConnectorInterface
+{
+ private $connectors = array();
+
+ public function __construct(LoopInterface $loop, array $options = array())
+ {
+ // apply default options if not explicitly given
+ $options += array(
+ 'tcp' => true,
+ 'tls' => true,
+ 'unix' => true,
+
+ 'dns' => true,
+ 'timeout' => true,
+ );
+
+ if ($options['timeout'] === true) {
+ $options['timeout'] = (float)ini_get("default_socket_timeout");
+ }
+
+ if ($options['tcp'] instanceof ConnectorInterface) {
+ $tcp = $options['tcp'];
+ } else {
+ $tcp = new TcpConnector(
+ $loop,
+ is_array($options['tcp']) ? $options['tcp'] : array()
+ );
+ }
+
+ if ($options['dns'] !== false) {
+ if ($options['dns'] instanceof Resolver) {
+ $resolver = $options['dns'];
+ } else {
+ if ($options['dns'] !== true) {
+ $server = $options['dns'];
+ } else {
+ // try to load nameservers from system config or default to Google's public DNS
+ $config = Config::loadSystemConfigBlocking();
+ $server = $config->nameservers ? reset($config->nameservers) : '8.8.8.8';
+ }
+
+ $factory = new Factory();
+ $resolver = $factory->create(
+ $server,
+ $loop
+ );
+ }
+
+ $tcp = new DnsConnector($tcp, $resolver);
+ }
+
+ if ($options['tcp'] !== false) {
+ $options['tcp'] = $tcp;
+
+ if ($options['timeout'] !== false) {
+ $options['tcp'] = new TimeoutConnector(
+ $options['tcp'],
+ $options['timeout'],
+ $loop
+ );
+ }
+
+ $this->connectors['tcp'] = $options['tcp'];
+ }
+
+ if ($options['tls'] !== false) {
+ if (!$options['tls'] instanceof ConnectorInterface) {
+ $options['tls'] = new SecureConnector(
+ $tcp,
+ $loop,
+ is_array($options['tls']) ? $options['tls'] : array()
+ );
+ }
+
+ if ($options['timeout'] !== false) {
+ $options['tls'] = new TimeoutConnector(
+ $options['tls'],
+ $options['timeout'],
+ $loop
+ );
+ }
+
+ $this->connectors['tls'] = $options['tls'];
+ }
+
+ if ($options['unix'] !== false) {
+ if (!$options['unix'] instanceof ConnectorInterface) {
+ $options['unix'] = new UnixConnector($loop);
+ }
+ $this->connectors['unix'] = $options['unix'];
+ }
+ }
+
+ public function connect($uri)
+ {
+ $scheme = 'tcp';
+ if (strpos($uri, '://') !== false) {
+ $scheme = (string)substr($uri, 0, strpos($uri, '://'));
+ }
+
+ if (!isset($this->connectors[$scheme])) {
+ return Promise\reject(new RuntimeException(
+ 'No connector available for URI scheme "' . $scheme . '"'
+ ));
+ }
+
+ return $this->connectors[$scheme]->connect($uri);
+ }
+}
+
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/ConnectorInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/ConnectorInterface.php
new file mode 100644
index 0000000..196d01a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/ConnectorInterface.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace React\Socket;
+
+/**
+ * The `ConnectorInterface` is responsible for providing an interface for
+ * establishing streaming connections, such as a normal TCP/IP connection.
+ *
+ * This is the main interface defined in this package and it is used throughout
+ * React's vast ecosystem.
+ *
+ * Most higher-level components (such as HTTP, database or other networking
+ * service clients) accept an instance implementing this interface to create their
+ * TCP/IP connection to the underlying networking service.
+ * This is usually done via dependency injection, so it's fairly simple to actually
+ * swap this implementation against any other implementation of this interface.
+ *
+ * The interface only offers a single `connect()` method.
+ *
+ * @see ConnectionInterface
+ */
+interface ConnectorInterface
+{
+ /**
+ * Creates a streaming connection to the given remote address
+ *
+ * If returns a Promise which either fulfills with a stream implementing
+ * `ConnectionInterface` on success or rejects with an `Exception` if the
+ * connection is not successful.
+ *
+ * ```php
+ * $connector->connect('google.com:443')->then(
+ * function (ConnectionInterface $connection) {
+ * // connection successfully established
+ * },
+ * function (Exception $error) {
+ * // failed to connect due to $error
+ * }
+ * );
+ * ```
+ *
+ * The returned Promise MUST be implemented in such a way that it can be
+ * cancelled when it is still pending. Cancelling a pending promise MUST
+ * reject its value with an Exception. It SHOULD clean up any underlying
+ * resources and references as applicable.
+ *
+ * ```php
+ * $promise = $connector->connect($uri);
+ *
+ * $promise->cancel();
+ * ```
+ *
+ * @param string $uri
+ * @return \React\Promise\PromiseInterface resolves with a stream implementing ConnectionInterface on success or rejects with an Exception on error
+ * @see ConnectionInterface
+ */
+ public function connect($uri);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/DnsConnector.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/DnsConnector.php
new file mode 100644
index 0000000..90170e5
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/DnsConnector.php
@@ -0,0 +1,111 @@
+<?php
+
+namespace React\Socket;
+
+use React\Dns\Resolver\Resolver;
+use React\Promise;
+use React\Promise\CancellablePromiseInterface;
+use InvalidArgumentException;
+use RuntimeException;
+
+final class DnsConnector implements ConnectorInterface
+{
+ private $connector;
+ private $resolver;
+
+ public function __construct(ConnectorInterface $connector, Resolver $resolver)
+ {
+ $this->connector = $connector;
+ $this->resolver = $resolver;
+ }
+
+ public function connect($uri)
+ {
+ if (strpos($uri, '://') === false) {
+ $parts = parse_url('tcp://' . $uri);
+ unset($parts['scheme']);
+ } else {
+ $parts = parse_url($uri);
+ }
+
+ if (!$parts || !isset($parts['host'])) {
+ return Promise\reject(new InvalidArgumentException('Given URI "' . $uri . '" is invalid'));
+ }
+
+ $host = trim($parts['host'], '[]');
+ $connector = $this->connector;
+
+ return $this
+ ->resolveHostname($host)
+ ->then(function ($ip) use ($connector, $host, $parts) {
+ $uri = '';
+
+ // prepend original scheme if known
+ if (isset($parts['scheme'])) {
+ $uri .= $parts['scheme'] . '://';
+ }
+
+ if (strpos($ip, ':') !== false) {
+ // enclose IPv6 addresses in square brackets before appending port
+ $uri .= '[' . $ip . ']';
+ } else {
+ $uri .= $ip;
+ }
+
+ // append original port if known
+ if (isset($parts['port'])) {
+ $uri .= ':' . $parts['port'];
+ }
+
+ // append orignal path if known
+ if (isset($parts['path'])) {
+ $uri .= $parts['path'];
+ }
+
+ // append original query if known
+ if (isset($parts['query'])) {
+ $uri .= '?' . $parts['query'];
+ }
+
+ // append original hostname as query if resolved via DNS and if
+ // destination URI does not contain "hostname" query param already
+ $args = array();
+ parse_str(isset($parts['query']) ? $parts['query'] : '', $args);
+ if ($host !== $ip && !isset($args['hostname'])) {
+ $uri .= (isset($parts['query']) ? '&' : '?') . 'hostname=' . rawurlencode($host);
+ }
+
+ // append original fragment if known
+ if (isset($parts['fragment'])) {
+ $uri .= '#' . $parts['fragment'];
+ }
+
+ return $connector->connect($uri);
+ });
+ }
+
+ private function resolveHostname($host)
+ {
+ if (false !== filter_var($host, FILTER_VALIDATE_IP)) {
+ return Promise\resolve($host);
+ }
+
+ $promise = $this->resolver->resolve($host);
+
+ return new Promise\Promise(
+ function ($resolve, $reject) use ($promise) {
+ // resolve/reject with result of DNS lookup
+ $promise->then($resolve, $reject);
+ },
+ function ($_, $reject) use ($promise) {
+ // cancellation should reject connection attempt
+ $reject(new RuntimeException('Connection attempt cancelled during DNS lookup'));
+
+ // (try to) cancel pending DNS lookup
+ if ($promise instanceof CancellablePromiseInterface) {
+ $promise->cancel();
+ }
+ }
+ );
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/FixedUriConnector.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/FixedUriConnector.php
new file mode 100644
index 0000000..057bcdf
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/FixedUriConnector.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace React\Socket;
+
+/**
+ * Decorates an existing Connector to always use a fixed, preconfigured URI
+ *
+ * This can be useful for consumers that do not support certain URIs, such as
+ * when you want to explicitly connect to a Unix domain socket (UDS) path
+ * instead of connecting to a default address assumed by an higher-level API:
+ *
+ * ```php
+ * $connector = new FixedUriConnector(
+ * 'unix:///var/run/docker.sock',
+ * new UnixConnector($loop)
+ * );
+ *
+ * // destination will be ignored, actually connects to Unix domain socket
+ * $promise = $connector->connect('localhost:80');
+ * ```
+ */
+class FixedUriConnector implements ConnectorInterface
+{
+ private $uri;
+ private $connector;
+
+ /**
+ * @param string $uri
+ * @param ConnectorInterface $connector
+ */
+ public function __construct($uri, ConnectorInterface $connector)
+ {
+ $this->uri = $uri;
+ $this->connector = $connector;
+ }
+
+ public function connect($_)
+ {
+ return $this->connector->connect($this->uri);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/LimitingServer.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/LimitingServer.php
new file mode 100644
index 0000000..c7874ee
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/LimitingServer.php
@@ -0,0 +1,203 @@
+<?php
+
+namespace React\Socket;
+
+use Evenement\EventEmitter;
+use Exception;
+use OverflowException;
+
+/**
+ * The `LimitingServer` decorator wraps a given `ServerInterface` and is responsible
+ * for limiting and keeping track of open connections to this server instance.
+ *
+ * Whenever the underlying server emits a `connection` event, it will check its
+ * limits and then either
+ * - keep track of this connection by adding it to the list of
+ * open connections and then forward the `connection` event
+ * - or reject (close) the connection when its limits are exceeded and will
+ * forward an `error` event instead.
+ *
+ * Whenever a connection closes, it will remove this connection from the list of
+ * open connections.
+ *
+ * ```php
+ * $server = new LimitingServer($server, 100);
+ * $server->on('connection', function (ConnectionInterface $connection) {
+ * $connection->write('hello there!' . PHP_EOL);
+ * …
+ * });
+ * ```
+ *
+ * See also the `ServerInterface` for more details.
+ *
+ * @see ServerInterface
+ * @see ConnectionInterface
+ */
+class LimitingServer extends EventEmitter implements ServerInterface
+{
+ private $connections = array();
+ private $server;
+ private $limit;
+
+ private $pauseOnLimit = false;
+ private $autoPaused = false;
+ private $manuPaused = false;
+
+ /**
+ * Instantiates a new LimitingServer.
+ *
+ * You have to pass a maximum number of open connections to ensure
+ * the server will automatically reject (close) connections once this limit
+ * is exceeded. In this case, it will emit an `error` event to inform about
+ * this and no `connection` event will be emitted.
+ *
+ * ```php
+ * $server = new LimitingServer($server, 100);
+ * $server->on('connection', function (ConnectionInterface $connection) {
+ * $connection->write('hello there!' . PHP_EOL);
+ * …
+ * });
+ * ```
+ *
+ * You MAY pass a `null` limit in order to put no limit on the number of
+ * open connections and keep accepting new connection until you run out of
+ * operating system resources (such as open file handles). This may be
+ * useful if you do not want to take care of applying a limit but still want
+ * to use the `getConnections()` method.
+ *
+ * You can optionally configure the server to pause accepting new
+ * connections once the connection limit is reached. In this case, it will
+ * pause the underlying server and no longer process any new connections at
+ * all, thus also no longer closing any excessive connections.
+ * The underlying operating system is responsible for keeping a backlog of
+ * pending connections until its limit is reached, at which point it will
+ * start rejecting further connections.
+ * Once the server is below the connection limit, it will continue consuming
+ * connections from the backlog and will process any outstanding data on
+ * each connection.
+ * This mode may be useful for some protocols that are designed to wait for
+ * a response message (such as HTTP), but may be less useful for other
+ * protocols that demand immediate responses (such as a "welcome" message in
+ * an interactive chat).
+ *
+ * ```php
+ * $server = new LimitingServer($server, 100, true);
+ * $server->on('connection', function (ConnectionInterface $connection) {
+ * $connection->write('hello there!' . PHP_EOL);
+ * …
+ * });
+ * ```
+ *
+ * @param ServerInterface $server
+ * @param int|null $connectionLimit
+ * @param bool $pauseOnLimit
+ */
+ public function __construct(ServerInterface $server, $connectionLimit, $pauseOnLimit = false)
+ {
+ $this->server = $server;
+ $this->limit = $connectionLimit;
+ if ($connectionLimit !== null) {
+ $this->pauseOnLimit = $pauseOnLimit;
+ }
+
+ $this->server->on('connection', array($this, 'handleConnection'));
+ $this->server->on('error', array($this, 'handleError'));
+ }
+
+ /**
+ * Returns an array with all currently active connections
+ *
+ * ```php
+ * foreach ($server->getConnection() as $connection) {
+ * $connection->write('Hi!');
+ * }
+ * ```
+ *
+ * @return ConnectionInterface[]
+ */
+ public function getConnections()
+ {
+ return $this->connections;
+ }
+
+ public function getAddress()
+ {
+ return $this->server->getAddress();
+ }
+
+ public function pause()
+ {
+ if (!$this->manuPaused) {
+ $this->manuPaused = true;
+
+ if (!$this->autoPaused) {
+ $this->server->pause();
+ }
+ }
+ }
+
+ public function resume()
+ {
+ if ($this->manuPaused) {
+ $this->manuPaused = false;
+
+ if (!$this->autoPaused) {
+ $this->server->resume();
+ }
+ }
+ }
+
+ public function close()
+ {
+ $this->server->close();
+ }
+
+ /** @internal */
+ public function handleConnection(ConnectionInterface $connection)
+ {
+ // close connection if limit exceeded
+ if ($this->limit !== null && count($this->connections) >= $this->limit) {
+ $this->handleError(new OverflowException('Connection closed because server reached connection limit'));
+ $connection->close();
+ return;
+ }
+
+ $this->connections[] = $connection;
+ $that = $this;
+ $connection->on('close', function () use ($that, $connection) {
+ $that->handleDisconnection($connection);
+ });
+
+ // pause accepting new connections if limit exceeded
+ if ($this->pauseOnLimit && !$this->autoPaused && count($this->connections) >= $this->limit) {
+ $this->autoPaused = true;
+
+ if (!$this->manuPaused) {
+ $this->server->pause();
+ }
+ }
+
+ $this->emit('connection', array($connection));
+ }
+
+ /** @internal */
+ public function handleDisconnection(ConnectionInterface $connection)
+ {
+ unset($this->connections[array_search($connection, $this->connections)]);
+
+ // continue accepting new connection if below limit
+ if ($this->autoPaused && count($this->connections) < $this->limit) {
+ $this->autoPaused = false;
+
+ if (!$this->manuPaused) {
+ $this->server->resume();
+ }
+ }
+ }
+
+ /** @internal */
+ public function handleError(Exception $error)
+ {
+ $this->emit('error', array($error));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/SecureConnector.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/SecureConnector.php
new file mode 100644
index 0000000..f04183d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/SecureConnector.php
@@ -0,0 +1,64 @@
+<?php
+
+namespace React\Socket;
+
+use React\EventLoop\LoopInterface;
+use React\Promise;
+use BadMethodCallException;
+use InvalidArgumentException;
+use UnexpectedValueException;
+
+final class SecureConnector implements ConnectorInterface
+{
+ private $connector;
+ private $streamEncryption;
+ private $context;
+
+ public function __construct(ConnectorInterface $connector, LoopInterface $loop, array $context = array())
+ {
+ $this->connector = $connector;
+ $this->streamEncryption = new StreamEncryption($loop, false);
+ $this->context = $context;
+ }
+
+ public function connect($uri)
+ {
+ if (!function_exists('stream_socket_enable_crypto')) {
+ return Promise\reject(new BadMethodCallException('Encryption not supported on your platform (HHVM < 3.8?)')); // @codeCoverageIgnore
+ }
+
+ if (strpos($uri, '://') === false) {
+ $uri = 'tls://' . $uri;
+ }
+
+ $parts = parse_url($uri);
+ if (!$parts || !isset($parts['scheme']) || $parts['scheme'] !== 'tls') {
+ return Promise\reject(new InvalidArgumentException('Given URI "' . $uri . '" is invalid'));
+ }
+
+ $uri = str_replace('tls://', '', $uri);
+ $context = $this->context;
+
+ $encryption = $this->streamEncryption;
+ return $this->connector->connect($uri)->then(function (ConnectionInterface $connection) use ($context, $encryption) {
+ // (unencrypted) TCP/IP connection succeeded
+
+ if (!$connection instanceof Connection) {
+ $connection->close();
+ throw new UnexpectedValueException('Base connector does not use internal Connection class exposing stream resource');
+ }
+
+ // set required SSL/TLS context options
+ foreach ($context as $name => $value) {
+ stream_context_set_option($connection->stream, 'ssl', $name, $value);
+ }
+
+ // try to enable encryption
+ return $encryption->enable($connection)->then(null, function ($error) use ($connection) {
+ // establishing encryption failed => close invalid connection and return error
+ $connection->close();
+ throw $error;
+ });
+ });
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/SecureServer.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/SecureServer.php
new file mode 100644
index 0000000..302ae93
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/SecureServer.php
@@ -0,0 +1,192 @@
+<?php
+
+namespace React\Socket;
+
+use Evenement\EventEmitter;
+use React\EventLoop\LoopInterface;
+use BadMethodCallException;
+use UnexpectedValueException;
+
+/**
+ * The `SecureServer` class implements the `ServerInterface` and is responsible
+ * for providing a secure TLS (formerly known as SSL) server.
+ *
+ * It does so by wrapping a `TcpServer` instance which waits for plaintext
+ * TCP/IP connections and then performs a TLS handshake for each connection.
+ *
+ * ```php
+ * $server = new TcpServer(8000, $loop);
+ * $server = new SecureServer($server, $loop, array(
+ * // tls context options here…
+ * ));
+ * ```
+ *
+ * Whenever a client completes the TLS handshake, it will emit a `connection` event
+ * with a connection instance implementing [`ConnectionInterface`](#connectioninterface):
+ *
+ * ```php
+ * $server->on('connection', function (ConnectionInterface $connection) {
+ * echo 'Secure connection from' . $connection->getRemoteAddress() . PHP_EOL;
+ *
+ * $connection->write('hello there!' . PHP_EOL);
+ * …
+ * });
+ * ```
+ *
+ * Whenever a client fails to perform a successful TLS handshake, it will emit an
+ * `error` event and then close the underlying TCP/IP connection:
+ *
+ * ```php
+ * $server->on('error', function (Exception $e) {
+ * echo 'Error' . $e->getMessage() . PHP_EOL;
+ * });
+ * ```
+ *
+ * See also the `ServerInterface` for more details.
+ *
+ * Note that the `SecureServer` class is a concrete implementation for TLS sockets.
+ * If you want to typehint in your higher-level protocol implementation, you SHOULD
+ * use the generic `ServerInterface` instead.
+ *
+ * @see ServerInterface
+ * @see ConnectionInterface
+ */
+final class SecureServer extends EventEmitter implements ServerInterface
+{
+ private $tcp;
+ private $encryption;
+ private $context;
+
+ /**
+ * Creates a secure TLS server and starts waiting for incoming connections
+ *
+ * It does so by wrapping a `TcpServer` instance which waits for plaintext
+ * TCP/IP connections and then performs a TLS handshake for each connection.
+ * It thus requires valid [TLS context options],
+ * which in its most basic form may look something like this if you're using a
+ * PEM encoded certificate file:
+ *
+ * ```php
+ * $server = new TcpServer(8000, $loop);
+ * $server = new SecureServer($server, $loop, array(
+ * 'local_cert' => 'server.pem'
+ * ));
+ * ```
+ *
+ * Note that the certificate file will not be loaded on instantiation but when an
+ * incoming connection initializes its TLS context.
+ * This implies that any invalid certificate file paths or contents will only cause
+ * an `error` event at a later time.
+ *
+ * If your private key is encrypted with a passphrase, you have to specify it
+ * like this:
+ *
+ * ```php
+ * $server = new TcpServer(8000, $loop);
+ * $server = new SecureServer($server, $loop, array(
+ * 'local_cert' => 'server.pem',
+ * 'passphrase' => 'secret'
+ * ));
+ * ```
+ *
+ * Note that available [TLS context options],
+ * their defaults and effects of changing these may vary depending on your system
+ * and/or PHP version.
+ * Passing unknown context options has no effect.
+ *
+ * Advanced usage: Despite allowing any `ServerInterface` as first parameter,
+ * you SHOULD pass a `TcpServer` instance as first parameter, unless you
+ * know what you're doing.
+ * Internally, the `SecureServer` has to set the required TLS context options on
+ * the underlying stream resources.
+ * These resources are not exposed through any of the interfaces defined in this
+ * package, but only through the internal `Connection` class.
+ * The `TcpServer` class is guaranteed to emit connections that implement
+ * the `ConnectionInterface` and uses the internal `Connection` class in order to
+ * expose these underlying resources.
+ * If you use a custom `ServerInterface` and its `connection` event does not
+ * meet this requirement, the `SecureServer` will emit an `error` event and
+ * then close the underlying connection.
+ *
+ * @param ServerInterface|TcpServer $tcp
+ * @param LoopInterface $loop
+ * @param array $context
+ * @throws BadMethodCallException for legacy HHVM < 3.8 due to lack of support
+ * @see TcpServer
+ * @link http://php.net/manual/en/context.ssl.php for TLS context options
+ */
+ public function __construct(ServerInterface $tcp, LoopInterface $loop, array $context)
+ {
+ if (!function_exists('stream_socket_enable_crypto')) {
+ throw new BadMethodCallException('Encryption not supported on your platform (HHVM < 3.8?)'); // @codeCoverageIgnore
+ }
+
+ // default to empty passphrase to suppress blocking passphrase prompt
+ $context += array(
+ 'passphrase' => ''
+ );
+
+ $this->tcp = $tcp;
+ $this->encryption = new StreamEncryption($loop);
+ $this->context = $context;
+
+ $that = $this;
+ $this->tcp->on('connection', function ($connection) use ($that) {
+ $that->handleConnection($connection);
+ });
+ $this->tcp->on('error', function ($error) use ($that) {
+ $that->emit('error', array($error));
+ });
+ }
+
+ public function getAddress()
+ {
+ $address = $this->tcp->getAddress();
+ if ($address === null) {
+ return null;
+ }
+
+ return str_replace('tcp://' , 'tls://', $address);
+ }
+
+ public function pause()
+ {
+ $this->tcp->pause();
+ }
+
+ public function resume()
+ {
+ $this->tcp->resume();
+ }
+
+ public function close()
+ {
+ return $this->tcp->close();
+ }
+
+ /** @internal */
+ public function handleConnection(ConnectionInterface $connection)
+ {
+ if (!$connection instanceof Connection) {
+ $this->emit('error', array(new UnexpectedValueException('Base server does not use internal Connection class exposing stream resource')));
+ $connection->end();
+ return;
+ }
+
+ foreach ($this->context as $name => $value) {
+ stream_context_set_option($connection->stream, 'ssl', $name, $value);
+ }
+
+ $that = $this;
+
+ $this->encryption->enable($connection)->then(
+ function ($conn) use ($that) {
+ $that->emit('connection', array($conn));
+ },
+ function ($error) use ($that, $connection) {
+ $that->emit('error', array($error));
+ $connection->end();
+ }
+ );
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/Server.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/Server.php
new file mode 100644
index 0000000..72712e4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/Server.php
@@ -0,0 +1,73 @@
+<?php
+
+namespace React\Socket;
+
+use Evenement\EventEmitter;
+use React\EventLoop\LoopInterface;
+use Exception;
+
+final class Server extends EventEmitter implements ServerInterface
+{
+ private $server;
+
+ public function __construct($uri, LoopInterface $loop, array $context = array())
+ {
+ // sanitize TCP context options if not properly wrapped
+ if ($context && (!isset($context['tcp']) && !isset($context['tls']) && !isset($context['unix']))) {
+ $context = array('tcp' => $context);
+ }
+
+ // apply default options if not explicitly given
+ $context += array(
+ 'tcp' => array(),
+ 'tls' => array(),
+ 'unix' => array()
+ );
+
+ $scheme = 'tcp';
+ $pos = strpos($uri, '://');
+ if ($pos !== false) {
+ $scheme = substr($uri, 0, $pos);
+ }
+
+ if ($scheme === 'unix') {
+ $server = new UnixServer($uri, $loop, $context['unix']);
+ } else {
+ $server = new TcpServer(str_replace('tls://', '', $uri), $loop, $context['tcp']);
+
+ if ($scheme === 'tls') {
+ $server = new SecureServer($server, $loop, $context['tls']);
+ }
+ }
+
+ $this->server = $server;
+
+ $that = $this;
+ $server->on('connection', function (ConnectionInterface $conn) use ($that) {
+ $that->emit('connection', array($conn));
+ });
+ $server->on('error', function (Exception $error) use ($that) {
+ $that->emit('error', array($error));
+ });
+ }
+
+ public function getAddress()
+ {
+ return $this->server->getAddress();
+ }
+
+ public function pause()
+ {
+ $this->server->pause();
+ }
+
+ public function resume()
+ {
+ $this->server->resume();
+ }
+
+ public function close()
+ {
+ $this->server->close();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/ServerInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/ServerInterface.php
new file mode 100644
index 0000000..5319678
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/ServerInterface.php
@@ -0,0 +1,151 @@
+<?php
+
+namespace React\Socket;
+
+use Evenement\EventEmitterInterface;
+
+/**
+ * The `ServerInterface` is responsible for providing an interface for accepting
+ * incoming streaming connections, such as a normal TCP/IP connection.
+ *
+ * Most higher-level components (such as a HTTP server) accept an instance
+ * implementing this interface to accept incoming streaming connections.
+ * This is usually done via dependency injection, so it's fairly simple to actually
+ * swap this implementation against any other implementation of this interface.
+ * This means that you SHOULD typehint against this interface instead of a concrete
+ * implementation of this interface.
+ *
+ * Besides defining a few methods, this interface also implements the
+ * `EventEmitterInterface` which allows you to react to certain events:
+ *
+ * connection event:
+ * The `connection` event will be emitted whenever a new connection has been
+ * established, i.e. a new client connects to this server socket:
+ *
+ * ```php
+ * $server->on('connection', function (ConnectionInterface $connection) {
+ * echo 'new connection' . PHP_EOL;
+ * });
+ * ```
+ *
+ * See also the `ConnectionInterface` for more details about handling the
+ * incoming connection.
+ *
+ * error event:
+ * The `error` event will be emitted whenever there's an error accepting a new
+ * connection from a client.
+ *
+ * ```php
+ * $server->on('error', function (Exception $e) {
+ * echo 'error: ' . $e->getMessage() . PHP_EOL;
+ * });
+ * ```
+ *
+ * Note that this is not a fatal error event, i.e. the server keeps listening for
+ * new connections even after this event.
+ *
+ * @see ConnectionInterface
+ */
+interface ServerInterface extends EventEmitterInterface
+{
+ /**
+ * Returns the full address (URI) this server is currently listening on
+ *
+ * ```php
+ * $address = $server->getAddress();
+ * echo 'Server listening on ' . $address . PHP_EOL;
+ * ```
+ *
+ * If the address can not be determined or is unknown at this time (such as
+ * after the socket has been closed), it MAY return a `NULL` value instead.
+ *
+ * Otherwise, it will return the full address (URI) as a string value, such
+ * as `tcp://127.0.0.1:8080`, `tcp://[::1]:80` or `tls://127.0.0.1:443`.
+ * Note that individual URI components are application specific and depend
+ * on the underlying transport protocol.
+ *
+ * If this is a TCP/IP based server and you only want the local port, you may
+ * use something like this:
+ *
+ * ```php
+ * $address = $server->getAddress();
+ * $port = parse_url($address, PHP_URL_PORT);
+ * echo 'Server listening on port ' . $port . PHP_EOL;
+ * ```
+ *
+ * @return ?string the full listening address (URI) or NULL if it is unknown (not applicable to this server socket or already closed)
+ */
+ public function getAddress();
+
+ /**
+ * Pauses accepting new incoming connections.
+ *
+ * Removes the socket resource from the EventLoop and thus stop accepting
+ * new connections. Note that the listening socket stays active and is not
+ * closed.
+ *
+ * This means that new incoming connections will stay pending in the
+ * operating system backlog until its configurable backlog is filled.
+ * Once the backlog is filled, the operating system may reject further
+ * incoming connections until the backlog is drained again by resuming
+ * to accept new connections.
+ *
+ * Once the server is paused, no futher `connection` events SHOULD
+ * be emitted.
+ *
+ * ```php
+ * $server->pause();
+ *
+ * $server->on('connection', assertShouldNeverCalled());
+ * ```
+ *
+ * This method is advisory-only, though generally not recommended, the
+ * server MAY continue emitting `connection` events.
+ *
+ * Unless otherwise noted, a successfully opened server SHOULD NOT start
+ * in paused state.
+ *
+ * You can continue processing events by calling `resume()` again.
+ *
+ * Note that both methods can be called any number of times, in particular
+ * calling `pause()` more than once SHOULD NOT have any effect.
+ * Similarly, calling this after `close()` is a NO-OP.
+ *
+ * @see self::resume()
+ * @return void
+ */
+ public function pause();
+
+ /**
+ * Resumes accepting new incoming connections.
+ *
+ * Re-attach the socket resource to the EventLoop after a previous `pause()`.
+ *
+ * ```php
+ * $server->pause();
+ *
+ * $loop->addTimer(1.0, function () use ($server) {
+ * $server->resume();
+ * });
+ * ```
+ *
+ * Note that both methods can be called any number of times, in particular
+ * calling `resume()` without a prior `pause()` SHOULD NOT have any effect.
+ * Similarly, calling this after `close()` is a NO-OP.
+ *
+ * @see self::pause()
+ * @return void
+ */
+ public function resume();
+
+ /**
+ * Shuts down this listening socket
+ *
+ * This will stop listening for new incoming connections on this socket.
+ *
+ * Calling this method more than once on the same instance is a NO-OP.
+ *
+ * @return void
+ */
+ public function close();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/StreamEncryption.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/StreamEncryption.php
new file mode 100644
index 0000000..ba5d472
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/StreamEncryption.php
@@ -0,0 +1,146 @@
+<?php
+
+namespace React\Socket;
+
+use React\EventLoop\LoopInterface;
+use React\Promise\Deferred;
+use RuntimeException;
+use UnexpectedValueException;
+
+/**
+ * This class is considered internal and its API should not be relied upon
+ * outside of Socket.
+ *
+ * @internal
+ */
+class StreamEncryption
+{
+ private $loop;
+ private $method;
+ private $server;
+
+ private $errstr;
+ private $errno;
+
+ public function __construct(LoopInterface $loop, $server = true)
+ {
+ $this->loop = $loop;
+ $this->server = $server;
+
+ // support TLSv1.0+ by default and exclude legacy SSLv2/SSLv3.
+ // PHP 5.6+ supports bitmasks, legacy PHP only supports predefined
+ // constants, so apply accordingly below.
+ // Also, since PHP 5.6.7 up until before PHP 7.2.0 the main constant did
+ // only support TLSv1.0, so we explicitly apply all versions.
+ // @link http://php.net/manual/en/migration56.openssl.php#migration56.openssl.crypto-method
+ // @link https://3v4l.org/plbFn
+ if ($server) {
+ $this->method = STREAM_CRYPTO_METHOD_TLS_SERVER;
+
+ if (defined('STREAM_CRYPTO_METHOD_TLSv1_0_SERVER')) {
+ $this->method |= STREAM_CRYPTO_METHOD_TLSv1_0_SERVER;
+ }
+ if (defined('STREAM_CRYPTO_METHOD_TLSv1_1_SERVER')) {
+ $this->method |= STREAM_CRYPTO_METHOD_TLSv1_1_SERVER;
+ }
+ if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_SERVER')) {
+ $this->method |= STREAM_CRYPTO_METHOD_TLSv1_2_SERVER;
+ }
+ } else {
+ $this->method = STREAM_CRYPTO_METHOD_TLS_CLIENT;
+
+ if (defined('STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT')) {
+ $this->method |= STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT;
+ }
+ if (defined('STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT')) {
+ $this->method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
+ }
+ if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
+ $this->method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
+ }
+ }
+ }
+
+ public function enable(Connection $stream)
+ {
+ return $this->toggle($stream, true);
+ }
+
+ public function disable(Connection $stream)
+ {
+ return $this->toggle($stream, false);
+ }
+
+ public function toggle(Connection $stream, $toggle)
+ {
+ // pause actual stream instance to continue operation on raw stream socket
+ $stream->pause();
+
+ // TODO: add write() event to make sure we're not sending any excessive data
+
+ $deferred = new Deferred(function ($_, $reject) use ($toggle) {
+ // cancelling this leaves this stream in an inconsistent state…
+ $reject(new RuntimeException('Cancelled toggling encryption ' . $toggle ? 'on' : 'off'));
+ });
+
+ // get actual stream socket from stream instance
+ $socket = $stream->stream;
+
+ // get crypto method from context options or use global setting from constructor
+ $method = $this->method;
+ $context = stream_context_get_options($socket);
+ if (isset($context['ssl']['crypto_method'])) {
+ $method = $context['ssl']['crypto_method'];
+ }
+
+ $that = $this;
+ $toggleCrypto = function () use ($socket, $deferred, $toggle, $method, $that) {
+ $that->toggleCrypto($socket, $deferred, $toggle, $method);
+ };
+
+ $this->loop->addReadStream($socket, $toggleCrypto);
+
+ if (!$this->server) {
+ $toggleCrypto();
+ }
+
+ $loop = $this->loop;
+
+ return $deferred->promise()->then(function () use ($stream, $socket, $loop, $toggle) {
+ $loop->removeReadStream($socket);
+
+ $stream->encryptionEnabled = $toggle;
+ $stream->resume();
+
+ return $stream;
+ }, function($error) use ($stream, $socket, $loop) {
+ $loop->removeReadStream($socket);
+ $stream->resume();
+ throw $error;
+ });
+ }
+
+ public function toggleCrypto($socket, Deferred $deferred, $toggle, $method)
+ {
+ set_error_handler(array($this, 'handleError'));
+ $result = stream_socket_enable_crypto($socket, $toggle, $method);
+ restore_error_handler();
+
+ if (true === $result) {
+ $deferred->resolve();
+ } else if (false === $result) {
+ $deferred->reject(new UnexpectedValueException(
+ sprintf("Unable to complete SSL/TLS handshake: %s", $this->errstr),
+ $this->errno
+ ));
+ } else {
+ // need more data, will retry
+ }
+ }
+
+ public function handleError($errno, $errstr)
+ {
+ $this->errstr = str_replace(array("\r", "\n"), ' ', $errstr);
+ $this->errno = $errno;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/TcpConnector.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/TcpConnector.php
new file mode 100644
index 0000000..90d7df1
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/TcpConnector.php
@@ -0,0 +1,122 @@
+<?php
+
+namespace React\Socket;
+
+use React\EventLoop\LoopInterface;
+use React\Promise;
+use InvalidArgumentException;
+use RuntimeException;
+
+final class TcpConnector implements ConnectorInterface
+{
+ private $loop;
+ private $context;
+
+ public function __construct(LoopInterface $loop, array $context = array())
+ {
+ $this->loop = $loop;
+ $this->context = $context;
+ }
+
+ public function connect($uri)
+ {
+ if (strpos($uri, '://') === false) {
+ $uri = 'tcp://' . $uri;
+ }
+
+ $parts = parse_url($uri);
+ if (!$parts || !isset($parts['scheme'], $parts['host'], $parts['port']) || $parts['scheme'] !== 'tcp') {
+ return Promise\reject(new InvalidArgumentException('Given URI "' . $uri . '" is invalid'));
+ }
+
+ $ip = trim($parts['host'], '[]');
+ if (false === filter_var($ip, FILTER_VALIDATE_IP)) {
+ return Promise\reject(new InvalidArgumentException('Given URI "' . $ip . '" does not contain a valid host IP'));
+ }
+
+ // use context given in constructor
+ $context = array(
+ 'socket' => $this->context
+ );
+
+ // parse arguments from query component of URI
+ $args = array();
+ if (isset($parts['query'])) {
+ parse_str($parts['query'], $args);
+ }
+
+ // If an original hostname has been given, use this for TLS setup.
+ // This can happen due to layers of nested connectors, such as a
+ // DnsConnector reporting its original hostname.
+ // These context options are here in case TLS is enabled later on this stream.
+ // If TLS is not enabled later, this doesn't hurt either.
+ if (isset($args['hostname'])) {
+ $context['ssl'] = array(
+ 'SNI_enabled' => true,
+ 'peer_name' => $args['hostname']
+ );
+
+ // Legacy PHP < 5.6 ignores peer_name and requires legacy context options instead.
+ // The SNI_server_name context option has to be set here during construction,
+ // as legacy PHP ignores any values set later.
+ if (PHP_VERSION_ID < 50600) {
+ $context['ssl'] += array(
+ 'SNI_server_name' => $args['hostname'],
+ 'CN_match' => $args['hostname']
+ );
+ }
+ }
+
+ // latest versions of PHP no longer accept any other URI components and
+ // HHVM fails to parse URIs with a query but no path, so let's simplify our URI here
+ $remote = 'tcp://' . $parts['host'] . ':' . $parts['port'];
+
+ $socket = @stream_socket_client(
+ $remote,
+ $errno,
+ $errstr,
+ 0,
+ STREAM_CLIENT_CONNECT | STREAM_CLIENT_ASYNC_CONNECT,
+ stream_context_create($context)
+ );
+
+ if (false === $socket) {
+ return Promise\reject(new RuntimeException(
+ sprintf("Connection to %s failed: %s", $uri, $errstr),
+ $errno
+ ));
+ }
+
+ stream_set_blocking($socket, 0);
+
+ // wait for connection
+
+ return $this->waitForStreamOnce($socket);
+ }
+
+ private function waitForStreamOnce($stream)
+ {
+ $loop = $this->loop;
+
+ return new Promise\Promise(function ($resolve, $reject) use ($loop, $stream) {
+ $loop->addWriteStream($stream, function ($stream) use ($loop, $resolve, $reject) {
+ $loop->removeWriteStream($stream);
+
+ // The following hack looks like the only way to
+ // detect connection refused errors with PHP's stream sockets.
+ if (false === stream_socket_get_name($stream, true)) {
+ fclose($stream);
+
+ $reject(new RuntimeException('Connection refused'));
+ } else {
+ $resolve(new Connection($stream, $loop));
+ }
+ });
+ }, function () use ($loop, $stream) {
+ $loop->removeWriteStream($stream);
+ fclose($stream);
+
+ throw new RuntimeException('Cancelled while waiting for TCP/IP connection to be established');
+ });
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/TcpServer.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/TcpServer.php
new file mode 100644
index 0000000..119e177
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/TcpServer.php
@@ -0,0 +1,236 @@
+<?php
+
+namespace React\Socket;
+
+use Evenement\EventEmitter;
+use React\EventLoop\LoopInterface;
+use InvalidArgumentException;
+use RuntimeException;
+
+/**
+ * The `TcpServer` class implements the `ServerInterface` and
+ * is responsible for accepting plaintext TCP/IP connections.
+ *
+ * ```php
+ * $server = new TcpServer(8080, $loop);
+ * ```
+ *
+ * Whenever a client connects, it will emit a `connection` event with a connection
+ * instance implementing `ConnectionInterface`:
+ *
+ * ```php
+ * $server->on('connection', function (ConnectionInterface $connection) {
+ * echo 'Plaintext connection from ' . $connection->getRemoteAddress() . PHP_EOL;
+ * $connection->write('hello there!' . PHP_EOL);
+ * …
+ * });
+ * ```
+ *
+ * See also the `ServerInterface` for more details.
+ *
+ * @see ServerInterface
+ * @see ConnectionInterface
+ */
+final class TcpServer extends EventEmitter implements ServerInterface
+{
+ private $master;
+ private $loop;
+ private $listening = false;
+
+ /**
+ * Creates a plaintext TCP/IP socket server and starts listening on the given address
+ *
+ * This starts accepting new incoming connections on the given address.
+ * See also the `connection event` documented in the `ServerInterface`
+ * for more details.
+ *
+ * ```php
+ * $server = new TcpServer(8080, $loop);
+ * ```
+ *
+ * As above, the `$uri` parameter can consist of only a port, in which case the
+ * server will default to listening on the localhost address `127.0.0.1`,
+ * which means it will not be reachable from outside of this system.
+ *
+ * In order to use a random port assignment, you can use the port `0`:
+ *
+ * ```php
+ * $server = new TcpServer(0, $loop);
+ * $address = $server->getAddress();
+ * ```
+ *
+ * In order to change the host the socket is listening on, you can provide an IP
+ * address through the first parameter provided to the constructor, optionally
+ * preceded by the `tcp://` scheme:
+ *
+ * ```php
+ * $server = new TcpServer('192.168.0.1:8080', $loop);
+ * ```
+ *
+ * If you want to listen on an IPv6 address, you MUST enclose the host in square
+ * brackets:
+ *
+ * ```php
+ * $server = new TcpServer('[::1]:8080', $loop);
+ * ```
+ *
+ * If the given URI is invalid, does not contain a port, any other scheme or if it
+ * contains a hostname, it will throw an `InvalidArgumentException`:
+ *
+ * ```php
+ * // throws InvalidArgumentException due to missing port
+ * $server = new TcpServer('127.0.0.1', $loop);
+ * ```
+ *
+ * If the given URI appears to be valid, but listening on it fails (such as if port
+ * is already in use or port below 1024 may require root access etc.), it will
+ * throw a `RuntimeException`:
+ *
+ * ```php
+ * $first = new TcpServer(8080, $loop);
+ *
+ * // throws RuntimeException because port is already in use
+ * $second = new TcpServer(8080, $loop);
+ * ```
+ *
+ * Note that these error conditions may vary depending on your system and/or
+ * configuration.
+ * See the exception message and code for more details about the actual error
+ * condition.
+ *
+ * Optionally, you can specify [socket context options](http://php.net/manual/en/context.socket.php)
+ * for the underlying stream socket resource like this:
+ *
+ * ```php
+ * $server = new TcpServer('[::1]:8080', $loop, array(
+ * 'backlog' => 200,
+ * 'so_reuseport' => true,
+ * 'ipv6_v6only' => true
+ * ));
+ * ```
+ *
+ * Note that available [socket context options](http://php.net/manual/en/context.socket.php),
+ * their defaults and effects of changing these may vary depending on your system
+ * and/or PHP version.
+ * Passing unknown context options has no effect.
+ *
+ * @param string|int $uri
+ * @param LoopInterface $loop
+ * @param array $context
+ * @throws InvalidArgumentException if the listening address is invalid
+ * @throws RuntimeException if listening on this address fails (already in use etc.)
+ */
+ public function __construct($uri, LoopInterface $loop, array $context = array())
+ {
+ $this->loop = $loop;
+
+ // a single port has been given => assume localhost
+ if ((string)(int)$uri === (string)$uri) {
+ $uri = '127.0.0.1:' . $uri;
+ }
+
+ // assume default scheme if none has been given
+ if (strpos($uri, '://') === false) {
+ $uri = 'tcp://' . $uri;
+ }
+
+ // parse_url() does not accept null ports (random port assignment) => manually remove
+ if (substr($uri, -2) === ':0') {
+ $parts = parse_url(substr($uri, 0, -2));
+ if ($parts) {
+ $parts['port'] = 0;
+ }
+ } else {
+ $parts = parse_url($uri);
+ }
+
+ // ensure URI contains TCP scheme, host and port
+ if (!$parts || !isset($parts['scheme'], $parts['host'], $parts['port']) || $parts['scheme'] !== 'tcp') {
+ throw new InvalidArgumentException('Invalid URI "' . $uri . '" given');
+ }
+
+ if (false === filter_var(trim($parts['host'], '[]'), FILTER_VALIDATE_IP)) {
+ throw new InvalidArgumentException('Given URI "' . $uri . '" does not contain a valid host IP');
+ }
+
+ $this->master = @stream_socket_server(
+ $uri,
+ $errno,
+ $errstr,
+ STREAM_SERVER_BIND | STREAM_SERVER_LISTEN,
+ stream_context_create(array('socket' => $context))
+ );
+ if (false === $this->master) {
+ throw new RuntimeException('Failed to listen on "' . $uri . '": ' . $errstr, $errno);
+ }
+ stream_set_blocking($this->master, 0);
+
+ $this->resume();
+ }
+
+ public function getAddress()
+ {
+ if (!is_resource($this->master)) {
+ return null;
+ }
+
+ $address = stream_socket_get_name($this->master, false);
+
+ // check if this is an IPv6 address which includes multiple colons but no square brackets
+ $pos = strrpos($address, ':');
+ if ($pos !== false && strpos($address, ':') < $pos && substr($address, 0, 1) !== '[') {
+ $port = substr($address, $pos + 1);
+ $address = '[' . substr($address, 0, $pos) . ']:' . $port;
+ }
+
+ return 'tcp://' . $address;
+ }
+
+ public function pause()
+ {
+ if (!$this->listening) {
+ return;
+ }
+
+ $this->loop->removeReadStream($this->master);
+ $this->listening = false;
+ }
+
+ public function resume()
+ {
+ if ($this->listening || !is_resource($this->master)) {
+ return;
+ }
+
+ $that = $this;
+ $this->loop->addReadStream($this->master, function ($master) use ($that) {
+ $newSocket = @stream_socket_accept($master);
+ if (false === $newSocket) {
+ $that->emit('error', array(new RuntimeException('Error accepting new connection')));
+
+ return;
+ }
+ $that->handleConnection($newSocket);
+ });
+ $this->listening = true;
+ }
+
+ public function close()
+ {
+ if (!is_resource($this->master)) {
+ return;
+ }
+
+ $this->pause();
+ fclose($this->master);
+ $this->removeAllListeners();
+ }
+
+ /** @internal */
+ public function handleConnection($socket)
+ {
+ $this->emit('connection', array(
+ new Connection($socket, $this->loop)
+ ));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/TimeoutConnector.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/TimeoutConnector.php
new file mode 100644
index 0000000..d4eba2e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/TimeoutConnector.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace React\Socket;
+
+use React\EventLoop\LoopInterface;
+use React\Promise\Timer;
+
+final class TimeoutConnector implements ConnectorInterface
+{
+ private $connector;
+ private $timeout;
+ private $loop;
+
+ public function __construct(ConnectorInterface $connector, $timeout, LoopInterface $loop)
+ {
+ $this->connector = $connector;
+ $this->timeout = $timeout;
+ $this->loop = $loop;
+ }
+
+ public function connect($uri)
+ {
+ return Timer\timeout($this->connector->connect($uri), $this->timeout, $this->loop);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/UnixConnector.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/UnixConnector.php
new file mode 100644
index 0000000..9b84ab0
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/UnixConnector.php
@@ -0,0 +1,44 @@
+<?php
+
+namespace React\Socket;
+
+use React\EventLoop\LoopInterface;
+use React\Promise;
+use InvalidArgumentException;
+use RuntimeException;
+
+/**
+ * Unix domain socket connector
+ *
+ * Unix domain sockets use atomic operations, so we can as well emulate
+ * async behavior.
+ */
+final class UnixConnector implements ConnectorInterface
+{
+ private $loop;
+
+ public function __construct(LoopInterface $loop)
+ {
+ $this->loop = $loop;
+ }
+
+ public function connect($path)
+ {
+ if (strpos($path, '://') === false) {
+ $path = 'unix://' . $path;
+ } elseif (substr($path, 0, 7) !== 'unix://') {
+ return Promise\reject(new InvalidArgumentException('Given URI "' . $path . '" is invalid'));
+ }
+
+ $resource = @stream_socket_client($path, $errno, $errstr, 1.0);
+
+ if (!$resource) {
+ return Promise\reject(new RuntimeException('Unable to connect to unix domain socket "' . $path . '": ' . $errstr, $errno));
+ }
+
+ $connection = new Connection($resource, $this->loop);
+ $connection->unix = true;
+
+ return Promise\resolve($connection);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/UnixServer.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/UnixServer.php
new file mode 100644
index 0000000..8f1ed98
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/src/UnixServer.php
@@ -0,0 +1,130 @@
+<?php
+
+namespace React\Socket;
+
+use Evenement\EventEmitter;
+use React\EventLoop\LoopInterface;
+use InvalidArgumentException;
+use RuntimeException;
+
+/**
+ * The `UnixServer` class implements the `ServerInterface` and
+ * is responsible for accepting plaintext connections on unix domain sockets.
+ *
+ * ```php
+ * $server = new UnixServer('unix:///tmp/app.sock', $loop);
+ * ```
+ *
+ * See also the `ServerInterface` for more details.
+ *
+ * @see ServerInterface
+ * @see ConnectionInterface
+ */
+final class UnixServer extends EventEmitter implements ServerInterface
+{
+ private $master;
+ private $loop;
+ private $listening = false;
+
+ /**
+ * Creates a plaintext socket server and starts listening on the given unix socket
+ *
+ * This starts accepting new incoming connections on the given address.
+ * See also the `connection event` documented in the `ServerInterface`
+ * for more details.
+ *
+ * ```php
+ * $server = new UnixServer('unix:///tmp/app.sock', $loop);
+ * ```
+ *
+ * @param string $path
+ * @param LoopInterface $loop
+ * @param array $context
+ * @throws InvalidArgumentException if the listening address is invalid
+ * @throws RuntimeException if listening on this address fails (already in use etc.)
+ */
+ public function __construct($path, LoopInterface $loop, array $context = array())
+ {
+ $this->loop = $loop;
+
+ if (strpos($path, '://') === false) {
+ $path = 'unix://' . $path;
+ } elseif (substr($path, 0, 7) !== 'unix://') {
+ throw new InvalidArgumentException('Given URI "' . $path . '" is invalid');
+ }
+
+ $this->master = @stream_socket_server(
+ $path,
+ $errno,
+ $errstr,
+ STREAM_SERVER_BIND | STREAM_SERVER_LISTEN,
+ stream_context_create(array('socket' => $context))
+ );
+ if (false === $this->master) {
+ throw new RuntimeException('Failed to listen on unix domain socket "' . $path . '": ' . $errstr, $errno);
+ }
+ stream_set_blocking($this->master, 0);
+
+ $this->resume();
+ }
+
+ public function getAddress()
+ {
+ if (!is_resource($this->master)) {
+ return null;
+ }
+
+ return 'unix://' . stream_socket_get_name($this->master, false);
+ }
+
+ public function pause()
+ {
+ if (!$this->listening) {
+ return;
+ }
+
+ $this->loop->removeReadStream($this->master);
+ $this->listening = false;
+ }
+
+ public function resume()
+ {
+ if ($this->listening || !is_resource($this->master)) {
+ return;
+ }
+
+ $that = $this;
+ $this->loop->addReadStream($this->master, function ($master) use ($that) {
+ $newSocket = @stream_socket_accept($master);
+ if (false === $newSocket) {
+ $that->emit('error', array(new RuntimeException('Error accepting new connection')));
+
+ return;
+ }
+ $that->handleConnection($newSocket);
+ });
+ $this->listening = true;
+ }
+
+ public function close()
+ {
+ if (!is_resource($this->master)) {
+ return;
+ }
+
+ $this->pause();
+ fclose($this->master);
+ $this->removeAllListeners();
+ }
+
+ /** @internal */
+ public function handleConnection($socket)
+ {
+ $connection = new Connection($socket, $this->loop);
+ $connection->unix = true;
+
+ $this->emit('connection', array(
+ $connection
+ ));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/ConnectionTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/ConnectionTest.php
new file mode 100644
index 0000000..d3563df
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/ConnectionTest.php
@@ -0,0 +1,47 @@
+<?php
+
+namespace React\Tests\Socket;
+
+use React\Socket\Connection;
+
+class ConnectionTest extends TestCase
+{
+ public function testCloseConnectionWillCloseSocketResource()
+ {
+ if (defined('HHVM_VERSION')) {
+ $this->markTestSkipped('HHVM does not support socket operation on test memory stream');
+ }
+
+ $resource = fopen('php://memory', 'r+');
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+
+ $connection = new Connection($resource, $loop);
+ $connection->close();
+
+ $this->assertFalse(is_resource($resource));
+ }
+
+ public function testCloseConnectionWillRemoveResourceFromLoopBeforeClosingResource()
+ {
+ if (defined('HHVM_VERSION')) {
+ $this->markTestSkipped('HHVM does not support socket operation on test memory stream');
+ }
+
+ $resource = fopen('php://memory', 'r+');
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ $loop->expects($this->once())->method('addWriteStream')->with($resource);
+
+ $onRemove = null;
+ $loop->expects($this->once())->method('removeWriteStream')->with($this->callback(function ($param) use (&$onRemove) {
+ $onRemove = is_resource($param);
+ return true;
+ }));
+
+ $connection = new Connection($resource, $loop);
+ $connection->write('test');
+ $connection->close();
+
+ $this->assertTrue($onRemove);
+ $this->assertFalse(is_resource($resource));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/ConnectorTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/ConnectorTest.php
new file mode 100644
index 0000000..c8eb19b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/ConnectorTest.php
@@ -0,0 +1,128 @@
+<?php
+
+namespace React\Tests\Socket;
+
+use React\Socket\Connector;
+use React\Promise\Promise;
+
+class ConnectorTest extends TestCase
+{
+ public function testConnectorUsesTcpAsDefaultScheme()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+
+ $promise = new Promise(function () { });
+ $tcp = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
+ $tcp->expects($this->once())->method('connect')->with('127.0.0.1:80')->willReturn($promise);
+
+ $connector = new Connector($loop, array(
+ 'tcp' => $tcp
+ ));
+
+ $connector->connect('127.0.0.1:80');
+ }
+
+ public function testConnectorPassedThroughHostnameIfDnsIsDisabled()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+
+ $promise = new Promise(function () { });
+ $tcp = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
+ $tcp->expects($this->once())->method('connect')->with('tcp://google.com:80')->willReturn($promise);
+
+ $connector = new Connector($loop, array(
+ 'tcp' => $tcp,
+ 'dns' => false
+ ));
+
+ $connector->connect('tcp://google.com:80');
+ }
+
+ public function testConnectorWithUnknownSchemeAlwaysFails()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ $connector = new Connector($loop);
+
+ $promise = $connector->connect('unknown://google.com:80');
+ $promise->then(null, $this->expectCallableOnce());
+ }
+
+ public function testConnectorWithDisabledTcpDefaultSchemeAlwaysFails()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ $connector = new Connector($loop, array(
+ 'tcp' => false
+ ));
+
+ $promise = $connector->connect('google.com:80');
+ $promise->then(null, $this->expectCallableOnce());
+ }
+
+ public function testConnectorWithDisabledTcpSchemeAlwaysFails()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ $connector = new Connector($loop, array(
+ 'tcp' => false
+ ));
+
+ $promise = $connector->connect('tcp://google.com:80');
+ $promise->then(null, $this->expectCallableOnce());
+ }
+
+ public function testConnectorWithDisabledTlsSchemeAlwaysFails()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ $connector = new Connector($loop, array(
+ 'tls' => false
+ ));
+
+ $promise = $connector->connect('tls://google.com:443');
+ $promise->then(null, $this->expectCallableOnce());
+ }
+
+ public function testConnectorWithDisabledUnixSchemeAlwaysFails()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ $connector = new Connector($loop, array(
+ 'unix' => false
+ ));
+
+ $promise = $connector->connect('unix://demo.sock');
+ $promise->then(null, $this->expectCallableOnce());
+ }
+
+ public function testConnectorUsesGivenResolverInstance()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+
+ $promise = new Promise(function () { });
+ $resolver = $this->getMockBuilder('React\Dns\Resolver\Resolver')->disableOriginalConstructor()->getMock();
+ $resolver->expects($this->once())->method('resolve')->with('google.com')->willReturn($promise);
+
+ $connector = new Connector($loop, array(
+ 'dns' => $resolver
+ ));
+
+ $connector->connect('google.com:80');
+ }
+
+ public function testConnectorUsesResolvedHostnameIfDnsIsUsed()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+
+ $promise = new Promise(function ($resolve) { $resolve('127.0.0.1'); });
+ $resolver = $this->getMockBuilder('React\Dns\Resolver\Resolver')->disableOriginalConstructor()->getMock();
+ $resolver->expects($this->once())->method('resolve')->with('google.com')->willReturn($promise);
+
+ $promise = new Promise(function () { });
+ $tcp = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
+ $tcp->expects($this->once())->method('connect')->with('tcp://127.0.0.1:80?hostname=google.com')->willReturn($promise);
+
+ $connector = new Connector($loop, array(
+ 'tcp' => $tcp,
+ 'dns' => $resolver
+ ));
+
+ $connector->connect('tcp://google.com:80');
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/DnsConnectorTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/DnsConnectorTest.php
new file mode 100644
index 0000000..3c94c39
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/DnsConnectorTest.php
@@ -0,0 +1,111 @@
+<?php
+
+namespace React\Tests\Socket;
+
+use React\Socket\DnsConnector;
+use React\Promise;
+
+class DnsConnectorTest extends TestCase
+{
+ private $tcp;
+ private $resolver;
+ private $connector;
+
+ public function setUp()
+ {
+ $this->tcp = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
+ $this->resolver = $this->getMockBuilder('React\Dns\Resolver\Resolver')->disableOriginalConstructor()->getMock();
+
+ $this->connector = new DnsConnector($this->tcp, $this->resolver);
+ }
+
+ public function testPassByResolverIfGivenIp()
+ {
+ $this->resolver->expects($this->never())->method('resolve');
+ $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('127.0.0.1:80'))->will($this->returnValue(Promise\reject()));
+
+ $this->connector->connect('127.0.0.1:80');
+ }
+
+ public function testPassThroughResolverIfGivenHost()
+ {
+ $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('google.com'))->will($this->returnValue(Promise\resolve('1.2.3.4')));
+ $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('1.2.3.4:80?hostname=google.com'))->will($this->returnValue(Promise\reject()));
+
+ $this->connector->connect('google.com:80');
+ }
+
+ public function testPassThroughResolverIfGivenHostWhichResolvesToIpv6()
+ {
+ $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('google.com'))->will($this->returnValue(Promise\resolve('::1')));
+ $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('[::1]:80?hostname=google.com'))->will($this->returnValue(Promise\reject()));
+
+ $this->connector->connect('google.com:80');
+ }
+
+ public function testPassByResolverIfGivenCompleteUri()
+ {
+ $this->resolver->expects($this->never())->method('resolve');
+ $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('scheme://127.0.0.1:80/path?query#fragment'))->will($this->returnValue(Promise\reject()));
+
+ $this->connector->connect('scheme://127.0.0.1:80/path?query#fragment');
+ }
+
+ public function testPassThroughResolverIfGivenCompleteUri()
+ {
+ $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('google.com'))->will($this->returnValue(Promise\resolve('1.2.3.4')));
+ $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('scheme://1.2.3.4:80/path?query&hostname=google.com#fragment'))->will($this->returnValue(Promise\reject()));
+
+ $this->connector->connect('scheme://google.com:80/path?query#fragment');
+ }
+
+ public function testPassThroughResolverIfGivenExplicitHost()
+ {
+ $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('google.com'))->will($this->returnValue(Promise\resolve('1.2.3.4')));
+ $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('scheme://1.2.3.4:80/?hostname=google.de'))->will($this->returnValue(Promise\reject()));
+
+ $this->connector->connect('scheme://google.com:80/?hostname=google.de');
+ }
+
+ public function testRejectsImmediatelyIfUriIsInvalid()
+ {
+ $this->resolver->expects($this->never())->method('resolve');
+ $this->tcp->expects($this->never())->method('connect');
+
+ $promise = $this->connector->connect('////');
+
+ $promise->then($this->expectCallableNever(), $this->expectCallableOnce());
+ }
+
+ public function testSkipConnectionIfDnsFails()
+ {
+ $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('example.invalid'))->will($this->returnValue(Promise\reject()));
+ $this->tcp->expects($this->never())->method('connect');
+
+ $this->connector->connect('example.invalid:80');
+ }
+
+ public function testCancelDuringDnsCancelsDnsAndDoesNotStartTcpConnection()
+ {
+ $pending = new Promise\Promise(function () { }, $this->expectCallableOnce());
+ $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('example.com'))->will($this->returnValue($pending));
+ $this->tcp->expects($this->never())->method('connect');
+
+ $promise = $this->connector->connect('example.com:80');
+ $promise->cancel();
+
+ $promise->then($this->expectCallableNever(), $this->expectCallableOnce());
+ }
+
+ public function testCancelDuringTcpConnectionCancelsTcpConnection()
+ {
+ $pending = new Promise\Promise(function () { }, function () { throw new \Exception(); });
+ $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('example.com'))->will($this->returnValue(Promise\resolve('1.2.3.4')));
+ $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('1.2.3.4:80?hostname=example.com'))->will($this->returnValue($pending));
+
+ $promise = $this->connector->connect('example.com:80');
+ $promise->cancel();
+
+ $promise->then($this->expectCallableNever(), $this->expectCallableOnce());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/FixedUriConnectorTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/FixedUriConnectorTest.php
new file mode 100644
index 0000000..f42d74f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/FixedUriConnectorTest.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace React\Tests\Socket;
+
+use React\Socket\FixedUriConnector;
+use React\Tests\Socket\TestCase;
+
+class FixedUriConnectorTest extends TestCase
+{
+ public function testWillInvokeGivenConnector()
+ {
+ $base = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
+ $base->expects($this->once())->method('connect')->with('test')->willReturn('ret');
+
+ $connector = new FixedUriConnector('test', $base);
+
+ $this->assertEquals('ret', $connector->connect('ignored'));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/FunctionalConnectorTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/FunctionalConnectorTest.php
new file mode 100644
index 0000000..6611352
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/FunctionalConnectorTest.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace React\Tests\Socket;
+
+use Clue\React\Block;
+use React\EventLoop\Factory;
+use React\Socket\Connector;
+use React\Socket\TcpServer;
+
+class FunctionalConnectorTest extends TestCase
+{
+ const TIMEOUT = 1.0;
+
+ /** @test */
+ public function connectionToTcpServerShouldSucceedWithLocalhost()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(9998, $loop);
+ $server->on('connection', $this->expectCallableOnce());
+ $server->on('connection', array($server, 'close'));
+
+ $connector = new Connector($loop);
+
+ $connection = Block\await($connector->connect('localhost:9998'), $loop, self::TIMEOUT);
+
+ $this->assertInstanceOf('React\Socket\ConnectionInterface', $connection);
+
+ $connection->close();
+ $server->close();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/FunctionalSecureServerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/FunctionalSecureServerTest.php
new file mode 100644
index 0000000..78a59d0
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/FunctionalSecureServerTest.php
@@ -0,0 +1,438 @@
+<?php
+
+namespace React\Tests\Socket;
+
+use React\EventLoop\Factory;
+use React\Socket\SecureServer;
+use React\Socket\ConnectionInterface;
+use React\Socket\TcpServer;
+use React\Socket\TcpConnector;
+use React\Socket\SecureConnector;
+use Clue\React\Block;
+
+class FunctionalSecureServerTest extends TestCase
+{
+ const TIMEOUT = 0.5;
+
+ public function setUp()
+ {
+ if (!function_exists('stream_socket_enable_crypto')) {
+ $this->markTestSkipped('Not supported on your platform (outdated HHVM?)');
+ }
+ }
+
+ public function testEmitsConnectionForNewConnection()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(0, $loop);
+ $server = new SecureServer($server, $loop, array(
+ 'local_cert' => __DIR__ . '/../examples/localhost.pem'
+ ));
+ $server->on('connection', $this->expectCallableOnce());
+
+ $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
+ 'verify_peer' => false
+ ));
+ $promise = $connector->connect($server->getAddress());
+
+ Block\await($promise, $loop, self::TIMEOUT);
+ }
+
+ public function testWritesDataToConnection()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(0, $loop);
+ $server = new SecureServer($server, $loop, array(
+ 'local_cert' => __DIR__ . '/../examples/localhost.pem'
+ ));
+ $server->on('connection', $this->expectCallableOnce());
+
+ $server->on('connection', function (ConnectionInterface $conn) {
+ $conn->write('foo');
+ });
+
+ $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
+ 'verify_peer' => false
+ ));
+ $promise = $connector->connect($server->getAddress());
+
+ $local = Block\await($promise, $loop, self::TIMEOUT);
+ /* @var $local ConnectionInterface */
+
+ $local->on('data', $this->expectCallableOnceWith('foo'));
+
+ Block\sleep(self::TIMEOUT, $loop);
+ }
+
+ public function testWritesDataInMultipleChunksToConnection()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(0, $loop);
+ $server = new SecureServer($server, $loop, array(
+ 'local_cert' => __DIR__ . '/../examples/localhost.pem'
+ ));
+ $server->on('connection', $this->expectCallableOnce());
+
+ $server->on('connection', function (ConnectionInterface $conn) {
+ $conn->write(str_repeat('*', 400000));
+ });
+
+ $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
+ 'verify_peer' => false
+ ));
+ $promise = $connector->connect($server->getAddress());
+
+ $local = Block\await($promise, $loop, self::TIMEOUT);
+ /* @var $local React\Stream\Stream */
+
+ $received = 0;
+ $local->on('data', function ($chunk) use (&$received) {
+ $received += strlen($chunk);
+ });
+
+ Block\sleep(self::TIMEOUT, $loop);
+
+ $this->assertEquals(400000, $received);
+ }
+
+ public function testWritesMoreDataInMultipleChunksToConnection()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(0, $loop);
+ $server = new SecureServer($server, $loop, array(
+ 'local_cert' => __DIR__ . '/../examples/localhost.pem'
+ ));
+ $server->on('connection', $this->expectCallableOnce());
+
+ $server->on('connection', function (ConnectionInterface $conn) {
+ $conn->write(str_repeat('*', 2000000));
+ });
+
+ $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
+ 'verify_peer' => false
+ ));
+ $promise = $connector->connect($server->getAddress());
+
+ $local = Block\await($promise, $loop, self::TIMEOUT);
+ /* @var $local React\Stream\Stream */
+
+ $received = 0;
+ $local->on('data', function ($chunk) use (&$received) {
+ $received += strlen($chunk);
+ });
+
+ Block\sleep(self::TIMEOUT, $loop);
+
+ $this->assertEquals(2000000, $received);
+ }
+
+ public function testEmitsDataFromConnection()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(0, $loop);
+ $server = new SecureServer($server, $loop, array(
+ 'local_cert' => __DIR__ . '/../examples/localhost.pem'
+ ));
+ $server->on('connection', $this->expectCallableOnce());
+
+ $once = $this->expectCallableOnceWith('foo');
+ $server->on('connection', function (ConnectionInterface $conn) use ($once) {
+ $conn->on('data', $once);
+ });
+
+ $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
+ 'verify_peer' => false
+ ));
+ $promise = $connector->connect($server->getAddress());
+
+ $local = Block\await($promise, $loop, self::TIMEOUT);
+ /* @var $local React\Stream\Stream */
+
+ $local->write("foo");
+
+ Block\sleep(self::TIMEOUT, $loop);
+ }
+
+ public function testEmitsDataInMultipleChunksFromConnection()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(0, $loop);
+ $server = new SecureServer($server, $loop, array(
+ 'local_cert' => __DIR__ . '/../examples/localhost.pem'
+ ));
+ $server->on('connection', $this->expectCallableOnce());
+
+ $received = 0;
+ $server->on('connection', function (ConnectionInterface $conn) use (&$received) {
+ $conn->on('data', function ($chunk) use (&$received) {
+ $received += strlen($chunk);
+ });
+ });
+
+ $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
+ 'verify_peer' => false
+ ));
+ $promise = $connector->connect($server->getAddress());
+
+ $local = Block\await($promise, $loop, self::TIMEOUT);
+ /* @var $local React\Stream\Stream */
+
+ $local->write(str_repeat('*', 400000));
+
+ Block\sleep(self::TIMEOUT, $loop);
+
+ $this->assertEquals(400000, $received);
+ }
+
+ public function testPipesDataBackInMultipleChunksFromConnection()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(0, $loop);
+ $server = new SecureServer($server, $loop, array(
+ 'local_cert' => __DIR__ . '/../examples/localhost.pem'
+ ));
+ $server->on('connection', $this->expectCallableOnce());
+
+ $server->on('connection', function (ConnectionInterface $conn) use (&$received) {
+ $conn->pipe($conn);
+ });
+
+ $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
+ 'verify_peer' => false
+ ));
+ $promise = $connector->connect($server->getAddress());
+
+ $local = Block\await($promise, $loop, self::TIMEOUT);
+ /* @var $local React\Stream\Stream */
+
+ $received = 0;
+ $local->on('data', function ($chunk) use (&$received) {
+ $received += strlen($chunk);
+ });
+
+ $local->write(str_repeat('*', 400000));
+
+ Block\sleep(self::TIMEOUT, $loop);
+
+ $this->assertEquals(400000, $received);
+ }
+
+ /**
+ * @requires PHP 5.6
+ */
+ public function testEmitsConnectionForNewTlsv11Connection()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(0, $loop);
+ $server = new SecureServer($server, $loop, array(
+ 'local_cert' => __DIR__ . '/../examples/localhost.pem',
+ 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_1_SERVER
+ ));
+ $server->on('connection', $this->expectCallableOnce());
+
+ $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
+ 'verify_peer' => false,
+ 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT
+ ));
+ $promise = $connector->connect($server->getAddress());
+
+ Block\await($promise, $loop, self::TIMEOUT);
+ }
+
+ /**
+ * @requires PHP 5.6
+ */
+ public function testEmitsErrorForClientWithTlsVersionMismatch()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(0, $loop);
+ $server = new SecureServer($server, $loop, array(
+ 'local_cert' => __DIR__ . '/../examples/localhost.pem',
+ 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_1_SERVER|STREAM_CRYPTO_METHOD_TLSv1_2_SERVER
+ ));
+ $server->on('connection', $this->expectCallableNever());
+ $server->on('error', $this->expectCallableOnce());
+
+ $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
+ 'verify_peer' => false,
+ 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT
+ ));
+ $promise = $connector->connect($server->getAddress());
+
+ $this->setExpectedException('RuntimeException', 'handshake');
+ Block\await($promise, $loop, self::TIMEOUT);
+ }
+
+ public function testEmitsConnectionForNewConnectionWithEncryptedCertificate()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(0, $loop);
+ $server = new SecureServer($server, $loop, array(
+ 'local_cert' => __DIR__ . '/../examples/localhost_swordfish.pem',
+ 'passphrase' => 'swordfish'
+ ));
+ $server->on('connection', $this->expectCallableOnce());
+
+ $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
+ 'verify_peer' => false
+ ));
+ $promise = $connector->connect($server->getAddress());
+
+ Block\await($promise, $loop, self::TIMEOUT);
+ }
+
+ public function testEmitsErrorForServerWithInvalidCertificate()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(0, $loop);
+ $server = new SecureServer($server, $loop, array(
+ 'local_cert' => 'invalid.pem'
+ ));
+ $server->on('connection', $this->expectCallableNever());
+ $server->on('error', $this->expectCallableOnce());
+
+ $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
+ 'verify_peer' => false
+ ));
+ $promise = $connector->connect($server->getAddress());
+
+ $this->setExpectedException('RuntimeException', 'handshake');
+ Block\await($promise, $loop, self::TIMEOUT);
+ }
+
+ public function testEmitsErrorForServerWithEncryptedCertificateMissingPassphrase()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(0, $loop);
+ $server = new SecureServer($server, $loop, array(
+ 'local_cert' => __DIR__ . '/../examples/localhost_swordfish.pem'
+ ));
+ $server->on('connection', $this->expectCallableNever());
+ $server->on('error', $this->expectCallableOnce());
+
+ $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
+ 'verify_peer' => false
+ ));
+ $promise = $connector->connect($server->getAddress());
+
+ $this->setExpectedException('RuntimeException', 'handshake');
+ Block\await($promise, $loop, self::TIMEOUT);
+ }
+
+ public function testEmitsErrorForServerWithEncryptedCertificateWithInvalidPassphrase()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(0, $loop);
+ $server = new SecureServer($server, $loop, array(
+ 'local_cert' => __DIR__ . '/../examples/localhost_swordfish.pem',
+ 'passphrase' => 'nope'
+ ));
+ $server->on('connection', $this->expectCallableNever());
+ $server->on('error', $this->expectCallableOnce());
+
+ $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
+ 'verify_peer' => false
+ ));
+ $promise = $connector->connect($server->getAddress());
+
+ $this->setExpectedException('RuntimeException', 'handshake');
+ Block\await($promise, $loop, self::TIMEOUT);
+ }
+
+ public function testEmitsErrorForConnectionWithPeerVerification()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(0, $loop);
+ $server = new SecureServer($server, $loop, array(
+ 'local_cert' => __DIR__ . '/../examples/localhost.pem'
+ ));
+ $server->on('connection', $this->expectCallableNever());
+ $server->on('error', $this->expectCallableOnce());
+
+ $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
+ 'verify_peer' => true
+ ));
+ $promise = $connector->connect($server->getAddress());
+
+ $promise->then(null, $this->expectCallableOnce());
+ Block\sleep(self::TIMEOUT, $loop);
+ }
+
+ public function testEmitsErrorIfConnectionIsCancelled()
+ {
+ if (PHP_OS !== 'Linux') {
+ $this->markTestSkipped('Linux only (OS is ' . PHP_OS . ')');
+ }
+
+ $loop = Factory::create();
+
+ $server = new TcpServer(0, $loop);
+ $server = new SecureServer($server, $loop, array(
+ 'local_cert' => __DIR__ . '/../examples/localhost.pem'
+ ));
+ $server->on('connection', $this->expectCallableNever());
+ $server->on('error', $this->expectCallableOnce());
+
+ $connector = new SecureConnector(new TcpConnector($loop), $loop, array(
+ 'verify_peer' => false
+ ));
+ $promise = $connector->connect($server->getAddress());
+ $promise->cancel();
+
+ $promise->then(null, $this->expectCallableOnce());
+ Block\sleep(self::TIMEOUT, $loop);
+ }
+
+ public function testEmitsNothingIfConnectionIsIdle()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(0, $loop);
+ $server = new SecureServer($server, $loop, array(
+ 'local_cert' => __DIR__ . '/../examples/localhost.pem'
+ ));
+ $server->on('connection', $this->expectCallableNever());
+ $server->on('error', $this->expectCallableNever());
+
+ $connector = new TcpConnector($loop);
+ $promise = $connector->connect(str_replace('tls://', '', $server->getAddress()));
+
+ $promise->then($this->expectCallableOnce());
+ Block\sleep(self::TIMEOUT, $loop);
+ }
+
+ public function testEmitsErrorIfConnectionIsNotSecureHandshake()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(0, $loop);
+ $server = new SecureServer($server, $loop, array(
+ 'local_cert' => __DIR__ . '/../examples/localhost.pem'
+ ));
+ $server->on('connection', $this->expectCallableNever());
+ $server->on('error', $this->expectCallableOnce());
+
+ $connector = new TcpConnector($loop);
+ $promise = $connector->connect(str_replace('tls://', '', $server->getAddress()));
+
+ $promise->then(function (ConnectionInterface $stream) {
+ $stream->write("GET / HTTP/1.0\r\n\r\n");
+ });
+
+ Block\sleep(self::TIMEOUT, $loop);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/FunctionalTcpServerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/FunctionalTcpServerTest.php
new file mode 100644
index 0000000..ec7855e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/FunctionalTcpServerTest.php
@@ -0,0 +1,324 @@
+<?php
+
+namespace React\Tests\Socket;
+
+use React\EventLoop\Factory;
+use React\Socket\TcpServer;
+use React\Socket\ConnectionInterface;
+use React\Socket\TcpConnector;
+use Clue\React\Block;
+
+class FunctionalTcpServerTest extends TestCase
+{
+ public function testEmitsConnectionForNewConnection()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(0, $loop);
+ $server->on('connection', $this->expectCallableOnce());
+
+ $connector = new TcpConnector($loop);
+ $promise = $connector->connect($server->getAddress());
+
+ $promise->then($this->expectCallableOnce());
+
+ Block\sleep(0.1, $loop);
+ }
+
+ public function testEmitsNoConnectionForNewConnectionWhenPaused()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(0, $loop);
+ $server->on('connection', $this->expectCallableNever());
+ $server->pause();
+
+ $connector = new TcpConnector($loop);
+ $promise = $connector->connect($server->getAddress());
+
+ $promise->then($this->expectCallableOnce());
+
+ Block\sleep(0.1, $loop);
+ }
+
+ public function testEmitsConnectionForNewConnectionWhenResumedAfterPause()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(0, $loop);
+ $server->on('connection', $this->expectCallableOnce());
+ $server->pause();
+ $server->resume();
+
+ $connector = new TcpConnector($loop);
+ $promise = $connector->connect($server->getAddress());
+
+ $promise->then($this->expectCallableOnce());
+
+ Block\sleep(0.1, $loop);
+ }
+
+ public function testEmitsConnectionWithRemoteIp()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(0, $loop);
+ $peer = null;
+ $server->on('connection', function (ConnectionInterface $conn) use (&$peer) {
+ $peer = $conn->getRemoteAddress();
+ });
+
+ $connector = new TcpConnector($loop);
+ $promise = $connector->connect($server->getAddress());
+
+ $promise->then($this->expectCallableOnce());
+
+ Block\sleep(0.1, $loop);
+
+ $this->assertContains('127.0.0.1:', $peer);
+ }
+
+ public function testEmitsConnectionWithLocalIp()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(0, $loop);
+ $local = null;
+ $server->on('connection', function (ConnectionInterface $conn) use (&$local) {
+ $local = $conn->getLocalAddress();
+ });
+
+ $connector = new TcpConnector($loop);
+ $promise = $connector->connect($server->getAddress());
+
+ $promise->then($this->expectCallableOnce());
+
+ Block\sleep(0.1, $loop);
+
+ $this->assertContains('127.0.0.1:', $local);
+ $this->assertEquals($server->getAddress(), $local);
+ }
+
+ public function testEmitsConnectionWithLocalIpDespiteListeningOnAll()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer('0.0.0.0:0', $loop);
+ $local = null;
+ $server->on('connection', function (ConnectionInterface $conn) use (&$local) {
+ $local = $conn->getLocalAddress();
+ });
+
+ $connector = new TcpConnector($loop);
+ $promise = $connector->connect($server->getAddress());
+
+ $promise->then($this->expectCallableOnce());
+
+ Block\sleep(0.1, $loop);
+
+ $this->assertContains('127.0.0.1:', $local);
+ }
+
+ public function testEmitsConnectionWithRemoteIpAfterConnectionIsClosedByPeer()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(0, $loop);
+ $peer = null;
+ $server->on('connection', function (ConnectionInterface $conn) use (&$peer) {
+ $conn->on('close', function () use ($conn, &$peer) {
+ $peer = $conn->getRemoteAddress();
+ });
+ });
+
+ $connector = new TcpConnector($loop);
+ $promise = $connector->connect($server->getAddress());
+
+ $client = Block\await($promise, $loop, 0.1);
+ $client->end();
+
+ Block\sleep(0.1, $loop);
+
+ $this->assertContains('127.0.0.1:', $peer);
+ }
+
+ public function testEmitsConnectionWithRemoteNullAddressAfterConnectionIsClosedLocally()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(0, $loop);
+ $peer = null;
+ $server->on('connection', function (ConnectionInterface $conn) use (&$peer) {
+ $conn->close();
+ $peer = $conn->getRemoteAddress();
+ });
+
+ $connector = new TcpConnector($loop);
+ $promise = $connector->connect($server->getAddress());
+
+ $promise->then($this->expectCallableOnce());
+
+ Block\sleep(0.1, $loop);
+
+ $this->assertNull($peer);
+ }
+
+ public function testEmitsConnectionEvenIfConnectionIsCancelled()
+ {
+ if (PHP_OS !== 'Linux') {
+ $this->markTestSkipped('Linux only (OS is ' . PHP_OS . ')');
+ }
+
+ $loop = Factory::create();
+
+ $server = new TcpServer(0, $loop);
+ $server->on('connection', $this->expectCallableOnce());
+
+ $connector = new TcpConnector($loop);
+ $promise = $connector->connect($server->getAddress());
+ $promise->cancel();
+
+ $promise->then(null, $this->expectCallableOnce());
+
+ Block\sleep(0.1, $loop);
+ }
+
+ public function testEmitsConnectionForNewIpv6Connection()
+ {
+ $loop = Factory::create();
+
+ try {
+ $server = new TcpServer('[::1]:0', $loop);
+ } catch (\RuntimeException $e) {
+ $this->markTestSkipped('Unable to start IPv6 server socket (not available on your platform?)');
+ }
+
+ $server->on('connection', $this->expectCallableOnce());
+
+ $connector = new TcpConnector($loop);
+ $promise = $connector->connect($server->getAddress());
+
+ $promise->then($this->expectCallableOnce());
+
+ Block\sleep(0.1, $loop);
+ }
+
+ public function testEmitsConnectionWithRemoteIpv6()
+ {
+ $loop = Factory::create();
+
+ try {
+ $server = new TcpServer('[::1]:0', $loop);
+ } catch (\RuntimeException $e) {
+ $this->markTestSkipped('Unable to start IPv6 server socket (not available on your platform?)');
+ }
+
+ $peer = null;
+ $server->on('connection', function (ConnectionInterface $conn) use (&$peer) {
+ $peer = $conn->getRemoteAddress();
+ });
+
+ $connector = new TcpConnector($loop);
+ $promise = $connector->connect($server->getAddress());
+
+ $promise->then($this->expectCallableOnce());
+
+ Block\sleep(0.1, $loop);
+
+ $this->assertContains('[::1]:', $peer);
+ }
+
+ public function testEmitsConnectionWithLocalIpv6()
+ {
+ $loop = Factory::create();
+
+ try {
+ $server = new TcpServer('[::1]:0', $loop);
+ } catch (\RuntimeException $e) {
+ $this->markTestSkipped('Unable to start IPv6 server socket (not available on your platform?)');
+ }
+
+ $local = null;
+ $server->on('connection', function (ConnectionInterface $conn) use (&$local) {
+ $local = $conn->getLocalAddress();
+ });
+
+ $connector = new TcpConnector($loop);
+ $promise = $connector->connect($server->getAddress());
+
+ $promise->then($this->expectCallableOnce());
+
+ Block\sleep(0.1, $loop);
+
+ $this->assertContains('[::1]:', $local);
+ $this->assertEquals($server->getAddress(), $local);
+ }
+
+ public function testEmitsConnectionWithInheritedContextOptions()
+ {
+ if (defined('HHVM_VERSION') && version_compare(HHVM_VERSION, '3.13', '<')) {
+ // https://3v4l.org/hB4Tc
+ $this->markTestSkipped('Not supported on legacy HHVM < 3.13');
+ }
+
+ $loop = Factory::create();
+
+ $server = new TcpServer(0, $loop, array(
+ 'backlog' => 4
+ ));
+
+ $all = null;
+ $server->on('connection', function (ConnectionInterface $conn) use (&$all) {
+ $all = stream_context_get_options($conn->stream);
+ });
+
+ $connector = new TcpConnector($loop);
+ $promise = $connector->connect($server->getAddress());
+
+ $promise->then($this->expectCallableOnce());
+
+ Block\sleep(0.1, $loop);
+
+ $this->assertEquals(array('socket' => array('backlog' => 4)), $all);
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ public function testFailsToListenOnInvalidUri()
+ {
+ $loop = Factory::create();
+
+ new TcpServer('///', $loop);
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ public function testFailsToListenOnUriWithoutPort()
+ {
+ $loop = Factory::create();
+
+ new TcpServer('127.0.0.1', $loop);
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ public function testFailsToListenOnUriWithWrongScheme()
+ {
+ $loop = Factory::create();
+
+ new TcpServer('udp://127.0.0.1:0', $loop);
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ public function testFailsToListenOnUriWIthHostname()
+ {
+ $loop = Factory::create();
+
+ new TcpServer('localhost:8080', $loop);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/IntegrationTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/IntegrationTest.php
new file mode 100644
index 0000000..24dbe37
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/IntegrationTest.php
@@ -0,0 +1,171 @@
+<?php
+
+namespace React\Tests\Socket;
+
+use Clue\React\Block;
+use React\Dns\Resolver\Factory as ResolverFactory;
+use React\EventLoop\Factory;
+use React\Socket\Connector;
+use React\Socket\DnsConnector;
+use React\Socket\SecureConnector;
+use React\Socket\TcpConnector;
+
+/** @group internet */
+class IntegrationTest extends TestCase
+{
+ const TIMEOUT = 5.0;
+
+ /** @test */
+ public function gettingStuffFromGoogleShouldWork()
+ {
+ $loop = Factory::create();
+ $connector = new Connector($loop);
+
+ $conn = Block\await($connector->connect('google.com:80'), $loop);
+
+ $this->assertContains(':80', $conn->getRemoteAddress());
+ $this->assertNotEquals('google.com:80', $conn->getRemoteAddress());
+
+ $conn->write("GET / HTTP/1.0\r\n\r\n");
+
+ $response = $this->buffer($conn, $loop, self::TIMEOUT);
+
+ $this->assertRegExp('#^HTTP/1\.0#', $response);
+ }
+
+ /** @test */
+ public function gettingEncryptedStuffFromGoogleShouldWork()
+ {
+ if (!function_exists('stream_socket_enable_crypto')) {
+ $this->markTestSkipped('Not supported on your platform (outdated HHVM?)');
+ }
+
+ $loop = Factory::create();
+ $secureConnector = new Connector($loop);
+
+ $conn = Block\await($secureConnector->connect('tls://google.com:443'), $loop);
+
+ $conn->write("GET / HTTP/1.0\r\n\r\n");
+
+ $response = $this->buffer($conn, $loop, self::TIMEOUT);
+
+ $this->assertRegExp('#^HTTP/1\.0#', $response);
+ }
+
+ /** @test */
+ public function gettingEncryptedStuffFromGoogleShouldWorkIfHostIsResolvedFirst()
+ {
+ if (!function_exists('stream_socket_enable_crypto')) {
+ $this->markTestSkipped('Not supported on your platform (outdated HHVM?)');
+ }
+
+ $loop = Factory::create();
+
+ $factory = new ResolverFactory();
+ $dns = $factory->create('8.8.8.8', $loop);
+
+ $connector = new DnsConnector(
+ new SecureConnector(
+ new TcpConnector($loop),
+ $loop
+ ),
+ $dns
+ );
+
+ $conn = Block\await($connector->connect('google.com:443'), $loop);
+
+ $conn->write("GET / HTTP/1.0\r\n\r\n");
+
+ $response = $this->buffer($conn, $loop, self::TIMEOUT);
+
+ $this->assertRegExp('#^HTTP/1\.0#', $response);
+ }
+
+ /** @test */
+ public function gettingPlaintextStuffFromEncryptedGoogleShouldNotWork()
+ {
+ $loop = Factory::create();
+ $connector = new Connector($loop);
+
+ $conn = Block\await($connector->connect('google.com:443'), $loop);
+
+ $this->assertContains(':443', $conn->getRemoteAddress());
+ $this->assertNotEquals('google.com:443', $conn->getRemoteAddress());
+
+ $conn->write("GET / HTTP/1.0\r\n\r\n");
+
+ $response = $this->buffer($conn, $loop, self::TIMEOUT);
+
+ $this->assertNotRegExp('#^HTTP/1\.0#', $response);
+ }
+
+ public function testConnectingFailsIfDnsUsesInvalidResolver()
+ {
+ $loop = Factory::create();
+
+ $factory = new ResolverFactory();
+ $dns = $factory->create('demo.invalid', $loop);
+
+ $connector = new Connector($loop, array(
+ 'dns' => $dns
+ ));
+
+ $this->setExpectedException('RuntimeException');
+ Block\await($connector->connect('google.com:80'), $loop, self::TIMEOUT);
+ }
+
+ public function testConnectingFailsIfTimeoutIsTooSmall()
+ {
+ if (!function_exists('stream_socket_enable_crypto')) {
+ $this->markTestSkipped('Not supported on your platform (outdated HHVM?)');
+ }
+
+ $loop = Factory::create();
+
+ $connector = new Connector($loop, array(
+ 'timeout' => 0.001
+ ));
+
+ $this->setExpectedException('RuntimeException');
+ Block\await($connector->connect('google.com:80'), $loop, self::TIMEOUT);
+ }
+
+ public function testSelfSignedRejectsIfVerificationIsEnabled()
+ {
+ if (!function_exists('stream_socket_enable_crypto')) {
+ $this->markTestSkipped('Not supported on your platform (outdated HHVM?)');
+ }
+
+ $loop = Factory::create();
+
+ $connector = new Connector($loop, array(
+ 'tls' => array(
+ 'verify_peer' => true
+ )
+ ));
+
+ $this->setExpectedException('RuntimeException');
+ Block\await($connector->connect('tls://self-signed.badssl.com:443'), $loop, self::TIMEOUT);
+ }
+
+ public function testSelfSignedResolvesIfVerificationIsDisabled()
+ {
+ if (!function_exists('stream_socket_enable_crypto')) {
+ $this->markTestSkipped('Not supported on your platform (outdated HHVM?)');
+ }
+
+ $loop = Factory::create();
+
+ $connector = new Connector($loop, array(
+ 'tls' => array(
+ 'verify_peer' => false
+ )
+ ));
+
+ $conn = Block\await($connector->connect('tls://self-signed.badssl.com:443'), $loop, self::TIMEOUT);
+ $conn->close();
+
+ // if we reach this, then everything is good
+ $this->assertNull(null);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/LimitingServerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/LimitingServerTest.php
new file mode 100644
index 0000000..2cc9a58
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/LimitingServerTest.php
@@ -0,0 +1,195 @@
+<?php
+
+namespace React\Tests\Socket;
+
+use React\Socket\LimitingServer;
+use React\Socket\TcpServer;
+use React\EventLoop\Factory;
+use Clue\React\Block;
+
+class LimitingServerTest extends TestCase
+{
+ public function testGetAddressWillBePassedThroughToTcpServer()
+ {
+ $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
+ $tcp->expects($this->once())->method('getAddress')->willReturn('127.0.0.1:1234');
+
+ $server = new LimitingServer($tcp, 100);
+
+ $this->assertEquals('127.0.0.1:1234', $server->getAddress());
+ }
+
+ public function testPauseWillBePassedThroughToTcpServer()
+ {
+ $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
+ $tcp->expects($this->once())->method('pause');
+
+ $server = new LimitingServer($tcp, 100);
+
+ $server->pause();
+ }
+
+ public function testPauseTwiceWillBePassedThroughToTcpServerOnce()
+ {
+ $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
+ $tcp->expects($this->once())->method('pause');
+
+ $server = new LimitingServer($tcp, 100);
+
+ $server->pause();
+ $server->pause();
+ }
+
+ public function testResumeWillBePassedThroughToTcpServer()
+ {
+ $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
+ $tcp->expects($this->once())->method('resume');
+
+ $server = new LimitingServer($tcp, 100);
+
+ $server->pause();
+ $server->resume();
+ }
+
+ public function testResumeTwiceWillBePassedThroughToTcpServerOnce()
+ {
+ $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
+ $tcp->expects($this->once())->method('resume');
+
+ $server = new LimitingServer($tcp, 100);
+
+ $server->pause();
+ $server->resume();
+ $server->resume();
+ }
+
+ public function testCloseWillBePassedThroughToTcpServer()
+ {
+ $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
+ $tcp->expects($this->once())->method('close');
+
+ $server = new LimitingServer($tcp, 100);
+
+ $server->close();
+ }
+
+ public function testSocketErrorWillBeForwarded()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+
+ $tcp = new TcpServer(0, $loop);
+
+ $server = new LimitingServer($tcp, 100);
+
+ $server->on('error', $this->expectCallableOnce());
+
+ $tcp->emit('error', array(new \RuntimeException('test')));
+ }
+
+ public function testSocketConnectionWillBeForwarded()
+ {
+ $connection = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock();
+
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+
+ $tcp = new TcpServer(0, $loop);
+
+ $server = new LimitingServer($tcp, 100);
+ $server->on('connection', $this->expectCallableOnceWith($connection));
+ $server->on('error', $this->expectCallableNever());
+
+ $tcp->emit('connection', array($connection));
+
+ $this->assertEquals(array($connection), $server->getConnections());
+ }
+
+ public function testSocketConnectionWillBeClosedOnceLimitIsReached()
+ {
+ $first = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock();
+ $first->expects($this->never())->method('close');
+ $second = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock();
+ $second->expects($this->once())->method('close');
+
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+
+ $tcp = new TcpServer(0, $loop);
+
+ $server = new LimitingServer($tcp, 1);
+ $server->on('connection', $this->expectCallableOnceWith($first));
+ $server->on('error', $this->expectCallableOnce());
+
+ $tcp->emit('connection', array($first));
+ $tcp->emit('connection', array($second));
+ }
+
+ public function testPausingServerWillBePausedOnceLimitIsReached()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ $loop->expects($this->once())->method('addReadStream');
+ $loop->expects($this->once())->method('removeReadStream');
+
+ $tcp = new TcpServer(0, $loop);
+
+ $connection = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock();
+
+ $server = new LimitingServer($tcp, 1, true);
+
+ $tcp->emit('connection', array($connection));
+ }
+
+ public function testSocketDisconnectionWillRemoveFromList()
+ {
+ $loop = Factory::create();
+
+ $tcp = new TcpServer(0, $loop);
+
+ $socket = stream_socket_client($tcp->getAddress());
+ fclose($socket);
+
+ $server = new LimitingServer($tcp, 100);
+ $server->on('connection', $this->expectCallableOnce());
+ $server->on('error', $this->expectCallableNever());
+
+ Block\sleep(0.1, $loop);
+
+ $this->assertEquals(array(), $server->getConnections());
+ }
+
+ public function testPausingServerWillEmitOnlyOneButAcceptTwoConnectionsDueToOperatingSystem()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(0, $loop);
+ $server = new LimitingServer($server, 1, true);
+ $server->on('connection', $this->expectCallableOnce());
+ $server->on('error', $this->expectCallableNever());
+
+ $first = stream_socket_client($server->getAddress());
+ $second = stream_socket_client($server->getAddress());
+
+ Block\sleep(0.1, $loop);
+
+ fclose($first);
+ fclose($second);
+ }
+
+ public function testPausingServerWillEmitTwoConnectionsFromBacklog()
+ {
+ $loop = Factory::create();
+
+ $twice = $this->createCallableMock();
+ $twice->expects($this->exactly(2))->method('__invoke');
+
+ $server = new TcpServer(0, $loop);
+ $server = new LimitingServer($server, 1, true);
+ $server->on('connection', $twice);
+ $server->on('error', $this->expectCallableNever());
+
+ $first = stream_socket_client($server->getAddress());
+ fclose($first);
+ $second = stream_socket_client($server->getAddress());
+ fclose($second);
+
+ Block\sleep(0.1, $loop);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/SecureConnectorTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/SecureConnectorTest.php
new file mode 100644
index 0000000..0b3a702
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/SecureConnectorTest.php
@@ -0,0 +1,74 @@
+<?php
+
+namespace React\Tests\Socket;
+
+use React\Promise;
+use React\Socket\SecureConnector;
+
+class SecureConnectorTest extends TestCase
+{
+ private $loop;
+ private $tcp;
+ private $connector;
+
+ public function setUp()
+ {
+ if (!function_exists('stream_socket_enable_crypto')) {
+ $this->markTestSkipped('Not supported on your platform (outdated HHVM?)');
+ }
+
+ $this->loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ $this->tcp = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
+ $this->connector = new SecureConnector($this->tcp, $this->loop);
+ }
+
+ public function testConnectionWillWaitForTcpConnection()
+ {
+ $pending = new Promise\Promise(function () { });
+ $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('example.com:80'))->will($this->returnValue($pending));
+
+ $promise = $this->connector->connect('example.com:80');
+
+ $this->assertInstanceOf('React\Promise\PromiseInterface', $promise);
+ }
+
+ public function testConnectionWithCompleteUriWillBePassedThroughExpectForScheme()
+ {
+ $pending = new Promise\Promise(function () { });
+ $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('example.com:80/path?query#fragment'))->will($this->returnValue($pending));
+
+ $this->connector->connect('tls://example.com:80/path?query#fragment');
+ }
+
+ public function testConnectionToInvalidSchemeWillReject()
+ {
+ $this->tcp->expects($this->never())->method('connect');
+
+ $promise = $this->connector->connect('tcp://example.com:80');
+
+ $promise->then(null, $this->expectCallableOnce());
+ }
+
+ public function testCancelDuringTcpConnectionCancelsTcpConnection()
+ {
+ $pending = new Promise\Promise(function () { }, function () { throw new \Exception(); });
+ $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('example.com:80'))->will($this->returnValue($pending));
+
+ $promise = $this->connector->connect('example.com:80');
+ $promise->cancel();
+
+ $promise->then($this->expectCallableNever(), $this->expectCallableOnce());
+ }
+
+ public function testConnectionWillBeClosedAndRejectedIfConnectioIsNoStream()
+ {
+ $connection = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock();
+ $connection->expects($this->once())->method('close');
+
+ $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('example.com:80'))->willReturn(Promise\resolve($connection));
+
+ $promise = $this->connector->connect('example.com:80');
+
+ $promise->then($this->expectCallableNever(), $this->expectCallableOnce());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/SecureIntegrationTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/SecureIntegrationTest.php
new file mode 100644
index 0000000..8c9ba14
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/SecureIntegrationTest.php
@@ -0,0 +1,204 @@
+<?php
+
+namespace React\Tests\Socket;
+
+use React\EventLoop\Factory as LoopFactory;
+use React\Socket\TcpServer;
+use React\Socket\SecureServer;
+use React\Socket\TcpConnector;
+use React\Socket\SecureConnector;
+use Clue\React\Block;
+use React\Promise\Promise;
+use Evenement\EventEmitterInterface;
+use React\Promise\Deferred;
+use React\Socket\ConnectionInterface;
+
+class SecureIntegrationTest extends TestCase
+{
+ const TIMEOUT = 0.5;
+
+ private $loop;
+ private $server;
+ private $connector;
+ private $address;
+
+ public function setUp()
+ {
+ if (!function_exists('stream_socket_enable_crypto')) {
+ $this->markTestSkipped('Not supported on your platform (outdated HHVM?)');
+ }
+
+ $this->loop = LoopFactory::create();
+ $this->server = new TcpServer(0, $this->loop);
+ $this->server = new SecureServer($this->server, $this->loop, array(
+ 'local_cert' => __DIR__ . '/../examples/localhost.pem'
+ ));
+ $this->address = $this->server->getAddress();
+ $this->connector = new SecureConnector(new TcpConnector($this->loop), $this->loop, array('verify_peer' => false));
+ }
+
+ public function tearDown()
+ {
+ if ($this->server !== null) {
+ $this->server->close();
+ $this->server = null;
+ }
+ }
+
+ public function testConnectToServer()
+ {
+ $client = Block\await($this->connector->connect($this->address), $this->loop, self::TIMEOUT);
+ /* @var $client ConnectionInterface */
+
+ $client->close();
+
+ // if we reach this, then everything is good
+ $this->assertNull(null);
+ }
+
+ public function testConnectToServerEmitsConnection()
+ {
+ $promiseServer = $this->createPromiseForEvent($this->server, 'connection', $this->expectCallableOnce());
+
+ $promiseClient = $this->connector->connect($this->address);
+
+ list($_, $client) = Block\awaitAll(array($promiseServer, $promiseClient), $this->loop, self::TIMEOUT);
+ /* @var $client ConnectionInterface */
+
+ $client->close();
+ }
+
+ public function testSendSmallDataToServerReceivesOneChunk()
+ {
+ // server expects one connection which emits one data event
+ $received = new Deferred();
+ $this->server->on('connection', function (ConnectionInterface $peer) use ($received) {
+ $peer->on('data', function ($chunk) use ($received) {
+ $received->resolve($chunk);
+ });
+ });
+
+ $client = Block\await($this->connector->connect($this->address), $this->loop, self::TIMEOUT);
+ /* @var $client ConnectionInterface */
+
+ $client->write('hello');
+
+ // await server to report one "data" event
+ $data = Block\await($received->promise(), $this->loop, self::TIMEOUT);
+
+ $client->close();
+
+ $this->assertEquals('hello', $data);
+ }
+
+ public function testSendDataWithEndToServerReceivesAllData()
+ {
+ $disconnected = new Deferred();
+ $this->server->on('connection', function (ConnectionInterface $peer) use ($disconnected) {
+ $received = '';
+ $peer->on('data', function ($chunk) use (&$received) {
+ $received .= $chunk;
+ });
+ $peer->on('close', function () use (&$received, $disconnected) {
+ $disconnected->resolve($received);
+ });
+ });
+
+ $client = Block\await($this->connector->connect($this->address), $this->loop, self::TIMEOUT);
+ /* @var $client ConnectionInterface */
+
+ $data = str_repeat('a', 200000);
+ $client->end($data);
+
+ // await server to report connection "close" event
+ $received = Block\await($disconnected->promise(), $this->loop, self::TIMEOUT);
+
+ $this->assertEquals($data, $received);
+ }
+
+ public function testSendDataWithoutEndingToServerReceivesAllData()
+ {
+ $received = '';
+ $this->server->on('connection', function (ConnectionInterface $peer) use (&$received) {
+ $peer->on('data', function ($chunk) use (&$received) {
+ $received .= $chunk;
+ });
+ });
+
+ $client = Block\await($this->connector->connect($this->address), $this->loop, self::TIMEOUT);
+ /* @var $client ConnectionInterface */
+
+ $data = str_repeat('d', 200000);
+ $client->write($data);
+
+ // buffer incoming data for 0.1s (should be plenty of time)
+ Block\sleep(0.1, $this->loop);
+
+ $client->close();
+
+ $this->assertEquals($data, $received);
+ }
+
+ public function testConnectToServerWhichSendsSmallDataReceivesOneChunk()
+ {
+ $this->server->on('connection', function (ConnectionInterface $peer) {
+ $peer->write('hello');
+ });
+
+ $client = Block\await($this->connector->connect($this->address), $this->loop, self::TIMEOUT);
+ /* @var $client ConnectionInterface */
+
+ // await client to report one "data" event
+ $receive = $this->createPromiseForEvent($client, 'data', $this->expectCallableOnceWith('hello'));
+ Block\await($receive, $this->loop, self::TIMEOUT);
+
+ $client->close();
+ }
+
+ public function testConnectToServerWhichSendsDataWithEndReceivesAllData()
+ {
+ $data = str_repeat('b', 100000);
+ $this->server->on('connection', function (ConnectionInterface $peer) use ($data) {
+ $peer->end($data);
+ });
+
+ $client = Block\await($this->connector->connect($this->address), $this->loop, self::TIMEOUT);
+ /* @var $client ConnectionInterface */
+
+ // await data from client until it closes
+ $received = $this->buffer($client, $this->loop, self::TIMEOUT);
+
+ $this->assertEquals($data, $received);
+ }
+
+ public function testConnectToServerWhichSendsDataWithoutEndingReceivesAllData()
+ {
+ $data = str_repeat('c', 100000);
+ $this->server->on('connection', function (ConnectionInterface $peer) use ($data) {
+ $peer->write($data);
+ });
+
+ $client = Block\await($this->connector->connect($this->address), $this->loop, self::TIMEOUT);
+ /* @var $client ConnectionInterface */
+
+ // buffer incoming data for 0.1s (should be plenty of time)
+ $received = '';
+ $client->on('data', function ($chunk) use (&$received) {
+ $received .= $chunk;
+ });
+ Block\sleep(0.1, $this->loop);
+
+ $client->close();
+
+ $this->assertEquals($data, $received);
+ }
+
+ private function createPromiseForEvent(EventEmitterInterface $emitter, $event, $fn)
+ {
+ return new Promise(function ($resolve) use ($emitter, $event, $fn) {
+ $emitter->on($event, function () use ($resolve, $fn) {
+ $resolve(call_user_func_array($fn, func_get_args()));
+ });
+ });
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/SecureServerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/SecureServerTest.php
new file mode 100644
index 0000000..92c641f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/SecureServerTest.php
@@ -0,0 +1,105 @@
+<?php
+
+namespace React\Tests\Socket;
+
+use React\Socket\SecureServer;
+use React\Socket\TcpServer;
+
+class SecureServerTest extends TestCase
+{
+ public function setUp()
+ {
+ if (!function_exists('stream_socket_enable_crypto')) {
+ $this->markTestSkipped('Not supported on your platform (outdated HHVM?)');
+ }
+ }
+
+ public function testGetAddressWillBePassedThroughToTcpServer()
+ {
+ $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
+ $tcp->expects($this->once())->method('getAddress')->willReturn('tcp://127.0.0.1:1234');
+
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+
+ $server = new SecureServer($tcp, $loop, array());
+
+ $this->assertEquals('tls://127.0.0.1:1234', $server->getAddress());
+ }
+
+ public function testGetAddressWillReturnNullIfTcpServerReturnsNull()
+ {
+ $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
+ $tcp->expects($this->once())->method('getAddress')->willReturn(null);
+
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+
+ $server = new SecureServer($tcp, $loop, array());
+
+ $this->assertNull($server->getAddress());
+ }
+
+ public function testPauseWillBePassedThroughToTcpServer()
+ {
+ $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
+ $tcp->expects($this->once())->method('pause');
+
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+
+ $server = new SecureServer($tcp, $loop, array());
+
+ $server->pause();
+ }
+
+ public function testResumeWillBePassedThroughToTcpServer()
+ {
+ $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
+ $tcp->expects($this->once())->method('resume');
+
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+
+ $server = new SecureServer($tcp, $loop, array());
+
+ $server->resume();
+ }
+
+ public function testCloseWillBePassedThroughToTcpServer()
+ {
+ $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
+ $tcp->expects($this->once())->method('close');
+
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+
+ $server = new SecureServer($tcp, $loop, array());
+
+ $server->close();
+ }
+
+ public function testConnectionWillBeEndedWithErrorIfItIsNotAStream()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+
+ $tcp = new TcpServer(0, $loop);
+
+ $connection = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock();
+ $connection->expects($this->once())->method('end');
+
+ $server = new SecureServer($tcp, $loop, array());
+
+ $server->on('error', $this->expectCallableOnce());
+
+ $tcp->emit('connection', array($connection));
+ }
+
+ public function testSocketErrorWillBeForwarded()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+
+ $tcp = new TcpServer(0, $loop);
+
+ $server = new SecureServer($tcp, $loop, array());
+
+ $server->on('error', $this->expectCallableOnce());
+
+ $tcp->emit('error', array(new \RuntimeException('test')));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/ServerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/ServerTest.php
new file mode 100644
index 0000000..14fdb2c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/ServerTest.php
@@ -0,0 +1,173 @@
+<?php
+
+namespace React\Tests\Socket;
+
+use React\EventLoop\Factory;
+use React\Socket\Server;
+use React\Socket\TcpConnector;
+use React\Socket\UnixConnector;
+use Clue\React\Block;
+use React\Socket\ConnectionInterface;
+
+class ServerTest extends TestCase
+{
+ const TIMEOUT = 0.1;
+
+ public function testCreateServerWithZeroPortAssignsRandomPort()
+ {
+ $loop = Factory::create();
+
+ $server = new Server(0, $loop);
+ $this->assertNotEquals(0, $server->getAddress());
+ $server->close();
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ public function testConstructorThrowsForInvalidUri()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+
+ $server = new Server('invalid URI', $loop);
+ }
+
+ public function testConstructorCreatesExpectedTcpServer()
+ {
+ $loop = Factory::create();
+
+ $server = new Server(0, $loop);
+
+ $connector = new TcpConnector($loop);
+ $connector->connect($server->getAddress())
+ ->then($this->expectCallableOnce(), $this->expectCallableNever());
+
+ $connection = Block\await($connector->connect($server->getAddress()), $loop, self::TIMEOUT);
+
+ $connection->close();
+ $server->close();
+ }
+
+ public function testConstructorCreatesExpectedUnixServer()
+ {
+ $loop = Factory::create();
+
+ $server = new Server($this->getRandomSocketUri(), $loop);
+
+ $connector = new UnixConnector($loop);
+ $connector->connect($server->getAddress())
+ ->then($this->expectCallableOnce(), $this->expectCallableNever());
+
+ $connection = Block\await($connector->connect($server->getAddress()), $loop, self::TIMEOUT);
+
+ $connection->close();
+ $server->close();
+ }
+
+ public function testEmitsConnectionForNewConnection()
+ {
+ $loop = Factory::create();
+
+ $server = new Server(0, $loop);
+ $server->on('connection', $this->expectCallableOnce());
+
+ $client = stream_socket_client($server->getAddress());
+
+ Block\sleep(0.1, $loop);
+ }
+
+ public function testDoesNotEmitConnectionForNewConnectionToPausedServer()
+ {
+ $loop = Factory::create();
+
+ $server = new Server(0, $loop);
+ $server->pause();
+ $server->on('connection', $this->expectCallableNever());
+
+ $client = stream_socket_client($server->getAddress());
+
+ Block\sleep(0.1, $loop);
+ }
+
+ public function testDoesEmitConnectionForNewConnectionToResumedServer()
+ {
+ $loop = Factory::create();
+
+ $server = new Server(0, $loop);
+ $server->pause();
+ $server->on('connection', $this->expectCallableOnce());
+
+ $client = stream_socket_client($server->getAddress());
+
+ Block\sleep(0.1, $loop);
+
+ $server->resume();
+ Block\sleep(0.1, $loop);
+ }
+
+ public function testDoesNotAllowConnectionToClosedServer()
+ {
+ $loop = Factory::create();
+
+ $server = new Server(0, $loop);
+ $server->on('connection', $this->expectCallableNever());
+ $address = $server->getAddress();
+ $server->close();
+
+ $client = @stream_socket_client($address);
+
+ Block\sleep(0.1, $loop);
+
+ $this->assertFalse($client);
+ }
+
+ public function testEmitsConnectionWithInheritedContextOptions()
+ {
+ if (defined('HHVM_VERSION') && version_compare(HHVM_VERSION, '3.13', '<')) {
+ // https://3v4l.org/hB4Tc
+ $this->markTestSkipped('Not supported on legacy HHVM < 3.13');
+ }
+
+ $loop = Factory::create();
+
+ $server = new Server(0, $loop, array(
+ 'backlog' => 4
+ ));
+
+ $all = null;
+ $server->on('connection', function (ConnectionInterface $conn) use (&$all) {
+ $all = stream_context_get_options($conn->stream);
+ });
+
+ $client = stream_socket_client($server->getAddress());
+
+ Block\sleep(0.1, $loop);
+
+ $this->assertEquals(array('socket' => array('backlog' => 4)), $all);
+ }
+
+ public function testDoesNotEmitSecureConnectionForNewPlainConnection()
+ {
+ if (!function_exists('stream_socket_enable_crypto')) {
+ $this->markTestSkipped('Not supported on your platform (outdated HHVM?)');
+ }
+
+ $loop = Factory::create();
+
+ $server = new Server('tls://127.0.0.1:0', $loop, array(
+ 'tls' => array(
+ 'local_cert' => __DIR__ . '/../examples/localhost.pem'
+ )
+ ));
+ $server->on('connection', $this->expectCallableNever());
+
+ $client = stream_socket_client(str_replace('tls://', '', $server->getAddress()));
+
+ Block\sleep(0.1, $loop);
+ }
+
+ private function getRandomSocketUri()
+ {
+ return "unix://" . sys_get_temp_dir() . DIRECTORY_SEPARATOR . uniqid(rand(), true) . '.sock';
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/Stub/CallableStub.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/Stub/CallableStub.php
new file mode 100644
index 0000000..1b197eb
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/Stub/CallableStub.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace React\Tests\Socket\Stub;
+
+class CallableStub
+{
+ public function __invoke()
+ {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/Stub/ConnectionStub.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/Stub/ConnectionStub.php
new file mode 100644
index 0000000..844b2ad
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/Stub/ConnectionStub.php
@@ -0,0 +1,63 @@
+<?php
+
+namespace React\Tests\Socket\Stub;
+
+use Evenement\EventEmitter;
+use React\Socket\ConnectionInterface;
+use React\Stream\WritableStreamInterface;
+use React\Stream\Util;
+
+class ConnectionStub extends EventEmitter implements ConnectionInterface
+{
+ private $data = '';
+
+ public function isReadable()
+ {
+ return true;
+ }
+
+ public function isWritable()
+ {
+ return true;
+ }
+
+ public function pause()
+ {
+ }
+
+ public function resume()
+ {
+ }
+
+ public function pipe(WritableStreamInterface $dest, array $options = array())
+ {
+ Util::pipe($this, $dest, $options);
+
+ return $dest;
+ }
+
+ public function write($data)
+ {
+ $this->data .= $data;
+
+ return true;
+ }
+
+ public function end($data = null)
+ {
+ }
+
+ public function close()
+ {
+ }
+
+ public function getData()
+ {
+ return $this->data;
+ }
+
+ public function getRemoteAddress()
+ {
+ return '127.0.0.1';
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/Stub/ServerStub.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/Stub/ServerStub.php
new file mode 100644
index 0000000..d9e74f4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/Stub/ServerStub.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace React\Tests\Socket\Stub;
+
+use Evenement\EventEmitter;
+use React\Socket\ServerInterface;
+
+class ServerStub extends EventEmitter implements ServerInterface
+{
+ public function getAddress()
+ {
+ return '127.0.0.1:80';
+ }
+
+ public function close()
+ {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/TcpConnectorTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/TcpConnectorTest.php
new file mode 100644
index 0000000..e3575a7
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/TcpConnectorTest.php
@@ -0,0 +1,255 @@
+<?php
+
+namespace React\Tests\Socket;
+
+use Clue\React\Block;
+use React\EventLoop\Factory;
+use React\Socket\ConnectionInterface;
+use React\Socket\TcpConnector;
+use React\Socket\TcpServer;
+
+class TcpConnectorTest extends TestCase
+{
+ const TIMEOUT = 0.1;
+
+ /** @test */
+ public function connectionToEmptyPortShouldFail()
+ {
+ $loop = Factory::create();
+
+ $connector = new TcpConnector($loop);
+ $connector->connect('127.0.0.1:9999')
+ ->then($this->expectCallableNever(), $this->expectCallableOnce());
+
+ $loop->run();
+ }
+
+ /** @test */
+ public function connectionToTcpServerShouldAddResourceToLoop()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ $connector = new TcpConnector($loop);
+
+ $server = new TcpServer(0, $loop);
+
+ $valid = false;
+ $loop->expects($this->once())->method('addWriteStream')->with($this->callback(function ($arg) use (&$valid) {
+ $valid = is_resource($arg);
+ return true;
+ }));
+ $connector->connect($server->getAddress());
+
+ $this->assertTrue($valid);
+ }
+
+ /** @test */
+ public function connectionToTcpServerShouldSucceed()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(9999, $loop);
+ $server->on('connection', $this->expectCallableOnce());
+ $server->on('connection', array($server, 'close'));
+
+ $connector = new TcpConnector($loop);
+
+ $connection = Block\await($connector->connect('127.0.0.1:9999'), $loop, self::TIMEOUT);
+
+ $this->assertInstanceOf('React\Socket\ConnectionInterface', $connection);
+
+ $connection->close();
+ }
+
+ /** @test */
+ public function connectionToTcpServerShouldSucceedWithRemoteAdressSameAsTarget()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(9999, $loop);
+ $server->on('connection', array($server, 'close'));
+
+ $connector = new TcpConnector($loop);
+
+ $connection = Block\await($connector->connect('127.0.0.1:9999'), $loop, self::TIMEOUT);
+ /* @var $connection ConnectionInterface */
+
+ $this->assertEquals('tcp://127.0.0.1:9999', $connection->getRemoteAddress());
+
+ $connection->close();
+ }
+
+ /** @test */
+ public function connectionToTcpServerShouldSucceedWithLocalAdressOnLocalhost()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(9999, $loop);
+ $server->on('connection', array($server, 'close'));
+
+ $connector = new TcpConnector($loop);
+
+ $connection = Block\await($connector->connect('127.0.0.1:9999'), $loop, self::TIMEOUT);
+ /* @var $connection ConnectionInterface */
+
+ $this->assertContains('tcp://127.0.0.1:', $connection->getLocalAddress());
+ $this->assertNotEquals('tcp://127.0.0.1:9999', $connection->getLocalAddress());
+
+ $connection->close();
+ }
+
+ /** @test */
+ public function connectionToTcpServerShouldSucceedWithNullAddressesAfterConnectionClosed()
+ {
+ $loop = Factory::create();
+
+ $server = new TcpServer(9999, $loop);
+ $server->on('connection', array($server, 'close'));
+
+ $connector = new TcpConnector($loop);
+
+ $connection = Block\await($connector->connect('127.0.0.1:9999'), $loop, self::TIMEOUT);
+ /* @var $connection ConnectionInterface */
+
+ $connection->close();
+
+ $this->assertNull($connection->getRemoteAddress());
+ $this->assertNull($connection->getLocalAddress());
+ }
+
+ /** @test */
+ public function connectionToTcpServerWillCloseWhenOtherSideCloses()
+ {
+ $loop = Factory::create();
+
+ // immediately close connection and server once connection is in
+ $server = new TcpServer(0, $loop);
+ $server->on('connection', function (ConnectionInterface $conn) use ($server) {
+ $conn->close();
+ $server->close();
+ });
+
+ $once = $this->expectCallableOnce();
+ $connector = new TcpConnector($loop);
+ $connector->connect($server->getAddress())->then(function (ConnectionInterface $conn) use ($once) {
+ $conn->write('hello');
+ $conn->on('close', $once);
+ });
+
+ $loop->run();
+ }
+
+ /** @test */
+ public function connectionToEmptyIp6PortShouldFail()
+ {
+ $loop = Factory::create();
+
+ $connector = new TcpConnector($loop);
+ $connector
+ ->connect('[::1]:9999')
+ ->then($this->expectCallableNever(), $this->expectCallableOnce());
+
+ $loop->run();
+ }
+
+ /** @test */
+ public function connectionToIp6TcpServerShouldSucceed()
+ {
+ $loop = Factory::create();
+
+ try {
+ $server = new TcpServer('[::1]:9999', $loop);
+ } catch (\Exception $e) {
+ $this->markTestSkipped('Unable to start IPv6 server socket (IPv6 not supported on this system?)');
+ }
+
+ $server->on('connection', $this->expectCallableOnce());
+ $server->on('connection', array($server, 'close'));
+
+ $connector = new TcpConnector($loop);
+
+ $connection = Block\await($connector->connect('[::1]:9999'), $loop, self::TIMEOUT);
+ /* @var $connection ConnectionInterface */
+
+ $this->assertEquals('tcp://[::1]:9999', $connection->getRemoteAddress());
+
+ $this->assertContains('tcp://[::1]:', $connection->getLocalAddress());
+ $this->assertNotEquals('tcp://[::1]:9999', $connection->getLocalAddress());
+
+ $connection->close();
+ }
+
+ /** @test */
+ public function connectionToHostnameShouldFailImmediately()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+
+ $connector = new TcpConnector($loop);
+ $connector->connect('www.google.com:80')->then(
+ $this->expectCallableNever(),
+ $this->expectCallableOnce()
+ );
+ }
+
+ /** @test */
+ public function connectionToInvalidPortShouldFailImmediately()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+
+ $connector = new TcpConnector($loop);
+ $connector->connect('255.255.255.255:12345678')->then(
+ $this->expectCallableNever(),
+ $this->expectCallableOnce()
+ );
+ }
+
+ /** @test */
+ public function connectionToInvalidSchemeShouldFailImmediately()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+
+ $connector = new TcpConnector($loop);
+ $connector->connect('tls://google.com:443')->then(
+ $this->expectCallableNever(),
+ $this->expectCallableOnce()
+ );
+ }
+
+ /** @test */
+ public function cancellingConnectionShouldRemoveResourceFromLoopAndCloseResource()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ $connector = new TcpConnector($loop);
+
+ $server = new TcpServer(0, $loop);
+
+ $loop->expects($this->once())->method('addWriteStream');
+ $promise = $connector->connect($server->getAddress());
+
+ $resource = null;
+ $valid = false;
+ $loop->expects($this->once())->method('removeWriteStream')->with($this->callback(function ($arg) use (&$resource, &$valid) {
+ $resource = $arg;
+ $valid = is_resource($arg);
+ return true;
+ }));
+ $promise->cancel();
+
+ $this->assertTrue($valid);
+ $this->assertFalse(is_resource($resource));
+ }
+
+ /** @test */
+ public function cancellingConnectionShouldRejectPromise()
+ {
+ $loop = Factory::create();
+ $connector = new TcpConnector($loop);
+
+ $server = new TcpServer(0, $loop);
+
+ $promise = $connector->connect($server->getAddress());
+ $promise->cancel();
+
+ $this->setExpectedException('RuntimeException', 'Cancelled');
+ Block\await($promise, $loop);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/TcpServerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/TcpServerTest.php
new file mode 100644
index 0000000..72b3c28
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/TcpServerTest.php
@@ -0,0 +1,285 @@
+<?php
+
+namespace React\Tests\Socket;
+
+use Clue\React\Block;
+use React\EventLoop\Factory;
+use React\Socket\TcpServer;
+use React\Stream\DuplexResourceStream;
+
+class TcpServerTest extends TestCase
+{
+ private $loop;
+ private $server;
+ private $port;
+
+ private function createLoop()
+ {
+ return Factory::create();
+ }
+
+ /**
+ * @covers React\Socket\TcpServer::__construct
+ * @covers React\Socket\TcpServer::getAddress
+ */
+ public function setUp()
+ {
+ $this->loop = $this->createLoop();
+ $this->server = new TcpServer(0, $this->loop);
+
+ $this->port = parse_url($this->server->getAddress(), PHP_URL_PORT);
+ }
+
+ /**
+ * @covers React\Socket\TcpServer::handleConnection
+ */
+ public function testConnection()
+ {
+ $client = stream_socket_client('tcp://localhost:'.$this->port);
+
+ $this->server->on('connection', $this->expectCallableOnce());
+
+ $this->tick();
+ }
+
+ /**
+ * @covers React\Socket\TcpServer::handleConnection
+ */
+ public function testConnectionWithManyClients()
+ {
+ $client1 = stream_socket_client('tcp://localhost:'.$this->port);
+ $client2 = stream_socket_client('tcp://localhost:'.$this->port);
+ $client3 = stream_socket_client('tcp://localhost:'.$this->port);
+
+ $this->server->on('connection', $this->expectCallableExactly(3));
+ $this->tick();
+ $this->tick();
+ $this->tick();
+ }
+
+ public function testDataEventWillNotBeEmittedWhenClientSendsNoData()
+ {
+ $client = stream_socket_client('tcp://localhost:'.$this->port);
+
+ $mock = $this->expectCallableNever();
+
+ $this->server->on('connection', function ($conn) use ($mock) {
+ $conn->on('data', $mock);
+ });
+ $this->tick();
+ $this->tick();
+ }
+
+ public function testDataWillBeEmittedWithDataClientSends()
+ {
+ $client = stream_socket_client('tcp://localhost:'.$this->port);
+
+ fwrite($client, "foo\n");
+
+ $mock = $this->expectCallableOnceWith("foo\n");
+
+ $this->server->on('connection', function ($conn) use ($mock) {
+ $conn->on('data', $mock);
+ });
+ $this->tick();
+ $this->tick();
+ }
+
+ public function testDataWillBeEmittedEvenWhenClientShutsDownAfterSending()
+ {
+ $client = stream_socket_client('tcp://localhost:' . $this->port);
+ fwrite($client, "foo\n");
+ stream_socket_shutdown($client, STREAM_SHUT_WR);
+
+ $mock = $this->expectCallableOnceWith("foo\n");
+
+ $this->server->on('connection', function ($conn) use ($mock) {
+ $conn->on('data', $mock);
+ });
+ $this->tick();
+ $this->tick();
+ }
+
+ public function testLoopWillEndWhenServerIsClosed()
+ {
+ // explicitly unset server because we already call close()
+ $this->server->close();
+ $this->server = null;
+
+ $this->loop->run();
+
+ // if we reach this, then everything is good
+ $this->assertNull(null);
+ }
+
+ public function testCloseTwiceIsNoOp()
+ {
+ $this->server->close();
+ $this->server->close();
+
+ // if we reach this, then everything is good
+ $this->assertNull(null);
+ }
+
+ public function testGetAddressAfterCloseReturnsNull()
+ {
+ $this->server->close();
+ $this->assertNull($this->server->getAddress());
+ }
+
+ public function testLoopWillEndWhenServerIsClosedAfterSingleConnection()
+ {
+ $client = stream_socket_client('tcp://localhost:' . $this->port);
+
+ // explicitly unset server because we only accept a single connection
+ // and then already call close()
+ $server = $this->server;
+ $this->server = null;
+
+ $server->on('connection', function ($conn) use ($server) {
+ $conn->close();
+ $server->close();
+ });
+
+ $this->loop->run();
+
+ // if we reach this, then everything is good
+ $this->assertNull(null);
+ }
+
+ public function testDataWillBeEmittedInMultipleChunksWhenClientSendsExcessiveAmounts()
+ {
+ $client = stream_socket_client('tcp://localhost:' . $this->port);
+ $stream = new DuplexResourceStream($client, $this->loop);
+
+ $bytes = 1024 * 1024;
+ $stream->end(str_repeat('*', $bytes));
+
+ $mock = $this->expectCallableOnce();
+
+ // explicitly unset server because we only accept a single connection
+ // and then already call close()
+ $server = $this->server;
+ $this->server = null;
+
+ $received = 0;
+ $server->on('connection', function ($conn) use ($mock, &$received, $server) {
+ // count number of bytes received
+ $conn->on('data', function ($data) use (&$received) {
+ $received += strlen($data);
+ });
+
+ $conn->on('end', $mock);
+
+ // do not await any further connections in order to let the loop terminate
+ $server->close();
+ });
+
+ $this->loop->run();
+
+ $this->assertEquals($bytes, $received);
+ }
+
+ public function testConnectionDoesNotEndWhenClientDoesNotClose()
+ {
+ $client = stream_socket_client('tcp://localhost:'.$this->port);
+
+ $mock = $this->expectCallableNever();
+
+ $this->server->on('connection', function ($conn) use ($mock) {
+ $conn->on('end', $mock);
+ });
+ $this->tick();
+ $this->tick();
+ }
+
+ /**
+ * @covers React\Socket\Connection::end
+ */
+ public function testConnectionDoesEndWhenClientCloses()
+ {
+ $client = stream_socket_client('tcp://localhost:'.$this->port);
+
+ fclose($client);
+
+ $mock = $this->expectCallableOnce();
+
+ $this->server->on('connection', function ($conn) use ($mock) {
+ $conn->on('end', $mock);
+ });
+ $this->tick();
+ $this->tick();
+ }
+
+ public function testCtorAddsResourceToLoop()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ $loop->expects($this->once())->method('addReadStream');
+
+ $server = new TcpServer(0, $loop);
+ }
+
+ public function testResumeWithoutPauseIsNoOp()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ $loop->expects($this->once())->method('addReadStream');
+
+ $server = new TcpServer(0, $loop);
+ $server->resume();
+ }
+
+ public function testPauseRemovesResourceFromLoop()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ $loop->expects($this->once())->method('removeReadStream');
+
+ $server = new TcpServer(0, $loop);
+ $server->pause();
+ }
+
+ public function testPauseAfterPauseIsNoOp()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ $loop->expects($this->once())->method('removeReadStream');
+
+ $server = new TcpServer(0, $loop);
+ $server->pause();
+ $server->pause();
+ }
+
+ public function testCloseRemovesResourceFromLoop()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ $loop->expects($this->once())->method('removeReadStream');
+
+ $server = new TcpServer(0, $loop);
+ $server->close();
+ }
+
+ /**
+ * @expectedException RuntimeException
+ */
+ public function testListenOnBusyPortThrows()
+ {
+ if (DIRECTORY_SEPARATOR === '\\') {
+ $this->markTestSkipped('Windows supports listening on same port multiple times');
+ }
+
+ $another = new TcpServer($this->port, $this->loop);
+ }
+
+ /**
+ * @covers React\Socket\TcpServer::close
+ */
+ public function tearDown()
+ {
+ if ($this->server) {
+ $this->server->close();
+ }
+ }
+
+ private function tick()
+ {
+ Block\sleep(0, $this->loop);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/TestCase.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/TestCase.php
new file mode 100644
index 0000000..e87fc2f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/TestCase.php
@@ -0,0 +1,101 @@
+<?php
+
+namespace React\Tests\Socket;
+
+use React\Stream\ReadableStreamInterface;
+use React\EventLoop\LoopInterface;
+use Clue\React\Block;
+use React\Promise\Promise;
+use PHPUnit\Framework\TestCase as BaseTestCase;
+
+class TestCase extends BaseTestCase
+{
+ protected function expectCallableExactly($amount)
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->exactly($amount))
+ ->method('__invoke');
+
+ return $mock;
+ }
+
+ protected function expectCallableOnce()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke');
+
+ return $mock;
+ }
+
+ protected function expectCallableOnceWith($value)
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($value);
+
+ return $mock;
+ }
+
+ protected function expectCallableNever()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->never())
+ ->method('__invoke');
+
+ return $mock;
+ }
+
+ protected function createCallableMock()
+ {
+ return $this->getMockBuilder('React\Tests\Socket\Stub\CallableStub')->getMock();
+ }
+
+ protected function buffer(ReadableStreamInterface $stream, LoopInterface $loop, $timeout)
+ {
+ if (!$stream->isReadable()) {
+ return '';
+ }
+
+ return Block\await(new Promise(
+ function ($resolve, $reject) use ($stream) {
+ $buffer = '';
+ $stream->on('data', function ($chunk) use (&$buffer) {
+ $buffer .= $chunk;
+ });
+
+ $stream->on('error', $reject);
+
+ $stream->on('close', function () use (&$buffer, $resolve) {
+ $resolve($buffer);
+ });
+ },
+ function () use ($stream) {
+ $stream->close();
+ throw new \RuntimeException();
+ }
+ ), $loop, $timeout);
+ }
+
+ public function setExpectedException($exception, $exceptionMessage = '', $exceptionCode = null)
+ {
+ if (method_exists($this, 'expectException')) {
+ // PHPUnit 5+
+ $this->expectException($exception);
+ if ($exceptionMessage !== '') {
+ $this->expectExceptionMessage($exceptionMessage);
+ }
+ if ($exceptionCode !== null) {
+ $this->expectExceptionCode($exceptionCode);
+ }
+ } else {
+ // legacy PHPUnit 4
+ parent::setExpectedException($exception, $exceptionMessage, $exceptionCode);
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/TimeoutConnectorTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/TimeoutConnectorTest.php
new file mode 100644
index 0000000..64787d9
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/TimeoutConnectorTest.php
@@ -0,0 +1,103 @@
+<?php
+
+namespace React\Tests\Socket;
+
+use React\Socket\TimeoutConnector;
+use React\Promise;
+use React\EventLoop\Factory;
+
+class TimeoutConnectorTest extends TestCase
+{
+ public function testRejectsOnTimeout()
+ {
+ $promise = new Promise\Promise(function () { });
+
+ $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
+ $connector->expects($this->once())->method('connect')->with('google.com:80')->will($this->returnValue($promise));
+
+ $loop = Factory::create();
+
+ $timeout = new TimeoutConnector($connector, 0.01, $loop);
+
+ $timeout->connect('google.com:80')->then(
+ $this->expectCallableNever(),
+ $this->expectCallableOnce()
+ );
+
+ $loop->run();
+ }
+
+ public function testRejectsWhenConnectorRejects()
+ {
+ $promise = Promise\reject(new \RuntimeException());
+
+ $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
+ $connector->expects($this->once())->method('connect')->with('google.com:80')->will($this->returnValue($promise));
+
+ $loop = Factory::create();
+
+ $timeout = new TimeoutConnector($connector, 5.0, $loop);
+
+ $timeout->connect('google.com:80')->then(
+ $this->expectCallableNever(),
+ $this->expectCallableOnce()
+ );
+
+ $loop->run();
+ }
+
+ public function testResolvesWhenConnectorResolves()
+ {
+ $promise = Promise\resolve();
+
+ $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
+ $connector->expects($this->once())->method('connect')->with('google.com:80')->will($this->returnValue($promise));
+
+ $loop = Factory::create();
+
+ $timeout = new TimeoutConnector($connector, 5.0, $loop);
+
+ $timeout->connect('google.com:80')->then(
+ $this->expectCallableOnce(),
+ $this->expectCallableNever()
+ );
+
+ $loop->run();
+ }
+
+ public function testRejectsAndCancelsPendingPromiseOnTimeout()
+ {
+ $promise = new Promise\Promise(function () { }, $this->expectCallableOnce());
+
+ $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
+ $connector->expects($this->once())->method('connect')->with('google.com:80')->will($this->returnValue($promise));
+
+ $loop = Factory::create();
+
+ $timeout = new TimeoutConnector($connector, 0.01, $loop);
+
+ $timeout->connect('google.com:80')->then(
+ $this->expectCallableNever(),
+ $this->expectCallableOnce()
+ );
+
+ $loop->run();
+ }
+
+ public function testCancelsPendingPromiseOnCancel()
+ {
+ $promise = new Promise\Promise(function () { }, function () { throw new \Exception(); });
+
+ $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
+ $connector->expects($this->once())->method('connect')->with('google.com:80')->will($this->returnValue($promise));
+
+ $loop = Factory::create();
+
+ $timeout = new TimeoutConnector($connector, 0.01, $loop);
+
+ $out = $timeout->connect('google.com:80');
+ $out->cancel();
+
+ $out->then($this->expectCallableNever(), $this->expectCallableOnce());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/UnixConnectorTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/UnixConnectorTest.php
new file mode 100644
index 0000000..1564064
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/UnixConnectorTest.php
@@ -0,0 +1,64 @@
+<?php
+
+namespace React\Tests\Socket;
+
+use React\Socket\ConnectionInterface;
+use React\Socket\UnixConnector;
+
+class UnixConnectorTest extends TestCase
+{
+ private $loop;
+ private $connector;
+
+ public function setUp()
+ {
+ $this->loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ $this->connector = new UnixConnector($this->loop);
+ }
+
+ public function testInvalid()
+ {
+ $promise = $this->connector->connect('google.com:80');
+ $promise->then(null, $this->expectCallableOnce());
+ }
+
+ public function testInvalidScheme()
+ {
+ $promise = $this->connector->connect('tcp://google.com:80');
+ $promise->then(null, $this->expectCallableOnce());
+ }
+
+ public function testValid()
+ {
+ // random unix domain socket path
+ $path = sys_get_temp_dir() . '/test' . uniqid() . '.sock';
+
+ // temporarily create unix domain socket server to connect to
+ $server = stream_socket_server('unix://' . $path, $errno, $errstr);
+
+ // skip test if we can not create a test server (Windows etc.)
+ if (!$server) {
+ $this->markTestSkipped('Unable to create socket "' . $path . '": ' . $errstr . '(' . $errno .')');
+ return;
+ }
+
+ // tests succeeds if we get notified of successful connection
+ $promise = $this->connector->connect($path);
+ $promise->then($this->expectCallableOnce());
+
+ // remember remote and local address of this connection and close again
+ $remote = $local = false;
+ $promise->then(function(ConnectionInterface $conn) use (&$remote, &$local) {
+ $remote = $conn->getRemoteAddress();
+ $local = $conn->getLocalAddress();
+ $conn->close();
+ });
+
+ // clean up server
+ fclose($server);
+ unlink($path);
+
+ $this->assertNull($local);
+ $this->assertEquals('unix://' . $path, $remote);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/UnixServerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/UnixServerTest.php
new file mode 100644
index 0000000..10f7e4f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/socket/tests/UnixServerTest.php
@@ -0,0 +1,283 @@
+<?php
+
+namespace React\Tests\Socket;
+
+use Clue\React\Block;
+use React\EventLoop\Factory;
+use React\Socket\UnixServer;
+use React\Stream\DuplexResourceStream;
+
+class UnixServerTest extends TestCase
+{
+ private $loop;
+ private $server;
+ private $uds;
+
+ /**
+ * @covers React\Socket\UnixServer::__construct
+ * @covers React\Socket\UnixServer::getAddress
+ */
+ public function setUp()
+ {
+ $this->loop = Factory::create();
+ $this->uds = $this->getRandomSocketUri();
+ $this->server = new UnixServer($this->uds, $this->loop);
+ }
+
+ /**
+ * @covers React\Socket\UnixServer::handleConnection
+ */
+ public function testConnection()
+ {
+ $client = stream_socket_client($this->uds);
+
+ $this->server->on('connection', $this->expectCallableOnce());
+ $this->tick();
+ }
+
+ /**
+ * @covers React\Socket\UnixServer::handleConnection
+ */
+ public function testConnectionWithManyClients()
+ {
+ $client1 = stream_socket_client($this->uds);
+ $client2 = stream_socket_client($this->uds);
+ $client3 = stream_socket_client($this->uds);
+
+ $this->server->on('connection', $this->expectCallableExactly(3));
+ $this->tick();
+ $this->tick();
+ $this->tick();
+ }
+
+ public function testDataEventWillNotBeEmittedWhenClientSendsNoData()
+ {
+ $client = stream_socket_client($this->uds);
+
+ $mock = $this->expectCallableNever();
+
+ $this->server->on('connection', function ($conn) use ($mock) {
+ $conn->on('data', $mock);
+ });
+ $this->tick();
+ $this->tick();
+ }
+
+ public function testDataWillBeEmittedWithDataClientSends()
+ {
+ $client = stream_socket_client($this->uds);
+
+ fwrite($client, "foo\n");
+
+ $mock = $this->expectCallableOnceWith("foo\n");
+
+ $this->server->on('connection', function ($conn) use ($mock) {
+ $conn->on('data', $mock);
+ });
+ $this->tick();
+ $this->tick();
+ }
+
+ public function testDataWillBeEmittedEvenWhenClientShutsDownAfterSending()
+ {
+ $client = stream_socket_client($this->uds);
+ fwrite($client, "foo\n");
+ stream_socket_shutdown($client, STREAM_SHUT_WR);
+
+ $mock = $this->expectCallableOnceWith("foo\n");
+
+ $this->server->on('connection', function ($conn) use ($mock) {
+ $conn->on('data', $mock);
+ });
+ $this->tick();
+ $this->tick();
+ }
+
+ public function testLoopWillEndWhenServerIsClosed()
+ {
+ // explicitly unset server because we already call close()
+ $this->server->close();
+ $this->server = null;
+
+ $this->loop->run();
+
+ // if we reach this, then everything is good
+ $this->assertNull(null);
+ }
+
+ public function testCloseTwiceIsNoOp()
+ {
+ $this->server->close();
+ $this->server->close();
+
+ // if we reach this, then everything is good
+ $this->assertNull(null);
+ }
+
+ public function testGetAddressAfterCloseReturnsNull()
+ {
+ $this->server->close();
+ $this->assertNull($this->server->getAddress());
+ }
+
+ public function testLoopWillEndWhenServerIsClosedAfterSingleConnection()
+ {
+ $client = stream_socket_client($this->uds);
+
+ // explicitly unset server because we only accept a single connection
+ // and then already call close()
+ $server = $this->server;
+ $this->server = null;
+
+ $server->on('connection', function ($conn) use ($server) {
+ $conn->close();
+ $server->close();
+ });
+
+ $this->loop->run();
+
+ // if we reach this, then everything is good
+ $this->assertNull(null);
+ }
+
+ public function testDataWillBeEmittedInMultipleChunksWhenClientSendsExcessiveAmounts()
+ {
+ $client = stream_socket_client($this->uds);
+ $stream = new DuplexResourceStream($client, $this->loop);
+
+ $bytes = 1024 * 1024;
+ $stream->end(str_repeat('*', $bytes));
+
+ $mock = $this->expectCallableOnce();
+
+ // explicitly unset server because we only accept a single connection
+ // and then already call close()
+ $server = $this->server;
+ $this->server = null;
+
+ $received = 0;
+ $server->on('connection', function ($conn) use ($mock, &$received, $server) {
+ // count number of bytes received
+ $conn->on('data', function ($data) use (&$received) {
+ $received += strlen($data);
+ });
+
+ $conn->on('end', $mock);
+
+ // do not await any further connections in order to let the loop terminate
+ $server->close();
+ });
+
+ $this->loop->run();
+
+ $this->assertEquals($bytes, $received);
+ }
+
+ public function testConnectionDoesNotEndWhenClientDoesNotClose()
+ {
+ $client = stream_socket_client($this->uds);
+
+ $mock = $this->expectCallableNever();
+
+ $this->server->on('connection', function ($conn) use ($mock) {
+ $conn->on('end', $mock);
+ });
+ $this->tick();
+ $this->tick();
+ }
+
+ /**
+ * @covers React\Socket\Connection::end
+ */
+ public function testConnectionDoesEndWhenClientCloses()
+ {
+ $client = stream_socket_client($this->uds);
+
+ fclose($client);
+
+ $mock = $this->expectCallableOnce();
+
+ $this->server->on('connection', function ($conn) use ($mock) {
+ $conn->on('end', $mock);
+ });
+ $this->tick();
+ $this->tick();
+ }
+
+ public function testCtorAddsResourceToLoop()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ $loop->expects($this->once())->method('addReadStream');
+
+ $server = new UnixServer($this->getRandomSocketUri(), $loop);
+ }
+
+ public function testResumeWithoutPauseIsNoOp()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ $loop->expects($this->once())->method('addReadStream');
+
+ $server = new UnixServer($this->getRandomSocketUri(), $loop);
+ $server->resume();
+ }
+
+ public function testPauseRemovesResourceFromLoop()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ $loop->expects($this->once())->method('removeReadStream');
+
+ $server = new UnixServer($this->getRandomSocketUri(), $loop);
+ $server->pause();
+ }
+
+ public function testPauseAfterPauseIsNoOp()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ $loop->expects($this->once())->method('removeReadStream');
+
+ $server = new UnixServer($this->getRandomSocketUri(), $loop);
+ $server->pause();
+ $server->pause();
+ }
+
+ public function testCloseRemovesResourceFromLoop()
+ {
+ $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ $loop->expects($this->once())->method('removeReadStream');
+
+ $server = new UnixServer($this->getRandomSocketUri(), $loop);
+ $server->close();
+ }
+
+ /**
+ * @expectedException RuntimeException
+ */
+ public function testListenOnBusyPortThrows()
+ {
+ if (DIRECTORY_SEPARATOR === '\\') {
+ $this->markTestSkipped('Windows supports listening on same port multiple times');
+ }
+
+ $another = new UnixServer($this->uds, $this->loop);
+ }
+
+ /**
+ * @covers React\Socket\UnixServer::close
+ */
+ public function tearDown()
+ {
+ if ($this->server) {
+ $this->server->close();
+ }
+ }
+
+ private function getRandomSocketUri()
+ {
+ return "unix://" . sys_get_temp_dir() . DIRECTORY_SEPARATOR . uniqid(rand(), true) . '.sock';
+ }
+
+ private function tick()
+ {
+ Block\sleep(0, $this->loop);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/.gitignore b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/.gitignore
new file mode 100644
index 0000000..987e2a2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/.gitignore
@@ -0,0 +1,2 @@
+composer.lock
+vendor
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/.travis.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/.travis.yml
new file mode 100644
index 0000000..f4e3376
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/.travis.yml
@@ -0,0 +1,50 @@
+language: php
+
+php:
+# - 5.3 # requires old distro, see below
+ - 5.4
+ - 5.5
+ - 5.6
+ - 7.0
+# - 7.0 # Mac OS X test setup, ignore errors, see below
+ - 7.1
+ - 7.2
+ - nightly # ignore errors, see below
+ - hhvm # ignore errors, see below
+
+# lock distro so new future defaults will not break the build
+dist: trusty
+
+matrix:
+ include:
+ - php: 5.3
+ dist: precise
+ include:
+ - os: osx
+ language: generic
+ php: 7.0 # just to look right on travis
+ env:
+ - PACKAGE: php70
+ allow_failures:
+ - php: nightly
+ - php: hhvm
+ - os: osx
+
+install:
+ # OSX install inspired by https://github.com/kiler129/TravisCI-OSX-PHP
+ - |
+ if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
+ brew tap homebrew/homebrew-php
+ echo "Installing PHP ..."
+ brew install "${PACKAGE}"
+ brew install "${PACKAGE}"-xdebug
+ brew link "${PACKAGE}"
+ echo "Installing composer ..."
+ curl -s http://getcomposer.org/installer | php
+ mv composer.phar /usr/local/bin/composer
+ fi
+ - composer install --no-interaction
+
+script:
+ - vendor/bin/phpunit --coverage-text
+ - time php examples/91-benchmark-throughput.php
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/CHANGELOG.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/CHANGELOG.md
new file mode 100644
index 0000000..f64815d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/CHANGELOG.md
@@ -0,0 +1,377 @@
+# Changelog
+
+## 0.7.7 (2018-01-19)
+
+* Improve test suite by fixing forward compatibility with upcoming EventLoop
+ releases, avoid risky tests and add test group to skip integration tests
+ relying on internet connection and apply appropriate test timeouts.
+ (#128, #131 and #132 by @clue)
+
+## 0.7.6 (2017-12-21)
+
+* Fix: Work around reading from unbuffered pipe stream in legacy PHP < 5.4.28 and PHP < 5.5.12
+ (#126 by @clue)
+
+* Improve test suite by simplifying test bootstrapping logic via Composer and
+ test against PHP 7.2
+ (#127 by @clue and #124 by @carusogabriel)
+
+## 0.7.5 (2017-11-20)
+
+* Fix: Igore excessive `fopen()` mode flags for `WritableResourceStream`
+ (#119 by @clue)
+
+* Fix: Fix forward compatibility with upcoming EventLoop releases
+ (#121 by @clue)
+
+* Restructure examples to ease getting started
+ (#123 by @clue)
+
+* Improve test suite by adding forward compatibility with PHPUnit 6 and
+ ignore Mac OS X test failures for now until Travis tests work again
+ (#122 by @gabriel-caruso and #120 by @clue)
+
+## 0.7.4 (2017-10-11)
+
+* Fix: Remove event listeners from `CompositeStream` once closed and
+ remove undocumented left-over `close` event argument
+ (#116 by @clue)
+
+* Minor documentation improvements: Fix wrong class name in example,
+ fix typos in README and
+ fix forward compatibility with upcoming EventLoop releases in example
+ (#113 by @docteurklein and #114 and #115 by @clue)
+
+* Improve test suite by running against Mac OS X on Travis
+ (#112 by @clue)
+
+## 0.7.3 (2017-08-05)
+
+* Improvement: Support Événement 3.0 a long side 2.0 and 1.0
+ (#108 by @WyriHaximus)
+
+* Readme: Corrected loop initialization in usage example
+ (#109 by @pulyavin)
+
+* Travis: Lock linux distribution preventing future builds from breaking
+ (#110 by @clue)
+
+## 0.7.2 (2017-06-15)
+
+* Bug fix: WritableResourceStream: Close the underlying stream when closing the stream.
+ (#107 by @WyriHaximus)
+
+## 0.7.1 (2017-05-20)
+
+* Feature: Add optional `$writeChunkSize` parameter to limit maximum number of
+ bytes to write at once.
+ (#105 by @clue)
+
+ ```php
+ $stream = new WritableResourceStream(STDOUT, $loop, null, 8192);
+ ```
+
+* Ignore HHVM test failures for now until Travis tests work again
+ (#106 by @clue)
+
+## 0.7.0 (2017-05-04)
+
+* Removed / BC break: Remove deprecated and unneeded functionality
+ (#45, #87, #90, #91 and #93 by @clue)
+
+ * Remove deprecated `Stream` class, use `DuplexResourceStream` instead
+ (#87 by @clue)
+
+ * Remove public `$buffer` property, use new constructor parameters instead
+ (#91 by @clue)
+
+ * Remove public `$stream` property from all resource streams
+ (#90 by @clue)
+
+ * Remove undocumented and now unused `ReadableStream` and `WritableStream`
+ (#93 by @clue)
+
+ * Remove `BufferedSink`
+ (#45 by @clue)
+
+* Feature / BC break: Simplify `ThroughStream` by using data callback instead of
+ inheritance. It is now a direct implementation of `DuplexStreamInterface`.
+ (#88 and #89 by @clue)
+
+ ```php
+ $through = new ThroughStream(function ($data) {
+ return json_encode($data) . PHP_EOL;
+ });
+ $through->on('data', $this->expectCallableOnceWith("[2, true]\n"));
+
+ $through->write(array(2, true));
+ ```
+
+* Feature / BC break: The `CompositeStream` starts closed if either side is
+ already closed and forwards pause to pipe source on first write attempt.
+ (#96 and #103 by @clue)
+
+ If either side of the composite stream closes, it will also close the other
+ side. We now also ensure that if either side is already closed during
+ instantiation, it will also close the other side.
+
+* BC break: Mark all classes as `final` and
+ mark internal API as `private` to discourage inheritance
+ (#95 and #99 by @clue)
+
+* Feature / BC break: Only emit `error` event for fatal errors
+ (#92 by @clue)
+
+ > The `error` event was previously also allowed to be emitted for non-fatal
+ errors, but our implementations actually only ever emitted this as a fatal
+ error and then closed the stream.
+
+* Feature: Explicitly allow custom events and exclude any semantics
+ (#97 by @clue)
+
+* Support legacy PHP 5.3 through PHP 7.1 and HHVM and improve usage documentation
+ (#100 and #102 by @clue)
+
+* Actually require all dependencies so this is self-contained and improve
+ forward compatibility with EventLoop v1.0 and v0.5
+ (#94 and #98 by @clue)
+
+## 0.6.0 (2017-03-26)
+
+* Feature / Fix / BC break: Add `DuplexResourceStream` and deprecate `Stream`
+ (#85 by @clue)
+
+ ```php
+ // old (does still work for BC reasons)
+ $stream = new Stream($connection, $loop);
+
+ // new
+ $stream = new DuplexResourceStream($connection, $loop);
+ ```
+
+ Note that the `DuplexResourceStream` now rejects read-only or write-only
+ streams, so this may affect BC. If you want a read-only or write-only
+ resource, use `ReadableResourceStream` or `WritableResourceStream` instead of
+ `DuplexResourceStream`.
+
+ > BC note: This class was previously called `Stream`. The `Stream` class still
+ exists for BC reasons and will be removed in future versions of this package.
+
+* Feature / BC break: Add `WritableResourceStream` (previously called `Buffer`)
+ (#84 by @clue)
+
+ ```php
+ // old
+ $stream = new Buffer(STDOUT, $loop);
+
+ // new
+ $stream = new WritableResourceStream(STDOUT, $loop);
+ ```
+
+* Feature: Add `ReadableResourceStream`
+ (#83 by @clue)
+
+ ```php
+ $stream = new ReadableResourceStream(STDIN, $loop);
+ ```
+
+* Fix / BC Break: Enforce using non-blocking I/O
+ (#46 by @clue)
+
+ > BC note: This is known to affect process pipes on Windows which do not
+ support non-blocking I/O and could thus block the whole EventLoop previously.
+
+* Feature / Fix / BC break: Consistent semantics for
+ `DuplexStreamInterface::end()` to ensure it SHOULD also end readable side
+ (#86 by @clue)
+
+* Fix: Do not use unbuffered reads on pipe streams for legacy PHP < 5.4
+ (#80 by @clue)
+
+## 0.5.0 (2017-03-08)
+
+* Feature / BC break: Consistent `end` event semantics (EOF)
+ (#70 by @clue)
+
+ The `end` event will now only be emitted for a *successful* end, not if the
+ stream closes due to an unrecoverable `error` event or if you call `close()`
+ explicitly.
+ If you want to detect when the stream closes (terminates), use the `close`
+ event instead.
+
+* BC break: Remove custom (undocumented) `full-drain` event from `Buffer`
+ (#63 and #68 by @clue)
+
+ > The `full-drain` event was undocumented and mostly used internally.
+ Relying on this event has attracted some low-quality code in the past, so
+ we've removed this from the public API in order to work out a better
+ solution instead.
+ If you want to detect when the buffer finishes flushing data to the stream,
+ you may want to look into its `end()` method or the `close` event instead.
+
+* Feature / BC break: Consistent event semantics and documentation,
+ explicitly state *when* events will be emitted and *which* arguments they
+ receive.
+ (#73 and #69 by @clue)
+
+ The documentation now explicitly defines each event and its arguments.
+ Custom events and event arguments are still supported.
+ Most notably, all defined events only receive inherently required event
+ arguments and no longer transmit the instance they are emitted on for
+ consistency and performance reasons.
+
+ ```php
+ // old (inconsistent and not supported by all implementations)
+ $stream->on('data', function ($data, $stream) {
+ // process $data
+ });
+
+ // new (consistent throughout the whole ecosystem)
+ $stream->on('data', function ($data) use ($stream) {
+ // process $data
+ });
+ ```
+
+ > This mostly adds documentation (and thus some stricter, consistent
+ definitions) for the existing behavior, it does NOT define any major
+ changes otherwise.
+ Most existing code should be compatible with these changes, unless
+ it relied on some undocumented/unintended semantics.
+
+* Feature / BC break: Consistent method semantics and documentation
+ (#72 by @clue)
+
+ > This mostly adds documentation (and thus some stricter, consistent
+ definitions) for the existing behavior, it does NOT define any major
+ changes otherwise.
+ Most existing code should be compatible with these changes, unless
+ it relied on some undocumented/unintended semantics.
+
+* Feature: Consistent `pipe()` semantics for closed and closing streams
+ (#71 from @clue)
+
+ The source stream will now always be paused via `pause()` when the
+ destination stream closes. Also, properly stop piping if the source
+ stream closes and remove all event forwarding.
+
+* Improve test suite by adding PHPUnit to `require-dev` and improving coverage.
+ (#74 and #75 by @clue, #66 by @nawarian)
+
+## 0.4.6 (2017-01-25)
+
+* Feature: The `Buffer` can now be injected into the `Stream` (or be used standalone)
+ (#62 by @clue)
+
+* Fix: Forward `close` event only once for `CompositeStream` and `ThroughStream`
+ (#60 by @clue)
+
+* Fix: Consistent `close` event behavior for `Buffer`
+ (#61 by @clue)
+
+## 0.4.5 (2016-11-13)
+
+* Feature: Support setting read buffer size to `null` (infinite)
+ (#42 by @clue)
+
+* Fix: Do not emit `full-drain` event if `Buffer` is closed during `drain` event
+ (#55 by @clue)
+
+* Vastly improved performance by factor of 10x to 20x.
+ Raise default buffer sizes to 64 KiB and simplify and improve error handling
+ and unneeded function calls.
+ (#53, #55, #56 by @clue)
+
+## 0.4.4 (2016-08-22)
+
+* Bug fix: Emit `error` event and close `Stream` when accessing the underlying
+ stream resource fails with a permanent error.
+ (#52 and #40 by @clue, #25 by @lysenkobv)
+
+* Bug fix: Do not emit empty `data` event if nothing has been read (stream reached EOF)
+ (#39 by @clue)
+
+* Bug fix: Ignore empty writes to `Buffer`
+ (#51 by @clue)
+
+* Add benchmarking script to measure throughput in CI
+ (#41 by @clue)
+
+## 0.4.3 (2015-10-07)
+
+* Bug fix: Read buffer to 0 fixes error with libevent and large quantity of I/O (@mbonneau)
+* Bug fix: No double-write during drain call (@arnaud-lb)
+* Bug fix: Support HHVM (@clue)
+* Adjust compatibility to 5.3 (@clue)
+
+## 0.4.2 (2014-09-09)
+
+* Added DuplexStreamInterface
+* Stream sets stream resources to non-blocking
+* Fixed potential race condition in pipe
+
+## 0.4.1 (2014-04-13)
+
+* Bug fix: v0.3.4 changes merged for v0.4.1
+
+## 0.3.4 (2014-03-30)
+
+* Bug fix: [Stream] Fixed 100% CPU spike from non-empty write buffer on closed stream
+
+## 0.4.0 (2014-02-02)
+
+* BC break: Bump minimum PHP version to PHP 5.4, remove 5.3 specific hacks
+* BC break: Update to Evenement 2.0
+* Dependency: Autoloading and filesystem structure now PSR-4 instead of PSR-0
+
+## 0.3.3 (2013-07-08)
+
+* Bug fix: [Stream] Correctly detect closed connections
+
+## 0.3.2 (2013-05-10)
+
+* Bug fix: [Stream] Make sure CompositeStream is closed properly
+
+## 0.3.1 (2013-04-21)
+
+* Bug fix: [Stream] Allow any `ReadableStreamInterface` on `BufferedSink::createPromise()`
+
+## 0.3.0 (2013-04-14)
+
+* Feature: [Stream] Factory method for BufferedSink
+
+## 0.2.6 (2012-12-26)
+
+* Version bump
+
+## 0.2.5 (2012-11-26)
+
+* Feature: Make BufferedSink trigger progress events on the promise (@jsor)
+
+## 0.2.4 (2012-11-18)
+
+* Feature: Added ThroughStream, CompositeStream, ReadableStream and WritableStream
+* Feature: Added BufferedSink
+
+## 0.2.3 (2012-11-14)
+
+* Version bump
+
+## 0.2.2 (2012-10-28)
+
+* Version bump
+
+## 0.2.1 (2012-10-14)
+
+* Bug fix: Check for EOF in `Buffer::write()`
+
+## 0.2.0 (2012-09-10)
+
+* Version bump
+
+## 0.1.1 (2012-07-12)
+
+* Bug fix: Testing and functional against PHP >= 5.3.3 and <= 5.3.8
+
+## 0.1.0 (2012-07-11)
+
+* First tagged release
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/LICENSE b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/LICENSE
new file mode 100644
index 0000000..a808108
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2012 Igor Wiedler, Chris Boden
+
+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.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/README.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/README.md
new file mode 100644
index 0000000..c362534
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/README.md
@@ -0,0 +1,1224 @@
+# Stream
+
+[![Build Status](https://travis-ci.org/reactphp/stream.svg?branch=master)](https://travis-ci.org/reactphp/stream)
+
+Event-driven readable and writable streams for non-blocking I/O in [ReactPHP](https://reactphp.org/).
+
+In order to make the [EventLoop](https://github.com/reactphp/event-loop)
+easier to use, this component introduces the powerful concept of "streams".
+Streams allow you to efficiently process huge amounts of data (such as a multi
+Gigabyte file download) in small chunks without having to store everything in
+memory at once.
+They are very similar to the streams found in PHP itself,
+but have an interface more suited for async, non-blocking I/O.
+
+**Table of contents**
+
+* [Stream usage](#stream-usage)
+ * [ReadableStreamInterface](#readablestreaminterface)
+ * [data event](#data-event)
+ * [end event](#end-event)
+ * [error event](#error-event)
+ * [close event](#close-event)
+ * [isReadable()](#isreadable)
+ * [pause()](#pause)
+ * [resume()](#resume)
+ * [pipe()](#pipe)
+ * [close()](#close)
+ * [WritableStreamInterface](#writablestreaminterface)
+ * [drain event](#drain-event)
+ * [pipe event](#pipe-event)
+ * [error event](#error-event-1)
+ * [close event](#close-event-1)
+ * [isWritable()](#iswritable)
+ * [write()](#write)
+ * [end()](#end)
+ * [close()](#close-1)
+ * [DuplexStreamInterface](#duplexstreaminterface)
+* [Creating streams](#creating-streams)
+ * [ReadableResourceStream](#readableresourcestream)
+ * [WritableResourceStream](#writableresourcestream)
+ * [DuplexResourceStream](#duplexresourcestream)
+ * [ThroughStream](#throughstream)
+ * [CompositeStream](#compositestream)
+* [Usage](#usage)
+* [Install](#install)
+* [Tests](#tests)
+* [License](#license)
+* [More](#more)
+
+## Stream usage
+
+ReactPHP uses the concept of "streams" throughout its ecosystem to provide a
+consistent higher-level abstraction for processing streams of arbitrary data
+contents and size.
+While a stream itself is a quite low-level concept, it can be used as a powerful
+abstraction to build higher-level components and protocols on top.
+
+If you're new to this concept, it helps to think of them as a water pipe:
+You can consume water from a source or you can produce water and forward (pipe)
+it to any destination (sink).
+
+Similarly, streams can either be
+
+* readable (such as `STDIN` terminal input) or
+* writable (such as `STDOUT` terminal output) or
+* duplex (both readable *and* writable, such as a TCP/IP connection)
+
+Accordingly, this package defines the following three interfaces
+
+* [`ReadableStreamInterface`](#readablestreaminterface)
+* [`WritableStreamInterface`](#writablestreaminterface)
+* [`DuplexStreamInterface`](#duplexstreaminterface)
+
+### ReadableStreamInterface
+
+The `ReadableStreamInterface` is responsible for providing an interface for
+read-only streams and the readable side of duplex streams.
+
+Besides defining a few methods, this interface also implements the
+`EventEmitterInterface` which allows you to react to certain events.
+
+The event callback functions MUST be a valid `callable` that obeys strict
+parameter definitions and MUST accept event parameters exactly as documented.
+The event callback functions MUST NOT throw an `Exception`.
+The return value of the event callback functions will be ignored and has no
+effect, so for performance reasons you're recommended to not return any
+excessive data structures.
+
+Every implementation of this interface MUST follow these event semantics in
+order to be considered a well-behaving stream.
+
+> Note that higher-level implementations of this interface may choose to
+ define additional events with dedicated semantics not defined as part of
+ this low-level stream specification. Conformance with these event semantics
+ is out of scope for this interface, so you may also have to refer to the
+ documentation of such a higher-level implementation.
+
+#### data event
+
+The `data` event will be emitted whenever some data was read/received
+from this source stream.
+The event receives a single mixed argument for incoming data.
+
+```php
+$stream->on('data', function ($data) {
+ echo $data;
+});
+```
+
+This event MAY be emitted any number of times, which may be zero times if
+this stream does not send any data at all.
+It SHOULD not be emitted after an `end` or `close` event.
+
+The given `$data` argument may be of mixed type, but it's usually
+recommended it SHOULD be a `string` value or MAY use a type that allows
+representation as a `string` for maximum compatibility.
+
+Many common streams (such as a TCP/IP connection or a file-based stream)
+will emit the raw (binary) payload data that is received over the wire as
+chunks of `string` values.
+
+Due to the stream-based nature of this, the sender may send any number
+of chunks with varying sizes. There are no guarantees that these chunks
+will be received with the exact same framing the sender intended to send.
+In other words, many lower-level protocols (such as TCP/IP) transfer the
+data in chunks that may be anywhere between single-byte values to several
+dozens of kilobytes. You may want to apply a higher-level protocol to
+these low-level data chunks in order to achieve proper message framing.
+
+#### end event
+
+The `end` event will be emitted once the source stream has successfully
+reached the end of the stream (EOF).
+
+```php
+$stream->on('end', function () {
+ echo 'END';
+});
+```
+
+This event SHOULD be emitted once or never at all, depending on whether
+a successful end was detected.
+It SHOULD NOT be emitted after a previous `end` or `close` event.
+It MUST NOT be emitted if the stream closes due to a non-successful
+end, such as after a previous `error` event.
+
+After the stream is ended, it MUST switch to non-readable mode,
+see also `isReadable()`.
+
+This event will only be emitted if the *end* was reached successfully,
+not if the stream was interrupted by an unrecoverable error or explicitly
+closed. Not all streams know this concept of a "successful end".
+Many use-cases involve detecting when the stream closes (terminates)
+instead, in this case you should use the `close` event.
+After the stream emits an `end` event, it SHOULD usually be followed by a
+`close` event.
+
+Many common streams (such as a TCP/IP connection or a file-based stream)
+will emit this event if either the remote side closes the connection or
+a file handle was successfully read until reaching its end (EOF).
+
+Note that this event should not be confused with the `end()` method.
+This event defines a successful end *reading* from a source stream, while
+the `end()` method defines *writing* a successful end to a destination
+stream.
+
+#### error event
+
+The `error` event will be emitted once a fatal error occurs, usually while
+trying to read from this stream.
+The event receives a single `Exception` argument for the error instance.
+
+```php
+$server->on('error', function (Exception $e) {
+ echo 'Error: ' . $e->getMessage() . PHP_EOL;
+});
+```
+
+This event SHOULD be emitted once the stream detects a fatal error, such
+as a fatal transmission error or after an unexpected `data` or premature
+`end` event.
+It SHOULD NOT be emitted after a previous `error`, `end` or `close` event.
+It MUST NOT be emitted if this is not a fatal error condition, such as
+a temporary network issue that did not cause any data to be lost.
+
+After the stream errors, it MUST close the stream and SHOULD thus be
+followed by a `close` event and then switch to non-readable mode, see
+also `close()` and `isReadable()`.
+
+Many common streams (such as a TCP/IP connection or a file-based stream)
+only deal with data transmission and do not make assumption about data
+boundaries (such as unexpected `data` or premature `end` events).
+In other words, many lower-level protocols (such as TCP/IP) may choose
+to only emit this for a fatal transmission error once and will then
+close (terminate) the stream in response.
+
+If this stream is a `DuplexStreamInterface`, you should also notice
+how the writable side of the stream also implements an `error` event.
+In other words, an error may occur while either reading or writing the
+stream which should result in the same error processing.
+
+#### close event
+
+The `close` event will be emitted once the stream closes (terminates).
+
+```php
+$stream->on('close', function () {
+ echo 'CLOSED';
+});
+```
+
+This event SHOULD be emitted once or never at all, depending on whether
+the stream ever terminates.
+It SHOULD NOT be emitted after a previous `close` event.
+
+After the stream is closed, it MUST switch to non-readable mode,
+see also `isReadable()`.
+
+Unlike the `end` event, this event SHOULD be emitted whenever the stream
+closes, irrespective of whether this happens implicitly due to an
+unrecoverable error or explicitly when either side closes the stream.
+If you only want to detect a *successful* end, you should use the `end`
+event instead.
+
+Many common streams (such as a TCP/IP connection or a file-based stream)
+will likely choose to emit this event after reading a *successful* `end`
+event or after a fatal transmission `error` event.
+
+If this stream is a `DuplexStreamInterface`, you should also notice
+how the writable side of the stream also implements a `close` event.
+In other words, after receiving this event, the stream MUST switch into
+non-writable AND non-readable mode, see also `isWritable()`.
+Note that this event should not be confused with the `end` event.
+
+#### isReadable()
+
+The `isReadable(): bool` method can be used to
+check whether this stream is in a readable state (not closed already).
+
+This method can be used to check if the stream still accepts incoming
+data events or if it is ended or closed already.
+Once the stream is non-readable, no further `data` or `end` events SHOULD
+be emitted.
+
+```php
+assert($stream->isReadable() === false);
+
+$stream->on('data', assertNeverCalled());
+$stream->on('end', assertNeverCalled());
+```
+
+A successfully opened stream always MUST start in readable mode.
+
+Once the stream ends or closes, it MUST switch to non-readable mode.
+This can happen any time, explicitly through `close()` or
+implicitly due to a remote close or an unrecoverable transmission error.
+Once a stream has switched to non-readable mode, it MUST NOT transition
+back to readable mode.
+
+If this stream is a `DuplexStreamInterface`, you should also notice
+how the writable side of the stream also implements an `isWritable()`
+method. Unless this is a half-open duplex stream, they SHOULD usually
+have the same return value.
+
+#### pause()
+
+The `pause(): void` method can be used to
+pause reading incoming data events.
+
+Removes the data source file descriptor from the event loop. This
+allows you to throttle incoming data.
+
+Unless otherwise noted, a successfully opened stream SHOULD NOT start
+in paused state.
+
+Once the stream is paused, no futher `data` or `end` events SHOULD
+be emitted.
+
+```php
+$stream->pause();
+
+$stream->on('data', assertShouldNeverCalled());
+$stream->on('end', assertShouldNeverCalled());
+```
+
+This method is advisory-only, though generally not recommended, the
+stream MAY continue emitting `data` events.
+
+You can continue processing events by calling `resume()` again.
+
+Note that both methods can be called any number of times, in particular
+calling `pause()` more than once SHOULD NOT have any effect.
+
+See also `resume()`.
+
+#### resume()
+
+The `resume(): void` method can be used to
+resume reading incoming data events.
+
+Re-attach the data source after a previous `pause()`.
+
+```php
+$stream->pause();
+
+$loop->addTimer(1.0, function () use ($stream) {
+ $stream->resume();
+});
+```
+
+Note that both methods can be called any number of times, in particular
+calling `resume()` without a prior `pause()` SHOULD NOT have any effect.
+
+See also `pause()`.
+
+#### pipe()
+
+The `pipe(WritableStreamInterface $dest, array $options = [])` method can be used to
+pipe all the data from this readable source into the given writable destination.
+
+Automatically sends all incoming data to the destination.
+Automatically throttles the source based on what the destination can handle.
+
+```php
+$source->pipe($dest);
+```
+
+Similarly, you can also pipe an instance implementing `DuplexStreamInterface`
+into itself in order to write back all the data that is received.
+This may be a useful feature for a TCP/IP echo service:
+
+```php
+$connection->pipe($connection);
+```
+
+This method returns the destination stream as-is, which can be used to
+set up chains of piped streams:
+
+```php
+$source->pipe($decodeGzip)->pipe($filterBadWords)->pipe($dest);
+```
+
+By default, this will call `end()` on the destination stream once the
+source stream emits an `end` event. This can be disabled like this:
+
+```php
+$source->pipe($dest, array('end' => false));
+```
+
+Note that this only applies to the `end` event.
+If an `error` or explicit `close` event happens on the source stream,
+you'll have to manually close the destination stream:
+
+```php
+$source->pipe($dest);
+$source->on('close', function () use ($dest) {
+ $dest->end('BYE!');
+});
+```
+
+If the source stream is not readable (closed state), then this is a NO-OP.
+
+```php
+$source->close();
+$source->pipe($dest); // NO-OP
+```
+
+If the destinantion stream is not writable (closed state), then this will simply
+throttle (pause) the source stream:
+
+```php
+$dest->close();
+$source->pipe($dest); // calls $source->pause()
+```
+
+Similarly, if the destination stream is closed while the pipe is still
+active, it will also throttle (pause) the source stream:
+
+```php
+$source->pipe($dest);
+$dest->close(); // calls $source->pause()
+```
+
+Once the pipe is set up successfully, the destination stream MUST emit
+a `pipe` event with this source stream an event argument.
+
+#### close()
+
+The `close(): void` method can be used to
+close the stream (forcefully).
+
+This method can be used to (forcefully) close the stream.
+
+```php
+$stream->close();
+```
+
+Once the stream is closed, it SHOULD emit a `close` event.
+Note that this event SHOULD NOT be emitted more than once, in particular
+if this method is called multiple times.
+
+After calling this method, the stream MUST switch into a non-readable
+mode, see also `isReadable()`.
+This means that no further `data` or `end` events SHOULD be emitted.
+
+```php
+$stream->close();
+assert($stream->isReadable() === false);
+
+$stream->on('data', assertNeverCalled());
+$stream->on('end', assertNeverCalled());
+```
+
+If this stream is a `DuplexStreamInterface`, you should also notice
+how the writable side of the stream also implements a `close()` method.
+In other words, after calling this method, the stream MUST switch into
+non-writable AND non-readable mode, see also `isWritable()`.
+Note that this method should not be confused with the `end()` method.
+
+### WritableStreamInterface
+
+The `WritableStreamInterface` is responsible for providing an interface for
+write-only streams and the writable side of duplex streams.
+
+Besides defining a few methods, this interface also implements the
+`EventEmitterInterface` which allows you to react to certain events.
+
+The event callback functions MUST be a valid `callable` that obeys strict
+parameter definitions and MUST accept event parameters exactly as documented.
+The event callback functions MUST NOT throw an `Exception`.
+The return value of the event callback functions will be ignored and has no
+effect, so for performance reasons you're recommended to not return any
+excessive data structures.
+
+Every implementation of this interface MUST follow these event semantics in
+order to be considered a well-behaving stream.
+
+> Note that higher-level implementations of this interface may choose to
+ define additional events with dedicated semantics not defined as part of
+ this low-level stream specification. Conformance with these event semantics
+ is out of scope for this interface, so you may also have to refer to the
+ documentation of such a higher-level implementation.
+
+#### drain event
+
+The `drain` event will be emitted whenever the write buffer became full
+previously and is now ready to accept more data.
+
+```php
+$stream->on('drain', function () use ($stream) {
+ echo 'Stream is now ready to accept more data';
+});
+```
+
+This event SHOULD be emitted once every time the buffer became full
+previously and is now ready to accept more data.
+In other words, this event MAY be emitted any number of times, which may
+be zero times if the buffer never became full in the first place.
+This event SHOULD NOT be emitted if the buffer has not become full
+previously.
+
+This event is mostly used internally, see also `write()` for more details.
+
+#### pipe event
+
+The `pipe` event will be emitted whenever a readable stream is `pipe()`d
+into this stream.
+The event receives a single `ReadableStreamInterface` argument for the
+source stream.
+
+```php
+$stream->on('pipe', function (ReadableStreamInterface $source) use ($stream) {
+ echo 'Now receiving piped data';
+
+ // explicitly close target if source emits an error
+ $source->on('error', function () use ($stream) {
+ $stream->close();
+ });
+});
+
+$source->pipe($stream);
+```
+
+This event MUST be emitted once for each readable stream that is
+successfully piped into this destination stream.
+In other words, this event MAY be emitted any number of times, which may
+be zero times if no stream is ever piped into this stream.
+This event MUST NOT be emitted if either the source is not readable
+(closed already) or this destination is not writable (closed already).
+
+This event is mostly used internally, see also `pipe()` for more details.
+
+#### error event
+
+The `error` event will be emitted once a fatal error occurs, usually while
+trying to write to this stream.
+The event receives a single `Exception` argument for the error instance.
+
+```php
+$stream->on('error', function (Exception $e) {
+ echo 'Error: ' . $e->getMessage() . PHP_EOL;
+});
+```
+
+This event SHOULD be emitted once the stream detects a fatal error, such
+as a fatal transmission error.
+It SHOULD NOT be emitted after a previous `error` or `close` event.
+It MUST NOT be emitted if this is not a fatal error condition, such as
+a temporary network issue that did not cause any data to be lost.
+
+After the stream errors, it MUST close the stream and SHOULD thus be
+followed by a `close` event and then switch to non-writable mode, see
+also `close()` and `isWritable()`.
+
+Many common streams (such as a TCP/IP connection or a file-based stream)
+only deal with data transmission and may choose
+to only emit this for a fatal transmission error once and will then
+close (terminate) the stream in response.
+
+If this stream is a `DuplexStreamInterface`, you should also notice
+how the readable side of the stream also implements an `error` event.
+In other words, an error may occur while either reading or writing the
+stream which should result in the same error processing.
+
+#### close event
+
+The `close` event will be emitted once the stream closes (terminates).
+
+```php
+$stream->on('close', function () {
+ echo 'CLOSED';
+});
+```
+
+This event SHOULD be emitted once or never at all, depending on whether
+the stream ever terminates.
+It SHOULD NOT be emitted after a previous `close` event.
+
+After the stream is closed, it MUST switch to non-writable mode,
+see also `isWritable()`.
+
+This event SHOULD be emitted whenever the stream closes, irrespective of
+whether this happens implicitly due to an unrecoverable error or
+explicitly when either side closes the stream.
+
+Many common streams (such as a TCP/IP connection or a file-based stream)
+will likely choose to emit this event after flushing the buffer from
+the `end()` method, after receiving a *successful* `end` event or after
+a fatal transmission `error` event.
+
+If this stream is a `DuplexStreamInterface`, you should also notice
+how the readable side of the stream also implements a `close` event.
+In other words, after receiving this event, the stream MUST switch into
+non-writable AND non-readable mode, see also `isReadable()`.
+Note that this event should not be confused with the `end` event.
+
+#### isWritable()
+
+The `isWritable(): bool` method can be used to
+check whether this stream is in a writable state (not closed already).
+
+This method can be used to check if the stream still accepts writing
+any data or if it is ended or closed already.
+Writing any data to a non-writable stream is a NO-OP:
+
+```php
+assert($stream->isWritable() === false);
+
+$stream->write('end'); // NO-OP
+$stream->end('end'); // NO-OP
+```
+
+A successfully opened stream always MUST start in writable mode.
+
+Once the stream ends or closes, it MUST switch to non-writable mode.
+This can happen any time, explicitly through `end()` or `close()` or
+implicitly due to a remote close or an unrecoverable transmission error.
+Once a stream has switched to non-writable mode, it MUST NOT transition
+back to writable mode.
+
+If this stream is a `DuplexStreamInterface`, you should also notice
+how the readable side of the stream also implements an `isReadable()`
+method. Unless this is a half-open duplex stream, they SHOULD usually
+have the same return value.
+
+#### write()
+
+The `write(mixed $data): bool` method can be used to
+write some data into the stream.
+
+A successful write MUST be confirmed with a boolean `true`, which means
+that either the data was written (flushed) immediately or is buffered and
+scheduled for a future write. Note that this interface gives you no
+control over explicitly flushing the buffered data, as finding the
+appropriate time for this is beyond the scope of this interface and left
+up to the implementation of this interface.
+
+Many common streams (such as a TCP/IP connection or file-based stream)
+may choose to buffer all given data and schedule a future flush by using
+an underlying EventLoop to check when the resource is actually writable.
+
+If a stream cannot handle writing (or flushing) the data, it SHOULD emit
+an `error` event and MAY `close()` the stream if it can not recover from
+this error.
+
+If the internal buffer is full after adding `$data`, then `write()`
+SHOULD return `false`, indicating that the caller should stop sending
+data until the buffer drains.
+The stream SHOULD send a `drain` event once the buffer is ready to accept
+more data.
+
+Similarly, if the the stream is not writable (already in a closed state)
+it MUST NOT process the given `$data` and SHOULD return `false`,
+indicating that the caller should stop sending data.
+
+The given `$data` argument MAY be of mixed type, but it's usually
+recommended it SHOULD be a `string` value or MAY use a type that allows
+representation as a `string` for maximum compatibility.
+
+Many common streams (such as a TCP/IP connection or a file-based stream)
+will only accept the raw (binary) payload data that is transferred over
+the wire as chunks of `string` values.
+
+Due to the stream-based nature of this, the sender may send any number
+of chunks with varying sizes. There are no guarantees that these chunks
+will be received with the exact same framing the sender intended to send.
+In other words, many lower-level protocols (such as TCP/IP) transfer the
+data in chunks that may be anywhere between single-byte values to several
+dozens of kilobytes. You may want to apply a higher-level protocol to
+these low-level data chunks in order to achieve proper message framing.
+
+#### end()
+
+The `end(mixed $data = null): void` method can be used to
+successfully end the stream (after optionally sending some final data).
+
+This method can be used to successfully end the stream, i.e. close
+the stream after sending out all data that is currently buffered.
+
+```php
+$stream->write('hello');
+$stream->write('world');
+$stream->end();
+```
+
+If there's no data currently buffered and nothing to be flushed, then
+this method MAY `close()` the stream immediately.
+
+If there's still data in the buffer that needs to be flushed first, then
+this method SHOULD try to write out this data and only then `close()`
+the stream.
+Once the stream is closed, it SHOULD emit a `close` event.
+
+Note that this interface gives you no control over explicitly flushing
+the buffered data, as finding the appropriate time for this is beyond the
+scope of this interface and left up to the implementation of this
+interface.
+
+Many common streams (such as a TCP/IP connection or file-based stream)
+may choose to buffer all given data and schedule a future flush by using
+an underlying EventLoop to check when the resource is actually writable.
+
+You can optionally pass some final data that is written to the stream
+before ending the stream. If a non-`null` value is given as `$data`, then
+this method will behave just like calling `write($data)` before ending
+with no data.
+
+```php
+// shorter version
+$stream->end('bye');
+
+// same as longer version
+$stream->write('bye');
+$stream->end();
+```
+
+After calling this method, the stream MUST switch into a non-writable
+mode, see also `isWritable()`.
+This means that no further writes are possible, so any additional
+`write()` or `end()` calls have no effect.
+
+```php
+$stream->end();
+assert($stream->isWritable() === false);
+
+$stream->write('nope'); // NO-OP
+$stream->end(); // NO-OP
+```
+
+If this stream is a `DuplexStreamInterface`, calling this method SHOULD
+also end its readable side, unless the stream supports half-open mode.
+In other words, after calling this method, these streams SHOULD switch
+into non-writable AND non-readable mode, see also `isReadable()`.
+This implies that in this case, the stream SHOULD NOT emit any `data`
+or `end` events anymore.
+Streams MAY choose to use the `pause()` method logic for this, but
+special care may have to be taken to ensure a following call to the
+`resume()` method SHOULD NOT continue emitting readable events.
+
+Note that this method should not be confused with the `close()` method.
+
+#### close()
+
+The `close(): void` method can be used to
+close the stream (forcefully).
+
+This method can be used to forcefully close the stream, i.e. close
+the stream without waiting for any buffered data to be flushed.
+If there's still data in the buffer, this data SHOULD be discarded.
+
+```php
+$stream->close();
+```
+
+Once the stream is closed, it SHOULD emit a `close` event.
+Note that this event SHOULD NOT be emitted more than once, in particular
+if this method is called multiple times.
+
+After calling this method, the stream MUST switch into a non-writable
+mode, see also `isWritable()`.
+This means that no further writes are possible, so any additional
+`write()` or `end()` calls have no effect.
+
+```php
+$stream->close();
+assert($stream->isWritable() === false);
+
+$stream->write('nope'); // NO-OP
+$stream->end(); // NO-OP
+```
+
+Note that this method should not be confused with the `end()` method.
+Unlike the `end()` method, this method does not take care of any existing
+buffers and simply discards any buffer contents.
+Likewise, this method may also be called after calling `end()` on a
+stream in order to stop waiting for the stream to flush its final data.
+
+```php
+$stream->end();
+$loop->addTimer(1.0, function () use ($stream) {
+ $stream->close();
+});
+```
+
+If this stream is a `DuplexStreamInterface`, you should also notice
+how the readable side of the stream also implements a `close()` method.
+In other words, after calling this method, the stream MUST switch into
+non-writable AND non-readable mode, see also `isReadable()`.
+
+### DuplexStreamInterface
+
+The `DuplexStreamInterface` is responsible for providing an interface for
+duplex streams (both readable and writable).
+
+It builds on top of the existing interfaces for readable and writable streams
+and follows the exact same method and event semantics.
+If you're new to this concept, you should look into the
+`ReadableStreamInterface` and `WritableStreamInterface` first.
+
+Besides defining a few methods, this interface also implements the
+`EventEmitterInterface` which allows you to react to the same events defined
+on the `ReadbleStreamInterface` and `WritableStreamInterface`.
+
+The event callback functions MUST be a valid `callable` that obeys strict
+parameter definitions and MUST accept event parameters exactly as documented.
+The event callback functions MUST NOT throw an `Exception`.
+The return value of the event callback functions will be ignored and has no
+effect, so for performance reasons you're recommended to not return any
+excessive data structures.
+
+Every implementation of this interface MUST follow these event semantics in
+order to be considered a well-behaving stream.
+
+> Note that higher-level implementations of this interface may choose to
+ define additional events with dedicated semantics not defined as part of
+ this low-level stream specification. Conformance with these event semantics
+ is out of scope for this interface, so you may also have to refer to the
+ documentation of such a higher-level implementation.
+
+See also [`ReadableStreamInterface`](#readablestreaminterface) and
+[`WritableStreamInterface`](#writablestreaminterface) for more details.
+
+## Creating streams
+
+ReactPHP uses the concept of "streams" throughout its ecosystem, so that
+many higher-level consumers of this package only deal with
+[stream usage](#stream-usage).
+This implies that stream instances are most often created within some
+higher-level components and many consumers never actually have to deal with
+creating a stream instance.
+
+* Use [react/socket](https://github.com/reactphp/socket)
+ if you want to accept incoming or establish outgoing plaintext TCP/IP or
+ secure TLS socket connection streams.
+* Use [react/http](https://github.com/reactphp/http)
+ if you want to receive an incoming HTTP request body streams.
+* Use [react/child-process](https://github.com/reactphp/child-process)
+ if you want to communicate with child processes via process pipes such as
+ STDIN, STDOUT, STDERR etc.
+* Use experimental [react/filesystem](https://github.com/reactphp/filesystem)
+ if you want to read from / write to the filesystem.
+* See also the last chapter for [more real-world applications](#more).
+
+However, if you are writing a lower-level component or want to create a stream
+instance from a stream resource, then the following chapter is for you.
+
+> Note that the following examples use `fopen()` and `stream_socket_client()`
+ for illustration purposes only.
+ These functions SHOULD NOT be used in a truly async program because each call
+ may take several seconds to complete and would block the EventLoop otherwise.
+ Additionally, the `fopen()` call will return a file handle on some platforms
+ which may or may not be supported by all EventLoop implementations.
+ As an alternative, you may want to use higher-level libraries listed above.
+
+### ReadableResourceStream
+
+The `ReadableResourceStream` is a concrete implementation of the
+[`ReadableStreamInterface`](#readablestreaminterface) for PHP's stream resources.
+
+This can be used to represent a read-only resource like a file stream opened in
+readable mode or a stream such as `STDIN`:
+
+```php
+$stream = new ReadableResourceStream(STDIN, $loop);
+$stream->on('data', function ($chunk) {
+ echo $chunk;
+});
+$stream->on('end', function () {
+ echo 'END';
+});
+```
+
+See also [`ReadableStreamInterface`](#readablestreaminterface) for more details.
+
+The first parameter given to the constructor MUST be a valid stream resource
+that is opened in reading mode (e.g. `fopen()` mode `r`).
+Otherwise, it will throw an `InvalidArgumentException`:
+
+```php
+// throws InvalidArgumentException
+$stream = new ReadableResourceStream(false, $loop);
+```
+
+See also the [`DuplexResourceStream`](#readableresourcestream) for read-and-write
+stream resources otherwise.
+
+Internally, this class tries to enable non-blocking mode on the stream resource
+which may not be supported for all stream resources.
+Most notably, this is not supported by pipes on Windows (STDIN etc.).
+If this fails, it will throw a `RuntimeException`:
+
+```php
+// throws RuntimeException on Windows
+$stream = new ReadableResourceStream(STDIN, $loop);
+```
+
+Once the constructor is called with a valid stream resource, this class will
+take care of the underlying stream resource.
+You SHOULD only use its public API and SHOULD NOT interfere with the underlying
+stream resource manually.
+
+This class takes an optional `int|null $readChunkSize` parameter that controls
+the maximum buffer size in bytes to read at once from the stream.
+You can use a `null` value here in order to apply its default value.
+This value SHOULD NOT be changed unless you know what you're doing.
+This can be a positive number which means that up to X bytes will be read
+at once from the underlying stream resource. Note that the actual number
+of bytes read may be lower if the stream resource has less than X bytes
+currently available.
+This can be `-1` which means "read everything available" from the
+underlying stream resource.
+This should read until the stream resource is not readable anymore
+(i.e. underlying buffer drained), note that this does not neccessarily
+mean it reached EOF.
+
+```php
+$stream = new ReadableResourceStream(STDIN, $loop, 8192);
+```
+
+> PHP bug warning: If the PHP process has explicitly been started without a
+ `STDIN` stream, then trying to read from `STDIN` may return data from
+ another stream resource. This does not happen if you start this with an empty
+ stream like `php test.php < /dev/null` instead of `php test.php <&-`.
+ See [#81](https://github.com/reactphp/stream/issues/81) for more details.
+
+### WritableResourceStream
+
+The `WritableResourceStream` is a concrete implementation of the
+[`WritableStreamInterface`](#writablestreaminterface) for PHP's stream resources.
+
+This can be used to represent a write-only resource like a file stream opened in
+writable mode or a stream such as `STDOUT` or `STDERR`:
+
+```php
+$stream = new WritableResourceStream(STDOUT, $loop);
+$stream->write('hello!');
+$stream->end();
+```
+
+See also [`WritableStreamInterface`](#writablestreaminterface) for more details.
+
+The first parameter given to the constructor MUST be a valid stream resource
+that is opened for writing.
+Otherwise, it will throw an `InvalidArgumentException`:
+
+```php
+// throws InvalidArgumentException
+$stream = new WritableResourceStream(false, $loop);
+```
+
+See also the [`DuplexResourceStream`](#readableresourcestream) for read-and-write
+stream resources otherwise.
+
+Internally, this class tries to enable non-blocking mode on the stream resource
+which may not be supported for all stream resources.
+Most notably, this is not supported by pipes on Windows (STDOUT, STDERR etc.).
+If this fails, it will throw a `RuntimeException`:
+
+```php
+// throws RuntimeException on Windows
+$stream = new WritableResourceStream(STDOUT, $loop);
+```
+
+Once the constructor is called with a valid stream resource, this class will
+take care of the underlying stream resource.
+You SHOULD only use its public API and SHOULD NOT interfere with the underlying
+stream resource manually.
+
+Any `write()` calls to this class will not be performed instantly, but will
+be performed asynchronously, once the EventLoop reports the stream resource is
+ready to accept data.
+For this, it uses an in-memory buffer string to collect all outstanding writes.
+This buffer has a soft-limit applied which defines how much data it is willing
+to accept before the caller SHOULD stop sending further data.
+
+This class takes an optional `int|null $writeBufferSoftLimit` parameter that controls
+this maximum buffer size in bytes.
+You can use a `null` value here in order to apply its default value.
+This value SHOULD NOT be changed unless you know what you're doing.
+
+```php
+$stream = new WritableResourceStream(STDOUT, $loop, 8192);
+```
+
+This class takes an optional `int|null $writeChunkSize` parameter that controls
+this maximum buffer size in bytes to write at once to the stream.
+You can use a `null` value here in order to apply its default value.
+This value SHOULD NOT be changed unless you know what you're doing.
+This can be a positive number which means that up to X bytes will be written
+at once to the underlying stream resource. Note that the actual number
+of bytes written may be lower if the stream resource has less than X bytes
+currently available.
+This can be `-1` which means "write everything available" to the
+underlying stream resource.
+
+```php
+$stream = new WritableResourceStream(STDOUT, $loop, null, 8192);
+```
+
+See also [`write()`](#write) for more details.
+
+### DuplexResourceStream
+
+The `DuplexResourceStream` is a concrete implementation of the
+[`DuplexStreamInterface`](#duplexstreaminterface) for PHP's stream resources.
+
+This can be used to represent a read-and-write resource like a file stream opened
+in read and write mode mode or a stream such as a TCP/IP connection:
+
+```php
+$conn = stream_socket_client('tcp://google.com:80');
+$stream = new DuplexResourceStream($conn, $loop);
+$stream->write('hello!');
+$stream->end();
+```
+
+See also [`DuplexStreamInterface`](#duplexstreaminterface) for more details.
+
+The first parameter given to the constructor MUST be a valid stream resource
+that is opened for reading *and* writing.
+Otherwise, it will throw an `InvalidArgumentException`:
+
+```php
+// throws InvalidArgumentException
+$stream = new DuplexResourceStream(false, $loop);
+```
+
+See also the [`ReadableResourceStream`](#readableresourcestream) for read-only
+and the [`WritableResourceStream`](#writableresourcestream) for write-only
+stream resources otherwise.
+
+Internally, this class tries to enable non-blocking mode on the stream resource
+which may not be supported for all stream resources.
+Most notably, this is not supported by pipes on Windows (STDOUT, STDERR etc.).
+If this fails, it will throw a `RuntimeException`:
+
+```php
+// throws RuntimeException on Windows
+$stream = new DuplexResourceStream(STDOUT, $loop);
+```
+
+Once the constructor is called with a valid stream resource, this class will
+take care of the underlying stream resource.
+You SHOULD only use its public API and SHOULD NOT interfere with the underlying
+stream resource manually.
+
+This class takes an optional `int|null $readChunkSize` parameter that controls
+the maximum buffer size in bytes to read at once from the stream.
+You can use a `null` value here in order to apply its default value.
+This value SHOULD NOT be changed unless you know what you're doing.
+This can be a positive number which means that up to X bytes will be read
+at once from the underlying stream resource. Note that the actual number
+of bytes read may be lower if the stream resource has less than X bytes
+currently available.
+This can be `-1` which means "read everything available" from the
+underlying stream resource.
+This should read until the stream resource is not readable anymore
+(i.e. underlying buffer drained), note that this does not neccessarily
+mean it reached EOF.
+
+```php
+$conn = stream_socket_client('tcp://google.com:80');
+$stream = new DuplexResourceStream($conn, $loop, 8192);
+```
+
+Any `write()` calls to this class will not be performed instantly, but will
+be performed asynchronously, once the EventLoop reports the stream resource is
+ready to accept data.
+For this, it uses an in-memory buffer string to collect all outstanding writes.
+This buffer has a soft-limit applied which defines how much data it is willing
+to accept before the caller SHOULD stop sending further data.
+
+This class takes another optional `WritableStreamInterface|null $buffer` parameter
+that controls this write behavior of this stream.
+You can use a `null` value here in order to apply its default value.
+This value SHOULD NOT be changed unless you know what you're doing.
+
+If you want to change the write buffer soft limit, you can pass an instance of
+[`WritableResourceStream`](#writableresourcestream) like this:
+
+```php
+$conn = stream_socket_client('tcp://google.com:80');
+$buffer = new WritableResourceStream($conn, $loop, 8192);
+$stream = new DuplexResourceStream($conn, $loop, null, $buffer);
+```
+
+See also [`WritableResourceStream`](#writableresourcestream) for more details.
+
+### ThroughStream
+
+The `ThroughStream` implements the
+[`DuplexStreamInterface`](#duplexstreaminterface) and will simply pass any data
+you write to it through to its readable end.
+
+```php
+$through = new ThroughStream();
+$through->on('data', $this->expectCallableOnceWith('hello'));
+
+$through->write('hello');
+```
+
+Similarly, the [`end()` method](#end) will end the stream and emit an
+[`end` event](#end-event) and then [`close()`](#close-1) the stream.
+The [`close()` method](#close-1) will close the stream and emit a
+[`close` event](#close-event).
+Accordingly, this is can also be used in a [`pipe()`](#pipe) context like this:
+
+```php
+$through = new ThroughStream();
+$source->pipe($through)->pipe($dest);
+```
+
+Optionally, its constructor accepts any callable function which will then be
+used to *filter* any data written to it. This function receives a single data
+argument as passed to the writable side and must return the data as it will be
+passed to its readable end:
+
+```php
+$through = new ThroughStream('strtoupper');
+$source->pipe($through)->pipe($dest);
+```
+
+Note that this class makes no assumptions about any data types. This can be
+used to convert data, for example for transforming any structured data into
+a newline-delimited JSON (NDJSON) stream like this:
+
+```php
+$through = new ThroughStream(function ($data) {
+ return json_encode($data) . PHP_EOL;
+});
+$through->on('data', $this->expectCallableOnceWith("[2, true]\n"));
+
+$through->write(array(2, true));
+```
+
+The callback function is allowed to throw an `Exception`. In this case,
+the stream will emit an `error` event and then [`close()`](#close-1) the stream.
+
+```php
+$through = new ThroughStream(function ($data) {
+ if (!is_string($data)) {
+ throw new \UnexpectedValueException('Only strings allowed');
+ }
+ return $data;
+});
+$through->on('error', $this->expectCallableOnce()));
+$through->on('close', $this->expectCallableOnce()));
+$through->on('data', $this->expectCallableNever()));
+
+$through->write(2);
+```
+
+### CompositeStream
+
+The `CompositeStream` implements the
+[`DuplexStreamInterface`](#duplexstreaminterface) and can be used to create a
+single duplex stream from two individual streams implementing
+[`ReadableStreamInterface`](#readablestreaminterface) and
+[`WritableStreamInterface`](#writablestreaminterface) respectively.
+
+This is useful for some APIs which may require a single
+[`DuplexStreamInterface`](#duplexstreaminterface) or simply because it's often
+more convenient to work with a single stream instance like this:
+
+```php
+$stdin = new ReadableResourceStream(STDIN, $loop);
+$stdout = new WritableResourceStream(STDOUT, $loop);
+
+$stdio = new CompositeStream($stdin, $stdout);
+
+$stdio->on('data', function ($chunk) use ($stdio) {
+ $stdio->write('You said: ' . $chunk);
+});
+```
+
+This is a well-behaving stream which forwards all stream events from the
+underlying streams and forwards all streams calls to the underlying streams.
+
+If you `write()` to the duplex stream, it will simply `write()` to the
+writable side and return its status.
+
+If you `end()` the duplex stream, it will `end()` the writable side and will
+`pause()` the readable side.
+
+If you `close()` the duplex stream, both input streams will be closed.
+If either of the two input streams emits a `close` event, the duplex stream
+will also close.
+If either of the two input streams is already closed while constructing the
+duplex stream, it will `close()` the other side and return a closed stream.
+
+## Usage
+
+The following example can be used to pipe the contents of a source file into
+a destination file without having to ever read the whole file into memory:
+
+```php
+$loop = new React\EventLoop\StreamSelectLoop;
+
+$source = new React\Stream\ReadableResourceStream(fopen('source.txt', 'r'), $loop);
+$dest = new React\Stream\WritableResourceStream(fopen('destination.txt', 'w'), $loop);
+
+$source->pipe($dest);
+
+$loop->run();
+```
+
+> Note that this example uses `fopen()` for illustration purposes only.
+ This should not be used in a truly async program because the filesystem is
+ inherently blocking and each call could potentially take several seconds.
+ See also [creating streams](#creating-streams) for more sophisticated
+ examples.
+
+## Install
+
+The recommended way to install this library is [through Composer](https://getcomposer.org).
+[New to Composer?](https://getcomposer.org/doc/00-intro.md)
+
+This will install the latest supported version:
+
+```bash
+$ composer require react/stream:^0.7.7
+```
+
+See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades.
+
+This project aims to run on any platform and thus does not require any PHP
+extensions and supports running on legacy PHP 5.3 through current PHP 7+ and HHVM.
+It's *highly recommended to use PHP 7+* for this project due to its vast
+performance improvements.
+
+## Tests
+
+To run the test suite, you first need to clone this repo and then install all
+dependencies [through Composer](https://getcomposer.org):
+
+```bash
+$ composer install
+```
+
+To run the test suite, go to the project root and run:
+
+```bash
+$ php vendor/bin/phpunit
+```
+
+The test suite also contains a number of functional integration tests that rely
+on a stable internet connection.
+If you do not want to run these, they can simply be skipped like this:
+
+```bash
+$ php vendor/bin/phpunit --exclude-group internet
+```
+
+## License
+
+MIT, see [LICENSE file](LICENSE).
+
+## More
+
+* See [creating streams](#creating-streams) for more information on how streams
+ are created in real-world applications.
+* See our [users wiki](https://github.com/reactphp/react/wiki/Users) and the
+ [dependents on Packagist](https://packagist.org/packages/react/stream/dependents)
+ for a list of packages that use streams in real-world applications.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/composer.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/composer.json
new file mode 100644
index 0000000..f6faa66
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/composer.json
@@ -0,0 +1,25 @@
+{
+ "name": "react/stream",
+ "description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP",
+ "keywords": ["event-driven", "readable", "writable", "stream", "non-blocking", "io", "pipe", "ReactPHP"],
+ "license": "MIT",
+ "require": {
+ "php": ">=5.3.8",
+ "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5",
+ "evenement/evenement": "^3.0 || ^2.0 || ^1.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35",
+ "clue/stream-filter": "~1.2"
+ },
+ "autoload": {
+ "psr-4": {
+ "React\\Stream\\": "src"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "React\\Tests\\Stream\\": "tests"
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/examples/01-http.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/examples/01-http.php
new file mode 100644
index 0000000..3687f7c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/examples/01-http.php
@@ -0,0 +1,40 @@
+<?php
+
+// Simple plaintext HTTP client example (for illustration purposes only).
+// This shows how a plaintext TCP/IP connection is established to then send an
+// application level protocol message (HTTP).
+// Real applications should use react/http-client instead!
+//
+// This simple example only accepts an optional host parameter to send the
+// request to.
+//
+// $ php examples/01-http.php
+// $ php examples/01-http.php reactphp.org
+
+use React\EventLoop\Factory;
+use React\Stream\DuplexResourceStream;
+
+require __DIR__ . '/../vendor/autoload.php';
+
+$host = isset($argv[1]) ? $argv[1] : 'www.google.com';
+
+// connect to tcp://www.google.com:80 (blocking call!)
+// for illustration purposes only, should use react/http-client or react/socket instead!
+$resource = stream_socket_client('tcp://' . $host . ':80');
+if (!$resource) {
+ exit(1);
+}
+
+$loop = Factory::create();
+$stream = new DuplexResourceStream($resource, $loop);
+
+$stream->on('data', function ($chunk) {
+ echo $chunk;
+});
+$stream->on('close', function () {
+ echo '[CLOSED]' . PHP_EOL;
+});
+
+$stream->write("GET / HTTP/1.0\r\nHost: $host\r\n\r\n");
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/examples/02-https.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/examples/02-https.php
new file mode 100644
index 0000000..163f7c8
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/examples/02-https.php
@@ -0,0 +1,40 @@
+<?php
+
+// Simple secure HTTPS client example (for illustration purposes only).
+// This shows how a secure TLS connection is established to then send an
+// application level protocol message (HTTP).
+// Real applications should use react/http-client instead!
+//
+// This simple example only accepts an optional host parameter to send the
+// request to.
+//
+// $ php examples/02-https.php
+// $ php examples/02-https.php reactphp.org
+
+use React\EventLoop\Factory;
+use React\Stream\DuplexResourceStream;
+
+require __DIR__ . '/../vendor/autoload.php';
+
+$host = isset($argv[1]) ? $argv[1] : 'www.google.com';
+
+// connect to tls://www.google.com:443 (blocking call!)
+// for illustration purposes only, should use react/http-client or react/socket instead!
+$resource = stream_socket_client('tls://' . $host . ':443');
+if (!$resource) {
+ exit(1);
+}
+
+$loop = Factory::create();
+$stream = new DuplexResourceStream($resource, $loop);
+
+$stream->on('data', function ($chunk) {
+ echo $chunk;
+});
+$stream->on('close', function () {
+ echo '[CLOSED]' . PHP_EOL;
+});
+
+$stream->write("GET / HTTP/1.0\r\nHost: $host\r\n\r\n");
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/examples/11-cat.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/examples/11-cat.php
new file mode 100644
index 0000000..90fadc0
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/examples/11-cat.php
@@ -0,0 +1,28 @@
+<?php
+
+// Simple example piping everything from STDIN to STDOUT.
+// This allows you to output everything you type on your keyboard or to redirect
+// the pipes to show contents of files and other streams.
+//
+// $ php examples/11-cat.php
+// $ php examples/11-cat.php < README.md
+// $ echo hello | php examples/11-cat.php
+
+use React\EventLoop\Factory;
+use React\Stream\ReadableResourceStream;
+use React\Stream\WritableResourceStream;
+
+require __DIR__ . '/../vendor/autoload.php';
+
+if (DIRECTORY_SEPARATOR === '\\') {
+ fwrite(STDERR, 'Non-blocking console I/O not supported on Microsoft Windows' . PHP_EOL);
+ exit(1);
+}
+
+$loop = Factory::create();
+
+$stdout = new WritableResourceStream(STDOUT, $loop);
+$stdin = new ReadableResourceStream(STDIN, $loop);
+$stdin->pipe($stdout);
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/examples/91-benchmark-throughput.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/examples/91-benchmark-throughput.php
new file mode 100644
index 0000000..ecf695c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/examples/91-benchmark-throughput.php
@@ -0,0 +1,62 @@
+<?php
+
+// Benchmark to measure throughput performance piping an input stream to an output stream.
+// This allows you to get an idea of how fast stream processing with PHP can be
+// and also to play around with differnt types of input and output streams.
+//
+// This example accepts a number of parameters to control the timeout (-t 1),
+// the input file (-i /dev/zero) and the output file (-o /dev/null).
+//
+// $ php examples/91-benchmark-throughput.php
+// $ php examples/91-benchmark-throughput.php -t 10 -o zero.bin
+// $ php examples/91-benchmark-throughput.php -t 60 -i zero.bin
+
+require __DIR__ . '/../vendor/autoload.php';
+
+if (DIRECTORY_SEPARATOR === '\\') {
+ fwrite(STDERR, 'Non-blocking console I/O not supported on Microsoft Windows' . PHP_EOL);
+ exit(1);
+}
+
+$args = getopt('i:o:t:');
+$if = isset($args['i']) ? $args['i'] : '/dev/zero';
+$of = isset($args['o']) ? $args['o'] : '/dev/null';
+$t = isset($args['t']) ? $args['t'] : 1;
+
+// passing file descriptors requires mapping paths (https://bugs.php.net/bug.php?id=53465)
+$if = str_replace('/dev/fd/', 'php://fd/', $if);
+$of = str_replace('/dev/fd/', 'php://fd/', $of);
+
+$loop = new React\EventLoop\StreamSelectLoop();
+
+// setup information stream
+$info = new React\Stream\WritableResourceStream(STDERR, $loop);
+if (extension_loaded('xdebug')) {
+ $info->write('NOTICE: The "xdebug" extension is loaded, this has a major impact on performance.' . PHP_EOL);
+}
+$info->write('piping from ' . $if . ' to ' . $of . ' (for max ' . $t . ' second(s)) ...'. PHP_EOL);
+
+// setup input and output streams and pipe inbetween
+$fh = fopen($if, 'r');
+$in = new React\Stream\ReadableResourceStream($fh, $loop);
+$out = new React\Stream\WritableResourceStream(fopen($of, 'w'), $loop);
+$in->pipe($out);
+
+// stop input stream in $t seconds
+$start = microtime(true);
+$timeout = $loop->addTimer($t, function () use ($in, &$bytes) {
+ $in->close();
+});
+
+// print stream position once stream closes
+$in->on('close', function () use ($fh, $start, $loop, $timeout, $info) {
+ $t = microtime(true) - $start;
+ $loop->cancelTimer($timeout);
+
+ $bytes = ftell($fh);
+
+ $info->write('read ' . $bytes . ' byte(s) in ' . round($t, 3) . ' second(s) => ' . round($bytes / 1024 / 1024 / $t, 1) . ' MiB/s' . PHP_EOL);
+ $info->write('peak memory usage of ' . round(memory_get_peak_usage(true) / 1024 / 1024, 1) . ' MiB' . PHP_EOL);
+});
+
+$loop->run();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/phpunit.xml.dist b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/phpunit.xml.dist
new file mode 100644
index 0000000..13d3fab
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/phpunit.xml.dist
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit backupGlobals="false"
+ backupStaticAttributes="false"
+ colors="true"
+ convertErrorsToExceptions="true"
+ convertNoticesToExceptions="true"
+ convertWarningsToExceptions="true"
+ processIsolation="false"
+ stopOnFailure="false"
+ syntaxCheck="false"
+ bootstrap="vendor/autoload.php"
+>
+ <testsuites>
+ <testsuite name="React Test Suite">
+ <directory>./tests/</directory>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist>
+ <directory>./src/</directory>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/CompositeStream.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/CompositeStream.php
new file mode 100644
index 0000000..153f2a3
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/CompositeStream.php
@@ -0,0 +1,82 @@
+<?php
+
+namespace React\Stream;
+
+use Evenement\EventEmitter;
+
+final class CompositeStream extends EventEmitter implements DuplexStreamInterface
+{
+ private $readable;
+ private $writable;
+ private $closed = false;
+
+ public function __construct(ReadableStreamInterface $readable, WritableStreamInterface $writable)
+ {
+ $this->readable = $readable;
+ $this->writable = $writable;
+
+ if (!$readable->isReadable() || !$writable->isWritable()) {
+ return $this->close();
+ }
+
+ Util::forwardEvents($this->readable, $this, array('data', 'end', 'error'));
+ Util::forwardEvents($this->writable, $this, array('drain', 'error', 'pipe'));
+
+ $this->readable->on('close', array($this, 'close'));
+ $this->writable->on('close', array($this, 'close'));
+ }
+
+ public function isReadable()
+ {
+ return $this->readable->isReadable();
+ }
+
+ public function pause()
+ {
+ $this->readable->pause();
+ }
+
+ public function resume()
+ {
+ if (!$this->writable->isWritable()) {
+ return;
+ }
+
+ $this->readable->resume();
+ }
+
+ public function pipe(WritableStreamInterface $dest, array $options = array())
+ {
+ return Util::pipe($this, $dest, $options);
+ }
+
+ public function isWritable()
+ {
+ return $this->writable->isWritable();
+ }
+
+ public function write($data)
+ {
+ return $this->writable->write($data);
+ }
+
+ public function end($data = null)
+ {
+ $this->readable->pause();
+ $this->writable->end($data);
+ }
+
+ public function close()
+ {
+ if ($this->closed) {
+ return;
+ }
+
+ $this->closed = true;
+ $this->readable->close();
+ $this->writable->close();
+
+ $this->emit('close');
+ $this->removeAllListeners();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/DuplexResourceStream.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/DuplexResourceStream.php
new file mode 100644
index 0000000..982ebb0
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/DuplexResourceStream.php
@@ -0,0 +1,224 @@
+<?php
+
+namespace React\Stream;
+
+use Evenement\EventEmitter;
+use React\EventLoop\LoopInterface;
+use InvalidArgumentException;
+
+final class DuplexResourceStream extends EventEmitter implements DuplexStreamInterface
+{
+ private $stream;
+ private $loop;
+
+ /**
+ * Controls the maximum buffer size in bytes to read at once from the stream.
+ *
+ * This can be a positive number which means that up to X bytes will be read
+ * at once from the underlying stream resource. Note that the actual number
+ * of bytes read may be lower if the stream resource has less than X bytes
+ * currently available.
+ *
+ * This can be `-1` which means read everything available from the
+ * underlying stream resource.
+ * This should read until the stream resource is not readable anymore
+ * (i.e. underlying buffer drained), note that this does not neccessarily
+ * mean it reached EOF.
+ *
+ * @var int
+ */
+ private $bufferSize;
+ private $buffer;
+
+ private $readable = true;
+ private $writable = true;
+ private $closing = false;
+ private $listening = false;
+
+ public function __construct($stream, LoopInterface $loop, $readChunkSize = null, WritableStreamInterface $buffer = null)
+ {
+ if (!is_resource($stream) || get_resource_type($stream) !== "stream") {
+ throw new InvalidArgumentException('First parameter must be a valid stream resource');
+ }
+
+ // ensure resource is opened for reading and wrting (fopen mode must contain "+")
+ $meta = stream_get_meta_data($stream);
+ if (isset($meta['mode']) && $meta['mode'] !== '' && strpos($meta['mode'], '+') === false) {
+ throw new InvalidArgumentException('Given stream resource is not opened in read and write mode');
+ }
+
+ // this class relies on non-blocking I/O in order to not interrupt the event loop
+ // e.g. pipes on Windows do not support this: https://bugs.php.net/bug.php?id=47918
+ if (stream_set_blocking($stream, 0) !== true) {
+ throw new \RuntimeException('Unable to set stream resource to non-blocking mode');
+ }
+
+ // Use unbuffered read operations on the underlying stream resource.
+ // Reading chunks from the stream may otherwise leave unread bytes in
+ // PHP's stream buffers which some event loop implementations do not
+ // trigger events on (edge triggered).
+ // This does not affect the default event loop implementation (level
+ // triggered), so we can ignore platforms not supporting this (HHVM).
+ // Pipe streams (such as STDIN) do not seem to require this and legacy
+ // PHP versions cause SEGFAULTs on unbuffered pipe streams, so skip this.
+ if (function_exists('stream_set_read_buffer') && !$this->isLegacyPipe($stream)) {
+ stream_set_read_buffer($stream, 0);
+ }
+
+ if ($buffer === null) {
+ $buffer = new WritableResourceStream($stream, $loop);
+ }
+
+ $this->stream = $stream;
+ $this->loop = $loop;
+ $this->bufferSize = ($readChunkSize === null) ? 65536 : (int)$readChunkSize;
+ $this->buffer = $buffer;
+
+ $that = $this;
+
+ $this->buffer->on('error', function ($error) use ($that) {
+ $that->emit('error', array($error));
+ });
+
+ $this->buffer->on('close', array($this, 'close'));
+
+ $this->buffer->on('drain', function () use ($that) {
+ $that->emit('drain');
+ });
+
+ $this->resume();
+ }
+
+ public function isReadable()
+ {
+ return $this->readable;
+ }
+
+ public function isWritable()
+ {
+ return $this->writable;
+ }
+
+ public function pause()
+ {
+ if ($this->listening) {
+ $this->loop->removeReadStream($this->stream);
+ $this->listening = false;
+ }
+ }
+
+ public function resume()
+ {
+ if (!$this->listening && $this->readable) {
+ $this->loop->addReadStream($this->stream, array($this, 'handleData'));
+ $this->listening = true;
+ }
+ }
+
+ public function write($data)
+ {
+ if (!$this->writable) {
+ return false;
+ }
+
+ return $this->buffer->write($data);
+ }
+
+ public function close()
+ {
+ if (!$this->writable && !$this->closing) {
+ return;
+ }
+
+ $this->closing = false;
+
+ $this->readable = false;
+ $this->writable = false;
+
+ $this->emit('close');
+ $this->pause();
+ $this->buffer->close();
+ $this->removeAllListeners();
+
+ if (is_resource($this->stream)) {
+ fclose($this->stream);
+ }
+ }
+
+ public function end($data = null)
+ {
+ if (!$this->writable) {
+ return;
+ }
+
+ $this->closing = true;
+
+ $this->readable = false;
+ $this->writable = false;
+ $this->pause();
+
+ $this->buffer->end($data);
+ }
+
+ public function pipe(WritableStreamInterface $dest, array $options = array())
+ {
+ return Util::pipe($this, $dest, $options);
+ }
+
+ /** @internal */
+ public function handleData($stream)
+ {
+ $error = null;
+ set_error_handler(function ($errno, $errstr, $errfile, $errline) use (&$error) {
+ $error = new \ErrorException(
+ $errstr,
+ 0,
+ $errno,
+ $errfile,
+ $errline
+ );
+ });
+
+ $data = stream_get_contents($stream, $this->bufferSize);
+
+ restore_error_handler();
+
+ if ($error !== null) {
+ $this->emit('error', array(new \RuntimeException('Unable to read from stream: ' . $error->getMessage(), 0, $error)));
+ $this->close();
+ return;
+ }
+
+ if ($data !== '') {
+ $this->emit('data', array($data));
+ } else{
+ // no data read => we reached the end and close the stream
+ $this->emit('end');
+ $this->close();
+ }
+ }
+
+ /**
+ * Returns whether this is a pipe resource in a legacy environment
+ *
+ * This works around a legacy PHP bug (#61019) that was fixed in PHP 5.4.28+
+ * and PHP 5.5.12+ and newer.
+ *
+ * @param resource $resource
+ * @return bool
+ * @link https://github.com/reactphp/child-process/issues/40
+ *
+ * @codeCoverageIgnore
+ */
+ private function isLegacyPipe($resource)
+ {
+ if (PHP_VERSION_ID < 50428 || (PHP_VERSION_ID >= 50500 && PHP_VERSION_ID < 50512)) {
+ $meta = stream_get_meta_data($resource);
+
+ if (isset($meta['stream_type']) && $meta['stream_type'] === 'STDIO') {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/DuplexStreamInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/DuplexStreamInterface.php
new file mode 100644
index 0000000..631ce31
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/DuplexStreamInterface.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace React\Stream;
+
+/**
+ * The `DuplexStreamInterface` is responsible for providing an interface for
+ * duplex streams (both readable and writable).
+ *
+ * It builds on top of the existing interfaces for readable and writable streams
+ * and follows the exact same method and event semantics.
+ * If you're new to this concept, you should look into the
+ * `ReadableStreamInterface` and `WritableStreamInterface` first.
+ *
+ * Besides defining a few methods, this interface also implements the
+ * `EventEmitterInterface` which allows you to react to the same events defined
+ * on the `ReadbleStreamInterface` and `WritableStreamInterface`.
+ *
+ * The event callback functions MUST be a valid `callable` that obeys strict
+ * parameter definitions and MUST accept event parameters exactly as documented.
+ * The event callback functions MUST NOT throw an `Exception`.
+ * The return value of the event callback functions will be ignored and has no
+ * effect, so for performance reasons you're recommended to not return any
+ * excessive data structures.
+ *
+ * Every implementation of this interface MUST follow these event semantics in
+ * order to be considered a well-behaving stream.
+ *
+ * > Note that higher-level implementations of this interface may choose to
+ * define additional events with dedicated semantics not defined as part of
+ * this low-level stream specification. Conformance with these event semantics
+ * is out of scope for this interface, so you may also have to refer to the
+ * documentation of such a higher-level implementation.
+ *
+ * @see ReadableStreamInterface
+ * @see WritableStreamInterface
+ */
+interface DuplexStreamInterface extends ReadableStreamInterface, WritableStreamInterface
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/ReadableResourceStream.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/ReadableResourceStream.php
new file mode 100644
index 0000000..015a96b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/ReadableResourceStream.php
@@ -0,0 +1,177 @@
+<?php
+
+namespace React\Stream;
+
+use Evenement\EventEmitter;
+use React\EventLoop\LoopInterface;
+use InvalidArgumentException;
+
+final class ReadableResourceStream extends EventEmitter implements ReadableStreamInterface
+{
+ /**
+ * @var resource
+ */
+ private $stream;
+
+ private $loop;
+
+ /**
+ * Controls the maximum buffer size in bytes to read at once from the stream.
+ *
+ * This value SHOULD NOT be changed unless you know what you're doing.
+ *
+ * This can be a positive number which means that up to X bytes will be read
+ * at once from the underlying stream resource. Note that the actual number
+ * of bytes read may be lower if the stream resource has less than X bytes
+ * currently available.
+ *
+ * This can be `-1` which means read everything available from the
+ * underlying stream resource.
+ * This should read until the stream resource is not readable anymore
+ * (i.e. underlying buffer drained), note that this does not neccessarily
+ * mean it reached EOF.
+ *
+ * @var int
+ */
+ private $bufferSize;
+
+ private $closed = false;
+ private $listening = false;
+
+ public function __construct($stream, LoopInterface $loop, $readChunkSize = null)
+ {
+ if (!is_resource($stream) || get_resource_type($stream) !== "stream") {
+ throw new InvalidArgumentException('First parameter must be a valid stream resource');
+ }
+
+ // ensure resource is opened for reading (fopen mode must contain "r" or "+")
+ $meta = stream_get_meta_data($stream);
+ if (isset($meta['mode']) && $meta['mode'] !== '' && strpos($meta['mode'], 'r') === strpos($meta['mode'], '+')) {
+ throw new InvalidArgumentException('Given stream resource is not opened in read mode');
+ }
+
+ // this class relies on non-blocking I/O in order to not interrupt the event loop
+ // e.g. pipes on Windows do not support this: https://bugs.php.net/bug.php?id=47918
+ if (stream_set_blocking($stream, 0) !== true) {
+ throw new \RuntimeException('Unable to set stream resource to non-blocking mode');
+ }
+
+ // Use unbuffered read operations on the underlying stream resource.
+ // Reading chunks from the stream may otherwise leave unread bytes in
+ // PHP's stream buffers which some event loop implementations do not
+ // trigger events on (edge triggered).
+ // This does not affect the default event loop implementation (level
+ // triggered), so we can ignore platforms not supporting this (HHVM).
+ // Pipe streams (such as STDIN) do not seem to require this and legacy
+ // PHP versions cause SEGFAULTs on unbuffered pipe streams, so skip this.
+ if (function_exists('stream_set_read_buffer') && !$this->isLegacyPipe($stream)) {
+ stream_set_read_buffer($stream, 0);
+ }
+
+ $this->stream = $stream;
+ $this->loop = $loop;
+ $this->bufferSize = ($readChunkSize === null) ? 65536 : (int)$readChunkSize;
+
+ $this->resume();
+ }
+
+ public function isReadable()
+ {
+ return !$this->closed;
+ }
+
+ public function pause()
+ {
+ if ($this->listening) {
+ $this->loop->removeReadStream($this->stream);
+ $this->listening = false;
+ }
+ }
+
+ public function resume()
+ {
+ if (!$this->listening && !$this->closed) {
+ $this->loop->addReadStream($this->stream, array($this, 'handleData'));
+ $this->listening = true;
+ }
+ }
+
+ public function pipe(WritableStreamInterface $dest, array $options = array())
+ {
+ return Util::pipe($this, $dest, $options);
+ }
+
+ public function close()
+ {
+ if ($this->closed) {
+ return;
+ }
+
+ $this->closed = true;
+
+ $this->emit('close');
+ $this->pause();
+ $this->removeAllListeners();
+
+ if (is_resource($this->stream)) {
+ fclose($this->stream);
+ }
+ }
+
+ /** @internal */
+ public function handleData()
+ {
+ $error = null;
+ set_error_handler(function ($errno, $errstr, $errfile, $errline) use (&$error) {
+ $error = new \ErrorException(
+ $errstr,
+ 0,
+ $errno,
+ $errfile,
+ $errline
+ );
+ });
+
+ $data = stream_get_contents($this->stream, $this->bufferSize);
+
+ restore_error_handler();
+
+ if ($error !== null) {
+ $this->emit('error', array(new \RuntimeException('Unable to read from stream: ' . $error->getMessage(), 0, $error)));
+ $this->close();
+ return;
+ }
+
+ if ($data !== '') {
+ $this->emit('data', array($data));
+ } else{
+ // no data read => we reached the end and close the stream
+ $this->emit('end');
+ $this->close();
+ }
+ }
+
+ /**
+ * Returns whether this is a pipe resource in a legacy environment
+ *
+ * This works around a legacy PHP bug (#61019) that was fixed in PHP 5.4.28+
+ * and PHP 5.5.12+ and newer.
+ *
+ * @param resource $resource
+ * @return bool
+ * @link https://github.com/reactphp/child-process/issues/40
+ *
+ * @codeCoverageIgnore
+ */
+ private function isLegacyPipe($resource)
+ {
+ if (PHP_VERSION_ID < 50428 || (PHP_VERSION_ID >= 50500 && PHP_VERSION_ID < 50512)) {
+ $meta = stream_get_meta_data($resource);
+
+ if (isset($meta['stream_type']) && $meta['stream_type'] === 'STDIO') {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/ReadableStreamInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/ReadableStreamInterface.php
new file mode 100644
index 0000000..2b4c3d0
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/ReadableStreamInterface.php
@@ -0,0 +1,362 @@
+<?php
+
+namespace React\Stream;
+
+use Evenement\EventEmitterInterface;
+
+/**
+ * The `ReadableStreamInterface` is responsible for providing an interface for
+ * read-only streams and the readable side of duplex streams.
+ *
+ * Besides defining a few methods, this interface also implements the
+ * `EventEmitterInterface` which allows you to react to certain events:
+ *
+ * data event:
+ * The `data` event will be emitted whenever some data was read/received
+ * from this source stream.
+ * The event receives a single mixed argument for incoming data.
+ *
+ * ```php
+ * $stream->on('data', function ($data) {
+ * echo $data;
+ * });
+ * ```
+ *
+ * This event MAY be emitted any number of times, which may be zero times if
+ * this stream does not send any data at all.
+ * It SHOULD not be emitted after an `end` or `close` event.
+ *
+ * The given `$data` argument may be of mixed type, but it's usually
+ * recommended it SHOULD be a `string` value or MAY use a type that allows
+ * representation as a `string` for maximum compatibility.
+ *
+ * Many common streams (such as a TCP/IP connection or a file-based stream)
+ * will emit the raw (binary) payload data that is received over the wire as
+ * chunks of `string` values.
+ *
+ * Due to the stream-based nature of this, the sender may send any number
+ * of chunks with varying sizes. There are no guarantees that these chunks
+ * will be received with the exact same framing the sender intended to send.
+ * In other words, many lower-level protocols (such as TCP/IP) transfer the
+ * data in chunks that may be anywhere between single-byte values to several
+ * dozens of kilobytes. You may want to apply a higher-level protocol to
+ * these low-level data chunks in order to achieve proper message framing.
+ *
+ * end event:
+ * The `end` event will be emitted once the source stream has successfully
+ * reached the end of the stream (EOF).
+ *
+ * ```php
+ * $stream->on('end', function () {
+ * echo 'END';
+ * });
+ * ```
+ *
+ * This event SHOULD be emitted once or never at all, depending on whether
+ * a successful end was detected.
+ * It SHOULD NOT be emitted after a previous `end` or `close` event.
+ * It MUST NOT be emitted if the stream closes due to a non-successful
+ * end, such as after a previous `error` event.
+ *
+ * After the stream is ended, it MUST switch to non-readable mode,
+ * see also `isReadable()`.
+ *
+ * This event will only be emitted if the *end* was reached successfully,
+ * not if the stream was interrupted by an unrecoverable error or explicitly
+ * closed. Not all streams know this concept of a "successful end".
+ * Many use-cases involve detecting when the stream closes (terminates)
+ * instead, in this case you should use the `close` event.
+ * After the stream emits an `end` event, it SHOULD usually be followed by a
+ * `close` event.
+ *
+ * Many common streams (such as a TCP/IP connection or a file-based stream)
+ * will emit this event if either the remote side closes the connection or
+ * a file handle was successfully read until reaching its end (EOF).
+ *
+ * Note that this event should not be confused with the `end()` method.
+ * This event defines a successful end *reading* from a source stream, while
+ * the `end()` method defines *writing* a successful end to a destination
+ * stream.
+ *
+ * error event:
+ * The `error` event will be emitted once a fatal error occurs, usually while
+ * trying to read from this stream.
+ * The event receives a single `Exception` argument for the error instance.
+ *
+ * ```php
+ * $stream->on('error', function (Exception $e) {
+ * echo 'Error: ' . $e->getMessage() . PHP_EOL;
+ * });
+ * ```
+ *
+ * This event SHOULD be emitted once the stream detects a fatal error, such
+ * as a fatal transmission error or after an unexpected `data` or premature
+ * `end` event.
+ * It SHOULD NOT be emitted after a previous `error`, `end` or `close` event.
+ * It MUST NOT be emitted if this is not a fatal error condition, such as
+ * a temporary network issue that did not cause any data to be lost.
+ *
+ * After the stream errors, it MUST close the stream and SHOULD thus be
+ * followed by a `close` event and then switch to non-readable mode, see
+ * also `close()` and `isReadable()`.
+ *
+ * Many common streams (such as a TCP/IP connection or a file-based stream)
+ * only deal with data transmission and do not make assumption about data
+ * boundaries (such as unexpected `data` or premature `end` events).
+ * In other words, many lower-level protocols (such as TCP/IP) may choose
+ * to only emit this for a fatal transmission error once and will then
+ * close (terminate) the stream in response.
+ *
+ * If this stream is a `DuplexStreamInterface`, you should also notice
+ * how the writable side of the stream also implements an `error` event.
+ * In other words, an error may occur while either reading or writing the
+ * stream which should result in the same error processing.
+ *
+ * close event:
+ * The `close` event will be emitted once the stream closes (terminates).
+ *
+ * ```php
+ * $stream->on('close', function () {
+ * echo 'CLOSED';
+ * });
+ * ```
+ *
+ * This event SHOULD be emitted once or never at all, depending on whether
+ * the stream ever terminates.
+ * It SHOULD NOT be emitted after a previous `close` event.
+ *
+ * After the stream is closed, it MUST switch to non-readable mode,
+ * see also `isReadable()`.
+ *
+ * Unlike the `end` event, this event SHOULD be emitted whenever the stream
+ * closes, irrespective of whether this happens implicitly due to an
+ * unrecoverable error or explicitly when either side closes the stream.
+ * If you only want to detect a *successful* end, you should use the `end`
+ * event instead.
+ *
+ * Many common streams (such as a TCP/IP connection or a file-based stream)
+ * will likely choose to emit this event after reading a *successful* `end`
+ * event or after a fatal transmission `error` event.
+ *
+ * If this stream is a `DuplexStreamInterface`, you should also notice
+ * how the writable side of the stream also implements a `close` event.
+ * In other words, after receiving this event, the stream MUST switch into
+ * non-writable AND non-readable mode, see also `isWritable()`.
+ * Note that this event should not be confused with the `end` event.
+ *
+ * The event callback functions MUST be a valid `callable` that obeys strict
+ * parameter definitions and MUST accept event parameters exactly as documented.
+ * The event callback functions MUST NOT throw an `Exception`.
+ * The return value of the event callback functions will be ignored and has no
+ * effect, so for performance reasons you're recommended to not return any
+ * excessive data structures.
+ *
+ * Every implementation of this interface MUST follow these event semantics in
+ * order to be considered a well-behaving stream.
+ *
+ * > Note that higher-level implementations of this interface may choose to
+ * define additional events with dedicated semantics not defined as part of
+ * this low-level stream specification. Conformance with these event semantics
+ * is out of scope for this interface, so you may also have to refer to the
+ * documentation of such a higher-level implementation.
+ *
+ * @see EventEmitterInterface
+ */
+interface ReadableStreamInterface extends EventEmitterInterface
+{
+ /**
+ * Checks whether this stream is in a readable state (not closed already).
+ *
+ * This method can be used to check if the stream still accepts incoming
+ * data events or if it is ended or closed already.
+ * Once the stream is non-readable, no further `data` or `end` events SHOULD
+ * be emitted.
+ *
+ * ```php
+ * assert($stream->isReadable() === false);
+ *
+ * $stream->on('data', assertNeverCalled());
+ * $stream->on('end', assertNeverCalled());
+ * ```
+ *
+ * A successfully opened stream always MUST start in readable mode.
+ *
+ * Once the stream ends or closes, it MUST switch to non-readable mode.
+ * This can happen any time, explicitly through `close()` or
+ * implicitly due to a remote close or an unrecoverable transmission error.
+ * Once a stream has switched to non-readable mode, it MUST NOT transition
+ * back to readable mode.
+ *
+ * If this stream is a `DuplexStreamInterface`, you should also notice
+ * how the writable side of the stream also implements an `isWritable()`
+ * method. Unless this is a half-open duplex stream, they SHOULD usually
+ * have the same return value.
+ *
+ * @return bool
+ */
+ public function isReadable();
+
+ /**
+ * Pauses reading incoming data events.
+ *
+ * Removes the data source file descriptor from the event loop. This
+ * allows you to throttle incoming data.
+ *
+ * Unless otherwise noted, a successfully opened stream SHOULD NOT start
+ * in paused state.
+ *
+ * Once the stream is paused, no futher `data` or `end` events SHOULD
+ * be emitted.
+ *
+ * ```php
+ * $stream->pause();
+ *
+ * $stream->on('data', assertShouldNeverCalled());
+ * $stream->on('end', assertShouldNeverCalled());
+ * ```
+ *
+ * This method is advisory-only, though generally not recommended, the
+ * stream MAY continue emitting `data` events.
+ *
+ * You can continue processing events by calling `resume()` again.
+ *
+ * Note that both methods can be called any number of times, in particular
+ * calling `pause()` more than once SHOULD NOT have any effect.
+ *
+ * @see self::resume()
+ * @return void
+ */
+ public function pause();
+
+ /**
+ * Resumes reading incoming data events.
+ *
+ * Re-attach the data source after a previous `pause()`.
+ *
+ * ```php
+ * $stream->pause();
+ *
+ * $loop->addTimer(1.0, function () use ($stream) {
+ * $stream->resume();
+ * });
+ * ```
+ *
+ * Note that both methods can be called any number of times, in particular
+ * calling `resume()` without a prior `pause()` SHOULD NOT have any effect.
+ *
+ * @see self::pause()
+ * @return void
+ */
+ public function resume();
+
+ /**
+ * Pipes all the data from this readable source into the given writable destination.
+ *
+ * Automatically sends all incoming data to the destination.
+ * Automatically throttles the source based on what the destination can handle.
+ *
+ * ```php
+ * $source->pipe($dest);
+ * ```
+ *
+ * Similarly, you can also pipe an instance implementing `DuplexStreamInterface`
+ * into itself in order to write back all the data that is received.
+ * This may be a useful feature for a TCP/IP echo service:
+ *
+ * ```php
+ * $connection->pipe($connection);
+ * ```
+ *
+ * This method returns the destination stream as-is, which can be used to
+ * set up chains of piped streams:
+ *
+ * ```php
+ * $source->pipe($decodeGzip)->pipe($filterBadWords)->pipe($dest);
+ * ```
+ *
+ * By default, this will call `end()` on the destination stream once the
+ * source stream emits an `end` event. This can be disabled like this:
+ *
+ * ```php
+ * $source->pipe($dest, array('end' => false));
+ * ```
+ *
+ * Note that this only applies to the `end` event.
+ * If an `error` or explicit `close` event happens on the source stream,
+ * you'll have to manually close the destination stream:
+ *
+ * ```php
+ * $source->pipe($dest);
+ * $source->on('close', function () use ($dest) {
+ * $dest->end('BYE!');
+ * });
+ * ```
+ *
+ * If the source stream is not readable (closed state), then this is a NO-OP.
+ *
+ * ```php
+ * $source->close();
+ * $source->pipe($dest); // NO-OP
+ * ```
+ *
+ * If the destinantion stream is not writable (closed state), then this will simply
+ * throttle (pause) the source stream:
+ *
+ * ```php
+ * $dest->close();
+ * $source->pipe($dest); // calls $source->pause()
+ * ```
+ *
+ * Similarly, if the destination stream is closed while the pipe is still
+ * active, it will also throttle (pause) the source stream:
+ *
+ * ```php
+ * $source->pipe($dest);
+ * $dest->close(); // calls $source->pause()
+ * ```
+ *
+ * Once the pipe is set up successfully, the destination stream MUST emit
+ * a `pipe` event with this source stream an event argument.
+ *
+ * @param WritableStreamInterface $dest
+ * @param array $options
+ * @return WritableStreamInterface $dest stream as-is
+ */
+ public function pipe(WritableStreamInterface $dest, array $options = array());
+
+ /**
+ * Closes the stream (forcefully).
+ *
+ * This method can be used to (forcefully) close the stream.
+ *
+ * ```php
+ * $stream->close();
+ * ```
+ *
+ * Once the stream is closed, it SHOULD emit a `close` event.
+ * Note that this event SHOULD NOT be emitted more than once, in particular
+ * if this method is called multiple times.
+ *
+ * After calling this method, the stream MUST switch into a non-readable
+ * mode, see also `isReadable()`.
+ * This means that no further `data` or `end` events SHOULD be emitted.
+ *
+ * ```php
+ * $stream->close();
+ * assert($stream->isReadable() === false);
+ *
+ * $stream->on('data', assertNeverCalled());
+ * $stream->on('end', assertNeverCalled());
+ * ```
+ *
+ * If this stream is a `DuplexStreamInterface`, you should also notice
+ * how the writable side of the stream also implements a `close()` method.
+ * In other words, after calling this method, the stream MUST switch into
+ * non-writable AND non-readable mode, see also `isWritable()`.
+ * Note that this method should not be confused with the `end()` method.
+ *
+ * @return void
+ * @see WritableStreamInterface::close()
+ */
+ public function close();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/ThroughStream.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/ThroughStream.php
new file mode 100644
index 0000000..da2fbb0
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/ThroughStream.php
@@ -0,0 +1,190 @@
+<?php
+
+namespace React\Stream;
+
+use Evenement\EventEmitter;
+use InvalidArgumentException;
+
+/**
+ * The `ThroughStream` implements the
+ * [`DuplexStreamInterface`](#duplexstreaminterface) and will simply pass any data
+ * you write to it through to its readable end.
+ *
+ * ```php
+ * $through = new ThroughStream();
+ * $through->on('data', $this->expectCallableOnceWith('hello'));
+ *
+ * $through->write('hello');
+ * ```
+ *
+ * Similarly, the [`end()` method](#end) will end the stream and emit an
+ * [`end` event](#end-event) and then [`close()`](#close-1) the stream.
+ * The [`close()` method](#close-1) will close the stream and emit a
+ * [`close` event](#close-event).
+ * Accordingly, this is can also be used in a [`pipe()`](#pipe) context like this:
+ *
+ * ```php
+ * $through = new ThroughStream();
+ * $source->pipe($through)->pipe($dest);
+ * ```
+ *
+ * Optionally, its constructor accepts any callable function which will then be
+ * used to *filter* any data written to it. This function receives a single data
+ * argument as passed to the writable side and must return the data as it will be
+ * passed to its readable end:
+ *
+ * ```php
+ * $through = new ThroughStream('strtoupper');
+ * $source->pipe($through)->pipe($dest);
+ * ```
+ *
+ * Note that this class makes no assumptions about any data types. This can be
+ * used to convert data, for example for transforming any structured data into
+ * a newline-delimited JSON (NDJSON) stream like this:
+ *
+ * ```php
+ * $through = new ThroughStream(function ($data) {
+ * return json_encode($data) . PHP_EOL;
+ * });
+ * $through->on('data', $this->expectCallableOnceWith("[2, true]\n"));
+ *
+ * $through->write(array(2, true));
+ * ```
+ *
+ * The callback function is allowed to throw an `Exception`. In this case,
+ * the stream will emit an `error` event and then [`close()`](#close-1) the stream.
+ *
+ * ```php
+ * $through = new ThroughStream(function ($data) {
+ * if (!is_string($data)) {
+ * throw new \UnexpectedValueException('Only strings allowed');
+ * }
+ * return $data;
+ * });
+ * $through->on('error', $this->expectCallableOnce()));
+ * $through->on('close', $this->expectCallableOnce()));
+ * $through->on('data', $this->expectCallableNever()));
+ *
+ * $through->write(2);
+ * ```
+ *
+ * @see WritableStreamInterface::write()
+ * @see WritableStreamInterface::end()
+ * @see DuplexStreamInterface::close()
+ * @see WritableStreamInterface::pipe()
+ */
+final class ThroughStream extends EventEmitter implements DuplexStreamInterface
+{
+ private $readable = true;
+ private $writable = true;
+ private $closed = false;
+ private $paused = false;
+ private $drain = false;
+ private $callback;
+
+ public function __construct($callback = null)
+ {
+ if ($callback !== null && !is_callable($callback)) {
+ throw new InvalidArgumentException('Invalid transformation callback given');
+ }
+
+ $this->callback = $callback;
+ }
+
+ public function pause()
+ {
+ $this->paused = true;
+ }
+
+ public function resume()
+ {
+ if ($this->drain) {
+ $this->drain = false;
+ $this->emit('drain');
+ }
+ $this->paused = false;
+ }
+
+ public function pipe(WritableStreamInterface $dest, array $options = array())
+ {
+ return Util::pipe($this, $dest, $options);
+ }
+
+ public function isReadable()
+ {
+ return $this->readable;
+ }
+
+ public function isWritable()
+ {
+ return $this->writable;
+ }
+
+ public function write($data)
+ {
+ if (!$this->writable) {
+ return false;
+ }
+
+ if ($this->callback !== null) {
+ try {
+ $data = call_user_func($this->callback, $data);
+ } catch (\Exception $e) {
+ $this->emit('error', array($e));
+ $this->close();
+
+ return false;
+ }
+ }
+
+ $this->emit('data', array($data));
+
+ if ($this->paused) {
+ $this->drain = true;
+ return false;
+ }
+
+ return true;
+ }
+
+ public function end($data = null)
+ {
+ if (!$this->writable) {
+ return;
+ }
+
+ if (null !== $data) {
+ $this->write($data);
+
+ // return if write() already caused the stream to close
+ if (!$this->writable) {
+ return;
+ }
+ }
+
+ $this->readable = false;
+ $this->writable = false;
+ $this->paused = true;
+ $this->drain = false;
+
+ $this->emit('end');
+ $this->close();
+ }
+
+ public function close()
+ {
+ if ($this->closed) {
+ return;
+ }
+
+ $this->readable = false;
+ $this->writable = false;
+ $this->closed = true;
+ $this->paused = true;
+ $this->drain = false;
+ $this->callback = null;
+
+ $this->emit('close');
+ $this->removeAllListeners();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/Util.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/Util.php
new file mode 100644
index 0000000..14ddcfc
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/Util.php
@@ -0,0 +1,75 @@
+<?php
+
+namespace React\Stream;
+
+final class Util
+{
+ /**
+ * Pipes all the data from the given $source into the $dest
+ *
+ * @param ReadableStreamInterface $source
+ * @param WritableStreamInterface $dest
+ * @param array $options
+ * @return WritableStreamInterface $dest stream as-is
+ * @see ReadableStreamInterface::pipe() for more details
+ */
+ public static function pipe(ReadableStreamInterface $source, WritableStreamInterface $dest, array $options = array())
+ {
+ // source not readable => NO-OP
+ if (!$source->isReadable()) {
+ return $dest;
+ }
+
+ // destination not writable => just pause() source
+ if (!$dest->isWritable()) {
+ $source->pause();
+
+ return $dest;
+ }
+
+ $dest->emit('pipe', array($source));
+
+ // forward all source data events as $dest->write()
+ $source->on('data', $dataer = function ($data) use ($source, $dest) {
+ $feedMore = $dest->write($data);
+
+ if (false === $feedMore) {
+ $source->pause();
+ }
+ });
+ $dest->on('close', function () use ($source, $dataer) {
+ $source->removeListener('data', $dataer);
+ $source->pause();
+ });
+
+ // forward destination drain as $source->resume()
+ $dest->on('drain', $drainer = function () use ($source) {
+ $source->resume();
+ });
+ $source->on('close', function () use ($dest, $drainer) {
+ $dest->removeListener('drain', $drainer);
+ });
+
+ // forward end event from source as $dest->end()
+ $end = isset($options['end']) ? $options['end'] : true;
+ if ($end) {
+ $source->on('end', $ender = function () use ($dest) {
+ $dest->end();
+ });
+ $dest->on('close', function () use ($source, $ender) {
+ $source->removeListener('end', $ender);
+ });
+ }
+
+ return $dest;
+ }
+
+ public static function forwardEvents($source, $target, array $events)
+ {
+ foreach ($events as $event) {
+ $source->on($event, function () use ($event, $target) {
+ $target->emit($event, func_get_args());
+ });
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/WritableResourceStream.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/WritableResourceStream.php
new file mode 100644
index 0000000..7e04205
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/WritableResourceStream.php
@@ -0,0 +1,171 @@
+<?php
+
+namespace React\Stream;
+
+use Evenement\EventEmitter;
+use React\EventLoop\LoopInterface;
+
+final class WritableResourceStream extends EventEmitter implements WritableStreamInterface
+{
+ private $stream;
+ private $loop;
+ private $softLimit;
+ private $writeChunkSize;
+
+ private $listening = false;
+ private $writable = true;
+ private $closed = false;
+ private $data = '';
+
+ public function __construct($stream, LoopInterface $loop, $writeBufferSoftLimit = null, $writeChunkSize = null)
+ {
+ if (!is_resource($stream) || get_resource_type($stream) !== "stream") {
+ throw new \InvalidArgumentException('First parameter must be a valid stream resource');
+ }
+
+ // ensure resource is opened for writing (fopen mode must contain either of "waxc+")
+ $meta = stream_get_meta_data($stream);
+ if (isset($meta['mode']) && $meta['mode'] !== '' && strtr($meta['mode'], 'waxc+', '.....') === $meta['mode']) {
+ throw new \InvalidArgumentException('Given stream resource is not opened in write mode');
+ }
+
+ // this class relies on non-blocking I/O in order to not interrupt the event loop
+ // e.g. pipes on Windows do not support this: https://bugs.php.net/bug.php?id=47918
+ if (stream_set_blocking($stream, 0) !== true) {
+ throw new \RuntimeException('Unable to set stream resource to non-blocking mode');
+ }
+
+ $this->stream = $stream;
+ $this->loop = $loop;
+ $this->softLimit = ($writeBufferSoftLimit === null) ? 65536 : (int)$writeBufferSoftLimit;
+ $this->writeChunkSize = ($writeChunkSize === null) ? -1 : (int)$writeChunkSize;
+ }
+
+ public function isWritable()
+ {
+ return $this->writable;
+ }
+
+ public function write($data)
+ {
+ if (!$this->writable) {
+ return false;
+ }
+
+ $this->data .= $data;
+
+ if (!$this->listening && $this->data !== '') {
+ $this->listening = true;
+
+ $this->loop->addWriteStream($this->stream, array($this, 'handleWrite'));
+ }
+
+ return !isset($this->data[$this->softLimit - 1]);
+ }
+
+ public function end($data = null)
+ {
+ if (null !== $data) {
+ $this->write($data);
+ }
+
+ $this->writable = false;
+
+ // close immediately if buffer is already empty
+ // otherwise wait for buffer to flush first
+ if ($this->data === '') {
+ $this->close();
+ }
+ }
+
+ public function close()
+ {
+ if ($this->closed) {
+ return;
+ }
+
+ if ($this->listening) {
+ $this->listening = false;
+ $this->loop->removeWriteStream($this->stream);
+ }
+
+ $this->closed = true;
+ $this->writable = false;
+ $this->data = '';
+
+ $this->emit('close');
+ $this->removeAllListeners();
+
+ if (is_resource($this->stream)) {
+ fclose($this->stream);
+ }
+ }
+
+ /** @internal */
+ public function handleWrite()
+ {
+ $error = null;
+ set_error_handler(function ($errno, $errstr, $errfile, $errline) use (&$error) {
+ $error = array(
+ 'message' => $errstr,
+ 'number' => $errno,
+ 'file' => $errfile,
+ 'line' => $errline
+ );
+ });
+
+ if ($this->writeChunkSize === -1) {
+ $sent = fwrite($this->stream, $this->data);
+ } else {
+ $sent = fwrite($this->stream, $this->data, $this->writeChunkSize);
+ }
+
+ restore_error_handler();
+
+ // Only report errors if *nothing* could be sent.
+ // Any hard (permanent) error will fail to send any data at all.
+ // Sending excessive amounts of data will only flush *some* data and then
+ // report a temporary error (EAGAIN) which we do not raise here in order
+ // to keep the stream open for further tries to write.
+ // Should this turn out to be a permanent error later, it will eventually
+ // send *nothing* and we can detect this.
+ if ($sent === 0 || $sent === false) {
+ if ($error !== null) {
+ $error = new \ErrorException(
+ $error['message'],
+ 0,
+ $error['number'],
+ $error['file'],
+ $error['line']
+ );
+ }
+
+ $this->emit('error', array(new \RuntimeException('Unable to write to stream: ' . ($error !== null ? $error->getMessage() : 'Unknown error'), 0, $error)));
+ $this->close();
+
+ return;
+ }
+
+ $exceeded = isset($this->data[$this->softLimit - 1]);
+ $this->data = (string) substr($this->data, $sent);
+
+ // buffer has been above limit and is now below limit
+ if ($exceeded && !isset($this->data[$this->softLimit - 1])) {
+ $this->emit('drain');
+ }
+
+ // buffer is now completely empty => stop trying to write
+ if ($this->data === '') {
+ // stop waiting for resource to be writable
+ if ($this->listening) {
+ $this->loop->removeWriteStream($this->stream);
+ $this->listening = false;
+ }
+
+ // buffer is end()ing and now completely empty => close buffer
+ if (!$this->writable) {
+ $this->close();
+ }
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/WritableStreamInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/WritableStreamInterface.php
new file mode 100644
index 0000000..3bc932e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/src/WritableStreamInterface.php
@@ -0,0 +1,347 @@
+<?php
+
+namespace React\Stream;
+
+use Evenement\EventEmitterInterface;
+
+/**
+ * The `WritableStreamInterface` is responsible for providing an interface for
+ * write-only streams and the writable side of duplex streams.
+ *
+ * Besides defining a few methods, this interface also implements the
+ * `EventEmitterInterface` which allows you to react to certain events:
+ *
+ * drain event:
+ * The `drain` event will be emitted whenever the write buffer became full
+ * previously and is now ready to accept more data.
+ *
+ * ```php
+ * $stream->on('drain', function () use ($stream) {
+ * echo 'Stream is now ready to accept more data';
+ * });
+ * ```
+ *
+ * This event SHOULD be emitted once every time the buffer became full
+ * previously and is now ready to accept more data.
+ * In other words, this event MAY be emitted any number of times, which may
+ * be zero times if the buffer never became full in the first place.
+ * This event SHOULD NOT be emitted if the buffer has not become full
+ * previously.
+ *
+ * This event is mostly used internally, see also `write()` for more details.
+ *
+ * pipe event:
+ * The `pipe` event will be emitted whenever a readable stream is `pipe()`d
+ * into this stream.
+ * The event receives a single `ReadableStreamInterface` argument for the
+ * source stream.
+ *
+ * ```php
+ * $stream->on('pipe', function (ReadableStreamInterface $source) use ($stream) {
+ * echo 'Now receiving piped data';
+ *
+ * // explicitly close target if source emits an error
+ * $source->on('error', function () use ($stream) {
+ * $stream->close();
+ * });
+ * });
+ *
+ * $source->pipe($stream);
+ * ```
+ *
+ * This event MUST be emitted once for each readable stream that is
+ * successfully piped into this destination stream.
+ * In other words, this event MAY be emitted any number of times, which may
+ * be zero times if no stream is ever piped into this stream.
+ * This event MUST NOT be emitted if either the source is not readable
+ * (closed already) or this destination is not writable (closed already).
+ *
+ * This event is mostly used internally, see also `pipe()` for more details.
+ *
+ * error event:
+ * The `error` event will be emitted once a fatal error occurs, usually while
+ * trying to write to this stream.
+ * The event receives a single `Exception` argument for the error instance.
+ *
+ * ```php
+ * $stream->on('error', function (Exception $e) {
+ * echo 'Error: ' . $e->getMessage() . PHP_EOL;
+ * });
+ * ```
+ *
+ * This event SHOULD be emitted once the stream detects a fatal error, such
+ * as a fatal transmission error.
+ * It SHOULD NOT be emitted after a previous `error` or `close` event.
+ * It MUST NOT be emitted if this is not a fatal error condition, such as
+ * a temporary network issue that did not cause any data to be lost.
+ *
+ * After the stream errors, it MUST close the stream and SHOULD thus be
+ * followed by a `close` event and then switch to non-writable mode, see
+ * also `close()` and `isWritable()`.
+ *
+ * Many common streams (such as a TCP/IP connection or a file-based stream)
+ * only deal with data transmission and may choose
+ * to only emit this for a fatal transmission error once and will then
+ * close (terminate) the stream in response.
+ *
+ * If this stream is a `DuplexStreamInterface`, you should also notice
+ * how the readable side of the stream also implements an `error` event.
+ * In other words, an error may occur while either reading or writing the
+ * stream which should result in the same error processing.
+ *
+ * close event:
+ * The `close` event will be emitted once the stream closes (terminates).
+ *
+ * ```php
+ * $stream->on('close', function () {
+ * echo 'CLOSED';
+ * });
+ * ```
+ *
+ * This event SHOULD be emitted once or never at all, depending on whether
+ * the stream ever terminates.
+ * It SHOULD NOT be emitted after a previous `close` event.
+ *
+ * After the stream is closed, it MUST switch to non-writable mode,
+ * see also `isWritable()`.
+ *
+ * This event SHOULD be emitted whenever the stream closes, irrespective of
+ * whether this happens implicitly due to an unrecoverable error or
+ * explicitly when either side closes the stream.
+ *
+ * Many common streams (such as a TCP/IP connection or a file-based stream)
+ * will likely choose to emit this event after flushing the buffer from
+ * the `end()` method, after receiving a *successful* `end` event or after
+ * a fatal transmission `error` event.
+ *
+ * If this stream is a `DuplexStreamInterface`, you should also notice
+ * how the readable side of the stream also implements a `close` event.
+ * In other words, after receiving this event, the stream MUST switch into
+ * non-writable AND non-readable mode, see also `isReadable()`.
+ * Note that this event should not be confused with the `end` event.
+ *
+ * The event callback functions MUST be a valid `callable` that obeys strict
+ * parameter definitions and MUST accept event parameters exactly as documented.
+ * The event callback functions MUST NOT throw an `Exception`.
+ * The return value of the event callback functions will be ignored and has no
+ * effect, so for performance reasons you're recommended to not return any
+ * excessive data structures.
+ *
+ * Every implementation of this interface MUST follow these event semantics in
+ * order to be considered a well-behaving stream.
+ *
+ * > Note that higher-level implementations of this interface may choose to
+ * define additional events with dedicated semantics not defined as part of
+ * this low-level stream specification. Conformance with these event semantics
+ * is out of scope for this interface, so you may also have to refer to the
+ * documentation of such a higher-level implementation.
+ *
+ * @see EventEmitterInterface
+ * @see DuplexStreamInterface
+ */
+interface WritableStreamInterface extends EventEmitterInterface
+{
+ /**
+ * Checks whether this stream is in a writable state (not closed already).
+ *
+ * This method can be used to check if the stream still accepts writing
+ * any data or if it is ended or closed already.
+ * Writing any data to a non-writable stream is a NO-OP:
+ *
+ * ```php
+ * assert($stream->isWritable() === false);
+ *
+ * $stream->write('end'); // NO-OP
+ * $stream->end('end'); // NO-OP
+ * ```
+ *
+ * A successfully opened stream always MUST start in writable mode.
+ *
+ * Once the stream ends or closes, it MUST switch to non-writable mode.
+ * This can happen any time, explicitly through `end()` or `close()` or
+ * implicitly due to a remote close or an unrecoverable transmission error.
+ * Once a stream has switched to non-writable mode, it MUST NOT transition
+ * back to writable mode.
+ *
+ * If this stream is a `DuplexStreamInterface`, you should also notice
+ * how the readable side of the stream also implements an `isReadable()`
+ * method. Unless this is a half-open duplex stream, they SHOULD usually
+ * have the same return value.
+ *
+ * @return bool
+ */
+ public function isWritable();
+
+ /**
+ * Write some data into the stream.
+ *
+ * A successful write MUST be confirmed with a boolean `true`, which means
+ * that either the data was written (flushed) immediately or is buffered and
+ * scheduled for a future write. Note that this interface gives you no
+ * control over explicitly flushing the buffered data, as finding the
+ * appropriate time for this is beyond the scope of this interface and left
+ * up to the implementation of this interface.
+ *
+ * Many common streams (such as a TCP/IP connection or file-based stream)
+ * may choose to buffer all given data and schedule a future flush by using
+ * an underlying EventLoop to check when the resource is actually writable.
+ *
+ * If a stream cannot handle writing (or flushing) the data, it SHOULD emit
+ * an `error` event and MAY `close()` the stream if it can not recover from
+ * this error.
+ *
+ * If the internal buffer is full after adding `$data`, then `write()`
+ * SHOULD return `false`, indicating that the caller should stop sending
+ * data until the buffer drains.
+ * The stream SHOULD send a `drain` event once the buffer is ready to accept
+ * more data.
+ *
+ * Similarly, if the the stream is not writable (already in a closed state)
+ * it MUST NOT process the given `$data` and SHOULD return `false`,
+ * indicating that the caller should stop sending data.
+ *
+ * The given `$data` argument MAY be of mixed type, but it's usually
+ * recommended it SHOULD be a `string` value or MAY use a type that allows
+ * representation as a `string` for maximum compatibility.
+ *
+ * Many common streams (such as a TCP/IP connection or a file-based stream)
+ * will only accept the raw (binary) payload data that is transferred over
+ * the wire as chunks of `string` values.
+ *
+ * Due to the stream-based nature of this, the sender may send any number
+ * of chunks with varying sizes. There are no guarantees that these chunks
+ * will be received with the exact same framing the sender intended to send.
+ * In other words, many lower-level protocols (such as TCP/IP) transfer the
+ * data in chunks that may be anywhere between single-byte values to several
+ * dozens of kilobytes. You may want to apply a higher-level protocol to
+ * these low-level data chunks in order to achieve proper message framing.
+ *
+ * @param mixed|string $data
+ * @return bool
+ */
+ public function write($data);
+
+ /**
+ * Successfully ends the stream (after optionally sending some final data).
+ *
+ * This method can be used to successfully end the stream, i.e. close
+ * the stream after sending out all data that is currently buffered.
+ *
+ * ```php
+ * $stream->write('hello');
+ * $stream->write('world');
+ * $stream->end();
+ * ```
+ *
+ * If there's no data currently buffered and nothing to be flushed, then
+ * this method MAY `close()` the stream immediately.
+ *
+ * If there's still data in the buffer that needs to be flushed first, then
+ * this method SHOULD try to write out this data and only then `close()`
+ * the stream.
+ * Once the stream is closed, it SHOULD emit a `close` event.
+ *
+ * Note that this interface gives you no control over explicitly flushing
+ * the buffered data, as finding the appropriate time for this is beyond the
+ * scope of this interface and left up to the implementation of this
+ * interface.
+ *
+ * Many common streams (such as a TCP/IP connection or file-based stream)
+ * may choose to buffer all given data and schedule a future flush by using
+ * an underlying EventLoop to check when the resource is actually writable.
+ *
+ * You can optionally pass some final data that is written to the stream
+ * before ending the stream. If a non-`null` value is given as `$data`, then
+ * this method will behave just like calling `write($data)` before ending
+ * with no data.
+ *
+ * ```php
+ * // shorter version
+ * $stream->end('bye');
+ *
+ * // same as longer version
+ * $stream->write('bye');
+ * $stream->end();
+ * ```
+ *
+ * After calling this method, the stream MUST switch into a non-writable
+ * mode, see also `isWritable()`.
+ * This means that no further writes are possible, so any additional
+ * `write()` or `end()` calls have no effect.
+ *
+ * ```php
+ * $stream->end();
+ * assert($stream->isWritable() === false);
+ *
+ * $stream->write('nope'); // NO-OP
+ * $stream->end(); // NO-OP
+ * ```
+ *
+ * If this stream is a `DuplexStreamInterface`, calling this method SHOULD
+ * also end its readable side, unless the stream supports half-open mode.
+ * In other words, after calling this method, these streams SHOULD switch
+ * into non-writable AND non-readable mode, see also `isReadable()`.
+ * This implies that in this case, the stream SHOULD NOT emit any `data`
+ * or `end` events anymore.
+ * Streams MAY choose to use the `pause()` method logic for this, but
+ * special care may have to be taken to ensure a following call to the
+ * `resume()` method SHOULD NOT continue emitting readable events.
+ *
+ * Note that this method should not be confused with the `close()` method.
+ *
+ * @param mixed|string|null $data
+ * @return void
+ */
+ public function end($data = null);
+
+ /**
+ * Closes the stream (forcefully).
+ *
+ * This method can be used to forcefully close the stream, i.e. close
+ * the stream without waiting for any buffered data to be flushed.
+ * If there's still data in the buffer, this data SHOULD be discarded.
+ *
+ * ```php
+ * $stream->close();
+ * ```
+ *
+ * Once the stream is closed, it SHOULD emit a `close` event.
+ * Note that this event SHOULD NOT be emitted more than once, in particular
+ * if this method is called multiple times.
+ *
+ * After calling this method, the stream MUST switch into a non-writable
+ * mode, see also `isWritable()`.
+ * This means that no further writes are possible, so any additional
+ * `write()` or `end()` calls have no effect.
+ *
+ * ```php
+ * $stream->close();
+ * assert($stream->isWritable() === false);
+ *
+ * $stream->write('nope'); // NO-OP
+ * $stream->end(); // NO-OP
+ * ```
+ *
+ * Note that this method should not be confused with the `end()` method.
+ * Unlike the `end()` method, this method does not take care of any existing
+ * buffers and simply discards any buffer contents.
+ * Likewise, this method may also be called after calling `end()` on a
+ * stream in order to stop waiting for the stream to flush its final data.
+ *
+ * ```php
+ * $stream->end();
+ * $loop->addTimer(1.0, function () use ($stream) {
+ * $stream->close();
+ * });
+ * ```
+ *
+ * If this stream is a `DuplexStreamInterface`, you should also notice
+ * how the readable side of the stream also implements a `close()` method.
+ * In other words, after calling this method, the stream MUST switch into
+ * non-writable AND non-readable mode, see also `isReadable()`.
+ *
+ * @return void
+ * @see ReadableStreamInterface::close()
+ */
+ public function close();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/CallableStub.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/CallableStub.php
new file mode 100644
index 0000000..31cc834
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/CallableStub.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace React\Tests\Stream;
+
+class CallableStub
+{
+ public function __invoke()
+ {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/CompositeStreamTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/CompositeStreamTest.php
new file mode 100644
index 0000000..df89c3e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/CompositeStreamTest.php
@@ -0,0 +1,267 @@
+<?php
+
+namespace React\Tests\Stream;
+
+use React\Stream\CompositeStream;
+use React\Stream\ThroughStream;
+
+/**
+ * @covers React\Stream\CompositeStream
+ */
+class CompositeStreamTest extends TestCase
+{
+ /** @test */
+ public function itShouldCloseReadableIfNotWritable()
+ {
+ $readable = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock();
+ $readable
+ ->expects($this->once())
+ ->method('isReadable')
+ ->willReturn(true);
+ $readable
+ ->expects($this->once())
+ ->method('close');
+
+ $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock();
+ $writable
+ ->expects($this->once())
+ ->method('isWritable')
+ ->willReturn(false);
+
+ $composite = new CompositeStream($readable, $writable);
+
+ $composite->on('close', $this->expectCallableNever());
+ $composite->close();
+ }
+
+ /** @test */
+ public function itShouldCloseWritableIfNotReadable()
+ {
+ $readable = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock();
+ $readable
+ ->expects($this->once())
+ ->method('isReadable')
+ ->willReturn(false);
+
+ $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock();
+ $writable
+ ->expects($this->once())
+ ->method('close');
+
+ $composite = new CompositeStream($readable, $writable);
+
+ $composite->on('close', $this->expectCallableNever());
+ $composite->close();
+ }
+
+ /** @test */
+ public function itShouldForwardWritableCallsToWritableStream()
+ {
+ $readable = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock();
+ $readable
+ ->expects($this->once())
+ ->method('isReadable')
+ ->willReturn(true);
+
+ $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock();
+ $writable
+ ->expects($this->once())
+ ->method('write')
+ ->with('foo');
+ $writable
+ ->expects($this->exactly(2))
+ ->method('isWritable')
+ ->willReturn(true);
+
+ $composite = new CompositeStream($readable, $writable);
+ $composite->write('foo');
+ $composite->isWritable();
+ }
+
+ /** @test */
+ public function itShouldForwardReadableCallsToReadableStream()
+ {
+ $readable = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock();
+ $readable
+ ->expects($this->exactly(2))
+ ->method('isReadable')
+ ->willReturn(true);
+ $readable
+ ->expects($this->once())
+ ->method('pause');
+ $readable
+ ->expects($this->once())
+ ->method('resume');
+
+ $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock();
+ $writable
+ ->expects($this->any())
+ ->method('isWritable')
+ ->willReturn(true);
+
+ $composite = new CompositeStream($readable, $writable);
+ $composite->isReadable();
+ $composite->pause();
+ $composite->resume();
+ }
+
+ /** @test */
+ public function itShouldNotForwardResumeIfStreamIsNotWritable()
+ {
+ $readable = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock();
+ $readable
+ ->expects($this->once())
+ ->method('isReadable')
+ ->willReturn(true);
+ $readable
+ ->expects($this->never())
+ ->method('resume');
+
+ $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock();
+ $writable
+ ->expects($this->exactly(2))
+ ->method('isWritable')
+ ->willReturnOnConsecutiveCalls(true, false);
+
+ $composite = new CompositeStream($readable, $writable);
+ $composite->resume();
+ }
+
+ /** @test */
+ public function endShouldDelegateToWritableWithData()
+ {
+ $readable = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock();
+ $readable
+ ->expects($this->once())
+ ->method('isReadable')
+ ->willReturn(true);
+
+ $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock();
+ $writable
+ ->expects($this->once())
+ ->method('isWritable')
+ ->willReturn(true);
+ $writable
+ ->expects($this->once())
+ ->method('end')
+ ->with('foo');
+
+ $composite = new CompositeStream($readable, $writable);
+ $composite->end('foo');
+ }
+
+ /** @test */
+ public function closeShouldCloseBothStreams()
+ {
+ $readable = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock();
+ $readable
+ ->expects($this->once())
+ ->method('isReadable')
+ ->willReturn(true);
+ $readable
+ ->expects($this->once())
+ ->method('close');
+
+ $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock();
+ $writable
+ ->expects($this->once())
+ ->method('isWritable')
+ ->willReturn(true);
+ $writable
+ ->expects($this->once())
+ ->method('close');
+
+ $composite = new CompositeStream($readable, $writable);
+ $composite->close();
+ }
+
+ /** @test */
+ public function itShouldForwardCloseOnlyOnce()
+ {
+ $readable = new ThroughStream();
+ $writable = new ThroughStream();
+
+ $composite = new CompositeStream($readable, $writable);
+ $composite->on('close', $this->expectCallableOnce());
+
+ $readable->close();
+ $writable->close();
+ }
+
+ /** @test */
+ public function itShouldForwardCloseAndRemoveAllListeners()
+ {
+ $in = new ThroughStream();
+
+ $composite = new CompositeStream($in, $in);
+ $composite->on('close', $this->expectCallableOnce());
+
+ $this->assertTrue($composite->isReadable());
+ $this->assertTrue($composite->isWritable());
+ $this->assertCount(1, $composite->listeners('close'));
+
+ $composite->close();
+
+ $this->assertFalse($composite->isReadable());
+ $this->assertFalse($composite->isWritable());
+ $this->assertCount(0, $composite->listeners('close'));
+ }
+
+ /** @test */
+ public function itShouldReceiveForwardedEvents()
+ {
+ $readable = new ThroughStream();
+ $writable = new ThroughStream();
+
+ $composite = new CompositeStream($readable, $writable);
+ $composite->on('data', $this->expectCallableOnce());
+ $composite->on('drain', $this->expectCallableOnce());
+
+ $readable->emit('data', array('foo'));
+ $writable->emit('drain');
+ }
+
+ /** @test */
+ public function itShouldHandlePipingCorrectly()
+ {
+ $readable = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock();
+ $readable
+ ->expects($this->once())
+ ->method('isReadable')
+ ->willReturn(true);
+
+ $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock();
+ $writable->expects($this->any())->method('isWritable')->willReturn(True);
+ $writable
+ ->expects($this->once())
+ ->method('write')
+ ->with('foo');
+
+ $composite = new CompositeStream($readable, $writable);
+
+ $input = new ThroughStream();
+ $input->pipe($composite);
+ $input->emit('data', array('foo'));
+ }
+
+ /** @test */
+ public function itShouldForwardPipeCallsToReadableStream()
+ {
+ $readable = new ThroughStream();
+
+ $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock();
+ $writable->expects($this->any())->method('isWritable')->willReturn(True);
+
+ $composite = new CompositeStream($readable, $writable);
+
+ $output = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock();
+ $output->expects($this->any())->method('isWritable')->willReturn(True);
+ $output
+ ->expects($this->once())
+ ->method('write')
+ ->with('foo');
+
+ $composite->pipe($output);
+ $readable->emit('data', array('foo'));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/DuplexResourceStreamIntegrationTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/DuplexResourceStreamIntegrationTest.php
new file mode 100644
index 0000000..fb5f02a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/DuplexResourceStreamIntegrationTest.php
@@ -0,0 +1,352 @@
+<?php
+
+namespace React\Tests\Stream;
+
+use React\Stream\DuplexResourceStream;
+use React\Stream\ReadableResourceStream;
+use React\EventLoop\ExtEventLoop;
+use React\EventLoop\ExtLibeventLoop;
+use React\EventLoop\ExtLibevLoop;
+use React\EventLoop\LoopInterface;
+use React\EventLoop\LibEventLoop;
+use React\EventLoop\LibEvLoop;
+use React\EventLoop\StreamSelectLoop;
+
+class DuplexResourceStreamIntegrationTest extends TestCase
+{
+ public function loopProvider()
+ {
+ return array(
+ array(
+ function() {
+ return true;
+ },
+ function () {
+ return new StreamSelectLoop();
+ }
+ ),
+ array(
+ function () {
+ return function_exists('event_base_new');
+ },
+ function () {
+ return class_exists('React\EventLoop\ExtLibeventLoop') ? new ExtLibeventLoop() : new LibEventLoop();
+ }
+ ),
+ array(
+ function () {
+ return class_exists('libev\EventLoop');
+ },
+ function () {
+ return class_exists('React\EventLoop\ExtLibevLoop') ? new ExtLibevLoop() : new LibEvLoop();
+ }
+ ),
+ array(
+ function () {
+ return class_exists('EventBase') && class_exists('React\EventLoop\ExtEventLoop');
+ },
+ function () {
+ return new ExtEventLoop();
+ }
+ )
+ );
+ }
+
+ /**
+ * @dataProvider loopProvider
+ */
+ public function testBufferReadsLargeChunks($condition, $loopFactory)
+ {
+ if (true !== $condition()) {
+ return $this->markTestSkipped('Loop implementation not available');
+ }
+
+ $loop = $loopFactory();
+
+ list($sockA, $sockB) = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, 0);
+
+ $bufferSize = 4096;
+ $streamA = new DuplexResourceStream($sockA, $loop, $bufferSize);
+ $streamB = new DuplexResourceStream($sockB, $loop, $bufferSize);
+
+ $testString = str_repeat("*", $bufferSize + 1);
+
+ $buffer = "";
+ $streamB->on('data', function ($data) use (&$buffer) {
+ $buffer .= $data;
+ });
+
+ $streamA->write($testString);
+
+ $this->loopTick($loop);
+ $this->loopTick($loop);
+ $this->loopTick($loop);
+
+ $streamA->close();
+ $streamB->close();
+
+ $this->assertEquals($testString, $buffer);
+ }
+
+ /**
+ * @dataProvider loopProvider
+ */
+ public function testWriteLargeChunk($condition, $loopFactory)
+ {
+ if (true !== $condition()) {
+ return $this->markTestSkipped('Loop implementation not available');
+ }
+
+ $loop = $loopFactory();
+
+ list($sockA, $sockB) = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, 0);
+
+ $streamA = new DuplexResourceStream($sockA, $loop);
+ $streamB = new DuplexResourceStream($sockB, $loop);
+
+ // limit seems to be 192 KiB
+ $size = 256 * 1024;
+
+ // sending side sends and expects clean close with no errors
+ $streamA->end(str_repeat('*', $size));
+ $streamA->on('close', $this->expectCallableOnce());
+ $streamA->on('error', $this->expectCallableNever());
+
+ // receiving side counts bytes and expects clean close with no errors
+ $received = 0;
+ $streamB->on('data', function ($chunk) use (&$received) {
+ $received += strlen($chunk);
+ });
+ $streamB->on('close', $this->expectCallableOnce());
+ $streamB->on('error', $this->expectCallableNever());
+
+ $loop->run();
+
+ $streamA->close();
+ $streamB->close();
+
+ $this->assertEquals($size, $received);
+ }
+
+ /**
+ * @dataProvider loopProvider
+ */
+ public function testDoesNotEmitDataIfNothingHasBeenWritten($condition, $loopFactory)
+ {
+ if (true !== $condition()) {
+ return $this->markTestSkipped('Loop implementation not available');
+ }
+
+ $loop = $loopFactory();
+
+ list($sockA, $sockB) = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, 0);
+
+ $streamA = new DuplexResourceStream($sockA, $loop);
+ $streamB = new DuplexResourceStream($sockB, $loop);
+
+ // end streamA without writing any data
+ $streamA->end();
+
+ // streamB should not emit any data
+ $streamB->on('data', $this->expectCallableNever());
+
+ $loop->run();
+
+ $streamA->close();
+ $streamB->close();
+ }
+
+ /**
+ * @dataProvider loopProvider
+ */
+ public function testDoesNotWriteDataIfRemoteSideFromPairHasBeenClosed($condition, $loopFactory)
+ {
+ if (true !== $condition()) {
+ return $this->markTestSkipped('Loop implementation not available');
+ }
+
+ $loop = $loopFactory();
+
+ list($sockA, $sockB) = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, 0);
+
+ $streamA = new DuplexResourceStream($sockA, $loop);
+ $streamB = new DuplexResourceStream($sockB, $loop);
+
+ // end streamA without writing any data
+ $streamA->pause();
+ $streamA->write('hello');
+ $streamA->on('close', $this->expectCallableOnce());
+
+ $streamB->on('data', $this->expectCallableNever());
+ $streamB->close();
+
+ $loop->run();
+
+ $streamA->close();
+ $streamB->close();
+ }
+
+ /**
+ * @dataProvider loopProvider
+ */
+ public function testDoesNotWriteDataIfServerSideHasBeenClosed($condition, $loopFactory)
+ {
+ if (true !== $condition()) {
+ return $this->markTestSkipped('Loop implementation not available');
+ }
+
+ $loop = $loopFactory();
+
+ $server = stream_socket_server('tcp://127.0.0.1:0');
+
+ $client = stream_socket_client(stream_socket_get_name($server, false));
+ $peer = stream_socket_accept($server);
+
+ $streamA = new DuplexResourceStream($client, $loop);
+ $streamB = new DuplexResourceStream($peer, $loop);
+
+ // end streamA without writing any data
+ $streamA->pause();
+ $streamA->write('hello');
+ $streamA->on('close', $this->expectCallableOnce());
+
+ $streamB->on('data', $this->expectCallableNever());
+ $streamB->close();
+
+ $loop->run();
+
+ $streamA->close();
+ $streamB->close();
+ }
+
+ /**
+ * @dataProvider loopProvider
+ */
+ public function testDoesNotWriteDataIfClientSideHasBeenClosed($condition, $loopFactory)
+ {
+ if (true !== $condition()) {
+ return $this->markTestSkipped('Loop implementation not available');
+ }
+
+ $loop = $loopFactory();
+
+ $server = stream_socket_server('tcp://127.0.0.1:0');
+
+ $client = stream_socket_client(stream_socket_get_name($server, false));
+ $peer = stream_socket_accept($server);
+
+ $streamA = new DuplexResourceStream($peer, $loop);
+ $streamB = new DuplexResourceStream($client, $loop);
+
+ // end streamA without writing any data
+ $streamA->pause();
+ $streamA->write('hello');
+ $streamA->on('close', $this->expectCallableOnce());
+
+ $streamB->on('data', $this->expectCallableNever());
+ $streamB->close();
+
+ $loop->run();
+
+ $streamA->close();
+ $streamB->close();
+ }
+
+ /**
+ * @dataProvider loopProvider
+ */
+ public function testReadsSingleChunkFromProcessPipe($condition, $loopFactory)
+ {
+ if (true !== $condition()) {
+ return $this->markTestSkipped('Loop implementation not available');
+ }
+
+ $loop = $loopFactory();
+
+ $stream = new ReadableResourceStream(popen('echo test', 'r'), $loop);
+ $stream->on('data', $this->expectCallableOnceWith("test\n"));
+ $stream->on('end', $this->expectCallableOnce());
+ $stream->on('error', $this->expectCallableNever());
+
+ $loop->run();
+ }
+
+ /**
+ * @dataProvider loopProvider
+ */
+ public function testReadsMultipleChunksFromProcessPipe($condition, $loopFactory)
+ {
+ if (true !== $condition()) {
+ return $this->markTestSkipped('Loop implementation not available');
+ }
+
+ $loop = $loopFactory();
+
+ $stream = new ReadableResourceStream(popen('echo a;sleep 0.1;echo b;sleep 0.1;echo c', 'r'), $loop);
+
+ $buffer = '';
+ $stream->on('data', function ($chunk) use (&$buffer) {
+ $buffer .= $chunk;
+ });
+
+ $stream->on('end', $this->expectCallableOnce());
+ $stream->on('error', $this->expectCallableNever());
+
+ $loop->run();
+
+ $this->assertEquals("a\n" . "b\n" . "c\n", $buffer);
+ }
+
+ /**
+ * @dataProvider loopProvider
+ */
+ public function testReadsLongChunksFromProcessPipe($condition, $loopFactory)
+ {
+ if (true !== $condition()) {
+ return $this->markTestSkipped('Loop implementation not available');
+ }
+
+ $loop = $loopFactory();
+
+ $stream = new ReadableResourceStream(popen('dd if=/dev/zero bs=12345 count=1234 2>&-', 'r'), $loop);
+
+ $bytes = 0;
+ $stream->on('data', function ($chunk) use (&$bytes) {
+ $bytes += strlen($chunk);
+ });
+
+ $stream->on('end', $this->expectCallableOnce());
+ $stream->on('error', $this->expectCallableNever());
+
+ $loop->run();
+
+ $this->assertEquals(12345 * 1234, $bytes);
+ }
+
+ /**
+ * @dataProvider loopProvider
+ */
+ public function testReadsNothingFromProcessPipeWithNoOutput($condition, $loopFactory)
+ {
+ if (true !== $condition()) {
+ return $this->markTestSkipped('Loop implementation not available');
+ }
+
+ $loop = $loopFactory();
+
+ $stream = new ReadableResourceStream(popen('true', 'r'), $loop);
+ $stream->on('data', $this->expectCallableNever());
+ $stream->on('end', $this->expectCallableOnce());
+ $stream->on('error', $this->expectCallableNever());
+
+ $loop->run();
+ }
+
+ private function loopTick(LoopInterface $loop)
+ {
+ $loop->addTimer(0, function () use ($loop) {
+ $loop->stop();
+ });
+ $loop->run();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/DuplexResourceStreamTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/DuplexResourceStreamTest.php
new file mode 100644
index 0000000..3212ae8
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/DuplexResourceStreamTest.php
@@ -0,0 +1,495 @@
+<?php
+
+namespace React\Tests\Stream;
+
+use React\Stream\DuplexResourceStream;
+use Clue\StreamFilter as Filter;
+use React\Stream\WritableResourceStream;
+
+class DuplexResourceStreamTest extends TestCase
+{
+ /**
+ * @covers React\Stream\DuplexResourceStream::__construct
+ * @doesNotPerformAssertions
+ */
+ public function testConstructor()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ new DuplexResourceStream($stream, $loop);
+ }
+
+ /**
+ * @covers React\Stream\DuplexResourceStream::__construct
+ * @doesNotPerformAssertions
+ */
+ public function testConstructorWithExcessiveMode()
+ {
+ // excessive flags are ignored for temp streams, so we have to use a file stream
+ $name = tempnam(sys_get_temp_dir(), 'test');
+ $stream = @fopen($name, 'r+eANYTHING');
+ unlink($name);
+
+ $loop = $this->createLoopMock();
+ $buffer = new DuplexResourceStream($stream, $loop);
+ $buffer->close();
+ }
+
+ /**
+ * @covers React\Stream\DuplexResourceStream::__construct
+ * @expectedException InvalidArgumentException
+ */
+ public function testConstructorThrowsExceptionOnInvalidStream()
+ {
+ $loop = $this->createLoopMock();
+
+ new DuplexResourceStream('breakme', $loop);
+ }
+
+ /**
+ * @covers React\Stream\DuplexResourceStream::__construct
+ * @expectedException InvalidArgumentException
+ */
+ public function testConstructorThrowsExceptionOnWriteOnlyStream()
+ {
+ if (defined('HHVM_VERSION')) {
+ $this->markTestSkipped('HHVM does not report fopen mode for STDOUT');
+ }
+
+ $loop = $this->createLoopMock();
+
+ new DuplexResourceStream(STDOUT, $loop);
+ }
+
+ /**
+ * @covers React\Stream\DuplexResourceStream::__construct
+ * @expectedException InvalidArgumentException
+ */
+ public function testConstructorThrowsExceptionOnWriteOnlyStreamWithExcessiveMode()
+ {
+ // excessive flags are ignored for temp streams, so we have to use a file stream
+ $name = tempnam(sys_get_temp_dir(), 'test');
+ $stream = fopen($name, 'weANYTHING');
+ unlink($name);
+
+ $loop = $this->createLoopMock();
+ new DuplexResourceStream($stream, $loop);
+ }
+
+ /**
+ * @covers React\Stream\DuplexResourceStream::__construct
+ * @expectedException RunTimeException
+ */
+ public function testConstructorThrowsExceptionIfStreamDoesNotSupportNonBlocking()
+ {
+ if (!in_array('blocking', stream_get_wrappers())) {
+ stream_wrapper_register('blocking', 'React\Tests\Stream\EnforceBlockingWrapper');
+ }
+
+ $stream = fopen('blocking://test', 'r+');
+ $loop = $this->createLoopMock();
+
+ new DuplexResourceStream($stream, $loop);
+ }
+
+ /**
+ * @covers React\Stream\DuplexResourceStream::__construct
+ * @doesNotPerformAssertions
+ */
+ public function testConstructorAcceptsBuffer()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $buffer = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock();
+
+ $conn = new DuplexResourceStream($stream, $loop, null, $buffer);
+ }
+
+ public function testCloseShouldEmitCloseEvent()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $conn = new DuplexResourceStream($stream, $loop);
+ $conn->on('close', $this->expectCallableOnce());
+ $conn->on('end', $this->expectCallableNever());
+
+ $conn->close();
+
+ $this->assertFalse($conn->isReadable());
+ }
+
+ public function testEndShouldEndBuffer()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $buffer = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock();
+ $buffer->expects($this->once())->method('end')->with('foo');
+
+ $conn = new DuplexResourceStream($stream, $loop, null, $buffer);
+ $conn->end('foo');
+ }
+
+
+ public function testEndAfterCloseIsNoOp()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $buffer = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock();
+ $buffer->expects($this->never())->method('end');
+
+ $conn = new DuplexResourceStream($stream, $loop);
+ $conn->close();
+ $conn->end();
+ }
+
+ /**
+ * @covers React\Stream\DuplexResourceStream::__construct
+ * @covers React\Stream\DuplexResourceStream::handleData
+ */
+ public function testDataEvent()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $capturedData = null;
+
+ $conn = new DuplexResourceStream($stream, $loop);
+ $conn->on('data', function ($data) use (&$capturedData) {
+ $capturedData = $data;
+ });
+
+ fwrite($stream, "foobar\n");
+ rewind($stream);
+
+ $conn->handleData($stream);
+ $this->assertSame("foobar\n", $capturedData);
+ }
+
+ /**
+ * @covers React\Stream\DuplexResourceStream::__construct
+ * @covers React\Stream\DuplexResourceStream::handleData
+ */
+ public function testDataEventDoesEmitOneChunkMatchingBufferSize()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $capturedData = null;
+
+ $conn = new DuplexResourceStream($stream, $loop, 4321);
+ $conn->on('data', function ($data) use (&$capturedData) {
+ $capturedData = $data;
+ });
+
+ fwrite($stream, str_repeat("a", 100000));
+ rewind($stream);
+
+ $conn->handleData($stream);
+
+ $this->assertTrue($conn->isReadable());
+ $this->assertEquals(4321, strlen($capturedData));
+ }
+
+ /**
+ * @covers React\Stream\DuplexResourceStream::__construct
+ * @covers React\Stream\DuplexResourceStream::handleData
+ */
+ public function testDataEventDoesEmitOneChunkUntilStreamEndsWhenBufferSizeIsInfinite()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $capturedData = null;
+
+ $conn = new DuplexResourceStream($stream, $loop, -1);
+
+ $conn->on('data', function ($data) use (&$capturedData) {
+ $capturedData = $data;
+ });
+
+ fwrite($stream, str_repeat("a", 100000));
+ rewind($stream);
+
+ $conn->handleData($stream);
+
+ $this->assertTrue($conn->isReadable());
+ $this->assertEquals(100000, strlen($capturedData));
+ }
+
+ /**
+ * @covers React\Stream\DuplexResourceStream::handleData
+ */
+ public function testEmptyStreamShouldNotEmitData()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $conn = new DuplexResourceStream($stream, $loop);
+ $conn->on('data', $this->expectCallableNever());
+
+ $conn->handleData($stream);
+ }
+
+ /**
+ * @covers React\Stream\DuplexResourceStream::write
+ */
+ public function testWrite()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createWriteableLoopMock();
+
+ $conn = new DuplexResourceStream($stream, $loop);
+ $conn->write("foo\n");
+
+ rewind($stream);
+ $this->assertSame("foo\n", fgets($stream));
+ }
+
+ /**
+ * @covers React\Stream\DuplexResourceStream::end
+ * @covers React\Stream\DuplexResourceStream::isReadable
+ * @covers React\Stream\DuplexResourceStream::isWritable
+ */
+ public function testEnd()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $conn = new DuplexResourceStream($stream, $loop);
+ $conn->end();
+
+ $this->assertFalse(is_resource($stream));
+ $this->assertFalse($conn->isReadable());
+ $this->assertFalse($conn->isWritable());
+ }
+
+ /**
+ * @covers React\Stream\DuplexResourceStream::end
+ */
+ public function testEndRemovesReadStreamFromLoop()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+ $loop->expects($this->once())->method('addReadStream')->with($stream);
+ $loop->expects($this->once())->method('removeReadStream')->with($stream);
+
+ $conn = new DuplexResourceStream($stream, $loop);
+ $conn->end('bye');
+ }
+
+ /**
+ * @covers React\Stream\DuplexResourceStream::pause
+ */
+ public function testPauseRemovesReadStreamFromLoop()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+ $loop->expects($this->once())->method('addReadStream')->with($stream);
+ $loop->expects($this->once())->method('removeReadStream')->with($stream);
+
+ $conn = new DuplexResourceStream($stream, $loop);
+ $conn->pause();
+ $conn->pause();
+ }
+
+ /**
+ * @covers React\Stream\DuplexResourceStream::pause
+ */
+ public function testResumeDoesAddStreamToLoopOnlyOnce()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+ $loop->expects($this->once())->method('addReadStream')->with($stream);
+
+ $conn = new DuplexResourceStream($stream, $loop);
+ $conn->resume();
+ $conn->resume();
+ }
+
+ /**
+ * @covers React\Stream\DuplexResourceStream::close
+ */
+ public function testCloseRemovesReadStreamFromLoop()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+ $loop->expects($this->once())->method('addReadStream')->with($stream);
+ $loop->expects($this->once())->method('removeReadStream')->with($stream);
+
+ $conn = new DuplexResourceStream($stream, $loop);
+ $conn->close();
+ }
+
+ /**
+ * @covers React\Stream\DuplexResourceStream::close
+ */
+ public function testCloseAfterPauseRemovesReadStreamFromLoopOnlyOnce()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+ $loop->expects($this->once())->method('addReadStream')->with($stream);
+ $loop->expects($this->once())->method('removeReadStream')->with($stream);
+
+ $conn = new DuplexResourceStream($stream, $loop);
+ $conn->pause();
+ $conn->close();
+ }
+
+ /**
+ * @covers React\Stream\DuplexResourceStream::close
+ */
+ public function testResumeAfterCloseDoesAddReadStreamToLoopOnlyOnce()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+ $loop->expects($this->once())->method('addReadStream')->with($stream);
+
+ $conn = new DuplexResourceStream($stream, $loop);
+ $conn->close();
+ $conn->resume();
+ }
+
+ public function testEndedStreamsShouldNotWrite()
+ {
+ $file = tempnam(sys_get_temp_dir(), 'reactphptest_');
+ $stream = fopen($file, 'r+');
+ $loop = $this->createWriteableLoopMock();
+
+ $conn = new DuplexResourceStream($stream, $loop);
+ $conn->write("foo\n");
+ $conn->end();
+
+ $res = $conn->write("bar\n");
+ $stream = fopen($file, 'r');
+
+ $this->assertSame("foo\n", fgets($stream));
+ $this->assertFalse($res);
+
+ unlink($file);
+ }
+
+ public function testPipeShouldReturnDestination()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $conn = new DuplexResourceStream($stream, $loop);
+ $dest = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock();
+
+ $this->assertSame($dest, $conn->pipe($dest));
+ }
+
+ public function testBufferEventsShouldBubbleUp()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $buffer = new WritableResourceStream($stream, $loop);
+ $conn = new DuplexResourceStream($stream, $loop, null, $buffer);
+
+ $conn->on('drain', $this->expectCallableOnce());
+ $conn->on('error', $this->expectCallableOnce());
+
+ $buffer->emit('drain');
+ $buffer->emit('error', array(new \RuntimeException('Whoops')));
+ }
+
+ /**
+ * @covers React\Stream\DuplexResourceStream::handleData
+ */
+ public function testClosingStreamInDataEventShouldNotTriggerError()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $conn = new DuplexResourceStream($stream, $loop);
+ $conn->on('error', $this->expectCallableNever());
+ $conn->on('data', function ($data) use ($conn) {
+ $conn->close();
+ });
+
+ fwrite($stream, "foobar\n");
+ rewind($stream);
+
+ $conn->handleData($stream);
+ }
+
+ /**
+ * @covers React\Stream\DuplexResourceStream::handleData
+ */
+ public function testDataFiltered()
+ {
+ $stream = fopen('php://temp', 'r+');
+
+ // add a filter which removes every 'a' when reading
+ Filter\append($stream, function ($chunk) {
+ return str_replace('a', '', $chunk);
+ }, STREAM_FILTER_READ);
+
+ $loop = $this->createLoopMock();
+
+ $capturedData = null;
+
+ $conn = new DuplexResourceStream($stream, $loop);
+ $conn->on('data', function ($data) use (&$capturedData) {
+ $capturedData = $data;
+ });
+
+ fwrite($stream, "foobar\n");
+ rewind($stream);
+
+ $conn->handleData($stream);
+ $this->assertSame("foobr\n", $capturedData);
+ }
+
+ /**
+ * @covers React\Stream\DuplexResourceStream::handleData
+ */
+ public function testDataErrorShouldEmitErrorAndClose()
+ {
+ $stream = fopen('php://temp', 'r+');
+
+ // add a filter which returns an error when encountering an 'a' when reading
+ Filter\append($stream, function ($chunk) {
+ if (strpos($chunk, 'a') !== false) {
+ throw new \Exception('Invalid');
+ }
+ return $chunk;
+ }, STREAM_FILTER_READ);
+
+ $loop = $this->createLoopMock();
+
+ $conn = new DuplexResourceStream($stream, $loop);
+ $conn->on('data', $this->expectCallableNever());
+ $conn->on('error', $this->expectCallableOnce());
+ $conn->on('close', $this->expectCallableOnce());
+
+ fwrite($stream, "foobar\n");
+ rewind($stream);
+
+ $conn->handleData($stream);
+ }
+
+ private function createWriteableLoopMock()
+ {
+ $loop = $this->createLoopMock();
+ $loop
+ ->expects($this->once())
+ ->method('addWriteStream')
+ ->will($this->returnCallback(function ($stream, $listener) {
+ call_user_func($listener, $stream);
+ }));
+
+ return $loop;
+ }
+
+ private function createLoopMock()
+ {
+ return $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/EnforceBlockingWrapper.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/EnforceBlockingWrapper.php
new file mode 100644
index 0000000..39c0487
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/EnforceBlockingWrapper.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace React\Tests\Stream;
+
+/**
+ * Used to test dummy stream resources that do not support setting non-blocking mode
+ *
+ * @link http://php.net/manual/de/class.streamwrapper.php
+ */
+class EnforceBlockingWrapper
+{
+ public function stream_open($path, $mode, $options, &$opened_path)
+ {
+ return true;
+ }
+
+ public function stream_cast($cast_as)
+ {
+ return false;
+ }
+
+ public function stream_eof()
+ {
+ return false;
+ }
+
+ public function stream_set_option($option, $arg1, $arg2)
+ {
+ if ($option === STREAM_OPTION_BLOCKING) {
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/FunctionalInternetTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/FunctionalInternetTest.php
new file mode 100644
index 0000000..4d31e8e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/FunctionalInternetTest.php
@@ -0,0 +1,122 @@
+<?php
+
+namespace React\Tests\Stream;
+
+use React\EventLoop\Factory;
+use React\EventLoop\LoopInterface;
+use React\Stream\DuplexResourceStream;
+use React\Stream\WritableResourceStream;
+
+/**
+ * @group internet
+ */
+class FunctionalInternetTest extends TestCase
+{
+ public function testUploadKilobytePlain()
+ {
+ $size = 1000;
+ $stream = stream_socket_client('tcp://httpbin.org:80');
+
+ $loop = Factory::create();
+ $stream = new DuplexResourceStream($stream, $loop);
+
+ $buffer = '';
+ $stream->on('data', function ($chunk) use (&$buffer) {
+ $buffer .= $chunk;
+ });
+
+ $stream->on('error', $this->expectCallableNever());
+
+ $stream->write("POST /post HTTP/1.0\r\nHost: httpbin.org\r\nContent-Length: $size\r\n\r\n" . str_repeat('.', $size));
+
+ $this->awaitStreamClose($stream, $loop);
+
+ $this->assertNotEquals('', $buffer);
+ }
+
+ public function testUploadBiggerBlockPlain()
+ {
+ $size = 50 * 1000;
+ $stream = stream_socket_client('tcp://httpbin.org:80');
+
+ $loop = Factory::create();
+ $stream = new DuplexResourceStream($stream, $loop);
+
+ $buffer = '';
+ $stream->on('data', function ($chunk) use (&$buffer) {
+ $buffer .= $chunk;
+ });
+
+ $stream->on('error', $this->expectCallableNever());
+
+ $stream->write("POST /post HTTP/1.0\r\nHost: httpbin.org\r\nContent-Length: $size\r\n\r\n" . str_repeat('.', $size));
+
+ $this->awaitStreamClose($stream, $loop);
+
+ $this->assertNotEquals('', $buffer);
+ }
+
+ public function testUploadKilobyteSecure()
+ {
+ $size = 1000;
+ $stream = stream_socket_client('tls://httpbin.org:443');
+
+ $loop = Factory::create();
+ $stream = new DuplexResourceStream($stream, $loop);
+
+ $buffer = '';
+ $stream->on('data', function ($chunk) use (&$buffer) {
+ $buffer .= $chunk;
+ });
+
+ $stream->on('error', $this->expectCallableNever());
+
+ $stream->write("POST /post HTTP/1.0\r\nHost: httpbin.org\r\nContent-Length: $size\r\n\r\n" . str_repeat('.', $size));
+
+ $this->awaitStreamClose($stream, $loop);
+
+ $this->assertNotEquals('', $buffer);
+ }
+
+ public function testUploadBiggerBlockSecureRequiresSmallerChunkSize()
+ {
+ $size = 50 * 1000;
+ $stream = stream_socket_client('tls://httpbin.org:443');
+
+ $loop = Factory::create();
+ $stream = new DuplexResourceStream(
+ $stream,
+ $loop,
+ null,
+ new WritableResourceStream($stream, $loop, null, 8192)
+ );
+
+ $buffer = '';
+ $stream->on('data', function ($chunk) use (&$buffer) {
+ $buffer .= $chunk;
+ });
+
+ $stream->on('error', $this->expectCallableNever());
+
+ $stream->write("POST /post HTTP/1.0\r\nHost: httpbin.org\r\nContent-Length: $size\r\n\r\n" . str_repeat('.', $size));
+
+ $this->awaitStreamClose($stream, $loop);
+
+ $this->assertNotEquals('', $buffer);
+ }
+
+ private function awaitStreamClose(DuplexResourceStream $stream, LoopInterface $loop, $timeout = 10.0)
+ {
+ $stream->on('close', function () use ($loop) {
+ $loop->stop();
+ });
+
+ $that = $this;
+ $loop->addTimer($timeout, function () use ($loop, $that) {
+ $loop->stop();
+ $that->fail('Timed out while waiting for stream to close');
+ });
+
+ $loop->run();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/ReadableResourceStreamTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/ReadableResourceStreamTest.php
new file mode 100644
index 0000000..20da96f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/ReadableResourceStreamTest.php
@@ -0,0 +1,372 @@
+<?php
+
+namespace React\Tests\Stream;
+
+use React\Stream\ReadableResourceStream;
+use Clue\StreamFilter as Filter;
+
+class ReadableResourceStreamTest extends TestCase
+{
+ /**
+ * @covers React\Stream\ReadableResourceStream::__construct
+ * @doesNotPerformAssertions
+ */
+ public function testConstructor()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ new ReadableResourceStream($stream, $loop);
+ }
+
+ /**
+ * @covers React\Stream\ReadableResourceStream::__construct
+ * @doesNotPerformAssertions
+ */
+ public function testConstructorWithExcessiveMode()
+ {
+ // excessive flags are ignored for temp streams, so we have to use a file stream
+ $name = tempnam(sys_get_temp_dir(), 'test');
+ $stream = @fopen($name, 'r+eANYTHING');
+ unlink($name);
+
+ $loop = $this->createLoopMock();
+ $buffer = new ReadableResourceStream($stream, $loop);
+ $buffer->close();
+ }
+
+ /**
+ * @covers React\Stream\ReadableResourceStream::__construct
+ * @expectedException InvalidArgumentException
+ */
+ public function testConstructorThrowsExceptionOnInvalidStream()
+ {
+ $loop = $this->createLoopMock();
+
+ new ReadableResourceStream(false, $loop);
+ }
+
+ /**
+ * @covers React\Stream\ReadableResourceStream::__construct
+ * @expectedException InvalidArgumentException
+ */
+ public function testConstructorThrowsExceptionOnWriteOnlyStream()
+ {
+ if (defined('HHVM_VERSION')) {
+ $this->markTestSkipped('HHVM does not report fopen mode for STDOUT');
+ }
+
+ $loop = $this->createLoopMock();
+
+ new ReadableResourceStream(STDOUT, $loop);
+ }
+
+ /**
+ * @covers React\Stream\ReadableResourceStream::__construct
+ * @expectedException InvalidArgumentException
+ */
+ public function testConstructorThrowsExceptionOnWriteOnlyStreamWithExcessiveMode()
+ {
+ // excessive flags are ignored for temp streams, so we have to use a file stream
+ $name = tempnam(sys_get_temp_dir(), 'test');
+ $stream = fopen($name, 'weANYTHING');
+ unlink($name);
+
+ $loop = $this->createLoopMock();
+ new ReadableResourceStream($stream, $loop);
+ }
+
+ /**
+ * @covers React\Stream\ReadableResourceStream::__construct
+ * @expectedException RuntimeException
+ */
+ public function testConstructorThrowsExceptionIfStreamDoesNotSupportNonBlocking()
+ {
+ if (!in_array('blocking', stream_get_wrappers())) {
+ stream_wrapper_register('blocking', 'React\Tests\Stream\EnforceBlockingWrapper');
+ }
+
+ $stream = fopen('blocking://test', 'r+');
+ $loop = $this->createLoopMock();
+
+ new ReadableResourceStream($stream, $loop);
+ }
+
+
+ public function testCloseShouldEmitCloseEvent()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $conn = new ReadableResourceStream($stream, $loop);
+ $conn->on('close', $this->expectCallableOnce());
+
+ $conn->close();
+
+ $this->assertFalse($conn->isReadable());
+ }
+
+ public function testCloseTwiceShouldEmitCloseEventOnce()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $conn = new ReadableResourceStream($stream, $loop);
+ $conn->on('close', $this->expectCallableOnce());
+
+ $conn->close();
+ $conn->close();
+ }
+
+ /**
+ * @covers React\Stream\ReadableResourceStream::__construct
+ * @covers React\Stream\ReadableResourceStream::handleData
+ */
+ public function testDataEvent()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $capturedData = null;
+
+ $conn = new ReadableResourceStream($stream, $loop);
+ $conn->on('data', function ($data) use (&$capturedData) {
+ $capturedData = $data;
+ });
+
+ fwrite($stream, "foobar\n");
+ rewind($stream);
+
+ $conn->handleData($stream);
+ $this->assertSame("foobar\n", $capturedData);
+ }
+
+ /**
+ * @covers React\Stream\ReadableResourceStream::__construct
+ * @covers React\Stream\ReadableResourceStream::handleData
+ */
+ public function testDataEventDoesEmitOneChunkMatchingBufferSize()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $capturedData = null;
+
+ $conn = new ReadableResourceStream($stream, $loop, 4321);
+ $conn->on('data', function ($data) use (&$capturedData) {
+ $capturedData = $data;
+ });
+
+ fwrite($stream, str_repeat("a", 100000));
+ rewind($stream);
+
+ $conn->handleData($stream);
+
+ $this->assertTrue($conn->isReadable());
+ $this->assertEquals(4321, strlen($capturedData));
+ }
+
+ /**
+ * @covers React\Stream\ReadableResourceStream::__construct
+ * @covers React\Stream\ReadableResourceStream::handleData
+ */
+ public function testDataEventDoesEmitOneChunkUntilStreamEndsWhenBufferSizeIsInfinite()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $capturedData = null;
+
+ $conn = new ReadableResourceStream($stream, $loop, -1);
+
+ $conn->on('data', function ($data) use (&$capturedData) {
+ $capturedData = $data;
+ });
+
+ fwrite($stream, str_repeat("a", 100000));
+ rewind($stream);
+
+ $conn->handleData($stream);
+
+ $this->assertTrue($conn->isReadable());
+ $this->assertEquals(100000, strlen($capturedData));
+ }
+
+ /**
+ * @covers React\Stream\ReadableResourceStream::handleData
+ */
+ public function testEmptyStreamShouldNotEmitData()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $conn = new ReadableResourceStream($stream, $loop);
+ $conn->on('data', $this->expectCallableNever());
+
+ $conn->handleData($stream);
+ }
+
+ public function testPipeShouldReturnDestination()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $conn = new ReadableResourceStream($stream, $loop);
+ $dest = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock();
+
+ $this->assertSame($dest, $conn->pipe($dest));
+ }
+
+ /**
+ * @covers React\Stream\ReadableResourceStream::handleData
+ */
+ public function testClosingStreamInDataEventShouldNotTriggerError()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $conn = new ReadableResourceStream($stream, $loop);
+ $conn->on('error', $this->expectCallableNever());
+ $conn->on('data', function ($data) use ($conn) {
+ $conn->close();
+ });
+
+ fwrite($stream, "foobar\n");
+ rewind($stream);
+
+ $conn->handleData($stream);
+ }
+
+ /**
+ * @covers React\Stream\ReadableResourceStream::pause
+ */
+ public function testPauseRemovesReadStreamFromLoop()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+ $loop->expects($this->once())->method('addReadStream')->with($stream);
+ $loop->expects($this->once())->method('removeReadStream')->with($stream);
+
+ $conn = new ReadableResourceStream($stream, $loop);
+ $conn->pause();
+ $conn->pause();
+ }
+
+ /**
+ * @covers React\Stream\ReadableResourceStream::pause
+ */
+ public function testResumeDoesAddStreamToLoopOnlyOnce()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+ $loop->expects($this->once())->method('addReadStream')->with($stream);
+
+ $conn = new ReadableResourceStream($stream, $loop);
+ $conn->resume();
+ $conn->resume();
+ }
+
+ /**
+ * @covers React\Stream\ReadableResourceStream::close
+ */
+ public function testCloseRemovesReadStreamFromLoop()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+ $loop->expects($this->once())->method('addReadStream')->with($stream);
+ $loop->expects($this->once())->method('removeReadStream')->with($stream);
+
+ $conn = new ReadableResourceStream($stream, $loop);
+ $conn->close();
+ }
+
+ /**
+ * @covers React\Stream\ReadableResourceStream::close
+ */
+ public function testCloseAfterPauseRemovesReadStreamFromLoopOnce()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+ $loop->expects($this->once())->method('addReadStream')->with($stream);
+ $loop->expects($this->once())->method('removeReadStream')->with($stream);
+
+ $conn = new ReadableResourceStream($stream, $loop);
+ $conn->pause();
+ $conn->close();
+ }
+
+ /**
+ * @covers React\Stream\ReadableResourceStream::close
+ */
+ public function testResumeAfterCloseDoesAddReadStreamToLoopOnlyOnce()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+ $loop->expects($this->once())->method('addReadStream')->with($stream);
+
+ $conn = new ReadableResourceStream($stream, $loop);
+ $conn->close();
+ $conn->resume();
+ }
+
+ /**
+ * @covers React\Stream\ReadableResourceStream::handleData
+ */
+ public function testDataFiltered()
+ {
+ $stream = fopen('php://temp', 'r+');
+
+ // add a filter which removes every 'a' when reading
+ Filter\append($stream, function ($chunk) {
+ return str_replace('a', '', $chunk);
+ }, STREAM_FILTER_READ);
+
+ $loop = $this->createLoopMock();
+
+ $capturedData = null;
+
+ $conn = new ReadableResourceStream($stream, $loop);
+ $conn->on('data', function ($data) use (&$capturedData) {
+ $capturedData = $data;
+ });
+
+ fwrite($stream, "foobar\n");
+ rewind($stream);
+
+ $conn->handleData($stream);
+ $this->assertSame("foobr\n", $capturedData);
+ }
+
+ /**
+ * @covers React\Stream\ReadableResourceStream::handleData
+ */
+ public function testDataErrorShouldEmitErrorAndClose()
+ {
+ $stream = fopen('php://temp', 'r+');
+
+ // add a filter which returns an error when encountering an 'a' when reading
+ Filter\append($stream, function ($chunk) {
+ if (strpos($chunk, 'a') !== false) {
+ throw new \Exception('Invalid');
+ }
+ return $chunk;
+ }, STREAM_FILTER_READ);
+
+ $loop = $this->createLoopMock();
+
+ $conn = new ReadableResourceStream($stream, $loop);
+ $conn->on('data', $this->expectCallableNever());
+ $conn->on('error', $this->expectCallableOnce());
+ $conn->on('close', $this->expectCallableOnce());
+
+ fwrite($stream, "foobar\n");
+ rewind($stream);
+
+ $conn->handleData($stream);
+ }
+
+ private function createLoopMock()
+ {
+ return $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/Stub/ReadableStreamStub.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/Stub/ReadableStreamStub.php
new file mode 100644
index 0000000..6984f24
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/Stub/ReadableStreamStub.php
@@ -0,0 +1,61 @@
+<?php
+
+namespace React\Tests\Stream\Stub;
+
+use Evenement\EventEmitter;
+use React\Stream\ReadableStreamInterface;
+use React\Stream\WritableStreamInterface;
+use React\Stream\Util;
+
+class ReadableStreamStub extends EventEmitter implements ReadableStreamInterface
+{
+ public $readable = true;
+ public $paused = false;
+
+ public function isReadable()
+ {
+ return true;
+ }
+
+ // trigger data event
+ public function write($data)
+ {
+ $this->emit('data', array($data));
+ }
+
+ // trigger error event
+ public function error($error)
+ {
+ $this->emit('error', array($error));
+ }
+
+ // trigger end event
+ public function end()
+ {
+ $this->emit('end', array());
+ }
+
+ public function pause()
+ {
+ $this->paused = true;
+ }
+
+ public function resume()
+ {
+ $this->paused = false;
+ }
+
+ public function close()
+ {
+ $this->readable = false;
+
+ $this->emit('close');
+ }
+
+ public function pipe(WritableStreamInterface $dest, array $options = array())
+ {
+ Util::pipe($this, $dest, $options);
+
+ return $dest;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/TestCase.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/TestCase.php
new file mode 100644
index 0000000..c8fc1db
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/TestCase.php
@@ -0,0 +1,54 @@
+<?php
+
+namespace React\Tests\Stream;
+
+use PHPUnit\Framework\TestCase as BaseTestCase;
+
+class TestCase extends BaseTestCase
+{
+ protected function expectCallableExactly($amount)
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->exactly($amount))
+ ->method('__invoke');
+
+ return $mock;
+ }
+
+ protected function expectCallableOnce()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->once())
+ ->method('__invoke');
+
+ return $mock;
+ }
+
+ protected function expectCallableOnceWith($value)
+ {
+ $callback = $this->createCallableMock();
+ $callback
+ ->expects($this->once())
+ ->method('__invoke')
+ ->with($value);
+
+ return $callback;
+ }
+
+ protected function expectCallableNever()
+ {
+ $mock = $this->createCallableMock();
+ $mock
+ ->expects($this->never())
+ ->method('__invoke');
+
+ return $mock;
+ }
+
+ protected function createCallableMock()
+ {
+ return $this->getMockBuilder('React\Tests\Stream\CallableStub')->getMock();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/ThroughStreamTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/ThroughStreamTest.php
new file mode 100644
index 0000000..a98badf
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/ThroughStreamTest.php
@@ -0,0 +1,267 @@
+<?php
+
+namespace React\Tests\Stream;
+
+use React\Stream\ThroughStream;
+
+/**
+ * @covers React\Stream\ThroughStream
+ */
+class ThroughStreamTest extends TestCase
+{
+ /**
+ * @test
+ * @expectedException InvalidArgumentException
+ */
+ public function itShouldRejectInvalidCallback()
+ {
+ new ThroughStream(123);
+ }
+
+ /** @test */
+ public function itShouldReturnTrueForAnyDataWrittenToIt()
+ {
+ $through = new ThroughStream();
+ $ret = $through->write('foo');
+
+ $this->assertTrue($ret);
+ }
+
+ /** @test */
+ public function itShouldEmitAnyDataWrittenToIt()
+ {
+ $through = new ThroughStream();
+ $through->on('data', $this->expectCallableOnceWith('foo'));
+ $through->write('foo');
+ }
+
+ /** @test */
+ public function itShouldEmitAnyDataWrittenToItPassedThruFunction()
+ {
+ $through = new ThroughStream('strtoupper');
+ $through->on('data', $this->expectCallableOnceWith('FOO'));
+ $through->write('foo');
+ }
+
+ /** @test */
+ public function itShouldEmitAnyDataWrittenToItPassedThruCallback()
+ {
+ $through = new ThroughStream('strtoupper');
+ $through->on('data', $this->expectCallableOnceWith('FOO'));
+ $through->write('foo');
+ }
+
+ /** @test */
+ public function itShouldEmitErrorAndCloseIfCallbackThrowsException()
+ {
+ $through = new ThroughStream(function () {
+ throw new \RuntimeException();
+ });
+ $through->on('error', $this->expectCallableOnce());
+ $through->on('close', $this->expectCallableOnce());
+ $through->on('data', $this->expectCallableNever());
+ $through->on('end', $this->expectCallableNever());
+
+ $through->write('foo');
+
+ $this->assertFalse($through->isReadable());
+ $this->assertFalse($through->isWritable());
+ }
+
+ /** @test */
+ public function itShouldEmitErrorAndCloseIfCallbackThrowsExceptionOnEnd()
+ {
+ $through = new ThroughStream(function () {
+ throw new \RuntimeException();
+ });
+ $through->on('error', $this->expectCallableOnce());
+ $through->on('close', $this->expectCallableOnce());
+ $through->on('data', $this->expectCallableNever());
+ $through->on('end', $this->expectCallableNever());
+
+ $through->end('foo');
+
+ $this->assertFalse($through->isReadable());
+ $this->assertFalse($through->isWritable());
+ }
+
+ /** @test */
+ public function itShouldReturnFalseForAnyDataWrittenToItWhenPaused()
+ {
+ $through = new ThroughStream();
+ $through->pause();
+ $ret = $through->write('foo');
+
+ $this->assertFalse($ret);
+ }
+
+ /** @test */
+ public function itShouldEmitDrainOnResumeAfterReturnFalseForAnyDataWrittenToItWhenPaused()
+ {
+ $through = new ThroughStream();
+ $through->pause();
+ $through->write('foo');
+
+ $through->on('drain', $this->expectCallableOnce());
+ $through->resume();
+ }
+
+ /** @test */
+ public function itShouldReturnTrueForAnyDataWrittenToItWhenResumedAfterPause()
+ {
+ $through = new ThroughStream();
+ $through->on('drain', $this->expectCallableNever());
+ $through->pause();
+ $through->resume();
+ $ret = $through->write('foo');
+
+ $this->assertTrue($ret);
+ }
+
+ /** @test */
+ public function pipingStuffIntoItShouldWork()
+ {
+ $readable = new ThroughStream();
+
+ $through = new ThroughStream();
+ $through->on('data', $this->expectCallableOnceWith('foo'));
+
+ $readable->pipe($through);
+ $readable->emit('data', array('foo'));
+ }
+
+ /** @test */
+ public function endShouldEmitEndAndClose()
+ {
+ $through = new ThroughStream();
+ $through->on('data', $this->expectCallableNever());
+ $through->on('end', $this->expectCallableOnce());
+ $through->on('close', $this->expectCallableOnce());
+ $through->end();
+ }
+
+ /** @test */
+ public function endShouldCloseTheStream()
+ {
+ $through = new ThroughStream();
+ $through->on('data', $this->expectCallableNever());
+ $through->end();
+
+ $this->assertFalse($through->isReadable());
+ $this->assertFalse($through->isWritable());
+ }
+
+ /** @test */
+ public function endShouldWriteDataBeforeClosing()
+ {
+ $through = new ThroughStream();
+ $through->on('data', $this->expectCallableOnceWith('foo'));
+ $through->end('foo');
+
+ $this->assertFalse($through->isReadable());
+ $this->assertFalse($through->isWritable());
+ }
+
+ /** @test */
+ public function endTwiceShouldOnlyEmitOnce()
+ {
+ $through = new ThroughStream();
+ $through->on('data', $this->expectCallableOnce('first'));
+ $through->end('first');
+ $through->end('ignored');
+ }
+
+ /** @test */
+ public function writeAfterEndShouldReturnFalse()
+ {
+ $through = new ThroughStream();
+ $through->on('data', $this->expectCallableNever());
+ $through->end();
+
+ $this->assertFalse($through->write('foo'));
+ }
+
+ /** @test */
+ public function writeDataWillCloseStreamShouldReturnFalse()
+ {
+ $through = new ThroughStream();
+ $through->on('data', array($through, 'close'));
+
+ $this->assertFalse($through->write('foo'));
+ }
+
+ /** @test */
+ public function writeDataToPausedShouldReturnFalse()
+ {
+ $through = new ThroughStream();
+ $through->pause();
+
+ $this->assertFalse($through->write('foo'));
+ }
+
+ /** @test */
+ public function writeDataToResumedShouldReturnTrue()
+ {
+ $through = new ThroughStream();
+ $through->pause();
+ $through->resume();
+
+ $this->assertTrue($through->write('foo'));
+ }
+
+ /** @test */
+ public function itShouldBeReadableByDefault()
+ {
+ $through = new ThroughStream();
+ $this->assertTrue($through->isReadable());
+ }
+
+ /** @test */
+ public function itShouldBeWritableByDefault()
+ {
+ $through = new ThroughStream();
+ $this->assertTrue($through->isWritable());
+ }
+
+ /** @test */
+ public function closeShouldCloseOnce()
+ {
+ $through = new ThroughStream();
+
+ $through->on('close', $this->expectCallableOnce());
+
+ $through->close();
+
+ $this->assertFalse($through->isReadable());
+ $this->assertFalse($through->isWritable());
+ }
+
+ /** @test */
+ public function doubleCloseShouldCloseOnce()
+ {
+ $through = new ThroughStream();
+
+ $through->on('close', $this->expectCallableOnce());
+
+ $through->close();
+ $through->close();
+
+ $this->assertFalse($through->isReadable());
+ $this->assertFalse($through->isWritable());
+ }
+
+ /** @test */
+ public function pipeShouldPipeCorrectly()
+ {
+ $output = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock();
+ $output->expects($this->any())->method('isWritable')->willReturn(True);
+ $output
+ ->expects($this->once())
+ ->method('write')
+ ->with('foo');
+
+ $through = new ThroughStream();
+ $through->pipe($output);
+ $through->write('foo');
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/UtilTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/UtilTest.php
new file mode 100644
index 0000000..3d113ab
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/UtilTest.php
@@ -0,0 +1,273 @@
+<?php
+
+namespace React\Tests\Stream;
+
+use React\Stream\WritableResourceStream;
+use React\Stream\Util;
+use React\Stream\CompositeStream;
+use React\Stream\ThroughStream;
+
+/**
+ * @covers React\Stream\Util
+ */
+class UtilTest extends TestCase
+{
+ public function testPipeReturnsDestinationStream()
+ {
+ $readable = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock();
+
+ $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock();
+
+ $ret = Util::pipe($readable, $writable);
+
+ $this->assertSame($writable, $ret);
+ }
+
+ public function testPipeNonReadableSourceShouldDoNothing()
+ {
+ $readable = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock();
+ $readable
+ ->expects($this->any())
+ ->method('isReadable')
+ ->willReturn(false);
+
+ $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock();
+ $writable
+ ->expects($this->never())
+ ->method('isWritable');
+ $writable
+ ->expects($this->never())
+ ->method('end');
+
+ Util::pipe($readable, $writable);
+ }
+
+ public function testPipeIntoNonWritableDestinationShouldPauseSource()
+ {
+ $readable = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock();
+ $readable
+ ->expects($this->any())
+ ->method('isReadable')
+ ->willReturn(true);
+ $readable
+ ->expects($this->once())
+ ->method('pause');
+
+ $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock();
+ $writable
+ ->expects($this->any())
+ ->method('isWritable')
+ ->willReturn(false);
+ $writable
+ ->expects($this->never())
+ ->method('end');
+
+ Util::pipe($readable, $writable);
+ }
+
+ public function testPipeClosingDestPausesSource()
+ {
+ $readable = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock();
+ $readable
+ ->expects($this->any())
+ ->method('isReadable')
+ ->willReturn(true);
+ $readable
+ ->expects($this->once())
+ ->method('pause');
+
+ $writable = new ThroughStream();
+
+ Util::pipe($readable, $writable);
+
+ $writable->close();
+ }
+
+ public function testPipeWithEnd()
+ {
+ $readable = new Stub\ReadableStreamStub();
+
+ $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock();
+ $writable
+ ->expects($this->any())
+ ->method('isWritable')
+ ->willReturn(true);
+ $writable
+ ->expects($this->once())
+ ->method('end');
+
+ Util::pipe($readable, $writable);
+
+ $readable->end();
+ }
+
+ public function testPipeWithoutEnd()
+ {
+ $readable = new Stub\ReadableStreamStub();
+
+ $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock();
+ $writable
+ ->expects($this->any())
+ ->method('isWritable')
+ ->willReturn(true);
+ $writable
+ ->expects($this->never())
+ ->method('end');
+
+ Util::pipe($readable, $writable, array('end' => false));
+
+ $readable->end();
+ }
+
+ public function testPipeWithTooSlowWritableShouldPauseReadable()
+ {
+ $readable = new Stub\ReadableStreamStub();
+
+ $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock();
+ $writable
+ ->expects($this->any())
+ ->method('isWritable')
+ ->willReturn(true);
+ $writable
+ ->expects($this->once())
+ ->method('write')
+ ->with('some data')
+ ->will($this->returnValue(false));
+
+ $readable->pipe($writable);
+
+ $this->assertFalse($readable->paused);
+ $readable->write('some data');
+ $this->assertTrue($readable->paused);
+ }
+
+ public function testPipeWithTooSlowWritableShouldResumeOnDrain()
+ {
+ $readable = new Stub\ReadableStreamStub();
+
+ $onDrain = null;
+
+ $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock();
+ $writable
+ ->expects($this->any())
+ ->method('isWritable')
+ ->willReturn(true);
+ $writable
+ ->expects($this->any())
+ ->method('on')
+ ->will($this->returnCallback(function ($name, $callback) use (&$onDrain) {
+ if ($name === 'drain') {
+ $onDrain = $callback;
+ }
+ }));
+
+ $readable->pipe($writable);
+ $readable->pause();
+
+ $this->assertTrue($readable->paused);
+ $this->assertNotNull($onDrain);
+ $onDrain();
+ $this->assertFalse($readable->paused);
+ }
+
+ public function testPipeWithWritableResourceStream()
+ {
+ $readable = new Stub\ReadableStreamStub();
+
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+ $buffer = new WritableResourceStream($stream, $loop);
+
+ $readable->pipe($buffer);
+
+ $readable->write('hello, I am some ');
+ $readable->write('random data');
+
+ $buffer->handleWrite();
+ rewind($stream);
+ $this->assertSame('hello, I am some random data', stream_get_contents($stream));
+ }
+
+ public function testPipeSetsUpListeners()
+ {
+ $source = new ThroughStream();
+ $dest = new ThroughStream();
+
+ $this->assertCount(0, $source->listeners('data'));
+ $this->assertCount(0, $source->listeners('end'));
+ $this->assertCount(0, $dest->listeners('drain'));
+
+ Util::pipe($source, $dest);
+
+ $this->assertCount(1, $source->listeners('data'));
+ $this->assertCount(1, $source->listeners('end'));
+ $this->assertCount(1, $dest->listeners('drain'));
+ }
+
+ public function testPipeClosingSourceRemovesListeners()
+ {
+ $source = new ThroughStream();
+ $dest = new ThroughStream();
+
+ Util::pipe($source, $dest);
+
+ $source->close();
+
+ $this->assertCount(0, $source->listeners('data'));
+ $this->assertCount(0, $source->listeners('end'));
+ $this->assertCount(0, $dest->listeners('drain'));
+ }
+
+ public function testPipeClosingDestRemovesListeners()
+ {
+ $source = new ThroughStream();
+ $dest = new ThroughStream();
+
+ Util::pipe($source, $dest);
+
+ $dest->close();
+
+ $this->assertCount(0, $source->listeners('data'));
+ $this->assertCount(0, $source->listeners('end'));
+ $this->assertCount(0, $dest->listeners('drain'));
+ }
+
+ public function testPipeDuplexIntoSelfEndsOnEnd()
+ {
+ $readable = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock();
+ $readable->expects($this->any())->method('isReadable')->willReturn(true);
+ $writable = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock();
+ $writable->expects($this->any())->method('isWritable')->willReturn(true);
+ $duplex = new CompositeStream($readable, $writable);
+
+ Util::pipe($duplex, $duplex);
+
+ $writable->expects($this->once())->method('end');
+
+ $duplex->emit('end');
+ }
+
+ /** @test */
+ public function forwardEventsShouldSetupForwards()
+ {
+ $source = new ThroughStream();
+ $target = new ThroughStream();
+
+ Util::forwardEvents($source, $target, array('data'));
+ $target->on('data', $this->expectCallableOnce());
+ $target->on('foo', $this->expectCallableNever());
+
+ $source->emit('data', array('hello'));
+ $source->emit('foo', array('bar'));
+ }
+
+ private function createLoopMock()
+ {
+ return $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ }
+
+ private function notEqualTo($value)
+ {
+ return new \PHPUnit_Framework_Constraint_Not($value);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/WritableStreamResourceTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/WritableStreamResourceTest.php
new file mode 100644
index 0000000..05bce9c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/react/stream/tests/WritableStreamResourceTest.php
@@ -0,0 +1,534 @@
+<?php
+
+namespace React\Tests\Stream;
+
+use Clue\StreamFilter as Filter;
+use React\Stream\WritableResourceStream;
+
+class WritableResourceStreamTest extends TestCase
+{
+ /**
+ * @covers React\Stream\WritableResourceStream::__construct
+ * @doesNotPerformAssertions
+ */
+ public function testConstructor()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ new WritableResourceStream($stream, $loop);
+ }
+
+ /**
+ * @covers React\Stream\WritableResourceStream::__construct
+ * @doesNotPerformAssertions
+ */
+ public function testConstructorWithExcessiveMode()
+ {
+ // excessive flags are ignored for temp streams, so we have to use a file stream
+ $name = tempnam(sys_get_temp_dir(), 'test');
+ $stream = @fopen($name, 'w+eANYTHING');
+ unlink($name);
+
+ $loop = $this->createLoopMock();
+ $buffer = new WritableResourceStream($stream, $loop);
+ $buffer->close();
+ }
+
+ /**
+ * @covers React\Stream\WritableResourceStream::__construct
+ * @expectedException InvalidArgumentException
+ */
+ public function testConstructorThrowsIfNotAValidStreamResource()
+ {
+ $stream = null;
+ $loop = $this->createLoopMock();
+
+ new WritableResourceStream($stream, $loop);
+ }
+
+ /**
+ * @covers React\Stream\WritableResourceStream::__construct
+ * @expectedException InvalidArgumentException
+ */
+ public function testConstructorThrowsExceptionOnReadOnlyStream()
+ {
+ $stream = fopen('php://temp', 'r');
+ $loop = $this->createLoopMock();
+
+ new WritableResourceStream($stream, $loop);
+ }
+
+ /**
+ * @covers React\Stream\WritableResourceStream::__construct
+ * @expectedException InvalidArgumentException
+ */
+ public function testConstructorThrowsExceptionOnReadOnlyStreamWithExcessiveMode()
+ {
+ // excessive flags are ignored for temp streams, so we have to use a file stream
+ $name = tempnam(sys_get_temp_dir(), 'test');
+ $stream = fopen($name, 'reANYTHING');
+ unlink($name);
+
+ $loop = $this->createLoopMock();
+ new WritableResourceStream($stream, $loop);
+ }
+
+ /**
+ * @covers React\Stream\WritableResourceStream::__construct
+ * @expectedException RuntimeException
+ */
+ public function testConstructorThrowsExceptionIfStreamDoesNotSupportNonBlocking()
+ {
+ if (!in_array('blocking', stream_get_wrappers())) {
+ stream_wrapper_register('blocking', 'React\Tests\Stream\EnforceBlockingWrapper');
+ }
+
+ $stream = fopen('blocking://test', 'r+');
+ $loop = $this->createLoopMock();
+
+ new WritableResourceStream($stream, $loop);
+ }
+
+ /**
+ * @covers React\Stream\WritableResourceStream::write
+ * @covers React\Stream\WritableResourceStream::handleWrite
+ */
+ public function testWrite()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createWriteableLoopMock();
+
+ $buffer = new WritableResourceStream($stream, $loop);
+ $buffer->on('error', $this->expectCallableNever());
+
+ $buffer->write("foobar\n");
+ rewind($stream);
+ $this->assertSame("foobar\n", fread($stream, 1024));
+ }
+
+ /**
+ * @covers React\Stream\WritableResourceStream::write
+ */
+ public function testWriteWithDataDoesAddResourceToLoop()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+ $loop->expects($this->once())->method('addWriteStream')->with($this->equalTo($stream));
+
+ $buffer = new WritableResourceStream($stream, $loop);
+
+ $buffer->write("foobar\n");
+ }
+
+ /**
+ * @covers React\Stream\WritableResourceStream::write
+ * @covers React\Stream\WritableResourceStream::handleWrite
+ */
+ public function testEmptyWriteDoesNotAddToLoop()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+ $loop->expects($this->never())->method('addWriteStream');
+
+ $buffer = new WritableResourceStream($stream, $loop);
+
+ $buffer->write("");
+ $buffer->write(null);
+ }
+
+ /**
+ * @covers React\Stream\WritableResourceStream::write
+ * @covers React\Stream\WritableResourceStream::handleWrite
+ */
+ public function testWriteReturnsFalseWhenWritableResourceStreamIsFull()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createWriteableLoopMock();
+ $loop->preventWrites = true;
+
+ $buffer = new WritableResourceStream($stream, $loop, 4);
+ $buffer->on('error', $this->expectCallableNever());
+
+ $this->assertTrue($buffer->write("foo"));
+ $loop->preventWrites = false;
+ $this->assertFalse($buffer->write("bar\n"));
+ }
+
+ /**
+ * @covers React\Stream\WritableResourceStream::write
+ */
+ public function testWriteReturnsFalseWhenWritableResourceStreamIsExactlyFull()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $buffer = new WritableResourceStream($stream, $loop, 3);
+
+ $this->assertFalse($buffer->write("foo"));
+ }
+
+ /**
+ * @covers React\Stream\WritableResourceStream::write
+ * @covers React\Stream\WritableResourceStream::handleWrite
+ */
+ public function testWriteDetectsWhenOtherSideIsClosed()
+ {
+ list($a, $b) = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
+
+ $loop = $this->createWriteableLoopMock();
+
+ $buffer = new WritableResourceStream($a, $loop, 4);
+ $buffer->on('error', $this->expectCallableOnce());
+
+ fclose($b);
+
+ $buffer->write("foo");
+ }
+
+ /**
+ * @covers React\Stream\WritableResourceStream::write
+ * @covers React\Stream\WritableResourceStream::handleWrite
+ */
+ public function testEmitsDrainAfterWriteWhichExceedsBuffer()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $buffer = new WritableResourceStream($stream, $loop, 2);
+ $buffer->on('error', $this->expectCallableNever());
+ $buffer->on('drain', $this->expectCallableOnce());
+
+ $buffer->write("foo");
+ $buffer->handleWrite();
+ }
+
+ /**
+ * @covers React\Stream\WritableResourceStream::write
+ * @covers React\Stream\WritableResourceStream::handleWrite
+ */
+ public function testWriteInDrain()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $buffer = new WritableResourceStream($stream, $loop, 2);
+ $buffer->on('error', $this->expectCallableNever());
+
+ $buffer->once('drain', function () use ($buffer) {
+ $buffer->write("bar\n");
+ $buffer->handleWrite();
+ });
+
+ $this->assertFalse($buffer->write("foo\n"));
+ $buffer->handleWrite();
+
+ fseek($stream, 0);
+ $this->assertSame("foo\nbar\n", stream_get_contents($stream));
+ }
+
+ /**
+ * @covers React\Stream\WritableResourceStream::write
+ * @covers React\Stream\WritableResourceStream::handleWrite
+ */
+ public function testDrainAfterWrite()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $buffer = new WritableResourceStream($stream, $loop, 2);
+
+ $buffer->on('drain', $this->expectCallableOnce());
+
+ $buffer->write("foo");
+ $buffer->handleWrite();
+ }
+
+ /**
+ * @covers React\Stream\WritableResourceStream::handleWrite
+ */
+ public function testDrainAfterWriteWillRemoveResourceFromLoopWithoutClosing()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+ $loop->expects($this->once())->method('removeWriteStream')->with($stream);
+
+ $buffer = new WritableResourceStream($stream, $loop, 2);
+
+ $buffer->on('drain', $this->expectCallableOnce());
+
+ $buffer->on('close', $this->expectCallableNever());
+
+ $buffer->write("foo");
+ $buffer->handleWrite();
+ }
+
+ /**
+ * @covers React\Stream\WritableResourceStream::handleWrite
+ */
+ public function testClosingDuringDrainAfterWriteWillRemoveResourceFromLoopOnceAndClose()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+ $loop->expects($this->once())->method('removeWriteStream')->with($stream);
+
+ $buffer = new WritableResourceStream($stream, $loop, 2);
+
+ $buffer->on('drain', function () use ($buffer) {
+ $buffer->close();
+ });
+
+ $buffer->on('close', $this->expectCallableOnce());
+
+ $buffer->write("foo");
+ $buffer->handleWrite();
+ }
+
+ /**
+ * @covers React\Stream\WritableResourceStream::end
+ */
+ public function testEndWithoutDataClosesImmediatelyIfWritableResourceStreamIsEmpty()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $buffer = new WritableResourceStream($stream, $loop);
+ $buffer->on('error', $this->expectCallableNever());
+ $buffer->on('close', $this->expectCallableOnce());
+
+ $this->assertTrue($buffer->isWritable());
+ $buffer->end();
+ $this->assertFalse($buffer->isWritable());
+ }
+
+ /**
+ * @covers React\Stream\WritableResourceStream::end
+ */
+ public function testEndWithoutDataDoesNotCloseIfWritableResourceStreamIsFull()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $buffer = new WritableResourceStream($stream, $loop);
+ $buffer->on('error', $this->expectCallableNever());
+ $buffer->on('close', $this->expectCallableNever());
+
+ $buffer->write('foo');
+
+ $this->assertTrue($buffer->isWritable());
+ $buffer->end();
+ $this->assertFalse($buffer->isWritable());
+ }
+
+ /**
+ * @covers React\Stream\WritableResourceStream::end
+ */
+ public function testEndWithDataClosesImmediatelyIfWritableResourceStreamFlushes()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $filterBuffer = '';
+ $loop = $this->createLoopMock();
+
+ $buffer = new WritableResourceStream($stream, $loop);
+ $buffer->on('error', $this->expectCallableNever());
+ $buffer->on('close', $this->expectCallableOnce());
+
+ Filter\append($stream, function ($chunk) use (&$filterBuffer) {
+ $filterBuffer .= $chunk;
+ return $chunk;
+ });
+
+ $this->assertTrue($buffer->isWritable());
+ $buffer->end('final words');
+ $this->assertFalse($buffer->isWritable());
+
+ $buffer->handleWrite();
+ $this->assertSame('final words', $filterBuffer);
+ }
+
+ /**
+ * @covers React\Stream\WritableResourceStream::end
+ */
+ public function testEndWithDataDoesNotCloseImmediatelyIfWritableResourceStreamIsFull()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $buffer = new WritableResourceStream($stream, $loop);
+ $buffer->on('error', $this->expectCallableNever());
+ $buffer->on('close', $this->expectCallableNever());
+
+ $buffer->write('foo');
+
+ $this->assertTrue($buffer->isWritable());
+ $buffer->end('final words');
+ $this->assertFalse($buffer->isWritable());
+
+ rewind($stream);
+ $this->assertSame('', stream_get_contents($stream));
+ }
+
+ /**
+ * @covers React\Stream\WritableResourceStream::isWritable
+ * @covers React\Stream\WritableResourceStream::close
+ */
+ public function testClose()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $buffer = new WritableResourceStream($stream, $loop);
+ $buffer->on('error', $this->expectCallableNever());
+ $buffer->on('close', $this->expectCallableOnce());
+
+ $this->assertTrue($buffer->isWritable());
+ $buffer->close();
+ $this->assertFalse($buffer->isWritable());
+
+ $this->assertEquals(array(), $buffer->listeners('close'));
+ }
+
+ /**
+ * @covers React\Stream\WritableResourceStream::close
+ */
+ public function testClosingAfterWriteRemovesStreamFromLoop()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+ $buffer = new WritableResourceStream($stream, $loop);
+
+ $loop->expects($this->once())->method('removeWriteStream')->with($stream);
+
+ $buffer->write('foo');
+ $buffer->close();
+ }
+
+ /**
+ * @covers React\Stream\WritableResourceStream::close
+ */
+ public function testClosingWithoutWritingDoesNotRemoveStreamFromLoop()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+ $buffer = new WritableResourceStream($stream, $loop);
+
+ $loop->expects($this->never())->method('removeWriteStream');
+
+ $buffer->close();
+ }
+
+ /**
+ * @covers React\Stream\WritableResourceStream::close
+ */
+ public function testDoubleCloseWillEmitOnlyOnce()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createLoopMock();
+
+ $buffer = new WritableResourceStream($stream, $loop);
+ $buffer->on('close', $this->expectCallableOnce());
+
+ $buffer->close();
+ $buffer->close();
+ }
+
+ /**
+ * @covers React\Stream\WritableResourceStream::write
+ * @covers React\Stream\WritableResourceStream::close
+ */
+ public function testWritingToClosedWritableResourceStreamShouldNotWriteToStream()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $filterBuffer = '';
+ $loop = $this->createLoopMock();
+
+ $buffer = new WritableResourceStream($stream, $loop);
+
+ Filter\append($stream, function ($chunk) use (&$filterBuffer) {
+ $filterBuffer .= $chunk;
+ return $chunk;
+ });
+
+ $buffer->close();
+
+ $buffer->write('foo');
+
+ $buffer->handleWrite();
+ $this->assertSame('', $filterBuffer);
+ }
+
+ /**
+ * @covers React\Stream\WritableResourceStream::handleWrite
+ */
+ public function testErrorWhenStreamResourceIsInvalid()
+ {
+ $stream = fopen('php://temp', 'r+');
+ $loop = $this->createWriteableLoopMock();
+
+ $error = null;
+
+ $buffer = new WritableResourceStream($stream, $loop);
+ $buffer->on('error', function ($message) use (&$error) {
+ $error = $message;
+ });
+
+ // invalidate stream resource
+ fclose($stream);
+
+ $buffer->write('Attempting to write to bad stream');
+
+ $this->assertInstanceOf('Exception', $error);
+
+ // the error messages differ between PHP versions, let's just check substrings
+ $this->assertContains('Unable to write to stream: ', $error->getMessage());
+ $this->assertContains(' not a valid stream resource', $error->getMessage(), '', true);
+ }
+
+ public function testWritingToClosedStream()
+ {
+ if ('Darwin' === PHP_OS) {
+ $this->markTestSkipped('OS X issue with shutting down pair for writing');
+ }
+
+ list($a, $b) = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
+ $loop = $this->createLoopMock();
+
+ $error = null;
+
+ $buffer = new WritableResourceStream($a, $loop);
+ $buffer->on('error', function($message) use (&$error) {
+ $error = $message;
+ });
+
+ $buffer->write('foo');
+ $buffer->handleWrite();
+ stream_socket_shutdown($b, STREAM_SHUT_RD);
+ stream_socket_shutdown($a, STREAM_SHUT_RD);
+ $buffer->write('bar');
+ $buffer->handleWrite();
+
+ $this->assertInstanceOf('Exception', $error);
+ $this->assertSame('Unable to write to stream: fwrite(): send of 3 bytes failed with errno=32 Broken pipe', $error->getMessage());
+ }
+
+ private function createWriteableLoopMock()
+ {
+ $loop = $this->createLoopMock();
+ $loop->preventWrites = false;
+ $loop
+ ->expects($this->any())
+ ->method('addWriteStream')
+ ->will($this->returnCallback(function ($stream, $listener) use ($loop) {
+ if (!$loop->preventWrites) {
+ call_user_func($listener, $stream);
+ }
+ }));
+
+ return $loop;
+ }
+
+ private function createLoopMock()
+ {
+ return $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/.gitignore b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/.gitignore
new file mode 100644
index 0000000..c49a5d8
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/.gitignore
@@ -0,0 +1,3 @@
+vendor/
+composer.lock
+phpunit.xml
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/AcceptHeader.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/AcceptHeader.php
new file mode 100644
index 0000000..d174026
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/AcceptHeader.php
@@ -0,0 +1,168 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * Represents an Accept-* header.
+ *
+ * An accept header is compound with a list of items,
+ * sorted by descending quality.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class AcceptHeader
+{
+ /**
+ * @var AcceptHeaderItem[]
+ */
+ private $items = array();
+
+ /**
+ * @var bool
+ */
+ private $sorted = true;
+
+ /**
+ * @param AcceptHeaderItem[] $items
+ */
+ public function __construct(array $items)
+ {
+ foreach ($items as $item) {
+ $this->add($item);
+ }
+ }
+
+ /**
+ * Builds an AcceptHeader instance from a string.
+ *
+ * @param string $headerValue
+ *
+ * @return self
+ */
+ public static function fromString($headerValue)
+ {
+ $index = 0;
+
+ return new self(array_map(function ($itemValue) use (&$index) {
+ $item = AcceptHeaderItem::fromString($itemValue);
+ $item->setIndex($index++);
+
+ return $item;
+ }, preg_split('/\s*(?:,*("[^"]+"),*|,*(\'[^\']+\'),*|,+)\s*/', $headerValue, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE)));
+ }
+
+ /**
+ * Returns header value's string representation.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return implode(',', $this->items);
+ }
+
+ /**
+ * Tests if header has given value.
+ *
+ * @param string $value
+ *
+ * @return bool
+ */
+ public function has($value)
+ {
+ return isset($this->items[$value]);
+ }
+
+ /**
+ * Returns given value's item, if exists.
+ *
+ * @param string $value
+ *
+ * @return AcceptHeaderItem|null
+ */
+ public function get($value)
+ {
+ return isset($this->items[$value]) ? $this->items[$value] : null;
+ }
+
+ /**
+ * Adds an item.
+ *
+ * @return $this
+ */
+ public function add(AcceptHeaderItem $item)
+ {
+ $this->items[$item->getValue()] = $item;
+ $this->sorted = false;
+
+ return $this;
+ }
+
+ /**
+ * Returns all items.
+ *
+ * @return AcceptHeaderItem[]
+ */
+ public function all()
+ {
+ $this->sort();
+
+ return $this->items;
+ }
+
+ /**
+ * Filters items on their value using given regex.
+ *
+ * @param string $pattern
+ *
+ * @return self
+ */
+ public function filter($pattern)
+ {
+ return new self(array_filter($this->items, function (AcceptHeaderItem $item) use ($pattern) {
+ return preg_match($pattern, $item->getValue());
+ }));
+ }
+
+ /**
+ * Returns first item.
+ *
+ * @return AcceptHeaderItem|null
+ */
+ public function first()
+ {
+ $this->sort();
+
+ return !empty($this->items) ? reset($this->items) : null;
+ }
+
+ /**
+ * Sorts items by descending quality.
+ */
+ private function sort()
+ {
+ if (!$this->sorted) {
+ uasort($this->items, function (AcceptHeaderItem $a, AcceptHeaderItem $b) {
+ $qA = $a->getQuality();
+ $qB = $b->getQuality();
+
+ if ($qA === $qB) {
+ return $a->getIndex() > $b->getIndex() ? 1 : -1;
+ }
+
+ return $qA > $qB ? -1 : 1;
+ });
+
+ $this->sorted = true;
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/AcceptHeaderItem.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/AcceptHeaderItem.php
new file mode 100644
index 0000000..c69dbbb
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/AcceptHeaderItem.php
@@ -0,0 +1,209 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * Represents an Accept-* header item.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class AcceptHeaderItem
+{
+ private $value;
+ private $quality = 1.0;
+ private $index = 0;
+ private $attributes = array();
+
+ /**
+ * @param string $value
+ * @param array $attributes
+ */
+ public function __construct($value, array $attributes = array())
+ {
+ $this->value = $value;
+ foreach ($attributes as $name => $value) {
+ $this->setAttribute($name, $value);
+ }
+ }
+
+ /**
+ * Builds an AcceptHeaderInstance instance from a string.
+ *
+ * @param string $itemValue
+ *
+ * @return self
+ */
+ public static function fromString($itemValue)
+ {
+ $bits = preg_split('/\s*(?:;*("[^"]+");*|;*(\'[^\']+\');*|;+)\s*/', $itemValue, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
+ $value = array_shift($bits);
+ $attributes = array();
+
+ $lastNullAttribute = null;
+ foreach ($bits as $bit) {
+ if (($start = substr($bit, 0, 1)) === ($end = substr($bit, -1)) && ('"' === $start || '\'' === $start)) {
+ $attributes[$lastNullAttribute] = substr($bit, 1, -1);
+ } elseif ('=' === $end) {
+ $lastNullAttribute = $bit = substr($bit, 0, -1);
+ $attributes[$bit] = null;
+ } else {
+ $parts = explode('=', $bit);
+ $attributes[$parts[0]] = isset($parts[1]) && strlen($parts[1]) > 0 ? $parts[1] : '';
+ }
+ }
+
+ return new self(($start = substr($value, 0, 1)) === ($end = substr($value, -1)) && ('"' === $start || '\'' === $start) ? substr($value, 1, -1) : $value, $attributes);
+ }
+
+ /**
+ * Returns header value's string representation.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ $string = $this->value.($this->quality < 1 ? ';q='.$this->quality : '');
+ if (count($this->attributes) > 0) {
+ $string .= ';'.implode(';', array_map(function ($name, $value) {
+ return sprintf(preg_match('/[,;=]/', $value) ? '%s="%s"' : '%s=%s', $name, $value);
+ }, array_keys($this->attributes), $this->attributes));
+ }
+
+ return $string;
+ }
+
+ /**
+ * Set the item value.
+ *
+ * @param string $value
+ *
+ * @return $this
+ */
+ public function setValue($value)
+ {
+ $this->value = $value;
+
+ return $this;
+ }
+
+ /**
+ * Returns the item value.
+ *
+ * @return string
+ */
+ public function getValue()
+ {
+ return $this->value;
+ }
+
+ /**
+ * Set the item quality.
+ *
+ * @param float $quality
+ *
+ * @return $this
+ */
+ public function setQuality($quality)
+ {
+ $this->quality = $quality;
+
+ return $this;
+ }
+
+ /**
+ * Returns the item quality.
+ *
+ * @return float
+ */
+ public function getQuality()
+ {
+ return $this->quality;
+ }
+
+ /**
+ * Set the item index.
+ *
+ * @param int $index
+ *
+ * @return $this
+ */
+ public function setIndex($index)
+ {
+ $this->index = $index;
+
+ return $this;
+ }
+
+ /**
+ * Returns the item index.
+ *
+ * @return int
+ */
+ public function getIndex()
+ {
+ return $this->index;
+ }
+
+ /**
+ * Tests if an attribute exists.
+ *
+ * @param string $name
+ *
+ * @return bool
+ */
+ public function hasAttribute($name)
+ {
+ return isset($this->attributes[$name]);
+ }
+
+ /**
+ * Returns an attribute by its name.
+ *
+ * @param string $name
+ * @param mixed $default
+ *
+ * @return mixed
+ */
+ public function getAttribute($name, $default = null)
+ {
+ return isset($this->attributes[$name]) ? $this->attributes[$name] : $default;
+ }
+
+ /**
+ * Returns all attributes.
+ *
+ * @return array
+ */
+ public function getAttributes()
+ {
+ return $this->attributes;
+ }
+
+ /**
+ * Set an attribute.
+ *
+ * @param string $name
+ * @param string $value
+ *
+ * @return $this
+ */
+ public function setAttribute($name, $value)
+ {
+ if ('q' === $name) {
+ $this->quality = (float) $value;
+ } else {
+ $this->attributes[$name] = (string) $value;
+ }
+
+ return $this;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/ApacheRequest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/ApacheRequest.php
new file mode 100644
index 0000000..84803eb
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/ApacheRequest.php
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * Request represents an HTTP request from an Apache server.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ApacheRequest extends Request
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function prepareRequestUri()
+ {
+ return $this->server->get('REQUEST_URI');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function prepareBaseUrl()
+ {
+ $baseUrl = $this->server->get('SCRIPT_NAME');
+
+ if (false === strpos($this->server->get('REQUEST_URI'), $baseUrl)) {
+ // assume mod_rewrite
+ return rtrim(dirname($baseUrl), '/\\');
+ }
+
+ return $baseUrl;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/BinaryFileResponse.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/BinaryFileResponse.php
new file mode 100644
index 0000000..1010223
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/BinaryFileResponse.php
@@ -0,0 +1,359 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+use Symfony\Component\HttpFoundation\File\File;
+use Symfony\Component\HttpFoundation\File\Exception\FileException;
+
+/**
+ * BinaryFileResponse represents an HTTP response delivering a file.
+ *
+ * @author Niklas Fiekas <niklas.fiekas@tu-clausthal.de>
+ * @author stealth35 <stealth35-php@live.fr>
+ * @author Igor Wiedler <igor@wiedler.ch>
+ * @author Jordan Alliot <jordan.alliot@gmail.com>
+ * @author Sergey Linnik <linniksa@gmail.com>
+ */
+class BinaryFileResponse extends Response
+{
+ protected static $trustXSendfileTypeHeader = false;
+
+ /**
+ * @var File
+ */
+ protected $file;
+ protected $offset;
+ protected $maxlen;
+ protected $deleteFileAfterSend = false;
+
+ /**
+ * @param \SplFileInfo|string $file The file to stream
+ * @param int $status The response status code
+ * @param array $headers An array of response headers
+ * @param bool $public Files are public by default
+ * @param null|string $contentDisposition The type of Content-Disposition to set automatically with the filename
+ * @param bool $autoEtag Whether the ETag header should be automatically set
+ * @param bool $autoLastModified Whether the Last-Modified header should be automatically set
+ */
+ public function __construct($file, $status = 200, $headers = array(), $public = true, $contentDisposition = null, $autoEtag = false, $autoLastModified = true)
+ {
+ parent::__construct(null, $status, $headers);
+
+ $this->setFile($file, $contentDisposition, $autoEtag, $autoLastModified);
+
+ if ($public) {
+ $this->setPublic();
+ }
+ }
+
+ /**
+ * @param \SplFileInfo|string $file The file to stream
+ * @param int $status The response status code
+ * @param array $headers An array of response headers
+ * @param bool $public Files are public by default
+ * @param null|string $contentDisposition The type of Content-Disposition to set automatically with the filename
+ * @param bool $autoEtag Whether the ETag header should be automatically set
+ * @param bool $autoLastModified Whether the Last-Modified header should be automatically set
+ *
+ * @return static
+ */
+ public static function create($file = null, $status = 200, $headers = array(), $public = true, $contentDisposition = null, $autoEtag = false, $autoLastModified = true)
+ {
+ return new static($file, $status, $headers, $public, $contentDisposition, $autoEtag, $autoLastModified);
+ }
+
+ /**
+ * Sets the file to stream.
+ *
+ * @param \SplFileInfo|string $file The file to stream
+ * @param string $contentDisposition
+ * @param bool $autoEtag
+ * @param bool $autoLastModified
+ *
+ * @return $this
+ *
+ * @throws FileException
+ */
+ public function setFile($file, $contentDisposition = null, $autoEtag = false, $autoLastModified = true)
+ {
+ if (!$file instanceof File) {
+ if ($file instanceof \SplFileInfo) {
+ $file = new File($file->getPathname());
+ } else {
+ $file = new File((string) $file);
+ }
+ }
+
+ if (!$file->isReadable()) {
+ throw new FileException('File must be readable.');
+ }
+
+ $this->file = $file;
+
+ if ($autoEtag) {
+ $this->setAutoEtag();
+ }
+
+ if ($autoLastModified) {
+ $this->setAutoLastModified();
+ }
+
+ if ($contentDisposition) {
+ $this->setContentDisposition($contentDisposition);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Gets the file.
+ *
+ * @return File The file to stream
+ */
+ public function getFile()
+ {
+ return $this->file;
+ }
+
+ /**
+ * Automatically sets the Last-Modified header according the file modification date.
+ */
+ public function setAutoLastModified()
+ {
+ $this->setLastModified(\DateTime::createFromFormat('U', $this->file->getMTime()));
+
+ return $this;
+ }
+
+ /**
+ * Automatically sets the ETag header according to the checksum of the file.
+ */
+ public function setAutoEtag()
+ {
+ $this->setEtag(base64_encode(hash_file('sha256', $this->file->getPathname(), true)));
+
+ return $this;
+ }
+
+ /**
+ * Sets the Content-Disposition header with the given filename.
+ *
+ * @param string $disposition ResponseHeaderBag::DISPOSITION_INLINE or ResponseHeaderBag::DISPOSITION_ATTACHMENT
+ * @param string $filename Optionally use this UTF-8 encoded filename instead of the real name of the file
+ * @param string $filenameFallback A fallback filename, containing only ASCII characters. Defaults to an automatically encoded filename
+ *
+ * @return $this
+ */
+ public function setContentDisposition($disposition, $filename = '', $filenameFallback = '')
+ {
+ if ('' === $filename) {
+ $filename = $this->file->getFilename();
+ }
+
+ if ('' === $filenameFallback && (!preg_match('/^[\x20-\x7e]*$/', $filename) || false !== strpos($filename, '%'))) {
+ $encoding = mb_detect_encoding($filename, null, true) ?: '8bit';
+
+ for ($i = 0, $filenameLength = mb_strlen($filename, $encoding); $i < $filenameLength; ++$i) {
+ $char = mb_substr($filename, $i, 1, $encoding);
+
+ if ('%' === $char || ord($char) < 32 || ord($char) > 126) {
+ $filenameFallback .= '_';
+ } else {
+ $filenameFallback .= $char;
+ }
+ }
+ }
+
+ $dispositionHeader = $this->headers->makeDisposition($disposition, $filename, $filenameFallback);
+ $this->headers->set('Content-Disposition', $dispositionHeader);
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function prepare(Request $request)
+ {
+ if (!$this->headers->has('Content-Type')) {
+ $this->headers->set('Content-Type', $this->file->getMimeType() ?: 'application/octet-stream');
+ }
+
+ if ('HTTP/1.0' !== $request->server->get('SERVER_PROTOCOL')) {
+ $this->setProtocolVersion('1.1');
+ }
+
+ $this->ensureIEOverSSLCompatibility($request);
+
+ $this->offset = 0;
+ $this->maxlen = -1;
+
+ if (false === $fileSize = $this->file->getSize()) {
+ return $this;
+ }
+ $this->headers->set('Content-Length', $fileSize);
+
+ if (!$this->headers->has('Accept-Ranges')) {
+ // Only accept ranges on safe HTTP methods
+ $this->headers->set('Accept-Ranges', $request->isMethodSafe(false) ? 'bytes' : 'none');
+ }
+
+ if (self::$trustXSendfileTypeHeader && $request->headers->has('X-Sendfile-Type')) {
+ // Use X-Sendfile, do not send any content.
+ $type = $request->headers->get('X-Sendfile-Type');
+ $path = $this->file->getRealPath();
+ // Fall back to scheme://path for stream wrapped locations.
+ if (false === $path) {
+ $path = $this->file->getPathname();
+ }
+ if ('x-accel-redirect' === strtolower($type)) {
+ // Do X-Accel-Mapping substitutions.
+ // @link http://wiki.nginx.org/X-accel#X-Accel-Redirect
+ foreach (explode(',', $request->headers->get('X-Accel-Mapping', '')) as $mapping) {
+ $mapping = explode('=', $mapping, 2);
+
+ if (2 === count($mapping)) {
+ $pathPrefix = trim($mapping[0]);
+ $location = trim($mapping[1]);
+
+ if (substr($path, 0, strlen($pathPrefix)) === $pathPrefix) {
+ $path = $location.substr($path, strlen($pathPrefix));
+ break;
+ }
+ }
+ }
+ }
+ $this->headers->set($type, $path);
+ $this->maxlen = 0;
+ } elseif ($request->headers->has('Range')) {
+ // Process the range headers.
+ if (!$request->headers->has('If-Range') || $this->hasValidIfRangeHeader($request->headers->get('If-Range'))) {
+ $range = $request->headers->get('Range');
+
+ list($start, $end) = explode('-', substr($range, 6), 2) + array(0);
+
+ $end = ('' === $end) ? $fileSize - 1 : (int) $end;
+
+ if ('' === $start) {
+ $start = $fileSize - $end;
+ $end = $fileSize - 1;
+ } else {
+ $start = (int) $start;
+ }
+
+ if ($start <= $end) {
+ if ($start < 0 || $end > $fileSize - 1) {
+ $this->setStatusCode(416);
+ $this->headers->set('Content-Range', sprintf('bytes */%s', $fileSize));
+ } elseif (0 !== $start || $end !== $fileSize - 1) {
+ $this->maxlen = $end < $fileSize ? $end - $start + 1 : -1;
+ $this->offset = $start;
+
+ $this->setStatusCode(206);
+ $this->headers->set('Content-Range', sprintf('bytes %s-%s/%s', $start, $end, $fileSize));
+ $this->headers->set('Content-Length', $end - $start + 1);
+ }
+ }
+ }
+ }
+
+ return $this;
+ }
+
+ private function hasValidIfRangeHeader($header)
+ {
+ if ($this->getEtag() === $header) {
+ return true;
+ }
+
+ if (null === $lastModified = $this->getLastModified()) {
+ return false;
+ }
+
+ return $lastModified->format('D, d M Y H:i:s').' GMT' === $header;
+ }
+
+ /**
+ * Sends the file.
+ *
+ * {@inheritdoc}
+ */
+ public function sendContent()
+ {
+ if (!$this->isSuccessful()) {
+ return parent::sendContent();
+ }
+
+ if (0 === $this->maxlen) {
+ return $this;
+ }
+
+ $out = fopen('php://output', 'wb');
+ $file = fopen($this->file->getPathname(), 'rb');
+
+ stream_copy_to_stream($file, $out, $this->maxlen, $this->offset);
+
+ fclose($out);
+ fclose($file);
+
+ if ($this->deleteFileAfterSend) {
+ unlink($this->file->getPathname());
+ }
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @throws \LogicException when the content is not null
+ */
+ public function setContent($content)
+ {
+ if (null !== $content) {
+ throw new \LogicException('The content cannot be set on a BinaryFileResponse instance.');
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @return false
+ */
+ public function getContent()
+ {
+ return false;
+ }
+
+ /**
+ * Trust X-Sendfile-Type header.
+ */
+ public static function trustXSendfileTypeHeader()
+ {
+ self::$trustXSendfileTypeHeader = true;
+ }
+
+ /**
+ * If this is set to true, the file will be unlinked after the request is send
+ * Note: If the X-Sendfile header is used, the deleteFileAfterSend setting will not be used.
+ *
+ * @param bool $shouldDelete
+ *
+ * @return $this
+ */
+ public function deleteFileAfterSend($shouldDelete)
+ {
+ $this->deleteFileAfterSend = $shouldDelete;
+
+ return $this;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/CHANGELOG.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/CHANGELOG.md
new file mode 100644
index 0000000..ee5b6ce
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/CHANGELOG.md
@@ -0,0 +1,159 @@
+CHANGELOG
+=========
+
+3.4.0
+-----
+
+ * implemented PHP 7.0's `SessionUpdateTimestampHandlerInterface` with a new
+ `AbstractSessionHandler` base class and a new `StrictSessionHandler` wrapper
+ * deprecated the `WriteCheckSessionHandler`, `NativeSessionHandler` and `NativeProxy` classes
+ * deprecated setting session save handlers that do not implement `\SessionHandlerInterface` in `NativeSessionStorage::setSaveHandler()`
+ * deprecated using `MongoDbSessionHandler` with the legacy mongo extension; use it with the mongodb/mongodb package and ext-mongodb instead
+ * deprecated `MemcacheSessionHandler`; use `MemcachedSessionHandler` instead
+
+3.3.0
+-----
+
+ * the `Request::setTrustedProxies()` method takes a new `$trustedHeaderSet` argument,
+ see http://symfony.com/doc/current/components/http_foundation/trusting_proxies.html for more info,
+ * deprecated the `Request::setTrustedHeaderName()` and `Request::getTrustedHeaderName()` methods,
+ * added `File\Stream`, to be passed to `BinaryFileResponse` when the size of the served file is unknown,
+ disabling `Range` and `Content-Length` handling, switching to chunked encoding instead
+ * added the `Cookie::fromString()` method that allows to create a cookie from a
+ raw header string
+
+3.1.0
+-----
+
+ * Added support for creating `JsonResponse` with a string of JSON data
+
+3.0.0
+-----
+
+ * The precedence of parameters returned from `Request::get()` changed from "GET, PATH, BODY" to "PATH, GET, BODY"
+
+2.8.0
+-----
+
+ * Finding deep items in `ParameterBag::get()` is deprecated since version 2.8 and
+ will be removed in 3.0.
+
+2.6.0
+-----
+
+ * PdoSessionHandler changes
+ - implemented different session locking strategies to prevent loss of data by concurrent access to the same session
+ - [BC BREAK] save session data in a binary column without base64_encode
+ - [BC BREAK] added lifetime column to the session table which allows to have different lifetimes for each session
+ - implemented lazy connections that are only opened when a session is used by either passing a dsn string
+ explicitly or falling back to session.save_path ini setting
+ - added a createTable method that initializes a correctly defined table depending on the database vendor
+
+2.5.0
+-----
+
+ * added `JsonResponse::setEncodingOptions()` & `JsonResponse::getEncodingOptions()` for easier manipulation
+ of the options used while encoding data to JSON format.
+
+2.4.0
+-----
+
+ * added RequestStack
+ * added Request::getEncodings()
+ * added accessors methods to session handlers
+
+2.3.0
+-----
+
+ * added support for ranges of IPs in trusted proxies
+ * `UploadedFile::isValid` now returns false if the file was not uploaded via HTTP (in a non-test mode)
+ * Improved error-handling of `\Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler`
+ to ensure the supplied PDO handler throws Exceptions on error (as the class expects). Added related test cases
+ to verify that Exceptions are properly thrown when the PDO queries fail.
+
+2.2.0
+-----
+
+ * fixed the Request::create() precedence (URI information always take precedence now)
+ * added Request::getTrustedProxies()
+ * deprecated Request::isProxyTrusted()
+ * [BC BREAK] JsonResponse does not turn a top level empty array to an object anymore, use an ArrayObject to enforce objects
+ * added a IpUtils class to check if an IP belongs to a CIDR
+ * added Request::getRealMethod() to get the "real" HTTP method (getMethod() returns the "intended" HTTP method)
+ * disabled _method request parameter support by default (call Request::enableHttpMethodParameterOverride() to
+ enable it, and Request::getHttpMethodParameterOverride() to check if it is supported)
+ * Request::splitHttpAcceptHeader() method is deprecated and will be removed in 2.3
+ * Deprecated Flashbag::count() and \Countable interface, will be removed in 2.3
+
+2.1.0
+-----
+
+ * added Request::getSchemeAndHttpHost() and Request::getUserInfo()
+ * added a fluent interface to the Response class
+ * added Request::isProxyTrusted()
+ * added JsonResponse
+ * added a getTargetUrl method to RedirectResponse
+ * added support for streamed responses
+ * made Response::prepare() method the place to enforce HTTP specification
+ * [BC BREAK] moved management of the locale from the Session class to the Request class
+ * added a generic access to the PHP built-in filter mechanism: ParameterBag::filter()
+ * made FileBinaryMimeTypeGuesser command configurable
+ * added Request::getUser() and Request::getPassword()
+ * added support for the PATCH method in Request
+ * removed the ContentTypeMimeTypeGuesser class as it is deprecated and never used on PHP 5.3
+ * added ResponseHeaderBag::makeDisposition() (implements RFC 6266)
+ * made mimetype to extension conversion configurable
+ * [BC BREAK] Moved all session related classes and interfaces into own namespace, as
+ `Symfony\Component\HttpFoundation\Session` and renamed classes accordingly.
+ Session handlers are located in the subnamespace `Symfony\Component\HttpFoundation\Session\Handler`.
+ * SessionHandlers must implement `\SessionHandlerInterface` or extend from the
+ `Symfony\Component\HttpFoundation\Storage\Handler\NativeSessionHandler` base class.
+ * Added internal storage driver proxy mechanism for forward compatibility with
+ PHP 5.4 `\SessionHandler` class.
+ * Added session handlers for custom Memcache, Memcached and Null session save handlers.
+ * [BC BREAK] Removed `NativeSessionStorage` and replaced with `NativeFileSessionHandler`.
+ * [BC BREAK] `SessionStorageInterface` methods removed: `write()`, `read()` and
+ `remove()`. Added `getBag()`, `registerBag()`. The `NativeSessionStorage` class
+ is a mediator for the session storage internals including the session handlers
+ which do the real work of participating in the internal PHP session workflow.
+ * [BC BREAK] Introduced mock implementations of `SessionStorage` to enable unit
+ and functional testing without starting real PHP sessions. Removed
+ `ArraySessionStorage`, and replaced with `MockArraySessionStorage` for unit
+ tests; removed `FilesystemSessionStorage`, and replaced with`MockFileSessionStorage`
+ for functional tests. These do not interact with global session ini
+ configuration values, session functions or `$_SESSION` superglobal. This means
+ they can be configured directly allowing multiple instances to work without
+ conflicting in the same PHP process.
+ * [BC BREAK] Removed the `close()` method from the `Session` class, as this is
+ now redundant.
+ * Deprecated the following methods from the Session class: `setFlash()`, `setFlashes()`
+ `getFlash()`, `hasFlash()`, and `removeFlash()`. Use `getFlashBag()` instead
+ which returns a `FlashBagInterface`.
+ * `Session->clear()` now only clears session attributes as before it cleared
+ flash messages and attributes. `Session->getFlashBag()->all()` clears flashes now.
+ * Session data is now managed by `SessionBagInterface` to better encapsulate
+ session data.
+ * Refactored session attribute and flash messages system to their own
+ `SessionBagInterface` implementations.
+ * Added `FlashBag`. Flashes expire when retrieved by `get()` or `all()`. This
+ implementation is ESI compatible.
+ * Added `AutoExpireFlashBag` (default) to replicate Symfony 2.0.x auto expire
+ behaviour of messages auto expiring after one page page load. Messages must
+ be retrieved by `get()` or `all()`.
+ * Added `Symfony\Component\HttpFoundation\Attribute\AttributeBag` to replicate
+ attributes storage behaviour from 2.0.x (default).
+ * Added `Symfony\Component\HttpFoundation\Attribute\NamespacedAttributeBag` for
+ namespace session attributes.
+ * Flash API can stores messages in an array so there may be multiple messages
+ per flash type. The old `Session` class API remains without BC break as it
+ will allow single messages as before.
+ * Added basic session meta-data to the session to record session create time,
+ last updated time, and the lifetime of the session cookie that was provided
+ to the client.
+ * Request::getClientIp() method doesn't take a parameter anymore but bases
+ itself on the trustProxy parameter.
+ * Added isMethod() to Request object.
+ * [BC BREAK] The methods `getPathInfo()`, `getBaseUrl()` and `getBasePath()` of
+ a `Request` now all return a raw value (vs a urldecoded value before). Any call
+ to one of these methods must be checked and wrapped in a `rawurldecode()` if
+ needed.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Cookie.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Cookie.php
new file mode 100644
index 0000000..4519a6a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Cookie.php
@@ -0,0 +1,289 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * Represents a cookie.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class Cookie
+{
+ protected $name;
+ protected $value;
+ protected $domain;
+ protected $expire;
+ protected $path;
+ protected $secure;
+ protected $httpOnly;
+ private $raw;
+ private $sameSite;
+
+ const SAMESITE_LAX = 'lax';
+ const SAMESITE_STRICT = 'strict';
+
+ /**
+ * Creates cookie from raw header string.
+ *
+ * @param string $cookie
+ * @param bool $decode
+ *
+ * @return static
+ */
+ public static function fromString($cookie, $decode = false)
+ {
+ $data = array(
+ 'expires' => 0,
+ 'path' => '/',
+ 'domain' => null,
+ 'secure' => false,
+ 'httponly' => false,
+ 'raw' => !$decode,
+ 'samesite' => null,
+ );
+ foreach (explode(';', $cookie) as $part) {
+ if (false === strpos($part, '=')) {
+ $key = trim($part);
+ $value = true;
+ } else {
+ list($key, $value) = explode('=', trim($part), 2);
+ $key = trim($key);
+ $value = trim($value);
+ }
+ if (!isset($data['name'])) {
+ $data['name'] = $decode ? urldecode($key) : $key;
+ $data['value'] = true === $value ? null : ($decode ? urldecode($value) : $value);
+ continue;
+ }
+ switch ($key = strtolower($key)) {
+ case 'name':
+ case 'value':
+ break;
+ case 'max-age':
+ $data['expires'] = time() + (int) $value;
+ break;
+ default:
+ $data[$key] = $value;
+ break;
+ }
+ }
+
+ return new static($data['name'], $data['value'], $data['expires'], $data['path'], $data['domain'], $data['secure'], $data['httponly'], $data['raw'], $data['samesite']);
+ }
+
+ /**
+ * @param string $name The name of the cookie
+ * @param string|null $value The value of the cookie
+ * @param int|string|\DateTimeInterface $expire The time the cookie expires
+ * @param string $path The path on the server in which the cookie will be available on
+ * @param string|null $domain The domain that the cookie is available to
+ * @param bool $secure Whether the cookie should only be transmitted over a secure HTTPS connection from the client
+ * @param bool $httpOnly Whether the cookie will be made accessible only through the HTTP protocol
+ * @param bool $raw Whether the cookie value should be sent with no url encoding
+ * @param string|null $sameSite Whether the cookie will be available for cross-site requests
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function __construct($name, $value = null, $expire = 0, $path = '/', $domain = null, $secure = false, $httpOnly = true, $raw = false, $sameSite = null)
+ {
+ // from PHP source code
+ if (preg_match("/[=,; \t\r\n\013\014]/", $name)) {
+ throw new \InvalidArgumentException(sprintf('The cookie name "%s" contains invalid characters.', $name));
+ }
+
+ if (empty($name)) {
+ throw new \InvalidArgumentException('The cookie name cannot be empty.');
+ }
+
+ // convert expiration time to a Unix timestamp
+ if ($expire instanceof \DateTimeInterface) {
+ $expire = $expire->format('U');
+ } elseif (!is_numeric($expire)) {
+ $expire = strtotime($expire);
+
+ if (false === $expire) {
+ throw new \InvalidArgumentException('The cookie expiration time is not valid.');
+ }
+ }
+
+ $this->name = $name;
+ $this->value = $value;
+ $this->domain = $domain;
+ $this->expire = 0 < $expire ? (int) $expire : 0;
+ $this->path = empty($path) ? '/' : $path;
+ $this->secure = (bool) $secure;
+ $this->httpOnly = (bool) $httpOnly;
+ $this->raw = (bool) $raw;
+
+ if (null !== $sameSite) {
+ $sameSite = strtolower($sameSite);
+ }
+
+ if (!in_array($sameSite, array(self::SAMESITE_LAX, self::SAMESITE_STRICT, null), true)) {
+ throw new \InvalidArgumentException('The "sameSite" parameter value is not valid.');
+ }
+
+ $this->sameSite = $sameSite;
+ }
+
+ /**
+ * Returns the cookie as a string.
+ *
+ * @return string The cookie
+ */
+ public function __toString()
+ {
+ $str = ($this->isRaw() ? $this->getName() : urlencode($this->getName())).'=';
+
+ if ('' === (string) $this->getValue()) {
+ $str .= 'deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; max-age=-31536001';
+ } else {
+ $str .= $this->isRaw() ? $this->getValue() : rawurlencode($this->getValue());
+
+ if (0 !== $this->getExpiresTime()) {
+ $str .= '; expires='.gmdate('D, d-M-Y H:i:s T', $this->getExpiresTime()).'; max-age='.$this->getMaxAge();
+ }
+ }
+
+ if ($this->getPath()) {
+ $str .= '; path='.$this->getPath();
+ }
+
+ if ($this->getDomain()) {
+ $str .= '; domain='.$this->getDomain();
+ }
+
+ if (true === $this->isSecure()) {
+ $str .= '; secure';
+ }
+
+ if (true === $this->isHttpOnly()) {
+ $str .= '; httponly';
+ }
+
+ if (null !== $this->getSameSite()) {
+ $str .= '; samesite='.$this->getSameSite();
+ }
+
+ return $str;
+ }
+
+ /**
+ * Gets the name of the cookie.
+ *
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Gets the value of the cookie.
+ *
+ * @return string|null
+ */
+ public function getValue()
+ {
+ return $this->value;
+ }
+
+ /**
+ * Gets the domain that the cookie is available to.
+ *
+ * @return string|null
+ */
+ public function getDomain()
+ {
+ return $this->domain;
+ }
+
+ /**
+ * Gets the time the cookie expires.
+ *
+ * @return int
+ */
+ public function getExpiresTime()
+ {
+ return $this->expire;
+ }
+
+ /**
+ * Gets the max-age attribute.
+ *
+ * @return int
+ */
+ public function getMaxAge()
+ {
+ return 0 !== $this->expire ? $this->expire - time() : 0;
+ }
+
+ /**
+ * Gets the path on the server in which the cookie will be available on.
+ *
+ * @return string
+ */
+ public function getPath()
+ {
+ return $this->path;
+ }
+
+ /**
+ * Checks whether the cookie should only be transmitted over a secure HTTPS connection from the client.
+ *
+ * @return bool
+ */
+ public function isSecure()
+ {
+ return $this->secure;
+ }
+
+ /**
+ * Checks whether the cookie will be made accessible only through the HTTP protocol.
+ *
+ * @return bool
+ */
+ public function isHttpOnly()
+ {
+ return $this->httpOnly;
+ }
+
+ /**
+ * Whether this cookie is about to be cleared.
+ *
+ * @return bool
+ */
+ public function isCleared()
+ {
+ return $this->expire < time();
+ }
+
+ /**
+ * Checks if the cookie value should be sent with no url encoding.
+ *
+ * @return bool
+ */
+ public function isRaw()
+ {
+ return $this->raw;
+ }
+
+ /**
+ * Gets the SameSite attribute.
+ *
+ * @return string|null
+ */
+ public function getSameSite()
+ {
+ return $this->sameSite;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Exception/ConflictingHeadersException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Exception/ConflictingHeadersException.php
new file mode 100644
index 0000000..5fcf5b4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Exception/ConflictingHeadersException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Exception;
+
+/**
+ * The HTTP request contains headers with conflicting information.
+ *
+ * @author Magnus Nordlander <magnus@fervo.se>
+ */
+class ConflictingHeadersException extends \UnexpectedValueException implements RequestExceptionInterface
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Exception/RequestExceptionInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Exception/RequestExceptionInterface.php
new file mode 100644
index 0000000..478d0dc
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Exception/RequestExceptionInterface.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Exception;
+
+/**
+ * Interface for Request exceptions.
+ *
+ * Exceptions implementing this interface should trigger an HTTP 400 response in the application code.
+ */
+interface RequestExceptionInterface
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Exception/SuspiciousOperationException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Exception/SuspiciousOperationException.php
new file mode 100644
index 0000000..ae7a5f1
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Exception/SuspiciousOperationException.php
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Exception;
+
+/**
+ * Raised when a user has performed an operation that should be considered
+ * suspicious from a security perspective.
+ */
+class SuspiciousOperationException extends \UnexpectedValueException implements RequestExceptionInterface
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/ExpressionRequestMatcher.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/ExpressionRequestMatcher.php
new file mode 100644
index 0000000..e9c8441
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/ExpressionRequestMatcher.php
@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
+
+/**
+ * ExpressionRequestMatcher uses an expression to match a Request.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ExpressionRequestMatcher extends RequestMatcher
+{
+ private $language;
+ private $expression;
+
+ public function setExpression(ExpressionLanguage $language, $expression)
+ {
+ $this->language = $language;
+ $this->expression = $expression;
+ }
+
+ public function matches(Request $request)
+ {
+ if (!$this->language) {
+ throw new \LogicException('Unable to match the request as the expression language is not available.');
+ }
+
+ return $this->language->evaluate($this->expression, array(
+ 'request' => $request,
+ 'method' => $request->getMethod(),
+ 'path' => rawurldecode($request->getPathInfo()),
+ 'host' => $request->getHost(),
+ 'ip' => $request->getClientIp(),
+ 'attributes' => $request->attributes->all(),
+ )) && parent::matches($request);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/Exception/AccessDeniedException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/Exception/AccessDeniedException.php
new file mode 100644
index 0000000..3b8e41d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/Exception/AccessDeniedException.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File\Exception;
+
+/**
+ * Thrown when the access on a file was denied.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class AccessDeniedException extends FileException
+{
+ /**
+ * @param string $path The path to the accessed file
+ */
+ public function __construct($path)
+ {
+ parent::__construct(sprintf('The file %s could not be accessed', $path));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/Exception/FileException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/Exception/FileException.php
new file mode 100644
index 0000000..fad5133
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/Exception/FileException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File\Exception;
+
+/**
+ * Thrown when an error occurred in the component File.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class FileException extends \RuntimeException
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/Exception/FileNotFoundException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/Exception/FileNotFoundException.php
new file mode 100644
index 0000000..bfcc37e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/Exception/FileNotFoundException.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File\Exception;
+
+/**
+ * Thrown when a file was not found.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class FileNotFoundException extends FileException
+{
+ /**
+ * @param string $path The path to the file that was not found
+ */
+ public function __construct($path)
+ {
+ parent::__construct(sprintf('The file "%s" does not exist', $path));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/Exception/UnexpectedTypeException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/Exception/UnexpectedTypeException.php
new file mode 100644
index 0000000..0444b87
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/Exception/UnexpectedTypeException.php
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File\Exception;
+
+class UnexpectedTypeException extends FileException
+{
+ public function __construct($value, $expectedType)
+ {
+ parent::__construct(sprintf('Expected argument of type %s, %s given', $expectedType, is_object($value) ? get_class($value) : gettype($value)));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/Exception/UploadException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/Exception/UploadException.php
new file mode 100644
index 0000000..7074e76
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/Exception/UploadException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File\Exception;
+
+/**
+ * Thrown when an error occurred during file upload.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class UploadException extends FileException
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/File.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/File.php
new file mode 100644
index 0000000..e2a6768
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/File.php
@@ -0,0 +1,136 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File;
+
+use Symfony\Component\HttpFoundation\File\Exception\FileException;
+use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
+use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser;
+use Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesser;
+
+/**
+ * A file in the file system.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class File extends \SplFileInfo
+{
+ /**
+ * Constructs a new file from the given path.
+ *
+ * @param string $path The path to the file
+ * @param bool $checkPath Whether to check the path or not
+ *
+ * @throws FileNotFoundException If the given path is not a file
+ */
+ public function __construct($path, $checkPath = true)
+ {
+ if ($checkPath && !is_file($path)) {
+ throw new FileNotFoundException($path);
+ }
+
+ parent::__construct($path);
+ }
+
+ /**
+ * Returns the extension based on the mime type.
+ *
+ * If the mime type is unknown, returns null.
+ *
+ * This method uses the mime type as guessed by getMimeType()
+ * to guess the file extension.
+ *
+ * @return string|null The guessed extension or null if it cannot be guessed
+ *
+ * @see ExtensionGuesser
+ * @see getMimeType()
+ */
+ public function guessExtension()
+ {
+ $type = $this->getMimeType();
+ $guesser = ExtensionGuesser::getInstance();
+
+ return $guesser->guess($type);
+ }
+
+ /**
+ * Returns the mime type of the file.
+ *
+ * The mime type is guessed using a MimeTypeGuesser instance, which uses finfo(),
+ * mime_content_type() and the system binary "file" (in this order), depending on
+ * which of those are available.
+ *
+ * @return string|null The guessed mime type (e.g. "application/pdf")
+ *
+ * @see MimeTypeGuesser
+ */
+ public function getMimeType()
+ {
+ $guesser = MimeTypeGuesser::getInstance();
+
+ return $guesser->guess($this->getPathname());
+ }
+
+ /**
+ * Moves the file to a new location.
+ *
+ * @param string $directory The destination folder
+ * @param string $name The new file name
+ *
+ * @return self A File object representing the new file
+ *
+ * @throws FileException if the target file could not be created
+ */
+ public function move($directory, $name = null)
+ {
+ $target = $this->getTargetFile($directory, $name);
+
+ if (!@rename($this->getPathname(), $target)) {
+ $error = error_get_last();
+ throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error['message'])));
+ }
+
+ @chmod($target, 0666 & ~umask());
+
+ return $target;
+ }
+
+ protected function getTargetFile($directory, $name = null)
+ {
+ if (!is_dir($directory)) {
+ if (false === @mkdir($directory, 0777, true) && !is_dir($directory)) {
+ throw new FileException(sprintf('Unable to create the "%s" directory', $directory));
+ }
+ } elseif (!is_writable($directory)) {
+ throw new FileException(sprintf('Unable to write in the "%s" directory', $directory));
+ }
+
+ $target = rtrim($directory, '/\\').DIRECTORY_SEPARATOR.(null === $name ? $this->getBasename() : $this->getName($name));
+
+ return new self($target, false);
+ }
+
+ /**
+ * Returns locale independent base name of the given path.
+ *
+ * @param string $name The new file name
+ *
+ * @return string containing
+ */
+ protected function getName($name)
+ {
+ $originalName = str_replace('\\', '/', $name);
+ $pos = strrpos($originalName, '/');
+ $originalName = false === $pos ? $originalName : substr($originalName, $pos + 1);
+
+ return $originalName;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/MimeType/ExtensionGuesser.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/MimeType/ExtensionGuesser.php
new file mode 100644
index 0000000..263fb32
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/MimeType/ExtensionGuesser.php
@@ -0,0 +1,94 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File\MimeType;
+
+/**
+ * A singleton mime type to file extension guesser.
+ *
+ * A default guesser is provided.
+ * You can register custom guessers by calling the register()
+ * method on the singleton instance:
+ *
+ * $guesser = ExtensionGuesser::getInstance();
+ * $guesser->register(new MyCustomExtensionGuesser());
+ *
+ * The last registered guesser is preferred over previously registered ones.
+ */
+class ExtensionGuesser implements ExtensionGuesserInterface
+{
+ /**
+ * The singleton instance.
+ *
+ * @var ExtensionGuesser
+ */
+ private static $instance = null;
+
+ /**
+ * All registered ExtensionGuesserInterface instances.
+ *
+ * @var array
+ */
+ protected $guessers = array();
+
+ /**
+ * Returns the singleton instance.
+ *
+ * @return self
+ */
+ public static function getInstance()
+ {
+ if (null === self::$instance) {
+ self::$instance = new self();
+ }
+
+ return self::$instance;
+ }
+
+ /**
+ * Registers all natively provided extension guessers.
+ */
+ private function __construct()
+ {
+ $this->register(new MimeTypeExtensionGuesser());
+ }
+
+ /**
+ * Registers a new extension guesser.
+ *
+ * When guessing, this guesser is preferred over previously registered ones.
+ */
+ public function register(ExtensionGuesserInterface $guesser)
+ {
+ array_unshift($this->guessers, $guesser);
+ }
+
+ /**
+ * Tries to guess the extension.
+ *
+ * The mime type is passed to each registered mime type guesser in reverse order
+ * of their registration (last registered is queried first). Once a guesser
+ * returns a value that is not NULL, this method terminates and returns the
+ * value.
+ *
+ * @param string $mimeType The mime type
+ *
+ * @return string The guessed extension or NULL, if none could be guessed
+ */
+ public function guess($mimeType)
+ {
+ foreach ($this->guessers as $guesser) {
+ if (null !== $extension = $guesser->guess($mimeType)) {
+ return $extension;
+ }
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/MimeType/ExtensionGuesserInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/MimeType/ExtensionGuesserInterface.php
new file mode 100644
index 0000000..d19a0e5
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/MimeType/ExtensionGuesserInterface.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File\MimeType;
+
+/**
+ * Guesses the file extension corresponding to a given mime type.
+ */
+interface ExtensionGuesserInterface
+{
+ /**
+ * Makes a best guess for a file extension, given a mime type.
+ *
+ * @param string $mimeType The mime type
+ *
+ * @return string The guessed extension or NULL, if none could be guessed
+ */
+ public function guess($mimeType);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/MimeType/FileBinaryMimeTypeGuesser.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/MimeType/FileBinaryMimeTypeGuesser.php
new file mode 100644
index 0000000..c2ac676
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/MimeType/FileBinaryMimeTypeGuesser.php
@@ -0,0 +1,85 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File\MimeType;
+
+use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
+use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;
+
+/**
+ * Guesses the mime type with the binary "file" (only available on *nix).
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class FileBinaryMimeTypeGuesser implements MimeTypeGuesserInterface
+{
+ private $cmd;
+
+ /**
+ * The $cmd pattern must contain a "%s" string that will be replaced
+ * with the file name to guess.
+ *
+ * The command output must start with the mime type of the file.
+ *
+ * @param string $cmd The command to run to get the mime type of a file
+ */
+ public function __construct($cmd = 'file -b --mime %s 2>/dev/null')
+ {
+ $this->cmd = $cmd;
+ }
+
+ /**
+ * Returns whether this guesser is supported on the current OS.
+ *
+ * @return bool
+ */
+ public static function isSupported()
+ {
+ return '\\' !== DIRECTORY_SEPARATOR && function_exists('passthru') && function_exists('escapeshellarg');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function guess($path)
+ {
+ if (!is_file($path)) {
+ throw new FileNotFoundException($path);
+ }
+
+ if (!is_readable($path)) {
+ throw new AccessDeniedException($path);
+ }
+
+ if (!self::isSupported()) {
+ return;
+ }
+
+ ob_start();
+
+ // need to use --mime instead of -i. see #6641
+ passthru(sprintf($this->cmd, escapeshellarg($path)), $return);
+ if ($return > 0) {
+ ob_end_clean();
+
+ return;
+ }
+
+ $type = trim(ob_get_clean());
+
+ if (!preg_match('#^([a-z0-9\-]+/[a-z0-9\-\.]+)#i', $type, $match)) {
+ // it's not a type, but an error message
+ return;
+ }
+
+ return $match[1];
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/MimeType/FileinfoMimeTypeGuesser.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/MimeType/FileinfoMimeTypeGuesser.php
new file mode 100644
index 0000000..9b42835
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/MimeType/FileinfoMimeTypeGuesser.php
@@ -0,0 +1,69 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File\MimeType;
+
+use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
+use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;
+
+/**
+ * Guesses the mime type using the PECL extension FileInfo.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class FileinfoMimeTypeGuesser implements MimeTypeGuesserInterface
+{
+ private $magicFile;
+
+ /**
+ * @param string $magicFile A magic file to use with the finfo instance
+ *
+ * @see http://www.php.net/manual/en/function.finfo-open.php
+ */
+ public function __construct($magicFile = null)
+ {
+ $this->magicFile = $magicFile;
+ }
+
+ /**
+ * Returns whether this guesser is supported on the current OS/PHP setup.
+ *
+ * @return bool
+ */
+ public static function isSupported()
+ {
+ return function_exists('finfo_open');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function guess($path)
+ {
+ if (!is_file($path)) {
+ throw new FileNotFoundException($path);
+ }
+
+ if (!is_readable($path)) {
+ throw new AccessDeniedException($path);
+ }
+
+ if (!self::isSupported()) {
+ return;
+ }
+
+ if (!$finfo = new \finfo(FILEINFO_MIME_TYPE, $this->magicFile)) {
+ return;
+ }
+
+ return $finfo->file($path);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/MimeType/MimeTypeExtensionGuesser.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/MimeType/MimeTypeExtensionGuesser.php
new file mode 100644
index 0000000..77bf51b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/MimeType/MimeTypeExtensionGuesser.php
@@ -0,0 +1,808 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File\MimeType;
+
+/**
+ * Provides a best-guess mapping of mime type to file extension.
+ */
+class MimeTypeExtensionGuesser implements ExtensionGuesserInterface
+{
+ /**
+ * A map of mime types and their default extensions.
+ *
+ * This list has been placed under the public domain by the Apache HTTPD project.
+ * This list has been updated from upstream on 2013-04-23.
+ *
+ * @see http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
+ */
+ protected $defaultExtensions = array(
+ 'application/andrew-inset' => 'ez',
+ 'application/applixware' => 'aw',
+ 'application/atom+xml' => 'atom',
+ 'application/atomcat+xml' => 'atomcat',
+ 'application/atomsvc+xml' => 'atomsvc',
+ 'application/ccxml+xml' => 'ccxml',
+ 'application/cdmi-capability' => 'cdmia',
+ 'application/cdmi-container' => 'cdmic',
+ 'application/cdmi-domain' => 'cdmid',
+ 'application/cdmi-object' => 'cdmio',
+ 'application/cdmi-queue' => 'cdmiq',
+ 'application/cu-seeme' => 'cu',
+ 'application/davmount+xml' => 'davmount',
+ 'application/docbook+xml' => 'dbk',
+ 'application/dssc+der' => 'dssc',
+ 'application/dssc+xml' => 'xdssc',
+ 'application/ecmascript' => 'ecma',
+ 'application/emma+xml' => 'emma',
+ 'application/epub+zip' => 'epub',
+ 'application/exi' => 'exi',
+ 'application/font-tdpfr' => 'pfr',
+ 'application/gml+xml' => 'gml',
+ 'application/gpx+xml' => 'gpx',
+ 'application/gxf' => 'gxf',
+ 'application/hyperstudio' => 'stk',
+ 'application/inkml+xml' => 'ink',
+ 'application/ipfix' => 'ipfix',
+ 'application/java-archive' => 'jar',
+ 'application/java-serialized-object' => 'ser',
+ 'application/java-vm' => 'class',
+ 'application/javascript' => 'js',
+ 'application/json' => 'json',
+ 'application/jsonml+json' => 'jsonml',
+ 'application/lost+xml' => 'lostxml',
+ 'application/mac-binhex40' => 'hqx',
+ 'application/mac-compactpro' => 'cpt',
+ 'application/mads+xml' => 'mads',
+ 'application/marc' => 'mrc',
+ 'application/marcxml+xml' => 'mrcx',
+ 'application/mathematica' => 'ma',
+ 'application/mathml+xml' => 'mathml',
+ 'application/mbox' => 'mbox',
+ 'application/mediaservercontrol+xml' => 'mscml',
+ 'application/metalink+xml' => 'metalink',
+ 'application/metalink4+xml' => 'meta4',
+ 'application/mets+xml' => 'mets',
+ 'application/mods+xml' => 'mods',
+ 'application/mp21' => 'm21',
+ 'application/mp4' => 'mp4s',
+ 'application/msword' => 'doc',
+ 'application/mxf' => 'mxf',
+ 'application/octet-stream' => 'bin',
+ 'application/oda' => 'oda',
+ 'application/oebps-package+xml' => 'opf',
+ 'application/ogg' => 'ogx',
+ 'application/omdoc+xml' => 'omdoc',
+ 'application/onenote' => 'onetoc',
+ 'application/oxps' => 'oxps',
+ 'application/patch-ops-error+xml' => 'xer',
+ 'application/pdf' => 'pdf',
+ 'application/pgp-encrypted' => 'pgp',
+ 'application/pgp-signature' => 'asc',
+ 'application/pics-rules' => 'prf',
+ 'application/pkcs10' => 'p10',
+ 'application/pkcs7-mime' => 'p7m',
+ 'application/pkcs7-signature' => 'p7s',
+ 'application/pkcs8' => 'p8',
+ 'application/pkix-attr-cert' => 'ac',
+ 'application/pkix-cert' => 'cer',
+ 'application/pkix-crl' => 'crl',
+ 'application/pkix-pkipath' => 'pkipath',
+ 'application/pkixcmp' => 'pki',
+ 'application/pls+xml' => 'pls',
+ 'application/postscript' => 'ai',
+ 'application/prs.cww' => 'cww',
+ 'application/pskc+xml' => 'pskcxml',
+ 'application/rdf+xml' => 'rdf',
+ 'application/reginfo+xml' => 'rif',
+ 'application/relax-ng-compact-syntax' => 'rnc',
+ 'application/resource-lists+xml' => 'rl',
+ 'application/resource-lists-diff+xml' => 'rld',
+ 'application/rls-services+xml' => 'rs',
+ 'application/rpki-ghostbusters' => 'gbr',
+ 'application/rpki-manifest' => 'mft',
+ 'application/rpki-roa' => 'roa',
+ 'application/rsd+xml' => 'rsd',
+ 'application/rss+xml' => 'rss',
+ 'application/rtf' => 'rtf',
+ 'application/sbml+xml' => 'sbml',
+ 'application/scvp-cv-request' => 'scq',
+ 'application/scvp-cv-response' => 'scs',
+ 'application/scvp-vp-request' => 'spq',
+ 'application/scvp-vp-response' => 'spp',
+ 'application/sdp' => 'sdp',
+ 'application/set-payment-initiation' => 'setpay',
+ 'application/set-registration-initiation' => 'setreg',
+ 'application/shf+xml' => 'shf',
+ 'application/smil+xml' => 'smi',
+ 'application/sparql-query' => 'rq',
+ 'application/sparql-results+xml' => 'srx',
+ 'application/srgs' => 'gram',
+ 'application/srgs+xml' => 'grxml',
+ 'application/sru+xml' => 'sru',
+ 'application/ssdl+xml' => 'ssdl',
+ 'application/ssml+xml' => 'ssml',
+ 'application/tei+xml' => 'tei',
+ 'application/thraud+xml' => 'tfi',
+ 'application/timestamped-data' => 'tsd',
+ 'application/vnd.3gpp.pic-bw-large' => 'plb',
+ 'application/vnd.3gpp.pic-bw-small' => 'psb',
+ 'application/vnd.3gpp.pic-bw-var' => 'pvb',
+ 'application/vnd.3gpp2.tcap' => 'tcap',
+ 'application/vnd.3m.post-it-notes' => 'pwn',
+ 'application/vnd.accpac.simply.aso' => 'aso',
+ 'application/vnd.accpac.simply.imp' => 'imp',
+ 'application/vnd.acucobol' => 'acu',
+ 'application/vnd.acucorp' => 'atc',
+ 'application/vnd.adobe.air-application-installer-package+zip' => 'air',
+ 'application/vnd.adobe.formscentral.fcdt' => 'fcdt',
+ 'application/vnd.adobe.fxp' => 'fxp',
+ 'application/vnd.adobe.xdp+xml' => 'xdp',
+ 'application/vnd.adobe.xfdf' => 'xfdf',
+ 'application/vnd.ahead.space' => 'ahead',
+ 'application/vnd.airzip.filesecure.azf' => 'azf',
+ 'application/vnd.airzip.filesecure.azs' => 'azs',
+ 'application/vnd.amazon.ebook' => 'azw',
+ 'application/vnd.americandynamics.acc' => 'acc',
+ 'application/vnd.amiga.ami' => 'ami',
+ 'application/vnd.android.package-archive' => 'apk',
+ 'application/vnd.anser-web-certificate-issue-initiation' => 'cii',
+ 'application/vnd.anser-web-funds-transfer-initiation' => 'fti',
+ 'application/vnd.antix.game-component' => 'atx',
+ 'application/vnd.apple.installer+xml' => 'mpkg',
+ 'application/vnd.apple.mpegurl' => 'm3u8',
+ 'application/vnd.aristanetworks.swi' => 'swi',
+ 'application/vnd.astraea-software.iota' => 'iota',
+ 'application/vnd.audiograph' => 'aep',
+ 'application/vnd.blueice.multipass' => 'mpm',
+ 'application/vnd.bmi' => 'bmi',
+ 'application/vnd.businessobjects' => 'rep',
+ 'application/vnd.chemdraw+xml' => 'cdxml',
+ 'application/vnd.chipnuts.karaoke-mmd' => 'mmd',
+ 'application/vnd.cinderella' => 'cdy',
+ 'application/vnd.claymore' => 'cla',
+ 'application/vnd.cloanto.rp9' => 'rp9',
+ 'application/vnd.clonk.c4group' => 'c4g',
+ 'application/vnd.cluetrust.cartomobile-config' => 'c11amc',
+ 'application/vnd.cluetrust.cartomobile-config-pkg' => 'c11amz',
+ 'application/vnd.commonspace' => 'csp',
+ 'application/vnd.contact.cmsg' => 'cdbcmsg',
+ 'application/vnd.cosmocaller' => 'cmc',
+ 'application/vnd.crick.clicker' => 'clkx',
+ 'application/vnd.crick.clicker.keyboard' => 'clkk',
+ 'application/vnd.crick.clicker.palette' => 'clkp',
+ 'application/vnd.crick.clicker.template' => 'clkt',
+ 'application/vnd.crick.clicker.wordbank' => 'clkw',
+ 'application/vnd.criticaltools.wbs+xml' => 'wbs',
+ 'application/vnd.ctc-posml' => 'pml',
+ 'application/vnd.cups-ppd' => 'ppd',
+ 'application/vnd.curl.car' => 'car',
+ 'application/vnd.curl.pcurl' => 'pcurl',
+ 'application/vnd.dart' => 'dart',
+ 'application/vnd.data-vision.rdz' => 'rdz',
+ 'application/vnd.dece.data' => 'uvf',
+ 'application/vnd.dece.ttml+xml' => 'uvt',
+ 'application/vnd.dece.unspecified' => 'uvx',
+ 'application/vnd.dece.zip' => 'uvz',
+ 'application/vnd.denovo.fcselayout-link' => 'fe_launch',
+ 'application/vnd.dna' => 'dna',
+ 'application/vnd.dolby.mlp' => 'mlp',
+ 'application/vnd.dpgraph' => 'dpg',
+ 'application/vnd.dreamfactory' => 'dfac',
+ 'application/vnd.ds-keypoint' => 'kpxx',
+ 'application/vnd.dvb.ait' => 'ait',
+ 'application/vnd.dvb.service' => 'svc',
+ 'application/vnd.dynageo' => 'geo',
+ 'application/vnd.ecowin.chart' => 'mag',
+ 'application/vnd.enliven' => 'nml',
+ 'application/vnd.epson.esf' => 'esf',
+ 'application/vnd.epson.msf' => 'msf',
+ 'application/vnd.epson.quickanime' => 'qam',
+ 'application/vnd.epson.salt' => 'slt',
+ 'application/vnd.epson.ssf' => 'ssf',
+ 'application/vnd.eszigno3+xml' => 'es3',
+ 'application/vnd.ezpix-album' => 'ez2',
+ 'application/vnd.ezpix-package' => 'ez3',
+ 'application/vnd.fdf' => 'fdf',
+ 'application/vnd.fdsn.mseed' => 'mseed',
+ 'application/vnd.fdsn.seed' => 'seed',
+ 'application/vnd.flographit' => 'gph',
+ 'application/vnd.fluxtime.clip' => 'ftc',
+ 'application/vnd.framemaker' => 'fm',
+ 'application/vnd.frogans.fnc' => 'fnc',
+ 'application/vnd.frogans.ltf' => 'ltf',
+ 'application/vnd.fsc.weblaunch' => 'fsc',
+ 'application/vnd.fujitsu.oasys' => 'oas',
+ 'application/vnd.fujitsu.oasys2' => 'oa2',
+ 'application/vnd.fujitsu.oasys3' => 'oa3',
+ 'application/vnd.fujitsu.oasysgp' => 'fg5',
+ 'application/vnd.fujitsu.oasysprs' => 'bh2',
+ 'application/vnd.fujixerox.ddd' => 'ddd',
+ 'application/vnd.fujixerox.docuworks' => 'xdw',
+ 'application/vnd.fujixerox.docuworks.binder' => 'xbd',
+ 'application/vnd.fuzzysheet' => 'fzs',
+ 'application/vnd.genomatix.tuxedo' => 'txd',
+ 'application/vnd.geogebra.file' => 'ggb',
+ 'application/vnd.geogebra.tool' => 'ggt',
+ 'application/vnd.geometry-explorer' => 'gex',
+ 'application/vnd.geonext' => 'gxt',
+ 'application/vnd.geoplan' => 'g2w',
+ 'application/vnd.geospace' => 'g3w',
+ 'application/vnd.gmx' => 'gmx',
+ 'application/vnd.google-earth.kml+xml' => 'kml',
+ 'application/vnd.google-earth.kmz' => 'kmz',
+ 'application/vnd.grafeq' => 'gqf',
+ 'application/vnd.groove-account' => 'gac',
+ 'application/vnd.groove-help' => 'ghf',
+ 'application/vnd.groove-identity-message' => 'gim',
+ 'application/vnd.groove-injector' => 'grv',
+ 'application/vnd.groove-tool-message' => 'gtm',
+ 'application/vnd.groove-tool-template' => 'tpl',
+ 'application/vnd.groove-vcard' => 'vcg',
+ 'application/vnd.hal+xml' => 'hal',
+ 'application/vnd.handheld-entertainment+xml' => 'zmm',
+ 'application/vnd.hbci' => 'hbci',
+ 'application/vnd.hhe.lesson-player' => 'les',
+ 'application/vnd.hp-hpgl' => 'hpgl',
+ 'application/vnd.hp-hpid' => 'hpid',
+ 'application/vnd.hp-hps' => 'hps',
+ 'application/vnd.hp-jlyt' => 'jlt',
+ 'application/vnd.hp-pcl' => 'pcl',
+ 'application/vnd.hp-pclxl' => 'pclxl',
+ 'application/vnd.hydrostatix.sof-data' => 'sfd-hdstx',
+ 'application/vnd.ibm.minipay' => 'mpy',
+ 'application/vnd.ibm.modcap' => 'afp',
+ 'application/vnd.ibm.rights-management' => 'irm',
+ 'application/vnd.ibm.secure-container' => 'sc',
+ 'application/vnd.iccprofile' => 'icc',
+ 'application/vnd.igloader' => 'igl',
+ 'application/vnd.immervision-ivp' => 'ivp',
+ 'application/vnd.immervision-ivu' => 'ivu',
+ 'application/vnd.insors.igm' => 'igm',
+ 'application/vnd.intercon.formnet' => 'xpw',
+ 'application/vnd.intergeo' => 'i2g',
+ 'application/vnd.intu.qbo' => 'qbo',
+ 'application/vnd.intu.qfx' => 'qfx',
+ 'application/vnd.ipunplugged.rcprofile' => 'rcprofile',
+ 'application/vnd.irepository.package+xml' => 'irp',
+ 'application/vnd.is-xpr' => 'xpr',
+ 'application/vnd.isac.fcs' => 'fcs',
+ 'application/vnd.jam' => 'jam',
+ 'application/vnd.jcp.javame.midlet-rms' => 'rms',
+ 'application/vnd.jisp' => 'jisp',
+ 'application/vnd.joost.joda-archive' => 'joda',
+ 'application/vnd.kahootz' => 'ktz',
+ 'application/vnd.kde.karbon' => 'karbon',
+ 'application/vnd.kde.kchart' => 'chrt',
+ 'application/vnd.kde.kformula' => 'kfo',
+ 'application/vnd.kde.kivio' => 'flw',
+ 'application/vnd.kde.kontour' => 'kon',
+ 'application/vnd.kde.kpresenter' => 'kpr',
+ 'application/vnd.kde.kspread' => 'ksp',
+ 'application/vnd.kde.kword' => 'kwd',
+ 'application/vnd.kenameaapp' => 'htke',
+ 'application/vnd.kidspiration' => 'kia',
+ 'application/vnd.kinar' => 'kne',
+ 'application/vnd.koan' => 'skp',
+ 'application/vnd.kodak-descriptor' => 'sse',
+ 'application/vnd.las.las+xml' => 'lasxml',
+ 'application/vnd.llamagraphics.life-balance.desktop' => 'lbd',
+ 'application/vnd.llamagraphics.life-balance.exchange+xml' => 'lbe',
+ 'application/vnd.lotus-1-2-3' => '123',
+ 'application/vnd.lotus-approach' => 'apr',
+ 'application/vnd.lotus-freelance' => 'pre',
+ 'application/vnd.lotus-notes' => 'nsf',
+ 'application/vnd.lotus-organizer' => 'org',
+ 'application/vnd.lotus-screencam' => 'scm',
+ 'application/vnd.lotus-wordpro' => 'lwp',
+ 'application/vnd.macports.portpkg' => 'portpkg',
+ 'application/vnd.mcd' => 'mcd',
+ 'application/vnd.medcalcdata' => 'mc1',
+ 'application/vnd.mediastation.cdkey' => 'cdkey',
+ 'application/vnd.mfer' => 'mwf',
+ 'application/vnd.mfmp' => 'mfm',
+ 'application/vnd.micrografx.flo' => 'flo',
+ 'application/vnd.micrografx.igx' => 'igx',
+ 'application/vnd.mif' => 'mif',
+ 'application/vnd.mobius.daf' => 'daf',
+ 'application/vnd.mobius.dis' => 'dis',
+ 'application/vnd.mobius.mbk' => 'mbk',
+ 'application/vnd.mobius.mqy' => 'mqy',
+ 'application/vnd.mobius.msl' => 'msl',
+ 'application/vnd.mobius.plc' => 'plc',
+ 'application/vnd.mobius.txf' => 'txf',
+ 'application/vnd.mophun.application' => 'mpn',
+ 'application/vnd.mophun.certificate' => 'mpc',
+ 'application/vnd.mozilla.xul+xml' => 'xul',
+ 'application/vnd.ms-artgalry' => 'cil',
+ 'application/vnd.ms-cab-compressed' => 'cab',
+ 'application/vnd.ms-excel' => 'xls',
+ 'application/vnd.ms-excel.addin.macroenabled.12' => 'xlam',
+ 'application/vnd.ms-excel.sheet.binary.macroenabled.12' => 'xlsb',
+ 'application/vnd.ms-excel.sheet.macroenabled.12' => 'xlsm',
+ 'application/vnd.ms-excel.template.macroenabled.12' => 'xltm',
+ 'application/vnd.ms-fontobject' => 'eot',
+ 'application/vnd.ms-htmlhelp' => 'chm',
+ 'application/vnd.ms-ims' => 'ims',
+ 'application/vnd.ms-lrm' => 'lrm',
+ 'application/vnd.ms-officetheme' => 'thmx',
+ 'application/vnd.ms-pki.seccat' => 'cat',
+ 'application/vnd.ms-pki.stl' => 'stl',
+ 'application/vnd.ms-powerpoint' => 'ppt',
+ 'application/vnd.ms-powerpoint.addin.macroenabled.12' => 'ppam',
+ 'application/vnd.ms-powerpoint.presentation.macroenabled.12' => 'pptm',
+ 'application/vnd.ms-powerpoint.slide.macroenabled.12' => 'sldm',
+ 'application/vnd.ms-powerpoint.slideshow.macroenabled.12' => 'ppsm',
+ 'application/vnd.ms-powerpoint.template.macroenabled.12' => 'potm',
+ 'application/vnd.ms-project' => 'mpp',
+ 'application/vnd.ms-word.document.macroenabled.12' => 'docm',
+ 'application/vnd.ms-word.template.macroenabled.12' => 'dotm',
+ 'application/vnd.ms-works' => 'wps',
+ 'application/vnd.ms-wpl' => 'wpl',
+ 'application/vnd.ms-xpsdocument' => 'xps',
+ 'application/vnd.mseq' => 'mseq',
+ 'application/vnd.musician' => 'mus',
+ 'application/vnd.muvee.style' => 'msty',
+ 'application/vnd.mynfc' => 'taglet',
+ 'application/vnd.neurolanguage.nlu' => 'nlu',
+ 'application/vnd.nitf' => 'ntf',
+ 'application/vnd.noblenet-directory' => 'nnd',
+ 'application/vnd.noblenet-sealer' => 'nns',
+ 'application/vnd.noblenet-web' => 'nnw',
+ 'application/vnd.nokia.n-gage.data' => 'ngdat',
+ 'application/vnd.nokia.n-gage.symbian.install' => 'n-gage',
+ 'application/vnd.nokia.radio-preset' => 'rpst',
+ 'application/vnd.nokia.radio-presets' => 'rpss',
+ 'application/vnd.novadigm.edm' => 'edm',
+ 'application/vnd.novadigm.edx' => 'edx',
+ 'application/vnd.novadigm.ext' => 'ext',
+ 'application/vnd.oasis.opendocument.chart' => 'odc',
+ 'application/vnd.oasis.opendocument.chart-template' => 'otc',
+ 'application/vnd.oasis.opendocument.database' => 'odb',
+ 'application/vnd.oasis.opendocument.formula' => 'odf',
+ 'application/vnd.oasis.opendocument.formula-template' => 'odft',
+ 'application/vnd.oasis.opendocument.graphics' => 'odg',
+ 'application/vnd.oasis.opendocument.graphics-template' => 'otg',
+ 'application/vnd.oasis.opendocument.image' => 'odi',
+ 'application/vnd.oasis.opendocument.image-template' => 'oti',
+ 'application/vnd.oasis.opendocument.presentation' => 'odp',
+ 'application/vnd.oasis.opendocument.presentation-template' => 'otp',
+ 'application/vnd.oasis.opendocument.spreadsheet' => 'ods',
+ 'application/vnd.oasis.opendocument.spreadsheet-template' => 'ots',
+ 'application/vnd.oasis.opendocument.text' => 'odt',
+ 'application/vnd.oasis.opendocument.text-master' => 'odm',
+ 'application/vnd.oasis.opendocument.text-template' => 'ott',
+ 'application/vnd.oasis.opendocument.text-web' => 'oth',
+ 'application/vnd.olpc-sugar' => 'xo',
+ 'application/vnd.oma.dd2+xml' => 'dd2',
+ 'application/vnd.openofficeorg.extension' => 'oxt',
+ 'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'pptx',
+ 'application/vnd.openxmlformats-officedocument.presentationml.slide' => 'sldx',
+ 'application/vnd.openxmlformats-officedocument.presentationml.slideshow' => 'ppsx',
+ 'application/vnd.openxmlformats-officedocument.presentationml.template' => 'potx',
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'xlsx',
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.template' => 'xltx',
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'docx',
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.template' => 'dotx',
+ 'application/vnd.osgeo.mapguide.package' => 'mgp',
+ 'application/vnd.osgi.dp' => 'dp',
+ 'application/vnd.osgi.subsystem' => 'esa',
+ 'application/vnd.palm' => 'pdb',
+ 'application/vnd.pawaafile' => 'paw',
+ 'application/vnd.pg.format' => 'str',
+ 'application/vnd.pg.osasli' => 'ei6',
+ 'application/vnd.picsel' => 'efif',
+ 'application/vnd.pmi.widget' => 'wg',
+ 'application/vnd.pocketlearn' => 'plf',
+ 'application/vnd.powerbuilder6' => 'pbd',
+ 'application/vnd.previewsystems.box' => 'box',
+ 'application/vnd.proteus.magazine' => 'mgz',
+ 'application/vnd.publishare-delta-tree' => 'qps',
+ 'application/vnd.pvi.ptid1' => 'ptid',
+ 'application/vnd.quark.quarkxpress' => 'qxd',
+ 'application/vnd.realvnc.bed' => 'bed',
+ 'application/vnd.recordare.musicxml' => 'mxl',
+ 'application/vnd.recordare.musicxml+xml' => 'musicxml',
+ 'application/vnd.rig.cryptonote' => 'cryptonote',
+ 'application/vnd.rim.cod' => 'cod',
+ 'application/vnd.rn-realmedia' => 'rm',
+ 'application/vnd.rn-realmedia-vbr' => 'rmvb',
+ 'application/vnd.route66.link66+xml' => 'link66',
+ 'application/vnd.sailingtracker.track' => 'st',
+ 'application/vnd.seemail' => 'see',
+ 'application/vnd.sema' => 'sema',
+ 'application/vnd.semd' => 'semd',
+ 'application/vnd.semf' => 'semf',
+ 'application/vnd.shana.informed.formdata' => 'ifm',
+ 'application/vnd.shana.informed.formtemplate' => 'itp',
+ 'application/vnd.shana.informed.interchange' => 'iif',
+ 'application/vnd.shana.informed.package' => 'ipk',
+ 'application/vnd.simtech-mindmapper' => 'twd',
+ 'application/vnd.smaf' => 'mmf',
+ 'application/vnd.smart.teacher' => 'teacher',
+ 'application/vnd.solent.sdkm+xml' => 'sdkm',
+ 'application/vnd.spotfire.dxp' => 'dxp',
+ 'application/vnd.spotfire.sfs' => 'sfs',
+ 'application/vnd.stardivision.calc' => 'sdc',
+ 'application/vnd.stardivision.draw' => 'sda',
+ 'application/vnd.stardivision.impress' => 'sdd',
+ 'application/vnd.stardivision.math' => 'smf',
+ 'application/vnd.stardivision.writer' => 'sdw',
+ 'application/vnd.stardivision.writer-global' => 'sgl',
+ 'application/vnd.stepmania.package' => 'smzip',
+ 'application/vnd.stepmania.stepchart' => 'sm',
+ 'application/vnd.sun.xml.calc' => 'sxc',
+ 'application/vnd.sun.xml.calc.template' => 'stc',
+ 'application/vnd.sun.xml.draw' => 'sxd',
+ 'application/vnd.sun.xml.draw.template' => 'std',
+ 'application/vnd.sun.xml.impress' => 'sxi',
+ 'application/vnd.sun.xml.impress.template' => 'sti',
+ 'application/vnd.sun.xml.math' => 'sxm',
+ 'application/vnd.sun.xml.writer' => 'sxw',
+ 'application/vnd.sun.xml.writer.global' => 'sxg',
+ 'application/vnd.sun.xml.writer.template' => 'stw',
+ 'application/vnd.sus-calendar' => 'sus',
+ 'application/vnd.svd' => 'svd',
+ 'application/vnd.symbian.install' => 'sis',
+ 'application/vnd.syncml+xml' => 'xsm',
+ 'application/vnd.syncml.dm+wbxml' => 'bdm',
+ 'application/vnd.syncml.dm+xml' => 'xdm',
+ 'application/vnd.tao.intent-module-archive' => 'tao',
+ 'application/vnd.tcpdump.pcap' => 'pcap',
+ 'application/vnd.tmobile-livetv' => 'tmo',
+ 'application/vnd.trid.tpt' => 'tpt',
+ 'application/vnd.triscape.mxs' => 'mxs',
+ 'application/vnd.trueapp' => 'tra',
+ 'application/vnd.ufdl' => 'ufd',
+ 'application/vnd.uiq.theme' => 'utz',
+ 'application/vnd.umajin' => 'umj',
+ 'application/vnd.unity' => 'unityweb',
+ 'application/vnd.uoml+xml' => 'uoml',
+ 'application/vnd.vcx' => 'vcx',
+ 'application/vnd.visio' => 'vsd',
+ 'application/vnd.visionary' => 'vis',
+ 'application/vnd.vsf' => 'vsf',
+ 'application/vnd.wap.wbxml' => 'wbxml',
+ 'application/vnd.wap.wmlc' => 'wmlc',
+ 'application/vnd.wap.wmlscriptc' => 'wmlsc',
+ 'application/vnd.webturbo' => 'wtb',
+ 'application/vnd.wolfram.player' => 'nbp',
+ 'application/vnd.wordperfect' => 'wpd',
+ 'application/vnd.wqd' => 'wqd',
+ 'application/vnd.wt.stf' => 'stf',
+ 'application/vnd.xara' => 'xar',
+ 'application/vnd.xfdl' => 'xfdl',
+ 'application/vnd.yamaha.hv-dic' => 'hvd',
+ 'application/vnd.yamaha.hv-script' => 'hvs',
+ 'application/vnd.yamaha.hv-voice' => 'hvp',
+ 'application/vnd.yamaha.openscoreformat' => 'osf',
+ 'application/vnd.yamaha.openscoreformat.osfpvg+xml' => 'osfpvg',
+ 'application/vnd.yamaha.smaf-audio' => 'saf',
+ 'application/vnd.yamaha.smaf-phrase' => 'spf',
+ 'application/vnd.yellowriver-custom-menu' => 'cmp',
+ 'application/vnd.zul' => 'zir',
+ 'application/vnd.zzazz.deck+xml' => 'zaz',
+ 'application/voicexml+xml' => 'vxml',
+ 'application/widget' => 'wgt',
+ 'application/winhlp' => 'hlp',
+ 'application/wsdl+xml' => 'wsdl',
+ 'application/wspolicy+xml' => 'wspolicy',
+ 'application/x-7z-compressed' => '7z',
+ 'application/x-abiword' => 'abw',
+ 'application/x-ace-compressed' => 'ace',
+ 'application/x-apple-diskimage' => 'dmg',
+ 'application/x-authorware-bin' => 'aab',
+ 'application/x-authorware-map' => 'aam',
+ 'application/x-authorware-seg' => 'aas',
+ 'application/x-bcpio' => 'bcpio',
+ 'application/x-bittorrent' => 'torrent',
+ 'application/x-blorb' => 'blb',
+ 'application/x-bzip' => 'bz',
+ 'application/x-bzip2' => 'bz2',
+ 'application/x-cbr' => 'cbr',
+ 'application/x-cdlink' => 'vcd',
+ 'application/x-cfs-compressed' => 'cfs',
+ 'application/x-chat' => 'chat',
+ 'application/x-chess-pgn' => 'pgn',
+ 'application/x-conference' => 'nsc',
+ 'application/x-cpio' => 'cpio',
+ 'application/x-csh' => 'csh',
+ 'application/x-debian-package' => 'deb',
+ 'application/x-dgc-compressed' => 'dgc',
+ 'application/x-director' => 'dir',
+ 'application/x-doom' => 'wad',
+ 'application/x-dtbncx+xml' => 'ncx',
+ 'application/x-dtbook+xml' => 'dtb',
+ 'application/x-dtbresource+xml' => 'res',
+ 'application/x-dvi' => 'dvi',
+ 'application/x-envoy' => 'evy',
+ 'application/x-eva' => 'eva',
+ 'application/x-font-bdf' => 'bdf',
+ 'application/x-font-ghostscript' => 'gsf',
+ 'application/x-font-linux-psf' => 'psf',
+ 'application/x-font-otf' => 'otf',
+ 'application/x-font-pcf' => 'pcf',
+ 'application/x-font-snf' => 'snf',
+ 'application/x-font-ttf' => 'ttf',
+ 'application/x-font-type1' => 'pfa',
+ 'application/x-font-woff' => 'woff',
+ 'application/x-freearc' => 'arc',
+ 'application/x-futuresplash' => 'spl',
+ 'application/x-gca-compressed' => 'gca',
+ 'application/x-glulx' => 'ulx',
+ 'application/x-gnumeric' => 'gnumeric',
+ 'application/x-gramps-xml' => 'gramps',
+ 'application/x-gtar' => 'gtar',
+ 'application/x-hdf' => 'hdf',
+ 'application/x-install-instructions' => 'install',
+ 'application/x-iso9660-image' => 'iso',
+ 'application/x-java-jnlp-file' => 'jnlp',
+ 'application/x-latex' => 'latex',
+ 'application/x-lzh-compressed' => 'lzh',
+ 'application/x-mie' => 'mie',
+ 'application/x-mobipocket-ebook' => 'prc',
+ 'application/x-ms-application' => 'application',
+ 'application/x-ms-shortcut' => 'lnk',
+ 'application/x-ms-wmd' => 'wmd',
+ 'application/x-ms-wmz' => 'wmz',
+ 'application/x-ms-xbap' => 'xbap',
+ 'application/x-msaccess' => 'mdb',
+ 'application/x-msbinder' => 'obd',
+ 'application/x-mscardfile' => 'crd',
+ 'application/x-msclip' => 'clp',
+ 'application/x-msdownload' => 'exe',
+ 'application/x-msmediaview' => 'mvb',
+ 'application/x-msmetafile' => 'wmf',
+ 'application/x-msmoney' => 'mny',
+ 'application/x-mspublisher' => 'pub',
+ 'application/x-msschedule' => 'scd',
+ 'application/x-msterminal' => 'trm',
+ 'application/x-mswrite' => 'wri',
+ 'application/x-netcdf' => 'nc',
+ 'application/x-nzb' => 'nzb',
+ 'application/x-pkcs12' => 'p12',
+ 'application/x-pkcs7-certificates' => 'p7b',
+ 'application/x-pkcs7-certreqresp' => 'p7r',
+ 'application/x-rar-compressed' => 'rar',
+ 'application/x-rar' => 'rar',
+ 'application/x-research-info-systems' => 'ris',
+ 'application/x-sh' => 'sh',
+ 'application/x-shar' => 'shar',
+ 'application/x-shockwave-flash' => 'swf',
+ 'application/x-silverlight-app' => 'xap',
+ 'application/x-sql' => 'sql',
+ 'application/x-stuffit' => 'sit',
+ 'application/x-stuffitx' => 'sitx',
+ 'application/x-subrip' => 'srt',
+ 'application/x-sv4cpio' => 'sv4cpio',
+ 'application/x-sv4crc' => 'sv4crc',
+ 'application/x-t3vm-image' => 't3',
+ 'application/x-tads' => 'gam',
+ 'application/x-tar' => 'tar',
+ 'application/x-tcl' => 'tcl',
+ 'application/x-tex' => 'tex',
+ 'application/x-tex-tfm' => 'tfm',
+ 'application/x-texinfo' => 'texinfo',
+ 'application/x-tgif' => 'obj',
+ 'application/x-ustar' => 'ustar',
+ 'application/x-wais-source' => 'src',
+ 'application/x-x509-ca-cert' => 'der',
+ 'application/x-xfig' => 'fig',
+ 'application/x-xliff+xml' => 'xlf',
+ 'application/x-xpinstall' => 'xpi',
+ 'application/x-xz' => 'xz',
+ 'application/x-zip-compressed' => 'zip',
+ 'application/x-zmachine' => 'z1',
+ 'application/xaml+xml' => 'xaml',
+ 'application/xcap-diff+xml' => 'xdf',
+ 'application/xenc+xml' => 'xenc',
+ 'application/xhtml+xml' => 'xhtml',
+ 'application/xml' => 'xml',
+ 'application/xml-dtd' => 'dtd',
+ 'application/xop+xml' => 'xop',
+ 'application/xproc+xml' => 'xpl',
+ 'application/xslt+xml' => 'xslt',
+ 'application/xspf+xml' => 'xspf',
+ 'application/xv+xml' => 'mxml',
+ 'application/yang' => 'yang',
+ 'application/yin+xml' => 'yin',
+ 'application/zip' => 'zip',
+ 'audio/adpcm' => 'adp',
+ 'audio/basic' => 'au',
+ 'audio/midi' => 'mid',
+ 'audio/mp4' => 'mp4a',
+ 'audio/mpeg' => 'mpga',
+ 'audio/ogg' => 'oga',
+ 'audio/s3m' => 's3m',
+ 'audio/silk' => 'sil',
+ 'audio/vnd.dece.audio' => 'uva',
+ 'audio/vnd.digital-winds' => 'eol',
+ 'audio/vnd.dra' => 'dra',
+ 'audio/vnd.dts' => 'dts',
+ 'audio/vnd.dts.hd' => 'dtshd',
+ 'audio/vnd.lucent.voice' => 'lvp',
+ 'audio/vnd.ms-playready.media.pya' => 'pya',
+ 'audio/vnd.nuera.ecelp4800' => 'ecelp4800',
+ 'audio/vnd.nuera.ecelp7470' => 'ecelp7470',
+ 'audio/vnd.nuera.ecelp9600' => 'ecelp9600',
+ 'audio/vnd.rip' => 'rip',
+ 'audio/webm' => 'weba',
+ 'audio/x-aac' => 'aac',
+ 'audio/x-aiff' => 'aif',
+ 'audio/x-caf' => 'caf',
+ 'audio/x-flac' => 'flac',
+ 'audio/x-matroska' => 'mka',
+ 'audio/x-mpegurl' => 'm3u',
+ 'audio/x-ms-wax' => 'wax',
+ 'audio/x-ms-wma' => 'wma',
+ 'audio/x-pn-realaudio' => 'ram',
+ 'audio/x-pn-realaudio-plugin' => 'rmp',
+ 'audio/x-wav' => 'wav',
+ 'audio/xm' => 'xm',
+ 'chemical/x-cdx' => 'cdx',
+ 'chemical/x-cif' => 'cif',
+ 'chemical/x-cmdf' => 'cmdf',
+ 'chemical/x-cml' => 'cml',
+ 'chemical/x-csml' => 'csml',
+ 'chemical/x-xyz' => 'xyz',
+ 'image/bmp' => 'bmp',
+ 'image/x-ms-bmp' => 'bmp',
+ 'image/cgm' => 'cgm',
+ 'image/g3fax' => 'g3',
+ 'image/gif' => 'gif',
+ 'image/ief' => 'ief',
+ 'image/jpeg' => 'jpeg',
+ 'image/pjpeg' => 'jpeg',
+ 'image/ktx' => 'ktx',
+ 'image/png' => 'png',
+ 'image/prs.btif' => 'btif',
+ 'image/sgi' => 'sgi',
+ 'image/svg+xml' => 'svg',
+ 'image/tiff' => 'tiff',
+ 'image/vnd.adobe.photoshop' => 'psd',
+ 'image/vnd.dece.graphic' => 'uvi',
+ 'image/vnd.dvb.subtitle' => 'sub',
+ 'image/vnd.djvu' => 'djvu',
+ 'image/vnd.dwg' => 'dwg',
+ 'image/vnd.dxf' => 'dxf',
+ 'image/vnd.fastbidsheet' => 'fbs',
+ 'image/vnd.fpx' => 'fpx',
+ 'image/vnd.fst' => 'fst',
+ 'image/vnd.fujixerox.edmics-mmr' => 'mmr',
+ 'image/vnd.fujixerox.edmics-rlc' => 'rlc',
+ 'image/vnd.ms-modi' => 'mdi',
+ 'image/vnd.ms-photo' => 'wdp',
+ 'image/vnd.net-fpx' => 'npx',
+ 'image/vnd.wap.wbmp' => 'wbmp',
+ 'image/vnd.xiff' => 'xif',
+ 'image/webp' => 'webp',
+ 'image/x-3ds' => '3ds',
+ 'image/x-cmu-raster' => 'ras',
+ 'image/x-cmx' => 'cmx',
+ 'image/x-freehand' => 'fh',
+ 'image/x-icon' => 'ico',
+ 'image/x-mrsid-image' => 'sid',
+ 'image/x-pcx' => 'pcx',
+ 'image/x-pict' => 'pic',
+ 'image/x-portable-anymap' => 'pnm',
+ 'image/x-portable-bitmap' => 'pbm',
+ 'image/x-portable-graymap' => 'pgm',
+ 'image/x-portable-pixmap' => 'ppm',
+ 'image/x-rgb' => 'rgb',
+ 'image/x-tga' => 'tga',
+ 'image/x-xbitmap' => 'xbm',
+ 'image/x-xpixmap' => 'xpm',
+ 'image/x-xwindowdump' => 'xwd',
+ 'message/rfc822' => 'eml',
+ 'model/iges' => 'igs',
+ 'model/mesh' => 'msh',
+ 'model/vnd.collada+xml' => 'dae',
+ 'model/vnd.dwf' => 'dwf',
+ 'model/vnd.gdl' => 'gdl',
+ 'model/vnd.gtw' => 'gtw',
+ 'model/vnd.mts' => 'mts',
+ 'model/vnd.vtu' => 'vtu',
+ 'model/vrml' => 'wrl',
+ 'model/x3d+binary' => 'x3db',
+ 'model/x3d+vrml' => 'x3dv',
+ 'model/x3d+xml' => 'x3d',
+ 'text/cache-manifest' => 'appcache',
+ 'text/calendar' => 'ics',
+ 'text/css' => 'css',
+ 'text/csv' => 'csv',
+ 'text/html' => 'html',
+ 'text/n3' => 'n3',
+ 'text/plain' => 'txt',
+ 'text/prs.lines.tag' => 'dsc',
+ 'text/richtext' => 'rtx',
+ 'text/rtf' => 'rtf',
+ 'text/sgml' => 'sgml',
+ 'text/tab-separated-values' => 'tsv',
+ 'text/troff' => 't',
+ 'text/turtle' => 'ttl',
+ 'text/uri-list' => 'uri',
+ 'text/vcard' => 'vcard',
+ 'text/vnd.curl' => 'curl',
+ 'text/vnd.curl.dcurl' => 'dcurl',
+ 'text/vnd.curl.scurl' => 'scurl',
+ 'text/vnd.curl.mcurl' => 'mcurl',
+ 'text/vnd.dvb.subtitle' => 'sub',
+ 'text/vnd.fly' => 'fly',
+ 'text/vnd.fmi.flexstor' => 'flx',
+ 'text/vnd.graphviz' => 'gv',
+ 'text/vnd.in3d.3dml' => '3dml',
+ 'text/vnd.in3d.spot' => 'spot',
+ 'text/vnd.sun.j2me.app-descriptor' => 'jad',
+ 'text/vnd.wap.wml' => 'wml',
+ 'text/vnd.wap.wmlscript' => 'wmls',
+ 'text/vtt' => 'vtt',
+ 'text/x-asm' => 's',
+ 'text/x-c' => 'c',
+ 'text/x-fortran' => 'f',
+ 'text/x-pascal' => 'p',
+ 'text/x-java-source' => 'java',
+ 'text/x-opml' => 'opml',
+ 'text/x-nfo' => 'nfo',
+ 'text/x-setext' => 'etx',
+ 'text/x-sfv' => 'sfv',
+ 'text/x-uuencode' => 'uu',
+ 'text/x-vcalendar' => 'vcs',
+ 'text/x-vcard' => 'vcf',
+ 'video/3gpp' => '3gp',
+ 'video/3gpp2' => '3g2',
+ 'video/h261' => 'h261',
+ 'video/h263' => 'h263',
+ 'video/h264' => 'h264',
+ 'video/jpeg' => 'jpgv',
+ 'video/jpm' => 'jpm',
+ 'video/mj2' => 'mj2',
+ 'video/mp4' => 'mp4',
+ 'video/mpeg' => 'mpeg',
+ 'video/ogg' => 'ogv',
+ 'video/quicktime' => 'qt',
+ 'video/vnd.dece.hd' => 'uvh',
+ 'video/vnd.dece.mobile' => 'uvm',
+ 'video/vnd.dece.pd' => 'uvp',
+ 'video/vnd.dece.sd' => 'uvs',
+ 'video/vnd.dece.video' => 'uvv',
+ 'video/vnd.dvb.file' => 'dvb',
+ 'video/vnd.fvt' => 'fvt',
+ 'video/vnd.mpegurl' => 'mxu',
+ 'video/vnd.ms-playready.media.pyv' => 'pyv',
+ 'video/vnd.uvvu.mp4' => 'uvu',
+ 'video/vnd.vivo' => 'viv',
+ 'video/webm' => 'webm',
+ 'video/x-f4v' => 'f4v',
+ 'video/x-fli' => 'fli',
+ 'video/x-flv' => 'flv',
+ 'video/x-m4v' => 'm4v',
+ 'video/x-matroska' => 'mkv',
+ 'video/x-mng' => 'mng',
+ 'video/x-ms-asf' => 'asf',
+ 'video/x-ms-vob' => 'vob',
+ 'video/x-ms-wm' => 'wm',
+ 'video/x-ms-wmv' => 'wmv',
+ 'video/x-ms-wmx' => 'wmx',
+ 'video/x-ms-wvx' => 'wvx',
+ 'video/x-msvideo' => 'avi',
+ 'video/x-sgi-movie' => 'movie',
+ 'video/x-smv' => 'smv',
+ 'x-conference/x-cooltalk' => 'ice',
+ );
+
+ /**
+ * {@inheritdoc}
+ */
+ public function guess($mimeType)
+ {
+ return isset($this->defaultExtensions[$mimeType]) ? $this->defaultExtensions[$mimeType] : null;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/MimeType/MimeTypeGuesser.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/MimeType/MimeTypeGuesser.php
new file mode 100644
index 0000000..e3ef45e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/MimeType/MimeTypeGuesser.php
@@ -0,0 +1,142 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File\MimeType;
+
+use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
+use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;
+
+/**
+ * A singleton mime type guesser.
+ *
+ * By default, all mime type guessers provided by the framework are installed
+ * (if available on the current OS/PHP setup).
+ *
+ * You can register custom guessers by calling the register() method on the
+ * singleton instance. Custom guessers are always called before any default ones.
+ *
+ * $guesser = MimeTypeGuesser::getInstance();
+ * $guesser->register(new MyCustomMimeTypeGuesser());
+ *
+ * If you want to change the order of the default guessers, just re-register your
+ * preferred one as a custom one. The last registered guesser is preferred over
+ * previously registered ones.
+ *
+ * Re-registering a built-in guesser also allows you to configure it:
+ *
+ * $guesser = MimeTypeGuesser::getInstance();
+ * $guesser->register(new FileinfoMimeTypeGuesser('/path/to/magic/file'));
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class MimeTypeGuesser implements MimeTypeGuesserInterface
+{
+ /**
+ * The singleton instance.
+ *
+ * @var MimeTypeGuesser
+ */
+ private static $instance = null;
+
+ /**
+ * All registered MimeTypeGuesserInterface instances.
+ *
+ * @var array
+ */
+ protected $guessers = array();
+
+ /**
+ * Returns the singleton instance.
+ *
+ * @return self
+ */
+ public static function getInstance()
+ {
+ if (null === self::$instance) {
+ self::$instance = new self();
+ }
+
+ return self::$instance;
+ }
+
+ /**
+ * Resets the singleton instance.
+ */
+ public static function reset()
+ {
+ self::$instance = null;
+ }
+
+ /**
+ * Registers all natively provided mime type guessers.
+ */
+ private function __construct()
+ {
+ if (FileBinaryMimeTypeGuesser::isSupported()) {
+ $this->register(new FileBinaryMimeTypeGuesser());
+ }
+
+ if (FileinfoMimeTypeGuesser::isSupported()) {
+ $this->register(new FileinfoMimeTypeGuesser());
+ }
+ }
+
+ /**
+ * Registers a new mime type guesser.
+ *
+ * When guessing, this guesser is preferred over previously registered ones.
+ */
+ public function register(MimeTypeGuesserInterface $guesser)
+ {
+ array_unshift($this->guessers, $guesser);
+ }
+
+ /**
+ * Tries to guess the mime type of the given file.
+ *
+ * The file is passed to each registered mime type guesser in reverse order
+ * of their registration (last registered is queried first). Once a guesser
+ * returns a value that is not NULL, this method terminates and returns the
+ * value.
+ *
+ * @param string $path The path to the file
+ *
+ * @return string The mime type or NULL, if none could be guessed
+ *
+ * @throws \LogicException
+ * @throws FileNotFoundException
+ * @throws AccessDeniedException
+ */
+ public function guess($path)
+ {
+ if (!is_file($path)) {
+ throw new FileNotFoundException($path);
+ }
+
+ if (!is_readable($path)) {
+ throw new AccessDeniedException($path);
+ }
+
+ if (!$this->guessers) {
+ $msg = 'Unable to guess the mime type as no guessers are available';
+ if (!FileinfoMimeTypeGuesser::isSupported()) {
+ $msg .= ' (Did you enable the php_fileinfo extension?)';
+ }
+ throw new \LogicException($msg);
+ }
+
+ foreach ($this->guessers as $guesser) {
+ if (null !== $mimeType = $guesser->guess($path)) {
+ return $mimeType;
+ }
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/MimeType/MimeTypeGuesserInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/MimeType/MimeTypeGuesserInterface.php
new file mode 100644
index 0000000..f8c3ad2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/MimeType/MimeTypeGuesserInterface.php
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File\MimeType;
+
+use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
+use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;
+
+/**
+ * Guesses the mime type of a file.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+interface MimeTypeGuesserInterface
+{
+ /**
+ * Guesses the mime type of the file with the given path.
+ *
+ * @param string $path The path to the file
+ *
+ * @return string The mime type or NULL, if none could be guessed
+ *
+ * @throws FileNotFoundException If the file does not exist
+ * @throws AccessDeniedException If the file could not be read
+ */
+ public function guess($path);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/Stream.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/Stream.php
new file mode 100644
index 0000000..69ae74c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/Stream.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File;
+
+/**
+ * A PHP stream of unknown size.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class Stream extends File
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function getSize()
+ {
+ return false;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/UploadedFile.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/UploadedFile.php
new file mode 100644
index 0000000..082d8d5
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/File/UploadedFile.php
@@ -0,0 +1,266 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File;
+
+use Symfony\Component\HttpFoundation\File\Exception\FileException;
+use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
+use Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesser;
+
+/**
+ * A file uploaded through a form.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @author Florian Eckerstorfer <florian@eckerstorfer.org>
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class UploadedFile extends File
+{
+ private $test = false;
+ private $originalName;
+ private $mimeType;
+ private $size;
+ private $error;
+
+ /**
+ * Accepts the information of the uploaded file as provided by the PHP global $_FILES.
+ *
+ * The file object is only created when the uploaded file is valid (i.e. when the
+ * isValid() method returns true). Otherwise the only methods that could be called
+ * on an UploadedFile instance are:
+ *
+ * * getClientOriginalName,
+ * * getClientMimeType,
+ * * isValid,
+ * * getError.
+ *
+ * Calling any other method on an non-valid instance will cause an unpredictable result.
+ *
+ * @param string $path The full temporary path to the file
+ * @param string $originalName The original file name of the uploaded file
+ * @param string|null $mimeType The type of the file as provided by PHP; null defaults to application/octet-stream
+ * @param int|null $size The file size provided by the uploader
+ * @param int|null $error The error constant of the upload (one of PHP's UPLOAD_ERR_XXX constants); null defaults to UPLOAD_ERR_OK
+ * @param bool $test Whether the test mode is active
+ * Local files are used in test mode hence the code should not enforce HTTP uploads
+ *
+ * @throws FileException If file_uploads is disabled
+ * @throws FileNotFoundException If the file does not exist
+ */
+ public function __construct($path, $originalName, $mimeType = null, $size = null, $error = null, $test = false)
+ {
+ $this->originalName = $this->getName($originalName);
+ $this->mimeType = $mimeType ?: 'application/octet-stream';
+ $this->size = $size;
+ $this->error = $error ?: UPLOAD_ERR_OK;
+ $this->test = (bool) $test;
+
+ parent::__construct($path, UPLOAD_ERR_OK === $this->error);
+ }
+
+ /**
+ * Returns the original file name.
+ *
+ * It is extracted from the request from which the file has been uploaded.
+ * Then it should not be considered as a safe value.
+ *
+ * @return string|null The original name
+ */
+ public function getClientOriginalName()
+ {
+ return $this->originalName;
+ }
+
+ /**
+ * Returns the original file extension.
+ *
+ * It is extracted from the original file name that was uploaded.
+ * Then it should not be considered as a safe value.
+ *
+ * @return string The extension
+ */
+ public function getClientOriginalExtension()
+ {
+ return pathinfo($this->originalName, PATHINFO_EXTENSION);
+ }
+
+ /**
+ * Returns the file mime type.
+ *
+ * The client mime type is extracted from the request from which the file
+ * was uploaded, so it should not be considered as a safe value.
+ *
+ * For a trusted mime type, use getMimeType() instead (which guesses the mime
+ * type based on the file content).
+ *
+ * @return string|null The mime type
+ *
+ * @see getMimeType()
+ */
+ public function getClientMimeType()
+ {
+ return $this->mimeType;
+ }
+
+ /**
+ * Returns the extension based on the client mime type.
+ *
+ * If the mime type is unknown, returns null.
+ *
+ * This method uses the mime type as guessed by getClientMimeType()
+ * to guess the file extension. As such, the extension returned
+ * by this method cannot be trusted.
+ *
+ * For a trusted extension, use guessExtension() instead (which guesses
+ * the extension based on the guessed mime type for the file).
+ *
+ * @return string|null The guessed extension or null if it cannot be guessed
+ *
+ * @see guessExtension()
+ * @see getClientMimeType()
+ */
+ public function guessClientExtension()
+ {
+ $type = $this->getClientMimeType();
+ $guesser = ExtensionGuesser::getInstance();
+
+ return $guesser->guess($type);
+ }
+
+ /**
+ * Returns the file size.
+ *
+ * It is extracted from the request from which the file has been uploaded.
+ * Then it should not be considered as a safe value.
+ *
+ * @return int|null The file size
+ */
+ public function getClientSize()
+ {
+ return $this->size;
+ }
+
+ /**
+ * Returns the upload error.
+ *
+ * If the upload was successful, the constant UPLOAD_ERR_OK is returned.
+ * Otherwise one of the other UPLOAD_ERR_XXX constants is returned.
+ *
+ * @return int The upload error
+ */
+ public function getError()
+ {
+ return $this->error;
+ }
+
+ /**
+ * Returns whether the file was uploaded successfully.
+ *
+ * @return bool True if the file has been uploaded with HTTP and no error occurred
+ */
+ public function isValid()
+ {
+ $isOk = UPLOAD_ERR_OK === $this->error;
+
+ return $this->test ? $isOk : $isOk && is_uploaded_file($this->getPathname());
+ }
+
+ /**
+ * Moves the file to a new location.
+ *
+ * @param string $directory The destination folder
+ * @param string $name The new file name
+ *
+ * @return File A File object representing the new file
+ *
+ * @throws FileException if, for any reason, the file could not have been moved
+ */
+ public function move($directory, $name = null)
+ {
+ if ($this->isValid()) {
+ if ($this->test) {
+ return parent::move($directory, $name);
+ }
+
+ $target = $this->getTargetFile($directory, $name);
+
+ if (!@move_uploaded_file($this->getPathname(), $target)) {
+ $error = error_get_last();
+ throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error['message'])));
+ }
+
+ @chmod($target, 0666 & ~umask());
+
+ return $target;
+ }
+
+ throw new FileException($this->getErrorMessage());
+ }
+
+ /**
+ * Returns the maximum size of an uploaded file as configured in php.ini.
+ *
+ * @return int The maximum size of an uploaded file in bytes
+ */
+ public static function getMaxFilesize()
+ {
+ $iniMax = strtolower(ini_get('upload_max_filesize'));
+
+ if ('' === $iniMax) {
+ return PHP_INT_MAX;
+ }
+
+ $max = ltrim($iniMax, '+');
+ if (0 === strpos($max, '0x')) {
+ $max = intval($max, 16);
+ } elseif (0 === strpos($max, '0')) {
+ $max = intval($max, 8);
+ } else {
+ $max = (int) $max;
+ }
+
+ switch (substr($iniMax, -1)) {
+ case 't': $max *= 1024;
+ // no break
+ case 'g': $max *= 1024;
+ // no break
+ case 'm': $max *= 1024;
+ // no break
+ case 'k': $max *= 1024;
+ }
+
+ return $max;
+ }
+
+ /**
+ * Returns an informative upload error message.
+ *
+ * @return string The error message regarding the specified error code
+ */
+ public function getErrorMessage()
+ {
+ static $errors = array(
+ UPLOAD_ERR_INI_SIZE => 'The file "%s" exceeds your upload_max_filesize ini directive (limit is %d KiB).',
+ UPLOAD_ERR_FORM_SIZE => 'The file "%s" exceeds the upload limit defined in your form.',
+ UPLOAD_ERR_PARTIAL => 'The file "%s" was only partially uploaded.',
+ UPLOAD_ERR_NO_FILE => 'No file was uploaded.',
+ UPLOAD_ERR_CANT_WRITE => 'The file "%s" could not be written on disk.',
+ UPLOAD_ERR_NO_TMP_DIR => 'File could not be uploaded: missing temporary directory.',
+ UPLOAD_ERR_EXTENSION => 'File upload was stopped by a PHP extension.',
+ );
+
+ $errorCode = $this->error;
+ $maxFilesize = UPLOAD_ERR_INI_SIZE === $errorCode ? self::getMaxFilesize() / 1024 : 0;
+ $message = isset($errors[$errorCode]) ? $errors[$errorCode] : 'The file "%s" was not uploaded due to an unknown error.';
+
+ return sprintf($message, $this->getClientOriginalName(), $maxFilesize);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/FileBag.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/FileBag.php
new file mode 100644
index 0000000..5edd0e6
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/FileBag.php
@@ -0,0 +1,144 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+use Symfony\Component\HttpFoundation\File\UploadedFile;
+
+/**
+ * FileBag is a container for uploaded files.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Bulat Shakirzyanov <mallluhuct@gmail.com>
+ */
+class FileBag extends ParameterBag
+{
+ private static $fileKeys = array('error', 'name', 'size', 'tmp_name', 'type');
+
+ /**
+ * @param array $parameters An array of HTTP files
+ */
+ public function __construct(array $parameters = array())
+ {
+ $this->replace($parameters);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function replace(array $files = array())
+ {
+ $this->parameters = array();
+ $this->add($files);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set($key, $value)
+ {
+ if (!is_array($value) && !$value instanceof UploadedFile) {
+ throw new \InvalidArgumentException('An uploaded file must be an array or an instance of UploadedFile.');
+ }
+
+ parent::set($key, $this->convertFileInformation($value));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function add(array $files = array())
+ {
+ foreach ($files as $key => $file) {
+ $this->set($key, $file);
+ }
+ }
+
+ /**
+ * Converts uploaded files to UploadedFile instances.
+ *
+ * @param array|UploadedFile $file A (multi-dimensional) array of uploaded file information
+ *
+ * @return UploadedFile[]|UploadedFile|null A (multi-dimensional) array of UploadedFile instances
+ */
+ protected function convertFileInformation($file)
+ {
+ if ($file instanceof UploadedFile) {
+ return $file;
+ }
+
+ $file = $this->fixPhpFilesArray($file);
+ if (is_array($file)) {
+ $keys = array_keys($file);
+ sort($keys);
+
+ if ($keys == self::$fileKeys) {
+ if (UPLOAD_ERR_NO_FILE == $file['error']) {
+ $file = null;
+ } else {
+ $file = new UploadedFile($file['tmp_name'], $file['name'], $file['type'], $file['size'], $file['error']);
+ }
+ } else {
+ $file = array_map(array($this, 'convertFileInformation'), $file);
+ if (array_keys($keys) === $keys) {
+ $file = array_filter($file);
+ }
+ }
+ }
+
+ return $file;
+ }
+
+ /**
+ * Fixes a malformed PHP $_FILES array.
+ *
+ * PHP has a bug that the format of the $_FILES array differs, depending on
+ * whether the uploaded file fields had normal field names or array-like
+ * field names ("normal" vs. "parent[child]").
+ *
+ * This method fixes the array to look like the "normal" $_FILES array.
+ *
+ * It's safe to pass an already converted array, in which case this method
+ * just returns the original array unmodified.
+ *
+ * @return array
+ */
+ protected function fixPhpFilesArray($data)
+ {
+ if (!is_array($data)) {
+ return $data;
+ }
+
+ $keys = array_keys($data);
+ sort($keys);
+
+ if (self::$fileKeys != $keys || !isset($data['name']) || !is_array($data['name'])) {
+ return $data;
+ }
+
+ $files = $data;
+ foreach (self::$fileKeys as $k) {
+ unset($files[$k]);
+ }
+
+ foreach ($data['name'] as $key => $name) {
+ $files[$key] = $this->fixPhpFilesArray(array(
+ 'error' => $data['error'][$key],
+ 'name' => $name,
+ 'type' => $data['type'][$key],
+ 'tmp_name' => $data['tmp_name'][$key],
+ 'size' => $data['size'][$key],
+ ));
+ }
+
+ return $files;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/HeaderBag.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/HeaderBag.php
new file mode 100644
index 0000000..7aaa52a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/HeaderBag.php
@@ -0,0 +1,331 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * HeaderBag is a container for HTTP headers.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class HeaderBag implements \IteratorAggregate, \Countable
+{
+ protected $headers = array();
+ protected $cacheControl = array();
+
+ /**
+ * @param array $headers An array of HTTP headers
+ */
+ public function __construct(array $headers = array())
+ {
+ foreach ($headers as $key => $values) {
+ $this->set($key, $values);
+ }
+ }
+
+ /**
+ * Returns the headers as a string.
+ *
+ * @return string The headers
+ */
+ public function __toString()
+ {
+ if (!$headers = $this->all()) {
+ return '';
+ }
+
+ ksort($headers);
+ $max = max(array_map('strlen', array_keys($headers))) + 1;
+ $content = '';
+ foreach ($headers as $name => $values) {
+ $name = implode('-', array_map('ucfirst', explode('-', $name)));
+ foreach ($values as $value) {
+ $content .= sprintf("%-{$max}s %s\r\n", $name.':', $value);
+ }
+ }
+
+ return $content;
+ }
+
+ /**
+ * Returns the headers.
+ *
+ * @return array An array of headers
+ */
+ public function all()
+ {
+ return $this->headers;
+ }
+
+ /**
+ * Returns the parameter keys.
+ *
+ * @return array An array of parameter keys
+ */
+ public function keys()
+ {
+ return array_keys($this->all());
+ }
+
+ /**
+ * Replaces the current HTTP headers by a new set.
+ *
+ * @param array $headers An array of HTTP headers
+ */
+ public function replace(array $headers = array())
+ {
+ $this->headers = array();
+ $this->add($headers);
+ }
+
+ /**
+ * Adds new headers the current HTTP headers set.
+ *
+ * @param array $headers An array of HTTP headers
+ */
+ public function add(array $headers)
+ {
+ foreach ($headers as $key => $values) {
+ $this->set($key, $values);
+ }
+ }
+
+ /**
+ * Returns a header value by name.
+ *
+ * @param string $key The header name
+ * @param string|string[] $default The default value
+ * @param bool $first Whether to return the first value or all header values
+ *
+ * @return string|string[] The first header value or default value if $first is true, an array of values otherwise
+ */
+ public function get($key, $default = null, $first = true)
+ {
+ $key = str_replace('_', '-', strtolower($key));
+ $headers = $this->all();
+
+ if (!array_key_exists($key, $headers)) {
+ if (null === $default) {
+ return $first ? null : array();
+ }
+
+ return $first ? $default : array($default);
+ }
+
+ if ($first) {
+ return \count($headers[$key]) ? $headers[$key][0] : $default;
+ }
+
+ return $headers[$key];
+ }
+
+ /**
+ * Sets a header by name.
+ *
+ * @param string $key The key
+ * @param string|string[] $values The value or an array of values
+ * @param bool $replace Whether to replace the actual value or not (true by default)
+ */
+ public function set($key, $values, $replace = true)
+ {
+ $key = str_replace('_', '-', strtolower($key));
+
+ if (\is_array($values)) {
+ $values = array_values($values);
+
+ if (true === $replace || !isset($this->headers[$key])) {
+ $this->headers[$key] = $values;
+ } else {
+ $this->headers[$key] = array_merge($this->headers[$key], $values);
+ }
+ } else {
+ if (true === $replace || !isset($this->headers[$key])) {
+ $this->headers[$key] = array($values);
+ } else {
+ $this->headers[$key][] = $values;
+ }
+ }
+
+ if ('cache-control' === $key) {
+ $this->cacheControl = $this->parseCacheControl(implode(', ', $this->headers[$key]));
+ }
+ }
+
+ /**
+ * Returns true if the HTTP header is defined.
+ *
+ * @param string $key The HTTP header
+ *
+ * @return bool true if the parameter exists, false otherwise
+ */
+ public function has($key)
+ {
+ return array_key_exists(str_replace('_', '-', strtolower($key)), $this->all());
+ }
+
+ /**
+ * Returns true if the given HTTP header contains the given value.
+ *
+ * @param string $key The HTTP header name
+ * @param string $value The HTTP value
+ *
+ * @return bool true if the value is contained in the header, false otherwise
+ */
+ public function contains($key, $value)
+ {
+ return in_array($value, $this->get($key, null, false));
+ }
+
+ /**
+ * Removes a header.
+ *
+ * @param string $key The HTTP header name
+ */
+ public function remove($key)
+ {
+ $key = str_replace('_', '-', strtolower($key));
+
+ unset($this->headers[$key]);
+
+ if ('cache-control' === $key) {
+ $this->cacheControl = array();
+ }
+ }
+
+ /**
+ * Returns the HTTP header value converted to a date.
+ *
+ * @param string $key The parameter key
+ * @param \DateTime $default The default value
+ *
+ * @return null|\DateTime The parsed DateTime or the default value if the header does not exist
+ *
+ * @throws \RuntimeException When the HTTP header is not parseable
+ */
+ public function getDate($key, \DateTime $default = null)
+ {
+ if (null === $value = $this->get($key)) {
+ return $default;
+ }
+
+ if (false === $date = \DateTime::createFromFormat(DATE_RFC2822, $value)) {
+ throw new \RuntimeException(sprintf('The %s HTTP header is not parseable (%s).', $key, $value));
+ }
+
+ return $date;
+ }
+
+ /**
+ * Adds a custom Cache-Control directive.
+ *
+ * @param string $key The Cache-Control directive name
+ * @param mixed $value The Cache-Control directive value
+ */
+ public function addCacheControlDirective($key, $value = true)
+ {
+ $this->cacheControl[$key] = $value;
+
+ $this->set('Cache-Control', $this->getCacheControlHeader());
+ }
+
+ /**
+ * Returns true if the Cache-Control directive is defined.
+ *
+ * @param string $key The Cache-Control directive
+ *
+ * @return bool true if the directive exists, false otherwise
+ */
+ public function hasCacheControlDirective($key)
+ {
+ return array_key_exists($key, $this->cacheControl);
+ }
+
+ /**
+ * Returns a Cache-Control directive value by name.
+ *
+ * @param string $key The directive name
+ *
+ * @return mixed|null The directive value if defined, null otherwise
+ */
+ public function getCacheControlDirective($key)
+ {
+ return array_key_exists($key, $this->cacheControl) ? $this->cacheControl[$key] : null;
+ }
+
+ /**
+ * Removes a Cache-Control directive.
+ *
+ * @param string $key The Cache-Control directive
+ */
+ public function removeCacheControlDirective($key)
+ {
+ unset($this->cacheControl[$key]);
+
+ $this->set('Cache-Control', $this->getCacheControlHeader());
+ }
+
+ /**
+ * Returns an iterator for headers.
+ *
+ * @return \ArrayIterator An \ArrayIterator instance
+ */
+ public function getIterator()
+ {
+ return new \ArrayIterator($this->headers);
+ }
+
+ /**
+ * Returns the number of headers.
+ *
+ * @return int The number of headers
+ */
+ public function count()
+ {
+ return count($this->headers);
+ }
+
+ protected function getCacheControlHeader()
+ {
+ $parts = array();
+ ksort($this->cacheControl);
+ foreach ($this->cacheControl as $key => $value) {
+ if (true === $value) {
+ $parts[] = $key;
+ } else {
+ if (preg_match('#[^a-zA-Z0-9._-]#', $value)) {
+ $value = '"'.$value.'"';
+ }
+
+ $parts[] = "$key=$value";
+ }
+ }
+
+ return implode(', ', $parts);
+ }
+
+ /**
+ * Parses a Cache-Control HTTP header.
+ *
+ * @param string $header The value of the Cache-Control HTTP header
+ *
+ * @return array An array representing the attribute values
+ */
+ protected function parseCacheControl($header)
+ {
+ $cacheControl = array();
+ preg_match_all('#([a-zA-Z][a-zA-Z_-]*)\s*(?:=(?:"([^"]*)"|([^ \t",;]*)))?#', $header, $matches, PREG_SET_ORDER);
+ foreach ($matches as $match) {
+ $cacheControl[strtolower($match[1])] = isset($match[3]) ? $match[3] : (isset($match[2]) ? $match[2] : true);
+ }
+
+ return $cacheControl;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/IpUtils.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/IpUtils.php
new file mode 100644
index 0000000..86d135b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/IpUtils.php
@@ -0,0 +1,156 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * Http utility functions.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class IpUtils
+{
+ private static $checkedIps = array();
+
+ /**
+ * This class should not be instantiated.
+ */
+ private function __construct()
+ {
+ }
+
+ /**
+ * Checks if an IPv4 or IPv6 address is contained in the list of given IPs or subnets.
+ *
+ * @param string $requestIp IP to check
+ * @param string|array $ips List of IPs or subnets (can be a string if only a single one)
+ *
+ * @return bool Whether the IP is valid
+ */
+ public static function checkIp($requestIp, $ips)
+ {
+ if (!is_array($ips)) {
+ $ips = array($ips);
+ }
+
+ $method = substr_count($requestIp, ':') > 1 ? 'checkIp6' : 'checkIp4';
+
+ foreach ($ips as $ip) {
+ if (self::$method($requestIp, $ip)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Compares two IPv4 addresses.
+ * In case a subnet is given, it checks if it contains the request IP.
+ *
+ * @param string $requestIp IPv4 address to check
+ * @param string $ip IPv4 address or subnet in CIDR notation
+ *
+ * @return bool Whether the request IP matches the IP, or whether the request IP is within the CIDR subnet
+ */
+ public static function checkIp4($requestIp, $ip)
+ {
+ $cacheKey = $requestIp.'-'.$ip;
+ if (isset(self::$checkedIps[$cacheKey])) {
+ return self::$checkedIps[$cacheKey];
+ }
+
+ if (!filter_var($requestIp, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
+ return self::$checkedIps[$cacheKey] = false;
+ }
+
+ if (false !== strpos($ip, '/')) {
+ list($address, $netmask) = explode('/', $ip, 2);
+
+ if ('0' === $netmask) {
+ return self::$checkedIps[$cacheKey] = filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
+ }
+
+ if ($netmask < 0 || $netmask > 32) {
+ return self::$checkedIps[$cacheKey] = false;
+ }
+ } else {
+ $address = $ip;
+ $netmask = 32;
+ }
+
+ if (false === ip2long($address)) {
+ return self::$checkedIps[$cacheKey] = false;
+ }
+
+ return self::$checkedIps[$cacheKey] = 0 === substr_compare(sprintf('%032b', ip2long($requestIp)), sprintf('%032b', ip2long($address)), 0, $netmask);
+ }
+
+ /**
+ * Compares two IPv6 addresses.
+ * In case a subnet is given, it checks if it contains the request IP.
+ *
+ * @author David Soria Parra <dsp at php dot net>
+ *
+ * @see https://github.com/dsp/v6tools
+ *
+ * @param string $requestIp IPv6 address to check
+ * @param string $ip IPv6 address or subnet in CIDR notation
+ *
+ * @return bool Whether the IP is valid
+ *
+ * @throws \RuntimeException When IPV6 support is not enabled
+ */
+ public static function checkIp6($requestIp, $ip)
+ {
+ $cacheKey = $requestIp.'-'.$ip;
+ if (isset(self::$checkedIps[$cacheKey])) {
+ return self::$checkedIps[$cacheKey];
+ }
+
+ if (!((extension_loaded('sockets') && defined('AF_INET6')) || @inet_pton('::1'))) {
+ throw new \RuntimeException('Unable to check Ipv6. Check that PHP was not compiled with option "disable-ipv6".');
+ }
+
+ if (false !== strpos($ip, '/')) {
+ list($address, $netmask) = explode('/', $ip, 2);
+
+ if ('0' === $netmask) {
+ return (bool) unpack('n*', @inet_pton($address));
+ }
+
+ if ($netmask < 1 || $netmask > 128) {
+ return self::$checkedIps[$cacheKey] = false;
+ }
+ } else {
+ $address = $ip;
+ $netmask = 128;
+ }
+
+ $bytesAddr = unpack('n*', @inet_pton($address));
+ $bytesTest = unpack('n*', @inet_pton($requestIp));
+
+ if (!$bytesAddr || !$bytesTest) {
+ return self::$checkedIps[$cacheKey] = false;
+ }
+
+ for ($i = 1, $ceil = ceil($netmask / 16); $i <= $ceil; ++$i) {
+ $left = $netmask - 16 * ($i - 1);
+ $left = ($left <= 16) ? $left : 16;
+ $mask = ~(0xffff >> $left) & 0xffff;
+ if (($bytesAddr[$i] & $mask) != ($bytesTest[$i] & $mask)) {
+ return self::$checkedIps[$cacheKey] = false;
+ }
+ }
+
+ return self::$checkedIps[$cacheKey] = true;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/JsonResponse.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/JsonResponse.php
new file mode 100644
index 0000000..137ac33
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/JsonResponse.php
@@ -0,0 +1,220 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * Response represents an HTTP response in JSON format.
+ *
+ * Note that this class does not force the returned JSON content to be an
+ * object. It is however recommended that you do return an object as it
+ * protects yourself against XSSI and JSON-JavaScript Hijacking.
+ *
+ * @see https://www.owasp.org/index.php/OWASP_AJAX_Security_Guidelines#Always_return_JSON_with_an_Object_on_the_outside
+ *
+ * @author Igor Wiedler <igor@wiedler.ch>
+ */
+class JsonResponse extends Response
+{
+ protected $data;
+ protected $callback;
+
+ // Encode <, >, ', &, and " characters in the JSON, making it also safe to be embedded into HTML.
+ // 15 === JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT
+ const DEFAULT_ENCODING_OPTIONS = 15;
+
+ protected $encodingOptions = self::DEFAULT_ENCODING_OPTIONS;
+
+ /**
+ * @param mixed $data The response data
+ * @param int $status The response status code
+ * @param array $headers An array of response headers
+ * @param bool $json If the data is already a JSON string
+ */
+ public function __construct($data = null, $status = 200, $headers = array(), $json = false)
+ {
+ parent::__construct('', $status, $headers);
+
+ if (null === $data) {
+ $data = new \ArrayObject();
+ }
+
+ $json ? $this->setJson($data) : $this->setData($data);
+ }
+
+ /**
+ * Factory method for chainability.
+ *
+ * Example:
+ *
+ * return JsonResponse::create($data, 200)
+ * ->setSharedMaxAge(300);
+ *
+ * @param mixed $data The json response data
+ * @param int $status The response status code
+ * @param array $headers An array of response headers
+ *
+ * @return static
+ */
+ public static function create($data = null, $status = 200, $headers = array())
+ {
+ return new static($data, $status, $headers);
+ }
+
+ /**
+ * Make easier the creation of JsonResponse from raw json.
+ */
+ public static function fromJsonString($data = null, $status = 200, $headers = array())
+ {
+ return new static($data, $status, $headers, true);
+ }
+
+ /**
+ * Sets the JSONP callback.
+ *
+ * @param string|null $callback The JSONP callback or null to use none
+ *
+ * @return $this
+ *
+ * @throws \InvalidArgumentException When the callback name is not valid
+ */
+ public function setCallback($callback = null)
+ {
+ if (null !== $callback) {
+ // partially taken from http://www.geekality.net/2011/08/03/valid-javascript-identifier/
+ // partially taken from https://github.com/willdurand/JsonpCallbackValidator
+ // JsonpCallbackValidator is released under the MIT License. See https://github.com/willdurand/JsonpCallbackValidator/blob/v1.1.0/LICENSE for details.
+ // (c) William Durand <william.durand1@gmail.com>
+ $pattern = '/^[$_\p{L}][$_\p{L}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]*(?:\[(?:"(?:\\\.|[^"\\\])*"|\'(?:\\\.|[^\'\\\])*\'|\d+)\])*?$/u';
+ $reserved = array(
+ 'break', 'do', 'instanceof', 'typeof', 'case', 'else', 'new', 'var', 'catch', 'finally', 'return', 'void', 'continue', 'for', 'switch', 'while',
+ 'debugger', 'function', 'this', 'with', 'default', 'if', 'throw', 'delete', 'in', 'try', 'class', 'enum', 'extends', 'super', 'const', 'export',
+ 'import', 'implements', 'let', 'private', 'public', 'yield', 'interface', 'package', 'protected', 'static', 'null', 'true', 'false',
+ );
+ $parts = explode('.', $callback);
+ foreach ($parts as $part) {
+ if (!preg_match($pattern, $part) || in_array($part, $reserved, true)) {
+ throw new \InvalidArgumentException('The callback name is not valid.');
+ }
+ }
+ }
+
+ $this->callback = $callback;
+
+ return $this->update();
+ }
+
+ /**
+ * Sets a raw string containing a JSON document to be sent.
+ *
+ * @param string $json
+ *
+ * @return $this
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function setJson($json)
+ {
+ $this->data = $json;
+
+ return $this->update();
+ }
+
+ /**
+ * Sets the data to be sent as JSON.
+ *
+ * @param mixed $data
+ *
+ * @return $this
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function setData($data = array())
+ {
+ if (defined('HHVM_VERSION')) {
+ // HHVM does not trigger any warnings and let exceptions
+ // thrown from a JsonSerializable object pass through.
+ // If only PHP did the same...
+ $data = json_encode($data, $this->encodingOptions);
+ } else {
+ if (!interface_exists('JsonSerializable', false)) {
+ set_error_handler(function () { return false; });
+ try {
+ $data = @json_encode($data, $this->encodingOptions);
+ } finally {
+ restore_error_handler();
+ }
+ } else {
+ try {
+ $data = json_encode($data, $this->encodingOptions);
+ } catch (\Exception $e) {
+ if ('Exception' === get_class($e) && 0 === strpos($e->getMessage(), 'Failed calling ')) {
+ throw $e->getPrevious() ?: $e;
+ }
+ throw $e;
+ }
+ }
+ }
+
+ if (JSON_ERROR_NONE !== json_last_error()) {
+ throw new \InvalidArgumentException(json_last_error_msg());
+ }
+
+ return $this->setJson($data);
+ }
+
+ /**
+ * Returns options used while encoding data to JSON.
+ *
+ * @return int
+ */
+ public function getEncodingOptions()
+ {
+ return $this->encodingOptions;
+ }
+
+ /**
+ * Sets options used while encoding data to JSON.
+ *
+ * @param int $encodingOptions
+ *
+ * @return $this
+ */
+ public function setEncodingOptions($encodingOptions)
+ {
+ $this->encodingOptions = (int) $encodingOptions;
+
+ return $this->setData(json_decode($this->data));
+ }
+
+ /**
+ * Updates the content and headers according to the JSON data and callback.
+ *
+ * @return $this
+ */
+ protected function update()
+ {
+ if (null !== $this->callback) {
+ // Not using application/javascript for compatibility reasons with older browsers.
+ $this->headers->set('Content-Type', 'text/javascript');
+
+ return $this->setContent(sprintf('/**/%s(%s);', $this->callback, $this->data));
+ }
+
+ // Only set the header when there is none or when it equals 'text/javascript' (from a previous update with callback)
+ // in order to not overwrite a custom definition.
+ if (!$this->headers->has('Content-Type') || 'text/javascript' === $this->headers->get('Content-Type')) {
+ $this->headers->set('Content-Type', 'application/json');
+ }
+
+ return $this->setContent($this->data);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/LICENSE b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/LICENSE
new file mode 100644
index 0000000..21d7fb9
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2004-2018 Fabien Potencier
+
+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.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/ParameterBag.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/ParameterBag.php
new file mode 100644
index 0000000..257ef8b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/ParameterBag.php
@@ -0,0 +1,234 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * ParameterBag is a container for key/value pairs.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ParameterBag implements \IteratorAggregate, \Countable
+{
+ /**
+ * Parameter storage.
+ */
+ protected $parameters;
+
+ /**
+ * @param array $parameters An array of parameters
+ */
+ public function __construct(array $parameters = array())
+ {
+ $this->parameters = $parameters;
+ }
+
+ /**
+ * Returns the parameters.
+ *
+ * @return array An array of parameters
+ */
+ public function all()
+ {
+ return $this->parameters;
+ }
+
+ /**
+ * Returns the parameter keys.
+ *
+ * @return array An array of parameter keys
+ */
+ public function keys()
+ {
+ return array_keys($this->parameters);
+ }
+
+ /**
+ * Replaces the current parameters by a new set.
+ *
+ * @param array $parameters An array of parameters
+ */
+ public function replace(array $parameters = array())
+ {
+ $this->parameters = $parameters;
+ }
+
+ /**
+ * Adds parameters.
+ *
+ * @param array $parameters An array of parameters
+ */
+ public function add(array $parameters = array())
+ {
+ $this->parameters = array_replace($this->parameters, $parameters);
+ }
+
+ /**
+ * Returns a parameter by name.
+ *
+ * @param string $key The key
+ * @param mixed $default The default value if the parameter key does not exist
+ *
+ * @return mixed
+ */
+ public function get($key, $default = null)
+ {
+ return array_key_exists($key, $this->parameters) ? $this->parameters[$key] : $default;
+ }
+
+ /**
+ * Sets a parameter by name.
+ *
+ * @param string $key The key
+ * @param mixed $value The value
+ */
+ public function set($key, $value)
+ {
+ $this->parameters[$key] = $value;
+ }
+
+ /**
+ * Returns true if the parameter is defined.
+ *
+ * @param string $key The key
+ *
+ * @return bool true if the parameter exists, false otherwise
+ */
+ public function has($key)
+ {
+ return array_key_exists($key, $this->parameters);
+ }
+
+ /**
+ * Removes a parameter.
+ *
+ * @param string $key The key
+ */
+ public function remove($key)
+ {
+ unset($this->parameters[$key]);
+ }
+
+ /**
+ * Returns the alphabetic characters of the parameter value.
+ *
+ * @param string $key The parameter key
+ * @param string $default The default value if the parameter key does not exist
+ *
+ * @return string The filtered value
+ */
+ public function getAlpha($key, $default = '')
+ {
+ return preg_replace('/[^[:alpha:]]/', '', $this->get($key, $default));
+ }
+
+ /**
+ * Returns the alphabetic characters and digits of the parameter value.
+ *
+ * @param string $key The parameter key
+ * @param string $default The default value if the parameter key does not exist
+ *
+ * @return string The filtered value
+ */
+ public function getAlnum($key, $default = '')
+ {
+ return preg_replace('/[^[:alnum:]]/', '', $this->get($key, $default));
+ }
+
+ /**
+ * Returns the digits of the parameter value.
+ *
+ * @param string $key The parameter key
+ * @param string $default The default value if the parameter key does not exist
+ *
+ * @return string The filtered value
+ */
+ public function getDigits($key, $default = '')
+ {
+ // we need to remove - and + because they're allowed in the filter
+ return str_replace(array('-', '+'), '', $this->filter($key, $default, FILTER_SANITIZE_NUMBER_INT));
+ }
+
+ /**
+ * Returns the parameter value converted to integer.
+ *
+ * @param string $key The parameter key
+ * @param int $default The default value if the parameter key does not exist
+ *
+ * @return int The filtered value
+ */
+ public function getInt($key, $default = 0)
+ {
+ return (int) $this->get($key, $default);
+ }
+
+ /**
+ * Returns the parameter value converted to boolean.
+ *
+ * @param string $key The parameter key
+ * @param mixed $default The default value if the parameter key does not exist
+ *
+ * @return bool The filtered value
+ */
+ public function getBoolean($key, $default = false)
+ {
+ return $this->filter($key, $default, FILTER_VALIDATE_BOOLEAN);
+ }
+
+ /**
+ * Filter key.
+ *
+ * @param string $key Key
+ * @param mixed $default Default = null
+ * @param int $filter FILTER_* constant
+ * @param mixed $options Filter options
+ *
+ * @see http://php.net/manual/en/function.filter-var.php
+ *
+ * @return mixed
+ */
+ public function filter($key, $default = null, $filter = FILTER_DEFAULT, $options = array())
+ {
+ $value = $this->get($key, $default);
+
+ // Always turn $options into an array - this allows filter_var option shortcuts.
+ if (!is_array($options) && $options) {
+ $options = array('flags' => $options);
+ }
+
+ // Add a convenience check for arrays.
+ if (is_array($value) && !isset($options['flags'])) {
+ $options['flags'] = FILTER_REQUIRE_ARRAY;
+ }
+
+ return filter_var($value, $filter, $options);
+ }
+
+ /**
+ * Returns an iterator for parameters.
+ *
+ * @return \ArrayIterator An \ArrayIterator instance
+ */
+ public function getIterator()
+ {
+ return new \ArrayIterator($this->parameters);
+ }
+
+ /**
+ * Returns the number of parameters.
+ *
+ * @return int The number of parameters
+ */
+ public function count()
+ {
+ return count($this->parameters);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/README.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/README.md
new file mode 100644
index 0000000..8907f0b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/README.md
@@ -0,0 +1,14 @@
+HttpFoundation Component
+========================
+
+The HttpFoundation component defines an object-oriented layer for the HTTP
+specification.
+
+Resources
+---------
+
+ * [Documentation](https://symfony.com/doc/current/components/http_foundation/index.html)
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/symfony/issues) and
+ [send Pull Requests](https://github.com/symfony/symfony/pulls)
+ in the [main Symfony repository](https://github.com/symfony/symfony)
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/RedirectResponse.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/RedirectResponse.php
new file mode 100644
index 0000000..01681dc
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/RedirectResponse.php
@@ -0,0 +1,109 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * RedirectResponse represents an HTTP response doing a redirect.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class RedirectResponse extends Response
+{
+ protected $targetUrl;
+
+ /**
+ * Creates a redirect response so that it conforms to the rules defined for a redirect status code.
+ *
+ * @param string $url The URL to redirect to. The URL should be a full URL, with schema etc.,
+ * but practically every browser redirects on paths only as well
+ * @param int $status The status code (302 by default)
+ * @param array $headers The headers (Location is always set to the given URL)
+ *
+ * @throws \InvalidArgumentException
+ *
+ * @see http://tools.ietf.org/html/rfc2616#section-10.3
+ */
+ public function __construct($url, $status = 302, $headers = array())
+ {
+ parent::__construct('', $status, $headers);
+
+ $this->setTargetUrl($url);
+
+ if (!$this->isRedirect()) {
+ throw new \InvalidArgumentException(sprintf('The HTTP status code is not a redirect ("%s" given).', $status));
+ }
+
+ if (301 == $status && !array_key_exists('cache-control', $headers)) {
+ $this->headers->remove('cache-control');
+ }
+ }
+
+ /**
+ * Factory method for chainability.
+ *
+ * @param string $url The url to redirect to
+ * @param int $status The response status code
+ * @param array $headers An array of response headers
+ *
+ * @return static
+ */
+ public static function create($url = '', $status = 302, $headers = array())
+ {
+ return new static($url, $status, $headers);
+ }
+
+ /**
+ * Returns the target URL.
+ *
+ * @return string target URL
+ */
+ public function getTargetUrl()
+ {
+ return $this->targetUrl;
+ }
+
+ /**
+ * Sets the redirect target of this response.
+ *
+ * @param string $url The URL to redirect to
+ *
+ * @return $this
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function setTargetUrl($url)
+ {
+ if (empty($url)) {
+ throw new \InvalidArgumentException('Cannot redirect to an empty URL.');
+ }
+
+ $this->targetUrl = $url;
+
+ $this->setContent(
+ sprintf('<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="UTF-8" />
+ <meta http-equiv="refresh" content="0;url=%1$s" />
+
+ <title>Redirecting to %1$s</title>
+ </head>
+ <body>
+ Redirecting to <a href="%1$s">%1$s</a>.
+ </body>
+</html>', htmlspecialchars($url, ENT_QUOTES, 'UTF-8')));
+
+ $this->headers->set('Location', $url);
+
+ return $this;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Request.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Request.php
new file mode 100644
index 0000000..164fb4e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Request.php
@@ -0,0 +1,2154 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+use Symfony\Component\HttpFoundation\Exception\ConflictingHeadersException;
+use Symfony\Component\HttpFoundation\Exception\SuspiciousOperationException;
+use Symfony\Component\HttpFoundation\Session\SessionInterface;
+
+/**
+ * Request represents an HTTP request.
+ *
+ * The methods dealing with URL accept / return a raw path (% encoded):
+ * * getBasePath
+ * * getBaseUrl
+ * * getPathInfo
+ * * getRequestUri
+ * * getUri
+ * * getUriForPath
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Request
+{
+ const HEADER_FORWARDED = 0b00001; // When using RFC 7239
+ const HEADER_X_FORWARDED_FOR = 0b00010;
+ const HEADER_X_FORWARDED_HOST = 0b00100;
+ const HEADER_X_FORWARDED_PROTO = 0b01000;
+ const HEADER_X_FORWARDED_PORT = 0b10000;
+ const HEADER_X_FORWARDED_ALL = 0b11110; // All "X-Forwarded-*" headers
+ const HEADER_X_FORWARDED_AWS_ELB = 0b11010; // AWS ELB doesn't send X-Forwarded-Host
+
+ /** @deprecated since version 3.3, to be removed in 4.0 */
+ const HEADER_CLIENT_IP = self::HEADER_X_FORWARDED_FOR;
+ /** @deprecated since version 3.3, to be removed in 4.0 */
+ const HEADER_CLIENT_HOST = self::HEADER_X_FORWARDED_HOST;
+ /** @deprecated since version 3.3, to be removed in 4.0 */
+ const HEADER_CLIENT_PROTO = self::HEADER_X_FORWARDED_PROTO;
+ /** @deprecated since version 3.3, to be removed in 4.0 */
+ const HEADER_CLIENT_PORT = self::HEADER_X_FORWARDED_PORT;
+
+ const METHOD_HEAD = 'HEAD';
+ const METHOD_GET = 'GET';
+ const METHOD_POST = 'POST';
+ const METHOD_PUT = 'PUT';
+ const METHOD_PATCH = 'PATCH';
+ const METHOD_DELETE = 'DELETE';
+ const METHOD_PURGE = 'PURGE';
+ const METHOD_OPTIONS = 'OPTIONS';
+ const METHOD_TRACE = 'TRACE';
+ const METHOD_CONNECT = 'CONNECT';
+
+ /**
+ * @var string[]
+ */
+ protected static $trustedProxies = array();
+
+ /**
+ * @var string[]
+ */
+ protected static $trustedHostPatterns = array();
+
+ /**
+ * @var string[]
+ */
+ protected static $trustedHosts = array();
+
+ /**
+ * Names for headers that can be trusted when
+ * using trusted proxies.
+ *
+ * The FORWARDED header is the standard as of rfc7239.
+ *
+ * The other headers are non-standard, but widely used
+ * by popular reverse proxies (like Apache mod_proxy or Amazon EC2).
+ *
+ * @deprecated since version 3.3, to be removed in 4.0
+ */
+ protected static $trustedHeaders = array(
+ self::HEADER_FORWARDED => 'FORWARDED',
+ self::HEADER_CLIENT_IP => 'X_FORWARDED_FOR',
+ self::HEADER_CLIENT_HOST => 'X_FORWARDED_HOST',
+ self::HEADER_CLIENT_PROTO => 'X_FORWARDED_PROTO',
+ self::HEADER_CLIENT_PORT => 'X_FORWARDED_PORT',
+ );
+
+ protected static $httpMethodParameterOverride = false;
+
+ /**
+ * Custom parameters.
+ *
+ * @var \Symfony\Component\HttpFoundation\ParameterBag
+ */
+ public $attributes;
+
+ /**
+ * Request body parameters ($_POST).
+ *
+ * @var \Symfony\Component\HttpFoundation\ParameterBag
+ */
+ public $request;
+
+ /**
+ * Query string parameters ($_GET).
+ *
+ * @var \Symfony\Component\HttpFoundation\ParameterBag
+ */
+ public $query;
+
+ /**
+ * Server and execution environment parameters ($_SERVER).
+ *
+ * @var \Symfony\Component\HttpFoundation\ServerBag
+ */
+ public $server;
+
+ /**
+ * Uploaded files ($_FILES).
+ *
+ * @var \Symfony\Component\HttpFoundation\FileBag
+ */
+ public $files;
+
+ /**
+ * Cookies ($_COOKIE).
+ *
+ * @var \Symfony\Component\HttpFoundation\ParameterBag
+ */
+ public $cookies;
+
+ /**
+ * Headers (taken from the $_SERVER).
+ *
+ * @var \Symfony\Component\HttpFoundation\HeaderBag
+ */
+ public $headers;
+
+ /**
+ * @var string|resource|false|null
+ */
+ protected $content;
+
+ /**
+ * @var array
+ */
+ protected $languages;
+
+ /**
+ * @var array
+ */
+ protected $charsets;
+
+ /**
+ * @var array
+ */
+ protected $encodings;
+
+ /**
+ * @var array
+ */
+ protected $acceptableContentTypes;
+
+ /**
+ * @var string
+ */
+ protected $pathInfo;
+
+ /**
+ * @var string
+ */
+ protected $requestUri;
+
+ /**
+ * @var string
+ */
+ protected $baseUrl;
+
+ /**
+ * @var string
+ */
+ protected $basePath;
+
+ /**
+ * @var string
+ */
+ protected $method;
+
+ /**
+ * @var string
+ */
+ protected $format;
+
+ /**
+ * @var \Symfony\Component\HttpFoundation\Session\SessionInterface
+ */
+ protected $session;
+
+ /**
+ * @var string
+ */
+ protected $locale;
+
+ /**
+ * @var string
+ */
+ protected $defaultLocale = 'en';
+
+ /**
+ * @var array
+ */
+ protected static $formats;
+
+ protected static $requestFactory;
+
+ private $isHostValid = true;
+ private $isForwardedValid = true;
+
+ private static $trustedHeaderSet = -1;
+
+ /** @deprecated since version 3.3, to be removed in 4.0 */
+ private static $trustedHeaderNames = array(
+ self::HEADER_FORWARDED => 'FORWARDED',
+ self::HEADER_CLIENT_IP => 'X_FORWARDED_FOR',
+ self::HEADER_CLIENT_HOST => 'X_FORWARDED_HOST',
+ self::HEADER_CLIENT_PROTO => 'X_FORWARDED_PROTO',
+ self::HEADER_CLIENT_PORT => 'X_FORWARDED_PORT',
+ );
+
+ private static $forwardedParams = array(
+ self::HEADER_X_FORWARDED_FOR => 'for',
+ self::HEADER_X_FORWARDED_HOST => 'host',
+ self::HEADER_X_FORWARDED_PROTO => 'proto',
+ self::HEADER_X_FORWARDED_PORT => 'host',
+ );
+
+ /**
+ * @param array $query The GET parameters
+ * @param array $request The POST parameters
+ * @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...)
+ * @param array $cookies The COOKIE parameters
+ * @param array $files The FILES parameters
+ * @param array $server The SERVER parameters
+ * @param string|resource|null $content The raw body data
+ */
+ public function __construct(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
+ {
+ $this->initialize($query, $request, $attributes, $cookies, $files, $server, $content);
+ }
+
+ /**
+ * Sets the parameters for this request.
+ *
+ * This method also re-initializes all properties.
+ *
+ * @param array $query The GET parameters
+ * @param array $request The POST parameters
+ * @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...)
+ * @param array $cookies The COOKIE parameters
+ * @param array $files The FILES parameters
+ * @param array $server The SERVER parameters
+ * @param string|resource|null $content The raw body data
+ */
+ public function initialize(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
+ {
+ $this->request = new ParameterBag($request);
+ $this->query = new ParameterBag($query);
+ $this->attributes = new ParameterBag($attributes);
+ $this->cookies = new ParameterBag($cookies);
+ $this->files = new FileBag($files);
+ $this->server = new ServerBag($server);
+ $this->headers = new HeaderBag($this->server->getHeaders());
+
+ $this->content = $content;
+ $this->languages = null;
+ $this->charsets = null;
+ $this->encodings = null;
+ $this->acceptableContentTypes = null;
+ $this->pathInfo = null;
+ $this->requestUri = null;
+ $this->baseUrl = null;
+ $this->basePath = null;
+ $this->method = null;
+ $this->format = null;
+ }
+
+ /**
+ * Creates a new request with values from PHP's super globals.
+ *
+ * @return static
+ */
+ public static function createFromGlobals()
+ {
+ // With the php's bug #66606, the php's built-in web server
+ // stores the Content-Type and Content-Length header values in
+ // HTTP_CONTENT_TYPE and HTTP_CONTENT_LENGTH fields.
+ $server = $_SERVER;
+ if ('cli-server' === PHP_SAPI) {
+ if (array_key_exists('HTTP_CONTENT_LENGTH', $_SERVER)) {
+ $server['CONTENT_LENGTH'] = $_SERVER['HTTP_CONTENT_LENGTH'];
+ }
+ if (array_key_exists('HTTP_CONTENT_TYPE', $_SERVER)) {
+ $server['CONTENT_TYPE'] = $_SERVER['HTTP_CONTENT_TYPE'];
+ }
+ }
+
+ $request = self::createRequestFromFactory($_GET, $_POST, array(), $_COOKIE, $_FILES, $server);
+
+ if (0 === strpos($request->headers->get('CONTENT_TYPE'), 'application/x-www-form-urlencoded')
+ && in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), array('PUT', 'DELETE', 'PATCH'))
+ ) {
+ parse_str($request->getContent(), $data);
+ $request->request = new ParameterBag($data);
+ }
+
+ return $request;
+ }
+
+ /**
+ * Creates a Request based on a given URI and configuration.
+ *
+ * The information contained in the URI always take precedence
+ * over the other information (server and parameters).
+ *
+ * @param string $uri The URI
+ * @param string $method The HTTP method
+ * @param array $parameters The query (GET) or request (POST) parameters
+ * @param array $cookies The request cookies ($_COOKIE)
+ * @param array $files The request files ($_FILES)
+ * @param array $server The server parameters ($_SERVER)
+ * @param string|resource|null $content The raw body data
+ *
+ * @return static
+ */
+ public static function create($uri, $method = 'GET', $parameters = array(), $cookies = array(), $files = array(), $server = array(), $content = null)
+ {
+ $server = array_replace(array(
+ 'SERVER_NAME' => 'localhost',
+ 'SERVER_PORT' => 80,
+ 'HTTP_HOST' => 'localhost',
+ 'HTTP_USER_AGENT' => 'Symfony/3.X',
+ 'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
+ 'HTTP_ACCEPT_LANGUAGE' => 'en-us,en;q=0.5',
+ 'HTTP_ACCEPT_CHARSET' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
+ 'REMOTE_ADDR' => '127.0.0.1',
+ 'SCRIPT_NAME' => '',
+ 'SCRIPT_FILENAME' => '',
+ 'SERVER_PROTOCOL' => 'HTTP/1.1',
+ 'REQUEST_TIME' => time(),
+ ), $server);
+
+ $server['PATH_INFO'] = '';
+ $server['REQUEST_METHOD'] = strtoupper($method);
+
+ $components = parse_url($uri);
+ if (isset($components['host'])) {
+ $server['SERVER_NAME'] = $components['host'];
+ $server['HTTP_HOST'] = $components['host'];
+ }
+
+ if (isset($components['scheme'])) {
+ if ('https' === $components['scheme']) {
+ $server['HTTPS'] = 'on';
+ $server['SERVER_PORT'] = 443;
+ } else {
+ unset($server['HTTPS']);
+ $server['SERVER_PORT'] = 80;
+ }
+ }
+
+ if (isset($components['port'])) {
+ $server['SERVER_PORT'] = $components['port'];
+ $server['HTTP_HOST'] = $server['HTTP_HOST'].':'.$components['port'];
+ }
+
+ if (isset($components['user'])) {
+ $server['PHP_AUTH_USER'] = $components['user'];
+ }
+
+ if (isset($components['pass'])) {
+ $server['PHP_AUTH_PW'] = $components['pass'];
+ }
+
+ if (!isset($components['path'])) {
+ $components['path'] = '/';
+ }
+
+ switch (strtoupper($method)) {
+ case 'POST':
+ case 'PUT':
+ case 'DELETE':
+ if (!isset($server['CONTENT_TYPE'])) {
+ $server['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
+ }
+ // no break
+ case 'PATCH':
+ $request = $parameters;
+ $query = array();
+ break;
+ default:
+ $request = array();
+ $query = $parameters;
+ break;
+ }
+
+ $queryString = '';
+ if (isset($components['query'])) {
+ parse_str(html_entity_decode($components['query']), $qs);
+
+ if ($query) {
+ $query = array_replace($qs, $query);
+ $queryString = http_build_query($query, '', '&');
+ } else {
+ $query = $qs;
+ $queryString = $components['query'];
+ }
+ } elseif ($query) {
+ $queryString = http_build_query($query, '', '&');
+ }
+
+ $server['REQUEST_URI'] = $components['path'].('' !== $queryString ? '?'.$queryString : '');
+ $server['QUERY_STRING'] = $queryString;
+
+ return self::createRequestFromFactory($query, $request, array(), $cookies, $files, $server, $content);
+ }
+
+ /**
+ * Sets a callable able to create a Request instance.
+ *
+ * This is mainly useful when you need to override the Request class
+ * to keep BC with an existing system. It should not be used for any
+ * other purpose.
+ *
+ * @param callable|null $callable A PHP callable
+ */
+ public static function setFactory($callable)
+ {
+ self::$requestFactory = $callable;
+ }
+
+ /**
+ * Clones a request and overrides some of its parameters.
+ *
+ * @param array $query The GET parameters
+ * @param array $request The POST parameters
+ * @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...)
+ * @param array $cookies The COOKIE parameters
+ * @param array $files The FILES parameters
+ * @param array $server The SERVER parameters
+ *
+ * @return static
+ */
+ public function duplicate(array $query = null, array $request = null, array $attributes = null, array $cookies = null, array $files = null, array $server = null)
+ {
+ $dup = clone $this;
+ if (null !== $query) {
+ $dup->query = new ParameterBag($query);
+ }
+ if (null !== $request) {
+ $dup->request = new ParameterBag($request);
+ }
+ if (null !== $attributes) {
+ $dup->attributes = new ParameterBag($attributes);
+ }
+ if (null !== $cookies) {
+ $dup->cookies = new ParameterBag($cookies);
+ }
+ if (null !== $files) {
+ $dup->files = new FileBag($files);
+ }
+ if (null !== $server) {
+ $dup->server = new ServerBag($server);
+ $dup->headers = new HeaderBag($dup->server->getHeaders());
+ }
+ $dup->languages = null;
+ $dup->charsets = null;
+ $dup->encodings = null;
+ $dup->acceptableContentTypes = null;
+ $dup->pathInfo = null;
+ $dup->requestUri = null;
+ $dup->baseUrl = null;
+ $dup->basePath = null;
+ $dup->method = null;
+ $dup->format = null;
+
+ if (!$dup->get('_format') && $this->get('_format')) {
+ $dup->attributes->set('_format', $this->get('_format'));
+ }
+
+ if (!$dup->getRequestFormat(null)) {
+ $dup->setRequestFormat($this->getRequestFormat(null));
+ }
+
+ return $dup;
+ }
+
+ /**
+ * Clones the current request.
+ *
+ * Note that the session is not cloned as duplicated requests
+ * are most of the time sub-requests of the main one.
+ */
+ public function __clone()
+ {
+ $this->query = clone $this->query;
+ $this->request = clone $this->request;
+ $this->attributes = clone $this->attributes;
+ $this->cookies = clone $this->cookies;
+ $this->files = clone $this->files;
+ $this->server = clone $this->server;
+ $this->headers = clone $this->headers;
+ }
+
+ /**
+ * Returns the request as a string.
+ *
+ * @return string The request
+ */
+ public function __toString()
+ {
+ try {
+ $content = $this->getContent();
+ } catch (\LogicException $e) {
+ return trigger_error($e, E_USER_ERROR);
+ }
+
+ $cookieHeader = '';
+ $cookies = array();
+
+ foreach ($this->cookies as $k => $v) {
+ $cookies[] = $k.'='.$v;
+ }
+
+ if (!empty($cookies)) {
+ $cookieHeader = 'Cookie: '.implode('; ', $cookies)."\r\n";
+ }
+
+ return
+ sprintf('%s %s %s', $this->getMethod(), $this->getRequestUri(), $this->server->get('SERVER_PROTOCOL'))."\r\n".
+ $this->headers.
+ $cookieHeader."\r\n".
+ $content;
+ }
+
+ /**
+ * Overrides the PHP global variables according to this request instance.
+ *
+ * It overrides $_GET, $_POST, $_REQUEST, $_SERVER, $_COOKIE.
+ * $_FILES is never overridden, see rfc1867
+ */
+ public function overrideGlobals()
+ {
+ $this->server->set('QUERY_STRING', static::normalizeQueryString(http_build_query($this->query->all(), '', '&')));
+
+ $_GET = $this->query->all();
+ $_POST = $this->request->all();
+ $_SERVER = $this->server->all();
+ $_COOKIE = $this->cookies->all();
+
+ foreach ($this->headers->all() as $key => $value) {
+ $key = strtoupper(str_replace('-', '_', $key));
+ if (in_array($key, array('CONTENT_TYPE', 'CONTENT_LENGTH'))) {
+ $_SERVER[$key] = implode(', ', $value);
+ } else {
+ $_SERVER['HTTP_'.$key] = implode(', ', $value);
+ }
+ }
+
+ $request = array('g' => $_GET, 'p' => $_POST, 'c' => $_COOKIE);
+
+ $requestOrder = ini_get('request_order') ?: ini_get('variables_order');
+ $requestOrder = preg_replace('#[^cgp]#', '', strtolower($requestOrder)) ?: 'gp';
+
+ $_REQUEST = array();
+ foreach (str_split($requestOrder) as $order) {
+ $_REQUEST = array_merge($_REQUEST, $request[$order]);
+ }
+ }
+
+ /**
+ * Sets a list of trusted proxies.
+ *
+ * You should only list the reverse proxies that you manage directly.
+ *
+ * @param array $proxies A list of trusted proxies
+ * @param int $trustedHeaderSet A bit field of Request::HEADER_*, to set which headers to trust from your proxies
+ *
+ * @throws \InvalidArgumentException When $trustedHeaderSet is invalid
+ */
+ public static function setTrustedProxies(array $proxies/*, int $trustedHeaderSet*/)
+ {
+ self::$trustedProxies = $proxies;
+
+ if (2 > func_num_args()) {
+ @trigger_error(sprintf('The %s() method expects a bit field of Request::HEADER_* as second argument since Symfony 3.3. Defining it will be required in 4.0. ', __METHOD__), E_USER_DEPRECATED);
+
+ return;
+ }
+ $trustedHeaderSet = (int) func_get_arg(1);
+
+ foreach (self::$trustedHeaderNames as $header => $name) {
+ self::$trustedHeaders[$header] = $header & $trustedHeaderSet ? $name : null;
+ }
+ self::$trustedHeaderSet = $trustedHeaderSet;
+ }
+
+ /**
+ * Gets the list of trusted proxies.
+ *
+ * @return array An array of trusted proxies
+ */
+ public static function getTrustedProxies()
+ {
+ return self::$trustedProxies;
+ }
+
+ /**
+ * Gets the set of trusted headers from trusted proxies.
+ *
+ * @return int A bit field of Request::HEADER_* that defines which headers are trusted from your proxies
+ */
+ public static function getTrustedHeaderSet()
+ {
+ return self::$trustedHeaderSet;
+ }
+
+ /**
+ * Sets a list of trusted host patterns.
+ *
+ * You should only list the hosts you manage using regexs.
+ *
+ * @param array $hostPatterns A list of trusted host patterns
+ */
+ public static function setTrustedHosts(array $hostPatterns)
+ {
+ self::$trustedHostPatterns = array_map(function ($hostPattern) {
+ return sprintf('#%s#i', $hostPattern);
+ }, $hostPatterns);
+ // we need to reset trusted hosts on trusted host patterns change
+ self::$trustedHosts = array();
+ }
+
+ /**
+ * Gets the list of trusted host patterns.
+ *
+ * @return array An array of trusted host patterns
+ */
+ public static function getTrustedHosts()
+ {
+ return self::$trustedHostPatterns;
+ }
+
+ /**
+ * Sets the name for trusted headers.
+ *
+ * The following header keys are supported:
+ *
+ * * Request::HEADER_CLIENT_IP: defaults to X-Forwarded-For (see getClientIp())
+ * * Request::HEADER_CLIENT_HOST: defaults to X-Forwarded-Host (see getHost())
+ * * Request::HEADER_CLIENT_PORT: defaults to X-Forwarded-Port (see getPort())
+ * * Request::HEADER_CLIENT_PROTO: defaults to X-Forwarded-Proto (see getScheme() and isSecure())
+ * * Request::HEADER_FORWARDED: defaults to Forwarded (see RFC 7239)
+ *
+ * Setting an empty value allows to disable the trusted header for the given key.
+ *
+ * @param string $key The header key
+ * @param string $value The header name
+ *
+ * @throws \InvalidArgumentException
+ *
+ * @deprecated since version 3.3, to be removed in 4.0. Use the $trustedHeaderSet argument of the Request::setTrustedProxies() method instead.
+ */
+ public static function setTrustedHeaderName($key, $value)
+ {
+ @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the $trustedHeaderSet argument of the Request::setTrustedProxies() method instead.', __METHOD__), E_USER_DEPRECATED);
+
+ if ('forwarded' === $key) {
+ $key = self::HEADER_FORWARDED;
+ } elseif ('client_ip' === $key) {
+ $key = self::HEADER_CLIENT_IP;
+ } elseif ('client_host' === $key) {
+ $key = self::HEADER_CLIENT_HOST;
+ } elseif ('client_proto' === $key) {
+ $key = self::HEADER_CLIENT_PROTO;
+ } elseif ('client_port' === $key) {
+ $key = self::HEADER_CLIENT_PORT;
+ } elseif (!array_key_exists($key, self::$trustedHeaders)) {
+ throw new \InvalidArgumentException(sprintf('Unable to set the trusted header name for key "%s".', $key));
+ }
+
+ self::$trustedHeaders[$key] = $value;
+
+ if (null !== $value) {
+ self::$trustedHeaderNames[$key] = $value;
+ self::$trustedHeaderSet |= $key;
+ } else {
+ self::$trustedHeaderSet &= ~$key;
+ }
+ }
+
+ /**
+ * Gets the trusted proxy header name.
+ *
+ * @param string $key The header key
+ *
+ * @return string The header name
+ *
+ * @throws \InvalidArgumentException
+ *
+ * @deprecated since version 3.3, to be removed in 4.0. Use the Request::getTrustedHeaderSet() method instead.
+ */
+ public static function getTrustedHeaderName($key)
+ {
+ if (2 > func_num_args() || func_get_arg(1)) {
+ @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the Request::getTrustedHeaderSet() method instead.', __METHOD__), E_USER_DEPRECATED);
+ }
+
+ if (!array_key_exists($key, self::$trustedHeaders)) {
+ throw new \InvalidArgumentException(sprintf('Unable to get the trusted header name for key "%s".', $key));
+ }
+
+ return self::$trustedHeaders[$key];
+ }
+
+ /**
+ * Normalizes a query string.
+ *
+ * It builds a normalized query string, where keys/value pairs are alphabetized,
+ * have consistent escaping and unneeded delimiters are removed.
+ *
+ * @param string $qs Query string
+ *
+ * @return string A normalized query string for the Request
+ */
+ public static function normalizeQueryString($qs)
+ {
+ if ('' == $qs) {
+ return '';
+ }
+
+ $parts = array();
+ $order = array();
+
+ foreach (explode('&', $qs) as $param) {
+ if ('' === $param || '=' === $param[0]) {
+ // Ignore useless delimiters, e.g. "x=y&".
+ // Also ignore pairs with empty key, even if there was a value, e.g. "=value", as such nameless values cannot be retrieved anyway.
+ // PHP also does not include them when building _GET.
+ continue;
+ }
+
+ $keyValuePair = explode('=', $param, 2);
+
+ // GET parameters, that are submitted from a HTML form, encode spaces as "+" by default (as defined in enctype application/x-www-form-urlencoded).
+ // PHP also converts "+" to spaces when filling the global _GET or when using the function parse_str. This is why we use urldecode and then normalize to
+ // RFC 3986 with rawurlencode.
+ $parts[] = isset($keyValuePair[1]) ?
+ rawurlencode(urldecode($keyValuePair[0])).'='.rawurlencode(urldecode($keyValuePair[1])) :
+ rawurlencode(urldecode($keyValuePair[0]));
+ $order[] = urldecode($keyValuePair[0]);
+ }
+
+ array_multisort($order, SORT_ASC, $parts);
+
+ return implode('&', $parts);
+ }
+
+ /**
+ * Enables support for the _method request parameter to determine the intended HTTP method.
+ *
+ * Be warned that enabling this feature might lead to CSRF issues in your code.
+ * Check that you are using CSRF tokens when required.
+ * If the HTTP method parameter override is enabled, an html-form with method "POST" can be altered
+ * and used to send a "PUT" or "DELETE" request via the _method request parameter.
+ * If these methods are not protected against CSRF, this presents a possible vulnerability.
+ *
+ * The HTTP method can only be overridden when the real HTTP method is POST.
+ */
+ public static function enableHttpMethodParameterOverride()
+ {
+ self::$httpMethodParameterOverride = true;
+ }
+
+ /**
+ * Checks whether support for the _method request parameter is enabled.
+ *
+ * @return bool True when the _method request parameter is enabled, false otherwise
+ */
+ public static function getHttpMethodParameterOverride()
+ {
+ return self::$httpMethodParameterOverride;
+ }
+
+ /**
+ * Gets a "parameter" value from any bag.
+ *
+ * This method is mainly useful for libraries that want to provide some flexibility. If you don't need the
+ * flexibility in controllers, it is better to explicitly get request parameters from the appropriate
+ * public property instead (attributes, query, request).
+ *
+ * Order of precedence: PATH (routing placeholders or custom attributes), GET, BODY
+ *
+ * @param string $key The key
+ * @param mixed $default The default value if the parameter key does not exist
+ *
+ * @return mixed
+ */
+ public function get($key, $default = null)
+ {
+ if ($this !== $result = $this->attributes->get($key, $this)) {
+ return $result;
+ }
+
+ if ($this !== $result = $this->query->get($key, $this)) {
+ return $result;
+ }
+
+ if ($this !== $result = $this->request->get($key, $this)) {
+ return $result;
+ }
+
+ return $default;
+ }
+
+ /**
+ * Gets the Session.
+ *
+ * @return SessionInterface|null The session
+ */
+ public function getSession()
+ {
+ return $this->session;
+ }
+
+ /**
+ * Whether the request contains a Session which was started in one of the
+ * previous requests.
+ *
+ * @return bool
+ */
+ public function hasPreviousSession()
+ {
+ // the check for $this->session avoids malicious users trying to fake a session cookie with proper name
+ return $this->hasSession() && $this->cookies->has($this->session->getName());
+ }
+
+ /**
+ * Whether the request contains a Session object.
+ *
+ * This method does not give any information about the state of the session object,
+ * like whether the session is started or not. It is just a way to check if this Request
+ * is associated with a Session instance.
+ *
+ * @return bool true when the Request contains a Session object, false otherwise
+ */
+ public function hasSession()
+ {
+ return null !== $this->session;
+ }
+
+ /**
+ * Sets the Session.
+ *
+ * @param SessionInterface $session The Session
+ */
+ public function setSession(SessionInterface $session)
+ {
+ $this->session = $session;
+ }
+
+ /**
+ * Returns the client IP addresses.
+ *
+ * In the returned array the most trusted IP address is first, and the
+ * least trusted one last. The "real" client IP address is the last one,
+ * but this is also the least trusted one. Trusted proxies are stripped.
+ *
+ * Use this method carefully; you should use getClientIp() instead.
+ *
+ * @return array The client IP addresses
+ *
+ * @see getClientIp()
+ */
+ public function getClientIps()
+ {
+ $ip = $this->server->get('REMOTE_ADDR');
+
+ if (!$this->isFromTrustedProxy()) {
+ return array($ip);
+ }
+
+ return $this->getTrustedValues(self::HEADER_CLIENT_IP, $ip) ?: array($ip);
+ }
+
+ /**
+ * Returns the client IP address.
+ *
+ * This method can read the client IP address from the "X-Forwarded-For" header
+ * when trusted proxies were set via "setTrustedProxies()". The "X-Forwarded-For"
+ * header value is a comma+space separated list of IP addresses, the left-most
+ * being the original client, and each successive proxy that passed the request
+ * adding the IP address where it received the request from.
+ *
+ * If your reverse proxy uses a different header name than "X-Forwarded-For",
+ * ("Client-Ip" for instance), configure it via the $trustedHeaderSet
+ * argument of the Request::setTrustedProxies() method instead.
+ *
+ * @return string|null The client IP address
+ *
+ * @see getClientIps()
+ * @see http://en.wikipedia.org/wiki/X-Forwarded-For
+ */
+ public function getClientIp()
+ {
+ $ipAddresses = $this->getClientIps();
+
+ return $ipAddresses[0];
+ }
+
+ /**
+ * Returns current script name.
+ *
+ * @return string
+ */
+ public function getScriptName()
+ {
+ return $this->server->get('SCRIPT_NAME', $this->server->get('ORIG_SCRIPT_NAME', ''));
+ }
+
+ /**
+ * Returns the path being requested relative to the executed script.
+ *
+ * The path info always starts with a /.
+ *
+ * Suppose this request is instantiated from /mysite on localhost:
+ *
+ * * http://localhost/mysite returns an empty string
+ * * http://localhost/mysite/about returns '/about'
+ * * http://localhost/mysite/enco%20ded returns '/enco%20ded'
+ * * http://localhost/mysite/about?var=1 returns '/about'
+ *
+ * @return string The raw path (i.e. not urldecoded)
+ */
+ public function getPathInfo()
+ {
+ if (null === $this->pathInfo) {
+ $this->pathInfo = $this->preparePathInfo();
+ }
+
+ return $this->pathInfo;
+ }
+
+ /**
+ * Returns the root path from which this request is executed.
+ *
+ * Suppose that an index.php file instantiates this request object:
+ *
+ * * http://localhost/index.php returns an empty string
+ * * http://localhost/index.php/page returns an empty string
+ * * http://localhost/web/index.php returns '/web'
+ * * http://localhost/we%20b/index.php returns '/we%20b'
+ *
+ * @return string The raw path (i.e. not urldecoded)
+ */
+ public function getBasePath()
+ {
+ if (null === $this->basePath) {
+ $this->basePath = $this->prepareBasePath();
+ }
+
+ return $this->basePath;
+ }
+
+ /**
+ * Returns the root URL from which this request is executed.
+ *
+ * The base URL never ends with a /.
+ *
+ * This is similar to getBasePath(), except that it also includes the
+ * script filename (e.g. index.php) if one exists.
+ *
+ * @return string The raw URL (i.e. not urldecoded)
+ */
+ public function getBaseUrl()
+ {
+ if (null === $this->baseUrl) {
+ $this->baseUrl = $this->prepareBaseUrl();
+ }
+
+ return $this->baseUrl;
+ }
+
+ /**
+ * Gets the request's scheme.
+ *
+ * @return string
+ */
+ public function getScheme()
+ {
+ return $this->isSecure() ? 'https' : 'http';
+ }
+
+ /**
+ * Returns the port on which the request is made.
+ *
+ * This method can read the client port from the "X-Forwarded-Port" header
+ * when trusted proxies were set via "setTrustedProxies()".
+ *
+ * The "X-Forwarded-Port" header must contain the client port.
+ *
+ * If your reverse proxy uses a different header name than "X-Forwarded-Port",
+ * configure it via via the $trustedHeaderSet argument of the
+ * Request::setTrustedProxies() method instead.
+ *
+ * @return int|string can be a string if fetched from the server bag
+ */
+ public function getPort()
+ {
+ if ($this->isFromTrustedProxy() && $host = $this->getTrustedValues(self::HEADER_CLIENT_PORT)) {
+ $host = $host[0];
+ } elseif ($this->isFromTrustedProxy() && $host = $this->getTrustedValues(self::HEADER_CLIENT_HOST)) {
+ $host = $host[0];
+ } elseif (!$host = $this->headers->get('HOST')) {
+ return $this->server->get('SERVER_PORT');
+ }
+
+ if ('[' === $host[0]) {
+ $pos = strpos($host, ':', strrpos($host, ']'));
+ } else {
+ $pos = strrpos($host, ':');
+ }
+
+ if (false !== $pos) {
+ return (int) substr($host, $pos + 1);
+ }
+
+ return 'https' === $this->getScheme() ? 443 : 80;
+ }
+
+ /**
+ * Returns the user.
+ *
+ * @return string|null
+ */
+ public function getUser()
+ {
+ return $this->headers->get('PHP_AUTH_USER');
+ }
+
+ /**
+ * Returns the password.
+ *
+ * @return string|null
+ */
+ public function getPassword()
+ {
+ return $this->headers->get('PHP_AUTH_PW');
+ }
+
+ /**
+ * Gets the user info.
+ *
+ * @return string A user name and, optionally, scheme-specific information about how to gain authorization to access the server
+ */
+ public function getUserInfo()
+ {
+ $userinfo = $this->getUser();
+
+ $pass = $this->getPassword();
+ if ('' != $pass) {
+ $userinfo .= ":$pass";
+ }
+
+ return $userinfo;
+ }
+
+ /**
+ * Returns the HTTP host being requested.
+ *
+ * The port name will be appended to the host if it's non-standard.
+ *
+ * @return string
+ */
+ public function getHttpHost()
+ {
+ $scheme = $this->getScheme();
+ $port = $this->getPort();
+
+ if (('http' == $scheme && 80 == $port) || ('https' == $scheme && 443 == $port)) {
+ return $this->getHost();
+ }
+
+ return $this->getHost().':'.$port;
+ }
+
+ /**
+ * Returns the requested URI (path and query string).
+ *
+ * @return string The raw URI (i.e. not URI decoded)
+ */
+ public function getRequestUri()
+ {
+ if (null === $this->requestUri) {
+ $this->requestUri = $this->prepareRequestUri();
+ }
+
+ return $this->requestUri;
+ }
+
+ /**
+ * Gets the scheme and HTTP host.
+ *
+ * If the URL was called with basic authentication, the user
+ * and the password are not added to the generated string.
+ *
+ * @return string The scheme and HTTP host
+ */
+ public function getSchemeAndHttpHost()
+ {
+ return $this->getScheme().'://'.$this->getHttpHost();
+ }
+
+ /**
+ * Generates a normalized URI (URL) for the Request.
+ *
+ * @return string A normalized URI (URL) for the Request
+ *
+ * @see getQueryString()
+ */
+ public function getUri()
+ {
+ if (null !== $qs = $this->getQueryString()) {
+ $qs = '?'.$qs;
+ }
+
+ return $this->getSchemeAndHttpHost().$this->getBaseUrl().$this->getPathInfo().$qs;
+ }
+
+ /**
+ * Generates a normalized URI for the given path.
+ *
+ * @param string $path A path to use instead of the current one
+ *
+ * @return string The normalized URI for the path
+ */
+ public function getUriForPath($path)
+ {
+ return $this->getSchemeAndHttpHost().$this->getBaseUrl().$path;
+ }
+
+ /**
+ * Returns the path as relative reference from the current Request path.
+ *
+ * Only the URIs path component (no schema, host etc.) is relevant and must be given.
+ * Both paths must be absolute and not contain relative parts.
+ * Relative URLs from one resource to another are useful when generating self-contained downloadable document archives.
+ * Furthermore, they can be used to reduce the link size in documents.
+ *
+ * Example target paths, given a base path of "/a/b/c/d":
+ * - "/a/b/c/d" -> ""
+ * - "/a/b/c/" -> "./"
+ * - "/a/b/" -> "../"
+ * - "/a/b/c/other" -> "other"
+ * - "/a/x/y" -> "../../x/y"
+ *
+ * @param string $path The target path
+ *
+ * @return string The relative target path
+ */
+ public function getRelativeUriForPath($path)
+ {
+ // be sure that we are dealing with an absolute path
+ if (!isset($path[0]) || '/' !== $path[0]) {
+ return $path;
+ }
+
+ if ($path === $basePath = $this->getPathInfo()) {
+ return '';
+ }
+
+ $sourceDirs = explode('/', isset($basePath[0]) && '/' === $basePath[0] ? substr($basePath, 1) : $basePath);
+ $targetDirs = explode('/', isset($path[0]) && '/' === $path[0] ? substr($path, 1) : $path);
+ array_pop($sourceDirs);
+ $targetFile = array_pop($targetDirs);
+
+ foreach ($sourceDirs as $i => $dir) {
+ if (isset($targetDirs[$i]) && $dir === $targetDirs[$i]) {
+ unset($sourceDirs[$i], $targetDirs[$i]);
+ } else {
+ break;
+ }
+ }
+
+ $targetDirs[] = $targetFile;
+ $path = str_repeat('../', count($sourceDirs)).implode('/', $targetDirs);
+
+ // A reference to the same base directory or an empty subdirectory must be prefixed with "./".
+ // This also applies to a segment with a colon character (e.g., "file:colon") that cannot be used
+ // as the first segment of a relative-path reference, as it would be mistaken for a scheme name
+ // (see http://tools.ietf.org/html/rfc3986#section-4.2).
+ return !isset($path[0]) || '/' === $path[0]
+ || false !== ($colonPos = strpos($path, ':')) && ($colonPos < ($slashPos = strpos($path, '/')) || false === $slashPos)
+ ? "./$path" : $path;
+ }
+
+ /**
+ * Generates the normalized query string for the Request.
+ *
+ * It builds a normalized query string, where keys/value pairs are alphabetized
+ * and have consistent escaping.
+ *
+ * @return string|null A normalized query string for the Request
+ */
+ public function getQueryString()
+ {
+ $qs = static::normalizeQueryString($this->server->get('QUERY_STRING'));
+
+ return '' === $qs ? null : $qs;
+ }
+
+ /**
+ * Checks whether the request is secure or not.
+ *
+ * This method can read the client protocol from the "X-Forwarded-Proto" header
+ * when trusted proxies were set via "setTrustedProxies()".
+ *
+ * The "X-Forwarded-Proto" header must contain the protocol: "https" or "http".
+ *
+ * If your reverse proxy uses a different header name than "X-Forwarded-Proto"
+ * ("SSL_HTTPS" for instance), configure it via the $trustedHeaderSet
+ * argument of the Request::setTrustedProxies() method instead.
+ *
+ * @return bool
+ */
+ public function isSecure()
+ {
+ if ($this->isFromTrustedProxy() && $proto = $this->getTrustedValues(self::HEADER_CLIENT_PROTO)) {
+ return in_array(strtolower($proto[0]), array('https', 'on', 'ssl', '1'), true);
+ }
+
+ $https = $this->server->get('HTTPS');
+
+ return !empty($https) && 'off' !== strtolower($https);
+ }
+
+ /**
+ * Returns the host name.
+ *
+ * This method can read the client host name from the "X-Forwarded-Host" header
+ * when trusted proxies were set via "setTrustedProxies()".
+ *
+ * The "X-Forwarded-Host" header must contain the client host name.
+ *
+ * If your reverse proxy uses a different header name than "X-Forwarded-Host",
+ * configure it via the $trustedHeaderSet argument of the
+ * Request::setTrustedProxies() method instead.
+ *
+ * @return string
+ *
+ * @throws SuspiciousOperationException when the host name is invalid or not trusted
+ */
+ public function getHost()
+ {
+ if ($this->isFromTrustedProxy() && $host = $this->getTrustedValues(self::HEADER_CLIENT_HOST)) {
+ $host = $host[0];
+ } elseif (!$host = $this->headers->get('HOST')) {
+ if (!$host = $this->server->get('SERVER_NAME')) {
+ $host = $this->server->get('SERVER_ADDR', '');
+ }
+ }
+
+ // trim and remove port number from host
+ // host is lowercase as per RFC 952/2181
+ $host = strtolower(preg_replace('/:\d+$/', '', trim($host)));
+
+ // as the host can come from the user (HTTP_HOST and depending on the configuration, SERVER_NAME too can come from the user)
+ // check that it does not contain forbidden characters (see RFC 952 and RFC 2181)
+ // use preg_replace() instead of preg_match() to prevent DoS attacks with long host names
+ if ($host && '' !== preg_replace('/(?:^\[)?[a-zA-Z0-9-:\]_]+\.?/', '', $host)) {
+ if (!$this->isHostValid) {
+ return '';
+ }
+ $this->isHostValid = false;
+
+ throw new SuspiciousOperationException(sprintf('Invalid Host "%s".', $host));
+ }
+
+ if (count(self::$trustedHostPatterns) > 0) {
+ // to avoid host header injection attacks, you should provide a list of trusted host patterns
+
+ if (in_array($host, self::$trustedHosts)) {
+ return $host;
+ }
+
+ foreach (self::$trustedHostPatterns as $pattern) {
+ if (preg_match($pattern, $host)) {
+ self::$trustedHosts[] = $host;
+
+ return $host;
+ }
+ }
+
+ if (!$this->isHostValid) {
+ return '';
+ }
+ $this->isHostValid = false;
+
+ throw new SuspiciousOperationException(sprintf('Untrusted Host "%s".', $host));
+ }
+
+ return $host;
+ }
+
+ /**
+ * Sets the request method.
+ *
+ * @param string $method
+ */
+ public function setMethod($method)
+ {
+ $this->method = null;
+ $this->server->set('REQUEST_METHOD', $method);
+ }
+
+ /**
+ * Gets the request "intended" method.
+ *
+ * If the X-HTTP-Method-Override header is set, and if the method is a POST,
+ * then it is used to determine the "real" intended HTTP method.
+ *
+ * The _method request parameter can also be used to determine the HTTP method,
+ * but only if enableHttpMethodParameterOverride() has been called.
+ *
+ * The method is always an uppercased string.
+ *
+ * @return string The request method
+ *
+ * @see getRealMethod()
+ */
+ public function getMethod()
+ {
+ if (null === $this->method) {
+ $this->method = strtoupper($this->server->get('REQUEST_METHOD', 'GET'));
+
+ if ('POST' === $this->method) {
+ if ($method = $this->headers->get('X-HTTP-METHOD-OVERRIDE')) {
+ $this->method = strtoupper($method);
+ } elseif (self::$httpMethodParameterOverride) {
+ $this->method = strtoupper($this->request->get('_method', $this->query->get('_method', 'POST')));
+ }
+ }
+ }
+
+ return $this->method;
+ }
+
+ /**
+ * Gets the "real" request method.
+ *
+ * @return string The request method
+ *
+ * @see getMethod()
+ */
+ public function getRealMethod()
+ {
+ return strtoupper($this->server->get('REQUEST_METHOD', 'GET'));
+ }
+
+ /**
+ * Gets the mime type associated with the format.
+ *
+ * @param string $format The format
+ *
+ * @return string The associated mime type (null if not found)
+ */
+ public function getMimeType($format)
+ {
+ if (null === static::$formats) {
+ static::initializeFormats();
+ }
+
+ return isset(static::$formats[$format]) ? static::$formats[$format][0] : null;
+ }
+
+ /**
+ * Gets the mime types associated with the format.
+ *
+ * @param string $format The format
+ *
+ * @return array The associated mime types
+ */
+ public static function getMimeTypes($format)
+ {
+ if (null === static::$formats) {
+ static::initializeFormats();
+ }
+
+ return isset(static::$formats[$format]) ? static::$formats[$format] : array();
+ }
+
+ /**
+ * Gets the format associated with the mime type.
+ *
+ * @param string $mimeType The associated mime type
+ *
+ * @return string|null The format (null if not found)
+ */
+ public function getFormat($mimeType)
+ {
+ $canonicalMimeType = null;
+ if (false !== $pos = strpos($mimeType, ';')) {
+ $canonicalMimeType = substr($mimeType, 0, $pos);
+ }
+
+ if (null === static::$formats) {
+ static::initializeFormats();
+ }
+
+ foreach (static::$formats as $format => $mimeTypes) {
+ if (in_array($mimeType, (array) $mimeTypes)) {
+ return $format;
+ }
+ if (null !== $canonicalMimeType && in_array($canonicalMimeType, (array) $mimeTypes)) {
+ return $format;
+ }
+ }
+ }
+
+ /**
+ * Associates a format with mime types.
+ *
+ * @param string $format The format
+ * @param string|array $mimeTypes The associated mime types (the preferred one must be the first as it will be used as the content type)
+ */
+ public function setFormat($format, $mimeTypes)
+ {
+ if (null === static::$formats) {
+ static::initializeFormats();
+ }
+
+ static::$formats[$format] = is_array($mimeTypes) ? $mimeTypes : array($mimeTypes);
+ }
+
+ /**
+ * Gets the request format.
+ *
+ * Here is the process to determine the format:
+ *
+ * * format defined by the user (with setRequestFormat())
+ * * _format request attribute
+ * * $default
+ *
+ * @param string $default The default format
+ *
+ * @return string The request format
+ */
+ public function getRequestFormat($default = 'html')
+ {
+ if (null === $this->format) {
+ $this->format = $this->attributes->get('_format');
+ }
+
+ return null === $this->format ? $default : $this->format;
+ }
+
+ /**
+ * Sets the request format.
+ *
+ * @param string $format The request format
+ */
+ public function setRequestFormat($format)
+ {
+ $this->format = $format;
+ }
+
+ /**
+ * Gets the format associated with the request.
+ *
+ * @return string|null The format (null if no content type is present)
+ */
+ public function getContentType()
+ {
+ return $this->getFormat($this->headers->get('CONTENT_TYPE'));
+ }
+
+ /**
+ * Sets the default locale.
+ *
+ * @param string $locale
+ */
+ public function setDefaultLocale($locale)
+ {
+ $this->defaultLocale = $locale;
+
+ if (null === $this->locale) {
+ $this->setPhpDefaultLocale($locale);
+ }
+ }
+
+ /**
+ * Get the default locale.
+ *
+ * @return string
+ */
+ public function getDefaultLocale()
+ {
+ return $this->defaultLocale;
+ }
+
+ /**
+ * Sets the locale.
+ *
+ * @param string $locale
+ */
+ public function setLocale($locale)
+ {
+ $this->setPhpDefaultLocale($this->locale = $locale);
+ }
+
+ /**
+ * Get the locale.
+ *
+ * @return string
+ */
+ public function getLocale()
+ {
+ return null === $this->locale ? $this->defaultLocale : $this->locale;
+ }
+
+ /**
+ * Checks if the request method is of specified type.
+ *
+ * @param string $method Uppercase request method (GET, POST etc)
+ *
+ * @return bool
+ */
+ public function isMethod($method)
+ {
+ return $this->getMethod() === strtoupper($method);
+ }
+
+ /**
+ * Checks whether or not the method is safe.
+ *
+ * @see https://tools.ietf.org/html/rfc7231#section-4.2.1
+ *
+ * @param bool $andCacheable Adds the additional condition that the method should be cacheable. True by default.
+ *
+ * @return bool
+ */
+ public function isMethodSafe(/* $andCacheable = true */)
+ {
+ if (!func_num_args() || func_get_arg(0)) {
+ // This deprecation should be turned into a BadMethodCallException in 4.0 (without adding the argument in the signature)
+ // then setting $andCacheable to false should be deprecated in 4.1
+ @trigger_error('Checking only for cacheable HTTP methods with Symfony\Component\HttpFoundation\Request::isMethodSafe() is deprecated since Symfony 3.2 and will throw an exception in 4.0. Disable checking only for cacheable methods by calling the method with `false` as first argument or use the Request::isMethodCacheable() instead.', E_USER_DEPRECATED);
+
+ return in_array($this->getMethod(), array('GET', 'HEAD'));
+ }
+
+ return in_array($this->getMethod(), array('GET', 'HEAD', 'OPTIONS', 'TRACE'));
+ }
+
+ /**
+ * Checks whether or not the method is idempotent.
+ *
+ * @return bool
+ */
+ public function isMethodIdempotent()
+ {
+ return in_array($this->getMethod(), array('HEAD', 'GET', 'PUT', 'DELETE', 'TRACE', 'OPTIONS', 'PURGE'));
+ }
+
+ /**
+ * Checks whether the method is cacheable or not.
+ *
+ * @see https://tools.ietf.org/html/rfc7231#section-4.2.3
+ *
+ * @return bool
+ */
+ public function isMethodCacheable()
+ {
+ return in_array($this->getMethod(), array('GET', 'HEAD'));
+ }
+
+ /**
+ * Returns the protocol version.
+ *
+ * If the application is behind a proxy, the protocol version used in the
+ * requests between the client and the proxy and between the proxy and the
+ * server might be different. This returns the former (from the "Via" header)
+ * if the proxy is trusted (see "setTrustedProxies()"), otherwise it returns
+ * the latter (from the "SERVER_PROTOCOL" server parameter).
+ *
+ * @return string
+ */
+ public function getProtocolVersion()
+ {
+ if ($this->isFromTrustedProxy()) {
+ preg_match('~^(HTTP/)?([1-9]\.[0-9]) ~', $this->headers->get('Via'), $matches);
+
+ if ($matches) {
+ return 'HTTP/'.$matches[2];
+ }
+ }
+
+ return $this->server->get('SERVER_PROTOCOL');
+ }
+
+ /**
+ * Returns the request body content.
+ *
+ * @param bool $asResource If true, a resource will be returned
+ *
+ * @return string|resource The request body content or a resource to read the body stream
+ *
+ * @throws \LogicException
+ */
+ public function getContent($asResource = false)
+ {
+ $currentContentIsResource = is_resource($this->content);
+ if (\PHP_VERSION_ID < 50600 && false === $this->content) {
+ throw new \LogicException('getContent() can only be called once when using the resource return type and PHP below 5.6.');
+ }
+
+ if (true === $asResource) {
+ if ($currentContentIsResource) {
+ rewind($this->content);
+
+ return $this->content;
+ }
+
+ // Content passed in parameter (test)
+ if (is_string($this->content)) {
+ $resource = fopen('php://temp', 'r+');
+ fwrite($resource, $this->content);
+ rewind($resource);
+
+ return $resource;
+ }
+
+ $this->content = false;
+
+ return fopen('php://input', 'rb');
+ }
+
+ if ($currentContentIsResource) {
+ rewind($this->content);
+
+ return stream_get_contents($this->content);
+ }
+
+ if (null === $this->content || false === $this->content) {
+ $this->content = file_get_contents('php://input');
+ }
+
+ return $this->content;
+ }
+
+ /**
+ * Gets the Etags.
+ *
+ * @return array The entity tags
+ */
+ public function getETags()
+ {
+ return preg_split('/\s*,\s*/', $this->headers->get('if_none_match'), null, PREG_SPLIT_NO_EMPTY);
+ }
+
+ /**
+ * @return bool
+ */
+ public function isNoCache()
+ {
+ return $this->headers->hasCacheControlDirective('no-cache') || 'no-cache' == $this->headers->get('Pragma');
+ }
+
+ /**
+ * Returns the preferred language.
+ *
+ * @param array $locales An array of ordered available locales
+ *
+ * @return string|null The preferred locale
+ */
+ public function getPreferredLanguage(array $locales = null)
+ {
+ $preferredLanguages = $this->getLanguages();
+
+ if (empty($locales)) {
+ return isset($preferredLanguages[0]) ? $preferredLanguages[0] : null;
+ }
+
+ if (!$preferredLanguages) {
+ return $locales[0];
+ }
+
+ $extendedPreferredLanguages = array();
+ foreach ($preferredLanguages as $language) {
+ $extendedPreferredLanguages[] = $language;
+ if (false !== $position = strpos($language, '_')) {
+ $superLanguage = substr($language, 0, $position);
+ if (!in_array($superLanguage, $preferredLanguages)) {
+ $extendedPreferredLanguages[] = $superLanguage;
+ }
+ }
+ }
+
+ $preferredLanguages = array_values(array_intersect($extendedPreferredLanguages, $locales));
+
+ return isset($preferredLanguages[0]) ? $preferredLanguages[0] : $locales[0];
+ }
+
+ /**
+ * Gets a list of languages acceptable by the client browser.
+ *
+ * @return array Languages ordered in the user browser preferences
+ */
+ public function getLanguages()
+ {
+ if (null !== $this->languages) {
+ return $this->languages;
+ }
+
+ $languages = AcceptHeader::fromString($this->headers->get('Accept-Language'))->all();
+ $this->languages = array();
+ foreach ($languages as $lang => $acceptHeaderItem) {
+ if (false !== strpos($lang, '-')) {
+ $codes = explode('-', $lang);
+ if ('i' === $codes[0]) {
+ // Language not listed in ISO 639 that are not variants
+ // of any listed language, which can be registered with the
+ // i-prefix, such as i-cherokee
+ if (count($codes) > 1) {
+ $lang = $codes[1];
+ }
+ } else {
+ for ($i = 0, $max = count($codes); $i < $max; ++$i) {
+ if (0 === $i) {
+ $lang = strtolower($codes[0]);
+ } else {
+ $lang .= '_'.strtoupper($codes[$i]);
+ }
+ }
+ }
+ }
+
+ $this->languages[] = $lang;
+ }
+
+ return $this->languages;
+ }
+
+ /**
+ * Gets a list of charsets acceptable by the client browser.
+ *
+ * @return array List of charsets in preferable order
+ */
+ public function getCharsets()
+ {
+ if (null !== $this->charsets) {
+ return $this->charsets;
+ }
+
+ return $this->charsets = array_keys(AcceptHeader::fromString($this->headers->get('Accept-Charset'))->all());
+ }
+
+ /**
+ * Gets a list of encodings acceptable by the client browser.
+ *
+ * @return array List of encodings in preferable order
+ */
+ public function getEncodings()
+ {
+ if (null !== $this->encodings) {
+ return $this->encodings;
+ }
+
+ return $this->encodings = array_keys(AcceptHeader::fromString($this->headers->get('Accept-Encoding'))->all());
+ }
+
+ /**
+ * Gets a list of content types acceptable by the client browser.
+ *
+ * @return array List of content types in preferable order
+ */
+ public function getAcceptableContentTypes()
+ {
+ if (null !== $this->acceptableContentTypes) {
+ return $this->acceptableContentTypes;
+ }
+
+ return $this->acceptableContentTypes = array_keys(AcceptHeader::fromString($this->headers->get('Accept'))->all());
+ }
+
+ /**
+ * Returns true if the request is a XMLHttpRequest.
+ *
+ * It works if your JavaScript library sets an X-Requested-With HTTP header.
+ * It is known to work with common JavaScript frameworks:
+ *
+ * @see http://en.wikipedia.org/wiki/List_of_Ajax_frameworks#JavaScript
+ *
+ * @return bool true if the request is an XMLHttpRequest, false otherwise
+ */
+ public function isXmlHttpRequest()
+ {
+ return 'XMLHttpRequest' == $this->headers->get('X-Requested-With');
+ }
+
+ /*
+ * The following methods are derived from code of the Zend Framework (1.10dev - 2010-01-24)
+ *
+ * Code subject to the new BSD license (http://framework.zend.com/license/new-bsd).
+ *
+ * Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ */
+
+ protected function prepareRequestUri()
+ {
+ $requestUri = '';
+
+ if ($this->headers->has('X_ORIGINAL_URL')) {
+ // IIS with Microsoft Rewrite Module
+ $requestUri = $this->headers->get('X_ORIGINAL_URL');
+ $this->headers->remove('X_ORIGINAL_URL');
+ $this->server->remove('HTTP_X_ORIGINAL_URL');
+ $this->server->remove('UNENCODED_URL');
+ $this->server->remove('IIS_WasUrlRewritten');
+ } elseif ($this->headers->has('X_REWRITE_URL')) {
+ // IIS with ISAPI_Rewrite
+ $requestUri = $this->headers->get('X_REWRITE_URL');
+ $this->headers->remove('X_REWRITE_URL');
+ } elseif ('1' == $this->server->get('IIS_WasUrlRewritten') && '' != $this->server->get('UNENCODED_URL')) {
+ // IIS7 with URL Rewrite: make sure we get the unencoded URL (double slash problem)
+ $requestUri = $this->server->get('UNENCODED_URL');
+ $this->server->remove('UNENCODED_URL');
+ $this->server->remove('IIS_WasUrlRewritten');
+ } elseif ($this->server->has('REQUEST_URI')) {
+ $requestUri = $this->server->get('REQUEST_URI');
+ // HTTP proxy reqs setup request URI with scheme and host [and port] + the URL path, only use URL path
+ $schemeAndHttpHost = $this->getSchemeAndHttpHost();
+ if (0 === strpos($requestUri, $schemeAndHttpHost)) {
+ $requestUri = substr($requestUri, strlen($schemeAndHttpHost));
+ }
+ } elseif ($this->server->has('ORIG_PATH_INFO')) {
+ // IIS 5.0, PHP as CGI
+ $requestUri = $this->server->get('ORIG_PATH_INFO');
+ if ('' != $this->server->get('QUERY_STRING')) {
+ $requestUri .= '?'.$this->server->get('QUERY_STRING');
+ }
+ $this->server->remove('ORIG_PATH_INFO');
+ }
+
+ // normalize the request URI to ease creating sub-requests from this request
+ $this->server->set('REQUEST_URI', $requestUri);
+
+ return $requestUri;
+ }
+
+ /**
+ * Prepares the base URL.
+ *
+ * @return string
+ */
+ protected function prepareBaseUrl()
+ {
+ $filename = basename($this->server->get('SCRIPT_FILENAME'));
+
+ if (basename($this->server->get('SCRIPT_NAME')) === $filename) {
+ $baseUrl = $this->server->get('SCRIPT_NAME');
+ } elseif (basename($this->server->get('PHP_SELF')) === $filename) {
+ $baseUrl = $this->server->get('PHP_SELF');
+ } elseif (basename($this->server->get('ORIG_SCRIPT_NAME')) === $filename) {
+ $baseUrl = $this->server->get('ORIG_SCRIPT_NAME'); // 1and1 shared hosting compatibility
+ } else {
+ // Backtrack up the script_filename to find the portion matching
+ // php_self
+ $path = $this->server->get('PHP_SELF', '');
+ $file = $this->server->get('SCRIPT_FILENAME', '');
+ $segs = explode('/', trim($file, '/'));
+ $segs = array_reverse($segs);
+ $index = 0;
+ $last = count($segs);
+ $baseUrl = '';
+ do {
+ $seg = $segs[$index];
+ $baseUrl = '/'.$seg.$baseUrl;
+ ++$index;
+ } while ($last > $index && (false !== $pos = strpos($path, $baseUrl)) && 0 != $pos);
+ }
+
+ // Does the baseUrl have anything in common with the request_uri?
+ $requestUri = $this->getRequestUri();
+ if ('' !== $requestUri && '/' !== $requestUri[0]) {
+ $requestUri = '/'.$requestUri;
+ }
+
+ if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, $baseUrl)) {
+ // full $baseUrl matches
+ return $prefix;
+ }
+
+ if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, rtrim(dirname($baseUrl), '/'.DIRECTORY_SEPARATOR).'/')) {
+ // directory portion of $baseUrl matches
+ return rtrim($prefix, '/'.DIRECTORY_SEPARATOR);
+ }
+
+ $truncatedRequestUri = $requestUri;
+ if (false !== $pos = strpos($requestUri, '?')) {
+ $truncatedRequestUri = substr($requestUri, 0, $pos);
+ }
+
+ $basename = basename($baseUrl);
+ if (empty($basename) || !strpos(rawurldecode($truncatedRequestUri), $basename)) {
+ // no match whatsoever; set it blank
+ return '';
+ }
+
+ // If using mod_rewrite or ISAPI_Rewrite strip the script filename
+ // out of baseUrl. $pos !== 0 makes sure it is not matching a value
+ // from PATH_INFO or QUERY_STRING
+ if (strlen($requestUri) >= strlen($baseUrl) && (false !== $pos = strpos($requestUri, $baseUrl)) && 0 !== $pos) {
+ $baseUrl = substr($requestUri, 0, $pos + strlen($baseUrl));
+ }
+
+ return rtrim($baseUrl, '/'.DIRECTORY_SEPARATOR);
+ }
+
+ /**
+ * Prepares the base path.
+ *
+ * @return string base path
+ */
+ protected function prepareBasePath()
+ {
+ $baseUrl = $this->getBaseUrl();
+ if (empty($baseUrl)) {
+ return '';
+ }
+
+ $filename = basename($this->server->get('SCRIPT_FILENAME'));
+ if (basename($baseUrl) === $filename) {
+ $basePath = dirname($baseUrl);
+ } else {
+ $basePath = $baseUrl;
+ }
+
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $basePath = str_replace('\\', '/', $basePath);
+ }
+
+ return rtrim($basePath, '/');
+ }
+
+ /**
+ * Prepares the path info.
+ *
+ * @return string path info
+ */
+ protected function preparePathInfo()
+ {
+ if (null === ($requestUri = $this->getRequestUri())) {
+ return '/';
+ }
+
+ // Remove the query string from REQUEST_URI
+ if (false !== $pos = strpos($requestUri, '?')) {
+ $requestUri = substr($requestUri, 0, $pos);
+ }
+ if ('' !== $requestUri && '/' !== $requestUri[0]) {
+ $requestUri = '/'.$requestUri;
+ }
+
+ if (null === ($baseUrl = $this->getBaseUrl())) {
+ return $requestUri;
+ }
+
+ $pathInfo = substr($requestUri, strlen($baseUrl));
+ if (false === $pathInfo || '' === $pathInfo) {
+ // If substr() returns false then PATH_INFO is set to an empty string
+ return '/';
+ }
+
+ return (string) $pathInfo;
+ }
+
+ /**
+ * Initializes HTTP request formats.
+ */
+ protected static function initializeFormats()
+ {
+ static::$formats = array(
+ 'html' => array('text/html', 'application/xhtml+xml'),
+ 'txt' => array('text/plain'),
+ 'js' => array('application/javascript', 'application/x-javascript', 'text/javascript'),
+ 'css' => array('text/css'),
+ 'json' => array('application/json', 'application/x-json'),
+ 'jsonld' => array('application/ld+json'),
+ 'xml' => array('text/xml', 'application/xml', 'application/x-xml'),
+ 'rdf' => array('application/rdf+xml'),
+ 'atom' => array('application/atom+xml'),
+ 'rss' => array('application/rss+xml'),
+ 'form' => array('application/x-www-form-urlencoded'),
+ );
+ }
+
+ /**
+ * Sets the default PHP locale.
+ *
+ * @param string $locale
+ */
+ private function setPhpDefaultLocale($locale)
+ {
+ // if either the class Locale doesn't exist, or an exception is thrown when
+ // setting the default locale, the intl module is not installed, and
+ // the call can be ignored:
+ try {
+ if (class_exists('Locale', false)) {
+ \Locale::setDefault($locale);
+ }
+ } catch (\Exception $e) {
+ }
+ }
+
+ /*
+ * Returns the prefix as encoded in the string when the string starts with
+ * the given prefix, false otherwise.
+ *
+ * @param string $string The urlencoded string
+ * @param string $prefix The prefix not encoded
+ *
+ * @return string|false The prefix as it is encoded in $string, or false
+ */
+ private function getUrlencodedPrefix($string, $prefix)
+ {
+ if (0 !== strpos(rawurldecode($string), $prefix)) {
+ return false;
+ }
+
+ $len = strlen($prefix);
+
+ if (preg_match(sprintf('#^(%%[[:xdigit:]]{2}|.){%d}#', $len), $string, $match)) {
+ return $match[0];
+ }
+
+ return false;
+ }
+
+ private static function createRequestFromFactory(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
+ {
+ if (self::$requestFactory) {
+ $request = call_user_func(self::$requestFactory, $query, $request, $attributes, $cookies, $files, $server, $content);
+
+ if (!$request instanceof self) {
+ throw new \LogicException('The Request factory must return an instance of Symfony\Component\HttpFoundation\Request.');
+ }
+
+ return $request;
+ }
+
+ return new static($query, $request, $attributes, $cookies, $files, $server, $content);
+ }
+
+ /**
+ * Indicates whether this request originated from a trusted proxy.
+ *
+ * This can be useful to determine whether or not to trust the
+ * contents of a proxy-specific header.
+ *
+ * @return bool true if the request came from a trusted proxy, false otherwise
+ */
+ public function isFromTrustedProxy()
+ {
+ return self::$trustedProxies && IpUtils::checkIp($this->server->get('REMOTE_ADDR'), self::$trustedProxies);
+ }
+
+ private function getTrustedValues($type, $ip = null)
+ {
+ $clientValues = array();
+ $forwardedValues = array();
+
+ if (self::$trustedHeaders[$type] && $this->headers->has(self::$trustedHeaders[$type])) {
+ foreach (explode(',', $this->headers->get(self::$trustedHeaders[$type])) as $v) {
+ $clientValues[] = (self::HEADER_CLIENT_PORT === $type ? '0.0.0.0:' : '').trim($v);
+ }
+ }
+
+ if (self::$trustedHeaders[self::HEADER_FORWARDED] && $this->headers->has(self::$trustedHeaders[self::HEADER_FORWARDED])) {
+ $forwardedValues = $this->headers->get(self::$trustedHeaders[self::HEADER_FORWARDED]);
+ $forwardedValues = preg_match_all(sprintf('{(?:%s)=(?:"?\[?)([a-zA-Z0-9\.:_\-/]*+)}', self::$forwardedParams[$type]), $forwardedValues, $matches) ? $matches[1] : array();
+ }
+
+ if (null !== $ip) {
+ $clientValues = $this->normalizeAndFilterClientIps($clientValues, $ip);
+ $forwardedValues = $this->normalizeAndFilterClientIps($forwardedValues, $ip);
+ }
+
+ if ($forwardedValues === $clientValues || !$clientValues) {
+ return $forwardedValues;
+ }
+
+ if (!$forwardedValues) {
+ return $clientValues;
+ }
+
+ if (!$this->isForwardedValid) {
+ return null !== $ip ? array('0.0.0.0', $ip) : array();
+ }
+ $this->isForwardedValid = false;
+
+ throw new ConflictingHeadersException(sprintf('The request has both a trusted "%s" header and a trusted "%s" header, conflicting with each other. You should either configure your proxy to remove one of them, or configure your project to distrust the offending one.', self::$trustedHeaders[self::HEADER_FORWARDED], self::$trustedHeaders[$type]));
+ }
+
+ private function normalizeAndFilterClientIps(array $clientIps, $ip)
+ {
+ if (!$clientIps) {
+ return array();
+ }
+ $clientIps[] = $ip; // Complete the IP chain with the IP the request actually came from
+ $firstTrustedIp = null;
+
+ foreach ($clientIps as $key => $clientIp) {
+ // Remove port (unfortunately, it does happen)
+ if (preg_match('{((?:\d+\.){3}\d+)\:\d+}', $clientIp, $match)) {
+ $clientIps[$key] = $clientIp = $match[1];
+ }
+
+ if (!filter_var($clientIp, FILTER_VALIDATE_IP)) {
+ unset($clientIps[$key]);
+
+ continue;
+ }
+
+ if (IpUtils::checkIp($clientIp, self::$trustedProxies)) {
+ unset($clientIps[$key]);
+
+ // Fallback to this when the client IP falls into the range of trusted proxies
+ if (null === $firstTrustedIp) {
+ $firstTrustedIp = $clientIp;
+ }
+ }
+ }
+
+ // Now the IP chain contains only untrusted proxies and the client IP
+ return $clientIps ? array_reverse($clientIps) : array($firstTrustedIp);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/RequestMatcher.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/RequestMatcher.php
new file mode 100644
index 0000000..076d077
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/RequestMatcher.php
@@ -0,0 +1,178 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * RequestMatcher compares a pre-defined set of checks against a Request instance.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class RequestMatcher implements RequestMatcherInterface
+{
+ /**
+ * @var string|null
+ */
+ private $path;
+
+ /**
+ * @var string|null
+ */
+ private $host;
+
+ /**
+ * @var string[]
+ */
+ private $methods = array();
+
+ /**
+ * @var string[]
+ */
+ private $ips = array();
+
+ /**
+ * @var array
+ */
+ private $attributes = array();
+
+ /**
+ * @var string[]
+ */
+ private $schemes = array();
+
+ /**
+ * @param string|null $path
+ * @param string|null $host
+ * @param string|string[]|null $methods
+ * @param string|string[]|null $ips
+ * @param array $attributes
+ * @param string|string[]|null $schemes
+ */
+ public function __construct($path = null, $host = null, $methods = null, $ips = null, array $attributes = array(), $schemes = null)
+ {
+ $this->matchPath($path);
+ $this->matchHost($host);
+ $this->matchMethod($methods);
+ $this->matchIps($ips);
+ $this->matchScheme($schemes);
+
+ foreach ($attributes as $k => $v) {
+ $this->matchAttribute($k, $v);
+ }
+ }
+
+ /**
+ * Adds a check for the HTTP scheme.
+ *
+ * @param string|string[]|null $scheme An HTTP scheme or an array of HTTP schemes
+ */
+ public function matchScheme($scheme)
+ {
+ $this->schemes = null !== $scheme ? array_map('strtolower', (array) $scheme) : array();
+ }
+
+ /**
+ * Adds a check for the URL host name.
+ *
+ * @param string|null $regexp A Regexp
+ */
+ public function matchHost($regexp)
+ {
+ $this->host = $regexp;
+ }
+
+ /**
+ * Adds a check for the URL path info.
+ *
+ * @param string|null $regexp A Regexp
+ */
+ public function matchPath($regexp)
+ {
+ $this->path = $regexp;
+ }
+
+ /**
+ * Adds a check for the client IP.
+ *
+ * @param string $ip A specific IP address or a range specified using IP/netmask like 192.168.1.0/24
+ */
+ public function matchIp($ip)
+ {
+ $this->matchIps($ip);
+ }
+
+ /**
+ * Adds a check for the client IP.
+ *
+ * @param string|string[]|null $ips A specific IP address or a range specified using IP/netmask like 192.168.1.0/24
+ */
+ public function matchIps($ips)
+ {
+ $this->ips = null !== $ips ? (array) $ips : array();
+ }
+
+ /**
+ * Adds a check for the HTTP method.
+ *
+ * @param string|string[]|null $method An HTTP method or an array of HTTP methods
+ */
+ public function matchMethod($method)
+ {
+ $this->methods = null !== $method ? array_map('strtoupper', (array) $method) : array();
+ }
+
+ /**
+ * Adds a check for request attribute.
+ *
+ * @param string $key The request attribute name
+ * @param string $regexp A Regexp
+ */
+ public function matchAttribute($key, $regexp)
+ {
+ $this->attributes[$key] = $regexp;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function matches(Request $request)
+ {
+ if ($this->schemes && !in_array($request->getScheme(), $this->schemes, true)) {
+ return false;
+ }
+
+ if ($this->methods && !in_array($request->getMethod(), $this->methods, true)) {
+ return false;
+ }
+
+ foreach ($this->attributes as $key => $pattern) {
+ if (!preg_match('{'.$pattern.'}', $request->attributes->get($key))) {
+ return false;
+ }
+ }
+
+ if (null !== $this->path && !preg_match('{'.$this->path.'}', rawurldecode($request->getPathInfo()))) {
+ return false;
+ }
+
+ if (null !== $this->host && !preg_match('{'.$this->host.'}i', $request->getHost())) {
+ return false;
+ }
+
+ if (IpUtils::checkIp($request->getClientIp(), $this->ips)) {
+ return true;
+ }
+
+ // Note to future implementors: add additional checks above the
+ // foreach above or else your check might not be run!
+ return 0 === count($this->ips);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/RequestMatcherInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/RequestMatcherInterface.php
new file mode 100644
index 0000000..c26db3e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/RequestMatcherInterface.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * RequestMatcherInterface is an interface for strategies to match a Request.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface RequestMatcherInterface
+{
+ /**
+ * Decides whether the rule(s) implemented by the strategy matches the supplied request.
+ *
+ * @return bool true if the request matches, false otherwise
+ */
+ public function matches(Request $request);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/RequestStack.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/RequestStack.php
new file mode 100644
index 0000000..3d9cfd0
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/RequestStack.php
@@ -0,0 +1,103 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * Request stack that controls the lifecycle of requests.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class RequestStack
+{
+ /**
+ * @var Request[]
+ */
+ private $requests = array();
+
+ /**
+ * Pushes a Request on the stack.
+ *
+ * This method should generally not be called directly as the stack
+ * management should be taken care of by the application itself.
+ */
+ public function push(Request $request)
+ {
+ $this->requests[] = $request;
+ }
+
+ /**
+ * Pops the current request from the stack.
+ *
+ * This operation lets the current request go out of scope.
+ *
+ * This method should generally not be called directly as the stack
+ * management should be taken care of by the application itself.
+ *
+ * @return Request|null
+ */
+ public function pop()
+ {
+ if (!$this->requests) {
+ return;
+ }
+
+ return array_pop($this->requests);
+ }
+
+ /**
+ * @return Request|null
+ */
+ public function getCurrentRequest()
+ {
+ return end($this->requests) ?: null;
+ }
+
+ /**
+ * Gets the master Request.
+ *
+ * Be warned that making your code aware of the master request
+ * might make it un-compatible with other features of your framework
+ * like ESI support.
+ *
+ * @return Request|null
+ */
+ public function getMasterRequest()
+ {
+ if (!$this->requests) {
+ return;
+ }
+
+ return $this->requests[0];
+ }
+
+ /**
+ * Returns the parent request of the current.
+ *
+ * Be warned that making your code aware of the parent request
+ * might make it un-compatible with other features of your framework
+ * like ESI support.
+ *
+ * If current Request is the master request, it returns null.
+ *
+ * @return Request|null
+ */
+ public function getParentRequest()
+ {
+ $pos = count($this->requests) - 2;
+
+ if (!isset($this->requests[$pos])) {
+ return;
+ }
+
+ return $this->requests[$pos];
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Response.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Response.php
new file mode 100644
index 0000000..6f8a623
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Response.php
@@ -0,0 +1,1298 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * Response represents an HTTP response.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Response
+{
+ const HTTP_CONTINUE = 100;
+ const HTTP_SWITCHING_PROTOCOLS = 101;
+ const HTTP_PROCESSING = 102; // RFC2518
+ const HTTP_OK = 200;
+ const HTTP_CREATED = 201;
+ const HTTP_ACCEPTED = 202;
+ const HTTP_NON_AUTHORITATIVE_INFORMATION = 203;
+ const HTTP_NO_CONTENT = 204;
+ const HTTP_RESET_CONTENT = 205;
+ const HTTP_PARTIAL_CONTENT = 206;
+ const HTTP_MULTI_STATUS = 207; // RFC4918
+ const HTTP_ALREADY_REPORTED = 208; // RFC5842
+ const HTTP_IM_USED = 226; // RFC3229
+ const HTTP_MULTIPLE_CHOICES = 300;
+ const HTTP_MOVED_PERMANENTLY = 301;
+ const HTTP_FOUND = 302;
+ const HTTP_SEE_OTHER = 303;
+ const HTTP_NOT_MODIFIED = 304;
+ const HTTP_USE_PROXY = 305;
+ const HTTP_RESERVED = 306;
+ const HTTP_TEMPORARY_REDIRECT = 307;
+ const HTTP_PERMANENTLY_REDIRECT = 308; // RFC7238
+ const HTTP_BAD_REQUEST = 400;
+ const HTTP_UNAUTHORIZED = 401;
+ const HTTP_PAYMENT_REQUIRED = 402;
+ const HTTP_FORBIDDEN = 403;
+ const HTTP_NOT_FOUND = 404;
+ const HTTP_METHOD_NOT_ALLOWED = 405;
+ const HTTP_NOT_ACCEPTABLE = 406;
+ const HTTP_PROXY_AUTHENTICATION_REQUIRED = 407;
+ const HTTP_REQUEST_TIMEOUT = 408;
+ const HTTP_CONFLICT = 409;
+ const HTTP_GONE = 410;
+ const HTTP_LENGTH_REQUIRED = 411;
+ const HTTP_PRECONDITION_FAILED = 412;
+ const HTTP_REQUEST_ENTITY_TOO_LARGE = 413;
+ const HTTP_REQUEST_URI_TOO_LONG = 414;
+ const HTTP_UNSUPPORTED_MEDIA_TYPE = 415;
+ const HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
+ const HTTP_EXPECTATION_FAILED = 417;
+ const HTTP_I_AM_A_TEAPOT = 418; // RFC2324
+ const HTTP_MISDIRECTED_REQUEST = 421; // RFC7540
+ const HTTP_UNPROCESSABLE_ENTITY = 422; // RFC4918
+ const HTTP_LOCKED = 423; // RFC4918
+ const HTTP_FAILED_DEPENDENCY = 424; // RFC4918
+ const HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL = 425; // RFC2817
+ const HTTP_UPGRADE_REQUIRED = 426; // RFC2817
+ const HTTP_PRECONDITION_REQUIRED = 428; // RFC6585
+ const HTTP_TOO_MANY_REQUESTS = 429; // RFC6585
+ const HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431; // RFC6585
+ const HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451;
+ const HTTP_INTERNAL_SERVER_ERROR = 500;
+ const HTTP_NOT_IMPLEMENTED = 501;
+ const HTTP_BAD_GATEWAY = 502;
+ const HTTP_SERVICE_UNAVAILABLE = 503;
+ const HTTP_GATEWAY_TIMEOUT = 504;
+ const HTTP_VERSION_NOT_SUPPORTED = 505;
+ const HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL = 506; // RFC2295
+ const HTTP_INSUFFICIENT_STORAGE = 507; // RFC4918
+ const HTTP_LOOP_DETECTED = 508; // RFC5842
+ const HTTP_NOT_EXTENDED = 510; // RFC2774
+ const HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511; // RFC6585
+
+ /**
+ * @var \Symfony\Component\HttpFoundation\ResponseHeaderBag
+ */
+ public $headers;
+
+ /**
+ * @var string
+ */
+ protected $content;
+
+ /**
+ * @var string
+ */
+ protected $version;
+
+ /**
+ * @var int
+ */
+ protected $statusCode;
+
+ /**
+ * @var string
+ */
+ protected $statusText;
+
+ /**
+ * @var string
+ */
+ protected $charset;
+
+ /**
+ * Status codes translation table.
+ *
+ * The list of codes is complete according to the
+ * {@link http://www.iana.org/assignments/http-status-codes/ Hypertext Transfer Protocol (HTTP) Status Code Registry}
+ * (last updated 2016-03-01).
+ *
+ * Unless otherwise noted, the status code is defined in RFC2616.
+ *
+ * @var array
+ */
+ public static $statusTexts = array(
+ 100 => 'Continue',
+ 101 => 'Switching Protocols',
+ 102 => 'Processing', // RFC2518
+ 103 => 'Early Hints',
+ 200 => 'OK',
+ 201 => 'Created',
+ 202 => 'Accepted',
+ 203 => 'Non-Authoritative Information',
+ 204 => 'No Content',
+ 205 => 'Reset Content',
+ 206 => 'Partial Content',
+ 207 => 'Multi-Status', // RFC4918
+ 208 => 'Already Reported', // RFC5842
+ 226 => 'IM Used', // RFC3229
+ 300 => 'Multiple Choices',
+ 301 => 'Moved Permanently',
+ 302 => 'Found',
+ 303 => 'See Other',
+ 304 => 'Not Modified',
+ 305 => 'Use Proxy',
+ 307 => 'Temporary Redirect',
+ 308 => 'Permanent Redirect', // RFC7238
+ 400 => 'Bad Request',
+ 401 => 'Unauthorized',
+ 402 => 'Payment Required',
+ 403 => 'Forbidden',
+ 404 => 'Not Found',
+ 405 => 'Method Not Allowed',
+ 406 => 'Not Acceptable',
+ 407 => 'Proxy Authentication Required',
+ 408 => 'Request Timeout',
+ 409 => 'Conflict',
+ 410 => 'Gone',
+ 411 => 'Length Required',
+ 412 => 'Precondition Failed',
+ 413 => 'Payload Too Large',
+ 414 => 'URI Too Long',
+ 415 => 'Unsupported Media Type',
+ 416 => 'Range Not Satisfiable',
+ 417 => 'Expectation Failed',
+ 418 => 'I\'m a teapot', // RFC2324
+ 421 => 'Misdirected Request', // RFC7540
+ 422 => 'Unprocessable Entity', // RFC4918
+ 423 => 'Locked', // RFC4918
+ 424 => 'Failed Dependency', // RFC4918
+ 425 => 'Reserved for WebDAV advanced collections expired proposal', // RFC2817
+ 426 => 'Upgrade Required', // RFC2817
+ 428 => 'Precondition Required', // RFC6585
+ 429 => 'Too Many Requests', // RFC6585
+ 431 => 'Request Header Fields Too Large', // RFC6585
+ 451 => 'Unavailable For Legal Reasons', // RFC7725
+ 500 => 'Internal Server Error',
+ 501 => 'Not Implemented',
+ 502 => 'Bad Gateway',
+ 503 => 'Service Unavailable',
+ 504 => 'Gateway Timeout',
+ 505 => 'HTTP Version Not Supported',
+ 506 => 'Variant Also Negotiates', // RFC2295
+ 507 => 'Insufficient Storage', // RFC4918
+ 508 => 'Loop Detected', // RFC5842
+ 510 => 'Not Extended', // RFC2774
+ 511 => 'Network Authentication Required', // RFC6585
+ );
+
+ /**
+ * @param mixed $content The response content, see setContent()
+ * @param int $status The response status code
+ * @param array $headers An array of response headers
+ *
+ * @throws \InvalidArgumentException When the HTTP status code is not valid
+ */
+ public function __construct($content = '', $status = 200, $headers = array())
+ {
+ $this->headers = new ResponseHeaderBag($headers);
+ $this->setContent($content);
+ $this->setStatusCode($status);
+ $this->setProtocolVersion('1.0');
+ }
+
+ /**
+ * Factory method for chainability.
+ *
+ * Example:
+ *
+ * return Response::create($body, 200)
+ * ->setSharedMaxAge(300);
+ *
+ * @param mixed $content The response content, see setContent()
+ * @param int $status The response status code
+ * @param array $headers An array of response headers
+ *
+ * @return static
+ */
+ public static function create($content = '', $status = 200, $headers = array())
+ {
+ return new static($content, $status, $headers);
+ }
+
+ /**
+ * Returns the Response as an HTTP string.
+ *
+ * The string representation of the Response is the same as the
+ * one that will be sent to the client only if the prepare() method
+ * has been called before.
+ *
+ * @return string The Response as an HTTP string
+ *
+ * @see prepare()
+ */
+ public function __toString()
+ {
+ return
+ sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText)."\r\n".
+ $this->headers."\r\n".
+ $this->getContent();
+ }
+
+ /**
+ * Clones the current Response instance.
+ */
+ public function __clone()
+ {
+ $this->headers = clone $this->headers;
+ }
+
+ /**
+ * Prepares the Response before it is sent to the client.
+ *
+ * This method tweaks the Response to ensure that it is
+ * compliant with RFC 2616. Most of the changes are based on
+ * the Request that is "associated" with this Response.
+ *
+ * @return $this
+ */
+ public function prepare(Request $request)
+ {
+ $headers = $this->headers;
+
+ if ($this->isInformational() || $this->isEmpty()) {
+ $this->setContent(null);
+ $headers->remove('Content-Type');
+ $headers->remove('Content-Length');
+ } else {
+ // Content-type based on the Request
+ if (!$headers->has('Content-Type')) {
+ $format = $request->getRequestFormat();
+ if (null !== $format && $mimeType = $request->getMimeType($format)) {
+ $headers->set('Content-Type', $mimeType);
+ }
+ }
+
+ // Fix Content-Type
+ $charset = $this->charset ?: 'UTF-8';
+ if (!$headers->has('Content-Type')) {
+ $headers->set('Content-Type', 'text/html; charset='.$charset);
+ } elseif (0 === stripos($headers->get('Content-Type'), 'text/') && false === stripos($headers->get('Content-Type'), 'charset')) {
+ // add the charset
+ $headers->set('Content-Type', $headers->get('Content-Type').'; charset='.$charset);
+ }
+
+ // Fix Content-Length
+ if ($headers->has('Transfer-Encoding')) {
+ $headers->remove('Content-Length');
+ }
+
+ if ($request->isMethod('HEAD')) {
+ // cf. RFC2616 14.13
+ $length = $headers->get('Content-Length');
+ $this->setContent(null);
+ if ($length) {
+ $headers->set('Content-Length', $length);
+ }
+ }
+ }
+
+ // Fix protocol
+ if ('HTTP/1.0' != $request->server->get('SERVER_PROTOCOL')) {
+ $this->setProtocolVersion('1.1');
+ }
+
+ // Check if we need to send extra expire info headers
+ if ('1.0' == $this->getProtocolVersion() && false !== strpos($this->headers->get('Cache-Control'), 'no-cache')) {
+ $this->headers->set('pragma', 'no-cache');
+ $this->headers->set('expires', -1);
+ }
+
+ $this->ensureIEOverSSLCompatibility($request);
+
+ return $this;
+ }
+
+ /**
+ * Sends HTTP headers.
+ *
+ * @return $this
+ */
+ public function sendHeaders()
+ {
+ // headers have already been sent by the developer
+ if (headers_sent()) {
+ return $this;
+ }
+
+ // headers
+ foreach ($this->headers->allPreserveCaseWithoutCookies() as $name => $values) {
+ foreach ($values as $value) {
+ header($name.': '.$value, false, $this->statusCode);
+ }
+ }
+
+ // status
+ header(sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText), true, $this->statusCode);
+
+ // cookies
+ foreach ($this->headers->getCookies() as $cookie) {
+ if ($cookie->isRaw()) {
+ setrawcookie($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly());
+ } else {
+ setcookie($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly());
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Sends content for the current web response.
+ *
+ * @return $this
+ */
+ public function sendContent()
+ {
+ echo $this->content;
+
+ return $this;
+ }
+
+ /**
+ * Sends HTTP headers and content.
+ *
+ * @return $this
+ */
+ public function send()
+ {
+ $this->sendHeaders();
+ $this->sendContent();
+
+ if (function_exists('fastcgi_finish_request')) {
+ fastcgi_finish_request();
+ } elseif (!\in_array(PHP_SAPI, array('cli', 'phpdbg'), true)) {
+ static::closeOutputBuffers(0, true);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Sets the response content.
+ *
+ * Valid types are strings, numbers, null, and objects that implement a __toString() method.
+ *
+ * @param mixed $content Content that can be cast to string
+ *
+ * @return $this
+ *
+ * @throws \UnexpectedValueException
+ */
+ public function setContent($content)
+ {
+ if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable(array($content, '__toString'))) {
+ throw new \UnexpectedValueException(sprintf('The Response content must be a string or object implementing __toString(), "%s" given.', gettype($content)));
+ }
+
+ $this->content = (string) $content;
+
+ return $this;
+ }
+
+ /**
+ * Gets the current response content.
+ *
+ * @return string Content
+ */
+ public function getContent()
+ {
+ return $this->content;
+ }
+
+ /**
+ * Sets the HTTP protocol version (1.0 or 1.1).
+ *
+ * @param string $version The HTTP protocol version
+ *
+ * @return $this
+ *
+ * @final since version 3.2
+ */
+ public function setProtocolVersion($version)
+ {
+ $this->version = $version;
+
+ return $this;
+ }
+
+ /**
+ * Gets the HTTP protocol version.
+ *
+ * @return string The HTTP protocol version
+ *
+ * @final since version 3.2
+ */
+ public function getProtocolVersion()
+ {
+ return $this->version;
+ }
+
+ /**
+ * Sets the response status code.
+ *
+ * If the status text is null it will be automatically populated for the known
+ * status codes and left empty otherwise.
+ *
+ * @param int $code HTTP status code
+ * @param mixed $text HTTP status text
+ *
+ * @return $this
+ *
+ * @throws \InvalidArgumentException When the HTTP status code is not valid
+ *
+ * @final since version 3.2
+ */
+ public function setStatusCode($code, $text = null)
+ {
+ $this->statusCode = $code = (int) $code;
+ if ($this->isInvalid()) {
+ throw new \InvalidArgumentException(sprintf('The HTTP status code "%s" is not valid.', $code));
+ }
+
+ if (null === $text) {
+ $this->statusText = isset(self::$statusTexts[$code]) ? self::$statusTexts[$code] : 'unknown status';
+
+ return $this;
+ }
+
+ if (false === $text) {
+ $this->statusText = '';
+
+ return $this;
+ }
+
+ $this->statusText = $text;
+
+ return $this;
+ }
+
+ /**
+ * Retrieves the status code for the current web response.
+ *
+ * @return int Status code
+ *
+ * @final since version 3.2
+ */
+ public function getStatusCode()
+ {
+ return $this->statusCode;
+ }
+
+ /**
+ * Sets the response charset.
+ *
+ * @param string $charset Character set
+ *
+ * @return $this
+ *
+ * @final since version 3.2
+ */
+ public function setCharset($charset)
+ {
+ $this->charset = $charset;
+
+ return $this;
+ }
+
+ /**
+ * Retrieves the response charset.
+ *
+ * @return string Character set
+ *
+ * @final since version 3.2
+ */
+ public function getCharset()
+ {
+ return $this->charset;
+ }
+
+ /**
+ * Returns true if the response is worth caching under any circumstance.
+ *
+ * Responses marked "private" with an explicit Cache-Control directive are
+ * considered uncacheable.
+ *
+ * Responses with neither a freshness lifetime (Expires, max-age) nor cache
+ * validator (Last-Modified, ETag) are considered uncacheable.
+ *
+ * @return bool true if the response is worth caching, false otherwise
+ *
+ * @final since version 3.3
+ */
+ public function isCacheable()
+ {
+ if (!in_array($this->statusCode, array(200, 203, 300, 301, 302, 404, 410))) {
+ return false;
+ }
+
+ if ($this->headers->hasCacheControlDirective('no-store') || $this->headers->getCacheControlDirective('private')) {
+ return false;
+ }
+
+ return $this->isValidateable() || $this->isFresh();
+ }
+
+ /**
+ * Returns true if the response is "fresh".
+ *
+ * Fresh responses may be served from cache without any interaction with the
+ * origin. A response is considered fresh when it includes a Cache-Control/max-age
+ * indicator or Expires header and the calculated age is less than the freshness lifetime.
+ *
+ * @return bool true if the response is fresh, false otherwise
+ *
+ * @final since version 3.3
+ */
+ public function isFresh()
+ {
+ return $this->getTtl() > 0;
+ }
+
+ /**
+ * Returns true if the response includes headers that can be used to validate
+ * the response with the origin server using a conditional GET request.
+ *
+ * @return bool true if the response is validateable, false otherwise
+ *
+ * @final since version 3.3
+ */
+ public function isValidateable()
+ {
+ return $this->headers->has('Last-Modified') || $this->headers->has('ETag');
+ }
+
+ /**
+ * Marks the response as "private".
+ *
+ * It makes the response ineligible for serving other clients.
+ *
+ * @return $this
+ *
+ * @final since version 3.2
+ */
+ public function setPrivate()
+ {
+ $this->headers->removeCacheControlDirective('public');
+ $this->headers->addCacheControlDirective('private');
+
+ return $this;
+ }
+
+ /**
+ * Marks the response as "public".
+ *
+ * It makes the response eligible for serving other clients.
+ *
+ * @return $this
+ *
+ * @final since version 3.2
+ */
+ public function setPublic()
+ {
+ $this->headers->addCacheControlDirective('public');
+ $this->headers->removeCacheControlDirective('private');
+
+ return $this;
+ }
+
+ /**
+ * Marks the response as "immutable".
+ *
+ * @param bool $immutable enables or disables the immutable directive
+ *
+ * @return $this
+ *
+ * @final
+ */
+ public function setImmutable($immutable = true)
+ {
+ if ($immutable) {
+ $this->headers->addCacheControlDirective('immutable');
+ } else {
+ $this->headers->removeCacheControlDirective('immutable');
+ }
+
+ return $this;
+ }
+
+ /**
+ * Returns true if the response is marked as "immutable".
+ *
+ * @return bool returns true if the response is marked as "immutable"; otherwise false
+ *
+ * @final
+ */
+ public function isImmutable()
+ {
+ return $this->headers->hasCacheControlDirective('immutable');
+ }
+
+ /**
+ * Returns true if the response must be revalidated by caches.
+ *
+ * This method indicates that the response must not be served stale by a
+ * cache in any circumstance without first revalidating with the origin.
+ * When present, the TTL of the response should not be overridden to be
+ * greater than the value provided by the origin.
+ *
+ * @return bool true if the response must be revalidated by a cache, false otherwise
+ *
+ * @final since version 3.3
+ */
+ public function mustRevalidate()
+ {
+ return $this->headers->hasCacheControlDirective('must-revalidate') || $this->headers->hasCacheControlDirective('proxy-revalidate');
+ }
+
+ /**
+ * Returns the Date header as a DateTime instance.
+ *
+ * @return \DateTime A \DateTime instance
+ *
+ * @throws \RuntimeException When the header is not parseable
+ *
+ * @final since version 3.2
+ */
+ public function getDate()
+ {
+ return $this->headers->getDate('Date');
+ }
+
+ /**
+ * Sets the Date header.
+ *
+ * @return $this
+ *
+ * @final since version 3.2
+ */
+ public function setDate(\DateTime $date)
+ {
+ $date->setTimezone(new \DateTimeZone('UTC'));
+ $this->headers->set('Date', $date->format('D, d M Y H:i:s').' GMT');
+
+ return $this;
+ }
+
+ /**
+ * Returns the age of the response.
+ *
+ * @return int The age of the response in seconds
+ *
+ * @final since version 3.2
+ */
+ public function getAge()
+ {
+ if (null !== $age = $this->headers->get('Age')) {
+ return (int) $age;
+ }
+
+ return max(time() - $this->getDate()->format('U'), 0);
+ }
+
+ /**
+ * Marks the response stale by setting the Age header to be equal to the maximum age of the response.
+ *
+ * @return $this
+ */
+ public function expire()
+ {
+ if ($this->isFresh()) {
+ $this->headers->set('Age', $this->getMaxAge());
+ }
+
+ return $this;
+ }
+
+ /**
+ * Returns the value of the Expires header as a DateTime instance.
+ *
+ * @return \DateTime|null A DateTime instance or null if the header does not exist
+ *
+ * @final since version 3.2
+ */
+ public function getExpires()
+ {
+ try {
+ return $this->headers->getDate('Expires');
+ } catch (\RuntimeException $e) {
+ // according to RFC 2616 invalid date formats (e.g. "0" and "-1") must be treated as in the past
+ return \DateTime::createFromFormat(DATE_RFC2822, 'Sat, 01 Jan 00 00:00:00 +0000');
+ }
+ }
+
+ /**
+ * Sets the Expires HTTP header with a DateTime instance.
+ *
+ * Passing null as value will remove the header.
+ *
+ * @param \DateTime|null $date A \DateTime instance or null to remove the header
+ *
+ * @return $this
+ *
+ * @final since version 3.2
+ */
+ public function setExpires(\DateTime $date = null)
+ {
+ if (null === $date) {
+ $this->headers->remove('Expires');
+ } else {
+ $date = clone $date;
+ $date->setTimezone(new \DateTimeZone('UTC'));
+ $this->headers->set('Expires', $date->format('D, d M Y H:i:s').' GMT');
+ }
+
+ return $this;
+ }
+
+ /**
+ * Returns the number of seconds after the time specified in the response's Date
+ * header when the response should no longer be considered fresh.
+ *
+ * First, it checks for a s-maxage directive, then a max-age directive, and then it falls
+ * back on an expires header. It returns null when no maximum age can be established.
+ *
+ * @return int|null Number of seconds
+ *
+ * @final since version 3.2
+ */
+ public function getMaxAge()
+ {
+ if ($this->headers->hasCacheControlDirective('s-maxage')) {
+ return (int) $this->headers->getCacheControlDirective('s-maxage');
+ }
+
+ if ($this->headers->hasCacheControlDirective('max-age')) {
+ return (int) $this->headers->getCacheControlDirective('max-age');
+ }
+
+ if (null !== $this->getExpires()) {
+ return $this->getExpires()->format('U') - $this->getDate()->format('U');
+ }
+ }
+
+ /**
+ * Sets the number of seconds after which the response should no longer be considered fresh.
+ *
+ * This methods sets the Cache-Control max-age directive.
+ *
+ * @param int $value Number of seconds
+ *
+ * @return $this
+ *
+ * @final since version 3.2
+ */
+ public function setMaxAge($value)
+ {
+ $this->headers->addCacheControlDirective('max-age', $value);
+
+ return $this;
+ }
+
+ /**
+ * Sets the number of seconds after which the response should no longer be considered fresh by shared caches.
+ *
+ * This methods sets the Cache-Control s-maxage directive.
+ *
+ * @param int $value Number of seconds
+ *
+ * @return $this
+ *
+ * @final since version 3.2
+ */
+ public function setSharedMaxAge($value)
+ {
+ $this->setPublic();
+ $this->headers->addCacheControlDirective('s-maxage', $value);
+
+ return $this;
+ }
+
+ /**
+ * Returns the response's time-to-live in seconds.
+ *
+ * It returns null when no freshness information is present in the response.
+ *
+ * When the responses TTL is <= 0, the response may not be served from cache without first
+ * revalidating with the origin.
+ *
+ * @return int|null The TTL in seconds
+ *
+ * @final since version 3.2
+ */
+ public function getTtl()
+ {
+ if (null !== $maxAge = $this->getMaxAge()) {
+ return $maxAge - $this->getAge();
+ }
+ }
+
+ /**
+ * Sets the response's time-to-live for shared caches.
+ *
+ * This method adjusts the Cache-Control/s-maxage directive.
+ *
+ * @param int $seconds Number of seconds
+ *
+ * @return $this
+ *
+ * @final since version 3.2
+ */
+ public function setTtl($seconds)
+ {
+ $this->setSharedMaxAge($this->getAge() + $seconds);
+
+ return $this;
+ }
+
+ /**
+ * Sets the response's time-to-live for private/client caches.
+ *
+ * This method adjusts the Cache-Control/max-age directive.
+ *
+ * @param int $seconds Number of seconds
+ *
+ * @return $this
+ *
+ * @final since version 3.2
+ */
+ public function setClientTtl($seconds)
+ {
+ $this->setMaxAge($this->getAge() + $seconds);
+
+ return $this;
+ }
+
+ /**
+ * Returns the Last-Modified HTTP header as a DateTime instance.
+ *
+ * @return \DateTime|null A DateTime instance or null if the header does not exist
+ *
+ * @throws \RuntimeException When the HTTP header is not parseable
+ *
+ * @final since version 3.2
+ */
+ public function getLastModified()
+ {
+ return $this->headers->getDate('Last-Modified');
+ }
+
+ /**
+ * Sets the Last-Modified HTTP header with a DateTime instance.
+ *
+ * Passing null as value will remove the header.
+ *
+ * @param \DateTime|null $date A \DateTime instance or null to remove the header
+ *
+ * @return $this
+ *
+ * @final since version 3.2
+ */
+ public function setLastModified(\DateTime $date = null)
+ {
+ if (null === $date) {
+ $this->headers->remove('Last-Modified');
+ } else {
+ $date = clone $date;
+ $date->setTimezone(new \DateTimeZone('UTC'));
+ $this->headers->set('Last-Modified', $date->format('D, d M Y H:i:s').' GMT');
+ }
+
+ return $this;
+ }
+
+ /**
+ * Returns the literal value of the ETag HTTP header.
+ *
+ * @return string|null The ETag HTTP header or null if it does not exist
+ *
+ * @final since version 3.2
+ */
+ public function getEtag()
+ {
+ return $this->headers->get('ETag');
+ }
+
+ /**
+ * Sets the ETag value.
+ *
+ * @param string|null $etag The ETag unique identifier or null to remove the header
+ * @param bool $weak Whether you want a weak ETag or not
+ *
+ * @return $this
+ *
+ * @final since version 3.2
+ */
+ public function setEtag($etag = null, $weak = false)
+ {
+ if (null === $etag) {
+ $this->headers->remove('Etag');
+ } else {
+ if (0 !== strpos($etag, '"')) {
+ $etag = '"'.$etag.'"';
+ }
+
+ $this->headers->set('ETag', (true === $weak ? 'W/' : '').$etag);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Sets the response's cache headers (validation and/or expiration).
+ *
+ * Available options are: etag, last_modified, max_age, s_maxage, private, public and immutable.
+ *
+ * @param array $options An array of cache options
+ *
+ * @return $this
+ *
+ * @throws \InvalidArgumentException
+ *
+ * @final since version 3.3
+ */
+ public function setCache(array $options)
+ {
+ if ($diff = array_diff(array_keys($options), array('etag', 'last_modified', 'max_age', 's_maxage', 'private', 'public', 'immutable'))) {
+ throw new \InvalidArgumentException(sprintf('Response does not support the following options: "%s".', implode('", "', array_values($diff))));
+ }
+
+ if (isset($options['etag'])) {
+ $this->setEtag($options['etag']);
+ }
+
+ if (isset($options['last_modified'])) {
+ $this->setLastModified($options['last_modified']);
+ }
+
+ if (isset($options['max_age'])) {
+ $this->setMaxAge($options['max_age']);
+ }
+
+ if (isset($options['s_maxage'])) {
+ $this->setSharedMaxAge($options['s_maxage']);
+ }
+
+ if (isset($options['public'])) {
+ if ($options['public']) {
+ $this->setPublic();
+ } else {
+ $this->setPrivate();
+ }
+ }
+
+ if (isset($options['private'])) {
+ if ($options['private']) {
+ $this->setPrivate();
+ } else {
+ $this->setPublic();
+ }
+ }
+
+ if (isset($options['immutable'])) {
+ $this->setImmutable((bool) $options['immutable']);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Modifies the response so that it conforms to the rules defined for a 304 status code.
+ *
+ * This sets the status, removes the body, and discards any headers
+ * that MUST NOT be included in 304 responses.
+ *
+ * @return $this
+ *
+ * @see http://tools.ietf.org/html/rfc2616#section-10.3.5
+ *
+ * @final since version 3.3
+ */
+ public function setNotModified()
+ {
+ $this->setStatusCode(304);
+ $this->setContent(null);
+
+ // remove headers that MUST NOT be included with 304 Not Modified responses
+ foreach (array('Allow', 'Content-Encoding', 'Content-Language', 'Content-Length', 'Content-MD5', 'Content-Type', 'Last-Modified') as $header) {
+ $this->headers->remove($header);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Returns true if the response includes a Vary header.
+ *
+ * @return bool true if the response includes a Vary header, false otherwise
+ *
+ * @final since version 3.2
+ */
+ public function hasVary()
+ {
+ return null !== $this->headers->get('Vary');
+ }
+
+ /**
+ * Returns an array of header names given in the Vary header.
+ *
+ * @return array An array of Vary names
+ *
+ * @final since version 3.2
+ */
+ public function getVary()
+ {
+ if (!$vary = $this->headers->get('Vary', null, false)) {
+ return array();
+ }
+
+ $ret = array();
+ foreach ($vary as $item) {
+ $ret = array_merge($ret, preg_split('/[\s,]+/', $item));
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Sets the Vary header.
+ *
+ * @param string|array $headers
+ * @param bool $replace Whether to replace the actual value or not (true by default)
+ *
+ * @return $this
+ *
+ * @final since version 3.2
+ */
+ public function setVary($headers, $replace = true)
+ {
+ $this->headers->set('Vary', $headers, $replace);
+
+ return $this;
+ }
+
+ /**
+ * Determines if the Response validators (ETag, Last-Modified) match
+ * a conditional value specified in the Request.
+ *
+ * If the Response is not modified, it sets the status code to 304 and
+ * removes the actual content by calling the setNotModified() method.
+ *
+ * @return bool true if the Response validators match the Request, false otherwise
+ *
+ * @final since version 3.3
+ */
+ public function isNotModified(Request $request)
+ {
+ if (!$request->isMethodCacheable()) {
+ return false;
+ }
+
+ $notModified = false;
+ $lastModified = $this->headers->get('Last-Modified');
+ $modifiedSince = $request->headers->get('If-Modified-Since');
+
+ if ($etags = $request->getETags()) {
+ $notModified = in_array($this->getEtag(), $etags) || in_array('*', $etags);
+ }
+
+ if ($modifiedSince && $lastModified) {
+ $notModified = strtotime($modifiedSince) >= strtotime($lastModified) && (!$etags || $notModified);
+ }
+
+ if ($notModified) {
+ $this->setNotModified();
+ }
+
+ return $notModified;
+ }
+
+ /**
+ * Is response invalid?
+ *
+ * @return bool
+ *
+ * @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
+ *
+ * @final since version 3.2
+ */
+ public function isInvalid()
+ {
+ return $this->statusCode < 100 || $this->statusCode >= 600;
+ }
+
+ /**
+ * Is response informative?
+ *
+ * @return bool
+ *
+ * @final since version 3.3
+ */
+ public function isInformational()
+ {
+ return $this->statusCode >= 100 && $this->statusCode < 200;
+ }
+
+ /**
+ * Is response successful?
+ *
+ * @return bool
+ *
+ * @final since version 3.2
+ */
+ public function isSuccessful()
+ {
+ return $this->statusCode >= 200 && $this->statusCode < 300;
+ }
+
+ /**
+ * Is the response a redirect?
+ *
+ * @return bool
+ *
+ * @final since version 3.2
+ */
+ public function isRedirection()
+ {
+ return $this->statusCode >= 300 && $this->statusCode < 400;
+ }
+
+ /**
+ * Is there a client error?
+ *
+ * @return bool
+ *
+ * @final since version 3.2
+ */
+ public function isClientError()
+ {
+ return $this->statusCode >= 400 && $this->statusCode < 500;
+ }
+
+ /**
+ * Was there a server side error?
+ *
+ * @return bool
+ *
+ * @final since version 3.3
+ */
+ public function isServerError()
+ {
+ return $this->statusCode >= 500 && $this->statusCode < 600;
+ }
+
+ /**
+ * Is the response OK?
+ *
+ * @return bool
+ *
+ * @final since version 3.2
+ */
+ public function isOk()
+ {
+ return 200 === $this->statusCode;
+ }
+
+ /**
+ * Is the response forbidden?
+ *
+ * @return bool
+ *
+ * @final since version 3.2
+ */
+ public function isForbidden()
+ {
+ return 403 === $this->statusCode;
+ }
+
+ /**
+ * Is the response a not found error?
+ *
+ * @return bool
+ *
+ * @final since version 3.2
+ */
+ public function isNotFound()
+ {
+ return 404 === $this->statusCode;
+ }
+
+ /**
+ * Is the response a redirect of some form?
+ *
+ * @param string $location
+ *
+ * @return bool
+ *
+ * @final since version 3.2
+ */
+ public function isRedirect($location = null)
+ {
+ return in_array($this->statusCode, array(201, 301, 302, 303, 307, 308)) && (null === $location ?: $location == $this->headers->get('Location'));
+ }
+
+ /**
+ * Is the response empty?
+ *
+ * @return bool
+ *
+ * @final since version 3.2
+ */
+ public function isEmpty()
+ {
+ return in_array($this->statusCode, array(204, 304));
+ }
+
+ /**
+ * Cleans or flushes output buffers up to target level.
+ *
+ * Resulting level can be greater than target level if a non-removable buffer has been encountered.
+ *
+ * @param int $targetLevel The target output buffering level
+ * @param bool $flush Whether to flush or clean the buffers
+ *
+ * @final since version 3.3
+ */
+ public static function closeOutputBuffers($targetLevel, $flush)
+ {
+ $status = ob_get_status(true);
+ $level = count($status);
+ // PHP_OUTPUT_HANDLER_* are not defined on HHVM 3.3
+ $flags = defined('PHP_OUTPUT_HANDLER_REMOVABLE') ? PHP_OUTPUT_HANDLER_REMOVABLE | ($flush ? PHP_OUTPUT_HANDLER_FLUSHABLE : PHP_OUTPUT_HANDLER_CLEANABLE) : -1;
+
+ while ($level-- > $targetLevel && ($s = $status[$level]) && (!isset($s['del']) ? !isset($s['flags']) || ($s['flags'] & $flags) === $flags : $s['del'])) {
+ if ($flush) {
+ ob_end_flush();
+ } else {
+ ob_end_clean();
+ }
+ }
+ }
+
+ /**
+ * Checks if we need to remove Cache-Control for SSL encrypted downloads when using IE < 9.
+ *
+ * @see http://support.microsoft.com/kb/323308
+ *
+ * @final since version 3.3
+ */
+ protected function ensureIEOverSSLCompatibility(Request $request)
+ {
+ if (false !== stripos($this->headers->get('Content-Disposition'), 'attachment') && 1 == preg_match('/MSIE (.*?);/i', $request->server->get('HTTP_USER_AGENT'), $match) && true === $request->isSecure()) {
+ if ((int) preg_replace('/(MSIE )(.*?);/', '$2', $match[0]) < 9) {
+ $this->headers->remove('Cache-Control');
+ }
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/ResponseHeaderBag.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/ResponseHeaderBag.php
new file mode 100644
index 0000000..11a8593
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/ResponseHeaderBag.php
@@ -0,0 +1,340 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * ResponseHeaderBag is a container for Response HTTP headers.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ResponseHeaderBag extends HeaderBag
+{
+ const COOKIES_FLAT = 'flat';
+ const COOKIES_ARRAY = 'array';
+
+ const DISPOSITION_ATTACHMENT = 'attachment';
+ const DISPOSITION_INLINE = 'inline';
+
+ protected $computedCacheControl = array();
+ protected $cookies = array();
+ protected $headerNames = array();
+
+ public function __construct(array $headers = array())
+ {
+ parent::__construct($headers);
+
+ if (!isset($this->headers['cache-control'])) {
+ $this->set('Cache-Control', '');
+ }
+
+ /* RFC2616 - 14.18 says all Responses need to have a Date */
+ if (!isset($this->headers['date'])) {
+ $this->initDate();
+ }
+ }
+
+ /**
+ * Returns the headers, with original capitalizations.
+ *
+ * @return array An array of headers
+ */
+ public function allPreserveCase()
+ {
+ $headers = array();
+ foreach ($this->all() as $name => $value) {
+ $headers[isset($this->headerNames[$name]) ? $this->headerNames[$name] : $name] = $value;
+ }
+
+ return $headers;
+ }
+
+ public function allPreserveCaseWithoutCookies()
+ {
+ $headers = $this->allPreserveCase();
+ if (isset($this->headerNames['set-cookie'])) {
+ unset($headers[$this->headerNames['set-cookie']]);
+ }
+
+ return $headers;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function replace(array $headers = array())
+ {
+ $this->headerNames = array();
+
+ parent::replace($headers);
+
+ if (!isset($this->headers['cache-control'])) {
+ $this->set('Cache-Control', '');
+ }
+
+ if (!isset($this->headers['date'])) {
+ $this->initDate();
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function all()
+ {
+ $headers = parent::all();
+ foreach ($this->getCookies() as $cookie) {
+ $headers['set-cookie'][] = (string) $cookie;
+ }
+
+ return $headers;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set($key, $values, $replace = true)
+ {
+ $uniqueKey = str_replace('_', '-', strtolower($key));
+
+ if ('set-cookie' === $uniqueKey) {
+ if ($replace) {
+ $this->cookies = array();
+ }
+ foreach ((array) $values as $cookie) {
+ $this->setCookie(Cookie::fromString($cookie));
+ }
+ $this->headerNames[$uniqueKey] = $key;
+
+ return;
+ }
+
+ $this->headerNames[$uniqueKey] = $key;
+
+ parent::set($key, $values, $replace);
+
+ // ensure the cache-control header has sensible defaults
+ if (\in_array($uniqueKey, array('cache-control', 'etag', 'last-modified', 'expires'), true)) {
+ $computed = $this->computeCacheControlValue();
+ $this->headers['cache-control'] = array($computed);
+ $this->headerNames['cache-control'] = 'Cache-Control';
+ $this->computedCacheControl = $this->parseCacheControl($computed);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function remove($key)
+ {
+ $uniqueKey = str_replace('_', '-', strtolower($key));
+ unset($this->headerNames[$uniqueKey]);
+
+ if ('set-cookie' === $uniqueKey) {
+ $this->cookies = array();
+
+ return;
+ }
+
+ parent::remove($key);
+
+ if ('cache-control' === $uniqueKey) {
+ $this->computedCacheControl = array();
+ }
+
+ if ('date' === $uniqueKey) {
+ $this->initDate();
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasCacheControlDirective($key)
+ {
+ return array_key_exists($key, $this->computedCacheControl);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getCacheControlDirective($key)
+ {
+ return array_key_exists($key, $this->computedCacheControl) ? $this->computedCacheControl[$key] : null;
+ }
+
+ public function setCookie(Cookie $cookie)
+ {
+ $this->cookies[$cookie->getDomain()][$cookie->getPath()][$cookie->getName()] = $cookie;
+ $this->headerNames['set-cookie'] = 'Set-Cookie';
+ }
+
+ /**
+ * Removes a cookie from the array, but does not unset it in the browser.
+ *
+ * @param string $name
+ * @param string $path
+ * @param string $domain
+ */
+ public function removeCookie($name, $path = '/', $domain = null)
+ {
+ if (null === $path) {
+ $path = '/';
+ }
+
+ unset($this->cookies[$domain][$path][$name]);
+
+ if (empty($this->cookies[$domain][$path])) {
+ unset($this->cookies[$domain][$path]);
+
+ if (empty($this->cookies[$domain])) {
+ unset($this->cookies[$domain]);
+ }
+ }
+
+ if (empty($this->cookies)) {
+ unset($this->headerNames['set-cookie']);
+ }
+ }
+
+ /**
+ * Returns an array with all cookies.
+ *
+ * @param string $format
+ *
+ * @return array
+ *
+ * @throws \InvalidArgumentException When the $format is invalid
+ */
+ public function getCookies($format = self::COOKIES_FLAT)
+ {
+ if (!in_array($format, array(self::COOKIES_FLAT, self::COOKIES_ARRAY))) {
+ throw new \InvalidArgumentException(sprintf('Format "%s" invalid (%s).', $format, implode(', ', array(self::COOKIES_FLAT, self::COOKIES_ARRAY))));
+ }
+
+ if (self::COOKIES_ARRAY === $format) {
+ return $this->cookies;
+ }
+
+ $flattenedCookies = array();
+ foreach ($this->cookies as $path) {
+ foreach ($path as $cookies) {
+ foreach ($cookies as $cookie) {
+ $flattenedCookies[] = $cookie;
+ }
+ }
+ }
+
+ return $flattenedCookies;
+ }
+
+ /**
+ * Clears a cookie in the browser.
+ *
+ * @param string $name
+ * @param string $path
+ * @param string $domain
+ * @param bool $secure
+ * @param bool $httpOnly
+ */
+ public function clearCookie($name, $path = '/', $domain = null, $secure = false, $httpOnly = true)
+ {
+ $this->setCookie(new Cookie($name, null, 1, $path, $domain, $secure, $httpOnly));
+ }
+
+ /**
+ * Generates a HTTP Content-Disposition field-value.
+ *
+ * @param string $disposition One of "inline" or "attachment"
+ * @param string $filename A unicode string
+ * @param string $filenameFallback A string containing only ASCII characters that
+ * is semantically equivalent to $filename. If the filename is already ASCII,
+ * it can be omitted, or just copied from $filename
+ *
+ * @return string A string suitable for use as a Content-Disposition field-value
+ *
+ * @throws \InvalidArgumentException
+ *
+ * @see RFC 6266
+ */
+ public function makeDisposition($disposition, $filename, $filenameFallback = '')
+ {
+ if (!in_array($disposition, array(self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE))) {
+ throw new \InvalidArgumentException(sprintf('The disposition must be either "%s" or "%s".', self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE));
+ }
+
+ if ('' == $filenameFallback) {
+ $filenameFallback = $filename;
+ }
+
+ // filenameFallback is not ASCII.
+ if (!preg_match('/^[\x20-\x7e]*$/', $filenameFallback)) {
+ throw new \InvalidArgumentException('The filename fallback must only contain ASCII characters.');
+ }
+
+ // percent characters aren't safe in fallback.
+ if (false !== strpos($filenameFallback, '%')) {
+ throw new \InvalidArgumentException('The filename fallback cannot contain the "%" character.');
+ }
+
+ // path separators aren't allowed in either.
+ if (false !== strpos($filename, '/') || false !== strpos($filename, '\\') || false !== strpos($filenameFallback, '/') || false !== strpos($filenameFallback, '\\')) {
+ throw new \InvalidArgumentException('The filename and the fallback cannot contain the "/" and "\\" characters.');
+ }
+
+ $output = sprintf('%s; filename="%s"', $disposition, str_replace('"', '\\"', $filenameFallback));
+
+ if ($filename !== $filenameFallback) {
+ $output .= sprintf("; filename*=utf-8''%s", rawurlencode($filename));
+ }
+
+ return $output;
+ }
+
+ /**
+ * Returns the calculated value of the cache-control header.
+ *
+ * This considers several other headers and calculates or modifies the
+ * cache-control header to a sensible, conservative value.
+ *
+ * @return string
+ */
+ protected function computeCacheControlValue()
+ {
+ if (!$this->cacheControl && !$this->has('ETag') && !$this->has('Last-Modified') && !$this->has('Expires')) {
+ return 'no-cache, private';
+ }
+
+ if (!$this->cacheControl) {
+ // conservative by default
+ return 'private, must-revalidate';
+ }
+
+ $header = $this->getCacheControlHeader();
+ if (isset($this->cacheControl['public']) || isset($this->cacheControl['private'])) {
+ return $header;
+ }
+
+ // public if s-maxage is defined, private otherwise
+ if (!isset($this->cacheControl['s-maxage'])) {
+ return $header.', private';
+ }
+
+ return $header;
+ }
+
+ private function initDate()
+ {
+ $now = \DateTime::createFromFormat('U', time());
+ $now->setTimezone(new \DateTimeZone('UTC'));
+ $this->set('Date', $now->format('D, d M Y H:i:s').' GMT');
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/ServerBag.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/ServerBag.php
new file mode 100644
index 0000000..19d2022
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/ServerBag.php
@@ -0,0 +1,102 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * ServerBag is a container for HTTP headers from the $_SERVER variable.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Bulat Shakirzyanov <mallluhuct@gmail.com>
+ * @author Robert Kiss <kepten@gmail.com>
+ */
+class ServerBag extends ParameterBag
+{
+ /**
+ * Gets the HTTP headers.
+ *
+ * @return array
+ */
+ public function getHeaders()
+ {
+ $headers = array();
+ $contentHeaders = array('CONTENT_LENGTH' => true, 'CONTENT_MD5' => true, 'CONTENT_TYPE' => true);
+ foreach ($this->parameters as $key => $value) {
+ if (0 === strpos($key, 'HTTP_')) {
+ $headers[substr($key, 5)] = $value;
+ }
+ // CONTENT_* are not prefixed with HTTP_
+ elseif (isset($contentHeaders[$key])) {
+ $headers[$key] = $value;
+ }
+ }
+
+ if (isset($this->parameters['PHP_AUTH_USER'])) {
+ $headers['PHP_AUTH_USER'] = $this->parameters['PHP_AUTH_USER'];
+ $headers['PHP_AUTH_PW'] = isset($this->parameters['PHP_AUTH_PW']) ? $this->parameters['PHP_AUTH_PW'] : '';
+ } else {
+ /*
+ * php-cgi under Apache does not pass HTTP Basic user/pass to PHP by default
+ * For this workaround to work, add these lines to your .htaccess file:
+ * RewriteCond %{HTTP:Authorization} ^(.+)$
+ * RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
+ *
+ * A sample .htaccess file:
+ * RewriteEngine On
+ * RewriteCond %{HTTP:Authorization} ^(.+)$
+ * RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
+ * RewriteCond %{REQUEST_FILENAME} !-f
+ * RewriteRule ^(.*)$ app.php [QSA,L]
+ */
+
+ $authorizationHeader = null;
+ if (isset($this->parameters['HTTP_AUTHORIZATION'])) {
+ $authorizationHeader = $this->parameters['HTTP_AUTHORIZATION'];
+ } elseif (isset($this->parameters['REDIRECT_HTTP_AUTHORIZATION'])) {
+ $authorizationHeader = $this->parameters['REDIRECT_HTTP_AUTHORIZATION'];
+ }
+
+ if (null !== $authorizationHeader) {
+ if (0 === stripos($authorizationHeader, 'basic ')) {
+ // Decode AUTHORIZATION header into PHP_AUTH_USER and PHP_AUTH_PW when authorization header is basic
+ $exploded = explode(':', base64_decode(substr($authorizationHeader, 6)), 2);
+ if (2 == count($exploded)) {
+ list($headers['PHP_AUTH_USER'], $headers['PHP_AUTH_PW']) = $exploded;
+ }
+ } elseif (empty($this->parameters['PHP_AUTH_DIGEST']) && (0 === stripos($authorizationHeader, 'digest '))) {
+ // In some circumstances PHP_AUTH_DIGEST needs to be set
+ $headers['PHP_AUTH_DIGEST'] = $authorizationHeader;
+ $this->parameters['PHP_AUTH_DIGEST'] = $authorizationHeader;
+ } elseif (0 === stripos($authorizationHeader, 'bearer ')) {
+ /*
+ * XXX: Since there is no PHP_AUTH_BEARER in PHP predefined variables,
+ * I'll just set $headers['AUTHORIZATION'] here.
+ * http://php.net/manual/en/reserved.variables.server.php
+ */
+ $headers['AUTHORIZATION'] = $authorizationHeader;
+ }
+ }
+ }
+
+ if (isset($headers['AUTHORIZATION'])) {
+ return $headers;
+ }
+
+ // PHP_AUTH_USER/PHP_AUTH_PW
+ if (isset($headers['PHP_AUTH_USER'])) {
+ $headers['AUTHORIZATION'] = 'Basic '.base64_encode($headers['PHP_AUTH_USER'].':'.$headers['PHP_AUTH_PW']);
+ } elseif (isset($headers['PHP_AUTH_DIGEST'])) {
+ $headers['AUTHORIZATION'] = $headers['PHP_AUTH_DIGEST'];
+ }
+
+ return $headers;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Attribute/AttributeBag.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Attribute/AttributeBag.php
new file mode 100644
index 0000000..ea1fda2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Attribute/AttributeBag.php
@@ -0,0 +1,148 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Attribute;
+
+/**
+ * This class relates to session attribute storage.
+ */
+class AttributeBag implements AttributeBagInterface, \IteratorAggregate, \Countable
+{
+ private $name = 'attributes';
+ private $storageKey;
+
+ protected $attributes = array();
+
+ /**
+ * @param string $storageKey The key used to store attributes in the session
+ */
+ public function __construct($storageKey = '_sf2_attributes')
+ {
+ $this->storageKey = $storageKey;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function initialize(array &$attributes)
+ {
+ $this->attributes = &$attributes;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getStorageKey()
+ {
+ return $this->storageKey;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function has($name)
+ {
+ return array_key_exists($name, $this->attributes);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get($name, $default = null)
+ {
+ return array_key_exists($name, $this->attributes) ? $this->attributes[$name] : $default;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set($name, $value)
+ {
+ $this->attributes[$name] = $value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function all()
+ {
+ return $this->attributes;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function replace(array $attributes)
+ {
+ $this->attributes = array();
+ foreach ($attributes as $key => $value) {
+ $this->set($key, $value);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function remove($name)
+ {
+ $retval = null;
+ if (array_key_exists($name, $this->attributes)) {
+ $retval = $this->attributes[$name];
+ unset($this->attributes[$name]);
+ }
+
+ return $retval;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clear()
+ {
+ $return = $this->attributes;
+ $this->attributes = array();
+
+ return $return;
+ }
+
+ /**
+ * Returns an iterator for attributes.
+ *
+ * @return \ArrayIterator An \ArrayIterator instance
+ */
+ public function getIterator()
+ {
+ return new \ArrayIterator($this->attributes);
+ }
+
+ /**
+ * Returns the number of attributes.
+ *
+ * @return int The number of attributes
+ */
+ public function count()
+ {
+ return count($this->attributes);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Attribute/AttributeBagInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Attribute/AttributeBagInterface.php
new file mode 100644
index 0000000..0d8d179
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Attribute/AttributeBagInterface.php
@@ -0,0 +1,72 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Attribute;
+
+use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
+
+/**
+ * Attributes store.
+ *
+ * @author Drak <drak@zikula.org>
+ */
+interface AttributeBagInterface extends SessionBagInterface
+{
+ /**
+ * Checks if an attribute is defined.
+ *
+ * @param string $name The attribute name
+ *
+ * @return bool true if the attribute is defined, false otherwise
+ */
+ public function has($name);
+
+ /**
+ * Returns an attribute.
+ *
+ * @param string $name The attribute name
+ * @param mixed $default The default value if not found
+ *
+ * @return mixed
+ */
+ public function get($name, $default = null);
+
+ /**
+ * Sets an attribute.
+ *
+ * @param string $name
+ * @param mixed $value
+ */
+ public function set($name, $value);
+
+ /**
+ * Returns attributes.
+ *
+ * @return array Attributes
+ */
+ public function all();
+
+ /**
+ * Sets attributes.
+ *
+ * @param array $attributes Attributes
+ */
+ public function replace(array $attributes);
+
+ /**
+ * Removes an attribute.
+ *
+ * @param string $name
+ *
+ * @return mixed The removed value or null when it does not exist
+ */
+ public function remove($name);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Attribute/NamespacedAttributeBag.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Attribute/NamespacedAttributeBag.php
new file mode 100644
index 0000000..abbf37e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Attribute/NamespacedAttributeBag.php
@@ -0,0 +1,153 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Attribute;
+
+/**
+ * This class provides structured storage of session attributes using
+ * a name spacing character in the key.
+ *
+ * @author Drak <drak@zikula.org>
+ */
+class NamespacedAttributeBag extends AttributeBag
+{
+ private $namespaceCharacter;
+
+ /**
+ * @param string $storageKey Session storage key
+ * @param string $namespaceCharacter Namespace character to use in keys
+ */
+ public function __construct($storageKey = '_sf2_attributes', $namespaceCharacter = '/')
+ {
+ $this->namespaceCharacter = $namespaceCharacter;
+ parent::__construct($storageKey);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function has($name)
+ {
+ // reference mismatch: if fixed, re-introduced in array_key_exists; keep as it is
+ $attributes = $this->resolveAttributePath($name);
+ $name = $this->resolveKey($name);
+
+ if (null === $attributes) {
+ return false;
+ }
+
+ return array_key_exists($name, $attributes);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get($name, $default = null)
+ {
+ // reference mismatch: if fixed, re-introduced in array_key_exists; keep as it is
+ $attributes = $this->resolveAttributePath($name);
+ $name = $this->resolveKey($name);
+
+ if (null === $attributes) {
+ return $default;
+ }
+
+ return array_key_exists($name, $attributes) ? $attributes[$name] : $default;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set($name, $value)
+ {
+ $attributes = &$this->resolveAttributePath($name, true);
+ $name = $this->resolveKey($name);
+ $attributes[$name] = $value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function remove($name)
+ {
+ $retval = null;
+ $attributes = &$this->resolveAttributePath($name);
+ $name = $this->resolveKey($name);
+ if (null !== $attributes && array_key_exists($name, $attributes)) {
+ $retval = $attributes[$name];
+ unset($attributes[$name]);
+ }
+
+ return $retval;
+ }
+
+ /**
+ * Resolves a path in attributes property and returns it as a reference.
+ *
+ * This method allows structured namespacing of session attributes.
+ *
+ * @param string $name Key name
+ * @param bool $writeContext Write context, default false
+ *
+ * @return array
+ */
+ protected function &resolveAttributePath($name, $writeContext = false)
+ {
+ $array = &$this->attributes;
+ $name = (0 === strpos($name, $this->namespaceCharacter)) ? substr($name, 1) : $name;
+
+ // Check if there is anything to do, else return
+ if (!$name) {
+ return $array;
+ }
+
+ $parts = explode($this->namespaceCharacter, $name);
+ if (count($parts) < 2) {
+ if (!$writeContext) {
+ return $array;
+ }
+
+ $array[$parts[0]] = array();
+
+ return $array;
+ }
+
+ unset($parts[count($parts) - 1]);
+
+ foreach ($parts as $part) {
+ if (null !== $array && !array_key_exists($part, $array)) {
+ $array[$part] = $writeContext ? array() : null;
+ }
+
+ $array = &$array[$part];
+ }
+
+ return $array;
+ }
+
+ /**
+ * Resolves the key from the name.
+ *
+ * This is the last part in a dot separated string.
+ *
+ * @param string $name
+ *
+ * @return string
+ */
+ protected function resolveKey($name)
+ {
+ if (false !== $pos = strrpos($name, $this->namespaceCharacter)) {
+ $name = substr($name, $pos + 1);
+ }
+
+ return $name;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Flash/AutoExpireFlashBag.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Flash/AutoExpireFlashBag.php
new file mode 100644
index 0000000..77521c2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Flash/AutoExpireFlashBag.php
@@ -0,0 +1,161 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Flash;
+
+/**
+ * AutoExpireFlashBag flash message container.
+ *
+ * @author Drak <drak@zikula.org>
+ */
+class AutoExpireFlashBag implements FlashBagInterface
+{
+ private $name = 'flashes';
+ private $flashes = array('display' => array(), 'new' => array());
+ private $storageKey;
+
+ /**
+ * @param string $storageKey The key used to store flashes in the session
+ */
+ public function __construct($storageKey = '_symfony_flashes')
+ {
+ $this->storageKey = $storageKey;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function initialize(array &$flashes)
+ {
+ $this->flashes = &$flashes;
+
+ // The logic: messages from the last request will be stored in new, so we move them to previous
+ // This request we will show what is in 'display'. What is placed into 'new' this time round will
+ // be moved to display next time round.
+ $this->flashes['display'] = array_key_exists('new', $this->flashes) ? $this->flashes['new'] : array();
+ $this->flashes['new'] = array();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function add($type, $message)
+ {
+ $this->flashes['new'][$type][] = $message;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function peek($type, array $default = array())
+ {
+ return $this->has($type) ? $this->flashes['display'][$type] : $default;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function peekAll()
+ {
+ return array_key_exists('display', $this->flashes) ? (array) $this->flashes['display'] : array();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get($type, array $default = array())
+ {
+ $return = $default;
+
+ if (!$this->has($type)) {
+ return $return;
+ }
+
+ if (isset($this->flashes['display'][$type])) {
+ $return = $this->flashes['display'][$type];
+ unset($this->flashes['display'][$type]);
+ }
+
+ return $return;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function all()
+ {
+ $return = $this->flashes['display'];
+ $this->flashes['display'] = array();
+
+ return $return;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setAll(array $messages)
+ {
+ $this->flashes['new'] = $messages;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set($type, $messages)
+ {
+ $this->flashes['new'][$type] = (array) $messages;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function has($type)
+ {
+ return array_key_exists($type, $this->flashes['display']) && $this->flashes['display'][$type];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function keys()
+ {
+ return array_keys($this->flashes['display']);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getStorageKey()
+ {
+ return $this->storageKey;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clear()
+ {
+ return $this->all();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Flash/FlashBag.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Flash/FlashBag.php
new file mode 100644
index 0000000..12fb740
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Flash/FlashBag.php
@@ -0,0 +1,152 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Flash;
+
+/**
+ * FlashBag flash message container.
+ *
+ * @author Drak <drak@zikula.org>
+ */
+class FlashBag implements FlashBagInterface
+{
+ private $name = 'flashes';
+ private $flashes = array();
+ private $storageKey;
+
+ /**
+ * @param string $storageKey The key used to store flashes in the session
+ */
+ public function __construct($storageKey = '_symfony_flashes')
+ {
+ $this->storageKey = $storageKey;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function initialize(array &$flashes)
+ {
+ $this->flashes = &$flashes;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function add($type, $message)
+ {
+ $this->flashes[$type][] = $message;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function peek($type, array $default = array())
+ {
+ return $this->has($type) ? $this->flashes[$type] : $default;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function peekAll()
+ {
+ return $this->flashes;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get($type, array $default = array())
+ {
+ if (!$this->has($type)) {
+ return $default;
+ }
+
+ $return = $this->flashes[$type];
+
+ unset($this->flashes[$type]);
+
+ return $return;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function all()
+ {
+ $return = $this->peekAll();
+ $this->flashes = array();
+
+ return $return;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set($type, $messages)
+ {
+ $this->flashes[$type] = (array) $messages;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setAll(array $messages)
+ {
+ $this->flashes = $messages;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function has($type)
+ {
+ return array_key_exists($type, $this->flashes) && $this->flashes[$type];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function keys()
+ {
+ return array_keys($this->flashes);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getStorageKey()
+ {
+ return $this->storageKey;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clear()
+ {
+ return $this->all();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Flash/FlashBagInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Flash/FlashBagInterface.php
new file mode 100644
index 0000000..80e97f1
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Flash/FlashBagInterface.php
@@ -0,0 +1,93 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Flash;
+
+use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
+
+/**
+ * FlashBagInterface.
+ *
+ * @author Drak <drak@zikula.org>
+ */
+interface FlashBagInterface extends SessionBagInterface
+{
+ /**
+ * Adds a flash message for type.
+ *
+ * @param string $type
+ * @param string $message
+ */
+ public function add($type, $message);
+
+ /**
+ * Registers a message for a given type.
+ *
+ * @param string $type
+ * @param string|array $message
+ */
+ public function set($type, $message);
+
+ /**
+ * Gets flash messages for a given type.
+ *
+ * @param string $type Message category type
+ * @param array $default Default value if $type does not exist
+ *
+ * @return array
+ */
+ public function peek($type, array $default = array());
+
+ /**
+ * Gets all flash messages.
+ *
+ * @return array
+ */
+ public function peekAll();
+
+ /**
+ * Gets and clears flash from the stack.
+ *
+ * @param string $type
+ * @param array $default Default value if $type does not exist
+ *
+ * @return array
+ */
+ public function get($type, array $default = array());
+
+ /**
+ * Gets and clears flashes from the stack.
+ *
+ * @return array
+ */
+ public function all();
+
+ /**
+ * Sets all flash messages.
+ */
+ public function setAll(array $messages);
+
+ /**
+ * Has flash messages for a given type?
+ *
+ * @param string $type
+ *
+ * @return bool
+ */
+ public function has($type);
+
+ /**
+ * Returns a list of all defined types.
+ *
+ * @return array
+ */
+ public function keys();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Session.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Session.php
new file mode 100644
index 0000000..a46cffb
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Session.php
@@ -0,0 +1,273 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session;
+
+use Symfony\Component\HttpFoundation\Session\Storage\SessionStorageInterface;
+use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
+use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBagInterface;
+use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;
+use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
+use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Drak <drak@zikula.org>
+ */
+class Session implements SessionInterface, \IteratorAggregate, \Countable
+{
+ protected $storage;
+
+ private $flashName;
+ private $attributeName;
+ private $data = array();
+ private $hasBeenStarted;
+
+ /**
+ * @param SessionStorageInterface $storage A SessionStorageInterface instance
+ * @param AttributeBagInterface $attributes An AttributeBagInterface instance, (defaults null for default AttributeBag)
+ * @param FlashBagInterface $flashes A FlashBagInterface instance (defaults null for default FlashBag)
+ */
+ public function __construct(SessionStorageInterface $storage = null, AttributeBagInterface $attributes = null, FlashBagInterface $flashes = null)
+ {
+ $this->storage = $storage ?: new NativeSessionStorage();
+
+ $attributes = $attributes ?: new AttributeBag();
+ $this->attributeName = $attributes->getName();
+ $this->registerBag($attributes);
+
+ $flashes = $flashes ?: new FlashBag();
+ $this->flashName = $flashes->getName();
+ $this->registerBag($flashes);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function start()
+ {
+ return $this->storage->start();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function has($name)
+ {
+ return $this->getAttributeBag()->has($name);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get($name, $default = null)
+ {
+ return $this->getAttributeBag()->get($name, $default);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set($name, $value)
+ {
+ $this->getAttributeBag()->set($name, $value);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function all()
+ {
+ return $this->getAttributeBag()->all();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function replace(array $attributes)
+ {
+ $this->getAttributeBag()->replace($attributes);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function remove($name)
+ {
+ return $this->getAttributeBag()->remove($name);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clear()
+ {
+ $this->getAttributeBag()->clear();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isStarted()
+ {
+ return $this->storage->isStarted();
+ }
+
+ /**
+ * Returns an iterator for attributes.
+ *
+ * @return \ArrayIterator An \ArrayIterator instance
+ */
+ public function getIterator()
+ {
+ return new \ArrayIterator($this->getAttributeBag()->all());
+ }
+
+ /**
+ * Returns the number of attributes.
+ *
+ * @return int The number of attributes
+ */
+ public function count()
+ {
+ return count($this->getAttributeBag()->all());
+ }
+
+ /**
+ * @return bool
+ *
+ * @internal
+ */
+ public function hasBeenStarted()
+ {
+ return $this->hasBeenStarted;
+ }
+
+ /**
+ * @return bool
+ *
+ * @internal
+ */
+ public function isEmpty()
+ {
+ foreach ($this->data as &$data) {
+ if (!empty($data)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function invalidate($lifetime = null)
+ {
+ $this->storage->clear();
+
+ return $this->migrate(true, $lifetime);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function migrate($destroy = false, $lifetime = null)
+ {
+ return $this->storage->regenerate($destroy, $lifetime);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function save()
+ {
+ $this->storage->save();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getId()
+ {
+ return $this->storage->getId();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setId($id)
+ {
+ $this->storage->setId($id);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return $this->storage->getName();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setName($name)
+ {
+ $this->storage->setName($name);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMetadataBag()
+ {
+ return $this->storage->getMetadataBag();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function registerBag(SessionBagInterface $bag)
+ {
+ $this->storage->registerBag(new SessionBagProxy($bag, $this->data, $this->hasBeenStarted));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getBag($name)
+ {
+ return $this->storage->getBag($name)->getBag();
+ }
+
+ /**
+ * Gets the flashbag interface.
+ *
+ * @return FlashBagInterface
+ */
+ public function getFlashBag()
+ {
+ return $this->getBag($this->flashName);
+ }
+
+ /**
+ * Gets the attributebag interface.
+ *
+ * Note that this method was added to help with IDE autocompletion.
+ *
+ * @return AttributeBagInterface
+ */
+ private function getAttributeBag()
+ {
+ return $this->getBag($this->attributeName);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/SessionBagInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/SessionBagInterface.php
new file mode 100644
index 0000000..8e37d06
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/SessionBagInterface.php
@@ -0,0 +1,46 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session;
+
+/**
+ * Session Bag store.
+ *
+ * @author Drak <drak@zikula.org>
+ */
+interface SessionBagInterface
+{
+ /**
+ * Gets this bag's name.
+ *
+ * @return string
+ */
+ public function getName();
+
+ /**
+ * Initializes the Bag.
+ */
+ public function initialize(array &$array);
+
+ /**
+ * Gets the storage key for this bag.
+ *
+ * @return string
+ */
+ public function getStorageKey();
+
+ /**
+ * Clears out data from bag.
+ *
+ * @return mixed Whatever data was contained
+ */
+ public function clear();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/SessionBagProxy.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/SessionBagProxy.php
new file mode 100644
index 0000000..307836d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/SessionBagProxy.php
@@ -0,0 +1,82 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session;
+
+/**
+ * @author Nicolas Grekas <p@tchwork.com>
+ *
+ * @internal
+ */
+final class SessionBagProxy implements SessionBagInterface
+{
+ private $bag;
+ private $data;
+ private $hasBeenStarted;
+
+ public function __construct(SessionBagInterface $bag, array &$data, &$hasBeenStarted)
+ {
+ $this->bag = $bag;
+ $this->data = &$data;
+ $this->hasBeenStarted = &$hasBeenStarted;
+ }
+
+ /**
+ * @return SessionBagInterface
+ */
+ public function getBag()
+ {
+ return $this->bag;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isEmpty()
+ {
+ return empty($this->data[$this->bag->getStorageKey()]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return $this->bag->getName();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function initialize(array &$array)
+ {
+ $this->hasBeenStarted = true;
+ $this->data[$this->bag->getStorageKey()] = &$array;
+
+ $this->bag->initialize($array);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getStorageKey()
+ {
+ return $this->bag->getStorageKey();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clear()
+ {
+ return $this->bag->clear();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/SessionInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/SessionInterface.php
new file mode 100644
index 0000000..95fca85
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/SessionInterface.php
@@ -0,0 +1,180 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session;
+
+use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag;
+
+/**
+ * Interface for the session.
+ *
+ * @author Drak <drak@zikula.org>
+ */
+interface SessionInterface
+{
+ /**
+ * Starts the session storage.
+ *
+ * @return bool True if session started
+ *
+ * @throws \RuntimeException if session fails to start
+ */
+ public function start();
+
+ /**
+ * Returns the session ID.
+ *
+ * @return string The session ID
+ */
+ public function getId();
+
+ /**
+ * Sets the session ID.
+ *
+ * @param string $id
+ */
+ public function setId($id);
+
+ /**
+ * Returns the session name.
+ *
+ * @return mixed The session name
+ */
+ public function getName();
+
+ /**
+ * Sets the session name.
+ *
+ * @param string $name
+ */
+ public function setName($name);
+
+ /**
+ * Invalidates the current session.
+ *
+ * Clears all session attributes and flashes and regenerates the
+ * session and deletes the old session from persistence.
+ *
+ * @param int $lifetime Sets the cookie lifetime for the session cookie. A null value
+ * will leave the system settings unchanged, 0 sets the cookie
+ * to expire with browser session. Time is in seconds, and is
+ * not a Unix timestamp.
+ *
+ * @return bool True if session invalidated, false if error
+ */
+ public function invalidate($lifetime = null);
+
+ /**
+ * Migrates the current session to a new session id while maintaining all
+ * session attributes.
+ *
+ * @param bool $destroy Whether to delete the old session or leave it to garbage collection
+ * @param int $lifetime Sets the cookie lifetime for the session cookie. A null value
+ * will leave the system settings unchanged, 0 sets the cookie
+ * to expire with browser session. Time is in seconds, and is
+ * not a Unix timestamp.
+ *
+ * @return bool True if session migrated, false if error
+ */
+ public function migrate($destroy = false, $lifetime = null);
+
+ /**
+ * Force the session to be saved and closed.
+ *
+ * This method is generally not required for real sessions as
+ * the session will be automatically saved at the end of
+ * code execution.
+ */
+ public function save();
+
+ /**
+ * Checks if an attribute is defined.
+ *
+ * @param string $name The attribute name
+ *
+ * @return bool true if the attribute is defined, false otherwise
+ */
+ public function has($name);
+
+ /**
+ * Returns an attribute.
+ *
+ * @param string $name The attribute name
+ * @param mixed $default The default value if not found
+ *
+ * @return mixed
+ */
+ public function get($name, $default = null);
+
+ /**
+ * Sets an attribute.
+ *
+ * @param string $name
+ * @param mixed $value
+ */
+ public function set($name, $value);
+
+ /**
+ * Returns attributes.
+ *
+ * @return array Attributes
+ */
+ public function all();
+
+ /**
+ * Sets attributes.
+ *
+ * @param array $attributes Attributes
+ */
+ public function replace(array $attributes);
+
+ /**
+ * Removes an attribute.
+ *
+ * @param string $name
+ *
+ * @return mixed The removed value or null when it does not exist
+ */
+ public function remove($name);
+
+ /**
+ * Clears all attributes.
+ */
+ public function clear();
+
+ /**
+ * Checks if the session was started.
+ *
+ * @return bool
+ */
+ public function isStarted();
+
+ /**
+ * Registers a SessionBagInterface with the session.
+ */
+ public function registerBag(SessionBagInterface $bag);
+
+ /**
+ * Gets a bag instance by name.
+ *
+ * @param string $name
+ *
+ * @return SessionBagInterface
+ */
+ public function getBag($name);
+
+ /**
+ * Gets session meta.
+ *
+ * @return MetadataBag
+ */
+ public function getMetadataBag();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/AbstractSessionHandler.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/AbstractSessionHandler.php
new file mode 100644
index 0000000..6ae1355
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/AbstractSessionHandler.php
@@ -0,0 +1,168 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
+
+/**
+ * This abstract session handler provides a generic implementation
+ * of the PHP 7.0 SessionUpdateTimestampHandlerInterface,
+ * enabling strict and lazy session handling.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+abstract class AbstractSessionHandler implements \SessionHandlerInterface, \SessionUpdateTimestampHandlerInterface
+{
+ private $sessionName;
+ private $prefetchId;
+ private $prefetchData;
+ private $newSessionId;
+ private $igbinaryEmptyData;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function open($savePath, $sessionName)
+ {
+ $this->sessionName = $sessionName;
+ if (!headers_sent() && !ini_get('session.cache_limiter') && '0' !== ini_get('session.cache_limiter')) {
+ header(sprintf('Cache-Control: max-age=%d, private, must-revalidate', 60 * (int) ini_get('session.cache_expire')));
+ }
+
+ return true;
+ }
+
+ /**
+ * @param string $sessionId
+ *
+ * @return string
+ */
+ abstract protected function doRead($sessionId);
+
+ /**
+ * @param string $sessionId
+ * @param string $data
+ *
+ * @return bool
+ */
+ abstract protected function doWrite($sessionId, $data);
+
+ /**
+ * @param string $sessionId
+ *
+ * @return bool
+ */
+ abstract protected function doDestroy($sessionId);
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validateId($sessionId)
+ {
+ $this->prefetchData = $this->read($sessionId);
+ $this->prefetchId = $sessionId;
+
+ return '' !== $this->prefetchData;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function read($sessionId)
+ {
+ if (null !== $this->prefetchId) {
+ $prefetchId = $this->prefetchId;
+ $prefetchData = $this->prefetchData;
+ $this->prefetchId = $this->prefetchData = null;
+
+ if ($prefetchId === $sessionId || '' === $prefetchData) {
+ $this->newSessionId = '' === $prefetchData ? $sessionId : null;
+
+ return $prefetchData;
+ }
+ }
+
+ $data = $this->doRead($sessionId);
+ $this->newSessionId = '' === $data ? $sessionId : null;
+ if (\PHP_VERSION_ID < 70000) {
+ $this->prefetchData = $data;
+ }
+
+ return $data;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function write($sessionId, $data)
+ {
+ if (\PHP_VERSION_ID < 70000 && $this->prefetchData) {
+ $readData = $this->prefetchData;
+ $this->prefetchData = null;
+
+ if ($readData === $data) {
+ return $this->updateTimestamp($sessionId, $data);
+ }
+ }
+ if (null === $this->igbinaryEmptyData) {
+ // see https://github.com/igbinary/igbinary/issues/146
+ $this->igbinaryEmptyData = \function_exists('igbinary_serialize') ? igbinary_serialize(array()) : '';
+ }
+ if ('' === $data || $this->igbinaryEmptyData === $data) {
+ return $this->destroy($sessionId);
+ }
+ $this->newSessionId = null;
+
+ return $this->doWrite($sessionId, $data);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function destroy($sessionId)
+ {
+ if (\PHP_VERSION_ID < 70000) {
+ $this->prefetchData = null;
+ }
+ if (!headers_sent() && ini_get('session.use_cookies')) {
+ if (!$this->sessionName) {
+ throw new \LogicException(sprintf('Session name cannot be empty, did you forget to call "parent::open()" in "%s"?.', get_class($this)));
+ }
+ $sessionCookie = sprintf(' %s=', urlencode($this->sessionName));
+ $sessionCookieWithId = sprintf('%s%s;', $sessionCookie, urlencode($sessionId));
+ $sessionCookieFound = false;
+ $otherCookies = array();
+ foreach (headers_list() as $h) {
+ if (0 !== stripos($h, 'Set-Cookie:')) {
+ continue;
+ }
+ if (11 === strpos($h, $sessionCookie, 11)) {
+ $sessionCookieFound = true;
+
+ if (11 !== strpos($h, $sessionCookieWithId, 11)) {
+ $otherCookies[] = $h;
+ }
+ } else {
+ $otherCookies[] = $h;
+ }
+ }
+ if ($sessionCookieFound) {
+ header_remove('Set-Cookie');
+ foreach ($otherCookies as $h) {
+ header($h, false);
+ }
+ } else {
+ setcookie($this->sessionName, '', 0, ini_get('session.cookie_path'), ini_get('session.cookie_domain'), ini_get('session.cookie_secure'), ini_get('session.cookie_httponly'));
+ }
+ }
+
+ return $this->newSessionId === $sessionId || $this->doDestroy($sessionId);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/MemcacheSessionHandler.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/MemcacheSessionHandler.php
new file mode 100644
index 0000000..90726be
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/MemcacheSessionHandler.php
@@ -0,0 +1,120 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
+
+@trigger_error(sprintf('The class %s is deprecated since Symfony 3.4 and will be removed in 4.0. Use Symfony\Component\HttpFoundation\Session\Storage\Handler\MemcachedSessionHandler instead.', MemcacheSessionHandler::class), E_USER_DEPRECATED);
+
+/**
+ * @author Drak <drak@zikula.org>
+ *
+ * @deprecated since version 3.4, to be removed in 4.0. Use Symfony\Component\HttpFoundation\Session\Storage\Handler\MemcachedSessionHandler instead.
+ */
+class MemcacheSessionHandler implements \SessionHandlerInterface
+{
+ private $memcache;
+
+ /**
+ * @var int Time to live in seconds
+ */
+ private $ttl;
+
+ /**
+ * @var string Key prefix for shared environments
+ */
+ private $prefix;
+
+ /**
+ * Constructor.
+ *
+ * List of available options:
+ * * prefix: The prefix to use for the memcache keys in order to avoid collision
+ * * expiretime: The time to live in seconds
+ *
+ * @param \Memcache $memcache A \Memcache instance
+ * @param array $options An associative array of Memcache options
+ *
+ * @throws \InvalidArgumentException When unsupported options are passed
+ */
+ public function __construct(\Memcache $memcache, array $options = array())
+ {
+ if ($diff = array_diff(array_keys($options), array('prefix', 'expiretime'))) {
+ throw new \InvalidArgumentException(sprintf(
+ 'The following options are not supported "%s"', implode(', ', $diff)
+ ));
+ }
+
+ $this->memcache = $memcache;
+ $this->ttl = isset($options['expiretime']) ? (int) $options['expiretime'] : 86400;
+ $this->prefix = isset($options['prefix']) ? $options['prefix'] : 'sf2s';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function open($savePath, $sessionName)
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function close()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function read($sessionId)
+ {
+ return $this->memcache->get($this->prefix.$sessionId) ?: '';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function write($sessionId, $data)
+ {
+ return $this->memcache->set($this->prefix.$sessionId, $data, 0, time() + $this->ttl);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function destroy($sessionId)
+ {
+ $this->memcache->delete($this->prefix.$sessionId);
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function gc($maxlifetime)
+ {
+ // not required here because memcache will auto expire the records anyhow.
+ return true;
+ }
+
+ /**
+ * Return a Memcache instance.
+ *
+ * @return \Memcache
+ */
+ protected function getMemcache()
+ {
+ return $this->memcache;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/MemcachedSessionHandler.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/MemcachedSessionHandler.php
new file mode 100644
index 0000000..dd37eae
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/MemcachedSessionHandler.php
@@ -0,0 +1,124 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
+
+/**
+ * Memcached based session storage handler based on the Memcached class
+ * provided by the PHP memcached extension.
+ *
+ * @see http://php.net/memcached
+ *
+ * @author Drak <drak@zikula.org>
+ */
+class MemcachedSessionHandler extends AbstractSessionHandler
+{
+ private $memcached;
+
+ /**
+ * @var int Time to live in seconds
+ */
+ private $ttl;
+
+ /**
+ * @var string Key prefix for shared environments
+ */
+ private $prefix;
+
+ /**
+ * Constructor.
+ *
+ * List of available options:
+ * * prefix: The prefix to use for the memcached keys in order to avoid collision
+ * * expiretime: The time to live in seconds.
+ *
+ * @param \Memcached $memcached A \Memcached instance
+ * @param array $options An associative array of Memcached options
+ *
+ * @throws \InvalidArgumentException When unsupported options are passed
+ */
+ public function __construct(\Memcached $memcached, array $options = array())
+ {
+ $this->memcached = $memcached;
+
+ if ($diff = array_diff(array_keys($options), array('prefix', 'expiretime'))) {
+ throw new \InvalidArgumentException(sprintf(
+ 'The following options are not supported "%s"', implode(', ', $diff)
+ ));
+ }
+
+ $this->ttl = isset($options['expiretime']) ? (int) $options['expiretime'] : 86400;
+ $this->prefix = isset($options['prefix']) ? $options['prefix'] : 'sf2s';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function close()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doRead($sessionId)
+ {
+ return $this->memcached->get($this->prefix.$sessionId) ?: '';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function updateTimestamp($sessionId, $data)
+ {
+ $this->memcached->touch($this->prefix.$sessionId, time() + $this->ttl);
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doWrite($sessionId, $data)
+ {
+ return $this->memcached->set($this->prefix.$sessionId, $data, time() + $this->ttl);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doDestroy($sessionId)
+ {
+ $result = $this->memcached->delete($this->prefix.$sessionId);
+
+ return $result || \Memcached::RES_NOTFOUND == $this->memcached->getResultCode();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function gc($maxlifetime)
+ {
+ // not required here because memcached will auto expire the records anyhow.
+ return true;
+ }
+
+ /**
+ * Return a Memcached instance.
+ *
+ * @return \Memcached
+ */
+ protected function getMemcached()
+ {
+ return $this->memcached;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/MongoDbSessionHandler.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/MongoDbSessionHandler.php
new file mode 100644
index 0000000..7d3fa21
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/MongoDbSessionHandler.php
@@ -0,0 +1,255 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
+
+/**
+ * Session handler using the mongodb/mongodb package and MongoDB driver extension.
+ *
+ * @author Markus Bachmann <markus.bachmann@bachi.biz>
+ *
+ * @see https://packagist.org/packages/mongodb/mongodb
+ * @see http://php.net/manual/en/set.mongodb.php
+ */
+class MongoDbSessionHandler extends AbstractSessionHandler
+{
+ private $mongo;
+
+ /**
+ * @var \MongoCollection
+ */
+ private $collection;
+
+ /**
+ * @var array
+ */
+ private $options;
+
+ /**
+ * Constructor.
+ *
+ * List of available options:
+ * * database: The name of the database [required]
+ * * collection: The name of the collection [required]
+ * * id_field: The field name for storing the session id [default: _id]
+ * * data_field: The field name for storing the session data [default: data]
+ * * time_field: The field name for storing the timestamp [default: time]
+ * * expiry_field: The field name for storing the expiry-timestamp [default: expires_at].
+ *
+ * It is strongly recommended to put an index on the `expiry_field` for
+ * garbage-collection. Alternatively it's possible to automatically expire
+ * the sessions in the database as described below:
+ *
+ * A TTL collections can be used on MongoDB 2.2+ to cleanup expired sessions
+ * automatically. Such an index can for example look like this:
+ *
+ * db.<session-collection>.ensureIndex(
+ * { "<expiry-field>": 1 },
+ * { "expireAfterSeconds": 0 }
+ * )
+ *
+ * More details on: http://docs.mongodb.org/manual/tutorial/expire-data/
+ *
+ * If you use such an index, you can drop `gc_probability` to 0 since
+ * no garbage-collection is required.
+ *
+ * @param \MongoDB\Client $mongo A MongoDB\Client instance
+ * @param array $options An associative array of field options
+ *
+ * @throws \InvalidArgumentException When MongoClient or Mongo instance not provided
+ * @throws \InvalidArgumentException When "database" or "collection" not provided
+ */
+ public function __construct($mongo, array $options)
+ {
+ if ($mongo instanceof \MongoClient || $mongo instanceof \Mongo) {
+ @trigger_error(sprintf('Using %s with the legacy mongo extension is deprecated as of 3.4 and will be removed in 4.0. Use it with the mongodb/mongodb package and ext-mongodb instead.', __CLASS__), E_USER_DEPRECATED);
+ }
+
+ if (!($mongo instanceof \MongoDB\Client || $mongo instanceof \MongoClient || $mongo instanceof \Mongo)) {
+ throw new \InvalidArgumentException('MongoClient or Mongo instance required');
+ }
+
+ if (!isset($options['database']) || !isset($options['collection'])) {
+ throw new \InvalidArgumentException('You must provide the "database" and "collection" option for MongoDBSessionHandler');
+ }
+
+ $this->mongo = $mongo;
+
+ $this->options = array_merge(array(
+ 'id_field' => '_id',
+ 'data_field' => 'data',
+ 'time_field' => 'time',
+ 'expiry_field' => 'expires_at',
+ ), $options);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function close()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doDestroy($sessionId)
+ {
+ $methodName = $this->mongo instanceof \MongoDB\Client ? 'deleteOne' : 'remove';
+
+ $this->getCollection()->$methodName(array(
+ $this->options['id_field'] => $sessionId,
+ ));
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function gc($maxlifetime)
+ {
+ $methodName = $this->mongo instanceof \MongoDB\Client ? 'deleteMany' : 'remove';
+
+ $this->getCollection()->$methodName(array(
+ $this->options['expiry_field'] => array('$lt' => $this->createDateTime()),
+ ));
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doWrite($sessionId, $data)
+ {
+ $expiry = $this->createDateTime(time() + (int) ini_get('session.gc_maxlifetime'));
+
+ $fields = array(
+ $this->options['time_field'] => $this->createDateTime(),
+ $this->options['expiry_field'] => $expiry,
+ );
+
+ $options = array('upsert' => true);
+
+ if ($this->mongo instanceof \MongoDB\Client) {
+ $fields[$this->options['data_field']] = new \MongoDB\BSON\Binary($data, \MongoDB\BSON\Binary::TYPE_OLD_BINARY);
+ } else {
+ $fields[$this->options['data_field']] = new \MongoBinData($data, \MongoBinData::BYTE_ARRAY);
+ $options['multiple'] = false;
+ }
+
+ $methodName = $this->mongo instanceof \MongoDB\Client ? 'updateOne' : 'update';
+
+ $this->getCollection()->$methodName(
+ array($this->options['id_field'] => $sessionId),
+ array('$set' => $fields),
+ $options
+ );
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function updateTimestamp($sessionId, $data)
+ {
+ $expiry = $this->createDateTime(time() + (int) ini_get('session.gc_maxlifetime'));
+
+ if ($this->mongo instanceof \MongoDB\Client) {
+ $methodName = 'updateOne';
+ $options = array();
+ } else {
+ $methodName = 'update';
+ $options = array('multiple' => false);
+ }
+
+ $this->getCollection()->$methodName(
+ array($this->options['id_field'] => $sessionId),
+ array('$set' => array(
+ $this->options['time_field'] => $this->createDateTime(),
+ $this->options['expiry_field'] => $expiry,
+ )),
+ $options
+ );
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doRead($sessionId)
+ {
+ $dbData = $this->getCollection()->findOne(array(
+ $this->options['id_field'] => $sessionId,
+ $this->options['expiry_field'] => array('$gte' => $this->createDateTime()),
+ ));
+
+ if (null === $dbData) {
+ return '';
+ }
+
+ if ($dbData[$this->options['data_field']] instanceof \MongoDB\BSON\Binary) {
+ return $dbData[$this->options['data_field']]->getData();
+ }
+
+ return $dbData[$this->options['data_field']]->bin;
+ }
+
+ /**
+ * Return a "MongoCollection" instance.
+ *
+ * @return \MongoCollection
+ */
+ private function getCollection()
+ {
+ if (null === $this->collection) {
+ $this->collection = $this->mongo->selectCollection($this->options['database'], $this->options['collection']);
+ }
+
+ return $this->collection;
+ }
+
+ /**
+ * Return a Mongo instance.
+ *
+ * @return \Mongo|\MongoClient|\MongoDB\Client
+ */
+ protected function getMongo()
+ {
+ return $this->mongo;
+ }
+
+ /**
+ * Create a date object using the class appropriate for the current mongo connection.
+ *
+ * Return an instance of a MongoDate or \MongoDB\BSON\UTCDateTime
+ *
+ * @param int $seconds An integer representing UTC seconds since Jan 1 1970. Defaults to now.
+ *
+ * @return \MongoDate|\MongoDB\BSON\UTCDateTime
+ */
+ private function createDateTime($seconds = null)
+ {
+ if (null === $seconds) {
+ $seconds = time();
+ }
+
+ if ($this->mongo instanceof \MongoDB\Client) {
+ return new \MongoDB\BSON\UTCDateTime($seconds * 1000);
+ }
+
+ return new \MongoDate($seconds);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/NativeFileSessionHandler.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/NativeFileSessionHandler.php
new file mode 100644
index 0000000..4e9704b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/NativeFileSessionHandler.php
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
+
+/**
+ * Native session handler using PHP's built in file storage.
+ *
+ * @author Drak <drak@zikula.org>
+ */
+class NativeFileSessionHandler extends NativeSessionHandler
+{
+ /**
+ * @param string $savePath Path of directory to save session files
+ * Default null will leave setting as defined by PHP.
+ * '/path', 'N;/path', or 'N;octal-mode;/path
+ *
+ * @see http://php.net/session.configuration.php#ini.session.save-path for further details.
+ *
+ * @throws \InvalidArgumentException On invalid $savePath
+ * @throws \RuntimeException When failing to create the save directory
+ */
+ public function __construct($savePath = null)
+ {
+ if (null === $savePath) {
+ $savePath = ini_get('session.save_path');
+ }
+
+ $baseDir = $savePath;
+
+ if ($count = substr_count($savePath, ';')) {
+ if ($count > 2) {
+ throw new \InvalidArgumentException(sprintf('Invalid argument $savePath \'%s\'', $savePath));
+ }
+
+ // characters after last ';' are the path
+ $baseDir = ltrim(strrchr($savePath, ';'), ';');
+ }
+
+ if ($baseDir && !is_dir($baseDir) && !@mkdir($baseDir, 0777, true) && !is_dir($baseDir)) {
+ throw new \RuntimeException(sprintf('Session Storage was not able to create directory "%s"', $baseDir));
+ }
+
+ ini_set('session.save_path', $savePath);
+ ini_set('session.save_handler', 'files');
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/NativeSessionHandler.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/NativeSessionHandler.php
new file mode 100644
index 0000000..9be4528
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/NativeSessionHandler.php
@@ -0,0 +1,24 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
+
+/**
+ * @deprecated since version 3.4, to be removed in 4.0. Use \SessionHandler instead.
+ * @see http://php.net/sessionhandler
+ */
+class NativeSessionHandler extends \SessionHandler
+{
+ public function __construct()
+ {
+ @trigger_error('The '.__NAMESPACE__.'\NativeSessionHandler class is deprecated since Symfony 3.4 and will be removed in 4.0. Use the \SessionHandler class instead.', E_USER_DEPRECATED);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/NullSessionHandler.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/NullSessionHandler.php
new file mode 100644
index 0000000..8d19315
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/NullSessionHandler.php
@@ -0,0 +1,76 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
+
+/**
+ * Can be used in unit testing or in a situations where persisted sessions are not desired.
+ *
+ * @author Drak <drak@zikula.org>
+ */
+class NullSessionHandler extends AbstractSessionHandler
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function close()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validateId($sessionId)
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doRead($sessionId)
+ {
+ return '';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function updateTimestamp($sessionId, $data)
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doWrite($sessionId, $data)
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doDestroy($sessionId)
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function gc($maxlifetime)
+ {
+ return true;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php
new file mode 100644
index 0000000..c8737be
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php
@@ -0,0 +1,910 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
+
+/**
+ * Session handler using a PDO connection to read and write data.
+ *
+ * It works with MySQL, PostgreSQL, Oracle, SQL Server and SQLite and implements
+ * different locking strategies to handle concurrent access to the same session.
+ * Locking is necessary to prevent loss of data due to race conditions and to keep
+ * the session data consistent between read() and write(). With locking, requests
+ * for the same session will wait until the other one finished writing. For this
+ * reason it's best practice to close a session as early as possible to improve
+ * concurrency. PHPs internal files session handler also implements locking.
+ *
+ * Attention: Since SQLite does not support row level locks but locks the whole database,
+ * it means only one session can be accessed at a time. Even different sessions would wait
+ * for another to finish. So saving session in SQLite should only be considered for
+ * development or prototypes.
+ *
+ * Session data is a binary string that can contain non-printable characters like the null byte.
+ * For this reason it must be saved in a binary column in the database like BLOB in MySQL.
+ * Saving it in a character column could corrupt the data. You can use createTable()
+ * to initialize a correctly defined table.
+ *
+ * @see http://php.net/sessionhandlerinterface
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Michael Williams <michael.williams@funsational.com>
+ * @author Tobias Schultze <http://tobion.de>
+ */
+class PdoSessionHandler extends AbstractSessionHandler
+{
+ /**
+ * No locking is done. This means sessions are prone to loss of data due to
+ * race conditions of concurrent requests to the same session. The last session
+ * write will win in this case. It might be useful when you implement your own
+ * logic to deal with this like an optimistic approach.
+ */
+ const LOCK_NONE = 0;
+
+ /**
+ * Creates an application-level lock on a session. The disadvantage is that the
+ * lock is not enforced by the database and thus other, unaware parts of the
+ * application could still concurrently modify the session. The advantage is it
+ * does not require a transaction.
+ * This mode is not available for SQLite and not yet implemented for oci and sqlsrv.
+ */
+ const LOCK_ADVISORY = 1;
+
+ /**
+ * Issues a real row lock. Since it uses a transaction between opening and
+ * closing a session, you have to be careful when you use same database connection
+ * that you also use for your application logic. This mode is the default because
+ * it's the only reliable solution across DBMSs.
+ */
+ const LOCK_TRANSACTIONAL = 2;
+
+ /**
+ * @var \PDO|null PDO instance or null when not connected yet
+ */
+ private $pdo;
+
+ /**
+ * @var string|null|false DSN string or null for session.save_path or false when lazy connection disabled
+ */
+ private $dsn = false;
+
+ /**
+ * @var string Database driver
+ */
+ private $driver;
+
+ /**
+ * @var string Table name
+ */
+ private $table = 'sessions';
+
+ /**
+ * @var string Column for session id
+ */
+ private $idCol = 'sess_id';
+
+ /**
+ * @var string Column for session data
+ */
+ private $dataCol = 'sess_data';
+
+ /**
+ * @var string Column for lifetime
+ */
+ private $lifetimeCol = 'sess_lifetime';
+
+ /**
+ * @var string Column for timestamp
+ */
+ private $timeCol = 'sess_time';
+
+ /**
+ * @var string Username when lazy-connect
+ */
+ private $username = '';
+
+ /**
+ * @var string Password when lazy-connect
+ */
+ private $password = '';
+
+ /**
+ * @var array Connection options when lazy-connect
+ */
+ private $connectionOptions = array();
+
+ /**
+ * @var int The strategy for locking, see constants
+ */
+ private $lockMode = self::LOCK_TRANSACTIONAL;
+
+ /**
+ * It's an array to support multiple reads before closing which is manual, non-standard usage.
+ *
+ * @var \PDOStatement[] An array of statements to release advisory locks
+ */
+ private $unlockStatements = array();
+
+ /**
+ * @var bool True when the current session exists but expired according to session.gc_maxlifetime
+ */
+ private $sessionExpired = false;
+
+ /**
+ * @var bool Whether a transaction is active
+ */
+ private $inTransaction = false;
+
+ /**
+ * @var bool Whether gc() has been called
+ */
+ private $gcCalled = false;
+
+ /**
+ * You can either pass an existing database connection as PDO instance or
+ * pass a DSN string that will be used to lazy-connect to the database
+ * when the session is actually used. Furthermore it's possible to pass null
+ * which will then use the session.save_path ini setting as PDO DSN parameter.
+ *
+ * List of available options:
+ * * db_table: The name of the table [default: sessions]
+ * * db_id_col: The column where to store the session id [default: sess_id]
+ * * db_data_col: The column where to store the session data [default: sess_data]
+ * * db_lifetime_col: The column where to store the lifetime [default: sess_lifetime]
+ * * db_time_col: The column where to store the timestamp [default: sess_time]
+ * * db_username: The username when lazy-connect [default: '']
+ * * db_password: The password when lazy-connect [default: '']
+ * * db_connection_options: An array of driver-specific connection options [default: array()]
+ * * lock_mode: The strategy for locking, see constants [default: LOCK_TRANSACTIONAL]
+ *
+ * @param \PDO|string|null $pdoOrDsn A \PDO instance or DSN string or URL string or null
+ * @param array $options An associative array of options
+ *
+ * @throws \InvalidArgumentException When PDO error mode is not PDO::ERRMODE_EXCEPTION
+ */
+ public function __construct($pdoOrDsn = null, array $options = array())
+ {
+ if ($pdoOrDsn instanceof \PDO) {
+ if (\PDO::ERRMODE_EXCEPTION !== $pdoOrDsn->getAttribute(\PDO::ATTR_ERRMODE)) {
+ throw new \InvalidArgumentException(sprintf('"%s" requires PDO error mode attribute be set to throw Exceptions (i.e. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION))', __CLASS__));
+ }
+
+ $this->pdo = $pdoOrDsn;
+ $this->driver = $this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME);
+ } elseif (is_string($pdoOrDsn) && false !== strpos($pdoOrDsn, '://')) {
+ $this->dsn = $this->buildDsnFromUrl($pdoOrDsn);
+ } else {
+ $this->dsn = $pdoOrDsn;
+ }
+
+ $this->table = isset($options['db_table']) ? $options['db_table'] : $this->table;
+ $this->idCol = isset($options['db_id_col']) ? $options['db_id_col'] : $this->idCol;
+ $this->dataCol = isset($options['db_data_col']) ? $options['db_data_col'] : $this->dataCol;
+ $this->lifetimeCol = isset($options['db_lifetime_col']) ? $options['db_lifetime_col'] : $this->lifetimeCol;
+ $this->timeCol = isset($options['db_time_col']) ? $options['db_time_col'] : $this->timeCol;
+ $this->username = isset($options['db_username']) ? $options['db_username'] : $this->username;
+ $this->password = isset($options['db_password']) ? $options['db_password'] : $this->password;
+ $this->connectionOptions = isset($options['db_connection_options']) ? $options['db_connection_options'] : $this->connectionOptions;
+ $this->lockMode = isset($options['lock_mode']) ? $options['lock_mode'] : $this->lockMode;
+ }
+
+ /**
+ * Creates the table to store sessions which can be called once for setup.
+ *
+ * Session ID is saved in a column of maximum length 128 because that is enough even
+ * for a 512 bit configured session.hash_function like Whirlpool. Session data is
+ * saved in a BLOB. One could also use a shorter inlined varbinary column
+ * if one was sure the data fits into it.
+ *
+ * @throws \PDOException When the table already exists
+ * @throws \DomainException When an unsupported PDO driver is used
+ */
+ public function createTable()
+ {
+ // connect if we are not yet
+ $this->getConnection();
+
+ switch ($this->driver) {
+ case 'mysql':
+ // We use varbinary for the ID column because it prevents unwanted conversions:
+ // - character set conversions between server and client
+ // - trailing space removal
+ // - case-insensitivity
+ // - language processing like é == e
+ $sql = "CREATE TABLE $this->table ($this->idCol VARBINARY(128) NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol MEDIUMINT NOT NULL, $this->timeCol INTEGER UNSIGNED NOT NULL) COLLATE utf8_bin, ENGINE = InnoDB";
+ break;
+ case 'sqlite':
+ $sql = "CREATE TABLE $this->table ($this->idCol TEXT NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol INTEGER NOT NULL, $this->timeCol INTEGER NOT NULL)";
+ break;
+ case 'pgsql':
+ $sql = "CREATE TABLE $this->table ($this->idCol VARCHAR(128) NOT NULL PRIMARY KEY, $this->dataCol BYTEA NOT NULL, $this->lifetimeCol INTEGER NOT NULL, $this->timeCol INTEGER NOT NULL)";
+ break;
+ case 'oci':
+ $sql = "CREATE TABLE $this->table ($this->idCol VARCHAR2(128) NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol INTEGER NOT NULL, $this->timeCol INTEGER NOT NULL)";
+ break;
+ case 'sqlsrv':
+ $sql = "CREATE TABLE $this->table ($this->idCol VARCHAR(128) NOT NULL PRIMARY KEY, $this->dataCol VARBINARY(MAX) NOT NULL, $this->lifetimeCol INTEGER NOT NULL, $this->timeCol INTEGER NOT NULL)";
+ break;
+ default:
+ throw new \DomainException(sprintf('Creating the session table is currently not implemented for PDO driver "%s".', $this->driver));
+ }
+
+ try {
+ $this->pdo->exec($sql);
+ } catch (\PDOException $e) {
+ $this->rollback();
+
+ throw $e;
+ }
+ }
+
+ /**
+ * Returns true when the current session exists but expired according to session.gc_maxlifetime.
+ *
+ * Can be used to distinguish between a new session and one that expired due to inactivity.
+ *
+ * @return bool Whether current session expired
+ */
+ public function isSessionExpired()
+ {
+ return $this->sessionExpired;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function open($savePath, $sessionName)
+ {
+ $this->sessionExpired = false;
+
+ if (null === $this->pdo) {
+ $this->connect($this->dsn ?: $savePath);
+ }
+
+ return parent::open($savePath, $sessionName);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function read($sessionId)
+ {
+ try {
+ return parent::read($sessionId);
+ } catch (\PDOException $e) {
+ $this->rollback();
+
+ throw $e;
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function gc($maxlifetime)
+ {
+ // We delay gc() to close() so that it is executed outside the transactional and blocking read-write process.
+ // This way, pruning expired sessions does not block them from being started while the current session is used.
+ $this->gcCalled = true;
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doDestroy($sessionId)
+ {
+ // delete the record associated with this id
+ $sql = "DELETE FROM $this->table WHERE $this->idCol = :id";
+
+ try {
+ $stmt = $this->pdo->prepare($sql);
+ $stmt->bindParam(':id', $sessionId, \PDO::PARAM_STR);
+ $stmt->execute();
+ } catch (\PDOException $e) {
+ $this->rollback();
+
+ throw $e;
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doWrite($sessionId, $data)
+ {
+ $maxlifetime = (int) ini_get('session.gc_maxlifetime');
+
+ try {
+ // We use a single MERGE SQL query when supported by the database.
+ $mergeStmt = $this->getMergeStatement($sessionId, $data, $maxlifetime);
+ if (null !== $mergeStmt) {
+ $mergeStmt->execute();
+
+ return true;
+ }
+
+ $updateStmt = $this->getUpdateStatement($sessionId, $data, $maxlifetime);
+ $updateStmt->execute();
+
+ // When MERGE is not supported, like in Postgres < 9.5, we have to use this approach that can result in
+ // duplicate key errors when the same session is written simultaneously (given the LOCK_NONE behavior).
+ // We can just catch such an error and re-execute the update. This is similar to a serializable
+ // transaction with retry logic on serialization failures but without the overhead and without possible
+ // false positives due to longer gap locking.
+ if (!$updateStmt->rowCount()) {
+ try {
+ $insertStmt = $this->getInsertStatement($sessionId, $data, $maxlifetime);
+ $insertStmt->execute();
+ } catch (\PDOException $e) {
+ // Handle integrity violation SQLSTATE 23000 (or a subclass like 23505 in Postgres) for duplicate keys
+ if (0 === strpos($e->getCode(), '23')) {
+ $updateStmt->execute();
+ } else {
+ throw $e;
+ }
+ }
+ }
+ } catch (\PDOException $e) {
+ $this->rollback();
+
+ throw $e;
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function updateTimestamp($sessionId, $data)
+ {
+ $maxlifetime = (int) ini_get('session.gc_maxlifetime');
+
+ try {
+ $updateStmt = $this->pdo->prepare(
+ "UPDATE $this->table SET $this->lifetimeCol = :lifetime, $this->timeCol = :time WHERE $this->idCol = :id"
+ );
+ $updateStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR);
+ $updateStmt->bindParam(':lifetime', $maxlifetime, \PDO::PARAM_INT);
+ $updateStmt->bindValue(':time', time(), \PDO::PARAM_INT);
+ $updateStmt->execute();
+ } catch (\PDOException $e) {
+ $this->rollback();
+
+ throw $e;
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function close()
+ {
+ $this->commit();
+
+ while ($unlockStmt = array_shift($this->unlockStatements)) {
+ $unlockStmt->execute();
+ }
+
+ if ($this->gcCalled) {
+ $this->gcCalled = false;
+
+ // delete the session records that have expired
+ if ('mysql' === $this->driver) {
+ $sql = "DELETE FROM $this->table WHERE $this->lifetimeCol + $this->timeCol < :time";
+ } else {
+ $sql = "DELETE FROM $this->table WHERE $this->lifetimeCol < :time - $this->timeCol";
+ }
+
+ $stmt = $this->pdo->prepare($sql);
+ $stmt->bindValue(':time', time(), \PDO::PARAM_INT);
+ $stmt->execute();
+ }
+
+ if (false !== $this->dsn) {
+ $this->pdo = null; // only close lazy-connection
+ }
+
+ return true;
+ }
+
+ /**
+ * Lazy-connects to the database.
+ *
+ * @param string $dsn DSN string
+ */
+ private function connect($dsn)
+ {
+ $this->pdo = new \PDO($dsn, $this->username, $this->password, $this->connectionOptions);
+ $this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+ $this->driver = $this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME);
+ }
+
+ /**
+ * Builds a PDO DSN from a URL-like connection string.
+ *
+ * @param string $dsnOrUrl
+ *
+ * @return string
+ *
+ * @todo implement missing support for oci DSN (which look totally different from other PDO ones)
+ */
+ private function buildDsnFromUrl($dsnOrUrl)
+ {
+ // (pdo_)?sqlite3?:///... => (pdo_)?sqlite3?://localhost/... or else the URL will be invalid
+ $url = preg_replace('#^((?:pdo_)?sqlite3?):///#', '$1://localhost/', $dsnOrUrl);
+
+ $params = parse_url($url);
+
+ if (false === $params) {
+ return $dsnOrUrl; // If the URL is not valid, let's assume it might be a DSN already.
+ }
+
+ $params = array_map('rawurldecode', $params);
+
+ // Override the default username and password. Values passed through options will still win over these in the constructor.
+ if (isset($params['user'])) {
+ $this->username = $params['user'];
+ }
+
+ if (isset($params['pass'])) {
+ $this->password = $params['pass'];
+ }
+
+ if (!isset($params['scheme'])) {
+ throw new \InvalidArgumentException('URLs without scheme are not supported to configure the PdoSessionHandler');
+ }
+
+ $driverAliasMap = array(
+ 'mssql' => 'sqlsrv',
+ 'mysql2' => 'mysql', // Amazon RDS, for some weird reason
+ 'postgres' => 'pgsql',
+ 'postgresql' => 'pgsql',
+ 'sqlite3' => 'sqlite',
+ );
+
+ $driver = isset($driverAliasMap[$params['scheme']]) ? $driverAliasMap[$params['scheme']] : $params['scheme'];
+
+ // Doctrine DBAL supports passing its internal pdo_* driver names directly too (allowing both dashes and underscores). This allows supporting the same here.
+ if (0 === strpos($driver, 'pdo_') || 0 === strpos($driver, 'pdo-')) {
+ $driver = substr($driver, 4);
+ }
+
+ switch ($driver) {
+ case 'mysql':
+ case 'pgsql':
+ $dsn = $driver.':';
+
+ if (isset($params['host']) && '' !== $params['host']) {
+ $dsn .= 'host='.$params['host'].';';
+ }
+
+ if (isset($params['port']) && '' !== $params['port']) {
+ $dsn .= 'port='.$params['port'].';';
+ }
+
+ if (isset($params['path'])) {
+ $dbName = substr($params['path'], 1); // Remove the leading slash
+ $dsn .= 'dbname='.$dbName.';';
+ }
+
+ return $dsn;
+
+ case 'sqlite':
+ return 'sqlite:'.substr($params['path'], 1);
+
+ case 'sqlsrv':
+ $dsn = 'sqlsrv:server=';
+
+ if (isset($params['host'])) {
+ $dsn .= $params['host'];
+ }
+
+ if (isset($params['port']) && '' !== $params['port']) {
+ $dsn .= ','.$params['port'];
+ }
+
+ if (isset($params['path'])) {
+ $dbName = substr($params['path'], 1); // Remove the leading slash
+ $dsn .= ';Database='.$dbName;
+ }
+
+ return $dsn;
+
+ default:
+ throw new \InvalidArgumentException(sprintf('The scheme "%s" is not supported by the PdoSessionHandler URL configuration. Pass a PDO DSN directly.', $params['scheme']));
+ }
+ }
+
+ /**
+ * Helper method to begin a transaction.
+ *
+ * Since SQLite does not support row level locks, we have to acquire a reserved lock
+ * on the database immediately. Because of https://bugs.php.net/42766 we have to create
+ * such a transaction manually which also means we cannot use PDO::commit or
+ * PDO::rollback or PDO::inTransaction for SQLite.
+ *
+ * Also MySQLs default isolation, REPEATABLE READ, causes deadlock for different sessions
+ * due to http://www.mysqlperformanceblog.com/2013/12/12/one-more-innodb-gap-lock-to-avoid/ .
+ * So we change it to READ COMMITTED.
+ */
+ private function beginTransaction()
+ {
+ if (!$this->inTransaction) {
+ if ('sqlite' === $this->driver) {
+ $this->pdo->exec('BEGIN IMMEDIATE TRANSACTION');
+ } else {
+ if ('mysql' === $this->driver) {
+ $this->pdo->exec('SET TRANSACTION ISOLATION LEVEL READ COMMITTED');
+ }
+ $this->pdo->beginTransaction();
+ }
+ $this->inTransaction = true;
+ }
+ }
+
+ /**
+ * Helper method to commit a transaction.
+ */
+ private function commit()
+ {
+ if ($this->inTransaction) {
+ try {
+ // commit read-write transaction which also releases the lock
+ if ('sqlite' === $this->driver) {
+ $this->pdo->exec('COMMIT');
+ } else {
+ $this->pdo->commit();
+ }
+ $this->inTransaction = false;
+ } catch (\PDOException $e) {
+ $this->rollback();
+
+ throw $e;
+ }
+ }
+ }
+
+ /**
+ * Helper method to rollback a transaction.
+ */
+ private function rollback()
+ {
+ // We only need to rollback if we are in a transaction. Otherwise the resulting
+ // error would hide the real problem why rollback was called. We might not be
+ // in a transaction when not using the transactional locking behavior or when
+ // two callbacks (e.g. destroy and write) are invoked that both fail.
+ if ($this->inTransaction) {
+ if ('sqlite' === $this->driver) {
+ $this->pdo->exec('ROLLBACK');
+ } else {
+ $this->pdo->rollBack();
+ }
+ $this->inTransaction = false;
+ }
+ }
+
+ /**
+ * Reads the session data in respect to the different locking strategies.
+ *
+ * We need to make sure we do not return session data that is already considered garbage according
+ * to the session.gc_maxlifetime setting because gc() is called after read() and only sometimes.
+ *
+ * @param string $sessionId Session ID
+ *
+ * @return string The session data
+ */
+ protected function doRead($sessionId)
+ {
+ if (self::LOCK_ADVISORY === $this->lockMode) {
+ $this->unlockStatements[] = $this->doAdvisoryLock($sessionId);
+ }
+
+ $selectSql = $this->getSelectSql();
+ $selectStmt = $this->pdo->prepare($selectSql);
+ $selectStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR);
+
+ do {
+ $selectStmt->execute();
+ $sessionRows = $selectStmt->fetchAll(\PDO::FETCH_NUM);
+
+ if ($sessionRows) {
+ if ($sessionRows[0][1] + $sessionRows[0][2] < time()) {
+ $this->sessionExpired = true;
+
+ return '';
+ }
+
+ return is_resource($sessionRows[0][0]) ? stream_get_contents($sessionRows[0][0]) : $sessionRows[0][0];
+ }
+
+ if (!ini_get('session.use_strict_mode') && self::LOCK_TRANSACTIONAL === $this->lockMode && 'sqlite' !== $this->driver) {
+ // In strict mode, session fixation is not possible: new sessions always start with a unique
+ // random id, so that concurrency is not possible and this code path can be skipped.
+ // Exclusive-reading of non-existent rows does not block, so we need to do an insert to block
+ // until other connections to the session are committed.
+ try {
+ $insertStmt = $this->getInsertStatement($sessionId, '', 0);
+ $insertStmt->execute();
+ } catch (\PDOException $e) {
+ // Catch duplicate key error because other connection created the session already.
+ // It would only not be the case when the other connection destroyed the session.
+ if (0 === strpos($e->getCode(), '23')) {
+ // Retrieve finished session data written by concurrent connection by restarting the loop.
+ // We have to start a new transaction as a failed query will mark the current transaction as
+ // aborted in PostgreSQL and disallow further queries within it.
+ $this->rollback();
+ $this->beginTransaction();
+ continue;
+ }
+
+ throw $e;
+ }
+ }
+
+ return '';
+ } while (true);
+ }
+
+ /**
+ * Executes an application-level lock on the database.
+ *
+ * @param string $sessionId Session ID
+ *
+ * @return \PDOStatement The statement that needs to be executed later to release the lock
+ *
+ * @throws \DomainException When an unsupported PDO driver is used
+ *
+ * @todo implement missing advisory locks
+ * - for oci using DBMS_LOCK.REQUEST
+ * - for sqlsrv using sp_getapplock with LockOwner = Session
+ */
+ private function doAdvisoryLock($sessionId)
+ {
+ switch ($this->driver) {
+ case 'mysql':
+ // should we handle the return value? 0 on timeout, null on error
+ // we use a timeout of 50 seconds which is also the default for innodb_lock_wait_timeout
+ $stmt = $this->pdo->prepare('SELECT GET_LOCK(:key, 50)');
+ $stmt->bindValue(':key', $sessionId, \PDO::PARAM_STR);
+ $stmt->execute();
+
+ $releaseStmt = $this->pdo->prepare('DO RELEASE_LOCK(:key)');
+ $releaseStmt->bindValue(':key', $sessionId, \PDO::PARAM_STR);
+
+ return $releaseStmt;
+ case 'pgsql':
+ // Obtaining an exclusive session level advisory lock requires an integer key.
+ // When session.sid_bits_per_character > 4, the session id can contain non-hex-characters.
+ // So we cannot just use hexdec().
+ if (4 === \PHP_INT_SIZE) {
+ $sessionInt1 = $this->convertStringToInt($sessionId);
+ $sessionInt2 = $this->convertStringToInt(substr($sessionId, 4, 4));
+
+ $stmt = $this->pdo->prepare('SELECT pg_advisory_lock(:key1, :key2)');
+ $stmt->bindValue(':key1', $sessionInt1, \PDO::PARAM_INT);
+ $stmt->bindValue(':key2', $sessionInt2, \PDO::PARAM_INT);
+ $stmt->execute();
+
+ $releaseStmt = $this->pdo->prepare('SELECT pg_advisory_unlock(:key1, :key2)');
+ $releaseStmt->bindValue(':key1', $sessionInt1, \PDO::PARAM_INT);
+ $releaseStmt->bindValue(':key2', $sessionInt2, \PDO::PARAM_INT);
+ } else {
+ $sessionBigInt = $this->convertStringToInt($sessionId);
+
+ $stmt = $this->pdo->prepare('SELECT pg_advisory_lock(:key)');
+ $stmt->bindValue(':key', $sessionBigInt, \PDO::PARAM_INT);
+ $stmt->execute();
+
+ $releaseStmt = $this->pdo->prepare('SELECT pg_advisory_unlock(:key)');
+ $releaseStmt->bindValue(':key', $sessionBigInt, \PDO::PARAM_INT);
+ }
+
+ return $releaseStmt;
+ case 'sqlite':
+ throw new \DomainException('SQLite does not support advisory locks.');
+ default:
+ throw new \DomainException(sprintf('Advisory locks are currently not implemented for PDO driver "%s".', $this->driver));
+ }
+ }
+
+ /**
+ * Encodes the first 4 (when PHP_INT_SIZE == 4) or 8 characters of the string as an integer.
+ *
+ * Keep in mind, PHP integers are signed.
+ *
+ * @param string $string
+ *
+ * @return int
+ */
+ private function convertStringToInt($string)
+ {
+ if (4 === \PHP_INT_SIZE) {
+ return (ord($string[3]) << 24) + (ord($string[2]) << 16) + (ord($string[1]) << 8) + ord($string[0]);
+ }
+
+ $int1 = (ord($string[7]) << 24) + (ord($string[6]) << 16) + (ord($string[5]) << 8) + ord($string[4]);
+ $int2 = (ord($string[3]) << 24) + (ord($string[2]) << 16) + (ord($string[1]) << 8) + ord($string[0]);
+
+ return $int2 + ($int1 << 32);
+ }
+
+ /**
+ * Return a locking or nonlocking SQL query to read session information.
+ *
+ * @return string The SQL string
+ *
+ * @throws \DomainException When an unsupported PDO driver is used
+ */
+ private function getSelectSql()
+ {
+ if (self::LOCK_TRANSACTIONAL === $this->lockMode) {
+ $this->beginTransaction();
+
+ switch ($this->driver) {
+ case 'mysql':
+ case 'oci':
+ case 'pgsql':
+ return "SELECT $this->dataCol, $this->lifetimeCol, $this->timeCol FROM $this->table WHERE $this->idCol = :id FOR UPDATE";
+ case 'sqlsrv':
+ return "SELECT $this->dataCol, $this->lifetimeCol, $this->timeCol FROM $this->table WITH (UPDLOCK, ROWLOCK) WHERE $this->idCol = :id";
+ case 'sqlite':
+ // we already locked when starting transaction
+ break;
+ default:
+ throw new \DomainException(sprintf('Transactional locks are currently not implemented for PDO driver "%s".', $this->driver));
+ }
+ }
+
+ return "SELECT $this->dataCol, $this->lifetimeCol, $this->timeCol FROM $this->table WHERE $this->idCol = :id";
+ }
+
+ /**
+ * Returns an insert statement supported by the database for writing session data.
+ *
+ * @param string $sessionId Session ID
+ * @param string $sessionData Encoded session data
+ * @param int $maxlifetime session.gc_maxlifetime
+ *
+ * @return \PDOStatement The insert statement
+ */
+ private function getInsertStatement($sessionId, $sessionData, $maxlifetime)
+ {
+ switch ($this->driver) {
+ case 'oci':
+ $data = fopen('php://memory', 'r+');
+ fwrite($data, $sessionData);
+ rewind($data);
+ $sql = "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, EMPTY_BLOB(), :lifetime, :time) RETURNING $this->dataCol into :data";
+ break;
+ default:
+ $data = $sessionData;
+ $sql = "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :lifetime, :time)";
+ break;
+ }
+
+ $stmt = $this->pdo->prepare($sql);
+ $stmt->bindParam(':id', $sessionId, \PDO::PARAM_STR);
+ $stmt->bindParam(':data', $data, \PDO::PARAM_LOB);
+ $stmt->bindParam(':lifetime', $maxlifetime, \PDO::PARAM_INT);
+ $stmt->bindValue(':time', time(), \PDO::PARAM_INT);
+
+ return $stmt;
+ }
+
+ /**
+ * Returns an update statement supported by the database for writing session data.
+ *
+ * @param string $sessionId Session ID
+ * @param string $sessionData Encoded session data
+ * @param int $maxlifetime session.gc_maxlifetime
+ *
+ * @return \PDOStatement The update statement
+ */
+ private function getUpdateStatement($sessionId, $sessionData, $maxlifetime)
+ {
+ switch ($this->driver) {
+ case 'oci':
+ $data = fopen('php://memory', 'r+');
+ fwrite($data, $sessionData);
+ rewind($data);
+ $sql = "UPDATE $this->table SET $this->dataCol = EMPTY_BLOB(), $this->lifetimeCol = :lifetime, $this->timeCol = :time WHERE $this->idCol = :id RETURNING $this->dataCol into :data";
+ break;
+ default:
+ $data = $sessionData;
+ $sql = "UPDATE $this->table SET $this->dataCol = :data, $this->lifetimeCol = :lifetime, $this->timeCol = :time WHERE $this->idCol = :id";
+ break;
+ }
+
+ $stmt = $this->pdo->prepare($sql);
+ $stmt->bindParam(':id', $sessionId, \PDO::PARAM_STR);
+ $stmt->bindParam(':data', $data, \PDO::PARAM_LOB);
+ $stmt->bindParam(':lifetime', $maxlifetime, \PDO::PARAM_INT);
+ $stmt->bindValue(':time', time(), \PDO::PARAM_INT);
+
+ return $stmt;
+ }
+
+ /**
+ * Returns a merge/upsert (i.e. insert or update) statement when supported by the database for writing session data.
+ *
+ * @param string $sessionId Session ID
+ * @param string $data Encoded session data
+ * @param int $maxlifetime session.gc_maxlifetime
+ *
+ * @return \PDOStatement|null The merge statement or null when not supported
+ */
+ private function getMergeStatement($sessionId, $data, $maxlifetime)
+ {
+ switch (true) {
+ case 'mysql' === $this->driver:
+ $mergeSql = "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :lifetime, :time) ".
+ "ON DUPLICATE KEY UPDATE $this->dataCol = VALUES($this->dataCol), $this->lifetimeCol = VALUES($this->lifetimeCol), $this->timeCol = VALUES($this->timeCol)";
+ break;
+ case 'sqlsrv' === $this->driver && version_compare($this->pdo->getAttribute(\PDO::ATTR_SERVER_VERSION), '10', '>='):
+ // MERGE is only available since SQL Server 2008 and must be terminated by semicolon
+ // It also requires HOLDLOCK according to http://weblogs.sqlteam.com/dang/archive/2009/01/31/UPSERT-Race-Condition-With-MERGE.aspx
+ $mergeSql = "MERGE INTO $this->table WITH (HOLDLOCK) USING (SELECT 1 AS dummy) AS src ON ($this->idCol = ?) ".
+ "WHEN NOT MATCHED THEN INSERT ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (?, ?, ?, ?) ".
+ "WHEN MATCHED THEN UPDATE SET $this->dataCol = ?, $this->lifetimeCol = ?, $this->timeCol = ?;";
+ break;
+ case 'sqlite' === $this->driver:
+ $mergeSql = "INSERT OR REPLACE INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :lifetime, :time)";
+ break;
+ case 'pgsql' === $this->driver && version_compare($this->pdo->getAttribute(\PDO::ATTR_SERVER_VERSION), '9.5', '>='):
+ $mergeSql = "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :lifetime, :time) ".
+ "ON CONFLICT ($this->idCol) DO UPDATE SET ($this->dataCol, $this->lifetimeCol, $this->timeCol) = (EXCLUDED.$this->dataCol, EXCLUDED.$this->lifetimeCol, EXCLUDED.$this->timeCol)";
+ break;
+ default:
+ // MERGE is not supported with LOBs: http://www.oracle.com/technetwork/articles/fuecks-lobs-095315.html
+ return null;
+ }
+
+ $mergeStmt = $this->pdo->prepare($mergeSql);
+
+ if ('sqlsrv' === $this->driver) {
+ $mergeStmt->bindParam(1, $sessionId, \PDO::PARAM_STR);
+ $mergeStmt->bindParam(2, $sessionId, \PDO::PARAM_STR);
+ $mergeStmt->bindParam(3, $data, \PDO::PARAM_LOB);
+ $mergeStmt->bindParam(4, $maxlifetime, \PDO::PARAM_INT);
+ $mergeStmt->bindValue(5, time(), \PDO::PARAM_INT);
+ $mergeStmt->bindParam(6, $data, \PDO::PARAM_LOB);
+ $mergeStmt->bindParam(7, $maxlifetime, \PDO::PARAM_INT);
+ $mergeStmt->bindValue(8, time(), \PDO::PARAM_INT);
+ } else {
+ $mergeStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR);
+ $mergeStmt->bindParam(':data', $data, \PDO::PARAM_LOB);
+ $mergeStmt->bindParam(':lifetime', $maxlifetime, \PDO::PARAM_INT);
+ $mergeStmt->bindValue(':time', time(), \PDO::PARAM_INT);
+ }
+
+ return $mergeStmt;
+ }
+
+ /**
+ * Return a PDO instance.
+ *
+ * @return \PDO
+ */
+ protected function getConnection()
+ {
+ if (null === $this->pdo) {
+ $this->connect($this->dsn ?: ini_get('session.save_path'));
+ }
+
+ return $this->pdo;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/StrictSessionHandler.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/StrictSessionHandler.php
new file mode 100644
index 0000000..2281192
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/StrictSessionHandler.php
@@ -0,0 +1,103 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
+
+/**
+ * Adds basic `SessionUpdateTimestampHandlerInterface` behaviors to another `SessionHandlerInterface`.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class StrictSessionHandler extends AbstractSessionHandler
+{
+ private $handler;
+ private $doDestroy;
+
+ public function __construct(\SessionHandlerInterface $handler)
+ {
+ if ($handler instanceof \SessionUpdateTimestampHandlerInterface) {
+ throw new \LogicException(sprintf('"%s" is already an instance of "SessionUpdateTimestampHandlerInterface", you cannot wrap it with "%s".', get_class($handler), self::class));
+ }
+
+ $this->handler = $handler;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function open($savePath, $sessionName)
+ {
+ parent::open($savePath, $sessionName);
+
+ return $this->handler->open($savePath, $sessionName);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doRead($sessionId)
+ {
+ return $this->handler->read($sessionId);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function updateTimestamp($sessionId, $data)
+ {
+ return $this->write($sessionId, $data);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doWrite($sessionId, $data)
+ {
+ return $this->handler->write($sessionId, $data);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function destroy($sessionId)
+ {
+ $this->doDestroy = true;
+ $destroyed = parent::destroy($sessionId);
+
+ return $this->doDestroy ? $this->doDestroy($sessionId) : $destroyed;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doDestroy($sessionId)
+ {
+ $this->doDestroy = false;
+
+ return $this->handler->destroy($sessionId);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function close()
+ {
+ return $this->handler->close();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function gc($maxlifetime)
+ {
+ return $this->handler->gc($maxlifetime);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/WriteCheckSessionHandler.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/WriteCheckSessionHandler.php
new file mode 100644
index 0000000..1541ec4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Handler/WriteCheckSessionHandler.php
@@ -0,0 +1,92 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
+
+@trigger_error(sprintf('The %s class is deprecated since Symfony 3.4 and will be removed in 4.0. Implement `SessionUpdateTimestampHandlerInterface` or extend `AbstractSessionHandler` instead.', WriteCheckSessionHandler::class), E_USER_DEPRECATED);
+
+/**
+ * Wraps another SessionHandlerInterface to only write the session when it has been modified.
+ *
+ * @author Adrien Brault <adrien.brault@gmail.com>
+ *
+ * @deprecated since version 3.4, to be removed in 4.0. Implement `SessionUpdateTimestampHandlerInterface` or extend `AbstractSessionHandler` instead.
+ */
+class WriteCheckSessionHandler implements \SessionHandlerInterface
+{
+ private $wrappedSessionHandler;
+
+ /**
+ * @var array sessionId => session
+ */
+ private $readSessions;
+
+ public function __construct(\SessionHandlerInterface $wrappedSessionHandler)
+ {
+ $this->wrappedSessionHandler = $wrappedSessionHandler;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function close()
+ {
+ return $this->wrappedSessionHandler->close();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function destroy($sessionId)
+ {
+ return $this->wrappedSessionHandler->destroy($sessionId);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function gc($maxlifetime)
+ {
+ return $this->wrappedSessionHandler->gc($maxlifetime);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function open($savePath, $sessionName)
+ {
+ return $this->wrappedSessionHandler->open($savePath, $sessionName);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function read($sessionId)
+ {
+ $session = $this->wrappedSessionHandler->read($sessionId);
+
+ $this->readSessions[$sessionId] = $session;
+
+ return $session;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function write($sessionId, $data)
+ {
+ if (isset($this->readSessions[$sessionId]) && $data === $this->readSessions[$sessionId]) {
+ return true;
+ }
+
+ return $this->wrappedSessionHandler->write($sessionId, $data);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/MetadataBag.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/MetadataBag.php
new file mode 100644
index 0000000..6f59af4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/MetadataBag.php
@@ -0,0 +1,168 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage;
+
+use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
+
+/**
+ * Metadata container.
+ *
+ * Adds metadata to the session.
+ *
+ * @author Drak <drak@zikula.org>
+ */
+class MetadataBag implements SessionBagInterface
+{
+ const CREATED = 'c';
+ const UPDATED = 'u';
+ const LIFETIME = 'l';
+
+ /**
+ * @var string
+ */
+ private $name = '__metadata';
+
+ /**
+ * @var string
+ */
+ private $storageKey;
+
+ /**
+ * @var array
+ */
+ protected $meta = array(self::CREATED => 0, self::UPDATED => 0, self::LIFETIME => 0);
+
+ /**
+ * Unix timestamp.
+ *
+ * @var int
+ */
+ private $lastUsed;
+
+ /**
+ * @var int
+ */
+ private $updateThreshold;
+
+ /**
+ * @param string $storageKey The key used to store bag in the session
+ * @param int $updateThreshold The time to wait between two UPDATED updates
+ */
+ public function __construct($storageKey = '_sf2_meta', $updateThreshold = 0)
+ {
+ $this->storageKey = $storageKey;
+ $this->updateThreshold = $updateThreshold;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function initialize(array &$array)
+ {
+ $this->meta = &$array;
+
+ if (isset($array[self::CREATED])) {
+ $this->lastUsed = $this->meta[self::UPDATED];
+
+ $timeStamp = time();
+ if ($timeStamp - $array[self::UPDATED] >= $this->updateThreshold) {
+ $this->meta[self::UPDATED] = $timeStamp;
+ }
+ } else {
+ $this->stampCreated();
+ }
+ }
+
+ /**
+ * Gets the lifetime that the session cookie was set with.
+ *
+ * @return int
+ */
+ public function getLifetime()
+ {
+ return $this->meta[self::LIFETIME];
+ }
+
+ /**
+ * Stamps a new session's metadata.
+ *
+ * @param int $lifetime Sets the cookie lifetime for the session cookie. A null value
+ * will leave the system settings unchanged, 0 sets the cookie
+ * to expire with browser session. Time is in seconds, and is
+ * not a Unix timestamp.
+ */
+ public function stampNew($lifetime = null)
+ {
+ $this->stampCreated($lifetime);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getStorageKey()
+ {
+ return $this->storageKey;
+ }
+
+ /**
+ * Gets the created timestamp metadata.
+ *
+ * @return int Unix timestamp
+ */
+ public function getCreated()
+ {
+ return $this->meta[self::CREATED];
+ }
+
+ /**
+ * Gets the last used metadata.
+ *
+ * @return int Unix timestamp
+ */
+ public function getLastUsed()
+ {
+ return $this->lastUsed;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clear()
+ {
+ // nothing to do
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Sets name.
+ *
+ * @param string $name
+ */
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ private function stampCreated($lifetime = null)
+ {
+ $timeStamp = time();
+ $this->meta[self::CREATED] = $this->meta[self::UPDATED] = $this->lastUsed = $timeStamp;
+ $this->meta[self::LIFETIME] = (null === $lifetime) ? ini_get('session.cookie_lifetime') : $lifetime;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/MockArraySessionStorage.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/MockArraySessionStorage.php
new file mode 100644
index 0000000..027f4ef
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/MockArraySessionStorage.php
@@ -0,0 +1,256 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage;
+
+use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
+
+/**
+ * MockArraySessionStorage mocks the session for unit tests.
+ *
+ * No PHP session is actually started since a session can be initialized
+ * and shutdown only once per PHP execution cycle.
+ *
+ * When doing functional testing, you should use MockFileSessionStorage instead.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Bulat Shakirzyanov <mallluhuct@gmail.com>
+ * @author Drak <drak@zikula.org>
+ */
+class MockArraySessionStorage implements SessionStorageInterface
+{
+ /**
+ * @var string
+ */
+ protected $id = '';
+
+ /**
+ * @var string
+ */
+ protected $name;
+
+ /**
+ * @var bool
+ */
+ protected $started = false;
+
+ /**
+ * @var bool
+ */
+ protected $closed = false;
+
+ /**
+ * @var array
+ */
+ protected $data = array();
+
+ /**
+ * @var MetadataBag
+ */
+ protected $metadataBag;
+
+ /**
+ * @var array|SessionBagInterface[]
+ */
+ protected $bags = array();
+
+ /**
+ * @param string $name Session name
+ * @param MetadataBag $metaBag MetadataBag instance
+ */
+ public function __construct($name = 'MOCKSESSID', MetadataBag $metaBag = null)
+ {
+ $this->name = $name;
+ $this->setMetadataBag($metaBag);
+ }
+
+ public function setSessionData(array $array)
+ {
+ $this->data = $array;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function start()
+ {
+ if ($this->started) {
+ return true;
+ }
+
+ if (empty($this->id)) {
+ $this->id = $this->generateId();
+ }
+
+ $this->loadSession();
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function regenerate($destroy = false, $lifetime = null)
+ {
+ if (!$this->started) {
+ $this->start();
+ }
+
+ $this->metadataBag->stampNew($lifetime);
+ $this->id = $this->generateId();
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getId()
+ {
+ return $this->id;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setId($id)
+ {
+ if ($this->started) {
+ throw new \LogicException('Cannot set session ID after the session has started.');
+ }
+
+ $this->id = $id;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function save()
+ {
+ if (!$this->started || $this->closed) {
+ throw new \RuntimeException('Trying to save a session that was not started yet or was already closed');
+ }
+ // nothing to do since we don't persist the session data
+ $this->closed = false;
+ $this->started = false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clear()
+ {
+ // clear out the bags
+ foreach ($this->bags as $bag) {
+ $bag->clear();
+ }
+
+ // clear out the session
+ $this->data = array();
+
+ // reconnect the bags to the session
+ $this->loadSession();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function registerBag(SessionBagInterface $bag)
+ {
+ $this->bags[$bag->getName()] = $bag;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getBag($name)
+ {
+ if (!isset($this->bags[$name])) {
+ throw new \InvalidArgumentException(sprintf('The SessionBagInterface %s is not registered.', $name));
+ }
+
+ if (!$this->started) {
+ $this->start();
+ }
+
+ return $this->bags[$name];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isStarted()
+ {
+ return $this->started;
+ }
+
+ public function setMetadataBag(MetadataBag $bag = null)
+ {
+ if (null === $bag) {
+ $bag = new MetadataBag();
+ }
+
+ $this->metadataBag = $bag;
+ }
+
+ /**
+ * Gets the MetadataBag.
+ *
+ * @return MetadataBag
+ */
+ public function getMetadataBag()
+ {
+ return $this->metadataBag;
+ }
+
+ /**
+ * Generates a session ID.
+ *
+ * This doesn't need to be particularly cryptographically secure since this is just
+ * a mock.
+ *
+ * @return string
+ */
+ protected function generateId()
+ {
+ return hash('sha256', uniqid('ss_mock_', true));
+ }
+
+ protected function loadSession()
+ {
+ $bags = array_merge($this->bags, array($this->metadataBag));
+
+ foreach ($bags as $bag) {
+ $key = $bag->getStorageKey();
+ $this->data[$key] = isset($this->data[$key]) ? $this->data[$key] : array();
+ $bag->initialize($this->data[$key]);
+ }
+
+ $this->started = true;
+ $this->closed = false;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/MockFileSessionStorage.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/MockFileSessionStorage.php
new file mode 100644
index 0000000..14f4270
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/MockFileSessionStorage.php
@@ -0,0 +1,152 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage;
+
+/**
+ * MockFileSessionStorage is used to mock sessions for
+ * functional testing when done in a single PHP process.
+ *
+ * No PHP session is actually started since a session can be initialized
+ * and shutdown only once per PHP execution cycle and this class does
+ * not pollute any session related globals, including session_*() functions
+ * or session.* PHP ini directives.
+ *
+ * @author Drak <drak@zikula.org>
+ */
+class MockFileSessionStorage extends MockArraySessionStorage
+{
+ private $savePath;
+
+ /**
+ * @param string $savePath Path of directory to save session files
+ * @param string $name Session name
+ * @param MetadataBag $metaBag MetadataBag instance
+ */
+ public function __construct($savePath = null, $name = 'MOCKSESSID', MetadataBag $metaBag = null)
+ {
+ if (null === $savePath) {
+ $savePath = sys_get_temp_dir();
+ }
+
+ if (!is_dir($savePath) && !@mkdir($savePath, 0777, true) && !is_dir($savePath)) {
+ throw new \RuntimeException(sprintf('Session Storage was not able to create directory "%s"', $savePath));
+ }
+
+ $this->savePath = $savePath;
+
+ parent::__construct($name, $metaBag);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function start()
+ {
+ if ($this->started) {
+ return true;
+ }
+
+ if (!$this->id) {
+ $this->id = $this->generateId();
+ }
+
+ $this->read();
+
+ $this->started = true;
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function regenerate($destroy = false, $lifetime = null)
+ {
+ if (!$this->started) {
+ $this->start();
+ }
+
+ if ($destroy) {
+ $this->destroy();
+ }
+
+ return parent::regenerate($destroy, $lifetime);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function save()
+ {
+ if (!$this->started) {
+ throw new \RuntimeException('Trying to save a session that was not started yet or was already closed');
+ }
+
+ $data = $this->data;
+
+ foreach ($this->bags as $bag) {
+ if (empty($data[$key = $bag->getStorageKey()])) {
+ unset($data[$key]);
+ }
+ }
+ if (array($key = $this->metadataBag->getStorageKey()) === array_keys($data)) {
+ unset($data[$key]);
+ }
+
+ try {
+ if ($data) {
+ file_put_contents($this->getFilePath(), serialize($data));
+ } else {
+ $this->destroy();
+ }
+ } finally {
+ $this->data = $data;
+ }
+
+ // this is needed for Silex, where the session object is re-used across requests
+ // in functional tests. In Symfony, the container is rebooted, so we don't have
+ // this issue
+ $this->started = false;
+ }
+
+ /**
+ * Deletes a session from persistent storage.
+ * Deliberately leaves session data in memory intact.
+ */
+ private function destroy()
+ {
+ if (is_file($this->getFilePath())) {
+ unlink($this->getFilePath());
+ }
+ }
+
+ /**
+ * Calculate path to file.
+ *
+ * @return string File path
+ */
+ private function getFilePath()
+ {
+ return $this->savePath.'/'.$this->id.'.mocksess';
+ }
+
+ /**
+ * Reads session from storage and loads session.
+ */
+ private function read()
+ {
+ $filePath = $this->getFilePath();
+ $this->data = is_readable($filePath) && is_file($filePath) ? unserialize(file_get_contents($filePath)) : array();
+
+ $this->loadSession();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php
new file mode 100644
index 0000000..0dfad9a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php
@@ -0,0 +1,445 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage;
+
+use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
+use Symfony\Component\HttpFoundation\Session\Storage\Handler\StrictSessionHandler;
+use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy;
+use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;
+
+/**
+ * This provides a base class for session attribute storage.
+ *
+ * @author Drak <drak@zikula.org>
+ */
+class NativeSessionStorage implements SessionStorageInterface
+{
+ /**
+ * @var SessionBagInterface[]
+ */
+ protected $bags = array();
+
+ /**
+ * @var bool
+ */
+ protected $started = false;
+
+ /**
+ * @var bool
+ */
+ protected $closed = false;
+
+ /**
+ * @var AbstractProxy|\SessionHandlerInterface
+ */
+ protected $saveHandler;
+
+ /**
+ * @var MetadataBag
+ */
+ protected $metadataBag;
+
+ /**
+ * Depending on how you want the storage driver to behave you probably
+ * want to override this constructor entirely.
+ *
+ * List of options for $options array with their defaults.
+ *
+ * @see http://php.net/session.configuration for options
+ * but we omit 'session.' from the beginning of the keys for convenience.
+ *
+ * ("auto_start", is not supported as it tells PHP to start a session before
+ * PHP starts to execute user-land code. Setting during runtime has no effect).
+ *
+ * cache_limiter, "" (use "0" to prevent headers from being sent entirely).
+ * cache_expire, "0"
+ * cookie_domain, ""
+ * cookie_httponly, ""
+ * cookie_lifetime, "0"
+ * cookie_path, "/"
+ * cookie_secure, ""
+ * entropy_file, ""
+ * entropy_length, "0"
+ * gc_divisor, "100"
+ * gc_maxlifetime, "1440"
+ * gc_probability, "1"
+ * hash_bits_per_character, "4"
+ * hash_function, "0"
+ * lazy_write, "1"
+ * name, "PHPSESSID"
+ * referer_check, ""
+ * serialize_handler, "php"
+ * use_strict_mode, "0"
+ * use_cookies, "1"
+ * use_only_cookies, "1"
+ * use_trans_sid, "0"
+ * upload_progress.enabled, "1"
+ * upload_progress.cleanup, "1"
+ * upload_progress.prefix, "upload_progress_"
+ * upload_progress.name, "PHP_SESSION_UPLOAD_PROGRESS"
+ * upload_progress.freq, "1%"
+ * upload_progress.min-freq, "1"
+ * url_rewriter.tags, "a=href,area=href,frame=src,form=,fieldset="
+ * sid_length, "32"
+ * sid_bits_per_character, "5"
+ * trans_sid_hosts, $_SERVER['HTTP_HOST']
+ * trans_sid_tags, "a=href,area=href,frame=src,form="
+ *
+ * @param array $options Session configuration options
+ * @param \SessionHandlerInterface|null $handler
+ * @param MetadataBag $metaBag MetadataBag
+ */
+ public function __construct(array $options = array(), $handler = null, MetadataBag $metaBag = null)
+ {
+ $options += array(
+ 'cache_limiter' => '',
+ 'cache_expire' => 0,
+ 'use_cookies' => 1,
+ 'lazy_write' => 1,
+ );
+
+ session_register_shutdown();
+
+ $this->setMetadataBag($metaBag);
+ $this->setOptions($options);
+ $this->setSaveHandler($handler);
+ }
+
+ /**
+ * Gets the save handler instance.
+ *
+ * @return AbstractProxy|\SessionHandlerInterface
+ */
+ public function getSaveHandler()
+ {
+ return $this->saveHandler;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function start()
+ {
+ if ($this->started) {
+ return true;
+ }
+
+ if (\PHP_SESSION_ACTIVE === session_status()) {
+ throw new \RuntimeException('Failed to start the session: already started by PHP.');
+ }
+
+ if (ini_get('session.use_cookies') && headers_sent($file, $line)) {
+ throw new \RuntimeException(sprintf('Failed to start the session because headers have already been sent by "%s" at line %d.', $file, $line));
+ }
+
+ // ok to try and start the session
+ if (!session_start()) {
+ throw new \RuntimeException('Failed to start the session');
+ }
+
+ $this->loadSession();
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getId()
+ {
+ return $this->saveHandler->getId();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setId($id)
+ {
+ $this->saveHandler->setId($id);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return $this->saveHandler->getName();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setName($name)
+ {
+ $this->saveHandler->setName($name);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function regenerate($destroy = false, $lifetime = null)
+ {
+ // Cannot regenerate the session ID for non-active sessions.
+ if (\PHP_SESSION_ACTIVE !== session_status()) {
+ return false;
+ }
+
+ if (headers_sent()) {
+ return false;
+ }
+
+ if (null !== $lifetime) {
+ ini_set('session.cookie_lifetime', $lifetime);
+ }
+
+ if ($destroy) {
+ $this->metadataBag->stampNew();
+ }
+
+ $isRegenerated = session_regenerate_id($destroy);
+
+ // The reference to $_SESSION in session bags is lost in PHP7 and we need to re-create it.
+ // @see https://bugs.php.net/bug.php?id=70013
+ $this->loadSession();
+
+ return $isRegenerated;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function save()
+ {
+ $session = $_SESSION;
+
+ foreach ($this->bags as $bag) {
+ if (empty($_SESSION[$key = $bag->getStorageKey()])) {
+ unset($_SESSION[$key]);
+ }
+ }
+ if (array($key = $this->metadataBag->getStorageKey()) === array_keys($_SESSION)) {
+ unset($_SESSION[$key]);
+ }
+
+ // Register custom error handler to catch a possible failure warning during session write
+ set_error_handler(function ($errno, $errstr, $errfile, $errline) {
+ throw new \ErrorException($errstr, $errno, E_WARNING, $errfile, $errline);
+ }, E_WARNING);
+
+ try {
+ $e = null;
+ session_write_close();
+ } catch (\ErrorException $e) {
+ } finally {
+ restore_error_handler();
+ $_SESSION = $session;
+ }
+ if (null !== $e) {
+ // The default PHP error message is not very helpful, as it does not give any information on the current save handler.
+ // Therefore, we catch this error and trigger a warning with a better error message
+ $handler = $this->getSaveHandler();
+ if ($handler instanceof SessionHandlerProxy) {
+ $handler = $handler->getHandler();
+ }
+
+ trigger_error(sprintf('session_write_close(): Failed to write session data with %s handler', get_class($handler)), E_USER_WARNING);
+ }
+
+ $this->closed = true;
+ $this->started = false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clear()
+ {
+ // clear out the bags
+ foreach ($this->bags as $bag) {
+ $bag->clear();
+ }
+
+ // clear out the session
+ $_SESSION = array();
+
+ // reconnect the bags to the session
+ $this->loadSession();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function registerBag(SessionBagInterface $bag)
+ {
+ if ($this->started) {
+ throw new \LogicException('Cannot register a bag when the session is already started.');
+ }
+
+ $this->bags[$bag->getName()] = $bag;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getBag($name)
+ {
+ if (!isset($this->bags[$name])) {
+ throw new \InvalidArgumentException(sprintf('The SessionBagInterface %s is not registered.', $name));
+ }
+
+ if (!$this->started && $this->saveHandler->isActive()) {
+ $this->loadSession();
+ } elseif (!$this->started) {
+ $this->start();
+ }
+
+ return $this->bags[$name];
+ }
+
+ public function setMetadataBag(MetadataBag $metaBag = null)
+ {
+ if (null === $metaBag) {
+ $metaBag = new MetadataBag();
+ }
+
+ $this->metadataBag = $metaBag;
+ }
+
+ /**
+ * Gets the MetadataBag.
+ *
+ * @return MetadataBag
+ */
+ public function getMetadataBag()
+ {
+ return $this->metadataBag;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isStarted()
+ {
+ return $this->started;
+ }
+
+ /**
+ * Sets session.* ini variables.
+ *
+ * For convenience we omit 'session.' from the beginning of the keys.
+ * Explicitly ignores other ini keys.
+ *
+ * @param array $options Session ini directives array(key => value)
+ *
+ * @see http://php.net/session.configuration
+ */
+ public function setOptions(array $options)
+ {
+ if (headers_sent() || \PHP_SESSION_ACTIVE === session_status()) {
+ return;
+ }
+
+ $validOptions = array_flip(array(
+ 'cache_limiter', 'cache_expire', 'cookie_domain', 'cookie_httponly',
+ 'cookie_lifetime', 'cookie_path', 'cookie_secure',
+ 'entropy_file', 'entropy_length', 'gc_divisor',
+ 'gc_maxlifetime', 'gc_probability', 'hash_bits_per_character',
+ 'hash_function', 'lazy_write', 'name', 'referer_check',
+ 'serialize_handler', 'use_strict_mode', 'use_cookies',
+ 'use_only_cookies', 'use_trans_sid', 'upload_progress.enabled',
+ 'upload_progress.cleanup', 'upload_progress.prefix', 'upload_progress.name',
+ 'upload_progress.freq', 'upload_progress.min-freq', 'url_rewriter.tags',
+ 'sid_length', 'sid_bits_per_character', 'trans_sid_hosts', 'trans_sid_tags',
+ ));
+
+ foreach ($options as $key => $value) {
+ if (isset($validOptions[$key])) {
+ ini_set('session.'.$key, $value);
+ }
+ }
+ }
+
+ /**
+ * Registers session save handler as a PHP session handler.
+ *
+ * To use internal PHP session save handlers, override this method using ini_set with
+ * session.save_handler and session.save_path e.g.
+ *
+ * ini_set('session.save_handler', 'files');
+ * ini_set('session.save_path', '/tmp');
+ *
+ * or pass in a \SessionHandler instance which configures session.save_handler in the
+ * constructor, for a template see NativeFileSessionHandler or use handlers in
+ * composer package drak/native-session
+ *
+ * @see http://php.net/session-set-save-handler
+ * @see http://php.net/sessionhandlerinterface
+ * @see http://php.net/sessionhandler
+ * @see http://github.com/drak/NativeSession
+ *
+ * @param \SessionHandlerInterface|null $saveHandler
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function setSaveHandler($saveHandler = null)
+ {
+ if (!$saveHandler instanceof AbstractProxy &&
+ !$saveHandler instanceof \SessionHandlerInterface &&
+ null !== $saveHandler) {
+ throw new \InvalidArgumentException('Must be instance of AbstractProxy; implement \SessionHandlerInterface; or be null.');
+ }
+
+ // Wrap $saveHandler in proxy and prevent double wrapping of proxy
+ if (!$saveHandler instanceof AbstractProxy && $saveHandler instanceof \SessionHandlerInterface) {
+ $saveHandler = new SessionHandlerProxy($saveHandler);
+ } elseif (!$saveHandler instanceof AbstractProxy) {
+ $saveHandler = new SessionHandlerProxy(new StrictSessionHandler(new \SessionHandler()));
+ }
+ $this->saveHandler = $saveHandler;
+
+ if (headers_sent() || \PHP_SESSION_ACTIVE === session_status()) {
+ return;
+ }
+
+ if ($this->saveHandler instanceof SessionHandlerProxy) {
+ session_set_save_handler($this->saveHandler->getHandler(), false);
+ } elseif ($this->saveHandler instanceof \SessionHandlerInterface) {
+ session_set_save_handler($this->saveHandler, false);
+ }
+ }
+
+ /**
+ * Load the session with attributes.
+ *
+ * After starting the session, PHP retrieves the session from whatever handlers
+ * are set to (either PHP's internal, or a custom save handler set with session_set_save_handler()).
+ * PHP takes the return value from the read() handler, unserializes it
+ * and populates $_SESSION with the result automatically.
+ */
+ protected function loadSession(array &$session = null)
+ {
+ if (null === $session) {
+ $session = &$_SESSION;
+ }
+
+ $bags = array_merge($this->bags, array($this->metadataBag));
+
+ foreach ($bags as $bag) {
+ $key = $bag->getStorageKey();
+ $session[$key] = isset($session[$key]) ? $session[$key] : array();
+ $bag->initialize($session[$key]);
+ }
+
+ $this->started = true;
+ $this->closed = false;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/PhpBridgeSessionStorage.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/PhpBridgeSessionStorage.php
new file mode 100644
index 0000000..662ed50
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/PhpBridgeSessionStorage.php
@@ -0,0 +1,59 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage;
+
+/**
+ * Allows session to be started by PHP and managed by Symfony.
+ *
+ * @author Drak <drak@zikula.org>
+ */
+class PhpBridgeSessionStorage extends NativeSessionStorage
+{
+ /**
+ * @param \SessionHandlerInterface|null $handler
+ * @param MetadataBag $metaBag MetadataBag
+ */
+ public function __construct($handler = null, MetadataBag $metaBag = null)
+ {
+ $this->setMetadataBag($metaBag);
+ $this->setSaveHandler($handler);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function start()
+ {
+ if ($this->started) {
+ return true;
+ }
+
+ $this->loadSession();
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clear()
+ {
+ // clear out the bags and nothing else that may be set
+ // since the purpose of this driver is to share a handler
+ foreach ($this->bags as $bag) {
+ $bag->clear();
+ }
+
+ // reconnect the bags to the session
+ $this->loadSession();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php
new file mode 100644
index 0000000..09c9248
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php
@@ -0,0 +1,122 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage\Proxy;
+
+/**
+ * @author Drak <drak@zikula.org>
+ */
+abstract class AbstractProxy
+{
+ /**
+ * Flag if handler wraps an internal PHP session handler (using \SessionHandler).
+ *
+ * @var bool
+ */
+ protected $wrapper = false;
+
+ /**
+ * @var string
+ */
+ protected $saveHandlerName;
+
+ /**
+ * Gets the session.save_handler name.
+ *
+ * @return string
+ */
+ public function getSaveHandlerName()
+ {
+ return $this->saveHandlerName;
+ }
+
+ /**
+ * Is this proxy handler and instance of \SessionHandlerInterface.
+ *
+ * @return bool
+ */
+ public function isSessionHandlerInterface()
+ {
+ return $this instanceof \SessionHandlerInterface;
+ }
+
+ /**
+ * Returns true if this handler wraps an internal PHP session save handler using \SessionHandler.
+ *
+ * @return bool
+ */
+ public function isWrapper()
+ {
+ return $this->wrapper;
+ }
+
+ /**
+ * Has a session started?
+ *
+ * @return bool
+ */
+ public function isActive()
+ {
+ return \PHP_SESSION_ACTIVE === session_status();
+ }
+
+ /**
+ * Gets the session ID.
+ *
+ * @return string
+ */
+ public function getId()
+ {
+ return session_id();
+ }
+
+ /**
+ * Sets the session ID.
+ *
+ * @param string $id
+ *
+ * @throws \LogicException
+ */
+ public function setId($id)
+ {
+ if ($this->isActive()) {
+ throw new \LogicException('Cannot change the ID of an active session');
+ }
+
+ session_id($id);
+ }
+
+ /**
+ * Gets the session name.
+ *
+ * @return string
+ */
+ public function getName()
+ {
+ return session_name();
+ }
+
+ /**
+ * Sets the session name.
+ *
+ * @param string $name
+ *
+ * @throws \LogicException
+ */
+ public function setName($name)
+ {
+ if ($this->isActive()) {
+ throw new \LogicException('Cannot change the name of an active session');
+ }
+
+ session_name($name);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Proxy/NativeProxy.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Proxy/NativeProxy.php
new file mode 100644
index 0000000..082eed1
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Proxy/NativeProxy.php
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage\Proxy;
+
+@trigger_error('The '.__NAMESPACE__.'\NativeProxy class is deprecated since Symfony 3.4 and will be removed in 4.0. Use your session handler implementation directly.', E_USER_DEPRECATED);
+
+/**
+ * This proxy is built-in session handlers in PHP 5.3.x.
+ *
+ * @deprecated since version 3.4, to be removed in 4.0. Use your session handler implementation directly.
+ *
+ * @author Drak <drak@zikula.org>
+ */
+class NativeProxy extends AbstractProxy
+{
+ public function __construct()
+ {
+ // this makes an educated guess as to what the handler is since it should already be set.
+ $this->saveHandlerName = ini_get('session.save_handler');
+ }
+
+ /**
+ * Returns true if this handler wraps an internal PHP session save handler using \SessionHandler.
+ *
+ * @return bool False
+ */
+ public function isWrapper()
+ {
+ return false;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php
new file mode 100644
index 0000000..53c1209
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php
@@ -0,0 +1,85 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage\Proxy;
+
+/**
+ * @author Drak <drak@zikula.org>
+ */
+class SessionHandlerProxy extends AbstractProxy implements \SessionHandlerInterface
+{
+ protected $handler;
+
+ public function __construct(\SessionHandlerInterface $handler)
+ {
+ $this->handler = $handler;
+ $this->wrapper = ($handler instanceof \SessionHandler);
+ $this->saveHandlerName = $this->wrapper ? ini_get('session.save_handler') : 'user';
+ }
+
+ /**
+ * @return \SessionHandlerInterface
+ */
+ public function getHandler()
+ {
+ return $this->handler;
+ }
+
+ // \SessionHandlerInterface
+
+ /**
+ * {@inheritdoc}
+ */
+ public function open($savePath, $sessionName)
+ {
+ return (bool) $this->handler->open($savePath, $sessionName);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function close()
+ {
+ return (bool) $this->handler->close();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function read($sessionId)
+ {
+ return (string) $this->handler->read($sessionId);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function write($sessionId, $data)
+ {
+ return (bool) $this->handler->write($sessionId, $data);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function destroy($sessionId)
+ {
+ return (bool) $this->handler->destroy($sessionId);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function gc($maxlifetime)
+ {
+ return (bool) $this->handler->gc($maxlifetime);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/SessionStorageInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/SessionStorageInterface.php
new file mode 100644
index 0000000..66e8b33
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Session/Storage/SessionStorageInterface.php
@@ -0,0 +1,137 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage;
+
+use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
+
+/**
+ * StorageInterface.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Drak <drak@zikula.org>
+ */
+interface SessionStorageInterface
+{
+ /**
+ * Starts the session.
+ *
+ * @return bool True if started
+ *
+ * @throws \RuntimeException if something goes wrong starting the session
+ */
+ public function start();
+
+ /**
+ * Checks if the session is started.
+ *
+ * @return bool True if started, false otherwise
+ */
+ public function isStarted();
+
+ /**
+ * Returns the session ID.
+ *
+ * @return string The session ID or empty
+ */
+ public function getId();
+
+ /**
+ * Sets the session ID.
+ *
+ * @param string $id
+ */
+ public function setId($id);
+
+ /**
+ * Returns the session name.
+ *
+ * @return mixed The session name
+ */
+ public function getName();
+
+ /**
+ * Sets the session name.
+ *
+ * @param string $name
+ */
+ public function setName($name);
+
+ /**
+ * Regenerates id that represents this storage.
+ *
+ * This method must invoke session_regenerate_id($destroy) unless
+ * this interface is used for a storage object designed for unit
+ * or functional testing where a real PHP session would interfere
+ * with testing.
+ *
+ * Note regenerate+destroy should not clear the session data in memory
+ * only delete the session data from persistent storage.
+ *
+ * Care: When regenerating the session ID no locking is involved in PHP's
+ * session design. See https://bugs.php.net/bug.php?id=61470 for a discussion.
+ * So you must make sure the regenerated session is saved BEFORE sending the
+ * headers with the new ID. Symfony's HttpKernel offers a listener for this.
+ * See Symfony\Component\HttpKernel\EventListener\SaveSessionListener.
+ * Otherwise session data could get lost again for concurrent requests with the
+ * new ID. One result could be that you get logged out after just logging in.
+ *
+ * @param bool $destroy Destroy session when regenerating?
+ * @param int $lifetime Sets the cookie lifetime for the session cookie. A null value
+ * will leave the system settings unchanged, 0 sets the cookie
+ * to expire with browser session. Time is in seconds, and is
+ * not a Unix timestamp.
+ *
+ * @return bool True if session regenerated, false if error
+ *
+ * @throws \RuntimeException If an error occurs while regenerating this storage
+ */
+ public function regenerate($destroy = false, $lifetime = null);
+
+ /**
+ * Force the session to be saved and closed.
+ *
+ * This method must invoke session_write_close() unless this interface is
+ * used for a storage object design for unit or functional testing where
+ * a real PHP session would interfere with testing, in which case
+ * it should actually persist the session data if required.
+ *
+ * @throws \RuntimeException if the session is saved without being started, or if the session
+ * is already closed
+ */
+ public function save();
+
+ /**
+ * Clear all session data in memory.
+ */
+ public function clear();
+
+ /**
+ * Gets a SessionBagInterface by name.
+ *
+ * @param string $name
+ *
+ * @return SessionBagInterface
+ *
+ * @throws \InvalidArgumentException If the bag does not exist
+ */
+ public function getBag($name);
+
+ /**
+ * Registers a SessionBagInterface for use.
+ */
+ public function registerBag(SessionBagInterface $bag);
+
+ /**
+ * @return MetadataBag
+ */
+ public function getMetadataBag();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/StreamedResponse.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/StreamedResponse.php
new file mode 100644
index 0000000..92868d3
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/StreamedResponse.php
@@ -0,0 +1,144 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * StreamedResponse represents a streamed HTTP response.
+ *
+ * A StreamedResponse uses a callback for its content.
+ *
+ * The callback should use the standard PHP functions like echo
+ * to stream the response back to the client. The flush() method
+ * can also be used if needed.
+ *
+ * @see flush()
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class StreamedResponse extends Response
+{
+ protected $callback;
+ protected $streamed;
+ private $headersSent;
+
+ /**
+ * @param callable|null $callback A valid PHP callback or null to set it later
+ * @param int $status The response status code
+ * @param array $headers An array of response headers
+ */
+ public function __construct(callable $callback = null, $status = 200, $headers = array())
+ {
+ parent::__construct(null, $status, $headers);
+
+ if (null !== $callback) {
+ $this->setCallback($callback);
+ }
+ $this->streamed = false;
+ $this->headersSent = false;
+ }
+
+ /**
+ * Factory method for chainability.
+ *
+ * @param callable|null $callback A valid PHP callback or null to set it later
+ * @param int $status The response status code
+ * @param array $headers An array of response headers
+ *
+ * @return static
+ */
+ public static function create($callback = null, $status = 200, $headers = array())
+ {
+ return new static($callback, $status, $headers);
+ }
+
+ /**
+ * Sets the PHP callback associated with this Response.
+ *
+ * @param callable $callback A valid PHP callback
+ *
+ * @return $this
+ */
+ public function setCallback(callable $callback)
+ {
+ $this->callback = $callback;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * This method only sends the headers once.
+ *
+ * @return $this
+ */
+ public function sendHeaders()
+ {
+ if ($this->headersSent) {
+ return $this;
+ }
+
+ $this->headersSent = true;
+
+ return parent::sendHeaders();
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * This method only sends the content once.
+ *
+ * @return $this
+ */
+ public function sendContent()
+ {
+ if ($this->streamed) {
+ return $this;
+ }
+
+ $this->streamed = true;
+
+ if (null === $this->callback) {
+ throw new \LogicException('The Response callback must not be null.');
+ }
+
+ call_user_func($this->callback);
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @throws \LogicException when the content is not null
+ *
+ * @return $this
+ */
+ public function setContent($content)
+ {
+ if (null !== $content) {
+ throw new \LogicException('The content cannot be set on a StreamedResponse instance.');
+ }
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @return false
+ */
+ public function getContent()
+ {
+ return false;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/AcceptHeaderItemTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/AcceptHeaderItemTest.php
new file mode 100644
index 0000000..cb43bb3
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/AcceptHeaderItemTest.php
@@ -0,0 +1,113 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\AcceptHeaderItem;
+
+class AcceptHeaderItemTest extends TestCase
+{
+ /**
+ * @dataProvider provideFromStringData
+ */
+ public function testFromString($string, $value, array $attributes)
+ {
+ $item = AcceptHeaderItem::fromString($string);
+ $this->assertEquals($value, $item->getValue());
+ $this->assertEquals($attributes, $item->getAttributes());
+ }
+
+ public function provideFromStringData()
+ {
+ return array(
+ array(
+ 'text/html',
+ 'text/html', array(),
+ ),
+ array(
+ '"this;should,not=matter"',
+ 'this;should,not=matter', array(),
+ ),
+ array(
+ "text/plain; charset=utf-8;param=\"this;should,not=matter\";\tfootnotes=true",
+ 'text/plain', array('charset' => 'utf-8', 'param' => 'this;should,not=matter', 'footnotes' => 'true'),
+ ),
+ array(
+ '"this;should,not=matter";charset=utf-8',
+ 'this;should,not=matter', array('charset' => 'utf-8'),
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider provideToStringData
+ */
+ public function testToString($value, array $attributes, $string)
+ {
+ $item = new AcceptHeaderItem($value, $attributes);
+ $this->assertEquals($string, (string) $item);
+ }
+
+ public function provideToStringData()
+ {
+ return array(
+ array(
+ 'text/html', array(),
+ 'text/html',
+ ),
+ array(
+ 'text/plain', array('charset' => 'utf-8', 'param' => 'this;should,not=matter', 'footnotes' => 'true'),
+ 'text/plain;charset=utf-8;param="this;should,not=matter";footnotes=true',
+ ),
+ );
+ }
+
+ public function testValue()
+ {
+ $item = new AcceptHeaderItem('value', array());
+ $this->assertEquals('value', $item->getValue());
+
+ $item->setValue('new value');
+ $this->assertEquals('new value', $item->getValue());
+
+ $item->setValue(1);
+ $this->assertEquals('1', $item->getValue());
+ }
+
+ public function testQuality()
+ {
+ $item = new AcceptHeaderItem('value', array());
+ $this->assertEquals(1.0, $item->getQuality());
+
+ $item->setQuality(0.5);
+ $this->assertEquals(0.5, $item->getQuality());
+
+ $item->setAttribute('q', 0.75);
+ $this->assertEquals(0.75, $item->getQuality());
+ $this->assertFalse($item->hasAttribute('q'));
+ }
+
+ public function testAttribute()
+ {
+ $item = new AcceptHeaderItem('value', array());
+ $this->assertEquals(array(), $item->getAttributes());
+ $this->assertFalse($item->hasAttribute('test'));
+ $this->assertNull($item->getAttribute('test'));
+ $this->assertEquals('default', $item->getAttribute('test', 'default'));
+
+ $item->setAttribute('test', 'value');
+ $this->assertEquals(array('test' => 'value'), $item->getAttributes());
+ $this->assertTrue($item->hasAttribute('test'));
+ $this->assertEquals('value', $item->getAttribute('test'));
+ $this->assertEquals('value', $item->getAttribute('test', 'default'));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/AcceptHeaderTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/AcceptHeaderTest.php
new file mode 100644
index 0000000..9929eac
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/AcceptHeaderTest.php
@@ -0,0 +1,103 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\AcceptHeader;
+use Symfony\Component\HttpFoundation\AcceptHeaderItem;
+
+class AcceptHeaderTest extends TestCase
+{
+ public function testFirst()
+ {
+ $header = AcceptHeader::fromString('text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c');
+ $this->assertSame('text/html', $header->first()->getValue());
+ }
+
+ /**
+ * @dataProvider provideFromStringData
+ */
+ public function testFromString($string, array $items)
+ {
+ $header = AcceptHeader::fromString($string);
+ $parsed = array_values($header->all());
+ // reset index since the fixtures don't have them set
+ foreach ($parsed as $item) {
+ $item->setIndex(0);
+ }
+ $this->assertEquals($items, $parsed);
+ }
+
+ public function provideFromStringData()
+ {
+ return array(
+ array('', array()),
+ array('gzip', array(new AcceptHeaderItem('gzip'))),
+ array('gzip,deflate,sdch', array(new AcceptHeaderItem('gzip'), new AcceptHeaderItem('deflate'), new AcceptHeaderItem('sdch'))),
+ array("gzip, deflate\t,sdch", array(new AcceptHeaderItem('gzip'), new AcceptHeaderItem('deflate'), new AcceptHeaderItem('sdch'))),
+ array('"this;should,not=matter"', array(new AcceptHeaderItem('this;should,not=matter'))),
+ );
+ }
+
+ /**
+ * @dataProvider provideToStringData
+ */
+ public function testToString(array $items, $string)
+ {
+ $header = new AcceptHeader($items);
+ $this->assertEquals($string, (string) $header);
+ }
+
+ public function provideToStringData()
+ {
+ return array(
+ array(array(), ''),
+ array(array(new AcceptHeaderItem('gzip')), 'gzip'),
+ array(array(new AcceptHeaderItem('gzip'), new AcceptHeaderItem('deflate'), new AcceptHeaderItem('sdch')), 'gzip,deflate,sdch'),
+ array(array(new AcceptHeaderItem('this;should,not=matter')), 'this;should,not=matter'),
+ );
+ }
+
+ /**
+ * @dataProvider provideFilterData
+ */
+ public function testFilter($string, $filter, array $values)
+ {
+ $header = AcceptHeader::fromString($string)->filter($filter);
+ $this->assertEquals($values, array_keys($header->all()));
+ }
+
+ public function provideFilterData()
+ {
+ return array(
+ array('fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4', '/fr.*/', array('fr-FR', 'fr')),
+ );
+ }
+
+ /**
+ * @dataProvider provideSortingData
+ */
+ public function testSorting($string, array $values)
+ {
+ $header = AcceptHeader::fromString($string);
+ $this->assertEquals($values, array_keys($header->all()));
+ }
+
+ public function provideSortingData()
+ {
+ return array(
+ 'quality has priority' => array('*;q=0.3,ISO-8859-1,utf-8;q=0.7', array('ISO-8859-1', 'utf-8', '*')),
+ 'order matters when q is equal' => array('*;q=0.3,ISO-8859-1;q=0.7,utf-8;q=0.7', array('ISO-8859-1', 'utf-8', '*')),
+ 'order matters when q is equal2' => array('*;q=0.3,utf-8;q=0.7,ISO-8859-1;q=0.7', array('utf-8', 'ISO-8859-1', '*')),
+ );
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/ApacheRequestTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/ApacheRequestTest.php
new file mode 100644
index 0000000..157ab90
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/ApacheRequestTest.php
@@ -0,0 +1,93 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\ApacheRequest;
+
+class ApacheRequestTest extends TestCase
+{
+ /**
+ * @dataProvider provideServerVars
+ */
+ public function testUriMethods($server, $expectedRequestUri, $expectedBaseUrl, $expectedPathInfo)
+ {
+ $request = new ApacheRequest();
+ $request->server->replace($server);
+
+ $this->assertEquals($expectedRequestUri, $request->getRequestUri(), '->getRequestUri() is correct');
+ $this->assertEquals($expectedBaseUrl, $request->getBaseUrl(), '->getBaseUrl() is correct');
+ $this->assertEquals($expectedPathInfo, $request->getPathInfo(), '->getPathInfo() is correct');
+ }
+
+ public function provideServerVars()
+ {
+ return array(
+ array(
+ array(
+ 'REQUEST_URI' => '/foo/app_dev.php/bar',
+ 'SCRIPT_NAME' => '/foo/app_dev.php',
+ 'PATH_INFO' => '/bar',
+ ),
+ '/foo/app_dev.php/bar',
+ '/foo/app_dev.php',
+ '/bar',
+ ),
+ array(
+ array(
+ 'REQUEST_URI' => '/foo/bar',
+ 'SCRIPT_NAME' => '/foo/app_dev.php',
+ ),
+ '/foo/bar',
+ '/foo',
+ '/bar',
+ ),
+ array(
+ array(
+ 'REQUEST_URI' => '/app_dev.php/foo/bar',
+ 'SCRIPT_NAME' => '/app_dev.php',
+ 'PATH_INFO' => '/foo/bar',
+ ),
+ '/app_dev.php/foo/bar',
+ '/app_dev.php',
+ '/foo/bar',
+ ),
+ array(
+ array(
+ 'REQUEST_URI' => '/foo/bar',
+ 'SCRIPT_NAME' => '/app_dev.php',
+ ),
+ '/foo/bar',
+ '',
+ '/foo/bar',
+ ),
+ array(
+ array(
+ 'REQUEST_URI' => '/app_dev.php',
+ 'SCRIPT_NAME' => '/app_dev.php',
+ ),
+ '/app_dev.php',
+ '/app_dev.php',
+ '/',
+ ),
+ array(
+ array(
+ 'REQUEST_URI' => '/',
+ 'SCRIPT_NAME' => '/app_dev.php',
+ ),
+ '/',
+ '',
+ '/',
+ ),
+ );
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/BinaryFileResponseTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/BinaryFileResponseTest.php
new file mode 100644
index 0000000..1b9e589
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/BinaryFileResponseTest.php
@@ -0,0 +1,352 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests;
+
+use Symfony\Component\HttpFoundation\BinaryFileResponse;
+use Symfony\Component\HttpFoundation\File\Stream;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\ResponseHeaderBag;
+use Symfony\Component\HttpFoundation\Tests\File\FakeFile;
+
+class BinaryFileResponseTest extends ResponseTestCase
+{
+ public function testConstruction()
+ {
+ $file = __DIR__.'/../README.md';
+ $response = new BinaryFileResponse($file, 404, array('X-Header' => 'Foo'), true, null, true, true);
+ $this->assertEquals(404, $response->getStatusCode());
+ $this->assertEquals('Foo', $response->headers->get('X-Header'));
+ $this->assertTrue($response->headers->has('ETag'));
+ $this->assertTrue($response->headers->has('Last-Modified'));
+ $this->assertFalse($response->headers->has('Content-Disposition'));
+
+ $response = BinaryFileResponse::create($file, 404, array(), true, ResponseHeaderBag::DISPOSITION_INLINE);
+ $this->assertEquals(404, $response->getStatusCode());
+ $this->assertFalse($response->headers->has('ETag'));
+ $this->assertEquals('inline; filename="README.md"', $response->headers->get('Content-Disposition'));
+ }
+
+ public function testConstructWithNonAsciiFilename()
+ {
+ touch(sys_get_temp_dir().'/fööö.html');
+
+ $response = new BinaryFileResponse(sys_get_temp_dir().'/fööö.html', 200, array(), true, 'attachment');
+
+ @unlink(sys_get_temp_dir().'/fööö.html');
+
+ $this->assertSame('fööö.html', $response->getFile()->getFilename());
+ }
+
+ /**
+ * @expectedException \LogicException
+ */
+ public function testSetContent()
+ {
+ $response = new BinaryFileResponse(__FILE__);
+ $response->setContent('foo');
+ }
+
+ public function testGetContent()
+ {
+ $response = new BinaryFileResponse(__FILE__);
+ $this->assertFalse($response->getContent());
+ }
+
+ public function testSetContentDispositionGeneratesSafeFallbackFilename()
+ {
+ $response = new BinaryFileResponse(__FILE__);
+ $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'föö.html');
+
+ $this->assertSame('attachment; filename="f__.html"; filename*=utf-8\'\'f%C3%B6%C3%B6.html', $response->headers->get('Content-Disposition'));
+ }
+
+ public function testSetContentDispositionGeneratesSafeFallbackFilenameForWronglyEncodedFilename()
+ {
+ $response = new BinaryFileResponse(__FILE__);
+
+ $iso88591EncodedFilename = utf8_decode('föö.html');
+ $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, $iso88591EncodedFilename);
+
+ // the parameter filename* is invalid in this case (rawurldecode('f%F6%F6') does not provide a UTF-8 string but an ISO-8859-1 encoded one)
+ $this->assertSame('attachment; filename="f__.html"; filename*=utf-8\'\'f%F6%F6.html', $response->headers->get('Content-Disposition'));
+ }
+
+ /**
+ * @dataProvider provideRanges
+ */
+ public function testRequests($requestRange, $offset, $length, $responseRange)
+ {
+ $response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200, array('Content-Type' => 'application/octet-stream'))->setAutoEtag();
+
+ // do a request to get the ETag
+ $request = Request::create('/');
+ $response->prepare($request);
+ $etag = $response->headers->get('ETag');
+
+ // prepare a request for a range of the testing file
+ $request = Request::create('/');
+ $request->headers->set('If-Range', $etag);
+ $request->headers->set('Range', $requestRange);
+
+ $file = fopen(__DIR__.'/File/Fixtures/test.gif', 'r');
+ fseek($file, $offset);
+ $data = fread($file, $length);
+ fclose($file);
+
+ $this->expectOutputString($data);
+ $response = clone $response;
+ $response->prepare($request);
+ $response->sendContent();
+
+ $this->assertEquals(206, $response->getStatusCode());
+ $this->assertEquals($responseRange, $response->headers->get('Content-Range'));
+ $this->assertSame($length, $response->headers->get('Content-Length'));
+ }
+
+ /**
+ * @dataProvider provideRanges
+ */
+ public function testRequestsWithoutEtag($requestRange, $offset, $length, $responseRange)
+ {
+ $response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200, array('Content-Type' => 'application/octet-stream'));
+
+ // do a request to get the LastModified
+ $request = Request::create('/');
+ $response->prepare($request);
+ $lastModified = $response->headers->get('Last-Modified');
+
+ // prepare a request for a range of the testing file
+ $request = Request::create('/');
+ $request->headers->set('If-Range', $lastModified);
+ $request->headers->set('Range', $requestRange);
+
+ $file = fopen(__DIR__.'/File/Fixtures/test.gif', 'r');
+ fseek($file, $offset);
+ $data = fread($file, $length);
+ fclose($file);
+
+ $this->expectOutputString($data);
+ $response = clone $response;
+ $response->prepare($request);
+ $response->sendContent();
+
+ $this->assertEquals(206, $response->getStatusCode());
+ $this->assertEquals($responseRange, $response->headers->get('Content-Range'));
+ }
+
+ public function provideRanges()
+ {
+ return array(
+ array('bytes=1-4', 1, 4, 'bytes 1-4/35'),
+ array('bytes=-5', 30, 5, 'bytes 30-34/35'),
+ array('bytes=30-', 30, 5, 'bytes 30-34/35'),
+ array('bytes=30-30', 30, 1, 'bytes 30-30/35'),
+ array('bytes=30-34', 30, 5, 'bytes 30-34/35'),
+ );
+ }
+
+ public function testRangeRequestsWithoutLastModifiedDate()
+ {
+ // prevent auto last modified
+ $response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200, array('Content-Type' => 'application/octet-stream'), true, null, false, false);
+
+ // prepare a request for a range of the testing file
+ $request = Request::create('/');
+ $request->headers->set('If-Range', date('D, d M Y H:i:s').' GMT');
+ $request->headers->set('Range', 'bytes=1-4');
+
+ $this->expectOutputString(file_get_contents(__DIR__.'/File/Fixtures/test.gif'));
+ $response = clone $response;
+ $response->prepare($request);
+ $response->sendContent();
+
+ $this->assertEquals(200, $response->getStatusCode());
+ $this->assertNull($response->headers->get('Content-Range'));
+ }
+
+ /**
+ * @dataProvider provideFullFileRanges
+ */
+ public function testFullFileRequests($requestRange)
+ {
+ $response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200, array('Content-Type' => 'application/octet-stream'))->setAutoEtag();
+
+ // prepare a request for a range of the testing file
+ $request = Request::create('/');
+ $request->headers->set('Range', $requestRange);
+
+ $file = fopen(__DIR__.'/File/Fixtures/test.gif', 'r');
+ $data = fread($file, 35);
+ fclose($file);
+
+ $this->expectOutputString($data);
+ $response = clone $response;
+ $response->prepare($request);
+ $response->sendContent();
+
+ $this->assertEquals(200, $response->getStatusCode());
+ }
+
+ public function provideFullFileRanges()
+ {
+ return array(
+ array('bytes=0-'),
+ array('bytes=0-34'),
+ array('bytes=-35'),
+ // Syntactical invalid range-request should also return the full resource
+ array('bytes=20-10'),
+ array('bytes=50-40'),
+ );
+ }
+
+ /**
+ * @dataProvider provideInvalidRanges
+ */
+ public function testInvalidRequests($requestRange)
+ {
+ $response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200, array('Content-Type' => 'application/octet-stream'))->setAutoEtag();
+
+ // prepare a request for a range of the testing file
+ $request = Request::create('/');
+ $request->headers->set('Range', $requestRange);
+
+ $response = clone $response;
+ $response->prepare($request);
+ $response->sendContent();
+
+ $this->assertEquals(416, $response->getStatusCode());
+ $this->assertEquals('bytes */35', $response->headers->get('Content-Range'));
+ }
+
+ public function provideInvalidRanges()
+ {
+ return array(
+ array('bytes=-40'),
+ array('bytes=30-40'),
+ );
+ }
+
+ /**
+ * @dataProvider provideXSendfileFiles
+ */
+ public function testXSendfile($file)
+ {
+ $request = Request::create('/');
+ $request->headers->set('X-Sendfile-Type', 'X-Sendfile');
+
+ BinaryFileResponse::trustXSendfileTypeHeader();
+ $response = BinaryFileResponse::create($file, 200, array('Content-Type' => 'application/octet-stream'));
+ $response->prepare($request);
+
+ $this->expectOutputString('');
+ $response->sendContent();
+
+ $this->assertContains('README.md', $response->headers->get('X-Sendfile'));
+ }
+
+ public function provideXSendfileFiles()
+ {
+ return array(
+ array(__DIR__.'/../README.md'),
+ array('file://'.__DIR__.'/../README.md'),
+ );
+ }
+
+ /**
+ * @dataProvider getSampleXAccelMappings
+ */
+ public function testXAccelMapping($realpath, $mapping, $virtual)
+ {
+ $request = Request::create('/');
+ $request->headers->set('X-Sendfile-Type', 'X-Accel-Redirect');
+ $request->headers->set('X-Accel-Mapping', $mapping);
+
+ $file = new FakeFile($realpath, __DIR__.'/File/Fixtures/test');
+
+ BinaryFileResponse::trustXSendfileTypeHeader();
+ $response = new BinaryFileResponse($file, 200, array('Content-Type' => 'application/octet-stream'));
+ $reflection = new \ReflectionObject($response);
+ $property = $reflection->getProperty('file');
+ $property->setAccessible(true);
+ $property->setValue($response, $file);
+
+ $response->prepare($request);
+ $this->assertEquals($virtual, $response->headers->get('X-Accel-Redirect'));
+ }
+
+ public function testDeleteFileAfterSend()
+ {
+ $request = Request::create('/');
+
+ $path = __DIR__.'/File/Fixtures/to_delete';
+ touch($path);
+ $realPath = realpath($path);
+ $this->assertFileExists($realPath);
+
+ $response = new BinaryFileResponse($realPath, 200, array('Content-Type' => 'application/octet-stream'));
+ $response->deleteFileAfterSend(true);
+
+ $response->prepare($request);
+ $response->sendContent();
+
+ $this->assertFileNotExists($path);
+ }
+
+ public function testAcceptRangeOnUnsafeMethods()
+ {
+ $request = Request::create('/', 'POST');
+ $response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200, array('Content-Type' => 'application/octet-stream'));
+ $response->prepare($request);
+
+ $this->assertEquals('none', $response->headers->get('Accept-Ranges'));
+ }
+
+ public function testAcceptRangeNotOverriden()
+ {
+ $request = Request::create('/', 'POST');
+ $response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200, array('Content-Type' => 'application/octet-stream'));
+ $response->headers->set('Accept-Ranges', 'foo');
+ $response->prepare($request);
+
+ $this->assertEquals('foo', $response->headers->get('Accept-Ranges'));
+ }
+
+ public function getSampleXAccelMappings()
+ {
+ return array(
+ array('/var/www/var/www/files/foo.txt', '/var/www/=/files/', '/files/var/www/files/foo.txt'),
+ array('/home/foo/bar.txt', '/var/www/=/files/,/home/foo/=/baz/', '/baz/bar.txt'),
+ );
+ }
+
+ public function testStream()
+ {
+ $request = Request::create('/');
+ $response = new BinaryFileResponse(new Stream(__DIR__.'/../README.md'), 200, array('Content-Type' => 'text/plain'));
+ $response->prepare($request);
+
+ $this->assertNull($response->headers->get('Content-Length'));
+ }
+
+ protected function provideResponse()
+ {
+ return new BinaryFileResponse(__DIR__.'/../README.md', 200, array('Content-Type' => 'application/octet-stream'));
+ }
+
+ public static function tearDownAfterClass()
+ {
+ $path = __DIR__.'/../Fixtures/to_delete';
+ if (file_exists($path)) {
+ @unlink($path);
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/CookieTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/CookieTest.php
new file mode 100644
index 0000000..070b7dd
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/CookieTest.php
@@ -0,0 +1,223 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Cookie;
+
+/**
+ * CookieTest.
+ *
+ * @author John Kary <john@johnkary.net>
+ * @author Hugo Hamon <hugo.hamon@sensio.com>
+ *
+ * @group time-sensitive
+ */
+class CookieTest extends TestCase
+{
+ public function invalidNames()
+ {
+ return array(
+ array(''),
+ array(',MyName'),
+ array(';MyName'),
+ array(' MyName'),
+ array("\tMyName"),
+ array("\rMyName"),
+ array("\nMyName"),
+ array("\013MyName"),
+ array("\014MyName"),
+ );
+ }
+
+ /**
+ * @dataProvider invalidNames
+ * @expectedException \InvalidArgumentException
+ */
+ public function testInstantiationThrowsExceptionIfCookieNameContainsInvalidCharacters($name)
+ {
+ new Cookie($name);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testInvalidExpiration()
+ {
+ new Cookie('MyCookie', 'foo', 'bar');
+ }
+
+ public function testNegativeExpirationIsNotPossible()
+ {
+ $cookie = new Cookie('foo', 'bar', -100);
+
+ $this->assertSame(0, $cookie->getExpiresTime());
+ }
+
+ public function testGetValue()
+ {
+ $value = 'MyValue';
+ $cookie = new Cookie('MyCookie', $value);
+
+ $this->assertSame($value, $cookie->getValue(), '->getValue() returns the proper value');
+ }
+
+ public function testGetPath()
+ {
+ $cookie = new Cookie('foo', 'bar');
+
+ $this->assertSame('/', $cookie->getPath(), '->getPath() returns / as the default path');
+ }
+
+ public function testGetExpiresTime()
+ {
+ $cookie = new Cookie('foo', 'bar');
+
+ $this->assertEquals(0, $cookie->getExpiresTime(), '->getExpiresTime() returns the default expire date');
+
+ $cookie = new Cookie('foo', 'bar', $expire = time() + 3600);
+
+ $this->assertEquals($expire, $cookie->getExpiresTime(), '->getExpiresTime() returns the expire date');
+ }
+
+ public function testGetExpiresTimeIsCastToInt()
+ {
+ $cookie = new Cookie('foo', 'bar', 3600.9);
+
+ $this->assertSame(3600, $cookie->getExpiresTime(), '->getExpiresTime() returns the expire date as an integer');
+ }
+
+ public function testConstructorWithDateTime()
+ {
+ $expire = new \DateTime();
+ $cookie = new Cookie('foo', 'bar', $expire);
+
+ $this->assertEquals($expire->format('U'), $cookie->getExpiresTime(), '->getExpiresTime() returns the expire date');
+ }
+
+ /**
+ * @requires PHP 5.5
+ */
+ public function testConstructorWithDateTimeImmutable()
+ {
+ $expire = new \DateTimeImmutable();
+ $cookie = new Cookie('foo', 'bar', $expire);
+
+ $this->assertEquals($expire->format('U'), $cookie->getExpiresTime(), '->getExpiresTime() returns the expire date');
+ }
+
+ public function testGetExpiresTimeWithStringValue()
+ {
+ $value = '+1 day';
+ $cookie = new Cookie('foo', 'bar', $value);
+ $expire = strtotime($value);
+
+ $this->assertEquals($expire, $cookie->getExpiresTime(), '->getExpiresTime() returns the expire date', 1);
+ }
+
+ public function testGetDomain()
+ {
+ $cookie = new Cookie('foo', 'bar', 0, '/', '.myfoodomain.com');
+
+ $this->assertEquals('.myfoodomain.com', $cookie->getDomain(), '->getDomain() returns the domain name on which the cookie is valid');
+ }
+
+ public function testIsSecure()
+ {
+ $cookie = new Cookie('foo', 'bar', 0, '/', '.myfoodomain.com', true);
+
+ $this->assertTrue($cookie->isSecure(), '->isSecure() returns whether the cookie is transmitted over HTTPS');
+ }
+
+ public function testIsHttpOnly()
+ {
+ $cookie = new Cookie('foo', 'bar', 0, '/', '.myfoodomain.com', false, true);
+
+ $this->assertTrue($cookie->isHttpOnly(), '->isHttpOnly() returns whether the cookie is only transmitted over HTTP');
+ }
+
+ public function testCookieIsNotCleared()
+ {
+ $cookie = new Cookie('foo', 'bar', time() + 3600 * 24);
+
+ $this->assertFalse($cookie->isCleared(), '->isCleared() returns false if the cookie did not expire yet');
+ }
+
+ public function testCookieIsCleared()
+ {
+ $cookie = new Cookie('foo', 'bar', time() - 20);
+
+ $this->assertTrue($cookie->isCleared(), '->isCleared() returns true if the cookie has expired');
+ }
+
+ public function testToString()
+ {
+ $cookie = new Cookie('foo', 'bar', $expire = strtotime('Fri, 20-May-2011 15:25:52 GMT'), '/', '.myfoodomain.com', true);
+ $this->assertEquals('foo=bar; expires=Fri, 20-May-2011 15:25:52 GMT; max-age='.($expire - time()).'; path=/; domain=.myfoodomain.com; secure; httponly', (string) $cookie, '->__toString() returns string representation of the cookie');
+
+ $cookie = new Cookie('foo', 'bar with white spaces', strtotime('Fri, 20-May-2011 15:25:52 GMT'), '/', '.myfoodomain.com', true);
+ $this->assertEquals('foo=bar%20with%20white%20spaces; expires=Fri, 20-May-2011 15:25:52 GMT; max-age='.($expire - time()).'; path=/; domain=.myfoodomain.com; secure; httponly', (string) $cookie, '->__toString() encodes the value of the cookie according to RFC 3986 (white space = %20)');
+
+ $cookie = new Cookie('foo', null, 1, '/admin/', '.myfoodomain.com');
+ $this->assertEquals('foo=deleted; expires='.gmdate('D, d-M-Y H:i:s T', $expire = time() - 31536001).'; max-age='.($expire - time()).'; path=/admin/; domain=.myfoodomain.com; httponly', (string) $cookie, '->__toString() returns string representation of a cleared cookie if value is NULL');
+
+ $cookie = new Cookie('foo', 'bar', 0, '/', '');
+ $this->assertEquals('foo=bar; path=/; httponly', (string) $cookie);
+ }
+
+ public function testRawCookie()
+ {
+ $cookie = new Cookie('foo', 'b a r', 0, '/', null, false, false);
+ $this->assertFalse($cookie->isRaw());
+ $this->assertEquals('foo=b%20a%20r; path=/', (string) $cookie);
+
+ $cookie = new Cookie('foo', 'b+a+r', 0, '/', null, false, false, true);
+ $this->assertTrue($cookie->isRaw());
+ $this->assertEquals('foo=b+a+r; path=/', (string) $cookie);
+ }
+
+ public function testGetMaxAge()
+ {
+ $cookie = new Cookie('foo', 'bar');
+ $this->assertEquals(0, $cookie->getMaxAge());
+
+ $cookie = new Cookie('foo', 'bar', $expire = time() + 100);
+ $this->assertEquals($expire - time(), $cookie->getMaxAge());
+
+ $cookie = new Cookie('foo', 'bar', $expire = time() - 100);
+ $this->assertEquals($expire - time(), $cookie->getMaxAge());
+ }
+
+ public function testFromString()
+ {
+ $cookie = Cookie::fromString('foo=bar; expires=Fri, 20-May-2011 15:25:52 GMT; path=/; domain=.myfoodomain.com; secure; httponly');
+ $this->assertEquals(new Cookie('foo', 'bar', strtotime('Fri, 20-May-2011 15:25:52 GMT'), '/', '.myfoodomain.com', true, true, true), $cookie);
+
+ $cookie = Cookie::fromString('foo=bar', true);
+ $this->assertEquals(new Cookie('foo', 'bar', 0, '/', null, false, false), $cookie);
+ }
+
+ public function testFromStringWithHttpOnly()
+ {
+ $cookie = Cookie::fromString('foo=bar; expires=Fri, 20-May-2011 15:25:52 GMT; path=/; domain=.myfoodomain.com; secure; httponly');
+ $this->assertTrue($cookie->isHttpOnly());
+
+ $cookie = Cookie::fromString('foo=bar; expires=Fri, 20-May-2011 15:25:52 GMT; path=/; domain=.myfoodomain.com; secure');
+ $this->assertFalse($cookie->isHttpOnly());
+ }
+
+ public function testSameSiteAttributeIsCaseInsensitive()
+ {
+ $cookie = new Cookie('foo', 'bar', 0, '/', null, false, true, false, 'Lax');
+ $this->assertEquals('lax', $cookie->getSameSite());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/ExpressionRequestMatcherTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/ExpressionRequestMatcherTest.php
new file mode 100644
index 0000000..1152e46
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/ExpressionRequestMatcherTest.php
@@ -0,0 +1,69 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
+use Symfony\Component\HttpFoundation\ExpressionRequestMatcher;
+use Symfony\Component\HttpFoundation\Request;
+
+class ExpressionRequestMatcherTest extends TestCase
+{
+ /**
+ * @expectedException \LogicException
+ */
+ public function testWhenNoExpressionIsSet()
+ {
+ $expressionRequestMatcher = new ExpressionRequestMatcher();
+ $expressionRequestMatcher->matches(new Request());
+ }
+
+ /**
+ * @dataProvider provideExpressions
+ */
+ public function testMatchesWhenParentMatchesIsTrue($expression, $expected)
+ {
+ $request = Request::create('/foo');
+ $expressionRequestMatcher = new ExpressionRequestMatcher();
+
+ $expressionRequestMatcher->setExpression(new ExpressionLanguage(), $expression);
+ $this->assertSame($expected, $expressionRequestMatcher->matches($request));
+ }
+
+ /**
+ * @dataProvider provideExpressions
+ */
+ public function testMatchesWhenParentMatchesIsFalse($expression)
+ {
+ $request = Request::create('/foo');
+ $request->attributes->set('foo', 'foo');
+ $expressionRequestMatcher = new ExpressionRequestMatcher();
+ $expressionRequestMatcher->matchAttribute('foo', 'bar');
+
+ $expressionRequestMatcher->setExpression(new ExpressionLanguage(), $expression);
+ $this->assertFalse($expressionRequestMatcher->matches($request));
+ }
+
+ public function provideExpressions()
+ {
+ return array(
+ array('request.getMethod() == method', true),
+ array('request.getPathInfo() == path', true),
+ array('request.getHost() == host', true),
+ array('request.getClientIp() == ip', true),
+ array('request.attributes.all() == attributes', true),
+ array('request.getMethod() == method && request.getPathInfo() == path && request.getHost() == host && request.getClientIp() == ip && request.attributes.all() == attributes', true),
+ array('request.getMethod() != method', false),
+ array('request.getMethod() != method && request.getPathInfo() == path && request.getHost() == host && request.getClientIp() == ip && request.attributes.all() == attributes', false),
+ );
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/FakeFile.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/FakeFile.php
new file mode 100644
index 0000000..c415989
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/FakeFile.php
@@ -0,0 +1,45 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests\File;
+
+use Symfony\Component\HttpFoundation\File\File as OrigFile;
+
+class FakeFile extends OrigFile
+{
+ private $realpath;
+
+ public function __construct($realpath, $path)
+ {
+ $this->realpath = $realpath;
+ parent::__construct($path, false);
+ }
+
+ public function isReadable()
+ {
+ return true;
+ }
+
+ public function getRealpath()
+ {
+ return $this->realpath;
+ }
+
+ public function getSize()
+ {
+ return 42;
+ }
+
+ public function getMTime()
+ {
+ return time();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/FileTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/FileTest.php
new file mode 100644
index 0000000..dbd9c44
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/FileTest.php
@@ -0,0 +1,180 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests\File;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\File\File;
+use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser;
+
+class FileTest extends TestCase
+{
+ protected $file;
+
+ public function testGetMimeTypeUsesMimeTypeGuessers()
+ {
+ $file = new File(__DIR__.'/Fixtures/test.gif');
+ $guesser = $this->createMockGuesser($file->getPathname(), 'image/gif');
+
+ MimeTypeGuesser::getInstance()->register($guesser);
+
+ $this->assertEquals('image/gif', $file->getMimeType());
+ }
+
+ public function testGuessExtensionWithoutGuesser()
+ {
+ $file = new File(__DIR__.'/Fixtures/directory/.empty');
+
+ $this->assertNull($file->guessExtension());
+ }
+
+ public function testGuessExtensionIsBasedOnMimeType()
+ {
+ $file = new File(__DIR__.'/Fixtures/test');
+ $guesser = $this->createMockGuesser($file->getPathname(), 'image/gif');
+
+ MimeTypeGuesser::getInstance()->register($guesser);
+
+ $this->assertEquals('gif', $file->guessExtension());
+ }
+
+ /**
+ * @requires extension fileinfo
+ */
+ public function testGuessExtensionWithReset()
+ {
+ $file = new File(__DIR__.'/Fixtures/other-file.example');
+ $guesser = $this->createMockGuesser($file->getPathname(), 'image/gif');
+ MimeTypeGuesser::getInstance()->register($guesser);
+
+ $this->assertEquals('gif', $file->guessExtension());
+
+ MimeTypeGuesser::reset();
+
+ $this->assertNull($file->guessExtension());
+ }
+
+ public function testConstructWhenFileNotExists()
+ {
+ $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException');
+
+ new File(__DIR__.'/Fixtures/not_here');
+ }
+
+ public function testMove()
+ {
+ $path = __DIR__.'/Fixtures/test.copy.gif';
+ $targetDir = __DIR__.'/Fixtures/directory';
+ $targetPath = $targetDir.'/test.copy.gif';
+ @unlink($path);
+ @unlink($targetPath);
+ copy(__DIR__.'/Fixtures/test.gif', $path);
+
+ $file = new File($path);
+ $movedFile = $file->move($targetDir);
+ $this->assertInstanceOf('Symfony\Component\HttpFoundation\File\File', $movedFile);
+
+ $this->assertFileExists($targetPath);
+ $this->assertFileNotExists($path);
+ $this->assertEquals(realpath($targetPath), $movedFile->getRealPath());
+
+ @unlink($targetPath);
+ }
+
+ public function testMoveWithNewName()
+ {
+ $path = __DIR__.'/Fixtures/test.copy.gif';
+ $targetDir = __DIR__.'/Fixtures/directory';
+ $targetPath = $targetDir.'/test.newname.gif';
+ @unlink($path);
+ @unlink($targetPath);
+ copy(__DIR__.'/Fixtures/test.gif', $path);
+
+ $file = new File($path);
+ $movedFile = $file->move($targetDir, 'test.newname.gif');
+
+ $this->assertFileExists($targetPath);
+ $this->assertFileNotExists($path);
+ $this->assertEquals(realpath($targetPath), $movedFile->getRealPath());
+
+ @unlink($targetPath);
+ }
+
+ public function getFilenameFixtures()
+ {
+ return array(
+ array('original.gif', 'original.gif'),
+ array('..\\..\\original.gif', 'original.gif'),
+ array('../../original.gif', 'original.gif'),
+ array('файлfile.gif', 'файлfile.gif'),
+ array('..\\..\\файлfile.gif', 'файлfile.gif'),
+ array('../../файлfile.gif', 'файлfile.gif'),
+ );
+ }
+
+ /**
+ * @dataProvider getFilenameFixtures
+ */
+ public function testMoveWithNonLatinName($filename, $sanitizedFilename)
+ {
+ $path = __DIR__.'/Fixtures/'.$sanitizedFilename;
+ $targetDir = __DIR__.'/Fixtures/directory/';
+ $targetPath = $targetDir.$sanitizedFilename;
+ @unlink($path);
+ @unlink($targetPath);
+ copy(__DIR__.'/Fixtures/test.gif', $path);
+
+ $file = new File($path);
+ $movedFile = $file->move($targetDir, $filename);
+ $this->assertInstanceOf('Symfony\Component\HttpFoundation\File\File', $movedFile);
+
+ $this->assertFileExists($targetPath);
+ $this->assertFileNotExists($path);
+ $this->assertEquals(realpath($targetPath), $movedFile->getRealPath());
+
+ @unlink($targetPath);
+ }
+
+ public function testMoveToAnUnexistentDirectory()
+ {
+ $sourcePath = __DIR__.'/Fixtures/test.copy.gif';
+ $targetDir = __DIR__.'/Fixtures/directory/sub';
+ $targetPath = $targetDir.'/test.copy.gif';
+ @unlink($sourcePath);
+ @unlink($targetPath);
+ @rmdir($targetDir);
+ copy(__DIR__.'/Fixtures/test.gif', $sourcePath);
+
+ $file = new File($sourcePath);
+ $movedFile = $file->move($targetDir);
+
+ $this->assertFileExists($targetPath);
+ $this->assertFileNotExists($sourcePath);
+ $this->assertEquals(realpath($targetPath), $movedFile->getRealPath());
+
+ @unlink($sourcePath);
+ @unlink($targetPath);
+ @rmdir($targetDir);
+ }
+
+ protected function createMockGuesser($path, $mimeType)
+ {
+ $guesser = $this->getMockBuilder('Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface')->getMock();
+ $guesser
+ ->expects($this->once())
+ ->method('guess')
+ ->with($this->equalTo($path))
+ ->will($this->returnValue($mimeType))
+ ;
+
+ return $guesser;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/Fixtures/.unknownextension b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/Fixtures/.unknownextension
new file mode 100644
index 0000000..4d1ae35
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/Fixtures/.unknownextension
@@ -0,0 +1 @@
+f \ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/Fixtures/directory/.empty b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/Fixtures/directory/.empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/Fixtures/directory/.empty
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/Fixtures/other-file.example b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/Fixtures/other-file.example
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/Fixtures/other-file.example
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/Fixtures/test b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/Fixtures/test
new file mode 100644
index 0000000..b636f4b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/Fixtures/test
Binary files differ
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/Fixtures/test.gif b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/Fixtures/test.gif
new file mode 100644
index 0000000..b636f4b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/Fixtures/test.gif
Binary files differ
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/MimeType/MimeTypeTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/MimeType/MimeTypeTest.php
new file mode 100644
index 0000000..b3f1f02
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/MimeType/MimeTypeTest.php
@@ -0,0 +1,90 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests\File\MimeType;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser;
+use Symfony\Component\HttpFoundation\File\MimeType\FileBinaryMimeTypeGuesser;
+
+/**
+ * @requires extension fileinfo
+ */
+class MimeTypeTest extends TestCase
+{
+ protected $path;
+
+ public function testGuessImageWithoutExtension()
+ {
+ $this->assertEquals('image/gif', MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test'));
+ }
+
+ public function testGuessImageWithDirectory()
+ {
+ $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException');
+
+ MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/directory');
+ }
+
+ public function testGuessImageWithFileBinaryMimeTypeGuesser()
+ {
+ $guesser = MimeTypeGuesser::getInstance();
+ $guesser->register(new FileBinaryMimeTypeGuesser());
+ $this->assertEquals('image/gif', MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test'));
+ }
+
+ public function testGuessImageWithKnownExtension()
+ {
+ $this->assertEquals('image/gif', MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test.gif'));
+ }
+
+ public function testGuessFileWithUnknownExtension()
+ {
+ $this->assertEquals('application/octet-stream', MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/.unknownextension'));
+ }
+
+ public function testGuessWithIncorrectPath()
+ {
+ $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException');
+ MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/not_here');
+ }
+
+ public function testGuessWithNonReadablePath()
+ {
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->markTestSkipped('Can not verify chmod operations on Windows');
+ }
+
+ if (!getenv('USER') || 'root' === getenv('USER')) {
+ $this->markTestSkipped('This test will fail if run under superuser');
+ }
+
+ $path = __DIR__.'/../Fixtures/to_delete';
+ touch($path);
+ @chmod($path, 0333);
+
+ if ('0333' == substr(sprintf('%o', fileperms($path)), -4)) {
+ $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException');
+ MimeTypeGuesser::getInstance()->guess($path);
+ } else {
+ $this->markTestSkipped('Can not verify chmod operations, change of file permissions failed');
+ }
+ }
+
+ public static function tearDownAfterClass()
+ {
+ $path = __DIR__.'/../Fixtures/to_delete';
+ if (file_exists($path)) {
+ @chmod($path, 0666);
+ @unlink($path);
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/UploadedFileTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/UploadedFileTest.php
new file mode 100644
index 0000000..36f122f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/File/UploadedFileTest.php
@@ -0,0 +1,273 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests\File;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\File\UploadedFile;
+
+class UploadedFileTest extends TestCase
+{
+ protected function setUp()
+ {
+ if (!ini_get('file_uploads')) {
+ $this->markTestSkipped('file_uploads is disabled in php.ini');
+ }
+ }
+
+ public function testConstructWhenFileNotExists()
+ {
+ $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException');
+
+ new UploadedFile(
+ __DIR__.'/Fixtures/not_here',
+ 'original.gif',
+ null
+ );
+ }
+
+ public function testFileUploadsWithNoMimeType()
+ {
+ $file = new UploadedFile(
+ __DIR__.'/Fixtures/test.gif',
+ 'original.gif',
+ null,
+ filesize(__DIR__.'/Fixtures/test.gif'),
+ UPLOAD_ERR_OK
+ );
+
+ $this->assertEquals('application/octet-stream', $file->getClientMimeType());
+
+ if (extension_loaded('fileinfo')) {
+ $this->assertEquals('image/gif', $file->getMimeType());
+ }
+ }
+
+ public function testFileUploadsWithUnknownMimeType()
+ {
+ $file = new UploadedFile(
+ __DIR__.'/Fixtures/.unknownextension',
+ 'original.gif',
+ null,
+ filesize(__DIR__.'/Fixtures/.unknownextension'),
+ UPLOAD_ERR_OK
+ );
+
+ $this->assertEquals('application/octet-stream', $file->getClientMimeType());
+ }
+
+ public function testGuessClientExtension()
+ {
+ $file = new UploadedFile(
+ __DIR__.'/Fixtures/test.gif',
+ 'original.gif',
+ 'image/gif',
+ filesize(__DIR__.'/Fixtures/test.gif'),
+ null
+ );
+
+ $this->assertEquals('gif', $file->guessClientExtension());
+ }
+
+ public function testGuessClientExtensionWithIncorrectMimeType()
+ {
+ $file = new UploadedFile(
+ __DIR__.'/Fixtures/test.gif',
+ 'original.gif',
+ 'image/jpeg',
+ filesize(__DIR__.'/Fixtures/test.gif'),
+ null
+ );
+
+ $this->assertEquals('jpeg', $file->guessClientExtension());
+ }
+
+ public function testErrorIsOkByDefault()
+ {
+ $file = new UploadedFile(
+ __DIR__.'/Fixtures/test.gif',
+ 'original.gif',
+ 'image/gif',
+ filesize(__DIR__.'/Fixtures/test.gif'),
+ null
+ );
+
+ $this->assertEquals(UPLOAD_ERR_OK, $file->getError());
+ }
+
+ public function testGetClientOriginalName()
+ {
+ $file = new UploadedFile(
+ __DIR__.'/Fixtures/test.gif',
+ 'original.gif',
+ 'image/gif',
+ filesize(__DIR__.'/Fixtures/test.gif'),
+ null
+ );
+
+ $this->assertEquals('original.gif', $file->getClientOriginalName());
+ }
+
+ public function testGetClientOriginalExtension()
+ {
+ $file = new UploadedFile(
+ __DIR__.'/Fixtures/test.gif',
+ 'original.gif',
+ 'image/gif',
+ filesize(__DIR__.'/Fixtures/test.gif'),
+ null
+ );
+
+ $this->assertEquals('gif', $file->getClientOriginalExtension());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\HttpFoundation\File\Exception\FileException
+ */
+ public function testMoveLocalFileIsNotAllowed()
+ {
+ $file = new UploadedFile(
+ __DIR__.'/Fixtures/test.gif',
+ 'original.gif',
+ 'image/gif',
+ filesize(__DIR__.'/Fixtures/test.gif'),
+ UPLOAD_ERR_OK
+ );
+
+ $movedFile = $file->move(__DIR__.'/Fixtures/directory');
+ }
+
+ public function testMoveLocalFileIsAllowedInTestMode()
+ {
+ $path = __DIR__.'/Fixtures/test.copy.gif';
+ $targetDir = __DIR__.'/Fixtures/directory';
+ $targetPath = $targetDir.'/test.copy.gif';
+ @unlink($path);
+ @unlink($targetPath);
+ copy(__DIR__.'/Fixtures/test.gif', $path);
+
+ $file = new UploadedFile(
+ $path,
+ 'original.gif',
+ 'image/gif',
+ filesize($path),
+ UPLOAD_ERR_OK,
+ true
+ );
+
+ $movedFile = $file->move(__DIR__.'/Fixtures/directory');
+
+ $this->assertFileExists($targetPath);
+ $this->assertFileNotExists($path);
+ $this->assertEquals(realpath($targetPath), $movedFile->getRealPath());
+
+ @unlink($targetPath);
+ }
+
+ public function testGetClientOriginalNameSanitizeFilename()
+ {
+ $file = new UploadedFile(
+ __DIR__.'/Fixtures/test.gif',
+ '../../original.gif',
+ 'image/gif',
+ filesize(__DIR__.'/Fixtures/test.gif'),
+ null
+ );
+
+ $this->assertEquals('original.gif', $file->getClientOriginalName());
+ }
+
+ public function testGetSize()
+ {
+ $file = new UploadedFile(
+ __DIR__.'/Fixtures/test.gif',
+ 'original.gif',
+ 'image/gif',
+ filesize(__DIR__.'/Fixtures/test.gif'),
+ null
+ );
+
+ $this->assertEquals(filesize(__DIR__.'/Fixtures/test.gif'), $file->getSize());
+
+ $file = new UploadedFile(
+ __DIR__.'/Fixtures/test',
+ 'original.gif',
+ 'image/gif'
+ );
+
+ $this->assertEquals(filesize(__DIR__.'/Fixtures/test'), $file->getSize());
+ }
+
+ public function testGetExtension()
+ {
+ $file = new UploadedFile(
+ __DIR__.'/Fixtures/test.gif',
+ 'original.gif',
+ null
+ );
+
+ $this->assertEquals('gif', $file->getExtension());
+ }
+
+ public function testIsValid()
+ {
+ $file = new UploadedFile(
+ __DIR__.'/Fixtures/test.gif',
+ 'original.gif',
+ null,
+ filesize(__DIR__.'/Fixtures/test.gif'),
+ UPLOAD_ERR_OK,
+ true
+ );
+
+ $this->assertTrue($file->isValid());
+ }
+
+ /**
+ * @dataProvider uploadedFileErrorProvider
+ */
+ public function testIsInvalidOnUploadError($error)
+ {
+ $file = new UploadedFile(
+ __DIR__.'/Fixtures/test.gif',
+ 'original.gif',
+ null,
+ filesize(__DIR__.'/Fixtures/test.gif'),
+ $error
+ );
+
+ $this->assertFalse($file->isValid());
+ }
+
+ public function uploadedFileErrorProvider()
+ {
+ return array(
+ array(UPLOAD_ERR_INI_SIZE),
+ array(UPLOAD_ERR_FORM_SIZE),
+ array(UPLOAD_ERR_PARTIAL),
+ array(UPLOAD_ERR_NO_TMP_DIR),
+ array(UPLOAD_ERR_EXTENSION),
+ );
+ }
+
+ public function testIsInvalidIfNotHttpUpload()
+ {
+ $file = new UploadedFile(
+ __DIR__.'/Fixtures/test.gif',
+ 'original.gif',
+ null,
+ filesize(__DIR__.'/Fixtures/test.gif'),
+ UPLOAD_ERR_OK
+ );
+
+ $this->assertFalse($file->isValid());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/FileBagTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/FileBagTest.php
new file mode 100644
index 0000000..b1bbba0
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/FileBagTest.php
@@ -0,0 +1,175 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\File\UploadedFile;
+use Symfony\Component\HttpFoundation\FileBag;
+
+/**
+ * FileBagTest.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Bulat Shakirzyanov <mallluhuct@gmail.com>
+ */
+class FileBagTest extends TestCase
+{
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testFileMustBeAnArrayOrUploadedFile()
+ {
+ new FileBag(array('file' => 'foo'));
+ }
+
+ public function testShouldConvertsUploadedFiles()
+ {
+ $tmpFile = $this->createTempFile();
+ $file = new UploadedFile($tmpFile, basename($tmpFile), 'text/plain', 100, 0);
+
+ $bag = new FileBag(array('file' => array(
+ 'name' => basename($tmpFile),
+ 'type' => 'text/plain',
+ 'tmp_name' => $tmpFile,
+ 'error' => 0,
+ 'size' => 100,
+ )));
+
+ $this->assertEquals($file, $bag->get('file'));
+ }
+
+ public function testShouldSetEmptyUploadedFilesToNull()
+ {
+ $bag = new FileBag(array('file' => array(
+ 'name' => '',
+ 'type' => '',
+ 'tmp_name' => '',
+ 'error' => UPLOAD_ERR_NO_FILE,
+ 'size' => 0,
+ )));
+
+ $this->assertNull($bag->get('file'));
+ }
+
+ public function testShouldRemoveEmptyUploadedFilesForMultiUpload()
+ {
+ $bag = new FileBag(array('files' => array(
+ 'name' => array(''),
+ 'type' => array(''),
+ 'tmp_name' => array(''),
+ 'error' => array(UPLOAD_ERR_NO_FILE),
+ 'size' => array(0),
+ )));
+
+ $this->assertSame(array(), $bag->get('files'));
+ }
+
+ public function testShouldNotRemoveEmptyUploadedFilesForAssociativeArray()
+ {
+ $bag = new FileBag(array('files' => array(
+ 'name' => array('file1' => ''),
+ 'type' => array('file1' => ''),
+ 'tmp_name' => array('file1' => ''),
+ 'error' => array('file1' => UPLOAD_ERR_NO_FILE),
+ 'size' => array('file1' => 0),
+ )));
+
+ $this->assertSame(array('file1' => null), $bag->get('files'));
+ }
+
+ public function testShouldConvertUploadedFilesWithPhpBug()
+ {
+ $tmpFile = $this->createTempFile();
+ $file = new UploadedFile($tmpFile, basename($tmpFile), 'text/plain', 100, 0);
+
+ $bag = new FileBag(array(
+ 'child' => array(
+ 'name' => array(
+ 'file' => basename($tmpFile),
+ ),
+ 'type' => array(
+ 'file' => 'text/plain',
+ ),
+ 'tmp_name' => array(
+ 'file' => $tmpFile,
+ ),
+ 'error' => array(
+ 'file' => 0,
+ ),
+ 'size' => array(
+ 'file' => 100,
+ ),
+ ),
+ ));
+
+ $files = $bag->all();
+ $this->assertEquals($file, $files['child']['file']);
+ }
+
+ public function testShouldConvertNestedUploadedFilesWithPhpBug()
+ {
+ $tmpFile = $this->createTempFile();
+ $file = new UploadedFile($tmpFile, basename($tmpFile), 'text/plain', 100, 0);
+
+ $bag = new FileBag(array(
+ 'child' => array(
+ 'name' => array(
+ 'sub' => array('file' => basename($tmpFile)),
+ ),
+ 'type' => array(
+ 'sub' => array('file' => 'text/plain'),
+ ),
+ 'tmp_name' => array(
+ 'sub' => array('file' => $tmpFile),
+ ),
+ 'error' => array(
+ 'sub' => array('file' => 0),
+ ),
+ 'size' => array(
+ 'sub' => array('file' => 100),
+ ),
+ ),
+ ));
+
+ $files = $bag->all();
+ $this->assertEquals($file, $files['child']['sub']['file']);
+ }
+
+ public function testShouldNotConvertNestedUploadedFiles()
+ {
+ $tmpFile = $this->createTempFile();
+ $file = new UploadedFile($tmpFile, basename($tmpFile), 'text/plain', 100, 0);
+ $bag = new FileBag(array('image' => array('file' => $file)));
+
+ $files = $bag->all();
+ $this->assertEquals($file, $files['image']['file']);
+ }
+
+ protected function createTempFile()
+ {
+ return tempnam(sys_get_temp_dir().'/form_test', 'FormTest');
+ }
+
+ protected function setUp()
+ {
+ mkdir(sys_get_temp_dir().'/form_test', 0777, true);
+ }
+
+ protected function tearDown()
+ {
+ foreach (glob(sys_get_temp_dir().'/form_test/*') as $file) {
+ unlink($file);
+ }
+
+ rmdir(sys_get_temp_dir().'/form_test');
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/HeaderBagTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/HeaderBagTest.php
new file mode 100644
index 0000000..6d19ceb
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/HeaderBagTest.php
@@ -0,0 +1,205 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\HeaderBag;
+
+class HeaderBagTest extends TestCase
+{
+ public function testConstructor()
+ {
+ $bag = new HeaderBag(array('foo' => 'bar'));
+ $this->assertTrue($bag->has('foo'));
+ }
+
+ public function testToStringNull()
+ {
+ $bag = new HeaderBag();
+ $this->assertEquals('', $bag->__toString());
+ }
+
+ public function testToStringNotNull()
+ {
+ $bag = new HeaderBag(array('foo' => 'bar'));
+ $this->assertEquals("Foo: bar\r\n", $bag->__toString());
+ }
+
+ public function testKeys()
+ {
+ $bag = new HeaderBag(array('foo' => 'bar'));
+ $keys = $bag->keys();
+ $this->assertEquals('foo', $keys[0]);
+ }
+
+ public function testGetDate()
+ {
+ $bag = new HeaderBag(array('foo' => 'Tue, 4 Sep 2012 20:00:00 +0200'));
+ $headerDate = $bag->getDate('foo');
+ $this->assertInstanceOf('DateTime', $headerDate);
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ */
+ public function testGetDateException()
+ {
+ $bag = new HeaderBag(array('foo' => 'Tue'));
+ $headerDate = $bag->getDate('foo');
+ }
+
+ public function testGetCacheControlHeader()
+ {
+ $bag = new HeaderBag();
+ $bag->addCacheControlDirective('public', '#a');
+ $this->assertTrue($bag->hasCacheControlDirective('public'));
+ $this->assertEquals('#a', $bag->getCacheControlDirective('public'));
+ }
+
+ public function testAll()
+ {
+ $bag = new HeaderBag(array('foo' => 'bar'));
+ $this->assertEquals(array('foo' => array('bar')), $bag->all(), '->all() gets all the input');
+
+ $bag = new HeaderBag(array('FOO' => 'BAR'));
+ $this->assertEquals(array('foo' => array('BAR')), $bag->all(), '->all() gets all the input key are lower case');
+ }
+
+ public function testReplace()
+ {
+ $bag = new HeaderBag(array('foo' => 'bar'));
+
+ $bag->replace(array('NOPE' => 'BAR'));
+ $this->assertEquals(array('nope' => array('BAR')), $bag->all(), '->replace() replaces the input with the argument');
+ $this->assertFalse($bag->has('foo'), '->replace() overrides previously set the input');
+ }
+
+ public function testGet()
+ {
+ $bag = new HeaderBag(array('foo' => 'bar', 'fuzz' => 'bizz'));
+ $this->assertEquals('bar', $bag->get('foo'), '->get return current value');
+ $this->assertEquals('bar', $bag->get('FoO'), '->get key in case insensitive');
+ $this->assertEquals(array('bar'), $bag->get('foo', 'nope', false), '->get return the value as array');
+
+ // defaults
+ $this->assertNull($bag->get('none'), '->get unknown values returns null');
+ $this->assertEquals('default', $bag->get('none', 'default'), '->get unknown values returns default');
+ $this->assertEquals(array('default'), $bag->get('none', 'default', false), '->get unknown values returns default as array');
+
+ $bag->set('foo', 'bor', false);
+ $this->assertEquals('bar', $bag->get('foo'), '->get return first value');
+ $this->assertEquals(array('bar', 'bor'), $bag->get('foo', 'nope', false), '->get return all values as array');
+ }
+
+ public function testSetAssociativeArray()
+ {
+ $bag = new HeaderBag();
+ $bag->set('foo', array('bad-assoc-index' => 'value'));
+ $this->assertSame('value', $bag->get('foo'));
+ $this->assertEquals(array('value'), $bag->get('foo', 'nope', false), 'assoc indices of multi-valued headers are ignored');
+ }
+
+ public function testContains()
+ {
+ $bag = new HeaderBag(array('foo' => 'bar', 'fuzz' => 'bizz'));
+ $this->assertTrue($bag->contains('foo', 'bar'), '->contains first value');
+ $this->assertTrue($bag->contains('fuzz', 'bizz'), '->contains second value');
+ $this->assertFalse($bag->contains('nope', 'nope'), '->contains unknown value');
+ $this->assertFalse($bag->contains('foo', 'nope'), '->contains unknown value');
+
+ // Multiple values
+ $bag->set('foo', 'bor', false);
+ $this->assertTrue($bag->contains('foo', 'bar'), '->contains first value');
+ $this->assertTrue($bag->contains('foo', 'bor'), '->contains second value');
+ $this->assertFalse($bag->contains('foo', 'nope'), '->contains unknown value');
+ }
+
+ public function testCacheControlDirectiveAccessors()
+ {
+ $bag = new HeaderBag();
+ $bag->addCacheControlDirective('public');
+
+ $this->assertTrue($bag->hasCacheControlDirective('public'));
+ $this->assertTrue($bag->getCacheControlDirective('public'));
+ $this->assertEquals('public', $bag->get('cache-control'));
+
+ $bag->addCacheControlDirective('max-age', 10);
+ $this->assertTrue($bag->hasCacheControlDirective('max-age'));
+ $this->assertEquals(10, $bag->getCacheControlDirective('max-age'));
+ $this->assertEquals('max-age=10, public', $bag->get('cache-control'));
+
+ $bag->removeCacheControlDirective('max-age');
+ $this->assertFalse($bag->hasCacheControlDirective('max-age'));
+ }
+
+ public function testCacheControlDirectiveParsing()
+ {
+ $bag = new HeaderBag(array('cache-control' => 'public, max-age=10'));
+ $this->assertTrue($bag->hasCacheControlDirective('public'));
+ $this->assertTrue($bag->getCacheControlDirective('public'));
+
+ $this->assertTrue($bag->hasCacheControlDirective('max-age'));
+ $this->assertEquals(10, $bag->getCacheControlDirective('max-age'));
+
+ $bag->addCacheControlDirective('s-maxage', 100);
+ $this->assertEquals('max-age=10, public, s-maxage=100', $bag->get('cache-control'));
+ }
+
+ public function testCacheControlDirectiveParsingQuotedZero()
+ {
+ $bag = new HeaderBag(array('cache-control' => 'max-age="0"'));
+ $this->assertTrue($bag->hasCacheControlDirective('max-age'));
+ $this->assertEquals(0, $bag->getCacheControlDirective('max-age'));
+ }
+
+ public function testCacheControlDirectiveOverrideWithReplace()
+ {
+ $bag = new HeaderBag(array('cache-control' => 'private, max-age=100'));
+ $bag->replace(array('cache-control' => 'public, max-age=10'));
+ $this->assertTrue($bag->hasCacheControlDirective('public'));
+ $this->assertTrue($bag->getCacheControlDirective('public'));
+
+ $this->assertTrue($bag->hasCacheControlDirective('max-age'));
+ $this->assertEquals(10, $bag->getCacheControlDirective('max-age'));
+ }
+
+ public function testCacheControlClone()
+ {
+ $headers = array('foo' => 'bar');
+ $bag1 = new HeaderBag($headers);
+ $bag2 = new HeaderBag($bag1->all());
+
+ $this->assertEquals($bag1->all(), $bag2->all());
+ }
+
+ public function testGetIterator()
+ {
+ $headers = array('foo' => 'bar', 'hello' => 'world', 'third' => 'charm');
+ $headerBag = new HeaderBag($headers);
+
+ $i = 0;
+ foreach ($headerBag as $key => $val) {
+ ++$i;
+ $this->assertEquals(array($headers[$key]), $val);
+ }
+
+ $this->assertEquals(count($headers), $i);
+ }
+
+ public function testCount()
+ {
+ $headers = array('foo' => 'bar', 'HELLO' => 'WORLD');
+ $headerBag = new HeaderBag($headers);
+
+ $this->assertCount(count($headers), $headerBag);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/IpUtilsTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/IpUtilsTest.php
new file mode 100644
index 0000000..7a93f99
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/IpUtilsTest.php
@@ -0,0 +1,104 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\IpUtils;
+
+class IpUtilsTest extends TestCase
+{
+ /**
+ * @dataProvider getIpv4Data
+ */
+ public function testIpv4($matches, $remoteAddr, $cidr)
+ {
+ $this->assertSame($matches, IpUtils::checkIp($remoteAddr, $cidr));
+ }
+
+ public function getIpv4Data()
+ {
+ return array(
+ array(true, '192.168.1.1', '192.168.1.1'),
+ array(true, '192.168.1.1', '192.168.1.1/1'),
+ array(true, '192.168.1.1', '192.168.1.0/24'),
+ array(false, '192.168.1.1', '1.2.3.4/1'),
+ array(false, '192.168.1.1', '192.168.1.1/33'), // invalid subnet
+ array(true, '192.168.1.1', array('1.2.3.4/1', '192.168.1.0/24')),
+ array(true, '192.168.1.1', array('192.168.1.0/24', '1.2.3.4/1')),
+ array(false, '192.168.1.1', array('1.2.3.4/1', '4.3.2.1/1')),
+ array(true, '1.2.3.4', '0.0.0.0/0'),
+ array(true, '1.2.3.4', '192.168.1.0/0'),
+ array(false, '1.2.3.4', '256.256.256/0'), // invalid CIDR notation
+ array(false, 'an_invalid_ip', '192.168.1.0/24'),
+ );
+ }
+
+ /**
+ * @dataProvider getIpv6Data
+ */
+ public function testIpv6($matches, $remoteAddr, $cidr)
+ {
+ if (!defined('AF_INET6')) {
+ $this->markTestSkipped('Only works when PHP is compiled without the option "disable-ipv6".');
+ }
+
+ $this->assertSame($matches, IpUtils::checkIp($remoteAddr, $cidr));
+ }
+
+ public function getIpv6Data()
+ {
+ return array(
+ array(true, '2a01:198:603:0:396e:4789:8e99:890f', '2a01:198:603:0::/65'),
+ array(false, '2a00:198:603:0:396e:4789:8e99:890f', '2a01:198:603:0::/65'),
+ array(false, '2a01:198:603:0:396e:4789:8e99:890f', '::1'),
+ array(true, '0:0:0:0:0:0:0:1', '::1'),
+ array(false, '0:0:603:0:396e:4789:8e99:0001', '::1'),
+ array(true, '0:0:603:0:396e:4789:8e99:0001', '::/0'),
+ array(true, '0:0:603:0:396e:4789:8e99:0001', '2a01:198:603:0::/0'),
+ array(true, '2a01:198:603:0:396e:4789:8e99:890f', array('::1', '2a01:198:603:0::/65')),
+ array(true, '2a01:198:603:0:396e:4789:8e99:890f', array('2a01:198:603:0::/65', '::1')),
+ array(false, '2a01:198:603:0:396e:4789:8e99:890f', array('::1', '1a01:198:603:0::/65')),
+ array(false, '}__test|O:21:&quot;JDatabaseDriverMysqli&quot;:3:{s:2', '::1'),
+ array(false, '2a01:198:603:0:396e:4789:8e99:890f', 'unknown'),
+ );
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ * @requires extension sockets
+ */
+ public function testAnIpv6WithOptionDisabledIpv6()
+ {
+ if (defined('AF_INET6')) {
+ $this->markTestSkipped('Only works when PHP is compiled with the option "disable-ipv6".');
+ }
+
+ IpUtils::checkIp('2a01:198:603:0:396e:4789:8e99:890f', '2a01:198:603:0::/65');
+ }
+
+ /**
+ * @dataProvider invalidIpAddressData
+ */
+ public function testInvalidIpAddressesDoNotMatch($requestIp, $proxyIp)
+ {
+ $this->assertFalse(IpUtils::checkIp4($requestIp, $proxyIp));
+ }
+
+ public function invalidIpAddressData()
+ {
+ return array(
+ 'invalid proxy wildcard' => array('192.168.20.13', '*'),
+ 'invalid proxy missing netmask' => array('192.168.20.13', '0.0.0.0'),
+ 'invalid request IP with invalid proxy wildcard' => array('0.0.0.0', '*'),
+ );
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/JsonResponseTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/JsonResponseTest.php
new file mode 100644
index 0000000..201839f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/JsonResponseTest.php
@@ -0,0 +1,257 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\JsonResponse;
+
+class JsonResponseTest extends TestCase
+{
+ public function testConstructorEmptyCreatesJsonObject()
+ {
+ $response = new JsonResponse();
+ $this->assertSame('{}', $response->getContent());
+ }
+
+ public function testConstructorWithArrayCreatesJsonArray()
+ {
+ $response = new JsonResponse(array(0, 1, 2, 3));
+ $this->assertSame('[0,1,2,3]', $response->getContent());
+ }
+
+ public function testConstructorWithAssocArrayCreatesJsonObject()
+ {
+ $response = new JsonResponse(array('foo' => 'bar'));
+ $this->assertSame('{"foo":"bar"}', $response->getContent());
+ }
+
+ public function testConstructorWithSimpleTypes()
+ {
+ $response = new JsonResponse('foo');
+ $this->assertSame('"foo"', $response->getContent());
+
+ $response = new JsonResponse(0);
+ $this->assertSame('0', $response->getContent());
+
+ $response = new JsonResponse(0.1);
+ $this->assertSame('0.1', $response->getContent());
+
+ $response = new JsonResponse(true);
+ $this->assertSame('true', $response->getContent());
+ }
+
+ public function testConstructorWithCustomStatus()
+ {
+ $response = new JsonResponse(array(), 202);
+ $this->assertSame(202, $response->getStatusCode());
+ }
+
+ public function testConstructorAddsContentTypeHeader()
+ {
+ $response = new JsonResponse();
+ $this->assertSame('application/json', $response->headers->get('Content-Type'));
+ }
+
+ public function testConstructorWithCustomHeaders()
+ {
+ $response = new JsonResponse(array(), 200, array('ETag' => 'foo'));
+ $this->assertSame('application/json', $response->headers->get('Content-Type'));
+ $this->assertSame('foo', $response->headers->get('ETag'));
+ }
+
+ public function testConstructorWithCustomContentType()
+ {
+ $headers = array('Content-Type' => 'application/vnd.acme.blog-v1+json');
+
+ $response = new JsonResponse(array(), 200, $headers);
+ $this->assertSame('application/vnd.acme.blog-v1+json', $response->headers->get('Content-Type'));
+ }
+
+ public function testSetJson()
+ {
+ $response = new JsonResponse('1', 200, array(), true);
+ $this->assertEquals('1', $response->getContent());
+
+ $response = new JsonResponse('[1]', 200, array(), true);
+ $this->assertEquals('[1]', $response->getContent());
+
+ $response = new JsonResponse(null, 200, array());
+ $response->setJson('true');
+ $this->assertEquals('true', $response->getContent());
+ }
+
+ public function testCreate()
+ {
+ $response = JsonResponse::create(array('foo' => 'bar'), 204);
+
+ $this->assertInstanceOf('Symfony\Component\HttpFoundation\JsonResponse', $response);
+ $this->assertEquals('{"foo":"bar"}', $response->getContent());
+ $this->assertEquals(204, $response->getStatusCode());
+ }
+
+ public function testStaticCreateEmptyJsonObject()
+ {
+ $response = JsonResponse::create();
+ $this->assertInstanceOf('Symfony\Component\HttpFoundation\JsonResponse', $response);
+ $this->assertSame('{}', $response->getContent());
+ }
+
+ public function testStaticCreateJsonArray()
+ {
+ $response = JsonResponse::create(array(0, 1, 2, 3));
+ $this->assertInstanceOf('Symfony\Component\HttpFoundation\JsonResponse', $response);
+ $this->assertSame('[0,1,2,3]', $response->getContent());
+ }
+
+ public function testStaticCreateJsonObject()
+ {
+ $response = JsonResponse::create(array('foo' => 'bar'));
+ $this->assertInstanceOf('Symfony\Component\HttpFoundation\JsonResponse', $response);
+ $this->assertSame('{"foo":"bar"}', $response->getContent());
+ }
+
+ public function testStaticCreateWithSimpleTypes()
+ {
+ $response = JsonResponse::create('foo');
+ $this->assertInstanceOf('Symfony\Component\HttpFoundation\JsonResponse', $response);
+ $this->assertSame('"foo"', $response->getContent());
+
+ $response = JsonResponse::create(0);
+ $this->assertInstanceOf('Symfony\Component\HttpFoundation\JsonResponse', $response);
+ $this->assertSame('0', $response->getContent());
+
+ $response = JsonResponse::create(0.1);
+ $this->assertInstanceOf('Symfony\Component\HttpFoundation\JsonResponse', $response);
+ $this->assertSame('0.1', $response->getContent());
+
+ $response = JsonResponse::create(true);
+ $this->assertInstanceOf('Symfony\Component\HttpFoundation\JsonResponse', $response);
+ $this->assertSame('true', $response->getContent());
+ }
+
+ public function testStaticCreateWithCustomStatus()
+ {
+ $response = JsonResponse::create(array(), 202);
+ $this->assertSame(202, $response->getStatusCode());
+ }
+
+ public function testStaticCreateAddsContentTypeHeader()
+ {
+ $response = JsonResponse::create();
+ $this->assertSame('application/json', $response->headers->get('Content-Type'));
+ }
+
+ public function testStaticCreateWithCustomHeaders()
+ {
+ $response = JsonResponse::create(array(), 200, array('ETag' => 'foo'));
+ $this->assertSame('application/json', $response->headers->get('Content-Type'));
+ $this->assertSame('foo', $response->headers->get('ETag'));
+ }
+
+ public function testStaticCreateWithCustomContentType()
+ {
+ $headers = array('Content-Type' => 'application/vnd.acme.blog-v1+json');
+
+ $response = JsonResponse::create(array(), 200, $headers);
+ $this->assertSame('application/vnd.acme.blog-v1+json', $response->headers->get('Content-Type'));
+ }
+
+ public function testSetCallback()
+ {
+ $response = JsonResponse::create(array('foo' => 'bar'))->setCallback('callback');
+
+ $this->assertEquals('/**/callback({"foo":"bar"});', $response->getContent());
+ $this->assertEquals('text/javascript', $response->headers->get('Content-Type'));
+ }
+
+ public function testJsonEncodeFlags()
+ {
+ $response = new JsonResponse('<>\'&"');
+
+ $this->assertEquals('"\u003C\u003E\u0027\u0026\u0022"', $response->getContent());
+ }
+
+ public function testGetEncodingOptions()
+ {
+ $response = new JsonResponse();
+
+ $this->assertEquals(JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT, $response->getEncodingOptions());
+ }
+
+ public function testSetEncodingOptions()
+ {
+ $response = new JsonResponse();
+ $response->setData(array(array(1, 2, 3)));
+
+ $this->assertEquals('[[1,2,3]]', $response->getContent());
+
+ $response->setEncodingOptions(JSON_FORCE_OBJECT);
+
+ $this->assertEquals('{"0":{"0":1,"1":2,"2":3}}', $response->getContent());
+ }
+
+ public function testItAcceptsJsonAsString()
+ {
+ $response = JsonResponse::fromJsonString('{"foo":"bar"}');
+ $this->assertSame('{"foo":"bar"}', $response->getContent());
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testSetCallbackInvalidIdentifier()
+ {
+ $response = new JsonResponse('foo');
+ $response->setCallback('+invalid');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testSetContent()
+ {
+ JsonResponse::create("\xB1\x31");
+ }
+
+ /**
+ * @expectedException \Exception
+ * @expectedExceptionMessage This error is expected
+ */
+ public function testSetContentJsonSerializeError()
+ {
+ if (!interface_exists('JsonSerializable', false)) {
+ $this->markTestSkipped('JsonSerializable is required.');
+ }
+
+ $serializable = new JsonSerializableObject();
+
+ JsonResponse::create($serializable);
+ }
+
+ public function testSetComplexCallback()
+ {
+ $response = JsonResponse::create(array('foo' => 'bar'));
+ $response->setCallback('ಠ_ಠ["foo"].bar[0]');
+
+ $this->assertEquals('/**/ಠ_ಠ["foo"].bar[0]({"foo":"bar"});', $response->getContent());
+ }
+}
+
+if (interface_exists('JsonSerializable', false)) {
+ class JsonSerializableObject implements \JsonSerializable
+ {
+ public function jsonSerialize()
+ {
+ throw new \Exception('This error is expected');
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/ParameterBagTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/ParameterBagTest.php
new file mode 100644
index 0000000..ab908d8
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/ParameterBagTest.php
@@ -0,0 +1,194 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\ParameterBag;
+
+class ParameterBagTest extends TestCase
+{
+ public function testConstructor()
+ {
+ $this->testAll();
+ }
+
+ public function testAll()
+ {
+ $bag = new ParameterBag(array('foo' => 'bar'));
+ $this->assertEquals(array('foo' => 'bar'), $bag->all(), '->all() gets all the input');
+ }
+
+ public function testKeys()
+ {
+ $bag = new ParameterBag(array('foo' => 'bar'));
+ $this->assertEquals(array('foo'), $bag->keys());
+ }
+
+ public function testAdd()
+ {
+ $bag = new ParameterBag(array('foo' => 'bar'));
+ $bag->add(array('bar' => 'bas'));
+ $this->assertEquals(array('foo' => 'bar', 'bar' => 'bas'), $bag->all());
+ }
+
+ public function testRemove()
+ {
+ $bag = new ParameterBag(array('foo' => 'bar'));
+ $bag->add(array('bar' => 'bas'));
+ $this->assertEquals(array('foo' => 'bar', 'bar' => 'bas'), $bag->all());
+ $bag->remove('bar');
+ $this->assertEquals(array('foo' => 'bar'), $bag->all());
+ }
+
+ public function testReplace()
+ {
+ $bag = new ParameterBag(array('foo' => 'bar'));
+
+ $bag->replace(array('FOO' => 'BAR'));
+ $this->assertEquals(array('FOO' => 'BAR'), $bag->all(), '->replace() replaces the input with the argument');
+ $this->assertFalse($bag->has('foo'), '->replace() overrides previously set the input');
+ }
+
+ public function testGet()
+ {
+ $bag = new ParameterBag(array('foo' => 'bar', 'null' => null));
+
+ $this->assertEquals('bar', $bag->get('foo'), '->get() gets the value of a parameter');
+ $this->assertEquals('default', $bag->get('unknown', 'default'), '->get() returns second argument as default if a parameter is not defined');
+ $this->assertNull($bag->get('null', 'default'), '->get() returns null if null is set');
+ }
+
+ public function testGetDoesNotUseDeepByDefault()
+ {
+ $bag = new ParameterBag(array('foo' => array('bar' => 'moo')));
+
+ $this->assertNull($bag->get('foo[bar]'));
+ }
+
+ public function testSet()
+ {
+ $bag = new ParameterBag(array());
+
+ $bag->set('foo', 'bar');
+ $this->assertEquals('bar', $bag->get('foo'), '->set() sets the value of parameter');
+
+ $bag->set('foo', 'baz');
+ $this->assertEquals('baz', $bag->get('foo'), '->set() overrides previously set parameter');
+ }
+
+ public function testHas()
+ {
+ $bag = new ParameterBag(array('foo' => 'bar'));
+
+ $this->assertTrue($bag->has('foo'), '->has() returns true if a parameter is defined');
+ $this->assertFalse($bag->has('unknown'), '->has() return false if a parameter is not defined');
+ }
+
+ public function testGetAlpha()
+ {
+ $bag = new ParameterBag(array('word' => 'foo_BAR_012'));
+
+ $this->assertEquals('fooBAR', $bag->getAlpha('word'), '->getAlpha() gets only alphabetic characters');
+ $this->assertEquals('', $bag->getAlpha('unknown'), '->getAlpha() returns empty string if a parameter is not defined');
+ }
+
+ public function testGetAlnum()
+ {
+ $bag = new ParameterBag(array('word' => 'foo_BAR_012'));
+
+ $this->assertEquals('fooBAR012', $bag->getAlnum('word'), '->getAlnum() gets only alphanumeric characters');
+ $this->assertEquals('', $bag->getAlnum('unknown'), '->getAlnum() returns empty string if a parameter is not defined');
+ }
+
+ public function testGetDigits()
+ {
+ $bag = new ParameterBag(array('word' => 'foo_BAR_012'));
+
+ $this->assertEquals('012', $bag->getDigits('word'), '->getDigits() gets only digits as string');
+ $this->assertEquals('', $bag->getDigits('unknown'), '->getDigits() returns empty string if a parameter is not defined');
+ }
+
+ public function testGetInt()
+ {
+ $bag = new ParameterBag(array('digits' => '0123'));
+
+ $this->assertEquals(123, $bag->getInt('digits'), '->getInt() gets a value of parameter as integer');
+ $this->assertEquals(0, $bag->getInt('unknown'), '->getInt() returns zero if a parameter is not defined');
+ }
+
+ public function testFilter()
+ {
+ $bag = new ParameterBag(array(
+ 'digits' => '0123ab',
+ 'email' => 'example@example.com',
+ 'url' => 'http://example.com/foo',
+ 'dec' => '256',
+ 'hex' => '0x100',
+ 'array' => array('bang'),
+ ));
+
+ $this->assertEmpty($bag->filter('nokey'), '->filter() should return empty by default if no key is found');
+
+ $this->assertEquals('0123', $bag->filter('digits', '', FILTER_SANITIZE_NUMBER_INT), '->filter() gets a value of parameter as integer filtering out invalid characters');
+
+ $this->assertEquals('example@example.com', $bag->filter('email', '', FILTER_VALIDATE_EMAIL), '->filter() gets a value of parameter as email');
+
+ $this->assertEquals('http://example.com/foo', $bag->filter('url', '', FILTER_VALIDATE_URL, array('flags' => FILTER_FLAG_PATH_REQUIRED)), '->filter() gets a value of parameter as URL with a path');
+
+ // This test is repeated for code-coverage
+ $this->assertEquals('http://example.com/foo', $bag->filter('url', '', FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED), '->filter() gets a value of parameter as URL with a path');
+
+ $this->assertFalse($bag->filter('dec', '', FILTER_VALIDATE_INT, array(
+ 'flags' => FILTER_FLAG_ALLOW_HEX,
+ 'options' => array('min_range' => 1, 'max_range' => 0xff),
+ )), '->filter() gets a value of parameter as integer between boundaries');
+
+ $this->assertFalse($bag->filter('hex', '', FILTER_VALIDATE_INT, array(
+ 'flags' => FILTER_FLAG_ALLOW_HEX,
+ 'options' => array('min_range' => 1, 'max_range' => 0xff),
+ )), '->filter() gets a value of parameter as integer between boundaries');
+
+ $this->assertEquals(array('bang'), $bag->filter('array', ''), '->filter() gets a value of parameter as an array');
+ }
+
+ public function testGetIterator()
+ {
+ $parameters = array('foo' => 'bar', 'hello' => 'world');
+ $bag = new ParameterBag($parameters);
+
+ $i = 0;
+ foreach ($bag as $key => $val) {
+ ++$i;
+ $this->assertEquals($parameters[$key], $val);
+ }
+
+ $this->assertEquals(count($parameters), $i);
+ }
+
+ public function testCount()
+ {
+ $parameters = array('foo' => 'bar', 'hello' => 'world');
+ $bag = new ParameterBag($parameters);
+
+ $this->assertCount(count($parameters), $bag);
+ }
+
+ public function testGetBoolean()
+ {
+ $parameters = array('string_true' => 'true', 'string_false' => 'false');
+ $bag = new ParameterBag($parameters);
+
+ $this->assertTrue($bag->getBoolean('string_true'), '->getBoolean() gets the string true as boolean true');
+ $this->assertFalse($bag->getBoolean('string_false'), '->getBoolean() gets the string false as boolean false');
+ $this->assertFalse($bag->getBoolean('unknown'), '->getBoolean() returns false if a parameter is not defined');
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/RedirectResponseTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/RedirectResponseTest.php
new file mode 100644
index 0000000..d389e83
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/RedirectResponseTest.php
@@ -0,0 +1,97 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\RedirectResponse;
+
+class RedirectResponseTest extends TestCase
+{
+ public function testGenerateMetaRedirect()
+ {
+ $response = new RedirectResponse('foo.bar');
+
+ $this->assertEquals(1, preg_match(
+ '#<meta http-equiv="refresh" content="\d+;url=foo\.bar" />#',
+ preg_replace(array('/\s+/', '/\'/'), array(' ', '"'), $response->getContent())
+ ));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testRedirectResponseConstructorNullUrl()
+ {
+ $response = new RedirectResponse(null);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testRedirectResponseConstructorWrongStatusCode()
+ {
+ $response = new RedirectResponse('foo.bar', 404);
+ }
+
+ public function testGenerateLocationHeader()
+ {
+ $response = new RedirectResponse('foo.bar');
+
+ $this->assertTrue($response->headers->has('Location'));
+ $this->assertEquals('foo.bar', $response->headers->get('Location'));
+ }
+
+ public function testGetTargetUrl()
+ {
+ $response = new RedirectResponse('foo.bar');
+
+ $this->assertEquals('foo.bar', $response->getTargetUrl());
+ }
+
+ public function testSetTargetUrl()
+ {
+ $response = new RedirectResponse('foo.bar');
+ $response->setTargetUrl('baz.beep');
+
+ $this->assertEquals('baz.beep', $response->getTargetUrl());
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testSetTargetUrlNull()
+ {
+ $response = new RedirectResponse('foo.bar');
+ $response->setTargetUrl(null);
+ }
+
+ public function testCreate()
+ {
+ $response = RedirectResponse::create('foo', 301);
+
+ $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $response);
+ $this->assertEquals(301, $response->getStatusCode());
+ }
+
+ public function testCacheHeaders()
+ {
+ $response = new RedirectResponse('foo.bar', 301);
+ $this->assertFalse($response->headers->hasCacheControlDirective('no-cache'));
+
+ $response = new RedirectResponse('foo.bar', 301, array('cache-control' => 'max-age=86400'));
+ $this->assertFalse($response->headers->hasCacheControlDirective('no-cache'));
+ $this->assertTrue($response->headers->hasCacheControlDirective('max-age'));
+
+ $response = new RedirectResponse('foo.bar', 302);
+ $this->assertTrue($response->headers->hasCacheControlDirective('no-cache'));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/RequestMatcherTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/RequestMatcherTest.php
new file mode 100644
index 0000000..b5d8004
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/RequestMatcherTest.php
@@ -0,0 +1,151 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\RequestMatcher;
+use Symfony\Component\HttpFoundation\Request;
+
+class RequestMatcherTest extends TestCase
+{
+ /**
+ * @dataProvider getMethodData
+ */
+ public function testMethod($requestMethod, $matcherMethod, $isMatch)
+ {
+ $matcher = new RequestMatcher();
+ $matcher->matchMethod($matcherMethod);
+ $request = Request::create('', $requestMethod);
+ $this->assertSame($isMatch, $matcher->matches($request));
+
+ $matcher = new RequestMatcher(null, null, $matcherMethod);
+ $request = Request::create('', $requestMethod);
+ $this->assertSame($isMatch, $matcher->matches($request));
+ }
+
+ public function getMethodData()
+ {
+ return array(
+ array('get', 'get', true),
+ array('get', array('get', 'post'), true),
+ array('get', 'post', false),
+ array('get', 'GET', true),
+ array('get', array('GET', 'POST'), true),
+ array('get', 'POST', false),
+ );
+ }
+
+ public function testScheme()
+ {
+ $httpRequest = $request = $request = Request::create('');
+ $httpsRequest = $request = $request = Request::create('', 'get', array(), array(), array(), array('HTTPS' => 'on'));
+
+ $matcher = new RequestMatcher();
+ $matcher->matchScheme('https');
+ $this->assertFalse($matcher->matches($httpRequest));
+ $this->assertTrue($matcher->matches($httpsRequest));
+
+ $matcher->matchScheme('http');
+ $this->assertFalse($matcher->matches($httpsRequest));
+ $this->assertTrue($matcher->matches($httpRequest));
+
+ $matcher = new RequestMatcher();
+ $this->assertTrue($matcher->matches($httpsRequest));
+ $this->assertTrue($matcher->matches($httpRequest));
+ }
+
+ /**
+ * @dataProvider getHostData
+ */
+ public function testHost($pattern, $isMatch)
+ {
+ $matcher = new RequestMatcher();
+ $request = Request::create('', 'get', array(), array(), array(), array('HTTP_HOST' => 'foo.example.com'));
+
+ $matcher->matchHost($pattern);
+ $this->assertSame($isMatch, $matcher->matches($request));
+
+ $matcher = new RequestMatcher(null, $pattern);
+ $this->assertSame($isMatch, $matcher->matches($request));
+ }
+
+ public function getHostData()
+ {
+ return array(
+ array('.*\.example\.com', true),
+ array('\.example\.com$', true),
+ array('^.*\.example\.com$', true),
+ array('.*\.sensio\.com', false),
+ array('.*\.example\.COM', true),
+ array('\.example\.COM$', true),
+ array('^.*\.example\.COM$', true),
+ array('.*\.sensio\.COM', false),
+ );
+ }
+
+ public function testPath()
+ {
+ $matcher = new RequestMatcher();
+
+ $request = Request::create('/admin/foo');
+
+ $matcher->matchPath('/admin/.*');
+ $this->assertTrue($matcher->matches($request));
+
+ $matcher->matchPath('/admin');
+ $this->assertTrue($matcher->matches($request));
+
+ $matcher->matchPath('^/admin/.*$');
+ $this->assertTrue($matcher->matches($request));
+
+ $matcher->matchMethod('/blog/.*');
+ $this->assertFalse($matcher->matches($request));
+ }
+
+ public function testPathWithLocaleIsNotSupported()
+ {
+ $matcher = new RequestMatcher();
+ $request = Request::create('/en/login');
+ $request->setLocale('en');
+
+ $matcher->matchPath('^/{_locale}/login$');
+ $this->assertFalse($matcher->matches($request));
+ }
+
+ public function testPathWithEncodedCharacters()
+ {
+ $matcher = new RequestMatcher();
+ $request = Request::create('/admin/fo%20o');
+ $matcher->matchPath('^/admin/fo o*$');
+ $this->assertTrue($matcher->matches($request));
+ }
+
+ public function testAttributes()
+ {
+ $matcher = new RequestMatcher();
+
+ $request = Request::create('/admin/foo');
+ $request->attributes->set('foo', 'foo_bar');
+
+ $matcher->matchAttribute('foo', 'foo_.*');
+ $this->assertTrue($matcher->matches($request));
+
+ $matcher->matchAttribute('foo', 'foo');
+ $this->assertTrue($matcher->matches($request));
+
+ $matcher->matchAttribute('foo', '^foo_bar$');
+ $this->assertTrue($matcher->matches($request));
+
+ $matcher->matchAttribute('foo', 'babar');
+ $this->assertFalse($matcher->matches($request));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/RequestStackTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/RequestStackTest.php
new file mode 100644
index 0000000..a84fb26
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/RequestStackTest.php
@@ -0,0 +1,70 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\RequestStack;
+
+class RequestStackTest extends TestCase
+{
+ public function testGetCurrentRequest()
+ {
+ $requestStack = new RequestStack();
+ $this->assertNull($requestStack->getCurrentRequest());
+
+ $request = Request::create('/foo');
+
+ $requestStack->push($request);
+ $this->assertSame($request, $requestStack->getCurrentRequest());
+
+ $this->assertSame($request, $requestStack->pop());
+ $this->assertNull($requestStack->getCurrentRequest());
+
+ $this->assertNull($requestStack->pop());
+ }
+
+ public function testGetMasterRequest()
+ {
+ $requestStack = new RequestStack();
+ $this->assertNull($requestStack->getMasterRequest());
+
+ $masterRequest = Request::create('/foo');
+ $subRequest = Request::create('/bar');
+
+ $requestStack->push($masterRequest);
+ $requestStack->push($subRequest);
+
+ $this->assertSame($masterRequest, $requestStack->getMasterRequest());
+ }
+
+ public function testGetParentRequest()
+ {
+ $requestStack = new RequestStack();
+ $this->assertNull($requestStack->getParentRequest());
+
+ $masterRequest = Request::create('/foo');
+
+ $requestStack->push($masterRequest);
+ $this->assertNull($requestStack->getParentRequest());
+
+ $firstSubRequest = Request::create('/bar');
+
+ $requestStack->push($firstSubRequest);
+ $this->assertSame($masterRequest, $requestStack->getParentRequest());
+
+ $secondSubRequest = Request::create('/baz');
+
+ $requestStack->push($secondSubRequest);
+ $this->assertSame($firstSubRequest, $requestStack->getParentRequest());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/RequestTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/RequestTest.php
new file mode 100644
index 0000000..230ad15
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/RequestTest.php
@@ -0,0 +1,2329 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Exception\SuspiciousOperationException;
+use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
+use Symfony\Component\HttpFoundation\Session\Session;
+use Symfony\Component\HttpFoundation\Request;
+
+class RequestTest extends TestCase
+{
+ protected function tearDown()
+ {
+ // reset
+ Request::setTrustedProxies(array(), -1);
+ }
+
+ public function testInitialize()
+ {
+ $request = new Request();
+
+ $request->initialize(array('foo' => 'bar'));
+ $this->assertEquals('bar', $request->query->get('foo'), '->initialize() takes an array of query parameters as its first argument');
+
+ $request->initialize(array(), array('foo' => 'bar'));
+ $this->assertEquals('bar', $request->request->get('foo'), '->initialize() takes an array of request parameters as its second argument');
+
+ $request->initialize(array(), array(), array('foo' => 'bar'));
+ $this->assertEquals('bar', $request->attributes->get('foo'), '->initialize() takes an array of attributes as its third argument');
+
+ $request->initialize(array(), array(), array(), array(), array(), array('HTTP_FOO' => 'bar'));
+ $this->assertEquals('bar', $request->headers->get('FOO'), '->initialize() takes an array of HTTP headers as its sixth argument');
+ }
+
+ public function testGetLocale()
+ {
+ $request = new Request();
+ $request->setLocale('pl');
+ $locale = $request->getLocale();
+ $this->assertEquals('pl', $locale);
+ }
+
+ public function testGetUser()
+ {
+ $request = Request::create('http://user:password@test.com');
+ $user = $request->getUser();
+
+ $this->assertEquals('user', $user);
+ }
+
+ public function testGetPassword()
+ {
+ $request = Request::create('http://user:password@test.com');
+ $password = $request->getPassword();
+
+ $this->assertEquals('password', $password);
+ }
+
+ public function testIsNoCache()
+ {
+ $request = new Request();
+ $isNoCache = $request->isNoCache();
+
+ $this->assertFalse($isNoCache);
+ }
+
+ public function testGetContentType()
+ {
+ $request = new Request();
+ $contentType = $request->getContentType();
+
+ $this->assertNull($contentType);
+ }
+
+ public function testSetDefaultLocale()
+ {
+ $request = new Request();
+ $request->setDefaultLocale('pl');
+ $locale = $request->getLocale();
+
+ $this->assertEquals('pl', $locale);
+ }
+
+ public function testCreate()
+ {
+ $request = Request::create('http://test.com/foo?bar=baz');
+ $this->assertEquals('http://test.com/foo?bar=baz', $request->getUri());
+ $this->assertEquals('/foo', $request->getPathInfo());
+ $this->assertEquals('bar=baz', $request->getQueryString());
+ $this->assertEquals(80, $request->getPort());
+ $this->assertEquals('test.com', $request->getHttpHost());
+ $this->assertFalse($request->isSecure());
+
+ $request = Request::create('http://test.com/foo', 'GET', array('bar' => 'baz'));
+ $this->assertEquals('http://test.com/foo?bar=baz', $request->getUri());
+ $this->assertEquals('/foo', $request->getPathInfo());
+ $this->assertEquals('bar=baz', $request->getQueryString());
+ $this->assertEquals(80, $request->getPort());
+ $this->assertEquals('test.com', $request->getHttpHost());
+ $this->assertFalse($request->isSecure());
+
+ $request = Request::create('http://test.com/foo?bar=foo', 'GET', array('bar' => 'baz'));
+ $this->assertEquals('http://test.com/foo?bar=baz', $request->getUri());
+ $this->assertEquals('/foo', $request->getPathInfo());
+ $this->assertEquals('bar=baz', $request->getQueryString());
+ $this->assertEquals(80, $request->getPort());
+ $this->assertEquals('test.com', $request->getHttpHost());
+ $this->assertFalse($request->isSecure());
+
+ $request = Request::create('https://test.com/foo?bar=baz');
+ $this->assertEquals('https://test.com/foo?bar=baz', $request->getUri());
+ $this->assertEquals('/foo', $request->getPathInfo());
+ $this->assertEquals('bar=baz', $request->getQueryString());
+ $this->assertEquals(443, $request->getPort());
+ $this->assertEquals('test.com', $request->getHttpHost());
+ $this->assertTrue($request->isSecure());
+
+ $request = Request::create('test.com:90/foo');
+ $this->assertEquals('http://test.com:90/foo', $request->getUri());
+ $this->assertEquals('/foo', $request->getPathInfo());
+ $this->assertEquals('test.com', $request->getHost());
+ $this->assertEquals('test.com:90', $request->getHttpHost());
+ $this->assertEquals(90, $request->getPort());
+ $this->assertFalse($request->isSecure());
+
+ $request = Request::create('https://test.com:90/foo');
+ $this->assertEquals('https://test.com:90/foo', $request->getUri());
+ $this->assertEquals('/foo', $request->getPathInfo());
+ $this->assertEquals('test.com', $request->getHost());
+ $this->assertEquals('test.com:90', $request->getHttpHost());
+ $this->assertEquals(90, $request->getPort());
+ $this->assertTrue($request->isSecure());
+
+ $request = Request::create('https://127.0.0.1:90/foo');
+ $this->assertEquals('https://127.0.0.1:90/foo', $request->getUri());
+ $this->assertEquals('/foo', $request->getPathInfo());
+ $this->assertEquals('127.0.0.1', $request->getHost());
+ $this->assertEquals('127.0.0.1:90', $request->getHttpHost());
+ $this->assertEquals(90, $request->getPort());
+ $this->assertTrue($request->isSecure());
+
+ $request = Request::create('https://[::1]:90/foo');
+ $this->assertEquals('https://[::1]:90/foo', $request->getUri());
+ $this->assertEquals('/foo', $request->getPathInfo());
+ $this->assertEquals('[::1]', $request->getHost());
+ $this->assertEquals('[::1]:90', $request->getHttpHost());
+ $this->assertEquals(90, $request->getPort());
+ $this->assertTrue($request->isSecure());
+
+ $request = Request::create('https://[::1]/foo');
+ $this->assertEquals('https://[::1]/foo', $request->getUri());
+ $this->assertEquals('/foo', $request->getPathInfo());
+ $this->assertEquals('[::1]', $request->getHost());
+ $this->assertEquals('[::1]', $request->getHttpHost());
+ $this->assertEquals(443, $request->getPort());
+ $this->assertTrue($request->isSecure());
+
+ $json = '{"jsonrpc":"2.0","method":"echo","id":7,"params":["Hello World"]}';
+ $request = Request::create('http://example.com/jsonrpc', 'POST', array(), array(), array(), array(), $json);
+ $this->assertEquals($json, $request->getContent());
+ $this->assertFalse($request->isSecure());
+
+ $request = Request::create('http://test.com');
+ $this->assertEquals('http://test.com/', $request->getUri());
+ $this->assertEquals('/', $request->getPathInfo());
+ $this->assertEquals('', $request->getQueryString());
+ $this->assertEquals(80, $request->getPort());
+ $this->assertEquals('test.com', $request->getHttpHost());
+ $this->assertFalse($request->isSecure());
+
+ $request = Request::create('http://test.com?test=1');
+ $this->assertEquals('http://test.com/?test=1', $request->getUri());
+ $this->assertEquals('/', $request->getPathInfo());
+ $this->assertEquals('test=1', $request->getQueryString());
+ $this->assertEquals(80, $request->getPort());
+ $this->assertEquals('test.com', $request->getHttpHost());
+ $this->assertFalse($request->isSecure());
+
+ $request = Request::create('http://test.com:90/?test=1');
+ $this->assertEquals('http://test.com:90/?test=1', $request->getUri());
+ $this->assertEquals('/', $request->getPathInfo());
+ $this->assertEquals('test=1', $request->getQueryString());
+ $this->assertEquals(90, $request->getPort());
+ $this->assertEquals('test.com:90', $request->getHttpHost());
+ $this->assertFalse($request->isSecure());
+
+ $request = Request::create('http://username:password@test.com');
+ $this->assertEquals('http://test.com/', $request->getUri());
+ $this->assertEquals('/', $request->getPathInfo());
+ $this->assertEquals('', $request->getQueryString());
+ $this->assertEquals(80, $request->getPort());
+ $this->assertEquals('test.com', $request->getHttpHost());
+ $this->assertEquals('username', $request->getUser());
+ $this->assertEquals('password', $request->getPassword());
+ $this->assertFalse($request->isSecure());
+
+ $request = Request::create('http://username@test.com');
+ $this->assertEquals('http://test.com/', $request->getUri());
+ $this->assertEquals('/', $request->getPathInfo());
+ $this->assertEquals('', $request->getQueryString());
+ $this->assertEquals(80, $request->getPort());
+ $this->assertEquals('test.com', $request->getHttpHost());
+ $this->assertEquals('username', $request->getUser());
+ $this->assertSame('', $request->getPassword());
+ $this->assertFalse($request->isSecure());
+
+ $request = Request::create('http://test.com/?foo');
+ $this->assertEquals('/?foo', $request->getRequestUri());
+ $this->assertEquals(array('foo' => ''), $request->query->all());
+
+ // assume rewrite rule: (.*) --> app/app.php; app/ is a symlink to a symfony web/ directory
+ $request = Request::create('http://test.com/apparthotel-1234', 'GET', array(), array(), array(),
+ array(
+ 'DOCUMENT_ROOT' => '/var/www/www.test.com',
+ 'SCRIPT_FILENAME' => '/var/www/www.test.com/app/app.php',
+ 'SCRIPT_NAME' => '/app/app.php',
+ 'PHP_SELF' => '/app/app.php/apparthotel-1234',
+ ));
+ $this->assertEquals('http://test.com/apparthotel-1234', $request->getUri());
+ $this->assertEquals('/apparthotel-1234', $request->getPathInfo());
+ $this->assertEquals('', $request->getQueryString());
+ $this->assertEquals(80, $request->getPort());
+ $this->assertEquals('test.com', $request->getHttpHost());
+ $this->assertFalse($request->isSecure());
+ }
+
+ public function testCreateCheckPrecedence()
+ {
+ // server is used by default
+ $request = Request::create('/', 'DELETE', array(), array(), array(), array(
+ 'HTTP_HOST' => 'example.com',
+ 'HTTPS' => 'on',
+ 'SERVER_PORT' => 443,
+ 'PHP_AUTH_USER' => 'fabien',
+ 'PHP_AUTH_PW' => 'pa$$',
+ 'QUERY_STRING' => 'foo=bar',
+ 'CONTENT_TYPE' => 'application/json',
+ ));
+ $this->assertEquals('example.com', $request->getHost());
+ $this->assertEquals(443, $request->getPort());
+ $this->assertTrue($request->isSecure());
+ $this->assertEquals('fabien', $request->getUser());
+ $this->assertEquals('pa$$', $request->getPassword());
+ $this->assertEquals('', $request->getQueryString());
+ $this->assertEquals('application/json', $request->headers->get('CONTENT_TYPE'));
+
+ // URI has precedence over server
+ $request = Request::create('http://thomas:pokemon@example.net:8080/?foo=bar', 'GET', array(), array(), array(), array(
+ 'HTTP_HOST' => 'example.com',
+ 'HTTPS' => 'on',
+ 'SERVER_PORT' => 443,
+ ));
+ $this->assertEquals('example.net', $request->getHost());
+ $this->assertEquals(8080, $request->getPort());
+ $this->assertFalse($request->isSecure());
+ $this->assertEquals('thomas', $request->getUser());
+ $this->assertEquals('pokemon', $request->getPassword());
+ $this->assertEquals('foo=bar', $request->getQueryString());
+ }
+
+ public function testDuplicate()
+ {
+ $request = new Request(array('foo' => 'bar'), array('foo' => 'bar'), array('foo' => 'bar'), array(), array(), array('HTTP_FOO' => 'bar'));
+ $dup = $request->duplicate();
+
+ $this->assertEquals($request->query->all(), $dup->query->all(), '->duplicate() duplicates a request an copy the current query parameters');
+ $this->assertEquals($request->request->all(), $dup->request->all(), '->duplicate() duplicates a request an copy the current request parameters');
+ $this->assertEquals($request->attributes->all(), $dup->attributes->all(), '->duplicate() duplicates a request an copy the current attributes');
+ $this->assertEquals($request->headers->all(), $dup->headers->all(), '->duplicate() duplicates a request an copy the current HTTP headers');
+
+ $dup = $request->duplicate(array('foo' => 'foobar'), array('foo' => 'foobar'), array('foo' => 'foobar'), array(), array(), array('HTTP_FOO' => 'foobar'));
+
+ $this->assertEquals(array('foo' => 'foobar'), $dup->query->all(), '->duplicate() overrides the query parameters if provided');
+ $this->assertEquals(array('foo' => 'foobar'), $dup->request->all(), '->duplicate() overrides the request parameters if provided');
+ $this->assertEquals(array('foo' => 'foobar'), $dup->attributes->all(), '->duplicate() overrides the attributes if provided');
+ $this->assertEquals(array('foo' => array('foobar')), $dup->headers->all(), '->duplicate() overrides the HTTP header if provided');
+ }
+
+ public function testDuplicateWithFormat()
+ {
+ $request = new Request(array(), array(), array('_format' => 'json'));
+ $dup = $request->duplicate();
+
+ $this->assertEquals('json', $dup->getRequestFormat());
+ $this->assertEquals('json', $dup->attributes->get('_format'));
+
+ $request = new Request();
+ $request->setRequestFormat('xml');
+ $dup = $request->duplicate();
+
+ $this->assertEquals('xml', $dup->getRequestFormat());
+ }
+
+ /**
+ * @dataProvider getFormatToMimeTypeMapProviderWithAdditionalNullFormat
+ */
+ public function testGetFormatFromMimeType($format, $mimeTypes)
+ {
+ $request = new Request();
+ foreach ($mimeTypes as $mime) {
+ $this->assertEquals($format, $request->getFormat($mime));
+ }
+ $request->setFormat($format, $mimeTypes);
+ foreach ($mimeTypes as $mime) {
+ $this->assertEquals($format, $request->getFormat($mime));
+
+ if (null !== $format) {
+ $this->assertEquals($mimeTypes[0], $request->getMimeType($format));
+ }
+ }
+ }
+
+ public function getFormatToMimeTypeMapProviderWithAdditionalNullFormat()
+ {
+ return array_merge(
+ array(array(null, array(null, 'unexistent-mime-type'))),
+ $this->getFormatToMimeTypeMapProvider()
+ );
+ }
+
+ public function testGetFormatFromMimeTypeWithParameters()
+ {
+ $request = new Request();
+ $this->assertEquals('json', $request->getFormat('application/json; charset=utf-8'));
+ }
+
+ /**
+ * @dataProvider getFormatToMimeTypeMapProvider
+ */
+ public function testGetMimeTypeFromFormat($format, $mimeTypes)
+ {
+ $request = new Request();
+ $this->assertEquals($mimeTypes[0], $request->getMimeType($format));
+ }
+
+ /**
+ * @dataProvider getFormatToMimeTypeMapProvider
+ */
+ public function testGetMimeTypesFromFormat($format, $mimeTypes)
+ {
+ $this->assertEquals($mimeTypes, Request::getMimeTypes($format));
+ }
+
+ public function testGetMimeTypesFromInexistentFormat()
+ {
+ $request = new Request();
+ $this->assertNull($request->getMimeType('foo'));
+ $this->assertEquals(array(), Request::getMimeTypes('foo'));
+ }
+
+ public function testGetFormatWithCustomMimeType()
+ {
+ $request = new Request();
+ $request->setFormat('custom', 'application/vnd.foo.api;myversion=2.3');
+ $this->assertEquals('custom', $request->getFormat('application/vnd.foo.api;myversion=2.3'));
+ }
+
+ public function getFormatToMimeTypeMapProvider()
+ {
+ return array(
+ array('txt', array('text/plain')),
+ array('js', array('application/javascript', 'application/x-javascript', 'text/javascript')),
+ array('css', array('text/css')),
+ array('json', array('application/json', 'application/x-json')),
+ array('jsonld', array('application/ld+json')),
+ array('xml', array('text/xml', 'application/xml', 'application/x-xml')),
+ array('rdf', array('application/rdf+xml')),
+ array('atom', array('application/atom+xml')),
+ );
+ }
+
+ public function testGetUri()
+ {
+ $server = array();
+
+ // Standard Request on non default PORT
+ // http://host:8080/index.php/path/info?query=string
+
+ $server['HTTP_HOST'] = 'host:8080';
+ $server['SERVER_NAME'] = 'servername';
+ $server['SERVER_PORT'] = '8080';
+
+ $server['QUERY_STRING'] = 'query=string';
+ $server['REQUEST_URI'] = '/index.php/path/info?query=string';
+ $server['SCRIPT_NAME'] = '/index.php';
+ $server['PATH_INFO'] = '/path/info';
+ $server['PATH_TRANSLATED'] = 'redirect:/index.php/path/info';
+ $server['PHP_SELF'] = '/index_dev.php/path/info';
+ $server['SCRIPT_FILENAME'] = '/some/where/index.php';
+
+ $request = new Request();
+
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+
+ $this->assertEquals('http://host:8080/index.php/path/info?query=string', $request->getUri(), '->getUri() with non default port');
+
+ // Use std port number
+ $server['HTTP_HOST'] = 'host';
+ $server['SERVER_NAME'] = 'servername';
+ $server['SERVER_PORT'] = '80';
+
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+
+ $this->assertEquals('http://host/index.php/path/info?query=string', $request->getUri(), '->getUri() with default port');
+
+ // Without HOST HEADER
+ unset($server['HTTP_HOST']);
+ $server['SERVER_NAME'] = 'servername';
+ $server['SERVER_PORT'] = '80';
+
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+
+ $this->assertEquals('http://servername/index.php/path/info?query=string', $request->getUri(), '->getUri() with default port without HOST_HEADER');
+
+ // Request with URL REWRITING (hide index.php)
+ // RewriteCond %{REQUEST_FILENAME} !-f
+ // RewriteRule ^(.*)$ index.php [QSA,L]
+ // http://host:8080/path/info?query=string
+ $server = array();
+ $server['HTTP_HOST'] = 'host:8080';
+ $server['SERVER_NAME'] = 'servername';
+ $server['SERVER_PORT'] = '8080';
+
+ $server['REDIRECT_QUERY_STRING'] = 'query=string';
+ $server['REDIRECT_URL'] = '/path/info';
+ $server['SCRIPT_NAME'] = '/index.php';
+ $server['QUERY_STRING'] = 'query=string';
+ $server['REQUEST_URI'] = '/path/info?toto=test&1=1';
+ $server['SCRIPT_NAME'] = '/index.php';
+ $server['PHP_SELF'] = '/index.php';
+ $server['SCRIPT_FILENAME'] = '/some/where/index.php';
+
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+ $this->assertEquals('http://host:8080/path/info?query=string', $request->getUri(), '->getUri() with rewrite');
+
+ // Use std port number
+ // http://host/path/info?query=string
+ $server['HTTP_HOST'] = 'host';
+ $server['SERVER_NAME'] = 'servername';
+ $server['SERVER_PORT'] = '80';
+
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+
+ $this->assertEquals('http://host/path/info?query=string', $request->getUri(), '->getUri() with rewrite and default port');
+
+ // Without HOST HEADER
+ unset($server['HTTP_HOST']);
+ $server['SERVER_NAME'] = 'servername';
+ $server['SERVER_PORT'] = '80';
+
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+
+ $this->assertEquals('http://servername/path/info?query=string', $request->getUri(), '->getUri() with rewrite, default port without HOST_HEADER');
+
+ // With encoded characters
+
+ $server = array(
+ 'HTTP_HOST' => 'host:8080',
+ 'SERVER_NAME' => 'servername',
+ 'SERVER_PORT' => '8080',
+ 'QUERY_STRING' => 'query=string',
+ 'REQUEST_URI' => '/ba%20se/index_dev.php/foo%20bar/in+fo?query=string',
+ 'SCRIPT_NAME' => '/ba se/index_dev.php',
+ 'PATH_TRANSLATED' => 'redirect:/index.php/foo bar/in+fo',
+ 'PHP_SELF' => '/ba se/index_dev.php/path/info',
+ 'SCRIPT_FILENAME' => '/some/where/ba se/index_dev.php',
+ );
+
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+
+ $this->assertEquals(
+ 'http://host:8080/ba%20se/index_dev.php/foo%20bar/in+fo?query=string',
+ $request->getUri()
+ );
+
+ // with user info
+
+ $server['PHP_AUTH_USER'] = 'fabien';
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+ $this->assertEquals('http://host:8080/ba%20se/index_dev.php/foo%20bar/in+fo?query=string', $request->getUri());
+
+ $server['PHP_AUTH_PW'] = 'symfony';
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+ $this->assertEquals('http://host:8080/ba%20se/index_dev.php/foo%20bar/in+fo?query=string', $request->getUri());
+ }
+
+ public function testGetUriForPath()
+ {
+ $request = Request::create('http://test.com/foo?bar=baz');
+ $this->assertEquals('http://test.com/some/path', $request->getUriForPath('/some/path'));
+
+ $request = Request::create('http://test.com:90/foo?bar=baz');
+ $this->assertEquals('http://test.com:90/some/path', $request->getUriForPath('/some/path'));
+
+ $request = Request::create('https://test.com/foo?bar=baz');
+ $this->assertEquals('https://test.com/some/path', $request->getUriForPath('/some/path'));
+
+ $request = Request::create('https://test.com:90/foo?bar=baz');
+ $this->assertEquals('https://test.com:90/some/path', $request->getUriForPath('/some/path'));
+
+ $server = array();
+
+ // Standard Request on non default PORT
+ // http://host:8080/index.php/path/info?query=string
+
+ $server['HTTP_HOST'] = 'host:8080';
+ $server['SERVER_NAME'] = 'servername';
+ $server['SERVER_PORT'] = '8080';
+
+ $server['QUERY_STRING'] = 'query=string';
+ $server['REQUEST_URI'] = '/index.php/path/info?query=string';
+ $server['SCRIPT_NAME'] = '/index.php';
+ $server['PATH_INFO'] = '/path/info';
+ $server['PATH_TRANSLATED'] = 'redirect:/index.php/path/info';
+ $server['PHP_SELF'] = '/index_dev.php/path/info';
+ $server['SCRIPT_FILENAME'] = '/some/where/index.php';
+
+ $request = new Request();
+
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+
+ $this->assertEquals('http://host:8080/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with non default port');
+
+ // Use std port number
+ $server['HTTP_HOST'] = 'host';
+ $server['SERVER_NAME'] = 'servername';
+ $server['SERVER_PORT'] = '80';
+
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+
+ $this->assertEquals('http://host/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with default port');
+
+ // Without HOST HEADER
+ unset($server['HTTP_HOST']);
+ $server['SERVER_NAME'] = 'servername';
+ $server['SERVER_PORT'] = '80';
+
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+
+ $this->assertEquals('http://servername/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with default port without HOST_HEADER');
+
+ // Request with URL REWRITING (hide index.php)
+ // RewriteCond %{REQUEST_FILENAME} !-f
+ // RewriteRule ^(.*)$ index.php [QSA,L]
+ // http://host:8080/path/info?query=string
+ $server = array();
+ $server['HTTP_HOST'] = 'host:8080';
+ $server['SERVER_NAME'] = 'servername';
+ $server['SERVER_PORT'] = '8080';
+
+ $server['REDIRECT_QUERY_STRING'] = 'query=string';
+ $server['REDIRECT_URL'] = '/path/info';
+ $server['SCRIPT_NAME'] = '/index.php';
+ $server['QUERY_STRING'] = 'query=string';
+ $server['REQUEST_URI'] = '/path/info?toto=test&1=1';
+ $server['SCRIPT_NAME'] = '/index.php';
+ $server['PHP_SELF'] = '/index.php';
+ $server['SCRIPT_FILENAME'] = '/some/where/index.php';
+
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+ $this->assertEquals('http://host:8080/some/path', $request->getUriForPath('/some/path'), '->getUri() with rewrite');
+
+ // Use std port number
+ // http://host/path/info?query=string
+ $server['HTTP_HOST'] = 'host';
+ $server['SERVER_NAME'] = 'servername';
+ $server['SERVER_PORT'] = '80';
+
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+
+ $this->assertEquals('http://host/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with rewrite and default port');
+
+ // Without HOST HEADER
+ unset($server['HTTP_HOST']);
+ $server['SERVER_NAME'] = 'servername';
+ $server['SERVER_PORT'] = '80';
+
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+
+ $this->assertEquals('http://servername/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with rewrite, default port without HOST_HEADER');
+ $this->assertEquals('servername', $request->getHttpHost());
+
+ // with user info
+
+ $server['PHP_AUTH_USER'] = 'fabien';
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+ $this->assertEquals('http://servername/some/path', $request->getUriForPath('/some/path'));
+
+ $server['PHP_AUTH_PW'] = 'symfony';
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+ $this->assertEquals('http://servername/some/path', $request->getUriForPath('/some/path'));
+ }
+
+ /**
+ * @dataProvider getRelativeUriForPathData()
+ */
+ public function testGetRelativeUriForPath($expected, $pathinfo, $path)
+ {
+ $this->assertEquals($expected, Request::create($pathinfo)->getRelativeUriForPath($path));
+ }
+
+ public function getRelativeUriForPathData()
+ {
+ return array(
+ array('me.png', '/foo', '/me.png'),
+ array('../me.png', '/foo/bar', '/me.png'),
+ array('me.png', '/foo/bar', '/foo/me.png'),
+ array('../baz/me.png', '/foo/bar/b', '/foo/baz/me.png'),
+ array('../../fooz/baz/me.png', '/foo/bar/b', '/fooz/baz/me.png'),
+ array('baz/me.png', '/foo/bar/b', 'baz/me.png'),
+ );
+ }
+
+ public function testGetUserInfo()
+ {
+ $request = new Request();
+
+ $server = array('PHP_AUTH_USER' => 'fabien');
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+ $this->assertEquals('fabien', $request->getUserInfo());
+
+ $server['PHP_AUTH_USER'] = '0';
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+ $this->assertEquals('0', $request->getUserInfo());
+
+ $server['PHP_AUTH_PW'] = '0';
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+ $this->assertEquals('0:0', $request->getUserInfo());
+ }
+
+ public function testGetSchemeAndHttpHost()
+ {
+ $request = new Request();
+
+ $server = array();
+ $server['SERVER_NAME'] = 'servername';
+ $server['SERVER_PORT'] = '90';
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+ $this->assertEquals('http://servername:90', $request->getSchemeAndHttpHost());
+
+ $server['PHP_AUTH_USER'] = 'fabien';
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+ $this->assertEquals('http://servername:90', $request->getSchemeAndHttpHost());
+
+ $server['PHP_AUTH_USER'] = '0';
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+ $this->assertEquals('http://servername:90', $request->getSchemeAndHttpHost());
+
+ $server['PHP_AUTH_PW'] = '0';
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+ $this->assertEquals('http://servername:90', $request->getSchemeAndHttpHost());
+ }
+
+ /**
+ * @dataProvider getQueryStringNormalizationData
+ */
+ public function testGetQueryString($query, $expectedQuery, $msg)
+ {
+ $request = new Request();
+
+ $request->server->set('QUERY_STRING', $query);
+ $this->assertSame($expectedQuery, $request->getQueryString(), $msg);
+ }
+
+ public function getQueryStringNormalizationData()
+ {
+ return array(
+ array('foo', 'foo', 'works with valueless parameters'),
+ array('foo=', 'foo=', 'includes a dangling equal sign'),
+ array('bar=&foo=bar', 'bar=&foo=bar', '->works with empty parameters'),
+ array('foo=bar&bar=', 'bar=&foo=bar', 'sorts keys alphabetically'),
+
+ // GET parameters, that are submitted from a HTML form, encode spaces as "+" by default (as defined in enctype application/x-www-form-urlencoded).
+ // PHP also converts "+" to spaces when filling the global _GET or when using the function parse_str.
+ array('him=John%20Doe&her=Jane+Doe', 'her=Jane%20Doe&him=John%20Doe', 'normalizes spaces in both encodings "%20" and "+"'),
+
+ array('foo[]=1&foo[]=2', 'foo%5B%5D=1&foo%5B%5D=2', 'allows array notation'),
+ array('foo=1&foo=2', 'foo=1&foo=2', 'allows repeated parameters'),
+ array('pa%3Dram=foo%26bar%3Dbaz&test=test', 'pa%3Dram=foo%26bar%3Dbaz&test=test', 'works with encoded delimiters'),
+ array('0', '0', 'allows "0"'),
+ array('Jane Doe&John%20Doe', 'Jane%20Doe&John%20Doe', 'normalizes encoding in keys'),
+ array('her=Jane Doe&him=John%20Doe', 'her=Jane%20Doe&him=John%20Doe', 'normalizes encoding in values'),
+ array('foo=bar&&&test&&', 'foo=bar&test', 'removes unneeded delimiters'),
+ array('formula=e=m*c^2', 'formula=e%3Dm%2Ac%5E2', 'correctly treats only the first "=" as delimiter and the next as value'),
+
+ // Ignore pairs with empty key, even if there was a value, e.g. "=value", as such nameless values cannot be retrieved anyway.
+ // PHP also does not include them when building _GET.
+ array('foo=bar&=a=b&=x=y', 'foo=bar', 'removes params with empty key'),
+ );
+ }
+
+ public function testGetQueryStringReturnsNull()
+ {
+ $request = new Request();
+
+ $this->assertNull($request->getQueryString(), '->getQueryString() returns null for non-existent query string');
+
+ $request->server->set('QUERY_STRING', '');
+ $this->assertNull($request->getQueryString(), '->getQueryString() returns null for empty query string');
+ }
+
+ public function testGetHost()
+ {
+ $request = new Request();
+
+ $request->initialize(array('foo' => 'bar'));
+ $this->assertEquals('', $request->getHost(), '->getHost() return empty string if not initialized');
+
+ $request->initialize(array(), array(), array(), array(), array(), array('HTTP_HOST' => 'www.example.com'));
+ $this->assertEquals('www.example.com', $request->getHost(), '->getHost() from Host Header');
+
+ // Host header with port number
+ $request->initialize(array(), array(), array(), array(), array(), array('HTTP_HOST' => 'www.example.com:8080'));
+ $this->assertEquals('www.example.com', $request->getHost(), '->getHost() from Host Header with port number');
+
+ // Server values
+ $request->initialize(array(), array(), array(), array(), array(), array('SERVER_NAME' => 'www.example.com'));
+ $this->assertEquals('www.example.com', $request->getHost(), '->getHost() from server name');
+
+ $request->initialize(array(), array(), array(), array(), array(), array('SERVER_NAME' => 'www.example.com', 'HTTP_HOST' => 'www.host.com'));
+ $this->assertEquals('www.host.com', $request->getHost(), '->getHost() value from Host header has priority over SERVER_NAME ');
+ }
+
+ public function testGetPort()
+ {
+ $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
+ 'HTTP_X_FORWARDED_PROTO' => 'https',
+ 'HTTP_X_FORWARDED_PORT' => '443',
+ ));
+ $port = $request->getPort();
+
+ $this->assertEquals(80, $port, 'Without trusted proxies FORWARDED_PROTO and FORWARDED_PORT are ignored.');
+
+ Request::setTrustedProxies(array('1.1.1.1'), Request::HEADER_X_FORWARDED_ALL);
+ $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
+ 'HTTP_X_FORWARDED_PROTO' => 'https',
+ 'HTTP_X_FORWARDED_PORT' => '8443',
+ ));
+ $this->assertEquals(80, $request->getPort(), 'With PROTO and PORT on untrusted connection server value takes precedence.');
+ $request->server->set('REMOTE_ADDR', '1.1.1.1');
+ $this->assertEquals(8443, $request->getPort(), 'With PROTO and PORT set PORT takes precedence.');
+
+ $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
+ 'HTTP_X_FORWARDED_PROTO' => 'https',
+ ));
+ $this->assertEquals(80, $request->getPort(), 'With only PROTO set getPort() ignores trusted headers on untrusted connection.');
+ $request->server->set('REMOTE_ADDR', '1.1.1.1');
+ $this->assertEquals(443, $request->getPort(), 'With only PROTO set getPort() defaults to 443.');
+
+ $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
+ 'HTTP_X_FORWARDED_PROTO' => 'http',
+ ));
+ $this->assertEquals(80, $request->getPort(), 'If X_FORWARDED_PROTO is set to HTTP getPort() ignores trusted headers on untrusted connection.');
+ $request->server->set('REMOTE_ADDR', '1.1.1.1');
+ $this->assertEquals(80, $request->getPort(), 'If X_FORWARDED_PROTO is set to HTTP getPort() returns port of the original request.');
+
+ $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
+ 'HTTP_X_FORWARDED_PROTO' => 'On',
+ ));
+ $this->assertEquals(80, $request->getPort(), 'With only PROTO set and value is On, getPort() ignores trusted headers on untrusted connection.');
+ $request->server->set('REMOTE_ADDR', '1.1.1.1');
+ $this->assertEquals(443, $request->getPort(), 'With only PROTO set and value is On, getPort() defaults to 443.');
+
+ $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
+ 'HTTP_X_FORWARDED_PROTO' => '1',
+ ));
+ $this->assertEquals(80, $request->getPort(), 'With only PROTO set and value is 1, getPort() ignores trusted headers on untrusted connection.');
+ $request->server->set('REMOTE_ADDR', '1.1.1.1');
+ $this->assertEquals(443, $request->getPort(), 'With only PROTO set and value is 1, getPort() defaults to 443.');
+
+ $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
+ 'HTTP_X_FORWARDED_PROTO' => 'something-else',
+ ));
+ $port = $request->getPort();
+ $this->assertEquals(80, $port, 'With only PROTO set and value is not recognized, getPort() defaults to 80.');
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ */
+ public function testGetHostWithFakeHttpHostValue()
+ {
+ $request = new Request();
+ $request->initialize(array(), array(), array(), array(), array(), array('HTTP_HOST' => 'www.host.com?query=string'));
+ $request->getHost();
+ }
+
+ public function testGetSetMethod()
+ {
+ $request = new Request();
+
+ $this->assertEquals('GET', $request->getMethod(), '->getMethod() returns GET if no method is defined');
+
+ $request->setMethod('get');
+ $this->assertEquals('GET', $request->getMethod(), '->getMethod() returns an uppercased string');
+
+ $request->setMethod('PURGE');
+ $this->assertEquals('PURGE', $request->getMethod(), '->getMethod() returns the method even if it is not a standard one');
+
+ $request->setMethod('POST');
+ $this->assertEquals('POST', $request->getMethod(), '->getMethod() returns the method POST if no _method is defined');
+
+ $request->setMethod('POST');
+ $request->request->set('_method', 'purge');
+ $this->assertEquals('POST', $request->getMethod(), '->getMethod() does not return the method from _method if defined and POST but support not enabled');
+
+ $request = new Request();
+ $request->setMethod('POST');
+ $request->request->set('_method', 'purge');
+
+ $this->assertFalse(Request::getHttpMethodParameterOverride(), 'httpMethodParameterOverride should be disabled by default');
+
+ Request::enableHttpMethodParameterOverride();
+
+ $this->assertTrue(Request::getHttpMethodParameterOverride(), 'httpMethodParameterOverride should be enabled now but it is not');
+
+ $this->assertEquals('PURGE', $request->getMethod(), '->getMethod() returns the method from _method if defined and POST');
+ $this->disableHttpMethodParameterOverride();
+
+ $request = new Request();
+ $request->setMethod('POST');
+ $request->query->set('_method', 'purge');
+ $this->assertEquals('POST', $request->getMethod(), '->getMethod() does not return the method from _method if defined and POST but support not enabled');
+
+ $request = new Request();
+ $request->setMethod('POST');
+ $request->query->set('_method', 'purge');
+ Request::enableHttpMethodParameterOverride();
+ $this->assertEquals('PURGE', $request->getMethod(), '->getMethod() returns the method from _method if defined and POST');
+ $this->disableHttpMethodParameterOverride();
+
+ $request = new Request();
+ $request->setMethod('POST');
+ $request->headers->set('X-HTTP-METHOD-OVERRIDE', 'delete');
+ $this->assertEquals('DELETE', $request->getMethod(), '->getMethod() returns the method from X-HTTP-Method-Override even though _method is set if defined and POST');
+
+ $request = new Request();
+ $request->setMethod('POST');
+ $request->headers->set('X-HTTP-METHOD-OVERRIDE', 'delete');
+ $this->assertEquals('DELETE', $request->getMethod(), '->getMethod() returns the method from X-HTTP-Method-Override if defined and POST');
+ }
+
+ /**
+ * @dataProvider getClientIpsProvider
+ */
+ public function testGetClientIp($expected, $remoteAddr, $httpForwardedFor, $trustedProxies)
+ {
+ $request = $this->getRequestInstanceForClientIpTests($remoteAddr, $httpForwardedFor, $trustedProxies);
+
+ $this->assertEquals($expected[0], $request->getClientIp());
+ }
+
+ /**
+ * @dataProvider getClientIpsProvider
+ */
+ public function testGetClientIps($expected, $remoteAddr, $httpForwardedFor, $trustedProxies)
+ {
+ $request = $this->getRequestInstanceForClientIpTests($remoteAddr, $httpForwardedFor, $trustedProxies);
+
+ $this->assertEquals($expected, $request->getClientIps());
+ }
+
+ /**
+ * @dataProvider getClientIpsForwardedProvider
+ */
+ public function testGetClientIpsForwarded($expected, $remoteAddr, $httpForwarded, $trustedProxies)
+ {
+ $request = $this->getRequestInstanceForClientIpsForwardedTests($remoteAddr, $httpForwarded, $trustedProxies);
+
+ $this->assertEquals($expected, $request->getClientIps());
+ }
+
+ public function getClientIpsForwardedProvider()
+ {
+ // $expected $remoteAddr $httpForwarded $trustedProxies
+ return array(
+ array(array('127.0.0.1'), '127.0.0.1', 'for="_gazonk"', null),
+ array(array('127.0.0.1'), '127.0.0.1', 'for="_gazonk"', array('127.0.0.1')),
+ array(array('88.88.88.88'), '127.0.0.1', 'for="88.88.88.88:80"', array('127.0.0.1')),
+ array(array('192.0.2.60'), '::1', 'for=192.0.2.60;proto=http;by=203.0.113.43', array('::1')),
+ array(array('2620:0:1cfe:face:b00c::3', '192.0.2.43'), '::1', 'for=192.0.2.43, for=2620:0:1cfe:face:b00c::3', array('::1')),
+ array(array('2001:db8:cafe::17'), '::1', 'for="[2001:db8:cafe::17]:4711', array('::1')),
+ );
+ }
+
+ public function getClientIpsProvider()
+ {
+ // $expected $remoteAddr $httpForwardedFor $trustedProxies
+ return array(
+ // simple IPv4
+ array(array('88.88.88.88'), '88.88.88.88', null, null),
+ // trust the IPv4 remote addr
+ array(array('88.88.88.88'), '88.88.88.88', null, array('88.88.88.88')),
+
+ // simple IPv6
+ array(array('::1'), '::1', null, null),
+ // trust the IPv6 remote addr
+ array(array('::1'), '::1', null, array('::1')),
+
+ // forwarded for with remote IPv4 addr not trusted
+ array(array('127.0.0.1'), '127.0.0.1', '88.88.88.88', null),
+ // forwarded for with remote IPv4 addr trusted
+ array(array('88.88.88.88'), '127.0.0.1', '88.88.88.88', array('127.0.0.1')),
+ // forwarded for with remote IPv4 and all FF addrs trusted
+ array(array('88.88.88.88'), '127.0.0.1', '88.88.88.88', array('127.0.0.1', '88.88.88.88')),
+ // forwarded for with remote IPv4 range trusted
+ array(array('88.88.88.88'), '123.45.67.89', '88.88.88.88', array('123.45.67.0/24')),
+
+ // forwarded for with remote IPv6 addr not trusted
+ array(array('1620:0:1cfe:face:b00c::3'), '1620:0:1cfe:face:b00c::3', '2620:0:1cfe:face:b00c::3', null),
+ // forwarded for with remote IPv6 addr trusted
+ array(array('2620:0:1cfe:face:b00c::3'), '1620:0:1cfe:face:b00c::3', '2620:0:1cfe:face:b00c::3', array('1620:0:1cfe:face:b00c::3')),
+ // forwarded for with remote IPv6 range trusted
+ array(array('88.88.88.88'), '2a01:198:603:0:396e:4789:8e99:890f', '88.88.88.88', array('2a01:198:603:0::/65')),
+
+ // multiple forwarded for with remote IPv4 addr trusted
+ array(array('88.88.88.88', '87.65.43.21', '127.0.0.1'), '123.45.67.89', '127.0.0.1, 87.65.43.21, 88.88.88.88', array('123.45.67.89')),
+ // multiple forwarded for with remote IPv4 addr and some reverse proxies trusted
+ array(array('87.65.43.21', '127.0.0.1'), '123.45.67.89', '127.0.0.1, 87.65.43.21, 88.88.88.88', array('123.45.67.89', '88.88.88.88')),
+ // multiple forwarded for with remote IPv4 addr and some reverse proxies trusted but in the middle
+ array(array('88.88.88.88', '127.0.0.1'), '123.45.67.89', '127.0.0.1, 87.65.43.21, 88.88.88.88', array('123.45.67.89', '87.65.43.21')),
+ // multiple forwarded for with remote IPv4 addr and all reverse proxies trusted
+ array(array('127.0.0.1'), '123.45.67.89', '127.0.0.1, 87.65.43.21, 88.88.88.88', array('123.45.67.89', '87.65.43.21', '88.88.88.88', '127.0.0.1')),
+
+ // multiple forwarded for with remote IPv6 addr trusted
+ array(array('2620:0:1cfe:face:b00c::3', '3620:0:1cfe:face:b00c::3'), '1620:0:1cfe:face:b00c::3', '3620:0:1cfe:face:b00c::3,2620:0:1cfe:face:b00c::3', array('1620:0:1cfe:face:b00c::3')),
+ // multiple forwarded for with remote IPv6 addr and some reverse proxies trusted
+ array(array('3620:0:1cfe:face:b00c::3'), '1620:0:1cfe:face:b00c::3', '3620:0:1cfe:face:b00c::3,2620:0:1cfe:face:b00c::3', array('1620:0:1cfe:face:b00c::3', '2620:0:1cfe:face:b00c::3')),
+ // multiple forwarded for with remote IPv4 addr and some reverse proxies trusted but in the middle
+ array(array('2620:0:1cfe:face:b00c::3', '4620:0:1cfe:face:b00c::3'), '1620:0:1cfe:face:b00c::3', '4620:0:1cfe:face:b00c::3,3620:0:1cfe:face:b00c::3,2620:0:1cfe:face:b00c::3', array('1620:0:1cfe:face:b00c::3', '3620:0:1cfe:face:b00c::3')),
+
+ // client IP with port
+ array(array('88.88.88.88'), '127.0.0.1', '88.88.88.88:12345, 127.0.0.1', array('127.0.0.1')),
+
+ // invalid forwarded IP is ignored
+ array(array('88.88.88.88'), '127.0.0.1', 'unknown,88.88.88.88', array('127.0.0.1')),
+ array(array('88.88.88.88'), '127.0.0.1', '}__test|O:21:&quot;JDatabaseDriverMysqli&quot;:3:{s:2,88.88.88.88', array('127.0.0.1')),
+ );
+ }
+
+ /**
+ * @expectedException \Symfony\Component\HttpFoundation\Exception\ConflictingHeadersException
+ * @dataProvider getClientIpsWithConflictingHeadersProvider
+ */
+ public function testGetClientIpsWithConflictingHeaders($httpForwarded, $httpXForwardedFor)
+ {
+ $request = new Request();
+
+ $server = array(
+ 'REMOTE_ADDR' => '88.88.88.88',
+ 'HTTP_FORWARDED' => $httpForwarded,
+ 'HTTP_X_FORWARDED_FOR' => $httpXForwardedFor,
+ );
+
+ Request::setTrustedProxies(array('88.88.88.88'), Request::HEADER_X_FORWARDED_ALL | Request::HEADER_FORWARDED);
+
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+
+ $request->getClientIps();
+ }
+
+ /**
+ * @dataProvider getClientIpsWithConflictingHeadersProvider
+ */
+ public function testGetClientIpsOnlyXHttpForwardedForTrusted($httpForwarded, $httpXForwardedFor)
+ {
+ $request = new Request();
+
+ $server = array(
+ 'REMOTE_ADDR' => '88.88.88.88',
+ 'HTTP_FORWARDED' => $httpForwarded,
+ 'HTTP_X_FORWARDED_FOR' => $httpXForwardedFor,
+ );
+
+ Request::setTrustedProxies(array('88.88.88.88'), Request::HEADER_X_FORWARDED_FOR);
+
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+
+ $this->assertSame(array_reverse(explode(',', $httpXForwardedFor)), $request->getClientIps());
+ }
+
+ public function getClientIpsWithConflictingHeadersProvider()
+ {
+ // $httpForwarded $httpXForwardedFor
+ return array(
+ array('for=87.65.43.21', '192.0.2.60'),
+ array('for=87.65.43.21, for=192.0.2.60', '192.0.2.60'),
+ array('for=192.0.2.60', '192.0.2.60,87.65.43.21'),
+ array('for="::face", for=192.0.2.60', '192.0.2.60,192.0.2.43'),
+ array('for=87.65.43.21, for=192.0.2.60', '192.0.2.60,87.65.43.21'),
+ );
+ }
+
+ /**
+ * @dataProvider getClientIpsWithAgreeingHeadersProvider
+ */
+ public function testGetClientIpsWithAgreeingHeaders($httpForwarded, $httpXForwardedFor, $expectedIps)
+ {
+ $request = new Request();
+
+ $server = array(
+ 'REMOTE_ADDR' => '88.88.88.88',
+ 'HTTP_FORWARDED' => $httpForwarded,
+ 'HTTP_X_FORWARDED_FOR' => $httpXForwardedFor,
+ );
+
+ Request::setTrustedProxies(array('88.88.88.88'), Request::HEADER_X_FORWARDED_ALL);
+
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+
+ $clientIps = $request->getClientIps();
+
+ $this->assertSame($expectedIps, $clientIps);
+ }
+
+ public function getClientIpsWithAgreeingHeadersProvider()
+ {
+ // $httpForwarded $httpXForwardedFor
+ return array(
+ array('for="192.0.2.60"', '192.0.2.60', array('192.0.2.60')),
+ array('for=192.0.2.60, for=87.65.43.21', '192.0.2.60,87.65.43.21', array('87.65.43.21', '192.0.2.60')),
+ array('for="[::face]", for=192.0.2.60', '::face,192.0.2.60', array('192.0.2.60', '::face')),
+ array('for="192.0.2.60:80"', '192.0.2.60', array('192.0.2.60')),
+ array('for=192.0.2.60;proto=http;by=203.0.113.43', '192.0.2.60', array('192.0.2.60')),
+ array('for="[2001:db8:cafe::17]:4711"', '2001:db8:cafe::17', array('2001:db8:cafe::17')),
+ );
+ }
+
+ public function testGetContentWorksTwiceInDefaultMode()
+ {
+ $req = new Request();
+ $this->assertEquals('', $req->getContent());
+ $this->assertEquals('', $req->getContent());
+ }
+
+ public function testGetContentReturnsResource()
+ {
+ $req = new Request();
+ $retval = $req->getContent(true);
+ $this->assertInternalType('resource', $retval);
+ $this->assertEquals('', fread($retval, 1));
+ $this->assertTrue(feof($retval));
+ }
+
+ public function testGetContentReturnsResourceWhenContentSetInConstructor()
+ {
+ $req = new Request(array(), array(), array(), array(), array(), array(), 'MyContent');
+ $resource = $req->getContent(true);
+
+ $this->assertInternalType('resource', $resource);
+ $this->assertEquals('MyContent', stream_get_contents($resource));
+ }
+
+ public function testContentAsResource()
+ {
+ $resource = fopen('php://memory', 'r+');
+ fwrite($resource, 'My other content');
+ rewind($resource);
+
+ $req = new Request(array(), array(), array(), array(), array(), array(), $resource);
+ $this->assertEquals('My other content', stream_get_contents($req->getContent(true)));
+ $this->assertEquals('My other content', $req->getContent());
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @dataProvider getContentCantBeCalledTwiceWithResourcesProvider
+ */
+ public function testGetContentCantBeCalledTwiceWithResources($first, $second)
+ {
+ if (\PHP_VERSION_ID >= 50600) {
+ $this->markTestSkipped('PHP >= 5.6 allows to open php://input several times.');
+ }
+
+ $req = new Request();
+ $req->getContent($first);
+ $req->getContent($second);
+ }
+
+ public function getContentCantBeCalledTwiceWithResourcesProvider()
+ {
+ return array(
+ 'Resource then fetch' => array(true, false),
+ 'Resource then resource' => array(true, true),
+ );
+ }
+
+ /**
+ * @dataProvider getContentCanBeCalledTwiceWithResourcesProvider
+ * @requires PHP 5.6
+ */
+ public function testGetContentCanBeCalledTwiceWithResources($first, $second)
+ {
+ $req = new Request();
+ $a = $req->getContent($first);
+ $b = $req->getContent($second);
+
+ if ($first) {
+ $a = stream_get_contents($a);
+ }
+
+ if ($second) {
+ $b = stream_get_contents($b);
+ }
+
+ $this->assertSame($a, $b);
+ }
+
+ public function getContentCanBeCalledTwiceWithResourcesProvider()
+ {
+ return array(
+ 'Fetch then fetch' => array(false, false),
+ 'Fetch then resource' => array(false, true),
+ 'Resource then fetch' => array(true, false),
+ 'Resource then resource' => array(true, true),
+ );
+ }
+
+ public function provideOverloadedMethods()
+ {
+ return array(
+ array('PUT'),
+ array('DELETE'),
+ array('PATCH'),
+ array('put'),
+ array('delete'),
+ array('patch'),
+ );
+ }
+
+ /**
+ * @dataProvider provideOverloadedMethods
+ */
+ public function testCreateFromGlobals($method)
+ {
+ $normalizedMethod = strtoupper($method);
+
+ $_GET['foo1'] = 'bar1';
+ $_POST['foo2'] = 'bar2';
+ $_COOKIE['foo3'] = 'bar3';
+ $_FILES['foo4'] = array('bar4');
+ $_SERVER['foo5'] = 'bar5';
+
+ $request = Request::createFromGlobals();
+ $this->assertEquals('bar1', $request->query->get('foo1'), '::fromGlobals() uses values from $_GET');
+ $this->assertEquals('bar2', $request->request->get('foo2'), '::fromGlobals() uses values from $_POST');
+ $this->assertEquals('bar3', $request->cookies->get('foo3'), '::fromGlobals() uses values from $_COOKIE');
+ $this->assertEquals(array('bar4'), $request->files->get('foo4'), '::fromGlobals() uses values from $_FILES');
+ $this->assertEquals('bar5', $request->server->get('foo5'), '::fromGlobals() uses values from $_SERVER');
+
+ unset($_GET['foo1'], $_POST['foo2'], $_COOKIE['foo3'], $_FILES['foo4'], $_SERVER['foo5']);
+
+ $_SERVER['REQUEST_METHOD'] = $method;
+ $_SERVER['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
+ $request = RequestContentProxy::createFromGlobals();
+ $this->assertEquals($normalizedMethod, $request->getMethod());
+ $this->assertEquals('mycontent', $request->request->get('content'));
+
+ unset($_SERVER['REQUEST_METHOD'], $_SERVER['CONTENT_TYPE']);
+
+ Request::createFromGlobals();
+ Request::enableHttpMethodParameterOverride();
+ $_POST['_method'] = $method;
+ $_POST['foo6'] = 'bar6';
+ $_SERVER['REQUEST_METHOD'] = 'PoSt';
+ $request = Request::createFromGlobals();
+ $this->assertEquals($normalizedMethod, $request->getMethod());
+ $this->assertEquals('POST', $request->getRealMethod());
+ $this->assertEquals('bar6', $request->request->get('foo6'));
+
+ unset($_POST['_method'], $_POST['foo6'], $_SERVER['REQUEST_METHOD']);
+ $this->disableHttpMethodParameterOverride();
+ }
+
+ public function testOverrideGlobals()
+ {
+ $request = new Request();
+ $request->initialize(array('foo' => 'bar'));
+
+ // as the Request::overrideGlobals really work, it erase $_SERVER, so we must backup it
+ $server = $_SERVER;
+
+ $request->overrideGlobals();
+
+ $this->assertEquals(array('foo' => 'bar'), $_GET);
+
+ $request->initialize(array(), array('foo' => 'bar'));
+ $request->overrideGlobals();
+
+ $this->assertEquals(array('foo' => 'bar'), $_POST);
+
+ $this->assertArrayNotHasKey('HTTP_X_FORWARDED_PROTO', $_SERVER);
+
+ $request->headers->set('X_FORWARDED_PROTO', 'https');
+
+ Request::setTrustedProxies(array('1.1.1.1'), Request::HEADER_X_FORWARDED_ALL);
+ $this->assertFalse($request->isSecure());
+ $request->server->set('REMOTE_ADDR', '1.1.1.1');
+ $this->assertTrue($request->isSecure());
+
+ $request->overrideGlobals();
+
+ $this->assertArrayHasKey('HTTP_X_FORWARDED_PROTO', $_SERVER);
+
+ $request->headers->set('CONTENT_TYPE', 'multipart/form-data');
+ $request->headers->set('CONTENT_LENGTH', 12345);
+
+ $request->overrideGlobals();
+
+ $this->assertArrayHasKey('CONTENT_TYPE', $_SERVER);
+ $this->assertArrayHasKey('CONTENT_LENGTH', $_SERVER);
+
+ $request->initialize(array('foo' => 'bar', 'baz' => 'foo'));
+ $request->query->remove('baz');
+
+ $request->overrideGlobals();
+
+ $this->assertEquals(array('foo' => 'bar'), $_GET);
+ $this->assertEquals('foo=bar', $_SERVER['QUERY_STRING']);
+ $this->assertEquals('foo=bar', $request->server->get('QUERY_STRING'));
+
+ // restore initial $_SERVER array
+ $_SERVER = $server;
+ }
+
+ public function testGetScriptName()
+ {
+ $request = new Request();
+ $this->assertEquals('', $request->getScriptName());
+
+ $server = array();
+ $server['SCRIPT_NAME'] = '/index.php';
+
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+
+ $this->assertEquals('/index.php', $request->getScriptName());
+
+ $server = array();
+ $server['ORIG_SCRIPT_NAME'] = '/frontend.php';
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+
+ $this->assertEquals('/frontend.php', $request->getScriptName());
+
+ $server = array();
+ $server['SCRIPT_NAME'] = '/index.php';
+ $server['ORIG_SCRIPT_NAME'] = '/frontend.php';
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+
+ $this->assertEquals('/index.php', $request->getScriptName());
+ }
+
+ public function testGetBasePath()
+ {
+ $request = new Request();
+ $this->assertEquals('', $request->getBasePath());
+
+ $server = array();
+ $server['SCRIPT_FILENAME'] = '/some/where/index.php';
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+ $this->assertEquals('', $request->getBasePath());
+
+ $server = array();
+ $server['SCRIPT_FILENAME'] = '/some/where/index.php';
+ $server['SCRIPT_NAME'] = '/index.php';
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+
+ $this->assertEquals('', $request->getBasePath());
+
+ $server = array();
+ $server['SCRIPT_FILENAME'] = '/some/where/index.php';
+ $server['PHP_SELF'] = '/index.php';
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+
+ $this->assertEquals('', $request->getBasePath());
+
+ $server = array();
+ $server['SCRIPT_FILENAME'] = '/some/where/index.php';
+ $server['ORIG_SCRIPT_NAME'] = '/index.php';
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+
+ $this->assertEquals('', $request->getBasePath());
+ }
+
+ public function testGetPathInfo()
+ {
+ $request = new Request();
+ $this->assertEquals('/', $request->getPathInfo());
+
+ $server = array();
+ $server['REQUEST_URI'] = '/path/info';
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+
+ $this->assertEquals('/path/info', $request->getPathInfo());
+
+ $server = array();
+ $server['REQUEST_URI'] = '/path%20test/info';
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+
+ $this->assertEquals('/path%20test/info', $request->getPathInfo());
+
+ $server = array();
+ $server['REQUEST_URI'] = '?a=b';
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+
+ $this->assertEquals('/', $request->getPathInfo());
+ }
+
+ public function testGetParameterPrecedence()
+ {
+ $request = new Request();
+ $request->attributes->set('foo', 'attr');
+ $request->query->set('foo', 'query');
+ $request->request->set('foo', 'body');
+
+ $this->assertSame('attr', $request->get('foo'));
+
+ $request->attributes->remove('foo');
+ $this->assertSame('query', $request->get('foo'));
+
+ $request->query->remove('foo');
+ $this->assertSame('body', $request->get('foo'));
+
+ $request->request->remove('foo');
+ $this->assertNull($request->get('foo'));
+ }
+
+ public function testGetPreferredLanguage()
+ {
+ $request = new Request();
+ $this->assertNull($request->getPreferredLanguage());
+ $this->assertNull($request->getPreferredLanguage(array()));
+ $this->assertEquals('fr', $request->getPreferredLanguage(array('fr')));
+ $this->assertEquals('fr', $request->getPreferredLanguage(array('fr', 'en')));
+ $this->assertEquals('en', $request->getPreferredLanguage(array('en', 'fr')));
+ $this->assertEquals('fr-ch', $request->getPreferredLanguage(array('fr-ch', 'fr-fr')));
+
+ $request = new Request();
+ $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
+ $this->assertEquals('en', $request->getPreferredLanguage(array('en', 'en-us')));
+
+ $request = new Request();
+ $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
+ $this->assertEquals('en', $request->getPreferredLanguage(array('fr', 'en')));
+
+ $request = new Request();
+ $request->headers->set('Accept-language', 'zh, en-us; q=0.8');
+ $this->assertEquals('en', $request->getPreferredLanguage(array('fr', 'en')));
+
+ $request = new Request();
+ $request->headers->set('Accept-language', 'zh, en-us; q=0.8, fr-fr; q=0.6, fr; q=0.5');
+ $this->assertEquals('en', $request->getPreferredLanguage(array('fr', 'en')));
+ }
+
+ public function testIsXmlHttpRequest()
+ {
+ $request = new Request();
+ $this->assertFalse($request->isXmlHttpRequest());
+
+ $request->headers->set('X-Requested-With', 'XMLHttpRequest');
+ $this->assertTrue($request->isXmlHttpRequest());
+
+ $request->headers->remove('X-Requested-With');
+ $this->assertFalse($request->isXmlHttpRequest());
+ }
+
+ /**
+ * @requires extension intl
+ */
+ public function testIntlLocale()
+ {
+ $request = new Request();
+
+ $request->setDefaultLocale('fr');
+ $this->assertEquals('fr', $request->getLocale());
+ $this->assertEquals('fr', \Locale::getDefault());
+
+ $request->setLocale('en');
+ $this->assertEquals('en', $request->getLocale());
+ $this->assertEquals('en', \Locale::getDefault());
+
+ $request->setDefaultLocale('de');
+ $this->assertEquals('en', $request->getLocale());
+ $this->assertEquals('en', \Locale::getDefault());
+ }
+
+ public function testGetCharsets()
+ {
+ $request = new Request();
+ $this->assertEquals(array(), $request->getCharsets());
+ $request->headers->set('Accept-Charset', 'ISO-8859-1, US-ASCII, UTF-8; q=0.8, ISO-10646-UCS-2; q=0.6');
+ $this->assertEquals(array(), $request->getCharsets()); // testing caching
+
+ $request = new Request();
+ $request->headers->set('Accept-Charset', 'ISO-8859-1, US-ASCII, UTF-8; q=0.8, ISO-10646-UCS-2; q=0.6');
+ $this->assertEquals(array('ISO-8859-1', 'US-ASCII', 'UTF-8', 'ISO-10646-UCS-2'), $request->getCharsets());
+
+ $request = new Request();
+ $request->headers->set('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.7');
+ $this->assertEquals(array('ISO-8859-1', 'utf-8', '*'), $request->getCharsets());
+ }
+
+ public function testGetEncodings()
+ {
+ $request = new Request();
+ $this->assertEquals(array(), $request->getEncodings());
+ $request->headers->set('Accept-Encoding', 'gzip,deflate,sdch');
+ $this->assertEquals(array(), $request->getEncodings()); // testing caching
+
+ $request = new Request();
+ $request->headers->set('Accept-Encoding', 'gzip,deflate,sdch');
+ $this->assertEquals(array('gzip', 'deflate', 'sdch'), $request->getEncodings());
+
+ $request = new Request();
+ $request->headers->set('Accept-Encoding', 'gzip;q=0.4,deflate;q=0.9,compress;q=0.7');
+ $this->assertEquals(array('deflate', 'compress', 'gzip'), $request->getEncodings());
+ }
+
+ public function testGetAcceptableContentTypes()
+ {
+ $request = new Request();
+ $this->assertEquals(array(), $request->getAcceptableContentTypes());
+ $request->headers->set('Accept', 'application/vnd.wap.wmlscriptc, text/vnd.wap.wml, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/html, multipart/mixed, */*');
+ $this->assertEquals(array(), $request->getAcceptableContentTypes()); // testing caching
+
+ $request = new Request();
+ $request->headers->set('Accept', 'application/vnd.wap.wmlscriptc, text/vnd.wap.wml, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/html, multipart/mixed, */*');
+ $this->assertEquals(array('application/vnd.wap.wmlscriptc', 'text/vnd.wap.wml', 'application/vnd.wap.xhtml+xml', 'application/xhtml+xml', 'text/html', 'multipart/mixed', '*/*'), $request->getAcceptableContentTypes());
+ }
+
+ public function testGetLanguages()
+ {
+ $request = new Request();
+ $this->assertEquals(array(), $request->getLanguages());
+
+ $request = new Request();
+ $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
+ $this->assertEquals(array('zh', 'en_US', 'en'), $request->getLanguages());
+ $this->assertEquals(array('zh', 'en_US', 'en'), $request->getLanguages());
+
+ $request = new Request();
+ $request->headers->set('Accept-language', 'zh, en-us; q=0.6, en; q=0.8');
+ $this->assertEquals(array('zh', 'en', 'en_US'), $request->getLanguages()); // Test out of order qvalues
+
+ $request = new Request();
+ $request->headers->set('Accept-language', 'zh, en, en-us');
+ $this->assertEquals(array('zh', 'en', 'en_US'), $request->getLanguages()); // Test equal weighting without qvalues
+
+ $request = new Request();
+ $request->headers->set('Accept-language', 'zh; q=0.6, en, en-us; q=0.6');
+ $this->assertEquals(array('en', 'zh', 'en_US'), $request->getLanguages()); // Test equal weighting with qvalues
+
+ $request = new Request();
+ $request->headers->set('Accept-language', 'zh, i-cherokee; q=0.6');
+ $this->assertEquals(array('zh', 'cherokee'), $request->getLanguages());
+ }
+
+ public function testGetRequestFormat()
+ {
+ $request = new Request();
+ $this->assertEquals('html', $request->getRequestFormat());
+
+ // Ensure that setting different default values over time is possible,
+ // aka. setRequestFormat determines the state.
+ $this->assertEquals('json', $request->getRequestFormat('json'));
+ $this->assertEquals('html', $request->getRequestFormat('html'));
+
+ $request = new Request();
+ $this->assertNull($request->getRequestFormat(null));
+
+ $request = new Request();
+ $this->assertNull($request->setRequestFormat('foo'));
+ $this->assertEquals('foo', $request->getRequestFormat(null));
+
+ $request = new Request(array('_format' => 'foo'));
+ $this->assertEquals('html', $request->getRequestFormat());
+ }
+
+ public function testHasSession()
+ {
+ $request = new Request();
+
+ $this->assertFalse($request->hasSession());
+ $request->setSession(new Session(new MockArraySessionStorage()));
+ $this->assertTrue($request->hasSession());
+ }
+
+ public function testGetSession()
+ {
+ $request = new Request();
+
+ $request->setSession(new Session(new MockArraySessionStorage()));
+ $this->assertTrue($request->hasSession());
+
+ $session = $request->getSession();
+ $this->assertObjectHasAttribute('storage', $session);
+ $this->assertObjectHasAttribute('flashName', $session);
+ $this->assertObjectHasAttribute('attributeName', $session);
+ }
+
+ public function testHasPreviousSession()
+ {
+ $request = new Request();
+
+ $this->assertFalse($request->hasPreviousSession());
+ $request->cookies->set('MOCKSESSID', 'foo');
+ $this->assertFalse($request->hasPreviousSession());
+ $request->setSession(new Session(new MockArraySessionStorage()));
+ $this->assertTrue($request->hasPreviousSession());
+ }
+
+ public function testToString()
+ {
+ $request = new Request();
+
+ $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
+ $request->cookies->set('Foo', 'Bar');
+
+ $asString = (string) $request;
+
+ $this->assertContains('Accept-Language: zh, en-us; q=0.8, en; q=0.6', $asString);
+ $this->assertContains('Cookie: Foo=Bar', $asString);
+
+ $request->cookies->set('Another', 'Cookie');
+
+ $asString = (string) $request;
+
+ $this->assertContains('Cookie: Foo=Bar; Another=Cookie', $asString);
+ }
+
+ public function testIsMethod()
+ {
+ $request = new Request();
+ $request->setMethod('POST');
+ $this->assertTrue($request->isMethod('POST'));
+ $this->assertTrue($request->isMethod('post'));
+ $this->assertFalse($request->isMethod('GET'));
+ $this->assertFalse($request->isMethod('get'));
+
+ $request->setMethod('GET');
+ $this->assertTrue($request->isMethod('GET'));
+ $this->assertTrue($request->isMethod('get'));
+ $this->assertFalse($request->isMethod('POST'));
+ $this->assertFalse($request->isMethod('post'));
+ }
+
+ /**
+ * @dataProvider getBaseUrlData
+ */
+ public function testGetBaseUrl($uri, $server, $expectedBaseUrl, $expectedPathInfo)
+ {
+ $request = Request::create($uri, 'GET', array(), array(), array(), $server);
+
+ $this->assertSame($expectedBaseUrl, $request->getBaseUrl(), 'baseUrl');
+ $this->assertSame($expectedPathInfo, $request->getPathInfo(), 'pathInfo');
+ }
+
+ public function getBaseUrlData()
+ {
+ return array(
+ array(
+ '/fruit/strawberry/1234index.php/blah',
+ array(
+ 'SCRIPT_FILENAME' => 'E:/Sites/cc-new/public_html/fruit/index.php',
+ 'SCRIPT_NAME' => '/fruit/index.php',
+ 'PHP_SELF' => '/fruit/index.php',
+ ),
+ '/fruit',
+ '/strawberry/1234index.php/blah',
+ ),
+ array(
+ '/fruit/strawberry/1234index.php/blah',
+ array(
+ 'SCRIPT_FILENAME' => 'E:/Sites/cc-new/public_html/index.php',
+ 'SCRIPT_NAME' => '/index.php',
+ 'PHP_SELF' => '/index.php',
+ ),
+ '',
+ '/fruit/strawberry/1234index.php/blah',
+ ),
+ array(
+ '/foo%20bar/',
+ array(
+ 'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
+ 'SCRIPT_NAME' => '/foo bar/app.php',
+ 'PHP_SELF' => '/foo bar/app.php',
+ ),
+ '/foo%20bar',
+ '/',
+ ),
+ array(
+ '/foo%20bar/home',
+ array(
+ 'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
+ 'SCRIPT_NAME' => '/foo bar/app.php',
+ 'PHP_SELF' => '/foo bar/app.php',
+ ),
+ '/foo%20bar',
+ '/home',
+ ),
+ array(
+ '/foo%20bar/app.php/home',
+ array(
+ 'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
+ 'SCRIPT_NAME' => '/foo bar/app.php',
+ 'PHP_SELF' => '/foo bar/app.php',
+ ),
+ '/foo%20bar/app.php',
+ '/home',
+ ),
+ array(
+ '/foo%20bar/app.php/home%3Dbaz',
+ array(
+ 'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
+ 'SCRIPT_NAME' => '/foo bar/app.php',
+ 'PHP_SELF' => '/foo bar/app.php',
+ ),
+ '/foo%20bar/app.php',
+ '/home%3Dbaz',
+ ),
+ array(
+ '/foo/bar+baz',
+ array(
+ 'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo/app.php',
+ 'SCRIPT_NAME' => '/foo/app.php',
+ 'PHP_SELF' => '/foo/app.php',
+ ),
+ '/foo',
+ '/bar+baz',
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider urlencodedStringPrefixData
+ */
+ public function testUrlencodedStringPrefix($string, $prefix, $expect)
+ {
+ $request = new Request();
+
+ $me = new \ReflectionMethod($request, 'getUrlencodedPrefix');
+ $me->setAccessible(true);
+
+ $this->assertSame($expect, $me->invoke($request, $string, $prefix));
+ }
+
+ public function urlencodedStringPrefixData()
+ {
+ return array(
+ array('foo', 'foo', 'foo'),
+ array('fo%6f', 'foo', 'fo%6f'),
+ array('foo/bar', 'foo', 'foo'),
+ array('fo%6f/bar', 'foo', 'fo%6f'),
+ array('f%6f%6f/bar', 'foo', 'f%6f%6f'),
+ array('%66%6F%6F/bar', 'foo', '%66%6F%6F'),
+ array('fo+o/bar', 'fo+o', 'fo+o'),
+ array('fo%2Bo/bar', 'fo+o', 'fo%2Bo'),
+ );
+ }
+
+ private function disableHttpMethodParameterOverride()
+ {
+ $class = new \ReflectionClass('Symfony\\Component\\HttpFoundation\\Request');
+ $property = $class->getProperty('httpMethodParameterOverride');
+ $property->setAccessible(true);
+ $property->setValue(false);
+ }
+
+ private function getRequestInstanceForClientIpTests($remoteAddr, $httpForwardedFor, $trustedProxies)
+ {
+ $request = new Request();
+
+ $server = array('REMOTE_ADDR' => $remoteAddr);
+ if (null !== $httpForwardedFor) {
+ $server['HTTP_X_FORWARDED_FOR'] = $httpForwardedFor;
+ }
+
+ if ($trustedProxies) {
+ Request::setTrustedProxies($trustedProxies, Request::HEADER_X_FORWARDED_ALL);
+ }
+
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+
+ return $request;
+ }
+
+ private function getRequestInstanceForClientIpsForwardedTests($remoteAddr, $httpForwarded, $trustedProxies)
+ {
+ $request = new Request();
+
+ $server = array('REMOTE_ADDR' => $remoteAddr);
+
+ if (null !== $httpForwarded) {
+ $server['HTTP_FORWARDED'] = $httpForwarded;
+ }
+
+ if ($trustedProxies) {
+ Request::setTrustedProxies($trustedProxies, Request::HEADER_FORWARDED);
+ }
+
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+
+ return $request;
+ }
+
+ public function testTrustedProxiesXForwardedFor()
+ {
+ $request = Request::create('http://example.com/');
+ $request->server->set('REMOTE_ADDR', '3.3.3.3');
+ $request->headers->set('X_FORWARDED_FOR', '1.1.1.1, 2.2.2.2');
+ $request->headers->set('X_FORWARDED_HOST', 'foo.example.com:1234, real.example.com:8080');
+ $request->headers->set('X_FORWARDED_PROTO', 'https');
+ $request->headers->set('X_FORWARDED_PORT', 443);
+
+ // no trusted proxies
+ $this->assertEquals('3.3.3.3', $request->getClientIp());
+ $this->assertEquals('example.com', $request->getHost());
+ $this->assertEquals(80, $request->getPort());
+ $this->assertFalse($request->isSecure());
+
+ // disabling proxy trusting
+ Request::setTrustedProxies(array(), Request::HEADER_X_FORWARDED_ALL);
+ $this->assertEquals('3.3.3.3', $request->getClientIp());
+ $this->assertEquals('example.com', $request->getHost());
+ $this->assertEquals(80, $request->getPort());
+ $this->assertFalse($request->isSecure());
+
+ // request is forwarded by a non-trusted proxy
+ Request::setTrustedProxies(array('2.2.2.2'), Request::HEADER_X_FORWARDED_ALL);
+ $this->assertEquals('3.3.3.3', $request->getClientIp());
+ $this->assertEquals('example.com', $request->getHost());
+ $this->assertEquals(80, $request->getPort());
+ $this->assertFalse($request->isSecure());
+
+ // trusted proxy via setTrustedProxies()
+ Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'), Request::HEADER_X_FORWARDED_ALL);
+ $this->assertEquals('1.1.1.1', $request->getClientIp());
+ $this->assertEquals('foo.example.com', $request->getHost());
+ $this->assertEquals(443, $request->getPort());
+ $this->assertTrue($request->isSecure());
+
+ // trusted proxy via setTrustedProxies()
+ Request::setTrustedProxies(array('3.3.3.4', '2.2.2.2'), Request::HEADER_X_FORWARDED_ALL);
+ $this->assertEquals('3.3.3.3', $request->getClientIp());
+ $this->assertEquals('example.com', $request->getHost());
+ $this->assertEquals(80, $request->getPort());
+ $this->assertFalse($request->isSecure());
+
+ // check various X_FORWARDED_PROTO header values
+ Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'), Request::HEADER_X_FORWARDED_ALL);
+ $request->headers->set('X_FORWARDED_PROTO', 'ssl');
+ $this->assertTrue($request->isSecure());
+
+ $request->headers->set('X_FORWARDED_PROTO', 'https, http');
+ $this->assertTrue($request->isSecure());
+ }
+
+ /**
+ * @group legacy
+ * @expectedDeprecation The "Symfony\Component\HttpFoundation\Request::setTrustedHeaderName()" method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the $trustedHeaderSet argument of the Request::setTrustedProxies() method instead.
+ */
+ public function testLegacyTrustedProxies()
+ {
+ $request = Request::create('http://example.com/');
+ $request->server->set('REMOTE_ADDR', '3.3.3.3');
+ $request->headers->set('X_FORWARDED_FOR', '1.1.1.1, 2.2.2.2');
+ $request->headers->set('X_FORWARDED_HOST', 'foo.example.com, real.example.com:8080');
+ $request->headers->set('X_FORWARDED_PROTO', 'https');
+ $request->headers->set('X_FORWARDED_PORT', 443);
+ $request->headers->set('X_MY_FOR', '3.3.3.3, 4.4.4.4');
+ $request->headers->set('X_MY_HOST', 'my.example.com');
+ $request->headers->set('X_MY_PROTO', 'http');
+ $request->headers->set('X_MY_PORT', 81);
+
+ Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'), Request::HEADER_X_FORWARDED_ALL);
+
+ // custom header names
+ Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'X_MY_FOR');
+ Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, 'X_MY_HOST');
+ Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, 'X_MY_PORT');
+ Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, 'X_MY_PROTO');
+ $this->assertEquals('4.4.4.4', $request->getClientIp());
+ $this->assertEquals('my.example.com', $request->getHost());
+ $this->assertEquals(81, $request->getPort());
+ $this->assertFalse($request->isSecure());
+
+ // disabling via empty header names
+ Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, null);
+ Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, null);
+ Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, null);
+ Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, null);
+ $this->assertEquals('3.3.3.3', $request->getClientIp());
+ $this->assertEquals('example.com', $request->getHost());
+ $this->assertEquals(80, $request->getPort());
+ $this->assertFalse($request->isSecure());
+
+ //reset
+ Request::setTrustedHeaderName(Request::HEADER_FORWARDED, 'FORWARDED');
+ Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'X_FORWARDED_FOR');
+ Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, 'X_FORWARDED_HOST');
+ Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, 'X_FORWARDED_PORT');
+ Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, 'X_FORWARDED_PROTO');
+ }
+
+ public function testTrustedProxiesForwarded()
+ {
+ $request = Request::create('http://example.com/');
+ $request->server->set('REMOTE_ADDR', '3.3.3.3');
+ $request->headers->set('FORWARDED', 'for=1.1.1.1, host=foo.example.com:8080, proto=https, for=2.2.2.2, host=real.example.com:8080');
+
+ // no trusted proxies
+ $this->assertEquals('3.3.3.3', $request->getClientIp());
+ $this->assertEquals('example.com', $request->getHost());
+ $this->assertEquals(80, $request->getPort());
+ $this->assertFalse($request->isSecure());
+
+ // disabling proxy trusting
+ Request::setTrustedProxies(array(), Request::HEADER_FORWARDED);
+ $this->assertEquals('3.3.3.3', $request->getClientIp());
+ $this->assertEquals('example.com', $request->getHost());
+ $this->assertEquals(80, $request->getPort());
+ $this->assertFalse($request->isSecure());
+
+ // request is forwarded by a non-trusted proxy
+ Request::setTrustedProxies(array('2.2.2.2'), Request::HEADER_FORWARDED);
+ $this->assertEquals('3.3.3.3', $request->getClientIp());
+ $this->assertEquals('example.com', $request->getHost());
+ $this->assertEquals(80, $request->getPort());
+ $this->assertFalse($request->isSecure());
+
+ // trusted proxy via setTrustedProxies()
+ Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'), Request::HEADER_FORWARDED);
+ $this->assertEquals('1.1.1.1', $request->getClientIp());
+ $this->assertEquals('foo.example.com', $request->getHost());
+ $this->assertEquals(8080, $request->getPort());
+ $this->assertTrue($request->isSecure());
+
+ // trusted proxy via setTrustedProxies()
+ Request::setTrustedProxies(array('3.3.3.4', '2.2.2.2'), Request::HEADER_FORWARDED);
+ $this->assertEquals('3.3.3.3', $request->getClientIp());
+ $this->assertEquals('example.com', $request->getHost());
+ $this->assertEquals(80, $request->getPort());
+ $this->assertFalse($request->isSecure());
+
+ // check various X_FORWARDED_PROTO header values
+ Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'), Request::HEADER_FORWARDED);
+ $request->headers->set('FORWARDED', 'proto=ssl');
+ $this->assertTrue($request->isSecure());
+
+ $request->headers->set('FORWARDED', 'proto=https, proto=http');
+ $this->assertTrue($request->isSecure());
+ }
+
+ /**
+ * @group legacy
+ * @expectedException \InvalidArgumentException
+ */
+ public function testSetTrustedProxiesInvalidHeaderName()
+ {
+ Request::create('http://example.com/');
+ Request::setTrustedHeaderName('bogus name', 'X_MY_FOR');
+ }
+
+ /**
+ * @group legacy
+ * @expectedException \InvalidArgumentException
+ */
+ public function testGetTrustedProxiesInvalidHeaderName()
+ {
+ Request::create('http://example.com/');
+ Request::getTrustedHeaderName('bogus name');
+ }
+
+ /**
+ * @dataProvider iisRequestUriProvider
+ */
+ public function testIISRequestUri($headers, $server, $expectedRequestUri)
+ {
+ $request = new Request();
+ $request->headers->replace($headers);
+ $request->server->replace($server);
+
+ $this->assertEquals($expectedRequestUri, $request->getRequestUri(), '->getRequestUri() is correct');
+
+ $subRequestUri = '/bar/foo';
+ $subRequest = Request::create($subRequestUri, 'get', array(), array(), array(), $request->server->all());
+ $this->assertEquals($subRequestUri, $subRequest->getRequestUri(), '->getRequestUri() is correct in sub request');
+ }
+
+ public function iisRequestUriProvider()
+ {
+ return array(
+ array(
+ array(
+ 'X_ORIGINAL_URL' => '/foo/bar',
+ ),
+ array(),
+ '/foo/bar',
+ ),
+ array(
+ array(
+ 'X_REWRITE_URL' => '/foo/bar',
+ ),
+ array(),
+ '/foo/bar',
+ ),
+ array(
+ array(),
+ array(
+ 'IIS_WasUrlRewritten' => '1',
+ 'UNENCODED_URL' => '/foo/bar',
+ ),
+ '/foo/bar',
+ ),
+ array(
+ array(
+ 'X_ORIGINAL_URL' => '/foo/bar',
+ ),
+ array(
+ 'HTTP_X_ORIGINAL_URL' => '/foo/bar',
+ ),
+ '/foo/bar',
+ ),
+ array(
+ array(
+ 'X_ORIGINAL_URL' => '/foo/bar',
+ ),
+ array(
+ 'IIS_WasUrlRewritten' => '1',
+ 'UNENCODED_URL' => '/foo/bar',
+ ),
+ '/foo/bar',
+ ),
+ array(
+ array(
+ 'X_ORIGINAL_URL' => '/foo/bar',
+ ),
+ array(
+ 'HTTP_X_ORIGINAL_URL' => '/foo/bar',
+ 'IIS_WasUrlRewritten' => '1',
+ 'UNENCODED_URL' => '/foo/bar',
+ ),
+ '/foo/bar',
+ ),
+ array(
+ array(),
+ array(
+ 'ORIG_PATH_INFO' => '/foo/bar',
+ ),
+ '/foo/bar',
+ ),
+ array(
+ array(),
+ array(
+ 'ORIG_PATH_INFO' => '/foo/bar',
+ 'QUERY_STRING' => 'foo=bar',
+ ),
+ '/foo/bar?foo=bar',
+ ),
+ );
+ }
+
+ public function testTrustedHosts()
+ {
+ // create a request
+ $request = Request::create('/');
+
+ // no trusted host set -> no host check
+ $request->headers->set('host', 'evil.com');
+ $this->assertEquals('evil.com', $request->getHost());
+
+ // add a trusted domain and all its subdomains
+ Request::setTrustedHosts(array('^([a-z]{9}\.)?trusted\.com$'));
+
+ // untrusted host
+ $request->headers->set('host', 'evil.com');
+ try {
+ $request->getHost();
+ $this->fail('Request::getHost() should throw an exception when host is not trusted.');
+ } catch (SuspiciousOperationException $e) {
+ $this->assertEquals('Untrusted Host "evil.com".', $e->getMessage());
+ }
+
+ // trusted hosts
+ $request->headers->set('host', 'trusted.com');
+ $this->assertEquals('trusted.com', $request->getHost());
+ $this->assertEquals(80, $request->getPort());
+
+ $request->server->set('HTTPS', true);
+ $request->headers->set('host', 'trusted.com');
+ $this->assertEquals('trusted.com', $request->getHost());
+ $this->assertEquals(443, $request->getPort());
+ $request->server->set('HTTPS', false);
+
+ $request->headers->set('host', 'trusted.com:8000');
+ $this->assertEquals('trusted.com', $request->getHost());
+ $this->assertEquals(8000, $request->getPort());
+
+ $request->headers->set('host', 'subdomain.trusted.com');
+ $this->assertEquals('subdomain.trusted.com', $request->getHost());
+
+ // reset request for following tests
+ Request::setTrustedHosts(array());
+ }
+
+ public function testFactory()
+ {
+ Request::setFactory(function (array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null) {
+ return new NewRequest();
+ });
+
+ $this->assertEquals('foo', Request::create('/')->getFoo());
+
+ Request::setFactory(null);
+ }
+
+ /**
+ * @dataProvider getLongHostNames
+ */
+ public function testVeryLongHosts($host)
+ {
+ $start = microtime(true);
+
+ $request = Request::create('/');
+ $request->headers->set('host', $host);
+ $this->assertEquals($host, $request->getHost());
+ $this->assertLessThan(5, microtime(true) - $start);
+ }
+
+ /**
+ * @dataProvider getHostValidities
+ */
+ public function testHostValidity($host, $isValid, $expectedHost = null, $expectedPort = null)
+ {
+ $request = Request::create('/');
+ $request->headers->set('host', $host);
+
+ if ($isValid) {
+ $this->assertSame($expectedHost ?: $host, $request->getHost());
+ if ($expectedPort) {
+ $this->assertSame($expectedPort, $request->getPort());
+ }
+ } else {
+ if (method_exists($this, 'expectException')) {
+ $this->expectException(SuspiciousOperationException::class);
+ $this->expectExceptionMessage('Invalid Host');
+ } else {
+ $this->setExpectedException(SuspiciousOperationException::class, 'Invalid Host');
+ }
+
+ $request->getHost();
+ }
+ }
+
+ public function getHostValidities()
+ {
+ return array(
+ array('.a', false),
+ array('a..', false),
+ array('a.', true),
+ array("\xE9", false),
+ array('[::1]', true),
+ array('[::1]:80', true, '[::1]', 80),
+ array(str_repeat('.', 101), false),
+ );
+ }
+
+ public function getLongHostNames()
+ {
+ return array(
+ array('a'.str_repeat('.a', 40000)),
+ array(str_repeat(':', 101)),
+ );
+ }
+
+ /**
+ * @dataProvider methodIdempotentProvider
+ */
+ public function testMethodIdempotent($method, $idempotent)
+ {
+ $request = new Request();
+ $request->setMethod($method);
+ $this->assertEquals($idempotent, $request->isMethodIdempotent());
+ }
+
+ public function methodIdempotentProvider()
+ {
+ return array(
+ array('HEAD', true),
+ array('GET', true),
+ array('POST', false),
+ array('PUT', true),
+ array('PATCH', false),
+ array('DELETE', true),
+ array('PURGE', true),
+ array('OPTIONS', true),
+ array('TRACE', true),
+ array('CONNECT', false),
+ );
+ }
+
+ /**
+ * @dataProvider methodSafeProvider
+ */
+ public function testMethodSafe($method, $safe)
+ {
+ $request = new Request();
+ $request->setMethod($method);
+ $this->assertEquals($safe, $request->isMethodSafe(false));
+ }
+
+ public function methodSafeProvider()
+ {
+ return array(
+ array('HEAD', true),
+ array('GET', true),
+ array('POST', false),
+ array('PUT', false),
+ array('PATCH', false),
+ array('DELETE', false),
+ array('PURGE', false),
+ array('OPTIONS', true),
+ array('TRACE', true),
+ array('CONNECT', false),
+ );
+ }
+
+ /**
+ * @group legacy
+ * @expectedDeprecation Checking only for cacheable HTTP methods with Symfony\Component\HttpFoundation\Request::isMethodSafe() is deprecated since Symfony 3.2 and will throw an exception in 4.0. Disable checking only for cacheable methods by calling the method with `false` as first argument or use the Request::isMethodCacheable() instead.
+ */
+ public function testMethodSafeChecksCacheable()
+ {
+ $request = new Request();
+ $request->setMethod('OPTIONS');
+ $this->assertFalse($request->isMethodSafe());
+ }
+
+ /**
+ * @dataProvider methodCacheableProvider
+ */
+ public function testMethodCacheable($method, $cacheable)
+ {
+ $request = new Request();
+ $request->setMethod($method);
+ $this->assertEquals($cacheable, $request->isMethodCacheable());
+ }
+
+ public function methodCacheableProvider()
+ {
+ return array(
+ array('HEAD', true),
+ array('GET', true),
+ array('POST', false),
+ array('PUT', false),
+ array('PATCH', false),
+ array('DELETE', false),
+ array('PURGE', false),
+ array('OPTIONS', false),
+ array('TRACE', false),
+ array('CONNECT', false),
+ );
+ }
+
+ /**
+ * @group legacy
+ */
+ public function testGetTrustedHeaderName()
+ {
+ Request::setTrustedProxies(array('8.8.8.8'), Request::HEADER_X_FORWARDED_ALL);
+
+ $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_FORWARDED));
+ $this->assertSame('X_FORWARDED_FOR', Request::getTrustedHeaderName(Request::HEADER_CLIENT_IP));
+ $this->assertSame('X_FORWARDED_HOST', Request::getTrustedHeaderName(Request::HEADER_CLIENT_HOST));
+ $this->assertSame('X_FORWARDED_PORT', Request::getTrustedHeaderName(Request::HEADER_CLIENT_PORT));
+ $this->assertSame('X_FORWARDED_PROTO', Request::getTrustedHeaderName(Request::HEADER_CLIENT_PROTO));
+
+ Request::setTrustedProxies(array('8.8.8.8'), Request::HEADER_FORWARDED);
+
+ $this->assertSame('FORWARDED', Request::getTrustedHeaderName(Request::HEADER_FORWARDED));
+ $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_IP));
+ $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_HOST));
+ $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_PORT));
+ $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_PROTO));
+
+ Request::setTrustedHeaderName(Request::HEADER_FORWARDED, 'A');
+ Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'B');
+ Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, 'C');
+ Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, 'D');
+ Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, 'E');
+
+ Request::setTrustedProxies(array('8.8.8.8'), Request::HEADER_FORWARDED);
+
+ $this->assertSame('A', Request::getTrustedHeaderName(Request::HEADER_FORWARDED));
+ $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_IP));
+ $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_HOST));
+ $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_PORT));
+ $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_PROTO));
+
+ Request::setTrustedProxies(array('8.8.8.8'), Request::HEADER_X_FORWARDED_ALL);
+
+ $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_FORWARDED));
+ $this->assertSame('B', Request::getTrustedHeaderName(Request::HEADER_CLIENT_IP));
+ $this->assertSame('C', Request::getTrustedHeaderName(Request::HEADER_CLIENT_HOST));
+ $this->assertSame('D', Request::getTrustedHeaderName(Request::HEADER_CLIENT_PORT));
+ $this->assertSame('E', Request::getTrustedHeaderName(Request::HEADER_CLIENT_PROTO));
+
+ Request::setTrustedProxies(array('8.8.8.8'), Request::HEADER_FORWARDED);
+
+ $this->assertSame('A', Request::getTrustedHeaderName(Request::HEADER_FORWARDED));
+
+ //reset
+ Request::setTrustedHeaderName(Request::HEADER_FORWARDED, 'FORWARDED');
+ Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'X_FORWARDED_FOR');
+ Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, 'X_FORWARDED_HOST');
+ Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, 'X_FORWARDED_PORT');
+ Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, 'X_FORWARDED_PROTO');
+ }
+
+ /**
+ * @dataProvider protocolVersionProvider
+ */
+ public function testProtocolVersion($serverProtocol, $trustedProxy, $via, $expected)
+ {
+ if ($trustedProxy) {
+ Request::setTrustedProxies(array('1.1.1.1'), -1);
+ }
+
+ $request = new Request();
+ $request->server->set('SERVER_PROTOCOL', $serverProtocol);
+ $request->server->set('REMOTE_ADDR', '1.1.1.1');
+ $request->headers->set('Via', $via);
+
+ $this->assertSame($expected, $request->getProtocolVersion());
+ }
+
+ public function protocolVersionProvider()
+ {
+ return array(
+ 'untrusted without via' => array('HTTP/2.0', false, '', 'HTTP/2.0'),
+ 'untrusted with via' => array('HTTP/2.0', false, '1.0 fred, 1.1 nowhere.com (Apache/1.1)', 'HTTP/2.0'),
+ 'trusted without via' => array('HTTP/2.0', true, '', 'HTTP/2.0'),
+ 'trusted with via' => array('HTTP/2.0', true, '1.0 fred, 1.1 nowhere.com (Apache/1.1)', 'HTTP/1.0'),
+ 'trusted with via and protocol name' => array('HTTP/2.0', true, 'HTTP/1.0 fred, HTTP/1.1 nowhere.com (Apache/1.1)', 'HTTP/1.0'),
+ 'trusted with broken via' => array('HTTP/2.0', true, 'HTTP/1^0 foo', 'HTTP/2.0'),
+ 'trusted with partially-broken via' => array('HTTP/2.0', true, '1.0 fred, foo', 'HTTP/1.0'),
+ );
+ }
+
+ public function nonstandardRequestsData()
+ {
+ return array(
+ array('', '', '/', 'http://host:8080/', ''),
+ array('/', '', '/', 'http://host:8080/', ''),
+
+ array('hello/app.php/x', '', '/x', 'http://host:8080/hello/app.php/x', '/hello', '/hello/app.php'),
+ array('/hello/app.php/x', '', '/x', 'http://host:8080/hello/app.php/x', '/hello', '/hello/app.php'),
+
+ array('', 'a=b', '/', 'http://host:8080/?a=b'),
+ array('?a=b', 'a=b', '/', 'http://host:8080/?a=b'),
+ array('/?a=b', 'a=b', '/', 'http://host:8080/?a=b'),
+
+ array('x', 'a=b', '/x', 'http://host:8080/x?a=b'),
+ array('x?a=b', 'a=b', '/x', 'http://host:8080/x?a=b'),
+ array('/x?a=b', 'a=b', '/x', 'http://host:8080/x?a=b'),
+
+ array('hello/x', '', '/x', 'http://host:8080/hello/x', '/hello'),
+ array('/hello/x', '', '/x', 'http://host:8080/hello/x', '/hello'),
+
+ array('hello/app.php/x', 'a=b', '/x', 'http://host:8080/hello/app.php/x?a=b', '/hello', '/hello/app.php'),
+ array('hello/app.php/x?a=b', 'a=b', '/x', 'http://host:8080/hello/app.php/x?a=b', '/hello', '/hello/app.php'),
+ array('/hello/app.php/x?a=b', 'a=b', '/x', 'http://host:8080/hello/app.php/x?a=b', '/hello', '/hello/app.php'),
+ );
+ }
+
+ /**
+ * @dataProvider nonstandardRequestsData
+ */
+ public function testNonstandardRequests($requestUri, $queryString, $expectedPathInfo, $expectedUri, $expectedBasePath = '', $expectedBaseUrl = null)
+ {
+ if (null === $expectedBaseUrl) {
+ $expectedBaseUrl = $expectedBasePath;
+ }
+
+ $server = array(
+ 'HTTP_HOST' => 'host:8080',
+ 'SERVER_PORT' => '8080',
+ 'QUERY_STRING' => $queryString,
+ 'PHP_SELF' => '/hello/app.php',
+ 'SCRIPT_FILENAME' => '/some/path/app.php',
+ 'REQUEST_URI' => $requestUri,
+ );
+
+ $request = new Request(array(), array(), array(), array(), array(), $server);
+
+ $this->assertEquals($expectedPathInfo, $request->getPathInfo());
+ $this->assertEquals($expectedUri, $request->getUri());
+ $this->assertEquals($queryString, $request->getQueryString());
+ $this->assertEquals(8080, $request->getPort());
+ $this->assertEquals('host:8080', $request->getHttpHost());
+ $this->assertEquals($expectedBaseUrl, $request->getBaseUrl());
+ $this->assertEquals($expectedBasePath, $request->getBasePath());
+ }
+}
+
+class RequestContentProxy extends Request
+{
+ public function getContent($asResource = false)
+ {
+ return http_build_query(array('_method' => 'PUT', 'content' => 'mycontent'), '', '&');
+ }
+}
+
+class NewRequest extends Request
+{
+ public function getFoo()
+ {
+ return 'foo';
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/ResponseHeaderBagTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/ResponseHeaderBagTest.php
new file mode 100644
index 0000000..ce85535
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/ResponseHeaderBagTest.php
@@ -0,0 +1,363 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\ResponseHeaderBag;
+use Symfony\Component\HttpFoundation\Cookie;
+
+/**
+ * @group time-sensitive
+ */
+class ResponseHeaderBagTest extends TestCase
+{
+ public function testAllPreserveCase()
+ {
+ $headers = array(
+ 'fOo' => 'BAR',
+ 'ETag' => 'xyzzy',
+ 'Content-MD5' => 'Q2hlY2sgSW50ZWdyaXR5IQ==',
+ 'P3P' => 'CP="CAO PSA OUR"',
+ 'WWW-Authenticate' => 'Basic realm="WallyWorld"',
+ 'X-UA-Compatible' => 'IE=edge,chrome=1',
+ 'X-XSS-Protection' => '1; mode=block',
+ );
+
+ $bag = new ResponseHeaderBag($headers);
+ $allPreservedCase = $bag->allPreserveCase();
+
+ foreach (array_keys($headers) as $headerName) {
+ $this->assertArrayHasKey($headerName, $allPreservedCase, '->allPreserveCase() gets all input keys in original case');
+ }
+ }
+
+ public function testCacheControlHeader()
+ {
+ $bag = new ResponseHeaderBag(array());
+ $this->assertEquals('no-cache, private', $bag->get('Cache-Control'));
+ $this->assertTrue($bag->hasCacheControlDirective('no-cache'));
+
+ $bag = new ResponseHeaderBag(array('Cache-Control' => 'public'));
+ $this->assertEquals('public', $bag->get('Cache-Control'));
+ $this->assertTrue($bag->hasCacheControlDirective('public'));
+
+ $bag = new ResponseHeaderBag(array('ETag' => 'abcde'));
+ $this->assertEquals('private, must-revalidate', $bag->get('Cache-Control'));
+ $this->assertTrue($bag->hasCacheControlDirective('private'));
+ $this->assertTrue($bag->hasCacheControlDirective('must-revalidate'));
+ $this->assertFalse($bag->hasCacheControlDirective('max-age'));
+
+ $bag = new ResponseHeaderBag(array('Expires' => 'Wed, 16 Feb 2011 14:17:43 GMT'));
+ $this->assertEquals('private, must-revalidate', $bag->get('Cache-Control'));
+
+ $bag = new ResponseHeaderBag(array(
+ 'Expires' => 'Wed, 16 Feb 2011 14:17:43 GMT',
+ 'Cache-Control' => 'max-age=3600',
+ ));
+ $this->assertEquals('max-age=3600, private', $bag->get('Cache-Control'));
+
+ $bag = new ResponseHeaderBag(array('Last-Modified' => 'abcde'));
+ $this->assertEquals('private, must-revalidate', $bag->get('Cache-Control'));
+
+ $bag = new ResponseHeaderBag(array('Etag' => 'abcde', 'Last-Modified' => 'abcde'));
+ $this->assertEquals('private, must-revalidate', $bag->get('Cache-Control'));
+
+ $bag = new ResponseHeaderBag(array('cache-control' => 'max-age=100'));
+ $this->assertEquals('max-age=100, private', $bag->get('Cache-Control'));
+
+ $bag = new ResponseHeaderBag(array('cache-control' => 's-maxage=100'));
+ $this->assertEquals('s-maxage=100', $bag->get('Cache-Control'));
+
+ $bag = new ResponseHeaderBag(array('cache-control' => 'private, max-age=100'));
+ $this->assertEquals('max-age=100, private', $bag->get('Cache-Control'));
+
+ $bag = new ResponseHeaderBag(array('cache-control' => 'public, max-age=100'));
+ $this->assertEquals('max-age=100, public', $bag->get('Cache-Control'));
+
+ $bag = new ResponseHeaderBag();
+ $bag->set('Last-Modified', 'abcde');
+ $this->assertEquals('private, must-revalidate', $bag->get('Cache-Control'));
+
+ $bag = new ResponseHeaderBag();
+ $bag->set('Cache-Control', array('public', 'must-revalidate'));
+ $this->assertCount(1, $bag->get('Cache-Control', null, false));
+ $this->assertEquals('must-revalidate, public', $bag->get('Cache-Control'));
+
+ $bag = new ResponseHeaderBag();
+ $bag->set('Cache-Control', 'public');
+ $bag->set('Cache-Control', 'must-revalidate', false);
+ $this->assertCount(1, $bag->get('Cache-Control', null, false));
+ $this->assertEquals('must-revalidate, public', $bag->get('Cache-Control'));
+ }
+
+ public function testCacheControlClone()
+ {
+ $headers = array('foo' => 'bar');
+ $bag1 = new ResponseHeaderBag($headers);
+ $bag2 = new ResponseHeaderBag($bag1->allPreserveCase());
+ $this->assertEquals($bag1->allPreserveCase(), $bag2->allPreserveCase());
+ }
+
+ public function testToStringIncludesCookieHeaders()
+ {
+ $bag = new ResponseHeaderBag(array());
+ $bag->setCookie(new Cookie('foo', 'bar'));
+
+ $this->assertSetCookieHeader('foo=bar; path=/; httponly', $bag);
+
+ $bag->clearCookie('foo');
+
+ $this->assertSetCookieHeader('foo=deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; max-age=-31536001; path=/; httponly', $bag);
+ }
+
+ public function testClearCookieSecureNotHttpOnly()
+ {
+ $bag = new ResponseHeaderBag(array());
+
+ $bag->clearCookie('foo', '/', null, true, false);
+
+ $this->assertSetCookieHeader('foo=deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; max-age=-31536001; path=/; secure', $bag);
+ }
+
+ public function testReplace()
+ {
+ $bag = new ResponseHeaderBag(array());
+ $this->assertEquals('no-cache, private', $bag->get('Cache-Control'));
+ $this->assertTrue($bag->hasCacheControlDirective('no-cache'));
+
+ $bag->replace(array('Cache-Control' => 'public'));
+ $this->assertEquals('public', $bag->get('Cache-Control'));
+ $this->assertTrue($bag->hasCacheControlDirective('public'));
+ }
+
+ public function testReplaceWithRemove()
+ {
+ $bag = new ResponseHeaderBag(array());
+ $this->assertEquals('no-cache, private', $bag->get('Cache-Control'));
+ $this->assertTrue($bag->hasCacheControlDirective('no-cache'));
+
+ $bag->remove('Cache-Control');
+ $bag->replace(array());
+ $this->assertEquals('no-cache, private', $bag->get('Cache-Control'));
+ $this->assertTrue($bag->hasCacheControlDirective('no-cache'));
+ }
+
+ public function testCookiesWithSameNames()
+ {
+ $bag = new ResponseHeaderBag();
+ $bag->setCookie(new Cookie('foo', 'bar', 0, '/path/foo', 'foo.bar'));
+ $bag->setCookie(new Cookie('foo', 'bar', 0, '/path/bar', 'foo.bar'));
+ $bag->setCookie(new Cookie('foo', 'bar', 0, '/path/bar', 'bar.foo'));
+ $bag->setCookie(new Cookie('foo', 'bar'));
+
+ $this->assertCount(4, $bag->getCookies());
+ $this->assertEquals('foo=bar; path=/path/foo; domain=foo.bar; httponly', $bag->get('set-cookie'));
+ $this->assertEquals(array(
+ 'foo=bar; path=/path/foo; domain=foo.bar; httponly',
+ 'foo=bar; path=/path/bar; domain=foo.bar; httponly',
+ 'foo=bar; path=/path/bar; domain=bar.foo; httponly',
+ 'foo=bar; path=/; httponly',
+ ), $bag->get('set-cookie', null, false));
+
+ $this->assertSetCookieHeader('foo=bar; path=/path/foo; domain=foo.bar; httponly', $bag);
+ $this->assertSetCookieHeader('foo=bar; path=/path/bar; domain=foo.bar; httponly', $bag);
+ $this->assertSetCookieHeader('foo=bar; path=/path/bar; domain=bar.foo; httponly', $bag);
+ $this->assertSetCookieHeader('foo=bar; path=/; httponly', $bag);
+
+ $cookies = $bag->getCookies(ResponseHeaderBag::COOKIES_ARRAY);
+
+ $this->assertArrayHasKey('foo', $cookies['foo.bar']['/path/foo']);
+ $this->assertArrayHasKey('foo', $cookies['foo.bar']['/path/bar']);
+ $this->assertArrayHasKey('foo', $cookies['bar.foo']['/path/bar']);
+ $this->assertArrayHasKey('foo', $cookies['']['/']);
+ }
+
+ public function testRemoveCookie()
+ {
+ $bag = new ResponseHeaderBag();
+ $this->assertFalse($bag->has('set-cookie'));
+
+ $bag->setCookie(new Cookie('foo', 'bar', 0, '/path/foo', 'foo.bar'));
+ $bag->setCookie(new Cookie('bar', 'foo', 0, '/path/bar', 'foo.bar'));
+ $this->assertTrue($bag->has('set-cookie'));
+
+ $cookies = $bag->getCookies(ResponseHeaderBag::COOKIES_ARRAY);
+ $this->assertArrayHasKey('/path/foo', $cookies['foo.bar']);
+
+ $bag->removeCookie('foo', '/path/foo', 'foo.bar');
+ $this->assertTrue($bag->has('set-cookie'));
+
+ $cookies = $bag->getCookies(ResponseHeaderBag::COOKIES_ARRAY);
+ $this->assertArrayNotHasKey('/path/foo', $cookies['foo.bar']);
+
+ $bag->removeCookie('bar', '/path/bar', 'foo.bar');
+ $this->assertFalse($bag->has('set-cookie'));
+
+ $cookies = $bag->getCookies(ResponseHeaderBag::COOKIES_ARRAY);
+ $this->assertArrayNotHasKey('foo.bar', $cookies);
+ }
+
+ public function testRemoveCookieWithNullRemove()
+ {
+ $bag = new ResponseHeaderBag();
+ $bag->setCookie(new Cookie('foo', 'bar', 0));
+ $bag->setCookie(new Cookie('bar', 'foo', 0));
+
+ $cookies = $bag->getCookies(ResponseHeaderBag::COOKIES_ARRAY);
+ $this->assertArrayHasKey('/', $cookies['']);
+
+ $bag->removeCookie('foo', null);
+ $cookies = $bag->getCookies(ResponseHeaderBag::COOKIES_ARRAY);
+ $this->assertArrayNotHasKey('foo', $cookies['']['/']);
+
+ $bag->removeCookie('bar', null);
+ $cookies = $bag->getCookies(ResponseHeaderBag::COOKIES_ARRAY);
+ $this->assertFalse(isset($cookies['']['/']['bar']));
+ }
+
+ public function testSetCookieHeader()
+ {
+ $bag = new ResponseHeaderBag();
+ $bag->set('set-cookie', 'foo=bar');
+ $this->assertEquals(array(new Cookie('foo', 'bar', 0, '/', null, false, false, true)), $bag->getCookies());
+
+ $bag->set('set-cookie', 'foo2=bar2', false);
+ $this->assertEquals(array(
+ new Cookie('foo', 'bar', 0, '/', null, false, false, true),
+ new Cookie('foo2', 'bar2', 0, '/', null, false, false, true),
+ ), $bag->getCookies());
+
+ $bag->remove('set-cookie');
+ $this->assertEquals(array(), $bag->getCookies());
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testGetCookiesWithInvalidArgument()
+ {
+ $bag = new ResponseHeaderBag();
+
+ $bag->getCookies('invalid_argument');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testMakeDispositionInvalidDisposition()
+ {
+ $headers = new ResponseHeaderBag();
+
+ $headers->makeDisposition('invalid', 'foo.html');
+ }
+
+ /**
+ * @dataProvider provideMakeDisposition
+ */
+ public function testMakeDisposition($disposition, $filename, $filenameFallback, $expected)
+ {
+ $headers = new ResponseHeaderBag();
+
+ $this->assertEquals($expected, $headers->makeDisposition($disposition, $filename, $filenameFallback));
+ }
+
+ public function testToStringDoesntMessUpHeaders()
+ {
+ $headers = new ResponseHeaderBag();
+
+ $headers->set('Location', 'http://www.symfony.com');
+ $headers->set('Content-type', 'text/html');
+
+ (string) $headers;
+
+ $allHeaders = $headers->allPreserveCase();
+ $this->assertEquals(array('http://www.symfony.com'), $allHeaders['Location']);
+ $this->assertEquals(array('text/html'), $allHeaders['Content-type']);
+ }
+
+ public function provideMakeDisposition()
+ {
+ return array(
+ array('attachment', 'foo.html', 'foo.html', 'attachment; filename="foo.html"'),
+ array('attachment', 'foo.html', '', 'attachment; filename="foo.html"'),
+ array('attachment', 'foo bar.html', '', 'attachment; filename="foo bar.html"'),
+ array('attachment', 'foo "bar".html', '', 'attachment; filename="foo \\"bar\\".html"'),
+ array('attachment', 'foo%20bar.html', 'foo bar.html', 'attachment; filename="foo bar.html"; filename*=utf-8\'\'foo%2520bar.html'),
+ array('attachment', 'föö.html', 'foo.html', 'attachment; filename="foo.html"; filename*=utf-8\'\'f%C3%B6%C3%B6.html'),
+ );
+ }
+
+ /**
+ * @dataProvider provideMakeDispositionFail
+ * @expectedException \InvalidArgumentException
+ */
+ public function testMakeDispositionFail($disposition, $filename)
+ {
+ $headers = new ResponseHeaderBag();
+
+ $headers->makeDisposition($disposition, $filename);
+ }
+
+ public function provideMakeDispositionFail()
+ {
+ return array(
+ array('attachment', 'foo%20bar.html'),
+ array('attachment', 'foo/bar.html'),
+ array('attachment', '/foo.html'),
+ array('attachment', 'foo\bar.html'),
+ array('attachment', '\foo.html'),
+ array('attachment', 'föö.html'),
+ );
+ }
+
+ public function testDateHeaderAddedOnCreation()
+ {
+ $now = time();
+
+ $bag = new ResponseHeaderBag();
+ $this->assertTrue($bag->has('Date'));
+
+ $this->assertEquals($now, $bag->getDate('Date')->getTimestamp());
+ }
+
+ public function testDateHeaderCanBeSetOnCreation()
+ {
+ $someDate = 'Thu, 23 Mar 2017 09:15:12 GMT';
+ $bag = new ResponseHeaderBag(array('Date' => $someDate));
+
+ $this->assertEquals($someDate, $bag->get('Date'));
+ }
+
+ public function testDateHeaderWillBeRecreatedWhenRemoved()
+ {
+ $someDate = 'Thu, 23 Mar 2017 09:15:12 GMT';
+ $bag = new ResponseHeaderBag(array('Date' => $someDate));
+ $bag->remove('Date');
+
+ // a (new) Date header is still present
+ $this->assertTrue($bag->has('Date'));
+ $this->assertNotEquals($someDate, $bag->get('Date'));
+ }
+
+ public function testDateHeaderWillBeRecreatedWhenHeadersAreReplaced()
+ {
+ $bag = new ResponseHeaderBag();
+ $bag->replace(array());
+
+ $this->assertTrue($bag->has('Date'));
+ }
+
+ private function assertSetCookieHeader($expected, ResponseHeaderBag $actual)
+ {
+ $this->assertRegExp('#^Set-Cookie:\s+'.preg_quote($expected, '#').'$#m', str_replace("\r\n", "\n", (string) $actual));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/ResponseTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/ResponseTest.php
new file mode 100644
index 0000000..350d972
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/ResponseTest.php
@@ -0,0 +1,1003 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+
+/**
+ * @group time-sensitive
+ */
+class ResponseTest extends ResponseTestCase
+{
+ public function testCreate()
+ {
+ $response = Response::create('foo', 301, array('Foo' => 'bar'));
+
+ $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $response);
+ $this->assertEquals(301, $response->getStatusCode());
+ $this->assertEquals('bar', $response->headers->get('foo'));
+ }
+
+ public function testToString()
+ {
+ $response = new Response();
+ $response = explode("\r\n", $response);
+ $this->assertEquals('HTTP/1.0 200 OK', $response[0]);
+ $this->assertEquals('Cache-Control: no-cache, private', $response[1]);
+ }
+
+ public function testClone()
+ {
+ $response = new Response();
+ $responseClone = clone $response;
+ $this->assertEquals($response, $responseClone);
+ }
+
+ public function testSendHeaders()
+ {
+ $response = new Response();
+ $headers = $response->sendHeaders();
+ $this->assertObjectHasAttribute('headers', $headers);
+ $this->assertObjectHasAttribute('content', $headers);
+ $this->assertObjectHasAttribute('version', $headers);
+ $this->assertObjectHasAttribute('statusCode', $headers);
+ $this->assertObjectHasAttribute('statusText', $headers);
+ $this->assertObjectHasAttribute('charset', $headers);
+ }
+
+ public function testSend()
+ {
+ $response = new Response();
+ $responseSend = $response->send();
+ $this->assertObjectHasAttribute('headers', $responseSend);
+ $this->assertObjectHasAttribute('content', $responseSend);
+ $this->assertObjectHasAttribute('version', $responseSend);
+ $this->assertObjectHasAttribute('statusCode', $responseSend);
+ $this->assertObjectHasAttribute('statusText', $responseSend);
+ $this->assertObjectHasAttribute('charset', $responseSend);
+ }
+
+ public function testGetCharset()
+ {
+ $response = new Response();
+ $charsetOrigin = 'UTF-8';
+ $response->setCharset($charsetOrigin);
+ $charset = $response->getCharset();
+ $this->assertEquals($charsetOrigin, $charset);
+ }
+
+ public function testIsCacheable()
+ {
+ $response = new Response();
+ $this->assertFalse($response->isCacheable());
+ }
+
+ public function testIsCacheableWithErrorCode()
+ {
+ $response = new Response('', 500);
+ $this->assertFalse($response->isCacheable());
+ }
+
+ public function testIsCacheableWithNoStoreDirective()
+ {
+ $response = new Response();
+ $response->headers->set('cache-control', 'private');
+ $this->assertFalse($response->isCacheable());
+ }
+
+ public function testIsCacheableWithSetTtl()
+ {
+ $response = new Response();
+ $response->setTtl(10);
+ $this->assertTrue($response->isCacheable());
+ }
+
+ public function testMustRevalidate()
+ {
+ $response = new Response();
+ $this->assertFalse($response->mustRevalidate());
+ }
+
+ public function testMustRevalidateWithMustRevalidateCacheControlHeader()
+ {
+ $response = new Response();
+ $response->headers->set('cache-control', 'must-revalidate');
+
+ $this->assertTrue($response->mustRevalidate());
+ }
+
+ public function testMustRevalidateWithProxyRevalidateCacheControlHeader()
+ {
+ $response = new Response();
+ $response->headers->set('cache-control', 'proxy-revalidate');
+
+ $this->assertTrue($response->mustRevalidate());
+ }
+
+ public function testSetNotModified()
+ {
+ $response = new Response();
+ $modified = $response->setNotModified();
+ $this->assertObjectHasAttribute('headers', $modified);
+ $this->assertObjectHasAttribute('content', $modified);
+ $this->assertObjectHasAttribute('version', $modified);
+ $this->assertObjectHasAttribute('statusCode', $modified);
+ $this->assertObjectHasAttribute('statusText', $modified);
+ $this->assertObjectHasAttribute('charset', $modified);
+ $this->assertEquals(304, $modified->getStatusCode());
+ }
+
+ public function testIsSuccessful()
+ {
+ $response = new Response();
+ $this->assertTrue($response->isSuccessful());
+ }
+
+ public function testIsNotModified()
+ {
+ $response = new Response();
+ $modified = $response->isNotModified(new Request());
+ $this->assertFalse($modified);
+ }
+
+ public function testIsNotModifiedNotSafe()
+ {
+ $request = Request::create('/homepage', 'POST');
+
+ $response = new Response();
+ $this->assertFalse($response->isNotModified($request));
+ }
+
+ public function testIsNotModifiedLastModified()
+ {
+ $before = 'Sun, 25 Aug 2013 18:32:31 GMT';
+ $modified = 'Sun, 25 Aug 2013 18:33:31 GMT';
+ $after = 'Sun, 25 Aug 2013 19:33:31 GMT';
+
+ $request = new Request();
+ $request->headers->set('If-Modified-Since', $modified);
+
+ $response = new Response();
+
+ $response->headers->set('Last-Modified', $modified);
+ $this->assertTrue($response->isNotModified($request));
+
+ $response->headers->set('Last-Modified', $before);
+ $this->assertTrue($response->isNotModified($request));
+
+ $response->headers->set('Last-Modified', $after);
+ $this->assertFalse($response->isNotModified($request));
+
+ $response->headers->set('Last-Modified', '');
+ $this->assertFalse($response->isNotModified($request));
+ }
+
+ public function testIsNotModifiedEtag()
+ {
+ $etagOne = 'randomly_generated_etag';
+ $etagTwo = 'randomly_generated_etag_2';
+
+ $request = new Request();
+ $request->headers->set('if_none_match', sprintf('%s, %s, %s', $etagOne, $etagTwo, 'etagThree'));
+
+ $response = new Response();
+
+ $response->headers->set('ETag', $etagOne);
+ $this->assertTrue($response->isNotModified($request));
+
+ $response->headers->set('ETag', $etagTwo);
+ $this->assertTrue($response->isNotModified($request));
+
+ $response->headers->set('ETag', '');
+ $this->assertFalse($response->isNotModified($request));
+ }
+
+ public function testIsNotModifiedLastModifiedAndEtag()
+ {
+ $before = 'Sun, 25 Aug 2013 18:32:31 GMT';
+ $modified = 'Sun, 25 Aug 2013 18:33:31 GMT';
+ $after = 'Sun, 25 Aug 2013 19:33:31 GMT';
+ $etag = 'randomly_generated_etag';
+
+ $request = new Request();
+ $request->headers->set('if_none_match', sprintf('%s, %s', $etag, 'etagThree'));
+ $request->headers->set('If-Modified-Since', $modified);
+
+ $response = new Response();
+
+ $response->headers->set('ETag', $etag);
+ $response->headers->set('Last-Modified', $after);
+ $this->assertFalse($response->isNotModified($request));
+
+ $response->headers->set('ETag', 'non-existent-etag');
+ $response->headers->set('Last-Modified', $before);
+ $this->assertFalse($response->isNotModified($request));
+
+ $response->headers->set('ETag', $etag);
+ $response->headers->set('Last-Modified', $modified);
+ $this->assertTrue($response->isNotModified($request));
+ }
+
+ public function testIsNotModifiedIfModifiedSinceAndEtagWithoutLastModified()
+ {
+ $modified = 'Sun, 25 Aug 2013 18:33:31 GMT';
+ $etag = 'randomly_generated_etag';
+
+ $request = new Request();
+ $request->headers->set('if_none_match', sprintf('%s, %s', $etag, 'etagThree'));
+ $request->headers->set('If-Modified-Since', $modified);
+
+ $response = new Response();
+
+ $response->headers->set('ETag', $etag);
+ $this->assertTrue($response->isNotModified($request));
+
+ $response->headers->set('ETag', 'non-existent-etag');
+ $this->assertFalse($response->isNotModified($request));
+ }
+
+ public function testIsValidateable()
+ {
+ $response = new Response('', 200, array('Last-Modified' => $this->createDateTimeOneHourAgo()->format(DATE_RFC2822)));
+ $this->assertTrue($response->isValidateable(), '->isValidateable() returns true if Last-Modified is present');
+
+ $response = new Response('', 200, array('ETag' => '"12345"'));
+ $this->assertTrue($response->isValidateable(), '->isValidateable() returns true if ETag is present');
+
+ $response = new Response();
+ $this->assertFalse($response->isValidateable(), '->isValidateable() returns false when no validator is present');
+ }
+
+ public function testGetDate()
+ {
+ $oneHourAgo = $this->createDateTimeOneHourAgo();
+ $response = new Response('', 200, array('Date' => $oneHourAgo->format(DATE_RFC2822)));
+ $date = $response->getDate();
+ $this->assertEquals($oneHourAgo->getTimestamp(), $date->getTimestamp(), '->getDate() returns the Date header if present');
+
+ $response = new Response();
+ $date = $response->getDate();
+ $this->assertEquals(time(), $date->getTimestamp(), '->getDate() returns the current Date if no Date header present');
+
+ $response = new Response('', 200, array('Date' => $this->createDateTimeOneHourAgo()->format(DATE_RFC2822)));
+ $now = $this->createDateTimeNow();
+ $response->headers->set('Date', $now->format(DATE_RFC2822));
+ $date = $response->getDate();
+ $this->assertEquals($now->getTimestamp(), $date->getTimestamp(), '->getDate() returns the date when the header has been modified');
+
+ $response = new Response('', 200);
+ $now = $this->createDateTimeNow();
+ $response->headers->remove('Date');
+ $date = $response->getDate();
+ $this->assertEquals($now->getTimestamp(), $date->getTimestamp(), '->getDate() returns the current Date when the header has previously been removed');
+ }
+
+ public function testGetMaxAge()
+ {
+ $response = new Response();
+ $response->headers->set('Cache-Control', 's-maxage=600, max-age=0');
+ $this->assertEquals(600, $response->getMaxAge(), '->getMaxAge() uses s-maxage cache control directive when present');
+
+ $response = new Response();
+ $response->headers->set('Cache-Control', 'max-age=600');
+ $this->assertEquals(600, $response->getMaxAge(), '->getMaxAge() falls back to max-age when no s-maxage directive present');
+
+ $response = new Response();
+ $response->headers->set('Cache-Control', 'must-revalidate');
+ $response->headers->set('Expires', $this->createDateTimeOneHourLater()->format(DATE_RFC2822));
+ $this->assertEquals(3600, $response->getMaxAge(), '->getMaxAge() falls back to Expires when no max-age or s-maxage directive present');
+
+ $response = new Response();
+ $response->headers->set('Cache-Control', 'must-revalidate');
+ $response->headers->set('Expires', -1);
+ $this->assertEquals('Sat, 01 Jan 00 00:00:00 +0000', $response->getExpires()->format(DATE_RFC822));
+
+ $response = new Response();
+ $this->assertNull($response->getMaxAge(), '->getMaxAge() returns null if no freshness information available');
+ }
+
+ public function testSetSharedMaxAge()
+ {
+ $response = new Response();
+ $response->setSharedMaxAge(20);
+
+ $cacheControl = $response->headers->get('Cache-Control');
+ $this->assertEquals('public, s-maxage=20', $cacheControl);
+ }
+
+ public function testIsPrivate()
+ {
+ $response = new Response();
+ $response->headers->set('Cache-Control', 'max-age=100');
+ $response->setPrivate();
+ $this->assertEquals(100, $response->headers->getCacheControlDirective('max-age'), '->isPrivate() adds the private Cache-Control directive when set to true');
+ $this->assertTrue($response->headers->getCacheControlDirective('private'), '->isPrivate() adds the private Cache-Control directive when set to true');
+
+ $response = new Response();
+ $response->headers->set('Cache-Control', 'public, max-age=100');
+ $response->setPrivate();
+ $this->assertEquals(100, $response->headers->getCacheControlDirective('max-age'), '->isPrivate() adds the private Cache-Control directive when set to true');
+ $this->assertTrue($response->headers->getCacheControlDirective('private'), '->isPrivate() adds the private Cache-Control directive when set to true');
+ $this->assertFalse($response->headers->hasCacheControlDirective('public'), '->isPrivate() removes the public Cache-Control directive');
+ }
+
+ public function testExpire()
+ {
+ $response = new Response();
+ $response->headers->set('Cache-Control', 'max-age=100');
+ $response->expire();
+ $this->assertEquals(100, $response->headers->get('Age'), '->expire() sets the Age to max-age when present');
+
+ $response = new Response();
+ $response->headers->set('Cache-Control', 'max-age=100, s-maxage=500');
+ $response->expire();
+ $this->assertEquals(500, $response->headers->get('Age'), '->expire() sets the Age to s-maxage when both max-age and s-maxage are present');
+
+ $response = new Response();
+ $response->headers->set('Cache-Control', 'max-age=5, s-maxage=500');
+ $response->headers->set('Age', '1000');
+ $response->expire();
+ $this->assertEquals(1000, $response->headers->get('Age'), '->expire() does nothing when the response is already stale/expired');
+
+ $response = new Response();
+ $response->expire();
+ $this->assertFalse($response->headers->has('Age'), '->expire() does nothing when the response does not include freshness information');
+
+ $response = new Response();
+ $response->headers->set('Expires', -1);
+ $response->expire();
+ $this->assertNull($response->headers->get('Age'), '->expire() does not set the Age when the response is expired');
+ }
+
+ public function testGetTtl()
+ {
+ $response = new Response();
+ $this->assertNull($response->getTtl(), '->getTtl() returns null when no Expires or Cache-Control headers are present');
+
+ $response = new Response();
+ $response->headers->set('Expires', $this->createDateTimeOneHourLater()->format(DATE_RFC2822));
+ $this->assertEquals(3600, $response->getTtl(), '->getTtl() uses the Expires header when no max-age is present');
+
+ $response = new Response();
+ $response->headers->set('Expires', $this->createDateTimeOneHourAgo()->format(DATE_RFC2822));
+ $this->assertLessThan(0, $response->getTtl(), '->getTtl() returns negative values when Expires is in past');
+
+ $response = new Response();
+ $response->headers->set('Expires', $response->getDate()->format(DATE_RFC2822));
+ $response->headers->set('Age', 0);
+ $this->assertSame(0, $response->getTtl(), '->getTtl() correctly handles zero');
+
+ $response = new Response();
+ $response->headers->set('Cache-Control', 'max-age=60');
+ $this->assertEquals(60, $response->getTtl(), '->getTtl() uses Cache-Control max-age when present');
+ }
+
+ public function testSetClientTtl()
+ {
+ $response = new Response();
+ $response->setClientTtl(10);
+
+ $this->assertEquals($response->getMaxAge(), $response->getAge() + 10);
+ }
+
+ public function testGetSetProtocolVersion()
+ {
+ $response = new Response();
+
+ $this->assertEquals('1.0', $response->getProtocolVersion());
+
+ $response->setProtocolVersion('1.1');
+
+ $this->assertEquals('1.1', $response->getProtocolVersion());
+ }
+
+ public function testGetVary()
+ {
+ $response = new Response();
+ $this->assertEquals(array(), $response->getVary(), '->getVary() returns an empty array if no Vary header is present');
+
+ $response = new Response();
+ $response->headers->set('Vary', 'Accept-Language');
+ $this->assertEquals(array('Accept-Language'), $response->getVary(), '->getVary() parses a single header name value');
+
+ $response = new Response();
+ $response->headers->set('Vary', 'Accept-Language User-Agent X-Foo');
+ $this->assertEquals(array('Accept-Language', 'User-Agent', 'X-Foo'), $response->getVary(), '->getVary() parses multiple header name values separated by spaces');
+
+ $response = new Response();
+ $response->headers->set('Vary', 'Accept-Language,User-Agent, X-Foo');
+ $this->assertEquals(array('Accept-Language', 'User-Agent', 'X-Foo'), $response->getVary(), '->getVary() parses multiple header name values separated by commas');
+
+ $vary = array('Accept-Language', 'User-Agent', 'X-foo');
+
+ $response = new Response();
+ $response->headers->set('Vary', $vary);
+ $this->assertEquals($vary, $response->getVary(), '->getVary() parses multiple header name values in arrays');
+
+ $response = new Response();
+ $response->headers->set('Vary', 'Accept-Language, User-Agent, X-foo');
+ $this->assertEquals($vary, $response->getVary(), '->getVary() parses multiple header name values in arrays');
+ }
+
+ public function testSetVary()
+ {
+ $response = new Response();
+ $response->setVary('Accept-Language');
+ $this->assertEquals(array('Accept-Language'), $response->getVary());
+
+ $response->setVary('Accept-Language, User-Agent');
+ $this->assertEquals(array('Accept-Language', 'User-Agent'), $response->getVary(), '->setVary() replace the vary header by default');
+
+ $response->setVary('X-Foo', false);
+ $this->assertEquals(array('Accept-Language', 'User-Agent', 'X-Foo'), $response->getVary(), '->setVary() doesn\'t wipe out earlier Vary headers if replace is set to false');
+ }
+
+ public function testDefaultContentType()
+ {
+ $headerMock = $this->getMockBuilder('Symfony\Component\HttpFoundation\ResponseHeaderBag')->setMethods(array('set'))->getMock();
+ $headerMock->expects($this->at(0))
+ ->method('set')
+ ->with('Content-Type', 'text/html');
+ $headerMock->expects($this->at(1))
+ ->method('set')
+ ->with('Content-Type', 'text/html; charset=UTF-8');
+
+ $response = new Response('foo');
+ $response->headers = $headerMock;
+
+ $response->prepare(new Request());
+ }
+
+ public function testContentTypeCharset()
+ {
+ $response = new Response();
+ $response->headers->set('Content-Type', 'text/css');
+
+ // force fixContentType() to be called
+ $response->prepare(new Request());
+
+ $this->assertEquals('text/css; charset=UTF-8', $response->headers->get('Content-Type'));
+ }
+
+ public function testPrepareDoesNothingIfContentTypeIsSet()
+ {
+ $response = new Response('foo');
+ $response->headers->set('Content-Type', 'text/plain');
+
+ $response->prepare(new Request());
+
+ $this->assertEquals('text/plain; charset=UTF-8', $response->headers->get('content-type'));
+ }
+
+ public function testPrepareDoesNothingIfRequestFormatIsNotDefined()
+ {
+ $response = new Response('foo');
+
+ $response->prepare(new Request());
+
+ $this->assertEquals('text/html; charset=UTF-8', $response->headers->get('content-type'));
+ }
+
+ public function testPrepareSetContentType()
+ {
+ $response = new Response('foo');
+ $request = Request::create('/');
+ $request->setRequestFormat('json');
+
+ $response->prepare($request);
+
+ $this->assertEquals('application/json', $response->headers->get('content-type'));
+ }
+
+ public function testPrepareRemovesContentForHeadRequests()
+ {
+ $response = new Response('foo');
+ $request = Request::create('/', 'HEAD');
+
+ $length = 12345;
+ $response->headers->set('Content-Length', $length);
+ $response->prepare($request);
+
+ $this->assertEquals('', $response->getContent());
+ $this->assertEquals($length, $response->headers->get('Content-Length'), 'Content-Length should be as if it was GET; see RFC2616 14.13');
+ }
+
+ public function testPrepareRemovesContentForInformationalResponse()
+ {
+ $response = new Response('foo');
+ $request = Request::create('/');
+
+ $response->setContent('content');
+ $response->setStatusCode(101);
+ $response->prepare($request);
+ $this->assertEquals('', $response->getContent());
+ $this->assertFalse($response->headers->has('Content-Type'));
+ $this->assertFalse($response->headers->has('Content-Type'));
+
+ $response->setContent('content');
+ $response->setStatusCode(304);
+ $response->prepare($request);
+ $this->assertEquals('', $response->getContent());
+ $this->assertFalse($response->headers->has('Content-Type'));
+ $this->assertFalse($response->headers->has('Content-Length'));
+ }
+
+ public function testPrepareRemovesContentLength()
+ {
+ $response = new Response('foo');
+ $request = Request::create('/');
+
+ $response->headers->set('Content-Length', 12345);
+ $response->prepare($request);
+ $this->assertEquals(12345, $response->headers->get('Content-Length'));
+
+ $response->headers->set('Transfer-Encoding', 'chunked');
+ $response->prepare($request);
+ $this->assertFalse($response->headers->has('Content-Length'));
+ }
+
+ public function testPrepareSetsPragmaOnHttp10Only()
+ {
+ $request = Request::create('/', 'GET');
+ $request->server->set('SERVER_PROTOCOL', 'HTTP/1.0');
+
+ $response = new Response('foo');
+ $response->prepare($request);
+ $this->assertEquals('no-cache', $response->headers->get('pragma'));
+ $this->assertEquals('-1', $response->headers->get('expires'));
+
+ $request->server->set('SERVER_PROTOCOL', 'HTTP/1.1');
+ $response = new Response('foo');
+ $response->prepare($request);
+ $this->assertFalse($response->headers->has('pragma'));
+ $this->assertFalse($response->headers->has('expires'));
+ }
+
+ public function testSetCache()
+ {
+ $response = new Response();
+ //array('etag', 'last_modified', 'max_age', 's_maxage', 'private', 'public')
+ try {
+ $response->setCache(array('wrong option' => 'value'));
+ $this->fail('->setCache() throws an InvalidArgumentException if an option is not supported');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('InvalidArgumentException', $e, '->setCache() throws an InvalidArgumentException if an option is not supported');
+ $this->assertContains('"wrong option"', $e->getMessage());
+ }
+
+ $options = array('etag' => '"whatever"');
+ $response->setCache($options);
+ $this->assertEquals($response->getEtag(), '"whatever"');
+
+ $now = $this->createDateTimeNow();
+ $options = array('last_modified' => $now);
+ $response->setCache($options);
+ $this->assertEquals($response->getLastModified()->getTimestamp(), $now->getTimestamp());
+
+ $options = array('max_age' => 100);
+ $response->setCache($options);
+ $this->assertEquals($response->getMaxAge(), 100);
+
+ $options = array('s_maxage' => 200);
+ $response->setCache($options);
+ $this->assertEquals($response->getMaxAge(), 200);
+
+ $this->assertTrue($response->headers->hasCacheControlDirective('public'));
+ $this->assertFalse($response->headers->hasCacheControlDirective('private'));
+
+ $response->setCache(array('public' => true));
+ $this->assertTrue($response->headers->hasCacheControlDirective('public'));
+ $this->assertFalse($response->headers->hasCacheControlDirective('private'));
+
+ $response->setCache(array('public' => false));
+ $this->assertFalse($response->headers->hasCacheControlDirective('public'));
+ $this->assertTrue($response->headers->hasCacheControlDirective('private'));
+
+ $response->setCache(array('private' => true));
+ $this->assertFalse($response->headers->hasCacheControlDirective('public'));
+ $this->assertTrue($response->headers->hasCacheControlDirective('private'));
+
+ $response->setCache(array('private' => false));
+ $this->assertTrue($response->headers->hasCacheControlDirective('public'));
+ $this->assertFalse($response->headers->hasCacheControlDirective('private'));
+
+ $response->setCache(array('immutable' => true));
+ $this->assertTrue($response->headers->hasCacheControlDirective('immutable'));
+
+ $response->setCache(array('immutable' => false));
+ $this->assertFalse($response->headers->hasCacheControlDirective('immutable'));
+ }
+
+ public function testSendContent()
+ {
+ $response = new Response('test response rendering', 200);
+
+ ob_start();
+ $response->sendContent();
+ $string = ob_get_clean();
+ $this->assertContains('test response rendering', $string);
+ }
+
+ public function testSetPublic()
+ {
+ $response = new Response();
+ $response->setPublic();
+
+ $this->assertTrue($response->headers->hasCacheControlDirective('public'));
+ $this->assertFalse($response->headers->hasCacheControlDirective('private'));
+ }
+
+ public function testSetImmutable()
+ {
+ $response = new Response();
+ $response->setImmutable();
+
+ $this->assertTrue($response->headers->hasCacheControlDirective('immutable'));
+ }
+
+ public function testIsImmutable()
+ {
+ $response = new Response();
+ $response->setImmutable();
+
+ $this->assertTrue($response->isImmutable());
+ }
+
+ public function testSetExpires()
+ {
+ $response = new Response();
+ $response->setExpires(null);
+
+ $this->assertNull($response->getExpires(), '->setExpires() remove the header when passed null');
+
+ $now = $this->createDateTimeNow();
+ $response->setExpires($now);
+
+ $this->assertEquals($response->getExpires()->getTimestamp(), $now->getTimestamp());
+ }
+
+ public function testSetLastModified()
+ {
+ $response = new Response();
+ $response->setLastModified($this->createDateTimeNow());
+ $this->assertNotNull($response->getLastModified());
+
+ $response->setLastModified(null);
+ $this->assertNull($response->getLastModified());
+ }
+
+ public function testIsInvalid()
+ {
+ $response = new Response();
+
+ try {
+ $response->setStatusCode(99);
+ $this->fail();
+ } catch (\InvalidArgumentException $e) {
+ $this->assertTrue($response->isInvalid());
+ }
+
+ try {
+ $response->setStatusCode(650);
+ $this->fail();
+ } catch (\InvalidArgumentException $e) {
+ $this->assertTrue($response->isInvalid());
+ }
+
+ $response = new Response('', 200);
+ $this->assertFalse($response->isInvalid());
+ }
+
+ /**
+ * @dataProvider getStatusCodeFixtures
+ */
+ public function testSetStatusCode($code, $text, $expectedText)
+ {
+ $response = new Response();
+
+ $response->setStatusCode($code, $text);
+
+ $statusText = new \ReflectionProperty($response, 'statusText');
+ $statusText->setAccessible(true);
+
+ $this->assertEquals($expectedText, $statusText->getValue($response));
+ }
+
+ public function getStatusCodeFixtures()
+ {
+ return array(
+ array('200', null, 'OK'),
+ array('200', false, ''),
+ array('200', 'foo', 'foo'),
+ array('199', null, 'unknown status'),
+ array('199', false, ''),
+ array('199', 'foo', 'foo'),
+ );
+ }
+
+ public function testIsInformational()
+ {
+ $response = new Response('', 100);
+ $this->assertTrue($response->isInformational());
+
+ $response = new Response('', 200);
+ $this->assertFalse($response->isInformational());
+ }
+
+ public function testIsRedirectRedirection()
+ {
+ foreach (array(301, 302, 303, 307) as $code) {
+ $response = new Response('', $code);
+ $this->assertTrue($response->isRedirection());
+ $this->assertTrue($response->isRedirect());
+ }
+
+ $response = new Response('', 304);
+ $this->assertTrue($response->isRedirection());
+ $this->assertFalse($response->isRedirect());
+
+ $response = new Response('', 200);
+ $this->assertFalse($response->isRedirection());
+ $this->assertFalse($response->isRedirect());
+
+ $response = new Response('', 404);
+ $this->assertFalse($response->isRedirection());
+ $this->assertFalse($response->isRedirect());
+
+ $response = new Response('', 301, array('Location' => '/good-uri'));
+ $this->assertFalse($response->isRedirect('/bad-uri'));
+ $this->assertTrue($response->isRedirect('/good-uri'));
+ }
+
+ public function testIsNotFound()
+ {
+ $response = new Response('', 404);
+ $this->assertTrue($response->isNotFound());
+
+ $response = new Response('', 200);
+ $this->assertFalse($response->isNotFound());
+ }
+
+ public function testIsEmpty()
+ {
+ foreach (array(204, 304) as $code) {
+ $response = new Response('', $code);
+ $this->assertTrue($response->isEmpty());
+ }
+
+ $response = new Response('', 200);
+ $this->assertFalse($response->isEmpty());
+ }
+
+ public function testIsForbidden()
+ {
+ $response = new Response('', 403);
+ $this->assertTrue($response->isForbidden());
+
+ $response = new Response('', 200);
+ $this->assertFalse($response->isForbidden());
+ }
+
+ public function testIsOk()
+ {
+ $response = new Response('', 200);
+ $this->assertTrue($response->isOk());
+
+ $response = new Response('', 404);
+ $this->assertFalse($response->isOk());
+ }
+
+ public function testIsServerOrClientError()
+ {
+ $response = new Response('', 404);
+ $this->assertTrue($response->isClientError());
+ $this->assertFalse($response->isServerError());
+
+ $response = new Response('', 500);
+ $this->assertFalse($response->isClientError());
+ $this->assertTrue($response->isServerError());
+ }
+
+ public function testHasVary()
+ {
+ $response = new Response();
+ $this->assertFalse($response->hasVary());
+
+ $response->setVary('User-Agent');
+ $this->assertTrue($response->hasVary());
+ }
+
+ public function testSetEtag()
+ {
+ $response = new Response('', 200, array('ETag' => '"12345"'));
+ $response->setEtag();
+
+ $this->assertNull($response->headers->get('Etag'), '->setEtag() removes Etags when call with null');
+ }
+
+ /**
+ * @dataProvider validContentProvider
+ */
+ public function testSetContent($content)
+ {
+ $response = new Response();
+ $response->setContent($content);
+ $this->assertEquals((string) $content, $response->getContent());
+ }
+
+ /**
+ * @expectedException \UnexpectedValueException
+ * @dataProvider invalidContentProvider
+ */
+ public function testSetContentInvalid($content)
+ {
+ $response = new Response();
+ $response->setContent($content);
+ }
+
+ public function testSettersAreChainable()
+ {
+ $response = new Response();
+
+ $setters = array(
+ 'setProtocolVersion' => '1.0',
+ 'setCharset' => 'UTF-8',
+ 'setPublic' => null,
+ 'setPrivate' => null,
+ 'setDate' => $this->createDateTimeNow(),
+ 'expire' => null,
+ 'setMaxAge' => 1,
+ 'setSharedMaxAge' => 1,
+ 'setTtl' => 1,
+ 'setClientTtl' => 1,
+ );
+
+ foreach ($setters as $setter => $arg) {
+ $this->assertEquals($response, $response->{$setter}($arg));
+ }
+ }
+
+ public function testNoDeprecationsAreTriggered()
+ {
+ new DefaultResponse();
+ $this->getMockBuilder(Response::class)->getMock();
+
+ // we just need to ensure that subclasses of Response can be created without any deprecations
+ // being triggered if the subclass does not override any final methods
+ $this->addToAssertionCount(1);
+ }
+
+ public function validContentProvider()
+ {
+ return array(
+ 'obj' => array(new StringableObject()),
+ 'string' => array('Foo'),
+ 'int' => array(2),
+ );
+ }
+
+ public function invalidContentProvider()
+ {
+ return array(
+ 'obj' => array(new \stdClass()),
+ 'array' => array(array()),
+ 'bool' => array(true, '1'),
+ );
+ }
+
+ protected function createDateTimeOneHourAgo()
+ {
+ return $this->createDateTimeNow()->sub(new \DateInterval('PT1H'));
+ }
+
+ protected function createDateTimeOneHourLater()
+ {
+ return $this->createDateTimeNow()->add(new \DateInterval('PT1H'));
+ }
+
+ protected function createDateTimeNow()
+ {
+ $date = new \DateTime();
+
+ return $date->setTimestamp(time());
+ }
+
+ protected function provideResponse()
+ {
+ return new Response();
+ }
+
+ /**
+ * @see http://github.com/zendframework/zend-diactoros for the canonical source repository
+ *
+ * @author Fábio Pacheco
+ * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License
+ */
+ public function ianaCodesReasonPhrasesProvider()
+ {
+ if (!in_array('https', stream_get_wrappers(), true)) {
+ $this->markTestSkipped('The "https" wrapper is not available');
+ }
+
+ $ianaHttpStatusCodes = new \DOMDocument();
+
+ libxml_set_streams_context(stream_context_create(array(
+ 'http' => array(
+ 'method' => 'GET',
+ 'timeout' => 30,
+ ),
+ )));
+
+ $ianaHttpStatusCodes->load('https://www.iana.org/assignments/http-status-codes/http-status-codes.xml');
+ if (!$ianaHttpStatusCodes->relaxNGValidate(__DIR__.'/schema/http-status-codes.rng')) {
+ self::fail('Invalid IANA\'s HTTP status code list.');
+ }
+
+ $ianaCodesReasonPhrases = array();
+
+ $xpath = new \DOMXPath($ianaHttpStatusCodes);
+ $xpath->registerNamespace('ns', 'http://www.iana.org/assignments');
+
+ $records = $xpath->query('//ns:record');
+ foreach ($records as $record) {
+ $value = $xpath->query('.//ns:value', $record)->item(0)->nodeValue;
+ $description = $xpath->query('.//ns:description', $record)->item(0)->nodeValue;
+
+ if (in_array($description, array('Unassigned', '(Unused)'), true)) {
+ continue;
+ }
+
+ if (preg_match('/^([0-9]+)\s*\-\s*([0-9]+)$/', $value, $matches)) {
+ for ($value = $matches[1]; $value <= $matches[2]; ++$value) {
+ $ianaCodesReasonPhrases[] = array($value, $description);
+ }
+ } else {
+ $ianaCodesReasonPhrases[] = array($value, $description);
+ }
+ }
+
+ return $ianaCodesReasonPhrases;
+ }
+
+ /**
+ * @dataProvider ianaCodesReasonPhrasesProvider
+ */
+ public function testReasonPhraseDefaultsAgainstIana($code, $reasonPhrase)
+ {
+ $this->assertEquals($reasonPhrase, Response::$statusTexts[$code]);
+ }
+}
+
+class StringableObject
+{
+ public function __toString()
+ {
+ return 'Foo';
+ }
+}
+
+class DefaultResponse extends Response
+{
+}
+
+class ExtendedResponse extends Response
+{
+ public function setLastModified(\DateTime $date = null)
+ {
+ }
+
+ public function getDate()
+ {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/ResponseTestCase.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/ResponseTestCase.php
new file mode 100644
index 0000000..4ead34c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/ResponseTestCase.php
@@ -0,0 +1,89 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Request;
+
+abstract class ResponseTestCase extends TestCase
+{
+ public function testNoCacheControlHeaderOnAttachmentUsingHTTPSAndMSIE()
+ {
+ // Check for HTTPS and IE 8
+ $request = new Request();
+ $request->server->set('HTTPS', true);
+ $request->server->set('HTTP_USER_AGENT', 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)');
+
+ $response = $this->provideResponse();
+ $response->headers->set('Content-Disposition', 'attachment; filename="fname.ext"');
+ $response->prepare($request);
+
+ $this->assertFalse($response->headers->has('Cache-Control'));
+
+ // Check for IE 10 and HTTPS
+ $request->server->set('HTTP_USER_AGENT', 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)');
+
+ $response = $this->provideResponse();
+ $response->headers->set('Content-Disposition', 'attachment; filename="fname.ext"');
+ $response->prepare($request);
+
+ $this->assertTrue($response->headers->has('Cache-Control'));
+
+ // Check for IE 9 and HTTPS
+ $request->server->set('HTTP_USER_AGENT', 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 7.1; Trident/5.0)');
+
+ $response = $this->provideResponse();
+ $response->headers->set('Content-Disposition', 'attachment; filename="fname.ext"');
+ $response->prepare($request);
+
+ $this->assertTrue($response->headers->has('Cache-Control'));
+
+ // Check for IE 9 and HTTP
+ $request->server->set('HTTPS', false);
+
+ $response = $this->provideResponse();
+ $response->headers->set('Content-Disposition', 'attachment; filename="fname.ext"');
+ $response->prepare($request);
+
+ $this->assertTrue($response->headers->has('Cache-Control'));
+
+ // Check for IE 8 and HTTP
+ $request->server->set('HTTP_USER_AGENT', 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)');
+
+ $response = $this->provideResponse();
+ $response->headers->set('Content-Disposition', 'attachment; filename="fname.ext"');
+ $response->prepare($request);
+
+ $this->assertTrue($response->headers->has('Cache-Control'));
+
+ // Check for non-IE and HTTPS
+ $request->server->set('HTTPS', true);
+ $request->server->set('HTTP_USER_AGENT', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.60 Safari/537.17');
+
+ $response = $this->provideResponse();
+ $response->headers->set('Content-Disposition', 'attachment; filename="fname.ext"');
+ $response->prepare($request);
+
+ $this->assertTrue($response->headers->has('Cache-Control'));
+
+ // Check for non-IE and HTTP
+ $request->server->set('HTTPS', false);
+
+ $response = $this->provideResponse();
+ $response->headers->set('Content-Disposition', 'attachment; filename="fname.ext"');
+ $response->prepare($request);
+
+ $this->assertTrue($response->headers->has('Cache-Control'));
+ }
+
+ abstract protected function provideResponse();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/ServerBagTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/ServerBagTest.php
new file mode 100644
index 0000000..f8becec
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/ServerBagTest.php
@@ -0,0 +1,170 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\ServerBag;
+
+/**
+ * ServerBagTest.
+ *
+ * @author Bulat Shakirzyanov <mallluhuct@gmail.com>
+ */
+class ServerBagTest extends TestCase
+{
+ public function testShouldExtractHeadersFromServerArray()
+ {
+ $server = array(
+ 'SOME_SERVER_VARIABLE' => 'value',
+ 'SOME_SERVER_VARIABLE2' => 'value',
+ 'ROOT' => 'value',
+ 'HTTP_CONTENT_TYPE' => 'text/html',
+ 'HTTP_CONTENT_LENGTH' => '0',
+ 'HTTP_ETAG' => 'asdf',
+ 'PHP_AUTH_USER' => 'foo',
+ 'PHP_AUTH_PW' => 'bar',
+ );
+
+ $bag = new ServerBag($server);
+
+ $this->assertEquals(array(
+ 'CONTENT_TYPE' => 'text/html',
+ 'CONTENT_LENGTH' => '0',
+ 'ETAG' => 'asdf',
+ 'AUTHORIZATION' => 'Basic '.base64_encode('foo:bar'),
+ 'PHP_AUTH_USER' => 'foo',
+ 'PHP_AUTH_PW' => 'bar',
+ ), $bag->getHeaders());
+ }
+
+ public function testHttpPasswordIsOptional()
+ {
+ $bag = new ServerBag(array('PHP_AUTH_USER' => 'foo'));
+
+ $this->assertEquals(array(
+ 'AUTHORIZATION' => 'Basic '.base64_encode('foo:'),
+ 'PHP_AUTH_USER' => 'foo',
+ 'PHP_AUTH_PW' => '',
+ ), $bag->getHeaders());
+ }
+
+ public function testHttpBasicAuthWithPhpCgi()
+ {
+ $bag = new ServerBag(array('HTTP_AUTHORIZATION' => 'Basic '.base64_encode('foo:bar')));
+
+ $this->assertEquals(array(
+ 'AUTHORIZATION' => 'Basic '.base64_encode('foo:bar'),
+ 'PHP_AUTH_USER' => 'foo',
+ 'PHP_AUTH_PW' => 'bar',
+ ), $bag->getHeaders());
+ }
+
+ public function testHttpBasicAuthWithPhpCgiBogus()
+ {
+ $bag = new ServerBag(array('HTTP_AUTHORIZATION' => 'Basic_'.base64_encode('foo:bar')));
+
+ // Username and passwords should not be set as the header is bogus
+ $headers = $bag->getHeaders();
+ $this->assertArrayNotHasKey('PHP_AUTH_USER', $headers);
+ $this->assertArrayNotHasKey('PHP_AUTH_PW', $headers);
+ }
+
+ public function testHttpBasicAuthWithPhpCgiRedirect()
+ {
+ $bag = new ServerBag(array('REDIRECT_HTTP_AUTHORIZATION' => 'Basic '.base64_encode('username:pass:word')));
+
+ $this->assertEquals(array(
+ 'AUTHORIZATION' => 'Basic '.base64_encode('username:pass:word'),
+ 'PHP_AUTH_USER' => 'username',
+ 'PHP_AUTH_PW' => 'pass:word',
+ ), $bag->getHeaders());
+ }
+
+ public function testHttpBasicAuthWithPhpCgiEmptyPassword()
+ {
+ $bag = new ServerBag(array('HTTP_AUTHORIZATION' => 'Basic '.base64_encode('foo:')));
+
+ $this->assertEquals(array(
+ 'AUTHORIZATION' => 'Basic '.base64_encode('foo:'),
+ 'PHP_AUTH_USER' => 'foo',
+ 'PHP_AUTH_PW' => '',
+ ), $bag->getHeaders());
+ }
+
+ public function testHttpDigestAuthWithPhpCgi()
+ {
+ $digest = 'Digest username="foo", realm="acme", nonce="'.md5('secret').'", uri="/protected, qop="auth"';
+ $bag = new ServerBag(array('HTTP_AUTHORIZATION' => $digest));
+
+ $this->assertEquals(array(
+ 'AUTHORIZATION' => $digest,
+ 'PHP_AUTH_DIGEST' => $digest,
+ ), $bag->getHeaders());
+ }
+
+ public function testHttpDigestAuthWithPhpCgiBogus()
+ {
+ $digest = 'Digest_username="foo", realm="acme", nonce="'.md5('secret').'", uri="/protected, qop="auth"';
+ $bag = new ServerBag(array('HTTP_AUTHORIZATION' => $digest));
+
+ // Username and passwords should not be set as the header is bogus
+ $headers = $bag->getHeaders();
+ $this->assertArrayNotHasKey('PHP_AUTH_USER', $headers);
+ $this->assertArrayNotHasKey('PHP_AUTH_PW', $headers);
+ }
+
+ public function testHttpDigestAuthWithPhpCgiRedirect()
+ {
+ $digest = 'Digest username="foo", realm="acme", nonce="'.md5('secret').'", uri="/protected, qop="auth"';
+ $bag = new ServerBag(array('REDIRECT_HTTP_AUTHORIZATION' => $digest));
+
+ $this->assertEquals(array(
+ 'AUTHORIZATION' => $digest,
+ 'PHP_AUTH_DIGEST' => $digest,
+ ), $bag->getHeaders());
+ }
+
+ public function testOAuthBearerAuth()
+ {
+ $headerContent = 'Bearer L-yLEOr9zhmUYRkzN1jwwxwQ-PBNiKDc8dgfB4hTfvo';
+ $bag = new ServerBag(array('HTTP_AUTHORIZATION' => $headerContent));
+
+ $this->assertEquals(array(
+ 'AUTHORIZATION' => $headerContent,
+ ), $bag->getHeaders());
+ }
+
+ public function testOAuthBearerAuthWithRedirect()
+ {
+ $headerContent = 'Bearer L-yLEOr9zhmUYRkzN1jwwxwQ-PBNiKDc8dgfB4hTfvo';
+ $bag = new ServerBag(array('REDIRECT_HTTP_AUTHORIZATION' => $headerContent));
+
+ $this->assertEquals(array(
+ 'AUTHORIZATION' => $headerContent,
+ ), $bag->getHeaders());
+ }
+
+ /**
+ * @see https://github.com/symfony/symfony/issues/17345
+ */
+ public function testItDoesNotOverwriteTheAuthorizationHeaderIfItIsAlreadySet()
+ {
+ $headerContent = 'Bearer L-yLEOr9zhmUYRkzN1jwwxwQ-PBNiKDc8dgfB4hTfvo';
+ $bag = new ServerBag(array('PHP_AUTH_USER' => 'foo', 'HTTP_AUTHORIZATION' => $headerContent));
+
+ $this->assertEquals(array(
+ 'AUTHORIZATION' => $headerContent,
+ 'PHP_AUTH_USER' => 'foo',
+ 'PHP_AUTH_PW' => '',
+ ), $bag->getHeaders());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Attribute/AttributeBagTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Attribute/AttributeBagTest.php
new file mode 100644
index 0000000..724a0b9
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Attribute/AttributeBagTest.php
@@ -0,0 +1,186 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests\Session\Attribute;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
+
+/**
+ * Tests AttributeBag.
+ *
+ * @author Drak <drak@zikula.org>
+ */
+class AttributeBagTest extends TestCase
+{
+ private $array = array();
+
+ /**
+ * @var AttributeBag
+ */
+ private $bag;
+
+ protected function setUp()
+ {
+ $this->array = array(
+ 'hello' => 'world',
+ 'always' => 'be happy',
+ 'user.login' => 'drak',
+ 'csrf.token' => array(
+ 'a' => '1234',
+ 'b' => '4321',
+ ),
+ 'category' => array(
+ 'fishing' => array(
+ 'first' => 'cod',
+ 'second' => 'sole',
+ ),
+ ),
+ );
+ $this->bag = new AttributeBag('_sf2');
+ $this->bag->initialize($this->array);
+ }
+
+ protected function tearDown()
+ {
+ $this->bag = null;
+ $this->array = array();
+ }
+
+ public function testInitialize()
+ {
+ $bag = new AttributeBag();
+ $bag->initialize($this->array);
+ $this->assertEquals($this->array, $bag->all());
+ $array = array('should' => 'change');
+ $bag->initialize($array);
+ $this->assertEquals($array, $bag->all());
+ }
+
+ public function testGetStorageKey()
+ {
+ $this->assertEquals('_sf2', $this->bag->getStorageKey());
+ $attributeBag = new AttributeBag('test');
+ $this->assertEquals('test', $attributeBag->getStorageKey());
+ }
+
+ public function testGetSetName()
+ {
+ $this->assertEquals('attributes', $this->bag->getName());
+ $this->bag->setName('foo');
+ $this->assertEquals('foo', $this->bag->getName());
+ }
+
+ /**
+ * @dataProvider attributesProvider
+ */
+ public function testHas($key, $value, $exists)
+ {
+ $this->assertEquals($exists, $this->bag->has($key));
+ }
+
+ /**
+ * @dataProvider attributesProvider
+ */
+ public function testGet($key, $value, $expected)
+ {
+ $this->assertEquals($value, $this->bag->get($key));
+ }
+
+ public function testGetDefaults()
+ {
+ $this->assertNull($this->bag->get('user2.login'));
+ $this->assertEquals('default', $this->bag->get('user2.login', 'default'));
+ }
+
+ /**
+ * @dataProvider attributesProvider
+ */
+ public function testSet($key, $value, $expected)
+ {
+ $this->bag->set($key, $value);
+ $this->assertEquals($value, $this->bag->get($key));
+ }
+
+ public function testAll()
+ {
+ $this->assertEquals($this->array, $this->bag->all());
+
+ $this->bag->set('hello', 'fabien');
+ $array = $this->array;
+ $array['hello'] = 'fabien';
+ $this->assertEquals($array, $this->bag->all());
+ }
+
+ public function testReplace()
+ {
+ $array = array();
+ $array['name'] = 'jack';
+ $array['foo.bar'] = 'beep';
+ $this->bag->replace($array);
+ $this->assertEquals($array, $this->bag->all());
+ $this->assertNull($this->bag->get('hello'));
+ $this->assertNull($this->bag->get('always'));
+ $this->assertNull($this->bag->get('user.login'));
+ }
+
+ public function testRemove()
+ {
+ $this->assertEquals('world', $this->bag->get('hello'));
+ $this->bag->remove('hello');
+ $this->assertNull($this->bag->get('hello'));
+
+ $this->assertEquals('be happy', $this->bag->get('always'));
+ $this->bag->remove('always');
+ $this->assertNull($this->bag->get('always'));
+
+ $this->assertEquals('drak', $this->bag->get('user.login'));
+ $this->bag->remove('user.login');
+ $this->assertNull($this->bag->get('user.login'));
+ }
+
+ public function testClear()
+ {
+ $this->bag->clear();
+ $this->assertEquals(array(), $this->bag->all());
+ }
+
+ public function attributesProvider()
+ {
+ return array(
+ array('hello', 'world', true),
+ array('always', 'be happy', true),
+ array('user.login', 'drak', true),
+ array('csrf.token', array('a' => '1234', 'b' => '4321'), true),
+ array('category', array('fishing' => array('first' => 'cod', 'second' => 'sole')), true),
+ array('user2.login', null, false),
+ array('never', null, false),
+ array('bye', null, false),
+ array('bye/for/now', null, false),
+ );
+ }
+
+ public function testGetIterator()
+ {
+ $i = 0;
+ foreach ($this->bag as $key => $val) {
+ $this->assertEquals($this->array[$key], $val);
+ ++$i;
+ }
+
+ $this->assertEquals(count($this->array), $i);
+ }
+
+ public function testCount()
+ {
+ $this->assertCount(count($this->array), $this->bag);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Attribute/NamespacedAttributeBagTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Attribute/NamespacedAttributeBagTest.php
new file mode 100644
index 0000000..f074ce1
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Attribute/NamespacedAttributeBagTest.php
@@ -0,0 +1,182 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests\Session\Attribute;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Session\Attribute\NamespacedAttributeBag;
+
+/**
+ * Tests NamespacedAttributeBag.
+ *
+ * @author Drak <drak@zikula.org>
+ */
+class NamespacedAttributeBagTest extends TestCase
+{
+ private $array = array();
+
+ /**
+ * @var NamespacedAttributeBag
+ */
+ private $bag;
+
+ protected function setUp()
+ {
+ $this->array = array(
+ 'hello' => 'world',
+ 'always' => 'be happy',
+ 'user.login' => 'drak',
+ 'csrf.token' => array(
+ 'a' => '1234',
+ 'b' => '4321',
+ ),
+ 'category' => array(
+ 'fishing' => array(
+ 'first' => 'cod',
+ 'second' => 'sole',
+ ),
+ ),
+ );
+ $this->bag = new NamespacedAttributeBag('_sf2', '/');
+ $this->bag->initialize($this->array);
+ }
+
+ protected function tearDown()
+ {
+ $this->bag = null;
+ $this->array = array();
+ }
+
+ public function testInitialize()
+ {
+ $bag = new NamespacedAttributeBag();
+ $bag->initialize($this->array);
+ $this->assertEquals($this->array, $this->bag->all());
+ $array = array('should' => 'not stick');
+ $bag->initialize($array);
+
+ // should have remained the same
+ $this->assertEquals($this->array, $this->bag->all());
+ }
+
+ public function testGetStorageKey()
+ {
+ $this->assertEquals('_sf2', $this->bag->getStorageKey());
+ $attributeBag = new NamespacedAttributeBag('test');
+ $this->assertEquals('test', $attributeBag->getStorageKey());
+ }
+
+ /**
+ * @dataProvider attributesProvider
+ */
+ public function testHas($key, $value, $exists)
+ {
+ $this->assertEquals($exists, $this->bag->has($key));
+ }
+
+ /**
+ * @dataProvider attributesProvider
+ */
+ public function testGet($key, $value, $expected)
+ {
+ $this->assertEquals($value, $this->bag->get($key));
+ }
+
+ public function testGetDefaults()
+ {
+ $this->assertNull($this->bag->get('user2.login'));
+ $this->assertEquals('default', $this->bag->get('user2.login', 'default'));
+ }
+
+ /**
+ * @dataProvider attributesProvider
+ */
+ public function testSet($key, $value, $expected)
+ {
+ $this->bag->set($key, $value);
+ $this->assertEquals($value, $this->bag->get($key));
+ }
+
+ public function testAll()
+ {
+ $this->assertEquals($this->array, $this->bag->all());
+
+ $this->bag->set('hello', 'fabien');
+ $array = $this->array;
+ $array['hello'] = 'fabien';
+ $this->assertEquals($array, $this->bag->all());
+ }
+
+ public function testReplace()
+ {
+ $array = array();
+ $array['name'] = 'jack';
+ $array['foo.bar'] = 'beep';
+ $this->bag->replace($array);
+ $this->assertEquals($array, $this->bag->all());
+ $this->assertNull($this->bag->get('hello'));
+ $this->assertNull($this->bag->get('always'));
+ $this->assertNull($this->bag->get('user.login'));
+ }
+
+ public function testRemove()
+ {
+ $this->assertEquals('world', $this->bag->get('hello'));
+ $this->bag->remove('hello');
+ $this->assertNull($this->bag->get('hello'));
+
+ $this->assertEquals('be happy', $this->bag->get('always'));
+ $this->bag->remove('always');
+ $this->assertNull($this->bag->get('always'));
+
+ $this->assertEquals('drak', $this->bag->get('user.login'));
+ $this->bag->remove('user.login');
+ $this->assertNull($this->bag->get('user.login'));
+ }
+
+ public function testRemoveExistingNamespacedAttribute()
+ {
+ $this->assertSame('cod', $this->bag->remove('category/fishing/first'));
+ }
+
+ public function testRemoveNonexistingNamespacedAttribute()
+ {
+ $this->assertNull($this->bag->remove('foo/bar/baz'));
+ }
+
+ public function testClear()
+ {
+ $this->bag->clear();
+ $this->assertEquals(array(), $this->bag->all());
+ }
+
+ public function attributesProvider()
+ {
+ return array(
+ array('hello', 'world', true),
+ array('always', 'be happy', true),
+ array('user.login', 'drak', true),
+ array('csrf.token', array('a' => '1234', 'b' => '4321'), true),
+ array('csrf.token/a', '1234', true),
+ array('csrf.token/b', '4321', true),
+ array('category', array('fishing' => array('first' => 'cod', 'second' => 'sole')), true),
+ array('category/fishing', array('first' => 'cod', 'second' => 'sole'), true),
+ array('category/fishing/missing/first', null, false),
+ array('category/fishing/first', 'cod', true),
+ array('category/fishing/second', 'sole', true),
+ array('category/fishing/missing/second', null, false),
+ array('user2.login', null, false),
+ array('never', null, false),
+ array('bye', null, false),
+ array('bye/for/now', null, false),
+ );
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Flash/AutoExpireFlashBagTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Flash/AutoExpireFlashBagTest.php
new file mode 100644
index 0000000..fa8626a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Flash/AutoExpireFlashBagTest.php
@@ -0,0 +1,161 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests\Session\Flash;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Session\Flash\AutoExpireFlashBag as FlashBag;
+
+/**
+ * AutoExpireFlashBagTest.
+ *
+ * @author Drak <drak@zikula.org>
+ */
+class AutoExpireFlashBagTest extends TestCase
+{
+ /**
+ * @var \Symfony\Component\HttpFoundation\Session\Flash\AutoExpireFlashBag
+ */
+ private $bag;
+
+ protected $array = array();
+
+ protected function setUp()
+ {
+ parent::setUp();
+ $this->bag = new FlashBag();
+ $this->array = array('new' => array('notice' => array('A previous flash message')));
+ $this->bag->initialize($this->array);
+ }
+
+ protected function tearDown()
+ {
+ $this->bag = null;
+ parent::tearDown();
+ }
+
+ public function testInitialize()
+ {
+ $bag = new FlashBag();
+ $array = array('new' => array('notice' => array('A previous flash message')));
+ $bag->initialize($array);
+ $this->assertEquals(array('A previous flash message'), $bag->peek('notice'));
+ $array = array('new' => array(
+ 'notice' => array('Something else'),
+ 'error' => array('a'),
+ ));
+ $bag->initialize($array);
+ $this->assertEquals(array('Something else'), $bag->peek('notice'));
+ $this->assertEquals(array('a'), $bag->peek('error'));
+ }
+
+ public function testGetStorageKey()
+ {
+ $this->assertEquals('_symfony_flashes', $this->bag->getStorageKey());
+ $attributeBag = new FlashBag('test');
+ $this->assertEquals('test', $attributeBag->getStorageKey());
+ }
+
+ public function testGetSetName()
+ {
+ $this->assertEquals('flashes', $this->bag->getName());
+ $this->bag->setName('foo');
+ $this->assertEquals('foo', $this->bag->getName());
+ }
+
+ public function testPeek()
+ {
+ $this->assertEquals(array(), $this->bag->peek('non_existing'));
+ $this->assertEquals(array('default'), $this->bag->peek('non_existing', array('default')));
+ $this->assertEquals(array('A previous flash message'), $this->bag->peek('notice'));
+ $this->assertEquals(array('A previous flash message'), $this->bag->peek('notice'));
+ }
+
+ public function testSet()
+ {
+ $this->bag->set('notice', 'Foo');
+ $this->assertEquals(array('A previous flash message'), $this->bag->peek('notice'));
+ }
+
+ public function testHas()
+ {
+ $this->assertFalse($this->bag->has('nothing'));
+ $this->assertTrue($this->bag->has('notice'));
+ }
+
+ public function testKeys()
+ {
+ $this->assertEquals(array('notice'), $this->bag->keys());
+ }
+
+ public function testPeekAll()
+ {
+ $array = array(
+ 'new' => array(
+ 'notice' => 'Foo',
+ 'error' => 'Bar',
+ ),
+ );
+
+ $this->bag->initialize($array);
+ $this->assertEquals(array(
+ 'notice' => 'Foo',
+ 'error' => 'Bar',
+ ), $this->bag->peekAll()
+ );
+
+ $this->assertEquals(array(
+ 'notice' => 'Foo',
+ 'error' => 'Bar',
+ ), $this->bag->peekAll()
+ );
+ }
+
+ public function testGet()
+ {
+ $this->assertEquals(array(), $this->bag->get('non_existing'));
+ $this->assertEquals(array('default'), $this->bag->get('non_existing', array('default')));
+ $this->assertEquals(array('A previous flash message'), $this->bag->get('notice'));
+ $this->assertEquals(array(), $this->bag->get('notice'));
+ }
+
+ public function testSetAll()
+ {
+ $this->bag->setAll(array('a' => 'first', 'b' => 'second'));
+ $this->assertFalse($this->bag->has('a'));
+ $this->assertFalse($this->bag->has('b'));
+ }
+
+ public function testAll()
+ {
+ $this->bag->set('notice', 'Foo');
+ $this->bag->set('error', 'Bar');
+ $this->assertEquals(array(
+ 'notice' => array('A previous flash message'),
+ ), $this->bag->all()
+ );
+
+ $this->assertEquals(array(), $this->bag->all());
+ }
+
+ public function testClear()
+ {
+ $this->assertEquals(array('notice' => array('A previous flash message')), $this->bag->clear());
+ }
+
+ public function testDoNotRemoveTheNewFlashesWhenDisplayingTheExistingOnes()
+ {
+ $this->bag->add('success', 'Something');
+ $this->bag->all();
+
+ $this->assertEquals(array('new' => array('success' => array('Something')), 'display' => array()), $this->array);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Flash/FlashBagTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Flash/FlashBagTest.php
new file mode 100644
index 0000000..c4e75b1
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Flash/FlashBagTest.php
@@ -0,0 +1,132 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests\Session\Flash;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;
+
+/**
+ * FlashBagTest.
+ *
+ * @author Drak <drak@zikula.org>
+ */
+class FlashBagTest extends TestCase
+{
+ /**
+ * @var \Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface
+ */
+ private $bag;
+
+ protected $array = array();
+
+ protected function setUp()
+ {
+ parent::setUp();
+ $this->bag = new FlashBag();
+ $this->array = array('notice' => array('A previous flash message'));
+ $this->bag->initialize($this->array);
+ }
+
+ protected function tearDown()
+ {
+ $this->bag = null;
+ parent::tearDown();
+ }
+
+ public function testInitialize()
+ {
+ $bag = new FlashBag();
+ $bag->initialize($this->array);
+ $this->assertEquals($this->array, $bag->peekAll());
+ $array = array('should' => array('change'));
+ $bag->initialize($array);
+ $this->assertEquals($array, $bag->peekAll());
+ }
+
+ public function testGetStorageKey()
+ {
+ $this->assertEquals('_symfony_flashes', $this->bag->getStorageKey());
+ $attributeBag = new FlashBag('test');
+ $this->assertEquals('test', $attributeBag->getStorageKey());
+ }
+
+ public function testGetSetName()
+ {
+ $this->assertEquals('flashes', $this->bag->getName());
+ $this->bag->setName('foo');
+ $this->assertEquals('foo', $this->bag->getName());
+ }
+
+ public function testPeek()
+ {
+ $this->assertEquals(array(), $this->bag->peek('non_existing'));
+ $this->assertEquals(array('default'), $this->bag->peek('not_existing', array('default')));
+ $this->assertEquals(array('A previous flash message'), $this->bag->peek('notice'));
+ $this->assertEquals(array('A previous flash message'), $this->bag->peek('notice'));
+ }
+
+ public function testGet()
+ {
+ $this->assertEquals(array(), $this->bag->get('non_existing'));
+ $this->assertEquals(array('default'), $this->bag->get('not_existing', array('default')));
+ $this->assertEquals(array('A previous flash message'), $this->bag->get('notice'));
+ $this->assertEquals(array(), $this->bag->get('notice'));
+ }
+
+ public function testAll()
+ {
+ $this->bag->set('notice', 'Foo');
+ $this->bag->set('error', 'Bar');
+ $this->assertEquals(array(
+ 'notice' => array('Foo'),
+ 'error' => array('Bar'), ), $this->bag->all()
+ );
+
+ $this->assertEquals(array(), $this->bag->all());
+ }
+
+ public function testSet()
+ {
+ $this->bag->set('notice', 'Foo');
+ $this->bag->set('notice', 'Bar');
+ $this->assertEquals(array('Bar'), $this->bag->peek('notice'));
+ }
+
+ public function testHas()
+ {
+ $this->assertFalse($this->bag->has('nothing'));
+ $this->assertTrue($this->bag->has('notice'));
+ }
+
+ public function testKeys()
+ {
+ $this->assertEquals(array('notice'), $this->bag->keys());
+ }
+
+ public function testPeekAll()
+ {
+ $this->bag->set('notice', 'Foo');
+ $this->bag->set('error', 'Bar');
+ $this->assertEquals(array(
+ 'notice' => array('Foo'),
+ 'error' => array('Bar'),
+ ), $this->bag->peekAll()
+ );
+ $this->assertTrue($this->bag->has('notice'));
+ $this->assertTrue($this->bag->has('error'));
+ $this->assertEquals(array(
+ 'notice' => array('Foo'),
+ 'error' => array('Bar'),
+ ), $this->bag->peekAll()
+ );
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/SessionTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/SessionTest.php
new file mode 100644
index 0000000..41720e4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/SessionTest.php
@@ -0,0 +1,242 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests\Session;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Session\Session;
+use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;
+use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
+use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
+
+/**
+ * SessionTest.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Robert Schönthal <seroscho@googlemail.com>
+ * @author Drak <drak@zikula.org>
+ */
+class SessionTest extends TestCase
+{
+ /**
+ * @var \Symfony\Component\HttpFoundation\Session\Storage\SessionStorageInterface
+ */
+ protected $storage;
+
+ /**
+ * @var \Symfony\Component\HttpFoundation\Session\SessionInterface
+ */
+ protected $session;
+
+ protected function setUp()
+ {
+ $this->storage = new MockArraySessionStorage();
+ $this->session = new Session($this->storage, new AttributeBag(), new FlashBag());
+ }
+
+ protected function tearDown()
+ {
+ $this->storage = null;
+ $this->session = null;
+ }
+
+ public function testStart()
+ {
+ $this->assertEquals('', $this->session->getId());
+ $this->assertTrue($this->session->start());
+ $this->assertNotEquals('', $this->session->getId());
+ }
+
+ public function testIsStarted()
+ {
+ $this->assertFalse($this->session->isStarted());
+ $this->session->start();
+ $this->assertTrue($this->session->isStarted());
+ }
+
+ public function testSetId()
+ {
+ $this->assertEquals('', $this->session->getId());
+ $this->session->setId('0123456789abcdef');
+ $this->session->start();
+ $this->assertEquals('0123456789abcdef', $this->session->getId());
+ }
+
+ public function testSetName()
+ {
+ $this->assertEquals('MOCKSESSID', $this->session->getName());
+ $this->session->setName('session.test.com');
+ $this->session->start();
+ $this->assertEquals('session.test.com', $this->session->getName());
+ }
+
+ public function testGet()
+ {
+ // tests defaults
+ $this->assertNull($this->session->get('foo'));
+ $this->assertEquals(1, $this->session->get('foo', 1));
+ }
+
+ /**
+ * @dataProvider setProvider
+ */
+ public function testSet($key, $value)
+ {
+ $this->session->set($key, $value);
+ $this->assertEquals($value, $this->session->get($key));
+ }
+
+ /**
+ * @dataProvider setProvider
+ */
+ public function testHas($key, $value)
+ {
+ $this->session->set($key, $value);
+ $this->assertTrue($this->session->has($key));
+ $this->assertFalse($this->session->has($key.'non_value'));
+ }
+
+ public function testReplace()
+ {
+ $this->session->replace(array('happiness' => 'be good', 'symfony' => 'awesome'));
+ $this->assertEquals(array('happiness' => 'be good', 'symfony' => 'awesome'), $this->session->all());
+ $this->session->replace(array());
+ $this->assertEquals(array(), $this->session->all());
+ }
+
+ /**
+ * @dataProvider setProvider
+ */
+ public function testAll($key, $value, $result)
+ {
+ $this->session->set($key, $value);
+ $this->assertEquals($result, $this->session->all());
+ }
+
+ /**
+ * @dataProvider setProvider
+ */
+ public function testClear($key, $value)
+ {
+ $this->session->set('hi', 'fabien');
+ $this->session->set($key, $value);
+ $this->session->clear();
+ $this->assertEquals(array(), $this->session->all());
+ }
+
+ public function setProvider()
+ {
+ return array(
+ array('foo', 'bar', array('foo' => 'bar')),
+ array('foo.bar', 'too much beer', array('foo.bar' => 'too much beer')),
+ array('great', 'symfony is great', array('great' => 'symfony is great')),
+ );
+ }
+
+ /**
+ * @dataProvider setProvider
+ */
+ public function testRemove($key, $value)
+ {
+ $this->session->set('hi.world', 'have a nice day');
+ $this->session->set($key, $value);
+ $this->session->remove($key);
+ $this->assertEquals(array('hi.world' => 'have a nice day'), $this->session->all());
+ }
+
+ public function testInvalidate()
+ {
+ $this->session->set('invalidate', 123);
+ $this->session->invalidate();
+ $this->assertEquals(array(), $this->session->all());
+ }
+
+ public function testMigrate()
+ {
+ $this->session->set('migrate', 321);
+ $this->session->migrate();
+ $this->assertEquals(321, $this->session->get('migrate'));
+ }
+
+ public function testMigrateDestroy()
+ {
+ $this->session->set('migrate', 333);
+ $this->session->migrate(true);
+ $this->assertEquals(333, $this->session->get('migrate'));
+ }
+
+ public function testSave()
+ {
+ $this->session->start();
+ $this->session->save();
+
+ $this->assertFalse($this->session->isStarted());
+ }
+
+ public function testGetId()
+ {
+ $this->assertEquals('', $this->session->getId());
+ $this->session->start();
+ $this->assertNotEquals('', $this->session->getId());
+ }
+
+ public function testGetFlashBag()
+ {
+ $this->assertInstanceOf('Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface', $this->session->getFlashBag());
+ }
+
+ public function testGetIterator()
+ {
+ $attributes = array('hello' => 'world', 'symfony' => 'rocks');
+ foreach ($attributes as $key => $val) {
+ $this->session->set($key, $val);
+ }
+
+ $i = 0;
+ foreach ($this->session as $key => $val) {
+ $this->assertEquals($attributes[$key], $val);
+ ++$i;
+ }
+
+ $this->assertEquals(count($attributes), $i);
+ }
+
+ public function testGetCount()
+ {
+ $this->session->set('hello', 'world');
+ $this->session->set('symfony', 'rocks');
+
+ $this->assertCount(2, $this->session);
+ }
+
+ public function testGetMeta()
+ {
+ $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\MetadataBag', $this->session->getMetadataBag());
+ }
+
+ public function testIsEmpty()
+ {
+ $this->assertTrue($this->session->isEmpty());
+
+ $this->session->set('hello', 'world');
+ $this->assertFalse($this->session->isEmpty());
+
+ $this->session->remove('hello');
+ $this->assertTrue($this->session->isEmpty());
+
+ $flash = $this->session->getFlashBag();
+ $flash->set('hello', 'world');
+ $this->assertFalse($this->session->isEmpty());
+
+ $flash->get('hello');
+ $this->assertTrue($this->session->isEmpty());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/AbstractSessionHandlerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/AbstractSessionHandlerTest.php
new file mode 100644
index 0000000..3ac081e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/AbstractSessionHandlerTest.php
@@ -0,0 +1,61 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @requires PHP 7.0
+ */
+class AbstractSessionHandlerTest extends TestCase
+{
+ private static $server;
+
+ public static function setUpBeforeClass()
+ {
+ $spec = array(
+ 1 => array('file', '/dev/null', 'w'),
+ 2 => array('file', '/dev/null', 'w'),
+ );
+ if (!self::$server = @proc_open('exec php -S localhost:8053', $spec, $pipes, __DIR__.'/Fixtures')) {
+ self::markTestSkipped('PHP server unable to start.');
+ }
+ sleep(1);
+ }
+
+ public static function tearDownAfterClass()
+ {
+ if (self::$server) {
+ proc_terminate(self::$server);
+ proc_close(self::$server);
+ }
+ }
+
+ /**
+ * @dataProvider provideSession
+ */
+ public function testSession($fixture)
+ {
+ $context = array('http' => array('header' => "Cookie: sid=123abc\r\n"));
+ $context = stream_context_create($context);
+ $result = file_get_contents(sprintf('http://localhost:8053/%s.php', $fixture), false, $context);
+
+ $this->assertStringEqualsFile(__DIR__.sprintf('/Fixtures/%s.expected', $fixture), $result);
+ }
+
+ public function provideSession()
+ {
+ foreach (glob(__DIR__.'/Fixtures/*.php') as $file) {
+ yield array(pathinfo($file, PATHINFO_FILENAME));
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/common.inc b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/common.inc
new file mode 100644
index 0000000..7a064c7
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/common.inc
@@ -0,0 +1,151 @@
+<?php
+
+use Symfony\Component\HttpFoundation\Session\Storage\Handler\AbstractSessionHandler;
+
+$parent = __DIR__;
+while (!@file_exists($parent.'/vendor/autoload.php')) {
+ if (!@file_exists($parent)) {
+ // open_basedir restriction in effect
+ break;
+ }
+ if ($parent === dirname($parent)) {
+ echo "vendor/autoload.php not found\n";
+ exit(1);
+ }
+
+ $parent = dirname($parent);
+}
+
+require $parent.'/vendor/autoload.php';
+
+error_reporting(-1);
+ini_set('html_errors', 0);
+ini_set('display_errors', 1);
+ini_set('session.gc_probability', 0);
+ini_set('session.serialize_handler', 'php');
+ini_set('session.cookie_lifetime', 0);
+ini_set('session.cookie_domain', '');
+ini_set('session.cookie_secure', '');
+ini_set('session.cookie_httponly', '');
+ini_set('session.use_cookies', 1);
+ini_set('session.use_only_cookies', 1);
+ini_set('session.cache_expire', 180);
+ini_set('session.cookie_path', '/');
+ini_set('session.cookie_domain', '');
+ini_set('session.cookie_secure', 1);
+ini_set('session.cookie_httponly', 1);
+ini_set('session.use_strict_mode', 1);
+ini_set('session.lazy_write', 1);
+ini_set('session.name', 'sid');
+ini_set('session.save_path', __DIR__);
+ini_set('session.cache_limiter', '');
+
+header_remove('X-Powered-By');
+header('Content-Type: text/plain; charset=utf-8');
+
+register_shutdown_function(function () {
+ echo "\n";
+ session_write_close();
+ print_r(headers_list());
+ echo "shutdown\n";
+});
+ob_start();
+
+class TestSessionHandler extends AbstractSessionHandler
+{
+ private $data;
+
+ public function __construct($data = '')
+ {
+ $this->data = $data;
+ }
+
+ public function open($path, $name)
+ {
+ echo __FUNCTION__, "\n";
+
+ return parent::open($path, $name);
+ }
+
+ public function validateId($sessionId)
+ {
+ echo __FUNCTION__, "\n";
+
+ return parent::validateId($sessionId);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function read($sessionId)
+ {
+ echo __FUNCTION__, "\n";
+
+ return parent::read($sessionId);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function updateTimestamp($sessionId, $data)
+ {
+ echo __FUNCTION__, "\n";
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function write($sessionId, $data)
+ {
+ echo __FUNCTION__, "\n";
+
+ return parent::write($sessionId, $data);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function destroy($sessionId)
+ {
+ echo __FUNCTION__, "\n";
+
+ return parent::destroy($sessionId);
+ }
+
+ public function close()
+ {
+ echo __FUNCTION__, "\n";
+
+ return true;
+ }
+
+ public function gc($maxLifetime)
+ {
+ echo __FUNCTION__, "\n";
+
+ return true;
+ }
+
+ protected function doRead($sessionId)
+ {
+ echo __FUNCTION__.': ', $this->data, "\n";
+
+ return $this->data;
+ }
+
+ protected function doWrite($sessionId, $data)
+ {
+ echo __FUNCTION__.': ', $data, "\n";
+
+ return true;
+ }
+
+ protected function doDestroy($sessionId)
+ {
+ echo __FUNCTION__, "\n";
+
+ return true;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/empty_destroys.expected b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/empty_destroys.expected
new file mode 100644
index 0000000..8203714
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/empty_destroys.expected
@@ -0,0 +1,17 @@
+open
+validateId
+read
+doRead: abc|i:123;
+read
+
+write
+destroy
+doDestroy
+close
+Array
+(
+ [0] => Content-Type: text/plain; charset=utf-8
+ [1] => Cache-Control: max-age=10800, private, must-revalidate
+ [2] => Set-Cookie: sid=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/; secure; HttpOnly
+)
+shutdown
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/empty_destroys.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/empty_destroys.php
new file mode 100644
index 0000000..3cfc125
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/empty_destroys.php
@@ -0,0 +1,8 @@
+<?php
+
+require __DIR__.'/common.inc';
+
+session_set_save_handler(new TestSessionHandler('abc|i:123;'), false);
+session_start();
+
+unset($_SESSION['abc']);
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/read_only.expected b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/read_only.expected
new file mode 100644
index 0000000..587adaf
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/read_only.expected
@@ -0,0 +1,14 @@
+open
+validateId
+read
+doRead: abc|i:123;
+read
+123
+updateTimestamp
+close
+Array
+(
+ [0] => Content-Type: text/plain; charset=utf-8
+ [1] => Cache-Control: max-age=10800, private, must-revalidate
+)
+shutdown
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/read_only.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/read_only.php
new file mode 100644
index 0000000..3e62fb9
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/read_only.php
@@ -0,0 +1,8 @@
+<?php
+
+require __DIR__.'/common.inc';
+
+session_set_save_handler(new TestSessionHandler('abc|i:123;'), false);
+session_start();
+
+echo $_SESSION['abc'];
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/regenerate.expected b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/regenerate.expected
new file mode 100644
index 0000000..baa5f2f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/regenerate.expected
@@ -0,0 +1,24 @@
+open
+validateId
+read
+doRead: abc|i:123;
+read
+destroy
+doDestroy
+close
+open
+validateId
+read
+doRead: abc|i:123;
+read
+
+write
+doWrite: abc|i:123;
+close
+Array
+(
+ [0] => Content-Type: text/plain; charset=utf-8
+ [1] => Cache-Control: max-age=10800, private, must-revalidate
+ [2] => Set-Cookie: sid=random_session_id; path=/; secure; HttpOnly
+)
+shutdown
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/regenerate.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/regenerate.php
new file mode 100644
index 0000000..a0f635c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/regenerate.php
@@ -0,0 +1,10 @@
+<?php
+
+require __DIR__.'/common.inc';
+
+session_set_save_handler(new TestSessionHandler('abc|i:123;'), false);
+session_start();
+
+session_regenerate_id(true);
+
+ob_start(function ($buffer) { return str_replace(session_id(), 'random_session_id', $buffer); });
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/storage.expected b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/storage.expected
new file mode 100644
index 0000000..4533a10
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/storage.expected
@@ -0,0 +1,20 @@
+open
+validateId
+read
+doRead:
+read
+Array
+(
+ [0] => bar
+)
+$_SESSION is not empty
+write
+destroy
+close
+$_SESSION is not empty
+Array
+(
+ [0] => Content-Type: text/plain; charset=utf-8
+ [1] => Cache-Control: max-age=0, private, must-revalidate
+)
+shutdown
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/storage.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/storage.php
new file mode 100644
index 0000000..96dca3c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/storage.php
@@ -0,0 +1,24 @@
+<?php
+
+require __DIR__.'/common.inc';
+
+use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;
+use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
+
+$storage = new NativeSessionStorage();
+$storage->setSaveHandler(new TestSessionHandler());
+$flash = new FlashBag();
+$storage->registerBag($flash);
+$storage->start();
+
+$flash->add('foo', 'bar');
+
+print_r($flash->get('foo'));
+echo empty($_SESSION) ? '$_SESSION is empty' : '$_SESSION is not empty';
+echo "\n";
+
+$storage->save();
+
+echo empty($_SESSION) ? '$_SESSION is empty' : '$_SESSION is not empty';
+
+ob_start(function ($buffer) { return str_replace(session_id(), 'random_session_id', $buffer); });
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/with_cookie.expected b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/with_cookie.expected
new file mode 100644
index 0000000..33da0a5
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/with_cookie.expected
@@ -0,0 +1,15 @@
+open
+validateId
+read
+doRead: abc|i:123;
+read
+
+updateTimestamp
+close
+Array
+(
+ [0] => Content-Type: text/plain; charset=utf-8
+ [1] => Cache-Control: max-age=10800, private, must-revalidate
+ [2] => Set-Cookie: abc=def
+)
+shutdown
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/with_cookie.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/with_cookie.php
new file mode 100644
index 0000000..ffb5b20
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/with_cookie.php
@@ -0,0 +1,8 @@
+<?php
+
+require __DIR__.'/common.inc';
+
+session_set_save_handler(new TestSessionHandler('abc|i:123;'), false);
+session_start();
+
+setcookie('abc', 'def');
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/with_cookie_and_session.expected b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/with_cookie_and_session.expected
new file mode 100644
index 0000000..5de2d9e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/with_cookie_and_session.expected
@@ -0,0 +1,24 @@
+open
+validateId
+read
+doRead: abc|i:123;
+read
+updateTimestamp
+close
+open
+validateId
+read
+doRead: abc|i:123;
+read
+
+write
+destroy
+doDestroy
+close
+Array
+(
+ [0] => Content-Type: text/plain; charset=utf-8
+ [1] => Cache-Control: max-age=10800, private, must-revalidate
+ [2] => Set-Cookie: abc=def
+)
+shutdown
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/with_cookie_and_session.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/with_cookie_and_session.php
new file mode 100644
index 0000000..ec51193
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/with_cookie_and_session.php
@@ -0,0 +1,13 @@
+<?php
+
+require __DIR__.'/common.inc';
+
+setcookie('abc', 'def');
+
+session_set_save_handler(new TestSessionHandler('abc|i:123;'), false);
+session_start();
+session_write_close();
+session_start();
+
+$_SESSION['abc'] = 234;
+unset($_SESSION['abc']);
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/MemcacheSessionHandlerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/MemcacheSessionHandlerTest.php
new file mode 100644
index 0000000..dda43c8
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/MemcacheSessionHandlerTest.php
@@ -0,0 +1,135 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Session\Storage\Handler\MemcacheSessionHandler;
+
+/**
+ * @requires extension memcache
+ * @group time-sensitive
+ * @group legacy
+ */
+class MemcacheSessionHandlerTest extends TestCase
+{
+ const PREFIX = 'prefix_';
+ const TTL = 1000;
+
+ /**
+ * @var MemcacheSessionHandler
+ */
+ protected $storage;
+
+ protected $memcache;
+
+ protected function setUp()
+ {
+ if (defined('HHVM_VERSION')) {
+ $this->markTestSkipped('PHPUnit_MockObject cannot mock the Memcache class on HHVM. See https://github.com/sebastianbergmann/phpunit-mock-objects/pull/289');
+ }
+
+ parent::setUp();
+ $this->memcache = $this->getMockBuilder('Memcache')->getMock();
+ $this->storage = new MemcacheSessionHandler(
+ $this->memcache,
+ array('prefix' => self::PREFIX, 'expiretime' => self::TTL)
+ );
+ }
+
+ protected function tearDown()
+ {
+ $this->memcache = null;
+ $this->storage = null;
+ parent::tearDown();
+ }
+
+ public function testOpenSession()
+ {
+ $this->assertTrue($this->storage->open('', ''));
+ }
+
+ public function testCloseSession()
+ {
+ $this->assertTrue($this->storage->close());
+ }
+
+ public function testReadSession()
+ {
+ $this->memcache
+ ->expects($this->once())
+ ->method('get')
+ ->with(self::PREFIX.'id')
+ ;
+
+ $this->assertEquals('', $this->storage->read('id'));
+ }
+
+ public function testWriteSession()
+ {
+ $this->memcache
+ ->expects($this->once())
+ ->method('set')
+ ->with(self::PREFIX.'id', 'data', 0, $this->equalTo(time() + self::TTL, 2))
+ ->will($this->returnValue(true))
+ ;
+
+ $this->assertTrue($this->storage->write('id', 'data'));
+ }
+
+ public function testDestroySession()
+ {
+ $this->memcache
+ ->expects($this->once())
+ ->method('delete')
+ ->with(self::PREFIX.'id')
+ ->will($this->returnValue(true))
+ ;
+
+ $this->assertTrue($this->storage->destroy('id'));
+ }
+
+ public function testGcSession()
+ {
+ $this->assertTrue($this->storage->gc(123));
+ }
+
+ /**
+ * @dataProvider getOptionFixtures
+ */
+ public function testSupportedOptions($options, $supported)
+ {
+ try {
+ new MemcacheSessionHandler($this->memcache, $options);
+ $this->assertTrue($supported);
+ } catch (\InvalidArgumentException $e) {
+ $this->assertFalse($supported);
+ }
+ }
+
+ public function getOptionFixtures()
+ {
+ return array(
+ array(array('prefix' => 'session'), true),
+ array(array('expiretime' => 100), true),
+ array(array('prefix' => 'session', 'expiretime' => 200), true),
+ array(array('expiretime' => 100, 'foo' => 'bar'), false),
+ );
+ }
+
+ public function testGetConnection()
+ {
+ $method = new \ReflectionMethod($this->storage, 'getMemcache');
+ $method->setAccessible(true);
+
+ $this->assertInstanceOf('\Memcache', $method->invoke($this->storage));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php
new file mode 100644
index 0000000..2e7be35
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php
@@ -0,0 +1,139 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Session\Storage\Handler\MemcachedSessionHandler;
+
+/**
+ * @requires extension memcached
+ * @group time-sensitive
+ */
+class MemcachedSessionHandlerTest extends TestCase
+{
+ const PREFIX = 'prefix_';
+ const TTL = 1000;
+
+ /**
+ * @var MemcachedSessionHandler
+ */
+ protected $storage;
+
+ protected $memcached;
+
+ protected function setUp()
+ {
+ if (defined('HHVM_VERSION')) {
+ $this->markTestSkipped('PHPUnit_MockObject cannot mock the Memcached class on HHVM. See https://github.com/sebastianbergmann/phpunit-mock-objects/pull/289');
+ }
+
+ parent::setUp();
+
+ if (version_compare(phpversion('memcached'), '2.2.0', '>=') && version_compare(phpversion('memcached'), '3.0.0b1', '<')) {
+ $this->markTestSkipped('Tests can only be run with memcached extension 2.1.0 or lower, or 3.0.0b1 or higher');
+ }
+
+ $this->memcached = $this->getMockBuilder('Memcached')->getMock();
+ $this->storage = new MemcachedSessionHandler(
+ $this->memcached,
+ array('prefix' => self::PREFIX, 'expiretime' => self::TTL)
+ );
+ }
+
+ protected function tearDown()
+ {
+ $this->memcached = null;
+ $this->storage = null;
+ parent::tearDown();
+ }
+
+ public function testOpenSession()
+ {
+ $this->assertTrue($this->storage->open('', ''));
+ }
+
+ public function testCloseSession()
+ {
+ $this->assertTrue($this->storage->close());
+ }
+
+ public function testReadSession()
+ {
+ $this->memcached
+ ->expects($this->once())
+ ->method('get')
+ ->with(self::PREFIX.'id')
+ ;
+
+ $this->assertEquals('', $this->storage->read('id'));
+ }
+
+ public function testWriteSession()
+ {
+ $this->memcached
+ ->expects($this->once())
+ ->method('set')
+ ->with(self::PREFIX.'id', 'data', $this->equalTo(time() + self::TTL, 2))
+ ->will($this->returnValue(true))
+ ;
+
+ $this->assertTrue($this->storage->write('id', 'data'));
+ }
+
+ public function testDestroySession()
+ {
+ $this->memcached
+ ->expects($this->once())
+ ->method('delete')
+ ->with(self::PREFIX.'id')
+ ->will($this->returnValue(true))
+ ;
+
+ $this->assertTrue($this->storage->destroy('id'));
+ }
+
+ public function testGcSession()
+ {
+ $this->assertTrue($this->storage->gc(123));
+ }
+
+ /**
+ * @dataProvider getOptionFixtures
+ */
+ public function testSupportedOptions($options, $supported)
+ {
+ try {
+ new MemcachedSessionHandler($this->memcached, $options);
+ $this->assertTrue($supported);
+ } catch (\InvalidArgumentException $e) {
+ $this->assertFalse($supported);
+ }
+ }
+
+ public function getOptionFixtures()
+ {
+ return array(
+ array(array('prefix' => 'session'), true),
+ array(array('expiretime' => 100), true),
+ array(array('prefix' => 'session', 'expiretime' => 200), true),
+ array(array('expiretime' => 100, 'foo' => 'bar'), false),
+ );
+ }
+
+ public function testGetConnection()
+ {
+ $method = new \ReflectionMethod($this->storage, 'getMemcached');
+ $method->setAccessible(true);
+
+ $this->assertInstanceOf('\Memcached', $method->invoke($this->storage));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/MongoDbSessionHandlerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/MongoDbSessionHandlerTest.php
new file mode 100644
index 0000000..da05109
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/MongoDbSessionHandlerTest.php
@@ -0,0 +1,333 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandler;
+
+/**
+ * @author Markus Bachmann <markus.bachmann@bachi.biz>
+ * @group time-sensitive
+ * @group legacy
+ */
+class MongoDbSessionHandlerTest extends TestCase
+{
+ /**
+ * @var \PHPUnit_Framework_MockObject_MockObject
+ */
+ private $mongo;
+ private $storage;
+ public $options;
+
+ protected function setUp()
+ {
+ parent::setUp();
+
+ if (extension_loaded('mongodb')) {
+ if (!class_exists('MongoDB\Client')) {
+ $this->markTestSkipped('The mongodb/mongodb package is required.');
+ }
+ } elseif (!extension_loaded('mongo')) {
+ $this->markTestSkipped('The Mongo or MongoDB extension is required.');
+ }
+
+ if (phpversion('mongodb')) {
+ $mongoClass = 'MongoDB\Client';
+ } else {
+ $mongoClass = version_compare(phpversion('mongo'), '1.3.0', '<') ? 'Mongo' : 'MongoClient';
+ }
+
+ $this->mongo = $this->getMockBuilder($mongoClass)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->options = array(
+ 'id_field' => '_id',
+ 'data_field' => 'data',
+ 'time_field' => 'time',
+ 'expiry_field' => 'expires_at',
+ 'database' => 'sf2-test',
+ 'collection' => 'session-test',
+ );
+
+ $this->storage = new MongoDbSessionHandler($this->mongo, $this->options);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testConstructorShouldThrowExceptionForInvalidMongo()
+ {
+ new MongoDbSessionHandler(new \stdClass(), $this->options);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testConstructorShouldThrowExceptionForMissingOptions()
+ {
+ new MongoDbSessionHandler($this->mongo, array());
+ }
+
+ public function testOpenMethodAlwaysReturnTrue()
+ {
+ $this->assertTrue($this->storage->open('test', 'test'), 'The "open" method should always return true');
+ }
+
+ public function testCloseMethodAlwaysReturnTrue()
+ {
+ $this->assertTrue($this->storage->close(), 'The "close" method should always return true');
+ }
+
+ public function testRead()
+ {
+ $collection = $this->createMongoCollectionMock();
+
+ $this->mongo->expects($this->once())
+ ->method('selectCollection')
+ ->with($this->options['database'], $this->options['collection'])
+ ->will($this->returnValue($collection));
+
+ // defining the timeout before the actual method call
+ // allows to test for "greater than" values in the $criteria
+ $testTimeout = time() + 1;
+
+ $collection->expects($this->once())
+ ->method('findOne')
+ ->will($this->returnCallback(function ($criteria) use ($testTimeout) {
+ $this->assertArrayHasKey($this->options['id_field'], $criteria);
+ $this->assertEquals($criteria[$this->options['id_field']], 'foo');
+
+ $this->assertArrayHasKey($this->options['expiry_field'], $criteria);
+ $this->assertArrayHasKey('$gte', $criteria[$this->options['expiry_field']]);
+
+ if (phpversion('mongodb')) {
+ $this->assertInstanceOf('MongoDB\BSON\UTCDateTime', $criteria[$this->options['expiry_field']]['$gte']);
+ $this->assertGreaterThanOrEqual(round((string) $criteria[$this->options['expiry_field']]['$gte'] / 1000), $testTimeout);
+ } else {
+ $this->assertInstanceOf('MongoDate', $criteria[$this->options['expiry_field']]['$gte']);
+ $this->assertGreaterThanOrEqual($criteria[$this->options['expiry_field']]['$gte']->sec, $testTimeout);
+ }
+
+ $fields = array(
+ $this->options['id_field'] => 'foo',
+ );
+
+ if (phpversion('mongodb')) {
+ $fields[$this->options['data_field']] = new \MongoDB\BSON\Binary('bar', \MongoDB\BSON\Binary::TYPE_OLD_BINARY);
+ $fields[$this->options['id_field']] = new \MongoDB\BSON\UTCDateTime(time() * 1000);
+ } else {
+ $fields[$this->options['data_field']] = new \MongoBinData('bar', \MongoBinData::BYTE_ARRAY);
+ $fields[$this->options['id_field']] = new \MongoDate();
+ }
+
+ return $fields;
+ }));
+
+ $this->assertEquals('bar', $this->storage->read('foo'));
+ }
+
+ public function testWrite()
+ {
+ $collection = $this->createMongoCollectionMock();
+
+ $this->mongo->expects($this->once())
+ ->method('selectCollection')
+ ->with($this->options['database'], $this->options['collection'])
+ ->will($this->returnValue($collection));
+
+ $data = array();
+
+ $methodName = phpversion('mongodb') ? 'updateOne' : 'update';
+
+ $collection->expects($this->once())
+ ->method($methodName)
+ ->will($this->returnCallback(function ($criteria, $updateData, $options) use (&$data) {
+ $this->assertEquals(array($this->options['id_field'] => 'foo'), $criteria);
+
+ if (phpversion('mongodb')) {
+ $this->assertEquals(array('upsert' => true), $options);
+ } else {
+ $this->assertEquals(array('upsert' => true, 'multiple' => false), $options);
+ }
+
+ $data = $updateData['$set'];
+ }));
+
+ $expectedExpiry = time() + (int) ini_get('session.gc_maxlifetime');
+ $this->assertTrue($this->storage->write('foo', 'bar'));
+
+ if (phpversion('mongodb')) {
+ $this->assertEquals('bar', $data[$this->options['data_field']]->getData());
+ $this->assertInstanceOf('MongoDB\BSON\UTCDateTime', $data[$this->options['time_field']]);
+ $this->assertInstanceOf('MongoDB\BSON\UTCDateTime', $data[$this->options['expiry_field']]);
+ $this->assertGreaterThanOrEqual($expectedExpiry, round((string) $data[$this->options['expiry_field']] / 1000));
+ } else {
+ $this->assertEquals('bar', $data[$this->options['data_field']]->bin);
+ $this->assertInstanceOf('MongoDate', $data[$this->options['time_field']]);
+ $this->assertInstanceOf('MongoDate', $data[$this->options['expiry_field']]);
+ $this->assertGreaterThanOrEqual($expectedExpiry, $data[$this->options['expiry_field']]->sec);
+ }
+ }
+
+ public function testWriteWhenUsingExpiresField()
+ {
+ $this->options = array(
+ 'id_field' => '_id',
+ 'data_field' => 'data',
+ 'time_field' => 'time',
+ 'database' => 'sf2-test',
+ 'collection' => 'session-test',
+ 'expiry_field' => 'expiresAt',
+ );
+
+ $this->storage = new MongoDbSessionHandler($this->mongo, $this->options);
+
+ $collection = $this->createMongoCollectionMock();
+
+ $this->mongo->expects($this->once())
+ ->method('selectCollection')
+ ->with($this->options['database'], $this->options['collection'])
+ ->will($this->returnValue($collection));
+
+ $data = array();
+
+ $methodName = phpversion('mongodb') ? 'updateOne' : 'update';
+
+ $collection->expects($this->once())
+ ->method($methodName)
+ ->will($this->returnCallback(function ($criteria, $updateData, $options) use (&$data) {
+ $this->assertEquals(array($this->options['id_field'] => 'foo'), $criteria);
+
+ if (phpversion('mongodb')) {
+ $this->assertEquals(array('upsert' => true), $options);
+ } else {
+ $this->assertEquals(array('upsert' => true, 'multiple' => false), $options);
+ }
+
+ $data = $updateData['$set'];
+ }));
+
+ $this->assertTrue($this->storage->write('foo', 'bar'));
+
+ if (phpversion('mongodb')) {
+ $this->assertEquals('bar', $data[$this->options['data_field']]->getData());
+ $this->assertInstanceOf('MongoDB\BSON\UTCDateTime', $data[$this->options['time_field']]);
+ $this->assertInstanceOf('MongoDB\BSON\UTCDateTime', $data[$this->options['expiry_field']]);
+ } else {
+ $this->assertEquals('bar', $data[$this->options['data_field']]->bin);
+ $this->assertInstanceOf('MongoDate', $data[$this->options['time_field']]);
+ $this->assertInstanceOf('MongoDate', $data[$this->options['expiry_field']]);
+ }
+ }
+
+ public function testReplaceSessionData()
+ {
+ $collection = $this->createMongoCollectionMock();
+
+ $this->mongo->expects($this->once())
+ ->method('selectCollection')
+ ->with($this->options['database'], $this->options['collection'])
+ ->will($this->returnValue($collection));
+
+ $data = array();
+
+ $methodName = phpversion('mongodb') ? 'updateOne' : 'update';
+
+ $collection->expects($this->exactly(2))
+ ->method($methodName)
+ ->will($this->returnCallback(function ($criteria, $updateData, $options) use (&$data) {
+ $data = $updateData;
+ }));
+
+ $this->storage->write('foo', 'bar');
+ $this->storage->write('foo', 'foobar');
+
+ if (phpversion('mongodb')) {
+ $this->assertEquals('foobar', $data['$set'][$this->options['data_field']]->getData());
+ } else {
+ $this->assertEquals('foobar', $data['$set'][$this->options['data_field']]->bin);
+ }
+ }
+
+ public function testDestroy()
+ {
+ $collection = $this->createMongoCollectionMock();
+
+ $this->mongo->expects($this->once())
+ ->method('selectCollection')
+ ->with($this->options['database'], $this->options['collection'])
+ ->will($this->returnValue($collection));
+
+ $methodName = phpversion('mongodb') ? 'deleteOne' : 'remove';
+
+ $collection->expects($this->once())
+ ->method($methodName)
+ ->with(array($this->options['id_field'] => 'foo'));
+
+ $this->assertTrue($this->storage->destroy('foo'));
+ }
+
+ public function testGc()
+ {
+ $collection = $this->createMongoCollectionMock();
+
+ $this->mongo->expects($this->once())
+ ->method('selectCollection')
+ ->with($this->options['database'], $this->options['collection'])
+ ->will($this->returnValue($collection));
+
+ $methodName = phpversion('mongodb') ? 'deleteMany' : 'remove';
+
+ $collection->expects($this->once())
+ ->method($methodName)
+ ->will($this->returnCallback(function ($criteria) {
+ if (phpversion('mongodb')) {
+ $this->assertInstanceOf('MongoDB\BSON\UTCDateTime', $criteria[$this->options['expiry_field']]['$lt']);
+ $this->assertGreaterThanOrEqual(time() - 1, round((string) $criteria[$this->options['expiry_field']]['$lt'] / 1000));
+ } else {
+ $this->assertInstanceOf('MongoDate', $criteria[$this->options['expiry_field']]['$lt']);
+ $this->assertGreaterThanOrEqual(time() - 1, $criteria[$this->options['expiry_field']]['$lt']->sec);
+ }
+ }));
+
+ $this->assertTrue($this->storage->gc(1));
+ }
+
+ public function testGetConnection()
+ {
+ $method = new \ReflectionMethod($this->storage, 'getMongo');
+ $method->setAccessible(true);
+
+ if (phpversion('mongodb')) {
+ $mongoClass = 'MongoDB\Client';
+ } else {
+ $mongoClass = version_compare(phpversion('mongo'), '1.3.0', '<') ? 'Mongo' : 'MongoClient';
+ }
+
+ $this->assertInstanceOf($mongoClass, $method->invoke($this->storage));
+ }
+
+ private function createMongoCollectionMock()
+ {
+ $collectionClass = 'MongoCollection';
+ if (phpversion('mongodb')) {
+ $collectionClass = 'MongoDB\Collection';
+ }
+
+ $collection = $this->getMockBuilder($collectionClass)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ return $collection;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/NativeFileSessionHandlerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/NativeFileSessionHandlerTest.php
new file mode 100644
index 0000000..a6264e5
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/NativeFileSessionHandlerTest.php
@@ -0,0 +1,77 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeFileSessionHandler;
+use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
+
+/**
+ * Test class for NativeFileSessionHandler.
+ *
+ * @author Drak <drak@zikula.org>
+ *
+ * @runTestsInSeparateProcesses
+ * @preserveGlobalState disabled
+ */
+class NativeFileSessionHandlerTest extends TestCase
+{
+ public function testConstruct()
+ {
+ $storage = new NativeSessionStorage(array('name' => 'TESTING'), new NativeFileSessionHandler(sys_get_temp_dir()));
+
+ $this->assertEquals('files', $storage->getSaveHandler()->getSaveHandlerName());
+ $this->assertEquals('user', ini_get('session.save_handler'));
+
+ $this->assertEquals(sys_get_temp_dir(), ini_get('session.save_path'));
+ $this->assertEquals('TESTING', ini_get('session.name'));
+ }
+
+ /**
+ * @dataProvider savePathDataProvider
+ */
+ public function testConstructSavePath($savePath, $expectedSavePath, $path)
+ {
+ $handler = new NativeFileSessionHandler($savePath);
+ $this->assertEquals($expectedSavePath, ini_get('session.save_path'));
+ $this->assertTrue(is_dir(realpath($path)));
+
+ rmdir($path);
+ }
+
+ public function savePathDataProvider()
+ {
+ $base = sys_get_temp_dir();
+
+ return array(
+ array("$base/foo", "$base/foo", "$base/foo"),
+ array("5;$base/foo", "5;$base/foo", "$base/foo"),
+ array("5;0600;$base/foo", "5;0600;$base/foo", "$base/foo"),
+ );
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testConstructException()
+ {
+ $handler = new NativeFileSessionHandler('something;invalid;with;too-many-args');
+ }
+
+ public function testConstructDefault()
+ {
+ $path = ini_get('session.save_path');
+ $storage = new NativeSessionStorage(array('name' => 'TESTING'), new NativeFileSessionHandler());
+
+ $this->assertEquals($path, ini_get('session.save_path'));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/NativeSessionHandlerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/NativeSessionHandlerTest.php
new file mode 100644
index 0000000..4a9fb60
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/NativeSessionHandlerTest.php
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler;
+
+/**
+ * Test class for NativeSessionHandler.
+ *
+ * @author Drak <drak@zikula.org>
+ *
+ * @runTestsInSeparateProcesses
+ * @preserveGlobalState disabled
+ * @group legacy
+ */
+class NativeSessionHandlerTest extends TestCase
+{
+ /**
+ * @expectedDeprecation The Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler class is deprecated since Symfony 3.4 and will be removed in 4.0. Use the \SessionHandler class instead.
+ */
+ public function testConstruct()
+ {
+ $handler = new NativeSessionHandler();
+
+ $this->assertInstanceOf('SessionHandler', $handler);
+ $this->assertTrue($handler instanceof NativeSessionHandler);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/NullSessionHandlerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/NullSessionHandlerTest.php
new file mode 100644
index 0000000..718fd0f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/NullSessionHandlerTest.php
@@ -0,0 +1,59 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Session\Storage\Handler\NullSessionHandler;
+use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
+use Symfony\Component\HttpFoundation\Session\Session;
+
+/**
+ * Test class for NullSessionHandler.
+ *
+ * @author Drak <drak@zikula.org>
+ *
+ * @runTestsInSeparateProcesses
+ * @preserveGlobalState disabled
+ */
+class NullSessionHandlerTest extends TestCase
+{
+ public function testSaveHandlers()
+ {
+ $storage = $this->getStorage();
+ $this->assertEquals('user', ini_get('session.save_handler'));
+ }
+
+ public function testSession()
+ {
+ session_id('nullsessionstorage');
+ $storage = $this->getStorage();
+ $session = new Session($storage);
+ $this->assertNull($session->get('something'));
+ $session->set('something', 'unique');
+ $this->assertEquals('unique', $session->get('something'));
+ }
+
+ public function testNothingIsPersisted()
+ {
+ session_id('nullsessionstorage');
+ $storage = $this->getStorage();
+ $session = new Session($storage);
+ $session->start();
+ $this->assertEquals('nullsessionstorage', $session->getId());
+ $this->assertNull($session->get('something'));
+ }
+
+ public function getStorage()
+ {
+ return new NativeSessionStorage(array(), new NullSessionHandler());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php
new file mode 100644
index 0000000..0a0e449
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php
@@ -0,0 +1,411 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
+
+/**
+ * @requires extension pdo_sqlite
+ * @group time-sensitive
+ */
+class PdoSessionHandlerTest extends TestCase
+{
+ private $dbFile;
+
+ protected function tearDown()
+ {
+ // make sure the temporary database file is deleted when it has been created (even when a test fails)
+ if ($this->dbFile) {
+ @unlink($this->dbFile);
+ }
+ parent::tearDown();
+ }
+
+ protected function getPersistentSqliteDsn()
+ {
+ $this->dbFile = tempnam(sys_get_temp_dir(), 'sf2_sqlite_sessions');
+
+ return 'sqlite:'.$this->dbFile;
+ }
+
+ protected function getMemorySqlitePdo()
+ {
+ $pdo = new \PDO('sqlite::memory:');
+ $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+ $storage = new PdoSessionHandler($pdo);
+ $storage->createTable();
+
+ return $pdo;
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testWrongPdoErrMode()
+ {
+ $pdo = $this->getMemorySqlitePdo();
+ $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_SILENT);
+
+ $storage = new PdoSessionHandler($pdo);
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ */
+ public function testInexistentTable()
+ {
+ $storage = new PdoSessionHandler($this->getMemorySqlitePdo(), array('db_table' => 'inexistent_table'));
+ $storage->open('', 'sid');
+ $storage->read('id');
+ $storage->write('id', 'data');
+ $storage->close();
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ */
+ public function testCreateTableTwice()
+ {
+ $storage = new PdoSessionHandler($this->getMemorySqlitePdo());
+ $storage->createTable();
+ }
+
+ public function testWithLazyDsnConnection()
+ {
+ $dsn = $this->getPersistentSqliteDsn();
+
+ $storage = new PdoSessionHandler($dsn);
+ $storage->createTable();
+ $storage->open('', 'sid');
+ $data = $storage->read('id');
+ $storage->write('id', 'data');
+ $storage->close();
+ $this->assertSame('', $data, 'New session returns empty string data');
+
+ $storage->open('', 'sid');
+ $data = $storage->read('id');
+ $storage->close();
+ $this->assertSame('data', $data, 'Written value can be read back correctly');
+ }
+
+ public function testWithLazySavePathConnection()
+ {
+ $dsn = $this->getPersistentSqliteDsn();
+
+ // Open is called with what ini_set('session.save_path', $dsn) would mean
+ $storage = new PdoSessionHandler(null);
+ $storage->open($dsn, 'sid');
+ $storage->createTable();
+ $data = $storage->read('id');
+ $storage->write('id', 'data');
+ $storage->close();
+ $this->assertSame('', $data, 'New session returns empty string data');
+
+ $storage->open($dsn, 'sid');
+ $data = $storage->read('id');
+ $storage->close();
+ $this->assertSame('data', $data, 'Written value can be read back correctly');
+ }
+
+ public function testReadWriteReadWithNullByte()
+ {
+ $sessionData = 'da'."\0".'ta';
+
+ $storage = new PdoSessionHandler($this->getMemorySqlitePdo());
+ $storage->open('', 'sid');
+ $readData = $storage->read('id');
+ $storage->write('id', $sessionData);
+ $storage->close();
+ $this->assertSame('', $readData, 'New session returns empty string data');
+
+ $storage->open('', 'sid');
+ $readData = $storage->read('id');
+ $storage->close();
+ $this->assertSame($sessionData, $readData, 'Written value can be read back correctly');
+ }
+
+ public function testReadConvertsStreamToString()
+ {
+ if (defined('HHVM_VERSION')) {
+ $this->markTestSkipped('PHPUnit_MockObject cannot mock the PDOStatement class on HHVM. See https://github.com/sebastianbergmann/phpunit-mock-objects/pull/289');
+ }
+
+ $pdo = new MockPdo('pgsql');
+ $pdo->prepareResult = $this->getMockBuilder('PDOStatement')->getMock();
+
+ $content = 'foobar';
+ $stream = $this->createStream($content);
+
+ $pdo->prepareResult->expects($this->once())->method('fetchAll')
+ ->will($this->returnValue(array(array($stream, 42, time()))));
+
+ $storage = new PdoSessionHandler($pdo);
+ $result = $storage->read('foo');
+
+ $this->assertSame($content, $result);
+ }
+
+ public function testReadLockedConvertsStreamToString()
+ {
+ if (defined('HHVM_VERSION')) {
+ $this->markTestSkipped('PHPUnit_MockObject cannot mock the PDOStatement class on HHVM. See https://github.com/sebastianbergmann/phpunit-mock-objects/pull/289');
+ }
+ if (ini_get('session.use_strict_mode')) {
+ $this->markTestSkipped('Strict mode needs no locking for new sessions.');
+ }
+
+ $pdo = new MockPdo('pgsql');
+ $selectStmt = $this->getMockBuilder('PDOStatement')->getMock();
+ $insertStmt = $this->getMockBuilder('PDOStatement')->getMock();
+
+ $pdo->prepareResult = function ($statement) use ($selectStmt, $insertStmt) {
+ return 0 === strpos($statement, 'INSERT') ? $insertStmt : $selectStmt;
+ };
+
+ $content = 'foobar';
+ $stream = $this->createStream($content);
+ $exception = null;
+
+ $selectStmt->expects($this->atLeast(2))->method('fetchAll')
+ ->will($this->returnCallback(function () use (&$exception, $stream) {
+ return $exception ? array(array($stream, 42, time())) : array();
+ }));
+
+ $insertStmt->expects($this->once())->method('execute')
+ ->will($this->returnCallback(function () use (&$exception) {
+ throw $exception = new \PDOException('', '23');
+ }));
+
+ $storage = new PdoSessionHandler($pdo);
+ $result = $storage->read('foo');
+
+ $this->assertSame($content, $result);
+ }
+
+ public function testReadingRequiresExactlySameId()
+ {
+ $storage = new PdoSessionHandler($this->getMemorySqlitePdo());
+ $storage->open('', 'sid');
+ $storage->write('id', 'data');
+ $storage->write('test', 'data');
+ $storage->write('space ', 'data');
+ $storage->close();
+
+ $storage->open('', 'sid');
+ $readDataCaseSensitive = $storage->read('ID');
+ $readDataNoCharFolding = $storage->read('tést');
+ $readDataKeepSpace = $storage->read('space ');
+ $readDataExtraSpace = $storage->read('space ');
+ $storage->close();
+
+ $this->assertSame('', $readDataCaseSensitive, 'Retrieval by ID should be case-sensitive (collation setting)');
+ $this->assertSame('', $readDataNoCharFolding, 'Retrieval by ID should not do character folding (collation setting)');
+ $this->assertSame('data', $readDataKeepSpace, 'Retrieval by ID requires spaces as-is');
+ $this->assertSame('', $readDataExtraSpace, 'Retrieval by ID requires spaces as-is');
+ }
+
+ /**
+ * Simulates session_regenerate_id(true) which will require an INSERT or UPDATE (replace).
+ */
+ public function testWriteDifferentSessionIdThanRead()
+ {
+ $storage = new PdoSessionHandler($this->getMemorySqlitePdo());
+ $storage->open('', 'sid');
+ $storage->read('id');
+ $storage->destroy('id');
+ $storage->write('new_id', 'data_of_new_session_id');
+ $storage->close();
+
+ $storage->open('', 'sid');
+ $data = $storage->read('new_id');
+ $storage->close();
+
+ $this->assertSame('data_of_new_session_id', $data, 'Data of regenerated session id is available');
+ }
+
+ public function testWrongUsageStillWorks()
+ {
+ // wrong method sequence that should no happen, but still works
+ $storage = new PdoSessionHandler($this->getMemorySqlitePdo());
+ $storage->write('id', 'data');
+ $storage->write('other_id', 'other_data');
+ $storage->destroy('inexistent');
+ $storage->open('', 'sid');
+ $data = $storage->read('id');
+ $otherData = $storage->read('other_id');
+ $storage->close();
+
+ $this->assertSame('data', $data);
+ $this->assertSame('other_data', $otherData);
+ }
+
+ public function testSessionDestroy()
+ {
+ $pdo = $this->getMemorySqlitePdo();
+ $storage = new PdoSessionHandler($pdo);
+
+ $storage->open('', 'sid');
+ $storage->read('id');
+ $storage->write('id', 'data');
+ $storage->close();
+ $this->assertEquals(1, $pdo->query('SELECT COUNT(*) FROM sessions')->fetchColumn());
+
+ $storage->open('', 'sid');
+ $storage->read('id');
+ $storage->destroy('id');
+ $storage->close();
+ $this->assertEquals(0, $pdo->query('SELECT COUNT(*) FROM sessions')->fetchColumn());
+
+ $storage->open('', 'sid');
+ $data = $storage->read('id');
+ $storage->close();
+ $this->assertSame('', $data, 'Destroyed session returns empty string');
+ }
+
+ /**
+ * @runInSeparateProcess
+ */
+ public function testSessionGC()
+ {
+ $previousLifeTime = ini_set('session.gc_maxlifetime', 1000);
+ $pdo = $this->getMemorySqlitePdo();
+ $storage = new PdoSessionHandler($pdo);
+
+ $storage->open('', 'sid');
+ $storage->read('id');
+ $storage->write('id', 'data');
+ $storage->close();
+
+ $storage->open('', 'sid');
+ $storage->read('gc_id');
+ ini_set('session.gc_maxlifetime', -1); // test that you can set lifetime of a session after it has been read
+ $storage->write('gc_id', 'data');
+ $storage->close();
+ $this->assertEquals(2, $pdo->query('SELECT COUNT(*) FROM sessions')->fetchColumn(), 'No session pruned because gc not called');
+
+ $storage->open('', 'sid');
+ $data = $storage->read('gc_id');
+ $storage->gc(-1);
+ $storage->close();
+
+ ini_set('session.gc_maxlifetime', $previousLifeTime);
+
+ $this->assertSame('', $data, 'Session already considered garbage, so not returning data even if it is not pruned yet');
+ $this->assertEquals(1, $pdo->query('SELECT COUNT(*) FROM sessions')->fetchColumn(), 'Expired session is pruned');
+ }
+
+ public function testGetConnection()
+ {
+ $storage = new PdoSessionHandler($this->getMemorySqlitePdo());
+
+ $method = new \ReflectionMethod($storage, 'getConnection');
+ $method->setAccessible(true);
+
+ $this->assertInstanceOf('\PDO', $method->invoke($storage));
+ }
+
+ public function testGetConnectionConnectsIfNeeded()
+ {
+ $storage = new PdoSessionHandler('sqlite::memory:');
+
+ $method = new \ReflectionMethod($storage, 'getConnection');
+ $method->setAccessible(true);
+
+ $this->assertInstanceOf('\PDO', $method->invoke($storage));
+ }
+
+ /**
+ * @dataProvider provideUrlDsnPairs
+ */
+ public function testUrlDsn($url, $expectedDsn, $expectedUser = null, $expectedPassword = null)
+ {
+ $storage = new PdoSessionHandler($url);
+
+ $this->assertAttributeEquals($expectedDsn, 'dsn', $storage);
+
+ if (null !== $expectedUser) {
+ $this->assertAttributeEquals($expectedUser, 'username', $storage);
+ }
+
+ if (null !== $expectedPassword) {
+ $this->assertAttributeEquals($expectedPassword, 'password', $storage);
+ }
+ }
+
+ public function provideUrlDsnPairs()
+ {
+ yield array('mysql://localhost/test', 'mysql:host=localhost;dbname=test;');
+ yield array('mysql://localhost:56/test', 'mysql:host=localhost;port=56;dbname=test;');
+ yield array('mysql2://root:pwd@localhost/test', 'mysql:host=localhost;dbname=test;', 'root', 'pwd');
+ yield array('postgres://localhost/test', 'pgsql:host=localhost;dbname=test;');
+ yield array('postgresql://localhost:5634/test', 'pgsql:host=localhost;port=5634;dbname=test;');
+ yield array('postgres://root:pwd@localhost/test', 'pgsql:host=localhost;dbname=test;', 'root', 'pwd');
+ yield 'sqlite relative path' => array('sqlite://localhost/tmp/test', 'sqlite:tmp/test');
+ yield 'sqlite absolute path' => array('sqlite://localhost//tmp/test', 'sqlite:/tmp/test');
+ yield 'sqlite relative path without host' => array('sqlite:///tmp/test', 'sqlite:tmp/test');
+ yield 'sqlite absolute path without host' => array('sqlite3:////tmp/test', 'sqlite:/tmp/test');
+ yield array('sqlite://localhost/:memory:', 'sqlite::memory:');
+ yield array('mssql://localhost/test', 'sqlsrv:server=localhost;Database=test');
+ yield array('mssql://localhost:56/test', 'sqlsrv:server=localhost,56;Database=test');
+ }
+
+ private function createStream($content)
+ {
+ $stream = tmpfile();
+ fwrite($stream, $content);
+ fseek($stream, 0);
+
+ return $stream;
+ }
+}
+
+class MockPdo extends \PDO
+{
+ public $prepareResult;
+ private $driverName;
+ private $errorMode;
+
+ public function __construct($driverName = null, $errorMode = null)
+ {
+ $this->driverName = $driverName;
+ $this->errorMode = null !== $errorMode ?: \PDO::ERRMODE_EXCEPTION;
+ }
+
+ public function getAttribute($attribute)
+ {
+ if (\PDO::ATTR_ERRMODE === $attribute) {
+ return $this->errorMode;
+ }
+
+ if (\PDO::ATTR_DRIVER_NAME === $attribute) {
+ return $this->driverName;
+ }
+
+ return parent::getAttribute($attribute);
+ }
+
+ public function prepare($statement, $driverOptions = array())
+ {
+ return is_callable($this->prepareResult)
+ ? call_user_func($this->prepareResult, $statement, $driverOptions)
+ : $this->prepareResult;
+ }
+
+ public function beginTransaction()
+ {
+ }
+
+ public function rollBack()
+ {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/StrictSessionHandlerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/StrictSessionHandlerTest.php
new file mode 100644
index 0000000..b02c41a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/StrictSessionHandlerTest.php
@@ -0,0 +1,189 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Session\Storage\Handler\AbstractSessionHandler;
+use Symfony\Component\HttpFoundation\Session\Storage\Handler\StrictSessionHandler;
+
+class StrictSessionHandlerTest extends TestCase
+{
+ public function testOpen()
+ {
+ $handler = $this->getMockBuilder('SessionHandlerInterface')->getMock();
+ $handler->expects($this->once())->method('open')
+ ->with('path', 'name')->willReturn(true);
+ $proxy = new StrictSessionHandler($handler);
+
+ $this->assertInstanceOf('SessionUpdateTimestampHandlerInterface', $proxy);
+ $this->assertInstanceOf(AbstractSessionHandler::class, $proxy);
+ $this->assertTrue($proxy->open('path', 'name'));
+ }
+
+ public function testCloseSession()
+ {
+ $handler = $this->getMockBuilder('SessionHandlerInterface')->getMock();
+ $handler->expects($this->once())->method('close')
+ ->willReturn(true);
+ $proxy = new StrictSessionHandler($handler);
+
+ $this->assertTrue($proxy->close());
+ }
+
+ public function testValidateIdOK()
+ {
+ $handler = $this->getMockBuilder('SessionHandlerInterface')->getMock();
+ $handler->expects($this->once())->method('read')
+ ->with('id')->willReturn('data');
+ $proxy = new StrictSessionHandler($handler);
+
+ $this->assertTrue($proxy->validateId('id'));
+ }
+
+ public function testValidateIdKO()
+ {
+ $handler = $this->getMockBuilder('SessionHandlerInterface')->getMock();
+ $handler->expects($this->once())->method('read')
+ ->with('id')->willReturn('');
+ $proxy = new StrictSessionHandler($handler);
+
+ $this->assertFalse($proxy->validateId('id'));
+ }
+
+ public function testRead()
+ {
+ $handler = $this->getMockBuilder('SessionHandlerInterface')->getMock();
+ $handler->expects($this->once())->method('read')
+ ->with('id')->willReturn('data');
+ $proxy = new StrictSessionHandler($handler);
+
+ $this->assertSame('data', $proxy->read('id'));
+ }
+
+ public function testReadWithValidateIdOK()
+ {
+ $handler = $this->getMockBuilder('SessionHandlerInterface')->getMock();
+ $handler->expects($this->once())->method('read')
+ ->with('id')->willReturn('data');
+ $proxy = new StrictSessionHandler($handler);
+
+ $this->assertTrue($proxy->validateId('id'));
+ $this->assertSame('data', $proxy->read('id'));
+ }
+
+ public function testReadWithValidateIdMismatch()
+ {
+ $handler = $this->getMockBuilder('SessionHandlerInterface')->getMock();
+ $handler->expects($this->exactly(2))->method('read')
+ ->withConsecutive(array('id1'), array('id2'))
+ ->will($this->onConsecutiveCalls('data1', 'data2'));
+ $proxy = new StrictSessionHandler($handler);
+
+ $this->assertTrue($proxy->validateId('id1'));
+ $this->assertSame('data2', $proxy->read('id2'));
+ }
+
+ public function testUpdateTimestamp()
+ {
+ $handler = $this->getMockBuilder('SessionHandlerInterface')->getMock();
+ $handler->expects($this->once())->method('write')
+ ->with('id', 'data')->willReturn(true);
+ $proxy = new StrictSessionHandler($handler);
+
+ $this->assertTrue($proxy->updateTimestamp('id', 'data'));
+ }
+
+ public function testWrite()
+ {
+ $handler = $this->getMockBuilder('SessionHandlerInterface')->getMock();
+ $handler->expects($this->once())->method('write')
+ ->with('id', 'data')->willReturn(true);
+ $proxy = new StrictSessionHandler($handler);
+
+ $this->assertTrue($proxy->write('id', 'data'));
+ }
+
+ public function testWriteEmptyNewSession()
+ {
+ $handler = $this->getMockBuilder('SessionHandlerInterface')->getMock();
+ $handler->expects($this->once())->method('read')
+ ->with('id')->willReturn('');
+ $handler->expects($this->never())->method('write');
+ $handler->expects($this->once())->method('destroy')->willReturn(true);
+ $proxy = new StrictSessionHandler($handler);
+
+ $this->assertFalse($proxy->validateId('id'));
+ $this->assertSame('', $proxy->read('id'));
+ $this->assertTrue($proxy->write('id', ''));
+ }
+
+ public function testWriteEmptyExistingSession()
+ {
+ $handler = $this->getMockBuilder('SessionHandlerInterface')->getMock();
+ $handler->expects($this->once())->method('read')
+ ->with('id')->willReturn('data');
+ $handler->expects($this->never())->method('write');
+ $handler->expects($this->once())->method('destroy')->willReturn(true);
+ $proxy = new StrictSessionHandler($handler);
+
+ $this->assertSame('data', $proxy->read('id'));
+ $this->assertTrue($proxy->write('id', ''));
+ }
+
+ public function testDestroy()
+ {
+ $handler = $this->getMockBuilder('SessionHandlerInterface')->getMock();
+ $handler->expects($this->once())->method('destroy')
+ ->with('id')->willReturn(true);
+ $proxy = new StrictSessionHandler($handler);
+
+ $this->assertTrue($proxy->destroy('id'));
+ }
+
+ public function testDestroyNewSession()
+ {
+ $handler = $this->getMockBuilder('SessionHandlerInterface')->getMock();
+ $handler->expects($this->once())->method('read')
+ ->with('id')->willReturn('');
+ $handler->expects($this->once())->method('destroy')->willReturn(true);
+ $proxy = new StrictSessionHandler($handler);
+
+ $this->assertSame('', $proxy->read('id'));
+ $this->assertTrue($proxy->destroy('id'));
+ }
+
+ public function testDestroyNonEmptyNewSession()
+ {
+ $handler = $this->getMockBuilder('SessionHandlerInterface')->getMock();
+ $handler->expects($this->once())->method('read')
+ ->with('id')->willReturn('');
+ $handler->expects($this->once())->method('write')
+ ->with('id', 'data')->willReturn(true);
+ $handler->expects($this->once())->method('destroy')
+ ->with('id')->willReturn(true);
+ $proxy = new StrictSessionHandler($handler);
+
+ $this->assertSame('', $proxy->read('id'));
+ $this->assertTrue($proxy->write('id', 'data'));
+ $this->assertTrue($proxy->destroy('id'));
+ }
+
+ public function testGc()
+ {
+ $handler = $this->getMockBuilder('SessionHandlerInterface')->getMock();
+ $handler->expects($this->once())->method('gc')
+ ->with(123)->willReturn(true);
+ $proxy = new StrictSessionHandler($handler);
+
+ $this->assertTrue($proxy->gc(123));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/WriteCheckSessionHandlerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/WriteCheckSessionHandlerTest.php
new file mode 100644
index 0000000..898a7d1
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/WriteCheckSessionHandlerTest.php
@@ -0,0 +1,97 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Session\Storage\Handler\WriteCheckSessionHandler;
+
+/**
+ * @author Adrien Brault <adrien.brault@gmail.com>
+ *
+ * @group legacy
+ */
+class WriteCheckSessionHandlerTest extends TestCase
+{
+ public function test()
+ {
+ $wrappedSessionHandlerMock = $this->getMockBuilder('SessionHandlerInterface')->getMock();
+ $writeCheckSessionHandler = new WriteCheckSessionHandler($wrappedSessionHandlerMock);
+
+ $wrappedSessionHandlerMock
+ ->expects($this->once())
+ ->method('close')
+ ->with()
+ ->will($this->returnValue(true))
+ ;
+
+ $this->assertTrue($writeCheckSessionHandler->close());
+ }
+
+ public function testWrite()
+ {
+ $wrappedSessionHandlerMock = $this->getMockBuilder('SessionHandlerInterface')->getMock();
+ $writeCheckSessionHandler = new WriteCheckSessionHandler($wrappedSessionHandlerMock);
+
+ $wrappedSessionHandlerMock
+ ->expects($this->once())
+ ->method('write')
+ ->with('foo', 'bar')
+ ->will($this->returnValue(true))
+ ;
+
+ $this->assertTrue($writeCheckSessionHandler->write('foo', 'bar'));
+ }
+
+ public function testSkippedWrite()
+ {
+ $wrappedSessionHandlerMock = $this->getMockBuilder('SessionHandlerInterface')->getMock();
+ $writeCheckSessionHandler = new WriteCheckSessionHandler($wrappedSessionHandlerMock);
+
+ $wrappedSessionHandlerMock
+ ->expects($this->once())
+ ->method('read')
+ ->with('foo')
+ ->will($this->returnValue('bar'))
+ ;
+
+ $wrappedSessionHandlerMock
+ ->expects($this->never())
+ ->method('write')
+ ;
+
+ $this->assertEquals('bar', $writeCheckSessionHandler->read('foo'));
+ $this->assertTrue($writeCheckSessionHandler->write('foo', 'bar'));
+ }
+
+ public function testNonSkippedWrite()
+ {
+ $wrappedSessionHandlerMock = $this->getMockBuilder('SessionHandlerInterface')->getMock();
+ $writeCheckSessionHandler = new WriteCheckSessionHandler($wrappedSessionHandlerMock);
+
+ $wrappedSessionHandlerMock
+ ->expects($this->once())
+ ->method('read')
+ ->with('foo')
+ ->will($this->returnValue('bar'))
+ ;
+
+ $wrappedSessionHandlerMock
+ ->expects($this->once())
+ ->method('write')
+ ->with('foo', 'baZZZ')
+ ->will($this->returnValue(true))
+ ;
+
+ $this->assertEquals('bar', $writeCheckSessionHandler->read('foo'));
+ $this->assertTrue($writeCheckSessionHandler->write('foo', 'baZZZ'));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/MetadataBagTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/MetadataBagTest.php
new file mode 100644
index 0000000..69cf616
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/MetadataBagTest.php
@@ -0,0 +1,139 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests\Session\Storage;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag;
+
+/**
+ * Test class for MetadataBag.
+ *
+ * @group time-sensitive
+ */
+class MetadataBagTest extends TestCase
+{
+ /**
+ * @var MetadataBag
+ */
+ protected $bag;
+
+ protected $array = array();
+
+ protected function setUp()
+ {
+ parent::setUp();
+ $this->bag = new MetadataBag();
+ $this->array = array(MetadataBag::CREATED => 1234567, MetadataBag::UPDATED => 12345678, MetadataBag::LIFETIME => 0);
+ $this->bag->initialize($this->array);
+ }
+
+ protected function tearDown()
+ {
+ $this->array = array();
+ $this->bag = null;
+ parent::tearDown();
+ }
+
+ public function testInitialize()
+ {
+ $sessionMetadata = array();
+
+ $bag1 = new MetadataBag();
+ $bag1->initialize($sessionMetadata);
+ $this->assertGreaterThanOrEqual(time(), $bag1->getCreated());
+ $this->assertEquals($bag1->getCreated(), $bag1->getLastUsed());
+
+ sleep(1);
+ $bag2 = new MetadataBag();
+ $bag2->initialize($sessionMetadata);
+ $this->assertEquals($bag1->getCreated(), $bag2->getCreated());
+ $this->assertEquals($bag1->getLastUsed(), $bag2->getLastUsed());
+ $this->assertEquals($bag2->getCreated(), $bag2->getLastUsed());
+
+ sleep(1);
+ $bag3 = new MetadataBag();
+ $bag3->initialize($sessionMetadata);
+ $this->assertEquals($bag1->getCreated(), $bag3->getCreated());
+ $this->assertGreaterThan($bag2->getLastUsed(), $bag3->getLastUsed());
+ $this->assertNotEquals($bag3->getCreated(), $bag3->getLastUsed());
+ }
+
+ public function testGetSetName()
+ {
+ $this->assertEquals('__metadata', $this->bag->getName());
+ $this->bag->setName('foo');
+ $this->assertEquals('foo', $this->bag->getName());
+ }
+
+ public function testGetStorageKey()
+ {
+ $this->assertEquals('_sf2_meta', $this->bag->getStorageKey());
+ }
+
+ public function testGetLifetime()
+ {
+ $bag = new MetadataBag();
+ $array = array(MetadataBag::CREATED => 1234567, MetadataBag::UPDATED => 12345678, MetadataBag::LIFETIME => 1000);
+ $bag->initialize($array);
+ $this->assertEquals(1000, $bag->getLifetime());
+ }
+
+ public function testGetCreated()
+ {
+ $this->assertEquals(1234567, $this->bag->getCreated());
+ }
+
+ public function testGetLastUsed()
+ {
+ $this->assertLessThanOrEqual(time(), $this->bag->getLastUsed());
+ }
+
+ public function testClear()
+ {
+ $this->bag->clear();
+
+ // the clear method has no side effects, we just want to ensure it doesn't trigger any exceptions
+ $this->addToAssertionCount(1);
+ }
+
+ public function testSkipLastUsedUpdate()
+ {
+ $bag = new MetadataBag('', 30);
+ $timeStamp = time();
+
+ $created = $timeStamp - 15;
+ $sessionMetadata = array(
+ MetadataBag::CREATED => $created,
+ MetadataBag::UPDATED => $created,
+ MetadataBag::LIFETIME => 1000,
+ );
+ $bag->initialize($sessionMetadata);
+
+ $this->assertEquals($created, $sessionMetadata[MetadataBag::UPDATED]);
+ }
+
+ public function testDoesNotSkipLastUsedUpdate()
+ {
+ $bag = new MetadataBag('', 30);
+ $timeStamp = time();
+
+ $created = $timeStamp - 45;
+ $sessionMetadata = array(
+ MetadataBag::CREATED => $created,
+ MetadataBag::UPDATED => $created,
+ MetadataBag::LIFETIME => 1000,
+ );
+ $bag->initialize($sessionMetadata);
+
+ $this->assertEquals($timeStamp, $sessionMetadata[MetadataBag::UPDATED]);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/MockArraySessionStorageTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/MockArraySessionStorageTest.php
new file mode 100644
index 0000000..82df554
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/MockArraySessionStorageTest.php
@@ -0,0 +1,131 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests\Session\Storage;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
+use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
+use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;
+
+/**
+ * Test class for MockArraySessionStorage.
+ *
+ * @author Drak <drak@zikula.org>
+ */
+class MockArraySessionStorageTest extends TestCase
+{
+ /**
+ * @var MockArraySessionStorage
+ */
+ private $storage;
+
+ /**
+ * @var AttributeBag
+ */
+ private $attributes;
+
+ /**
+ * @var FlashBag
+ */
+ private $flashes;
+
+ private $data;
+
+ protected function setUp()
+ {
+ $this->attributes = new AttributeBag();
+ $this->flashes = new FlashBag();
+
+ $this->data = array(
+ $this->attributes->getStorageKey() => array('foo' => 'bar'),
+ $this->flashes->getStorageKey() => array('notice' => 'hello'),
+ );
+
+ $this->storage = new MockArraySessionStorage();
+ $this->storage->registerBag($this->flashes);
+ $this->storage->registerBag($this->attributes);
+ $this->storage->setSessionData($this->data);
+ }
+
+ protected function tearDown()
+ {
+ $this->data = null;
+ $this->flashes = null;
+ $this->attributes = null;
+ $this->storage = null;
+ }
+
+ public function testStart()
+ {
+ $this->assertEquals('', $this->storage->getId());
+ $this->storage->start();
+ $id = $this->storage->getId();
+ $this->assertNotEquals('', $id);
+ $this->storage->start();
+ $this->assertEquals($id, $this->storage->getId());
+ }
+
+ public function testRegenerate()
+ {
+ $this->storage->start();
+ $id = $this->storage->getId();
+ $this->storage->regenerate();
+ $this->assertNotEquals($id, $this->storage->getId());
+ $this->assertEquals(array('foo' => 'bar'), $this->storage->getBag('attributes')->all());
+ $this->assertEquals(array('notice' => 'hello'), $this->storage->getBag('flashes')->peekAll());
+
+ $id = $this->storage->getId();
+ $this->storage->regenerate(true);
+ $this->assertNotEquals($id, $this->storage->getId());
+ $this->assertEquals(array('foo' => 'bar'), $this->storage->getBag('attributes')->all());
+ $this->assertEquals(array('notice' => 'hello'), $this->storage->getBag('flashes')->peekAll());
+ }
+
+ public function testGetId()
+ {
+ $this->assertEquals('', $this->storage->getId());
+ $this->storage->start();
+ $this->assertNotEquals('', $this->storage->getId());
+ }
+
+ public function testClearClearsBags()
+ {
+ $this->storage->clear();
+
+ $this->assertSame(array(), $this->storage->getBag('attributes')->all());
+ $this->assertSame(array(), $this->storage->getBag('flashes')->peekAll());
+ }
+
+ public function testClearStartsSession()
+ {
+ $this->storage->clear();
+
+ $this->assertTrue($this->storage->isStarted());
+ }
+
+ public function testClearWithNoBagsStartsSession()
+ {
+ $storage = new MockArraySessionStorage();
+
+ $storage->clear();
+
+ $this->assertTrue($storage->isStarted());
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ */
+ public function testUnstartedSave()
+ {
+ $this->storage->save();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/MockFileSessionStorageTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/MockFileSessionStorageTest.php
new file mode 100644
index 0000000..53accd3
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/MockFileSessionStorageTest.php
@@ -0,0 +1,127 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests\Session\Storage;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorage;
+use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;
+use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
+
+/**
+ * Test class for MockFileSessionStorage.
+ *
+ * @author Drak <drak@zikula.org>
+ */
+class MockFileSessionStorageTest extends TestCase
+{
+ /**
+ * @var string
+ */
+ private $sessionDir;
+
+ /**
+ * @var MockFileSessionStorage
+ */
+ protected $storage;
+
+ protected function setUp()
+ {
+ $this->sessionDir = sys_get_temp_dir().'/sf2test';
+ $this->storage = $this->getStorage();
+ }
+
+ protected function tearDown()
+ {
+ $this->sessionDir = null;
+ $this->storage = null;
+ array_map('unlink', glob($this->sessionDir.'/*.session'));
+ if (is_dir($this->sessionDir)) {
+ rmdir($this->sessionDir);
+ }
+ }
+
+ public function testStart()
+ {
+ $this->assertEquals('', $this->storage->getId());
+ $this->assertTrue($this->storage->start());
+ $id = $this->storage->getId();
+ $this->assertNotEquals('', $this->storage->getId());
+ $this->assertTrue($this->storage->start());
+ $this->assertEquals($id, $this->storage->getId());
+ }
+
+ public function testRegenerate()
+ {
+ $this->storage->start();
+ $this->storage->getBag('attributes')->set('regenerate', 1234);
+ $this->storage->regenerate();
+ $this->assertEquals(1234, $this->storage->getBag('attributes')->get('regenerate'));
+ $this->storage->regenerate(true);
+ $this->assertEquals(1234, $this->storage->getBag('attributes')->get('regenerate'));
+ }
+
+ public function testGetId()
+ {
+ $this->assertEquals('', $this->storage->getId());
+ $this->storage->start();
+ $this->assertNotEquals('', $this->storage->getId());
+ }
+
+ public function testSave()
+ {
+ $this->storage->start();
+ $id = $this->storage->getId();
+ $this->assertNotEquals('108', $this->storage->getBag('attributes')->get('new'));
+ $this->assertFalse($this->storage->getBag('flashes')->has('newkey'));
+ $this->storage->getBag('attributes')->set('new', '108');
+ $this->storage->getBag('flashes')->set('newkey', 'test');
+ $this->storage->save();
+
+ $storage = $this->getStorage();
+ $storage->setId($id);
+ $storage->start();
+ $this->assertEquals('108', $storage->getBag('attributes')->get('new'));
+ $this->assertTrue($storage->getBag('flashes')->has('newkey'));
+ $this->assertEquals(array('test'), $storage->getBag('flashes')->peek('newkey'));
+ }
+
+ public function testMultipleInstances()
+ {
+ $storage1 = $this->getStorage();
+ $storage1->start();
+ $storage1->getBag('attributes')->set('foo', 'bar');
+ $storage1->save();
+
+ $storage2 = $this->getStorage();
+ $storage2->setId($storage1->getId());
+ $storage2->start();
+ $this->assertEquals('bar', $storage2->getBag('attributes')->get('foo'), 'values persist between instances');
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ */
+ public function testSaveWithoutStart()
+ {
+ $storage1 = $this->getStorage();
+ $storage1->save();
+ }
+
+ private function getStorage()
+ {
+ $storage = new MockFileSessionStorage($this->sessionDir);
+ $storage->registerBag(new FlashBag());
+ $storage->registerBag(new AttributeBag());
+
+ return $storage;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/NativeSessionStorageTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/NativeSessionStorageTest.php
new file mode 100644
index 0000000..8fb8b42
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/NativeSessionStorageTest.php
@@ -0,0 +1,277 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests\Session\Storage;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
+use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;
+use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeFileSessionHandler;
+use Symfony\Component\HttpFoundation\Session\Storage\Handler\NullSessionHandler;
+use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
+use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;
+
+/**
+ * Test class for NativeSessionStorage.
+ *
+ * @author Drak <drak@zikula.org>
+ *
+ * These tests require separate processes.
+ *
+ * @runTestsInSeparateProcesses
+ * @preserveGlobalState disabled
+ */
+class NativeSessionStorageTest extends TestCase
+{
+ private $savePath;
+
+ protected function setUp()
+ {
+ $this->iniSet('session.save_handler', 'files');
+ $this->iniSet('session.save_path', $this->savePath = sys_get_temp_dir().'/sf2test');
+ if (!is_dir($this->savePath)) {
+ mkdir($this->savePath);
+ }
+ }
+
+ protected function tearDown()
+ {
+ session_write_close();
+ array_map('unlink', glob($this->savePath.'/*'));
+ if (is_dir($this->savePath)) {
+ rmdir($this->savePath);
+ }
+
+ $this->savePath = null;
+ }
+
+ /**
+ * @return NativeSessionStorage
+ */
+ protected function getStorage(array $options = array())
+ {
+ $storage = new NativeSessionStorage($options);
+ $storage->registerBag(new AttributeBag());
+
+ return $storage;
+ }
+
+ public function testBag()
+ {
+ $storage = $this->getStorage();
+ $bag = new FlashBag();
+ $storage->registerBag($bag);
+ $this->assertSame($bag, $storage->getBag($bag->getName()));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testRegisterBagException()
+ {
+ $storage = $this->getStorage();
+ $storage->getBag('non_existing');
+ }
+
+ /**
+ * @expectedException \LogicException
+ */
+ public function testRegisterBagForAStartedSessionThrowsException()
+ {
+ $storage = $this->getStorage();
+ $storage->start();
+ $storage->registerBag(new AttributeBag());
+ }
+
+ public function testGetId()
+ {
+ $storage = $this->getStorage();
+ $this->assertSame('', $storage->getId(), 'Empty ID before starting session');
+
+ $storage->start();
+ $id = $storage->getId();
+ $this->assertInternalType('string', $id);
+ $this->assertNotSame('', $id);
+
+ $storage->save();
+ $this->assertSame($id, $storage->getId(), 'ID stays after saving session');
+ }
+
+ public function testRegenerate()
+ {
+ $storage = $this->getStorage();
+ $storage->start();
+ $id = $storage->getId();
+ $storage->getBag('attributes')->set('lucky', 7);
+ $storage->regenerate();
+ $this->assertNotEquals($id, $storage->getId());
+ $this->assertEquals(7, $storage->getBag('attributes')->get('lucky'));
+ }
+
+ public function testRegenerateDestroy()
+ {
+ $storage = $this->getStorage();
+ $storage->start();
+ $id = $storage->getId();
+ $storage->getBag('attributes')->set('legs', 11);
+ $storage->regenerate(true);
+ $this->assertNotEquals($id, $storage->getId());
+ $this->assertEquals(11, $storage->getBag('attributes')->get('legs'));
+ }
+
+ public function testSessionGlobalIsUpToDateAfterIdRegeneration()
+ {
+ $storage = $this->getStorage();
+ $storage->start();
+ $storage->getBag('attributes')->set('lucky', 7);
+ $storage->regenerate();
+ $storage->getBag('attributes')->set('lucky', 42);
+
+ $this->assertEquals(42, $_SESSION['_sf2_attributes']['lucky']);
+ }
+
+ public function testRegenerationFailureDoesNotFlagStorageAsStarted()
+ {
+ $storage = $this->getStorage();
+ $this->assertFalse($storage->regenerate());
+ $this->assertFalse($storage->isStarted());
+ }
+
+ public function testDefaultSessionCacheLimiter()
+ {
+ $this->iniSet('session.cache_limiter', 'nocache');
+
+ $storage = new NativeSessionStorage();
+ $this->assertEquals('', ini_get('session.cache_limiter'));
+ }
+
+ public function testExplicitSessionCacheLimiter()
+ {
+ $this->iniSet('session.cache_limiter', 'nocache');
+
+ $storage = new NativeSessionStorage(array('cache_limiter' => 'public'));
+ $this->assertEquals('public', ini_get('session.cache_limiter'));
+ }
+
+ public function testCookieOptions()
+ {
+ $options = array(
+ 'cookie_lifetime' => 123456,
+ 'cookie_path' => '/my/cookie/path',
+ 'cookie_domain' => 'symfony.example.com',
+ 'cookie_secure' => true,
+ 'cookie_httponly' => false,
+ );
+
+ $this->getStorage($options);
+ $temp = session_get_cookie_params();
+ $gco = array();
+
+ foreach ($temp as $key => $value) {
+ $gco['cookie_'.$key] = $value;
+ }
+
+ $this->assertEquals($options, $gco);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testSetSaveHandlerException()
+ {
+ $storage = $this->getStorage();
+ $storage->setSaveHandler(new \stdClass());
+ }
+
+ public function testSetSaveHandler()
+ {
+ $this->iniSet('session.save_handler', 'files');
+ $storage = $this->getStorage();
+ $storage->setSaveHandler();
+ $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
+ $storage->setSaveHandler(null);
+ $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
+ $storage->setSaveHandler(new SessionHandlerProxy(new NativeFileSessionHandler()));
+ $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
+ $storage->setSaveHandler(new NativeFileSessionHandler());
+ $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
+ $storage->setSaveHandler(new SessionHandlerProxy(new NullSessionHandler()));
+ $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
+ $storage->setSaveHandler(new NullSessionHandler());
+ $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ */
+ public function testStarted()
+ {
+ $storage = $this->getStorage();
+
+ $this->assertFalse($storage->getSaveHandler()->isActive());
+ $this->assertFalse($storage->isStarted());
+
+ session_start();
+ $this->assertTrue(isset($_SESSION));
+ $this->assertTrue($storage->getSaveHandler()->isActive());
+
+ // PHP session might have started, but the storage driver has not, so false is correct here
+ $this->assertFalse($storage->isStarted());
+
+ $key = $storage->getMetadataBag()->getStorageKey();
+ $this->assertArrayNotHasKey($key, $_SESSION);
+ $storage->start();
+ }
+
+ public function testRestart()
+ {
+ $storage = $this->getStorage();
+ $storage->start();
+ $id = $storage->getId();
+ $storage->getBag('attributes')->set('lucky', 7);
+ $storage->save();
+ $storage->start();
+ $this->assertSame($id, $storage->getId(), 'Same session ID after restarting');
+ $this->assertSame(7, $storage->getBag('attributes')->get('lucky'), 'Data still available');
+ }
+
+ public function testCanCreateNativeSessionStorageWhenSessionAlreadyStarted()
+ {
+ session_start();
+ $this->getStorage();
+
+ // Assert no exception has been thrown by `getStorage()`
+ $this->addToAssertionCount(1);
+ }
+
+ public function testSetSessionOptionsOnceSessionStartedIsIgnored()
+ {
+ session_start();
+ $this->getStorage(array(
+ 'name' => 'something-else',
+ ));
+
+ // Assert no exception has been thrown by `getStorage()`
+ $this->addToAssertionCount(1);
+ }
+
+ public function testGetBagsOnceSessionStartedIsIgnored()
+ {
+ session_start();
+ $bag = new AttributeBag();
+ $bag->setName('flashes');
+
+ $storage = $this->getStorage();
+ $storage->registerBag($bag);
+
+ $this->assertEquals($storage->getBag('flashes'), $bag);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/PhpBridgeSessionStorageTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/PhpBridgeSessionStorageTest.php
new file mode 100644
index 0000000..958dc0b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/PhpBridgeSessionStorageTest.php
@@ -0,0 +1,96 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests\Session\Storage;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Session\Storage\PhpBridgeSessionStorage;
+use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
+
+/**
+ * Test class for PhpSessionStorage.
+ *
+ * @author Drak <drak@zikula.org>
+ *
+ * These tests require separate processes.
+ *
+ * @runTestsInSeparateProcesses
+ * @preserveGlobalState disabled
+ */
+class PhpBridgeSessionStorageTest extends TestCase
+{
+ private $savePath;
+
+ protected function setUp()
+ {
+ $this->iniSet('session.save_handler', 'files');
+ $this->iniSet('session.save_path', $this->savePath = sys_get_temp_dir().'/sf2test');
+ if (!is_dir($this->savePath)) {
+ mkdir($this->savePath);
+ }
+ }
+
+ protected function tearDown()
+ {
+ session_write_close();
+ array_map('unlink', glob($this->savePath.'/*'));
+ if (is_dir($this->savePath)) {
+ rmdir($this->savePath);
+ }
+
+ $this->savePath = null;
+ }
+
+ /**
+ * @return PhpBridgeSessionStorage
+ */
+ protected function getStorage()
+ {
+ $storage = new PhpBridgeSessionStorage();
+ $storage->registerBag(new AttributeBag());
+
+ return $storage;
+ }
+
+ public function testPhpSession()
+ {
+ $storage = $this->getStorage();
+
+ $this->assertFalse($storage->getSaveHandler()->isActive());
+ $this->assertFalse($storage->isStarted());
+
+ session_start();
+ $this->assertTrue(isset($_SESSION));
+ // in PHP 5.4 we can reliably detect a session started
+ $this->assertTrue($storage->getSaveHandler()->isActive());
+ // PHP session might have started, but the storage driver has not, so false is correct here
+ $this->assertFalse($storage->isStarted());
+
+ $key = $storage->getMetadataBag()->getStorageKey();
+ $this->assertArrayNotHasKey($key, $_SESSION);
+ $storage->start();
+ $this->assertArrayHasKey($key, $_SESSION);
+ }
+
+ public function testClear()
+ {
+ $storage = $this->getStorage();
+ session_start();
+ $_SESSION['drak'] = 'loves symfony';
+ $storage->getBag('attributes')->set('symfony', 'greatness');
+ $key = $storage->getBag('attributes')->getStorageKey();
+ $this->assertEquals($_SESSION[$key], array('symfony' => 'greatness'));
+ $this->assertEquals($_SESSION['drak'], 'loves symfony');
+ $storage->clear();
+ $this->assertEquals($_SESSION[$key], array());
+ $this->assertEquals($_SESSION['drak'], 'loves symfony');
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Proxy/AbstractProxyTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Proxy/AbstractProxyTest.php
new file mode 100644
index 0000000..cbb291f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Proxy/AbstractProxyTest.php
@@ -0,0 +1,113 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Proxy;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy;
+use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;
+
+/**
+ * Test class for AbstractProxy.
+ *
+ * @author Drak <drak@zikula.org>
+ */
+class AbstractProxyTest extends TestCase
+{
+ /**
+ * @var AbstractProxy
+ */
+ protected $proxy;
+
+ protected function setUp()
+ {
+ $this->proxy = $this->getMockForAbstractClass(AbstractProxy::class);
+ }
+
+ protected function tearDown()
+ {
+ $this->proxy = null;
+ }
+
+ public function testGetSaveHandlerName()
+ {
+ $this->assertNull($this->proxy->getSaveHandlerName());
+ }
+
+ public function testIsSessionHandlerInterface()
+ {
+ $this->assertFalse($this->proxy->isSessionHandlerInterface());
+ $sh = new SessionHandlerProxy(new \SessionHandler());
+ $this->assertTrue($sh->isSessionHandlerInterface());
+ }
+
+ public function testIsWrapper()
+ {
+ $this->assertFalse($this->proxy->isWrapper());
+ }
+
+ /**
+ * @runInSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testIsActive()
+ {
+ $this->assertFalse($this->proxy->isActive());
+ session_start();
+ $this->assertTrue($this->proxy->isActive());
+ }
+
+ /**
+ * @runInSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testName()
+ {
+ $this->assertEquals(session_name(), $this->proxy->getName());
+ $this->proxy->setName('foo');
+ $this->assertEquals('foo', $this->proxy->getName());
+ $this->assertEquals(session_name(), $this->proxy->getName());
+ }
+
+ /**
+ * @runInSeparateProcess
+ * @preserveGlobalState disabled
+ * @expectedException \LogicException
+ */
+ public function testNameException()
+ {
+ session_start();
+ $this->proxy->setName('foo');
+ }
+
+ /**
+ * @runInSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testId()
+ {
+ $this->assertEquals(session_id(), $this->proxy->getId());
+ $this->proxy->setId('foo');
+ $this->assertEquals('foo', $this->proxy->getId());
+ $this->assertEquals(session_id(), $this->proxy->getId());
+ }
+
+ /**
+ * @runInSeparateProcess
+ * @preserveGlobalState disabled
+ * @expectedException \LogicException
+ */
+ public function testIdException()
+ {
+ session_start();
+ $this->proxy->setId('foo');
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Proxy/NativeProxyTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Proxy/NativeProxyTest.php
new file mode 100644
index 0000000..ed4fee6
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Proxy/NativeProxyTest.php
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Proxy;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy;
+
+/**
+ * Test class for NativeProxy.
+ *
+ * @group legacy
+ *
+ * @author Drak <drak@zikula.org>
+ */
+class NativeProxyTest extends TestCase
+{
+ public function testIsWrapper()
+ {
+ $proxy = new NativeProxy();
+ $this->assertFalse($proxy->isWrapper());
+ }
+
+ public function testGetSaveHandlerName()
+ {
+ $name = ini_get('session.save_handler');
+ $proxy = new NativeProxy();
+ $this->assertEquals($name, $proxy->getSaveHandlerName());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Proxy/SessionHandlerProxyTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Proxy/SessionHandlerProxyTest.php
new file mode 100644
index 0000000..6828253
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/Session/Storage/Proxy/SessionHandlerProxyTest.php
@@ -0,0 +1,124 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Proxy;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;
+
+/**
+ * Tests for SessionHandlerProxy class.
+ *
+ * @author Drak <drak@zikula.org>
+ *
+ * @runTestsInSeparateProcesses
+ * @preserveGlobalState disabled
+ */
+class SessionHandlerProxyTest extends TestCase
+{
+ /**
+ * @var \PHPUnit_Framework_MockObject_Matcher
+ */
+ private $mock;
+
+ /**
+ * @var SessionHandlerProxy
+ */
+ private $proxy;
+
+ protected function setUp()
+ {
+ $this->mock = $this->getMockBuilder('SessionHandlerInterface')->getMock();
+ $this->proxy = new SessionHandlerProxy($this->mock);
+ }
+
+ protected function tearDown()
+ {
+ $this->mock = null;
+ $this->proxy = null;
+ }
+
+ public function testOpenTrue()
+ {
+ $this->mock->expects($this->once())
+ ->method('open')
+ ->will($this->returnValue(true));
+
+ $this->assertFalse($this->proxy->isActive());
+ $this->proxy->open('name', 'id');
+ $this->assertFalse($this->proxy->isActive());
+ }
+
+ public function testOpenFalse()
+ {
+ $this->mock->expects($this->once())
+ ->method('open')
+ ->will($this->returnValue(false));
+
+ $this->assertFalse($this->proxy->isActive());
+ $this->proxy->open('name', 'id');
+ $this->assertFalse($this->proxy->isActive());
+ }
+
+ public function testClose()
+ {
+ $this->mock->expects($this->once())
+ ->method('close')
+ ->will($this->returnValue(true));
+
+ $this->assertFalse($this->proxy->isActive());
+ $this->proxy->close();
+ $this->assertFalse($this->proxy->isActive());
+ }
+
+ public function testCloseFalse()
+ {
+ $this->mock->expects($this->once())
+ ->method('close')
+ ->will($this->returnValue(false));
+
+ $this->assertFalse($this->proxy->isActive());
+ $this->proxy->close();
+ $this->assertFalse($this->proxy->isActive());
+ }
+
+ public function testRead()
+ {
+ $this->mock->expects($this->once())
+ ->method('read');
+
+ $this->proxy->read('id');
+ }
+
+ public function testWrite()
+ {
+ $this->mock->expects($this->once())
+ ->method('write');
+
+ $this->proxy->write('id', 'data');
+ }
+
+ public function testDestroy()
+ {
+ $this->mock->expects($this->once())
+ ->method('destroy');
+
+ $this->proxy->destroy('id');
+ }
+
+ public function testGc()
+ {
+ $this->mock->expects($this->once())
+ ->method('gc');
+
+ $this->proxy->gc(86400);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/StreamedResponseTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/StreamedResponseTest.php
new file mode 100644
index 0000000..c2ded99
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/StreamedResponseTest.php
@@ -0,0 +1,126 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\StreamedResponse;
+
+class StreamedResponseTest extends TestCase
+{
+ public function testConstructor()
+ {
+ $response = new StreamedResponse(function () { echo 'foo'; }, 404, array('Content-Type' => 'text/plain'));
+
+ $this->assertEquals(404, $response->getStatusCode());
+ $this->assertEquals('text/plain', $response->headers->get('Content-Type'));
+ }
+
+ public function testPrepareWith11Protocol()
+ {
+ $response = new StreamedResponse(function () { echo 'foo'; });
+ $request = Request::create('/');
+ $request->server->set('SERVER_PROTOCOL', 'HTTP/1.1');
+
+ $response->prepare($request);
+
+ $this->assertEquals('1.1', $response->getProtocolVersion());
+ $this->assertNotEquals('chunked', $response->headers->get('Transfer-Encoding'), 'Apache assumes responses with a Transfer-Encoding header set to chunked to already be encoded.');
+ }
+
+ public function testPrepareWith10Protocol()
+ {
+ $response = new StreamedResponse(function () { echo 'foo'; });
+ $request = Request::create('/');
+ $request->server->set('SERVER_PROTOCOL', 'HTTP/1.0');
+
+ $response->prepare($request);
+
+ $this->assertEquals('1.0', $response->getProtocolVersion());
+ $this->assertNull($response->headers->get('Transfer-Encoding'));
+ }
+
+ public function testPrepareWithHeadRequest()
+ {
+ $response = new StreamedResponse(function () { echo 'foo'; }, 200, array('Content-Length' => '123'));
+ $request = Request::create('/', 'HEAD');
+
+ $response->prepare($request);
+
+ $this->assertSame('123', $response->headers->get('Content-Length'));
+ }
+
+ public function testPrepareWithCacheHeaders()
+ {
+ $response = new StreamedResponse(function () { echo 'foo'; }, 200, array('Cache-Control' => 'max-age=600, public'));
+ $request = Request::create('/', 'GET');
+
+ $response->prepare($request);
+ $this->assertEquals('max-age=600, public', $response->headers->get('Cache-Control'));
+ }
+
+ public function testSendContent()
+ {
+ $called = 0;
+
+ $response = new StreamedResponse(function () use (&$called) { ++$called; });
+
+ $response->sendContent();
+ $this->assertEquals(1, $called);
+
+ $response->sendContent();
+ $this->assertEquals(1, $called);
+ }
+
+ /**
+ * @expectedException \LogicException
+ */
+ public function testSendContentWithNonCallable()
+ {
+ $response = new StreamedResponse(null);
+ $response->sendContent();
+ }
+
+ /**
+ * @expectedException \LogicException
+ */
+ public function testSetContent()
+ {
+ $response = new StreamedResponse(function () { echo 'foo'; });
+ $response->setContent('foo');
+ }
+
+ public function testGetContent()
+ {
+ $response = new StreamedResponse(function () { echo 'foo'; });
+ $this->assertFalse($response->getContent());
+ }
+
+ public function testCreate()
+ {
+ $response = StreamedResponse::create(function () {}, 204);
+
+ $this->assertInstanceOf('Symfony\Component\HttpFoundation\StreamedResponse', $response);
+ $this->assertEquals(204, $response->getStatusCode());
+ }
+
+ public function testReturnThis()
+ {
+ $response = new StreamedResponse(function () {});
+ $this->assertInstanceOf('Symfony\Component\HttpFoundation\StreamedResponse', $response->sendContent());
+ $this->assertInstanceOf('Symfony\Component\HttpFoundation\StreamedResponse', $response->sendContent());
+
+ $response = new StreamedResponse(function () {});
+ $this->assertInstanceOf('Symfony\Component\HttpFoundation\StreamedResponse', $response->sendHeaders());
+ $this->assertInstanceOf('Symfony\Component\HttpFoundation\StreamedResponse', $response->sendHeaders());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/schema/http-status-codes.rng b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/schema/http-status-codes.rng
new file mode 100644
index 0000000..73708ca
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/schema/http-status-codes.rng
@@ -0,0 +1,31 @@
+<?xml version='1.0'?>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0"
+ datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
+ ns="http://www.iana.org/assignments">
+
+ <include href="iana-registry.rng"/>
+
+ <start>
+ <element name="registry">
+ <ref name="registryMeta"/>
+ <element name="registry">
+ <ref name="registryMeta"/>
+ <zeroOrMore>
+ <element name="record">
+ <optional>
+ <attribute name="date"><ref name="genericDate"/></attribute>
+ </optional>
+ <optional>
+ <attribute name="updated"><ref name="genericDate"/></attribute>
+ </optional>
+ <element name="value"><ref name="genericRange"/></element>
+ <element name="description"><text/></element>
+ <ref name="references"/>
+ </element>
+ </zeroOrMore>
+ </element>
+ <ref name="people"/>
+ </element>
+ </start>
+
+</grammar>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/schema/iana-registry.rng b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/schema/iana-registry.rng
new file mode 100644
index 0000000..b9c3ca9
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/Tests/schema/iana-registry.rng
@@ -0,0 +1,198 @@
+<?xml version='1.0'?>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0"
+ datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
+ ns="http://www.iana.org/assignments">
+
+ <define name="registryMeta">
+ <interleave>
+ <attribute name="id"><data type="ID"/></attribute>
+ <optional><element name="title"><ref name="text_with_references"/></element></optional>
+ <optional><element name="created"><ref name="genericDate"/></element></optional>
+ <optional><element name="updated"><data type="date"/></element></optional>
+ <optional><element name="registration_rule"><ref
+ name="text_with_references"/></element></optional>
+ <optional><element name="expert"><text/></element></optional>
+ <optional><element name="description"><ref name="text_with_references"/></element></optional>
+ <zeroOrMore><element name="note"><ref name="text_with_references"/></element></zeroOrMore>
+ <ref name="references"/>
+ <optional><element name="hide"><empty/></element></optional>
+ <zeroOrMore><element name="category"><text/></element></zeroOrMore>
+ <zeroOrMore><ref name="range"/></zeroOrMore>
+ <optional><ref name="file"/></optional>
+ </interleave>
+ </define>
+
+ <define name="range">
+ <element name="range">
+ <interleave>
+ <element name="value"><text/></element>
+ <optional><element name="hex"><text/></element></optional>
+ <element name="registration_rule"><ref name="text_with_references"/></element>
+ <optional><element name="note"><ref name="text_with_references"/></element></optional>
+ <optional><ref name="xref"/></optional>
+ </interleave>
+ </element>
+ </define>
+
+ <define name="people">
+ <element name="people">
+ <zeroOrMore>
+ <element name="person">
+ <attribute name="id"><data type="ID"/></attribute>
+ <optional><element name="name"><text/></element></optional>
+ <optional><element name="org"><text/></element></optional>
+ <zeroOrMore><element name="uri"><data type="anyURI"/></element></zeroOrMore>
+ <optional><element name="updated"><ref name="genericDate"/></element></optional>
+ </element>
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="xref">
+ <element name="xref">
+ <optional>
+ <attribute name="lastupdated"><ref name="genericDate"/></attribute>
+ </optional>
+ <choice>
+ <group>
+ <attribute name="type"><value>uri</value></attribute>
+ <attribute name="data"><data type="anyURI"/></attribute>
+ </group>
+ <group>
+ <attribute name="type"><value>rfc</value></attribute>
+ <attribute name="data">
+ <data type="string">
+ <param name="pattern">(rfc|bcp|std)\d+</param>
+ </data>
+ </attribute>
+ </group>
+ <group>
+ <attribute name="type"><value>rfc-errata</value></attribute>
+ <attribute name="data"><data type="positiveInteger"/></attribute>
+ </group>
+ <group>
+ <attribute name="type"><value>draft</value></attribute>
+ <attribute name="data">
+ <data type="string">
+ <param name="pattern">(draft|RFC)(-[a-zA-Z0-9]+)+</param>
+ </data>
+ </attribute>
+ </group>
+ <group>
+ <attribute name="type"><value>registry</value></attribute>
+ <attribute name="data"><data type="NCName"/></attribute>
+ </group>
+ <group>
+ <attribute name="type"><value>person</value></attribute>
+ <attribute name="data"><data type="NCName"/></attribute>
+ </group>
+ <group>
+ <attribute name="type"><value>text</value></attribute>
+ </group>
+ <group>
+ <attribute name="type"><value>note</value></attribute>
+ <attribute name="data"><data type="positiveInteger"/></attribute>
+ </group>
+ <group>
+ <attribute name="type"><value>unicode</value></attribute>
+ <attribute name="data">
+ <data type="string">
+ <param name="pattern">ucd\d+\.\d+\.\d+</param>
+ </data>
+ </attribute>
+ </group>
+ </choice>
+ <text/>
+ </element>
+ </define>
+
+ <define name="references">
+ <zeroOrMore>
+ <ref name="xref"/>
+ </zeroOrMore>
+ </define>
+
+ <define name="text_with_references">
+ <interleave>
+ <zeroOrMore>
+ <text/>
+ <optional><ref name="xref"/></optional>
+ </zeroOrMore>
+ </interleave>
+ </define>
+
+ <define name="richText">
+ <zeroOrMore>
+ <choice>
+ <interleave>
+ <ref name="text_with_references"/>
+ <optional><element name="br"><empty/></element></optional>
+ </interleave>
+ <element name="paragraph">
+ <interleave>
+ <ref name="text_with_references"/>
+ <optional><element name="br"><empty/></element></optional>
+ </interleave>
+ </element>
+ <element name="artwork"><text/></element>
+ </choice>
+ </zeroOrMore>
+ </define>
+
+ <define name="genericRange">
+ <data type="string">
+ <param name="pattern">(\d+|0x[\da-fA-F]+)(\s*-\s*(\d+|0x[\da-fA-F]+))?</param>
+ </data>
+ </define>
+
+ <define name="genericDate">
+ <choice>
+ <data type="date"/>
+ <data type="gYearMonth"/>
+ </choice>
+ </define>
+
+ <define name="hex32">
+ <data type="string">
+ <param name="pattern">0x[0-9]{8}</param>
+ </data>
+ </define>
+
+ <define name="binary">
+ <data type="string">
+ <param name="pattern">[0-1]+</param>
+ </data>
+ </define>
+
+ <define name="footnotes">
+ <zeroOrMore>
+ <element name="footnote">
+ <attribute name="anchor"><data type="positiveInteger"/></attribute>
+ <interleave>
+ <zeroOrMore>
+ <text/>
+ <optional><ref name="xref"/></optional>
+ </zeroOrMore>
+ </interleave>
+ </element>
+ </zeroOrMore>
+ </define>
+
+ <define name="file">
+ <element name="file">
+ <attribute name="type">
+ <choice>
+ <value>legacy</value>
+ <value>mib</value>
+ <value>template</value>
+ <value>json</value>
+ </choice>
+ </attribute>
+ <optional>
+ <attribute name="name"/>
+ </optional>
+ <data type="anyURI"/>
+ </element>
+ </define>
+
+</grammar>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/composer.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/composer.json
new file mode 100644
index 0000000..f6c6f2e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/composer.json
@@ -0,0 +1,38 @@
+{
+ "name": "symfony/http-foundation",
+ "type": "library",
+ "description": "Symfony HttpFoundation Component",
+ "keywords": [],
+ "homepage": "https://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": "^5.5.9|>=7.0.8",
+ "symfony/polyfill-mbstring": "~1.1",
+ "symfony/polyfill-php70": "~1.6"
+ },
+ "require-dev": {
+ "symfony/expression-language": "~2.8|~3.0|~4.0"
+ },
+ "autoload": {
+ "psr-4": { "Symfony\\Component\\HttpFoundation\\": "" },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.4-dev"
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/phpunit.xml.dist b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/phpunit.xml.dist
new file mode 100644
index 0000000..c1d61f8
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/http-foundation/phpunit.xml.dist
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
+ backupGlobals="false"
+ colors="true"
+ bootstrap="vendor/autoload.php"
+ failOnRisky="true"
+ failOnWarning="true"
+>
+ <php>
+ <ini name="error_reporting" value="-1" />
+ </php>
+
+ <testsuites>
+ <testsuite name="Symfony HttpFoundation Component Test Suite">
+ <directory>./Tests/</directory>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist>
+ <directory>./</directory>
+ <exclude>
+ <directory>./Resources</directory>
+ <directory>./Tests</directory>
+ <directory>./vendor</directory>
+ </exclude>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-mbstring/LICENSE b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-mbstring/LICENSE
new file mode 100644
index 0000000..24fa32c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-mbstring/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2015-2018 Fabien Potencier
+
+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.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-mbstring/Mbstring.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-mbstring/Mbstring.php
new file mode 100644
index 0000000..67cf9ab
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-mbstring/Mbstring.php
@@ -0,0 +1,791 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Polyfill\Mbstring;
+
+/**
+ * Partial mbstring implementation in PHP, iconv based, UTF-8 centric.
+ *
+ * Implemented:
+ * - mb_chr - Returns a specific character from its Unicode code point
+ * - mb_convert_encoding - Convert character encoding
+ * - mb_convert_variables - Convert character code in variable(s)
+ * - mb_decode_mimeheader - Decode string in MIME header field
+ * - mb_encode_mimeheader - Encode string for MIME header XXX NATIVE IMPLEMENTATION IS REALLY BUGGED
+ * - mb_decode_numericentity - Decode HTML numeric string reference to character
+ * - mb_encode_numericentity - Encode character to HTML numeric string reference
+ * - mb_convert_case - Perform case folding on a string
+ * - mb_detect_encoding - Detect character encoding
+ * - mb_get_info - Get internal settings of mbstring
+ * - mb_http_input - Detect HTTP input character encoding
+ * - mb_http_output - Set/Get HTTP output character encoding
+ * - mb_internal_encoding - Set/Get internal character encoding
+ * - mb_list_encodings - Returns an array of all supported encodings
+ * - mb_ord - Returns the Unicode code point of a character
+ * - mb_output_handler - Callback function converts character encoding in output buffer
+ * - mb_scrub - Replaces ill-formed byte sequences with substitute characters
+ * - mb_strlen - Get string length
+ * - mb_strpos - Find position of first occurrence of string in a string
+ * - mb_strrpos - Find position of last occurrence of a string in a string
+ * - mb_strtolower - Make a string lowercase
+ * - mb_strtoupper - Make a string uppercase
+ * - mb_substitute_character - Set/Get substitution character
+ * - mb_substr - Get part of string
+ * - mb_stripos - Finds position of first occurrence of a string within another, case insensitive
+ * - mb_stristr - Finds first occurrence of a string within another, case insensitive
+ * - mb_strrchr - Finds the last occurrence of a character in a string within another
+ * - mb_strrichr - Finds the last occurrence of a character in a string within another, case insensitive
+ * - mb_strripos - Finds position of last occurrence of a string within another, case insensitive
+ * - mb_strstr - Finds first occurrence of a string within anothers
+ * - mb_strwidth - Return width of string
+ * - mb_substr_count - Count the number of substring occurrences
+ *
+ * Not implemented:
+ * - mb_convert_kana - Convert "kana" one from another ("zen-kaku", "han-kaku" and more)
+ * - mb_ereg_* - Regular expression with multibyte support
+ * - mb_parse_str - Parse GET/POST/COOKIE data and set global variable
+ * - mb_preferred_mime_name - Get MIME charset string
+ * - mb_regex_encoding - Returns current encoding for multibyte regex as string
+ * - mb_regex_set_options - Set/Get the default options for mbregex functions
+ * - mb_send_mail - Send encoded mail
+ * - mb_split - Split multibyte string using regular expression
+ * - mb_strcut - Get part of string
+ * - mb_strimwidth - Get truncated string with specified width
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ *
+ * @internal
+ */
+final class Mbstring
+{
+ const MB_CASE_FOLD = PHP_INT_MAX;
+
+ private static $encodingList = array('ASCII', 'UTF-8');
+ private static $language = 'neutral';
+ private static $internalEncoding = 'UTF-8';
+ private static $caseFold = array(
+ array('µ','ſ',"\xCD\x85",'ς',"\xCF\x90","\xCF\x91","\xCF\x95","\xCF\x96","\xCF\xB0","\xCF\xB1","\xCF\xB5","\xE1\xBA\x9B","\xE1\xBE\xBE"),
+ array('μ','s','ι', 'σ','β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', "\xE1\xB9\xA1",'ι'),
+ );
+
+ public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null)
+ {
+ if (is_array($fromEncoding) || false !== strpos($fromEncoding, ',')) {
+ $fromEncoding = self::mb_detect_encoding($s, $fromEncoding);
+ } else {
+ $fromEncoding = self::getEncoding($fromEncoding);
+ }
+
+ $toEncoding = self::getEncoding($toEncoding);
+
+ if ('BASE64' === $fromEncoding) {
+ $s = base64_decode($s);
+ $fromEncoding = $toEncoding;
+ }
+
+ if ('BASE64' === $toEncoding) {
+ return base64_encode($s);
+ }
+
+ if ('HTML-ENTITIES' === $toEncoding || 'HTML' === $toEncoding) {
+ if ('HTML-ENTITIES' === $fromEncoding || 'HTML' === $fromEncoding) {
+ $fromEncoding = 'Windows-1252';
+ }
+ if ('UTF-8' !== $fromEncoding) {
+ $s = iconv($fromEncoding, 'UTF-8//IGNORE', $s);
+ }
+
+ return preg_replace_callback('/[\x80-\xFF]+/', array(__CLASS__, 'html_encoding_callback'), $s);
+ }
+
+ if ('HTML-ENTITIES' === $fromEncoding) {
+ $s = html_entity_decode($s, ENT_COMPAT, 'UTF-8');
+ $fromEncoding = 'UTF-8';
+ }
+
+ return iconv($fromEncoding, $toEncoding.'//IGNORE', $s);
+ }
+
+ public static function mb_convert_variables($toEncoding, $fromEncoding, &$a = null, &$b = null, &$c = null, &$d = null, &$e = null, &$f = null)
+ {
+ $vars = array(&$a, &$b, &$c, &$d, &$e, &$f);
+
+ $ok = true;
+ array_walk_recursive($vars, function (&$v) use (&$ok, $toEncoding, $fromEncoding) {
+ if (false === $v = Mbstring::mb_convert_encoding($v, $toEncoding, $fromEncoding)) {
+ $ok = false;
+ }
+ });
+
+ return $ok ? $fromEncoding : false;
+ }
+
+ public static function mb_decode_mimeheader($s)
+ {
+ return iconv_mime_decode($s, 2, self::$internalEncoding);
+ }
+
+ public static function mb_encode_mimeheader($s, $charset = null, $transferEncoding = null, $linefeed = null, $indent = null)
+ {
+ trigger_error('mb_encode_mimeheader() is bugged. Please use iconv_mime_encode() instead', E_USER_WARNING);
+ }
+
+ public static function mb_decode_numericentity($s, $convmap, $encoding = null)
+ {
+ if (null !== $s && !is_scalar($s) && !(is_object($s) && method_exists($s, '__toString'))) {
+ trigger_error('mb_decode_numericentity() expects parameter 1 to be string, '.gettype($s).' given', E_USER_WARNING);
+ return null;
+ }
+
+ if (!is_array($convmap) || !$convmap) {
+ return false;
+ }
+
+ if (null !== $encoding && !is_scalar($encoding)) {
+ trigger_error('mb_decode_numericentity() expects parameter 3 to be string, '.gettype($s).' given', E_USER_WARNING);
+ return ''; // Instead of null (cf. mb_encode_numericentity).
+ }
+
+ $s = (string) $s;
+ if ('' === $s) {
+ return '';
+ }
+
+ $encoding = self::getEncoding($encoding);
+
+ if ('UTF-8' === $encoding) {
+ $encoding = null;
+ if (!preg_match('//u', $s)) {
+ $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s);
+ }
+ } else {
+ $s = iconv($encoding, 'UTF-8//IGNORE', $s);
+ }
+
+ $cnt = floor(count($convmap) / 4) * 4;
+
+ for ($i = 0; $i < $cnt; $i += 4) {
+ // collector_decode_htmlnumericentity ignores $convmap[$i + 3]
+ $convmap[$i] += $convmap[$i + 2];
+ $convmap[$i + 1] += $convmap[$i + 2];
+ }
+
+ $s = preg_replace_callback('/&#(?:0*([0-9]+)|x0*([0-9a-fA-F]+))(?!&);?/', function (array $m) use ($cnt, $convmap) {
+ $c = isset($m[2]) ? (int) hexdec($m[2]) : $m[1];
+ for ($i = 0; $i < $cnt; $i += 4) {
+ if ($c >= $convmap[$i] && $c <= $convmap[$i + 1]) {
+ return Mbstring::mb_chr($c - $convmap[$i + 2]);
+ }
+ }
+ return $m[0];
+ }, $s);
+
+ if (null === $encoding) {
+ return $s;
+ }
+
+ return iconv('UTF-8', $encoding.'//IGNORE', $s);
+ }
+
+ public static function mb_encode_numericentity($s, $convmap, $encoding = null, $is_hex = false)
+ {
+ if (null !== $s && !is_scalar($s) && !(is_object($s) && method_exists($s, '__toString'))) {
+ trigger_error('mb_encode_numericentity() expects parameter 1 to be string, '.gettype($s).' given', E_USER_WARNING);
+ return null;
+ }
+
+ if (!is_array($convmap) || !$convmap) {
+ return false;
+ }
+
+ if (null !== $encoding && !is_scalar($encoding)) {
+ trigger_error('mb_encode_numericentity() expects parameter 3 to be string, '.gettype($s).' given', E_USER_WARNING);
+ return null; // Instead of '' (cf. mb_decode_numericentity).
+ }
+
+ if (null !== $is_hex && !is_scalar($is_hex)) {
+ trigger_error('mb_encode_numericentity() expects parameter 4 to be boolean, '.gettype($s).' given', E_USER_WARNING);
+ return null;
+ }
+
+ $s = (string) $s;
+ if ('' === $s) {
+ return '';
+ }
+
+ $encoding = self::getEncoding($encoding);
+
+ if ('UTF-8' === $encoding) {
+ $encoding = null;
+ if (!preg_match('//u', $s)) {
+ $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s);
+ }
+ } else {
+ $s = iconv($encoding, 'UTF-8//IGNORE', $s);
+ }
+
+ static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4);
+
+ $cnt = floor(count($convmap) / 4) * 4;
+ $i = 0;
+ $len = strlen($s);
+ $result = '';
+
+ while ($i < $len) {
+ $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"];
+ $uchr = substr($s, $i, $ulen);
+ $i += $ulen;
+ $c = self::mb_ord($uchr);
+
+ for ($j = 0; $j < $cnt; $j += 4) {
+ if ($c >= $convmap[$j] && $c <= $convmap[$j + 1]) {
+ $cOffset = ($c + $convmap[$j + 2]) & $convmap[$j + 3];
+ $result .= $is_hex ? sprintf('&#x%X;', $cOffset) : '&#'.$cOffset.';';
+ continue 2;
+ }
+ }
+ $result .= $uchr;
+ }
+
+ if (null === $encoding) {
+ return $result;
+ }
+
+ return iconv('UTF-8', $encoding.'//IGNORE', $result);
+ }
+
+ public static function mb_convert_case($s, $mode, $encoding = null)
+ {
+ $s = (string) $s;
+ if ('' === $s) {
+ return '';
+ }
+
+ $encoding = self::getEncoding($encoding);
+
+ if ('UTF-8' === $encoding) {
+ $encoding = null;
+ if (!preg_match('//u', $s)) {
+ $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s);
+ }
+ } else {
+ $s = iconv($encoding, 'UTF-8//IGNORE', $s);
+ }
+
+ if (MB_CASE_TITLE == $mode) {
+ $s = preg_replace_callback('/\b\p{Ll}/u', array(__CLASS__, 'title_case_upper'), $s);
+ $s = preg_replace_callback('/\B[\p{Lu}\p{Lt}]+/u', array(__CLASS__, 'title_case_lower'), $s);
+ } else {
+ if (MB_CASE_UPPER == $mode) {
+ static $upper = null;
+ if (null === $upper) {
+ $upper = self::getData('upperCase');
+ }
+ $map = $upper;
+ } else {
+ if (self::MB_CASE_FOLD === $mode) {
+ $s = str_replace(self::$caseFold[0], self::$caseFold[1], $s);
+ }
+
+ static $lower = null;
+ if (null === $lower) {
+ $lower = self::getData('lowerCase');
+ }
+ $map = $lower;
+ }
+
+ static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4);
+
+ $i = 0;
+ $len = strlen($s);
+
+ while ($i < $len) {
+ $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"];
+ $uchr = substr($s, $i, $ulen);
+ $i += $ulen;
+
+ if (isset($map[$uchr])) {
+ $uchr = $map[$uchr];
+ $nlen = strlen($uchr);
+
+ if ($nlen == $ulen) {
+ $nlen = $i;
+ do {
+ $s[--$nlen] = $uchr[--$ulen];
+ } while ($ulen);
+ } else {
+ $s = substr_replace($s, $uchr, $i - $ulen, $ulen);
+ $len += $nlen - $ulen;
+ $i += $nlen - $ulen;
+ }
+ }
+ }
+ }
+
+ if (null === $encoding) {
+ return $s;
+ }
+
+ return iconv('UTF-8', $encoding.'//IGNORE', $s);
+ }
+
+ public static function mb_internal_encoding($encoding = null)
+ {
+ if (null === $encoding) {
+ return self::$internalEncoding;
+ }
+
+ $encoding = self::getEncoding($encoding);
+
+ if ('UTF-8' === $encoding || false !== @iconv($encoding, $encoding, ' ')) {
+ self::$internalEncoding = $encoding;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ public static function mb_language($lang = null)
+ {
+ if (null === $lang) {
+ return self::$language;
+ }
+
+ switch ($lang = strtolower($lang)) {
+ case 'uni':
+ case 'neutral':
+ self::$language = $lang;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ public static function mb_list_encodings()
+ {
+ return array('UTF-8');
+ }
+
+ public static function mb_encoding_aliases($encoding)
+ {
+ switch (strtoupper($encoding)) {
+ case 'UTF8':
+ case 'UTF-8':
+ return array('utf8');
+ }
+
+ return false;
+ }
+
+ public static function mb_check_encoding($var = null, $encoding = null)
+ {
+ if (null === $encoding) {
+ if (null === $var) {
+ return false;
+ }
+ $encoding = self::$internalEncoding;
+ }
+
+ return self::mb_detect_encoding($var, array($encoding)) || false !== @iconv($encoding, $encoding, $var);
+ }
+
+ public static function mb_detect_encoding($str, $encodingList = null, $strict = false)
+ {
+ if (null === $encodingList) {
+ $encodingList = self::$encodingList;
+ } else {
+ if (!is_array($encodingList)) {
+ $encodingList = array_map('trim', explode(',', $encodingList));
+ }
+ $encodingList = array_map('strtoupper', $encodingList);
+ }
+
+ foreach ($encodingList as $enc) {
+ switch ($enc) {
+ case 'ASCII':
+ if (!preg_match('/[\x80-\xFF]/', $str)) {
+ return $enc;
+ }
+ break;
+
+ case 'UTF8':
+ case 'UTF-8':
+ if (preg_match('//u', $str)) {
+ return 'UTF-8';
+ }
+ break;
+
+ default:
+ if (0 === strncmp($enc, 'ISO-8859-', 9)) {
+ return $enc;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public static function mb_detect_order($encodingList = null)
+ {
+ if (null === $encodingList) {
+ return self::$encodingList;
+ }
+
+ if (!is_array($encodingList)) {
+ $encodingList = array_map('trim', explode(',', $encodingList));
+ }
+ $encodingList = array_map('strtoupper', $encodingList);
+
+ foreach ($encodingList as $enc) {
+ switch ($enc) {
+ default:
+ if (strncmp($enc, 'ISO-8859-', 9)) {
+ return false;
+ }
+ case 'ASCII':
+ case 'UTF8':
+ case 'UTF-8':
+ }
+ }
+
+ self::$encodingList = $encodingList;
+
+ return true;
+ }
+
+ public static function mb_strlen($s, $encoding = null)
+ {
+ $encoding = self::getEncoding($encoding);
+ if ('CP850' === $encoding || 'ASCII' === $encoding) {
+ return strlen($s);
+ }
+
+ return @iconv_strlen($s, $encoding);
+ }
+
+ public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null)
+ {
+ $encoding = self::getEncoding($encoding);
+ if ('CP850' === $encoding || 'ASCII' === $encoding) {
+ return strpos($haystack, $needle, $offset);
+ }
+
+ $needle = (string) $needle;
+ if ('' === $needle) {
+ trigger_error(__METHOD__.': Empty delimiter', E_USER_WARNING);
+
+ return false;
+ }
+
+ return iconv_strpos($haystack, $needle, $offset, $encoding);
+ }
+
+ public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null)
+ {
+ $encoding = self::getEncoding($encoding);
+ if ('CP850' === $encoding || 'ASCII' === $encoding) {
+ return strrpos($haystack, $needle, $offset);
+ }
+
+ if ($offset != (int) $offset) {
+ $offset = 0;
+ } elseif ($offset = (int) $offset) {
+ if ($offset < 0) {
+ $haystack = self::mb_substr($haystack, 0, $offset, $encoding);
+ $offset = 0;
+ } else {
+ $haystack = self::mb_substr($haystack, $offset, 2147483647, $encoding);
+ }
+ }
+
+ $pos = iconv_strrpos($haystack, $needle, $encoding);
+
+ return false !== $pos ? $offset + $pos : false;
+ }
+
+ public static function mb_strtolower($s, $encoding = null)
+ {
+ return self::mb_convert_case($s, MB_CASE_LOWER, $encoding);
+ }
+
+ public static function mb_strtoupper($s, $encoding = null)
+ {
+ return self::mb_convert_case($s, MB_CASE_UPPER, $encoding);
+ }
+
+ public static function mb_substitute_character($c = null)
+ {
+ if (0 === strcasecmp($c, 'none')) {
+ return true;
+ }
+
+ return null !== $c ? false : 'none';
+ }
+
+ public static function mb_substr($s, $start, $length = null, $encoding = null)
+ {
+ $encoding = self::getEncoding($encoding);
+ if ('CP850' === $encoding || 'ASCII' === $encoding) {
+ return substr($s, $start, null === $length ? 2147483647 : $length);
+ }
+
+ if ($start < 0) {
+ $start = iconv_strlen($s, $encoding) + $start;
+ if ($start < 0) {
+ $start = 0;
+ }
+ }
+
+ if (null === $length) {
+ $length = 2147483647;
+ } elseif ($length < 0) {
+ $length = iconv_strlen($s, $encoding) + $length - $start;
+ if ($length < 0) {
+ return '';
+ }
+ }
+
+ return (string) iconv_substr($s, $start, $length, $encoding);
+ }
+
+ public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = null)
+ {
+ $haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding);
+ $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding);
+
+ return self::mb_strpos($haystack, $needle, $offset, $encoding);
+ }
+
+ public static function mb_stristr($haystack, $needle, $part = false, $encoding = null)
+ {
+ $pos = self::mb_stripos($haystack, $needle, 0, $encoding);
+
+ return self::getSubpart($pos, $part, $haystack, $encoding);
+ }
+
+ public static function mb_strrchr($haystack, $needle, $part = false, $encoding = null)
+ {
+ $encoding = self::getEncoding($encoding);
+ if ('CP850' === $encoding || 'ASCII' === $encoding) {
+ return strrchr($haystack, $needle, $part);
+ }
+ $needle = self::mb_substr($needle, 0, 1, $encoding);
+ $pos = iconv_strrpos($haystack, $needle, $encoding);
+
+ return self::getSubpart($pos, $part, $haystack, $encoding);
+ }
+
+ public static function mb_strrichr($haystack, $needle, $part = false, $encoding = null)
+ {
+ $needle = self::mb_substr($needle, 0, 1, $encoding);
+ $pos = self::mb_strripos($haystack, $needle, $encoding);
+
+ return self::getSubpart($pos, $part, $haystack, $encoding);
+ }
+
+ public static function mb_strripos($haystack, $needle, $offset = 0, $encoding = null)
+ {
+ $haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding);
+ $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding);
+
+ return self::mb_strrpos($haystack, $needle, $offset, $encoding);
+ }
+
+ public static function mb_strstr($haystack, $needle, $part = false, $encoding = null)
+ {
+ $pos = strpos($haystack, $needle);
+ if (false === $pos) {
+ return false;
+ }
+ if ($part) {
+ return substr($haystack, 0, $pos);
+ }
+
+ return substr($haystack, $pos);
+ }
+
+ public static function mb_get_info($type = 'all')
+ {
+ $info = array(
+ 'internal_encoding' => self::$internalEncoding,
+ 'http_output' => 'pass',
+ 'http_output_conv_mimetypes' => '^(text/|application/xhtml\+xml)',
+ 'func_overload' => 0,
+ 'func_overload_list' => 'no overload',
+ 'mail_charset' => 'UTF-8',
+ 'mail_header_encoding' => 'BASE64',
+ 'mail_body_encoding' => 'BASE64',
+ 'illegal_chars' => 0,
+ 'encoding_translation' => 'Off',
+ 'language' => self::$language,
+ 'detect_order' => self::$encodingList,
+ 'substitute_character' => 'none',
+ 'strict_detection' => 'Off',
+ );
+
+ if ('all' === $type) {
+ return $info;
+ }
+ if (isset($info[$type])) {
+ return $info[$type];
+ }
+
+ return false;
+ }
+
+ public static function mb_http_input($type = '')
+ {
+ return false;
+ }
+
+ public static function mb_http_output($encoding = null)
+ {
+ return null !== $encoding ? 'pass' === $encoding : 'pass';
+ }
+
+ public static function mb_strwidth($s, $encoding = null)
+ {
+ $encoding = self::getEncoding($encoding);
+
+ if ('UTF-8' !== $encoding) {
+ $s = iconv($encoding, 'UTF-8//IGNORE', $s);
+ }
+
+ $s = preg_replace('/[\x{1100}-\x{115F}\x{2329}\x{232A}\x{2E80}-\x{303E}\x{3040}-\x{A4CF}\x{AC00}-\x{D7A3}\x{F900}-\x{FAFF}\x{FE10}-\x{FE19}\x{FE30}-\x{FE6F}\x{FF00}-\x{FF60}\x{FFE0}-\x{FFE6}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}]/u', '', $s, -1, $wide);
+
+ return ($wide << 1) + iconv_strlen($s, 'UTF-8');
+ }
+
+ public static function mb_substr_count($haystack, $needle, $encoding = null)
+ {
+ return substr_count($haystack, $needle);
+ }
+
+ public static function mb_output_handler($contents, $status)
+ {
+ return $contents;
+ }
+
+ public static function mb_chr($code, $encoding = null)
+ {
+ if (0x80 > $code %= 0x200000) {
+ $s = chr($code);
+ } elseif (0x800 > $code) {
+ $s = chr(0xC0 | $code >> 6).chr(0x80 | $code & 0x3F);
+ } elseif (0x10000 > $code) {
+ $s = chr(0xE0 | $code >> 12).chr(0x80 | $code >> 6 & 0x3F).chr(0x80 | $code & 0x3F);
+ } else {
+ $s = chr(0xF0 | $code >> 18).chr(0x80 | $code >> 12 & 0x3F).chr(0x80 | $code >> 6 & 0x3F).chr(0x80 | $code & 0x3F);
+ }
+
+ if ('UTF-8' !== $encoding = self::getEncoding($encoding)) {
+ $s = mb_convert_encoding($s, $encoding, 'UTF-8');
+ }
+
+ return $s;
+ }
+
+ public static function mb_ord($s, $encoding = null)
+ {
+ if ('UTF-8' !== $encoding = self::getEncoding($encoding)) {
+ $s = mb_convert_encoding($s, 'UTF-8', $encoding);
+ }
+
+ $code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0;
+ if (0xF0 <= $code) {
+ return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80;
+ }
+ if (0xE0 <= $code) {
+ return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80;
+ }
+ if (0xC0 <= $code) {
+ return (($code - 0xC0) << 6) + $s[2] - 0x80;
+ }
+
+ return $code;
+ }
+
+ private static function getSubpart($pos, $part, $haystack, $encoding)
+ {
+ if (false === $pos) {
+ return false;
+ }
+ if ($part) {
+ return self::mb_substr($haystack, 0, $pos, $encoding);
+ }
+
+ return self::mb_substr($haystack, $pos, null, $encoding);
+ }
+
+ private static function html_encoding_callback(array $m)
+ {
+ $i = 1;
+ $entities = '';
+ $m = unpack('C*', htmlentities($m[0], ENT_COMPAT, 'UTF-8'));
+
+ while (isset($m[$i])) {
+ if (0x80 > $m[$i]) {
+ $entities .= chr($m[$i++]);
+ continue;
+ }
+ if (0xF0 <= $m[$i]) {
+ $c = (($m[$i++] - 0xF0) << 18) + (($m[$i++] - 0x80) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
+ } elseif (0xE0 <= $m[$i]) {
+ $c = (($m[$i++] - 0xE0) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
+ } else {
+ $c = (($m[$i++] - 0xC0) << 6) + $m[$i++] - 0x80;
+ }
+
+ $entities .= '&#'.$c.';';
+ }
+
+ return $entities;
+ }
+
+ private static function title_case_lower(array $s)
+ {
+ return self::mb_convert_case($s[0], MB_CASE_LOWER, 'UTF-8');
+ }
+
+ private static function title_case_upper(array $s)
+ {
+ return self::mb_convert_case($s[0], MB_CASE_UPPER, 'UTF-8');
+ }
+
+ private static function getData($file)
+ {
+ if (file_exists($file = __DIR__.'/Resources/unidata/'.$file.'.php')) {
+ return require $file;
+ }
+
+ return false;
+ }
+
+ private static function getEncoding($encoding)
+ {
+ if (null === $encoding) {
+ return self::$internalEncoding;
+ }
+
+ $encoding = strtoupper($encoding);
+
+ if ('8BIT' === $encoding || 'BINARY' === $encoding) {
+ return 'CP850';
+ }
+ if ('UTF8' === $encoding) {
+ return 'UTF-8';
+ }
+
+ return $encoding;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-mbstring/README.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-mbstring/README.md
new file mode 100644
index 0000000..342e828
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-mbstring/README.md
@@ -0,0 +1,13 @@
+Symfony Polyfill / Mbstring
+===========================
+
+This component provides a partial, native PHP implementation for the
+[Mbstring](http://php.net/mbstring) extension.
+
+More information can be found in the
+[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md).
+
+License
+=======
+
+This library is released under the [MIT license](LICENSE).
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php
new file mode 100644
index 0000000..3ca1641
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php
@@ -0,0 +1,1101 @@
+<?php
+
+static $data = array (
+ 'A' => 'a',
+ 'B' => 'b',
+ 'C' => 'c',
+ 'D' => 'd',
+ 'E' => 'e',
+ 'F' => 'f',
+ 'G' => 'g',
+ 'H' => 'h',
+ 'I' => 'i',
+ 'J' => 'j',
+ 'K' => 'k',
+ 'L' => 'l',
+ 'M' => 'm',
+ 'N' => 'n',
+ 'O' => 'o',
+ 'P' => 'p',
+ 'Q' => 'q',
+ 'R' => 'r',
+ 'S' => 's',
+ 'T' => 't',
+ 'U' => 'u',
+ 'V' => 'v',
+ 'W' => 'w',
+ 'X' => 'x',
+ 'Y' => 'y',
+ 'Z' => 'z',
+ 'À' => 'à',
+ 'Á' => 'á',
+ 'Â' => 'â',
+ 'Ã' => 'ã',
+ 'Ä' => 'ä',
+ 'Å' => 'å',
+ 'Æ' => 'æ',
+ 'Ç' => 'ç',
+ 'È' => 'è',
+ 'É' => 'é',
+ 'Ê' => 'ê',
+ 'Ë' => 'ë',
+ 'Ì' => 'ì',
+ 'Í' => 'í',
+ 'Î' => 'î',
+ 'Ï' => 'ï',
+ 'Ð' => 'ð',
+ 'Ñ' => 'ñ',
+ 'Ò' => 'ò',
+ 'Ó' => 'ó',
+ 'Ô' => 'ô',
+ 'Õ' => 'õ',
+ 'Ö' => 'ö',
+ 'Ø' => 'ø',
+ 'Ù' => 'ù',
+ 'Ú' => 'ú',
+ 'Û' => 'û',
+ 'Ü' => 'ü',
+ 'Ý' => 'ý',
+ 'Þ' => 'þ',
+ 'Ā' => 'ā',
+ 'Ă' => 'ă',
+ 'Ą' => 'ą',
+ 'Ć' => 'ć',
+ 'Ĉ' => 'ĉ',
+ 'Ċ' => 'ċ',
+ 'Č' => 'č',
+ 'Ď' => 'ď',
+ 'Đ' => 'đ',
+ 'Ē' => 'ē',
+ 'Ĕ' => 'ĕ',
+ 'Ė' => 'ė',
+ 'Ę' => 'ę',
+ 'Ě' => 'ě',
+ 'Ĝ' => 'ĝ',
+ 'Ğ' => 'ğ',
+ 'Ġ' => 'ġ',
+ 'Ģ' => 'ģ',
+ 'Ĥ' => 'ĥ',
+ 'Ħ' => 'ħ',
+ 'Ĩ' => 'ĩ',
+ 'Ī' => 'ī',
+ 'Ĭ' => 'ĭ',
+ 'Į' => 'į',
+ 'İ' => 'i',
+ 'IJ' => 'ij',
+ 'Ĵ' => 'ĵ',
+ 'Ķ' => 'ķ',
+ 'Ĺ' => 'ĺ',
+ 'Ļ' => 'ļ',
+ 'Ľ' => 'ľ',
+ 'Ŀ' => 'ŀ',
+ 'Ł' => 'ł',
+ 'Ń' => 'ń',
+ 'Ņ' => 'ņ',
+ 'Ň' => 'ň',
+ 'Ŋ' => 'ŋ',
+ 'Ō' => 'ō',
+ 'Ŏ' => 'ŏ',
+ 'Ő' => 'ő',
+ 'Œ' => 'œ',
+ 'Ŕ' => 'ŕ',
+ 'Ŗ' => 'ŗ',
+ 'Ř' => 'ř',
+ 'Ś' => 'ś',
+ 'Ŝ' => 'ŝ',
+ 'Ş' => 'ş',
+ 'Š' => 'š',
+ 'Ţ' => 'ţ',
+ 'Ť' => 'ť',
+ 'Ŧ' => 'ŧ',
+ 'Ũ' => 'ũ',
+ 'Ū' => 'ū',
+ 'Ŭ' => 'ŭ',
+ 'Ů' => 'ů',
+ 'Ű' => 'ű',
+ 'Ų' => 'ų',
+ 'Ŵ' => 'ŵ',
+ 'Ŷ' => 'ŷ',
+ 'Ÿ' => 'ÿ',
+ 'Ź' => 'ź',
+ 'Ż' => 'ż',
+ 'Ž' => 'ž',
+ 'Ɓ' => 'ɓ',
+ 'Ƃ' => 'ƃ',
+ 'Ƅ' => 'ƅ',
+ 'Ɔ' => 'ɔ',
+ 'Ƈ' => 'ƈ',
+ 'Ɖ' => 'ɖ',
+ 'Ɗ' => 'ɗ',
+ 'Ƌ' => 'ƌ',
+ 'Ǝ' => 'ǝ',
+ 'Ə' => 'ə',
+ 'Ɛ' => 'ɛ',
+ 'Ƒ' => 'ƒ',
+ 'Ɠ' => 'ɠ',
+ 'Ɣ' => 'ɣ',
+ 'Ɩ' => 'ɩ',
+ 'Ɨ' => 'ɨ',
+ 'Ƙ' => 'ƙ',
+ 'Ɯ' => 'ɯ',
+ 'Ɲ' => 'ɲ',
+ 'Ɵ' => 'ɵ',
+ 'Ơ' => 'ơ',
+ 'Ƣ' => 'ƣ',
+ 'Ƥ' => 'ƥ',
+ 'Ʀ' => 'ʀ',
+ 'Ƨ' => 'ƨ',
+ 'Ʃ' => 'ʃ',
+ 'Ƭ' => 'ƭ',
+ 'Ʈ' => 'ʈ',
+ 'Ư' => 'ư',
+ 'Ʊ' => 'ʊ',
+ 'Ʋ' => 'ʋ',
+ 'Ƴ' => 'ƴ',
+ 'Ƶ' => 'ƶ',
+ 'Ʒ' => 'ʒ',
+ 'Ƹ' => 'ƹ',
+ 'Ƽ' => 'ƽ',
+ 'DŽ' => 'dž',
+ 'Dž' => 'dž',
+ 'LJ' => 'lj',
+ 'Lj' => 'lj',
+ 'NJ' => 'nj',
+ 'Nj' => 'nj',
+ 'Ǎ' => 'ǎ',
+ 'Ǐ' => 'ǐ',
+ 'Ǒ' => 'ǒ',
+ 'Ǔ' => 'ǔ',
+ 'Ǖ' => 'ǖ',
+ 'Ǘ' => 'ǘ',
+ 'Ǚ' => 'ǚ',
+ 'Ǜ' => 'ǜ',
+ 'Ǟ' => 'ǟ',
+ 'Ǡ' => 'ǡ',
+ 'Ǣ' => 'ǣ',
+ 'Ǥ' => 'ǥ',
+ 'Ǧ' => 'ǧ',
+ 'Ǩ' => 'ǩ',
+ 'Ǫ' => 'ǫ',
+ 'Ǭ' => 'ǭ',
+ 'Ǯ' => 'ǯ',
+ 'DZ' => 'dz',
+ 'Dz' => 'dz',
+ 'Ǵ' => 'ǵ',
+ 'Ƕ' => 'ƕ',
+ 'Ƿ' => 'ƿ',
+ 'Ǹ' => 'ǹ',
+ 'Ǻ' => 'ǻ',
+ 'Ǽ' => 'ǽ',
+ 'Ǿ' => 'ǿ',
+ 'Ȁ' => 'ȁ',
+ 'Ȃ' => 'ȃ',
+ 'Ȅ' => 'ȅ',
+ 'Ȇ' => 'ȇ',
+ 'Ȉ' => 'ȉ',
+ 'Ȋ' => 'ȋ',
+ 'Ȍ' => 'ȍ',
+ 'Ȏ' => 'ȏ',
+ 'Ȑ' => 'ȑ',
+ 'Ȓ' => 'ȓ',
+ 'Ȕ' => 'ȕ',
+ 'Ȗ' => 'ȗ',
+ 'Ș' => 'ș',
+ 'Ț' => 'ț',
+ 'Ȝ' => 'ȝ',
+ 'Ȟ' => 'ȟ',
+ 'Ƞ' => 'ƞ',
+ 'Ȣ' => 'ȣ',
+ 'Ȥ' => 'ȥ',
+ 'Ȧ' => 'ȧ',
+ 'Ȩ' => 'ȩ',
+ 'Ȫ' => 'ȫ',
+ 'Ȭ' => 'ȭ',
+ 'Ȯ' => 'ȯ',
+ 'Ȱ' => 'ȱ',
+ 'Ȳ' => 'ȳ',
+ 'Ⱥ' => 'ⱥ',
+ 'Ȼ' => 'ȼ',
+ 'Ƚ' => 'ƚ',
+ 'Ⱦ' => 'ⱦ',
+ 'Ɂ' => 'ɂ',
+ 'Ƀ' => 'ƀ',
+ 'Ʉ' => 'ʉ',
+ 'Ʌ' => 'ʌ',
+ 'Ɇ' => 'ɇ',
+ 'Ɉ' => 'ɉ',
+ 'Ɋ' => 'ɋ',
+ 'Ɍ' => 'ɍ',
+ 'Ɏ' => 'ɏ',
+ 'Ͱ' => 'ͱ',
+ 'Ͳ' => 'ͳ',
+ 'Ͷ' => 'ͷ',
+ 'Ϳ' => 'ϳ',
+ 'Ά' => 'ά',
+ 'Έ' => 'έ',
+ 'Ή' => 'ή',
+ 'Ί' => 'ί',
+ 'Ό' => 'ό',
+ 'Ύ' => 'ύ',
+ 'Ώ' => 'ώ',
+ 'Α' => 'α',
+ 'Β' => 'β',
+ 'Γ' => 'γ',
+ 'Δ' => 'δ',
+ 'Ε' => 'ε',
+ 'Ζ' => 'ζ',
+ 'Η' => 'η',
+ 'Θ' => 'θ',
+ 'Ι' => 'ι',
+ 'Κ' => 'κ',
+ 'Λ' => 'λ',
+ 'Μ' => 'μ',
+ 'Ν' => 'ν',
+ 'Ξ' => 'ξ',
+ 'Ο' => 'ο',
+ 'Π' => 'π',
+ 'Ρ' => 'ρ',
+ 'Σ' => 'σ',
+ 'Τ' => 'τ',
+ 'Υ' => 'υ',
+ 'Φ' => 'φ',
+ 'Χ' => 'χ',
+ 'Ψ' => 'ψ',
+ 'Ω' => 'ω',
+ 'Ϊ' => 'ϊ',
+ 'Ϋ' => 'ϋ',
+ 'Ϗ' => 'ϗ',
+ 'Ϙ' => 'ϙ',
+ 'Ϛ' => 'ϛ',
+ 'Ϝ' => 'ϝ',
+ 'Ϟ' => 'ϟ',
+ 'Ϡ' => 'ϡ',
+ 'Ϣ' => 'ϣ',
+ 'Ϥ' => 'ϥ',
+ 'Ϧ' => 'ϧ',
+ 'Ϩ' => 'ϩ',
+ 'Ϫ' => 'ϫ',
+ 'Ϭ' => 'ϭ',
+ 'Ϯ' => 'ϯ',
+ 'ϴ' => 'θ',
+ 'Ϸ' => 'ϸ',
+ 'Ϲ' => 'ϲ',
+ 'Ϻ' => 'ϻ',
+ 'Ͻ' => 'ͻ',
+ 'Ͼ' => 'ͼ',
+ 'Ͽ' => 'ͽ',
+ 'Ѐ' => 'ѐ',
+ 'Ё' => 'ё',
+ 'Ђ' => 'ђ',
+ 'Ѓ' => 'ѓ',
+ 'Є' => 'є',
+ 'Ѕ' => 'ѕ',
+ 'І' => 'і',
+ 'Ї' => 'ї',
+ 'Ј' => 'ј',
+ 'Љ' => 'љ',
+ 'Њ' => 'њ',
+ 'Ћ' => 'ћ',
+ 'Ќ' => 'ќ',
+ 'Ѝ' => 'ѝ',
+ 'Ў' => 'ў',
+ 'Џ' => 'џ',
+ 'А' => 'а',
+ 'Б' => 'б',
+ 'В' => 'в',
+ 'Г' => 'г',
+ 'Д' => 'д',
+ 'Е' => 'е',
+ 'Ж' => 'ж',
+ 'З' => 'з',
+ 'И' => 'и',
+ 'Й' => 'й',
+ 'К' => 'к',
+ 'Л' => 'л',
+ 'М' => 'м',
+ 'Н' => 'н',
+ 'О' => 'о',
+ 'П' => 'п',
+ 'Р' => 'р',
+ 'С' => 'с',
+ 'Т' => 'т',
+ 'У' => 'у',
+ 'Ф' => 'ф',
+ 'Х' => 'х',
+ 'Ц' => 'ц',
+ 'Ч' => 'ч',
+ 'Ш' => 'ш',
+ 'Щ' => 'щ',
+ 'Ъ' => 'ъ',
+ 'Ы' => 'ы',
+ 'Ь' => 'ь',
+ 'Э' => 'э',
+ 'Ю' => 'ю',
+ 'Я' => 'я',
+ 'Ѡ' => 'ѡ',
+ 'Ѣ' => 'ѣ',
+ 'Ѥ' => 'ѥ',
+ 'Ѧ' => 'ѧ',
+ 'Ѩ' => 'ѩ',
+ 'Ѫ' => 'ѫ',
+ 'Ѭ' => 'ѭ',
+ 'Ѯ' => 'ѯ',
+ 'Ѱ' => 'ѱ',
+ 'Ѳ' => 'ѳ',
+ 'Ѵ' => 'ѵ',
+ 'Ѷ' => 'ѷ',
+ 'Ѹ' => 'ѹ',
+ 'Ѻ' => 'ѻ',
+ 'Ѽ' => 'ѽ',
+ 'Ѿ' => 'ѿ',
+ 'Ҁ' => 'ҁ',
+ 'Ҋ' => 'ҋ',
+ 'Ҍ' => 'ҍ',
+ 'Ҏ' => 'ҏ',
+ 'Ґ' => 'ґ',
+ 'Ғ' => 'ғ',
+ 'Ҕ' => 'ҕ',
+ 'Җ' => 'җ',
+ 'Ҙ' => 'ҙ',
+ 'Қ' => 'қ',
+ 'Ҝ' => 'ҝ',
+ 'Ҟ' => 'ҟ',
+ 'Ҡ' => 'ҡ',
+ 'Ң' => 'ң',
+ 'Ҥ' => 'ҥ',
+ 'Ҧ' => 'ҧ',
+ 'Ҩ' => 'ҩ',
+ 'Ҫ' => 'ҫ',
+ 'Ҭ' => 'ҭ',
+ 'Ү' => 'ү',
+ 'Ұ' => 'ұ',
+ 'Ҳ' => 'ҳ',
+ 'Ҵ' => 'ҵ',
+ 'Ҷ' => 'ҷ',
+ 'Ҹ' => 'ҹ',
+ 'Һ' => 'һ',
+ 'Ҽ' => 'ҽ',
+ 'Ҿ' => 'ҿ',
+ 'Ӏ' => 'ӏ',
+ 'Ӂ' => 'ӂ',
+ 'Ӄ' => 'ӄ',
+ 'Ӆ' => 'ӆ',
+ 'Ӈ' => 'ӈ',
+ 'Ӊ' => 'ӊ',
+ 'Ӌ' => 'ӌ',
+ 'Ӎ' => 'ӎ',
+ 'Ӑ' => 'ӑ',
+ 'Ӓ' => 'ӓ',
+ 'Ӕ' => 'ӕ',
+ 'Ӗ' => 'ӗ',
+ 'Ә' => 'ә',
+ 'Ӛ' => 'ӛ',
+ 'Ӝ' => 'ӝ',
+ 'Ӟ' => 'ӟ',
+ 'Ӡ' => 'ӡ',
+ 'Ӣ' => 'ӣ',
+ 'Ӥ' => 'ӥ',
+ 'Ӧ' => 'ӧ',
+ 'Ө' => 'ө',
+ 'Ӫ' => 'ӫ',
+ 'Ӭ' => 'ӭ',
+ 'Ӯ' => 'ӯ',
+ 'Ӱ' => 'ӱ',
+ 'Ӳ' => 'ӳ',
+ 'Ӵ' => 'ӵ',
+ 'Ӷ' => 'ӷ',
+ 'Ӹ' => 'ӹ',
+ 'Ӻ' => 'ӻ',
+ 'Ӽ' => 'ӽ',
+ 'Ӿ' => 'ӿ',
+ 'Ԁ' => 'ԁ',
+ 'Ԃ' => 'ԃ',
+ 'Ԅ' => 'ԅ',
+ 'Ԇ' => 'ԇ',
+ 'Ԉ' => 'ԉ',
+ 'Ԋ' => 'ԋ',
+ 'Ԍ' => 'ԍ',
+ 'Ԏ' => 'ԏ',
+ 'Ԑ' => 'ԑ',
+ 'Ԓ' => 'ԓ',
+ 'Ԕ' => 'ԕ',
+ 'Ԗ' => 'ԗ',
+ 'Ԙ' => 'ԙ',
+ 'Ԛ' => 'ԛ',
+ 'Ԝ' => 'ԝ',
+ 'Ԟ' => 'ԟ',
+ 'Ԡ' => 'ԡ',
+ 'Ԣ' => 'ԣ',
+ 'Ԥ' => 'ԥ',
+ 'Ԧ' => 'ԧ',
+ 'Ԩ' => 'ԩ',
+ 'Ԫ' => 'ԫ',
+ 'Ԭ' => 'ԭ',
+ 'Ԯ' => 'ԯ',
+ 'Ա' => 'ա',
+ 'Բ' => 'բ',
+ 'Գ' => 'գ',
+ 'Դ' => 'դ',
+ 'Ե' => 'ե',
+ 'Զ' => 'զ',
+ 'Է' => 'է',
+ 'Ը' => 'ը',
+ 'Թ' => 'թ',
+ 'Ժ' => 'ժ',
+ 'Ի' => 'ի',
+ 'Լ' => 'լ',
+ 'Խ' => 'խ',
+ 'Ծ' => 'ծ',
+ 'Կ' => 'կ',
+ 'Հ' => 'հ',
+ 'Ձ' => 'ձ',
+ 'Ղ' => 'ղ',
+ 'Ճ' => 'ճ',
+ 'Մ' => 'մ',
+ 'Յ' => 'յ',
+ 'Ն' => 'ն',
+ 'Շ' => 'շ',
+ 'Ո' => 'ո',
+ 'Չ' => 'չ',
+ 'Պ' => 'պ',
+ 'Ջ' => 'ջ',
+ 'Ռ' => 'ռ',
+ 'Ս' => 'ս',
+ 'Վ' => 'վ',
+ 'Տ' => 'տ',
+ 'Ր' => 'ր',
+ 'Ց' => 'ց',
+ 'Ւ' => 'ւ',
+ 'Փ' => 'փ',
+ 'Ք' => 'ք',
+ 'Օ' => 'օ',
+ 'Ֆ' => 'ֆ',
+ 'Ⴀ' => 'ⴀ',
+ 'Ⴁ' => 'ⴁ',
+ 'Ⴂ' => 'ⴂ',
+ 'Ⴃ' => 'ⴃ',
+ 'Ⴄ' => 'ⴄ',
+ 'Ⴅ' => 'ⴅ',
+ 'Ⴆ' => 'ⴆ',
+ 'Ⴇ' => 'ⴇ',
+ 'Ⴈ' => 'ⴈ',
+ 'Ⴉ' => 'ⴉ',
+ 'Ⴊ' => 'ⴊ',
+ 'Ⴋ' => 'ⴋ',
+ 'Ⴌ' => 'ⴌ',
+ 'Ⴍ' => 'ⴍ',
+ 'Ⴎ' => 'ⴎ',
+ 'Ⴏ' => 'ⴏ',
+ 'Ⴐ' => 'ⴐ',
+ 'Ⴑ' => 'ⴑ',
+ 'Ⴒ' => 'ⴒ',
+ 'Ⴓ' => 'ⴓ',
+ 'Ⴔ' => 'ⴔ',
+ 'Ⴕ' => 'ⴕ',
+ 'Ⴖ' => 'ⴖ',
+ 'Ⴗ' => 'ⴗ',
+ 'Ⴘ' => 'ⴘ',
+ 'Ⴙ' => 'ⴙ',
+ 'Ⴚ' => 'ⴚ',
+ 'Ⴛ' => 'ⴛ',
+ 'Ⴜ' => 'ⴜ',
+ 'Ⴝ' => 'ⴝ',
+ 'Ⴞ' => 'ⴞ',
+ 'Ⴟ' => 'ⴟ',
+ 'Ⴠ' => 'ⴠ',
+ 'Ⴡ' => 'ⴡ',
+ 'Ⴢ' => 'ⴢ',
+ 'Ⴣ' => 'ⴣ',
+ 'Ⴤ' => 'ⴤ',
+ 'Ⴥ' => 'ⴥ',
+ 'Ⴧ' => 'ⴧ',
+ 'Ⴭ' => 'ⴭ',
+ 'Ḁ' => 'ḁ',
+ 'Ḃ' => 'ḃ',
+ 'Ḅ' => 'ḅ',
+ 'Ḇ' => 'ḇ',
+ 'Ḉ' => 'ḉ',
+ 'Ḋ' => 'ḋ',
+ 'Ḍ' => 'ḍ',
+ 'Ḏ' => 'ḏ',
+ 'Ḑ' => 'ḑ',
+ 'Ḓ' => 'ḓ',
+ 'Ḕ' => 'ḕ',
+ 'Ḗ' => 'ḗ',
+ 'Ḙ' => 'ḙ',
+ 'Ḛ' => 'ḛ',
+ 'Ḝ' => 'ḝ',
+ 'Ḟ' => 'ḟ',
+ 'Ḡ' => 'ḡ',
+ 'Ḣ' => 'ḣ',
+ 'Ḥ' => 'ḥ',
+ 'Ḧ' => 'ḧ',
+ 'Ḩ' => 'ḩ',
+ 'Ḫ' => 'ḫ',
+ 'Ḭ' => 'ḭ',
+ 'Ḯ' => 'ḯ',
+ 'Ḱ' => 'ḱ',
+ 'Ḳ' => 'ḳ',
+ 'Ḵ' => 'ḵ',
+ 'Ḷ' => 'ḷ',
+ 'Ḹ' => 'ḹ',
+ 'Ḻ' => 'ḻ',
+ 'Ḽ' => 'ḽ',
+ 'Ḿ' => 'ḿ',
+ 'Ṁ' => 'ṁ',
+ 'Ṃ' => 'ṃ',
+ 'Ṅ' => 'ṅ',
+ 'Ṇ' => 'ṇ',
+ 'Ṉ' => 'ṉ',
+ 'Ṋ' => 'ṋ',
+ 'Ṍ' => 'ṍ',
+ 'Ṏ' => 'ṏ',
+ 'Ṑ' => 'ṑ',
+ 'Ṓ' => 'ṓ',
+ 'Ṕ' => 'ṕ',
+ 'Ṗ' => 'ṗ',
+ 'Ṙ' => 'ṙ',
+ 'Ṛ' => 'ṛ',
+ 'Ṝ' => 'ṝ',
+ 'Ṟ' => 'ṟ',
+ 'Ṡ' => 'ṡ',
+ 'Ṣ' => 'ṣ',
+ 'Ṥ' => 'ṥ',
+ 'Ṧ' => 'ṧ',
+ 'Ṩ' => 'ṩ',
+ 'Ṫ' => 'ṫ',
+ 'Ṭ' => 'ṭ',
+ 'Ṯ' => 'ṯ',
+ 'Ṱ' => 'ṱ',
+ 'Ṳ' => 'ṳ',
+ 'Ṵ' => 'ṵ',
+ 'Ṷ' => 'ṷ',
+ 'Ṹ' => 'ṹ',
+ 'Ṻ' => 'ṻ',
+ 'Ṽ' => 'ṽ',
+ 'Ṿ' => 'ṿ',
+ 'Ẁ' => 'ẁ',
+ 'Ẃ' => 'ẃ',
+ 'Ẅ' => 'ẅ',
+ 'Ẇ' => 'ẇ',
+ 'Ẉ' => 'ẉ',
+ 'Ẋ' => 'ẋ',
+ 'Ẍ' => 'ẍ',
+ 'Ẏ' => 'ẏ',
+ 'Ẑ' => 'ẑ',
+ 'Ẓ' => 'ẓ',
+ 'Ẕ' => 'ẕ',
+ 'ẞ' => 'ß',
+ 'Ạ' => 'ạ',
+ 'Ả' => 'ả',
+ 'Ấ' => 'ấ',
+ 'Ầ' => 'ầ',
+ 'Ẩ' => 'ẩ',
+ 'Ẫ' => 'ẫ',
+ 'Ậ' => 'ậ',
+ 'Ắ' => 'ắ',
+ 'Ằ' => 'ằ',
+ 'Ẳ' => 'ẳ',
+ 'Ẵ' => 'ẵ',
+ 'Ặ' => 'ặ',
+ 'Ẹ' => 'ẹ',
+ 'Ẻ' => 'ẻ',
+ 'Ẽ' => 'ẽ',
+ 'Ế' => 'ế',
+ 'Ề' => 'ề',
+ 'Ể' => 'ể',
+ 'Ễ' => 'ễ',
+ 'Ệ' => 'ệ',
+ 'Ỉ' => 'ỉ',
+ 'Ị' => 'ị',
+ 'Ọ' => 'ọ',
+ 'Ỏ' => 'ỏ',
+ 'Ố' => 'ố',
+ 'Ồ' => 'ồ',
+ 'Ổ' => 'ổ',
+ 'Ỗ' => 'ỗ',
+ 'Ộ' => 'ộ',
+ 'Ớ' => 'ớ',
+ 'Ờ' => 'ờ',
+ 'Ở' => 'ở',
+ 'Ỡ' => 'ỡ',
+ 'Ợ' => 'ợ',
+ 'Ụ' => 'ụ',
+ 'Ủ' => 'ủ',
+ 'Ứ' => 'ứ',
+ 'Ừ' => 'ừ',
+ 'Ử' => 'ử',
+ 'Ữ' => 'ữ',
+ 'Ự' => 'ự',
+ 'Ỳ' => 'ỳ',
+ 'Ỵ' => 'ỵ',
+ 'Ỷ' => 'ỷ',
+ 'Ỹ' => 'ỹ',
+ 'Ỻ' => 'ỻ',
+ 'Ỽ' => 'ỽ',
+ 'Ỿ' => 'ỿ',
+ 'Ἀ' => 'ἀ',
+ 'Ἁ' => 'ἁ',
+ 'Ἂ' => 'ἂ',
+ 'Ἃ' => 'ἃ',
+ 'Ἄ' => 'ἄ',
+ 'Ἅ' => 'ἅ',
+ 'Ἆ' => 'ἆ',
+ 'Ἇ' => 'ἇ',
+ 'Ἐ' => 'ἐ',
+ 'Ἑ' => 'ἑ',
+ 'Ἒ' => 'ἒ',
+ 'Ἓ' => 'ἓ',
+ 'Ἔ' => 'ἔ',
+ 'Ἕ' => 'ἕ',
+ 'Ἠ' => 'ἠ',
+ 'Ἡ' => 'ἡ',
+ 'Ἢ' => 'ἢ',
+ 'Ἣ' => 'ἣ',
+ 'Ἤ' => 'ἤ',
+ 'Ἥ' => 'ἥ',
+ 'Ἦ' => 'ἦ',
+ 'Ἧ' => 'ἧ',
+ 'Ἰ' => 'ἰ',
+ 'Ἱ' => 'ἱ',
+ 'Ἲ' => 'ἲ',
+ 'Ἳ' => 'ἳ',
+ 'Ἴ' => 'ἴ',
+ 'Ἵ' => 'ἵ',
+ 'Ἶ' => 'ἶ',
+ 'Ἷ' => 'ἷ',
+ 'Ὀ' => 'ὀ',
+ 'Ὁ' => 'ὁ',
+ 'Ὂ' => 'ὂ',
+ 'Ὃ' => 'ὃ',
+ 'Ὄ' => 'ὄ',
+ 'Ὅ' => 'ὅ',
+ 'Ὑ' => 'ὑ',
+ 'Ὓ' => 'ὓ',
+ 'Ὕ' => 'ὕ',
+ 'Ὗ' => 'ὗ',
+ 'Ὠ' => 'ὠ',
+ 'Ὡ' => 'ὡ',
+ 'Ὢ' => 'ὢ',
+ 'Ὣ' => 'ὣ',
+ 'Ὤ' => 'ὤ',
+ 'Ὥ' => 'ὥ',
+ 'Ὦ' => 'ὦ',
+ 'Ὧ' => 'ὧ',
+ 'ᾈ' => 'ᾀ',
+ 'ᾉ' => 'ᾁ',
+ 'ᾊ' => 'ᾂ',
+ 'ᾋ' => 'ᾃ',
+ 'ᾌ' => 'ᾄ',
+ 'ᾍ' => 'ᾅ',
+ 'ᾎ' => 'ᾆ',
+ 'ᾏ' => 'ᾇ',
+ 'ᾘ' => 'ᾐ',
+ 'ᾙ' => 'ᾑ',
+ 'ᾚ' => 'ᾒ',
+ 'ᾛ' => 'ᾓ',
+ 'ᾜ' => 'ᾔ',
+ 'ᾝ' => 'ᾕ',
+ 'ᾞ' => 'ᾖ',
+ 'ᾟ' => 'ᾗ',
+ 'ᾨ' => 'ᾠ',
+ 'ᾩ' => 'ᾡ',
+ 'ᾪ' => 'ᾢ',
+ 'ᾫ' => 'ᾣ',
+ 'ᾬ' => 'ᾤ',
+ 'ᾭ' => 'ᾥ',
+ 'ᾮ' => 'ᾦ',
+ 'ᾯ' => 'ᾧ',
+ 'Ᾰ' => 'ᾰ',
+ 'Ᾱ' => 'ᾱ',
+ 'Ὰ' => 'ὰ',
+ 'Ά' => 'ά',
+ 'ᾼ' => 'ᾳ',
+ 'Ὲ' => 'ὲ',
+ 'Έ' => 'έ',
+ 'Ὴ' => 'ὴ',
+ 'Ή' => 'ή',
+ 'ῌ' => 'ῃ',
+ 'Ῐ' => 'ῐ',
+ 'Ῑ' => 'ῑ',
+ 'Ὶ' => 'ὶ',
+ 'Ί' => 'ί',
+ 'Ῠ' => 'ῠ',
+ 'Ῡ' => 'ῡ',
+ 'Ὺ' => 'ὺ',
+ 'Ύ' => 'ύ',
+ 'Ῥ' => 'ῥ',
+ 'Ὸ' => 'ὸ',
+ 'Ό' => 'ό',
+ 'Ὼ' => 'ὼ',
+ 'Ώ' => 'ώ',
+ 'ῼ' => 'ῳ',
+ 'Ω' => 'ω',
+ 'K' => 'k',
+ 'Å' => 'å',
+ 'Ⅎ' => 'ⅎ',
+ 'Ⅰ' => 'ⅰ',
+ 'Ⅱ' => 'ⅱ',
+ 'Ⅲ' => 'ⅲ',
+ 'Ⅳ' => 'ⅳ',
+ 'Ⅴ' => 'ⅴ',
+ 'Ⅵ' => 'ⅵ',
+ 'Ⅶ' => 'ⅶ',
+ 'Ⅷ' => 'ⅷ',
+ 'Ⅸ' => 'ⅸ',
+ 'Ⅹ' => 'ⅹ',
+ 'Ⅺ' => 'ⅺ',
+ 'Ⅻ' => 'ⅻ',
+ 'Ⅼ' => 'ⅼ',
+ 'Ⅽ' => 'ⅽ',
+ 'Ⅾ' => 'ⅾ',
+ 'Ⅿ' => 'ⅿ',
+ 'Ↄ' => 'ↄ',
+ 'Ⓐ' => 'ⓐ',
+ 'Ⓑ' => 'ⓑ',
+ 'Ⓒ' => 'ⓒ',
+ 'Ⓓ' => 'ⓓ',
+ 'Ⓔ' => 'ⓔ',
+ 'Ⓕ' => 'ⓕ',
+ 'Ⓖ' => 'ⓖ',
+ 'Ⓗ' => 'ⓗ',
+ 'Ⓘ' => 'ⓘ',
+ 'Ⓙ' => 'ⓙ',
+ 'Ⓚ' => 'ⓚ',
+ 'Ⓛ' => 'ⓛ',
+ 'Ⓜ' => 'ⓜ',
+ 'Ⓝ' => 'ⓝ',
+ 'Ⓞ' => 'ⓞ',
+ 'Ⓟ' => 'ⓟ',
+ 'Ⓠ' => 'ⓠ',
+ 'Ⓡ' => 'ⓡ',
+ 'Ⓢ' => 'ⓢ',
+ 'Ⓣ' => 'ⓣ',
+ 'Ⓤ' => 'ⓤ',
+ 'Ⓥ' => 'ⓥ',
+ 'Ⓦ' => 'ⓦ',
+ 'Ⓧ' => 'ⓧ',
+ 'Ⓨ' => 'ⓨ',
+ 'Ⓩ' => 'ⓩ',
+ 'Ⰰ' => 'ⰰ',
+ 'Ⰱ' => 'ⰱ',
+ 'Ⰲ' => 'ⰲ',
+ 'Ⰳ' => 'ⰳ',
+ 'Ⰴ' => 'ⰴ',
+ 'Ⰵ' => 'ⰵ',
+ 'Ⰶ' => 'ⰶ',
+ 'Ⰷ' => 'ⰷ',
+ 'Ⰸ' => 'ⰸ',
+ 'Ⰹ' => 'ⰹ',
+ 'Ⰺ' => 'ⰺ',
+ 'Ⰻ' => 'ⰻ',
+ 'Ⰼ' => 'ⰼ',
+ 'Ⰽ' => 'ⰽ',
+ 'Ⰾ' => 'ⰾ',
+ 'Ⰿ' => 'ⰿ',
+ 'Ⱀ' => 'ⱀ',
+ 'Ⱁ' => 'ⱁ',
+ 'Ⱂ' => 'ⱂ',
+ 'Ⱃ' => 'ⱃ',
+ 'Ⱄ' => 'ⱄ',
+ 'Ⱅ' => 'ⱅ',
+ 'Ⱆ' => 'ⱆ',
+ 'Ⱇ' => 'ⱇ',
+ 'Ⱈ' => 'ⱈ',
+ 'Ⱉ' => 'ⱉ',
+ 'Ⱊ' => 'ⱊ',
+ 'Ⱋ' => 'ⱋ',
+ 'Ⱌ' => 'ⱌ',
+ 'Ⱍ' => 'ⱍ',
+ 'Ⱎ' => 'ⱎ',
+ 'Ⱏ' => 'ⱏ',
+ 'Ⱐ' => 'ⱐ',
+ 'Ⱑ' => 'ⱑ',
+ 'Ⱒ' => 'ⱒ',
+ 'Ⱓ' => 'ⱓ',
+ 'Ⱔ' => 'ⱔ',
+ 'Ⱕ' => 'ⱕ',
+ 'Ⱖ' => 'ⱖ',
+ 'Ⱗ' => 'ⱗ',
+ 'Ⱘ' => 'ⱘ',
+ 'Ⱙ' => 'ⱙ',
+ 'Ⱚ' => 'ⱚ',
+ 'Ⱛ' => 'ⱛ',
+ 'Ⱜ' => 'ⱜ',
+ 'Ⱝ' => 'ⱝ',
+ 'Ⱞ' => 'ⱞ',
+ 'Ⱡ' => 'ⱡ',
+ 'Ɫ' => 'ɫ',
+ 'Ᵽ' => 'ᵽ',
+ 'Ɽ' => 'ɽ',
+ 'Ⱨ' => 'ⱨ',
+ 'Ⱪ' => 'ⱪ',
+ 'Ⱬ' => 'ⱬ',
+ 'Ɑ' => 'ɑ',
+ 'Ɱ' => 'ɱ',
+ 'Ɐ' => 'ɐ',
+ 'Ɒ' => 'ɒ',
+ 'Ⱳ' => 'ⱳ',
+ 'Ⱶ' => 'ⱶ',
+ 'Ȿ' => 'ȿ',
+ 'Ɀ' => 'ɀ',
+ 'Ⲁ' => 'ⲁ',
+ 'Ⲃ' => 'ⲃ',
+ 'Ⲅ' => 'ⲅ',
+ 'Ⲇ' => 'ⲇ',
+ 'Ⲉ' => 'ⲉ',
+ 'Ⲋ' => 'ⲋ',
+ 'Ⲍ' => 'ⲍ',
+ 'Ⲏ' => 'ⲏ',
+ 'Ⲑ' => 'ⲑ',
+ 'Ⲓ' => 'ⲓ',
+ 'Ⲕ' => 'ⲕ',
+ 'Ⲗ' => 'ⲗ',
+ 'Ⲙ' => 'ⲙ',
+ 'Ⲛ' => 'ⲛ',
+ 'Ⲝ' => 'ⲝ',
+ 'Ⲟ' => 'ⲟ',
+ 'Ⲡ' => 'ⲡ',
+ 'Ⲣ' => 'ⲣ',
+ 'Ⲥ' => 'ⲥ',
+ 'Ⲧ' => 'ⲧ',
+ 'Ⲩ' => 'ⲩ',
+ 'Ⲫ' => 'ⲫ',
+ 'Ⲭ' => 'ⲭ',
+ 'Ⲯ' => 'ⲯ',
+ 'Ⲱ' => 'ⲱ',
+ 'Ⲳ' => 'ⲳ',
+ 'Ⲵ' => 'ⲵ',
+ 'Ⲷ' => 'ⲷ',
+ 'Ⲹ' => 'ⲹ',
+ 'Ⲻ' => 'ⲻ',
+ 'Ⲽ' => 'ⲽ',
+ 'Ⲿ' => 'ⲿ',
+ 'Ⳁ' => 'ⳁ',
+ 'Ⳃ' => 'ⳃ',
+ 'Ⳅ' => 'ⳅ',
+ 'Ⳇ' => 'ⳇ',
+ 'Ⳉ' => 'ⳉ',
+ 'Ⳋ' => 'ⳋ',
+ 'Ⳍ' => 'ⳍ',
+ 'Ⳏ' => 'ⳏ',
+ 'Ⳑ' => 'ⳑ',
+ 'Ⳓ' => 'ⳓ',
+ 'Ⳕ' => 'ⳕ',
+ 'Ⳗ' => 'ⳗ',
+ 'Ⳙ' => 'ⳙ',
+ 'Ⳛ' => 'ⳛ',
+ 'Ⳝ' => 'ⳝ',
+ 'Ⳟ' => 'ⳟ',
+ 'Ⳡ' => 'ⳡ',
+ 'Ⳣ' => 'ⳣ',
+ 'Ⳬ' => 'ⳬ',
+ 'Ⳮ' => 'ⳮ',
+ 'Ⳳ' => 'ⳳ',
+ 'Ꙁ' => 'ꙁ',
+ 'Ꙃ' => 'ꙃ',
+ 'Ꙅ' => 'ꙅ',
+ 'Ꙇ' => 'ꙇ',
+ 'Ꙉ' => 'ꙉ',
+ 'Ꙋ' => 'ꙋ',
+ 'Ꙍ' => 'ꙍ',
+ 'Ꙏ' => 'ꙏ',
+ 'Ꙑ' => 'ꙑ',
+ 'Ꙓ' => 'ꙓ',
+ 'Ꙕ' => 'ꙕ',
+ 'Ꙗ' => 'ꙗ',
+ 'Ꙙ' => 'ꙙ',
+ 'Ꙛ' => 'ꙛ',
+ 'Ꙝ' => 'ꙝ',
+ 'Ꙟ' => 'ꙟ',
+ 'Ꙡ' => 'ꙡ',
+ 'Ꙣ' => 'ꙣ',
+ 'Ꙥ' => 'ꙥ',
+ 'Ꙧ' => 'ꙧ',
+ 'Ꙩ' => 'ꙩ',
+ 'Ꙫ' => 'ꙫ',
+ 'Ꙭ' => 'ꙭ',
+ 'Ꚁ' => 'ꚁ',
+ 'Ꚃ' => 'ꚃ',
+ 'Ꚅ' => 'ꚅ',
+ 'Ꚇ' => 'ꚇ',
+ 'Ꚉ' => 'ꚉ',
+ 'Ꚋ' => 'ꚋ',
+ 'Ꚍ' => 'ꚍ',
+ 'Ꚏ' => 'ꚏ',
+ 'Ꚑ' => 'ꚑ',
+ 'Ꚓ' => 'ꚓ',
+ 'Ꚕ' => 'ꚕ',
+ 'Ꚗ' => 'ꚗ',
+ 'Ꚙ' => 'ꚙ',
+ 'Ꚛ' => 'ꚛ',
+ 'Ꜣ' => 'ꜣ',
+ 'Ꜥ' => 'ꜥ',
+ 'Ꜧ' => 'ꜧ',
+ 'Ꜩ' => 'ꜩ',
+ 'Ꜫ' => 'ꜫ',
+ 'Ꜭ' => 'ꜭ',
+ 'Ꜯ' => 'ꜯ',
+ 'Ꜳ' => 'ꜳ',
+ 'Ꜵ' => 'ꜵ',
+ 'Ꜷ' => 'ꜷ',
+ 'Ꜹ' => 'ꜹ',
+ 'Ꜻ' => 'ꜻ',
+ 'Ꜽ' => 'ꜽ',
+ 'Ꜿ' => 'ꜿ',
+ 'Ꝁ' => 'ꝁ',
+ 'Ꝃ' => 'ꝃ',
+ 'Ꝅ' => 'ꝅ',
+ 'Ꝇ' => 'ꝇ',
+ 'Ꝉ' => 'ꝉ',
+ 'Ꝋ' => 'ꝋ',
+ 'Ꝍ' => 'ꝍ',
+ 'Ꝏ' => 'ꝏ',
+ 'Ꝑ' => 'ꝑ',
+ 'Ꝓ' => 'ꝓ',
+ 'Ꝕ' => 'ꝕ',
+ 'Ꝗ' => 'ꝗ',
+ 'Ꝙ' => 'ꝙ',
+ 'Ꝛ' => 'ꝛ',
+ 'Ꝝ' => 'ꝝ',
+ 'Ꝟ' => 'ꝟ',
+ 'Ꝡ' => 'ꝡ',
+ 'Ꝣ' => 'ꝣ',
+ 'Ꝥ' => 'ꝥ',
+ 'Ꝧ' => 'ꝧ',
+ 'Ꝩ' => 'ꝩ',
+ 'Ꝫ' => 'ꝫ',
+ 'Ꝭ' => 'ꝭ',
+ 'Ꝯ' => 'ꝯ',
+ 'Ꝺ' => 'ꝺ',
+ 'Ꝼ' => 'ꝼ',
+ 'Ᵹ' => 'ᵹ',
+ 'Ꝿ' => 'ꝿ',
+ 'Ꞁ' => 'ꞁ',
+ 'Ꞃ' => 'ꞃ',
+ 'Ꞅ' => 'ꞅ',
+ 'Ꞇ' => 'ꞇ',
+ 'Ꞌ' => 'ꞌ',
+ 'Ɥ' => 'ɥ',
+ 'Ꞑ' => 'ꞑ',
+ 'Ꞓ' => 'ꞓ',
+ 'Ꞗ' => 'ꞗ',
+ 'Ꞙ' => 'ꞙ',
+ 'Ꞛ' => 'ꞛ',
+ 'Ꞝ' => 'ꞝ',
+ 'Ꞟ' => 'ꞟ',
+ 'Ꞡ' => 'ꞡ',
+ 'Ꞣ' => 'ꞣ',
+ 'Ꞥ' => 'ꞥ',
+ 'Ꞧ' => 'ꞧ',
+ 'Ꞩ' => 'ꞩ',
+ 'Ɦ' => 'ɦ',
+ 'Ɜ' => 'ɜ',
+ 'Ɡ' => 'ɡ',
+ 'Ɬ' => 'ɬ',
+ 'Ʞ' => 'ʞ',
+ 'Ʇ' => 'ʇ',
+ 'A' => 'a',
+ 'B' => 'b',
+ 'C' => 'c',
+ 'D' => 'd',
+ 'E' => 'e',
+ 'F' => 'f',
+ 'G' => 'g',
+ 'H' => 'h',
+ 'I' => 'i',
+ 'J' => 'j',
+ 'K' => 'k',
+ 'L' => 'l',
+ 'M' => 'm',
+ 'N' => 'n',
+ 'O' => 'o',
+ 'P' => 'p',
+ 'Q' => 'q',
+ 'R' => 'r',
+ 'S' => 's',
+ 'T' => 't',
+ 'U' => 'u',
+ 'V' => 'v',
+ 'W' => 'w',
+ 'X' => 'x',
+ 'Y' => 'y',
+ 'Z' => 'z',
+ '𐐀' => '𐐨',
+ '𐐁' => '𐐩',
+ '𐐂' => '𐐪',
+ '𐐃' => '𐐫',
+ '𐐄' => '𐐬',
+ '𐐅' => '𐐭',
+ '𐐆' => '𐐮',
+ '𐐇' => '𐐯',
+ '𐐈' => '𐐰',
+ '𐐉' => '𐐱',
+ '𐐊' => '𐐲',
+ '𐐋' => '𐐳',
+ '𐐌' => '𐐴',
+ '𐐍' => '𐐵',
+ '𐐎' => '𐐶',
+ '𐐏' => '𐐷',
+ '𐐐' => '𐐸',
+ '𐐑' => '𐐹',
+ '𐐒' => '𐐺',
+ '𐐓' => '𐐻',
+ '𐐔' => '𐐼',
+ '𐐕' => '𐐽',
+ '𐐖' => '𐐾',
+ '𐐗' => '𐐿',
+ '𐐘' => '𐑀',
+ '𐐙' => '𐑁',
+ '𐐚' => '𐑂',
+ '𐐛' => '𐑃',
+ '𐐜' => '𐑄',
+ '𐐝' => '𐑅',
+ '𐐞' => '𐑆',
+ '𐐟' => '𐑇',
+ '𐐠' => '𐑈',
+ '𐐡' => '𐑉',
+ '𐐢' => '𐑊',
+ '𐐣' => '𐑋',
+ '𐐤' => '𐑌',
+ '𐐥' => '𐑍',
+ '𐐦' => '𐑎',
+ '𐐧' => '𐑏',
+ '𑢠' => '𑣀',
+ '𑢡' => '𑣁',
+ '𑢢' => '𑣂',
+ '𑢣' => '𑣃',
+ '𑢤' => '𑣄',
+ '𑢥' => '𑣅',
+ '𑢦' => '𑣆',
+ '𑢧' => '𑣇',
+ '𑢨' => '𑣈',
+ '𑢩' => '𑣉',
+ '𑢪' => '𑣊',
+ '𑢫' => '𑣋',
+ '𑢬' => '𑣌',
+ '𑢭' => '𑣍',
+ '𑢮' => '𑣎',
+ '𑢯' => '𑣏',
+ '𑢰' => '𑣐',
+ '𑢱' => '𑣑',
+ '𑢲' => '𑣒',
+ '𑢳' => '𑣓',
+ '𑢴' => '𑣔',
+ '𑢵' => '𑣕',
+ '𑢶' => '𑣖',
+ '𑢷' => '𑣗',
+ '𑢸' => '𑣘',
+ '𑢹' => '𑣙',
+ '𑢺' => '𑣚',
+ '𑢻' => '𑣛',
+ '𑢼' => '𑣜',
+ '𑢽' => '𑣝',
+ '𑢾' => '𑣞',
+ '𑢿' => '𑣟',
+);
+
+$result =& $data;
+unset($data);
+
+return $result;
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php
new file mode 100644
index 0000000..ec94221
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php
@@ -0,0 +1,1109 @@
+<?php
+
+static $data = array (
+ 'a' => 'A',
+ 'b' => 'B',
+ 'c' => 'C',
+ 'd' => 'D',
+ 'e' => 'E',
+ 'f' => 'F',
+ 'g' => 'G',
+ 'h' => 'H',
+ 'i' => 'I',
+ 'j' => 'J',
+ 'k' => 'K',
+ 'l' => 'L',
+ 'm' => 'M',
+ 'n' => 'N',
+ 'o' => 'O',
+ 'p' => 'P',
+ 'q' => 'Q',
+ 'r' => 'R',
+ 's' => 'S',
+ 't' => 'T',
+ 'u' => 'U',
+ 'v' => 'V',
+ 'w' => 'W',
+ 'x' => 'X',
+ 'y' => 'Y',
+ 'z' => 'Z',
+ 'µ' => 'Μ',
+ 'à' => 'À',
+ 'á' => 'Á',
+ 'â' => 'Â',
+ 'ã' => 'Ã',
+ 'ä' => 'Ä',
+ 'å' => 'Å',
+ 'æ' => 'Æ',
+ 'ç' => 'Ç',
+ 'è' => 'È',
+ 'é' => 'É',
+ 'ê' => 'Ê',
+ 'ë' => 'Ë',
+ 'ì' => 'Ì',
+ 'í' => 'Í',
+ 'î' => 'Î',
+ 'ï' => 'Ï',
+ 'ð' => 'Ð',
+ 'ñ' => 'Ñ',
+ 'ò' => 'Ò',
+ 'ó' => 'Ó',
+ 'ô' => 'Ô',
+ 'õ' => 'Õ',
+ 'ö' => 'Ö',
+ 'ø' => 'Ø',
+ 'ù' => 'Ù',
+ 'ú' => 'Ú',
+ 'û' => 'Û',
+ 'ü' => 'Ü',
+ 'ý' => 'Ý',
+ 'þ' => 'Þ',
+ 'ÿ' => 'Ÿ',
+ 'ā' => 'Ā',
+ 'ă' => 'Ă',
+ 'ą' => 'Ą',
+ 'ć' => 'Ć',
+ 'ĉ' => 'Ĉ',
+ 'ċ' => 'Ċ',
+ 'č' => 'Č',
+ 'ď' => 'Ď',
+ 'đ' => 'Đ',
+ 'ē' => 'Ē',
+ 'ĕ' => 'Ĕ',
+ 'ė' => 'Ė',
+ 'ę' => 'Ę',
+ 'ě' => 'Ě',
+ 'ĝ' => 'Ĝ',
+ 'ğ' => 'Ğ',
+ 'ġ' => 'Ġ',
+ 'ģ' => 'Ģ',
+ 'ĥ' => 'Ĥ',
+ 'ħ' => 'Ħ',
+ 'ĩ' => 'Ĩ',
+ 'ī' => 'Ī',
+ 'ĭ' => 'Ĭ',
+ 'į' => 'Į',
+ 'ı' => 'I',
+ 'ij' => 'IJ',
+ 'ĵ' => 'Ĵ',
+ 'ķ' => 'Ķ',
+ 'ĺ' => 'Ĺ',
+ 'ļ' => 'Ļ',
+ 'ľ' => 'Ľ',
+ 'ŀ' => 'Ŀ',
+ 'ł' => 'Ł',
+ 'ń' => 'Ń',
+ 'ņ' => 'Ņ',
+ 'ň' => 'Ň',
+ 'ŋ' => 'Ŋ',
+ 'ō' => 'Ō',
+ 'ŏ' => 'Ŏ',
+ 'ő' => 'Ő',
+ 'œ' => 'Œ',
+ 'ŕ' => 'Ŕ',
+ 'ŗ' => 'Ŗ',
+ 'ř' => 'Ř',
+ 'ś' => 'Ś',
+ 'ŝ' => 'Ŝ',
+ 'ş' => 'Ş',
+ 'š' => 'Š',
+ 'ţ' => 'Ţ',
+ 'ť' => 'Ť',
+ 'ŧ' => 'Ŧ',
+ 'ũ' => 'Ũ',
+ 'ū' => 'Ū',
+ 'ŭ' => 'Ŭ',
+ 'ů' => 'Ů',
+ 'ű' => 'Ű',
+ 'ų' => 'Ų',
+ 'ŵ' => 'Ŵ',
+ 'ŷ' => 'Ŷ',
+ 'ź' => 'Ź',
+ 'ż' => 'Ż',
+ 'ž' => 'Ž',
+ 'ſ' => 'S',
+ 'ƀ' => 'Ƀ',
+ 'ƃ' => 'Ƃ',
+ 'ƅ' => 'Ƅ',
+ 'ƈ' => 'Ƈ',
+ 'ƌ' => 'Ƌ',
+ 'ƒ' => 'Ƒ',
+ 'ƕ' => 'Ƕ',
+ 'ƙ' => 'Ƙ',
+ 'ƚ' => 'Ƚ',
+ 'ƞ' => 'Ƞ',
+ 'ơ' => 'Ơ',
+ 'ƣ' => 'Ƣ',
+ 'ƥ' => 'Ƥ',
+ 'ƨ' => 'Ƨ',
+ 'ƭ' => 'Ƭ',
+ 'ư' => 'Ư',
+ 'ƴ' => 'Ƴ',
+ 'ƶ' => 'Ƶ',
+ 'ƹ' => 'Ƹ',
+ 'ƽ' => 'Ƽ',
+ 'ƿ' => 'Ƿ',
+ 'Dž' => 'DŽ',
+ 'dž' => 'DŽ',
+ 'Lj' => 'LJ',
+ 'lj' => 'LJ',
+ 'Nj' => 'NJ',
+ 'nj' => 'NJ',
+ 'ǎ' => 'Ǎ',
+ 'ǐ' => 'Ǐ',
+ 'ǒ' => 'Ǒ',
+ 'ǔ' => 'Ǔ',
+ 'ǖ' => 'Ǖ',
+ 'ǘ' => 'Ǘ',
+ 'ǚ' => 'Ǚ',
+ 'ǜ' => 'Ǜ',
+ 'ǝ' => 'Ǝ',
+ 'ǟ' => 'Ǟ',
+ 'ǡ' => 'Ǡ',
+ 'ǣ' => 'Ǣ',
+ 'ǥ' => 'Ǥ',
+ 'ǧ' => 'Ǧ',
+ 'ǩ' => 'Ǩ',
+ 'ǫ' => 'Ǫ',
+ 'ǭ' => 'Ǭ',
+ 'ǯ' => 'Ǯ',
+ 'Dz' => 'DZ',
+ 'dz' => 'DZ',
+ 'ǵ' => 'Ǵ',
+ 'ǹ' => 'Ǹ',
+ 'ǻ' => 'Ǻ',
+ 'ǽ' => 'Ǽ',
+ 'ǿ' => 'Ǿ',
+ 'ȁ' => 'Ȁ',
+ 'ȃ' => 'Ȃ',
+ 'ȅ' => 'Ȅ',
+ 'ȇ' => 'Ȇ',
+ 'ȉ' => 'Ȉ',
+ 'ȋ' => 'Ȋ',
+ 'ȍ' => 'Ȍ',
+ 'ȏ' => 'Ȏ',
+ 'ȑ' => 'Ȑ',
+ 'ȓ' => 'Ȓ',
+ 'ȕ' => 'Ȕ',
+ 'ȗ' => 'Ȗ',
+ 'ș' => 'Ș',
+ 'ț' => 'Ț',
+ 'ȝ' => 'Ȝ',
+ 'ȟ' => 'Ȟ',
+ 'ȣ' => 'Ȣ',
+ 'ȥ' => 'Ȥ',
+ 'ȧ' => 'Ȧ',
+ 'ȩ' => 'Ȩ',
+ 'ȫ' => 'Ȫ',
+ 'ȭ' => 'Ȭ',
+ 'ȯ' => 'Ȯ',
+ 'ȱ' => 'Ȱ',
+ 'ȳ' => 'Ȳ',
+ 'ȼ' => 'Ȼ',
+ 'ȿ' => 'Ȿ',
+ 'ɀ' => 'Ɀ',
+ 'ɂ' => 'Ɂ',
+ 'ɇ' => 'Ɇ',
+ 'ɉ' => 'Ɉ',
+ 'ɋ' => 'Ɋ',
+ 'ɍ' => 'Ɍ',
+ 'ɏ' => 'Ɏ',
+ 'ɐ' => 'Ɐ',
+ 'ɑ' => 'Ɑ',
+ 'ɒ' => 'Ɒ',
+ 'ɓ' => 'Ɓ',
+ 'ɔ' => 'Ɔ',
+ 'ɖ' => 'Ɖ',
+ 'ɗ' => 'Ɗ',
+ 'ə' => 'Ə',
+ 'ɛ' => 'Ɛ',
+ 'ɜ' => 'Ɜ',
+ 'ɠ' => 'Ɠ',
+ 'ɡ' => 'Ɡ',
+ 'ɣ' => 'Ɣ',
+ 'ɥ' => 'Ɥ',
+ 'ɦ' => 'Ɦ',
+ 'ɨ' => 'Ɨ',
+ 'ɩ' => 'Ɩ',
+ 'ɫ' => 'Ɫ',
+ 'ɬ' => 'Ɬ',
+ 'ɯ' => 'Ɯ',
+ 'ɱ' => 'Ɱ',
+ 'ɲ' => 'Ɲ',
+ 'ɵ' => 'Ɵ',
+ 'ɽ' => 'Ɽ',
+ 'ʀ' => 'Ʀ',
+ 'ʃ' => 'Ʃ',
+ 'ʇ' => 'Ʇ',
+ 'ʈ' => 'Ʈ',
+ 'ʉ' => 'Ʉ',
+ 'ʊ' => 'Ʊ',
+ 'ʋ' => 'Ʋ',
+ 'ʌ' => 'Ʌ',
+ 'ʒ' => 'Ʒ',
+ 'ʞ' => 'Ʞ',
+ 'ͅ' => 'Ι',
+ 'ͱ' => 'Ͱ',
+ 'ͳ' => 'Ͳ',
+ 'ͷ' => 'Ͷ',
+ 'ͻ' => 'Ͻ',
+ 'ͼ' => 'Ͼ',
+ 'ͽ' => 'Ͽ',
+ 'ά' => 'Ά',
+ 'έ' => 'Έ',
+ 'ή' => 'Ή',
+ 'ί' => 'Ί',
+ 'α' => 'Α',
+ 'β' => 'Β',
+ 'γ' => 'Γ',
+ 'δ' => 'Δ',
+ 'ε' => 'Ε',
+ 'ζ' => 'Ζ',
+ 'η' => 'Η',
+ 'θ' => 'Θ',
+ 'ι' => 'Ι',
+ 'κ' => 'Κ',
+ 'λ' => 'Λ',
+ 'μ' => 'Μ',
+ 'ν' => 'Ν',
+ 'ξ' => 'Ξ',
+ 'ο' => 'Ο',
+ 'π' => 'Π',
+ 'ρ' => 'Ρ',
+ 'ς' => 'Σ',
+ 'σ' => 'Σ',
+ 'τ' => 'Τ',
+ 'υ' => 'Υ',
+ 'φ' => 'Φ',
+ 'χ' => 'Χ',
+ 'ψ' => 'Ψ',
+ 'ω' => 'Ω',
+ 'ϊ' => 'Ϊ',
+ 'ϋ' => 'Ϋ',
+ 'ό' => 'Ό',
+ 'ύ' => 'Ύ',
+ 'ώ' => 'Ώ',
+ 'ϐ' => 'Β',
+ 'ϑ' => 'Θ',
+ 'ϕ' => 'Φ',
+ 'ϖ' => 'Π',
+ 'ϗ' => 'Ϗ',
+ 'ϙ' => 'Ϙ',
+ 'ϛ' => 'Ϛ',
+ 'ϝ' => 'Ϝ',
+ 'ϟ' => 'Ϟ',
+ 'ϡ' => 'Ϡ',
+ 'ϣ' => 'Ϣ',
+ 'ϥ' => 'Ϥ',
+ 'ϧ' => 'Ϧ',
+ 'ϩ' => 'Ϩ',
+ 'ϫ' => 'Ϫ',
+ 'ϭ' => 'Ϭ',
+ 'ϯ' => 'Ϯ',
+ 'ϰ' => 'Κ',
+ 'ϱ' => 'Ρ',
+ 'ϲ' => 'Ϲ',
+ 'ϳ' => 'Ϳ',
+ 'ϵ' => 'Ε',
+ 'ϸ' => 'Ϸ',
+ 'ϻ' => 'Ϻ',
+ 'а' => 'А',
+ 'б' => 'Б',
+ 'в' => 'В',
+ 'г' => 'Г',
+ 'д' => 'Д',
+ 'е' => 'Е',
+ 'ж' => 'Ж',
+ 'з' => 'З',
+ 'и' => 'И',
+ 'й' => 'Й',
+ 'к' => 'К',
+ 'л' => 'Л',
+ 'м' => 'М',
+ 'н' => 'Н',
+ 'о' => 'О',
+ 'п' => 'П',
+ 'р' => 'Р',
+ 'с' => 'С',
+ 'т' => 'Т',
+ 'у' => 'У',
+ 'ф' => 'Ф',
+ 'х' => 'Х',
+ 'ц' => 'Ц',
+ 'ч' => 'Ч',
+ 'ш' => 'Ш',
+ 'щ' => 'Щ',
+ 'ъ' => 'Ъ',
+ 'ы' => 'Ы',
+ 'ь' => 'Ь',
+ 'э' => 'Э',
+ 'ю' => 'Ю',
+ 'я' => 'Я',
+ 'ѐ' => 'Ѐ',
+ 'ё' => 'Ё',
+ 'ђ' => 'Ђ',
+ 'ѓ' => 'Ѓ',
+ 'є' => 'Є',
+ 'ѕ' => 'Ѕ',
+ 'і' => 'І',
+ 'ї' => 'Ї',
+ 'ј' => 'Ј',
+ 'љ' => 'Љ',
+ 'њ' => 'Њ',
+ 'ћ' => 'Ћ',
+ 'ќ' => 'Ќ',
+ 'ѝ' => 'Ѝ',
+ 'ў' => 'Ў',
+ 'џ' => 'Џ',
+ 'ѡ' => 'Ѡ',
+ 'ѣ' => 'Ѣ',
+ 'ѥ' => 'Ѥ',
+ 'ѧ' => 'Ѧ',
+ 'ѩ' => 'Ѩ',
+ 'ѫ' => 'Ѫ',
+ 'ѭ' => 'Ѭ',
+ 'ѯ' => 'Ѯ',
+ 'ѱ' => 'Ѱ',
+ 'ѳ' => 'Ѳ',
+ 'ѵ' => 'Ѵ',
+ 'ѷ' => 'Ѷ',
+ 'ѹ' => 'Ѹ',
+ 'ѻ' => 'Ѻ',
+ 'ѽ' => 'Ѽ',
+ 'ѿ' => 'Ѿ',
+ 'ҁ' => 'Ҁ',
+ 'ҋ' => 'Ҋ',
+ 'ҍ' => 'Ҍ',
+ 'ҏ' => 'Ҏ',
+ 'ґ' => 'Ґ',
+ 'ғ' => 'Ғ',
+ 'ҕ' => 'Ҕ',
+ 'җ' => 'Җ',
+ 'ҙ' => 'Ҙ',
+ 'қ' => 'Қ',
+ 'ҝ' => 'Ҝ',
+ 'ҟ' => 'Ҟ',
+ 'ҡ' => 'Ҡ',
+ 'ң' => 'Ң',
+ 'ҥ' => 'Ҥ',
+ 'ҧ' => 'Ҧ',
+ 'ҩ' => 'Ҩ',
+ 'ҫ' => 'Ҫ',
+ 'ҭ' => 'Ҭ',
+ 'ү' => 'Ү',
+ 'ұ' => 'Ұ',
+ 'ҳ' => 'Ҳ',
+ 'ҵ' => 'Ҵ',
+ 'ҷ' => 'Ҷ',
+ 'ҹ' => 'Ҹ',
+ 'һ' => 'Һ',
+ 'ҽ' => 'Ҽ',
+ 'ҿ' => 'Ҿ',
+ 'ӂ' => 'Ӂ',
+ 'ӄ' => 'Ӄ',
+ 'ӆ' => 'Ӆ',
+ 'ӈ' => 'Ӈ',
+ 'ӊ' => 'Ӊ',
+ 'ӌ' => 'Ӌ',
+ 'ӎ' => 'Ӎ',
+ 'ӏ' => 'Ӏ',
+ 'ӑ' => 'Ӑ',
+ 'ӓ' => 'Ӓ',
+ 'ӕ' => 'Ӕ',
+ 'ӗ' => 'Ӗ',
+ 'ә' => 'Ә',
+ 'ӛ' => 'Ӛ',
+ 'ӝ' => 'Ӝ',
+ 'ӟ' => 'Ӟ',
+ 'ӡ' => 'Ӡ',
+ 'ӣ' => 'Ӣ',
+ 'ӥ' => 'Ӥ',
+ 'ӧ' => 'Ӧ',
+ 'ө' => 'Ө',
+ 'ӫ' => 'Ӫ',
+ 'ӭ' => 'Ӭ',
+ 'ӯ' => 'Ӯ',
+ 'ӱ' => 'Ӱ',
+ 'ӳ' => 'Ӳ',
+ 'ӵ' => 'Ӵ',
+ 'ӷ' => 'Ӷ',
+ 'ӹ' => 'Ӹ',
+ 'ӻ' => 'Ӻ',
+ 'ӽ' => 'Ӽ',
+ 'ӿ' => 'Ӿ',
+ 'ԁ' => 'Ԁ',
+ 'ԃ' => 'Ԃ',
+ 'ԅ' => 'Ԅ',
+ 'ԇ' => 'Ԇ',
+ 'ԉ' => 'Ԉ',
+ 'ԋ' => 'Ԋ',
+ 'ԍ' => 'Ԍ',
+ 'ԏ' => 'Ԏ',
+ 'ԑ' => 'Ԑ',
+ 'ԓ' => 'Ԓ',
+ 'ԕ' => 'Ԕ',
+ 'ԗ' => 'Ԗ',
+ 'ԙ' => 'Ԙ',
+ 'ԛ' => 'Ԛ',
+ 'ԝ' => 'Ԝ',
+ 'ԟ' => 'Ԟ',
+ 'ԡ' => 'Ԡ',
+ 'ԣ' => 'Ԣ',
+ 'ԥ' => 'Ԥ',
+ 'ԧ' => 'Ԧ',
+ 'ԩ' => 'Ԩ',
+ 'ԫ' => 'Ԫ',
+ 'ԭ' => 'Ԭ',
+ 'ԯ' => 'Ԯ',
+ 'ա' => 'Ա',
+ 'բ' => 'Բ',
+ 'գ' => 'Գ',
+ 'դ' => 'Դ',
+ 'ե' => 'Ե',
+ 'զ' => 'Զ',
+ 'է' => 'Է',
+ 'ը' => 'Ը',
+ 'թ' => 'Թ',
+ 'ժ' => 'Ժ',
+ 'ի' => 'Ի',
+ 'լ' => 'Լ',
+ 'խ' => 'Խ',
+ 'ծ' => 'Ծ',
+ 'կ' => 'Կ',
+ 'հ' => 'Հ',
+ 'ձ' => 'Ձ',
+ 'ղ' => 'Ղ',
+ 'ճ' => 'Ճ',
+ 'մ' => 'Մ',
+ 'յ' => 'Յ',
+ 'ն' => 'Ն',
+ 'շ' => 'Շ',
+ 'ո' => 'Ո',
+ 'չ' => 'Չ',
+ 'պ' => 'Պ',
+ 'ջ' => 'Ջ',
+ 'ռ' => 'Ռ',
+ 'ս' => 'Ս',
+ 'վ' => 'Վ',
+ 'տ' => 'Տ',
+ 'ր' => 'Ր',
+ 'ց' => 'Ց',
+ 'ւ' => 'Ւ',
+ 'փ' => 'Փ',
+ 'ք' => 'Ք',
+ 'օ' => 'Օ',
+ 'ֆ' => 'Ֆ',
+ 'ᵹ' => 'Ᵹ',
+ 'ᵽ' => 'Ᵽ',
+ 'ḁ' => 'Ḁ',
+ 'ḃ' => 'Ḃ',
+ 'ḅ' => 'Ḅ',
+ 'ḇ' => 'Ḇ',
+ 'ḉ' => 'Ḉ',
+ 'ḋ' => 'Ḋ',
+ 'ḍ' => 'Ḍ',
+ 'ḏ' => 'Ḏ',
+ 'ḑ' => 'Ḑ',
+ 'ḓ' => 'Ḓ',
+ 'ḕ' => 'Ḕ',
+ 'ḗ' => 'Ḗ',
+ 'ḙ' => 'Ḙ',
+ 'ḛ' => 'Ḛ',
+ 'ḝ' => 'Ḝ',
+ 'ḟ' => 'Ḟ',
+ 'ḡ' => 'Ḡ',
+ 'ḣ' => 'Ḣ',
+ 'ḥ' => 'Ḥ',
+ 'ḧ' => 'Ḧ',
+ 'ḩ' => 'Ḩ',
+ 'ḫ' => 'Ḫ',
+ 'ḭ' => 'Ḭ',
+ 'ḯ' => 'Ḯ',
+ 'ḱ' => 'Ḱ',
+ 'ḳ' => 'Ḳ',
+ 'ḵ' => 'Ḵ',
+ 'ḷ' => 'Ḷ',
+ 'ḹ' => 'Ḹ',
+ 'ḻ' => 'Ḻ',
+ 'ḽ' => 'Ḽ',
+ 'ḿ' => 'Ḿ',
+ 'ṁ' => 'Ṁ',
+ 'ṃ' => 'Ṃ',
+ 'ṅ' => 'Ṅ',
+ 'ṇ' => 'Ṇ',
+ 'ṉ' => 'Ṉ',
+ 'ṋ' => 'Ṋ',
+ 'ṍ' => 'Ṍ',
+ 'ṏ' => 'Ṏ',
+ 'ṑ' => 'Ṑ',
+ 'ṓ' => 'Ṓ',
+ 'ṕ' => 'Ṕ',
+ 'ṗ' => 'Ṗ',
+ 'ṙ' => 'Ṙ',
+ 'ṛ' => 'Ṛ',
+ 'ṝ' => 'Ṝ',
+ 'ṟ' => 'Ṟ',
+ 'ṡ' => 'Ṡ',
+ 'ṣ' => 'Ṣ',
+ 'ṥ' => 'Ṥ',
+ 'ṧ' => 'Ṧ',
+ 'ṩ' => 'Ṩ',
+ 'ṫ' => 'Ṫ',
+ 'ṭ' => 'Ṭ',
+ 'ṯ' => 'Ṯ',
+ 'ṱ' => 'Ṱ',
+ 'ṳ' => 'Ṳ',
+ 'ṵ' => 'Ṵ',
+ 'ṷ' => 'Ṷ',
+ 'ṹ' => 'Ṹ',
+ 'ṻ' => 'Ṻ',
+ 'ṽ' => 'Ṽ',
+ 'ṿ' => 'Ṿ',
+ 'ẁ' => 'Ẁ',
+ 'ẃ' => 'Ẃ',
+ 'ẅ' => 'Ẅ',
+ 'ẇ' => 'Ẇ',
+ 'ẉ' => 'Ẉ',
+ 'ẋ' => 'Ẋ',
+ 'ẍ' => 'Ẍ',
+ 'ẏ' => 'Ẏ',
+ 'ẑ' => 'Ẑ',
+ 'ẓ' => 'Ẓ',
+ 'ẕ' => 'Ẕ',
+ 'ẛ' => 'Ṡ',
+ 'ạ' => 'Ạ',
+ 'ả' => 'Ả',
+ 'ấ' => 'Ấ',
+ 'ầ' => 'Ầ',
+ 'ẩ' => 'Ẩ',
+ 'ẫ' => 'Ẫ',
+ 'ậ' => 'Ậ',
+ 'ắ' => 'Ắ',
+ 'ằ' => 'Ằ',
+ 'ẳ' => 'Ẳ',
+ 'ẵ' => 'Ẵ',
+ 'ặ' => 'Ặ',
+ 'ẹ' => 'Ẹ',
+ 'ẻ' => 'Ẻ',
+ 'ẽ' => 'Ẽ',
+ 'ế' => 'Ế',
+ 'ề' => 'Ề',
+ 'ể' => 'Ể',
+ 'ễ' => 'Ễ',
+ 'ệ' => 'Ệ',
+ 'ỉ' => 'Ỉ',
+ 'ị' => 'Ị',
+ 'ọ' => 'Ọ',
+ 'ỏ' => 'Ỏ',
+ 'ố' => 'Ố',
+ 'ồ' => 'Ồ',
+ 'ổ' => 'Ổ',
+ 'ỗ' => 'Ỗ',
+ 'ộ' => 'Ộ',
+ 'ớ' => 'Ớ',
+ 'ờ' => 'Ờ',
+ 'ở' => 'Ở',
+ 'ỡ' => 'Ỡ',
+ 'ợ' => 'Ợ',
+ 'ụ' => 'Ụ',
+ 'ủ' => 'Ủ',
+ 'ứ' => 'Ứ',
+ 'ừ' => 'Ừ',
+ 'ử' => 'Ử',
+ 'ữ' => 'Ữ',
+ 'ự' => 'Ự',
+ 'ỳ' => 'Ỳ',
+ 'ỵ' => 'Ỵ',
+ 'ỷ' => 'Ỷ',
+ 'ỹ' => 'Ỹ',
+ 'ỻ' => 'Ỻ',
+ 'ỽ' => 'Ỽ',
+ 'ỿ' => 'Ỿ',
+ 'ἀ' => 'Ἀ',
+ 'ἁ' => 'Ἁ',
+ 'ἂ' => 'Ἂ',
+ 'ἃ' => 'Ἃ',
+ 'ἄ' => 'Ἄ',
+ 'ἅ' => 'Ἅ',
+ 'ἆ' => 'Ἆ',
+ 'ἇ' => 'Ἇ',
+ 'ἐ' => 'Ἐ',
+ 'ἑ' => 'Ἑ',
+ 'ἒ' => 'Ἒ',
+ 'ἓ' => 'Ἓ',
+ 'ἔ' => 'Ἔ',
+ 'ἕ' => 'Ἕ',
+ 'ἠ' => 'Ἠ',
+ 'ἡ' => 'Ἡ',
+ 'ἢ' => 'Ἢ',
+ 'ἣ' => 'Ἣ',
+ 'ἤ' => 'Ἤ',
+ 'ἥ' => 'Ἥ',
+ 'ἦ' => 'Ἦ',
+ 'ἧ' => 'Ἧ',
+ 'ἰ' => 'Ἰ',
+ 'ἱ' => 'Ἱ',
+ 'ἲ' => 'Ἲ',
+ 'ἳ' => 'Ἳ',
+ 'ἴ' => 'Ἴ',
+ 'ἵ' => 'Ἵ',
+ 'ἶ' => 'Ἶ',
+ 'ἷ' => 'Ἷ',
+ 'ὀ' => 'Ὀ',
+ 'ὁ' => 'Ὁ',
+ 'ὂ' => 'Ὂ',
+ 'ὃ' => 'Ὃ',
+ 'ὄ' => 'Ὄ',
+ 'ὅ' => 'Ὅ',
+ 'ὑ' => 'Ὑ',
+ 'ὓ' => 'Ὓ',
+ 'ὕ' => 'Ὕ',
+ 'ὗ' => 'Ὗ',
+ 'ὠ' => 'Ὠ',
+ 'ὡ' => 'Ὡ',
+ 'ὢ' => 'Ὢ',
+ 'ὣ' => 'Ὣ',
+ 'ὤ' => 'Ὤ',
+ 'ὥ' => 'Ὥ',
+ 'ὦ' => 'Ὦ',
+ 'ὧ' => 'Ὧ',
+ 'ὰ' => 'Ὰ',
+ 'ά' => 'Ά',
+ 'ὲ' => 'Ὲ',
+ 'έ' => 'Έ',
+ 'ὴ' => 'Ὴ',
+ 'ή' => 'Ή',
+ 'ὶ' => 'Ὶ',
+ 'ί' => 'Ί',
+ 'ὸ' => 'Ὸ',
+ 'ό' => 'Ό',
+ 'ὺ' => 'Ὺ',
+ 'ύ' => 'Ύ',
+ 'ὼ' => 'Ὼ',
+ 'ώ' => 'Ώ',
+ 'ᾀ' => 'ᾈ',
+ 'ᾁ' => 'ᾉ',
+ 'ᾂ' => 'ᾊ',
+ 'ᾃ' => 'ᾋ',
+ 'ᾄ' => 'ᾌ',
+ 'ᾅ' => 'ᾍ',
+ 'ᾆ' => 'ᾎ',
+ 'ᾇ' => 'ᾏ',
+ 'ᾐ' => 'ᾘ',
+ 'ᾑ' => 'ᾙ',
+ 'ᾒ' => 'ᾚ',
+ 'ᾓ' => 'ᾛ',
+ 'ᾔ' => 'ᾜ',
+ 'ᾕ' => 'ᾝ',
+ 'ᾖ' => 'ᾞ',
+ 'ᾗ' => 'ᾟ',
+ 'ᾠ' => 'ᾨ',
+ 'ᾡ' => 'ᾩ',
+ 'ᾢ' => 'ᾪ',
+ 'ᾣ' => 'ᾫ',
+ 'ᾤ' => 'ᾬ',
+ 'ᾥ' => 'ᾭ',
+ 'ᾦ' => 'ᾮ',
+ 'ᾧ' => 'ᾯ',
+ 'ᾰ' => 'Ᾰ',
+ 'ᾱ' => 'Ᾱ',
+ 'ᾳ' => 'ᾼ',
+ 'ι' => 'Ι',
+ 'ῃ' => 'ῌ',
+ 'ῐ' => 'Ῐ',
+ 'ῑ' => 'Ῑ',
+ 'ῠ' => 'Ῠ',
+ 'ῡ' => 'Ῡ',
+ 'ῥ' => 'Ῥ',
+ 'ῳ' => 'ῼ',
+ 'ⅎ' => 'Ⅎ',
+ 'ⅰ' => 'Ⅰ',
+ 'ⅱ' => 'Ⅱ',
+ 'ⅲ' => 'Ⅲ',
+ 'ⅳ' => 'Ⅳ',
+ 'ⅴ' => 'Ⅴ',
+ 'ⅵ' => 'Ⅵ',
+ 'ⅶ' => 'Ⅶ',
+ 'ⅷ' => 'Ⅷ',
+ 'ⅸ' => 'Ⅸ',
+ 'ⅹ' => 'Ⅹ',
+ 'ⅺ' => 'Ⅺ',
+ 'ⅻ' => 'Ⅻ',
+ 'ⅼ' => 'Ⅼ',
+ 'ⅽ' => 'Ⅽ',
+ 'ⅾ' => 'Ⅾ',
+ 'ⅿ' => 'Ⅿ',
+ 'ↄ' => 'Ↄ',
+ 'ⓐ' => 'Ⓐ',
+ 'ⓑ' => 'Ⓑ',
+ 'ⓒ' => 'Ⓒ',
+ 'ⓓ' => 'Ⓓ',
+ 'ⓔ' => 'Ⓔ',
+ 'ⓕ' => 'Ⓕ',
+ 'ⓖ' => 'Ⓖ',
+ 'ⓗ' => 'Ⓗ',
+ 'ⓘ' => 'Ⓘ',
+ 'ⓙ' => 'Ⓙ',
+ 'ⓚ' => 'Ⓚ',
+ 'ⓛ' => 'Ⓛ',
+ 'ⓜ' => 'Ⓜ',
+ 'ⓝ' => 'Ⓝ',
+ 'ⓞ' => 'Ⓞ',
+ 'ⓟ' => 'Ⓟ',
+ 'ⓠ' => 'Ⓠ',
+ 'ⓡ' => 'Ⓡ',
+ 'ⓢ' => 'Ⓢ',
+ 'ⓣ' => 'Ⓣ',
+ 'ⓤ' => 'Ⓤ',
+ 'ⓥ' => 'Ⓥ',
+ 'ⓦ' => 'Ⓦ',
+ 'ⓧ' => 'Ⓧ',
+ 'ⓨ' => 'Ⓨ',
+ 'ⓩ' => 'Ⓩ',
+ 'ⰰ' => 'Ⰰ',
+ 'ⰱ' => 'Ⰱ',
+ 'ⰲ' => 'Ⰲ',
+ 'ⰳ' => 'Ⰳ',
+ 'ⰴ' => 'Ⰴ',
+ 'ⰵ' => 'Ⰵ',
+ 'ⰶ' => 'Ⰶ',
+ 'ⰷ' => 'Ⰷ',
+ 'ⰸ' => 'Ⰸ',
+ 'ⰹ' => 'Ⰹ',
+ 'ⰺ' => 'Ⰺ',
+ 'ⰻ' => 'Ⰻ',
+ 'ⰼ' => 'Ⰼ',
+ 'ⰽ' => 'Ⰽ',
+ 'ⰾ' => 'Ⰾ',
+ 'ⰿ' => 'Ⰿ',
+ 'ⱀ' => 'Ⱀ',
+ 'ⱁ' => 'Ⱁ',
+ 'ⱂ' => 'Ⱂ',
+ 'ⱃ' => 'Ⱃ',
+ 'ⱄ' => 'Ⱄ',
+ 'ⱅ' => 'Ⱅ',
+ 'ⱆ' => 'Ⱆ',
+ 'ⱇ' => 'Ⱇ',
+ 'ⱈ' => 'Ⱈ',
+ 'ⱉ' => 'Ⱉ',
+ 'ⱊ' => 'Ⱊ',
+ 'ⱋ' => 'Ⱋ',
+ 'ⱌ' => 'Ⱌ',
+ 'ⱍ' => 'Ⱍ',
+ 'ⱎ' => 'Ⱎ',
+ 'ⱏ' => 'Ⱏ',
+ 'ⱐ' => 'Ⱐ',
+ 'ⱑ' => 'Ⱑ',
+ 'ⱒ' => 'Ⱒ',
+ 'ⱓ' => 'Ⱓ',
+ 'ⱔ' => 'Ⱔ',
+ 'ⱕ' => 'Ⱕ',
+ 'ⱖ' => 'Ⱖ',
+ 'ⱗ' => 'Ⱗ',
+ 'ⱘ' => 'Ⱘ',
+ 'ⱙ' => 'Ⱙ',
+ 'ⱚ' => 'Ⱚ',
+ 'ⱛ' => 'Ⱛ',
+ 'ⱜ' => 'Ⱜ',
+ 'ⱝ' => 'Ⱝ',
+ 'ⱞ' => 'Ⱞ',
+ 'ⱡ' => 'Ⱡ',
+ 'ⱥ' => 'Ⱥ',
+ 'ⱦ' => 'Ⱦ',
+ 'ⱨ' => 'Ⱨ',
+ 'ⱪ' => 'Ⱪ',
+ 'ⱬ' => 'Ⱬ',
+ 'ⱳ' => 'Ⱳ',
+ 'ⱶ' => 'Ⱶ',
+ 'ⲁ' => 'Ⲁ',
+ 'ⲃ' => 'Ⲃ',
+ 'ⲅ' => 'Ⲅ',
+ 'ⲇ' => 'Ⲇ',
+ 'ⲉ' => 'Ⲉ',
+ 'ⲋ' => 'Ⲋ',
+ 'ⲍ' => 'Ⲍ',
+ 'ⲏ' => 'Ⲏ',
+ 'ⲑ' => 'Ⲑ',
+ 'ⲓ' => 'Ⲓ',
+ 'ⲕ' => 'Ⲕ',
+ 'ⲗ' => 'Ⲗ',
+ 'ⲙ' => 'Ⲙ',
+ 'ⲛ' => 'Ⲛ',
+ 'ⲝ' => 'Ⲝ',
+ 'ⲟ' => 'Ⲟ',
+ 'ⲡ' => 'Ⲡ',
+ 'ⲣ' => 'Ⲣ',
+ 'ⲥ' => 'Ⲥ',
+ 'ⲧ' => 'Ⲧ',
+ 'ⲩ' => 'Ⲩ',
+ 'ⲫ' => 'Ⲫ',
+ 'ⲭ' => 'Ⲭ',
+ 'ⲯ' => 'Ⲯ',
+ 'ⲱ' => 'Ⲱ',
+ 'ⲳ' => 'Ⲳ',
+ 'ⲵ' => 'Ⲵ',
+ 'ⲷ' => 'Ⲷ',
+ 'ⲹ' => 'Ⲹ',
+ 'ⲻ' => 'Ⲻ',
+ 'ⲽ' => 'Ⲽ',
+ 'ⲿ' => 'Ⲿ',
+ 'ⳁ' => 'Ⳁ',
+ 'ⳃ' => 'Ⳃ',
+ 'ⳅ' => 'Ⳅ',
+ 'ⳇ' => 'Ⳇ',
+ 'ⳉ' => 'Ⳉ',
+ 'ⳋ' => 'Ⳋ',
+ 'ⳍ' => 'Ⳍ',
+ 'ⳏ' => 'Ⳏ',
+ 'ⳑ' => 'Ⳑ',
+ 'ⳓ' => 'Ⳓ',
+ 'ⳕ' => 'Ⳕ',
+ 'ⳗ' => 'Ⳗ',
+ 'ⳙ' => 'Ⳙ',
+ 'ⳛ' => 'Ⳛ',
+ 'ⳝ' => 'Ⳝ',
+ 'ⳟ' => 'Ⳟ',
+ 'ⳡ' => 'Ⳡ',
+ 'ⳣ' => 'Ⳣ',
+ 'ⳬ' => 'Ⳬ',
+ 'ⳮ' => 'Ⳮ',
+ 'ⳳ' => 'Ⳳ',
+ 'ⴀ' => 'Ⴀ',
+ 'ⴁ' => 'Ⴁ',
+ 'ⴂ' => 'Ⴂ',
+ 'ⴃ' => 'Ⴃ',
+ 'ⴄ' => 'Ⴄ',
+ 'ⴅ' => 'Ⴅ',
+ 'ⴆ' => 'Ⴆ',
+ 'ⴇ' => 'Ⴇ',
+ 'ⴈ' => 'Ⴈ',
+ 'ⴉ' => 'Ⴉ',
+ 'ⴊ' => 'Ⴊ',
+ 'ⴋ' => 'Ⴋ',
+ 'ⴌ' => 'Ⴌ',
+ 'ⴍ' => 'Ⴍ',
+ 'ⴎ' => 'Ⴎ',
+ 'ⴏ' => 'Ⴏ',
+ 'ⴐ' => 'Ⴐ',
+ 'ⴑ' => 'Ⴑ',
+ 'ⴒ' => 'Ⴒ',
+ 'ⴓ' => 'Ⴓ',
+ 'ⴔ' => 'Ⴔ',
+ 'ⴕ' => 'Ⴕ',
+ 'ⴖ' => 'Ⴖ',
+ 'ⴗ' => 'Ⴗ',
+ 'ⴘ' => 'Ⴘ',
+ 'ⴙ' => 'Ⴙ',
+ 'ⴚ' => 'Ⴚ',
+ 'ⴛ' => 'Ⴛ',
+ 'ⴜ' => 'Ⴜ',
+ 'ⴝ' => 'Ⴝ',
+ 'ⴞ' => 'Ⴞ',
+ 'ⴟ' => 'Ⴟ',
+ 'ⴠ' => 'Ⴠ',
+ 'ⴡ' => 'Ⴡ',
+ 'ⴢ' => 'Ⴢ',
+ 'ⴣ' => 'Ⴣ',
+ 'ⴤ' => 'Ⴤ',
+ 'ⴥ' => 'Ⴥ',
+ 'ⴧ' => 'Ⴧ',
+ 'ⴭ' => 'Ⴭ',
+ 'ꙁ' => 'Ꙁ',
+ 'ꙃ' => 'Ꙃ',
+ 'ꙅ' => 'Ꙅ',
+ 'ꙇ' => 'Ꙇ',
+ 'ꙉ' => 'Ꙉ',
+ 'ꙋ' => 'Ꙋ',
+ 'ꙍ' => 'Ꙍ',
+ 'ꙏ' => 'Ꙏ',
+ 'ꙑ' => 'Ꙑ',
+ 'ꙓ' => 'Ꙓ',
+ 'ꙕ' => 'Ꙕ',
+ 'ꙗ' => 'Ꙗ',
+ 'ꙙ' => 'Ꙙ',
+ 'ꙛ' => 'Ꙛ',
+ 'ꙝ' => 'Ꙝ',
+ 'ꙟ' => 'Ꙟ',
+ 'ꙡ' => 'Ꙡ',
+ 'ꙣ' => 'Ꙣ',
+ 'ꙥ' => 'Ꙥ',
+ 'ꙧ' => 'Ꙧ',
+ 'ꙩ' => 'Ꙩ',
+ 'ꙫ' => 'Ꙫ',
+ 'ꙭ' => 'Ꙭ',
+ 'ꚁ' => 'Ꚁ',
+ 'ꚃ' => 'Ꚃ',
+ 'ꚅ' => 'Ꚅ',
+ 'ꚇ' => 'Ꚇ',
+ 'ꚉ' => 'Ꚉ',
+ 'ꚋ' => 'Ꚋ',
+ 'ꚍ' => 'Ꚍ',
+ 'ꚏ' => 'Ꚏ',
+ 'ꚑ' => 'Ꚑ',
+ 'ꚓ' => 'Ꚓ',
+ 'ꚕ' => 'Ꚕ',
+ 'ꚗ' => 'Ꚗ',
+ 'ꚙ' => 'Ꚙ',
+ 'ꚛ' => 'Ꚛ',
+ 'ꜣ' => 'Ꜣ',
+ 'ꜥ' => 'Ꜥ',
+ 'ꜧ' => 'Ꜧ',
+ 'ꜩ' => 'Ꜩ',
+ 'ꜫ' => 'Ꜫ',
+ 'ꜭ' => 'Ꜭ',
+ 'ꜯ' => 'Ꜯ',
+ 'ꜳ' => 'Ꜳ',
+ 'ꜵ' => 'Ꜵ',
+ 'ꜷ' => 'Ꜷ',
+ 'ꜹ' => 'Ꜹ',
+ 'ꜻ' => 'Ꜻ',
+ 'ꜽ' => 'Ꜽ',
+ 'ꜿ' => 'Ꜿ',
+ 'ꝁ' => 'Ꝁ',
+ 'ꝃ' => 'Ꝃ',
+ 'ꝅ' => 'Ꝅ',
+ 'ꝇ' => 'Ꝇ',
+ 'ꝉ' => 'Ꝉ',
+ 'ꝋ' => 'Ꝋ',
+ 'ꝍ' => 'Ꝍ',
+ 'ꝏ' => 'Ꝏ',
+ 'ꝑ' => 'Ꝑ',
+ 'ꝓ' => 'Ꝓ',
+ 'ꝕ' => 'Ꝕ',
+ 'ꝗ' => 'Ꝗ',
+ 'ꝙ' => 'Ꝙ',
+ 'ꝛ' => 'Ꝛ',
+ 'ꝝ' => 'Ꝝ',
+ 'ꝟ' => 'Ꝟ',
+ 'ꝡ' => 'Ꝡ',
+ 'ꝣ' => 'Ꝣ',
+ 'ꝥ' => 'Ꝥ',
+ 'ꝧ' => 'Ꝧ',
+ 'ꝩ' => 'Ꝩ',
+ 'ꝫ' => 'Ꝫ',
+ 'ꝭ' => 'Ꝭ',
+ 'ꝯ' => 'Ꝯ',
+ 'ꝺ' => 'Ꝺ',
+ 'ꝼ' => 'Ꝼ',
+ 'ꝿ' => 'Ꝿ',
+ 'ꞁ' => 'Ꞁ',
+ 'ꞃ' => 'Ꞃ',
+ 'ꞅ' => 'Ꞅ',
+ 'ꞇ' => 'Ꞇ',
+ 'ꞌ' => 'Ꞌ',
+ 'ꞑ' => 'Ꞑ',
+ 'ꞓ' => 'Ꞓ',
+ 'ꞗ' => 'Ꞗ',
+ 'ꞙ' => 'Ꞙ',
+ 'ꞛ' => 'Ꞛ',
+ 'ꞝ' => 'Ꞝ',
+ 'ꞟ' => 'Ꞟ',
+ 'ꞡ' => 'Ꞡ',
+ 'ꞣ' => 'Ꞣ',
+ 'ꞥ' => 'Ꞥ',
+ 'ꞧ' => 'Ꞧ',
+ 'ꞩ' => 'Ꞩ',
+ 'a' => 'A',
+ 'b' => 'B',
+ 'c' => 'C',
+ 'd' => 'D',
+ 'e' => 'E',
+ 'f' => 'F',
+ 'g' => 'G',
+ 'h' => 'H',
+ 'i' => 'I',
+ 'j' => 'J',
+ 'k' => 'K',
+ 'l' => 'L',
+ 'm' => 'M',
+ 'n' => 'N',
+ 'o' => 'O',
+ 'p' => 'P',
+ 'q' => 'Q',
+ 'r' => 'R',
+ 's' => 'S',
+ 't' => 'T',
+ 'u' => 'U',
+ 'v' => 'V',
+ 'w' => 'W',
+ 'x' => 'X',
+ 'y' => 'Y',
+ 'z' => 'Z',
+ '𐐨' => '𐐀',
+ '𐐩' => '𐐁',
+ '𐐪' => '𐐂',
+ '𐐫' => '𐐃',
+ '𐐬' => '𐐄',
+ '𐐭' => '𐐅',
+ '𐐮' => '𐐆',
+ '𐐯' => '𐐇',
+ '𐐰' => '𐐈',
+ '𐐱' => '𐐉',
+ '𐐲' => '𐐊',
+ '𐐳' => '𐐋',
+ '𐐴' => '𐐌',
+ '𐐵' => '𐐍',
+ '𐐶' => '𐐎',
+ '𐐷' => '𐐏',
+ '𐐸' => '𐐐',
+ '𐐹' => '𐐑',
+ '𐐺' => '𐐒',
+ '𐐻' => '𐐓',
+ '𐐼' => '𐐔',
+ '𐐽' => '𐐕',
+ '𐐾' => '𐐖',
+ '𐐿' => '𐐗',
+ '𐑀' => '𐐘',
+ '𐑁' => '𐐙',
+ '𐑂' => '𐐚',
+ '𐑃' => '𐐛',
+ '𐑄' => '𐐜',
+ '𐑅' => '𐐝',
+ '𐑆' => '𐐞',
+ '𐑇' => '𐐟',
+ '𐑈' => '𐐠',
+ '𐑉' => '𐐡',
+ '𐑊' => '𐐢',
+ '𐑋' => '𐐣',
+ '𐑌' => '𐐤',
+ '𐑍' => '𐐥',
+ '𐑎' => '𐐦',
+ '𐑏' => '𐐧',
+ '𑣀' => '𑢠',
+ '𑣁' => '𑢡',
+ '𑣂' => '𑢢',
+ '𑣃' => '𑢣',
+ '𑣄' => '𑢤',
+ '𑣅' => '𑢥',
+ '𑣆' => '𑢦',
+ '𑣇' => '𑢧',
+ '𑣈' => '𑢨',
+ '𑣉' => '𑢩',
+ '𑣊' => '𑢪',
+ '𑣋' => '𑢫',
+ '𑣌' => '𑢬',
+ '𑣍' => '𑢭',
+ '𑣎' => '𑢮',
+ '𑣏' => '𑢯',
+ '𑣐' => '𑢰',
+ '𑣑' => '𑢱',
+ '𑣒' => '𑢲',
+ '𑣓' => '𑢳',
+ '𑣔' => '𑢴',
+ '𑣕' => '𑢵',
+ '𑣖' => '𑢶',
+ '𑣗' => '𑢷',
+ '𑣘' => '𑢸',
+ '𑣙' => '𑢹',
+ '𑣚' => '𑢺',
+ '𑣛' => '𑢻',
+ '𑣜' => '𑢼',
+ '𑣝' => '𑢽',
+ '𑣞' => '𑢾',
+ '𑣟' => '𑢿',
+);
+
+$result =& $data;
+unset($data);
+
+return $result;
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-mbstring/bootstrap.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-mbstring/bootstrap.php
new file mode 100644
index 0000000..2fdcc5a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-mbstring/bootstrap.php
@@ -0,0 +1,58 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use Symfony\Polyfill\Mbstring as p;
+
+if (!function_exists('mb_strlen')) {
+ define('MB_CASE_UPPER', 0);
+ define('MB_CASE_LOWER', 1);
+ define('MB_CASE_TITLE', 2);
+
+ function mb_convert_encoding($s, $to, $from = null) { return p\Mbstring::mb_convert_encoding($s, $to, $from); }
+ function mb_decode_mimeheader($s) { return p\Mbstring::mb_decode_mimeheader($s); }
+ function mb_encode_mimeheader($s, $charset = null, $transferEnc = null, $lf = null, $indent = null) { return p\Mbstring::mb_encode_mimeheader($s, $charset, $transferEnc, $lf, $indent); }
+ function mb_decode_numericentity($s, $convmap, $enc = null) { return p\Mbstring::mb_decode_numericentity($s, $convmap, $enc); }
+ function mb_encode_numericentity($s, $convmap, $enc = null, $is_hex = false) { return p\Mbstring::mb_encode_numericentity($s, $convmap, $enc, $is_hex); }
+ function mb_convert_case($s, $mode, $enc = null) { return p\Mbstring::mb_convert_case($s, $mode, $enc); }
+ function mb_internal_encoding($enc = null) { return p\Mbstring::mb_internal_encoding($enc); }
+ function mb_language($lang = null) { return p\Mbstring::mb_language($lang); }
+ function mb_list_encodings() { return p\Mbstring::mb_list_encodings(); }
+ function mb_encoding_aliases($encoding) { return p\Mbstring::mb_encoding_aliases($encoding); }
+ function mb_check_encoding($var = null, $encoding = null) { return p\Mbstring::mb_check_encoding($var, $encoding); }
+ function mb_detect_encoding($str, $encodingList = null, $strict = false) { return p\Mbstring::mb_detect_encoding($str, $encodingList, $strict); }
+ function mb_detect_order($encodingList = null) { return p\Mbstring::mb_detect_order($encodingList); }
+ function mb_parse_str($s, &$result = array()) { parse_str($s, $result); }
+ function mb_strlen($s, $enc = null) { return p\Mbstring::mb_strlen($s, $enc); }
+ function mb_strpos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_strpos($s, $needle, $offset, $enc); }
+ function mb_strtolower($s, $enc = null) { return p\Mbstring::mb_strtolower($s, $enc); }
+ function mb_strtoupper($s, $enc = null) { return p\Mbstring::mb_strtoupper($s, $enc); }
+ function mb_substitute_character($char = null) { return p\Mbstring::mb_substitute_character($char); }
+ function mb_substr($s, $start, $length = 2147483647, $enc = null) { return p\Mbstring::mb_substr($s, $start, $length, $enc); }
+ function mb_stripos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_stripos($s, $needle, $offset, $enc); }
+ function mb_stristr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_stristr($s, $needle, $part, $enc); }
+ function mb_strrchr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_strrchr($s, $needle, $part, $enc); }
+ function mb_strrichr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_strrichr($s, $needle, $part, $enc); }
+ function mb_strripos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_strripos($s, $needle, $offset, $enc); }
+ function mb_strrpos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_strrpos($s, $needle, $offset, $enc); }
+ function mb_strstr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_strstr($s, $needle, $part, $enc); }
+ function mb_get_info($type = 'all') { return p\Mbstring::mb_get_info($type); }
+ function mb_http_output($enc = null) { return p\Mbstring::mb_http_output($enc); }
+ function mb_strwidth($s, $enc = null) { return p\Mbstring::mb_strwidth($s, $enc); }
+ function mb_substr_count($haystack, $needle, $enc = null) { return p\Mbstring::mb_substr_count($haystack, $needle, $enc); }
+ function mb_output_handler($contents, $status) { return p\Mbstring::mb_output_handler($contents, $status); }
+ function mb_http_input($type = '') { return p\Mbstring::mb_http_input($type); }
+ function mb_convert_variables($toEncoding, $fromEncoding, &$a = null, &$b = null, &$c = null, &$d = null, &$e = null, &$f = null) { return p\Mbstring::mb_convert_variables($toEncoding, $fromEncoding, $a, $b, $c, $d, $e, $f); }
+}
+if (!function_exists('mb_chr')) {
+ function mb_ord($s, $enc = null) { return p\Mbstring::mb_ord($s, $enc); }
+ function mb_chr($code, $enc = null) { return p\Mbstring::mb_chr($code, $enc); }
+ function mb_scrub($s, $enc = null) { $enc = null === $enc ? mb_internal_encoding() : $enc; return mb_convert_encoding($s, $enc, $enc); }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-mbstring/composer.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-mbstring/composer.json
new file mode 100644
index 0000000..4febcdd
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-mbstring/composer.json
@@ -0,0 +1,34 @@
+{
+ "name": "symfony/polyfill-mbstring",
+ "type": "library",
+ "description": "Symfony polyfill for the Mbstring extension",
+ "keywords": ["polyfill", "shim", "compatibility", "portable", "mbstring"],
+ "homepage": "https://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "autoload": {
+ "psr-4": { "Symfony\\Polyfill\\Mbstring\\": "" },
+ "files": [ "bootstrap.php" ]
+ },
+ "suggest": {
+ "ext-mbstring": "For best performance"
+ },
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.7-dev"
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/LICENSE b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/LICENSE
new file mode 100644
index 0000000..24fa32c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2015-2018 Fabien Potencier
+
+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.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Php70.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Php70.php
new file mode 100644
index 0000000..8e78450
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Php70.php
@@ -0,0 +1,74 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Polyfill\Php70;
+
+/**
+ * @author Nicolas Grekas <p@tchwork.com>
+ *
+ * @internal
+ */
+final class Php70
+{
+ public static function intdiv($dividend, $divisor)
+ {
+ $dividend = self::intArg($dividend, __FUNCTION__, 1);
+ $divisor = self::intArg($divisor, __FUNCTION__, 2);
+
+ if (0 === $divisor) {
+ throw new \DivisionByZeroError('Division by zero');
+ }
+ if (-1 === $divisor && ~PHP_INT_MAX === $dividend) {
+ throw new \ArithmeticError('Division of PHP_INT_MIN by -1 is not an integer');
+ }
+
+ return ($dividend - ($dividend % $divisor)) / $divisor;
+ }
+
+ public static function preg_replace_callback_array(array $patterns, $subject, $limit = -1, &$count = 0)
+ {
+ $count = 0;
+ $result = (string) $subject;
+ if (0 === $limit = self::intArg($limit, __FUNCTION__, 3)) {
+ return $result;
+ }
+
+ foreach ($patterns as $pattern => $callback) {
+ $result = preg_replace_callback($pattern, $callback, $result, $limit, $c);
+ $count += $c;
+ }
+
+ return $result;
+ }
+
+ public static function error_clear_last()
+ {
+ static $handler;
+ if (!$handler) {
+ $handler = function() { return false; };
+ }
+ set_error_handler($handler);
+ @trigger_error('');
+ restore_error_handler();
+ }
+
+ public static function intArg($value, $caller, $pos)
+ {
+ if (is_int($value)) {
+ return $value;
+ }
+ if (!is_numeric($value) || PHP_INT_MAX <= ($value += 0) || ~PHP_INT_MAX >= $value) {
+ throw new \TypeError(sprintf('%s() expects parameter %d to be integer, %s given', $caller, $pos, gettype($value)));
+ }
+
+ return (int) $value;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/README.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/README.md
new file mode 100644
index 0000000..04988c6
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/README.md
@@ -0,0 +1,28 @@
+Symfony Polyfill / Php70
+========================
+
+This component provides features unavailable in releases prior to PHP 7.0:
+
+- [`intdiv`](http://php.net/intdiv)
+- [`preg_replace_callback_array`](http://php.net/preg_replace_callback_array)
+- [`error_clear_last`](http://php.net/error_clear_last)
+- `random_bytes` and `random_int` (from [paragonie/random_compat](https://github.com/paragonie/random_compat))
+- [`*Error` throwable classes](http://php.net/Error)
+- [`PHP_INT_MIN`](http://php.net/manual/en/reserved.constants.php#constant.php-int-min)
+- `SessionUpdateTimestampHandlerInterface`
+
+More information can be found in the
+[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md).
+
+Compatibility notes
+===================
+
+To write portable code between PHP5 and PHP7, some care must be taken:
+- `\*Error` exceptions must be caught before `\Exception`;
+- after calling `error_clear_last()`, the result of `$e = error_get_last()` must be
+ verified using `isset($e['message'][0])` instead of `null !== $e`.
+
+License
+=======
+
+This library is released under the [MIT license](LICENSE).
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Resources/stubs/ArithmeticError.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Resources/stubs/ArithmeticError.php
new file mode 100644
index 0000000..6819124
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Resources/stubs/ArithmeticError.php
@@ -0,0 +1,5 @@
+<?php
+
+class ArithmeticError extends Error
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Resources/stubs/AssertionError.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Resources/stubs/AssertionError.php
new file mode 100644
index 0000000..acb1250
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Resources/stubs/AssertionError.php
@@ -0,0 +1,5 @@
+<?php
+
+class AssertionError extends Error
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Resources/stubs/DivisionByZeroError.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Resources/stubs/DivisionByZeroError.php
new file mode 100644
index 0000000..c99278b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Resources/stubs/DivisionByZeroError.php
@@ -0,0 +1,5 @@
+<?php
+
+class DivisionByZeroError extends Error
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Resources/stubs/Error.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Resources/stubs/Error.php
new file mode 100644
index 0000000..405847f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Resources/stubs/Error.php
@@ -0,0 +1,5 @@
+<?php
+
+class Error extends Exception
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Resources/stubs/ParseError.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Resources/stubs/ParseError.php
new file mode 100644
index 0000000..2dd447d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Resources/stubs/ParseError.php
@@ -0,0 +1,5 @@
+<?php
+
+class ParseError extends Error
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Resources/stubs/SessionUpdateTimestampHandlerInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Resources/stubs/SessionUpdateTimestampHandlerInterface.php
new file mode 100644
index 0000000..0cc02c8
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Resources/stubs/SessionUpdateTimestampHandlerInterface.php
@@ -0,0 +1,23 @@
+<?php
+
+interface SessionUpdateTimestampHandlerInterface
+{
+ /**
+ * Checks if a session identifier already exists or not.
+ *
+ * @param string $key
+ *
+ * @return bool
+ */
+ public function validateId($key);
+
+ /**
+ * Updates the timestamp of a session when its data didn't change.
+ *
+ * @param string $key
+ * @param string $val
+ *
+ * @return bool
+ */
+ public function updateTimestamp($key, $val);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Resources/stubs/TypeError.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Resources/stubs/TypeError.php
new file mode 100644
index 0000000..2bed1b4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/Resources/stubs/TypeError.php
@@ -0,0 +1,5 @@
+<?php
+
+class TypeError extends Error
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/bootstrap.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/bootstrap.php
new file mode 100644
index 0000000..445c398
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/bootstrap.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use Symfony\Polyfill\Php70 as p;
+
+if (PHP_VERSION_ID < 70000) {
+ if (!defined('PHP_INT_MIN')) {
+ define('PHP_INT_MIN', ~PHP_INT_MAX);
+ }
+ if (!function_exists('intdiv')) {
+ function intdiv($dividend, $divisor) { return p\Php70::intdiv($dividend, $divisor); }
+ }
+ if (!function_exists('preg_replace_callback_array')) {
+ function preg_replace_callback_array(array $patterns, $subject, $limit = -1, &$count = 0) { return p\Php70::preg_replace_callback_array($patterns, $subject, $limit, $count); }
+ }
+ if (!function_exists('error_clear_last')) {
+ function error_clear_last() { return p\Php70::error_clear_last(); }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/composer.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/composer.json
new file mode 100644
index 0000000..88ff357
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/polyfill-php70/composer.json
@@ -0,0 +1,33 @@
+{
+ "name": "symfony/polyfill-php70",
+ "type": "library",
+ "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions",
+ "keywords": ["polyfill", "shim", "compatibility", "portable"],
+ "homepage": "https://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.3",
+ "paragonie/random_compat": "~1.0|~2.0"
+ },
+ "autoload": {
+ "psr-4": { "Symfony\\Polyfill\\Php70\\": "" },
+ "files": [ "bootstrap.php" ],
+ "classmap": [ "Resources/stubs" ]
+ },
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.7-dev"
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/.gitignore b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/.gitignore
new file mode 100644
index 0000000..c49a5d8
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/.gitignore
@@ -0,0 +1,3 @@
+vendor/
+composer.lock
+phpunit.xml
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/CHANGELOG.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/CHANGELOG.md
new file mode 100644
index 0000000..c5cdb99
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/CHANGELOG.md
@@ -0,0 +1,57 @@
+CHANGELOG
+=========
+
+3.4.0
+-----
+
+ * deprecated the ProcessBuilder class
+ * deprecated calling `Process::start()` without setting a valid working directory beforehand (via `setWorkingDirectory()` or constructor)
+
+3.3.0
+-----
+
+ * added command line arrays in the `Process` class
+ * added `$env` argument to `Process::start()`, `run()`, `mustRun()` and `restart()` methods
+ * deprecated the `ProcessUtils::escapeArgument()` method
+ * deprecated not inheriting environment variables
+ * deprecated configuring `proc_open()` options
+ * deprecated configuring enhanced Windows compatibility
+ * deprecated configuring enhanced sigchild compatibility
+
+2.5.0
+-----
+
+ * added support for PTY mode
+ * added the convenience method "mustRun"
+ * deprecation: Process::setStdin() is deprecated in favor of Process::setInput()
+ * deprecation: Process::getStdin() is deprecated in favor of Process::getInput()
+ * deprecation: Process::setInput() and ProcessBuilder::setInput() do not accept non-scalar types
+
+2.4.0
+-----
+
+ * added the ability to define an idle timeout
+
+2.3.0
+-----
+
+ * added ProcessUtils::escapeArgument() to fix the bug in escapeshellarg() function on Windows
+ * added Process::signal()
+ * added Process::getPid()
+ * added support for a TTY mode
+
+2.2.0
+-----
+
+ * added ProcessBuilder::setArguments() to reset the arguments on a builder
+ * added a way to retrieve the standard and error output incrementally
+ * added Process:restart()
+
+2.1.0
+-----
+
+ * added support for non-blocking processes (start(), wait(), isRunning(), stop())
+ * enhanced Windows compatibility
+ * added Process::getExitCodeText() that returns a string representation for
+ the exit code returned by the process
+ * added ProcessBuilder
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Exception/ExceptionInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Exception/ExceptionInterface.php
new file mode 100644
index 0000000..75c1c9e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Exception/ExceptionInterface.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Process\Exception;
+
+/**
+ * Marker Interface for the Process Component.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+interface ExceptionInterface
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Exception/InvalidArgumentException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Exception/InvalidArgumentException.php
new file mode 100644
index 0000000..926ee21
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Exception/InvalidArgumentException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Process\Exception;
+
+/**
+ * InvalidArgumentException for the Process Component.
+ *
+ * @author Romain Neutron <imprec@gmail.com>
+ */
+class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Exception/LogicException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Exception/LogicException.php
new file mode 100644
index 0000000..be3d490
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Exception/LogicException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Process\Exception;
+
+/**
+ * LogicException for the Process Component.
+ *
+ * @author Romain Neutron <imprec@gmail.com>
+ */
+class LogicException extends \LogicException implements ExceptionInterface
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Exception/ProcessFailedException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Exception/ProcessFailedException.php
new file mode 100644
index 0000000..328acfd
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Exception/ProcessFailedException.php
@@ -0,0 +1,54 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Process\Exception;
+
+use Symfony\Component\Process\Process;
+
+/**
+ * Exception for failed processes.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class ProcessFailedException extends RuntimeException
+{
+ private $process;
+
+ public function __construct(Process $process)
+ {
+ if ($process->isSuccessful()) {
+ throw new InvalidArgumentException('Expected a failed process, but the given process was successful.');
+ }
+
+ $error = sprintf('The command "%s" failed.'."\n\nExit Code: %s(%s)\n\nWorking directory: %s",
+ $process->getCommandLine(),
+ $process->getExitCode(),
+ $process->getExitCodeText(),
+ $process->getWorkingDirectory()
+ );
+
+ if (!$process->isOutputDisabled()) {
+ $error .= sprintf("\n\nOutput:\n================\n%s\n\nError Output:\n================\n%s",
+ $process->getOutput(),
+ $process->getErrorOutput()
+ );
+ }
+
+ parent::__construct($error);
+
+ $this->process = $process;
+ }
+
+ public function getProcess()
+ {
+ return $this->process;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Exception/ProcessTimedOutException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Exception/ProcessTimedOutException.php
new file mode 100644
index 0000000..fef4a8a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Exception/ProcessTimedOutException.php
@@ -0,0 +1,69 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Process\Exception;
+
+use Symfony\Component\Process\Process;
+
+/**
+ * Exception that is thrown when a process times out.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class ProcessTimedOutException extends RuntimeException
+{
+ const TYPE_GENERAL = 1;
+ const TYPE_IDLE = 2;
+
+ private $process;
+ private $timeoutType;
+
+ public function __construct(Process $process, $timeoutType)
+ {
+ $this->process = $process;
+ $this->timeoutType = $timeoutType;
+
+ parent::__construct(sprintf(
+ 'The process "%s" exceeded the timeout of %s seconds.',
+ $process->getCommandLine(),
+ $this->getExceededTimeout()
+ ));
+ }
+
+ public function getProcess()
+ {
+ return $this->process;
+ }
+
+ public function isGeneralTimeout()
+ {
+ return self::TYPE_GENERAL === $this->timeoutType;
+ }
+
+ public function isIdleTimeout()
+ {
+ return self::TYPE_IDLE === $this->timeoutType;
+ }
+
+ public function getExceededTimeout()
+ {
+ switch ($this->timeoutType) {
+ case self::TYPE_GENERAL:
+ return $this->process->getTimeout();
+
+ case self::TYPE_IDLE:
+ return $this->process->getIdleTimeout();
+
+ default:
+ throw new \LogicException(sprintf('Unknown timeout type "%d".', $this->timeoutType));
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Exception/RuntimeException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Exception/RuntimeException.php
new file mode 100644
index 0000000..adead25
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Exception/RuntimeException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Process\Exception;
+
+/**
+ * RuntimeException for the Process Component.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class RuntimeException extends \RuntimeException implements ExceptionInterface
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/ExecutableFinder.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/ExecutableFinder.php
new file mode 100644
index 0000000..d042a5b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/ExecutableFinder.php
@@ -0,0 +1,88 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Process;
+
+/**
+ * Generic executable finder.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class ExecutableFinder
+{
+ private $suffixes = array('.exe', '.bat', '.cmd', '.com');
+
+ /**
+ * Replaces default suffixes of executable.
+ */
+ public function setSuffixes(array $suffixes)
+ {
+ $this->suffixes = $suffixes;
+ }
+
+ /**
+ * Adds new possible suffix to check for executable.
+ *
+ * @param string $suffix
+ */
+ public function addSuffix($suffix)
+ {
+ $this->suffixes[] = $suffix;
+ }
+
+ /**
+ * Finds an executable by name.
+ *
+ * @param string $name The executable name (without the extension)
+ * @param string $default The default to return if no executable is found
+ * @param array $extraDirs Additional dirs to check into
+ *
+ * @return string The executable path or default value
+ */
+ public function find($name, $default = null, array $extraDirs = array())
+ {
+ if (ini_get('open_basedir')) {
+ $searchPath = explode(PATH_SEPARATOR, ini_get('open_basedir'));
+ $dirs = array();
+ foreach ($searchPath as $path) {
+ // Silencing against https://bugs.php.net/69240
+ if (@is_dir($path)) {
+ $dirs[] = $path;
+ } else {
+ if (basename($path) == $name && @is_executable($path)) {
+ return $path;
+ }
+ }
+ }
+ } else {
+ $dirs = array_merge(
+ explode(PATH_SEPARATOR, getenv('PATH') ?: getenv('Path')),
+ $extraDirs
+ );
+ }
+
+ $suffixes = array('');
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $pathExt = getenv('PATHEXT');
+ $suffixes = array_merge($suffixes, $pathExt ? explode(PATH_SEPARATOR, $pathExt) : $this->suffixes);
+ }
+ foreach ($suffixes as $suffix) {
+ foreach ($dirs as $dir) {
+ if (@is_file($file = $dir.DIRECTORY_SEPARATOR.$name.$suffix) && ('\\' === DIRECTORY_SEPARATOR || is_executable($file))) {
+ return $file;
+ }
+ }
+ }
+
+ return $default;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/InputStream.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/InputStream.php
new file mode 100644
index 0000000..9bd917a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/InputStream.php
@@ -0,0 +1,92 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Process;
+
+use Symfony\Component\Process\Exception\RuntimeException;
+
+/**
+ * Provides a way to continuously write to the input of a Process until the InputStream is closed.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class InputStream implements \IteratorAggregate
+{
+ /** @var null|callable */
+ private $onEmpty = null;
+ private $input = array();
+ private $open = true;
+
+ /**
+ * Sets a callback that is called when the write buffer becomes empty.
+ */
+ public function onEmpty(callable $onEmpty = null)
+ {
+ $this->onEmpty = $onEmpty;
+ }
+
+ /**
+ * Appends an input to the write buffer.
+ *
+ * @param resource|string|int|float|bool|\Traversable|null The input to append as scalar,
+ * stream resource or \Traversable
+ */
+ public function write($input)
+ {
+ if (null === $input) {
+ return;
+ }
+ if ($this->isClosed()) {
+ throw new RuntimeException(sprintf('%s is closed', static::class));
+ }
+ $this->input[] = ProcessUtils::validateInput(__METHOD__, $input);
+ }
+
+ /**
+ * Closes the write buffer.
+ */
+ public function close()
+ {
+ $this->open = false;
+ }
+
+ /**
+ * Tells whether the write buffer is closed or not.
+ */
+ public function isClosed()
+ {
+ return !$this->open;
+ }
+
+ public function getIterator()
+ {
+ $this->open = true;
+
+ while ($this->open || $this->input) {
+ if (!$this->input) {
+ yield '';
+ continue;
+ }
+ $current = array_shift($this->input);
+
+ if ($current instanceof \Iterator) {
+ foreach ($current as $cur) {
+ yield $cur;
+ }
+ } else {
+ yield $current;
+ }
+ if (!$this->input && $this->open && null !== $onEmpty = $this->onEmpty) {
+ $this->write($onEmpty($this));
+ }
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/LICENSE b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/LICENSE
new file mode 100644
index 0000000..21d7fb9
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2004-2018 Fabien Potencier
+
+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.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/PhpExecutableFinder.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/PhpExecutableFinder.php
new file mode 100644
index 0000000..c9c113c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/PhpExecutableFinder.php
@@ -0,0 +1,94 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Process;
+
+/**
+ * An executable finder specifically designed for the PHP executable.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class PhpExecutableFinder
+{
+ private $executableFinder;
+
+ public function __construct()
+ {
+ $this->executableFinder = new ExecutableFinder();
+ }
+
+ /**
+ * Finds The PHP executable.
+ *
+ * @param bool $includeArgs Whether or not include command arguments
+ *
+ * @return string|false The PHP executable path or false if it cannot be found
+ */
+ public function find($includeArgs = true)
+ {
+ $args = $this->findArguments();
+ $args = $includeArgs && $args ? ' '.implode(' ', $args) : '';
+
+ // HHVM support
+ if (defined('HHVM_VERSION')) {
+ return (getenv('PHP_BINARY') ?: PHP_BINARY).$args;
+ }
+
+ // PHP_BINARY return the current sapi executable
+ if (PHP_BINARY && \in_array(PHP_SAPI, array('cli', 'cli-server', 'phpdbg'), true)) {
+ return PHP_BINARY.$args;
+ }
+
+ if ($php = getenv('PHP_PATH')) {
+ if (!is_executable($php)) {
+ return false;
+ }
+
+ return $php;
+ }
+
+ if ($php = getenv('PHP_PEAR_PHP_BIN')) {
+ if (is_executable($php)) {
+ return $php;
+ }
+ }
+
+ if (is_executable($php = PHP_BINDIR.('\\' === DIRECTORY_SEPARATOR ? '\\php.exe' : '/php'))) {
+ return $php;
+ }
+
+ $dirs = array(PHP_BINDIR);
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $dirs[] = 'C:\xampp\php\\';
+ }
+
+ return $this->executableFinder->find('php', false, $dirs);
+ }
+
+ /**
+ * Finds the PHP executable arguments.
+ *
+ * @return array The PHP executable arguments
+ */
+ public function findArguments()
+ {
+ $arguments = array();
+
+ if (defined('HHVM_VERSION')) {
+ $arguments[] = '--php';
+ } elseif ('phpdbg' === PHP_SAPI) {
+ $arguments[] = '-qrr';
+ }
+
+ return $arguments;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/PhpProcess.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/PhpProcess.php
new file mode 100644
index 0000000..d3fd384
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/PhpProcess.php
@@ -0,0 +1,76 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Process;
+
+use Symfony\Component\Process\Exception\RuntimeException;
+
+/**
+ * PhpProcess runs a PHP script in an independent process.
+ *
+ * $p = new PhpProcess('<?php echo "foo"; ?>');
+ * $p->run();
+ * print $p->getOutput()."\n";
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class PhpProcess extends Process
+{
+ /**
+ * @param string $script The PHP script to run (as a string)
+ * @param string|null $cwd The working directory or null to use the working dir of the current PHP process
+ * @param array|null $env The environment variables or null to use the same environment as the current PHP process
+ * @param int $timeout The timeout in seconds
+ * @param array $options An array of options for proc_open
+ */
+ public function __construct($script, $cwd = null, array $env = null, $timeout = 60, array $options = null)
+ {
+ $executableFinder = new PhpExecutableFinder();
+ if (false === $php = $executableFinder->find(false)) {
+ $php = null;
+ } else {
+ $php = array_merge(array($php), $executableFinder->findArguments());
+ }
+ if ('phpdbg' === PHP_SAPI) {
+ $file = tempnam(sys_get_temp_dir(), 'dbg');
+ file_put_contents($file, $script);
+ register_shutdown_function('unlink', $file);
+ $php[] = $file;
+ $script = null;
+ }
+ if (null !== $options) {
+ @trigger_error(sprintf('The $options parameter of the %s constructor is deprecated since Symfony 3.3 and will be removed in 4.0.', __CLASS__), E_USER_DEPRECATED);
+ }
+
+ parent::__construct($php, $cwd, $env, $script, $timeout, $options);
+ }
+
+ /**
+ * Sets the path to the PHP binary to use.
+ */
+ public function setPhpBinary($php)
+ {
+ $this->setCommandLine($php);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function start(callable $callback = null/*, array $env = array()*/)
+ {
+ if (null === $this->getCommandLine()) {
+ throw new RuntimeException('Unable to find the PHP executable.');
+ }
+ $env = 1 < func_num_args() ? func_get_arg(1) : null;
+
+ parent::start($callback, $env);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Pipes/AbstractPipes.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Pipes/AbstractPipes.php
new file mode 100644
index 0000000..2bd1fe7
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Pipes/AbstractPipes.php
@@ -0,0 +1,168 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Process\Pipes;
+
+use Symfony\Component\Process\Exception\InvalidArgumentException;
+
+/**
+ * @author Romain Neutron <imprec@gmail.com>
+ *
+ * @internal
+ */
+abstract class AbstractPipes implements PipesInterface
+{
+ public $pipes = array();
+
+ private $inputBuffer = '';
+ private $input;
+ private $blocked = true;
+
+ /**
+ * @param resource|string|int|float|bool|\Iterator|null $input
+ */
+ public function __construct($input)
+ {
+ if (is_resource($input) || $input instanceof \Iterator) {
+ $this->input = $input;
+ } elseif (is_string($input)) {
+ $this->inputBuffer = $input;
+ } else {
+ $this->inputBuffer = (string) $input;
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function close()
+ {
+ foreach ($this->pipes as $pipe) {
+ fclose($pipe);
+ }
+ $this->pipes = array();
+ }
+
+ /**
+ * Returns true if a system call has been interrupted.
+ *
+ * @return bool
+ */
+ protected function hasSystemCallBeenInterrupted()
+ {
+ $lastError = error_get_last();
+
+ // stream_select returns false when the `select` system call is interrupted by an incoming signal
+ return isset($lastError['message']) && false !== stripos($lastError['message'], 'interrupted system call');
+ }
+
+ /**
+ * Unblocks streams.
+ */
+ protected function unblock()
+ {
+ if (!$this->blocked) {
+ return;
+ }
+
+ foreach ($this->pipes as $pipe) {
+ stream_set_blocking($pipe, 0);
+ }
+ if (is_resource($this->input)) {
+ stream_set_blocking($this->input, 0);
+ }
+
+ $this->blocked = false;
+ }
+
+ /**
+ * Writes input to stdin.
+ *
+ * @throws InvalidArgumentException When an input iterator yields a non supported value
+ */
+ protected function write()
+ {
+ if (!isset($this->pipes[0])) {
+ return;
+ }
+ $input = $this->input;
+
+ if ($input instanceof \Iterator) {
+ if (!$input->valid()) {
+ $input = null;
+ } elseif (is_resource($input = $input->current())) {
+ stream_set_blocking($input, 0);
+ } elseif (!isset($this->inputBuffer[0])) {
+ if (!is_string($input)) {
+ if (!is_scalar($input)) {
+ throw new InvalidArgumentException(sprintf('%s yielded a value of type "%s", but only scalars and stream resources are supported', get_class($this->input), gettype($input)));
+ }
+ $input = (string) $input;
+ }
+ $this->inputBuffer = $input;
+ $this->input->next();
+ $input = null;
+ } else {
+ $input = null;
+ }
+ }
+
+ $r = $e = array();
+ $w = array($this->pipes[0]);
+
+ // let's have a look if something changed in streams
+ if (false === @stream_select($r, $w, $e, 0, 0)) {
+ return;
+ }
+
+ foreach ($w as $stdin) {
+ if (isset($this->inputBuffer[0])) {
+ $written = fwrite($stdin, $this->inputBuffer);
+ $this->inputBuffer = substr($this->inputBuffer, $written);
+ if (isset($this->inputBuffer[0])) {
+ return array($this->pipes[0]);
+ }
+ }
+
+ if ($input) {
+ for (;;) {
+ $data = fread($input, self::CHUNK_SIZE);
+ if (!isset($data[0])) {
+ break;
+ }
+ $written = fwrite($stdin, $data);
+ $data = substr($data, $written);
+ if (isset($data[0])) {
+ $this->inputBuffer = $data;
+
+ return array($this->pipes[0]);
+ }
+ }
+ if (feof($input)) {
+ if ($this->input instanceof \Iterator) {
+ $this->input->next();
+ } else {
+ $this->input = null;
+ }
+ }
+ }
+ }
+
+ // no input to read on resource, buffer is empty
+ if (!isset($this->inputBuffer[0]) && !($this->input instanceof \Iterator ? $this->input->valid() : $this->input)) {
+ $this->input = null;
+ fclose($this->pipes[0]);
+ unset($this->pipes[0]);
+ } elseif (!$w) {
+ return array($this->pipes[0]);
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Pipes/PipesInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Pipes/PipesInterface.php
new file mode 100644
index 0000000..52bbe76
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Pipes/PipesInterface.php
@@ -0,0 +1,67 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Process\Pipes;
+
+/**
+ * PipesInterface manages descriptors and pipes for the use of proc_open.
+ *
+ * @author Romain Neutron <imprec@gmail.com>
+ *
+ * @internal
+ */
+interface PipesInterface
+{
+ const CHUNK_SIZE = 16384;
+
+ /**
+ * Returns an array of descriptors for the use of proc_open.
+ *
+ * @return array
+ */
+ public function getDescriptors();
+
+ /**
+ * Returns an array of filenames indexed by their related stream in case these pipes use temporary files.
+ *
+ * @return string[]
+ */
+ public function getFiles();
+
+ /**
+ * Reads data in file handles and pipes.
+ *
+ * @param bool $blocking Whether to use blocking calls or not
+ * @param bool $close Whether to close pipes if they've reached EOF
+ *
+ * @return string[] An array of read data indexed by their fd
+ */
+ public function readAndWrite($blocking, $close = false);
+
+ /**
+ * Returns if the current state has open file handles or pipes.
+ *
+ * @return bool
+ */
+ public function areOpen();
+
+ /**
+ * Returns if pipes are able to read output.
+ *
+ * @return bool
+ */
+ public function haveReadSupport();
+
+ /**
+ * Closes file handles and pipes.
+ */
+ public function close();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Pipes/UnixPipes.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Pipes/UnixPipes.php
new file mode 100644
index 0000000..78ffee7
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Pipes/UnixPipes.php
@@ -0,0 +1,150 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Process\Pipes;
+
+use Symfony\Component\Process\Process;
+
+/**
+ * UnixPipes implementation uses unix pipes as handles.
+ *
+ * @author Romain Neutron <imprec@gmail.com>
+ *
+ * @internal
+ */
+class UnixPipes extends AbstractPipes
+{
+ private $ttyMode;
+ private $ptyMode;
+ private $haveReadSupport;
+
+ public function __construct($ttyMode, $ptyMode, $input, $haveReadSupport)
+ {
+ $this->ttyMode = (bool) $ttyMode;
+ $this->ptyMode = (bool) $ptyMode;
+ $this->haveReadSupport = (bool) $haveReadSupport;
+
+ parent::__construct($input);
+ }
+
+ public function __destruct()
+ {
+ $this->close();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getDescriptors()
+ {
+ if (!$this->haveReadSupport) {
+ $nullstream = fopen('/dev/null', 'c');
+
+ return array(
+ array('pipe', 'r'),
+ $nullstream,
+ $nullstream,
+ );
+ }
+
+ if ($this->ttyMode) {
+ return array(
+ array('file', '/dev/tty', 'r'),
+ array('file', '/dev/tty', 'w'),
+ array('file', '/dev/tty', 'w'),
+ );
+ }
+
+ if ($this->ptyMode && Process::isPtySupported()) {
+ return array(
+ array('pty'),
+ array('pty'),
+ array('pty'),
+ );
+ }
+
+ return array(
+ array('pipe', 'r'),
+ array('pipe', 'w'), // stdout
+ array('pipe', 'w'), // stderr
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFiles()
+ {
+ return array();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function readAndWrite($blocking, $close = false)
+ {
+ $this->unblock();
+ $w = $this->write();
+
+ $read = $e = array();
+ $r = $this->pipes;
+ unset($r[0]);
+
+ // let's have a look if something changed in streams
+ if (($r || $w) && false === @stream_select($r, $w, $e, 0, $blocking ? Process::TIMEOUT_PRECISION * 1E6 : 0)) {
+ // if a system call has been interrupted, forget about it, let's try again
+ // otherwise, an error occurred, let's reset pipes
+ if (!$this->hasSystemCallBeenInterrupted()) {
+ $this->pipes = array();
+ }
+
+ return $read;
+ }
+
+ foreach ($r as $pipe) {
+ // prior PHP 5.4 the array passed to stream_select is modified and
+ // lose key association, we have to find back the key
+ $read[$type = array_search($pipe, $this->pipes, true)] = '';
+
+ do {
+ $data = fread($pipe, self::CHUNK_SIZE);
+ $read[$type] .= $data;
+ } while (isset($data[0]) && ($close || isset($data[self::CHUNK_SIZE - 1])));
+
+ if (!isset($read[$type][0])) {
+ unset($read[$type]);
+ }
+
+ if ($close && feof($pipe)) {
+ fclose($pipe);
+ unset($this->pipes[$type]);
+ }
+ }
+
+ return $read;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function haveReadSupport()
+ {
+ return $this->haveReadSupport;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function areOpen()
+ {
+ return (bool) $this->pipes;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Pipes/WindowsPipes.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Pipes/WindowsPipes.php
new file mode 100644
index 0000000..d5fa2fd
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Pipes/WindowsPipes.php
@@ -0,0 +1,196 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Process\Pipes;
+
+use Symfony\Component\Process\Process;
+use Symfony\Component\Process\Exception\RuntimeException;
+
+/**
+ * WindowsPipes implementation uses temporary files as handles.
+ *
+ * @see https://bugs.php.net/bug.php?id=51800
+ * @see https://bugs.php.net/bug.php?id=65650
+ *
+ * @author Romain Neutron <imprec@gmail.com>
+ *
+ * @internal
+ */
+class WindowsPipes extends AbstractPipes
+{
+ private $files = array();
+ private $fileHandles = array();
+ private $readBytes = array(
+ Process::STDOUT => 0,
+ Process::STDERR => 0,
+ );
+ private $haveReadSupport;
+
+ public function __construct($input, $haveReadSupport)
+ {
+ $this->haveReadSupport = (bool) $haveReadSupport;
+
+ if ($this->haveReadSupport) {
+ // Fix for PHP bug #51800: reading from STDOUT pipe hangs forever on Windows if the output is too big.
+ // Workaround for this problem is to use temporary files instead of pipes on Windows platform.
+ //
+ // @see https://bugs.php.net/bug.php?id=51800
+ $pipes = array(
+ Process::STDOUT => Process::OUT,
+ Process::STDERR => Process::ERR,
+ );
+ $tmpCheck = false;
+ $tmpDir = sys_get_temp_dir();
+ $lastError = 'unknown reason';
+ set_error_handler(function ($type, $msg) use (&$lastError) { $lastError = $msg; });
+ for ($i = 0;; ++$i) {
+ foreach ($pipes as $pipe => $name) {
+ $file = sprintf('%s\\sf_proc_%02X.%s', $tmpDir, $i, $name);
+ if (file_exists($file) && !unlink($file)) {
+ continue 2;
+ }
+ $h = fopen($file, 'xb');
+ if (!$h) {
+ $error = $lastError;
+ if ($tmpCheck || $tmpCheck = unlink(tempnam(false, 'sf_check_'))) {
+ continue;
+ }
+ restore_error_handler();
+ throw new RuntimeException(sprintf('A temporary file could not be opened to write the process output: %s', $error));
+ }
+ if (!$h || !$this->fileHandles[$pipe] = fopen($file, 'rb')) {
+ continue 2;
+ }
+ if (isset($this->files[$pipe])) {
+ unlink($this->files[$pipe]);
+ }
+ $this->files[$pipe] = $file;
+ }
+ break;
+ }
+ restore_error_handler();
+ }
+
+ parent::__construct($input);
+ }
+
+ public function __destruct()
+ {
+ $this->close();
+ $this->removeFiles();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getDescriptors()
+ {
+ if (!$this->haveReadSupport) {
+ $nullstream = fopen('NUL', 'c');
+
+ return array(
+ array('pipe', 'r'),
+ $nullstream,
+ $nullstream,
+ );
+ }
+
+ // We're not using pipe on Windows platform as it hangs (https://bugs.php.net/bug.php?id=51800)
+ // We're not using file handles as it can produce corrupted output https://bugs.php.net/bug.php?id=65650
+ // So we redirect output within the commandline and pass the nul device to the process
+ return array(
+ array('pipe', 'r'),
+ array('file', 'NUL', 'w'),
+ array('file', 'NUL', 'w'),
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFiles()
+ {
+ return $this->files;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function readAndWrite($blocking, $close = false)
+ {
+ $this->unblock();
+ $w = $this->write();
+ $read = $r = $e = array();
+
+ if ($blocking) {
+ if ($w) {
+ @stream_select($r, $w, $e, 0, Process::TIMEOUT_PRECISION * 1E6);
+ } elseif ($this->fileHandles) {
+ usleep(Process::TIMEOUT_PRECISION * 1E6);
+ }
+ }
+ foreach ($this->fileHandles as $type => $fileHandle) {
+ $data = stream_get_contents($fileHandle, -1, $this->readBytes[$type]);
+
+ if (isset($data[0])) {
+ $this->readBytes[$type] += strlen($data);
+ $read[$type] = $data;
+ }
+ if ($close) {
+ fclose($fileHandle);
+ unset($this->fileHandles[$type]);
+ }
+ }
+
+ return $read;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function haveReadSupport()
+ {
+ return $this->haveReadSupport;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function areOpen()
+ {
+ return $this->pipes && $this->fileHandles;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function close()
+ {
+ parent::close();
+ foreach ($this->fileHandles as $handle) {
+ fclose($handle);
+ }
+ $this->fileHandles = array();
+ }
+
+ /**
+ * Removes temporary files.
+ */
+ private function removeFiles()
+ {
+ foreach ($this->files as $filename) {
+ if (file_exists($filename)) {
+ @unlink($filename);
+ }
+ }
+ $this->files = array();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Process.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Process.php
new file mode 100644
index 0000000..830c623
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Process.php
@@ -0,0 +1,1751 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Process;
+
+use Symfony\Component\Process\Exception\InvalidArgumentException;
+use Symfony\Component\Process\Exception\LogicException;
+use Symfony\Component\Process\Exception\ProcessFailedException;
+use Symfony\Component\Process\Exception\ProcessTimedOutException;
+use Symfony\Component\Process\Exception\RuntimeException;
+use Symfony\Component\Process\Pipes\PipesInterface;
+use Symfony\Component\Process\Pipes\UnixPipes;
+use Symfony\Component\Process\Pipes\WindowsPipes;
+
+/**
+ * Process is a thin wrapper around proc_* functions to easily
+ * start independent PHP processes.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Romain Neutron <imprec@gmail.com>
+ */
+class Process implements \IteratorAggregate
+{
+ const ERR = 'err';
+ const OUT = 'out';
+
+ const STATUS_READY = 'ready';
+ const STATUS_STARTED = 'started';
+ const STATUS_TERMINATED = 'terminated';
+
+ const STDIN = 0;
+ const STDOUT = 1;
+ const STDERR = 2;
+
+ // Timeout Precision in seconds.
+ const TIMEOUT_PRECISION = 0.2;
+
+ const ITER_NON_BLOCKING = 1; // By default, iterating over outputs is a blocking call, use this flag to make it non-blocking
+ const ITER_KEEP_OUTPUT = 2; // By default, outputs are cleared while iterating, use this flag to keep them in memory
+ const ITER_SKIP_OUT = 4; // Use this flag to skip STDOUT while iterating
+ const ITER_SKIP_ERR = 8; // Use this flag to skip STDERR while iterating
+
+ private $callback;
+ private $hasCallback = false;
+ private $commandline;
+ private $cwd;
+ private $env;
+ private $input;
+ private $starttime;
+ private $lastOutputTime;
+ private $timeout;
+ private $idleTimeout;
+ private $options = array('suppress_errors' => true);
+ private $exitcode;
+ private $fallbackStatus = array();
+ private $processInformation;
+ private $outputDisabled = false;
+ private $stdout;
+ private $stderr;
+ private $enhanceWindowsCompatibility = true;
+ private $enhanceSigchildCompatibility;
+ private $process;
+ private $status = self::STATUS_READY;
+ private $incrementalOutputOffset = 0;
+ private $incrementalErrorOutputOffset = 0;
+ private $tty;
+ private $pty;
+ private $inheritEnv = false;
+
+ private $useFileHandles = false;
+ /** @var PipesInterface */
+ private $processPipes;
+
+ private $latestSignal;
+
+ private static $sigchild;
+
+ /**
+ * Exit codes translation table.
+ *
+ * User-defined errors must use exit codes in the 64-113 range.
+ */
+ public static $exitCodes = array(
+ 0 => 'OK',
+ 1 => 'General error',
+ 2 => 'Misuse of shell builtins',
+
+ 126 => 'Invoked command cannot execute',
+ 127 => 'Command not found',
+ 128 => 'Invalid exit argument',
+
+ // signals
+ 129 => 'Hangup',
+ 130 => 'Interrupt',
+ 131 => 'Quit and dump core',
+ 132 => 'Illegal instruction',
+ 133 => 'Trace/breakpoint trap',
+ 134 => 'Process aborted',
+ 135 => 'Bus error: "access to undefined portion of memory object"',
+ 136 => 'Floating point exception: "erroneous arithmetic operation"',
+ 137 => 'Kill (terminate immediately)',
+ 138 => 'User-defined 1',
+ 139 => 'Segmentation violation',
+ 140 => 'User-defined 2',
+ 141 => 'Write to pipe with no one reading',
+ 142 => 'Signal raised by alarm',
+ 143 => 'Termination (request to terminate)',
+ // 144 - not defined
+ 145 => 'Child process terminated, stopped (or continued*)',
+ 146 => 'Continue if stopped',
+ 147 => 'Stop executing temporarily',
+ 148 => 'Terminal stop signal',
+ 149 => 'Background process attempting to read from tty ("in")',
+ 150 => 'Background process attempting to write to tty ("out")',
+ 151 => 'Urgent data available on socket',
+ 152 => 'CPU time limit exceeded',
+ 153 => 'File size limit exceeded',
+ 154 => 'Signal raised by timer counting virtual time: "virtual timer expired"',
+ 155 => 'Profiling timer expired',
+ // 156 - not defined
+ 157 => 'Pollable event',
+ // 158 - not defined
+ 159 => 'Bad syscall',
+ );
+
+ /**
+ * @param string|array $commandline The command line to run
+ * @param string|null $cwd The working directory or null to use the working dir of the current PHP process
+ * @param array|null $env The environment variables or null to use the same environment as the current PHP process
+ * @param mixed|null $input The input as stream resource, scalar or \Traversable, or null for no input
+ * @param int|float|null $timeout The timeout in seconds or null to disable
+ * @param array $options An array of options for proc_open
+ *
+ * @throws RuntimeException When proc_open is not installed
+ */
+ public function __construct($commandline, $cwd = null, array $env = null, $input = null, $timeout = 60, array $options = null)
+ {
+ if (!function_exists('proc_open')) {
+ throw new RuntimeException('The Process class relies on proc_open, which is not available on your PHP installation.');
+ }
+
+ $this->commandline = $commandline;
+ $this->cwd = $cwd;
+
+ // on Windows, if the cwd changed via chdir(), proc_open defaults to the dir where PHP was started
+ // on Gnu/Linux, PHP builds with --enable-maintainer-zts are also affected
+ // @see : https://bugs.php.net/bug.php?id=51800
+ // @see : https://bugs.php.net/bug.php?id=50524
+ if (null === $this->cwd && (defined('ZEND_THREAD_SAFE') || '\\' === DIRECTORY_SEPARATOR)) {
+ $this->cwd = getcwd();
+ }
+ if (null !== $env) {
+ $this->setEnv($env);
+ }
+
+ $this->setInput($input);
+ $this->setTimeout($timeout);
+ $this->useFileHandles = '\\' === DIRECTORY_SEPARATOR;
+ $this->pty = false;
+ $this->enhanceSigchildCompatibility = '\\' !== DIRECTORY_SEPARATOR && $this->isSigchildEnabled();
+ if (null !== $options) {
+ @trigger_error(sprintf('The $options parameter of the %s constructor is deprecated since Symfony 3.3 and will be removed in 4.0.', __CLASS__), E_USER_DEPRECATED);
+ $this->options = array_replace($this->options, $options);
+ }
+ }
+
+ public function __destruct()
+ {
+ $this->stop(0);
+ }
+
+ public function __clone()
+ {
+ $this->resetProcessData();
+ }
+
+ /**
+ * Runs the process.
+ *
+ * The callback receives the type of output (out or err) and
+ * some bytes from the output in real-time. It allows to have feedback
+ * from the independent process during execution.
+ *
+ * The STDOUT and STDERR are also available after the process is finished
+ * via the getOutput() and getErrorOutput() methods.
+ *
+ * @param callable|null $callback A PHP callback to run whenever there is some
+ * output available on STDOUT or STDERR
+ * @param array $env An array of additional env vars to set when running the process
+ *
+ * @return int The exit status code
+ *
+ * @throws RuntimeException When process can't be launched
+ * @throws RuntimeException When process stopped after receiving signal
+ * @throws LogicException In case a callback is provided and output has been disabled
+ *
+ * @final since version 3.3
+ */
+ public function run($callback = null/*, array $env = array()*/)
+ {
+ $env = 1 < func_num_args() ? func_get_arg(1) : null;
+ $this->start($callback, $env);
+
+ return $this->wait();
+ }
+
+ /**
+ * Runs the process.
+ *
+ * This is identical to run() except that an exception is thrown if the process
+ * exits with a non-zero exit code.
+ *
+ * @param callable|null $callback
+ * @param array $env An array of additional env vars to set when running the process
+ *
+ * @return self
+ *
+ * @throws RuntimeException if PHP was compiled with --enable-sigchild and the enhanced sigchild compatibility mode is not enabled
+ * @throws ProcessFailedException if the process didn't terminate successfully
+ *
+ * @final since version 3.3
+ */
+ public function mustRun(callable $callback = null/*, array $env = array()*/)
+ {
+ if (!$this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
+ throw new RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.');
+ }
+ $env = 1 < func_num_args() ? func_get_arg(1) : null;
+
+ if (0 !== $this->run($callback, $env)) {
+ throw new ProcessFailedException($this);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Starts the process and returns after writing the input to STDIN.
+ *
+ * This method blocks until all STDIN data is sent to the process then it
+ * returns while the process runs in the background.
+ *
+ * The termination of the process can be awaited with wait().
+ *
+ * The callback receives the type of output (out or err) and some bytes from
+ * the output in real-time while writing the standard input to the process.
+ * It allows to have feedback from the independent process during execution.
+ *
+ * @param callable|null $callback A PHP callback to run whenever there is some
+ * output available on STDOUT or STDERR
+ * @param array $env An array of additional env vars to set when running the process
+ *
+ * @throws RuntimeException When process can't be launched
+ * @throws RuntimeException When process is already running
+ * @throws LogicException In case a callback is provided and output has been disabled
+ */
+ public function start(callable $callback = null/*, array $env = array()*/)
+ {
+ if ($this->isRunning()) {
+ throw new RuntimeException('Process is already running');
+ }
+ if (2 <= func_num_args()) {
+ $env = func_get_arg(1);
+ } else {
+ if (__CLASS__ !== static::class) {
+ $r = new \ReflectionMethod($this, __FUNCTION__);
+ if (__CLASS__ !== $r->getDeclaringClass()->getName() && (2 > $r->getNumberOfParameters() || 'env' !== $r->getParameters()[0]->name)) {
+ @trigger_error(sprintf('The %s::start() method expects a second "$env" argument since Symfony 3.3. It will be made mandatory in 4.0.', static::class), E_USER_DEPRECATED);
+ }
+ }
+ $env = null;
+ }
+
+ $this->resetProcessData();
+ $this->starttime = $this->lastOutputTime = microtime(true);
+ $this->callback = $this->buildCallback($callback);
+ $this->hasCallback = null !== $callback;
+ $descriptors = $this->getDescriptors();
+ $inheritEnv = $this->inheritEnv;
+
+ if (is_array($commandline = $this->commandline)) {
+ $commandline = implode(' ', array_map(array($this, 'escapeArgument'), $commandline));
+
+ if ('\\' !== DIRECTORY_SEPARATOR) {
+ // exec is mandatory to deal with sending a signal to the process
+ $commandline = 'exec '.$commandline;
+ }
+ }
+
+ if (null === $env) {
+ $env = $this->env;
+ } else {
+ if ($this->env) {
+ $env += $this->env;
+ }
+ $inheritEnv = true;
+ }
+
+ if (null !== $env && $inheritEnv) {
+ $env += $this->getDefaultEnv();
+ } elseif (null !== $env) {
+ @trigger_error('Not inheriting environment variables is deprecated since Symfony 3.3 and will always happen in 4.0. Set "Process::inheritEnvironmentVariables()" to true instead.', E_USER_DEPRECATED);
+ } else {
+ $env = $this->getDefaultEnv();
+ }
+ if ('\\' === DIRECTORY_SEPARATOR && $this->enhanceWindowsCompatibility) {
+ $this->options['bypass_shell'] = true;
+ $commandline = $this->prepareWindowsCommandLine($commandline, $env);
+ } elseif (!$this->useFileHandles && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
+ // last exit code is output on the fourth pipe and caught to work around --enable-sigchild
+ $descriptors[3] = array('pipe', 'w');
+
+ // See https://unix.stackexchange.com/questions/71205/background-process-pipe-input
+ $commandline = '{ ('.$commandline.') <&3 3<&- 3>/dev/null & } 3<&0;';
+ $commandline .= 'pid=$!; echo $pid >&3; wait $pid; code=$?; echo $code >&3; exit $code';
+
+ // Workaround for the bug, when PTS functionality is enabled.
+ // @see : https://bugs.php.net/69442
+ $ptsWorkaround = fopen(__FILE__, 'r');
+ }
+ if (defined('HHVM_VERSION')) {
+ $envPairs = $env;
+ } else {
+ $envPairs = array();
+ foreach ($env as $k => $v) {
+ if (false !== $v) {
+ $envPairs[] = $k.'='.$v;
+ }
+ }
+ }
+
+ if (!is_dir($this->cwd)) {
+ @trigger_error('The provided cwd does not exist. Command is currently ran against getcwd(). This behavior is deprecated since Symfony 3.4 and will be removed in 4.0.', E_USER_DEPRECATED);
+ }
+
+ $this->process = proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $envPairs, $this->options);
+
+ if (!is_resource($this->process)) {
+ throw new RuntimeException('Unable to launch a new process.');
+ }
+ $this->status = self::STATUS_STARTED;
+
+ if (isset($descriptors[3])) {
+ $this->fallbackStatus['pid'] = (int) fgets($this->processPipes->pipes[3]);
+ }
+
+ if ($this->tty) {
+ return;
+ }
+
+ $this->updateStatus(false);
+ $this->checkTimeout();
+ }
+
+ /**
+ * Restarts the process.
+ *
+ * Be warned that the process is cloned before being started.
+ *
+ * @param callable|null $callback A PHP callback to run whenever there is some
+ * output available on STDOUT or STDERR
+ * @param array $env An array of additional env vars to set when running the process
+ *
+ * @return $this
+ *
+ * @throws RuntimeException When process can't be launched
+ * @throws RuntimeException When process is already running
+ *
+ * @see start()
+ *
+ * @final since version 3.3
+ */
+ public function restart(callable $callback = null/*, array $env = array()*/)
+ {
+ if ($this->isRunning()) {
+ throw new RuntimeException('Process is already running');
+ }
+ $env = 1 < func_num_args() ? func_get_arg(1) : null;
+
+ $process = clone $this;
+ $process->start($callback, $env);
+
+ return $process;
+ }
+
+ /**
+ * Waits for the process to terminate.
+ *
+ * The callback receives the type of output (out or err) and some bytes
+ * from the output in real-time while writing the standard input to the process.
+ * It allows to have feedback from the independent process during execution.
+ *
+ * @param callable|null $callback A valid PHP callback
+ *
+ * @return int The exitcode of the process
+ *
+ * @throws RuntimeException When process timed out
+ * @throws RuntimeException When process stopped after receiving signal
+ * @throws LogicException When process is not yet started
+ */
+ public function wait(callable $callback = null)
+ {
+ $this->requireProcessIsStarted(__FUNCTION__);
+
+ $this->updateStatus(false);
+
+ if (null !== $callback) {
+ if (!$this->processPipes->haveReadSupport()) {
+ $this->stop(0);
+ throw new \LogicException('Pass the callback to the Process::start method or enableOutput to use a callback with Process::wait');
+ }
+ $this->callback = $this->buildCallback($callback);
+ }
+
+ do {
+ $this->checkTimeout();
+ $running = '\\' === DIRECTORY_SEPARATOR ? $this->isRunning() : $this->processPipes->areOpen();
+ $this->readPipes($running, '\\' !== DIRECTORY_SEPARATOR || !$running);
+ } while ($running);
+
+ while ($this->isRunning()) {
+ usleep(1000);
+ }
+
+ if ($this->processInformation['signaled'] && $this->processInformation['termsig'] !== $this->latestSignal) {
+ throw new RuntimeException(sprintf('The process has been signaled with signal "%s".', $this->processInformation['termsig']));
+ }
+
+ return $this->exitcode;
+ }
+
+ /**
+ * Returns the Pid (process identifier), if applicable.
+ *
+ * @return int|null The process id if running, null otherwise
+ */
+ public function getPid()
+ {
+ return $this->isRunning() ? $this->processInformation['pid'] : null;
+ }
+
+ /**
+ * Sends a POSIX signal to the process.
+ *
+ * @param int $signal A valid POSIX signal (see http://www.php.net/manual/en/pcntl.constants.php)
+ *
+ * @return $this
+ *
+ * @throws LogicException In case the process is not running
+ * @throws RuntimeException In case --enable-sigchild is activated and the process can't be killed
+ * @throws RuntimeException In case of failure
+ */
+ public function signal($signal)
+ {
+ $this->doSignal($signal, true);
+
+ return $this;
+ }
+
+ /**
+ * Disables fetching output and error output from the underlying process.
+ *
+ * @return $this
+ *
+ * @throws RuntimeException In case the process is already running
+ * @throws LogicException if an idle timeout is set
+ */
+ public function disableOutput()
+ {
+ if ($this->isRunning()) {
+ throw new RuntimeException('Disabling output while the process is running is not possible.');
+ }
+ if (null !== $this->idleTimeout) {
+ throw new LogicException('Output can not be disabled while an idle timeout is set.');
+ }
+
+ $this->outputDisabled = true;
+
+ return $this;
+ }
+
+ /**
+ * Enables fetching output and error output from the underlying process.
+ *
+ * @return $this
+ *
+ * @throws RuntimeException In case the process is already running
+ */
+ public function enableOutput()
+ {
+ if ($this->isRunning()) {
+ throw new RuntimeException('Enabling output while the process is running is not possible.');
+ }
+
+ $this->outputDisabled = false;
+
+ return $this;
+ }
+
+ /**
+ * Returns true in case the output is disabled, false otherwise.
+ *
+ * @return bool
+ */
+ public function isOutputDisabled()
+ {
+ return $this->outputDisabled;
+ }
+
+ /**
+ * Returns the current output of the process (STDOUT).
+ *
+ * @return string The process output
+ *
+ * @throws LogicException in case the output has been disabled
+ * @throws LogicException In case the process is not started
+ */
+ public function getOutput()
+ {
+ $this->readPipesForOutput(__FUNCTION__);
+
+ if (false === $ret = stream_get_contents($this->stdout, -1, 0)) {
+ return '';
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Returns the output incrementally.
+ *
+ * In comparison with the getOutput method which always return the whole
+ * output, this one returns the new output since the last call.
+ *
+ * @return string The process output since the last call
+ *
+ * @throws LogicException in case the output has been disabled
+ * @throws LogicException In case the process is not started
+ */
+ public function getIncrementalOutput()
+ {
+ $this->readPipesForOutput(__FUNCTION__);
+
+ $latest = stream_get_contents($this->stdout, -1, $this->incrementalOutputOffset);
+ $this->incrementalOutputOffset = ftell($this->stdout);
+
+ if (false === $latest) {
+ return '';
+ }
+
+ return $latest;
+ }
+
+ /**
+ * Returns an iterator to the output of the process, with the output type as keys (Process::OUT/ERR).
+ *
+ * @param int $flags A bit field of Process::ITER_* flags
+ *
+ * @throws LogicException in case the output has been disabled
+ * @throws LogicException In case the process is not started
+ *
+ * @return \Generator
+ */
+ public function getIterator($flags = 0)
+ {
+ $this->readPipesForOutput(__FUNCTION__, false);
+
+ $clearOutput = !(self::ITER_KEEP_OUTPUT & $flags);
+ $blocking = !(self::ITER_NON_BLOCKING & $flags);
+ $yieldOut = !(self::ITER_SKIP_OUT & $flags);
+ $yieldErr = !(self::ITER_SKIP_ERR & $flags);
+
+ while (null !== $this->callback || ($yieldOut && !feof($this->stdout)) || ($yieldErr && !feof($this->stderr))) {
+ if ($yieldOut) {
+ $out = stream_get_contents($this->stdout, -1, $this->incrementalOutputOffset);
+
+ if (isset($out[0])) {
+ if ($clearOutput) {
+ $this->clearOutput();
+ } else {
+ $this->incrementalOutputOffset = ftell($this->stdout);
+ }
+
+ yield self::OUT => $out;
+ }
+ }
+
+ if ($yieldErr) {
+ $err = stream_get_contents($this->stderr, -1, $this->incrementalErrorOutputOffset);
+
+ if (isset($err[0])) {
+ if ($clearOutput) {
+ $this->clearErrorOutput();
+ } else {
+ $this->incrementalErrorOutputOffset = ftell($this->stderr);
+ }
+
+ yield self::ERR => $err;
+ }
+ }
+
+ if (!$blocking && !isset($out[0]) && !isset($err[0])) {
+ yield self::OUT => '';
+ }
+
+ $this->checkTimeout();
+ $this->readPipesForOutput(__FUNCTION__, $blocking);
+ }
+ }
+
+ /**
+ * Clears the process output.
+ *
+ * @return $this
+ */
+ public function clearOutput()
+ {
+ ftruncate($this->stdout, 0);
+ fseek($this->stdout, 0);
+ $this->incrementalOutputOffset = 0;
+
+ return $this;
+ }
+
+ /**
+ * Returns the current error output of the process (STDERR).
+ *
+ * @return string The process error output
+ *
+ * @throws LogicException in case the output has been disabled
+ * @throws LogicException In case the process is not started
+ */
+ public function getErrorOutput()
+ {
+ $this->readPipesForOutput(__FUNCTION__);
+
+ if (false === $ret = stream_get_contents($this->stderr, -1, 0)) {
+ return '';
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Returns the errorOutput incrementally.
+ *
+ * In comparison with the getErrorOutput method which always return the
+ * whole error output, this one returns the new error output since the last
+ * call.
+ *
+ * @return string The process error output since the last call
+ *
+ * @throws LogicException in case the output has been disabled
+ * @throws LogicException In case the process is not started
+ */
+ public function getIncrementalErrorOutput()
+ {
+ $this->readPipesForOutput(__FUNCTION__);
+
+ $latest = stream_get_contents($this->stderr, -1, $this->incrementalErrorOutputOffset);
+ $this->incrementalErrorOutputOffset = ftell($this->stderr);
+
+ if (false === $latest) {
+ return '';
+ }
+
+ return $latest;
+ }
+
+ /**
+ * Clears the process output.
+ *
+ * @return $this
+ */
+ public function clearErrorOutput()
+ {
+ ftruncate($this->stderr, 0);
+ fseek($this->stderr, 0);
+ $this->incrementalErrorOutputOffset = 0;
+
+ return $this;
+ }
+
+ /**
+ * Returns the exit code returned by the process.
+ *
+ * @return null|int The exit status code, null if the Process is not terminated
+ *
+ * @throws RuntimeException In case --enable-sigchild is activated and the sigchild compatibility mode is disabled
+ */
+ public function getExitCode()
+ {
+ if (!$this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
+ throw new RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.');
+ }
+
+ $this->updateStatus(false);
+
+ return $this->exitcode;
+ }
+
+ /**
+ * Returns a string representation for the exit code returned by the process.
+ *
+ * This method relies on the Unix exit code status standardization
+ * and might not be relevant for other operating systems.
+ *
+ * @return null|string A string representation for the exit status code, null if the Process is not terminated
+ *
+ * @see http://tldp.org/LDP/abs/html/exitcodes.html
+ * @see http://en.wikipedia.org/wiki/Unix_signal
+ */
+ public function getExitCodeText()
+ {
+ if (null === $exitcode = $this->getExitCode()) {
+ return;
+ }
+
+ return isset(self::$exitCodes[$exitcode]) ? self::$exitCodes[$exitcode] : 'Unknown error';
+ }
+
+ /**
+ * Checks if the process ended successfully.
+ *
+ * @return bool true if the process ended successfully, false otherwise
+ */
+ public function isSuccessful()
+ {
+ return 0 === $this->getExitCode();
+ }
+
+ /**
+ * Returns true if the child process has been terminated by an uncaught signal.
+ *
+ * It always returns false on Windows.
+ *
+ * @return bool
+ *
+ * @throws RuntimeException In case --enable-sigchild is activated
+ * @throws LogicException In case the process is not terminated
+ */
+ public function hasBeenSignaled()
+ {
+ $this->requireProcessIsTerminated(__FUNCTION__);
+
+ if (!$this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
+ throw new RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.');
+ }
+
+ return $this->processInformation['signaled'];
+ }
+
+ /**
+ * Returns the number of the signal that caused the child process to terminate its execution.
+ *
+ * It is only meaningful if hasBeenSignaled() returns true.
+ *
+ * @return int
+ *
+ * @throws RuntimeException In case --enable-sigchild is activated
+ * @throws LogicException In case the process is not terminated
+ */
+ public function getTermSignal()
+ {
+ $this->requireProcessIsTerminated(__FUNCTION__);
+
+ if ($this->isSigchildEnabled() && (!$this->enhanceSigchildCompatibility || -1 === $this->processInformation['termsig'])) {
+ throw new RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.');
+ }
+
+ return $this->processInformation['termsig'];
+ }
+
+ /**
+ * Returns true if the child process has been stopped by a signal.
+ *
+ * It always returns false on Windows.
+ *
+ * @return bool
+ *
+ * @throws LogicException In case the process is not terminated
+ */
+ public function hasBeenStopped()
+ {
+ $this->requireProcessIsTerminated(__FUNCTION__);
+
+ return $this->processInformation['stopped'];
+ }
+
+ /**
+ * Returns the number of the signal that caused the child process to stop its execution.
+ *
+ * It is only meaningful if hasBeenStopped() returns true.
+ *
+ * @return int
+ *
+ * @throws LogicException In case the process is not terminated
+ */
+ public function getStopSignal()
+ {
+ $this->requireProcessIsTerminated(__FUNCTION__);
+
+ return $this->processInformation['stopsig'];
+ }
+
+ /**
+ * Checks if the process is currently running.
+ *
+ * @return bool true if the process is currently running, false otherwise
+ */
+ public function isRunning()
+ {
+ if (self::STATUS_STARTED !== $this->status) {
+ return false;
+ }
+
+ $this->updateStatus(false);
+
+ return $this->processInformation['running'];
+ }
+
+ /**
+ * Checks if the process has been started with no regard to the current state.
+ *
+ * @return bool true if status is ready, false otherwise
+ */
+ public function isStarted()
+ {
+ return self::STATUS_READY != $this->status;
+ }
+
+ /**
+ * Checks if the process is terminated.
+ *
+ * @return bool true if process is terminated, false otherwise
+ */
+ public function isTerminated()
+ {
+ $this->updateStatus(false);
+
+ return self::STATUS_TERMINATED == $this->status;
+ }
+
+ /**
+ * Gets the process status.
+ *
+ * The status is one of: ready, started, terminated.
+ *
+ * @return string The current process status
+ */
+ public function getStatus()
+ {
+ $this->updateStatus(false);
+
+ return $this->status;
+ }
+
+ /**
+ * Stops the process.
+ *
+ * @param int|float $timeout The timeout in seconds
+ * @param int $signal A POSIX signal to send in case the process has not stop at timeout, default is SIGKILL (9)
+ *
+ * @return int The exit-code of the process
+ */
+ public function stop($timeout = 10, $signal = null)
+ {
+ $timeoutMicro = microtime(true) + $timeout;
+ if ($this->isRunning()) {
+ // given `SIGTERM` may not be defined and that `proc_terminate` uses the constant value and not the constant itself, we use the same here
+ $this->doSignal(15, false);
+ do {
+ usleep(1000);
+ } while ($this->isRunning() && microtime(true) < $timeoutMicro);
+
+ if ($this->isRunning()) {
+ // Avoid exception here: process is supposed to be running, but it might have stopped just
+ // after this line. In any case, let's silently discard the error, we cannot do anything.
+ $this->doSignal($signal ?: 9, false);
+ }
+ }
+
+ if ($this->isRunning()) {
+ if (isset($this->fallbackStatus['pid'])) {
+ unset($this->fallbackStatus['pid']);
+
+ return $this->stop(0, $signal);
+ }
+ $this->close();
+ }
+
+ return $this->exitcode;
+ }
+
+ /**
+ * Adds a line to the STDOUT stream.
+ *
+ * @internal
+ *
+ * @param string $line The line to append
+ */
+ public function addOutput($line)
+ {
+ $this->lastOutputTime = microtime(true);
+
+ fseek($this->stdout, 0, SEEK_END);
+ fwrite($this->stdout, $line);
+ fseek($this->stdout, $this->incrementalOutputOffset);
+ }
+
+ /**
+ * Adds a line to the STDERR stream.
+ *
+ * @internal
+ *
+ * @param string $line The line to append
+ */
+ public function addErrorOutput($line)
+ {
+ $this->lastOutputTime = microtime(true);
+
+ fseek($this->stderr, 0, SEEK_END);
+ fwrite($this->stderr, $line);
+ fseek($this->stderr, $this->incrementalErrorOutputOffset);
+ }
+
+ /**
+ * Gets the command line to be executed.
+ *
+ * @return string The command to execute
+ */
+ public function getCommandLine()
+ {
+ return is_array($this->commandline) ? implode(' ', array_map(array($this, 'escapeArgument'), $this->commandline)) : $this->commandline;
+ }
+
+ /**
+ * Sets the command line to be executed.
+ *
+ * @param string|array $commandline The command to execute
+ *
+ * @return self The current Process instance
+ */
+ public function setCommandLine($commandline)
+ {
+ $this->commandline = $commandline;
+
+ return $this;
+ }
+
+ /**
+ * Gets the process timeout (max. runtime).
+ *
+ * @return float|null The timeout in seconds or null if it's disabled
+ */
+ public function getTimeout()
+ {
+ return $this->timeout;
+ }
+
+ /**
+ * Gets the process idle timeout (max. time since last output).
+ *
+ * @return float|null The timeout in seconds or null if it's disabled
+ */
+ public function getIdleTimeout()
+ {
+ return $this->idleTimeout;
+ }
+
+ /**
+ * Sets the process timeout (max. runtime).
+ *
+ * To disable the timeout, set this value to null.
+ *
+ * @param int|float|null $timeout The timeout in seconds
+ *
+ * @return self The current Process instance
+ *
+ * @throws InvalidArgumentException if the timeout is negative
+ */
+ public function setTimeout($timeout)
+ {
+ $this->timeout = $this->validateTimeout($timeout);
+
+ return $this;
+ }
+
+ /**
+ * Sets the process idle timeout (max. time since last output).
+ *
+ * To disable the timeout, set this value to null.
+ *
+ * @param int|float|null $timeout The timeout in seconds
+ *
+ * @return self The current Process instance
+ *
+ * @throws LogicException if the output is disabled
+ * @throws InvalidArgumentException if the timeout is negative
+ */
+ public function setIdleTimeout($timeout)
+ {
+ if (null !== $timeout && $this->outputDisabled) {
+ throw new LogicException('Idle timeout can not be set while the output is disabled.');
+ }
+
+ $this->idleTimeout = $this->validateTimeout($timeout);
+
+ return $this;
+ }
+
+ /**
+ * Enables or disables the TTY mode.
+ *
+ * @param bool $tty True to enabled and false to disable
+ *
+ * @return self The current Process instance
+ *
+ * @throws RuntimeException In case the TTY mode is not supported
+ */
+ public function setTty($tty)
+ {
+ if ('\\' === DIRECTORY_SEPARATOR && $tty) {
+ throw new RuntimeException('TTY mode is not supported on Windows platform.');
+ }
+ if ($tty) {
+ static $isTtySupported;
+
+ if (null === $isTtySupported) {
+ $isTtySupported = (bool) @proc_open('echo 1 >/dev/null', array(array('file', '/dev/tty', 'r'), array('file', '/dev/tty', 'w'), array('file', '/dev/tty', 'w')), $pipes);
+ }
+
+ if (!$isTtySupported) {
+ throw new RuntimeException('TTY mode requires /dev/tty to be read/writable.');
+ }
+ }
+
+ $this->tty = (bool) $tty;
+
+ return $this;
+ }
+
+ /**
+ * Checks if the TTY mode is enabled.
+ *
+ * @return bool true if the TTY mode is enabled, false otherwise
+ */
+ public function isTty()
+ {
+ return $this->tty;
+ }
+
+ /**
+ * Sets PTY mode.
+ *
+ * @param bool $bool
+ *
+ * @return self
+ */
+ public function setPty($bool)
+ {
+ $this->pty = (bool) $bool;
+
+ return $this;
+ }
+
+ /**
+ * Returns PTY state.
+ *
+ * @return bool
+ */
+ public function isPty()
+ {
+ return $this->pty;
+ }
+
+ /**
+ * Gets the working directory.
+ *
+ * @return string|null The current working directory or null on failure
+ */
+ public function getWorkingDirectory()
+ {
+ if (null === $this->cwd) {
+ // getcwd() will return false if any one of the parent directories does not have
+ // the readable or search mode set, even if the current directory does
+ return getcwd() ?: null;
+ }
+
+ return $this->cwd;
+ }
+
+ /**
+ * Sets the current working directory.
+ *
+ * @param string $cwd The new working directory
+ *
+ * @return self The current Process instance
+ */
+ public function setWorkingDirectory($cwd)
+ {
+ $this->cwd = $cwd;
+
+ return $this;
+ }
+
+ /**
+ * Gets the environment variables.
+ *
+ * @return array The current environment variables
+ */
+ public function getEnv()
+ {
+ return $this->env;
+ }
+
+ /**
+ * Sets the environment variables.
+ *
+ * Each environment variable value should be a string.
+ * If it is an array, the variable is ignored.
+ * If it is false or null, it will be removed when
+ * env vars are otherwise inherited.
+ *
+ * That happens in PHP when 'argv' is registered into
+ * the $_ENV array for instance.
+ *
+ * @param array $env The new environment variables
+ *
+ * @return self The current Process instance
+ */
+ public function setEnv(array $env)
+ {
+ // Process can not handle env values that are arrays
+ $env = array_filter($env, function ($value) {
+ return !is_array($value);
+ });
+
+ $this->env = $env;
+
+ return $this;
+ }
+
+ /**
+ * Gets the Process input.
+ *
+ * @return resource|string|\Iterator|null The Process input
+ */
+ public function getInput()
+ {
+ return $this->input;
+ }
+
+ /**
+ * Sets the input.
+ *
+ * This content will be passed to the underlying process standard input.
+ *
+ * @param string|int|float|bool|resource|\Traversable|null $input The content
+ *
+ * @return self The current Process instance
+ *
+ * @throws LogicException In case the process is running
+ */
+ public function setInput($input)
+ {
+ if ($this->isRunning()) {
+ throw new LogicException('Input can not be set while the process is running.');
+ }
+
+ $this->input = ProcessUtils::validateInput(__METHOD__, $input);
+
+ return $this;
+ }
+
+ /**
+ * Gets the options for proc_open.
+ *
+ * @return array The current options
+ *
+ * @deprecated since version 3.3, to be removed in 4.0.
+ */
+ public function getOptions()
+ {
+ @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED);
+
+ return $this->options;
+ }
+
+ /**
+ * Sets the options for proc_open.
+ *
+ * @param array $options The new options
+ *
+ * @return self The current Process instance
+ *
+ * @deprecated since version 3.3, to be removed in 4.0.
+ */
+ public function setOptions(array $options)
+ {
+ @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED);
+
+ $this->options = $options;
+
+ return $this;
+ }
+
+ /**
+ * Gets whether or not Windows compatibility is enabled.
+ *
+ * This is true by default.
+ *
+ * @return bool
+ *
+ * @deprecated since version 3.3, to be removed in 4.0. Enhanced Windows compatibility will always be enabled.
+ */
+ public function getEnhanceWindowsCompatibility()
+ {
+ @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Enhanced Windows compatibility will always be enabled.', __METHOD__), E_USER_DEPRECATED);
+
+ return $this->enhanceWindowsCompatibility;
+ }
+
+ /**
+ * Sets whether or not Windows compatibility is enabled.
+ *
+ * @param bool $enhance
+ *
+ * @return self The current Process instance
+ *
+ * @deprecated since version 3.3, to be removed in 4.0. Enhanced Windows compatibility will always be enabled.
+ */
+ public function setEnhanceWindowsCompatibility($enhance)
+ {
+ @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Enhanced Windows compatibility will always be enabled.', __METHOD__), E_USER_DEPRECATED);
+
+ $this->enhanceWindowsCompatibility = (bool) $enhance;
+
+ return $this;
+ }
+
+ /**
+ * Returns whether sigchild compatibility mode is activated or not.
+ *
+ * @return bool
+ *
+ * @deprecated since version 3.3, to be removed in 4.0. Sigchild compatibility will always be enabled.
+ */
+ public function getEnhanceSigchildCompatibility()
+ {
+ @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Sigchild compatibility will always be enabled.', __METHOD__), E_USER_DEPRECATED);
+
+ return $this->enhanceSigchildCompatibility;
+ }
+
+ /**
+ * Activates sigchild compatibility mode.
+ *
+ * Sigchild compatibility mode is required to get the exit code and
+ * determine the success of a process when PHP has been compiled with
+ * the --enable-sigchild option
+ *
+ * @param bool $enhance
+ *
+ * @return self The current Process instance
+ *
+ * @deprecated since version 3.3, to be removed in 4.0.
+ */
+ public function setEnhanceSigchildCompatibility($enhance)
+ {
+ @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Sigchild compatibility will always be enabled.', __METHOD__), E_USER_DEPRECATED);
+
+ $this->enhanceSigchildCompatibility = (bool) $enhance;
+
+ return $this;
+ }
+
+ /**
+ * Sets whether environment variables will be inherited or not.
+ *
+ * @param bool $inheritEnv
+ *
+ * @return self The current Process instance
+ */
+ public function inheritEnvironmentVariables($inheritEnv = true)
+ {
+ if (!$inheritEnv) {
+ @trigger_error('Not inheriting environment variables is deprecated since Symfony 3.3 and will always happen in 4.0. Set "Process::inheritEnvironmentVariables()" to true instead.', E_USER_DEPRECATED);
+ }
+
+ $this->inheritEnv = (bool) $inheritEnv;
+
+ return $this;
+ }
+
+ /**
+ * Returns whether environment variables will be inherited or not.
+ *
+ * @return bool
+ *
+ * @deprecated since version 3.3, to be removed in 4.0. Environment variables will always be inherited.
+ */
+ public function areEnvironmentVariablesInherited()
+ {
+ @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Environment variables will always be inherited.', __METHOD__), E_USER_DEPRECATED);
+
+ return $this->inheritEnv;
+ }
+
+ /**
+ * Performs a check between the timeout definition and the time the process started.
+ *
+ * In case you run a background process (with the start method), you should
+ * trigger this method regularly to ensure the process timeout
+ *
+ * @throws ProcessTimedOutException In case the timeout was reached
+ */
+ public function checkTimeout()
+ {
+ if (self::STATUS_STARTED !== $this->status) {
+ return;
+ }
+
+ if (null !== $this->timeout && $this->timeout < microtime(true) - $this->starttime) {
+ $this->stop(0);
+
+ throw new ProcessTimedOutException($this, ProcessTimedOutException::TYPE_GENERAL);
+ }
+
+ if (null !== $this->idleTimeout && $this->idleTimeout < microtime(true) - $this->lastOutputTime) {
+ $this->stop(0);
+
+ throw new ProcessTimedOutException($this, ProcessTimedOutException::TYPE_IDLE);
+ }
+ }
+
+ /**
+ * Returns whether PTY is supported on the current operating system.
+ *
+ * @return bool
+ */
+ public static function isPtySupported()
+ {
+ static $result;
+
+ if (null !== $result) {
+ return $result;
+ }
+
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ return $result = false;
+ }
+
+ return $result = (bool) @proc_open('echo 1 >/dev/null', array(array('pty'), array('pty'), array('pty')), $pipes);
+ }
+
+ /**
+ * Creates the descriptors needed by the proc_open.
+ *
+ * @return array
+ */
+ private function getDescriptors()
+ {
+ if ($this->input instanceof \Iterator) {
+ $this->input->rewind();
+ }
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->processPipes = new WindowsPipes($this->input, !$this->outputDisabled || $this->hasCallback);
+ } else {
+ $this->processPipes = new UnixPipes($this->isTty(), $this->isPty(), $this->input, !$this->outputDisabled || $this->hasCallback);
+ }
+
+ return $this->processPipes->getDescriptors();
+ }
+
+ /**
+ * Builds up the callback used by wait().
+ *
+ * The callbacks adds all occurred output to the specific buffer and calls
+ * the user callback (if present) with the received output.
+ *
+ * @param callable|null $callback The user defined PHP callback
+ *
+ * @return \Closure A PHP closure
+ */
+ protected function buildCallback(callable $callback = null)
+ {
+ if ($this->outputDisabled) {
+ return function ($type, $data) use ($callback) {
+ if (null !== $callback) {
+ call_user_func($callback, $type, $data);
+ }
+ };
+ }
+
+ $out = self::OUT;
+
+ return function ($type, $data) use ($callback, $out) {
+ if ($out == $type) {
+ $this->addOutput($data);
+ } else {
+ $this->addErrorOutput($data);
+ }
+
+ if (null !== $callback) {
+ call_user_func($callback, $type, $data);
+ }
+ };
+ }
+
+ /**
+ * Updates the status of the process, reads pipes.
+ *
+ * @param bool $blocking Whether to use a blocking read call
+ */
+ protected function updateStatus($blocking)
+ {
+ if (self::STATUS_STARTED !== $this->status) {
+ return;
+ }
+
+ $this->processInformation = proc_get_status($this->process);
+ $running = $this->processInformation['running'];
+
+ $this->readPipes($running && $blocking, '\\' !== DIRECTORY_SEPARATOR || !$running);
+
+ if ($this->fallbackStatus && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
+ $this->processInformation = $this->fallbackStatus + $this->processInformation;
+ }
+
+ if (!$running) {
+ $this->close();
+ }
+ }
+
+ /**
+ * Returns whether PHP has been compiled with the '--enable-sigchild' option or not.
+ *
+ * @return bool
+ */
+ protected function isSigchildEnabled()
+ {
+ if (null !== self::$sigchild) {
+ return self::$sigchild;
+ }
+
+ if (!function_exists('phpinfo') || defined('HHVM_VERSION')) {
+ return self::$sigchild = false;
+ }
+
+ ob_start();
+ phpinfo(INFO_GENERAL);
+
+ return self::$sigchild = false !== strpos(ob_get_clean(), '--enable-sigchild');
+ }
+
+ /**
+ * Reads pipes for the freshest output.
+ *
+ * @param string $caller The name of the method that needs fresh outputs
+ * @param bool $blocking Whether to use blocking calls or not
+ *
+ * @throws LogicException in case output has been disabled or process is not started
+ */
+ private function readPipesForOutput($caller, $blocking = false)
+ {
+ if ($this->outputDisabled) {
+ throw new LogicException('Output has been disabled.');
+ }
+
+ $this->requireProcessIsStarted($caller);
+
+ $this->updateStatus($blocking);
+ }
+
+ /**
+ * Validates and returns the filtered timeout.
+ *
+ * @param int|float|null $timeout
+ *
+ * @return float|null
+ *
+ * @throws InvalidArgumentException if the given timeout is a negative number
+ */
+ private function validateTimeout($timeout)
+ {
+ $timeout = (float) $timeout;
+
+ if (0.0 === $timeout) {
+ $timeout = null;
+ } elseif ($timeout < 0) {
+ throw new InvalidArgumentException('The timeout value must be a valid positive integer or float number.');
+ }
+
+ return $timeout;
+ }
+
+ /**
+ * Reads pipes, executes callback.
+ *
+ * @param bool $blocking Whether to use blocking calls or not
+ * @param bool $close Whether to close file handles or not
+ */
+ private function readPipes($blocking, $close)
+ {
+ $result = $this->processPipes->readAndWrite($blocking, $close);
+
+ $callback = $this->callback;
+ foreach ($result as $type => $data) {
+ if (3 !== $type) {
+ $callback(self::STDOUT === $type ? self::OUT : self::ERR, $data);
+ } elseif (!isset($this->fallbackStatus['signaled'])) {
+ $this->fallbackStatus['exitcode'] = (int) $data;
+ }
+ }
+ }
+
+ /**
+ * Closes process resource, closes file handles, sets the exitcode.
+ *
+ * @return int The exitcode
+ */
+ private function close()
+ {
+ $this->processPipes->close();
+ if (is_resource($this->process)) {
+ proc_close($this->process);
+ }
+ $this->exitcode = $this->processInformation['exitcode'];
+ $this->status = self::STATUS_TERMINATED;
+
+ if (-1 === $this->exitcode) {
+ if ($this->processInformation['signaled'] && 0 < $this->processInformation['termsig']) {
+ // if process has been signaled, no exitcode but a valid termsig, apply Unix convention
+ $this->exitcode = 128 + $this->processInformation['termsig'];
+ } elseif ($this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
+ $this->processInformation['signaled'] = true;
+ $this->processInformation['termsig'] = -1;
+ }
+ }
+
+ // Free memory from self-reference callback created by buildCallback
+ // Doing so in other contexts like __destruct or by garbage collector is ineffective
+ // Now pipes are closed, so the callback is no longer necessary
+ $this->callback = null;
+
+ return $this->exitcode;
+ }
+
+ /**
+ * Resets data related to the latest run of the process.
+ */
+ private function resetProcessData()
+ {
+ $this->starttime = null;
+ $this->callback = null;
+ $this->exitcode = null;
+ $this->fallbackStatus = array();
+ $this->processInformation = null;
+ $this->stdout = fopen('php://temp/maxmemory:'.(1024 * 1024), 'wb+');
+ $this->stderr = fopen('php://temp/maxmemory:'.(1024 * 1024), 'wb+');
+ $this->process = null;
+ $this->latestSignal = null;
+ $this->status = self::STATUS_READY;
+ $this->incrementalOutputOffset = 0;
+ $this->incrementalErrorOutputOffset = 0;
+ }
+
+ /**
+ * Sends a POSIX signal to the process.
+ *
+ * @param int $signal A valid POSIX signal (see http://www.php.net/manual/en/pcntl.constants.php)
+ * @param bool $throwException Whether to throw exception in case signal failed
+ *
+ * @return bool True if the signal was sent successfully, false otherwise
+ *
+ * @throws LogicException In case the process is not running
+ * @throws RuntimeException In case --enable-sigchild is activated and the process can't be killed
+ * @throws RuntimeException In case of failure
+ */
+ private function doSignal($signal, $throwException)
+ {
+ if (null === $pid = $this->getPid()) {
+ if ($throwException) {
+ throw new LogicException('Can not send signal on a non running process.');
+ }
+
+ return false;
+ }
+
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ exec(sprintf('taskkill /F /T /PID %d 2>&1', $pid), $output, $exitCode);
+ if ($exitCode && $this->isRunning()) {
+ if ($throwException) {
+ throw new RuntimeException(sprintf('Unable to kill the process (%s).', implode(' ', $output)));
+ }
+
+ return false;
+ }
+ } else {
+ if (!$this->enhanceSigchildCompatibility || !$this->isSigchildEnabled()) {
+ $ok = @proc_terminate($this->process, $signal);
+ } elseif (function_exists('posix_kill')) {
+ $ok = @posix_kill($pid, $signal);
+ } elseif ($ok = proc_open(sprintf('kill -%d %d', $signal, $pid), array(2 => array('pipe', 'w')), $pipes)) {
+ $ok = false === fgets($pipes[2]);
+ }
+ if (!$ok) {
+ if ($throwException) {
+ throw new RuntimeException(sprintf('Error while sending signal `%s`.', $signal));
+ }
+
+ return false;
+ }
+ }
+
+ $this->latestSignal = (int) $signal;
+ $this->fallbackStatus['signaled'] = true;
+ $this->fallbackStatus['exitcode'] = -1;
+ $this->fallbackStatus['termsig'] = $this->latestSignal;
+
+ return true;
+ }
+
+ private function prepareWindowsCommandLine($cmd, array &$env)
+ {
+ $uid = uniqid('', true);
+ $varCount = 0;
+ $varCache = array();
+ $cmd = preg_replace_callback(
+ '/"(?:(
+ [^"%!^]*+
+ (?:
+ (?: !LF! | "(?:\^[%!^])?+" )
+ [^"%!^]*+
+ )++
+ ) | [^"]*+ )"/x',
+ function ($m) use (&$env, &$varCache, &$varCount, $uid) {
+ if (!isset($m[1])) {
+ return $m[0];
+ }
+ if (isset($varCache[$m[0]])) {
+ return $varCache[$m[0]];
+ }
+ if (false !== strpos($value = $m[1], "\0")) {
+ $value = str_replace("\0", '?', $value);
+ }
+ if (false === strpbrk($value, "\"%!\n")) {
+ return '"'.$value.'"';
+ }
+
+ $value = str_replace(array('!LF!', '"^!"', '"^%"', '"^^"', '""'), array("\n", '!', '%', '^', '"'), $value);
+ $value = '"'.preg_replace('/(\\\\*)"/', '$1$1\\"', $value).'"';
+ $var = $uid.++$varCount;
+
+ $env[$var] = $value;
+
+ return $varCache[$m[0]] = '!'.$var.'!';
+ },
+ $cmd
+ );
+
+ $cmd = 'cmd /V:ON /E:ON /D /C ('.str_replace("\n", ' ', $cmd).')';
+ foreach ($this->processPipes->getFiles() as $offset => $filename) {
+ $cmd .= ' '.$offset.'>"'.$filename.'"';
+ }
+
+ return $cmd;
+ }
+
+ /**
+ * Ensures the process is running or terminated, throws a LogicException if the process has a not started.
+ *
+ * @param string $functionName The function name that was called
+ *
+ * @throws LogicException if the process has not run
+ */
+ private function requireProcessIsStarted($functionName)
+ {
+ if (!$this->isStarted()) {
+ throw new LogicException(sprintf('Process must be started before calling %s.', $functionName));
+ }
+ }
+
+ /**
+ * Ensures the process is terminated, throws a LogicException if the process has a status different than `terminated`.
+ *
+ * @param string $functionName The function name that was called
+ *
+ * @throws LogicException if the process is not yet terminated
+ */
+ private function requireProcessIsTerminated($functionName)
+ {
+ if (!$this->isTerminated()) {
+ throw new LogicException(sprintf('Process must be terminated before calling %s.', $functionName));
+ }
+ }
+
+ /**
+ * Escapes a string to be used as a shell argument.
+ *
+ * @param string $argument The argument that will be escaped
+ *
+ * @return string The escaped argument
+ */
+ private function escapeArgument($argument)
+ {
+ if ('\\' !== DIRECTORY_SEPARATOR) {
+ return "'".str_replace("'", "'\\''", $argument)."'";
+ }
+ if ('' === $argument = (string) $argument) {
+ return '""';
+ }
+ if (false !== strpos($argument, "\0")) {
+ $argument = str_replace("\0", '?', $argument);
+ }
+ if (!preg_match('/[\/()%!^"<>&|\s]/', $argument)) {
+ return $argument;
+ }
+ $argument = preg_replace('/(\\\\+)$/', '$1$1', $argument);
+
+ return '"'.str_replace(array('"', '^', '%', '!', "\n"), array('""', '"^^"', '"^%"', '"^!"', '!LF!'), $argument).'"';
+ }
+
+ private function getDefaultEnv()
+ {
+ $env = array();
+
+ foreach ($_SERVER as $k => $v) {
+ if (is_string($v) && false !== $v = getenv($k)) {
+ $env[$k] = $v;
+ }
+ }
+
+ foreach ($_ENV as $k => $v) {
+ if (is_string($v)) {
+ $env[$k] = $v;
+ }
+ }
+
+ return $env;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/ProcessBuilder.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/ProcessBuilder.php
new file mode 100644
index 0000000..a91147c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/ProcessBuilder.php
@@ -0,0 +1,280 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Process;
+
+@trigger_error(sprintf('The %s class is deprecated since Symfony 3.4 and will be removed in 4.0. Use the Process class instead.', ProcessBuilder::class), E_USER_DEPRECATED);
+
+use Symfony\Component\Process\Exception\InvalidArgumentException;
+use Symfony\Component\Process\Exception\LogicException;
+
+/**
+ * @author Kris Wallsmith <kris@symfony.com>
+ *
+ * @deprecated since version 3.4, to be removed in 4.0. Use the Process class instead.
+ */
+class ProcessBuilder
+{
+ private $arguments;
+ private $cwd;
+ private $env = array();
+ private $input;
+ private $timeout = 60;
+ private $options;
+ private $inheritEnv = true;
+ private $prefix = array();
+ private $outputDisabled = false;
+
+ /**
+ * @param string[] $arguments An array of arguments
+ */
+ public function __construct(array $arguments = array())
+ {
+ $this->arguments = $arguments;
+ }
+
+ /**
+ * Creates a process builder instance.
+ *
+ * @param string[] $arguments An array of arguments
+ *
+ * @return static
+ */
+ public static function create(array $arguments = array())
+ {
+ return new static($arguments);
+ }
+
+ /**
+ * Adds an unescaped argument to the command string.
+ *
+ * @param string $argument A command argument
+ *
+ * @return $this
+ */
+ public function add($argument)
+ {
+ $this->arguments[] = $argument;
+
+ return $this;
+ }
+
+ /**
+ * Adds a prefix to the command string.
+ *
+ * The prefix is preserved when resetting arguments.
+ *
+ * @param string|array $prefix A command prefix or an array of command prefixes
+ *
+ * @return $this
+ */
+ public function setPrefix($prefix)
+ {
+ $this->prefix = is_array($prefix) ? $prefix : array($prefix);
+
+ return $this;
+ }
+
+ /**
+ * Sets the arguments of the process.
+ *
+ * Arguments must not be escaped.
+ * Previous arguments are removed.
+ *
+ * @param string[] $arguments
+ *
+ * @return $this
+ */
+ public function setArguments(array $arguments)
+ {
+ $this->arguments = $arguments;
+
+ return $this;
+ }
+
+ /**
+ * Sets the working directory.
+ *
+ * @param null|string $cwd The working directory
+ *
+ * @return $this
+ */
+ public function setWorkingDirectory($cwd)
+ {
+ $this->cwd = $cwd;
+
+ return $this;
+ }
+
+ /**
+ * Sets whether environment variables will be inherited or not.
+ *
+ * @param bool $inheritEnv
+ *
+ * @return $this
+ */
+ public function inheritEnvironmentVariables($inheritEnv = true)
+ {
+ $this->inheritEnv = $inheritEnv;
+
+ return $this;
+ }
+
+ /**
+ * Sets an environment variable.
+ *
+ * Setting a variable overrides its previous value. Use `null` to unset a
+ * defined environment variable.
+ *
+ * @param string $name The variable name
+ * @param null|string $value The variable value
+ *
+ * @return $this
+ */
+ public function setEnv($name, $value)
+ {
+ $this->env[$name] = $value;
+
+ return $this;
+ }
+
+ /**
+ * Adds a set of environment variables.
+ *
+ * Already existing environment variables with the same name will be
+ * overridden by the new values passed to this method. Pass `null` to unset
+ * a variable.
+ *
+ * @param array $variables The variables
+ *
+ * @return $this
+ */
+ public function addEnvironmentVariables(array $variables)
+ {
+ $this->env = array_replace($this->env, $variables);
+
+ return $this;
+ }
+
+ /**
+ * Sets the input of the process.
+ *
+ * @param resource|string|int|float|bool|\Traversable|null $input The input content
+ *
+ * @return $this
+ *
+ * @throws InvalidArgumentException In case the argument is invalid
+ */
+ public function setInput($input)
+ {
+ $this->input = ProcessUtils::validateInput(__METHOD__, $input);
+
+ return $this;
+ }
+
+ /**
+ * Sets the process timeout.
+ *
+ * To disable the timeout, set this value to null.
+ *
+ * @param float|null $timeout
+ *
+ * @return $this
+ *
+ * @throws InvalidArgumentException
+ */
+ public function setTimeout($timeout)
+ {
+ if (null === $timeout) {
+ $this->timeout = null;
+
+ return $this;
+ }
+
+ $timeout = (float) $timeout;
+
+ if ($timeout < 0) {
+ throw new InvalidArgumentException('The timeout value must be a valid positive integer or float number.');
+ }
+
+ $this->timeout = $timeout;
+
+ return $this;
+ }
+
+ /**
+ * Adds a proc_open option.
+ *
+ * @param string $name The option name
+ * @param string $value The option value
+ *
+ * @return $this
+ */
+ public function setOption($name, $value)
+ {
+ $this->options[$name] = $value;
+
+ return $this;
+ }
+
+ /**
+ * Disables fetching output and error output from the underlying process.
+ *
+ * @return $this
+ */
+ public function disableOutput()
+ {
+ $this->outputDisabled = true;
+
+ return $this;
+ }
+
+ /**
+ * Enables fetching output and error output from the underlying process.
+ *
+ * @return $this
+ */
+ public function enableOutput()
+ {
+ $this->outputDisabled = false;
+
+ return $this;
+ }
+
+ /**
+ * Creates a Process instance and returns it.
+ *
+ * @return Process
+ *
+ * @throws LogicException In case no arguments have been provided
+ */
+ public function getProcess()
+ {
+ if (0 === count($this->prefix) && 0 === count($this->arguments)) {
+ throw new LogicException('You must add() command arguments before calling getProcess().');
+ }
+
+ $arguments = array_merge($this->prefix, $this->arguments);
+ $process = new Process($arguments, $this->cwd, $this->env, $this->input, $this->timeout, $this->options);
+ // to preserve the BC with symfony <3.3, we convert the array structure
+ // to a string structure to avoid the prefixing with the exec command
+ $process->setCommandLine($process->getCommandLine());
+
+ if ($this->inheritEnv) {
+ $process->inheritEnvironmentVariables();
+ }
+ if ($this->outputDisabled) {
+ $process->disableOutput();
+ }
+
+ return $process;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/ProcessUtils.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/ProcessUtils.php
new file mode 100644
index 0000000..c30950c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/ProcessUtils.php
@@ -0,0 +1,123 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Process;
+
+use Symfony\Component\Process\Exception\InvalidArgumentException;
+
+/**
+ * ProcessUtils is a bunch of utility methods.
+ *
+ * This class contains static methods only and is not meant to be instantiated.
+ *
+ * @author Martin Hasoň <martin.hason@gmail.com>
+ */
+class ProcessUtils
+{
+ /**
+ * This class should not be instantiated.
+ */
+ private function __construct()
+ {
+ }
+
+ /**
+ * Escapes a string to be used as a shell argument.
+ *
+ * @param string $argument The argument that will be escaped
+ *
+ * @return string The escaped argument
+ *
+ * @deprecated since version 3.3, to be removed in 4.0. Use a command line array or give env vars to the `Process::start/run()` method instead.
+ */
+ public static function escapeArgument($argument)
+ {
+ @trigger_error('The '.__METHOD__.'() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use a command line array or give env vars to the Process::start/run() method instead.', E_USER_DEPRECATED);
+
+ //Fix for PHP bug #43784 escapeshellarg removes % from given string
+ //Fix for PHP bug #49446 escapeshellarg doesn't work on Windows
+ //@see https://bugs.php.net/bug.php?id=43784
+ //@see https://bugs.php.net/bug.php?id=49446
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ if ('' === $argument) {
+ return escapeshellarg($argument);
+ }
+
+ $escapedArgument = '';
+ $quote = false;
+ foreach (preg_split('/(")/', $argument, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE) as $part) {
+ if ('"' === $part) {
+ $escapedArgument .= '\\"';
+ } elseif (self::isSurroundedBy($part, '%')) {
+ // Avoid environment variable expansion
+ $escapedArgument .= '^%"'.substr($part, 1, -1).'"^%';
+ } else {
+ // escape trailing backslash
+ if ('\\' === substr($part, -1)) {
+ $part .= '\\';
+ }
+ $quote = true;
+ $escapedArgument .= $part;
+ }
+ }
+ if ($quote) {
+ $escapedArgument = '"'.$escapedArgument.'"';
+ }
+
+ return $escapedArgument;
+ }
+
+ return "'".str_replace("'", "'\\''", $argument)."'";
+ }
+
+ /**
+ * Validates and normalizes a Process input.
+ *
+ * @param string $caller The name of method call that validates the input
+ * @param mixed $input The input to validate
+ *
+ * @return mixed The validated input
+ *
+ * @throws InvalidArgumentException In case the input is not valid
+ */
+ public static function validateInput($caller, $input)
+ {
+ if (null !== $input) {
+ if (is_resource($input)) {
+ return $input;
+ }
+ if (is_string($input)) {
+ return $input;
+ }
+ if (is_scalar($input)) {
+ return (string) $input;
+ }
+ if ($input instanceof Process) {
+ return $input->getIterator($input::ITER_SKIP_ERR);
+ }
+ if ($input instanceof \Iterator) {
+ return $input;
+ }
+ if ($input instanceof \Traversable) {
+ return new \IteratorIterator($input);
+ }
+
+ throw new InvalidArgumentException(sprintf('%s only accepts strings, Traversable objects or stream resources.', $caller));
+ }
+
+ return $input;
+ }
+
+ private static function isSurroundedBy($arg, $char)
+ {
+ return 2 < strlen($arg) && $char === $arg[0] && $char === $arg[strlen($arg) - 1];
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/README.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/README.md
new file mode 100644
index 0000000..b7ca5b4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/README.md
@@ -0,0 +1,13 @@
+Process Component
+=================
+
+The Process component executes commands in sub-processes.
+
+Resources
+---------
+
+ * [Documentation](https://symfony.com/doc/current/components/process.html)
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/symfony/issues) and
+ [send Pull Requests](https://github.com/symfony/symfony/pulls)
+ in the [main Symfony repository](https://github.com/symfony/symfony)
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/ExecutableFinderTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/ExecutableFinderTest.php
new file mode 100644
index 0000000..bc692f6
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/ExecutableFinderTest.php
@@ -0,0 +1,133 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Process\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Process\ExecutableFinder;
+
+/**
+ * @author Chris Smith <chris@cs278.org>
+ */
+class ExecutableFinderTest extends TestCase
+{
+ private $path;
+
+ protected function tearDown()
+ {
+ if ($this->path) {
+ // Restore path if it was changed.
+ putenv('PATH='.$this->path);
+ }
+ }
+
+ private function setPath($path)
+ {
+ $this->path = getenv('PATH');
+ putenv('PATH='.$path);
+ }
+
+ public function testFind()
+ {
+ if (ini_get('open_basedir')) {
+ $this->markTestSkipped('Cannot test when open_basedir is set');
+ }
+
+ $this->setPath(dirname(PHP_BINARY));
+
+ $finder = new ExecutableFinder();
+ $result = $finder->find($this->getPhpBinaryName());
+
+ $this->assertSamePath(PHP_BINARY, $result);
+ }
+
+ public function testFindWithDefault()
+ {
+ if (ini_get('open_basedir')) {
+ $this->markTestSkipped('Cannot test when open_basedir is set');
+ }
+
+ $expected = 'defaultValue';
+
+ $this->setPath('');
+
+ $finder = new ExecutableFinder();
+ $result = $finder->find('foo', $expected);
+
+ $this->assertEquals($expected, $result);
+ }
+
+ public function testFindWithExtraDirs()
+ {
+ if (ini_get('open_basedir')) {
+ $this->markTestSkipped('Cannot test when open_basedir is set');
+ }
+
+ $this->setPath('');
+
+ $extraDirs = array(dirname(PHP_BINARY));
+
+ $finder = new ExecutableFinder();
+ $result = $finder->find($this->getPhpBinaryName(), null, $extraDirs);
+
+ $this->assertSamePath(PHP_BINARY, $result);
+ }
+
+ public function testFindWithOpenBaseDir()
+ {
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->markTestSkipped('Cannot run test on windows');
+ }
+
+ if (ini_get('open_basedir')) {
+ $this->markTestSkipped('Cannot test when open_basedir is set');
+ }
+
+ $this->iniSet('open_basedir', dirname(PHP_BINARY).(!defined('HHVM_VERSION') || HHVM_VERSION_ID >= 30800 ? PATH_SEPARATOR.'/' : ''));
+
+ $finder = new ExecutableFinder();
+ $result = $finder->find($this->getPhpBinaryName());
+
+ $this->assertSamePath(PHP_BINARY, $result);
+ }
+
+ public function testFindProcessInOpenBasedir()
+ {
+ if (ini_get('open_basedir')) {
+ $this->markTestSkipped('Cannot test when open_basedir is set');
+ }
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->markTestSkipped('Cannot run test on windows');
+ }
+
+ $this->setPath('');
+ $this->iniSet('open_basedir', PHP_BINARY.(!defined('HHVM_VERSION') || HHVM_VERSION_ID >= 30800 ? PATH_SEPARATOR.'/' : ''));
+
+ $finder = new ExecutableFinder();
+ $result = $finder->find($this->getPhpBinaryName(), false);
+
+ $this->assertSamePath(PHP_BINARY, $result);
+ }
+
+ private function assertSamePath($expected, $tested)
+ {
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->assertEquals(strtolower($expected), strtolower($tested));
+ } else {
+ $this->assertEquals($expected, $tested);
+ }
+ }
+
+ private function getPhpBinaryName()
+ {
+ return basename(PHP_BINARY, '\\' === DIRECTORY_SEPARATOR ? '.exe' : '');
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/NonStopableProcess.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/NonStopableProcess.php
new file mode 100644
index 0000000..5643259
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/NonStopableProcess.php
@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Runs a PHP script that can be stopped only with a SIGKILL (9) signal for 3 seconds.
+ *
+ * @args duration Run this script with a custom duration
+ *
+ * @example `php NonStopableProcess.php 42` will run the script for 42 seconds
+ */
+function handleSignal($signal)
+{
+ switch ($signal) {
+ case SIGTERM:
+ $name = 'SIGTERM';
+ break;
+ case SIGINT:
+ $name = 'SIGINT';
+ break;
+ default:
+ $name = $signal.' (unknown)';
+ break;
+ }
+
+ echo "signal $name\n";
+}
+
+pcntl_signal(SIGTERM, 'handleSignal');
+pcntl_signal(SIGINT, 'handleSignal');
+
+echo 'received ';
+
+$duration = isset($argv[1]) ? (int) $argv[1] : 3;
+$start = microtime(true);
+
+while ($duration > (microtime(true) - $start)) {
+ usleep(10000);
+ pcntl_signal_dispatch();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/PhpExecutableFinderTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/PhpExecutableFinderTest.php
new file mode 100644
index 0000000..b08ad5d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/PhpExecutableFinderTest.php
@@ -0,0 +1,72 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Process\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Process\PhpExecutableFinder;
+
+/**
+ * @author Robert Schönthal <seroscho@googlemail.com>
+ */
+class PhpExecutableFinderTest extends TestCase
+{
+ /**
+ * tests find() with the constant PHP_BINARY.
+ */
+ public function testFind()
+ {
+ if (defined('HHVM_VERSION')) {
+ $this->markTestSkipped('Should not be executed in HHVM context.');
+ }
+
+ $f = new PhpExecutableFinder();
+
+ $current = PHP_BINARY;
+ $args = 'phpdbg' === PHP_SAPI ? ' -qrr' : '';
+
+ $this->assertEquals($current.$args, $f->find(), '::find() returns the executable PHP');
+ $this->assertEquals($current, $f->find(false), '::find() returns the executable PHP');
+ }
+
+ /**
+ * tests find() with the env var / constant PHP_BINARY with HHVM.
+ */
+ public function testFindWithHHVM()
+ {
+ if (!defined('HHVM_VERSION')) {
+ $this->markTestSkipped('Should be executed in HHVM context.');
+ }
+
+ $f = new PhpExecutableFinder();
+
+ $current = getenv('PHP_BINARY') ?: PHP_BINARY;
+
+ $this->assertEquals($current.' --php', $f->find(), '::find() returns the executable PHP');
+ $this->assertEquals($current, $f->find(false), '::find() returns the executable PHP');
+ }
+
+ /**
+ * tests find() with the env var PHP_PATH.
+ */
+ public function testFindArguments()
+ {
+ $f = new PhpExecutableFinder();
+
+ if (defined('HHVM_VERSION')) {
+ $this->assertEquals($f->findArguments(), array('--php'), '::findArguments() returns HHVM arguments');
+ } elseif ('phpdbg' === PHP_SAPI) {
+ $this->assertEquals($f->findArguments(), array('-qrr'), '::findArguments() returns phpdbg arguments');
+ } else {
+ $this->assertEquals($f->findArguments(), array(), '::findArguments() returns no arguments');
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/PhpProcessTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/PhpProcessTest.php
new file mode 100644
index 0000000..f67368c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/PhpProcessTest.php
@@ -0,0 +1,48 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Process\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Process\PhpProcess;
+
+class PhpProcessTest extends TestCase
+{
+ public function testNonBlockingWorks()
+ {
+ $expected = 'hello world!';
+ $process = new PhpProcess(<<<PHP
+<?php echo '$expected';
+PHP
+ );
+ $process->start();
+ $process->wait();
+ $this->assertEquals($expected, $process->getOutput());
+ }
+
+ public function testCommandLine()
+ {
+ $process = new PhpProcess(<<<'PHP'
+<?php echo phpversion().PHP_SAPI;
+PHP
+ );
+
+ $commandLine = $process->getCommandLine();
+
+ $process->start();
+ $this->assertContains($commandLine, $process->getCommandLine(), '::getCommandLine() returns the command line of PHP after start');
+
+ $process->wait();
+ $this->assertContains($commandLine, $process->getCommandLine(), '::getCommandLine() returns the command line of PHP after wait');
+
+ $this->assertSame(PHP_VERSION.PHP_SAPI, $process->getOutput());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/PipeStdinInStdoutStdErrStreamSelect.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/PipeStdinInStdoutStdErrStreamSelect.php
new file mode 100644
index 0000000..bbd7ddf
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/PipeStdinInStdoutStdErrStreamSelect.php
@@ -0,0 +1,72 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+define('ERR_SELECT_FAILED', 1);
+define('ERR_TIMEOUT', 2);
+define('ERR_READ_FAILED', 3);
+define('ERR_WRITE_FAILED', 4);
+
+$read = array(STDIN);
+$write = array(STDOUT, STDERR);
+
+stream_set_blocking(STDIN, 0);
+stream_set_blocking(STDOUT, 0);
+stream_set_blocking(STDERR, 0);
+
+$out = $err = '';
+while ($read || $write) {
+ $r = $read;
+ $w = $write;
+ $e = null;
+ $n = stream_select($r, $w, $e, 5);
+
+ if (false === $n) {
+ die(ERR_SELECT_FAILED);
+ } elseif ($n < 1) {
+ die(ERR_TIMEOUT);
+ }
+
+ if (in_array(STDOUT, $w) && strlen($out) > 0) {
+ $written = fwrite(STDOUT, (binary) $out, 32768);
+ if (false === $written) {
+ die(ERR_WRITE_FAILED);
+ }
+ $out = (binary) substr($out, $written);
+ }
+ if (null === $read && '' === $out) {
+ $write = array_diff($write, array(STDOUT));
+ }
+
+ if (in_array(STDERR, $w) && strlen($err) > 0) {
+ $written = fwrite(STDERR, (binary) $err, 32768);
+ if (false === $written) {
+ die(ERR_WRITE_FAILED);
+ }
+ $err = (binary) substr($err, $written);
+ }
+ if (null === $read && '' === $err) {
+ $write = array_diff($write, array(STDERR));
+ }
+
+ if ($r) {
+ $str = fread(STDIN, 32768);
+ if (false !== $str) {
+ $out .= $str;
+ $err .= $str;
+ }
+ if (false === $str || feof(STDIN)) {
+ $read = null;
+ if (!feof(STDIN)) {
+ die(ERR_READ_FAILED);
+ }
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/ProcessBuilderTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/ProcessBuilderTest.php
new file mode 100644
index 0000000..36c40bf
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/ProcessBuilderTest.php
@@ -0,0 +1,226 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Process\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Process\ProcessBuilder;
+
+/**
+ * @group legacy
+ */
+class ProcessBuilderTest extends TestCase
+{
+ public function testInheritEnvironmentVars()
+ {
+ $proc = ProcessBuilder::create()
+ ->add('foo')
+ ->getProcess();
+
+ $this->assertTrue($proc->areEnvironmentVariablesInherited());
+
+ $proc = ProcessBuilder::create()
+ ->add('foo')
+ ->inheritEnvironmentVariables(false)
+ ->getProcess();
+
+ $this->assertFalse($proc->areEnvironmentVariablesInherited());
+ }
+
+ public function testAddEnvironmentVariables()
+ {
+ $pb = new ProcessBuilder();
+ $env = array(
+ 'foo' => 'bar',
+ 'foo2' => 'bar2',
+ );
+ $proc = $pb
+ ->add('command')
+ ->setEnv('foo', 'bar2')
+ ->addEnvironmentVariables($env)
+ ->getProcess()
+ ;
+
+ $this->assertSame($env, $proc->getEnv());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Process\Exception\InvalidArgumentException
+ */
+ public function testNegativeTimeoutFromSetter()
+ {
+ $pb = new ProcessBuilder();
+ $pb->setTimeout(-1);
+ }
+
+ public function testNullTimeout()
+ {
+ $pb = new ProcessBuilder();
+ $pb->setTimeout(10);
+ $pb->setTimeout(null);
+
+ $r = new \ReflectionObject($pb);
+ $p = $r->getProperty('timeout');
+ $p->setAccessible(true);
+
+ $this->assertNull($p->getValue($pb));
+ }
+
+ public function testShouldSetArguments()
+ {
+ $pb = new ProcessBuilder(array('initial'));
+ $pb->setArguments(array('second'));
+
+ $proc = $pb->getProcess();
+
+ $this->assertContains('second', $proc->getCommandLine());
+ }
+
+ public function testPrefixIsPrependedToAllGeneratedProcess()
+ {
+ $pb = new ProcessBuilder();
+ $pb->setPrefix('/usr/bin/php');
+
+ $proc = $pb->setArguments(array('-v'))->getProcess();
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->assertEquals('"/usr/bin/php" -v', $proc->getCommandLine());
+ } else {
+ $this->assertEquals("'/usr/bin/php' '-v'", $proc->getCommandLine());
+ }
+
+ $proc = $pb->setArguments(array('-i'))->getProcess();
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->assertEquals('"/usr/bin/php" -i', $proc->getCommandLine());
+ } else {
+ $this->assertEquals("'/usr/bin/php' '-i'", $proc->getCommandLine());
+ }
+ }
+
+ public function testArrayPrefixesArePrependedToAllGeneratedProcess()
+ {
+ $pb = new ProcessBuilder();
+ $pb->setPrefix(array('/usr/bin/php', 'composer.phar'));
+
+ $proc = $pb->setArguments(array('-v'))->getProcess();
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->assertEquals('"/usr/bin/php" composer.phar -v', $proc->getCommandLine());
+ } else {
+ $this->assertEquals("'/usr/bin/php' 'composer.phar' '-v'", $proc->getCommandLine());
+ }
+
+ $proc = $pb->setArguments(array('-i'))->getProcess();
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->assertEquals('"/usr/bin/php" composer.phar -i', $proc->getCommandLine());
+ } else {
+ $this->assertEquals("'/usr/bin/php' 'composer.phar' '-i'", $proc->getCommandLine());
+ }
+ }
+
+ public function testShouldEscapeArguments()
+ {
+ $pb = new ProcessBuilder(array('%path%', 'foo " bar', '%baz%baz'));
+ $proc = $pb->getProcess();
+
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->assertSame('""^%"path"^%"" "foo "" bar" ""^%"baz"^%"baz"', $proc->getCommandLine());
+ } else {
+ $this->assertSame("'%path%' 'foo \" bar' '%baz%baz'", $proc->getCommandLine());
+ }
+ }
+
+ public function testShouldEscapeArgumentsAndPrefix()
+ {
+ $pb = new ProcessBuilder(array('arg'));
+ $pb->setPrefix('%prefix%');
+ $proc = $pb->getProcess();
+
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->assertSame('""^%"prefix"^%"" arg', $proc->getCommandLine());
+ } else {
+ $this->assertSame("'%prefix%' 'arg'", $proc->getCommandLine());
+ }
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Process\Exception\LogicException
+ */
+ public function testShouldThrowALogicExceptionIfNoPrefixAndNoArgument()
+ {
+ ProcessBuilder::create()->getProcess();
+ }
+
+ public function testShouldNotThrowALogicExceptionIfNoArgument()
+ {
+ $process = ProcessBuilder::create()
+ ->setPrefix('/usr/bin/php')
+ ->getProcess();
+
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->assertEquals('"/usr/bin/php"', $process->getCommandLine());
+ } else {
+ $this->assertEquals("'/usr/bin/php'", $process->getCommandLine());
+ }
+ }
+
+ public function testShouldNotThrowALogicExceptionIfNoPrefix()
+ {
+ $process = ProcessBuilder::create(array('/usr/bin/php'))
+ ->getProcess();
+
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->assertEquals('"/usr/bin/php"', $process->getCommandLine());
+ } else {
+ $this->assertEquals("'/usr/bin/php'", $process->getCommandLine());
+ }
+ }
+
+ public function testShouldReturnProcessWithDisabledOutput()
+ {
+ $process = ProcessBuilder::create(array('/usr/bin/php'))
+ ->disableOutput()
+ ->getProcess();
+
+ $this->assertTrue($process->isOutputDisabled());
+ }
+
+ public function testShouldReturnProcessWithEnabledOutput()
+ {
+ $process = ProcessBuilder::create(array('/usr/bin/php'))
+ ->disableOutput()
+ ->enableOutput()
+ ->getProcess();
+
+ $this->assertFalse($process->isOutputDisabled());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Process\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Symfony\Component\Process\ProcessBuilder::setInput only accepts strings, Traversable objects or stream resources.
+ */
+ public function testInvalidInput()
+ {
+ $builder = ProcessBuilder::create();
+ $builder->setInput(array());
+ }
+
+ public function testDoesNotPrefixExec()
+ {
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->markTestSkipped('This test cannot run on Windows.');
+ }
+
+ $builder = ProcessBuilder::create(array('command', '-v', 'ls'));
+ $process = $builder->getProcess();
+ $process->run();
+
+ $this->assertTrue($process->isSuccessful());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/ProcessFailedExceptionTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/ProcessFailedExceptionTest.php
new file mode 100644
index 0000000..25712af
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/ProcessFailedExceptionTest.php
@@ -0,0 +1,137 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Process\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Process\Exception\ProcessFailedException;
+
+/**
+ * @author Sebastian Marek <proofek@gmail.com>
+ */
+class ProcessFailedExceptionTest extends TestCase
+{
+ /**
+ * tests ProcessFailedException throws exception if the process was successful.
+ */
+ public function testProcessFailedExceptionThrowsException()
+ {
+ $process = $this->getMockBuilder('Symfony\Component\Process\Process')->setMethods(array('isSuccessful'))->setConstructorArgs(array('php'))->getMock();
+ $process->expects($this->once())
+ ->method('isSuccessful')
+ ->will($this->returnValue(true));
+
+ if (method_exists($this, 'expectException')) {
+ $this->expectException(\InvalidArgumentException::class);
+ $this->expectExceptionMessage('Expected a failed process, but the given process was successful.');
+ } else {
+ $this->setExpectedException(\InvalidArgumentException::class, 'Expected a failed process, but the given process was successful.');
+ }
+
+ new ProcessFailedException($process);
+ }
+
+ /**
+ * tests ProcessFailedException uses information from process output
+ * to generate exception message.
+ */
+ public function testProcessFailedExceptionPopulatesInformationFromProcessOutput()
+ {
+ $cmd = 'php';
+ $exitCode = 1;
+ $exitText = 'General error';
+ $output = 'Command output';
+ $errorOutput = 'FATAL: Unexpected error';
+ $workingDirectory = getcwd();
+
+ $process = $this->getMockBuilder('Symfony\Component\Process\Process')->setMethods(array('isSuccessful', 'getOutput', 'getErrorOutput', 'getExitCode', 'getExitCodeText', 'isOutputDisabled', 'getWorkingDirectory'))->setConstructorArgs(array($cmd))->getMock();
+ $process->expects($this->once())
+ ->method('isSuccessful')
+ ->will($this->returnValue(false));
+
+ $process->expects($this->once())
+ ->method('getOutput')
+ ->will($this->returnValue($output));
+
+ $process->expects($this->once())
+ ->method('getErrorOutput')
+ ->will($this->returnValue($errorOutput));
+
+ $process->expects($this->once())
+ ->method('getExitCode')
+ ->will($this->returnValue($exitCode));
+
+ $process->expects($this->once())
+ ->method('getExitCodeText')
+ ->will($this->returnValue($exitText));
+
+ $process->expects($this->once())
+ ->method('isOutputDisabled')
+ ->will($this->returnValue(false));
+
+ $process->expects($this->once())
+ ->method('getWorkingDirectory')
+ ->will($this->returnValue($workingDirectory));
+
+ $exception = new ProcessFailedException($process);
+
+ $this->assertEquals(
+ "The command \"$cmd\" failed.\n\nExit Code: $exitCode($exitText)\n\nWorking directory: {$workingDirectory}\n\nOutput:\n================\n{$output}\n\nError Output:\n================\n{$errorOutput}",
+ $exception->getMessage()
+ );
+ }
+
+ /**
+ * Tests that ProcessFailedException does not extract information from
+ * process output if it was previously disabled.
+ */
+ public function testDisabledOutputInFailedExceptionDoesNotPopulateOutput()
+ {
+ $cmd = 'php';
+ $exitCode = 1;
+ $exitText = 'General error';
+ $workingDirectory = getcwd();
+
+ $process = $this->getMockBuilder('Symfony\Component\Process\Process')->setMethods(array('isSuccessful', 'isOutputDisabled', 'getExitCode', 'getExitCodeText', 'getOutput', 'getErrorOutput', 'getWorkingDirectory'))->setConstructorArgs(array($cmd))->getMock();
+ $process->expects($this->once())
+ ->method('isSuccessful')
+ ->will($this->returnValue(false));
+
+ $process->expects($this->never())
+ ->method('getOutput');
+
+ $process->expects($this->never())
+ ->method('getErrorOutput');
+
+ $process->expects($this->once())
+ ->method('getExitCode')
+ ->will($this->returnValue($exitCode));
+
+ $process->expects($this->once())
+ ->method('getExitCodeText')
+ ->will($this->returnValue($exitText));
+
+ $process->expects($this->once())
+ ->method('isOutputDisabled')
+ ->will($this->returnValue(true));
+
+ $process->expects($this->once())
+ ->method('getWorkingDirectory')
+ ->will($this->returnValue($workingDirectory));
+
+ $exception = new ProcessFailedException($process);
+
+ $this->assertEquals(
+ "The command \"$cmd\" failed.\n\nExit Code: $exitCode($exitText)\n\nWorking directory: {$workingDirectory}",
+ $exception->getMessage()
+ );
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/ProcessTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/ProcessTest.php
new file mode 100644
index 0000000..bca7ddd
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/ProcessTest.php
@@ -0,0 +1,1621 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Process\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Process\Exception\LogicException;
+use Symfony\Component\Process\Exception\ProcessTimedOutException;
+use Symfony\Component\Process\Exception\RuntimeException;
+use Symfony\Component\Process\InputStream;
+use Symfony\Component\Process\PhpExecutableFinder;
+use Symfony\Component\Process\Pipes\PipesInterface;
+use Symfony\Component\Process\Process;
+
+/**
+ * @author Robert Schönthal <seroscho@googlemail.com>
+ */
+class ProcessTest extends TestCase
+{
+ private static $phpBin;
+ private static $process;
+ private static $sigchild;
+ private static $notEnhancedSigchild = false;
+
+ public static function setUpBeforeClass()
+ {
+ $phpBin = new PhpExecutableFinder();
+ self::$phpBin = getenv('SYMFONY_PROCESS_PHP_TEST_BINARY') ?: ('phpdbg' === PHP_SAPI ? 'php' : $phpBin->find());
+
+ ob_start();
+ phpinfo(INFO_GENERAL);
+ self::$sigchild = false !== strpos(ob_get_clean(), '--enable-sigchild');
+ }
+
+ protected function tearDown()
+ {
+ if (self::$process) {
+ self::$process->stop(0);
+ self::$process = null;
+ }
+ }
+
+ /**
+ * @group legacy
+ * @expectedDeprecation The provided cwd does not exist. Command is currently ran against getcwd(). This behavior is deprecated since Symfony 3.4 and will be removed in 4.0.
+ */
+ public function testInvalidCwd()
+ {
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->markTestSkipped('False-positive on Windows/appveyor.');
+ }
+
+ // Check that it works fine if the CWD exists
+ $cmd = new Process('echo test', __DIR__);
+ $cmd->run();
+
+ $cmd = new Process('echo test', __DIR__.'/notfound/');
+ $cmd->run();
+ }
+
+ public function testThatProcessDoesNotThrowWarningDuringRun()
+ {
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->markTestSkipped('This test is transient on Windows');
+ }
+ @trigger_error('Test Error', E_USER_NOTICE);
+ $process = $this->getProcessForCode('sleep(3)');
+ $process->run();
+ $actualError = error_get_last();
+ $this->assertEquals('Test Error', $actualError['message']);
+ $this->assertEquals(E_USER_NOTICE, $actualError['type']);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Process\Exception\InvalidArgumentException
+ */
+ public function testNegativeTimeoutFromConstructor()
+ {
+ $this->getProcess('', null, null, null, -1);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Process\Exception\InvalidArgumentException
+ */
+ public function testNegativeTimeoutFromSetter()
+ {
+ $p = $this->getProcess('');
+ $p->setTimeout(-1);
+ }
+
+ public function testFloatAndNullTimeout()
+ {
+ $p = $this->getProcess('');
+
+ $p->setTimeout(10);
+ $this->assertSame(10.0, $p->getTimeout());
+
+ $p->setTimeout(null);
+ $this->assertNull($p->getTimeout());
+
+ $p->setTimeout(0.0);
+ $this->assertNull($p->getTimeout());
+ }
+
+ /**
+ * @requires extension pcntl
+ */
+ public function testStopWithTimeoutIsActuallyWorking()
+ {
+ $p = $this->getProcess(array(self::$phpBin, __DIR__.'/NonStopableProcess.php', 30));
+ $p->start();
+
+ while (false === strpos($p->getOutput(), 'received')) {
+ usleep(1000);
+ }
+ $start = microtime(true);
+ $p->stop(0.1);
+
+ $p->wait();
+
+ $this->assertLessThan(15, microtime(true) - $start);
+ }
+
+ public function testAllOutputIsActuallyReadOnTermination()
+ {
+ // this code will result in a maximum of 2 reads of 8192 bytes by calling
+ // start() and isRunning(). by the time getOutput() is called the process
+ // has terminated so the internal pipes array is already empty. normally
+ // the call to start() will not read any data as the process will not have
+ // generated output, but this is non-deterministic so we must count it as
+ // a possibility. therefore we need 2 * PipesInterface::CHUNK_SIZE plus
+ // another byte which will never be read.
+ $expectedOutputSize = PipesInterface::CHUNK_SIZE * 2 + 2;
+
+ $code = sprintf('echo str_repeat(\'*\', %d);', $expectedOutputSize);
+ $p = $this->getProcessForCode($code);
+
+ $p->start();
+
+ // Don't call Process::run nor Process::wait to avoid any read of pipes
+ $h = new \ReflectionProperty($p, 'process');
+ $h->setAccessible(true);
+ $h = $h->getValue($p);
+ $s = @proc_get_status($h);
+
+ while (!empty($s['running'])) {
+ usleep(1000);
+ $s = proc_get_status($h);
+ }
+
+ $o = $p->getOutput();
+
+ $this->assertEquals($expectedOutputSize, strlen($o));
+ }
+
+ public function testCallbacksAreExecutedWithStart()
+ {
+ $process = $this->getProcess('echo foo');
+ $process->start(function ($type, $buffer) use (&$data) {
+ $data .= $buffer;
+ });
+
+ $process->wait();
+
+ $this->assertSame('foo'.PHP_EOL, $data);
+ }
+
+ /**
+ * tests results from sub processes.
+ *
+ * @dataProvider responsesCodeProvider
+ */
+ public function testProcessResponses($expected, $getter, $code)
+ {
+ $p = $this->getProcessForCode($code);
+ $p->run();
+
+ $this->assertSame($expected, $p->$getter());
+ }
+
+ /**
+ * tests results from sub processes.
+ *
+ * @dataProvider pipesCodeProvider
+ */
+ public function testProcessPipes($code, $size)
+ {
+ $expected = str_repeat(str_repeat('*', 1024), $size).'!';
+ $expectedLength = (1024 * $size) + 1;
+
+ $p = $this->getProcessForCode($code);
+ $p->setInput($expected);
+ $p->run();
+
+ $this->assertEquals($expectedLength, strlen($p->getOutput()));
+ $this->assertEquals($expectedLength, strlen($p->getErrorOutput()));
+ }
+
+ /**
+ * @dataProvider pipesCodeProvider
+ */
+ public function testSetStreamAsInput($code, $size)
+ {
+ $expected = str_repeat(str_repeat('*', 1024), $size).'!';
+ $expectedLength = (1024 * $size) + 1;
+
+ $stream = fopen('php://temporary', 'w+');
+ fwrite($stream, $expected);
+ rewind($stream);
+
+ $p = $this->getProcessForCode($code);
+ $p->setInput($stream);
+ $p->run();
+
+ fclose($stream);
+
+ $this->assertEquals($expectedLength, strlen($p->getOutput()));
+ $this->assertEquals($expectedLength, strlen($p->getErrorOutput()));
+ }
+
+ public function testLiveStreamAsInput()
+ {
+ $stream = fopen('php://memory', 'r+');
+ fwrite($stream, 'hello');
+ rewind($stream);
+
+ $p = $this->getProcessForCode('stream_copy_to_stream(STDIN, STDOUT);');
+ $p->setInput($stream);
+ $p->start(function ($type, $data) use ($stream) {
+ if ('hello' === $data) {
+ fclose($stream);
+ }
+ });
+ $p->wait();
+
+ $this->assertSame('hello', $p->getOutput());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Process\Exception\LogicException
+ * @expectedExceptionMessage Input can not be set while the process is running.
+ */
+ public function testSetInputWhileRunningThrowsAnException()
+ {
+ $process = $this->getProcessForCode('sleep(30);');
+ $process->start();
+ try {
+ $process->setInput('foobar');
+ $process->stop();
+ $this->fail('A LogicException should have been raised.');
+ } catch (LogicException $e) {
+ }
+ $process->stop();
+
+ throw $e;
+ }
+
+ /**
+ * @dataProvider provideInvalidInputValues
+ * @expectedException \Symfony\Component\Process\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Symfony\Component\Process\Process::setInput only accepts strings, Traversable objects or stream resources.
+ */
+ public function testInvalidInput($value)
+ {
+ $process = $this->getProcess('foo');
+ $process->setInput($value);
+ }
+
+ public function provideInvalidInputValues()
+ {
+ return array(
+ array(array()),
+ array(new NonStringifiable()),
+ );
+ }
+
+ /**
+ * @dataProvider provideInputValues
+ */
+ public function testValidInput($expected, $value)
+ {
+ $process = $this->getProcess('foo');
+ $process->setInput($value);
+ $this->assertSame($expected, $process->getInput());
+ }
+
+ public function provideInputValues()
+ {
+ return array(
+ array(null, null),
+ array('24.5', 24.5),
+ array('input data', 'input data'),
+ );
+ }
+
+ public function chainedCommandsOutputProvider()
+ {
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ return array(
+ array("2 \r\n2\r\n", '&&', '2'),
+ );
+ }
+
+ return array(
+ array("1\n1\n", ';', '1'),
+ array("2\n2\n", '&&', '2'),
+ );
+ }
+
+ /**
+ * @dataProvider chainedCommandsOutputProvider
+ */
+ public function testChainedCommandsOutput($expected, $operator, $input)
+ {
+ $process = $this->getProcess(sprintf('echo %s %s echo %s', $input, $operator, $input));
+ $process->run();
+ $this->assertEquals($expected, $process->getOutput());
+ }
+
+ public function testCallbackIsExecutedForOutput()
+ {
+ $p = $this->getProcessForCode('echo \'foo\';');
+
+ $called = false;
+ $p->run(function ($type, $buffer) use (&$called) {
+ $called = 'foo' === $buffer;
+ });
+
+ $this->assertTrue($called, 'The callback should be executed with the output');
+ }
+
+ public function testCallbackIsExecutedForOutputWheneverOutputIsDisabled()
+ {
+ $p = $this->getProcessForCode('echo \'foo\';');
+ $p->disableOutput();
+
+ $called = false;
+ $p->run(function ($type, $buffer) use (&$called) {
+ $called = 'foo' === $buffer;
+ });
+
+ $this->assertTrue($called, 'The callback should be executed with the output');
+ }
+
+ public function testGetErrorOutput()
+ {
+ $p = $this->getProcessForCode('$n = 0; while ($n < 3) { file_put_contents(\'php://stderr\', \'ERROR\'); $n++; }');
+
+ $p->run();
+ $this->assertEquals(3, preg_match_all('/ERROR/', $p->getErrorOutput(), $matches));
+ }
+
+ public function testFlushErrorOutput()
+ {
+ $p = $this->getProcessForCode('$n = 0; while ($n < 3) { file_put_contents(\'php://stderr\', \'ERROR\'); $n++; }');
+
+ $p->run();
+ $p->clearErrorOutput();
+ $this->assertEmpty($p->getErrorOutput());
+ }
+
+ /**
+ * @dataProvider provideIncrementalOutput
+ */
+ public function testIncrementalOutput($getOutput, $getIncrementalOutput, $uri)
+ {
+ $lock = tempnam(sys_get_temp_dir(), __FUNCTION__);
+
+ $p = $this->getProcessForCode('file_put_contents($s = \''.$uri.'\', \'foo\'); flock(fopen('.var_export($lock, true).', \'r\'), LOCK_EX); file_put_contents($s, \'bar\');');
+
+ $h = fopen($lock, 'w');
+ flock($h, LOCK_EX);
+
+ $p->start();
+
+ foreach (array('foo', 'bar') as $s) {
+ while (false === strpos($p->$getOutput(), $s)) {
+ usleep(1000);
+ }
+
+ $this->assertSame($s, $p->$getIncrementalOutput());
+ $this->assertSame('', $p->$getIncrementalOutput());
+
+ flock($h, LOCK_UN);
+ }
+
+ fclose($h);
+ }
+
+ public function provideIncrementalOutput()
+ {
+ return array(
+ array('getOutput', 'getIncrementalOutput', 'php://stdout'),
+ array('getErrorOutput', 'getIncrementalErrorOutput', 'php://stderr'),
+ );
+ }
+
+ public function testGetOutput()
+ {
+ $p = $this->getProcessForCode('$n = 0; while ($n < 3) { echo \' foo \'; $n++; }');
+
+ $p->run();
+ $this->assertEquals(3, preg_match_all('/foo/', $p->getOutput(), $matches));
+ }
+
+ public function testFlushOutput()
+ {
+ $p = $this->getProcessForCode('$n=0;while ($n<3) {echo \' foo \';$n++;}');
+
+ $p->run();
+ $p->clearOutput();
+ $this->assertEmpty($p->getOutput());
+ }
+
+ public function testZeroAsOutput()
+ {
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ // see http://stackoverflow.com/questions/7105433/windows-batch-echo-without-new-line
+ $p = $this->getProcess('echo | set /p dummyName=0');
+ } else {
+ $p = $this->getProcess('printf 0');
+ }
+
+ $p->run();
+ $this->assertSame('0', $p->getOutput());
+ }
+
+ public function testExitCodeCommandFailed()
+ {
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->markTestSkipped('Windows does not support POSIX exit code');
+ }
+ $this->skipIfNotEnhancedSigchild();
+
+ // such command run in bash return an exitcode 127
+ $process = $this->getProcess('nonexistingcommandIhopeneversomeonewouldnameacommandlikethis');
+ $process->run();
+
+ $this->assertGreaterThan(0, $process->getExitCode());
+ }
+
+ /**
+ * @group tty
+ */
+ public function testTTYCommand()
+ {
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->markTestSkipped('Windows does not have /dev/tty support');
+ }
+
+ $process = $this->getProcess('echo "foo" >> /dev/null && '.$this->getProcessForCode('usleep(100000);')->getCommandLine());
+ $process->setTty(true);
+ $process->start();
+ $this->assertTrue($process->isRunning());
+ $process->wait();
+
+ $this->assertSame(Process::STATUS_TERMINATED, $process->getStatus());
+ }
+
+ /**
+ * @group tty
+ */
+ public function testTTYCommandExitCode()
+ {
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->markTestSkipped('Windows does have /dev/tty support');
+ }
+ $this->skipIfNotEnhancedSigchild();
+
+ $process = $this->getProcess('echo "foo" >> /dev/null');
+ $process->setTty(true);
+ $process->run();
+
+ $this->assertTrue($process->isSuccessful());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Process\Exception\RuntimeException
+ * @expectedExceptionMessage TTY mode is not supported on Windows platform.
+ */
+ public function testTTYInWindowsEnvironment()
+ {
+ if ('\\' !== DIRECTORY_SEPARATOR) {
+ $this->markTestSkipped('This test is for Windows platform only');
+ }
+
+ $process = $this->getProcess('echo "foo" >> /dev/null');
+ $process->setTty(false);
+ $process->setTty(true);
+ }
+
+ public function testExitCodeTextIsNullWhenExitCodeIsNull()
+ {
+ $this->skipIfNotEnhancedSigchild();
+
+ $process = $this->getProcess('');
+ $this->assertNull($process->getExitCodeText());
+ }
+
+ public function testPTYCommand()
+ {
+ if (!Process::isPtySupported()) {
+ $this->markTestSkipped('PTY is not supported on this operating system.');
+ }
+
+ $process = $this->getProcess('echo "foo"');
+ $process->setPty(true);
+ $process->run();
+
+ $this->assertSame(Process::STATUS_TERMINATED, $process->getStatus());
+ $this->assertEquals("foo\r\n", $process->getOutput());
+ }
+
+ public function testMustRun()
+ {
+ $this->skipIfNotEnhancedSigchild();
+
+ $process = $this->getProcess('echo foo');
+
+ $this->assertSame($process, $process->mustRun());
+ $this->assertEquals('foo'.PHP_EOL, $process->getOutput());
+ }
+
+ public function testSuccessfulMustRunHasCorrectExitCode()
+ {
+ $this->skipIfNotEnhancedSigchild();
+
+ $process = $this->getProcess('echo foo')->mustRun();
+ $this->assertEquals(0, $process->getExitCode());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Process\Exception\ProcessFailedException
+ */
+ public function testMustRunThrowsException()
+ {
+ $this->skipIfNotEnhancedSigchild();
+
+ $process = $this->getProcess('exit 1');
+ $process->mustRun();
+ }
+
+ public function testExitCodeText()
+ {
+ $this->skipIfNotEnhancedSigchild();
+
+ $process = $this->getProcess('');
+ $r = new \ReflectionObject($process);
+ $p = $r->getProperty('exitcode');
+ $p->setAccessible(true);
+
+ $p->setValue($process, 2);
+ $this->assertEquals('Misuse of shell builtins', $process->getExitCodeText());
+ }
+
+ public function testStartIsNonBlocking()
+ {
+ $process = $this->getProcessForCode('usleep(500000);');
+ $start = microtime(true);
+ $process->start();
+ $end = microtime(true);
+ $this->assertLessThan(0.4, $end - $start);
+ $process->stop();
+ }
+
+ public function testUpdateStatus()
+ {
+ $process = $this->getProcess('echo foo');
+ $process->run();
+ $this->assertGreaterThan(0, strlen($process->getOutput()));
+ }
+
+ public function testGetExitCodeIsNullOnStart()
+ {
+ $this->skipIfNotEnhancedSigchild();
+
+ $process = $this->getProcessForCode('usleep(100000);');
+ $this->assertNull($process->getExitCode());
+ $process->start();
+ $this->assertNull($process->getExitCode());
+ $process->wait();
+ $this->assertEquals(0, $process->getExitCode());
+ }
+
+ public function testGetExitCodeIsNullOnWhenStartingAgain()
+ {
+ $this->skipIfNotEnhancedSigchild();
+
+ $process = $this->getProcessForCode('usleep(100000);');
+ $process->run();
+ $this->assertEquals(0, $process->getExitCode());
+ $process->start();
+ $this->assertNull($process->getExitCode());
+ $process->wait();
+ $this->assertEquals(0, $process->getExitCode());
+ }
+
+ public function testGetExitCode()
+ {
+ $this->skipIfNotEnhancedSigchild();
+
+ $process = $this->getProcess('echo foo');
+ $process->run();
+ $this->assertSame(0, $process->getExitCode());
+ }
+
+ public function testStatus()
+ {
+ $process = $this->getProcessForCode('usleep(100000);');
+ $this->assertFalse($process->isRunning());
+ $this->assertFalse($process->isStarted());
+ $this->assertFalse($process->isTerminated());
+ $this->assertSame(Process::STATUS_READY, $process->getStatus());
+ $process->start();
+ $this->assertTrue($process->isRunning());
+ $this->assertTrue($process->isStarted());
+ $this->assertFalse($process->isTerminated());
+ $this->assertSame(Process::STATUS_STARTED, $process->getStatus());
+ $process->wait();
+ $this->assertFalse($process->isRunning());
+ $this->assertTrue($process->isStarted());
+ $this->assertTrue($process->isTerminated());
+ $this->assertSame(Process::STATUS_TERMINATED, $process->getStatus());
+ }
+
+ public function testStop()
+ {
+ $process = $this->getProcessForCode('sleep(31);');
+ $process->start();
+ $this->assertTrue($process->isRunning());
+ $process->stop();
+ $this->assertFalse($process->isRunning());
+ }
+
+ public function testIsSuccessful()
+ {
+ $this->skipIfNotEnhancedSigchild();
+
+ $process = $this->getProcess('echo foo');
+ $process->run();
+ $this->assertTrue($process->isSuccessful());
+ }
+
+ public function testIsSuccessfulOnlyAfterTerminated()
+ {
+ $this->skipIfNotEnhancedSigchild();
+
+ $process = $this->getProcessForCode('usleep(100000);');
+ $process->start();
+
+ $this->assertFalse($process->isSuccessful());
+
+ $process->wait();
+
+ $this->assertTrue($process->isSuccessful());
+ }
+
+ public function testIsNotSuccessful()
+ {
+ $this->skipIfNotEnhancedSigchild();
+
+ $process = $this->getProcessForCode('throw new \Exception(\'BOUM\');');
+ $process->run();
+ $this->assertFalse($process->isSuccessful());
+ }
+
+ public function testProcessIsNotSignaled()
+ {
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->markTestSkipped('Windows does not support POSIX signals');
+ }
+ $this->skipIfNotEnhancedSigchild();
+
+ $process = $this->getProcess('echo foo');
+ $process->run();
+ $this->assertFalse($process->hasBeenSignaled());
+ }
+
+ public function testProcessWithoutTermSignal()
+ {
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->markTestSkipped('Windows does not support POSIX signals');
+ }
+ $this->skipIfNotEnhancedSigchild();
+
+ $process = $this->getProcess('echo foo');
+ $process->run();
+ $this->assertEquals(0, $process->getTermSignal());
+ }
+
+ public function testProcessIsSignaledIfStopped()
+ {
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->markTestSkipped('Windows does not support POSIX signals');
+ }
+ $this->skipIfNotEnhancedSigchild();
+
+ $process = $this->getProcessForCode('sleep(32);');
+ $process->start();
+ $process->stop();
+ $this->assertTrue($process->hasBeenSignaled());
+ $this->assertEquals(15, $process->getTermSignal()); // SIGTERM
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Process\Exception\RuntimeException
+ * @expectedExceptionMessage The process has been signaled
+ */
+ public function testProcessThrowsExceptionWhenExternallySignaled()
+ {
+ if (!function_exists('posix_kill')) {
+ $this->markTestSkipped('Function posix_kill is required.');
+ }
+ $this->skipIfNotEnhancedSigchild(false);
+
+ $process = $this->getProcessForCode('sleep(32.1);');
+ $process->start();
+ posix_kill($process->getPid(), 9); // SIGKILL
+
+ $process->wait();
+ }
+
+ public function testRestart()
+ {
+ $process1 = $this->getProcessForCode('echo getmypid();');
+ $process1->run();
+ $process2 = $process1->restart();
+
+ $process2->wait(); // wait for output
+
+ // Ensure that both processed finished and the output is numeric
+ $this->assertFalse($process1->isRunning());
+ $this->assertFalse($process2->isRunning());
+ $this->assertInternalType('numeric', $process1->getOutput());
+ $this->assertInternalType('numeric', $process2->getOutput());
+
+ // Ensure that restart returned a new process by check that the output is different
+ $this->assertNotEquals($process1->getOutput(), $process2->getOutput());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Process\Exception\ProcessTimedOutException
+ * @expectedExceptionMessage exceeded the timeout of 0.1 seconds.
+ */
+ public function testRunProcessWithTimeout()
+ {
+ $process = $this->getProcessForCode('sleep(30);');
+ $process->setTimeout(0.1);
+ $start = microtime(true);
+ try {
+ $process->run();
+ $this->fail('A RuntimeException should have been raised');
+ } catch (RuntimeException $e) {
+ }
+
+ $this->assertLessThan(15, microtime(true) - $start);
+
+ throw $e;
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Process\Exception\ProcessTimedOutException
+ * @expectedExceptionMessage exceeded the timeout of 0.1 seconds.
+ */
+ public function testIterateOverProcessWithTimeout()
+ {
+ $process = $this->getProcessForCode('sleep(30);');
+ $process->setTimeout(0.1);
+ $start = microtime(true);
+ try {
+ $process->start();
+ foreach ($process as $buffer);
+ $this->fail('A RuntimeException should have been raised');
+ } catch (RuntimeException $e) {
+ }
+
+ $this->assertLessThan(15, microtime(true) - $start);
+
+ throw $e;
+ }
+
+ public function testCheckTimeoutOnNonStartedProcess()
+ {
+ $process = $this->getProcess('echo foo');
+ $this->assertNull($process->checkTimeout());
+ }
+
+ public function testCheckTimeoutOnTerminatedProcess()
+ {
+ $process = $this->getProcess('echo foo');
+ $process->run();
+ $this->assertNull($process->checkTimeout());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Process\Exception\ProcessTimedOutException
+ * @expectedExceptionMessage exceeded the timeout of 0.1 seconds.
+ */
+ public function testCheckTimeoutOnStartedProcess()
+ {
+ $process = $this->getProcessForCode('sleep(33);');
+ $process->setTimeout(0.1);
+
+ $process->start();
+ $start = microtime(true);
+
+ try {
+ while ($process->isRunning()) {
+ $process->checkTimeout();
+ usleep(100000);
+ }
+ $this->fail('A ProcessTimedOutException should have been raised');
+ } catch (ProcessTimedOutException $e) {
+ }
+
+ $this->assertLessThan(15, microtime(true) - $start);
+
+ throw $e;
+ }
+
+ public function testIdleTimeout()
+ {
+ $process = $this->getProcessForCode('sleep(34);');
+ $process->setTimeout(60);
+ $process->setIdleTimeout(0.1);
+
+ try {
+ $process->run();
+
+ $this->fail('A timeout exception was expected.');
+ } catch (ProcessTimedOutException $e) {
+ $this->assertTrue($e->isIdleTimeout());
+ $this->assertFalse($e->isGeneralTimeout());
+ $this->assertEquals(0.1, $e->getExceededTimeout());
+ }
+ }
+
+ public function testIdleTimeoutNotExceededWhenOutputIsSent()
+ {
+ $process = $this->getProcessForCode('while (true) {echo \'foo \'; usleep(1000);}');
+ $process->setTimeout(1);
+ $process->start();
+
+ while (false === strpos($process->getOutput(), 'foo')) {
+ usleep(1000);
+ }
+
+ $process->setIdleTimeout(0.5);
+
+ try {
+ $process->wait();
+ $this->fail('A timeout exception was expected.');
+ } catch (ProcessTimedOutException $e) {
+ $this->assertTrue($e->isGeneralTimeout(), 'A general timeout is expected.');
+ $this->assertFalse($e->isIdleTimeout(), 'No idle timeout is expected.');
+ $this->assertEquals(1, $e->getExceededTimeout());
+ }
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Process\Exception\ProcessTimedOutException
+ * @expectedExceptionMessage exceeded the timeout of 0.1 seconds.
+ */
+ public function testStartAfterATimeout()
+ {
+ $process = $this->getProcessForCode('sleep(35);');
+ $process->setTimeout(0.1);
+
+ try {
+ $process->run();
+ $this->fail('A ProcessTimedOutException should have been raised.');
+ } catch (ProcessTimedOutException $e) {
+ }
+ $this->assertFalse($process->isRunning());
+ $process->start();
+ $this->assertTrue($process->isRunning());
+ $process->stop(0);
+
+ throw $e;
+ }
+
+ public function testGetPid()
+ {
+ $process = $this->getProcessForCode('sleep(36);');
+ $process->start();
+ $this->assertGreaterThan(0, $process->getPid());
+ $process->stop(0);
+ }
+
+ public function testGetPidIsNullBeforeStart()
+ {
+ $process = $this->getProcess('foo');
+ $this->assertNull($process->getPid());
+ }
+
+ public function testGetPidIsNullAfterRun()
+ {
+ $process = $this->getProcess('echo foo');
+ $process->run();
+ $this->assertNull($process->getPid());
+ }
+
+ /**
+ * @requires extension pcntl
+ */
+ public function testSignal()
+ {
+ $process = $this->getProcess(array(self::$phpBin, __DIR__.'/SignalListener.php'));
+ $process->start();
+
+ while (false === strpos($process->getOutput(), 'Caught')) {
+ usleep(1000);
+ }
+ $process->signal(SIGUSR1);
+ $process->wait();
+
+ $this->assertEquals('Caught SIGUSR1', $process->getOutput());
+ }
+
+ /**
+ * @requires extension pcntl
+ */
+ public function testExitCodeIsAvailableAfterSignal()
+ {
+ $this->skipIfNotEnhancedSigchild();
+
+ $process = $this->getProcess('sleep 4');
+ $process->start();
+ $process->signal(SIGKILL);
+
+ while ($process->isRunning()) {
+ usleep(10000);
+ }
+
+ $this->assertFalse($process->isRunning());
+ $this->assertTrue($process->hasBeenSignaled());
+ $this->assertFalse($process->isSuccessful());
+ $this->assertEquals(137, $process->getExitCode());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Process\Exception\LogicException
+ * @expectedExceptionMessage Can not send signal on a non running process.
+ */
+ public function testSignalProcessNotRunning()
+ {
+ $process = $this->getProcess('foo');
+ $process->signal(1); // SIGHUP
+ }
+
+ /**
+ * @dataProvider provideMethodsThatNeedARunningProcess
+ */
+ public function testMethodsThatNeedARunningProcess($method)
+ {
+ $process = $this->getProcess('foo');
+
+ if (method_exists($this, 'expectException')) {
+ $this->expectException('Symfony\Component\Process\Exception\LogicException');
+ $this->expectExceptionMessage(sprintf('Process must be started before calling %s.', $method));
+ } else {
+ $this->setExpectedException('Symfony\Component\Process\Exception\LogicException', sprintf('Process must be started before calling %s.', $method));
+ }
+
+ $process->{$method}();
+ }
+
+ public function provideMethodsThatNeedARunningProcess()
+ {
+ return array(
+ array('getOutput'),
+ array('getIncrementalOutput'),
+ array('getErrorOutput'),
+ array('getIncrementalErrorOutput'),
+ array('wait'),
+ );
+ }
+
+ /**
+ * @dataProvider provideMethodsThatNeedATerminatedProcess
+ * @expectedException \Symfony\Component\Process\Exception\LogicException
+ * @expectedExceptionMessage Process must be terminated before calling
+ */
+ public function testMethodsThatNeedATerminatedProcess($method)
+ {
+ $process = $this->getProcessForCode('sleep(37);');
+ $process->start();
+ try {
+ $process->{$method}();
+ $process->stop(0);
+ $this->fail('A LogicException must have been thrown');
+ } catch (\Exception $e) {
+ }
+ $process->stop(0);
+
+ throw $e;
+ }
+
+ public function provideMethodsThatNeedATerminatedProcess()
+ {
+ return array(
+ array('hasBeenSignaled'),
+ array('getTermSignal'),
+ array('hasBeenStopped'),
+ array('getStopSignal'),
+ );
+ }
+
+ /**
+ * @dataProvider provideWrongSignal
+ * @expectedException \Symfony\Component\Process\Exception\RuntimeException
+ */
+ public function testWrongSignal($signal)
+ {
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->markTestSkipped('POSIX signals do not work on Windows');
+ }
+
+ $process = $this->getProcessForCode('sleep(38);');
+ $process->start();
+ try {
+ $process->signal($signal);
+ $this->fail('A RuntimeException must have been thrown');
+ } catch (RuntimeException $e) {
+ $process->stop(0);
+ }
+
+ throw $e;
+ }
+
+ public function provideWrongSignal()
+ {
+ return array(
+ array(-4),
+ array('Céphalopodes'),
+ );
+ }
+
+ public function testDisableOutputDisablesTheOutput()
+ {
+ $p = $this->getProcess('foo');
+ $this->assertFalse($p->isOutputDisabled());
+ $p->disableOutput();
+ $this->assertTrue($p->isOutputDisabled());
+ $p->enableOutput();
+ $this->assertFalse($p->isOutputDisabled());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Process\Exception\RuntimeException
+ * @expectedExceptionMessage Disabling output while the process is running is not possible.
+ */
+ public function testDisableOutputWhileRunningThrowsException()
+ {
+ $p = $this->getProcessForCode('sleep(39);');
+ $p->start();
+ $p->disableOutput();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Process\Exception\RuntimeException
+ * @expectedExceptionMessage Enabling output while the process is running is not possible.
+ */
+ public function testEnableOutputWhileRunningThrowsException()
+ {
+ $p = $this->getProcessForCode('sleep(40);');
+ $p->disableOutput();
+ $p->start();
+ $p->enableOutput();
+ }
+
+ public function testEnableOrDisableOutputAfterRunDoesNotThrowException()
+ {
+ $p = $this->getProcess('echo foo');
+ $p->disableOutput();
+ $p->run();
+ $p->enableOutput();
+ $p->disableOutput();
+ $this->assertTrue($p->isOutputDisabled());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Process\Exception\LogicException
+ * @expectedExceptionMessage Output can not be disabled while an idle timeout is set.
+ */
+ public function testDisableOutputWhileIdleTimeoutIsSet()
+ {
+ $process = $this->getProcess('foo');
+ $process->setIdleTimeout(1);
+ $process->disableOutput();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Process\Exception\LogicException
+ * @expectedExceptionMessage timeout can not be set while the output is disabled.
+ */
+ public function testSetIdleTimeoutWhileOutputIsDisabled()
+ {
+ $process = $this->getProcess('foo');
+ $process->disableOutput();
+ $process->setIdleTimeout(1);
+ }
+
+ public function testSetNullIdleTimeoutWhileOutputIsDisabled()
+ {
+ $process = $this->getProcess('foo');
+ $process->disableOutput();
+ $this->assertSame($process, $process->setIdleTimeout(null));
+ }
+
+ /**
+ * @dataProvider provideOutputFetchingMethods
+ * @expectedException \Symfony\Component\Process\Exception\LogicException
+ * @expectedExceptionMessage Output has been disabled.
+ */
+ public function testGetOutputWhileDisabled($fetchMethod)
+ {
+ $p = $this->getProcessForCode('sleep(41);');
+ $p->disableOutput();
+ $p->start();
+ $p->{$fetchMethod}();
+ }
+
+ public function provideOutputFetchingMethods()
+ {
+ return array(
+ array('getOutput'),
+ array('getIncrementalOutput'),
+ array('getErrorOutput'),
+ array('getIncrementalErrorOutput'),
+ );
+ }
+
+ public function testStopTerminatesProcessCleanly()
+ {
+ $process = $this->getProcessForCode('echo 123; sleep(42);');
+ $process->run(function () use ($process) {
+ $process->stop();
+ });
+ $this->assertTrue(true, 'A call to stop() is not expected to cause wait() to throw a RuntimeException');
+ }
+
+ public function testKillSignalTerminatesProcessCleanly()
+ {
+ $process = $this->getProcessForCode('echo 123; sleep(43);');
+ $process->run(function () use ($process) {
+ $process->signal(9); // SIGKILL
+ });
+ $this->assertTrue(true, 'A call to signal() is not expected to cause wait() to throw a RuntimeException');
+ }
+
+ public function testTermSignalTerminatesProcessCleanly()
+ {
+ $process = $this->getProcessForCode('echo 123; sleep(44);');
+ $process->run(function () use ($process) {
+ $process->signal(15); // SIGTERM
+ });
+ $this->assertTrue(true, 'A call to signal() is not expected to cause wait() to throw a RuntimeException');
+ }
+
+ public function responsesCodeProvider()
+ {
+ return array(
+ //expected output / getter / code to execute
+ //array(1,'getExitCode','exit(1);'),
+ //array(true,'isSuccessful','exit();'),
+ array('output', 'getOutput', 'echo \'output\';'),
+ );
+ }
+
+ public function pipesCodeProvider()
+ {
+ $variations = array(
+ 'fwrite(STDOUT, $in = file_get_contents(\'php://stdin\')); fwrite(STDERR, $in);',
+ 'include \''.__DIR__.'/PipeStdinInStdoutStdErrStreamSelect.php\';',
+ );
+
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ // Avoid XL buffers on Windows because of https://bugs.php.net/bug.php?id=65650
+ $sizes = array(1, 2, 4, 8);
+ } else {
+ $sizes = array(1, 16, 64, 1024, 4096);
+ }
+
+ $codes = array();
+ foreach ($sizes as $size) {
+ foreach ($variations as $code) {
+ $codes[] = array($code, $size);
+ }
+ }
+
+ return $codes;
+ }
+
+ /**
+ * @dataProvider provideVariousIncrementals
+ */
+ public function testIncrementalOutputDoesNotRequireAnotherCall($stream, $method)
+ {
+ $process = $this->getProcessForCode('$n = 0; while ($n < 3) { file_put_contents(\''.$stream.'\', $n, 1); $n++; usleep(1000); }', null, null, null, null);
+ $process->start();
+ $result = '';
+ $limit = microtime(true) + 3;
+ $expected = '012';
+
+ while ($result !== $expected && microtime(true) < $limit) {
+ $result .= $process->$method();
+ }
+
+ $this->assertSame($expected, $result);
+ $process->stop();
+ }
+
+ public function provideVariousIncrementals()
+ {
+ return array(
+ array('php://stdout', 'getIncrementalOutput'),
+ array('php://stderr', 'getIncrementalErrorOutput'),
+ );
+ }
+
+ public function testIteratorInput()
+ {
+ $input = function () {
+ yield 'ping';
+ yield 'pong';
+ };
+
+ $process = $this->getProcessForCode('stream_copy_to_stream(STDIN, STDOUT);', null, null, $input());
+ $process->run();
+ $this->assertSame('pingpong', $process->getOutput());
+ }
+
+ public function testSimpleInputStream()
+ {
+ $input = new InputStream();
+
+ $process = $this->getProcessForCode('echo \'ping\'; echo fread(STDIN, 4); echo fread(STDIN, 4);');
+ $process->setInput($input);
+
+ $process->start(function ($type, $data) use ($input) {
+ if ('ping' === $data) {
+ $input->write('pang');
+ } elseif (!$input->isClosed()) {
+ $input->write('pong');
+ $input->close();
+ }
+ });
+
+ $process->wait();
+ $this->assertSame('pingpangpong', $process->getOutput());
+ }
+
+ public function testInputStreamWithCallable()
+ {
+ $i = 0;
+ $stream = fopen('php://memory', 'w+');
+ $stream = function () use ($stream, &$i) {
+ if ($i < 3) {
+ rewind($stream);
+ fwrite($stream, ++$i);
+ rewind($stream);
+
+ return $stream;
+ }
+ };
+
+ $input = new InputStream();
+ $input->onEmpty($stream);
+ $input->write($stream());
+
+ $process = $this->getProcessForCode('echo fread(STDIN, 3);');
+ $process->setInput($input);
+ $process->start(function ($type, $data) use ($input) {
+ $input->close();
+ });
+
+ $process->wait();
+ $this->assertSame('123', $process->getOutput());
+ }
+
+ public function testInputStreamWithGenerator()
+ {
+ $input = new InputStream();
+ $input->onEmpty(function ($input) {
+ yield 'pong';
+ $input->close();
+ });
+
+ $process = $this->getProcessForCode('stream_copy_to_stream(STDIN, STDOUT);');
+ $process->setInput($input);
+ $process->start();
+ $input->write('ping');
+ $process->wait();
+ $this->assertSame('pingpong', $process->getOutput());
+ }
+
+ public function testInputStreamOnEmpty()
+ {
+ $i = 0;
+ $input = new InputStream();
+ $input->onEmpty(function () use (&$i) { ++$i; });
+
+ $process = $this->getProcessForCode('echo 123; echo fread(STDIN, 1); echo 456;');
+ $process->setInput($input);
+ $process->start(function ($type, $data) use ($input) {
+ if ('123' === $data) {
+ $input->close();
+ }
+ });
+ $process->wait();
+
+ $this->assertSame(0, $i, 'InputStream->onEmpty callback should be called only when the input *becomes* empty');
+ $this->assertSame('123456', $process->getOutput());
+ }
+
+ public function testIteratorOutput()
+ {
+ $input = new InputStream();
+
+ $process = $this->getProcessForCode('fwrite(STDOUT, 123); fwrite(STDERR, 234); flush(); usleep(10000); fwrite(STDOUT, fread(STDIN, 3)); fwrite(STDERR, 456);');
+ $process->setInput($input);
+ $process->start();
+ $output = array();
+
+ foreach ($process as $type => $data) {
+ $output[] = array($type, $data);
+ break;
+ }
+ $expectedOutput = array(
+ array($process::OUT, '123'),
+ );
+ $this->assertSame($expectedOutput, $output);
+
+ $input->write(345);
+
+ foreach ($process as $type => $data) {
+ $output[] = array($type, $data);
+ }
+
+ $this->assertSame('', $process->getOutput());
+ $this->assertFalse($process->isRunning());
+
+ $expectedOutput = array(
+ array($process::OUT, '123'),
+ array($process::ERR, '234'),
+ array($process::OUT, '345'),
+ array($process::ERR, '456'),
+ );
+ $this->assertSame($expectedOutput, $output);
+ }
+
+ public function testNonBlockingNorClearingIteratorOutput()
+ {
+ $input = new InputStream();
+
+ $process = $this->getProcessForCode('fwrite(STDOUT, fread(STDIN, 3));');
+ $process->setInput($input);
+ $process->start();
+ $output = array();
+
+ foreach ($process->getIterator($process::ITER_NON_BLOCKING | $process::ITER_KEEP_OUTPUT) as $type => $data) {
+ $output[] = array($type, $data);
+ break;
+ }
+ $expectedOutput = array(
+ array($process::OUT, ''),
+ );
+ $this->assertSame($expectedOutput, $output);
+
+ $input->write(123);
+
+ foreach ($process->getIterator($process::ITER_NON_BLOCKING | $process::ITER_KEEP_OUTPUT) as $type => $data) {
+ if ('' !== $data) {
+ $output[] = array($type, $data);
+ }
+ }
+
+ $this->assertSame('123', $process->getOutput());
+ $this->assertFalse($process->isRunning());
+
+ $expectedOutput = array(
+ array($process::OUT, ''),
+ array($process::OUT, '123'),
+ );
+ $this->assertSame($expectedOutput, $output);
+ }
+
+ public function testChainedProcesses()
+ {
+ $p1 = $this->getProcessForCode('fwrite(STDERR, 123); fwrite(STDOUT, 456);');
+ $p2 = $this->getProcessForCode('stream_copy_to_stream(STDIN, STDOUT);');
+ $p2->setInput($p1);
+
+ $p1->start();
+ $p2->run();
+
+ $this->assertSame('123', $p1->getErrorOutput());
+ $this->assertSame('', $p1->getOutput());
+ $this->assertSame('', $p2->getErrorOutput());
+ $this->assertSame('456', $p2->getOutput());
+ }
+
+ public function testSetBadEnv()
+ {
+ $process = $this->getProcess('echo hello');
+ $process->setEnv(array('bad%%' => '123'));
+ $process->inheritEnvironmentVariables(true);
+
+ $process->run();
+
+ $this->assertSame('hello'.PHP_EOL, $process->getOutput());
+ $this->assertSame('', $process->getErrorOutput());
+ }
+
+ public function testEnvBackupDoesNotDeleteExistingVars()
+ {
+ putenv('existing_var=foo');
+ $_ENV['existing_var'] = 'foo';
+ $process = $this->getProcess('php -r "echo getenv(\'new_test_var\');"');
+ $process->setEnv(array('existing_var' => 'bar', 'new_test_var' => 'foo'));
+ $process->inheritEnvironmentVariables();
+
+ $process->run();
+
+ $this->assertSame('foo', $process->getOutput());
+ $this->assertSame('foo', getenv('existing_var'));
+ $this->assertFalse(getenv('new_test_var'));
+
+ putenv('existing_var');
+ unset($_ENV['existing_var']);
+ }
+
+ public function testEnvIsInherited()
+ {
+ $process = $this->getProcessForCode('echo serialize($_SERVER);', null, array('BAR' => 'BAZ', 'EMPTY' => ''));
+
+ putenv('FOO=BAR');
+ $_ENV['FOO'] = 'BAR';
+
+ $process->run();
+
+ $expected = array('BAR' => 'BAZ', 'EMPTY' => '', 'FOO' => 'BAR');
+ $env = array_intersect_key(unserialize($process->getOutput()), $expected);
+
+ $this->assertEquals($expected, $env);
+
+ putenv('FOO');
+ unset($_ENV['FOO']);
+ }
+
+ /**
+ * @group legacy
+ */
+ public function testInheritEnvDisabled()
+ {
+ $process = $this->getProcessForCode('echo serialize($_SERVER);', null, array('BAR' => 'BAZ'));
+
+ putenv('FOO=BAR');
+ $_ENV['FOO'] = 'BAR';
+
+ $this->assertSame($process, $process->inheritEnvironmentVariables(false));
+ $this->assertFalse($process->areEnvironmentVariablesInherited());
+
+ $process->run();
+
+ $expected = array('BAR' => 'BAZ', 'FOO' => 'BAR');
+ $env = array_intersect_key(unserialize($process->getOutput()), $expected);
+ unset($expected['FOO']);
+
+ $this->assertSame($expected, $env);
+
+ putenv('FOO');
+ unset($_ENV['FOO']);
+ }
+
+ public function testGetCommandLine()
+ {
+ $p = new Process(array('/usr/bin/php'));
+
+ $expected = '\\' === DIRECTORY_SEPARATOR ? '"/usr/bin/php"' : "'/usr/bin/php'";
+ $this->assertSame($expected, $p->getCommandLine());
+ }
+
+ /**
+ * @dataProvider provideEscapeArgument
+ */
+ public function testEscapeArgument($arg)
+ {
+ $p = new Process(array(self::$phpBin, '-r', 'echo $argv[1];', $arg));
+ $p->run();
+
+ $this->assertSame($arg, $p->getOutput());
+ }
+
+ /**
+ * @dataProvider provideEscapeArgument
+ * @group legacy
+ */
+ public function testEscapeArgumentWhenInheritEnvDisabled($arg)
+ {
+ $p = new Process(array(self::$phpBin, '-r', 'echo $argv[1];', $arg), null, array('BAR' => 'BAZ'));
+ $p->inheritEnvironmentVariables(false);
+ $p->run();
+
+ $this->assertSame($arg, $p->getOutput());
+ }
+
+ public function testRawCommandLine()
+ {
+ $p = new Process(sprintf('"%s" -r %s "a" "" "b"', self::$phpBin, escapeshellarg('print_r($argv);')));
+ $p->run();
+
+ $expected = <<<EOTXT
+Array
+(
+ [0] => -
+ [1] => a
+ [2] =>
+ [3] => b
+)
+
+EOTXT;
+ $this->assertSame($expected, str_replace('Standard input code', '-', $p->getOutput()));
+ }
+
+ public function provideEscapeArgument()
+ {
+ yield array('a"b%c%');
+ yield array('a"b^c^');
+ yield array("a\nb'c");
+ yield array('a^b c!');
+ yield array("a!b\tc");
+ yield array('a\\\\"\\"');
+ yield array('éÉèÈàÀöä');
+ }
+
+ public function testEnvArgument()
+ {
+ $env = array('FOO' => 'Foo', 'BAR' => 'Bar');
+ $cmd = '\\' === DIRECTORY_SEPARATOR ? 'echo !FOO! !BAR! !BAZ!' : 'echo $FOO $BAR $BAZ';
+ $p = new Process($cmd, null, $env);
+ $p->run(null, array('BAR' => 'baR', 'BAZ' => 'baZ'));
+
+ $this->assertSame('Foo baR baZ', rtrim($p->getOutput()));
+ $this->assertSame($env, $p->getEnv());
+ }
+
+ /**
+ * @param string $commandline
+ * @param null|string $cwd
+ * @param null|array $env
+ * @param null|string $input
+ * @param int $timeout
+ * @param array $options
+ *
+ * @return Process
+ */
+ private function getProcess($commandline, $cwd = null, array $env = null, $input = null, $timeout = 60)
+ {
+ $process = new Process($commandline, $cwd, $env, $input, $timeout);
+ $process->inheritEnvironmentVariables();
+
+ if (false !== $enhance = getenv('ENHANCE_SIGCHLD')) {
+ try {
+ $process->setEnhanceSigchildCompatibility(false);
+ $process->getExitCode();
+ $this->fail('ENHANCE_SIGCHLD must be used together with a sigchild-enabled PHP.');
+ } catch (RuntimeException $e) {
+ $this->assertSame('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.', $e->getMessage());
+ if ($enhance) {
+ $process->setEnhanceSigchildCompatibility(true);
+ } else {
+ self::$notEnhancedSigchild = true;
+ }
+ }
+ }
+
+ if (self::$process) {
+ self::$process->stop(0);
+ }
+
+ return self::$process = $process;
+ }
+
+ /**
+ * @return Process
+ */
+ private function getProcessForCode($code, $cwd = null, array $env = null, $input = null, $timeout = 60)
+ {
+ return $this->getProcess(array(self::$phpBin, '-r', $code), $cwd, $env, $input, $timeout);
+ }
+
+ private function skipIfNotEnhancedSigchild($expectException = true)
+ {
+ if (self::$sigchild) {
+ if (!$expectException) {
+ $this->markTestSkipped('PHP is compiled with --enable-sigchild.');
+ } elseif (self::$notEnhancedSigchild) {
+ if (method_exists($this, 'expectException')) {
+ $this->expectException('Symfony\Component\Process\Exception\RuntimeException');
+ $this->expectExceptionMessage('This PHP has been compiled with --enable-sigchild.');
+ } else {
+ $this->setExpectedException('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild.');
+ }
+ }
+ }
+ }
+}
+
+class NonStringifiable
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/ProcessUtilsTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/ProcessUtilsTest.php
new file mode 100644
index 0000000..82fd8cf
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/ProcessUtilsTest.php
@@ -0,0 +1,53 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Process\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Process\ProcessUtils;
+
+/**
+ * @group legacy
+ */
+class ProcessUtilsTest extends TestCase
+{
+ /**
+ * @dataProvider dataArguments
+ */
+ public function testEscapeArgument($result, $argument)
+ {
+ $this->assertSame($result, ProcessUtils::escapeArgument($argument));
+ }
+
+ public function dataArguments()
+ {
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ return array(
+ array('"\"php\" \"-v\""', '"php" "-v"'),
+ array('"foo bar"', 'foo bar'),
+ array('^%"path"^%', '%path%'),
+ array('"<|>\\" \\"\'f"', '<|>" "\'f'),
+ array('""', ''),
+ array('"with\trailingbs\\\\"', 'with\trailingbs\\'),
+ );
+ }
+
+ return array(
+ array("'\"php\" \"-v\"'", '"php" "-v"'),
+ array("'foo bar'", 'foo bar'),
+ array("'%path%'", '%path%'),
+ array("'<|>\" \"'\\''f'", '<|>" "\'f'),
+ array("''", ''),
+ array("'with\\trailingbs\\'", 'with\trailingbs\\'),
+ array("'withNonAsciiAccentLikeéÉèÈàÀöä'", 'withNonAsciiAccentLikeéÉèÈàÀöä'),
+ );
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/SignalListener.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/SignalListener.php
new file mode 100644
index 0000000..9e30ce3
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/Tests/SignalListener.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+pcntl_signal(SIGUSR1, function () { echo 'SIGUSR1'; exit; });
+
+echo 'Caught ';
+
+$n = 0;
+
+while ($n++ < 400) {
+ usleep(10000);
+ pcntl_signal_dispatch();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/composer.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/composer.json
new file mode 100644
index 0000000..b8867db
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/composer.json
@@ -0,0 +1,33 @@
+{
+ "name": "symfony/process",
+ "type": "library",
+ "description": "Symfony Process Component",
+ "keywords": [],
+ "homepage": "https://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": "^5.5.9|>=7.0.8"
+ },
+ "autoload": {
+ "psr-4": { "Symfony\\Component\\Process\\": "" },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.4-dev"
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/phpunit.xml.dist b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/phpunit.xml.dist
new file mode 100644
index 0000000..d388467
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/process/phpunit.xml.dist
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
+ backupGlobals="false"
+ colors="true"
+ bootstrap="vendor/autoload.php"
+ failOnRisky="true"
+ failOnWarning="true"
+>
+ <php>
+ <ini name="error_reporting" value="-1" />
+ </php>
+
+ <testsuites>
+ <testsuite name="Symfony Process Component Test Suite">
+ <directory>./Tests/</directory>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist>
+ <directory>./</directory>
+ <exclude>
+ <directory>./Tests</directory>
+ <directory>./vendor</directory>
+ </exclude>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/.gitignore b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/.gitignore
new file mode 100644
index 0000000..c49a5d8
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/.gitignore
@@ -0,0 +1,3 @@
+vendor/
+composer.lock
+phpunit.xml
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Annotation/Route.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Annotation/Route.php
new file mode 100644
index 0000000..5b3cbea
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Annotation/Route.php
@@ -0,0 +1,144 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Annotation;
+
+/**
+ * Annotation class for @Route().
+ *
+ * @Annotation
+ * @Target({"CLASS", "METHOD"})
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Route
+{
+ private $path;
+ private $name;
+ private $requirements = array();
+ private $options = array();
+ private $defaults = array();
+ private $host;
+ private $methods = array();
+ private $schemes = array();
+ private $condition;
+
+ /**
+ * @param array $data An array of key/value parameters
+ *
+ * @throws \BadMethodCallException
+ */
+ public function __construct(array $data)
+ {
+ if (isset($data['value'])) {
+ $data['path'] = $data['value'];
+ unset($data['value']);
+ }
+
+ foreach ($data as $key => $value) {
+ $method = 'set'.str_replace('_', '', $key);
+ if (!method_exists($this, $method)) {
+ throw new \BadMethodCallException(sprintf('Unknown property "%s" on annotation "%s".', $key, get_class($this)));
+ }
+ $this->$method($value);
+ }
+ }
+
+ public function setPath($path)
+ {
+ $this->path = $path;
+ }
+
+ public function getPath()
+ {
+ return $this->path;
+ }
+
+ public function setHost($pattern)
+ {
+ $this->host = $pattern;
+ }
+
+ public function getHost()
+ {
+ return $this->host;
+ }
+
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public function setRequirements($requirements)
+ {
+ $this->requirements = $requirements;
+ }
+
+ public function getRequirements()
+ {
+ return $this->requirements;
+ }
+
+ public function setOptions($options)
+ {
+ $this->options = $options;
+ }
+
+ public function getOptions()
+ {
+ return $this->options;
+ }
+
+ public function setDefaults($defaults)
+ {
+ $this->defaults = $defaults;
+ }
+
+ public function getDefaults()
+ {
+ return $this->defaults;
+ }
+
+ public function setSchemes($schemes)
+ {
+ $this->schemes = is_array($schemes) ? $schemes : array($schemes);
+ }
+
+ public function getSchemes()
+ {
+ return $this->schemes;
+ }
+
+ public function setMethods($methods)
+ {
+ $this->methods = is_array($methods) ? $methods : array($methods);
+ }
+
+ public function getMethods()
+ {
+ return $this->methods;
+ }
+
+ public function setCondition($condition)
+ {
+ $this->condition = $condition;
+ }
+
+ public function getCondition()
+ {
+ return $this->condition;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/CHANGELOG.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/CHANGELOG.md
new file mode 100644
index 0000000..e278f8b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/CHANGELOG.md
@@ -0,0 +1,228 @@
+CHANGELOG
+=========
+
+3.4.0
+-----
+
+ * Added `NoConfigurationException`.
+ * Added the possibility to define a prefix for all routes of a controller via @Route(name="prefix_")
+ * Added support for prioritized routing loaders.
+ * Add matched and default parameters to redirect responses
+ * Added support for a `controller` keyword for configuring route controllers in YAML and XML configurations.
+
+3.3.0
+-----
+
+ * [DEPRECATION] Class parameters have been deprecated and will be removed in 4.0.
+ * router.options.generator_class
+ * router.options.generator_base_class
+ * router.options.generator_dumper_class
+ * router.options.matcher_class
+ * router.options.matcher_base_class
+ * router.options.matcher_dumper_class
+ * router.options.matcher.cache_class
+ * router.options.generator.cache_class
+
+3.2.0
+-----
+
+ * Added support for `bool`, `int`, `float`, `string`, `list` and `map` defaults in XML configurations.
+ * Added support for UTF-8 requirements
+
+2.8.0
+-----
+
+ * allowed specifying a directory to recursively load all routing configuration files it contains
+ * Added ObjectRouteLoader and ServiceRouteLoader that allow routes to be loaded
+ by calling a method on an object/service.
+ * [DEPRECATION] Deprecated the hardcoded value for the `$referenceType` argument of the `UrlGeneratorInterface::generate` method.
+ Use the constants defined in the `UrlGeneratorInterface` instead.
+
+ Before:
+
+ ```php
+ $router->generate('blog_show', array('slug' => 'my-blog-post'), true);
+ ```
+
+ After:
+
+ ```php
+ use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
+
+ $router->generate('blog_show', array('slug' => 'my-blog-post'), UrlGeneratorInterface::ABSOLUTE_URL);
+ ```
+
+2.5.0
+-----
+
+ * [DEPRECATION] The `ApacheMatcherDumper` and `ApacheUrlMatcher` were deprecated and
+ will be removed in Symfony 3.0, since the performance gains were minimal and
+ it's hard to replicate the behaviour of PHP implementation.
+
+2.3.0
+-----
+
+ * added RequestContext::getQueryString()
+
+2.2.0
+-----
+
+ * [DEPRECATION] Several route settings have been renamed (the old ones will be removed in 3.0):
+
+ * The `pattern` setting for a route has been deprecated in favor of `path`
+ * The `_scheme` and `_method` requirements have been moved to the `schemes` and `methods` settings
+
+ Before:
+
+ ```yaml
+ article_edit:
+ pattern: /article/{id}
+ requirements: { '_method': 'POST|PUT', '_scheme': 'https', 'id': '\d+' }
+ ```
+
+ ```xml
+ <route id="article_edit" pattern="/article/{id}">
+ <requirement key="_method">POST|PUT</requirement>
+ <requirement key="_scheme">https</requirement>
+ <requirement key="id">\d+</requirement>
+ </route>
+ ```
+
+ ```php
+ $route = new Route();
+ $route->setPattern('/article/{id}');
+ $route->setRequirement('_method', 'POST|PUT');
+ $route->setRequirement('_scheme', 'https');
+ ```
+
+ After:
+
+ ```yaml
+ article_edit:
+ path: /article/{id}
+ methods: [POST, PUT]
+ schemes: https
+ requirements: { 'id': '\d+' }
+ ```
+
+ ```xml
+ <route id="article_edit" pattern="/article/{id}" methods="POST PUT" schemes="https">
+ <requirement key="id">\d+</requirement>
+ </route>
+ ```
+
+ ```php
+ $route = new Route();
+ $route->setPath('/article/{id}');
+ $route->setMethods(array('POST', 'PUT'));
+ $route->setSchemes('https');
+ ```
+
+ * [BC BREAK] RouteCollection does not behave like a tree structure anymore but as
+ a flat array of Routes. So when using PHP to build the RouteCollection, you must
+ make sure to add routes to the sub-collection before adding it to the parent
+ collection (this is not relevant when using YAML or XML for Route definitions).
+
+ Before:
+
+ ```php
+ $rootCollection = new RouteCollection();
+ $subCollection = new RouteCollection();
+ $rootCollection->addCollection($subCollection);
+ $subCollection->add('foo', new Route('/foo'));
+ ```
+
+ After:
+
+ ```php
+ $rootCollection = new RouteCollection();
+ $subCollection = new RouteCollection();
+ $subCollection->add('foo', new Route('/foo'));
+ $rootCollection->addCollection($subCollection);
+ ```
+
+ Also one must call `addCollection` from the bottom to the top hierarchy.
+ So the correct sequence is the following (and not the reverse):
+
+ ```php
+ $childCollection->addCollection($grandchildCollection);
+ $rootCollection->addCollection($childCollection);
+ ```
+
+ * [DEPRECATION] The methods `RouteCollection::getParent()` and `RouteCollection::getRoot()`
+ have been deprecated and will be removed in Symfony 2.3.
+ * [BC BREAK] Misusing the `RouteCollection::addPrefix` method to add defaults, requirements
+ or options without adding a prefix is not supported anymore. So if you called `addPrefix`
+ with an empty prefix or `/` only (both have no relevance), like
+ `addPrefix('', $defaultsArray, $requirementsArray, $optionsArray)`
+ you need to use the new dedicated methods `addDefaults($defaultsArray)`,
+ `addRequirements($requirementsArray)` or `addOptions($optionsArray)` instead.
+ * [DEPRECATION] The `$options` parameter to `RouteCollection::addPrefix()` has been deprecated
+ because adding options has nothing to do with adding a path prefix. If you want to add options
+ to all child routes of a RouteCollection, you can use `addOptions()`.
+ * [DEPRECATION] The method `RouteCollection::getPrefix()` has been deprecated
+ because it suggested that all routes in the collection would have this prefix, which is
+ not necessarily true. On top of that, since there is no tree structure anymore, this method
+ is also useless. Don't worry about performance, prefix optimization for matching is still done
+ in the dumper, which was also improved in 2.2.0 to find even more grouping possibilities.
+ * [DEPRECATION] `RouteCollection::addCollection(RouteCollection $collection)` should now only be
+ used with a single parameter. The other params `$prefix`, `$default`, `$requirements` and `$options`
+ will still work, but have been deprecated. The `addPrefix` method should be used for this
+ use-case instead.
+ Before: `$parentCollection->addCollection($collection, '/prefix', array(...), array(...))`
+ After:
+ ```php
+ $collection->addPrefix('/prefix', array(...), array(...));
+ $parentCollection->addCollection($collection);
+ ```
+ * added support for the method default argument values when defining a @Route
+ * Adjacent placeholders without separator work now, e.g. `/{x}{y}{z}.{_format}`.
+ * Characters that function as separator between placeholders are now whitelisted
+ to fix routes with normal text around a variable, e.g. `/prefix{var}suffix`.
+ * [BC BREAK] The default requirement of a variable has been changed slightly.
+ Previously it disallowed the previous and the next char around a variable. Now
+ it disallows the slash (`/`) and the next char. Using the previous char added
+ no value and was problematic because the route `/index.{_format}` would be
+ matched by `/index.ht/ml`.
+ * The default requirement now uses possessive quantifiers when possible which
+ improves matching performance by up to 20% because it prevents backtracking
+ when it's not needed.
+ * The ConfigurableRequirementsInterface can now also be used to disable the requirements
+ check on URL generation completely by calling `setStrictRequirements(null)`. It
+ improves performance in production environment as you should know that params always
+ pass the requirements (otherwise it would break your link anyway).
+ * There is no restriction on the route name anymore. So non-alphanumeric characters
+ are now also allowed.
+ * [BC BREAK] `RouteCompilerInterface::compile(Route $route)` was made static
+ (only relevant if you implemented your own RouteCompiler).
+ * Added possibility to generate relative paths and network paths in the UrlGenerator, e.g.
+ "../parent-file" and "//example.com/dir/file". The third parameter in
+ `UrlGeneratorInterface::generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH)`
+ now accepts more values and you should use the constants defined in `UrlGeneratorInterface` for
+ claritiy. The old method calls with a Boolean parameter will continue to work because they
+ equal the signature using the constants.
+
+2.1.0
+-----
+
+ * added RequestMatcherInterface
+ * added RequestContext::fromRequest()
+ * the UrlMatcher does not throw a \LogicException anymore when the required
+ scheme is not the current one
+ * added TraceableUrlMatcher
+ * added the possibility to define options, default values and requirements
+ for placeholders in prefix, including imported routes
+ * added RouterInterface::getRouteCollection
+ * [BC BREAK] the UrlMatcher urldecodes the route parameters only once, they
+ were decoded twice before. Note that the `urldecode()` calls have been
+ changed for a single `rawurldecode()` in order to support `+` for input
+ paths.
+ * added RouteCollection::getRoot method to retrieve the root of a
+ RouteCollection tree
+ * [BC BREAK] made RouteCollection::setParent private which could not have
+ been used anyway without creating inconsistencies
+ * [BC BREAK] RouteCollection::remove also removes a route from parent
+ collections (not only from its children)
+ * added ConfigurableRequirementsInterface that allows to disable exceptions
+ (and generate empty URLs instead) when generating a route with an invalid
+ parameter value
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/CompiledRoute.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/CompiledRoute.php
new file mode 100644
index 0000000..8ecf515
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/CompiledRoute.php
@@ -0,0 +1,169 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing;
+
+/**
+ * CompiledRoutes are returned by the RouteCompiler class.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class CompiledRoute implements \Serializable
+{
+ private $variables;
+ private $tokens;
+ private $staticPrefix;
+ private $regex;
+ private $pathVariables;
+ private $hostVariables;
+ private $hostRegex;
+ private $hostTokens;
+
+ /**
+ * @param string $staticPrefix The static prefix of the compiled route
+ * @param string $regex The regular expression to use to match this route
+ * @param array $tokens An array of tokens to use to generate URL for this route
+ * @param array $pathVariables An array of path variables
+ * @param string|null $hostRegex Host regex
+ * @param array $hostTokens Host tokens
+ * @param array $hostVariables An array of host variables
+ * @param array $variables An array of variables (variables defined in the path and in the host patterns)
+ */
+ public function __construct($staticPrefix, $regex, array $tokens, array $pathVariables, $hostRegex = null, array $hostTokens = array(), array $hostVariables = array(), array $variables = array())
+ {
+ $this->staticPrefix = (string) $staticPrefix;
+ $this->regex = $regex;
+ $this->tokens = $tokens;
+ $this->pathVariables = $pathVariables;
+ $this->hostRegex = $hostRegex;
+ $this->hostTokens = $hostTokens;
+ $this->hostVariables = $hostVariables;
+ $this->variables = $variables;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function serialize()
+ {
+ return serialize(array(
+ 'vars' => $this->variables,
+ 'path_prefix' => $this->staticPrefix,
+ 'path_regex' => $this->regex,
+ 'path_tokens' => $this->tokens,
+ 'path_vars' => $this->pathVariables,
+ 'host_regex' => $this->hostRegex,
+ 'host_tokens' => $this->hostTokens,
+ 'host_vars' => $this->hostVariables,
+ ));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function unserialize($serialized)
+ {
+ if (\PHP_VERSION_ID >= 70000) {
+ $data = unserialize($serialized, array('allowed_classes' => false));
+ } else {
+ $data = unserialize($serialized);
+ }
+
+ $this->variables = $data['vars'];
+ $this->staticPrefix = $data['path_prefix'];
+ $this->regex = $data['path_regex'];
+ $this->tokens = $data['path_tokens'];
+ $this->pathVariables = $data['path_vars'];
+ $this->hostRegex = $data['host_regex'];
+ $this->hostTokens = $data['host_tokens'];
+ $this->hostVariables = $data['host_vars'];
+ }
+
+ /**
+ * Returns the static prefix.
+ *
+ * @return string The static prefix
+ */
+ public function getStaticPrefix()
+ {
+ return $this->staticPrefix;
+ }
+
+ /**
+ * Returns the regex.
+ *
+ * @return string The regex
+ */
+ public function getRegex()
+ {
+ return $this->regex;
+ }
+
+ /**
+ * Returns the host regex.
+ *
+ * @return string|null The host regex or null
+ */
+ public function getHostRegex()
+ {
+ return $this->hostRegex;
+ }
+
+ /**
+ * Returns the tokens.
+ *
+ * @return array The tokens
+ */
+ public function getTokens()
+ {
+ return $this->tokens;
+ }
+
+ /**
+ * Returns the host tokens.
+ *
+ * @return array The tokens
+ */
+ public function getHostTokens()
+ {
+ return $this->hostTokens;
+ }
+
+ /**
+ * Returns the variables.
+ *
+ * @return array The variables
+ */
+ public function getVariables()
+ {
+ return $this->variables;
+ }
+
+ /**
+ * Returns the path variables.
+ *
+ * @return array The variables
+ */
+ public function getPathVariables()
+ {
+ return $this->pathVariables;
+ }
+
+ /**
+ * Returns the host variables.
+ *
+ * @return array The variables
+ */
+ public function getHostVariables()
+ {
+ return $this->hostVariables;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/DependencyInjection/RoutingResolverPass.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/DependencyInjection/RoutingResolverPass.php
new file mode 100644
index 0000000..4af0a5a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/DependencyInjection/RoutingResolverPass.php
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\DependencyInjection;
+
+use Symfony\Component\DependencyInjection\Reference;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait;
+
+/**
+ * Adds tagged routing.loader services to routing.resolver service.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class RoutingResolverPass implements CompilerPassInterface
+{
+ use PriorityTaggedServiceTrait;
+
+ private $resolverServiceId;
+ private $loaderTag;
+
+ public function __construct($resolverServiceId = 'routing.resolver', $loaderTag = 'routing.loader')
+ {
+ $this->resolverServiceId = $resolverServiceId;
+ $this->loaderTag = $loaderTag;
+ }
+
+ public function process(ContainerBuilder $container)
+ {
+ if (false === $container->hasDefinition($this->resolverServiceId)) {
+ return;
+ }
+
+ $definition = $container->getDefinition($this->resolverServiceId);
+
+ foreach ($this->findAndSortTaggedServices($this->loaderTag, $container) as $id) {
+ $definition->addMethodCall('addLoader', array(new Reference($id)));
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Exception/ExceptionInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Exception/ExceptionInterface.php
new file mode 100644
index 0000000..db76362
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Exception/ExceptionInterface.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Exception;
+
+/**
+ * ExceptionInterface.
+ *
+ * @author Alexandre Salomé <alexandre.salome@gmail.com>
+ */
+interface ExceptionInterface
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Exception/InvalidParameterException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Exception/InvalidParameterException.php
new file mode 100644
index 0000000..94d841f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Exception/InvalidParameterException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Exception;
+
+/**
+ * Exception thrown when a parameter is not valid.
+ *
+ * @author Alexandre Salomé <alexandre.salome@gmail.com>
+ */
+class InvalidParameterException extends \InvalidArgumentException implements ExceptionInterface
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Exception/MethodNotAllowedException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Exception/MethodNotAllowedException.php
new file mode 100644
index 0000000..712412f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Exception/MethodNotAllowedException.php
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Exception;
+
+/**
+ * The resource was found but the request method is not allowed.
+ *
+ * This exception should trigger an HTTP 405 response in your application code.
+ *
+ * @author Kris Wallsmith <kris@symfony.com>
+ */
+class MethodNotAllowedException extends \RuntimeException implements ExceptionInterface
+{
+ protected $allowedMethods = array();
+
+ public function __construct(array $allowedMethods, $message = null, $code = 0, \Exception $previous = null)
+ {
+ $this->allowedMethods = array_map('strtoupper', $allowedMethods);
+
+ parent::__construct($message, $code, $previous);
+ }
+
+ /**
+ * Gets the allowed HTTP methods.
+ *
+ * @return array
+ */
+ public function getAllowedMethods()
+ {
+ return $this->allowedMethods;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Exception/MissingMandatoryParametersException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Exception/MissingMandatoryParametersException.php
new file mode 100644
index 0000000..57f3a40
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Exception/MissingMandatoryParametersException.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Exception;
+
+/**
+ * Exception thrown when a route cannot be generated because of missing
+ * mandatory parameters.
+ *
+ * @author Alexandre Salomé <alexandre.salome@gmail.com>
+ */
+class MissingMandatoryParametersException extends \InvalidArgumentException implements ExceptionInterface
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Exception/NoConfigurationException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Exception/NoConfigurationException.php
new file mode 100644
index 0000000..333bc74
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Exception/NoConfigurationException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Exception;
+
+/**
+ * Exception thrown when no routes are configured.
+ *
+ * @author Yonel Ceruto <yonelceruto@gmail.com>
+ */
+class NoConfigurationException extends ResourceNotFoundException
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Exception/ResourceNotFoundException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Exception/ResourceNotFoundException.php
new file mode 100644
index 0000000..ccbca15
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Exception/ResourceNotFoundException.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Exception;
+
+/**
+ * The resource was not found.
+ *
+ * This exception should trigger an HTTP 404 response in your application code.
+ *
+ * @author Kris Wallsmith <kris@symfony.com>
+ */
+class ResourceNotFoundException extends \RuntimeException implements ExceptionInterface
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Exception/RouteNotFoundException.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Exception/RouteNotFoundException.php
new file mode 100644
index 0000000..24ab0b4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Exception/RouteNotFoundException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Exception;
+
+/**
+ * Exception thrown when a route does not exist.
+ *
+ * @author Alexandre Salomé <alexandre.salome@gmail.com>
+ */
+class RouteNotFoundException extends \InvalidArgumentException implements ExceptionInterface
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Generator/ConfigurableRequirementsInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Generator/ConfigurableRequirementsInterface.php
new file mode 100644
index 0000000..dc97b7e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Generator/ConfigurableRequirementsInterface.php
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Generator;
+
+/**
+ * ConfigurableRequirementsInterface must be implemented by URL generators that
+ * can be configured whether an exception should be generated when the parameters
+ * do not match the requirements. It is also possible to disable the requirements
+ * check for URL generation completely.
+ *
+ * The possible configurations and use-cases:
+ * - setStrictRequirements(true): Throw an exception for mismatching requirements. This
+ * is mostly useful in development environment.
+ * - setStrictRequirements(false): Don't throw an exception but return null as URL for
+ * mismatching requirements and log the problem. Useful when you cannot control all
+ * params because they come from third party libs but don't want to have a 404 in
+ * production environment. It should log the mismatch so one can review it.
+ * - setStrictRequirements(null): Return the URL with the given parameters without
+ * checking the requirements at all. When generating a URL you should either trust
+ * your params or you validated them beforehand because otherwise it would break your
+ * link anyway. So in production environment you should know that params always pass
+ * the requirements. Thus this option allows to disable the check on URL generation for
+ * performance reasons (saving a preg_match for each requirement every time a URL is
+ * generated).
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Tobias Schultze <http://tobion.de>
+ */
+interface ConfigurableRequirementsInterface
+{
+ /**
+ * Enables or disables the exception on incorrect parameters.
+ * Passing null will deactivate the requirements check completely.
+ *
+ * @param bool|null $enabled
+ */
+ public function setStrictRequirements($enabled);
+
+ /**
+ * Returns whether to throw an exception on incorrect parameters.
+ * Null means the requirements check is deactivated completely.
+ *
+ * @return bool|null
+ */
+ public function isStrictRequirements();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Generator/Dumper/GeneratorDumper.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Generator/Dumper/GeneratorDumper.php
new file mode 100644
index 0000000..659c5ba
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Generator/Dumper/GeneratorDumper.php
@@ -0,0 +1,37 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Generator\Dumper;
+
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * GeneratorDumper is the base class for all built-in generator dumpers.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+abstract class GeneratorDumper implements GeneratorDumperInterface
+{
+ private $routes;
+
+ public function __construct(RouteCollection $routes)
+ {
+ $this->routes = $routes;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getRoutes()
+ {
+ return $this->routes;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Generator/Dumper/GeneratorDumperInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Generator/Dumper/GeneratorDumperInterface.php
new file mode 100644
index 0000000..fed3472
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Generator/Dumper/GeneratorDumperInterface.php
@@ -0,0 +1,39 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Generator\Dumper;
+
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * GeneratorDumperInterface is the interface that all generator dumper classes must implement.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface GeneratorDumperInterface
+{
+ /**
+ * Dumps a set of routes to a string representation of executable code
+ * that can then be used to generate a URL of such a route.
+ *
+ * @param array $options An array of options
+ *
+ * @return string Executable code
+ */
+ public function dump(array $options = array());
+
+ /**
+ * Gets the routes to dump.
+ *
+ * @return RouteCollection A RouteCollection instance
+ */
+ public function getRoutes();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Generator/Dumper/PhpGeneratorDumper.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Generator/Dumper/PhpGeneratorDumper.php
new file mode 100644
index 0000000..60bdf1d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Generator/Dumper/PhpGeneratorDumper.php
@@ -0,0 +1,118 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Generator\Dumper;
+
+/**
+ * PhpGeneratorDumper creates a PHP class able to generate URLs for a given set of routes.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Tobias Schultze <http://tobion.de>
+ */
+class PhpGeneratorDumper extends GeneratorDumper
+{
+ /**
+ * Dumps a set of routes to a PHP class.
+ *
+ * Available options:
+ *
+ * * class: The class name
+ * * base_class: The base class name
+ *
+ * @param array $options An array of options
+ *
+ * @return string A PHP class representing the generator class
+ */
+ public function dump(array $options = array())
+ {
+ $options = array_merge(array(
+ 'class' => 'ProjectUrlGenerator',
+ 'base_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator',
+ ), $options);
+
+ return <<<EOF
+<?php
+
+use Symfony\Component\Routing\RequestContext;
+use Symfony\Component\Routing\Exception\RouteNotFoundException;
+use Psr\Log\LoggerInterface;
+
+/**
+ * This class has been auto-generated
+ * by the Symfony Routing Component.
+ */
+class {$options['class']} extends {$options['base_class']}
+{
+ private static \$declaredRoutes;
+
+ public function __construct(RequestContext \$context, LoggerInterface \$logger = null)
+ {
+ \$this->context = \$context;
+ \$this->logger = \$logger;
+ if (null === self::\$declaredRoutes) {
+ self::\$declaredRoutes = {$this->generateDeclaredRoutes()};
+ }
+ }
+
+{$this->generateGenerateMethod()}
+}
+
+EOF;
+ }
+
+ /**
+ * Generates PHP code representing an array of defined routes
+ * together with the routes properties (e.g. requirements).
+ *
+ * @return string PHP code
+ */
+ private function generateDeclaredRoutes()
+ {
+ $routes = "array(\n";
+ foreach ($this->getRoutes()->all() as $name => $route) {
+ $compiledRoute = $route->compile();
+
+ $properties = array();
+ $properties[] = $compiledRoute->getVariables();
+ $properties[] = $route->getDefaults();
+ $properties[] = $route->getRequirements();
+ $properties[] = $compiledRoute->getTokens();
+ $properties[] = $compiledRoute->getHostTokens();
+ $properties[] = $route->getSchemes();
+
+ $routes .= sprintf(" '%s' => %s,\n", $name, str_replace("\n", '', var_export($properties, true)));
+ }
+ $routes .= ' )';
+
+ return $routes;
+ }
+
+ /**
+ * Generates PHP code representing the `generate` method that implements the UrlGeneratorInterface.
+ *
+ * @return string PHP code
+ */
+ private function generateGenerateMethod()
+ {
+ return <<<'EOF'
+ public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH)
+ {
+ if (!isset(self::$declaredRoutes[$name])) {
+ throw new RouteNotFoundException(sprintf('Unable to generate a URL for the named route "%s" as such route does not exist.', $name));
+ }
+
+ list($variables, $defaults, $requirements, $tokens, $hostTokens, $requiredSchemes) = self::$declaredRoutes[$name];
+
+ return $this->doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens, $requiredSchemes);
+ }
+EOF;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Generator/UrlGenerator.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Generator/UrlGenerator.php
new file mode 100644
index 0000000..02a59a9
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Generator/UrlGenerator.php
@@ -0,0 +1,321 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Generator;
+
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\RequestContext;
+use Symfony\Component\Routing\Exception\InvalidParameterException;
+use Symfony\Component\Routing\Exception\RouteNotFoundException;
+use Symfony\Component\Routing\Exception\MissingMandatoryParametersException;
+use Psr\Log\LoggerInterface;
+
+/**
+ * UrlGenerator can generate a URL or a path for any route in the RouteCollection
+ * based on the passed parameters.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Tobias Schultze <http://tobion.de>
+ */
+class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInterface
+{
+ protected $routes;
+ protected $context;
+
+ /**
+ * @var bool|null
+ */
+ protected $strictRequirements = true;
+
+ protected $logger;
+
+ /**
+ * This array defines the characters (besides alphanumeric ones) that will not be percent-encoded in the path segment of the generated URL.
+ *
+ * PHP's rawurlencode() encodes all chars except "a-zA-Z0-9-._~" according to RFC 3986. But we want to allow some chars
+ * to be used in their literal form (reasons below). Other chars inside the path must of course be encoded, e.g.
+ * "?" and "#" (would be interpreted wrongly as query and fragment identifier),
+ * "'" and """ (are used as delimiters in HTML).
+ */
+ protected $decodedChars = array(
+ // the slash can be used to designate a hierarchical structure and we want allow using it with this meaning
+ // some webservers don't allow the slash in encoded form in the path for security reasons anyway
+ // see http://stackoverflow.com/questions/4069002/http-400-if-2f-part-of-get-url-in-jboss
+ '%2F' => '/',
+ // the following chars are general delimiters in the URI specification but have only special meaning in the authority component
+ // so they can safely be used in the path in unencoded form
+ '%40' => '@',
+ '%3A' => ':',
+ // these chars are only sub-delimiters that have no predefined meaning and can therefore be used literally
+ // so URI producing applications can use these chars to delimit subcomponents in a path segment without being encoded for better readability
+ '%3B' => ';',
+ '%2C' => ',',
+ '%3D' => '=',
+ '%2B' => '+',
+ '%21' => '!',
+ '%2A' => '*',
+ '%7C' => '|',
+ );
+
+ public function __construct(RouteCollection $routes, RequestContext $context, LoggerInterface $logger = null)
+ {
+ $this->routes = $routes;
+ $this->context = $context;
+ $this->logger = $logger;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setContext(RequestContext $context)
+ {
+ $this->context = $context;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getContext()
+ {
+ return $this->context;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setStrictRequirements($enabled)
+ {
+ $this->strictRequirements = null === $enabled ? null : (bool) $enabled;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isStrictRequirements()
+ {
+ return $this->strictRequirements;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH)
+ {
+ if (null === $route = $this->routes->get($name)) {
+ throw new RouteNotFoundException(sprintf('Unable to generate a URL for the named route "%s" as such route does not exist.', $name));
+ }
+
+ // the Route has a cache of its own and is not recompiled as long as it does not get modified
+ $compiledRoute = $route->compile();
+
+ return $this->doGenerate($compiledRoute->getVariables(), $route->getDefaults(), $route->getRequirements(), $compiledRoute->getTokens(), $parameters, $name, $referenceType, $compiledRoute->getHostTokens(), $route->getSchemes());
+ }
+
+ /**
+ * @throws MissingMandatoryParametersException When some parameters are missing that are mandatory for the route
+ * @throws InvalidParameterException When a parameter value for a placeholder is not correct because
+ * it does not match the requirement
+ */
+ protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens, array $requiredSchemes = array())
+ {
+ $variables = array_flip($variables);
+ $mergedParams = array_replace($defaults, $this->context->getParameters(), $parameters);
+
+ // all params must be given
+ if ($diff = array_diff_key($variables, $mergedParams)) {
+ throw new MissingMandatoryParametersException(sprintf('Some mandatory parameters are missing ("%s") to generate a URL for route "%s".', implode('", "', array_keys($diff)), $name));
+ }
+
+ $url = '';
+ $optional = true;
+ $message = 'Parameter "{parameter}" for route "{route}" must match "{expected}" ("{given}" given) to generate a corresponding URL.';
+ foreach ($tokens as $token) {
+ if ('variable' === $token[0]) {
+ if (!$optional || !array_key_exists($token[3], $defaults) || null !== $mergedParams[$token[3]] && (string) $mergedParams[$token[3]] !== (string) $defaults[$token[3]]) {
+ // check requirement
+ if (null !== $this->strictRequirements && !preg_match('#^'.$token[2].'$#'.(empty($token[4]) ? '' : 'u'), $mergedParams[$token[3]])) {
+ if ($this->strictRequirements) {
+ throw new InvalidParameterException(strtr($message, array('{parameter}' => $token[3], '{route}' => $name, '{expected}' => $token[2], '{given}' => $mergedParams[$token[3]])));
+ }
+
+ if ($this->logger) {
+ $this->logger->error($message, array('parameter' => $token[3], 'route' => $name, 'expected' => $token[2], 'given' => $mergedParams[$token[3]]));
+ }
+
+ return;
+ }
+
+ $url = $token[1].$mergedParams[$token[3]].$url;
+ $optional = false;
+ }
+ } else {
+ // static text
+ $url = $token[1].$url;
+ $optional = false;
+ }
+ }
+
+ if ('' === $url) {
+ $url = '/';
+ }
+
+ // the contexts base URL is already encoded (see Symfony\Component\HttpFoundation\Request)
+ $url = strtr(rawurlencode($url), $this->decodedChars);
+
+ // the path segments "." and ".." are interpreted as relative reference when resolving a URI; see http://tools.ietf.org/html/rfc3986#section-3.3
+ // so we need to encode them as they are not used for this purpose here
+ // otherwise we would generate a URI that, when followed by a user agent (e.g. browser), does not match this route
+ $url = strtr($url, array('/../' => '/%2E%2E/', '/./' => '/%2E/'));
+ if ('/..' === substr($url, -3)) {
+ $url = substr($url, 0, -2).'%2E%2E';
+ } elseif ('/.' === substr($url, -2)) {
+ $url = substr($url, 0, -1).'%2E';
+ }
+
+ $schemeAuthority = '';
+ $host = $this->context->getHost();
+ $scheme = $this->context->getScheme();
+
+ if ($requiredSchemes) {
+ if (!in_array($scheme, $requiredSchemes, true)) {
+ $referenceType = self::ABSOLUTE_URL;
+ $scheme = current($requiredSchemes);
+ }
+ }
+
+ if ($hostTokens) {
+ $routeHost = '';
+ foreach ($hostTokens as $token) {
+ if ('variable' === $token[0]) {
+ if (null !== $this->strictRequirements && !preg_match('#^'.$token[2].'$#i'.(empty($token[4]) ? '' : 'u'), $mergedParams[$token[3]])) {
+ if ($this->strictRequirements) {
+ throw new InvalidParameterException(strtr($message, array('{parameter}' => $token[3], '{route}' => $name, '{expected}' => $token[2], '{given}' => $mergedParams[$token[3]])));
+ }
+
+ if ($this->logger) {
+ $this->logger->error($message, array('parameter' => $token[3], 'route' => $name, 'expected' => $token[2], 'given' => $mergedParams[$token[3]]));
+ }
+
+ return;
+ }
+
+ $routeHost = $token[1].$mergedParams[$token[3]].$routeHost;
+ } else {
+ $routeHost = $token[1].$routeHost;
+ }
+ }
+
+ if ($routeHost !== $host) {
+ $host = $routeHost;
+ if (self::ABSOLUTE_URL !== $referenceType) {
+ $referenceType = self::NETWORK_PATH;
+ }
+ }
+ }
+
+ if ((self::ABSOLUTE_URL === $referenceType || self::NETWORK_PATH === $referenceType) && !empty($host)) {
+ $port = '';
+ if ('http' === $scheme && 80 != $this->context->getHttpPort()) {
+ $port = ':'.$this->context->getHttpPort();
+ } elseif ('https' === $scheme && 443 != $this->context->getHttpsPort()) {
+ $port = ':'.$this->context->getHttpsPort();
+ }
+
+ $schemeAuthority = self::NETWORK_PATH === $referenceType ? '//' : "$scheme://";
+ $schemeAuthority .= $host.$port;
+ }
+
+ if (self::RELATIVE_PATH === $referenceType) {
+ $url = self::getRelativePath($this->context->getPathInfo(), $url);
+ } else {
+ $url = $schemeAuthority.$this->context->getBaseUrl().$url;
+ }
+
+ // add a query string if needed
+ $extra = array_udiff_assoc(array_diff_key($parameters, $variables), $defaults, function ($a, $b) {
+ return $a == $b ? 0 : 1;
+ });
+
+ // extract fragment
+ $fragment = '';
+ if (isset($defaults['_fragment'])) {
+ $fragment = $defaults['_fragment'];
+ }
+
+ if (isset($extra['_fragment'])) {
+ $fragment = $extra['_fragment'];
+ unset($extra['_fragment']);
+ }
+
+ if ($extra && $query = http_build_query($extra, '', '&', PHP_QUERY_RFC3986)) {
+ // "/" and "?" can be left decoded for better user experience, see
+ // http://tools.ietf.org/html/rfc3986#section-3.4
+ $url .= '?'.strtr($query, array('%2F' => '/'));
+ }
+
+ if ('' !== $fragment) {
+ $url .= '#'.strtr(rawurlencode($fragment), array('%2F' => '/', '%3F' => '?'));
+ }
+
+ return $url;
+ }
+
+ /**
+ * Returns the target path as relative reference from the base path.
+ *
+ * Only the URIs path component (no schema, host etc.) is relevant and must be given, starting with a slash.
+ * Both paths must be absolute and not contain relative parts.
+ * Relative URLs from one resource to another are useful when generating self-contained downloadable document archives.
+ * Furthermore, they can be used to reduce the link size in documents.
+ *
+ * Example target paths, given a base path of "/a/b/c/d":
+ * - "/a/b/c/d" -> ""
+ * - "/a/b/c/" -> "./"
+ * - "/a/b/" -> "../"
+ * - "/a/b/c/other" -> "other"
+ * - "/a/x/y" -> "../../x/y"
+ *
+ * @param string $basePath The base path
+ * @param string $targetPath The target path
+ *
+ * @return string The relative target path
+ */
+ public static function getRelativePath($basePath, $targetPath)
+ {
+ if ($basePath === $targetPath) {
+ return '';
+ }
+
+ $sourceDirs = explode('/', isset($basePath[0]) && '/' === $basePath[0] ? substr($basePath, 1) : $basePath);
+ $targetDirs = explode('/', isset($targetPath[0]) && '/' === $targetPath[0] ? substr($targetPath, 1) : $targetPath);
+ array_pop($sourceDirs);
+ $targetFile = array_pop($targetDirs);
+
+ foreach ($sourceDirs as $i => $dir) {
+ if (isset($targetDirs[$i]) && $dir === $targetDirs[$i]) {
+ unset($sourceDirs[$i], $targetDirs[$i]);
+ } else {
+ break;
+ }
+ }
+
+ $targetDirs[] = $targetFile;
+ $path = str_repeat('../', count($sourceDirs)).implode('/', $targetDirs);
+
+ // A reference to the same base directory or an empty subdirectory must be prefixed with "./".
+ // This also applies to a segment with a colon character (e.g., "file:colon") that cannot be used
+ // as the first segment of a relative-path reference, as it would be mistaken for a scheme name
+ // (see http://tools.ietf.org/html/rfc3986#section-4.2).
+ return '' === $path || '/' === $path[0]
+ || false !== ($colonPos = strpos($path, ':')) && ($colonPos < ($slashPos = strpos($path, '/')) || false === $slashPos)
+ ? "./$path" : $path;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Generator/UrlGeneratorInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Generator/UrlGeneratorInterface.php
new file mode 100644
index 0000000..d6e7938
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Generator/UrlGeneratorInterface.php
@@ -0,0 +1,86 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Generator;
+
+use Symfony\Component\Routing\Exception\InvalidParameterException;
+use Symfony\Component\Routing\Exception\MissingMandatoryParametersException;
+use Symfony\Component\Routing\Exception\RouteNotFoundException;
+use Symfony\Component\Routing\RequestContextAwareInterface;
+
+/**
+ * UrlGeneratorInterface is the interface that all URL generator classes must implement.
+ *
+ * The constants in this interface define the different types of resource references that
+ * are declared in RFC 3986: http://tools.ietf.org/html/rfc3986
+ * We are using the term "URL" instead of "URI" as this is more common in web applications
+ * and we do not need to distinguish them as the difference is mostly semantical and
+ * less technical. Generating URIs, i.e. representation-independent resource identifiers,
+ * is also possible.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Tobias Schultze <http://tobion.de>
+ */
+interface UrlGeneratorInterface extends RequestContextAwareInterface
+{
+ /**
+ * Generates an absolute URL, e.g. "http://example.com/dir/file".
+ */
+ const ABSOLUTE_URL = 0;
+
+ /**
+ * Generates an absolute path, e.g. "/dir/file".
+ */
+ const ABSOLUTE_PATH = 1;
+
+ /**
+ * Generates a relative path based on the current request path, e.g. "../parent-file".
+ *
+ * @see UrlGenerator::getRelativePath()
+ */
+ const RELATIVE_PATH = 2;
+
+ /**
+ * Generates a network path, e.g. "//example.com/dir/file".
+ * Such reference reuses the current scheme but specifies the host.
+ */
+ const NETWORK_PATH = 3;
+
+ /**
+ * Generates a URL or path for a specific route based on the given parameters.
+ *
+ * Parameters that reference placeholders in the route pattern will substitute them in the
+ * path or host. Extra params are added as query string to the URL.
+ *
+ * When the passed reference type cannot be generated for the route because it requires a different
+ * host or scheme than the current one, the method will return a more comprehensive reference
+ * that includes the required params. For example, when you call this method with $referenceType = ABSOLUTE_PATH
+ * but the route requires the https scheme whereas the current scheme is http, it will instead return an
+ * ABSOLUTE_URL with the https scheme and the current host. This makes sure the generated URL matches
+ * the route in any case.
+ *
+ * If there is no route with the given name, the generator must throw the RouteNotFoundException.
+ *
+ * The special parameter _fragment will be used as the document fragment suffixed to the final URL.
+ *
+ * @param string $name The name of the route
+ * @param mixed $parameters An array of parameters
+ * @param int $referenceType The type of reference to be generated (one of the constants)
+ *
+ * @return string The generated URL
+ *
+ * @throws RouteNotFoundException If the named route doesn't exist
+ * @throws MissingMandatoryParametersException When some parameters are missing that are mandatory for the route
+ * @throws InvalidParameterException When a parameter value for a placeholder is not correct because
+ * it does not match the requirement
+ */
+ public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/LICENSE b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/LICENSE
new file mode 100644
index 0000000..21d7fb9
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2004-2018 Fabien Potencier
+
+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.
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/AnnotationClassLoader.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/AnnotationClassLoader.php
new file mode 100644
index 0000000..2fe6fb5
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/AnnotationClassLoader.php
@@ -0,0 +1,269 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Loader;
+
+use Doctrine\Common\Annotations\Reader;
+use Symfony\Component\Config\Resource\FileResource;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Config\Loader\LoaderInterface;
+use Symfony\Component\Config\Loader\LoaderResolverInterface;
+
+/**
+ * AnnotationClassLoader loads routing information from a PHP class and its methods.
+ *
+ * You need to define an implementation for the getRouteDefaults() method. Most of the
+ * time, this method should define some PHP callable to be called for the route
+ * (a controller in MVC speak).
+ *
+ * The @Route annotation can be set on the class (for global parameters),
+ * and on each method.
+ *
+ * The @Route annotation main value is the route path. The annotation also
+ * recognizes several parameters: requirements, options, defaults, schemes,
+ * methods, host, and name. The name parameter is mandatory.
+ * Here is an example of how you should be able to use it:
+ *
+ * /**
+ * * @Route("/Blog")
+ * * /
+ * class Blog
+ * {
+ * /**
+ * * @Route("/", name="blog_index")
+ * * /
+ * public function index()
+ * {
+ * }
+ *
+ * /**
+ * * @Route("/{id}", name="blog_post", requirements = {"id" = "\d+"})
+ * * /
+ * public function show()
+ * {
+ * }
+ * }
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+abstract class AnnotationClassLoader implements LoaderInterface
+{
+ protected $reader;
+
+ /**
+ * @var string
+ */
+ protected $routeAnnotationClass = 'Symfony\\Component\\Routing\\Annotation\\Route';
+
+ /**
+ * @var int
+ */
+ protected $defaultRouteIndex = 0;
+
+ public function __construct(Reader $reader)
+ {
+ $this->reader = $reader;
+ }
+
+ /**
+ * Sets the annotation class to read route properties from.
+ *
+ * @param string $class A fully-qualified class name
+ */
+ public function setRouteAnnotationClass($class)
+ {
+ $this->routeAnnotationClass = $class;
+ }
+
+ /**
+ * Loads from annotations from a class.
+ *
+ * @param string $class A class name
+ * @param string|null $type The resource type
+ *
+ * @return RouteCollection A RouteCollection instance
+ *
+ * @throws \InvalidArgumentException When route can't be parsed
+ */
+ public function load($class, $type = null)
+ {
+ if (!class_exists($class)) {
+ throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class));
+ }
+
+ $class = new \ReflectionClass($class);
+ if ($class->isAbstract()) {
+ throw new \InvalidArgumentException(sprintf('Annotations from class "%s" cannot be read as it is abstract.', $class->getName()));
+ }
+
+ $globals = $this->getGlobals($class);
+
+ $collection = new RouteCollection();
+ $collection->addResource(new FileResource($class->getFileName()));
+
+ foreach ($class->getMethods() as $method) {
+ $this->defaultRouteIndex = 0;
+ foreach ($this->reader->getMethodAnnotations($method) as $annot) {
+ if ($annot instanceof $this->routeAnnotationClass) {
+ $this->addRoute($collection, $annot, $globals, $class, $method);
+ }
+ }
+ }
+
+ if (0 === $collection->count() && $class->hasMethod('__invoke') && $annot = $this->reader->getClassAnnotation($class, $this->routeAnnotationClass)) {
+ $globals['path'] = '';
+ $globals['name'] = '';
+ $this->addRoute($collection, $annot, $globals, $class, $class->getMethod('__invoke'));
+ }
+
+ return $collection;
+ }
+
+ protected function addRoute(RouteCollection $collection, $annot, $globals, \ReflectionClass $class, \ReflectionMethod $method)
+ {
+ $name = $annot->getName();
+ if (null === $name) {
+ $name = $this->getDefaultRouteName($class, $method);
+ }
+ $name = $globals['name'].$name;
+
+ $defaults = array_replace($globals['defaults'], $annot->getDefaults());
+ foreach ($method->getParameters() as $param) {
+ if (false !== strpos($globals['path'].$annot->getPath(), sprintf('{%s}', $param->getName())) && !isset($defaults[$param->getName()]) && $param->isDefaultValueAvailable()) {
+ $defaults[$param->getName()] = $param->getDefaultValue();
+ }
+ }
+ $requirements = array_replace($globals['requirements'], $annot->getRequirements());
+ $options = array_replace($globals['options'], $annot->getOptions());
+ $schemes = array_merge($globals['schemes'], $annot->getSchemes());
+ $methods = array_merge($globals['methods'], $annot->getMethods());
+
+ $host = $annot->getHost();
+ if (null === $host) {
+ $host = $globals['host'];
+ }
+
+ $condition = $annot->getCondition();
+ if (null === $condition) {
+ $condition = $globals['condition'];
+ }
+
+ $route = $this->createRoute($globals['path'].$annot->getPath(), $defaults, $requirements, $options, $host, $schemes, $methods, $condition);
+
+ $this->configureRoute($route, $class, $method, $annot);
+
+ $collection->add($name, $route);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supports($resource, $type = null)
+ {
+ return is_string($resource) && preg_match('/^(?:\\\\?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)+$/', $resource) && (!$type || 'annotation' === $type);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setResolver(LoaderResolverInterface $resolver)
+ {
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getResolver()
+ {
+ }
+
+ /**
+ * Gets the default route name for a class method.
+ *
+ * @param \ReflectionClass $class
+ * @param \ReflectionMethod $method
+ *
+ * @return string
+ */
+ protected function getDefaultRouteName(\ReflectionClass $class, \ReflectionMethod $method)
+ {
+ $name = strtolower(str_replace('\\', '_', $class->name).'_'.$method->name);
+ if ($this->defaultRouteIndex > 0) {
+ $name .= '_'.$this->defaultRouteIndex;
+ }
+ ++$this->defaultRouteIndex;
+
+ return $name;
+ }
+
+ protected function getGlobals(\ReflectionClass $class)
+ {
+ $globals = array(
+ 'path' => '',
+ 'requirements' => array(),
+ 'options' => array(),
+ 'defaults' => array(),
+ 'schemes' => array(),
+ 'methods' => array(),
+ 'host' => '',
+ 'condition' => '',
+ 'name' => '',
+ );
+
+ if ($annot = $this->reader->getClassAnnotation($class, $this->routeAnnotationClass)) {
+ if (null !== $annot->getName()) {
+ $globals['name'] = $annot->getName();
+ }
+
+ if (null !== $annot->getPath()) {
+ $globals['path'] = $annot->getPath();
+ }
+
+ if (null !== $annot->getRequirements()) {
+ $globals['requirements'] = $annot->getRequirements();
+ }
+
+ if (null !== $annot->getOptions()) {
+ $globals['options'] = $annot->getOptions();
+ }
+
+ if (null !== $annot->getDefaults()) {
+ $globals['defaults'] = $annot->getDefaults();
+ }
+
+ if (null !== $annot->getSchemes()) {
+ $globals['schemes'] = $annot->getSchemes();
+ }
+
+ if (null !== $annot->getMethods()) {
+ $globals['methods'] = $annot->getMethods();
+ }
+
+ if (null !== $annot->getHost()) {
+ $globals['host'] = $annot->getHost();
+ }
+
+ if (null !== $annot->getCondition()) {
+ $globals['condition'] = $annot->getCondition();
+ }
+ }
+
+ return $globals;
+ }
+
+ protected function createRoute($path, $defaults, $requirements, $options, $host, $schemes, $methods, $condition)
+ {
+ return new Route($path, $defaults, $requirements, $options, $host, $schemes, $methods, $condition);
+ }
+
+ abstract protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, $annot);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/AnnotationDirectoryLoader.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/AnnotationDirectoryLoader.php
new file mode 100644
index 0000000..4574a02
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/AnnotationDirectoryLoader.php
@@ -0,0 +1,93 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Loader;
+
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Config\Resource\DirectoryResource;
+
+/**
+ * AnnotationDirectoryLoader loads routing information from annotations set
+ * on PHP classes and methods.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class AnnotationDirectoryLoader extends AnnotationFileLoader
+{
+ /**
+ * Loads from annotations from a directory.
+ *
+ * @param string $path A directory path
+ * @param string|null $type The resource type
+ *
+ * @return RouteCollection A RouteCollection instance
+ *
+ * @throws \InvalidArgumentException When the directory does not exist or its routes cannot be parsed
+ */
+ public function load($path, $type = null)
+ {
+ if (!is_dir($dir = $this->locator->locate($path))) {
+ return parent::supports($path, $type) ? parent::load($path, $type) : new RouteCollection();
+ }
+
+ $collection = new RouteCollection();
+ $collection->addResource(new DirectoryResource($dir, '/\.php$/'));
+ $files = iterator_to_array(new \RecursiveIteratorIterator(
+ new \RecursiveCallbackFilterIterator(
+ new \RecursiveDirectoryIterator($dir, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS),
+ function (\SplFileInfo $current) {
+ return '.' !== substr($current->getBasename(), 0, 1);
+ }
+ ),
+ \RecursiveIteratorIterator::LEAVES_ONLY
+ ));
+ usort($files, function (\SplFileInfo $a, \SplFileInfo $b) {
+ return (string) $a > (string) $b ? 1 : -1;
+ });
+
+ foreach ($files as $file) {
+ if (!$file->isFile() || '.php' !== substr($file->getFilename(), -4)) {
+ continue;
+ }
+
+ if ($class = $this->findClass($file)) {
+ $refl = new \ReflectionClass($class);
+ if ($refl->isAbstract()) {
+ continue;
+ }
+
+ $collection->addCollection($this->loader->load($class, $type));
+ }
+ }
+
+ return $collection;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supports($resource, $type = null)
+ {
+ if ('annotation' === $type) {
+ return true;
+ }
+
+ if ($type || !is_string($resource)) {
+ return false;
+ }
+
+ try {
+ return is_dir($this->locator->locate($resource));
+ } catch (\Exception $e) {
+ return false;
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/AnnotationFileLoader.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/AnnotationFileLoader.php
new file mode 100644
index 0000000..cf9f070
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/AnnotationFileLoader.php
@@ -0,0 +1,142 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Loader;
+
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Config\Resource\FileResource;
+use Symfony\Component\Config\Loader\FileLoader;
+use Symfony\Component\Config\FileLocatorInterface;
+
+/**
+ * AnnotationFileLoader loads routing information from annotations set
+ * on a PHP class and its methods.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class AnnotationFileLoader extends FileLoader
+{
+ protected $loader;
+
+ /**
+ * @throws \RuntimeException
+ */
+ public function __construct(FileLocatorInterface $locator, AnnotationClassLoader $loader)
+ {
+ if (!function_exists('token_get_all')) {
+ throw new \RuntimeException('The Tokenizer extension is required for the routing annotation loaders.');
+ }
+
+ parent::__construct($locator);
+
+ $this->loader = $loader;
+ }
+
+ /**
+ * Loads from annotations from a file.
+ *
+ * @param string $file A PHP file path
+ * @param string|null $type The resource type
+ *
+ * @return RouteCollection A RouteCollection instance
+ *
+ * @throws \InvalidArgumentException When the file does not exist or its routes cannot be parsed
+ */
+ public function load($file, $type = null)
+ {
+ $path = $this->locator->locate($file);
+
+ $collection = new RouteCollection();
+ if ($class = $this->findClass($path)) {
+ $collection->addResource(new FileResource($path));
+ $collection->addCollection($this->loader->load($class, $type));
+ }
+ if (\PHP_VERSION_ID >= 70000) {
+ // PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098
+ gc_mem_caches();
+ }
+
+ return $collection;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supports($resource, $type = null)
+ {
+ return is_string($resource) && 'php' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'annotation' === $type);
+ }
+
+ /**
+ * Returns the full class name for the first class in the file.
+ *
+ * @param string $file A PHP file path
+ *
+ * @return string|false Full class name if found, false otherwise
+ */
+ protected function findClass($file)
+ {
+ $class = false;
+ $namespace = false;
+ $tokens = token_get_all(file_get_contents($file));
+
+ if (1 === count($tokens) && T_INLINE_HTML === $tokens[0][0]) {
+ throw new \InvalidArgumentException(sprintf('The file "%s" does not contain PHP code. Did you forgot to add the "<?php" start tag at the beginning of the file?', $file));
+ }
+
+ for ($i = 0; isset($tokens[$i]); ++$i) {
+ $token = $tokens[$i];
+
+ if (!isset($token[1])) {
+ continue;
+ }
+
+ if (true === $class && T_STRING === $token[0]) {
+ return $namespace.'\\'.$token[1];
+ }
+
+ if (true === $namespace && T_STRING === $token[0]) {
+ $namespace = $token[1];
+ while (isset($tokens[++$i][1]) && in_array($tokens[$i][0], array(T_NS_SEPARATOR, T_STRING))) {
+ $namespace .= $tokens[$i][1];
+ }
+ $token = $tokens[$i];
+ }
+
+ if (T_CLASS === $token[0]) {
+ // Skip usage of ::class constant and anonymous classes
+ $skipClassToken = false;
+ for ($j = $i - 1; $j > 0; --$j) {
+ if (!isset($tokens[$j][1])) {
+ break;
+ }
+
+ if (T_DOUBLE_COLON === $tokens[$j][0] || T_NEW === $tokens[$j][0]) {
+ $skipClassToken = true;
+ break;
+ } elseif (!in_array($tokens[$j][0], array(T_WHITESPACE, T_DOC_COMMENT, T_COMMENT))) {
+ break;
+ }
+ }
+
+ if (!$skipClassToken) {
+ $class = true;
+ }
+ }
+
+ if (T_NAMESPACE === $token[0]) {
+ $namespace = true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/ClosureLoader.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/ClosureLoader.php
new file mode 100644
index 0000000..5df9f6a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/ClosureLoader.php
@@ -0,0 +1,46 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Loader;
+
+use Symfony\Component\Config\Loader\Loader;
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * ClosureLoader loads routes from a PHP closure.
+ *
+ * The Closure must return a RouteCollection instance.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ClosureLoader extends Loader
+{
+ /**
+ * Loads a Closure.
+ *
+ * @param \Closure $closure A Closure
+ * @param string|null $type The resource type
+ *
+ * @return RouteCollection A RouteCollection instance
+ */
+ public function load($closure, $type = null)
+ {
+ return $closure();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supports($resource, $type = null)
+ {
+ return $resource instanceof \Closure && (!$type || 'closure' === $type);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/Configurator/CollectionConfigurator.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/Configurator/CollectionConfigurator.php
new file mode 100644
index 0000000..8baefdd
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/Configurator/CollectionConfigurator.php
@@ -0,0 +1,81 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Loader\Configurator;
+
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class CollectionConfigurator
+{
+ use Traits\AddTrait;
+ use Traits\RouteTrait;
+
+ private $parent;
+ private $parentConfigurator;
+
+ public function __construct(RouteCollection $parent, $name, self $parentConfigurator = null)
+ {
+ $this->parent = $parent;
+ $this->name = $name;
+ $this->collection = new RouteCollection();
+ $this->route = new Route('');
+ $this->parentConfigurator = $parentConfigurator; // for GC control
+ }
+
+ public function __destruct()
+ {
+ $this->collection->addPrefix(rtrim($this->route->getPath(), '/'));
+ $this->parent->addCollection($this->collection);
+ }
+
+ /**
+ * Adds a route.
+ *
+ * @param string $name
+ * @param string $path
+ *
+ * @return RouteConfigurator
+ */
+ final public function add($name, $path)
+ {
+ $this->collection->add($this->name.$name, $route = clone $this->route);
+
+ return new RouteConfigurator($this->collection, $route->setPath($path), $this->name, $this);
+ }
+
+ /**
+ * Creates a sub-collection.
+ *
+ * @return self
+ */
+ final public function collection($name = '')
+ {
+ return new self($this->collection, $this->name.$name, $this);
+ }
+
+ /**
+ * Sets the prefix to add to the path of all child routes.
+ *
+ * @param string $prefix
+ *
+ * @return $this
+ */
+ final public function prefix($prefix)
+ {
+ $this->route->setPath($prefix);
+
+ return $this;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/Configurator/ImportConfigurator.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/Configurator/ImportConfigurator.php
new file mode 100644
index 0000000..d0a3c37
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/Configurator/ImportConfigurator.php
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Loader\Configurator;
+
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class ImportConfigurator
+{
+ use Traits\RouteTrait;
+
+ private $parent;
+
+ public function __construct(RouteCollection $parent, RouteCollection $route)
+ {
+ $this->parent = $parent;
+ $this->route = $route;
+ }
+
+ public function __destruct()
+ {
+ $this->parent->addCollection($this->route);
+ }
+
+ /**
+ * Sets the prefix to add to the path of all child routes.
+ *
+ * @param string $prefix
+ *
+ * @return $this
+ */
+ final public function prefix($prefix)
+ {
+ $this->route->addPrefix($prefix);
+
+ return $this;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/Configurator/RouteConfigurator.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/Configurator/RouteConfigurator.php
new file mode 100644
index 0000000..6422bbf
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/Configurator/RouteConfigurator.php
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Loader\Configurator;
+
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class RouteConfigurator
+{
+ use Traits\AddTrait;
+ use Traits\RouteTrait;
+
+ private $parentConfigurator;
+
+ public function __construct(RouteCollection $collection, Route $route, $name = '', CollectionConfigurator $parentConfigurator = null)
+ {
+ $this->collection = $collection;
+ $this->route = $route;
+ $this->name = $name;
+ $this->parentConfigurator = $parentConfigurator; // for GC control
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/Configurator/RoutingConfigurator.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/Configurator/RoutingConfigurator.php
new file mode 100644
index 0000000..d992cef
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/Configurator/RoutingConfigurator.php
@@ -0,0 +1,62 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Loader\Configurator;
+
+use Symfony\Component\Routing\Loader\PhpFileLoader;
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class RoutingConfigurator
+{
+ use Traits\AddTrait;
+
+ private $loader;
+ private $path;
+ private $file;
+
+ public function __construct(RouteCollection $collection, PhpFileLoader $loader, $path, $file)
+ {
+ $this->collection = $collection;
+ $this->loader = $loader;
+ $this->path = $path;
+ $this->file = $file;
+ }
+
+ /**
+ * @return ImportConfigurator
+ */
+ final public function import($resource, $type = null, $ignoreErrors = false)
+ {
+ $this->loader->setCurrentDir(dirname($this->path));
+ $imported = $this->loader->import($resource, $type, $ignoreErrors, $this->file);
+ if (!is_array($imported)) {
+ return new ImportConfigurator($this->collection, $imported);
+ }
+
+ $mergedCollection = new RouteCollection();
+ foreach ($imported as $subCollection) {
+ $mergedCollection->addCollection($subCollection);
+ }
+
+ return new ImportConfigurator($this->collection, $mergedCollection);
+ }
+
+ /**
+ * @return CollectionConfigurator
+ */
+ final public function collection($name = '')
+ {
+ return new CollectionConfigurator($this->collection, $name);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/Configurator/Traits/AddTrait.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/Configurator/Traits/AddTrait.php
new file mode 100644
index 0000000..e8b8fa2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/Configurator/Traits/AddTrait.php
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Loader\Configurator\Traits;
+
+use Symfony\Component\Routing\Loader\Configurator\RouteConfigurator;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+
+trait AddTrait
+{
+ /**
+ * @var RouteCollection
+ */
+ private $collection;
+
+ private $name = '';
+
+ /**
+ * Adds a route.
+ *
+ * @param string $name
+ * @param string $path
+ *
+ * @return RouteConfigurator
+ */
+ final public function add($name, $path)
+ {
+ $parentConfigurator = $this instanceof RouteConfigurator ? $this->parentConfigurator : null;
+ $this->collection->add($this->name.$name, $route = new Route($path));
+
+ return new RouteConfigurator($this->collection, $route, '', $parentConfigurator);
+ }
+
+ /**
+ * Adds a route.
+ *
+ * @param string $name
+ * @param string $path
+ *
+ * @return RouteConfigurator
+ */
+ final public function __invoke($name, $path)
+ {
+ return $this->add($name, $path);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/Configurator/Traits/RouteTrait.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/Configurator/Traits/RouteTrait.php
new file mode 100644
index 0000000..4d2e255
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/Configurator/Traits/RouteTrait.php
@@ -0,0 +1,131 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Loader\Configurator\Traits;
+
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+
+trait RouteTrait
+{
+ /**
+ * @var RouteCollection|Route
+ */
+ private $route;
+
+ /**
+ * Adds defaults.
+ *
+ * @return $this
+ */
+ final public function defaults(array $defaults)
+ {
+ $this->route->addDefaults($defaults);
+
+ return $this;
+ }
+
+ /**
+ * Adds requirements.
+ *
+ * @return $this
+ */
+ final public function requirements(array $requirements)
+ {
+ $this->route->addRequirements($requirements);
+
+ return $this;
+ }
+
+ /**
+ * Adds options.
+ *
+ * @return $this
+ */
+ final public function options(array $options)
+ {
+ $this->route->addOptions($options);
+
+ return $this;
+ }
+
+ /**
+ * Sets the condition.
+ *
+ * @param string $condition
+ *
+ * @return $this
+ */
+ final public function condition($condition)
+ {
+ $this->route->setCondition($condition);
+
+ return $this;
+ }
+
+ /**
+ * Sets the pattern for the host.
+ *
+ * @param string $pattern
+ *
+ * @return $this
+ */
+ final public function host($pattern)
+ {
+ $this->route->setHost($pattern);
+
+ return $this;
+ }
+
+ /**
+ * Sets the schemes (e.g. 'https') this route is restricted to.
+ * So an empty array means that any scheme is allowed.
+ *
+ * @param string[] $schemes
+ *
+ * @return $this
+ */
+ final public function schemes(array $schemes)
+ {
+ $this->route->setSchemes($schemes);
+
+ return $this;
+ }
+
+ /**
+ * Sets the HTTP methods (e.g. 'POST') this route is restricted to.
+ * So an empty array means that any method is allowed.
+ *
+ * @param string[] $methods
+ *
+ * @return $this
+ */
+ final public function methods(array $methods)
+ {
+ $this->route->setMethods($methods);
+
+ return $this;
+ }
+
+ /**
+ * Adds the "_controller" entry to defaults.
+ *
+ * @param callable|string $controller a callable or parseable pseudo-callable
+ *
+ * @return $this
+ */
+ final public function controller($controller)
+ {
+ $this->route->addDefaults(array('_controller' => $controller));
+
+ return $this;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/DependencyInjection/ServiceRouterLoader.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/DependencyInjection/ServiceRouterLoader.php
new file mode 100644
index 0000000..6c16216
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/DependencyInjection/ServiceRouterLoader.php
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Loader\DependencyInjection;
+
+use Psr\Container\ContainerInterface;
+use Symfony\Component\Routing\Loader\ObjectRouteLoader;
+
+/**
+ * A route loader that executes a service to load the routes.
+ *
+ * This depends on the DependencyInjection component.
+ *
+ * @author Ryan Weaver <ryan@knpuniversity.com>
+ */
+class ServiceRouterLoader extends ObjectRouteLoader
+{
+ /**
+ * @var ContainerInterface
+ */
+ private $container;
+
+ public function __construct(ContainerInterface $container)
+ {
+ $this->container = $container;
+ }
+
+ protected function getServiceObject($id)
+ {
+ return $this->container->get($id);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/DirectoryLoader.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/DirectoryLoader.php
new file mode 100644
index 0000000..4bb5b31
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/DirectoryLoader.php
@@ -0,0 +1,58 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Loader;
+
+use Symfony\Component\Config\Loader\FileLoader;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Config\Resource\DirectoryResource;
+
+class DirectoryLoader extends FileLoader
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function load($file, $type = null)
+ {
+ $path = $this->locator->locate($file);
+
+ $collection = new RouteCollection();
+ $collection->addResource(new DirectoryResource($path));
+
+ foreach (scandir($path) as $dir) {
+ if ('.' !== $dir[0]) {
+ $this->setCurrentDir($path);
+ $subPath = $path.'/'.$dir;
+ $subType = null;
+
+ if (is_dir($subPath)) {
+ $subPath .= '/';
+ $subType = 'directory';
+ }
+
+ $subCollection = $this->import($subPath, $subType, false, $path);
+ $collection->addCollection($subCollection);
+ }
+ }
+
+ return $collection;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supports($resource, $type = null)
+ {
+ // only when type is forced to directory, not to conflict with AnnotationLoader
+
+ return 'directory' === $type;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/GlobFileLoader.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/GlobFileLoader.php
new file mode 100644
index 0000000..03ee341
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/GlobFileLoader.php
@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Loader;
+
+use Symfony\Component\Config\Loader\FileLoader;
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * GlobFileLoader loads files from a glob pattern.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class GlobFileLoader extends FileLoader
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function load($resource, $type = null)
+ {
+ $collection = new RouteCollection();
+
+ foreach ($this->glob($resource, false, $globResource) as $path => $info) {
+ $collection->addCollection($this->import($path));
+ }
+
+ $collection->addResource($globResource);
+
+ return $collection;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supports($resource, $type = null)
+ {
+ return 'glob' === $type;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/ObjectRouteLoader.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/ObjectRouteLoader.php
new file mode 100644
index 0000000..0899a81
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/ObjectRouteLoader.php
@@ -0,0 +1,95 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Loader;
+
+use Symfony\Component\Config\Loader\Loader;
+use Symfony\Component\Config\Resource\FileResource;
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * A route loader that calls a method on an object to load the routes.
+ *
+ * @author Ryan Weaver <ryan@knpuniversity.com>
+ */
+abstract class ObjectRouteLoader extends Loader
+{
+ /**
+ * Returns the object that the method will be called on to load routes.
+ *
+ * For example, if your application uses a service container,
+ * the $id may be a service id.
+ *
+ * @param string $id
+ *
+ * @return object
+ */
+ abstract protected function getServiceObject($id);
+
+ /**
+ * Calls the service that will load the routes.
+ *
+ * @param mixed $resource Some value that will resolve to a callable
+ * @param string|null $type The resource type
+ *
+ * @return RouteCollection
+ */
+ public function load($resource, $type = null)
+ {
+ $parts = explode(':', $resource);
+ if (2 != count($parts)) {
+ throw new \InvalidArgumentException(sprintf('Invalid resource "%s" passed to the "service" route loader: use the format "service_name:methodName"', $resource));
+ }
+
+ $serviceString = $parts[0];
+ $method = $parts[1];
+
+ $loaderObject = $this->getServiceObject($serviceString);
+
+ if (!is_object($loaderObject)) {
+ throw new \LogicException(sprintf('%s:getServiceObject() must return an object: %s returned', get_class($this), gettype($loaderObject)));
+ }
+
+ if (!method_exists($loaderObject, $method)) {
+ throw new \BadMethodCallException(sprintf('Method "%s" not found on "%s" when importing routing resource "%s"', $method, get_class($loaderObject), $resource));
+ }
+
+ $routeCollection = call_user_func(array($loaderObject, $method), $this);
+
+ if (!$routeCollection instanceof RouteCollection) {
+ $type = is_object($routeCollection) ? get_class($routeCollection) : gettype($routeCollection);
+
+ throw new \LogicException(sprintf('The %s::%s method must return a RouteCollection: %s returned', get_class($loaderObject), $method, $type));
+ }
+
+ // make the service file tracked so that if it changes, the cache rebuilds
+ $this->addClassResource(new \ReflectionClass($loaderObject), $routeCollection);
+
+ return $routeCollection;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supports($resource, $type = null)
+ {
+ return 'service' === $type;
+ }
+
+ private function addClassResource(\ReflectionClass $class, RouteCollection $collection)
+ {
+ do {
+ if (is_file($class->getFileName())) {
+ $collection->addResource(new FileResource($class->getFileName()));
+ }
+ } while ($class = $class->getParentClass());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/PhpFileLoader.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/PhpFileLoader.php
new file mode 100644
index 0000000..3fcd692
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/PhpFileLoader.php
@@ -0,0 +1,75 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Loader;
+
+use Symfony\Component\Config\Loader\FileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * PhpFileLoader loads routes from a PHP file.
+ *
+ * The file must return a RouteCollection instance.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class PhpFileLoader extends FileLoader
+{
+ /**
+ * Loads a PHP file.
+ *
+ * @param string $file A PHP file path
+ * @param string|null $type The resource type
+ *
+ * @return RouteCollection A RouteCollection instance
+ */
+ public function load($file, $type = null)
+ {
+ $path = $this->locator->locate($file);
+ $this->setCurrentDir(dirname($path));
+
+ // the closure forbids access to the private scope in the included file
+ $loader = $this;
+ $load = \Closure::bind(function ($file) use ($loader) {
+ return include $file;
+ }, null, ProtectedPhpFileLoader::class);
+
+ $result = $load($path);
+
+ if ($result instanceof \Closure) {
+ $collection = new RouteCollection();
+ $result(new RoutingConfigurator($collection, $this, $path, $file), $this);
+ } else {
+ $collection = $result;
+ }
+
+ $collection->addResource(new FileResource($path));
+
+ return $collection;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supports($resource, $type = null)
+ {
+ return is_string($resource) && 'php' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'php' === $type);
+ }
+}
+
+/**
+ * @internal
+ */
+final class ProtectedPhpFileLoader extends PhpFileLoader
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/XmlFileLoader.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/XmlFileLoader.php
new file mode 100644
index 0000000..f3f6605
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/XmlFileLoader.php
@@ -0,0 +1,359 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Loader;
+
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Config\Resource\FileResource;
+use Symfony\Component\Config\Loader\FileLoader;
+use Symfony\Component\Config\Util\XmlUtils;
+
+/**
+ * XmlFileLoader loads XML routing files.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Tobias Schultze <http://tobion.de>
+ */
+class XmlFileLoader extends FileLoader
+{
+ const NAMESPACE_URI = 'http://symfony.com/schema/routing';
+ const SCHEME_PATH = '/schema/routing/routing-1.0.xsd';
+
+ /**
+ * Loads an XML file.
+ *
+ * @param string $file An XML file path
+ * @param string|null $type The resource type
+ *
+ * @return RouteCollection A RouteCollection instance
+ *
+ * @throws \InvalidArgumentException when the file cannot be loaded or when the XML cannot be
+ * parsed because it does not validate against the scheme
+ */
+ public function load($file, $type = null)
+ {
+ $path = $this->locator->locate($file);
+
+ $xml = $this->loadFile($path);
+
+ $collection = new RouteCollection();
+ $collection->addResource(new FileResource($path));
+
+ // process routes and imports
+ foreach ($xml->documentElement->childNodes as $node) {
+ if (!$node instanceof \DOMElement) {
+ continue;
+ }
+
+ $this->parseNode($collection, $node, $path, $file);
+ }
+
+ return $collection;
+ }
+
+ /**
+ * Parses a node from a loaded XML file.
+ *
+ * @param RouteCollection $collection Collection to associate with the node
+ * @param \DOMElement $node Element to parse
+ * @param string $path Full path of the XML file being processed
+ * @param string $file Loaded file name
+ *
+ * @throws \InvalidArgumentException When the XML is invalid
+ */
+ protected function parseNode(RouteCollection $collection, \DOMElement $node, $path, $file)
+ {
+ if (self::NAMESPACE_URI !== $node->namespaceURI) {
+ return;
+ }
+
+ switch ($node->localName) {
+ case 'route':
+ $this->parseRoute($collection, $node, $path);
+ break;
+ case 'import':
+ $this->parseImport($collection, $node, $path, $file);
+ break;
+ default:
+ throw new \InvalidArgumentException(sprintf('Unknown tag "%s" used in file "%s". Expected "route" or "import".', $node->localName, $path));
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supports($resource, $type = null)
+ {
+ return is_string($resource) && 'xml' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'xml' === $type);
+ }
+
+ /**
+ * Parses a route and adds it to the RouteCollection.
+ *
+ * @param RouteCollection $collection RouteCollection instance
+ * @param \DOMElement $node Element to parse that represents a Route
+ * @param string $path Full path of the XML file being processed
+ *
+ * @throws \InvalidArgumentException When the XML is invalid
+ */
+ protected function parseRoute(RouteCollection $collection, \DOMElement $node, $path)
+ {
+ if ('' === ($id = $node->getAttribute('id')) || !$node->hasAttribute('path')) {
+ throw new \InvalidArgumentException(sprintf('The <route> element in file "%s" must have an "id" and a "path" attribute.', $path));
+ }
+
+ $schemes = preg_split('/[\s,\|]++/', $node->getAttribute('schemes'), -1, PREG_SPLIT_NO_EMPTY);
+ $methods = preg_split('/[\s,\|]++/', $node->getAttribute('methods'), -1, PREG_SPLIT_NO_EMPTY);
+
+ list($defaults, $requirements, $options, $condition) = $this->parseConfigs($node, $path);
+
+ $route = new Route($node->getAttribute('path'), $defaults, $requirements, $options, $node->getAttribute('host'), $schemes, $methods, $condition);
+ $collection->add($id, $route);
+ }
+
+ /**
+ * Parses an import and adds the routes in the resource to the RouteCollection.
+ *
+ * @param RouteCollection $collection RouteCollection instance
+ * @param \DOMElement $node Element to parse that represents a Route
+ * @param string $path Full path of the XML file being processed
+ * @param string $file Loaded file name
+ *
+ * @throws \InvalidArgumentException When the XML is invalid
+ */
+ protected function parseImport(RouteCollection $collection, \DOMElement $node, $path, $file)
+ {
+ if ('' === $resource = $node->getAttribute('resource')) {
+ throw new \InvalidArgumentException(sprintf('The <import> element in file "%s" must have a "resource" attribute.', $path));
+ }
+
+ $type = $node->getAttribute('type');
+ $prefix = $node->getAttribute('prefix');
+ $host = $node->hasAttribute('host') ? $node->getAttribute('host') : null;
+ $schemes = $node->hasAttribute('schemes') ? preg_split('/[\s,\|]++/', $node->getAttribute('schemes'), -1, PREG_SPLIT_NO_EMPTY) : null;
+ $methods = $node->hasAttribute('methods') ? preg_split('/[\s,\|]++/', $node->getAttribute('methods'), -1, PREG_SPLIT_NO_EMPTY) : null;
+
+ list($defaults, $requirements, $options, $condition) = $this->parseConfigs($node, $path);
+
+ $this->setCurrentDir(dirname($path));
+
+ $imported = $this->import($resource, ('' !== $type ? $type : null), false, $file);
+
+ if (!is_array($imported)) {
+ $imported = array($imported);
+ }
+
+ foreach ($imported as $subCollection) {
+ /* @var $subCollection RouteCollection */
+ $subCollection->addPrefix($prefix);
+ if (null !== $host) {
+ $subCollection->setHost($host);
+ }
+ if (null !== $condition) {
+ $subCollection->setCondition($condition);
+ }
+ if (null !== $schemes) {
+ $subCollection->setSchemes($schemes);
+ }
+ if (null !== $methods) {
+ $subCollection->setMethods($methods);
+ }
+ $subCollection->addDefaults($defaults);
+ $subCollection->addRequirements($requirements);
+ $subCollection->addOptions($options);
+
+ $collection->addCollection($subCollection);
+ }
+ }
+
+ /**
+ * Loads an XML file.
+ *
+ * @param string $file An XML file path
+ *
+ * @return \DOMDocument
+ *
+ * @throws \InvalidArgumentException When loading of XML file fails because of syntax errors
+ * or when the XML structure is not as expected by the scheme -
+ * see validate()
+ */
+ protected function loadFile($file)
+ {
+ return XmlUtils::loadFile($file, __DIR__.static::SCHEME_PATH);
+ }
+
+ /**
+ * Parses the config elements (default, requirement, option).
+ *
+ * @param \DOMElement $node Element to parse that contains the configs
+ * @param string $path Full path of the XML file being processed
+ *
+ * @return array An array with the defaults as first item, requirements as second and options as third
+ *
+ * @throws \InvalidArgumentException When the XML is invalid
+ */
+ private function parseConfigs(\DOMElement $node, $path)
+ {
+ $defaults = array();
+ $requirements = array();
+ $options = array();
+ $condition = null;
+
+ foreach ($node->getElementsByTagNameNS(self::NAMESPACE_URI, '*') as $n) {
+ if ($node !== $n->parentNode) {
+ continue;
+ }
+
+ switch ($n->localName) {
+ case 'default':
+ if ($this->isElementValueNull($n)) {
+ $defaults[$n->getAttribute('key')] = null;
+ } else {
+ $defaults[$n->getAttribute('key')] = $this->parseDefaultsConfig($n, $path);
+ }
+
+ break;
+ case 'requirement':
+ $requirements[$n->getAttribute('key')] = trim($n->textContent);
+ break;
+ case 'option':
+ $options[$n->getAttribute('key')] = trim($n->textContent);
+ break;
+ case 'condition':
+ $condition = trim($n->textContent);
+ break;
+ default:
+ throw new \InvalidArgumentException(sprintf('Unknown tag "%s" used in file "%s". Expected "default", "requirement", "option" or "condition".', $n->localName, $path));
+ }
+ }
+
+ if ($controller = $node->getAttribute('controller')) {
+ if (isset($defaults['_controller'])) {
+ $name = $node->hasAttribute('id') ? sprintf('"%s"', $node->getAttribute('id')) : sprintf('the "%s" tag', $node->tagName);
+
+ throw new \InvalidArgumentException(sprintf('The routing file "%s" must not specify both the "controller" attribute and the defaults key "_controller" for %s.', $path, $name));
+ }
+
+ $defaults['_controller'] = $controller;
+ }
+
+ return array($defaults, $requirements, $options, $condition);
+ }
+
+ /**
+ * Parses the "default" elements.
+ *
+ * @param \DOMElement $element The "default" element to parse
+ * @param string $path Full path of the XML file being processed
+ *
+ * @return array|bool|float|int|string|null The parsed value of the "default" element
+ */
+ private function parseDefaultsConfig(\DOMElement $element, $path)
+ {
+ if ($this->isElementValueNull($element)) {
+ return;
+ }
+
+ // Check for existing element nodes in the default element. There can
+ // only be a single element inside a default element. So this element
+ // (if one was found) can safely be returned.
+ foreach ($element->childNodes as $child) {
+ if (!$child instanceof \DOMElement) {
+ continue;
+ }
+
+ if (self::NAMESPACE_URI !== $child->namespaceURI) {
+ continue;
+ }
+
+ return $this->parseDefaultNode($child, $path);
+ }
+
+ // If the default element doesn't contain a nested "bool", "int", "float",
+ // "string", "list", or "map" element, the element contents will be treated
+ // as the string value of the associated default option.
+ return trim($element->textContent);
+ }
+
+ /**
+ * Recursively parses the value of a "default" element.
+ *
+ * @param \DOMElement $node The node value
+ * @param string $path Full path of the XML file being processed
+ *
+ * @return array|bool|float|int|string The parsed value
+ *
+ * @throws \InvalidArgumentException when the XML is invalid
+ */
+ private function parseDefaultNode(\DOMElement $node, $path)
+ {
+ if ($this->isElementValueNull($node)) {
+ return;
+ }
+
+ switch ($node->localName) {
+ case 'bool':
+ return 'true' === trim($node->nodeValue) || '1' === trim($node->nodeValue);
+ case 'int':
+ return (int) trim($node->nodeValue);
+ case 'float':
+ return (float) trim($node->nodeValue);
+ case 'string':
+ return trim($node->nodeValue);
+ case 'list':
+ $list = array();
+
+ foreach ($node->childNodes as $element) {
+ if (!$element instanceof \DOMElement) {
+ continue;
+ }
+
+ if (self::NAMESPACE_URI !== $element->namespaceURI) {
+ continue;
+ }
+
+ $list[] = $this->parseDefaultNode($element, $path);
+ }
+
+ return $list;
+ case 'map':
+ $map = array();
+
+ foreach ($node->childNodes as $element) {
+ if (!$element instanceof \DOMElement) {
+ continue;
+ }
+
+ if (self::NAMESPACE_URI !== $element->namespaceURI) {
+ continue;
+ }
+
+ $map[$element->getAttribute('key')] = $this->parseDefaultNode($element, $path);
+ }
+
+ return $map;
+ default:
+ throw new \InvalidArgumentException(sprintf('Unknown tag "%s" used in file "%s". Expected "bool", "int", "float", "string", "list", or "map".', $node->localName, $path));
+ }
+ }
+
+ private function isElementValueNull(\DOMElement $element)
+ {
+ $namespaceUri = 'http://www.w3.org/2001/XMLSchema-instance';
+
+ if (!$element->hasAttributeNS($namespaceUri, 'nil')) {
+ return false;
+ }
+
+ return 'true' === $element->getAttributeNS($namespaceUri, 'nil') || '1' === $element->getAttributeNS($namespaceUri, 'nil');
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/YamlFileLoader.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/YamlFileLoader.php
new file mode 100644
index 0000000..f59f909
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/YamlFileLoader.php
@@ -0,0 +1,233 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Loader;
+
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Config\Resource\FileResource;
+use Symfony\Component\Yaml\Exception\ParseException;
+use Symfony\Component\Yaml\Parser as YamlParser;
+use Symfony\Component\Config\Loader\FileLoader;
+
+/**
+ * YamlFileLoader loads Yaml routing files.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Tobias Schultze <http://tobion.de>
+ */
+class YamlFileLoader extends FileLoader
+{
+ private static $availableKeys = array(
+ 'resource', 'type', 'prefix', 'path', 'host', 'schemes', 'methods', 'defaults', 'requirements', 'options', 'condition', 'controller',
+ );
+ private $yamlParser;
+
+ /**
+ * Loads a Yaml file.
+ *
+ * @param string $file A Yaml file path
+ * @param string|null $type The resource type
+ *
+ * @return RouteCollection A RouteCollection instance
+ *
+ * @throws \InvalidArgumentException When a route can't be parsed because YAML is invalid
+ */
+ public function load($file, $type = null)
+ {
+ $path = $this->locator->locate($file);
+
+ if (!stream_is_local($path)) {
+ throw new \InvalidArgumentException(sprintf('This is not a local file "%s".', $path));
+ }
+
+ if (!file_exists($path)) {
+ throw new \InvalidArgumentException(sprintf('File "%s" not found.', $path));
+ }
+
+ if (null === $this->yamlParser) {
+ $this->yamlParser = new YamlParser();
+ }
+
+ $prevErrorHandler = set_error_handler(function ($level, $message, $script, $line) use ($file, &$prevErrorHandler) {
+ $message = E_USER_DEPRECATED === $level ? preg_replace('/ on line \d+/', ' in "'.$file.'"$0', $message) : $message;
+
+ return $prevErrorHandler ? $prevErrorHandler($level, $message, $script, $line) : false;
+ });
+
+ try {
+ $parsedConfig = $this->yamlParser->parseFile($path);
+ } catch (ParseException $e) {
+ throw new \InvalidArgumentException(sprintf('The file "%s" does not contain valid YAML.', $path), 0, $e);
+ } finally {
+ restore_error_handler();
+ }
+
+ $collection = new RouteCollection();
+ $collection->addResource(new FileResource($path));
+
+ // empty file
+ if (null === $parsedConfig) {
+ return $collection;
+ }
+
+ // not an array
+ if (!is_array($parsedConfig)) {
+ throw new \InvalidArgumentException(sprintf('The file "%s" must contain a YAML array.', $path));
+ }
+
+ foreach ($parsedConfig as $name => $config) {
+ $this->validate($config, $name, $path);
+
+ if (isset($config['resource'])) {
+ $this->parseImport($collection, $config, $path, $file);
+ } else {
+ $this->parseRoute($collection, $name, $config, $path);
+ }
+ }
+
+ return $collection;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supports($resource, $type = null)
+ {
+ return is_string($resource) && in_array(pathinfo($resource, PATHINFO_EXTENSION), array('yml', 'yaml'), true) && (!$type || 'yaml' === $type);
+ }
+
+ /**
+ * Parses a route and adds it to the RouteCollection.
+ *
+ * @param RouteCollection $collection A RouteCollection instance
+ * @param string $name Route name
+ * @param array $config Route definition
+ * @param string $path Full path of the YAML file being processed
+ */
+ protected function parseRoute(RouteCollection $collection, $name, array $config, $path)
+ {
+ $defaults = isset($config['defaults']) ? $config['defaults'] : array();
+ $requirements = isset($config['requirements']) ? $config['requirements'] : array();
+ $options = isset($config['options']) ? $config['options'] : array();
+ $host = isset($config['host']) ? $config['host'] : '';
+ $schemes = isset($config['schemes']) ? $config['schemes'] : array();
+ $methods = isset($config['methods']) ? $config['methods'] : array();
+ $condition = isset($config['condition']) ? $config['condition'] : null;
+
+ if (isset($config['controller'])) {
+ $defaults['_controller'] = $config['controller'];
+ }
+
+ $route = new Route($config['path'], $defaults, $requirements, $options, $host, $schemes, $methods, $condition);
+
+ $collection->add($name, $route);
+ }
+
+ /**
+ * Parses an import and adds the routes in the resource to the RouteCollection.
+ *
+ * @param RouteCollection $collection A RouteCollection instance
+ * @param array $config Route definition
+ * @param string $path Full path of the YAML file being processed
+ * @param string $file Loaded file name
+ */
+ protected function parseImport(RouteCollection $collection, array $config, $path, $file)
+ {
+ $type = isset($config['type']) ? $config['type'] : null;
+ $prefix = isset($config['prefix']) ? $config['prefix'] : '';
+ $defaults = isset($config['defaults']) ? $config['defaults'] : array();
+ $requirements = isset($config['requirements']) ? $config['requirements'] : array();
+ $options = isset($config['options']) ? $config['options'] : array();
+ $host = isset($config['host']) ? $config['host'] : null;
+ $condition = isset($config['condition']) ? $config['condition'] : null;
+ $schemes = isset($config['schemes']) ? $config['schemes'] : null;
+ $methods = isset($config['methods']) ? $config['methods'] : null;
+
+ if (isset($config['controller'])) {
+ $defaults['_controller'] = $config['controller'];
+ }
+
+ $this->setCurrentDir(dirname($path));
+
+ $imported = $this->import($config['resource'], $type, false, $file);
+
+ if (!is_array($imported)) {
+ $imported = array($imported);
+ }
+
+ foreach ($imported as $subCollection) {
+ /* @var $subCollection RouteCollection */
+ $subCollection->addPrefix($prefix);
+ if (null !== $host) {
+ $subCollection->setHost($host);
+ }
+ if (null !== $condition) {
+ $subCollection->setCondition($condition);
+ }
+ if (null !== $schemes) {
+ $subCollection->setSchemes($schemes);
+ }
+ if (null !== $methods) {
+ $subCollection->setMethods($methods);
+ }
+ $subCollection->addDefaults($defaults);
+ $subCollection->addRequirements($requirements);
+ $subCollection->addOptions($options);
+
+ $collection->addCollection($subCollection);
+ }
+ }
+
+ /**
+ * Validates the route configuration.
+ *
+ * @param array $config A resource config
+ * @param string $name The config key
+ * @param string $path The loaded file path
+ *
+ * @throws \InvalidArgumentException If one of the provided config keys is not supported,
+ * something is missing or the combination is nonsense
+ */
+ protected function validate($config, $name, $path)
+ {
+ if (!is_array($config)) {
+ throw new \InvalidArgumentException(sprintf('The definition of "%s" in "%s" must be a YAML array.', $name, $path));
+ }
+ if ($extraKeys = array_diff(array_keys($config), self::$availableKeys)) {
+ throw new \InvalidArgumentException(sprintf(
+ 'The routing file "%s" contains unsupported keys for "%s": "%s". Expected one of: "%s".',
+ $path, $name, implode('", "', $extraKeys), implode('", "', self::$availableKeys)
+ ));
+ }
+ if (isset($config['resource']) && isset($config['path'])) {
+ throw new \InvalidArgumentException(sprintf(
+ 'The routing file "%s" must not specify both the "resource" key and the "path" key for "%s". Choose between an import and a route definition.',
+ $path, $name
+ ));
+ }
+ if (!isset($config['resource']) && isset($config['type'])) {
+ throw new \InvalidArgumentException(sprintf(
+ 'The "type" key for the route definition "%s" in "%s" is unsupported. It is only available for imports in combination with the "resource" key.',
+ $name, $path
+ ));
+ }
+ if (!isset($config['resource']) && !isset($config['path'])) {
+ throw new \InvalidArgumentException(sprintf(
+ 'You must define a "path" for the route "%s" in file "%s".',
+ $name, $path
+ ));
+ }
+ if (isset($config['controller']) && isset($config['defaults']['_controller'])) {
+ throw new \InvalidArgumentException(sprintf('The routing file "%s" must not specify both the "controller" key and the defaults key "_controller" for "%s".', $path, $name));
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/schema/routing/routing-1.0.xsd b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/schema/routing/routing-1.0.xsd
new file mode 100644
index 0000000..a97111a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Loader/schema/routing/routing-1.0.xsd
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<xsd:schema xmlns="http://symfony.com/schema/routing"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://symfony.com/schema/routing"
+ elementFormDefault="qualified">
+
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Symfony XML Routing Schema, version 1.0
+ Authors: Fabien Potencier, Tobias Schultze
+
+ This scheme defines the elements and attributes that can be used to define
+ routes. A route maps an HTTP request to a set of configuration variables.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:element name="routes" type="routes" />
+
+ <xsd:complexType name="routes">
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
+ <xsd:element name="import" type="import" />
+ <xsd:element name="route" type="route" />
+ </xsd:choice>
+ </xsd:complexType>
+
+ <xsd:group name="configs">
+ <xsd:choice>
+ <xsd:element name="default" nillable="true" type="default" />
+ <xsd:element name="requirement" type="element" />
+ <xsd:element name="option" type="element" />
+ <xsd:element name="condition" type="xsd:string" />
+ </xsd:choice>
+ </xsd:group>
+
+ <xsd:complexType name="route">
+ <xsd:group ref="configs" minOccurs="0" maxOccurs="unbounded" />
+
+ <xsd:attribute name="id" type="xsd:string" use="required" />
+ <xsd:attribute name="path" type="xsd:string" use="required" />
+ <xsd:attribute name="host" type="xsd:string" />
+ <xsd:attribute name="schemes" type="xsd:string" />
+ <xsd:attribute name="methods" type="xsd:string" />
+ <xsd:attribute name="controller" type="xsd:string" />
+ </xsd:complexType>
+
+ <xsd:complexType name="import">
+ <xsd:group ref="configs" minOccurs="0" maxOccurs="unbounded" />
+
+ <xsd:attribute name="resource" type="xsd:string" use="required" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="prefix" type="xsd:string" />
+ <xsd:attribute name="host" type="xsd:string" />
+ <xsd:attribute name="schemes" type="xsd:string" />
+ <xsd:attribute name="methods" type="xsd:string" />
+ <xsd:attribute name="controller" type="xsd:string" />
+ </xsd:complexType>
+
+ <xsd:complexType name="default" mixed="true">
+ <xsd:choice minOccurs="0" maxOccurs="1">
+ <xsd:element name="bool" type="xsd:boolean" />
+ <xsd:element name="int" type="xsd:integer" />
+ <xsd:element name="float" type="xsd:float" />
+ <xsd:element name="string" type="xsd:string" />
+ <xsd:element name="list" type="list" />
+ <xsd:element name="map" type="map" />
+ </xsd:choice>
+ <xsd:attribute name="key" type="xsd:string" use="required" />
+ </xsd:complexType>
+
+ <xsd:complexType name="element">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="key" type="xsd:string" use="required" />
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="list">
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
+ <xsd:element name="bool" nillable="true" type="xsd:boolean" />
+ <xsd:element name="int" nillable="true" type="xsd:integer" />
+ <xsd:element name="float" nillable="true" type="xsd:float" />
+ <xsd:element name="string" nillable="true" type="xsd:string" />
+ <xsd:element name="list" nillable="true" type="list" />
+ <xsd:element name="map" nillable="true" type="map" />
+ </xsd:choice>
+ </xsd:complexType>
+
+ <xsd:complexType name="map">
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
+ <xsd:element name="bool" nillable="true" type="map-bool-entry" />
+ <xsd:element name="int" nillable="true" type="map-int-entry" />
+ <xsd:element name="float" nillable="true" type="map-float-entry" />
+ <xsd:element name="string" nillable="true" type="map-string-entry" />
+ <xsd:element name="list" nillable="true" type="map-list-entry" />
+ <xsd:element name="map" nillable="true" type="map-map-entry" />
+ </xsd:choice>
+ </xsd:complexType>
+
+ <xsd:complexType name="map-bool-entry">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:boolean">
+ <xsd:attribute name="key" type="xsd:string" use="required" />
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="map-int-entry">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:integer">
+ <xsd:attribute name="key" type="xsd:string" use="required" />
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="map-float-entry">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:float">
+ <xsd:attribute name="key" type="xsd:string" use="required" />
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="map-string-entry">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="key" type="xsd:string" use="required" />
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="map-list-entry">
+ <xsd:complexContent>
+ <xsd:extension base="list">
+ <xsd:attribute name="key" type="xsd:string" use="required" />
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="map-map-entry">
+ <xsd:complexContent>
+ <xsd:extension base="map">
+ <xsd:attribute name="key" type="xsd:string" use="required" />
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+</xsd:schema>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/Dumper/DumperCollection.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/Dumper/DumperCollection.php
new file mode 100644
index 0000000..6916297
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/Dumper/DumperCollection.php
@@ -0,0 +1,159 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Matcher\Dumper;
+
+/**
+ * Collection of routes.
+ *
+ * @author Arnaud Le Blanc <arnaud.lb@gmail.com>
+ *
+ * @internal
+ */
+class DumperCollection implements \IteratorAggregate
+{
+ /**
+ * @var DumperCollection|null
+ */
+ private $parent;
+
+ /**
+ * @var DumperCollection[]|DumperRoute[]
+ */
+ private $children = array();
+
+ /**
+ * @var array
+ */
+ private $attributes = array();
+
+ /**
+ * Returns the children routes and collections.
+ *
+ * @return self[]|DumperRoute[]
+ */
+ public function all()
+ {
+ return $this->children;
+ }
+
+ /**
+ * Adds a route or collection.
+ *
+ * @param DumperRoute|DumperCollection The route or collection
+ */
+ public function add($child)
+ {
+ if ($child instanceof self) {
+ $child->setParent($this);
+ }
+ $this->children[] = $child;
+ }
+
+ /**
+ * Sets children.
+ *
+ * @param array $children The children
+ */
+ public function setAll(array $children)
+ {
+ foreach ($children as $child) {
+ if ($child instanceof self) {
+ $child->setParent($this);
+ }
+ }
+ $this->children = $children;
+ }
+
+ /**
+ * Returns an iterator over the children.
+ *
+ * @return \Iterator|DumperCollection[]|DumperRoute[] The iterator
+ */
+ public function getIterator()
+ {
+ return new \ArrayIterator($this->children);
+ }
+
+ /**
+ * Returns the root of the collection.
+ *
+ * @return self The root collection
+ */
+ public function getRoot()
+ {
+ return (null !== $this->parent) ? $this->parent->getRoot() : $this;
+ }
+
+ /**
+ * Returns the parent collection.
+ *
+ * @return self|null The parent collection or null if the collection has no parent
+ */
+ protected function getParent()
+ {
+ return $this->parent;
+ }
+
+ /**
+ * Sets the parent collection.
+ */
+ protected function setParent(DumperCollection $parent)
+ {
+ $this->parent = $parent;
+ }
+
+ /**
+ * Returns true if the attribute is defined.
+ *
+ * @param string $name The attribute name
+ *
+ * @return bool true if the attribute is defined, false otherwise
+ */
+ public function hasAttribute($name)
+ {
+ return array_key_exists($name, $this->attributes);
+ }
+
+ /**
+ * Returns an attribute by name.
+ *
+ * @param string $name The attribute name
+ * @param mixed $default Default value is the attribute doesn't exist
+ *
+ * @return mixed The attribute value
+ */
+ public function getAttribute($name, $default = null)
+ {
+ return $this->hasAttribute($name) ? $this->attributes[$name] : $default;
+ }
+
+ /**
+ * Sets an attribute by name.
+ *
+ * @param string $name The attribute name
+ * @param mixed $value The attribute value
+ */
+ public function setAttribute($name, $value)
+ {
+ $this->attributes[$name] = $value;
+ }
+
+ /**
+ * Sets multiple attributes.
+ *
+ * @param array $attributes The attributes
+ */
+ public function setAttributes($attributes)
+ {
+ $this->attributes = $attributes;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/Dumper/DumperRoute.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/Dumper/DumperRoute.php
new file mode 100644
index 0000000..c71989a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/Dumper/DumperRoute.php
@@ -0,0 +1,57 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Matcher\Dumper;
+
+use Symfony\Component\Routing\Route;
+
+/**
+ * Container for a Route.
+ *
+ * @author Arnaud Le Blanc <arnaud.lb@gmail.com>
+ *
+ * @internal
+ */
+class DumperRoute
+{
+ private $name;
+ private $route;
+
+ /**
+ * @param string $name The route name
+ * @param Route $route The route
+ */
+ public function __construct($name, Route $route)
+ {
+ $this->name = $name;
+ $this->route = $route;
+ }
+
+ /**
+ * Returns the route name.
+ *
+ * @return string The route name
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Returns the route.
+ *
+ * @return Route The route
+ */
+ public function getRoute()
+ {
+ return $this->route;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/Dumper/MatcherDumper.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/Dumper/MatcherDumper.php
new file mode 100644
index 0000000..ea51ab4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/Dumper/MatcherDumper.php
@@ -0,0 +1,37 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Matcher\Dumper;
+
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * MatcherDumper is the abstract class for all built-in matcher dumpers.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+abstract class MatcherDumper implements MatcherDumperInterface
+{
+ private $routes;
+
+ public function __construct(RouteCollection $routes)
+ {
+ $this->routes = $routes;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getRoutes()
+ {
+ return $this->routes;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/Dumper/MatcherDumperInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/Dumper/MatcherDumperInterface.php
new file mode 100644
index 0000000..5e7c134
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/Dumper/MatcherDumperInterface.php
@@ -0,0 +1,39 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Matcher\Dumper;
+
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * MatcherDumperInterface is the interface that all matcher dumper classes must implement.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface MatcherDumperInterface
+{
+ /**
+ * Dumps a set of routes to a string representation of executable code
+ * that can then be used to match a request against these routes.
+ *
+ * @param array $options An array of options
+ *
+ * @return string Executable code
+ */
+ public function dump(array $options = array());
+
+ /**
+ * Gets the routes to dump.
+ *
+ * @return RouteCollection A RouteCollection instance
+ */
+ public function getRoutes();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/Dumper/PhpMatcherDumper.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/Dumper/PhpMatcherDumper.php
new file mode 100644
index 0000000..40d8df6
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/Dumper/PhpMatcherDumper.php
@@ -0,0 +1,429 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Matcher\Dumper;
+
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
+use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
+
+/**
+ * PhpMatcherDumper creates a PHP class able to match URLs for a given set of routes.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Tobias Schultze <http://tobion.de>
+ * @author Arnaud Le Blanc <arnaud.lb@gmail.com>
+ */
+class PhpMatcherDumper extends MatcherDumper
+{
+ private $expressionLanguage;
+
+ /**
+ * @var ExpressionFunctionProviderInterface[]
+ */
+ private $expressionLanguageProviders = array();
+
+ /**
+ * Dumps a set of routes to a PHP class.
+ *
+ * Available options:
+ *
+ * * class: The class name
+ * * base_class: The base class name
+ *
+ * @param array $options An array of options
+ *
+ * @return string A PHP class representing the matcher class
+ */
+ public function dump(array $options = array())
+ {
+ $options = array_replace(array(
+ 'class' => 'ProjectUrlMatcher',
+ 'base_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher',
+ ), $options);
+
+ // trailing slash support is only enabled if we know how to redirect the user
+ $interfaces = class_implements($options['base_class']);
+ $supportsRedirections = isset($interfaces['Symfony\\Component\\Routing\\Matcher\\RedirectableUrlMatcherInterface']);
+
+ return <<<EOF
+<?php
+
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\RequestContext;
+
+/**
+ * This class has been auto-generated
+ * by the Symfony Routing Component.
+ */
+class {$options['class']} extends {$options['base_class']}
+{
+ public function __construct(RequestContext \$context)
+ {
+ \$this->context = \$context;
+ }
+
+{$this->generateMatchMethod($supportsRedirections)}
+}
+
+EOF;
+ }
+
+ public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider)
+ {
+ $this->expressionLanguageProviders[] = $provider;
+ }
+
+ /**
+ * Generates the code for the match method implementing UrlMatcherInterface.
+ *
+ * @param bool $supportsRedirections Whether redirections are supported by the base class
+ *
+ * @return string Match method as PHP code
+ */
+ private function generateMatchMethod($supportsRedirections)
+ {
+ $code = rtrim($this->compileRoutes($this->getRoutes(), $supportsRedirections), "\n");
+
+ return <<<EOF
+ public function match(\$rawPathinfo)
+ {
+ \$allow = array();
+ \$pathinfo = rawurldecode(\$rawPathinfo);
+ \$trimmedPathinfo = rtrim(\$pathinfo, '/');
+ \$context = \$this->context;
+ \$request = \$this->request ?: \$this->createRequest(\$pathinfo);
+ \$requestMethod = \$canonicalMethod = \$context->getMethod();
+
+ if ('HEAD' === \$requestMethod) {
+ \$canonicalMethod = 'GET';
+ }
+
+$code
+
+ throw 0 < count(\$allow) ? new MethodNotAllowedException(array_unique(\$allow)) : new ResourceNotFoundException();
+ }
+EOF;
+ }
+
+ /**
+ * Generates PHP code to match a RouteCollection with all its routes.
+ *
+ * @param RouteCollection $routes A RouteCollection instance
+ * @param bool $supportsRedirections Whether redirections are supported by the base class
+ *
+ * @return string PHP code
+ */
+ private function compileRoutes(RouteCollection $routes, $supportsRedirections)
+ {
+ $fetchedHost = false;
+ $groups = $this->groupRoutesByHostRegex($routes);
+ $code = '';
+
+ foreach ($groups as $collection) {
+ if (null !== $regex = $collection->getAttribute('host_regex')) {
+ if (!$fetchedHost) {
+ $code .= " \$host = \$context->getHost();\n\n";
+ $fetchedHost = true;
+ }
+
+ $code .= sprintf(" if (preg_match(%s, \$host, \$hostMatches)) {\n", var_export($regex, true));
+ }
+
+ $tree = $this->buildStaticPrefixCollection($collection);
+ $groupCode = $this->compileStaticPrefixRoutes($tree, $supportsRedirections);
+
+ if (null !== $regex) {
+ // apply extra indention at each line (except empty ones)
+ $groupCode = preg_replace('/^.{2,}$/m', ' $0', $groupCode);
+ $code .= $groupCode;
+ $code .= " }\n\n";
+ } else {
+ $code .= $groupCode;
+ }
+ }
+
+ // used to display the Welcome Page in apps that don't define a homepage
+ $code .= " if ('/' === \$pathinfo && !\$allow) {\n";
+ $code .= " throw new Symfony\Component\Routing\Exception\NoConfigurationException();\n";
+ $code .= " }\n";
+
+ return $code;
+ }
+
+ private function buildStaticPrefixCollection(DumperCollection $collection)
+ {
+ $prefixCollection = new StaticPrefixCollection();
+
+ foreach ($collection as $dumperRoute) {
+ $prefix = $dumperRoute->getRoute()->compile()->getStaticPrefix();
+ $prefixCollection->addRoute($prefix, $dumperRoute);
+ }
+
+ $prefixCollection->optimizeGroups();
+
+ return $prefixCollection;
+ }
+
+ /**
+ * Generates PHP code to match a tree of routes.
+ *
+ * @param StaticPrefixCollection $collection A StaticPrefixCollection instance
+ * @param bool $supportsRedirections Whether redirections are supported by the base class
+ * @param string $ifOrElseIf either "if" or "elseif" to influence chaining
+ *
+ * @return string PHP code
+ */
+ private function compileStaticPrefixRoutes(StaticPrefixCollection $collection, $supportsRedirections, $ifOrElseIf = 'if')
+ {
+ $code = '';
+ $prefix = $collection->getPrefix();
+
+ if (!empty($prefix) && '/' !== $prefix) {
+ $code .= sprintf(" %s (0 === strpos(\$pathinfo, %s)) {\n", $ifOrElseIf, var_export($prefix, true));
+ }
+
+ $ifOrElseIf = 'if';
+
+ foreach ($collection->getItems() as $route) {
+ if ($route instanceof StaticPrefixCollection) {
+ $code .= $this->compileStaticPrefixRoutes($route, $supportsRedirections, $ifOrElseIf);
+ $ifOrElseIf = 'elseif';
+ } else {
+ $code .= $this->compileRoute($route[1]->getRoute(), $route[1]->getName(), $supportsRedirections, $prefix)."\n";
+ $ifOrElseIf = 'if';
+ }
+ }
+
+ if (!empty($prefix) && '/' !== $prefix) {
+ $code .= " }\n\n";
+ // apply extra indention at each line (except empty ones)
+ $code = preg_replace('/^.{2,}$/m', ' $0', $code);
+ }
+
+ return $code;
+ }
+
+ /**
+ * Compiles a single Route to PHP code used to match it against the path info.
+ *
+ * @param Route $route A Route instance
+ * @param string $name The name of the Route
+ * @param bool $supportsRedirections Whether redirections are supported by the base class
+ * @param string|null $parentPrefix The prefix of the parent collection used to optimize the code
+ *
+ * @return string PHP code
+ *
+ * @throws \LogicException
+ */
+ private function compileRoute(Route $route, $name, $supportsRedirections, $parentPrefix = null)
+ {
+ $code = '';
+ $compiledRoute = $route->compile();
+ $conditions = array();
+ $hasTrailingSlash = false;
+ $matches = false;
+ $hostMatches = false;
+ $methods = $route->getMethods();
+
+ $supportsTrailingSlash = $supportsRedirections && (!$methods || in_array('GET', $methods));
+ $regex = $compiledRoute->getRegex();
+
+ if (!count($compiledRoute->getPathVariables()) && false !== preg_match('#^(.)\^(?P<url>.*?)\$\1#'.('u' === substr($regex, -1) ? 'u' : ''), $regex, $m)) {
+ if ($supportsTrailingSlash && '/' === substr($m['url'], -1)) {
+ $conditions[] = sprintf('%s === $trimmedPathinfo', var_export(rtrim(str_replace('\\', '', $m['url']), '/'), true));
+ $hasTrailingSlash = true;
+ } else {
+ $conditions[] = sprintf('%s === $pathinfo', var_export(str_replace('\\', '', $m['url']), true));
+ }
+ } else {
+ if ($compiledRoute->getStaticPrefix() && $compiledRoute->getStaticPrefix() !== $parentPrefix) {
+ $conditions[] = sprintf('0 === strpos($pathinfo, %s)', var_export($compiledRoute->getStaticPrefix(), true));
+ }
+
+ if ($supportsTrailingSlash && $pos = strpos($regex, '/$')) {
+ $regex = substr($regex, 0, $pos).'/?$'.substr($regex, $pos + 2);
+ $hasTrailingSlash = true;
+ }
+ $conditions[] = sprintf('preg_match(%s, $pathinfo, $matches)', var_export($regex, true));
+
+ $matches = true;
+ }
+
+ if ($compiledRoute->getHostVariables()) {
+ $hostMatches = true;
+ }
+
+ if ($route->getCondition()) {
+ $conditions[] = $this->getExpressionLanguage()->compile($route->getCondition(), array('context', 'request'));
+ }
+
+ $conditions = implode(' && ', $conditions);
+
+ $code .= <<<EOF
+ // $name
+ if ($conditions) {
+
+EOF;
+
+ $gotoname = 'not_'.preg_replace('/[^A-Za-z0-9_]/', '', $name);
+
+ // the offset where the return value is appended below, with indendation
+ $retOffset = 12 + strlen($code);
+
+ // optimize parameters array
+ if ($matches || $hostMatches) {
+ $vars = array();
+ if ($hostMatches) {
+ $vars[] = '$hostMatches';
+ }
+ if ($matches) {
+ $vars[] = '$matches';
+ }
+ $vars[] = "array('_route' => '$name')";
+
+ $code .= sprintf(
+ " \$ret = \$this->mergeDefaults(array_replace(%s), %s);\n",
+ implode(', ', $vars),
+ str_replace("\n", '', var_export($route->getDefaults(), true))
+ );
+ } elseif ($route->getDefaults()) {
+ $code .= sprintf(" \$ret = %s;\n", str_replace("\n", '', var_export(array_replace($route->getDefaults(), array('_route' => $name)), true)));
+ } else {
+ $code .= sprintf(" \$ret = array('_route' => '%s');\n", $name);
+ }
+
+ if ($hasTrailingSlash) {
+ $code .= <<<EOF
+ if ('/' === substr(\$pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== \$canonicalMethod) {
+ goto $gotoname;
+ } else {
+ return array_replace(\$ret, \$this->redirect(\$rawPathinfo.'/', '$name'));
+ }
+
+
+EOF;
+ }
+
+ if ($methods) {
+ $methodVariable = in_array('GET', $methods) ? '$canonicalMethod' : '$requestMethod';
+ $methods = implode("', '", $methods);
+ }
+
+ if ($schemes = $route->getSchemes()) {
+ if (!$supportsRedirections) {
+ throw new \LogicException('The "schemes" requirement is only supported for URL matchers that implement RedirectableUrlMatcherInterface.');
+ }
+ $schemes = str_replace("\n", '', var_export(array_flip($schemes), true));
+ if ($methods) {
+ $code .= <<<EOF
+ \$requiredSchemes = $schemes;
+ \$hasRequiredScheme = isset(\$requiredSchemes[\$context->getScheme()]);
+ if (!in_array($methodVariable, array('$methods'))) {
+ if (\$hasRequiredScheme) {
+ \$allow = array_merge(\$allow, array('$methods'));
+ }
+ goto $gotoname;
+ }
+ if (!\$hasRequiredScheme) {
+ if ('GET' !== \$canonicalMethod) {
+ goto $gotoname;
+ }
+
+ return array_replace(\$ret, \$this->redirect(\$rawPathinfo, '$name', key(\$requiredSchemes)));
+ }
+
+
+EOF;
+ } else {
+ $code .= <<<EOF
+ \$requiredSchemes = $schemes;
+ if (!isset(\$requiredSchemes[\$context->getScheme()])) {
+ if ('GET' !== \$canonicalMethod) {
+ goto $gotoname;
+ }
+
+ return array_replace(\$ret, \$this->redirect(\$rawPathinfo, '$name', key(\$requiredSchemes)));
+ }
+
+
+EOF;
+ }
+ } elseif ($methods) {
+ $code .= <<<EOF
+ if (!in_array($methodVariable, array('$methods'))) {
+ \$allow = array_merge(\$allow, array('$methods'));
+ goto $gotoname;
+ }
+
+
+EOF;
+ }
+
+ if ($hasTrailingSlash || $schemes || $methods) {
+ $code .= " return \$ret;\n";
+ } else {
+ $code = substr_replace($code, 'return', $retOffset, 6);
+ }
+ $code .= " }\n";
+
+ if ($hasTrailingSlash || $schemes || $methods) {
+ $code .= " $gotoname:\n";
+ }
+
+ return $code;
+ }
+
+ /**
+ * Groups consecutive routes having the same host regex.
+ *
+ * The result is a collection of collections of routes having the same host regex.
+ *
+ * @param RouteCollection $routes A flat RouteCollection
+ *
+ * @return DumperCollection A collection with routes grouped by host regex in sub-collections
+ */
+ private function groupRoutesByHostRegex(RouteCollection $routes)
+ {
+ $groups = new DumperCollection();
+ $currentGroup = new DumperCollection();
+ $currentGroup->setAttribute('host_regex', null);
+ $groups->add($currentGroup);
+
+ foreach ($routes as $name => $route) {
+ $hostRegex = $route->compile()->getHostRegex();
+ if ($currentGroup->getAttribute('host_regex') !== $hostRegex) {
+ $currentGroup = new DumperCollection();
+ $currentGroup->setAttribute('host_regex', $hostRegex);
+ $groups->add($currentGroup);
+ }
+ $currentGroup->add(new DumperRoute($name, $route));
+ }
+
+ return $groups;
+ }
+
+ private function getExpressionLanguage()
+ {
+ if (null === $this->expressionLanguage) {
+ if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
+ throw new \RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
+ }
+ $this->expressionLanguage = new ExpressionLanguage(null, $this->expressionLanguageProviders);
+ }
+
+ return $this->expressionLanguage;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/Dumper/StaticPrefixCollection.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/Dumper/StaticPrefixCollection.php
new file mode 100644
index 0000000..7365808
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/Dumper/StaticPrefixCollection.php
@@ -0,0 +1,238 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Matcher\Dumper;
+
+/**
+ * Prefix tree of routes preserving routes order.
+ *
+ * @author Frank de Jonge <info@frankdejonge.nl>
+ *
+ * @internal
+ */
+class StaticPrefixCollection
+{
+ /**
+ * @var string
+ */
+ private $prefix;
+
+ /**
+ * @var array[]|StaticPrefixCollection[]
+ */
+ private $items = array();
+
+ /**
+ * @var int
+ */
+ private $matchStart = 0;
+
+ public function __construct($prefix = '')
+ {
+ $this->prefix = $prefix;
+ }
+
+ public function getPrefix()
+ {
+ return $this->prefix;
+ }
+
+ /**
+ * @return mixed[]|StaticPrefixCollection[]
+ */
+ public function getItems()
+ {
+ return $this->items;
+ }
+
+ /**
+ * Adds a route to a group.
+ *
+ * @param string $prefix
+ * @param mixed $route
+ */
+ public function addRoute($prefix, $route)
+ {
+ $prefix = '/' === $prefix ? $prefix : rtrim($prefix, '/');
+ $this->guardAgainstAddingNotAcceptedRoutes($prefix);
+
+ if ($this->prefix === $prefix) {
+ // When a prefix is exactly the same as the base we move up the match start position.
+ // This is needed because otherwise routes that come afterwards have higher precedence
+ // than a possible regular expression, which goes against the input order sorting.
+ $this->items[] = array($prefix, $route);
+ $this->matchStart = count($this->items);
+
+ return;
+ }
+
+ foreach ($this->items as $i => $item) {
+ if ($i < $this->matchStart) {
+ continue;
+ }
+
+ if ($item instanceof self && $item->accepts($prefix)) {
+ $item->addRoute($prefix, $route);
+
+ return;
+ }
+
+ $group = $this->groupWithItem($item, $prefix, $route);
+
+ if ($group instanceof self) {
+ $this->items[$i] = $group;
+
+ return;
+ }
+ }
+
+ // No optimised case was found, in this case we simple add the route for possible
+ // grouping when new routes are added.
+ $this->items[] = array($prefix, $route);
+ }
+
+ /**
+ * Tries to combine a route with another route or group.
+ *
+ * @param StaticPrefixCollection|array $item
+ * @param string $prefix
+ * @param mixed $route
+ *
+ * @return null|StaticPrefixCollection
+ */
+ private function groupWithItem($item, $prefix, $route)
+ {
+ $itemPrefix = $item instanceof self ? $item->prefix : $item[0];
+ $commonPrefix = $this->detectCommonPrefix($prefix, $itemPrefix);
+
+ if (!$commonPrefix) {
+ return;
+ }
+
+ $child = new self($commonPrefix);
+
+ if ($item instanceof self) {
+ $child->items = array($item);
+ } else {
+ $child->addRoute($item[0], $item[1]);
+ }
+
+ $child->addRoute($prefix, $route);
+
+ return $child;
+ }
+
+ /**
+ * Checks whether a prefix can be contained within the group.
+ *
+ * @param string $prefix
+ *
+ * @return bool Whether a prefix could belong in a given group
+ */
+ private function accepts($prefix)
+ {
+ return '' === $this->prefix || 0 === strpos($prefix, $this->prefix);
+ }
+
+ /**
+ * Detects whether there's a common prefix relative to the group prefix and returns it.
+ *
+ * @param string $prefix
+ * @param string $anotherPrefix
+ *
+ * @return false|string A common prefix, longer than the base/group prefix, or false when none available
+ */
+ private function detectCommonPrefix($prefix, $anotherPrefix)
+ {
+ $baseLength = strlen($this->prefix);
+ $commonLength = $baseLength;
+ $end = min(strlen($prefix), strlen($anotherPrefix));
+
+ for ($i = $baseLength; $i <= $end; ++$i) {
+ if (substr($prefix, 0, $i) !== substr($anotherPrefix, 0, $i)) {
+ break;
+ }
+
+ $commonLength = $i;
+ }
+
+ $commonPrefix = rtrim(substr($prefix, 0, $commonLength), '/');
+
+ if (strlen($commonPrefix) > $baseLength) {
+ return $commonPrefix;
+ }
+
+ return false;
+ }
+
+ /**
+ * Optimizes the tree by inlining items from groups with less than 3 items.
+ */
+ public function optimizeGroups()
+ {
+ $index = -1;
+
+ while (isset($this->items[++$index])) {
+ $item = $this->items[$index];
+
+ if ($item instanceof self) {
+ $item->optimizeGroups();
+
+ // When a group contains only two items there's no reason to optimize because at minimum
+ // the amount of prefix check is 2. In this case inline the group.
+ if ($item->shouldBeInlined()) {
+ array_splice($this->items, $index, 1, $item->items);
+
+ // Lower index to pass through the same index again after optimizing.
+ // The first item of the replacements might be a group needing optimization.
+ --$index;
+ }
+ }
+ }
+ }
+
+ private function shouldBeInlined()
+ {
+ if (count($this->items) >= 3) {
+ return false;
+ }
+
+ foreach ($this->items as $item) {
+ if ($item instanceof self) {
+ return true;
+ }
+ }
+
+ foreach ($this->items as $item) {
+ if (is_array($item) && $item[0] === $this->prefix) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Guards against adding incompatible prefixes in a group.
+ *
+ * @param string $prefix
+ *
+ * @throws \LogicException when a prefix does not belong in a group
+ */
+ private function guardAgainstAddingNotAcceptedRoutes($prefix)
+ {
+ if (!$this->accepts($prefix)) {
+ $message = sprintf('Could not add route with prefix %s to collection with prefix %s', $prefix, $this->prefix);
+
+ throw new \LogicException($message);
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/RedirectableUrlMatcher.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/RedirectableUrlMatcher.php
new file mode 100644
index 0000000..3770a9c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/RedirectableUrlMatcher.php
@@ -0,0 +1,65 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Matcher;
+
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\Route;
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+abstract class RedirectableUrlMatcher extends UrlMatcher implements RedirectableUrlMatcherInterface
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function match($pathinfo)
+ {
+ try {
+ $parameters = parent::match($pathinfo);
+ } catch (ResourceNotFoundException $e) {
+ if ('/' === substr($pathinfo, -1) || !in_array($this->context->getMethod(), array('HEAD', 'GET'))) {
+ throw $e;
+ }
+
+ try {
+ $parameters = parent::match($pathinfo.'/');
+
+ return array_replace($parameters, $this->redirect($pathinfo.'/', isset($parameters['_route']) ? $parameters['_route'] : null));
+ } catch (ResourceNotFoundException $e2) {
+ throw $e;
+ }
+ }
+
+ return $parameters;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function handleRouteRequirements($pathinfo, $name, Route $route)
+ {
+ // expression condition
+ if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), array('context' => $this->context, 'request' => $this->request ?: $this->createRequest($pathinfo)))) {
+ return array(self::REQUIREMENT_MISMATCH, null);
+ }
+
+ // check HTTP scheme requirement
+ $scheme = $this->context->getScheme();
+ $schemes = $route->getSchemes();
+ if ($schemes && !$route->hasScheme($scheme)) {
+ return array(self::ROUTE_MATCH, $this->redirect($pathinfo, $name, current($schemes)));
+ }
+
+ return array(self::REQUIREMENT_MATCH, null);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/RedirectableUrlMatcherInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/RedirectableUrlMatcherInterface.php
new file mode 100644
index 0000000..7c27bc8
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/RedirectableUrlMatcherInterface.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Matcher;
+
+/**
+ * RedirectableUrlMatcherInterface knows how to redirect the user.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface RedirectableUrlMatcherInterface
+{
+ /**
+ * Redirects the user to another URL.
+ *
+ * @param string $path The path info to redirect to
+ * @param string $route The route name that matched
+ * @param string|null $scheme The URL scheme (null to keep the current one)
+ *
+ * @return array An array of parameters
+ */
+ public function redirect($path, $route, $scheme = null);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/RequestMatcherInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/RequestMatcherInterface.php
new file mode 100644
index 0000000..1eef778
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/RequestMatcherInterface.php
@@ -0,0 +1,39 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Matcher;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Routing\Exception\NoConfigurationException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+
+/**
+ * RequestMatcherInterface is the interface that all request matcher classes must implement.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface RequestMatcherInterface
+{
+ /**
+ * Tries to match a request with a set of routes.
+ *
+ * If the matcher can not find information, it must throw one of the exceptions documented
+ * below.
+ *
+ * @return array An array of parameters
+ *
+ * @throws NoConfigurationException If no routing configuration could be found
+ * @throws ResourceNotFoundException If no matching resource could be found
+ * @throws MethodNotAllowedException If a matching resource was found but the request method is not allowed
+ */
+ public function matchRequest(Request $request);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/TraceableUrlMatcher.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/TraceableUrlMatcher.php
new file mode 100644
index 0000000..9085be0
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/TraceableUrlMatcher.php
@@ -0,0 +1,141 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Matcher;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Routing\Exception\ExceptionInterface;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * TraceableUrlMatcher helps debug path info matching by tracing the match.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class TraceableUrlMatcher extends UrlMatcher
+{
+ const ROUTE_DOES_NOT_MATCH = 0;
+ const ROUTE_ALMOST_MATCHES = 1;
+ const ROUTE_MATCHES = 2;
+
+ protected $traces;
+
+ public function getTraces($pathinfo)
+ {
+ $this->traces = array();
+
+ try {
+ $this->match($pathinfo);
+ } catch (ExceptionInterface $e) {
+ }
+
+ return $this->traces;
+ }
+
+ public function getTracesForRequest(Request $request)
+ {
+ $this->request = $request;
+ $traces = $this->getTraces($request->getPathInfo());
+ $this->request = null;
+
+ return $traces;
+ }
+
+ protected function matchCollection($pathinfo, RouteCollection $routes)
+ {
+ foreach ($routes as $name => $route) {
+ $compiledRoute = $route->compile();
+
+ if (!preg_match($compiledRoute->getRegex(), $pathinfo, $matches)) {
+ // does it match without any requirements?
+ $r = new Route($route->getPath(), $route->getDefaults(), array(), $route->getOptions());
+ $cr = $r->compile();
+ if (!preg_match($cr->getRegex(), $pathinfo)) {
+ $this->addTrace(sprintf('Path "%s" does not match', $route->getPath()), self::ROUTE_DOES_NOT_MATCH, $name, $route);
+
+ continue;
+ }
+
+ foreach ($route->getRequirements() as $n => $regex) {
+ $r = new Route($route->getPath(), $route->getDefaults(), array($n => $regex), $route->getOptions());
+ $cr = $r->compile();
+
+ if (in_array($n, $cr->getVariables()) && !preg_match($cr->getRegex(), $pathinfo)) {
+ $this->addTrace(sprintf('Requirement for "%s" does not match (%s)', $n, $regex), self::ROUTE_ALMOST_MATCHES, $name, $route);
+
+ continue 2;
+ }
+ }
+
+ continue;
+ }
+
+ // check host requirement
+ $hostMatches = array();
+ if ($compiledRoute->getHostRegex() && !preg_match($compiledRoute->getHostRegex(), $this->context->getHost(), $hostMatches)) {
+ $this->addTrace(sprintf('Host "%s" does not match the requirement ("%s")', $this->context->getHost(), $route->getHost()), self::ROUTE_ALMOST_MATCHES, $name, $route);
+
+ continue;
+ }
+
+ // check HTTP method requirement
+ if ($requiredMethods = $route->getMethods()) {
+ // HEAD and GET are equivalent as per RFC
+ if ('HEAD' === $method = $this->context->getMethod()) {
+ $method = 'GET';
+ }
+
+ if (!in_array($method, $requiredMethods)) {
+ $this->allow = array_merge($this->allow, $requiredMethods);
+
+ $this->addTrace(sprintf('Method "%s" does not match any of the required methods (%s)', $this->context->getMethod(), implode(', ', $requiredMethods)), self::ROUTE_ALMOST_MATCHES, $name, $route);
+
+ continue;
+ }
+ }
+
+ // check condition
+ if ($condition = $route->getCondition()) {
+ if (!$this->getExpressionLanguage()->evaluate($condition, array('context' => $this->context, 'request' => $this->request ?: $this->createRequest($pathinfo)))) {
+ $this->addTrace(sprintf('Condition "%s" does not evaluate to "true"', $condition), self::ROUTE_ALMOST_MATCHES, $name, $route);
+
+ continue;
+ }
+ }
+
+ // check HTTP scheme requirement
+ if ($requiredSchemes = $route->getSchemes()) {
+ $scheme = $this->context->getScheme();
+
+ if (!$route->hasScheme($scheme)) {
+ $this->addTrace(sprintf('Scheme "%s" does not match any of the required schemes (%s); the user will be redirected to first required scheme', $scheme, implode(', ', $requiredSchemes)), self::ROUTE_ALMOST_MATCHES, $name, $route);
+
+ return true;
+ }
+ }
+
+ $this->addTrace('Route matches!', self::ROUTE_MATCHES, $name, $route);
+
+ return true;
+ }
+ }
+
+ private function addTrace($log, $level = self::ROUTE_DOES_NOT_MATCH, $name = null, $route = null)
+ {
+ $this->traces[] = array(
+ 'log' => $log,
+ 'name' => $name,
+ 'level' => $level,
+ 'path' => null !== $route ? $route->getPath() : null,
+ );
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/UrlMatcher.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/UrlMatcher.php
new file mode 100644
index 0000000..445cfc4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/UrlMatcher.php
@@ -0,0 +1,252 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Matcher;
+
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+use Symfony\Component\Routing\Exception\NoConfigurationException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\RequestContext;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
+use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
+
+/**
+ * UrlMatcher matches URL based on a set of routes.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
+{
+ const REQUIREMENT_MATCH = 0;
+ const REQUIREMENT_MISMATCH = 1;
+ const ROUTE_MATCH = 2;
+
+ protected $context;
+ protected $allow = array();
+ protected $routes;
+ protected $request;
+ protected $expressionLanguage;
+
+ /**
+ * @var ExpressionFunctionProviderInterface[]
+ */
+ protected $expressionLanguageProviders = array();
+
+ public function __construct(RouteCollection $routes, RequestContext $context)
+ {
+ $this->routes = $routes;
+ $this->context = $context;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setContext(RequestContext $context)
+ {
+ $this->context = $context;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getContext()
+ {
+ return $this->context;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function match($pathinfo)
+ {
+ $this->allow = array();
+
+ if ($ret = $this->matchCollection(rawurldecode($pathinfo), $this->routes)) {
+ return $ret;
+ }
+
+ if ('/' === $pathinfo && !$this->allow) {
+ throw new NoConfigurationException();
+ }
+
+ throw 0 < count($this->allow)
+ ? new MethodNotAllowedException(array_unique($this->allow))
+ : new ResourceNotFoundException(sprintf('No routes found for "%s".', $pathinfo));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function matchRequest(Request $request)
+ {
+ $this->request = $request;
+
+ $ret = $this->match($request->getPathInfo());
+
+ $this->request = null;
+
+ return $ret;
+ }
+
+ public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider)
+ {
+ $this->expressionLanguageProviders[] = $provider;
+ }
+
+ /**
+ * Tries to match a URL with a set of routes.
+ *
+ * @param string $pathinfo The path info to be parsed
+ * @param RouteCollection $routes The set of routes
+ *
+ * @return array An array of parameters
+ *
+ * @throws NoConfigurationException If no routing configuration could be found
+ * @throws ResourceNotFoundException If the resource could not be found
+ * @throws MethodNotAllowedException If the resource was found but the request method is not allowed
+ */
+ protected function matchCollection($pathinfo, RouteCollection $routes)
+ {
+ foreach ($routes as $name => $route) {
+ $compiledRoute = $route->compile();
+
+ // check the static prefix of the URL first. Only use the more expensive preg_match when it matches
+ if ('' !== $compiledRoute->getStaticPrefix() && 0 !== strpos($pathinfo, $compiledRoute->getStaticPrefix())) {
+ continue;
+ }
+
+ if (!preg_match($compiledRoute->getRegex(), $pathinfo, $matches)) {
+ continue;
+ }
+
+ $hostMatches = array();
+ if ($compiledRoute->getHostRegex() && !preg_match($compiledRoute->getHostRegex(), $this->context->getHost(), $hostMatches)) {
+ continue;
+ }
+
+ $status = $this->handleRouteRequirements($pathinfo, $name, $route);
+
+ if (self::REQUIREMENT_MISMATCH === $status[0]) {
+ continue;
+ }
+
+ // check HTTP method requirement
+ if ($requiredMethods = $route->getMethods()) {
+ // HEAD and GET are equivalent as per RFC
+ if ('HEAD' === $method = $this->context->getMethod()) {
+ $method = 'GET';
+ }
+
+ if (!in_array($method, $requiredMethods)) {
+ if (self::REQUIREMENT_MATCH === $status[0]) {
+ $this->allow = array_merge($this->allow, $requiredMethods);
+ }
+
+ continue;
+ }
+ }
+
+ return $this->getAttributes($route, $name, array_replace($matches, $hostMatches, isset($status[1]) ? $status[1] : array()));
+ }
+ }
+
+ /**
+ * Returns an array of values to use as request attributes.
+ *
+ * As this method requires the Route object, it is not available
+ * in matchers that do not have access to the matched Route instance
+ * (like the PHP and Apache matcher dumpers).
+ *
+ * @param Route $route The route we are matching against
+ * @param string $name The name of the route
+ * @param array $attributes An array of attributes from the matcher
+ *
+ * @return array An array of parameters
+ */
+ protected function getAttributes(Route $route, $name, array $attributes)
+ {
+ $attributes['_route'] = $name;
+
+ return $this->mergeDefaults($attributes, $route->getDefaults());
+ }
+
+ /**
+ * Handles specific route requirements.
+ *
+ * @param string $pathinfo The path
+ * @param string $name The route name
+ * @param Route $route The route
+ *
+ * @return array The first element represents the status, the second contains additional information
+ */
+ protected function handleRouteRequirements($pathinfo, $name, Route $route)
+ {
+ // expression condition
+ if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), array('context' => $this->context, 'request' => $this->request ?: $this->createRequest($pathinfo)))) {
+ return array(self::REQUIREMENT_MISMATCH, null);
+ }
+
+ // check HTTP scheme requirement
+ $scheme = $this->context->getScheme();
+ $status = $route->getSchemes() && !$route->hasScheme($scheme) ? self::REQUIREMENT_MISMATCH : self::REQUIREMENT_MATCH;
+
+ return array($status, null);
+ }
+
+ /**
+ * Get merged default parameters.
+ *
+ * @param array $params The parameters
+ * @param array $defaults The defaults
+ *
+ * @return array Merged default parameters
+ */
+ protected function mergeDefaults($params, $defaults)
+ {
+ foreach ($params as $key => $value) {
+ if (!is_int($key)) {
+ $defaults[$key] = $value;
+ }
+ }
+
+ return $defaults;
+ }
+
+ protected function getExpressionLanguage()
+ {
+ if (null === $this->expressionLanguage) {
+ if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
+ throw new \RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
+ }
+ $this->expressionLanguage = new ExpressionLanguage(null, $this->expressionLanguageProviders);
+ }
+
+ return $this->expressionLanguage;
+ }
+
+ /**
+ * @internal
+ */
+ protected function createRequest($pathinfo)
+ {
+ if (!class_exists('Symfony\Component\HttpFoundation\Request')) {
+ return null;
+ }
+
+ return Request::create($this->context->getScheme().'://'.$this->context->getHost().$this->context->getBaseUrl().$pathinfo, $this->context->getMethod(), $this->context->getParameters(), array(), array(), array(
+ 'SCRIPT_FILENAME' => $this->context->getBaseUrl(),
+ 'SCRIPT_NAME' => $this->context->getBaseUrl(),
+ ));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/UrlMatcherInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/UrlMatcherInterface.php
new file mode 100644
index 0000000..2c7c313
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Matcher/UrlMatcherInterface.php
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Matcher;
+
+use Symfony\Component\Routing\Exception\NoConfigurationException;
+use Symfony\Component\Routing\RequestContextAwareInterface;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+
+/**
+ * UrlMatcherInterface is the interface that all URL matcher classes must implement.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface UrlMatcherInterface extends RequestContextAwareInterface
+{
+ /**
+ * Tries to match a URL path with a set of routes.
+ *
+ * If the matcher can not find information, it must throw one of the exceptions documented
+ * below.
+ *
+ * @param string $pathinfo The path info to be parsed (raw format, i.e. not urldecoded)
+ *
+ * @return array An array of parameters
+ *
+ * @throws NoConfigurationException If no routing configuration could be found
+ * @throws ResourceNotFoundException If the resource could not be found
+ * @throws MethodNotAllowedException If the resource was found but the request method is not allowed
+ */
+ public function match($pathinfo);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/README.md b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/README.md
new file mode 100644
index 0000000..88fb1fd
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/README.md
@@ -0,0 +1,13 @@
+Routing Component
+=================
+
+The Routing component maps an HTTP request to a set of configuration variables.
+
+Resources
+---------
+
+ * [Documentation](https://symfony.com/doc/current/components/routing/index.html)
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/symfony/issues) and
+ [send Pull Requests](https://github.com/symfony/symfony/pulls)
+ in the [main Symfony repository](https://github.com/symfony/symfony)
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/RequestContext.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/RequestContext.php
new file mode 100644
index 0000000..d62a776
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/RequestContext.php
@@ -0,0 +1,336 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing;
+
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Holds information about the current request.
+ *
+ * This class implements a fluent interface.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Tobias Schultze <http://tobion.de>
+ */
+class RequestContext
+{
+ private $baseUrl;
+ private $pathInfo;
+ private $method;
+ private $host;
+ private $scheme;
+ private $httpPort;
+ private $httpsPort;
+ private $queryString;
+ private $parameters = array();
+
+ /**
+ * @param string $baseUrl The base URL
+ * @param string $method The HTTP method
+ * @param string $host The HTTP host name
+ * @param string $scheme The HTTP scheme
+ * @param int $httpPort The HTTP port
+ * @param int $httpsPort The HTTPS port
+ * @param string $path The path
+ * @param string $queryString The query string
+ */
+ public function __construct($baseUrl = '', $method = 'GET', $host = 'localhost', $scheme = 'http', $httpPort = 80, $httpsPort = 443, $path = '/', $queryString = '')
+ {
+ $this->setBaseUrl($baseUrl);
+ $this->setMethod($method);
+ $this->setHost($host);
+ $this->setScheme($scheme);
+ $this->setHttpPort($httpPort);
+ $this->setHttpsPort($httpsPort);
+ $this->setPathInfo($path);
+ $this->setQueryString($queryString);
+ }
+
+ /**
+ * Updates the RequestContext information based on a HttpFoundation Request.
+ *
+ * @return $this
+ */
+ public function fromRequest(Request $request)
+ {
+ $this->setBaseUrl($request->getBaseUrl());
+ $this->setPathInfo($request->getPathInfo());
+ $this->setMethod($request->getMethod());
+ $this->setHost($request->getHost());
+ $this->setScheme($request->getScheme());
+ $this->setHttpPort($request->isSecure() ? $this->httpPort : $request->getPort());
+ $this->setHttpsPort($request->isSecure() ? $request->getPort() : $this->httpsPort);
+ $this->setQueryString($request->server->get('QUERY_STRING', ''));
+
+ return $this;
+ }
+
+ /**
+ * Gets the base URL.
+ *
+ * @return string The base URL
+ */
+ public function getBaseUrl()
+ {
+ return $this->baseUrl;
+ }
+
+ /**
+ * Sets the base URL.
+ *
+ * @param string $baseUrl The base URL
+ *
+ * @return $this
+ */
+ public function setBaseUrl($baseUrl)
+ {
+ $this->baseUrl = $baseUrl;
+
+ return $this;
+ }
+
+ /**
+ * Gets the path info.
+ *
+ * @return string The path info
+ */
+ public function getPathInfo()
+ {
+ return $this->pathInfo;
+ }
+
+ /**
+ * Sets the path info.
+ *
+ * @param string $pathInfo The path info
+ *
+ * @return $this
+ */
+ public function setPathInfo($pathInfo)
+ {
+ $this->pathInfo = $pathInfo;
+
+ return $this;
+ }
+
+ /**
+ * Gets the HTTP method.
+ *
+ * The method is always an uppercased string.
+ *
+ * @return string The HTTP method
+ */
+ public function getMethod()
+ {
+ return $this->method;
+ }
+
+ /**
+ * Sets the HTTP method.
+ *
+ * @param string $method The HTTP method
+ *
+ * @return $this
+ */
+ public function setMethod($method)
+ {
+ $this->method = strtoupper($method);
+
+ return $this;
+ }
+
+ /**
+ * Gets the HTTP host.
+ *
+ * The host is always lowercased because it must be treated case-insensitive.
+ *
+ * @return string The HTTP host
+ */
+ public function getHost()
+ {
+ return $this->host;
+ }
+
+ /**
+ * Sets the HTTP host.
+ *
+ * @param string $host The HTTP host
+ *
+ * @return $this
+ */
+ public function setHost($host)
+ {
+ $this->host = strtolower($host);
+
+ return $this;
+ }
+
+ /**
+ * Gets the HTTP scheme.
+ *
+ * @return string The HTTP scheme
+ */
+ public function getScheme()
+ {
+ return $this->scheme;
+ }
+
+ /**
+ * Sets the HTTP scheme.
+ *
+ * @param string $scheme The HTTP scheme
+ *
+ * @return $this
+ */
+ public function setScheme($scheme)
+ {
+ $this->scheme = strtolower($scheme);
+
+ return $this;
+ }
+
+ /**
+ * Gets the HTTP port.
+ *
+ * @return int The HTTP port
+ */
+ public function getHttpPort()
+ {
+ return $this->httpPort;
+ }
+
+ /**
+ * Sets the HTTP port.
+ *
+ * @param int $httpPort The HTTP port
+ *
+ * @return $this
+ */
+ public function setHttpPort($httpPort)
+ {
+ $this->httpPort = (int) $httpPort;
+
+ return $this;
+ }
+
+ /**
+ * Gets the HTTPS port.
+ *
+ * @return int The HTTPS port
+ */
+ public function getHttpsPort()
+ {
+ return $this->httpsPort;
+ }
+
+ /**
+ * Sets the HTTPS port.
+ *
+ * @param int $httpsPort The HTTPS port
+ *
+ * @return $this
+ */
+ public function setHttpsPort($httpsPort)
+ {
+ $this->httpsPort = (int) $httpsPort;
+
+ return $this;
+ }
+
+ /**
+ * Gets the query string.
+ *
+ * @return string The query string without the "?"
+ */
+ public function getQueryString()
+ {
+ return $this->queryString;
+ }
+
+ /**
+ * Sets the query string.
+ *
+ * @param string $queryString The query string (after "?")
+ *
+ * @return $this
+ */
+ public function setQueryString($queryString)
+ {
+ // string cast to be fault-tolerant, accepting null
+ $this->queryString = (string) $queryString;
+
+ return $this;
+ }
+
+ /**
+ * Returns the parameters.
+ *
+ * @return array The parameters
+ */
+ public function getParameters()
+ {
+ return $this->parameters;
+ }
+
+ /**
+ * Sets the parameters.
+ *
+ * @param array $parameters The parameters
+ *
+ * @return $this
+ */
+ public function setParameters(array $parameters)
+ {
+ $this->parameters = $parameters;
+
+ return $this;
+ }
+
+ /**
+ * Gets a parameter value.
+ *
+ * @param string $name A parameter name
+ *
+ * @return mixed The parameter value or null if nonexistent
+ */
+ public function getParameter($name)
+ {
+ return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
+ }
+
+ /**
+ * Checks if a parameter value is set for the given parameter.
+ *
+ * @param string $name A parameter name
+ *
+ * @return bool True if the parameter value is set, false otherwise
+ */
+ public function hasParameter($name)
+ {
+ return array_key_exists($name, $this->parameters);
+ }
+
+ /**
+ * Sets a parameter value.
+ *
+ * @param string $name A parameter name
+ * @param mixed $parameter The parameter value
+ *
+ * @return $this
+ */
+ public function setParameter($name, $parameter)
+ {
+ $this->parameters[$name] = $parameter;
+
+ return $this;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/RequestContextAwareInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/RequestContextAwareInterface.php
new file mode 100644
index 0000000..df5b9fc
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/RequestContextAwareInterface.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing;
+
+interface RequestContextAwareInterface
+{
+ /**
+ * Sets the request context.
+ */
+ public function setContext(RequestContext $context);
+
+ /**
+ * Gets the request context.
+ *
+ * @return RequestContext The context
+ */
+ public function getContext();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Route.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Route.php
new file mode 100644
index 0000000..cd50ac8
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Route.php
@@ -0,0 +1,558 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing;
+
+/**
+ * A Route describes a route and its parameters.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Tobias Schultze <http://tobion.de>
+ */
+class Route implements \Serializable
+{
+ private $path = '/';
+ private $host = '';
+ private $schemes = array();
+ private $methods = array();
+ private $defaults = array();
+ private $requirements = array();
+ private $options = array();
+ private $condition = '';
+
+ /**
+ * @var null|CompiledRoute
+ */
+ private $compiled;
+
+ /**
+ * Constructor.
+ *
+ * Available options:
+ *
+ * * compiler_class: A class name able to compile this route instance (RouteCompiler by default)
+ * * utf8: Whether UTF-8 matching is enforced ot not
+ *
+ * @param string $path The path pattern to match
+ * @param array $defaults An array of default parameter values
+ * @param array $requirements An array of requirements for parameters (regexes)
+ * @param array $options An array of options
+ * @param string $host The host pattern to match
+ * @param string|string[] $schemes A required URI scheme or an array of restricted schemes
+ * @param string|string[] $methods A required HTTP method or an array of restricted methods
+ * @param string $condition A condition that should evaluate to true for the route to match
+ */
+ public function __construct($path, array $defaults = array(), array $requirements = array(), array $options = array(), $host = '', $schemes = array(), $methods = array(), $condition = '')
+ {
+ $this->setPath($path);
+ $this->setDefaults($defaults);
+ $this->setRequirements($requirements);
+ $this->setOptions($options);
+ $this->setHost($host);
+ $this->setSchemes($schemes);
+ $this->setMethods($methods);
+ $this->setCondition($condition);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function serialize()
+ {
+ return serialize(array(
+ 'path' => $this->path,
+ 'host' => $this->host,
+ 'defaults' => $this->defaults,
+ 'requirements' => $this->requirements,
+ 'options' => $this->options,
+ 'schemes' => $this->schemes,
+ 'methods' => $this->methods,
+ 'condition' => $this->condition,
+ 'compiled' => $this->compiled,
+ ));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function unserialize($serialized)
+ {
+ $data = unserialize($serialized);
+ $this->path = $data['path'];
+ $this->host = $data['host'];
+ $this->defaults = $data['defaults'];
+ $this->requirements = $data['requirements'];
+ $this->options = $data['options'];
+ $this->schemes = $data['schemes'];
+ $this->methods = $data['methods'];
+
+ if (isset($data['condition'])) {
+ $this->condition = $data['condition'];
+ }
+ if (isset($data['compiled'])) {
+ $this->compiled = $data['compiled'];
+ }
+ }
+
+ /**
+ * Returns the pattern for the path.
+ *
+ * @return string The path pattern
+ */
+ public function getPath()
+ {
+ return $this->path;
+ }
+
+ /**
+ * Sets the pattern for the path.
+ *
+ * This method implements a fluent interface.
+ *
+ * @param string $pattern The path pattern
+ *
+ * @return $this
+ */
+ public function setPath($pattern)
+ {
+ // A pattern must start with a slash and must not have multiple slashes at the beginning because the
+ // generated path for this route would be confused with a network path, e.g. '//domain.com/path'.
+ $this->path = '/'.ltrim(trim($pattern), '/');
+ $this->compiled = null;
+
+ return $this;
+ }
+
+ /**
+ * Returns the pattern for the host.
+ *
+ * @return string The host pattern
+ */
+ public function getHost()
+ {
+ return $this->host;
+ }
+
+ /**
+ * Sets the pattern for the host.
+ *
+ * This method implements a fluent interface.
+ *
+ * @param string $pattern The host pattern
+ *
+ * @return $this
+ */
+ public function setHost($pattern)
+ {
+ $this->host = (string) $pattern;
+ $this->compiled = null;
+
+ return $this;
+ }
+
+ /**
+ * Returns the lowercased schemes this route is restricted to.
+ * So an empty array means that any scheme is allowed.
+ *
+ * @return string[] The schemes
+ */
+ public function getSchemes()
+ {
+ return $this->schemes;
+ }
+
+ /**
+ * Sets the schemes (e.g. 'https') this route is restricted to.
+ * So an empty array means that any scheme is allowed.
+ *
+ * This method implements a fluent interface.
+ *
+ * @param string|string[] $schemes The scheme or an array of schemes
+ *
+ * @return $this
+ */
+ public function setSchemes($schemes)
+ {
+ $this->schemes = array_map('strtolower', (array) $schemes);
+ $this->compiled = null;
+
+ return $this;
+ }
+
+ /**
+ * Checks if a scheme requirement has been set.
+ *
+ * @param string $scheme
+ *
+ * @return bool true if the scheme requirement exists, otherwise false
+ */
+ public function hasScheme($scheme)
+ {
+ return in_array(strtolower($scheme), $this->schemes, true);
+ }
+
+ /**
+ * Returns the uppercased HTTP methods this route is restricted to.
+ * So an empty array means that any method is allowed.
+ *
+ * @return string[] The methods
+ */
+ public function getMethods()
+ {
+ return $this->methods;
+ }
+
+ /**
+ * Sets the HTTP methods (e.g. 'POST') this route is restricted to.
+ * So an empty array means that any method is allowed.
+ *
+ * This method implements a fluent interface.
+ *
+ * @param string|string[] $methods The method or an array of methods
+ *
+ * @return $this
+ */
+ public function setMethods($methods)
+ {
+ $this->methods = array_map('strtoupper', (array) $methods);
+ $this->compiled = null;
+
+ return $this;
+ }
+
+ /**
+ * Returns the options.
+ *
+ * @return array The options
+ */
+ public function getOptions()
+ {
+ return $this->options;
+ }
+
+ /**
+ * Sets the options.
+ *
+ * This method implements a fluent interface.
+ *
+ * @param array $options The options
+ *
+ * @return $this
+ */
+ public function setOptions(array $options)
+ {
+ $this->options = array(
+ 'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler',
+ );
+
+ return $this->addOptions($options);
+ }
+
+ /**
+ * Adds options.
+ *
+ * This method implements a fluent interface.
+ *
+ * @param array $options The options
+ *
+ * @return $this
+ */
+ public function addOptions(array $options)
+ {
+ foreach ($options as $name => $option) {
+ $this->options[$name] = $option;
+ }
+ $this->compiled = null;
+
+ return $this;
+ }
+
+ /**
+ * Sets an option value.
+ *
+ * This method implements a fluent interface.
+ *
+ * @param string $name An option name
+ * @param mixed $value The option value
+ *
+ * @return $this
+ */
+ public function setOption($name, $value)
+ {
+ $this->options[$name] = $value;
+ $this->compiled = null;
+
+ return $this;
+ }
+
+ /**
+ * Get an option value.
+ *
+ * @param string $name An option name
+ *
+ * @return mixed The option value or null when not given
+ */
+ public function getOption($name)
+ {
+ return isset($this->options[$name]) ? $this->options[$name] : null;
+ }
+
+ /**
+ * Checks if an option has been set.
+ *
+ * @param string $name An option name
+ *
+ * @return bool true if the option is set, false otherwise
+ */
+ public function hasOption($name)
+ {
+ return array_key_exists($name, $this->options);
+ }
+
+ /**
+ * Returns the defaults.
+ *
+ * @return array The defaults
+ */
+ public function getDefaults()
+ {
+ return $this->defaults;
+ }
+
+ /**
+ * Sets the defaults.
+ *
+ * This method implements a fluent interface.
+ *
+ * @param array $defaults The defaults
+ *
+ * @return $this
+ */
+ public function setDefaults(array $defaults)
+ {
+ $this->defaults = array();
+
+ return $this->addDefaults($defaults);
+ }
+
+ /**
+ * Adds defaults.
+ *
+ * This method implements a fluent interface.
+ *
+ * @param array $defaults The defaults
+ *
+ * @return $this
+ */
+ public function addDefaults(array $defaults)
+ {
+ foreach ($defaults as $name => $default) {
+ $this->defaults[$name] = $default;
+ }
+ $this->compiled = null;
+
+ return $this;
+ }
+
+ /**
+ * Gets a default value.
+ *
+ * @param string $name A variable name
+ *
+ * @return mixed The default value or null when not given
+ */
+ public function getDefault($name)
+ {
+ return isset($this->defaults[$name]) ? $this->defaults[$name] : null;
+ }
+
+ /**
+ * Checks if a default value is set for the given variable.
+ *
+ * @param string $name A variable name
+ *
+ * @return bool true if the default value is set, false otherwise
+ */
+ public function hasDefault($name)
+ {
+ return array_key_exists($name, $this->defaults);
+ }
+
+ /**
+ * Sets a default value.
+ *
+ * @param string $name A variable name
+ * @param mixed $default The default value
+ *
+ * @return $this
+ */
+ public function setDefault($name, $default)
+ {
+ $this->defaults[$name] = $default;
+ $this->compiled = null;
+
+ return $this;
+ }
+
+ /**
+ * Returns the requirements.
+ *
+ * @return array The requirements
+ */
+ public function getRequirements()
+ {
+ return $this->requirements;
+ }
+
+ /**
+ * Sets the requirements.
+ *
+ * This method implements a fluent interface.
+ *
+ * @param array $requirements The requirements
+ *
+ * @return $this
+ */
+ public function setRequirements(array $requirements)
+ {
+ $this->requirements = array();
+
+ return $this->addRequirements($requirements);
+ }
+
+ /**
+ * Adds requirements.
+ *
+ * This method implements a fluent interface.
+ *
+ * @param array $requirements The requirements
+ *
+ * @return $this
+ */
+ public function addRequirements(array $requirements)
+ {
+ foreach ($requirements as $key => $regex) {
+ $this->requirements[$key] = $this->sanitizeRequirement($key, $regex);
+ }
+ $this->compiled = null;
+
+ return $this;
+ }
+
+ /**
+ * Returns the requirement for the given key.
+ *
+ * @param string $key The key
+ *
+ * @return string|null The regex or null when not given
+ */
+ public function getRequirement($key)
+ {
+ return isset($this->requirements[$key]) ? $this->requirements[$key] : null;
+ }
+
+ /**
+ * Checks if a requirement is set for the given key.
+ *
+ * @param string $key A variable name
+ *
+ * @return bool true if a requirement is specified, false otherwise
+ */
+ public function hasRequirement($key)
+ {
+ return array_key_exists($key, $this->requirements);
+ }
+
+ /**
+ * Sets a requirement for the given key.
+ *
+ * @param string $key The key
+ * @param string $regex The regex
+ *
+ * @return $this
+ */
+ public function setRequirement($key, $regex)
+ {
+ $this->requirements[$key] = $this->sanitizeRequirement($key, $regex);
+ $this->compiled = null;
+
+ return $this;
+ }
+
+ /**
+ * Returns the condition.
+ *
+ * @return string The condition
+ */
+ public function getCondition()
+ {
+ return $this->condition;
+ }
+
+ /**
+ * Sets the condition.
+ *
+ * This method implements a fluent interface.
+ *
+ * @param string $condition The condition
+ *
+ * @return $this
+ */
+ public function setCondition($condition)
+ {
+ $this->condition = (string) $condition;
+ $this->compiled = null;
+
+ return $this;
+ }
+
+ /**
+ * Compiles the route.
+ *
+ * @return CompiledRoute A CompiledRoute instance
+ *
+ * @throws \LogicException If the Route cannot be compiled because the
+ * path or host pattern is invalid
+ *
+ * @see RouteCompiler which is responsible for the compilation process
+ */
+ public function compile()
+ {
+ if (null !== $this->compiled) {
+ return $this->compiled;
+ }
+
+ $class = $this->getOption('compiler_class');
+
+ return $this->compiled = $class::compile($this);
+ }
+
+ private function sanitizeRequirement($key, $regex)
+ {
+ if (!is_string($regex)) {
+ throw new \InvalidArgumentException(sprintf('Routing requirement for "%s" must be a string.', $key));
+ }
+
+ if ('' !== $regex && '^' === $regex[0]) {
+ $regex = (string) substr($regex, 1); // returns false for a single character
+ }
+
+ if ('$' === substr($regex, -1)) {
+ $regex = substr($regex, 0, -1);
+ }
+
+ if ('' === $regex) {
+ throw new \InvalidArgumentException(sprintf('Routing requirement for "%s" cannot be empty.', $key));
+ }
+
+ return $regex;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/RouteCollection.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/RouteCollection.php
new file mode 100644
index 0000000..e22cbc5
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/RouteCollection.php
@@ -0,0 +1,280 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing;
+
+use Symfony\Component\Config\Resource\ResourceInterface;
+
+/**
+ * A RouteCollection represents a set of Route instances.
+ *
+ * When adding a route at the end of the collection, an existing route
+ * with the same name is removed first. So there can only be one route
+ * with a given name.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Tobias Schultze <http://tobion.de>
+ */
+class RouteCollection implements \IteratorAggregate, \Countable
+{
+ /**
+ * @var Route[]
+ */
+ private $routes = array();
+
+ /**
+ * @var array
+ */
+ private $resources = array();
+
+ public function __clone()
+ {
+ foreach ($this->routes as $name => $route) {
+ $this->routes[$name] = clone $route;
+ }
+ }
+
+ /**
+ * Gets the current RouteCollection as an Iterator that includes all routes.
+ *
+ * It implements \IteratorAggregate.
+ *
+ * @see all()
+ *
+ * @return \ArrayIterator|Route[] An \ArrayIterator object for iterating over routes
+ */
+ public function getIterator()
+ {
+ return new \ArrayIterator($this->routes);
+ }
+
+ /**
+ * Gets the number of Routes in this collection.
+ *
+ * @return int The number of routes
+ */
+ public function count()
+ {
+ return count($this->routes);
+ }
+
+ /**
+ * Adds a route.
+ *
+ * @param string $name The route name
+ * @param Route $route A Route instance
+ */
+ public function add($name, Route $route)
+ {
+ unset($this->routes[$name]);
+
+ $this->routes[$name] = $route;
+ }
+
+ /**
+ * Returns all routes in this collection.
+ *
+ * @return Route[] An array of routes
+ */
+ public function all()
+ {
+ return $this->routes;
+ }
+
+ /**
+ * Gets a route by name.
+ *
+ * @param string $name The route name
+ *
+ * @return Route|null A Route instance or null when not found
+ */
+ public function get($name)
+ {
+ return isset($this->routes[$name]) ? $this->routes[$name] : null;
+ }
+
+ /**
+ * Removes a route or an array of routes by name from the collection.
+ *
+ * @param string|string[] $name The route name or an array of route names
+ */
+ public function remove($name)
+ {
+ foreach ((array) $name as $n) {
+ unset($this->routes[$n]);
+ }
+ }
+
+ /**
+ * Adds a route collection at the end of the current set by appending all
+ * routes of the added collection.
+ */
+ public function addCollection(self $collection)
+ {
+ // we need to remove all routes with the same names first because just replacing them
+ // would not place the new route at the end of the merged array
+ foreach ($collection->all() as $name => $route) {
+ unset($this->routes[$name]);
+ $this->routes[$name] = $route;
+ }
+
+ foreach ($collection->getResources() as $resource) {
+ $this->addResource($resource);
+ }
+ }
+
+ /**
+ * Adds a prefix to the path of all child routes.
+ *
+ * @param string $prefix An optional prefix to add before each pattern of the route collection
+ * @param array $defaults An array of default values
+ * @param array $requirements An array of requirements
+ */
+ public function addPrefix($prefix, array $defaults = array(), array $requirements = array())
+ {
+ $prefix = trim(trim($prefix), '/');
+
+ if ('' === $prefix) {
+ return;
+ }
+
+ foreach ($this->routes as $route) {
+ $route->setPath('/'.$prefix.$route->getPath());
+ $route->addDefaults($defaults);
+ $route->addRequirements($requirements);
+ }
+ }
+
+ /**
+ * Sets the host pattern on all routes.
+ *
+ * @param string $pattern The pattern
+ * @param array $defaults An array of default values
+ * @param array $requirements An array of requirements
+ */
+ public function setHost($pattern, array $defaults = array(), array $requirements = array())
+ {
+ foreach ($this->routes as $route) {
+ $route->setHost($pattern);
+ $route->addDefaults($defaults);
+ $route->addRequirements($requirements);
+ }
+ }
+
+ /**
+ * Sets a condition on all routes.
+ *
+ * Existing conditions will be overridden.
+ *
+ * @param string $condition The condition
+ */
+ public function setCondition($condition)
+ {
+ foreach ($this->routes as $route) {
+ $route->setCondition($condition);
+ }
+ }
+
+ /**
+ * Adds defaults to all routes.
+ *
+ * An existing default value under the same name in a route will be overridden.
+ *
+ * @param array $defaults An array of default values
+ */
+ public function addDefaults(array $defaults)
+ {
+ if ($defaults) {
+ foreach ($this->routes as $route) {
+ $route->addDefaults($defaults);
+ }
+ }
+ }
+
+ /**
+ * Adds requirements to all routes.
+ *
+ * An existing requirement under the same name in a route will be overridden.
+ *
+ * @param array $requirements An array of requirements
+ */
+ public function addRequirements(array $requirements)
+ {
+ if ($requirements) {
+ foreach ($this->routes as $route) {
+ $route->addRequirements($requirements);
+ }
+ }
+ }
+
+ /**
+ * Adds options to all routes.
+ *
+ * An existing option value under the same name in a route will be overridden.
+ *
+ * @param array $options An array of options
+ */
+ public function addOptions(array $options)
+ {
+ if ($options) {
+ foreach ($this->routes as $route) {
+ $route->addOptions($options);
+ }
+ }
+ }
+
+ /**
+ * Sets the schemes (e.g. 'https') all child routes are restricted to.
+ *
+ * @param string|string[] $schemes The scheme or an array of schemes
+ */
+ public function setSchemes($schemes)
+ {
+ foreach ($this->routes as $route) {
+ $route->setSchemes($schemes);
+ }
+ }
+
+ /**
+ * Sets the HTTP methods (e.g. 'POST') all child routes are restricted to.
+ *
+ * @param string|string[] $methods The method or an array of methods
+ */
+ public function setMethods($methods)
+ {
+ foreach ($this->routes as $route) {
+ $route->setMethods($methods);
+ }
+ }
+
+ /**
+ * Returns an array of resources loaded to build this collection.
+ *
+ * @return ResourceInterface[] An array of resources
+ */
+ public function getResources()
+ {
+ return array_values($this->resources);
+ }
+
+ /**
+ * Adds a resource for this collection. If the resource already exists
+ * it is not added.
+ */
+ public function addResource(ResourceInterface $resource)
+ {
+ $key = (string) $resource;
+
+ if (!isset($this->resources[$key])) {
+ $this->resources[$key] = $resource;
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/RouteCollectionBuilder.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/RouteCollectionBuilder.php
new file mode 100644
index 0000000..e8a9a16
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/RouteCollectionBuilder.php
@@ -0,0 +1,380 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing;
+
+use Symfony\Component\Config\Exception\FileLoaderLoadException;
+use Symfony\Component\Config\Loader\LoaderInterface;
+use Symfony\Component\Config\Resource\ResourceInterface;
+
+/**
+ * Helps add and import routes into a RouteCollection.
+ *
+ * @author Ryan Weaver <ryan@knpuniversity.com>
+ */
+class RouteCollectionBuilder
+{
+ /**
+ * @var Route[]|RouteCollectionBuilder[]
+ */
+ private $routes = array();
+
+ private $loader;
+ private $defaults = array();
+ private $prefix;
+ private $host;
+ private $condition;
+ private $requirements = array();
+ private $options = array();
+ private $schemes;
+ private $methods;
+ private $resources = array();
+
+ public function __construct(LoaderInterface $loader = null)
+ {
+ $this->loader = $loader;
+ }
+
+ /**
+ * Import an external routing resource and returns the RouteCollectionBuilder.
+ *
+ * $routes->import('blog.yml', '/blog');
+ *
+ * @param mixed $resource
+ * @param string|null $prefix
+ * @param string $type
+ *
+ * @return self
+ *
+ * @throws FileLoaderLoadException
+ */
+ public function import($resource, $prefix = '/', $type = null)
+ {
+ /** @var RouteCollection[] $collection */
+ $collections = $this->load($resource, $type);
+
+ // create a builder from the RouteCollection
+ $builder = $this->createBuilder();
+
+ foreach ($collections as $collection) {
+ if (null === $collection) {
+ continue;
+ }
+
+ foreach ($collection->all() as $name => $route) {
+ $builder->addRoute($route, $name);
+ }
+
+ foreach ($collection->getResources() as $resource) {
+ $builder->addResource($resource);
+ }
+ }
+
+ // mount into this builder
+ $this->mount($prefix, $builder);
+
+ return $builder;
+ }
+
+ /**
+ * Adds a route and returns it for future modification.
+ *
+ * @param string $path The route path
+ * @param string $controller The route's controller
+ * @param string|null $name The name to give this route
+ *
+ * @return Route
+ */
+ public function add($path, $controller, $name = null)
+ {
+ $route = new Route($path);
+ $route->setDefault('_controller', $controller);
+ $this->addRoute($route, $name);
+
+ return $route;
+ }
+
+ /**
+ * Returns a RouteCollectionBuilder that can be configured and then added with mount().
+ *
+ * @return self
+ */
+ public function createBuilder()
+ {
+ return new self($this->loader);
+ }
+
+ /**
+ * Add a RouteCollectionBuilder.
+ *
+ * @param string $prefix
+ * @param RouteCollectionBuilder $builder
+ */
+ public function mount($prefix, RouteCollectionBuilder $builder)
+ {
+ $builder->prefix = trim(trim($prefix), '/');
+ $this->routes[] = $builder;
+ }
+
+ /**
+ * Adds a Route object to the builder.
+ *
+ * @param Route $route
+ * @param string|null $name
+ *
+ * @return $this
+ */
+ public function addRoute(Route $route, $name = null)
+ {
+ if (null === $name) {
+ // used as a flag to know which routes will need a name later
+ $name = '_unnamed_route_'.spl_object_hash($route);
+ }
+
+ $this->routes[$name] = $route;
+
+ return $this;
+ }
+
+ /**
+ * Sets the host on all embedded routes (unless already set).
+ *
+ * @param string $pattern
+ *
+ * @return $this
+ */
+ public function setHost($pattern)
+ {
+ $this->host = $pattern;
+
+ return $this;
+ }
+
+ /**
+ * Sets a condition on all embedded routes (unless already set).
+ *
+ * @param string $condition
+ *
+ * @return $this
+ */
+ public function setCondition($condition)
+ {
+ $this->condition = $condition;
+
+ return $this;
+ }
+
+ /**
+ * Sets a default value that will be added to all embedded routes (unless that
+ * default value is already set).
+ *
+ * @param string $key
+ * @param mixed $value
+ *
+ * @return $this
+ */
+ public function setDefault($key, $value)
+ {
+ $this->defaults[$key] = $value;
+
+ return $this;
+ }
+
+ /**
+ * Sets a requirement that will be added to all embedded routes (unless that
+ * requirement is already set).
+ *
+ * @param string $key
+ * @param mixed $regex
+ *
+ * @return $this
+ */
+ public function setRequirement($key, $regex)
+ {
+ $this->requirements[$key] = $regex;
+
+ return $this;
+ }
+
+ /**
+ * Sets an option that will be added to all embedded routes (unless that
+ * option is already set).
+ *
+ * @param string $key
+ * @param mixed $value
+ *
+ * @return $this
+ */
+ public function setOption($key, $value)
+ {
+ $this->options[$key] = $value;
+
+ return $this;
+ }
+
+ /**
+ * Sets the schemes on all embedded routes (unless already set).
+ *
+ * @param array|string $schemes
+ *
+ * @return $this
+ */
+ public function setSchemes($schemes)
+ {
+ $this->schemes = $schemes;
+
+ return $this;
+ }
+
+ /**
+ * Sets the methods on all embedded routes (unless already set).
+ *
+ * @param array|string $methods
+ *
+ * @return $this
+ */
+ public function setMethods($methods)
+ {
+ $this->methods = $methods;
+
+ return $this;
+ }
+
+ /**
+ * Adds a resource for this collection.
+ *
+ * @param ResourceInterface $resource
+ *
+ * @return $this
+ */
+ private function addResource(ResourceInterface $resource)
+ {
+ $this->resources[] = $resource;
+
+ return $this;
+ }
+
+ /**
+ * Creates the final RouteCollection and returns it.
+ *
+ * @return RouteCollection
+ */
+ public function build()
+ {
+ $routeCollection = new RouteCollection();
+
+ foreach ($this->routes as $name => $route) {
+ if ($route instanceof Route) {
+ $route->setDefaults(array_merge($this->defaults, $route->getDefaults()));
+ $route->setOptions(array_merge($this->options, $route->getOptions()));
+
+ foreach ($this->requirements as $key => $val) {
+ if (!$route->hasRequirement($key)) {
+ $route->setRequirement($key, $val);
+ }
+ }
+
+ if (null !== $this->prefix) {
+ $route->setPath('/'.$this->prefix.$route->getPath());
+ }
+
+ if (!$route->getHost()) {
+ $route->setHost($this->host);
+ }
+
+ if (!$route->getCondition()) {
+ $route->setCondition($this->condition);
+ }
+
+ if (!$route->getSchemes()) {
+ $route->setSchemes($this->schemes);
+ }
+
+ if (!$route->getMethods()) {
+ $route->setMethods($this->methods);
+ }
+
+ // auto-generate the route name if it's been marked
+ if ('_unnamed_route_' === substr($name, 0, 15)) {
+ $name = $this->generateRouteName($route);
+ }
+
+ $routeCollection->add($name, $route);
+ } else {
+ /* @var self $route */
+ $subCollection = $route->build();
+ $subCollection->addPrefix($this->prefix);
+
+ $routeCollection->addCollection($subCollection);
+ }
+ }
+
+ foreach ($this->resources as $resource) {
+ $routeCollection->addResource($resource);
+ }
+
+ return $routeCollection;
+ }
+
+ /**
+ * Generates a route name based on details of this route.
+ *
+ * @return string
+ */
+ private function generateRouteName(Route $route)
+ {
+ $methods = implode('_', $route->getMethods()).'_';
+
+ $routeName = $methods.$route->getPath();
+ $routeName = str_replace(array('/', ':', '|', '-'), '_', $routeName);
+ $routeName = preg_replace('/[^a-z0-9A-Z_.]+/', '', $routeName);
+
+ // Collapse consecutive underscores down into a single underscore.
+ $routeName = preg_replace('/_+/', '_', $routeName);
+
+ return $routeName;
+ }
+
+ /**
+ * Finds a loader able to load an imported resource and loads it.
+ *
+ * @param mixed $resource A resource
+ * @param string|null $type The resource type or null if unknown
+ *
+ * @return RouteCollection[]
+ *
+ * @throws FileLoaderLoadException If no loader is found
+ */
+ private function load($resource, $type = null)
+ {
+ if (null === $this->loader) {
+ throw new \BadMethodCallException('Cannot import other routing resources: you must pass a LoaderInterface when constructing RouteCollectionBuilder.');
+ }
+
+ if ($this->loader->supports($resource, $type)) {
+ $collections = $this->loader->load($resource, $type);
+
+ return is_array($collections) ? $collections : array($collections);
+ }
+
+ if (null === $resolver = $this->loader->getResolver()) {
+ throw new FileLoaderLoadException($resource, null, null, null, $type);
+ }
+
+ if (false === $loader = $resolver->resolve($resource, $type)) {
+ throw new FileLoaderLoadException($resource, null, null, null, $type);
+ }
+
+ $collections = $loader->load($resource, $type);
+
+ return is_array($collections) ? $collections : array($collections);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/RouteCompiler.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/RouteCompiler.php
new file mode 100644
index 0000000..dc4e4f8
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/RouteCompiler.php
@@ -0,0 +1,316 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing;
+
+/**
+ * RouteCompiler compiles Route instances to CompiledRoute instances.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Tobias Schultze <http://tobion.de>
+ */
+class RouteCompiler implements RouteCompilerInterface
+{
+ const REGEX_DELIMITER = '#';
+
+ /**
+ * This string defines the characters that are automatically considered separators in front of
+ * optional placeholders (with default and no static text following). Such a single separator
+ * can be left out together with the optional placeholder from matching and generating URLs.
+ */
+ const SEPARATORS = '/,;.:-_~+*=@|';
+
+ /**
+ * The maximum supported length of a PCRE subpattern name
+ * http://pcre.org/current/doc/html/pcre2pattern.html#SEC16.
+ *
+ * @internal
+ */
+ const VARIABLE_MAXIMUM_LENGTH = 32;
+
+ /**
+ * {@inheritdoc}
+ *
+ * @throws \InvalidArgumentException if a path variable is named _fragment
+ * @throws \LogicException if a variable is referenced more than once
+ * @throws \DomainException if a variable name starts with a digit or if it is too long to be successfully used as
+ * a PCRE subpattern
+ */
+ public static function compile(Route $route)
+ {
+ $hostVariables = array();
+ $variables = array();
+ $hostRegex = null;
+ $hostTokens = array();
+
+ if ('' !== $host = $route->getHost()) {
+ $result = self::compilePattern($route, $host, true);
+
+ $hostVariables = $result['variables'];
+ $variables = $hostVariables;
+
+ $hostTokens = $result['tokens'];
+ $hostRegex = $result['regex'];
+ }
+
+ $path = $route->getPath();
+
+ $result = self::compilePattern($route, $path, false);
+
+ $staticPrefix = $result['staticPrefix'];
+
+ $pathVariables = $result['variables'];
+
+ foreach ($pathVariables as $pathParam) {
+ if ('_fragment' === $pathParam) {
+ throw new \InvalidArgumentException(sprintf('Route pattern "%s" cannot contain "_fragment" as a path parameter.', $route->getPath()));
+ }
+ }
+
+ $variables = array_merge($variables, $pathVariables);
+
+ $tokens = $result['tokens'];
+ $regex = $result['regex'];
+
+ return new CompiledRoute(
+ $staticPrefix,
+ $regex,
+ $tokens,
+ $pathVariables,
+ $hostRegex,
+ $hostTokens,
+ $hostVariables,
+ array_unique($variables)
+ );
+ }
+
+ private static function compilePattern(Route $route, $pattern, $isHost)
+ {
+ $tokens = array();
+ $variables = array();
+ $matches = array();
+ $pos = 0;
+ $defaultSeparator = $isHost ? '.' : '/';
+ $useUtf8 = preg_match('//u', $pattern);
+ $needsUtf8 = $route->getOption('utf8');
+
+ if (!$needsUtf8 && $useUtf8 && preg_match('/[\x80-\xFF]/', $pattern)) {
+ $needsUtf8 = true;
+ @trigger_error(sprintf('Using UTF-8 route patterns without setting the "utf8" option is deprecated since Symfony 3.2 and will throw a LogicException in 4.0. Turn on the "utf8" route option for pattern "%s".', $pattern), E_USER_DEPRECATED);
+ }
+ if (!$useUtf8 && $needsUtf8) {
+ throw new \LogicException(sprintf('Cannot mix UTF-8 requirements with non-UTF-8 pattern "%s".', $pattern));
+ }
+
+ // Match all variables enclosed in "{}" and iterate over them. But we only want to match the innermost variable
+ // in case of nested "{}", e.g. {foo{bar}}. This in ensured because \w does not match "{" or "}" itself.
+ preg_match_all('#\{\w+\}#', $pattern, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
+ foreach ($matches as $match) {
+ $varName = substr($match[0][0], 1, -1);
+ // get all static text preceding the current variable
+ $precedingText = substr($pattern, $pos, $match[0][1] - $pos);
+ $pos = $match[0][1] + strlen($match[0][0]);
+
+ if (!strlen($precedingText)) {
+ $precedingChar = '';
+ } elseif ($useUtf8) {
+ preg_match('/.$/u', $precedingText, $precedingChar);
+ $precedingChar = $precedingChar[0];
+ } else {
+ $precedingChar = substr($precedingText, -1);
+ }
+ $isSeparator = '' !== $precedingChar && false !== strpos(static::SEPARATORS, $precedingChar);
+
+ // A PCRE subpattern name must start with a non-digit. Also a PHP variable cannot start with a digit so the
+ // variable would not be usable as a Controller action argument.
+ if (preg_match('/^\d/', $varName)) {
+ throw new \DomainException(sprintf('Variable name "%s" cannot start with a digit in route pattern "%s". Please use a different name.', $varName, $pattern));
+ }
+ if (in_array($varName, $variables)) {
+ throw new \LogicException(sprintf('Route pattern "%s" cannot reference variable name "%s" more than once.', $pattern, $varName));
+ }
+
+ if (strlen($varName) > self::VARIABLE_MAXIMUM_LENGTH) {
+ throw new \DomainException(sprintf('Variable name "%s" cannot be longer than %s characters in route pattern "%s". Please use a shorter name.', $varName, self::VARIABLE_MAXIMUM_LENGTH, $pattern));
+ }
+
+ if ($isSeparator && $precedingText !== $precedingChar) {
+ $tokens[] = array('text', substr($precedingText, 0, -strlen($precedingChar)));
+ } elseif (!$isSeparator && strlen($precedingText) > 0) {
+ $tokens[] = array('text', $precedingText);
+ }
+
+ $regexp = $route->getRequirement($varName);
+ if (null === $regexp) {
+ $followingPattern = (string) substr($pattern, $pos);
+ // Find the next static character after the variable that functions as a separator. By default, this separator and '/'
+ // are disallowed for the variable. This default requirement makes sure that optional variables can be matched at all
+ // and that the generating-matching-combination of URLs unambiguous, i.e. the params used for generating the URL are
+ // the same that will be matched. Example: new Route('/{page}.{_format}', array('_format' => 'html'))
+ // If {page} would also match the separating dot, {_format} would never match as {page} will eagerly consume everything.
+ // Also even if {_format} was not optional the requirement prevents that {page} matches something that was originally
+ // part of {_format} when generating the URL, e.g. _format = 'mobile.html'.
+ $nextSeparator = self::findNextSeparator($followingPattern, $useUtf8);
+ $regexp = sprintf(
+ '[^%s%s]+',
+ preg_quote($defaultSeparator, self::REGEX_DELIMITER),
+ $defaultSeparator !== $nextSeparator && '' !== $nextSeparator ? preg_quote($nextSeparator, self::REGEX_DELIMITER) : ''
+ );
+ if (('' !== $nextSeparator && !preg_match('#^\{\w+\}#', $followingPattern)) || '' === $followingPattern) {
+ // When we have a separator, which is disallowed for the variable, we can optimize the regex with a possessive
+ // quantifier. This prevents useless backtracking of PCRE and improves performance by 20% for matching those patterns.
+ // Given the above example, there is no point in backtracking into {page} (that forbids the dot) when a dot must follow
+ // after it. This optimization cannot be applied when the next char is no real separator or when the next variable is
+ // directly adjacent, e.g. '/{x}{y}'.
+ $regexp .= '+';
+ }
+ } else {
+ if (!preg_match('//u', $regexp)) {
+ $useUtf8 = false;
+ } elseif (!$needsUtf8 && preg_match('/[\x80-\xFF]|(?<!\\\\)\\\\(?:\\\\\\\\)*+(?-i:X|[pP][\{CLMNPSZ]|x\{[A-Fa-f0-9]{3})/', $regexp)) {
+ $needsUtf8 = true;
+ @trigger_error(sprintf('Using UTF-8 route requirements without setting the "utf8" option is deprecated since Symfony 3.2 and will throw a LogicException in 4.0. Turn on the "utf8" route option for variable "%s" in pattern "%s".', $varName, $pattern), E_USER_DEPRECATED);
+ }
+ if (!$useUtf8 && $needsUtf8) {
+ throw new \LogicException(sprintf('Cannot mix UTF-8 requirement with non-UTF-8 charset for variable "%s" in pattern "%s".', $varName, $pattern));
+ }
+ }
+
+ $tokens[] = array('variable', $isSeparator ? $precedingChar : '', $regexp, $varName);
+ $variables[] = $varName;
+ }
+
+ if ($pos < strlen($pattern)) {
+ $tokens[] = array('text', substr($pattern, $pos));
+ }
+
+ // find the first optional token
+ $firstOptional = PHP_INT_MAX;
+ if (!$isHost) {
+ for ($i = count($tokens) - 1; $i >= 0; --$i) {
+ $token = $tokens[$i];
+ if ('variable' === $token[0] && $route->hasDefault($token[3])) {
+ $firstOptional = $i;
+ } else {
+ break;
+ }
+ }
+ }
+
+ // compute the matching regexp
+ $regexp = '';
+ for ($i = 0, $nbToken = count($tokens); $i < $nbToken; ++$i) {
+ $regexp .= self::computeRegexp($tokens, $i, $firstOptional);
+ }
+ $regexp = self::REGEX_DELIMITER.'^'.$regexp.'$'.self::REGEX_DELIMITER.'sD'.($isHost ? 'i' : '');
+
+ // enable Utf8 matching if really required
+ if ($needsUtf8) {
+ $regexp .= 'u';
+ for ($i = 0, $nbToken = count($tokens); $i < $nbToken; ++$i) {
+ if ('variable' === $tokens[$i][0]) {
+ $tokens[$i][] = true;
+ }
+ }
+ }
+
+ return array(
+ 'staticPrefix' => self::determineStaticPrefix($route, $tokens),
+ 'regex' => $regexp,
+ 'tokens' => array_reverse($tokens),
+ 'variables' => $variables,
+ );
+ }
+
+ /**
+ * Determines the longest static prefix possible for a route.
+ *
+ * @return string The leading static part of a route's path
+ */
+ private static function determineStaticPrefix(Route $route, array $tokens)
+ {
+ if ('text' !== $tokens[0][0]) {
+ return ($route->hasDefault($tokens[0][3]) || '/' === $tokens[0][1]) ? '' : $tokens[0][1];
+ }
+
+ $prefix = $tokens[0][1];
+
+ if (isset($tokens[1][1]) && '/' !== $tokens[1][1] && false === $route->hasDefault($tokens[1][3])) {
+ $prefix .= $tokens[1][1];
+ }
+
+ return $prefix;
+ }
+
+ /**
+ * Returns the next static character in the Route pattern that will serve as a separator.
+ *
+ * @param string $pattern The route pattern
+ * @param bool $useUtf8 Whether the character is encoded in UTF-8 or not
+ *
+ * @return string The next static character that functions as separator (or empty string when none available)
+ */
+ private static function findNextSeparator($pattern, $useUtf8)
+ {
+ if ('' == $pattern) {
+ // return empty string if pattern is empty or false (false which can be returned by substr)
+ return '';
+ }
+ // first remove all placeholders from the pattern so we can find the next real static character
+ if ('' === $pattern = preg_replace('#\{\w+\}#', '', $pattern)) {
+ return '';
+ }
+ if ($useUtf8) {
+ preg_match('/^./u', $pattern, $pattern);
+ }
+
+ return false !== strpos(static::SEPARATORS, $pattern[0]) ? $pattern[0] : '';
+ }
+
+ /**
+ * Computes the regexp used to match a specific token. It can be static text or a subpattern.
+ *
+ * @param array $tokens The route tokens
+ * @param int $index The index of the current token
+ * @param int $firstOptional The index of the first optional token
+ *
+ * @return string The regexp pattern for a single token
+ */
+ private static function computeRegexp(array $tokens, $index, $firstOptional)
+ {
+ $token = $tokens[$index];
+ if ('text' === $token[0]) {
+ // Text tokens
+ return preg_quote($token[1], self::REGEX_DELIMITER);
+ } else {
+ // Variable tokens
+ if (0 === $index && 0 === $firstOptional) {
+ // When the only token is an optional variable token, the separator is required
+ return sprintf('%s(?P<%s>%s)?', preg_quote($token[1], self::REGEX_DELIMITER), $token[3], $token[2]);
+ } else {
+ $regexp = sprintf('%s(?P<%s>%s)', preg_quote($token[1], self::REGEX_DELIMITER), $token[3], $token[2]);
+ if ($index >= $firstOptional) {
+ // Enclose each optional token in a subpattern to make it optional.
+ // "?:" means it is non-capturing, i.e. the portion of the subject string that
+ // matched the optional subpattern is not passed back.
+ $regexp = "(?:$regexp";
+ $nbTokens = count($tokens);
+ if ($nbTokens - 1 == $index) {
+ // Close the optional subpatterns
+ $regexp .= str_repeat(')?', $nbTokens - $firstOptional - (0 === $firstOptional ? 1 : 0));
+ }
+ }
+
+ return $regexp;
+ }
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/RouteCompilerInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/RouteCompilerInterface.php
new file mode 100644
index 0000000..ddfa7ca
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/RouteCompilerInterface.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing;
+
+/**
+ * RouteCompilerInterface is the interface that all RouteCompiler classes must implement.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface RouteCompilerInterface
+{
+ /**
+ * Compiles the current route instance.
+ *
+ * @return CompiledRoute A CompiledRoute instance
+ *
+ * @throws \LogicException If the Route cannot be compiled because the
+ * path or host pattern is invalid
+ */
+ public static function compile(Route $route);
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Router.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Router.php
new file mode 100644
index 0000000..ed56332
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Router.php
@@ -0,0 +1,388 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing;
+
+use Symfony\Component\Config\Loader\LoaderInterface;
+use Symfony\Component\Config\ConfigCacheInterface;
+use Symfony\Component\Config\ConfigCacheFactoryInterface;
+use Symfony\Component\Config\ConfigCacheFactory;
+use Psr\Log\LoggerInterface;
+use Symfony\Component\Routing\Generator\ConfigurableRequirementsInterface;
+use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
+use Symfony\Component\Routing\Generator\Dumper\GeneratorDumperInterface;
+use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
+use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
+use Symfony\Component\Routing\Matcher\Dumper\MatcherDumperInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
+
+/**
+ * The Router class is an example of the integration of all pieces of the
+ * routing system for easier use.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Router implements RouterInterface, RequestMatcherInterface
+{
+ /**
+ * @var UrlMatcherInterface|null
+ */
+ protected $matcher;
+
+ /**
+ * @var UrlGeneratorInterface|null
+ */
+ protected $generator;
+
+ /**
+ * @var RequestContext
+ */
+ protected $context;
+
+ /**
+ * @var LoaderInterface
+ */
+ protected $loader;
+
+ /**
+ * @var RouteCollection|null
+ */
+ protected $collection;
+
+ /**
+ * @var mixed
+ */
+ protected $resource;
+
+ /**
+ * @var array
+ */
+ protected $options = array();
+
+ /**
+ * @var LoggerInterface|null
+ */
+ protected $logger;
+
+ /**
+ * @var ConfigCacheFactoryInterface|null
+ */
+ private $configCacheFactory;
+
+ /**
+ * @var ExpressionFunctionProviderInterface[]
+ */
+ private $expressionLanguageProviders = array();
+
+ /**
+ * @param LoaderInterface $loader A LoaderInterface instance
+ * @param mixed $resource The main resource to load
+ * @param array $options An array of options
+ * @param RequestContext $context The context
+ * @param LoggerInterface $logger A logger instance
+ */
+ public function __construct(LoaderInterface $loader, $resource, array $options = array(), RequestContext $context = null, LoggerInterface $logger = null)
+ {
+ $this->loader = $loader;
+ $this->resource = $resource;
+ $this->logger = $logger;
+ $this->context = $context ?: new RequestContext();
+ $this->setOptions($options);
+ }
+
+ /**
+ * Sets options.
+ *
+ * Available options:
+ *
+ * * cache_dir: The cache directory (or null to disable caching)
+ * * debug: Whether to enable debugging or not (false by default)
+ * * generator_class: The name of a UrlGeneratorInterface implementation
+ * * generator_base_class: The base class for the dumped generator class
+ * * generator_cache_class: The class name for the dumped generator class
+ * * generator_dumper_class: The name of a GeneratorDumperInterface implementation
+ * * matcher_class: The name of a UrlMatcherInterface implementation
+ * * matcher_base_class: The base class for the dumped matcher class
+ * * matcher_dumper_class: The class name for the dumped matcher class
+ * * matcher_cache_class: The name of a MatcherDumperInterface implementation
+ * * resource_type: Type hint for the main resource (optional)
+ * * strict_requirements: Configure strict requirement checking for generators
+ * implementing ConfigurableRequirementsInterface (default is true)
+ *
+ * @param array $options An array of options
+ *
+ * @throws \InvalidArgumentException When unsupported option is provided
+ */
+ public function setOptions(array $options)
+ {
+ $this->options = array(
+ 'cache_dir' => null,
+ 'debug' => false,
+ 'generator_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator',
+ 'generator_base_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator',
+ 'generator_dumper_class' => 'Symfony\\Component\\Routing\\Generator\\Dumper\\PhpGeneratorDumper',
+ 'generator_cache_class' => 'ProjectUrlGenerator',
+ 'matcher_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher',
+ 'matcher_base_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher',
+ 'matcher_dumper_class' => 'Symfony\\Component\\Routing\\Matcher\\Dumper\\PhpMatcherDumper',
+ 'matcher_cache_class' => 'ProjectUrlMatcher',
+ 'resource_type' => null,
+ 'strict_requirements' => true,
+ );
+
+ // check option names and live merge, if errors are encountered Exception will be thrown
+ $invalid = array();
+ foreach ($options as $key => $value) {
+ if (array_key_exists($key, $this->options)) {
+ $this->options[$key] = $value;
+ } else {
+ $invalid[] = $key;
+ }
+ }
+
+ if ($invalid) {
+ throw new \InvalidArgumentException(sprintf('The Router does not support the following options: "%s".', implode('", "', $invalid)));
+ }
+ }
+
+ /**
+ * Sets an option.
+ *
+ * @param string $key The key
+ * @param mixed $value The value
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function setOption($key, $value)
+ {
+ if (!array_key_exists($key, $this->options)) {
+ throw new \InvalidArgumentException(sprintf('The Router does not support the "%s" option.', $key));
+ }
+
+ $this->options[$key] = $value;
+ }
+
+ /**
+ * Gets an option value.
+ *
+ * @param string $key The key
+ *
+ * @return mixed The value
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function getOption($key)
+ {
+ if (!array_key_exists($key, $this->options)) {
+ throw new \InvalidArgumentException(sprintf('The Router does not support the "%s" option.', $key));
+ }
+
+ return $this->options[$key];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getRouteCollection()
+ {
+ if (null === $this->collection) {
+ $this->collection = $this->loader->load($this->resource, $this->options['resource_type']);
+ }
+
+ return $this->collection;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setContext(RequestContext $context)
+ {
+ $this->context = $context;
+
+ if (null !== $this->matcher) {
+ $this->getMatcher()->setContext($context);
+ }
+ if (null !== $this->generator) {
+ $this->getGenerator()->setContext($context);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getContext()
+ {
+ return $this->context;
+ }
+
+ /**
+ * Sets the ConfigCache factory to use.
+ */
+ public function setConfigCacheFactory(ConfigCacheFactoryInterface $configCacheFactory)
+ {
+ $this->configCacheFactory = $configCacheFactory;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH)
+ {
+ return $this->getGenerator()->generate($name, $parameters, $referenceType);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function match($pathinfo)
+ {
+ return $this->getMatcher()->match($pathinfo);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function matchRequest(Request $request)
+ {
+ $matcher = $this->getMatcher();
+ if (!$matcher instanceof RequestMatcherInterface) {
+ // fallback to the default UrlMatcherInterface
+ return $matcher->match($request->getPathInfo());
+ }
+
+ return $matcher->matchRequest($request);
+ }
+
+ /**
+ * Gets the UrlMatcher instance associated with this Router.
+ *
+ * @return UrlMatcherInterface A UrlMatcherInterface instance
+ */
+ public function getMatcher()
+ {
+ if (null !== $this->matcher) {
+ return $this->matcher;
+ }
+
+ if (null === $this->options['cache_dir'] || null === $this->options['matcher_cache_class']) {
+ $this->matcher = new $this->options['matcher_class']($this->getRouteCollection(), $this->context);
+ if (method_exists($this->matcher, 'addExpressionLanguageProvider')) {
+ foreach ($this->expressionLanguageProviders as $provider) {
+ $this->matcher->addExpressionLanguageProvider($provider);
+ }
+ }
+
+ return $this->matcher;
+ }
+
+ $cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/'.$this->options['matcher_cache_class'].'.php',
+ function (ConfigCacheInterface $cache) {
+ $dumper = $this->getMatcherDumperInstance();
+ if (method_exists($dumper, 'addExpressionLanguageProvider')) {
+ foreach ($this->expressionLanguageProviders as $provider) {
+ $dumper->addExpressionLanguageProvider($provider);
+ }
+ }
+
+ $options = array(
+ 'class' => $this->options['matcher_cache_class'],
+ 'base_class' => $this->options['matcher_base_class'],
+ );
+
+ $cache->write($dumper->dump($options), $this->getRouteCollection()->getResources());
+ }
+ );
+
+ if (!class_exists($this->options['matcher_cache_class'], false)) {
+ require_once $cache->getPath();
+ }
+
+ return $this->matcher = new $this->options['matcher_cache_class']($this->context);
+ }
+
+ /**
+ * Gets the UrlGenerator instance associated with this Router.
+ *
+ * @return UrlGeneratorInterface A UrlGeneratorInterface instance
+ */
+ public function getGenerator()
+ {
+ if (null !== $this->generator) {
+ return $this->generator;
+ }
+
+ if (null === $this->options['cache_dir'] || null === $this->options['generator_cache_class']) {
+ $this->generator = new $this->options['generator_class']($this->getRouteCollection(), $this->context, $this->logger);
+ } else {
+ $cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/'.$this->options['generator_cache_class'].'.php',
+ function (ConfigCacheInterface $cache) {
+ $dumper = $this->getGeneratorDumperInstance();
+
+ $options = array(
+ 'class' => $this->options['generator_cache_class'],
+ 'base_class' => $this->options['generator_base_class'],
+ );
+
+ $cache->write($dumper->dump($options), $this->getRouteCollection()->getResources());
+ }
+ );
+
+ if (!class_exists($this->options['generator_cache_class'], false)) {
+ require_once $cache->getPath();
+ }
+
+ $this->generator = new $this->options['generator_cache_class']($this->context, $this->logger);
+ }
+
+ if ($this->generator instanceof ConfigurableRequirementsInterface) {
+ $this->generator->setStrictRequirements($this->options['strict_requirements']);
+ }
+
+ return $this->generator;
+ }
+
+ public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider)
+ {
+ $this->expressionLanguageProviders[] = $provider;
+ }
+
+ /**
+ * @return GeneratorDumperInterface
+ */
+ protected function getGeneratorDumperInstance()
+ {
+ return new $this->options['generator_dumper_class']($this->getRouteCollection());
+ }
+
+ /**
+ * @return MatcherDumperInterface
+ */
+ protected function getMatcherDumperInstance()
+ {
+ return new $this->options['matcher_dumper_class']($this->getRouteCollection());
+ }
+
+ /**
+ * Provides the ConfigCache factory implementation, falling back to a
+ * default implementation if necessary.
+ *
+ * @return ConfigCacheFactoryInterface $configCacheFactory
+ */
+ private function getConfigCacheFactory()
+ {
+ if (null === $this->configCacheFactory) {
+ $this->configCacheFactory = new ConfigCacheFactory($this->options['debug']);
+ }
+
+ return $this->configCacheFactory;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/RouterInterface.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/RouterInterface.php
new file mode 100644
index 0000000..a10ae34
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/RouterInterface.php
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing;
+
+use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
+use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
+
+/**
+ * RouterInterface is the interface that all Router classes must implement.
+ *
+ * This interface is the concatenation of UrlMatcherInterface and UrlGeneratorInterface.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface RouterInterface extends UrlMatcherInterface, UrlGeneratorInterface
+{
+ /**
+ * Gets the RouteCollection instance associated with this Router.
+ *
+ * @return RouteCollection A RouteCollection instance
+ */
+ public function getRouteCollection();
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Annotation/RouteTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Annotation/RouteTest.php
new file mode 100644
index 0000000..9af22f2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Annotation/RouteTest.php
@@ -0,0 +1,50 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Annotation;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Routing\Annotation\Route;
+
+class RouteTest extends TestCase
+{
+ /**
+ * @expectedException \BadMethodCallException
+ */
+ public function testInvalidRouteParameter()
+ {
+ $route = new Route(array('foo' => 'bar'));
+ }
+
+ /**
+ * @dataProvider getValidParameters
+ */
+ public function testRouteParameters($parameter, $value, $getter)
+ {
+ $route = new Route(array($parameter => $value));
+ $this->assertEquals($route->$getter(), $value);
+ }
+
+ public function getValidParameters()
+ {
+ return array(
+ array('value', '/Blog', 'getPath'),
+ array('requirements', array('locale' => 'en'), 'getRequirements'),
+ array('options', array('compiler_class' => 'RouteCompiler'), 'getOptions'),
+ array('name', 'blog_index', 'getName'),
+ array('defaults', array('_controller' => 'MyBlogBundle:Blog:index'), 'getDefaults'),
+ array('schemes', array('https'), 'getSchemes'),
+ array('methods', array('GET', 'POST'), 'getMethods'),
+ array('host', '{locale}.example.com', 'getHost'),
+ array('condition', 'context.getMethod() == "GET"', 'getCondition'),
+ );
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/CompiledRouteTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/CompiledRouteTest.php
new file mode 100644
index 0000000..5bec7bb
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/CompiledRouteTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Routing\CompiledRoute;
+
+class CompiledRouteTest extends TestCase
+{
+ public function testAccessors()
+ {
+ $compiled = new CompiledRoute('prefix', 'regex', array('tokens'), array(), null, array(), array(), array('variables'));
+ $this->assertEquals('prefix', $compiled->getStaticPrefix(), '__construct() takes a static prefix as its second argument');
+ $this->assertEquals('regex', $compiled->getRegex(), '__construct() takes a regexp as its third argument');
+ $this->assertEquals(array('tokens'), $compiled->getTokens(), '__construct() takes an array of tokens as its fourth argument');
+ $this->assertEquals(array('variables'), $compiled->getVariables(), '__construct() takes an array of variables as its ninth argument');
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/DependencyInjection/RoutingResolverPassTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/DependencyInjection/RoutingResolverPassTest.php
new file mode 100644
index 0000000..97a34c9
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/DependencyInjection/RoutingResolverPassTest.php
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\DependencyInjection;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Config\Loader\LoaderResolver;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Reference;
+use Symfony\Component\Routing\DependencyInjection\RoutingResolverPass;
+
+class RoutingResolverPassTest extends TestCase
+{
+ public function testProcess()
+ {
+ $container = new ContainerBuilder();
+ $container->register('routing.resolver', LoaderResolver::class);
+ $container->register('loader1')->addTag('routing.loader');
+ $container->register('loader2')->addTag('routing.loader');
+
+ (new RoutingResolverPass())->process($container);
+
+ $this->assertEquals(
+ array(array('addLoader', array(new Reference('loader1'))), array('addLoader', array(new Reference('loader2')))),
+ $container->getDefinition('routing.resolver')->getMethodCalls()
+ );
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/AbstractClass.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/AbstractClass.php
new file mode 100644
index 0000000..56bcab2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/AbstractClass.php
@@ -0,0 +1,16 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses;
+
+abstract class AbstractClass
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/BarClass.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/BarClass.php
new file mode 100644
index 0000000..a388277
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/BarClass.php
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses;
+
+class BarClass
+{
+ public function routeAction($arg1, $arg2 = 'defaultValue2', $arg3 = 'defaultValue3')
+ {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/BazClass.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/BazClass.php
new file mode 100644
index 0000000..471968b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/BazClass.php
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses;
+
+class BazClass
+{
+ public function __invoke()
+ {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/FooClass.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/FooClass.php
new file mode 100644
index 0000000..320dc35
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/FooClass.php
@@ -0,0 +1,16 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses;
+
+class FooClass
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/FooTrait.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/FooTrait.php
new file mode 100644
index 0000000..ee8f4b0
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/AnnotatedClasses/FooTrait.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses;
+
+trait FooTrait
+{
+ public function doBar()
+ {
+ $baz = self::class;
+ if (true) {
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/CustomCompiledRoute.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/CustomCompiledRoute.php
new file mode 100644
index 0000000..0f6e198
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/CustomCompiledRoute.php
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Fixtures;
+
+use Symfony\Component\Routing\CompiledRoute;
+
+class CustomCompiledRoute extends CompiledRoute
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/CustomRouteCompiler.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/CustomRouteCompiler.php
new file mode 100644
index 0000000..c2e2afd
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/CustomRouteCompiler.php
@@ -0,0 +1,26 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Fixtures;
+
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCompiler;
+
+class CustomRouteCompiler extends RouteCompiler
+{
+ /**
+ * {@inheritdoc}
+ */
+ public static function compile(Route $route)
+ {
+ return new CustomCompiledRoute('', '', array(), array());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/CustomXmlFileLoader.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/CustomXmlFileLoader.php
new file mode 100644
index 0000000..9fd5754
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/CustomXmlFileLoader.php
@@ -0,0 +1,26 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Fixtures;
+
+use Symfony\Component\Routing\Loader\XmlFileLoader;
+use Symfony\Component\Config\Util\XmlUtils;
+
+/**
+ * XmlFileLoader with schema validation turned off.
+ */
+class CustomXmlFileLoader extends XmlFileLoader
+{
+ protected function loadFile($file)
+ {
+ return XmlUtils::loadFile($file, function () { return true; });
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/OtherAnnotatedClasses/AnonymousClassInTrait.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/OtherAnnotatedClasses/AnonymousClassInTrait.php
new file mode 100644
index 0000000..de87895
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/OtherAnnotatedClasses/AnonymousClassInTrait.php
@@ -0,0 +1,24 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Fixtures\OtherAnnotatedClasses;
+
+trait AnonymousClassInTrait
+{
+ public function test()
+ {
+ return new class() {
+ public function foo()
+ {
+ }
+ };
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/OtherAnnotatedClasses/NoStartTagClass.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/OtherAnnotatedClasses/NoStartTagClass.php
new file mode 100644
index 0000000..8900d34
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/OtherAnnotatedClasses/NoStartTagClass.php
@@ -0,0 +1,3 @@
+class NoStartTagClass
+{
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/OtherAnnotatedClasses/VariadicClass.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/OtherAnnotatedClasses/VariadicClass.php
new file mode 100644
index 0000000..729c9b4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/OtherAnnotatedClasses/VariadicClass.php
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Fixtures\OtherAnnotatedClasses;
+
+class VariadicClass
+{
+ public function routeAction(...$params)
+ {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/RedirectableUrlMatcher.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/RedirectableUrlMatcher.php
new file mode 100644
index 0000000..15937bc
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/RedirectableUrlMatcher.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Fixtures;
+
+use Symfony\Component\Routing\Matcher\UrlMatcher;
+use Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface;
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class RedirectableUrlMatcher extends UrlMatcher implements RedirectableUrlMatcherInterface
+{
+ public function redirect($path, $route, $scheme = null)
+ {
+ return array(
+ '_controller' => 'Some controller reference...',
+ 'path' => $path,
+ 'scheme' => $scheme,
+ );
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/annotated.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/annotated.php
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/annotated.php
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/bad_format.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/bad_format.yml
new file mode 100644
index 0000000..8ba50e2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/bad_format.yml
@@ -0,0 +1,3 @@
+blog_show:
+ path: /blog/{slug}
+ defaults: { _controller: "MyBundle:Blog:show" }
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/bar.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/bar.xml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/bar.xml
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/import__controller.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/import__controller.xml
new file mode 100644
index 0000000..bbe727d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/import__controller.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <import resource="routing.xml">
+ <default key="_controller">FrameworkBundle:Template:template</default>
+ </import>
+</routes>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/import__controller.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/import__controller.yml
new file mode 100644
index 0000000..4240b74
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/import__controller.yml
@@ -0,0 +1,4 @@
+_static:
+ resource: routing.yml
+ defaults:
+ _controller: FrameworkBundle:Template:template
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_controller.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_controller.xml
new file mode 100644
index 0000000..378b9ca
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_controller.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <import resource="routing.xml" controller="FrameworkBundle:Template:template" />
+</routes>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_controller.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_controller.yml
new file mode 100644
index 0000000..1a71c62
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_controller.yml
@@ -0,0 +1,3 @@
+_static:
+ resource: routing.yml
+ controller: FrameworkBundle:Template:template
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_override_defaults.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_override_defaults.xml
new file mode 100644
index 0000000..e3c755a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_override_defaults.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <import resource="routing.xml" controller="FrameworkBundle:Template:template">
+ <default key="_controller">AppBundle:Blog:index</default>
+ </import>
+</routes>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_override_defaults.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_override_defaults.yml
new file mode 100644
index 0000000..db1ab3c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/import_override_defaults.yml
@@ -0,0 +1,5 @@
+_static:
+ resource: routing.yml
+ controller: FrameworkBundle:Template:template
+ defaults:
+ _controller: AppBundle:Homepage:show
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/override_defaults.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/override_defaults.xml
new file mode 100644
index 0000000..f47c57b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/override_defaults.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="app_blog" path="/blog" controller="AppBundle:Homepage:show">
+ <default key="_controller">AppBundle:Blog:index</default>
+ </route>
+</routes>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/override_defaults.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/override_defaults.yml
new file mode 100644
index 0000000..00a2c0e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/override_defaults.yml
@@ -0,0 +1,5 @@
+app_blog:
+ path: /blog
+ controller: AppBundle:Homepage:show
+ defaults:
+ _controller: AppBundle:Blog:index
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/routing.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/routing.xml
new file mode 100644
index 0000000..6420138
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/routing.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="app_homepage" path="/" controller="AppBundle:Homepage:show" />
+
+ <route id="app_blog" path="/blog">
+ <default key="_controller">AppBundle:Blog:list</default>
+ </route>
+
+ <route id="app_logout" path="/logout" />
+</routes>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/routing.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/routing.yml
new file mode 100644
index 0000000..cb71ec3
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/controller/routing.yml
@@ -0,0 +1,11 @@
+app_homepage:
+ path: /
+ controller: AppBundle:Homepage:show
+
+app_blog:
+ path: /blog
+ defaults:
+ _controller: AppBundle:Blog:list
+
+app_logout:
+ path: /logout
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/directory/recurse/routes1.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/directory/recurse/routes1.yml
new file mode 100644
index 0000000..d078836
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/directory/recurse/routes1.yml
@@ -0,0 +1,2 @@
+route1:
+ path: /route/1
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/directory/recurse/routes2.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/directory/recurse/routes2.yml
new file mode 100644
index 0000000..938fb24
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/directory/recurse/routes2.yml
@@ -0,0 +1,2 @@
+route2:
+ path: /route/2
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/directory/routes3.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/directory/routes3.yml
new file mode 100644
index 0000000..088cfb4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/directory/routes3.yml
@@ -0,0 +1,2 @@
+route3:
+ path: /route/3
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/directory_import/import.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/directory_import/import.yml
new file mode 100644
index 0000000..af829e5
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/directory_import/import.yml
@@ -0,0 +1,3 @@
+_directory:
+ resource: "../directory"
+ type: directory
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher0.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher0.php
new file mode 100644
index 0000000..9e9b910
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher0.php
@@ -0,0 +1,37 @@
+<?php
+
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\RequestContext;
+
+/**
+ * This class has been auto-generated
+ * by the Symfony Routing Component.
+ */
+class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
+{
+ public function __construct(RequestContext $context)
+ {
+ $this->context = $context;
+ }
+
+ public function match($rawPathinfo)
+ {
+ $allow = array();
+ $pathinfo = rawurldecode($rawPathinfo);
+ $trimmedPathinfo = rtrim($pathinfo, '/');
+ $context = $this->context;
+ $request = $this->request ?: $this->createRequest($pathinfo);
+ $requestMethod = $canonicalMethod = $context->getMethod();
+
+ if ('HEAD' === $requestMethod) {
+ $canonicalMethod = 'GET';
+ }
+
+ if ('/' === $pathinfo && !$allow) {
+ throw new Symfony\Component\Routing\Exception\NoConfigurationException();
+ }
+
+ throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher1.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher1.php
new file mode 100644
index 0000000..23a93c1
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher1.php
@@ -0,0 +1,318 @@
+<?php
+
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\RequestContext;
+
+/**
+ * This class has been auto-generated
+ * by the Symfony Routing Component.
+ */
+class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
+{
+ public function __construct(RequestContext $context)
+ {
+ $this->context = $context;
+ }
+
+ public function match($rawPathinfo)
+ {
+ $allow = array();
+ $pathinfo = rawurldecode($rawPathinfo);
+ $trimmedPathinfo = rtrim($pathinfo, '/');
+ $context = $this->context;
+ $request = $this->request ?: $this->createRequest($pathinfo);
+ $requestMethod = $canonicalMethod = $context->getMethod();
+
+ if ('HEAD' === $requestMethod) {
+ $canonicalMethod = 'GET';
+ }
+
+ if (0 === strpos($pathinfo, '/foo')) {
+ // foo
+ if (preg_match('#^/foo/(?P<bar>baz|symfony)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo')), array ( 'def' => 'test',));
+ }
+
+ // foofoo
+ if ('/foofoo' === $pathinfo) {
+ return array ( 'def' => 'test', '_route' => 'foofoo',);
+ }
+
+ }
+
+ elseif (0 === strpos($pathinfo, '/bar')) {
+ // bar
+ if (preg_match('#^/bar/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'bar')), array ());
+ if (!in_array($canonicalMethod, array('GET', 'HEAD'))) {
+ $allow = array_merge($allow, array('GET', 'HEAD'));
+ goto not_bar;
+ }
+
+ return $ret;
+ }
+ not_bar:
+
+ // barhead
+ if (0 === strpos($pathinfo, '/barhead') && preg_match('#^/barhead/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'barhead')), array ());
+ if (!in_array($canonicalMethod, array('GET'))) {
+ $allow = array_merge($allow, array('GET'));
+ goto not_barhead;
+ }
+
+ return $ret;
+ }
+ not_barhead:
+
+ }
+
+ elseif (0 === strpos($pathinfo, '/test')) {
+ if (0 === strpos($pathinfo, '/test/baz')) {
+ // baz
+ if ('/test/baz' === $pathinfo) {
+ return array('_route' => 'baz');
+ }
+
+ // baz2
+ if ('/test/baz.html' === $pathinfo) {
+ return array('_route' => 'baz2');
+ }
+
+ // baz3
+ if ('/test/baz3/' === $pathinfo) {
+ return array('_route' => 'baz3');
+ }
+
+ }
+
+ // baz4
+ if (preg_match('#^/test/(?P<foo>[^/]++)/$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'baz4')), array ());
+ }
+
+ // baz5
+ if (preg_match('#^/test/(?P<foo>[^/]++)/$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'baz5')), array ());
+ if (!in_array($requestMethod, array('POST'))) {
+ $allow = array_merge($allow, array('POST'));
+ goto not_baz5;
+ }
+
+ return $ret;
+ }
+ not_baz5:
+
+ // baz.baz6
+ if (preg_match('#^/test/(?P<foo>[^/]++)/$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'baz.baz6')), array ());
+ if (!in_array($requestMethod, array('PUT'))) {
+ $allow = array_merge($allow, array('PUT'));
+ goto not_bazbaz6;
+ }
+
+ return $ret;
+ }
+ not_bazbaz6:
+
+ }
+
+ // quoter
+ if (preg_match('#^/(?P<quoter>[\']+)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'quoter')), array ());
+ }
+
+ // space
+ if ('/spa ce' === $pathinfo) {
+ return array('_route' => 'space');
+ }
+
+ if (0 === strpos($pathinfo, '/a')) {
+ if (0 === strpos($pathinfo, '/a/b\'b')) {
+ // foo1
+ if (preg_match('#^/a/b\'b/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo1')), array ());
+ }
+
+ // bar1
+ if (preg_match('#^/a/b\'b/(?P<bar>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'bar1')), array ());
+ }
+
+ }
+
+ // overridden
+ if (preg_match('#^/a/(?P<var>.*)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'overridden')), array ());
+ }
+
+ if (0 === strpos($pathinfo, '/a/b\'b')) {
+ // foo2
+ if (preg_match('#^/a/b\'b/(?P<foo1>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo2')), array ());
+ }
+
+ // bar2
+ if (preg_match('#^/a/b\'b/(?P<bar1>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'bar2')), array ());
+ }
+
+ }
+
+ }
+
+ elseif (0 === strpos($pathinfo, '/multi')) {
+ // helloWorld
+ if (0 === strpos($pathinfo, '/multi/hello') && preg_match('#^/multi/hello(?:/(?P<who>[^/]++))?$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'helloWorld')), array ( 'who' => 'World!',));
+ }
+
+ // hey
+ if ('/multi/hey/' === $pathinfo) {
+ return array('_route' => 'hey');
+ }
+
+ // overridden2
+ if ('/multi/new' === $pathinfo) {
+ return array('_route' => 'overridden2');
+ }
+
+ }
+
+ // foo3
+ if (preg_match('#^/(?P<_locale>[^/]++)/b/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo3')), array ());
+ }
+
+ // bar3
+ if (preg_match('#^/(?P<_locale>[^/]++)/b/(?P<bar>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'bar3')), array ());
+ }
+
+ if (0 === strpos($pathinfo, '/aba')) {
+ // ababa
+ if ('/ababa' === $pathinfo) {
+ return array('_route' => 'ababa');
+ }
+
+ // foo4
+ if (preg_match('#^/aba/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo4')), array ());
+ }
+
+ }
+
+ $host = $context->getHost();
+
+ if (preg_match('#^a\\.example\\.com$#sDi', $host, $hostMatches)) {
+ // route1
+ if ('/route1' === $pathinfo) {
+ return array('_route' => 'route1');
+ }
+
+ // route2
+ if ('/c2/route2' === $pathinfo) {
+ return array('_route' => 'route2');
+ }
+
+ }
+
+ if (preg_match('#^b\\.example\\.com$#sDi', $host, $hostMatches)) {
+ // route3
+ if ('/c2/route3' === $pathinfo) {
+ return array('_route' => 'route3');
+ }
+
+ }
+
+ if (preg_match('#^a\\.example\\.com$#sDi', $host, $hostMatches)) {
+ // route4
+ if ('/route4' === $pathinfo) {
+ return array('_route' => 'route4');
+ }
+
+ }
+
+ if (preg_match('#^c\\.example\\.com$#sDi', $host, $hostMatches)) {
+ // route5
+ if ('/route5' === $pathinfo) {
+ return array('_route' => 'route5');
+ }
+
+ }
+
+ // route6
+ if ('/route6' === $pathinfo) {
+ return array('_route' => 'route6');
+ }
+
+ if (preg_match('#^(?P<var1>[^\\.]++)\\.example\\.com$#sDi', $host, $hostMatches)) {
+ if (0 === strpos($pathinfo, '/route1')) {
+ // route11
+ if ('/route11' === $pathinfo) {
+ return $this->mergeDefaults(array_replace($hostMatches, array('_route' => 'route11')), array ());
+ }
+
+ // route12
+ if ('/route12' === $pathinfo) {
+ return $this->mergeDefaults(array_replace($hostMatches, array('_route' => 'route12')), array ( 'var1' => 'val',));
+ }
+
+ // route13
+ if (0 === strpos($pathinfo, '/route13') && preg_match('#^/route13/(?P<name>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($hostMatches, $matches, array('_route' => 'route13')), array ());
+ }
+
+ // route14
+ if (0 === strpos($pathinfo, '/route14') && preg_match('#^/route14/(?P<name>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($hostMatches, $matches, array('_route' => 'route14')), array ( 'var1' => 'val',));
+ }
+
+ }
+
+ }
+
+ if (preg_match('#^c\\.example\\.com$#sDi', $host, $hostMatches)) {
+ // route15
+ if (0 === strpos($pathinfo, '/route15') && preg_match('#^/route15/(?P<name>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'route15')), array ());
+ }
+
+ }
+
+ // route16
+ if (0 === strpos($pathinfo, '/route16') && preg_match('#^/route16/(?P<name>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'route16')), array ( 'var1' => 'val',));
+ }
+
+ // route17
+ if ('/route17' === $pathinfo) {
+ return array('_route' => 'route17');
+ }
+
+ // a
+ if ('/a/a...' === $pathinfo) {
+ return array('_route' => 'a');
+ }
+
+ if (0 === strpos($pathinfo, '/a/b')) {
+ // b
+ if (preg_match('#^/a/b/(?P<var>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'b')), array ());
+ }
+
+ // c
+ if (0 === strpos($pathinfo, '/a/b/c') && preg_match('#^/a/b/c/(?P<var>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'c')), array ());
+ }
+
+ }
+
+ if ('/' === $pathinfo && !$allow) {
+ throw new Symfony\Component\Routing\Exception\NoConfigurationException();
+ }
+
+ throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher2.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher2.php
new file mode 100644
index 0000000..e430adb
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher2.php
@@ -0,0 +1,380 @@
+<?php
+
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\RequestContext;
+
+/**
+ * This class has been auto-generated
+ * by the Symfony Routing Component.
+ */
+class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher
+{
+ public function __construct(RequestContext $context)
+ {
+ $this->context = $context;
+ }
+
+ public function match($rawPathinfo)
+ {
+ $allow = array();
+ $pathinfo = rawurldecode($rawPathinfo);
+ $trimmedPathinfo = rtrim($pathinfo, '/');
+ $context = $this->context;
+ $request = $this->request ?: $this->createRequest($pathinfo);
+ $requestMethod = $canonicalMethod = $context->getMethod();
+
+ if ('HEAD' === $requestMethod) {
+ $canonicalMethod = 'GET';
+ }
+
+ if (0 === strpos($pathinfo, '/foo')) {
+ // foo
+ if (preg_match('#^/foo/(?P<bar>baz|symfony)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo')), array ( 'def' => 'test',));
+ }
+
+ // foofoo
+ if ('/foofoo' === $pathinfo) {
+ return array ( 'def' => 'test', '_route' => 'foofoo',);
+ }
+
+ }
+
+ elseif (0 === strpos($pathinfo, '/bar')) {
+ // bar
+ if (preg_match('#^/bar/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'bar')), array ());
+ if (!in_array($canonicalMethod, array('GET', 'HEAD'))) {
+ $allow = array_merge($allow, array('GET', 'HEAD'));
+ goto not_bar;
+ }
+
+ return $ret;
+ }
+ not_bar:
+
+ // barhead
+ if (0 === strpos($pathinfo, '/barhead') && preg_match('#^/barhead/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'barhead')), array ());
+ if (!in_array($canonicalMethod, array('GET'))) {
+ $allow = array_merge($allow, array('GET'));
+ goto not_barhead;
+ }
+
+ return $ret;
+ }
+ not_barhead:
+
+ }
+
+ elseif (0 === strpos($pathinfo, '/test')) {
+ if (0 === strpos($pathinfo, '/test/baz')) {
+ // baz
+ if ('/test/baz' === $pathinfo) {
+ return array('_route' => 'baz');
+ }
+
+ // baz2
+ if ('/test/baz.html' === $pathinfo) {
+ return array('_route' => 'baz2');
+ }
+
+ // baz3
+ if ('/test/baz3' === $trimmedPathinfo) {
+ $ret = array('_route' => 'baz3');
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_baz3;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'baz3'));
+ }
+
+ return $ret;
+ }
+ not_baz3:
+
+ }
+
+ // baz4
+ if (preg_match('#^/test/(?P<foo>[^/]++)/?$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'baz4')), array ());
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_baz4;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'baz4'));
+ }
+
+ return $ret;
+ }
+ not_baz4:
+
+ // baz5
+ if (preg_match('#^/test/(?P<foo>[^/]++)/$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'baz5')), array ());
+ if (!in_array($requestMethod, array('POST'))) {
+ $allow = array_merge($allow, array('POST'));
+ goto not_baz5;
+ }
+
+ return $ret;
+ }
+ not_baz5:
+
+ // baz.baz6
+ if (preg_match('#^/test/(?P<foo>[^/]++)/$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'baz.baz6')), array ());
+ if (!in_array($requestMethod, array('PUT'))) {
+ $allow = array_merge($allow, array('PUT'));
+ goto not_bazbaz6;
+ }
+
+ return $ret;
+ }
+ not_bazbaz6:
+
+ }
+
+ // quoter
+ if (preg_match('#^/(?P<quoter>[\']+)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'quoter')), array ());
+ }
+
+ // space
+ if ('/spa ce' === $pathinfo) {
+ return array('_route' => 'space');
+ }
+
+ if (0 === strpos($pathinfo, '/a')) {
+ if (0 === strpos($pathinfo, '/a/b\'b')) {
+ // foo1
+ if (preg_match('#^/a/b\'b/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo1')), array ());
+ }
+
+ // bar1
+ if (preg_match('#^/a/b\'b/(?P<bar>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'bar1')), array ());
+ }
+
+ }
+
+ // overridden
+ if (preg_match('#^/a/(?P<var>.*)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'overridden')), array ());
+ }
+
+ if (0 === strpos($pathinfo, '/a/b\'b')) {
+ // foo2
+ if (preg_match('#^/a/b\'b/(?P<foo1>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo2')), array ());
+ }
+
+ // bar2
+ if (preg_match('#^/a/b\'b/(?P<bar1>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'bar2')), array ());
+ }
+
+ }
+
+ }
+
+ elseif (0 === strpos($pathinfo, '/multi')) {
+ // helloWorld
+ if (0 === strpos($pathinfo, '/multi/hello') && preg_match('#^/multi/hello(?:/(?P<who>[^/]++))?$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'helloWorld')), array ( 'who' => 'World!',));
+ }
+
+ // hey
+ if ('/multi/hey' === $trimmedPathinfo) {
+ $ret = array('_route' => 'hey');
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_hey;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'hey'));
+ }
+
+ return $ret;
+ }
+ not_hey:
+
+ // overridden2
+ if ('/multi/new' === $pathinfo) {
+ return array('_route' => 'overridden2');
+ }
+
+ }
+
+ // foo3
+ if (preg_match('#^/(?P<_locale>[^/]++)/b/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo3')), array ());
+ }
+
+ // bar3
+ if (preg_match('#^/(?P<_locale>[^/]++)/b/(?P<bar>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'bar3')), array ());
+ }
+
+ if (0 === strpos($pathinfo, '/aba')) {
+ // ababa
+ if ('/ababa' === $pathinfo) {
+ return array('_route' => 'ababa');
+ }
+
+ // foo4
+ if (preg_match('#^/aba/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo4')), array ());
+ }
+
+ }
+
+ $host = $context->getHost();
+
+ if (preg_match('#^a\\.example\\.com$#sDi', $host, $hostMatches)) {
+ // route1
+ if ('/route1' === $pathinfo) {
+ return array('_route' => 'route1');
+ }
+
+ // route2
+ if ('/c2/route2' === $pathinfo) {
+ return array('_route' => 'route2');
+ }
+
+ }
+
+ if (preg_match('#^b\\.example\\.com$#sDi', $host, $hostMatches)) {
+ // route3
+ if ('/c2/route3' === $pathinfo) {
+ return array('_route' => 'route3');
+ }
+
+ }
+
+ if (preg_match('#^a\\.example\\.com$#sDi', $host, $hostMatches)) {
+ // route4
+ if ('/route4' === $pathinfo) {
+ return array('_route' => 'route4');
+ }
+
+ }
+
+ if (preg_match('#^c\\.example\\.com$#sDi', $host, $hostMatches)) {
+ // route5
+ if ('/route5' === $pathinfo) {
+ return array('_route' => 'route5');
+ }
+
+ }
+
+ // route6
+ if ('/route6' === $pathinfo) {
+ return array('_route' => 'route6');
+ }
+
+ if (preg_match('#^(?P<var1>[^\\.]++)\\.example\\.com$#sDi', $host, $hostMatches)) {
+ if (0 === strpos($pathinfo, '/route1')) {
+ // route11
+ if ('/route11' === $pathinfo) {
+ return $this->mergeDefaults(array_replace($hostMatches, array('_route' => 'route11')), array ());
+ }
+
+ // route12
+ if ('/route12' === $pathinfo) {
+ return $this->mergeDefaults(array_replace($hostMatches, array('_route' => 'route12')), array ( 'var1' => 'val',));
+ }
+
+ // route13
+ if (0 === strpos($pathinfo, '/route13') && preg_match('#^/route13/(?P<name>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($hostMatches, $matches, array('_route' => 'route13')), array ());
+ }
+
+ // route14
+ if (0 === strpos($pathinfo, '/route14') && preg_match('#^/route14/(?P<name>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($hostMatches, $matches, array('_route' => 'route14')), array ( 'var1' => 'val',));
+ }
+
+ }
+
+ }
+
+ if (preg_match('#^c\\.example\\.com$#sDi', $host, $hostMatches)) {
+ // route15
+ if (0 === strpos($pathinfo, '/route15') && preg_match('#^/route15/(?P<name>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'route15')), array ());
+ }
+
+ }
+
+ // route16
+ if (0 === strpos($pathinfo, '/route16') && preg_match('#^/route16/(?P<name>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'route16')), array ( 'var1' => 'val',));
+ }
+
+ // route17
+ if ('/route17' === $pathinfo) {
+ return array('_route' => 'route17');
+ }
+
+ // a
+ if ('/a/a...' === $pathinfo) {
+ return array('_route' => 'a');
+ }
+
+ if (0 === strpos($pathinfo, '/a/b')) {
+ // b
+ if (preg_match('#^/a/b/(?P<var>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'b')), array ());
+ }
+
+ // c
+ if (0 === strpos($pathinfo, '/a/b/c') && preg_match('#^/a/b/c/(?P<var>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'c')), array ());
+ }
+
+ }
+
+ // secure
+ if ('/secure' === $pathinfo) {
+ $ret = array('_route' => 'secure');
+ $requiredSchemes = array ( 'https' => 0,);
+ if (!isset($requiredSchemes[$context->getScheme()])) {
+ if ('GET' !== $canonicalMethod) {
+ goto not_secure;
+ }
+
+ return array_replace($ret, $this->redirect($rawPathinfo, 'secure', key($requiredSchemes)));
+ }
+
+ return $ret;
+ }
+ not_secure:
+
+ // nonsecure
+ if ('/nonsecure' === $pathinfo) {
+ $ret = array('_route' => 'nonsecure');
+ $requiredSchemes = array ( 'http' => 0,);
+ if (!isset($requiredSchemes[$context->getScheme()])) {
+ if ('GET' !== $canonicalMethod) {
+ goto not_nonsecure;
+ }
+
+ return array_replace($ret, $this->redirect($rawPathinfo, 'nonsecure', key($requiredSchemes)));
+ }
+
+ return $ret;
+ }
+ not_nonsecure:
+
+ if ('/' === $pathinfo && !$allow) {
+ throw new Symfony\Component\Routing\Exception\NoConfigurationException();
+ }
+
+ throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher3.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher3.php
new file mode 100644
index 0000000..67c4667
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher3.php
@@ -0,0 +1,55 @@
+<?php
+
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\RequestContext;
+
+/**
+ * This class has been auto-generated
+ * by the Symfony Routing Component.
+ */
+class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
+{
+ public function __construct(RequestContext $context)
+ {
+ $this->context = $context;
+ }
+
+ public function match($rawPathinfo)
+ {
+ $allow = array();
+ $pathinfo = rawurldecode($rawPathinfo);
+ $trimmedPathinfo = rtrim($pathinfo, '/');
+ $context = $this->context;
+ $request = $this->request ?: $this->createRequest($pathinfo);
+ $requestMethod = $canonicalMethod = $context->getMethod();
+
+ if ('HEAD' === $requestMethod) {
+ $canonicalMethod = 'GET';
+ }
+
+ if (0 === strpos($pathinfo, '/rootprefix')) {
+ // static
+ if ('/rootprefix/test' === $pathinfo) {
+ return array('_route' => 'static');
+ }
+
+ // dynamic
+ if (preg_match('#^/rootprefix/(?P<var>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'dynamic')), array ());
+ }
+
+ }
+
+ // with-condition
+ if ('/with-condition' === $pathinfo && ($context->getMethod() == "GET")) {
+ return array('_route' => 'with-condition');
+ }
+
+ if ('/' === $pathinfo && !$allow) {
+ throw new Symfony\Component\Routing\Exception\NoConfigurationException();
+ }
+
+ throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher4.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher4.php
new file mode 100644
index 0000000..ed07194
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher4.php
@@ -0,0 +1,112 @@
+<?php
+
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\RequestContext;
+
+/**
+ * This class has been auto-generated
+ * by the Symfony Routing Component.
+ */
+class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
+{
+ public function __construct(RequestContext $context)
+ {
+ $this->context = $context;
+ }
+
+ public function match($rawPathinfo)
+ {
+ $allow = array();
+ $pathinfo = rawurldecode($rawPathinfo);
+ $trimmedPathinfo = rtrim($pathinfo, '/');
+ $context = $this->context;
+ $request = $this->request ?: $this->createRequest($pathinfo);
+ $requestMethod = $canonicalMethod = $context->getMethod();
+
+ if ('HEAD' === $requestMethod) {
+ $canonicalMethod = 'GET';
+ }
+
+ // just_head
+ if ('/just_head' === $pathinfo) {
+ $ret = array('_route' => 'just_head');
+ if (!in_array($requestMethod, array('HEAD'))) {
+ $allow = array_merge($allow, array('HEAD'));
+ goto not_just_head;
+ }
+
+ return $ret;
+ }
+ not_just_head:
+
+ // head_and_get
+ if ('/head_and_get' === $pathinfo) {
+ $ret = array('_route' => 'head_and_get');
+ if (!in_array($canonicalMethod, array('HEAD', 'GET'))) {
+ $allow = array_merge($allow, array('HEAD', 'GET'));
+ goto not_head_and_get;
+ }
+
+ return $ret;
+ }
+ not_head_and_get:
+
+ // get_and_head
+ if ('/get_and_head' === $pathinfo) {
+ $ret = array('_route' => 'get_and_head');
+ if (!in_array($canonicalMethod, array('GET', 'HEAD'))) {
+ $allow = array_merge($allow, array('GET', 'HEAD'));
+ goto not_get_and_head;
+ }
+
+ return $ret;
+ }
+ not_get_and_head:
+
+ // post_and_head
+ if ('/post_and_head' === $pathinfo) {
+ $ret = array('_route' => 'post_and_head');
+ if (!in_array($requestMethod, array('POST', 'HEAD'))) {
+ $allow = array_merge($allow, array('POST', 'HEAD'));
+ goto not_post_and_head;
+ }
+
+ return $ret;
+ }
+ not_post_and_head:
+
+ if (0 === strpos($pathinfo, '/put_and_post')) {
+ // put_and_post
+ if ('/put_and_post' === $pathinfo) {
+ $ret = array('_route' => 'put_and_post');
+ if (!in_array($requestMethod, array('PUT', 'POST'))) {
+ $allow = array_merge($allow, array('PUT', 'POST'));
+ goto not_put_and_post;
+ }
+
+ return $ret;
+ }
+ not_put_and_post:
+
+ // put_and_get_and_head
+ if ('/put_and_post' === $pathinfo) {
+ $ret = array('_route' => 'put_and_get_and_head');
+ if (!in_array($canonicalMethod, array('PUT', 'GET', 'HEAD'))) {
+ $allow = array_merge($allow, array('PUT', 'GET', 'HEAD'));
+ goto not_put_and_get_and_head;
+ }
+
+ return $ret;
+ }
+ not_put_and_get_and_head:
+
+ }
+
+ if ('/' === $pathinfo && !$allow) {
+ throw new Symfony\Component\Routing\Exception\NoConfigurationException();
+ }
+
+ throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher5.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher5.php
new file mode 100644
index 0000000..2b22513
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher5.php
@@ -0,0 +1,209 @@
+<?php
+
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\RequestContext;
+
+/**
+ * This class has been auto-generated
+ * by the Symfony Routing Component.
+ */
+class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher
+{
+ public function __construct(RequestContext $context)
+ {
+ $this->context = $context;
+ }
+
+ public function match($rawPathinfo)
+ {
+ $allow = array();
+ $pathinfo = rawurldecode($rawPathinfo);
+ $trimmedPathinfo = rtrim($pathinfo, '/');
+ $context = $this->context;
+ $request = $this->request ?: $this->createRequest($pathinfo);
+ $requestMethod = $canonicalMethod = $context->getMethod();
+
+ if ('HEAD' === $requestMethod) {
+ $canonicalMethod = 'GET';
+ }
+
+ if (0 === strpos($pathinfo, '/a')) {
+ // a_first
+ if ('/a/11' === $pathinfo) {
+ return array('_route' => 'a_first');
+ }
+
+ // a_second
+ if ('/a/22' === $pathinfo) {
+ return array('_route' => 'a_second');
+ }
+
+ // a_third
+ if ('/a/333' === $pathinfo) {
+ return array('_route' => 'a_third');
+ }
+
+ }
+
+ // a_wildcard
+ if (preg_match('#^/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'a_wildcard')), array ());
+ }
+
+ if (0 === strpos($pathinfo, '/a')) {
+ // a_fourth
+ if ('/a/44' === $trimmedPathinfo) {
+ $ret = array('_route' => 'a_fourth');
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_a_fourth;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'a_fourth'));
+ }
+
+ return $ret;
+ }
+ not_a_fourth:
+
+ // a_fifth
+ if ('/a/55' === $trimmedPathinfo) {
+ $ret = array('_route' => 'a_fifth');
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_a_fifth;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'a_fifth'));
+ }
+
+ return $ret;
+ }
+ not_a_fifth:
+
+ // a_sixth
+ if ('/a/66' === $trimmedPathinfo) {
+ $ret = array('_route' => 'a_sixth');
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_a_sixth;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'a_sixth'));
+ }
+
+ return $ret;
+ }
+ not_a_sixth:
+
+ }
+
+ // nested_wildcard
+ if (0 === strpos($pathinfo, '/nested') && preg_match('#^/nested/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'nested_wildcard')), array ());
+ }
+
+ if (0 === strpos($pathinfo, '/nested/group')) {
+ // nested_a
+ if ('/nested/group/a' === $trimmedPathinfo) {
+ $ret = array('_route' => 'nested_a');
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_nested_a;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'nested_a'));
+ }
+
+ return $ret;
+ }
+ not_nested_a:
+
+ // nested_b
+ if ('/nested/group/b' === $trimmedPathinfo) {
+ $ret = array('_route' => 'nested_b');
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_nested_b;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'nested_b'));
+ }
+
+ return $ret;
+ }
+ not_nested_b:
+
+ // nested_c
+ if ('/nested/group/c' === $trimmedPathinfo) {
+ $ret = array('_route' => 'nested_c');
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_nested_c;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'nested_c'));
+ }
+
+ return $ret;
+ }
+ not_nested_c:
+
+ }
+
+ elseif (0 === strpos($pathinfo, '/slashed/group')) {
+ // slashed_a
+ if ('/slashed/group' === $trimmedPathinfo) {
+ $ret = array('_route' => 'slashed_a');
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_slashed_a;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'slashed_a'));
+ }
+
+ return $ret;
+ }
+ not_slashed_a:
+
+ // slashed_b
+ if ('/slashed/group/b' === $trimmedPathinfo) {
+ $ret = array('_route' => 'slashed_b');
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_slashed_b;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'slashed_b'));
+ }
+
+ return $ret;
+ }
+ not_slashed_b:
+
+ // slashed_c
+ if ('/slashed/group/c' === $trimmedPathinfo) {
+ $ret = array('_route' => 'slashed_c');
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_slashed_c;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'slashed_c'));
+ }
+
+ return $ret;
+ }
+ not_slashed_c:
+
+ }
+
+ if ('/' === $pathinfo && !$allow) {
+ throw new Symfony\Component\Routing\Exception\NoConfigurationException();
+ }
+
+ throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher6.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher6.php
new file mode 100644
index 0000000..48ecdf8
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher6.php
@@ -0,0 +1,213 @@
+<?php
+
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\RequestContext;
+
+/**
+ * This class has been auto-generated
+ * by the Symfony Routing Component.
+ */
+class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
+{
+ public function __construct(RequestContext $context)
+ {
+ $this->context = $context;
+ }
+
+ public function match($rawPathinfo)
+ {
+ $allow = array();
+ $pathinfo = rawurldecode($rawPathinfo);
+ $trimmedPathinfo = rtrim($pathinfo, '/');
+ $context = $this->context;
+ $request = $this->request ?: $this->createRequest($pathinfo);
+ $requestMethod = $canonicalMethod = $context->getMethod();
+
+ if ('HEAD' === $requestMethod) {
+ $canonicalMethod = 'GET';
+ }
+
+ if (0 === strpos($pathinfo, '/trailing/simple')) {
+ // simple_trailing_slash_no_methods
+ if ('/trailing/simple/no-methods/' === $pathinfo) {
+ return array('_route' => 'simple_trailing_slash_no_methods');
+ }
+
+ // simple_trailing_slash_GET_method
+ if ('/trailing/simple/get-method/' === $pathinfo) {
+ $ret = array('_route' => 'simple_trailing_slash_GET_method');
+ if (!in_array($canonicalMethod, array('GET'))) {
+ $allow = array_merge($allow, array('GET'));
+ goto not_simple_trailing_slash_GET_method;
+ }
+
+ return $ret;
+ }
+ not_simple_trailing_slash_GET_method:
+
+ // simple_trailing_slash_HEAD_method
+ if ('/trailing/simple/head-method/' === $pathinfo) {
+ $ret = array('_route' => 'simple_trailing_slash_HEAD_method');
+ if (!in_array($requestMethod, array('HEAD'))) {
+ $allow = array_merge($allow, array('HEAD'));
+ goto not_simple_trailing_slash_HEAD_method;
+ }
+
+ return $ret;
+ }
+ not_simple_trailing_slash_HEAD_method:
+
+ // simple_trailing_slash_POST_method
+ if ('/trailing/simple/post-method/' === $pathinfo) {
+ $ret = array('_route' => 'simple_trailing_slash_POST_method');
+ if (!in_array($requestMethod, array('POST'))) {
+ $allow = array_merge($allow, array('POST'));
+ goto not_simple_trailing_slash_POST_method;
+ }
+
+ return $ret;
+ }
+ not_simple_trailing_slash_POST_method:
+
+ }
+
+ elseif (0 === strpos($pathinfo, '/trailing/regex')) {
+ // regex_trailing_slash_no_methods
+ if (0 === strpos($pathinfo, '/trailing/regex/no-methods') && preg_match('#^/trailing/regex/no\\-methods/(?P<param>[^/]++)/$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_no_methods')), array ());
+ }
+
+ // regex_trailing_slash_GET_method
+ if (0 === strpos($pathinfo, '/trailing/regex/get-method') && preg_match('#^/trailing/regex/get\\-method/(?P<param>[^/]++)/$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_GET_method')), array ());
+ if (!in_array($canonicalMethod, array('GET'))) {
+ $allow = array_merge($allow, array('GET'));
+ goto not_regex_trailing_slash_GET_method;
+ }
+
+ return $ret;
+ }
+ not_regex_trailing_slash_GET_method:
+
+ // regex_trailing_slash_HEAD_method
+ if (0 === strpos($pathinfo, '/trailing/regex/head-method') && preg_match('#^/trailing/regex/head\\-method/(?P<param>[^/]++)/$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_HEAD_method')), array ());
+ if (!in_array($requestMethod, array('HEAD'))) {
+ $allow = array_merge($allow, array('HEAD'));
+ goto not_regex_trailing_slash_HEAD_method;
+ }
+
+ return $ret;
+ }
+ not_regex_trailing_slash_HEAD_method:
+
+ // regex_trailing_slash_POST_method
+ if (0 === strpos($pathinfo, '/trailing/regex/post-method') && preg_match('#^/trailing/regex/post\\-method/(?P<param>[^/]++)/$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_POST_method')), array ());
+ if (!in_array($requestMethod, array('POST'))) {
+ $allow = array_merge($allow, array('POST'));
+ goto not_regex_trailing_slash_POST_method;
+ }
+
+ return $ret;
+ }
+ not_regex_trailing_slash_POST_method:
+
+ }
+
+ elseif (0 === strpos($pathinfo, '/not-trailing/simple')) {
+ // simple_not_trailing_slash_no_methods
+ if ('/not-trailing/simple/no-methods' === $pathinfo) {
+ return array('_route' => 'simple_not_trailing_slash_no_methods');
+ }
+
+ // simple_not_trailing_slash_GET_method
+ if ('/not-trailing/simple/get-method' === $pathinfo) {
+ $ret = array('_route' => 'simple_not_trailing_slash_GET_method');
+ if (!in_array($canonicalMethod, array('GET'))) {
+ $allow = array_merge($allow, array('GET'));
+ goto not_simple_not_trailing_slash_GET_method;
+ }
+
+ return $ret;
+ }
+ not_simple_not_trailing_slash_GET_method:
+
+ // simple_not_trailing_slash_HEAD_method
+ if ('/not-trailing/simple/head-method' === $pathinfo) {
+ $ret = array('_route' => 'simple_not_trailing_slash_HEAD_method');
+ if (!in_array($requestMethod, array('HEAD'))) {
+ $allow = array_merge($allow, array('HEAD'));
+ goto not_simple_not_trailing_slash_HEAD_method;
+ }
+
+ return $ret;
+ }
+ not_simple_not_trailing_slash_HEAD_method:
+
+ // simple_not_trailing_slash_POST_method
+ if ('/not-trailing/simple/post-method' === $pathinfo) {
+ $ret = array('_route' => 'simple_not_trailing_slash_POST_method');
+ if (!in_array($requestMethod, array('POST'))) {
+ $allow = array_merge($allow, array('POST'));
+ goto not_simple_not_trailing_slash_POST_method;
+ }
+
+ return $ret;
+ }
+ not_simple_not_trailing_slash_POST_method:
+
+ }
+
+ elseif (0 === strpos($pathinfo, '/not-trailing/regex')) {
+ // regex_not_trailing_slash_no_methods
+ if (0 === strpos($pathinfo, '/not-trailing/regex/no-methods') && preg_match('#^/not\\-trailing/regex/no\\-methods/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_not_trailing_slash_no_methods')), array ());
+ }
+
+ // regex_not_trailing_slash_GET_method
+ if (0 === strpos($pathinfo, '/not-trailing/regex/get-method') && preg_match('#^/not\\-trailing/regex/get\\-method/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_not_trailing_slash_GET_method')), array ());
+ if (!in_array($canonicalMethod, array('GET'))) {
+ $allow = array_merge($allow, array('GET'));
+ goto not_regex_not_trailing_slash_GET_method;
+ }
+
+ return $ret;
+ }
+ not_regex_not_trailing_slash_GET_method:
+
+ // regex_not_trailing_slash_HEAD_method
+ if (0 === strpos($pathinfo, '/not-trailing/regex/head-method') && preg_match('#^/not\\-trailing/regex/head\\-method/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_not_trailing_slash_HEAD_method')), array ());
+ if (!in_array($requestMethod, array('HEAD'))) {
+ $allow = array_merge($allow, array('HEAD'));
+ goto not_regex_not_trailing_slash_HEAD_method;
+ }
+
+ return $ret;
+ }
+ not_regex_not_trailing_slash_HEAD_method:
+
+ // regex_not_trailing_slash_POST_method
+ if (0 === strpos($pathinfo, '/not-trailing/regex/post-method') && preg_match('#^/not\\-trailing/regex/post\\-method/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_not_trailing_slash_POST_method')), array ());
+ if (!in_array($requestMethod, array('POST'))) {
+ $allow = array_merge($allow, array('POST'));
+ goto not_regex_not_trailing_slash_POST_method;
+ }
+
+ return $ret;
+ }
+ not_regex_not_trailing_slash_POST_method:
+
+ }
+
+ if ('/' === $pathinfo && !$allow) {
+ throw new Symfony\Component\Routing\Exception\NoConfigurationException();
+ }
+
+ throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher7.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher7.php
new file mode 100644
index 0000000..81d76ea
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/dumper/url_matcher7.php
@@ -0,0 +1,249 @@
+<?php
+
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\RequestContext;
+
+/**
+ * This class has been auto-generated
+ * by the Symfony Routing Component.
+ */
+class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher
+{
+ public function __construct(RequestContext $context)
+ {
+ $this->context = $context;
+ }
+
+ public function match($rawPathinfo)
+ {
+ $allow = array();
+ $pathinfo = rawurldecode($rawPathinfo);
+ $trimmedPathinfo = rtrim($pathinfo, '/');
+ $context = $this->context;
+ $request = $this->request ?: $this->createRequest($pathinfo);
+ $requestMethod = $canonicalMethod = $context->getMethod();
+
+ if ('HEAD' === $requestMethod) {
+ $canonicalMethod = 'GET';
+ }
+
+ if (0 === strpos($pathinfo, '/trailing/simple')) {
+ // simple_trailing_slash_no_methods
+ if ('/trailing/simple/no-methods' === $trimmedPathinfo) {
+ $ret = array('_route' => 'simple_trailing_slash_no_methods');
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_simple_trailing_slash_no_methods;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'simple_trailing_slash_no_methods'));
+ }
+
+ return $ret;
+ }
+ not_simple_trailing_slash_no_methods:
+
+ // simple_trailing_slash_GET_method
+ if ('/trailing/simple/get-method' === $trimmedPathinfo) {
+ $ret = array('_route' => 'simple_trailing_slash_GET_method');
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_simple_trailing_slash_GET_method;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'simple_trailing_slash_GET_method'));
+ }
+
+ if (!in_array($canonicalMethod, array('GET'))) {
+ $allow = array_merge($allow, array('GET'));
+ goto not_simple_trailing_slash_GET_method;
+ }
+
+ return $ret;
+ }
+ not_simple_trailing_slash_GET_method:
+
+ // simple_trailing_slash_HEAD_method
+ if ('/trailing/simple/head-method/' === $pathinfo) {
+ $ret = array('_route' => 'simple_trailing_slash_HEAD_method');
+ if (!in_array($requestMethod, array('HEAD'))) {
+ $allow = array_merge($allow, array('HEAD'));
+ goto not_simple_trailing_slash_HEAD_method;
+ }
+
+ return $ret;
+ }
+ not_simple_trailing_slash_HEAD_method:
+
+ // simple_trailing_slash_POST_method
+ if ('/trailing/simple/post-method/' === $pathinfo) {
+ $ret = array('_route' => 'simple_trailing_slash_POST_method');
+ if (!in_array($requestMethod, array('POST'))) {
+ $allow = array_merge($allow, array('POST'));
+ goto not_simple_trailing_slash_POST_method;
+ }
+
+ return $ret;
+ }
+ not_simple_trailing_slash_POST_method:
+
+ }
+
+ elseif (0 === strpos($pathinfo, '/trailing/regex')) {
+ // regex_trailing_slash_no_methods
+ if (0 === strpos($pathinfo, '/trailing/regex/no-methods') && preg_match('#^/trailing/regex/no\\-methods/(?P<param>[^/]++)/?$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_no_methods')), array ());
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_regex_trailing_slash_no_methods;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'regex_trailing_slash_no_methods'));
+ }
+
+ return $ret;
+ }
+ not_regex_trailing_slash_no_methods:
+
+ // regex_trailing_slash_GET_method
+ if (0 === strpos($pathinfo, '/trailing/regex/get-method') && preg_match('#^/trailing/regex/get\\-method/(?P<param>[^/]++)/?$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_GET_method')), array ());
+ if ('/' === substr($pathinfo, -1)) {
+ // no-op
+ } elseif ('GET' !== $canonicalMethod) {
+ goto not_regex_trailing_slash_GET_method;
+ } else {
+ return array_replace($ret, $this->redirect($rawPathinfo.'/', 'regex_trailing_slash_GET_method'));
+ }
+
+ if (!in_array($canonicalMethod, array('GET'))) {
+ $allow = array_merge($allow, array('GET'));
+ goto not_regex_trailing_slash_GET_method;
+ }
+
+ return $ret;
+ }
+ not_regex_trailing_slash_GET_method:
+
+ // regex_trailing_slash_HEAD_method
+ if (0 === strpos($pathinfo, '/trailing/regex/head-method') && preg_match('#^/trailing/regex/head\\-method/(?P<param>[^/]++)/$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_HEAD_method')), array ());
+ if (!in_array($requestMethod, array('HEAD'))) {
+ $allow = array_merge($allow, array('HEAD'));
+ goto not_regex_trailing_slash_HEAD_method;
+ }
+
+ return $ret;
+ }
+ not_regex_trailing_slash_HEAD_method:
+
+ // regex_trailing_slash_POST_method
+ if (0 === strpos($pathinfo, '/trailing/regex/post-method') && preg_match('#^/trailing/regex/post\\-method/(?P<param>[^/]++)/$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_POST_method')), array ());
+ if (!in_array($requestMethod, array('POST'))) {
+ $allow = array_merge($allow, array('POST'));
+ goto not_regex_trailing_slash_POST_method;
+ }
+
+ return $ret;
+ }
+ not_regex_trailing_slash_POST_method:
+
+ }
+
+ elseif (0 === strpos($pathinfo, '/not-trailing/simple')) {
+ // simple_not_trailing_slash_no_methods
+ if ('/not-trailing/simple/no-methods' === $pathinfo) {
+ return array('_route' => 'simple_not_trailing_slash_no_methods');
+ }
+
+ // simple_not_trailing_slash_GET_method
+ if ('/not-trailing/simple/get-method' === $pathinfo) {
+ $ret = array('_route' => 'simple_not_trailing_slash_GET_method');
+ if (!in_array($canonicalMethod, array('GET'))) {
+ $allow = array_merge($allow, array('GET'));
+ goto not_simple_not_trailing_slash_GET_method;
+ }
+
+ return $ret;
+ }
+ not_simple_not_trailing_slash_GET_method:
+
+ // simple_not_trailing_slash_HEAD_method
+ if ('/not-trailing/simple/head-method' === $pathinfo) {
+ $ret = array('_route' => 'simple_not_trailing_slash_HEAD_method');
+ if (!in_array($requestMethod, array('HEAD'))) {
+ $allow = array_merge($allow, array('HEAD'));
+ goto not_simple_not_trailing_slash_HEAD_method;
+ }
+
+ return $ret;
+ }
+ not_simple_not_trailing_slash_HEAD_method:
+
+ // simple_not_trailing_slash_POST_method
+ if ('/not-trailing/simple/post-method' === $pathinfo) {
+ $ret = array('_route' => 'simple_not_trailing_slash_POST_method');
+ if (!in_array($requestMethod, array('POST'))) {
+ $allow = array_merge($allow, array('POST'));
+ goto not_simple_not_trailing_slash_POST_method;
+ }
+
+ return $ret;
+ }
+ not_simple_not_trailing_slash_POST_method:
+
+ }
+
+ elseif (0 === strpos($pathinfo, '/not-trailing/regex')) {
+ // regex_not_trailing_slash_no_methods
+ if (0 === strpos($pathinfo, '/not-trailing/regex/no-methods') && preg_match('#^/not\\-trailing/regex/no\\-methods/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
+ return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_not_trailing_slash_no_methods')), array ());
+ }
+
+ // regex_not_trailing_slash_GET_method
+ if (0 === strpos($pathinfo, '/not-trailing/regex/get-method') && preg_match('#^/not\\-trailing/regex/get\\-method/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_not_trailing_slash_GET_method')), array ());
+ if (!in_array($canonicalMethod, array('GET'))) {
+ $allow = array_merge($allow, array('GET'));
+ goto not_regex_not_trailing_slash_GET_method;
+ }
+
+ return $ret;
+ }
+ not_regex_not_trailing_slash_GET_method:
+
+ // regex_not_trailing_slash_HEAD_method
+ if (0 === strpos($pathinfo, '/not-trailing/regex/head-method') && preg_match('#^/not\\-trailing/regex/head\\-method/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_not_trailing_slash_HEAD_method')), array ());
+ if (!in_array($requestMethod, array('HEAD'))) {
+ $allow = array_merge($allow, array('HEAD'));
+ goto not_regex_not_trailing_slash_HEAD_method;
+ }
+
+ return $ret;
+ }
+ not_regex_not_trailing_slash_HEAD_method:
+
+ // regex_not_trailing_slash_POST_method
+ if (0 === strpos($pathinfo, '/not-trailing/regex/post-method') && preg_match('#^/not\\-trailing/regex/post\\-method/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_not_trailing_slash_POST_method')), array ());
+ if (!in_array($requestMethod, array('POST'))) {
+ $allow = array_merge($allow, array('POST'));
+ goto not_regex_not_trailing_slash_POST_method;
+ }
+
+ return $ret;
+ }
+ not_regex_not_trailing_slash_POST_method:
+
+ }
+
+ if ('/' === $pathinfo && !$allow) {
+ throw new Symfony\Component\Routing\Exception\NoConfigurationException();
+ }
+
+ throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/empty.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/empty.yml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/empty.yml
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/file_resource.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/file_resource.yml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/file_resource.yml
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/foo.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/foo.xml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/foo.xml
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/foo1.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/foo1.xml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/foo1.xml
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/bar.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/bar.xml
new file mode 100644
index 0000000..0d31eeb
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/bar.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="bar_route" path="/bar" controller="AppBundle:Bar:view" />
+</routes>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/bar.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/bar.yml
new file mode 100644
index 0000000..ba3bc22
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/bar.yml
@@ -0,0 +1,4 @@
+bar_route:
+ path: /bar
+ defaults:
+ _controller: AppBundle:Bar:view
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/baz.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/baz.xml
new file mode 100644
index 0000000..3abba1a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/baz.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="baz_route" path="/baz" controller="AppBundle:Baz:view" />
+</routes>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/baz.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/baz.yml
new file mode 100644
index 0000000..f7d8c67
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/baz.yml
@@ -0,0 +1,4 @@
+baz_route:
+ path: /baz
+ defaults:
+ _controller: AppBundle:Baz:view
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_multiple.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_multiple.xml
new file mode 100644
index 0000000..ca6b1b5
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_multiple.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <import resource="ba?.xml" />
+</routes>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_multiple.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_multiple.yml
new file mode 100644
index 0000000..d1ae585
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_multiple.yml
@@ -0,0 +1,2 @@
+_static:
+ resource: ba?.yml
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_single.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_single.xml
new file mode 100644
index 0000000..15f5698
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_single.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <import resource="b?r.xml" />
+</routes>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_single.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_single.yml
new file mode 100644
index 0000000..f56ddbd
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/import_single.yml
@@ -0,0 +1,2 @@
+_static:
+ resource: b?r.yml
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/php_dsl.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/php_dsl.php
new file mode 100644
index 0000000..897fa11
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/php_dsl.php
@@ -0,0 +1,7 @@
+<?php
+
+namespace Symfony\Component\Routing\Loader\Configurator;
+
+return function (RoutingConfigurator $routes) {
+ return $routes->import('php_dsl_ba?.php');
+};
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/php_dsl_bar.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/php_dsl_bar.php
new file mode 100644
index 0000000..e2b91b1
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/php_dsl_bar.php
@@ -0,0 +1,12 @@
+<?php
+
+namespace Symfony\Component\Routing\Loader\Configurator;
+
+return function (RoutingConfigurator $routes) {
+ $collection = $routes->collection();
+
+ $collection->add('bar_route', '/bar')
+ ->defaults(array('_controller' => 'AppBundle:Bar:view'));
+
+ return $collection;
+};
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/php_dsl_baz.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/php_dsl_baz.php
new file mode 100644
index 0000000..ca8f188
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/glob/php_dsl_baz.php
@@ -0,0 +1,12 @@
+<?php
+
+namespace Symfony\Component\Routing\Loader\Configurator;
+
+return function (RoutingConfigurator $routes) {
+ $collection = $routes->collection();
+
+ $collection->add('baz_route', '/baz')
+ ->defaults(array('_controller' => 'AppBundle:Baz:view'));
+
+ return $collection;
+};
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/incomplete.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/incomplete.yml
new file mode 100644
index 0000000..df64d32
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/incomplete.yml
@@ -0,0 +1,2 @@
+blog_show:
+ defaults: { _controller: MyBlogBundle:Blog:show }
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/list_defaults.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/list_defaults.xml
new file mode 100644
index 0000000..f93bf9c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/list_defaults.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="blog" path="/blog">
+ <default key="_controller">
+ <string>AcmeBlogBundle:Blog:index</string>
+ </default>
+ <default key="values">
+ <list>
+ <bool>true</bool>
+ <int>1</int>
+ <float>3.5</float>
+ <string>foo</string>
+ </list>
+ </default>
+ </route>
+</routes>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/list_in_list_defaults.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/list_in_list_defaults.xml
new file mode 100644
index 0000000..987086d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/list_in_list_defaults.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="blog" path="/blog">
+ <default key="_controller">
+ <string>AcmeBlogBundle:Blog:index</string>
+ </default>
+ <default key="values">
+ <list>
+ <list>
+ <bool>true</bool>
+ <int>1</int>
+ <float>3.5</float>
+ <string>foo</string>
+ </list>
+ </list>
+ </default>
+ </route>
+</routes>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/list_in_map_defaults.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/list_in_map_defaults.xml
new file mode 100644
index 0000000..32d393c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/list_in_map_defaults.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="blog" path="/blog">
+ <default key="_controller">
+ <string>AcmeBlogBundle:Blog:index</string>
+ </default>
+ <default key="values">
+ <map>
+ <list key="list">
+ <bool>true</bool>
+ <int>1</int>
+ <float>3.5</float>
+ <string>foo</string>
+ </list>
+ </map>
+ </default>
+ </route>
+</routes>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/list_null_values.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/list_null_values.xml
new file mode 100644
index 0000000..c70e03c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/list_null_values.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="blog" path="/blog">
+ <default key="_controller">
+ <string>AcmeBlogBundle:Blog:index</string>
+ </default>
+ <default key="list">
+ <list>
+ <bool xsi:nil="true" />
+ <int xsi:nil="true" />
+ <float xsi:nil="1" />
+ <string xsi:nil="true" />
+ <list xsi:nil="true" />
+ <map xsi:nil="true" />
+ </list>
+ </default>
+ </route>
+</routes>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/map_defaults.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/map_defaults.xml
new file mode 100644
index 0000000..47feb29
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/map_defaults.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="blog" path="/blog">
+ <default key="_controller">
+ <string>AcmeBlogBundle:Blog:index</string>
+ </default>
+ <default key="values">
+ <map>
+ <bool key="public">true</bool>
+ <int key="page">1</int>
+ <float key="price">3.5</float>
+ <string key="title">foo</string>
+ </map>
+ </default>
+ </route>
+</routes>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/map_in_list_defaults.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/map_in_list_defaults.xml
new file mode 100644
index 0000000..6d77065
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/map_in_list_defaults.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="blog" path="/blog">
+ <default key="_controller">
+ <string>AcmeBlogBundle:Blog:index</string>
+ </default>
+ <default key="values">
+ <list>
+ <map>
+ <bool key="public">true</bool>
+ <int key="page">1</int>
+ <float key="price">3.5</float>
+ <string key="title">foo</string>
+ </map>
+ </list>
+ </default>
+ </route>
+</routes>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/map_in_map_defaults.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/map_in_map_defaults.xml
new file mode 100644
index 0000000..2beee61
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/map_in_map_defaults.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="blog" path="/blog">
+ <default key="_controller">
+ <string>AcmeBlogBundle:Blog:index</string>
+ </default>
+ <default key="values">
+ <map>
+ <map key="map">
+ <bool key="public">true</bool>
+ <int key="page">1</int>
+ <float key="price">3.5</float>
+ <string key="title">foo</string>
+ </map>
+ </map>
+ </default>
+ </route>
+</routes>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/map_null_values.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/map_null_values.xml
new file mode 100644
index 0000000..8fd8954
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/map_null_values.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="blog" path="/blog">
+ <default key="_controller">
+ <string>AcmeBlogBundle:Blog:index</string>
+ </default>
+ <default key="map">
+ <map>
+ <bool key="boolean" xsi:nil="true" />
+ <int key="integer" xsi:nil="true" />
+ <float key="float" xsi:nil="true" />
+ <string key="string" xsi:nil="1" />
+ <list key="list" xsi:nil="true" />
+ <map key="map" xsi:nil="true" />
+ </map>
+ </default>
+ </route>
+</routes>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/missing_id.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/missing_id.xml
new file mode 100644
index 0000000..4ea4115
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/missing_id.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route path="/test"></route>
+</routes>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/missing_path.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/missing_path.xml
new file mode 100644
index 0000000..ef5bc08
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/missing_path.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="myroute"></route>
+</routes>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/namespaceprefix.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/namespaceprefix.xml
new file mode 100644
index 0000000..e33955a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/namespaceprefix.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<r:routes xmlns:r="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <r:route id="blog_show" path="/blog/{slug}" host="{_locale}.example.com">
+ <r:default key="_controller">MyBundle:Blog:show</r:default>
+ <requirement xmlns="http://symfony.com/schema/routing" key="slug">\w+</requirement>
+ <r2:requirement xmlns:r2="http://symfony.com/schema/routing" key="_locale">en|fr|de</r2:requirement>
+ <r:option key="compiler_class">RouteCompiler</r:option>
+ <r:default key="page">
+ <r3:int xmlns:r3="http://symfony.com/schema/routing">1</r3:int>
+ </r:default>
+ </r:route>
+</r:routes>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonesense_resource_plus_path.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonesense_resource_plus_path.yml
new file mode 100644
index 0000000..a3e9473
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonesense_resource_plus_path.yml
@@ -0,0 +1,3 @@
+blog_show:
+ resource: validpattern.yml
+ path: /test
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonesense_type_without_resource.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonesense_type_without_resource.yml
new file mode 100644
index 0000000..547cda3
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonesense_type_without_resource.yml
@@ -0,0 +1,3 @@
+blog_show:
+ path: /blog/{slug}
+ type: custom
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonvalid.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonvalid.xml
new file mode 100644
index 0000000..dc147d2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonvalid.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="blog_show" path="/blog/{slug}">
+ <default key="_controller">MyBundle:Blog:show</default>
+ <!-- </route> -->
+</routes>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonvalid.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonvalid.yml
new file mode 100644
index 0000000..257cc56
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonvalid.yml
@@ -0,0 +1 @@
+foo
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonvalid2.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonvalid2.yml
new file mode 100644
index 0000000..cfa9992
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonvalid2.yml
@@ -0,0 +1 @@
+route: string
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonvalidkeys.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonvalidkeys.yml
new file mode 100644
index 0000000..015e270
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonvalidkeys.yml
@@ -0,0 +1,3 @@
+someroute:
+ resource: path/to/some.yml
+ name_prefix: test_
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonvalidnode.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonvalidnode.xml
new file mode 100644
index 0000000..863ef03
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonvalidnode.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <foo>bar</foo>
+</routes>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonvalidroute.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonvalidroute.xml
new file mode 100644
index 0000000..908958c
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/nonvalidroute.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="blog_show" path="/blog/{slug}">
+ <default key="_controller">MyBundle:Blog:show</default>
+ <option key="compiler_class">RouteCompiler</option>
+ <foo key="bar">baz</foo>
+ </route>
+</routes>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/null_values.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/null_values.xml
new file mode 100644
index 0000000..f9e2aa2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/null_values.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="blog_show" path="/blog/{slug}">
+ <default key="foo" xsi:nil="true" />
+ <default key="bar" xsi:nil="1" />
+ <default key="foobar" xsi:nil="false">foo</default>
+ <default key="baz" xsi:nil="0">bar</default>
+ </route>
+</routes>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/php_dsl.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/php_dsl.php
new file mode 100644
index 0000000..0780c9f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/php_dsl.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace Symfony\Component\Routing\Loader\Configurator;
+
+return function (RoutingConfigurator $routes) {
+ $routes
+ ->collection()
+ ->add('foo', '/foo')
+ ->condition('abc')
+ ->options(array('utf8' => true))
+ ->add('buz', 'zub')
+ ->controller('foo:act');
+
+ $routes->import('php_dsl_sub.php')
+ ->prefix('/sub')
+ ->requirements(array('id' => '\d+'));
+
+ $routes->add('ouf', '/ouf')
+ ->schemes(array('https'))
+ ->methods(array('GET'))
+ ->defaults(array('id' => 0));
+};
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/php_dsl_sub.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/php_dsl_sub.php
new file mode 100644
index 0000000..9eb444d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/php_dsl_sub.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace Symfony\Component\Routing\Loader\Configurator;
+
+return function (RoutingConfigurator $routes) {
+ $add = $routes->collection('c_')
+ ->prefix('pub');
+
+ $add('bar', '/bar');
+
+ $add->collection('pub_')
+ ->host('host')
+ ->add('buz', 'buz');
+};
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/scalar_defaults.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/scalar_defaults.xml
new file mode 100644
index 0000000..ecfde28
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/scalar_defaults.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing
+ http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="blog" path="/blog">
+ <default key="_controller">
+ <string>AcmeBlogBundle:Blog:index</string>
+ </default>
+ <default key="slug" xsi:nil="true" />
+ <default key="published">
+ <bool>true</bool>
+ </default>
+ <default key="page">
+ <int>1</int>
+ </default>
+ <default key="price">
+ <float>3.5</float>
+ </default>
+ <default key="archived">
+ <bool>false</bool>
+ </default>
+ <default key="free">
+ <bool>1</bool>
+ </default>
+ <default key="locked">
+ <bool>0</bool>
+ </default>
+ <default key="foo" xsi:nil="true" />
+ <default key="bar" xsi:nil="1" />
+ </route>
+</routes>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/special_route_name.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/special_route_name.yml
new file mode 100644
index 0000000..78be239
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/special_route_name.yml
@@ -0,0 +1,2 @@
+"#$péß^a|":
+ path: "true"
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/validpattern.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/validpattern.php
new file mode 100644
index 0000000..edc16d8
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/validpattern.php
@@ -0,0 +1,18 @@
+<?php
+
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\Route;
+
+$collection = new RouteCollection();
+$collection->add('blog_show', new Route(
+ '/blog/{slug}',
+ array('_controller' => 'MyBlogBundle:Blog:show'),
+ array('locale' => '\w+'),
+ array('compiler_class' => 'RouteCompiler'),
+ '{locale}.example.com',
+ array('https'),
+ array('GET', 'POST', 'put', 'OpTiOnS'),
+ 'context.getMethod() == "GET"'
+));
+
+return $collection;
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/validpattern.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/validpattern.xml
new file mode 100644
index 0000000..dbc72e4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/validpattern.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <route id="blog_show" path="/blog/{slug}" host="{locale}.example.com" methods="GET|POST put,OpTiOnS" schemes="hTTps">
+ <default key="_controller">MyBundle:Blog:show</default>
+ <requirement key="locale">\w+</requirement>
+ <option key="compiler_class">RouteCompiler</option>
+ <condition>context.getMethod() == "GET"</condition>
+ </route>
+
+ <route id="blog_show_inherited" path="/blog/{slug}" />
+</routes>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/validpattern.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/validpattern.yml
new file mode 100644
index 0000000..565abaa
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/validpattern.yml
@@ -0,0 +1,13 @@
+blog_show:
+ path: /blog/{slug}
+ defaults: { _controller: "MyBundle:Blog:show" }
+ host: "{locale}.example.com"
+ requirements: { 'locale': '\w+' }
+ methods: ['GET','POST','put','OpTiOnS']
+ schemes: ['https']
+ condition: 'context.getMethod() == "GET"'
+ options:
+ compiler_class: RouteCompiler
+
+blog_show_inherited:
+ path: /blog/{slug}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/validresource.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/validresource.php
new file mode 100644
index 0000000..482c80b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/validresource.php
@@ -0,0 +1,18 @@
+<?php
+
+/** @var $loader \Symfony\Component\Routing\Loader\PhpFileLoader */
+/** @var \Symfony\Component\Routing\RouteCollection $collection */
+$collection = $loader->import('validpattern.php');
+$collection->addDefaults(array(
+ 'foo' => 123,
+));
+$collection->addRequirements(array(
+ 'foo' => '\d+',
+));
+$collection->addOptions(array(
+ 'foo' => 'bar',
+));
+$collection->setCondition('context.getMethod() == "POST"');
+$collection->addPrefix('/prefix');
+
+return $collection;
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/validresource.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/validresource.xml
new file mode 100644
index 0000000..b7a15dd
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/validresource.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<routes xmlns="http://symfony.com/schema/routing"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
+
+ <import resource="validpattern.xml" prefix="/{foo}" host="">
+ <default key="foo">123</default>
+ <requirement key="foo">\d+</requirement>
+ <option key="foo">bar</option>
+ <condition>context.getMethod() == "POST"</condition>
+ </import>
+</routes>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/validresource.yml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/validresource.yml
new file mode 100644
index 0000000..faf2263
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/validresource.yml
@@ -0,0 +1,8 @@
+_blog:
+ resource: validpattern.yml
+ prefix: /{foo}
+ defaults: { 'foo': '123' }
+ requirements: { 'foo': '\d+' }
+ options: { 'foo': 'bar' }
+ host: ""
+ condition: 'context.getMethod() == "POST"'
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/with_define_path_variable.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/with_define_path_variable.php
new file mode 100644
index 0000000..5871420
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/with_define_path_variable.php
@@ -0,0 +1,5 @@
+<?php
+
+$path = '/1/2/3';
+
+return new \Symfony\Component\Routing\RouteCollection();
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/withdoctype.xml b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/withdoctype.xml
new file mode 100644
index 0000000..f217d5b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Fixtures/withdoctype.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<!DOCTYPE foo>
+<foo></foo>
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Generator/Dumper/PhpGeneratorDumperTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Generator/Dumper/PhpGeneratorDumperTest.php
new file mode 100644
index 0000000..f84802b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Generator/Dumper/PhpGeneratorDumperTest.php
@@ -0,0 +1,181 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Generator\Dumper;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\Generator\Dumper\PhpGeneratorDumper;
+use Symfony\Component\Routing\RequestContext;
+
+class PhpGeneratorDumperTest extends TestCase
+{
+ /**
+ * @var RouteCollection
+ */
+ private $routeCollection;
+
+ /**
+ * @var PhpGeneratorDumper
+ */
+ private $generatorDumper;
+
+ /**
+ * @var string
+ */
+ private $testTmpFilepath;
+
+ /**
+ * @var string
+ */
+ private $largeTestTmpFilepath;
+
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $this->routeCollection = new RouteCollection();
+ $this->generatorDumper = new PhpGeneratorDumper($this->routeCollection);
+ $this->testTmpFilepath = sys_get_temp_dir().DIRECTORY_SEPARATOR.'php_generator.'.$this->getName().'.php';
+ $this->largeTestTmpFilepath = sys_get_temp_dir().DIRECTORY_SEPARATOR.'php_generator.'.$this->getName().'.large.php';
+ @unlink($this->testTmpFilepath);
+ @unlink($this->largeTestTmpFilepath);
+ }
+
+ protected function tearDown()
+ {
+ parent::tearDown();
+
+ @unlink($this->testTmpFilepath);
+
+ $this->routeCollection = null;
+ $this->generatorDumper = null;
+ $this->testTmpFilepath = null;
+ }
+
+ public function testDumpWithRoutes()
+ {
+ $this->routeCollection->add('Test', new Route('/testing/{foo}'));
+ $this->routeCollection->add('Test2', new Route('/testing2'));
+
+ file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump());
+ include $this->testTmpFilepath;
+
+ $projectUrlGenerator = new \ProjectUrlGenerator(new RequestContext('/app.php'));
+
+ $absoluteUrlWithParameter = $projectUrlGenerator->generate('Test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_URL);
+ $absoluteUrlWithoutParameter = $projectUrlGenerator->generate('Test2', array(), UrlGeneratorInterface::ABSOLUTE_URL);
+ $relativeUrlWithParameter = $projectUrlGenerator->generate('Test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_PATH);
+ $relativeUrlWithoutParameter = $projectUrlGenerator->generate('Test2', array(), UrlGeneratorInterface::ABSOLUTE_PATH);
+
+ $this->assertEquals('http://localhost/app.php/testing/bar', $absoluteUrlWithParameter);
+ $this->assertEquals('http://localhost/app.php/testing2', $absoluteUrlWithoutParameter);
+ $this->assertEquals('/app.php/testing/bar', $relativeUrlWithParameter);
+ $this->assertEquals('/app.php/testing2', $relativeUrlWithoutParameter);
+ }
+
+ public function testDumpWithTooManyRoutes()
+ {
+ if (defined('HHVM_VERSION_ID')) {
+ $this->markTestSkipped('HHVM consumes too much memory on this test.');
+ }
+
+ $this->routeCollection->add('Test', new Route('/testing/{foo}'));
+ for ($i = 0; $i < 32769; ++$i) {
+ $this->routeCollection->add('route_'.$i, new Route('/route_'.$i));
+ }
+ $this->routeCollection->add('Test2', new Route('/testing2'));
+
+ file_put_contents($this->largeTestTmpFilepath, $this->generatorDumper->dump(array(
+ 'class' => 'ProjectLargeUrlGenerator',
+ )));
+ $this->routeCollection = $this->generatorDumper = null;
+ include $this->largeTestTmpFilepath;
+
+ $projectUrlGenerator = new \ProjectLargeUrlGenerator(new RequestContext('/app.php'));
+
+ $absoluteUrlWithParameter = $projectUrlGenerator->generate('Test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_URL);
+ $absoluteUrlWithoutParameter = $projectUrlGenerator->generate('Test2', array(), UrlGeneratorInterface::ABSOLUTE_URL);
+ $relativeUrlWithParameter = $projectUrlGenerator->generate('Test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_PATH);
+ $relativeUrlWithoutParameter = $projectUrlGenerator->generate('Test2', array(), UrlGeneratorInterface::ABSOLUTE_PATH);
+
+ $this->assertEquals('http://localhost/app.php/testing/bar', $absoluteUrlWithParameter);
+ $this->assertEquals('http://localhost/app.php/testing2', $absoluteUrlWithoutParameter);
+ $this->assertEquals('/app.php/testing/bar', $relativeUrlWithParameter);
+ $this->assertEquals('/app.php/testing2', $relativeUrlWithoutParameter);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testDumpWithoutRoutes()
+ {
+ file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump(array('class' => 'WithoutRoutesUrlGenerator')));
+ include $this->testTmpFilepath;
+
+ $projectUrlGenerator = new \WithoutRoutesUrlGenerator(new RequestContext('/app.php'));
+
+ $projectUrlGenerator->generate('Test', array());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\RouteNotFoundException
+ */
+ public function testGenerateNonExistingRoute()
+ {
+ $this->routeCollection->add('Test', new Route('/test'));
+
+ file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump(array('class' => 'NonExistingRoutesUrlGenerator')));
+ include $this->testTmpFilepath;
+
+ $projectUrlGenerator = new \NonExistingRoutesUrlGenerator(new RequestContext());
+ $url = $projectUrlGenerator->generate('NonExisting', array());
+ }
+
+ public function testDumpForRouteWithDefaults()
+ {
+ $this->routeCollection->add('Test', new Route('/testing/{foo}', array('foo' => 'bar')));
+
+ file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump(array('class' => 'DefaultRoutesUrlGenerator')));
+ include $this->testTmpFilepath;
+
+ $projectUrlGenerator = new \DefaultRoutesUrlGenerator(new RequestContext());
+ $url = $projectUrlGenerator->generate('Test', array());
+
+ $this->assertEquals('/testing', $url);
+ }
+
+ public function testDumpWithSchemeRequirement()
+ {
+ $this->routeCollection->add('Test1', new Route('/testing', array(), array(), array(), '', array('ftp', 'https')));
+
+ file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump(array('class' => 'SchemeUrlGenerator')));
+ include $this->testTmpFilepath;
+
+ $projectUrlGenerator = new \SchemeUrlGenerator(new RequestContext('/app.php'));
+
+ $absoluteUrl = $projectUrlGenerator->generate('Test1', array(), UrlGeneratorInterface::ABSOLUTE_URL);
+ $relativeUrl = $projectUrlGenerator->generate('Test1', array(), UrlGeneratorInterface::ABSOLUTE_PATH);
+
+ $this->assertEquals('ftp://localhost/app.php/testing', $absoluteUrl);
+ $this->assertEquals('ftp://localhost/app.php/testing', $relativeUrl);
+
+ $projectUrlGenerator = new \SchemeUrlGenerator(new RequestContext('/app.php', 'GET', 'localhost', 'https'));
+
+ $absoluteUrl = $projectUrlGenerator->generate('Test1', array(), UrlGeneratorInterface::ABSOLUTE_URL);
+ $relativeUrl = $projectUrlGenerator->generate('Test1', array(), UrlGeneratorInterface::ABSOLUTE_PATH);
+
+ $this->assertEquals('https://localhost/app.php/testing', $absoluteUrl);
+ $this->assertEquals('/app.php/testing', $relativeUrl);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Generator/UrlGeneratorTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Generator/UrlGeneratorTest.php
new file mode 100644
index 0000000..68add77
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Generator/UrlGeneratorTest.php
@@ -0,0 +1,724 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Generator;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\Generator\UrlGenerator;
+use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
+use Symfony\Component\Routing\RequestContext;
+
+class UrlGeneratorTest extends TestCase
+{
+ public function testAbsoluteUrlWithPort80()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing'));
+ $url = $this->getGenerator($routes)->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL);
+
+ $this->assertEquals('http://localhost/app.php/testing', $url);
+ }
+
+ public function testAbsoluteSecureUrlWithPort443()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing'));
+ $url = $this->getGenerator($routes, array('scheme' => 'https'))->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL);
+
+ $this->assertEquals('https://localhost/app.php/testing', $url);
+ }
+
+ public function testAbsoluteUrlWithNonStandardPort()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing'));
+ $url = $this->getGenerator($routes, array('httpPort' => 8080))->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL);
+
+ $this->assertEquals('http://localhost:8080/app.php/testing', $url);
+ }
+
+ public function testAbsoluteSecureUrlWithNonStandardPort()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing'));
+ $url = $this->getGenerator($routes, array('httpsPort' => 8080, 'scheme' => 'https'))->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL);
+
+ $this->assertEquals('https://localhost:8080/app.php/testing', $url);
+ }
+
+ public function testRelativeUrlWithoutParameters()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing'));
+ $url = $this->getGenerator($routes)->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_PATH);
+
+ $this->assertEquals('/app.php/testing', $url);
+ }
+
+ public function testRelativeUrlWithParameter()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing/{foo}'));
+ $url = $this->getGenerator($routes)->generate('test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_PATH);
+
+ $this->assertEquals('/app.php/testing/bar', $url);
+ }
+
+ public function testRelativeUrlWithNullParameter()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing.{format}', array('format' => null)));
+ $url = $this->getGenerator($routes)->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_PATH);
+
+ $this->assertEquals('/app.php/testing', $url);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
+ */
+ public function testRelativeUrlWithNullParameterButNotOptional()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing/{foo}/bar', array('foo' => null)));
+ // This must raise an exception because the default requirement for "foo" is "[^/]+" which is not met with these params.
+ // Generating path "/testing//bar" would be wrong as matching this route would fail.
+ $this->getGenerator($routes)->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_PATH);
+ }
+
+ public function testRelativeUrlWithOptionalZeroParameter()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing/{page}'));
+ $url = $this->getGenerator($routes)->generate('test', array('page' => 0), UrlGeneratorInterface::ABSOLUTE_PATH);
+
+ $this->assertEquals('/app.php/testing/0', $url);
+ }
+
+ public function testNotPassedOptionalParameterInBetween()
+ {
+ $routes = $this->getRoutes('test', new Route('/{slug}/{page}', array('slug' => 'index', 'page' => 0)));
+ $this->assertSame('/app.php/index/1', $this->getGenerator($routes)->generate('test', array('page' => 1)));
+ $this->assertSame('/app.php/', $this->getGenerator($routes)->generate('test'));
+ }
+
+ public function testRelativeUrlWithExtraParameters()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing'));
+ $url = $this->getGenerator($routes)->generate('test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_PATH);
+
+ $this->assertEquals('/app.php/testing?foo=bar', $url);
+ }
+
+ public function testAbsoluteUrlWithExtraParameters()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing'));
+ $url = $this->getGenerator($routes)->generate('test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_URL);
+
+ $this->assertEquals('http://localhost/app.php/testing?foo=bar', $url);
+ }
+
+ public function testUrlWithNullExtraParameters()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing'));
+ $url = $this->getGenerator($routes)->generate('test', array('foo' => null), UrlGeneratorInterface::ABSOLUTE_URL);
+
+ $this->assertEquals('http://localhost/app.php/testing', $url);
+ }
+
+ public function testUrlWithExtraParametersFromGlobals()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing'));
+ $generator = $this->getGenerator($routes);
+ $context = new RequestContext('/app.php');
+ $context->setParameter('bar', 'bar');
+ $generator->setContext($context);
+ $url = $generator->generate('test', array('foo' => 'bar'));
+
+ $this->assertEquals('/app.php/testing?foo=bar', $url);
+ }
+
+ public function testUrlWithGlobalParameter()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing/{foo}'));
+ $generator = $this->getGenerator($routes);
+ $context = new RequestContext('/app.php');
+ $context->setParameter('foo', 'bar');
+ $generator->setContext($context);
+ $url = $generator->generate('test', array());
+
+ $this->assertEquals('/app.php/testing/bar', $url);
+ }
+
+ public function testGlobalParameterHasHigherPriorityThanDefault()
+ {
+ $routes = $this->getRoutes('test', new Route('/{_locale}', array('_locale' => 'en')));
+ $generator = $this->getGenerator($routes);
+ $context = new RequestContext('/app.php');
+ $context->setParameter('_locale', 'de');
+ $generator->setContext($context);
+ $url = $generator->generate('test', array());
+
+ $this->assertSame('/app.php/de', $url);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\RouteNotFoundException
+ */
+ public function testGenerateWithoutRoutes()
+ {
+ $routes = $this->getRoutes('foo', new Route('/testing/{foo}'));
+ $this->getGenerator($routes)->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\MissingMandatoryParametersException
+ */
+ public function testGenerateForRouteWithoutMandatoryParameter()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing/{foo}'));
+ $this->getGenerator($routes)->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
+ */
+ public function testGenerateForRouteWithInvalidOptionalParameter()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing/{foo}', array('foo' => '1'), array('foo' => 'd+')));
+ $this->getGenerator($routes)->generate('test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_URL);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
+ */
+ public function testGenerateForRouteWithInvalidParameter()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing/{foo}', array(), array('foo' => '1|2')));
+ $this->getGenerator($routes)->generate('test', array('foo' => '0'), UrlGeneratorInterface::ABSOLUTE_URL);
+ }
+
+ public function testGenerateForRouteWithInvalidOptionalParameterNonStrict()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing/{foo}', array('foo' => '1'), array('foo' => 'd+')));
+ $generator = $this->getGenerator($routes);
+ $generator->setStrictRequirements(false);
+ $this->assertNull($generator->generate('test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_URL));
+ }
+
+ public function testGenerateForRouteWithInvalidOptionalParameterNonStrictWithLogger()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing/{foo}', array('foo' => '1'), array('foo' => 'd+')));
+ $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
+ $logger->expects($this->once())
+ ->method('error');
+ $generator = $this->getGenerator($routes, array(), $logger);
+ $generator->setStrictRequirements(false);
+ $this->assertNull($generator->generate('test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_URL));
+ }
+
+ public function testGenerateForRouteWithInvalidParameterButDisabledRequirementsCheck()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing/{foo}', array('foo' => '1'), array('foo' => 'd+')));
+ $generator = $this->getGenerator($routes);
+ $generator->setStrictRequirements(null);
+ $this->assertSame('/app.php/testing/bar', $generator->generate('test', array('foo' => 'bar')));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
+ */
+ public function testGenerateForRouteWithInvalidMandatoryParameter()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing/{foo}', array(), array('foo' => 'd+')));
+ $this->getGenerator($routes)->generate('test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_URL);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
+ */
+ public function testGenerateForRouteWithInvalidUtf8Parameter()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing/{foo}', array(), array('foo' => '\pL+'), array('utf8' => true)));
+ $this->getGenerator($routes)->generate('test', array('foo' => 'abc123'), UrlGeneratorInterface::ABSOLUTE_URL);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
+ */
+ public function testRequiredParamAndEmptyPassed()
+ {
+ $routes = $this->getRoutes('test', new Route('/{slug}', array(), array('slug' => '.+')));
+ $this->getGenerator($routes)->generate('test', array('slug' => ''));
+ }
+
+ public function testSchemeRequirementDoesNothingIfSameCurrentScheme()
+ {
+ $routes = $this->getRoutes('test', new Route('/', array(), array(), array(), '', array('http')));
+ $this->assertEquals('/app.php/', $this->getGenerator($routes)->generate('test'));
+
+ $routes = $this->getRoutes('test', new Route('/', array(), array(), array(), '', array('https')));
+ $this->assertEquals('/app.php/', $this->getGenerator($routes, array('scheme' => 'https'))->generate('test'));
+ }
+
+ public function testSchemeRequirementForcesAbsoluteUrl()
+ {
+ $routes = $this->getRoutes('test', new Route('/', array(), array(), array(), '', array('https')));
+ $this->assertEquals('https://localhost/app.php/', $this->getGenerator($routes)->generate('test'));
+
+ $routes = $this->getRoutes('test', new Route('/', array(), array(), array(), '', array('http')));
+ $this->assertEquals('http://localhost/app.php/', $this->getGenerator($routes, array('scheme' => 'https'))->generate('test'));
+ }
+
+ public function testSchemeRequirementCreatesUrlForFirstRequiredScheme()
+ {
+ $routes = $this->getRoutes('test', new Route('/', array(), array(), array(), '', array('Ftp', 'https')));
+ $this->assertEquals('ftp://localhost/app.php/', $this->getGenerator($routes)->generate('test'));
+ }
+
+ public function testPathWithTwoStartingSlashes()
+ {
+ $routes = $this->getRoutes('test', new Route('//path-and-not-domain'));
+
+ // this must not generate '//path-and-not-domain' because that would be a network path
+ $this->assertSame('/path-and-not-domain', $this->getGenerator($routes, array('BaseUrl' => ''))->generate('test'));
+ }
+
+ public function testNoTrailingSlashForMultipleOptionalParameters()
+ {
+ $routes = $this->getRoutes('test', new Route('/category/{slug1}/{slug2}/{slug3}', array('slug2' => null, 'slug3' => null)));
+
+ $this->assertEquals('/app.php/category/foo', $this->getGenerator($routes)->generate('test', array('slug1' => 'foo')));
+ }
+
+ public function testWithAnIntegerAsADefaultValue()
+ {
+ $routes = $this->getRoutes('test', new Route('/{default}', array('default' => 0)));
+
+ $this->assertEquals('/app.php/foo', $this->getGenerator($routes)->generate('test', array('default' => 'foo')));
+ }
+
+ public function testNullForOptionalParameterIsIgnored()
+ {
+ $routes = $this->getRoutes('test', new Route('/test/{default}', array('default' => 0)));
+
+ $this->assertEquals('/app.php/test', $this->getGenerator($routes)->generate('test', array('default' => null)));
+ }
+
+ public function testQueryParamSameAsDefault()
+ {
+ $routes = $this->getRoutes('test', new Route('/test', array('page' => 1)));
+
+ $this->assertSame('/app.php/test?page=2', $this->getGenerator($routes)->generate('test', array('page' => 2)));
+ $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test', array('page' => 1)));
+ $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test', array('page' => '1')));
+ $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test'));
+ }
+
+ public function testArrayQueryParamSameAsDefault()
+ {
+ $routes = $this->getRoutes('test', new Route('/test', array('array' => array('foo', 'bar'))));
+
+ $this->assertSame('/app.php/test?array%5B0%5D=bar&array%5B1%5D=foo', $this->getGenerator($routes)->generate('test', array('array' => array('bar', 'foo'))));
+ $this->assertSame('/app.php/test?array%5Ba%5D=foo&array%5Bb%5D=bar', $this->getGenerator($routes)->generate('test', array('array' => array('a' => 'foo', 'b' => 'bar'))));
+ $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test', array('array' => array('foo', 'bar'))));
+ $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test', array('array' => array(1 => 'bar', 0 => 'foo'))));
+ $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test'));
+ }
+
+ public function testGenerateWithSpecialRouteName()
+ {
+ $routes = $this->getRoutes('$péß^a|', new Route('/bar'));
+
+ $this->assertSame('/app.php/bar', $this->getGenerator($routes)->generate('$péß^a|'));
+ }
+
+ public function testUrlEncoding()
+ {
+ $expectedPath = '/app.php/@:%5B%5D/%28%29*%27%22%20+,;-._~%26%24%3C%3E|%7B%7D%25%5C%5E%60!%3Ffoo=bar%23id'
+ .'/@:%5B%5D/%28%29*%27%22%20+,;-._~%26%24%3C%3E|%7B%7D%25%5C%5E%60!%3Ffoo=bar%23id'
+ .'?query=%40%3A%5B%5D/%28%29%2A%27%22%20%2B%2C%3B-._~%26%24%3C%3E%7C%7B%7D%25%5C%5E%60%21%3Ffoo%3Dbar%23id';
+
+ // This tests the encoding of reserved characters that are used for delimiting of URI components (defined in RFC 3986)
+ // and other special ASCII chars. These chars are tested as static text path, variable path and query param.
+ $chars = '@:[]/()*\'" +,;-._~&$<>|{}%\\^`!?foo=bar#id';
+ $routes = $this->getRoutes('test', new Route("/$chars/{varpath}", array(), array('varpath' => '.+')));
+ $this->assertSame($expectedPath, $this->getGenerator($routes)->generate('test', array(
+ 'varpath' => $chars,
+ 'query' => $chars,
+ )));
+ }
+
+ public function testEncodingOfRelativePathSegments()
+ {
+ $routes = $this->getRoutes('test', new Route('/dir/../dir/..'));
+ $this->assertSame('/app.php/dir/%2E%2E/dir/%2E%2E', $this->getGenerator($routes)->generate('test'));
+ $routes = $this->getRoutes('test', new Route('/dir/./dir/.'));
+ $this->assertSame('/app.php/dir/%2E/dir/%2E', $this->getGenerator($routes)->generate('test'));
+ $routes = $this->getRoutes('test', new Route('/a./.a/a../..a/...'));
+ $this->assertSame('/app.php/a./.a/a../..a/...', $this->getGenerator($routes)->generate('test'));
+ }
+
+ public function testAdjacentVariables()
+ {
+ $routes = $this->getRoutes('test', new Route('/{x}{y}{z}.{_format}', array('z' => 'default-z', '_format' => 'html'), array('y' => '\d+')));
+ $generator = $this->getGenerator($routes);
+ $this->assertSame('/app.php/foo123', $generator->generate('test', array('x' => 'foo', 'y' => '123')));
+ $this->assertSame('/app.php/foo123bar.xml', $generator->generate('test', array('x' => 'foo', 'y' => '123', 'z' => 'bar', '_format' => 'xml')));
+
+ // The default requirement for 'x' should not allow the separator '.' in this case because it would otherwise match everything
+ // and following optional variables like _format could never match.
+ $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('Symfony\Component\Routing\Exception\InvalidParameterException');
+ $generator->generate('test', array('x' => 'do.t', 'y' => '123', 'z' => 'bar', '_format' => 'xml'));
+ }
+
+ public function testOptionalVariableWithNoRealSeparator()
+ {
+ $routes = $this->getRoutes('test', new Route('/get{what}', array('what' => 'All')));
+ $generator = $this->getGenerator($routes);
+
+ $this->assertSame('/app.php/get', $generator->generate('test'));
+ $this->assertSame('/app.php/getSites', $generator->generate('test', array('what' => 'Sites')));
+ }
+
+ public function testRequiredVariableWithNoRealSeparator()
+ {
+ $routes = $this->getRoutes('test', new Route('/get{what}Suffix'));
+ $generator = $this->getGenerator($routes);
+
+ $this->assertSame('/app.php/getSitesSuffix', $generator->generate('test', array('what' => 'Sites')));
+ }
+
+ public function testDefaultRequirementOfVariable()
+ {
+ $routes = $this->getRoutes('test', new Route('/{page}.{_format}'));
+ $generator = $this->getGenerator($routes);
+
+ $this->assertSame('/app.php/index.mobile.html', $generator->generate('test', array('page' => 'index', '_format' => 'mobile.html')));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
+ */
+ public function testDefaultRequirementOfVariableDisallowsSlash()
+ {
+ $routes = $this->getRoutes('test', new Route('/{page}.{_format}'));
+ $this->getGenerator($routes)->generate('test', array('page' => 'index', '_format' => 'sl/ash'));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
+ */
+ public function testDefaultRequirementOfVariableDisallowsNextSeparator()
+ {
+ $routes = $this->getRoutes('test', new Route('/{page}.{_format}'));
+ $this->getGenerator($routes)->generate('test', array('page' => 'do.t', '_format' => 'html'));
+ }
+
+ public function testWithHostDifferentFromContext()
+ {
+ $routes = $this->getRoutes('test', new Route('/{name}', array(), array(), array(), '{locale}.example.com'));
+
+ $this->assertEquals('//fr.example.com/app.php/Fabien', $this->getGenerator($routes)->generate('test', array('name' => 'Fabien', 'locale' => 'fr')));
+ }
+
+ public function testWithHostSameAsContext()
+ {
+ $routes = $this->getRoutes('test', new Route('/{name}', array(), array(), array(), '{locale}.example.com'));
+
+ $this->assertEquals('/app.php/Fabien', $this->getGenerator($routes, array('host' => 'fr.example.com'))->generate('test', array('name' => 'Fabien', 'locale' => 'fr')));
+ }
+
+ public function testWithHostSameAsContextAndAbsolute()
+ {
+ $routes = $this->getRoutes('test', new Route('/{name}', array(), array(), array(), '{locale}.example.com'));
+
+ $this->assertEquals('http://fr.example.com/app.php/Fabien', $this->getGenerator($routes, array('host' => 'fr.example.com'))->generate('test', array('name' => 'Fabien', 'locale' => 'fr'), UrlGeneratorInterface::ABSOLUTE_URL));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
+ */
+ public function testUrlWithInvalidParameterInHost()
+ {
+ $routes = $this->getRoutes('test', new Route('/', array(), array('foo' => 'bar'), array(), '{foo}.example.com'));
+ $this->getGenerator($routes)->generate('test', array('foo' => 'baz'), UrlGeneratorInterface::ABSOLUTE_PATH);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
+ */
+ public function testUrlWithInvalidParameterInHostWhenParamHasADefaultValue()
+ {
+ $routes = $this->getRoutes('test', new Route('/', array('foo' => 'bar'), array('foo' => 'bar'), array(), '{foo}.example.com'));
+ $this->getGenerator($routes)->generate('test', array('foo' => 'baz'), UrlGeneratorInterface::ABSOLUTE_PATH);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
+ */
+ public function testUrlWithInvalidParameterEqualsDefaultValueInHost()
+ {
+ $routes = $this->getRoutes('test', new Route('/', array('foo' => 'baz'), array('foo' => 'bar'), array(), '{foo}.example.com'));
+ $this->getGenerator($routes)->generate('test', array('foo' => 'baz'), UrlGeneratorInterface::ABSOLUTE_PATH);
+ }
+
+ public function testUrlWithInvalidParameterInHostInNonStrictMode()
+ {
+ $routes = $this->getRoutes('test', new Route('/', array(), array('foo' => 'bar'), array(), '{foo}.example.com'));
+ $generator = $this->getGenerator($routes);
+ $generator->setStrictRequirements(false);
+ $this->assertNull($generator->generate('test', array('foo' => 'baz'), UrlGeneratorInterface::ABSOLUTE_PATH));
+ }
+
+ public function testHostIsCaseInsensitive()
+ {
+ $routes = $this->getRoutes('test', new Route('/', array(), array('locale' => 'en|de|fr'), array(), '{locale}.FooBar.com'));
+ $generator = $this->getGenerator($routes);
+ $this->assertSame('//EN.FooBar.com/app.php/', $generator->generate('test', array('locale' => 'EN'), UrlGeneratorInterface::NETWORK_PATH));
+ }
+
+ public function testDefaultHostIsUsedWhenContextHostIsEmpty()
+ {
+ $routes = $this->getRoutes('test', new Route('/route', array('domain' => 'my.fallback.host'), array('domain' => '.+'), array(), '{domain}', array('http')));
+
+ $generator = $this->getGenerator($routes);
+ $generator->getContext()->setHost('');
+
+ $this->assertSame('http://my.fallback.host/app.php/route', $generator->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL));
+ }
+
+ public function testDefaultHostIsUsedWhenContextHostIsEmptyAndSchemeIsNot()
+ {
+ $routes = $this->getRoutes('test', new Route('/route', array('domain' => 'my.fallback.host'), array('domain' => '.+'), array(), '{domain}', array('http', 'https')));
+
+ $generator = $this->getGenerator($routes);
+ $generator->getContext()->setHost('');
+ $generator->getContext()->setScheme('https');
+
+ $this->assertSame('https://my.fallback.host/app.php/route', $generator->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL));
+ }
+
+ public function testAbsoluteUrlFallbackToRelativeIfHostIsEmptyAndSchemeIsNot()
+ {
+ $routes = $this->getRoutes('test', new Route('/route', array(), array(), array(), '', array('http', 'https')));
+
+ $generator = $this->getGenerator($routes);
+ $generator->getContext()->setHost('');
+ $generator->getContext()->setScheme('https');
+
+ $this->assertSame('/app.php/route', $generator->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL));
+ }
+
+ public function testGenerateNetworkPath()
+ {
+ $routes = $this->getRoutes('test', new Route('/{name}', array(), array(), array(), '{locale}.example.com', array('http')));
+
+ $this->assertSame('//fr.example.com/app.php/Fabien', $this->getGenerator($routes)->generate('test',
+ array('name' => 'Fabien', 'locale' => 'fr'), UrlGeneratorInterface::NETWORK_PATH), 'network path with different host'
+ );
+ $this->assertSame('//fr.example.com/app.php/Fabien?query=string', $this->getGenerator($routes, array('host' => 'fr.example.com'))->generate('test',
+ array('name' => 'Fabien', 'locale' => 'fr', 'query' => 'string'), UrlGeneratorInterface::NETWORK_PATH), 'network path although host same as context'
+ );
+ $this->assertSame('http://fr.example.com/app.php/Fabien', $this->getGenerator($routes, array('scheme' => 'https'))->generate('test',
+ array('name' => 'Fabien', 'locale' => 'fr'), UrlGeneratorInterface::NETWORK_PATH), 'absolute URL because scheme requirement does not match context'
+ );
+ $this->assertSame('http://fr.example.com/app.php/Fabien', $this->getGenerator($routes)->generate('test',
+ array('name' => 'Fabien', 'locale' => 'fr'), UrlGeneratorInterface::ABSOLUTE_URL), 'absolute URL with same scheme because it is requested'
+ );
+ }
+
+ public function testGenerateRelativePath()
+ {
+ $routes = new RouteCollection();
+ $routes->add('article', new Route('/{author}/{article}/'));
+ $routes->add('comments', new Route('/{author}/{article}/comments'));
+ $routes->add('host', new Route('/{article}', array(), array(), array(), '{author}.example.com'));
+ $routes->add('scheme', new Route('/{author}/blog', array(), array(), array(), '', array('https')));
+ $routes->add('unrelated', new Route('/about'));
+
+ $generator = $this->getGenerator($routes, array('host' => 'example.com', 'pathInfo' => '/fabien/symfony-is-great/'));
+
+ $this->assertSame('comments', $generator->generate('comments',
+ array('author' => 'fabien', 'article' => 'symfony-is-great'), UrlGeneratorInterface::RELATIVE_PATH)
+ );
+ $this->assertSame('comments?page=2', $generator->generate('comments',
+ array('author' => 'fabien', 'article' => 'symfony-is-great', 'page' => 2), UrlGeneratorInterface::RELATIVE_PATH)
+ );
+ $this->assertSame('../twig-is-great/', $generator->generate('article',
+ array('author' => 'fabien', 'article' => 'twig-is-great'), UrlGeneratorInterface::RELATIVE_PATH)
+ );
+ $this->assertSame('../../bernhard/forms-are-great/', $generator->generate('article',
+ array('author' => 'bernhard', 'article' => 'forms-are-great'), UrlGeneratorInterface::RELATIVE_PATH)
+ );
+ $this->assertSame('//bernhard.example.com/app.php/forms-are-great', $generator->generate('host',
+ array('author' => 'bernhard', 'article' => 'forms-are-great'), UrlGeneratorInterface::RELATIVE_PATH)
+ );
+ $this->assertSame('https://example.com/app.php/bernhard/blog', $generator->generate('scheme',
+ array('author' => 'bernhard'), UrlGeneratorInterface::RELATIVE_PATH)
+ );
+ $this->assertSame('../../about', $generator->generate('unrelated',
+ array(), UrlGeneratorInterface::RELATIVE_PATH)
+ );
+ }
+
+ /**
+ * @dataProvider provideRelativePaths
+ */
+ public function testGetRelativePath($sourcePath, $targetPath, $expectedPath)
+ {
+ $this->assertSame($expectedPath, UrlGenerator::getRelativePath($sourcePath, $targetPath));
+ }
+
+ public function provideRelativePaths()
+ {
+ return array(
+ array(
+ '/same/dir/',
+ '/same/dir/',
+ '',
+ ),
+ array(
+ '/same/file',
+ '/same/file',
+ '',
+ ),
+ array(
+ '/',
+ '/file',
+ 'file',
+ ),
+ array(
+ '/',
+ '/dir/file',
+ 'dir/file',
+ ),
+ array(
+ '/dir/file.html',
+ '/dir/different-file.html',
+ 'different-file.html',
+ ),
+ array(
+ '/same/dir/extra-file',
+ '/same/dir/',
+ './',
+ ),
+ array(
+ '/parent/dir/',
+ '/parent/',
+ '../',
+ ),
+ array(
+ '/parent/dir/extra-file',
+ '/parent/',
+ '../',
+ ),
+ array(
+ '/a/b/',
+ '/x/y/z/',
+ '../../x/y/z/',
+ ),
+ array(
+ '/a/b/c/d/e',
+ '/a/c/d',
+ '../../../c/d',
+ ),
+ array(
+ '/a/b/c//',
+ '/a/b/c/',
+ '../',
+ ),
+ array(
+ '/a/b/c/',
+ '/a/b/c//',
+ './/',
+ ),
+ array(
+ '/root/a/b/c/',
+ '/root/x/b/c/',
+ '../../../x/b/c/',
+ ),
+ array(
+ '/a/b/c/d/',
+ '/a',
+ '../../../../a',
+ ),
+ array(
+ '/special-chars/sp%20ce/1€/mäh/e=mc²',
+ '/special-chars/sp%20ce/1€/<µ>/e=mc²',
+ '../<µ>/e=mc²',
+ ),
+ array(
+ 'not-rooted',
+ 'dir/file',
+ 'dir/file',
+ ),
+ array(
+ '//dir/',
+ '',
+ '../../',
+ ),
+ array(
+ '/dir/',
+ '/dir/file:with-colon',
+ './file:with-colon',
+ ),
+ array(
+ '/dir/',
+ '/dir/subdir/file:with-colon',
+ 'subdir/file:with-colon',
+ ),
+ array(
+ '/dir/',
+ '/dir/:subdir/',
+ './:subdir/',
+ ),
+ );
+ }
+
+ public function testFragmentsCanBeAppendedToUrls()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing'));
+
+ $url = $this->getGenerator($routes)->generate('test', array('_fragment' => 'frag ment'), UrlGeneratorInterface::ABSOLUTE_PATH);
+ $this->assertEquals('/app.php/testing#frag%20ment', $url);
+
+ $url = $this->getGenerator($routes)->generate('test', array('_fragment' => '0'), UrlGeneratorInterface::ABSOLUTE_PATH);
+ $this->assertEquals('/app.php/testing#0', $url);
+ }
+
+ public function testFragmentsDoNotEscapeValidCharacters()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing'));
+ $url = $this->getGenerator($routes)->generate('test', array('_fragment' => '?/'), UrlGeneratorInterface::ABSOLUTE_PATH);
+
+ $this->assertEquals('/app.php/testing#?/', $url);
+ }
+
+ public function testFragmentsCanBeDefinedAsDefaults()
+ {
+ $routes = $this->getRoutes('test', new Route('/testing', array('_fragment' => 'fragment')));
+ $url = $this->getGenerator($routes)->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_PATH);
+
+ $this->assertEquals('/app.php/testing#fragment', $url);
+ }
+
+ protected function getGenerator(RouteCollection $routes, array $parameters = array(), $logger = null)
+ {
+ $context = new RequestContext('/app.php');
+ foreach ($parameters as $key => $value) {
+ $method = 'set'.$key;
+ $context->$method($value);
+ }
+
+ return new UrlGenerator($routes, $context, $logger);
+ }
+
+ protected function getRoutes($name, Route $route)
+ {
+ $routes = new RouteCollection();
+ $routes->add($name, $route);
+
+ return $routes;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/AbstractAnnotationLoaderTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/AbstractAnnotationLoaderTest.php
new file mode 100644
index 0000000..e8bbe8f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/AbstractAnnotationLoaderTest.php
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Loader;
+
+use PHPUnit\Framework\TestCase;
+
+abstract class AbstractAnnotationLoaderTest extends TestCase
+{
+ public function getReader()
+ {
+ return $this->getMockBuilder('Doctrine\Common\Annotations\Reader')
+ ->disableOriginalConstructor()
+ ->getMock()
+ ;
+ }
+
+ public function getClassLoader($reader)
+ {
+ return $this->getMockBuilder('Symfony\Component\Routing\Loader\AnnotationClassLoader')
+ ->setConstructorArgs(array($reader))
+ ->getMockForAbstractClass()
+ ;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/AnnotationClassLoaderTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/AnnotationClassLoaderTest.php
new file mode 100644
index 0000000..70db1cc
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/AnnotationClassLoaderTest.php
@@ -0,0 +1,255 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Loader;
+
+use Symfony\Component\Routing\Annotation\Route;
+
+class AnnotationClassLoaderTest extends AbstractAnnotationLoaderTest
+{
+ protected $loader;
+ private $reader;
+
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $this->reader = $this->getReader();
+ $this->loader = $this->getClassLoader($this->reader);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testLoadMissingClass()
+ {
+ $this->loader->load('MissingClass');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testLoadAbstractClass()
+ {
+ $this->loader->load('Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\AbstractClass');
+ }
+
+ /**
+ * @dataProvider provideTestSupportsChecksResource
+ */
+ public function testSupportsChecksResource($resource, $expectedSupports)
+ {
+ $this->assertSame($expectedSupports, $this->loader->supports($resource), '->supports() returns true if the resource is loadable');
+ }
+
+ public function provideTestSupportsChecksResource()
+ {
+ return array(
+ array('class', true),
+ array('\fully\qualified\class\name', true),
+ array('namespaced\class\without\leading\slash', true),
+ array('ÿClassWithLegalSpecialCharacters', true),
+ array('5', false),
+ array('foo.foo', false),
+ array(null, false),
+ );
+ }
+
+ public function testSupportsChecksTypeIfSpecified()
+ {
+ $this->assertTrue($this->loader->supports('class', 'annotation'), '->supports() checks the resource type if specified');
+ $this->assertFalse($this->loader->supports('class', 'foo'), '->supports() checks the resource type if specified');
+ }
+
+ public function getLoadTests()
+ {
+ return array(
+ array(
+ 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass',
+ array('name' => 'route1', 'path' => '/path'),
+ array('arg2' => 'defaultValue2', 'arg3' => 'defaultValue3'),
+ ),
+ array(
+ 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass',
+ array('defaults' => array('arg2' => 'foo'), 'requirements' => array('arg3' => '\w+')),
+ array('arg2' => 'defaultValue2', 'arg3' => 'defaultValue3'),
+ ),
+ array(
+ 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass',
+ array('options' => array('foo' => 'bar')),
+ array('arg2' => 'defaultValue2', 'arg3' => 'defaultValue3'),
+ ),
+ array(
+ 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass',
+ array('schemes' => array('https'), 'methods' => array('GET')),
+ array('arg2' => 'defaultValue2', 'arg3' => 'defaultValue3'),
+ ),
+ array(
+ 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass',
+ array('condition' => 'context.getMethod() == "GET"'),
+ array('arg2' => 'defaultValue2', 'arg3' => 'defaultValue3'),
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider getLoadTests
+ */
+ public function testLoad($className, $routeData = array(), $methodArgs = array())
+ {
+ $routeData = array_replace(array(
+ 'name' => 'route',
+ 'path' => '/',
+ 'requirements' => array(),
+ 'options' => array(),
+ 'defaults' => array(),
+ 'schemes' => array(),
+ 'methods' => array(),
+ 'condition' => '',
+ ), $routeData);
+
+ $this->reader
+ ->expects($this->once())
+ ->method('getMethodAnnotations')
+ ->will($this->returnValue(array($this->getAnnotatedRoute($routeData))))
+ ;
+
+ $routeCollection = $this->loader->load($className);
+ $route = $routeCollection->get($routeData['name']);
+
+ $this->assertSame($routeData['path'], $route->getPath(), '->load preserves path annotation');
+ $this->assertCount(
+ count($routeData['requirements']),
+ array_intersect_assoc($routeData['requirements'], $route->getRequirements()),
+ '->load preserves requirements annotation'
+ );
+ $this->assertCount(
+ count($routeData['options']),
+ array_intersect_assoc($routeData['options'], $route->getOptions()),
+ '->load preserves options annotation'
+ );
+ $this->assertCount(
+ count($routeData['defaults']),
+ $route->getDefaults(),
+ '->load preserves defaults annotation'
+ );
+ $this->assertEquals($routeData['schemes'], $route->getSchemes(), '->load preserves schemes annotation');
+ $this->assertEquals($routeData['methods'], $route->getMethods(), '->load preserves methods annotation');
+ $this->assertSame($routeData['condition'], $route->getCondition(), '->load preserves condition annotation');
+ }
+
+ public function testClassRouteLoad()
+ {
+ $classRouteData = array(
+ 'name' => 'prefix_',
+ 'path' => '/prefix',
+ 'schemes' => array('https'),
+ 'methods' => array('GET'),
+ );
+
+ $methodRouteData = array(
+ 'name' => 'route1',
+ 'path' => '/path',
+ 'schemes' => array('http'),
+ 'methods' => array('POST', 'PUT'),
+ );
+
+ $this->reader
+ ->expects($this->once())
+ ->method('getClassAnnotation')
+ ->will($this->returnValue($this->getAnnotatedRoute($classRouteData)))
+ ;
+ $this->reader
+ ->expects($this->once())
+ ->method('getMethodAnnotations')
+ ->will($this->returnValue(array($this->getAnnotatedRoute($methodRouteData))))
+ ;
+
+ $routeCollection = $this->loader->load('Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass');
+ $route = $routeCollection->get($classRouteData['name'].$methodRouteData['name']);
+
+ $this->assertSame($classRouteData['path'].$methodRouteData['path'], $route->getPath(), '->load concatenates class and method route path');
+ $this->assertEquals(array_merge($classRouteData['schemes'], $methodRouteData['schemes']), $route->getSchemes(), '->load merges class and method route schemes');
+ $this->assertEquals(array_merge($classRouteData['methods'], $methodRouteData['methods']), $route->getMethods(), '->load merges class and method route methods');
+ }
+
+ public function testInvokableClassRouteLoad()
+ {
+ $classRouteData = array(
+ 'name' => 'route1',
+ 'path' => '/',
+ 'schemes' => array('https'),
+ 'methods' => array('GET'),
+ );
+
+ $this->reader
+ ->expects($this->exactly(2))
+ ->method('getClassAnnotation')
+ ->will($this->returnValue($this->getAnnotatedRoute($classRouteData)))
+ ;
+ $this->reader
+ ->expects($this->once())
+ ->method('getMethodAnnotations')
+ ->will($this->returnValue(array()))
+ ;
+
+ $routeCollection = $this->loader->load('Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BazClass');
+ $route = $routeCollection->get($classRouteData['name']);
+
+ $this->assertSame($classRouteData['path'], $route->getPath(), '->load preserves class route path');
+ $this->assertEquals(array_merge($classRouteData['schemes'], $classRouteData['schemes']), $route->getSchemes(), '->load preserves class route schemes');
+ $this->assertEquals(array_merge($classRouteData['methods'], $classRouteData['methods']), $route->getMethods(), '->load preserves class route methods');
+ }
+
+ public function testInvokableClassWithMethodRouteLoad()
+ {
+ $classRouteData = array(
+ 'name' => 'route1',
+ 'path' => '/prefix',
+ 'schemes' => array('https'),
+ 'methods' => array('GET'),
+ );
+
+ $methodRouteData = array(
+ 'name' => 'route2',
+ 'path' => '/path',
+ 'schemes' => array('http'),
+ 'methods' => array('POST', 'PUT'),
+ );
+
+ $this->reader
+ ->expects($this->once())
+ ->method('getClassAnnotation')
+ ->will($this->returnValue($this->getAnnotatedRoute($classRouteData)))
+ ;
+ $this->reader
+ ->expects($this->once())
+ ->method('getMethodAnnotations')
+ ->will($this->returnValue(array($this->getAnnotatedRoute($methodRouteData))))
+ ;
+
+ $routeCollection = $this->loader->load('Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BazClass');
+ $route = $routeCollection->get($classRouteData['name']);
+
+ $this->assertNull($route, '->load ignores class route');
+
+ $route = $routeCollection->get($classRouteData['name'].$methodRouteData['name']);
+
+ $this->assertSame($classRouteData['path'].$methodRouteData['path'], $route->getPath(), '->load concatenates class and method route path');
+ $this->assertEquals(array_merge($classRouteData['schemes'], $methodRouteData['schemes']), $route->getSchemes(), '->load merges class and method route schemes');
+ $this->assertEquals(array_merge($classRouteData['methods'], $methodRouteData['methods']), $route->getMethods(), '->load merges class and method route methods');
+ }
+
+ private function getAnnotatedRoute($data)
+ {
+ return new Route($data);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/AnnotationDirectoryLoaderTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/AnnotationDirectoryLoaderTest.php
new file mode 100644
index 0000000..1e8ee39
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/AnnotationDirectoryLoaderTest.php
@@ -0,0 +1,98 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Loader;
+
+use Symfony\Component\Routing\Loader\AnnotationDirectoryLoader;
+use Symfony\Component\Config\FileLocator;
+
+class AnnotationDirectoryLoaderTest extends AbstractAnnotationLoaderTest
+{
+ protected $loader;
+ protected $reader;
+
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $this->reader = $this->getReader();
+ $this->loader = new AnnotationDirectoryLoader(new FileLocator(), $this->getClassLoader($this->reader));
+ }
+
+ public function testLoad()
+ {
+ $this->reader->expects($this->exactly(4))->method('getClassAnnotation');
+
+ $this->reader
+ ->expects($this->any())
+ ->method('getMethodAnnotations')
+ ->will($this->returnValue(array()))
+ ;
+
+ $this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses');
+ }
+
+ public function testLoadIgnoresHiddenDirectories()
+ {
+ $this->expectAnnotationsToBeReadFrom(array(
+ 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass',
+ 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BazClass',
+ 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BazClass',
+ 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\FooClass',
+ ));
+
+ $this->reader
+ ->expects($this->any())
+ ->method('getMethodAnnotations')
+ ->will($this->returnValue(array()))
+ ;
+
+ $this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses');
+ }
+
+ public function testSupports()
+ {
+ $fixturesDir = __DIR__.'/../Fixtures';
+
+ $this->assertTrue($this->loader->supports($fixturesDir), '->supports() returns true if the resource is loadable');
+ $this->assertFalse($this->loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
+
+ $this->assertTrue($this->loader->supports($fixturesDir, 'annotation'), '->supports() checks the resource type if specified');
+ $this->assertFalse($this->loader->supports($fixturesDir, 'foo'), '->supports() checks the resource type if specified');
+ }
+
+ public function testItSupportsAnyAnnotation()
+ {
+ $this->assertTrue($this->loader->supports(__DIR__.'/../Fixtures/even-with-not-existing-folder', 'annotation'));
+ }
+
+ public function testLoadFileIfLocatedResourceIsFile()
+ {
+ $this->reader->expects($this->exactly(1))->method('getClassAnnotation');
+
+ $this->reader
+ ->expects($this->any())
+ ->method('getMethodAnnotations')
+ ->will($this->returnValue(array()))
+ ;
+
+ $this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses/FooClass.php');
+ }
+
+ private function expectAnnotationsToBeReadFrom(array $classes)
+ {
+ $this->reader->expects($this->exactly(count($classes)))
+ ->method('getClassAnnotation')
+ ->with($this->callback(function (\ReflectionClass $class) use ($classes) {
+ return in_array($class->getName(), $classes);
+ }));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/AnnotationFileLoaderTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/AnnotationFileLoaderTest.php
new file mode 100644
index 0000000..7f1d576
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/AnnotationFileLoaderTest.php
@@ -0,0 +1,91 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Loader;
+
+use Symfony\Component\Routing\Loader\AnnotationFileLoader;
+use Symfony\Component\Config\FileLocator;
+use Symfony\Component\Routing\Annotation\Route;
+
+class AnnotationFileLoaderTest extends AbstractAnnotationLoaderTest
+{
+ protected $loader;
+ protected $reader;
+
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $this->reader = $this->getReader();
+ $this->loader = new AnnotationFileLoader(new FileLocator(), $this->getClassLoader($this->reader));
+ }
+
+ public function testLoad()
+ {
+ $this->reader->expects($this->once())->method('getClassAnnotation');
+
+ $this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses/FooClass.php');
+ }
+
+ /**
+ * @requires PHP 5.4
+ */
+ public function testLoadTraitWithClassConstant()
+ {
+ $this->reader->expects($this->never())->method('getClassAnnotation');
+
+ $this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses/FooTrait.php');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Did you forgot to add the "<?php" start tag at the beginning of the file?
+ */
+ public function testLoadFileWithoutStartTag()
+ {
+ $this->loader->load(__DIR__.'/../Fixtures/OtherAnnotatedClasses/NoStartTagClass.php');
+ }
+
+ /**
+ * @requires PHP 5.6
+ */
+ public function testLoadVariadic()
+ {
+ $route = new Route(array('path' => '/path/to/{id}'));
+ $this->reader->expects($this->once())->method('getClassAnnotation');
+ $this->reader->expects($this->once())->method('getMethodAnnotations')
+ ->will($this->returnValue(array($route)));
+
+ $this->loader->load(__DIR__.'/../Fixtures/OtherAnnotatedClasses/VariadicClass.php');
+ }
+
+ /**
+ * @requires PHP 7.0
+ */
+ public function testLoadAnonymousClass()
+ {
+ $this->reader->expects($this->never())->method('getClassAnnotation');
+ $this->reader->expects($this->never())->method('getMethodAnnotations');
+
+ $this->loader->load(__DIR__.'/../Fixtures/OtherAnnotatedClasses/AnonymousClassInTrait.php');
+ }
+
+ public function testSupports()
+ {
+ $fixture = __DIR__.'/../Fixtures/annotated.php';
+
+ $this->assertTrue($this->loader->supports($fixture), '->supports() returns true if the resource is loadable');
+ $this->assertFalse($this->loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
+
+ $this->assertTrue($this->loader->supports($fixture, 'annotation'), '->supports() checks the resource type if specified');
+ $this->assertFalse($this->loader->supports($fixture, 'foo'), '->supports() checks the resource type if specified');
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/ClosureLoaderTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/ClosureLoaderTest.php
new file mode 100644
index 0000000..5d963f8
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/ClosureLoaderTest.php
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Loader;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Routing\Loader\ClosureLoader;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+
+class ClosureLoaderTest extends TestCase
+{
+ public function testSupports()
+ {
+ $loader = new ClosureLoader();
+
+ $closure = function () {};
+
+ $this->assertTrue($loader->supports($closure), '->supports() returns true if the resource is loadable');
+ $this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
+
+ $this->assertTrue($loader->supports($closure, 'closure'), '->supports() checks the resource type if specified');
+ $this->assertFalse($loader->supports($closure, 'foo'), '->supports() checks the resource type if specified');
+ }
+
+ public function testLoad()
+ {
+ $loader = new ClosureLoader();
+
+ $route = new Route('/');
+ $routes = $loader->load(function () use ($route) {
+ $routes = new RouteCollection();
+
+ $routes->add('foo', $route);
+
+ return $routes;
+ });
+
+ $this->assertEquals($route, $routes->get('foo'), '->load() loads a \Closure resource');
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/DirectoryLoaderTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/DirectoryLoaderTest.php
new file mode 100644
index 0000000..fc29d37
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/DirectoryLoaderTest.php
@@ -0,0 +1,74 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Loader;
+
+use Symfony\Component\Routing\Loader\DirectoryLoader;
+use Symfony\Component\Routing\Loader\YamlFileLoader;
+use Symfony\Component\Routing\Loader\AnnotationFileLoader;
+use Symfony\Component\Config\Loader\LoaderResolver;
+use Symfony\Component\Config\FileLocator;
+use Symfony\Component\Routing\RouteCollection;
+
+class DirectoryLoaderTest extends AbstractAnnotationLoaderTest
+{
+ private $loader;
+ private $reader;
+
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $locator = new FileLocator();
+ $this->reader = $this->getReader();
+ $this->loader = new DirectoryLoader($locator);
+ $resolver = new LoaderResolver(array(
+ new YamlFileLoader($locator),
+ new AnnotationFileLoader($locator, $this->getClassLoader($this->reader)),
+ $this->loader,
+ ));
+ $this->loader->setResolver($resolver);
+ }
+
+ public function testLoadDirectory()
+ {
+ $collection = $this->loader->load(__DIR__.'/../Fixtures/directory', 'directory');
+ $this->verifyCollection($collection);
+ }
+
+ public function testImportDirectory()
+ {
+ $collection = $this->loader->load(__DIR__.'/../Fixtures/directory_import', 'directory');
+ $this->verifyCollection($collection);
+ }
+
+ private function verifyCollection(RouteCollection $collection)
+ {
+ $routes = $collection->all();
+
+ $this->assertCount(3, $routes, 'Three routes are loaded');
+ $this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
+
+ for ($i = 1; $i <= 3; ++$i) {
+ $this->assertSame('/route/'.$i, $routes['route'.$i]->getPath());
+ }
+ }
+
+ public function testSupports()
+ {
+ $fixturesDir = __DIR__.'/../Fixtures';
+
+ $this->assertFalse($this->loader->supports($fixturesDir), '->supports(*) returns false');
+
+ $this->assertTrue($this->loader->supports($fixturesDir, 'directory'), '->supports(*, "directory") returns true');
+ $this->assertFalse($this->loader->supports($fixturesDir, 'foo'), '->supports(*, "foo") returns false');
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/GlobFileLoaderTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/GlobFileLoaderTest.php
new file mode 100644
index 0000000..08d806a
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/GlobFileLoaderTest.php
@@ -0,0 +1,45 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Loader;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Config\Resource\GlobResource;
+use Symfony\Component\Config\FileLocator;
+use Symfony\Component\Routing\Loader\GlobFileLoader;
+use Symfony\Component\Routing\RouteCollection;
+
+class GlobFileLoaderTest extends TestCase
+{
+ public function testSupports()
+ {
+ $loader = new GlobFileLoader(new FileLocator());
+
+ $this->assertTrue($loader->supports('any-path', 'glob'), '->supports() returns true if the resource has the glob type');
+ $this->assertFalse($loader->supports('any-path'), '->supports() returns false if the resource is not of glob type');
+ }
+
+ public function testLoadAddsTheGlobResourceToTheContainer()
+ {
+ $loader = new GlobFileLoaderWithoutImport(new FileLocator());
+ $collection = $loader->load(__DIR__.'/../Fixtures/directory/*.yml');
+
+ $this->assertEquals(new GlobResource(__DIR__.'/../Fixtures/directory', '/*.yml', false), $collection->getResources()[0]);
+ }
+}
+
+class GlobFileLoaderWithoutImport extends GlobFileLoader
+{
+ public function import($resource, $type = null, $ignoreErrors = false, $sourceResource = null)
+ {
+ return new RouteCollection();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/ObjectRouteLoaderTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/ObjectRouteLoaderTest.php
new file mode 100644
index 0000000..408fa0b
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/ObjectRouteLoaderTest.php
@@ -0,0 +1,123 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Loader;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Routing\Loader\ObjectRouteLoader;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+
+class ObjectRouteLoaderTest extends TestCase
+{
+ public function testLoadCallsServiceAndReturnsCollection()
+ {
+ $loader = new ObjectRouteLoaderForTest();
+
+ // create a basic collection that will be returned
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/foo'));
+
+ $loader->loaderMap = array(
+ 'my_route_provider_service' => new RouteService($collection),
+ );
+
+ $actualRoutes = $loader->load(
+ 'my_route_provider_service:loadRoutes',
+ 'service'
+ );
+
+ $this->assertSame($collection, $actualRoutes);
+ // the service file should be listed as a resource
+ $this->assertNotEmpty($actualRoutes->getResources());
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @dataProvider getBadResourceStrings
+ */
+ public function testExceptionWithoutSyntax($resourceString)
+ {
+ $loader = new ObjectRouteLoaderForTest();
+ $loader->load($resourceString);
+ }
+
+ public function getBadResourceStrings()
+ {
+ return array(
+ array('Foo'),
+ array('Bar::baz'),
+ array('Foo:Bar:baz'),
+ );
+ }
+
+ /**
+ * @expectedException \LogicException
+ */
+ public function testExceptionOnNoObjectReturned()
+ {
+ $loader = new ObjectRouteLoaderForTest();
+ $loader->loaderMap = array('my_service' => 'NOT_AN_OBJECT');
+ $loader->load('my_service:method');
+ }
+
+ /**
+ * @expectedException \BadMethodCallException
+ */
+ public function testExceptionOnBadMethod()
+ {
+ $loader = new ObjectRouteLoaderForTest();
+ $loader->loaderMap = array('my_service' => new \stdClass());
+ $loader->load('my_service:method');
+ }
+
+ /**
+ * @expectedException \LogicException
+ */
+ public function testExceptionOnMethodNotReturningCollection()
+ {
+ $service = $this->getMockBuilder('stdClass')
+ ->setMethods(array('loadRoutes'))
+ ->getMock();
+ $service->expects($this->once())
+ ->method('loadRoutes')
+ ->will($this->returnValue('NOT_A_COLLECTION'));
+
+ $loader = new ObjectRouteLoaderForTest();
+ $loader->loaderMap = array('my_service' => $service);
+ $loader->load('my_service:loadRoutes');
+ }
+}
+
+class ObjectRouteLoaderForTest extends ObjectRouteLoader
+{
+ public $loaderMap = array();
+
+ protected function getServiceObject($id)
+ {
+ return isset($this->loaderMap[$id]) ? $this->loaderMap[$id] : null;
+ }
+}
+
+class RouteService
+{
+ private $collection;
+
+ public function __construct($collection)
+ {
+ $this->collection = $collection;
+ }
+
+ public function loadRoutes()
+ {
+ return $this->collection;
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/PhpFileLoaderTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/PhpFileLoaderTest.php
new file mode 100644
index 0000000..0dcf5d4
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/PhpFileLoaderTest.php
@@ -0,0 +1,133 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Loader;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Config\FileLocator;
+use Symfony\Component\Config\Resource\FileResource;
+use Symfony\Component\Routing\Loader\PhpFileLoader;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+
+class PhpFileLoaderTest extends TestCase
+{
+ public function testSupports()
+ {
+ $loader = new PhpFileLoader($this->getMockBuilder('Symfony\Component\Config\FileLocator')->getMock());
+
+ $this->assertTrue($loader->supports('foo.php'), '->supports() returns true if the resource is loadable');
+ $this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
+
+ $this->assertTrue($loader->supports('foo.php', 'php'), '->supports() checks the resource type if specified');
+ $this->assertFalse($loader->supports('foo.php', 'foo'), '->supports() checks the resource type if specified');
+ }
+
+ public function testLoadWithRoute()
+ {
+ $loader = new PhpFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('validpattern.php');
+ $routes = $routeCollection->all();
+
+ $this->assertCount(1, $routes, 'One route is loaded');
+ $this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
+
+ foreach ($routes as $route) {
+ $this->assertSame('/blog/{slug}', $route->getPath());
+ $this->assertSame('MyBlogBundle:Blog:show', $route->getDefault('_controller'));
+ $this->assertSame('{locale}.example.com', $route->getHost());
+ $this->assertSame('RouteCompiler', $route->getOption('compiler_class'));
+ $this->assertEquals(array('GET', 'POST', 'PUT', 'OPTIONS'), $route->getMethods());
+ $this->assertEquals(array('https'), $route->getSchemes());
+ }
+ }
+
+ public function testLoadWithImport()
+ {
+ $loader = new PhpFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('validresource.php');
+ $routes = $routeCollection->all();
+
+ $this->assertCount(1, $routes, 'One route is loaded');
+ $this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
+
+ foreach ($routes as $route) {
+ $this->assertSame('/prefix/blog/{slug}', $route->getPath());
+ $this->assertSame('MyBlogBundle:Blog:show', $route->getDefault('_controller'));
+ $this->assertSame('{locale}.example.com', $route->getHost());
+ $this->assertSame('RouteCompiler', $route->getOption('compiler_class'));
+ $this->assertEquals(array('GET', 'POST', 'PUT', 'OPTIONS'), $route->getMethods());
+ $this->assertEquals(array('https'), $route->getSchemes());
+ }
+ }
+
+ public function testThatDefiningVariableInConfigFileHasNoSideEffects()
+ {
+ $locator = new FileLocator(array(__DIR__.'/../Fixtures'));
+ $loader = new PhpFileLoader($locator);
+ $routeCollection = $loader->load('with_define_path_variable.php');
+ $resources = $routeCollection->getResources();
+ $this->assertCount(1, $resources);
+ $this->assertContainsOnly('Symfony\Component\Config\Resource\ResourceInterface', $resources);
+ $fileResource = reset($resources);
+ $this->assertSame(
+ realpath($locator->locate('with_define_path_variable.php')),
+ (string) $fileResource
+ );
+ }
+
+ public function testRoutingConfigurator()
+ {
+ $locator = new FileLocator(array(__DIR__.'/../Fixtures'));
+ $loader = new PhpFileLoader($locator);
+ $routeCollection = $loader->load('php_dsl.php');
+
+ $expectedCollection = new RouteCollection();
+
+ $expectedCollection->add('foo', (new Route('/foo'))
+ ->setOptions(array('utf8' => true))
+ ->setCondition('abc')
+ );
+ $expectedCollection->add('buz', (new Route('/zub'))
+ ->setDefaults(array('_controller' => 'foo:act'))
+ );
+ $expectedCollection->add('c_bar', (new Route('/sub/pub/bar'))
+ ->setRequirements(array('id' => '\d+'))
+ );
+ $expectedCollection->add('c_pub_buz', (new Route('/sub/pub/buz'))
+ ->setHost('host')
+ ->setRequirements(array('id' => '\d+'))
+ );
+ $expectedCollection->add('ouf', (new Route('/ouf'))
+ ->setSchemes(array('https'))
+ ->setMethods(array('GET'))
+ ->setDefaults(array('id' => 0))
+ );
+
+ $expectedCollection->addResource(new FileResource(realpath(__DIR__.'/../Fixtures/php_dsl_sub.php')));
+ $expectedCollection->addResource(new FileResource(realpath(__DIR__.'/../Fixtures/php_dsl.php')));
+
+ $this->assertEquals($expectedCollection, $routeCollection);
+ }
+
+ public function testRoutingConfiguratorCanImportGlobPatterns()
+ {
+ $locator = new FileLocator(array(__DIR__.'/../Fixtures/glob'));
+ $loader = new PhpFileLoader($locator);
+ $routeCollection = $loader->load('php_dsl.php');
+
+ $route = $routeCollection->get('bar_route');
+ $this->assertSame('AppBundle:Bar:view', $route->getDefault('_controller'));
+
+ $route = $routeCollection->get('baz_route');
+ $this->assertSame('AppBundle:Baz:view', $route->getDefault('_controller'));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/XmlFileLoaderTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/XmlFileLoaderTest.php
new file mode 100644
index 0000000..21fc340
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/XmlFileLoaderTest.php
@@ -0,0 +1,385 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Loader;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Config\FileLocator;
+use Symfony\Component\Routing\Loader\XmlFileLoader;
+use Symfony\Component\Routing\Tests\Fixtures\CustomXmlFileLoader;
+
+class XmlFileLoaderTest extends TestCase
+{
+ public function testSupports()
+ {
+ $loader = new XmlFileLoader($this->getMockBuilder('Symfony\Component\Config\FileLocator')->getMock());
+
+ $this->assertTrue($loader->supports('foo.xml'), '->supports() returns true if the resource is loadable');
+ $this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
+
+ $this->assertTrue($loader->supports('foo.xml', 'xml'), '->supports() checks the resource type if specified');
+ $this->assertFalse($loader->supports('foo.xml', 'foo'), '->supports() checks the resource type if specified');
+ }
+
+ public function testLoadWithRoute()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('validpattern.xml');
+ $route = $routeCollection->get('blog_show');
+
+ $this->assertInstanceOf('Symfony\Component\Routing\Route', $route);
+ $this->assertSame('/blog/{slug}', $route->getPath());
+ $this->assertSame('{locale}.example.com', $route->getHost());
+ $this->assertSame('MyBundle:Blog:show', $route->getDefault('_controller'));
+ $this->assertSame('\w+', $route->getRequirement('locale'));
+ $this->assertSame('RouteCompiler', $route->getOption('compiler_class'));
+ $this->assertEquals(array('GET', 'POST', 'PUT', 'OPTIONS'), $route->getMethods());
+ $this->assertEquals(array('https'), $route->getSchemes());
+ $this->assertEquals('context.getMethod() == "GET"', $route->getCondition());
+ }
+
+ public function testLoadWithNamespacePrefix()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('namespaceprefix.xml');
+
+ $this->assertCount(1, $routeCollection->all(), 'One route is loaded');
+
+ $route = $routeCollection->get('blog_show');
+ $this->assertSame('/blog/{slug}', $route->getPath());
+ $this->assertSame('{_locale}.example.com', $route->getHost());
+ $this->assertSame('MyBundle:Blog:show', $route->getDefault('_controller'));
+ $this->assertSame('\w+', $route->getRequirement('slug'));
+ $this->assertSame('en|fr|de', $route->getRequirement('_locale'));
+ $this->assertNull($route->getDefault('slug'));
+ $this->assertSame('RouteCompiler', $route->getOption('compiler_class'));
+ $this->assertSame(1, $route->getDefault('page'));
+ }
+
+ public function testLoadWithImport()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('validresource.xml');
+ $routes = $routeCollection->all();
+
+ $this->assertCount(2, $routes, 'Two routes are loaded');
+ $this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
+
+ foreach ($routes as $route) {
+ $this->assertSame('/{foo}/blog/{slug}', $route->getPath());
+ $this->assertSame('123', $route->getDefault('foo'));
+ $this->assertSame('\d+', $route->getRequirement('foo'));
+ $this->assertSame('bar', $route->getOption('foo'));
+ $this->assertSame('', $route->getHost());
+ $this->assertSame('context.getMethod() == "POST"', $route->getCondition());
+ }
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @dataProvider getPathsToInvalidFiles
+ */
+ public function testLoadThrowsExceptionWithInvalidFile($filePath)
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $loader->load($filePath);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @dataProvider getPathsToInvalidFiles
+ */
+ public function testLoadThrowsExceptionWithInvalidFileEvenWithoutSchemaValidation($filePath)
+ {
+ $loader = new CustomXmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $loader->load($filePath);
+ }
+
+ public function getPathsToInvalidFiles()
+ {
+ return array(array('nonvalidnode.xml'), array('nonvalidroute.xml'), array('nonvalid.xml'), array('missing_id.xml'), array('missing_path.xml'));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Document types are not allowed.
+ */
+ public function testDocTypeIsNotAllowed()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $loader->load('withdoctype.xml');
+ }
+
+ public function testNullValues()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('null_values.xml');
+ $route = $routeCollection->get('blog_show');
+
+ $this->assertTrue($route->hasDefault('foo'));
+ $this->assertNull($route->getDefault('foo'));
+ $this->assertTrue($route->hasDefault('bar'));
+ $this->assertNull($route->getDefault('bar'));
+ $this->assertEquals('foo', $route->getDefault('foobar'));
+ $this->assertEquals('bar', $route->getDefault('baz'));
+ }
+
+ public function testScalarDataTypeDefaults()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('scalar_defaults.xml');
+ $route = $routeCollection->get('blog');
+
+ $this->assertSame(
+ array(
+ '_controller' => 'AcmeBlogBundle:Blog:index',
+ 'slug' => null,
+ 'published' => true,
+ 'page' => 1,
+ 'price' => 3.5,
+ 'archived' => false,
+ 'free' => true,
+ 'locked' => false,
+ 'foo' => null,
+ 'bar' => null,
+ ),
+ $route->getDefaults()
+ );
+ }
+
+ public function testListDefaults()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('list_defaults.xml');
+ $route = $routeCollection->get('blog');
+
+ $this->assertSame(
+ array(
+ '_controller' => 'AcmeBlogBundle:Blog:index',
+ 'values' => array(true, 1, 3.5, 'foo'),
+ ),
+ $route->getDefaults()
+ );
+ }
+
+ public function testListInListDefaults()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('list_in_list_defaults.xml');
+ $route = $routeCollection->get('blog');
+
+ $this->assertSame(
+ array(
+ '_controller' => 'AcmeBlogBundle:Blog:index',
+ 'values' => array(array(true, 1, 3.5, 'foo')),
+ ),
+ $route->getDefaults()
+ );
+ }
+
+ public function testListInMapDefaults()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('list_in_map_defaults.xml');
+ $route = $routeCollection->get('blog');
+
+ $this->assertSame(
+ array(
+ '_controller' => 'AcmeBlogBundle:Blog:index',
+ 'values' => array('list' => array(true, 1, 3.5, 'foo')),
+ ),
+ $route->getDefaults()
+ );
+ }
+
+ public function testMapDefaults()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('map_defaults.xml');
+ $route = $routeCollection->get('blog');
+
+ $this->assertSame(
+ array(
+ '_controller' => 'AcmeBlogBundle:Blog:index',
+ 'values' => array(
+ 'public' => true,
+ 'page' => 1,
+ 'price' => 3.5,
+ 'title' => 'foo',
+ ),
+ ),
+ $route->getDefaults()
+ );
+ }
+
+ public function testMapInListDefaults()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('map_in_list_defaults.xml');
+ $route = $routeCollection->get('blog');
+
+ $this->assertSame(
+ array(
+ '_controller' => 'AcmeBlogBundle:Blog:index',
+ 'values' => array(array(
+ 'public' => true,
+ 'page' => 1,
+ 'price' => 3.5,
+ 'title' => 'foo',
+ )),
+ ),
+ $route->getDefaults()
+ );
+ }
+
+ public function testMapInMapDefaults()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('map_in_map_defaults.xml');
+ $route = $routeCollection->get('blog');
+
+ $this->assertSame(
+ array(
+ '_controller' => 'AcmeBlogBundle:Blog:index',
+ 'values' => array('map' => array(
+ 'public' => true,
+ 'page' => 1,
+ 'price' => 3.5,
+ 'title' => 'foo',
+ )),
+ ),
+ $route->getDefaults()
+ );
+ }
+
+ public function testNullValuesInList()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('list_null_values.xml');
+ $route = $routeCollection->get('blog');
+
+ $this->assertSame(array(null, null, null, null, null, null), $route->getDefault('list'));
+ }
+
+ public function testNullValuesInMap()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('map_null_values.xml');
+ $route = $routeCollection->get('blog');
+
+ $this->assertSame(
+ array(
+ 'boolean' => null,
+ 'integer' => null,
+ 'float' => null,
+ 'string' => null,
+ 'list' => null,
+ 'map' => null,
+ ),
+ $route->getDefault('map')
+ );
+ }
+
+ public function testLoadRouteWithControllerAttribute()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
+ $routeCollection = $loader->load('routing.xml');
+
+ $route = $routeCollection->get('app_homepage');
+
+ $this->assertSame('AppBundle:Homepage:show', $route->getDefault('_controller'));
+ }
+
+ public function testLoadRouteWithoutControllerAttribute()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
+ $routeCollection = $loader->load('routing.xml');
+
+ $route = $routeCollection->get('app_logout');
+
+ $this->assertNull($route->getDefault('_controller'));
+ }
+
+ public function testLoadRouteWithControllerSetInDefaults()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
+ $routeCollection = $loader->load('routing.xml');
+
+ $route = $routeCollection->get('app_blog');
+
+ $this->assertSame('AppBundle:Blog:list', $route->getDefault('_controller'));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessageRegExp /The routing file "[^"]*" must not specify both the "controller" attribute and the defaults key "_controller" for "app_blog"/
+ */
+ public function testOverrideControllerInDefaults()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
+ $loader->load('override_defaults.xml');
+ }
+
+ /**
+ * @dataProvider provideFilesImportingRoutesWithControllers
+ */
+ public function testImportRouteWithController($file)
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
+ $routeCollection = $loader->load($file);
+
+ $route = $routeCollection->get('app_homepage');
+ $this->assertSame('FrameworkBundle:Template:template', $route->getDefault('_controller'));
+
+ $route = $routeCollection->get('app_blog');
+ $this->assertSame('FrameworkBundle:Template:template', $route->getDefault('_controller'));
+
+ $route = $routeCollection->get('app_logout');
+ $this->assertSame('FrameworkBundle:Template:template', $route->getDefault('_controller'));
+ }
+
+ public function provideFilesImportingRoutesWithControllers()
+ {
+ yield array('import_controller.xml');
+ yield array('import__controller.xml');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessageRegExp /The routing file "[^"]*" must not specify both the "controller" attribute and the defaults key "_controller" for the "import" tag/
+ */
+ public function testImportWithOverriddenController()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
+ $loader->load('import_override_defaults.xml');
+ }
+
+ public function testImportRouteWithGlobMatchingSingleFile()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/glob')));
+ $routeCollection = $loader->load('import_single.xml');
+
+ $route = $routeCollection->get('bar_route');
+ $this->assertSame('AppBundle:Bar:view', $route->getDefault('_controller'));
+ }
+
+ public function testImportRouteWithGlobMatchingMultipleFiles()
+ {
+ $loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/glob')));
+ $routeCollection = $loader->load('import_multiple.xml');
+
+ $route = $routeCollection->get('bar_route');
+ $this->assertSame('AppBundle:Bar:view', $route->getDefault('_controller'));
+
+ $route = $routeCollection->get('baz_route');
+ $this->assertSame('AppBundle:Baz:view', $route->getDefault('_controller'));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/YamlFileLoaderTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/YamlFileLoaderTest.php
new file mode 100644
index 0000000..822bddf
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Loader/YamlFileLoaderTest.php
@@ -0,0 +1,206 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Loader;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Config\FileLocator;
+use Symfony\Component\Routing\Loader\YamlFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class YamlFileLoaderTest extends TestCase
+{
+ public function testSupports()
+ {
+ $loader = new YamlFileLoader($this->getMockBuilder('Symfony\Component\Config\FileLocator')->getMock());
+
+ $this->assertTrue($loader->supports('foo.yml'), '->supports() returns true if the resource is loadable');
+ $this->assertTrue($loader->supports('foo.yaml'), '->supports() returns true if the resource is loadable');
+ $this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
+
+ $this->assertTrue($loader->supports('foo.yml', 'yaml'), '->supports() checks the resource type if specified');
+ $this->assertTrue($loader->supports('foo.yaml', 'yaml'), '->supports() checks the resource type if specified');
+ $this->assertFalse($loader->supports('foo.yml', 'foo'), '->supports() checks the resource type if specified');
+ }
+
+ public function testLoadDoesNothingIfEmpty()
+ {
+ $loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $collection = $loader->load('empty.yml');
+
+ $this->assertEquals(array(), $collection->all());
+ $this->assertEquals(array(new FileResource(realpath(__DIR__.'/../Fixtures/empty.yml'))), $collection->getResources());
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @dataProvider getPathsToInvalidFiles
+ */
+ public function testLoadThrowsExceptionWithInvalidFile($filePath)
+ {
+ $loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $loader->load($filePath);
+ }
+
+ public function getPathsToInvalidFiles()
+ {
+ return array(
+ array('nonvalid.yml'),
+ array('nonvalid2.yml'),
+ array('incomplete.yml'),
+ array('nonvalidkeys.yml'),
+ array('nonesense_resource_plus_path.yml'),
+ array('nonesense_type_without_resource.yml'),
+ array('bad_format.yml'),
+ );
+ }
+
+ public function testLoadSpecialRouteName()
+ {
+ $loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('special_route_name.yml');
+ $route = $routeCollection->get('#$péß^a|');
+
+ $this->assertInstanceOf('Symfony\Component\Routing\Route', $route);
+ $this->assertSame('/true', $route->getPath());
+ }
+
+ public function testLoadWithRoute()
+ {
+ $loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('validpattern.yml');
+ $route = $routeCollection->get('blog_show');
+
+ $this->assertInstanceOf('Symfony\Component\Routing\Route', $route);
+ $this->assertSame('/blog/{slug}', $route->getPath());
+ $this->assertSame('{locale}.example.com', $route->getHost());
+ $this->assertSame('MyBundle:Blog:show', $route->getDefault('_controller'));
+ $this->assertSame('\w+', $route->getRequirement('locale'));
+ $this->assertSame('RouteCompiler', $route->getOption('compiler_class'));
+ $this->assertEquals(array('GET', 'POST', 'PUT', 'OPTIONS'), $route->getMethods());
+ $this->assertEquals(array('https'), $route->getSchemes());
+ $this->assertEquals('context.getMethod() == "GET"', $route->getCondition());
+ }
+
+ public function testLoadWithResource()
+ {
+ $loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
+ $routeCollection = $loader->load('validresource.yml');
+ $routes = $routeCollection->all();
+
+ $this->assertCount(2, $routes, 'Two routes are loaded');
+ $this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
+
+ foreach ($routes as $route) {
+ $this->assertSame('/{foo}/blog/{slug}', $route->getPath());
+ $this->assertSame('123', $route->getDefault('foo'));
+ $this->assertSame('\d+', $route->getRequirement('foo'));
+ $this->assertSame('bar', $route->getOption('foo'));
+ $this->assertSame('', $route->getHost());
+ $this->assertSame('context.getMethod() == "POST"', $route->getCondition());
+ }
+ }
+
+ public function testLoadRouteWithControllerAttribute()
+ {
+ $loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
+ $routeCollection = $loader->load('routing.yml');
+
+ $route = $routeCollection->get('app_homepage');
+
+ $this->assertSame('AppBundle:Homepage:show', $route->getDefault('_controller'));
+ }
+
+ public function testLoadRouteWithoutControllerAttribute()
+ {
+ $loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
+ $routeCollection = $loader->load('routing.yml');
+
+ $route = $routeCollection->get('app_logout');
+
+ $this->assertNull($route->getDefault('_controller'));
+ }
+
+ public function testLoadRouteWithControllerSetInDefaults()
+ {
+ $loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
+ $routeCollection = $loader->load('routing.yml');
+
+ $route = $routeCollection->get('app_blog');
+
+ $this->assertSame('AppBundle:Blog:list', $route->getDefault('_controller'));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessageRegExp /The routing file "[^"]*" must not specify both the "controller" key and the defaults key "_controller" for "app_blog"/
+ */
+ public function testOverrideControllerInDefaults()
+ {
+ $loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
+ $loader->load('override_defaults.yml');
+ }
+
+ /**
+ * @dataProvider provideFilesImportingRoutesWithControllers
+ */
+ public function testImportRouteWithController($file)
+ {
+ $loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
+ $routeCollection = $loader->load($file);
+
+ $route = $routeCollection->get('app_homepage');
+ $this->assertSame('FrameworkBundle:Template:template', $route->getDefault('_controller'));
+
+ $route = $routeCollection->get('app_blog');
+ $this->assertSame('FrameworkBundle:Template:template', $route->getDefault('_controller'));
+
+ $route = $routeCollection->get('app_logout');
+ $this->assertSame('FrameworkBundle:Template:template', $route->getDefault('_controller'));
+ }
+
+ public function provideFilesImportingRoutesWithControllers()
+ {
+ yield array('import_controller.yml');
+ yield array('import__controller.yml');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessageRegExp /The routing file "[^"]*" must not specify both the "controller" key and the defaults key "_controller" for "_static"/
+ */
+ public function testImportWithOverriddenController()
+ {
+ $loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
+ $loader->load('import_override_defaults.yml');
+ }
+
+ public function testImportRouteWithGlobMatchingSingleFile()
+ {
+ $loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/glob')));
+ $routeCollection = $loader->load('import_single.yml');
+
+ $route = $routeCollection->get('bar_route');
+ $this->assertSame('AppBundle:Bar:view', $route->getDefault('_controller'));
+ }
+
+ public function testImportRouteWithGlobMatchingMultipleFiles()
+ {
+ $loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/glob')));
+ $routeCollection = $loader->load('import_multiple.yml');
+
+ $route = $routeCollection->get('bar_route');
+ $this->assertSame('AppBundle:Bar:view', $route->getDefault('_controller'));
+
+ $route = $routeCollection->get('baz_route');
+ $this->assertSame('AppBundle:Baz:view', $route->getDefault('_controller'));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/DumpedRedirectableUrlMatcherTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/DumpedRedirectableUrlMatcherTest.php
new file mode 100644
index 0000000..cfbb524
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/DumpedRedirectableUrlMatcherTest.php
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Matcher;
+
+use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper;
+use Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface;
+use Symfony\Component\Routing\Matcher\UrlMatcher;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\RequestContext;
+
+class DumpedRedirectableUrlMatcherTest extends RedirectableUrlMatcherTest
+{
+ protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null)
+ {
+ static $i = 0;
+
+ $class = 'DumpedRedirectableUrlMatcher'.++$i;
+ $dumper = new PhpMatcherDumper($routes);
+ eval('?>'.$dumper->dump(array('class' => $class, 'base_class' => 'Symfony\Component\Routing\Tests\Matcher\TestDumpedRedirectableUrlMatcher')));
+
+ return $this->getMockBuilder($class)
+ ->setConstructorArgs(array($context ?: new RequestContext()))
+ ->setMethods(array('redirect'))
+ ->getMock();
+ }
+}
+
+class TestDumpedRedirectableUrlMatcher extends UrlMatcher implements RedirectableUrlMatcherInterface
+{
+ public function redirect($path, $route, $scheme = null)
+ {
+ return array();
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/DumpedUrlMatcherTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/DumpedUrlMatcherTest.php
new file mode 100644
index 0000000..880b2b1
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/DumpedUrlMatcherTest.php
@@ -0,0 +1,48 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Matcher;
+
+use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\RequestContext;
+
+class DumpedUrlMatcherTest extends UrlMatcherTest
+{
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage The "schemes" requirement is only supported for URL matchers that implement RedirectableUrlMatcherInterface.
+ */
+ public function testSchemeRequirement()
+ {
+ parent::testSchemeRequirement();
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage The "schemes" requirement is only supported for URL matchers that implement RedirectableUrlMatcherInterface.
+ */
+ public function testSchemeAndMethodMismatch()
+ {
+ parent::testSchemeRequirement();
+ }
+
+ protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null)
+ {
+ static $i = 0;
+
+ $class = 'DumpedUrlMatcher'.++$i;
+ $dumper = new PhpMatcherDumper($routes);
+ eval('?>'.$dumper->dump(array('class' => $class)));
+
+ return new $class($context ?: new RequestContext());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/Dumper/DumperCollectionTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/Dumper/DumperCollectionTest.php
new file mode 100644
index 0000000..823efdb
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/Dumper/DumperCollectionTest.php
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Matcher\Dumper;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Routing\Matcher\Dumper\DumperCollection;
+
+class DumperCollectionTest extends TestCase
+{
+ public function testGetRoot()
+ {
+ $a = new DumperCollection();
+
+ $b = new DumperCollection();
+ $a->add($b);
+
+ $c = new DumperCollection();
+ $b->add($c);
+
+ $d = new DumperCollection();
+ $c->add($d);
+
+ $this->assertSame($a, $c->getRoot());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php
new file mode 100644
index 0000000..f29a6d6
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php
@@ -0,0 +1,459 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Matcher\Dumper;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper;
+use Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface;
+use Symfony\Component\Routing\Matcher\UrlMatcher;
+use Symfony\Component\Routing\RequestContext;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+
+class PhpMatcherDumperTest extends TestCase
+{
+ /**
+ * @var string
+ */
+ private $matcherClass;
+
+ /**
+ * @var string
+ */
+ private $dumpPath;
+
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $this->matcherClass = uniqid('ProjectUrlMatcher');
+ $this->dumpPath = sys_get_temp_dir().DIRECTORY_SEPARATOR.'php_matcher.'.$this->matcherClass.'.php';
+ }
+
+ protected function tearDown()
+ {
+ parent::tearDown();
+
+ @unlink($this->dumpPath);
+ }
+
+ /**
+ * @expectedException \LogicException
+ */
+ public function testDumpWhenSchemeIsUsedWithoutAProperDumper()
+ {
+ $collection = new RouteCollection();
+ $collection->add('secure', new Route(
+ '/secure',
+ array(),
+ array(),
+ array(),
+ '',
+ array('https')
+ ));
+ $dumper = new PhpMatcherDumper($collection);
+ $dumper->dump();
+ }
+
+ public function testRedirectPreservesUrlEncoding()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/foo:bar/'));
+
+ $class = $this->generateDumpedMatcher($collection, true);
+
+ $matcher = $this->getMockBuilder($class)
+ ->setMethods(array('redirect'))
+ ->setConstructorArgs(array(new RequestContext()))
+ ->getMock();
+
+ $matcher->expects($this->once())->method('redirect')->with('/foo%3Abar/', 'foo')->willReturn(array());
+
+ $matcher->match('/foo%3Abar');
+ }
+
+ /**
+ * @dataProvider getRouteCollections
+ */
+ public function testDump(RouteCollection $collection, $fixture, $options = array())
+ {
+ $basePath = __DIR__.'/../../Fixtures/dumper/';
+
+ $dumper = new PhpMatcherDumper($collection);
+ $this->assertStringEqualsFile($basePath.$fixture, $dumper->dump($options), '->dump() correctly dumps routes as optimized PHP code.');
+ }
+
+ public function getRouteCollections()
+ {
+ /* test case 1 */
+
+ $collection = new RouteCollection();
+
+ $collection->add('overridden', new Route('/overridden'));
+
+ // defaults and requirements
+ $collection->add('foo', new Route(
+ '/foo/{bar}',
+ array('def' => 'test'),
+ array('bar' => 'baz|symfony')
+ ));
+ // method requirement
+ $collection->add('bar', new Route(
+ '/bar/{foo}',
+ array(),
+ array(),
+ array(),
+ '',
+ array(),
+ array('GET', 'head')
+ ));
+ // GET method requirement automatically adds HEAD as valid
+ $collection->add('barhead', new Route(
+ '/barhead/{foo}',
+ array(),
+ array(),
+ array(),
+ '',
+ array(),
+ array('GET')
+ ));
+ // simple
+ $collection->add('baz', new Route(
+ '/test/baz'
+ ));
+ // simple with extension
+ $collection->add('baz2', new Route(
+ '/test/baz.html'
+ ));
+ // trailing slash
+ $collection->add('baz3', new Route(
+ '/test/baz3/'
+ ));
+ // trailing slash with variable
+ $collection->add('baz4', new Route(
+ '/test/{foo}/'
+ ));
+ // trailing slash and method
+ $collection->add('baz5', new Route(
+ '/test/{foo}/',
+ array(),
+ array(),
+ array(),
+ '',
+ array(),
+ array('post')
+ ));
+ // complex name
+ $collection->add('baz.baz6', new Route(
+ '/test/{foo}/',
+ array(),
+ array(),
+ array(),
+ '',
+ array(),
+ array('put')
+ ));
+ // defaults without variable
+ $collection->add('foofoo', new Route(
+ '/foofoo',
+ array('def' => 'test')
+ ));
+ // pattern with quotes
+ $collection->add('quoter', new Route(
+ '/{quoter}',
+ array(),
+ array('quoter' => '[\']+')
+ ));
+ // space in pattern
+ $collection->add('space', new Route(
+ '/spa ce'
+ ));
+
+ // prefixes
+ $collection1 = new RouteCollection();
+ $collection1->add('overridden', new Route('/overridden1'));
+ $collection1->add('foo1', new Route('/{foo}'));
+ $collection1->add('bar1', new Route('/{bar}'));
+ $collection1->addPrefix('/b\'b');
+ $collection2 = new RouteCollection();
+ $collection2->addCollection($collection1);
+ $collection2->add('overridden', new Route('/{var}', array(), array('var' => '.*')));
+ $collection1 = new RouteCollection();
+ $collection1->add('foo2', new Route('/{foo1}'));
+ $collection1->add('bar2', new Route('/{bar1}'));
+ $collection1->addPrefix('/b\'b');
+ $collection2->addCollection($collection1);
+ $collection2->addPrefix('/a');
+ $collection->addCollection($collection2);
+
+ // overridden through addCollection() and multiple sub-collections with no own prefix
+ $collection1 = new RouteCollection();
+ $collection1->add('overridden2', new Route('/old'));
+ $collection1->add('helloWorld', new Route('/hello/{who}', array('who' => 'World!')));
+ $collection2 = new RouteCollection();
+ $collection3 = new RouteCollection();
+ $collection3->add('overridden2', new Route('/new'));
+ $collection3->add('hey', new Route('/hey/'));
+ $collection2->addCollection($collection3);
+ $collection1->addCollection($collection2);
+ $collection1->addPrefix('/multi');
+ $collection->addCollection($collection1);
+
+ // "dynamic" prefix
+ $collection1 = new RouteCollection();
+ $collection1->add('foo3', new Route('/{foo}'));
+ $collection1->add('bar3', new Route('/{bar}'));
+ $collection1->addPrefix('/b');
+ $collection1->addPrefix('{_locale}');
+ $collection->addCollection($collection1);
+
+ // route between collections
+ $collection->add('ababa', new Route('/ababa'));
+
+ // collection with static prefix but only one route
+ $collection1 = new RouteCollection();
+ $collection1->add('foo4', new Route('/{foo}'));
+ $collection1->addPrefix('/aba');
+ $collection->addCollection($collection1);
+
+ // prefix and host
+
+ $collection1 = new RouteCollection();
+
+ $route1 = new Route('/route1', array(), array(), array(), 'a.example.com');
+ $collection1->add('route1', $route1);
+
+ $route2 = new Route('/c2/route2', array(), array(), array(), 'a.example.com');
+ $collection1->add('route2', $route2);
+
+ $route3 = new Route('/c2/route3', array(), array(), array(), 'b.example.com');
+ $collection1->add('route3', $route3);
+
+ $route4 = new Route('/route4', array(), array(), array(), 'a.example.com');
+ $collection1->add('route4', $route4);
+
+ $route5 = new Route('/route5', array(), array(), array(), 'c.example.com');
+ $collection1->add('route5', $route5);
+
+ $route6 = new Route('/route6', array(), array(), array(), null);
+ $collection1->add('route6', $route6);
+
+ $collection->addCollection($collection1);
+
+ // host and variables
+
+ $collection1 = new RouteCollection();
+
+ $route11 = new Route('/route11', array(), array(), array(), '{var1}.example.com');
+ $collection1->add('route11', $route11);
+
+ $route12 = new Route('/route12', array('var1' => 'val'), array(), array(), '{var1}.example.com');
+ $collection1->add('route12', $route12);
+
+ $route13 = new Route('/route13/{name}', array(), array(), array(), '{var1}.example.com');
+ $collection1->add('route13', $route13);
+
+ $route14 = new Route('/route14/{name}', array('var1' => 'val'), array(), array(), '{var1}.example.com');
+ $collection1->add('route14', $route14);
+
+ $route15 = new Route('/route15/{name}', array(), array(), array(), 'c.example.com');
+ $collection1->add('route15', $route15);
+
+ $route16 = new Route('/route16/{name}', array('var1' => 'val'), array(), array(), null);
+ $collection1->add('route16', $route16);
+
+ $route17 = new Route('/route17', array(), array(), array(), null);
+ $collection1->add('route17', $route17);
+
+ $collection->addCollection($collection1);
+
+ // multiple sub-collections with a single route and a prefix each
+ $collection1 = new RouteCollection();
+ $collection1->add('a', new Route('/a...'));
+ $collection2 = new RouteCollection();
+ $collection2->add('b', new Route('/{var}'));
+ $collection3 = new RouteCollection();
+ $collection3->add('c', new Route('/{var}'));
+ $collection3->addPrefix('/c');
+ $collection2->addCollection($collection3);
+ $collection2->addPrefix('/b');
+ $collection1->addCollection($collection2);
+ $collection1->addPrefix('/a');
+ $collection->addCollection($collection1);
+
+ /* test case 2 */
+
+ $redirectCollection = clone $collection;
+
+ // force HTTPS redirection
+ $redirectCollection->add('secure', new Route(
+ '/secure',
+ array(),
+ array(),
+ array(),
+ '',
+ array('https')
+ ));
+
+ // force HTTP redirection
+ $redirectCollection->add('nonsecure', new Route(
+ '/nonsecure',
+ array(),
+ array(),
+ array(),
+ '',
+ array('http')
+ ));
+
+ /* test case 3 */
+
+ $rootprefixCollection = new RouteCollection();
+ $rootprefixCollection->add('static', new Route('/test'));
+ $rootprefixCollection->add('dynamic', new Route('/{var}'));
+ $rootprefixCollection->addPrefix('rootprefix');
+ $route = new Route('/with-condition');
+ $route->setCondition('context.getMethod() == "GET"');
+ $rootprefixCollection->add('with-condition', $route);
+
+ /* test case 4 */
+ $headMatchCasesCollection = new RouteCollection();
+ $headMatchCasesCollection->add('just_head', new Route(
+ '/just_head',
+ array(),
+ array(),
+ array(),
+ '',
+ array(),
+ array('HEAD')
+ ));
+ $headMatchCasesCollection->add('head_and_get', new Route(
+ '/head_and_get',
+ array(),
+ array(),
+ array(),
+ '',
+ array(),
+ array('HEAD', 'GET')
+ ));
+ $headMatchCasesCollection->add('get_and_head', new Route(
+ '/get_and_head',
+ array(),
+ array(),
+ array(),
+ '',
+ array(),
+ array('GET', 'HEAD')
+ ));
+ $headMatchCasesCollection->add('post_and_head', new Route(
+ '/post_and_head',
+ array(),
+ array(),
+ array(),
+ '',
+ array(),
+ array('POST', 'HEAD')
+ ));
+ $headMatchCasesCollection->add('put_and_post', new Route(
+ '/put_and_post',
+ array(),
+ array(),
+ array(),
+ '',
+ array(),
+ array('PUT', 'POST')
+ ));
+ $headMatchCasesCollection->add('put_and_get_and_head', new Route(
+ '/put_and_post',
+ array(),
+ array(),
+ array(),
+ '',
+ array(),
+ array('PUT', 'GET', 'HEAD')
+ ));
+
+ /* test case 5 */
+ $groupOptimisedCollection = new RouteCollection();
+ $groupOptimisedCollection->add('a_first', new Route('/a/11'));
+ $groupOptimisedCollection->add('a_second', new Route('/a/22'));
+ $groupOptimisedCollection->add('a_third', new Route('/a/333'));
+ $groupOptimisedCollection->add('a_wildcard', new Route('/{param}'));
+ $groupOptimisedCollection->add('a_fourth', new Route('/a/44/'));
+ $groupOptimisedCollection->add('a_fifth', new Route('/a/55/'));
+ $groupOptimisedCollection->add('a_sixth', new Route('/a/66/'));
+ $groupOptimisedCollection->add('nested_wildcard', new Route('/nested/{param}'));
+ $groupOptimisedCollection->add('nested_a', new Route('/nested/group/a/'));
+ $groupOptimisedCollection->add('nested_b', new Route('/nested/group/b/'));
+ $groupOptimisedCollection->add('nested_c', new Route('/nested/group/c/'));
+
+ $groupOptimisedCollection->add('slashed_a', new Route('/slashed/group/'));
+ $groupOptimisedCollection->add('slashed_b', new Route('/slashed/group/b/'));
+ $groupOptimisedCollection->add('slashed_c', new Route('/slashed/group/c/'));
+
+ $trailingSlashCollection = new RouteCollection();
+ $trailingSlashCollection->add('simple_trailing_slash_no_methods', new Route('/trailing/simple/no-methods/', array(), array(), array(), '', array(), array()));
+ $trailingSlashCollection->add('simple_trailing_slash_GET_method', new Route('/trailing/simple/get-method/', array(), array(), array(), '', array(), array('GET')));
+ $trailingSlashCollection->add('simple_trailing_slash_HEAD_method', new Route('/trailing/simple/head-method/', array(), array(), array(), '', array(), array('HEAD')));
+ $trailingSlashCollection->add('simple_trailing_slash_POST_method', new Route('/trailing/simple/post-method/', array(), array(), array(), '', array(), array('POST')));
+ $trailingSlashCollection->add('regex_trailing_slash_no_methods', new Route('/trailing/regex/no-methods/{param}/', array(), array(), array(), '', array(), array()));
+ $trailingSlashCollection->add('regex_trailing_slash_GET_method', new Route('/trailing/regex/get-method/{param}/', array(), array(), array(), '', array(), array('GET')));
+ $trailingSlashCollection->add('regex_trailing_slash_HEAD_method', new Route('/trailing/regex/head-method/{param}/', array(), array(), array(), '', array(), array('HEAD')));
+ $trailingSlashCollection->add('regex_trailing_slash_POST_method', new Route('/trailing/regex/post-method/{param}/', array(), array(), array(), '', array(), array('POST')));
+
+ $trailingSlashCollection->add('simple_not_trailing_slash_no_methods', new Route('/not-trailing/simple/no-methods', array(), array(), array(), '', array(), array()));
+ $trailingSlashCollection->add('simple_not_trailing_slash_GET_method', new Route('/not-trailing/simple/get-method', array(), array(), array(), '', array(), array('GET')));
+ $trailingSlashCollection->add('simple_not_trailing_slash_HEAD_method', new Route('/not-trailing/simple/head-method', array(), array(), array(), '', array(), array('HEAD')));
+ $trailingSlashCollection->add('simple_not_trailing_slash_POST_method', new Route('/not-trailing/simple/post-method', array(), array(), array(), '', array(), array('POST')));
+ $trailingSlashCollection->add('regex_not_trailing_slash_no_methods', new Route('/not-trailing/regex/no-methods/{param}', array(), array(), array(), '', array(), array()));
+ $trailingSlashCollection->add('regex_not_trailing_slash_GET_method', new Route('/not-trailing/regex/get-method/{param}', array(), array(), array(), '', array(), array('GET')));
+ $trailingSlashCollection->add('regex_not_trailing_slash_HEAD_method', new Route('/not-trailing/regex/head-method/{param}', array(), array(), array(), '', array(), array('HEAD')));
+ $trailingSlashCollection->add('regex_not_trailing_slash_POST_method', new Route('/not-trailing/regex/post-method/{param}', array(), array(), array(), '', array(), array('POST')));
+
+ return array(
+ array(new RouteCollection(), 'url_matcher0.php', array()),
+ array($collection, 'url_matcher1.php', array()),
+ array($redirectCollection, 'url_matcher2.php', array('base_class' => 'Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher')),
+ array($rootprefixCollection, 'url_matcher3.php', array()),
+ array($headMatchCasesCollection, 'url_matcher4.php', array()),
+ array($groupOptimisedCollection, 'url_matcher5.php', array('base_class' => 'Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher')),
+ array($trailingSlashCollection, 'url_matcher6.php', array()),
+ array($trailingSlashCollection, 'url_matcher7.php', array('base_class' => 'Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher')),
+ );
+ }
+
+ /**
+ * @param $dumper
+ */
+ private function generateDumpedMatcher(RouteCollection $collection, $redirectableStub = false)
+ {
+ $options = array('class' => $this->matcherClass);
+
+ if ($redirectableStub) {
+ $options['base_class'] = '\Symfony\Component\Routing\Tests\Matcher\Dumper\RedirectableUrlMatcherStub';
+ }
+
+ $dumper = new PhpMatcherDumper($collection);
+ $code = $dumper->dump($options);
+
+ file_put_contents($this->dumpPath, $code);
+ include $this->dumpPath;
+
+ return $this->matcherClass;
+ }
+}
+
+abstract class RedirectableUrlMatcherStub extends UrlMatcher implements RedirectableUrlMatcherInterface
+{
+ public function redirect($path, $route, $scheme = null)
+ {
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/Dumper/StaticPrefixCollectionTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/Dumper/StaticPrefixCollectionTest.php
new file mode 100644
index 0000000..37419e7
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/Dumper/StaticPrefixCollectionTest.php
@@ -0,0 +1,175 @@
+<?php
+
+namespace Symfony\Component\Routing\Tests\Matcher\Dumper;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Routing\Matcher\Dumper\StaticPrefixCollection;
+use Symfony\Component\Routing\Route;
+
+class StaticPrefixCollectionTest extends TestCase
+{
+ /**
+ * @dataProvider routeProvider
+ */
+ public function testGrouping(array $routes, $expected)
+ {
+ $collection = new StaticPrefixCollection('/');
+
+ foreach ($routes as $route) {
+ list($path, $name) = $route;
+ $staticPrefix = (new Route($path))->compile()->getStaticPrefix();
+ $collection->addRoute($staticPrefix, $name);
+ }
+
+ $collection->optimizeGroups();
+ $dumped = $this->dumpCollection($collection);
+ $this->assertEquals($expected, $dumped);
+ }
+
+ public function routeProvider()
+ {
+ return array(
+ 'Simple - not nested' => array(
+ array(
+ array('/', 'root'),
+ array('/prefix/segment/', 'prefix_segment'),
+ array('/leading/segment/', 'leading_segment'),
+ ),
+ <<<EOF
+/ root
+/prefix/segment prefix_segment
+/leading/segment leading_segment
+EOF
+ ),
+ 'Not nested - group too small' => array(
+ array(
+ array('/', 'root'),
+ array('/prefix/segment/aa', 'prefix_segment'),
+ array('/prefix/segment/bb', 'leading_segment'),
+ ),
+ <<<EOF
+/ root
+/prefix/segment/aa prefix_segment
+/prefix/segment/bb leading_segment
+EOF
+ ),
+ 'Nested - contains item at intersection' => array(
+ array(
+ array('/', 'root'),
+ array('/prefix/segment/', 'prefix_segment'),
+ array('/prefix/segment/bb', 'leading_segment'),
+ ),
+ <<<EOF
+/ root
+/prefix/segment
+-> /prefix/segment prefix_segment
+-> /prefix/segment/bb leading_segment
+EOF
+ ),
+ 'Simple one level nesting' => array(
+ array(
+ array('/', 'root'),
+ array('/group/segment/', 'nested_segment'),
+ array('/group/thing/', 'some_segment'),
+ array('/group/other/', 'other_segment'),
+ ),
+ <<<EOF
+/ root
+/group
+-> /group/segment nested_segment
+-> /group/thing some_segment
+-> /group/other other_segment
+EOF
+ ),
+ 'Retain matching order with groups' => array(
+ array(
+ array('/group/aa/', 'aa'),
+ array('/group/bb/', 'bb'),
+ array('/group/cc/', 'cc'),
+ array('/', 'root'),
+ array('/group/dd/', 'dd'),
+ array('/group/ee/', 'ee'),
+ array('/group/ff/', 'ff'),
+ ),
+ <<<EOF
+/group
+-> /group/aa aa
+-> /group/bb bb
+-> /group/cc cc
+/ root
+/group
+-> /group/dd dd
+-> /group/ee ee
+-> /group/ff ff
+EOF
+ ),
+ 'Retain complex matching order with groups at base' => array(
+ array(
+ array('/aaa/111/', 'first_aaa'),
+ array('/prefixed/group/aa/', 'aa'),
+ array('/prefixed/group/bb/', 'bb'),
+ array('/prefixed/group/cc/', 'cc'),
+ array('/prefixed/', 'root'),
+ array('/prefixed/group/dd/', 'dd'),
+ array('/prefixed/group/ee/', 'ee'),
+ array('/prefixed/group/ff/', 'ff'),
+ array('/aaa/222/', 'second_aaa'),
+ array('/aaa/333/', 'third_aaa'),
+ ),
+ <<<EOF
+/aaa
+-> /aaa/111 first_aaa
+-> /aaa/222 second_aaa
+-> /aaa/333 third_aaa
+/prefixed
+-> /prefixed/group
+-> -> /prefixed/group/aa aa
+-> -> /prefixed/group/bb bb
+-> -> /prefixed/group/cc cc
+-> /prefixed root
+-> /prefixed/group
+-> -> /prefixed/group/dd dd
+-> -> /prefixed/group/ee ee
+-> -> /prefixed/group/ff ff
+EOF
+ ),
+
+ 'Group regardless of segments' => array(
+ array(
+ array('/aaa-111/', 'a1'),
+ array('/aaa-222/', 'a2'),
+ array('/aaa-333/', 'a3'),
+ array('/group-aa/', 'g1'),
+ array('/group-bb/', 'g2'),
+ array('/group-cc/', 'g3'),
+ ),
+ <<<EOF
+/aaa-
+-> /aaa-111 a1
+-> /aaa-222 a2
+-> /aaa-333 a3
+/group-
+-> /group-aa g1
+-> /group-bb g2
+-> /group-cc g3
+EOF
+ ),
+ );
+ }
+
+ private function dumpCollection(StaticPrefixCollection $collection, $prefix = '')
+ {
+ $lines = array();
+
+ foreach ($collection->getItems() as $item) {
+ if ($item instanceof StaticPrefixCollection) {
+ $lines[] = $prefix.$item->getPrefix();
+ $lines[] = $this->dumpCollection($item, $prefix.'-> ');
+ } else {
+ $lines[] = $prefix.implode(' ', $item);
+ }
+ }
+
+ return implode("\n", $lines);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/RedirectableUrlMatcherTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/RedirectableUrlMatcherTest.php
new file mode 100644
index 0000000..7984391
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/RedirectableUrlMatcherTest.php
@@ -0,0 +1,124 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Matcher;
+
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\RequestContext;
+
+class RedirectableUrlMatcherTest extends UrlMatcherTest
+{
+ public function testMissingTrailingSlash()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo/'));
+
+ $matcher = $this->getUrlMatcher($coll);
+ $matcher->expects($this->once())->method('redirect')->will($this->returnValue(array()));
+ $matcher->match('/foo');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
+ */
+ public function testRedirectWhenNoSlashForNonSafeMethod()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo/'));
+
+ $context = new RequestContext();
+ $context->setMethod('POST');
+ $matcher = $this->getUrlMatcher($coll, $context);
+ $matcher->match('/foo');
+ }
+
+ public function testSchemeRedirectRedirectsToFirstScheme()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo', array(), array(), array(), '', array('FTP', 'HTTPS')));
+
+ $matcher = $this->getUrlMatcher($coll);
+ $matcher
+ ->expects($this->once())
+ ->method('redirect')
+ ->with('/foo', 'foo', 'ftp')
+ ->will($this->returnValue(array('_route' => 'foo')))
+ ;
+ $matcher->match('/foo');
+ }
+
+ public function testNoSchemaRedirectIfOneOfMultipleSchemesMatches()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo', array(), array(), array(), '', array('https', 'http')));
+
+ $matcher = $this->getUrlMatcher($coll);
+ $matcher
+ ->expects($this->never())
+ ->method('redirect');
+ $matcher->match('/foo');
+ }
+
+ public function testSchemeRedirectWithParams()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo/{bar}', array(), array(), array(), '', array('https')));
+
+ $matcher = $this->getUrlMatcher($coll);
+ $matcher
+ ->expects($this->once())
+ ->method('redirect')
+ ->with('/foo/baz', 'foo', 'https')
+ ->will($this->returnValue(array('redirect' => 'value')))
+ ;
+ $this->assertEquals(array('_route' => 'foo', 'bar' => 'baz', 'redirect' => 'value'), $matcher->match('/foo/baz'));
+ }
+
+ public function testSlashRedirectWithParams()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo/{bar}/'));
+
+ $matcher = $this->getUrlMatcher($coll);
+ $matcher
+ ->expects($this->once())
+ ->method('redirect')
+ ->with('/foo/baz/', 'foo', null)
+ ->will($this->returnValue(array('redirect' => 'value')))
+ ;
+ $this->assertEquals(array('_route' => 'foo', 'bar' => 'baz', 'redirect' => 'value'), $matcher->match('/foo/baz'));
+ }
+
+ public function testRedirectPreservesUrlEncoding()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo:bar/'));
+
+ $matcher = $this->getUrlMatcher($coll);
+ $matcher->expects($this->once())->method('redirect')->with('/foo%3Abar/')->willReturn(array());
+ $matcher->match('/foo%3Abar');
+ }
+
+ public function testSchemeRequirement()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo', array(), array(), array(), '', array('https')));
+ $matcher = $this->getUrlMatcher($coll, new RequestContext());
+ $matcher->expects($this->once())->method('redirect')->with('/foo', 'foo', 'https')->willReturn(array());
+ $this->assertSame(array('_route' => 'foo'), $matcher->match('/foo'));
+ }
+
+ protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null)
+ {
+ return $this->getMockForAbstractClass('Symfony\Component\Routing\Matcher\RedirectableUrlMatcher', array($routes, $context ?: new RequestContext()));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/TraceableUrlMatcherTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/TraceableUrlMatcherTest.php
new file mode 100644
index 0000000..9f0529e
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/TraceableUrlMatcherTest.php
@@ -0,0 +1,122 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Matcher;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\RequestContext;
+use Symfony\Component\Routing\Matcher\TraceableUrlMatcher;
+
+class TraceableUrlMatcherTest extends TestCase
+{
+ public function test()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo', array(), array(), array(), '', array(), array('POST')));
+ $coll->add('bar', new Route('/bar/{id}', array(), array('id' => '\d+')));
+ $coll->add('bar1', new Route('/bar/{name}', array(), array('id' => '\w+'), array(), '', array(), array('POST')));
+ $coll->add('bar2', new Route('/foo', array(), array(), array(), 'baz'));
+ $coll->add('bar3', new Route('/foo1', array(), array(), array(), 'baz'));
+ $coll->add('bar4', new Route('/foo2', array(), array(), array(), 'baz', array(), array(), 'context.getMethod() == "GET"'));
+
+ $context = new RequestContext();
+ $context->setHost('baz');
+
+ $matcher = new TraceableUrlMatcher($coll, $context);
+ $traces = $matcher->getTraces('/babar');
+ $this->assertSame(array(0, 0, 0, 0, 0, 0), $this->getLevels($traces));
+
+ $traces = $matcher->getTraces('/foo');
+ $this->assertSame(array(1, 0, 0, 2), $this->getLevels($traces));
+
+ $traces = $matcher->getTraces('/bar/12');
+ $this->assertSame(array(0, 2), $this->getLevels($traces));
+
+ $traces = $matcher->getTraces('/bar/dd');
+ $this->assertSame(array(0, 1, 1, 0, 0, 0), $this->getLevels($traces));
+
+ $traces = $matcher->getTraces('/foo1');
+ $this->assertSame(array(0, 0, 0, 0, 2), $this->getLevels($traces));
+
+ $context->setMethod('POST');
+ $traces = $matcher->getTraces('/foo');
+ $this->assertSame(array(2), $this->getLevels($traces));
+
+ $traces = $matcher->getTraces('/bar/dd');
+ $this->assertSame(array(0, 1, 2), $this->getLevels($traces));
+
+ $traces = $matcher->getTraces('/foo2');
+ $this->assertSame(array(0, 0, 0, 0, 0, 1), $this->getLevels($traces));
+ }
+
+ public function testMatchRouteOnMultipleHosts()
+ {
+ $routes = new RouteCollection();
+ $routes->add('first', new Route(
+ '/mypath/',
+ array('_controller' => 'MainBundle:Info:first'),
+ array(),
+ array(),
+ 'some.example.com'
+ ));
+
+ $routes->add('second', new Route(
+ '/mypath/',
+ array('_controller' => 'MainBundle:Info:second'),
+ array(),
+ array(),
+ 'another.example.com'
+ ));
+
+ $context = new RequestContext();
+ $context->setHost('baz');
+
+ $matcher = new TraceableUrlMatcher($routes, $context);
+
+ $traces = $matcher->getTraces('/mypath/');
+ $this->assertSame(
+ array(TraceableUrlMatcher::ROUTE_ALMOST_MATCHES, TraceableUrlMatcher::ROUTE_ALMOST_MATCHES),
+ $this->getLevels($traces)
+ );
+ }
+
+ public function getLevels($traces)
+ {
+ $levels = array();
+ foreach ($traces as $trace) {
+ $levels[] = $trace['level'];
+ }
+
+ return $levels;
+ }
+
+ public function testRoutesWithConditions()
+ {
+ $routes = new RouteCollection();
+ $routes->add('foo', new Route('/foo', array(), array(), array(), 'baz', array(), array(), "request.headers.get('User-Agent') matches '/firefox/i'"));
+
+ $context = new RequestContext();
+ $context->setHost('baz');
+
+ $matcher = new TraceableUrlMatcher($routes, $context);
+
+ $notMatchingRequest = Request::create('/foo', 'GET');
+ $traces = $matcher->getTracesForRequest($notMatchingRequest);
+ $this->assertEquals("Condition \"request.headers.get('User-Agent') matches '/firefox/i'\" does not evaluate to \"true\"", $traces[0]['log']);
+
+ $matchingRequest = Request::create('/foo', 'GET', array(), array(), array(), array('HTTP_USER_AGENT' => 'Firefox'));
+ $traces = $matcher->getTracesForRequest($matchingRequest);
+ $this->assertEquals('Route matches!', $traces[0]['log']);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/UrlMatcherTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/UrlMatcherTest.php
new file mode 100644
index 0000000..e8d31e2
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/Matcher/UrlMatcherTest.php
@@ -0,0 +1,509 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests\Matcher;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\Matcher\UrlMatcher;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\RequestContext;
+
+class UrlMatcherTest extends TestCase
+{
+ public function testNoMethodSoAllowed()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo'));
+
+ $matcher = $this->getUrlMatcher($coll);
+ $this->assertInternalType('array', $matcher->match('/foo'));
+ }
+
+ public function testMethodNotAllowed()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo', array(), array(), array(), '', array(), array('post')));
+
+ $matcher = $this->getUrlMatcher($coll);
+
+ try {
+ $matcher->match('/foo');
+ $this->fail();
+ } catch (MethodNotAllowedException $e) {
+ $this->assertEquals(array('POST'), $e->getAllowedMethods());
+ }
+ }
+
+ public function testMethodNotAllowedOnRoot()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/', array(), array(), array(), '', array(), array('GET')));
+
+ $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'POST'));
+
+ try {
+ $matcher->match('/');
+ $this->fail();
+ } catch (MethodNotAllowedException $e) {
+ $this->assertEquals(array('GET'), $e->getAllowedMethods());
+ }
+ }
+
+ public function testHeadAllowedWhenRequirementContainsGet()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo', array(), array(), array(), '', array(), array('get')));
+
+ $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'head'));
+ $this->assertInternalType('array', $matcher->match('/foo'));
+ }
+
+ public function testMethodNotAllowedAggregatesAllowedMethods()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo1', new Route('/foo', array(), array(), array(), '', array(), array('post')));
+ $coll->add('foo2', new Route('/foo', array(), array(), array(), '', array(), array('put', 'delete')));
+
+ $matcher = $this->getUrlMatcher($coll);
+
+ try {
+ $matcher->match('/foo');
+ $this->fail();
+ } catch (MethodNotAllowedException $e) {
+ $this->assertEquals(array('POST', 'PUT', 'DELETE'), $e->getAllowedMethods());
+ }
+ }
+
+ public function testMatch()
+ {
+ // test the patterns are matched and parameters are returned
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/foo/{bar}'));
+ $matcher = $this->getUrlMatcher($collection);
+ try {
+ $matcher->match('/no-match');
+ $this->fail();
+ } catch (ResourceNotFoundException $e) {
+ }
+ $this->assertEquals(array('_route' => 'foo', 'bar' => 'baz'), $matcher->match('/foo/baz'));
+
+ // test that defaults are merged
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/foo/{bar}', array('def' => 'test')));
+ $matcher = $this->getUrlMatcher($collection);
+ $this->assertEquals(array('_route' => 'foo', 'bar' => 'baz', 'def' => 'test'), $matcher->match('/foo/baz'));
+
+ // test that route "method" is ignored if no method is given in the context
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/foo', array(), array(), array(), '', array(), array('get', 'head')));
+ $matcher = $this->getUrlMatcher($collection);
+ $this->assertInternalType('array', $matcher->match('/foo'));
+
+ // route does not match with POST method context
+ $matcher = $this->getUrlMatcher($collection, new RequestContext('', 'post'));
+ try {
+ $matcher->match('/foo');
+ $this->fail();
+ } catch (MethodNotAllowedException $e) {
+ }
+
+ // route does match with GET or HEAD method context
+ $matcher = $this->getUrlMatcher($collection);
+ $this->assertInternalType('array', $matcher->match('/foo'));
+ $matcher = $this->getUrlMatcher($collection, new RequestContext('', 'head'));
+ $this->assertInternalType('array', $matcher->match('/foo'));
+
+ // route with an optional variable as the first segment
+ $collection = new RouteCollection();
+ $collection->add('bar', new Route('/{bar}/foo', array('bar' => 'bar'), array('bar' => 'foo|bar')));
+ $matcher = $this->getUrlMatcher($collection);
+ $this->assertEquals(array('_route' => 'bar', 'bar' => 'bar'), $matcher->match('/bar/foo'));
+ $this->assertEquals(array('_route' => 'bar', 'bar' => 'foo'), $matcher->match('/foo/foo'));
+
+ $collection = new RouteCollection();
+ $collection->add('bar', new Route('/{bar}', array('bar' => 'bar'), array('bar' => 'foo|bar')));
+ $matcher = $this->getUrlMatcher($collection);
+ $this->assertEquals(array('_route' => 'bar', 'bar' => 'foo'), $matcher->match('/foo'));
+ $this->assertEquals(array('_route' => 'bar', 'bar' => 'bar'), $matcher->match('/'));
+
+ // route with only optional variables
+ $collection = new RouteCollection();
+ $collection->add('bar', new Route('/{foo}/{bar}', array('foo' => 'foo', 'bar' => 'bar'), array()));
+ $matcher = $this->getUrlMatcher($collection);
+ $this->assertEquals(array('_route' => 'bar', 'foo' => 'foo', 'bar' => 'bar'), $matcher->match('/'));
+ $this->assertEquals(array('_route' => 'bar', 'foo' => 'a', 'bar' => 'bar'), $matcher->match('/a'));
+ $this->assertEquals(array('_route' => 'bar', 'foo' => 'a', 'bar' => 'b'), $matcher->match('/a/b'));
+ }
+
+ public function testMatchWithPrefixes()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/{foo}'));
+ $collection->addPrefix('/b');
+ $collection->addPrefix('/a');
+
+ $matcher = $this->getUrlMatcher($collection);
+ $this->assertEquals(array('_route' => 'foo', 'foo' => 'foo'), $matcher->match('/a/b/foo'));
+ }
+
+ public function testMatchWithDynamicPrefix()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/{foo}'));
+ $collection->addPrefix('/b');
+ $collection->addPrefix('/{_locale}');
+
+ $matcher = $this->getUrlMatcher($collection);
+ $this->assertEquals(array('_locale' => 'fr', '_route' => 'foo', 'foo' => 'foo'), $matcher->match('/fr/b/foo'));
+ }
+
+ public function testMatchSpecialRouteName()
+ {
+ $collection = new RouteCollection();
+ $collection->add('$péß^a|', new Route('/bar'));
+
+ $matcher = $this->getUrlMatcher($collection);
+ $this->assertEquals(array('_route' => '$péß^a|'), $matcher->match('/bar'));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
+ */
+ public function testTrailingEncodedNewlineIsNotOverlooked()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/foo'));
+
+ $matcher = $this->getUrlMatcher($collection);
+ $matcher->match('/foo%0a');
+ }
+
+ public function testMatchNonAlpha()
+ {
+ $collection = new RouteCollection();
+ $chars = '!"$%éà &\'()*+,./:;<=>@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\[]^_`abcdefghijklmnopqrstuvwxyz{|}~-';
+ $collection->add('foo', new Route('/{foo}/bar', array(), array('foo' => '['.preg_quote($chars).']+'), array('utf8' => true)));
+
+ $matcher = $this->getUrlMatcher($collection);
+ $this->assertEquals(array('_route' => 'foo', 'foo' => $chars), $matcher->match('/'.rawurlencode($chars).'/bar'));
+ $this->assertEquals(array('_route' => 'foo', 'foo' => $chars), $matcher->match('/'.strtr($chars, array('%' => '%25')).'/bar'));
+ }
+
+ public function testMatchWithDotMetacharacterInRequirements()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/{foo}/bar', array(), array('foo' => '.+')));
+
+ $matcher = $this->getUrlMatcher($collection);
+ $this->assertEquals(array('_route' => 'foo', 'foo' => "\n"), $matcher->match('/'.urlencode("\n").'/bar'), 'linefeed character is matched');
+ }
+
+ public function testMatchOverriddenRoute()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/foo'));
+
+ $collection1 = new RouteCollection();
+ $collection1->add('foo', new Route('/foo1'));
+
+ $collection->addCollection($collection1);
+
+ $matcher = $this->getUrlMatcher($collection);
+
+ $this->assertEquals(array('_route' => 'foo'), $matcher->match('/foo1'));
+ $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('Symfony\Component\Routing\Exception\ResourceNotFoundException');
+ $this->assertEquals(array(), $matcher->match('/foo'));
+ }
+
+ public function testMatchRegression()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo/{foo}'));
+ $coll->add('bar', new Route('/foo/bar/{foo}'));
+
+ $matcher = $this->getUrlMatcher($coll);
+ $this->assertEquals(array('foo' => 'bar', '_route' => 'bar'), $matcher->match('/foo/bar/bar'));
+
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/{bar}'));
+ $matcher = $this->getUrlMatcher($collection);
+ try {
+ $matcher->match('/');
+ $this->fail();
+ } catch (ResourceNotFoundException $e) {
+ }
+ }
+
+ public function testDefaultRequirementForOptionalVariables()
+ {
+ $coll = new RouteCollection();
+ $coll->add('test', new Route('/{page}.{_format}', array('page' => 'index', '_format' => 'html')));
+
+ $matcher = $this->getUrlMatcher($coll);
+ $this->assertEquals(array('page' => 'my-page', '_format' => 'xml', '_route' => 'test'), $matcher->match('/my-page.xml'));
+ }
+
+ public function testMatchingIsEager()
+ {
+ $coll = new RouteCollection();
+ $coll->add('test', new Route('/{foo}-{bar}-', array(), array('foo' => '.+', 'bar' => '.+')));
+
+ $matcher = $this->getUrlMatcher($coll);
+ $this->assertEquals(array('foo' => 'text1-text2-text3', 'bar' => 'text4', '_route' => 'test'), $matcher->match('/text1-text2-text3-text4-'));
+ }
+
+ public function testAdjacentVariables()
+ {
+ $coll = new RouteCollection();
+ $coll->add('test', new Route('/{w}{x}{y}{z}.{_format}', array('z' => 'default-z', '_format' => 'html'), array('y' => 'y|Y')));
+
+ $matcher = $this->getUrlMatcher($coll);
+ // 'w' eagerly matches as much as possible and the other variables match the remaining chars.
+ // This also shows that the variables w-z must all exclude the separating char (the dot '.' in this case) by default requirement.
+ // Otherwise they would also consume '.xml' and _format would never match as it's an optional variable.
+ $this->assertEquals(array('w' => 'wwwww', 'x' => 'x', 'y' => 'Y', 'z' => 'Z', '_format' => 'xml', '_route' => 'test'), $matcher->match('/wwwwwxYZ.xml'));
+ // As 'y' has custom requirement and can only be of value 'y|Y', it will leave 'ZZZ' to variable z.
+ // So with carefully chosen requirements adjacent variables, can be useful.
+ $this->assertEquals(array('w' => 'wwwww', 'x' => 'x', 'y' => 'y', 'z' => 'ZZZ', '_format' => 'html', '_route' => 'test'), $matcher->match('/wwwwwxyZZZ'));
+ // z and _format are optional.
+ $this->assertEquals(array('w' => 'wwwww', 'x' => 'x', 'y' => 'y', 'z' => 'default-z', '_format' => 'html', '_route' => 'test'), $matcher->match('/wwwwwxy'));
+
+ $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('Symfony\Component\Routing\Exception\ResourceNotFoundException');
+ $matcher->match('/wxy.html');
+ }
+
+ public function testOptionalVariableWithNoRealSeparator()
+ {
+ $coll = new RouteCollection();
+ $coll->add('test', new Route('/get{what}', array('what' => 'All')));
+ $matcher = $this->getUrlMatcher($coll);
+
+ $this->assertEquals(array('what' => 'All', '_route' => 'test'), $matcher->match('/get'));
+ $this->assertEquals(array('what' => 'Sites', '_route' => 'test'), $matcher->match('/getSites'));
+
+ // Usually the character in front of an optional parameter can be left out, e.g. with pattern '/get/{what}' just '/get' would match.
+ // But here the 't' in 'get' is not a separating character, so it makes no sense to match without it.
+ $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('Symfony\Component\Routing\Exception\ResourceNotFoundException');
+ $matcher->match('/ge');
+ }
+
+ public function testRequiredVariableWithNoRealSeparator()
+ {
+ $coll = new RouteCollection();
+ $coll->add('test', new Route('/get{what}Suffix'));
+ $matcher = $this->getUrlMatcher($coll);
+
+ $this->assertEquals(array('what' => 'Sites', '_route' => 'test'), $matcher->match('/getSitesSuffix'));
+ }
+
+ public function testDefaultRequirementOfVariable()
+ {
+ $coll = new RouteCollection();
+ $coll->add('test', new Route('/{page}.{_format}'));
+ $matcher = $this->getUrlMatcher($coll);
+
+ $this->assertEquals(array('page' => 'index', '_format' => 'mobile.html', '_route' => 'test'), $matcher->match('/index.mobile.html'));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
+ */
+ public function testDefaultRequirementOfVariableDisallowsSlash()
+ {
+ $coll = new RouteCollection();
+ $coll->add('test', new Route('/{page}.{_format}'));
+ $matcher = $this->getUrlMatcher($coll);
+
+ $matcher->match('/index.sl/ash');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
+ */
+ public function testDefaultRequirementOfVariableDisallowsNextSeparator()
+ {
+ $coll = new RouteCollection();
+ $coll->add('test', new Route('/{page}.{_format}', array(), array('_format' => 'html|xml')));
+ $matcher = $this->getUrlMatcher($coll);
+
+ $matcher->match('/do.t.html');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
+ */
+ public function testSchemeRequirement()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo', array(), array(), array(), '', array('https')));
+ $matcher = $this->getUrlMatcher($coll);
+ $matcher->match('/foo');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
+ */
+ public function testCondition()
+ {
+ $coll = new RouteCollection();
+ $route = new Route('/foo');
+ $route->setCondition('context.getMethod() == "POST"');
+ $coll->add('foo', $route);
+ $matcher = $this->getUrlMatcher($coll);
+ $matcher->match('/foo');
+ }
+
+ public function testRequestCondition()
+ {
+ $coll = new RouteCollection();
+ $route = new Route('/foo/{bar}');
+ $route->setCondition('request.getBaseUrl() == "/sub/front.php" and request.getPathInfo() == "/foo/bar"');
+ $coll->add('foo', $route);
+ $matcher = $this->getUrlMatcher($coll, new RequestContext('/sub/front.php'));
+ $this->assertEquals(array('bar' => 'bar', '_route' => 'foo'), $matcher->match('/foo/bar'));
+ }
+
+ public function testDecodeOnce()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo/{foo}'));
+
+ $matcher = $this->getUrlMatcher($coll);
+ $this->assertEquals(array('foo' => 'bar%23', '_route' => 'foo'), $matcher->match('/foo/bar%2523'));
+ }
+
+ public function testCannotRelyOnPrefix()
+ {
+ $coll = new RouteCollection();
+
+ $subColl = new RouteCollection();
+ $subColl->add('bar', new Route('/bar'));
+ $subColl->addPrefix('/prefix');
+ // overwrite the pattern, so the prefix is not valid anymore for this route in the collection
+ $subColl->get('bar')->setPath('/new');
+
+ $coll->addCollection($subColl);
+
+ $matcher = $this->getUrlMatcher($coll);
+ $this->assertEquals(array('_route' => 'bar'), $matcher->match('/new'));
+ }
+
+ public function testWithHost()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo/{foo}', array(), array(), array(), '{locale}.example.com'));
+
+ $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'en.example.com'));
+ $this->assertEquals(array('foo' => 'bar', '_route' => 'foo', 'locale' => 'en'), $matcher->match('/foo/bar'));
+ }
+
+ public function testWithHostOnRouteCollection()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo/{foo}'));
+ $coll->add('bar', new Route('/bar/{foo}', array(), array(), array(), '{locale}.example.net'));
+ $coll->setHost('{locale}.example.com');
+
+ $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'en.example.com'));
+ $this->assertEquals(array('foo' => 'bar', '_route' => 'foo', 'locale' => 'en'), $matcher->match('/foo/bar'));
+
+ $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'en.example.com'));
+ $this->assertEquals(array('foo' => 'bar', '_route' => 'bar', 'locale' => 'en'), $matcher->match('/bar/bar'));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
+ */
+ public function testWithOutHostHostDoesNotMatch()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo/{foo}', array(), array(), array(), '{locale}.example.com'));
+
+ $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'example.com'));
+ $matcher->match('/foo/bar');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
+ */
+ public function testPathIsCaseSensitive()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/locale', array(), array('locale' => 'EN|FR|DE')));
+
+ $matcher = $this->getUrlMatcher($coll);
+ $matcher->match('/en');
+ }
+
+ public function testHostIsCaseInsensitive()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/', array(), array('locale' => 'EN|FR|DE'), array(), '{locale}.example.com'));
+
+ $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'en.example.com'));
+ $this->assertEquals(array('_route' => 'foo', 'locale' => 'en'), $matcher->match('/'));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\NoConfigurationException
+ */
+ public function testNoConfiguration()
+ {
+ $coll = new RouteCollection();
+
+ $matcher = $this->getUrlMatcher($coll);
+ $matcher->match('/');
+ }
+
+ public function testNestedCollections()
+ {
+ $coll = new RouteCollection();
+
+ $subColl = new RouteCollection();
+ $subColl->add('a', new Route('/a'));
+ $subColl->add('b', new Route('/b'));
+ $subColl->add('c', new Route('/c'));
+ $subColl->addPrefix('/p');
+ $coll->addCollection($subColl);
+
+ $coll->add('baz', new Route('/{baz}'));
+
+ $subColl = new RouteCollection();
+ $subColl->add('buz', new Route('/buz'));
+ $subColl->addPrefix('/prefix');
+ $coll->addCollection($subColl);
+
+ $matcher = $this->getUrlMatcher($coll);
+ $this->assertEquals(array('_route' => 'a'), $matcher->match('/p/a'));
+ $this->assertEquals(array('_route' => 'baz', 'baz' => 'p'), $matcher->match('/p'));
+ $this->assertEquals(array('_route' => 'buz'), $matcher->match('/prefix/buz'));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
+ */
+ public function testSchemeAndMethodMismatch()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/', array(), array(), array(), null, array('https'), array('POST')));
+
+ $matcher = $this->getUrlMatcher($coll);
+ $matcher->match('/');
+ }
+
+ protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null)
+ {
+ return new UrlMatcher($routes, $context ?: new RequestContext());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/RequestContextTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/RequestContextTest.php
new file mode 100644
index 0000000..ffe29d1
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/RequestContextTest.php
@@ -0,0 +1,160 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Routing\RequestContext;
+
+class RequestContextTest extends TestCase
+{
+ public function testConstruct()
+ {
+ $requestContext = new RequestContext(
+ 'foo',
+ 'post',
+ 'foo.bar',
+ 'HTTPS',
+ 8080,
+ 444,
+ '/baz',
+ 'bar=foobar'
+ );
+
+ $this->assertEquals('foo', $requestContext->getBaseUrl());
+ $this->assertEquals('POST', $requestContext->getMethod());
+ $this->assertEquals('foo.bar', $requestContext->getHost());
+ $this->assertEquals('https', $requestContext->getScheme());
+ $this->assertSame(8080, $requestContext->getHttpPort());
+ $this->assertSame(444, $requestContext->getHttpsPort());
+ $this->assertEquals('/baz', $requestContext->getPathInfo());
+ $this->assertEquals('bar=foobar', $requestContext->getQueryString());
+ }
+
+ public function testFromRequest()
+ {
+ $request = Request::create('https://test.com:444/foo?bar=baz');
+ $requestContext = new RequestContext();
+ $requestContext->setHttpPort(123);
+ $requestContext->fromRequest($request);
+
+ $this->assertEquals('', $requestContext->getBaseUrl());
+ $this->assertEquals('GET', $requestContext->getMethod());
+ $this->assertEquals('test.com', $requestContext->getHost());
+ $this->assertEquals('https', $requestContext->getScheme());
+ $this->assertEquals('/foo', $requestContext->getPathInfo());
+ $this->assertEquals('bar=baz', $requestContext->getQueryString());
+ $this->assertSame(123, $requestContext->getHttpPort());
+ $this->assertSame(444, $requestContext->getHttpsPort());
+
+ $request = Request::create('http://test.com:8080/foo?bar=baz');
+ $requestContext = new RequestContext();
+ $requestContext->setHttpsPort(567);
+ $requestContext->fromRequest($request);
+
+ $this->assertSame(8080, $requestContext->getHttpPort());
+ $this->assertSame(567, $requestContext->getHttpsPort());
+ }
+
+ public function testGetParameters()
+ {
+ $requestContext = new RequestContext();
+ $this->assertEquals(array(), $requestContext->getParameters());
+
+ $requestContext->setParameters(array('foo' => 'bar'));
+ $this->assertEquals(array('foo' => 'bar'), $requestContext->getParameters());
+ }
+
+ public function testHasParameter()
+ {
+ $requestContext = new RequestContext();
+ $requestContext->setParameters(array('foo' => 'bar'));
+
+ $this->assertTrue($requestContext->hasParameter('foo'));
+ $this->assertFalse($requestContext->hasParameter('baz'));
+ }
+
+ public function testGetParameter()
+ {
+ $requestContext = new RequestContext();
+ $requestContext->setParameters(array('foo' => 'bar'));
+
+ $this->assertEquals('bar', $requestContext->getParameter('foo'));
+ $this->assertNull($requestContext->getParameter('baz'));
+ }
+
+ public function testSetParameter()
+ {
+ $requestContext = new RequestContext();
+ $requestContext->setParameter('foo', 'bar');
+
+ $this->assertEquals('bar', $requestContext->getParameter('foo'));
+ }
+
+ public function testMethod()
+ {
+ $requestContext = new RequestContext();
+ $requestContext->setMethod('post');
+
+ $this->assertSame('POST', $requestContext->getMethod());
+ }
+
+ public function testScheme()
+ {
+ $requestContext = new RequestContext();
+ $requestContext->setScheme('HTTPS');
+
+ $this->assertSame('https', $requestContext->getScheme());
+ }
+
+ public function testHost()
+ {
+ $requestContext = new RequestContext();
+ $requestContext->setHost('eXampLe.com');
+
+ $this->assertSame('example.com', $requestContext->getHost());
+ }
+
+ public function testQueryString()
+ {
+ $requestContext = new RequestContext();
+ $requestContext->setQueryString(null);
+
+ $this->assertSame('', $requestContext->getQueryString());
+ }
+
+ public function testPort()
+ {
+ $requestContext = new RequestContext();
+ $requestContext->setHttpPort('123');
+ $requestContext->setHttpsPort('456');
+
+ $this->assertSame(123, $requestContext->getHttpPort());
+ $this->assertSame(456, $requestContext->getHttpsPort());
+ }
+
+ public function testFluentInterface()
+ {
+ $requestContext = new RequestContext();
+
+ $this->assertSame($requestContext, $requestContext->setBaseUrl('/app.php'));
+ $this->assertSame($requestContext, $requestContext->setPathInfo('/index'));
+ $this->assertSame($requestContext, $requestContext->setMethod('POST'));
+ $this->assertSame($requestContext, $requestContext->setScheme('https'));
+ $this->assertSame($requestContext, $requestContext->setHost('example.com'));
+ $this->assertSame($requestContext, $requestContext->setQueryString('foo=bar'));
+ $this->assertSame($requestContext, $requestContext->setHttpPort(80));
+ $this->assertSame($requestContext, $requestContext->setHttpsPort(443));
+ $this->assertSame($requestContext, $requestContext->setParameters(array()));
+ $this->assertSame($requestContext, $requestContext->setParameter('foo', 'bar'));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/RouteCollectionBuilderTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/RouteCollectionBuilderTest.php
new file mode 100644
index 0000000..76a042d
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/RouteCollectionBuilderTest.php
@@ -0,0 +1,364 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Config\FileLocator;
+use Symfony\Component\Config\Resource\FileResource;
+use Symfony\Component\Routing\Loader\YamlFileLoader;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\RouteCollectionBuilder;
+
+class RouteCollectionBuilderTest extends TestCase
+{
+ public function testImport()
+ {
+ $resolvedLoader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
+ $resolver = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderResolverInterface')->getMock();
+ $resolver->expects($this->once())
+ ->method('resolve')
+ ->with('admin_routing.yml', 'yaml')
+ ->will($this->returnValue($resolvedLoader));
+
+ $originalRoute = new Route('/foo/path');
+ $expectedCollection = new RouteCollection();
+ $expectedCollection->add('one_test_route', $originalRoute);
+ $expectedCollection->addResource(new FileResource(__DIR__.'/Fixtures/file_resource.yml'));
+
+ $resolvedLoader
+ ->expects($this->once())
+ ->method('load')
+ ->with('admin_routing.yml', 'yaml')
+ ->will($this->returnValue($expectedCollection));
+
+ $loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
+ $loader->expects($this->any())
+ ->method('getResolver')
+ ->will($this->returnValue($resolver));
+
+ // import the file!
+ $routes = new RouteCollectionBuilder($loader);
+ $importedRoutes = $routes->import('admin_routing.yml', '/', 'yaml');
+
+ // we should get back a RouteCollectionBuilder
+ $this->assertInstanceOf('Symfony\Component\Routing\RouteCollectionBuilder', $importedRoutes);
+
+ // get the collection back so we can look at it
+ $addedCollection = $importedRoutes->build();
+ $route = $addedCollection->get('one_test_route');
+ $this->assertSame($originalRoute, $route);
+ // should return file_resource.yml, which is in the original collection
+ $this->assertCount(1, $addedCollection->getResources());
+
+ // make sure the routes were imported into the top-level builder
+ $routeCollection = $routes->build();
+ $this->assertCount(1, $routes->build());
+ $this->assertCount(1, $routeCollection->getResources());
+ }
+
+ public function testImportAddResources()
+ {
+ $routeCollectionBuilder = new RouteCollectionBuilder(new YamlFileLoader(new FileLocator(array(__DIR__.'/Fixtures/'))));
+ $routeCollectionBuilder->import('file_resource.yml');
+ $routeCollection = $routeCollectionBuilder->build();
+
+ $this->assertCount(1, $routeCollection->getResources());
+ }
+
+ /**
+ * @expectedException \BadMethodCallException
+ */
+ public function testImportWithoutLoaderThrowsException()
+ {
+ $collectionBuilder = new RouteCollectionBuilder();
+ $collectionBuilder->import('routing.yml');
+ }
+
+ public function testAdd()
+ {
+ $collectionBuilder = new RouteCollectionBuilder();
+
+ $addedRoute = $collectionBuilder->add('/checkout', 'AppBundle:Order:checkout');
+ $addedRoute2 = $collectionBuilder->add('/blogs', 'AppBundle:Blog:list', 'blog_list');
+ $this->assertInstanceOf('Symfony\Component\Routing\Route', $addedRoute);
+ $this->assertEquals('AppBundle:Order:checkout', $addedRoute->getDefault('_controller'));
+
+ $finalCollection = $collectionBuilder->build();
+ $this->assertSame($addedRoute2, $finalCollection->get('blog_list'));
+ }
+
+ public function testFlushOrdering()
+ {
+ $importedCollection = new RouteCollection();
+ $importedCollection->add('imported_route1', new Route('/imported/foo1'));
+ $importedCollection->add('imported_route2', new Route('/imported/foo2'));
+
+ $loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
+ // make this loader able to do the import - keeps mocking simple
+ $loader->expects($this->any())
+ ->method('supports')
+ ->will($this->returnValue(true));
+ $loader
+ ->expects($this->once())
+ ->method('load')
+ ->will($this->returnValue($importedCollection));
+
+ $routes = new RouteCollectionBuilder($loader);
+
+ // 1) Add a route
+ $routes->add('/checkout', 'AppBundle:Order:checkout', 'checkout_route');
+ // 2) Import from a file
+ $routes->mount('/', $routes->import('admin_routing.yml'));
+ // 3) Add another route
+ $routes->add('/', 'AppBundle:Default:homepage', 'homepage');
+ // 4) Add another route
+ $routes->add('/admin', 'AppBundle:Admin:dashboard', 'admin_dashboard');
+
+ // set a default value
+ $routes->setDefault('_locale', 'fr');
+
+ $actualCollection = $routes->build();
+
+ $this->assertCount(5, $actualCollection);
+ $actualRouteNames = array_keys($actualCollection->all());
+ $this->assertEquals(array(
+ 'checkout_route',
+ 'imported_route1',
+ 'imported_route2',
+ 'homepage',
+ 'admin_dashboard',
+ ), $actualRouteNames);
+
+ // make sure the defaults were set
+ $checkoutRoute = $actualCollection->get('checkout_route');
+ $defaults = $checkoutRoute->getDefaults();
+ $this->assertArrayHasKey('_locale', $defaults);
+ $this->assertEquals('fr', $defaults['_locale']);
+ }
+
+ public function testFlushSetsRouteNames()
+ {
+ $collectionBuilder = new RouteCollectionBuilder();
+
+ // add a "named" route
+ $collectionBuilder->add('/admin', 'AppBundle:Admin:dashboard', 'admin_dashboard');
+ // add an unnamed route
+ $collectionBuilder->add('/blogs', 'AppBundle:Blog:list')
+ ->setMethods(array('GET'));
+
+ // integer route names are allowed - they don't confuse things
+ $collectionBuilder->add('/products', 'AppBundle:Product:list', 100);
+
+ $actualCollection = $collectionBuilder->build();
+ $actualRouteNames = array_keys($actualCollection->all());
+ $this->assertEquals(array(
+ 'admin_dashboard',
+ 'GET_blogs',
+ '100',
+ ), $actualRouteNames);
+ }
+
+ public function testFlushSetsDetailsOnChildrenRoutes()
+ {
+ $routes = new RouteCollectionBuilder();
+
+ $routes->add('/blogs/{page}', 'listAction', 'blog_list')
+ // unique things for the route
+ ->setDefault('page', 1)
+ ->setRequirement('id', '\d+')
+ ->setOption('expose', true)
+ // things that the collection will try to override (but won't)
+ ->setDefault('_format', 'html')
+ ->setRequirement('_format', 'json|xml')
+ ->setOption('fooBar', true)
+ ->setHost('example.com')
+ ->setCondition('request.isSecure()')
+ ->setSchemes(array('https'))
+ ->setMethods(array('POST'));
+
+ // a simple route, nothing added to it
+ $routes->add('/blogs/{id}', 'editAction', 'blog_edit');
+
+ // configure the collection itself
+ $routes
+ // things that will not override the child route
+ ->setDefault('_format', 'json')
+ ->setRequirement('_format', 'xml')
+ ->setOption('fooBar', false)
+ ->setHost('symfony.com')
+ ->setCondition('request.query.get("page")==1')
+ // some unique things that should be set on the child
+ ->setDefault('_locale', 'fr')
+ ->setRequirement('_locale', 'fr|en')
+ ->setOption('niceRoute', true)
+ ->setSchemes(array('http'))
+ ->setMethods(array('GET', 'POST'));
+
+ $collection = $routes->build();
+ $actualListRoute = $collection->get('blog_list');
+
+ $this->assertEquals(1, $actualListRoute->getDefault('page'));
+ $this->assertEquals('\d+', $actualListRoute->getRequirement('id'));
+ $this->assertTrue($actualListRoute->getOption('expose'));
+ // none of these should be overridden
+ $this->assertEquals('html', $actualListRoute->getDefault('_format'));
+ $this->assertEquals('json|xml', $actualListRoute->getRequirement('_format'));
+ $this->assertTrue($actualListRoute->getOption('fooBar'));
+ $this->assertEquals('example.com', $actualListRoute->getHost());
+ $this->assertEquals('request.isSecure()', $actualListRoute->getCondition());
+ $this->assertEquals(array('https'), $actualListRoute->getSchemes());
+ $this->assertEquals(array('POST'), $actualListRoute->getMethods());
+ // inherited from the main collection
+ $this->assertEquals('fr', $actualListRoute->getDefault('_locale'));
+ $this->assertEquals('fr|en', $actualListRoute->getRequirement('_locale'));
+ $this->assertTrue($actualListRoute->getOption('niceRoute'));
+
+ $actualEditRoute = $collection->get('blog_edit');
+ // inherited from the collection
+ $this->assertEquals('symfony.com', $actualEditRoute->getHost());
+ $this->assertEquals('request.query.get("page")==1', $actualEditRoute->getCondition());
+ $this->assertEquals(array('http'), $actualEditRoute->getSchemes());
+ $this->assertEquals(array('GET', 'POST'), $actualEditRoute->getMethods());
+ }
+
+ /**
+ * @dataProvider providePrefixTests
+ */
+ public function testFlushPrefixesPaths($collectionPrefix, $routePath, $expectedPath)
+ {
+ $routes = new RouteCollectionBuilder();
+
+ $routes->add($routePath, 'someController', 'test_route');
+
+ $outerRoutes = new RouteCollectionBuilder();
+ $outerRoutes->mount($collectionPrefix, $routes);
+
+ $collection = $outerRoutes->build();
+
+ $this->assertEquals($expectedPath, $collection->get('test_route')->getPath());
+ }
+
+ public function providePrefixTests()
+ {
+ $tests = array();
+ // empty prefix is of course ok
+ $tests[] = array('', '/foo', '/foo');
+ // normal prefix - does not matter if it's a wildcard
+ $tests[] = array('/{admin}', '/foo', '/{admin}/foo');
+ // shows that a prefix will always be given the starting slash
+ $tests[] = array('0', '/foo', '/0/foo');
+
+ // spaces are ok, and double slahses at the end are cleaned
+ $tests[] = array('/ /', '/foo', '/ /foo');
+
+ return $tests;
+ }
+
+ public function testFlushSetsPrefixedWithMultipleLevels()
+ {
+ $loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
+ $routes = new RouteCollectionBuilder($loader);
+
+ $routes->add('homepage', 'MainController::homepageAction', 'homepage');
+
+ $adminRoutes = $routes->createBuilder();
+ $adminRoutes->add('/dashboard', 'AdminController::dashboardAction', 'admin_dashboard');
+
+ // embedded collection under /admin
+ $adminBlogRoutes = $routes->createBuilder();
+ $adminBlogRoutes->add('/new', 'BlogController::newAction', 'admin_blog_new');
+ // mount into admin, but before the parent collection has been mounted
+ $adminRoutes->mount('/blog', $adminBlogRoutes);
+
+ // now mount the /admin routes, above should all still be /blog/admin
+ $routes->mount('/admin', $adminRoutes);
+ // add a route after mounting
+ $adminRoutes->add('/users', 'AdminController::userAction', 'admin_users');
+
+ // add another sub-collection after the mount
+ $otherAdminRoutes = $routes->createBuilder();
+ $otherAdminRoutes->add('/sales', 'StatsController::indexAction', 'admin_stats_sales');
+ $adminRoutes->mount('/stats', $otherAdminRoutes);
+
+ // add a normal collection and see that it is also prefixed
+ $importedCollection = new RouteCollection();
+ $importedCollection->add('imported_route', new Route('/foo'));
+ // make this loader able to do the import - keeps mocking simple
+ $loader->expects($this->any())
+ ->method('supports')
+ ->will($this->returnValue(true));
+ $loader
+ ->expects($this->any())
+ ->method('load')
+ ->will($this->returnValue($importedCollection));
+ // import this from the /admin route builder
+ $adminRoutes->import('admin.yml', '/imported');
+
+ $collection = $routes->build();
+ $this->assertEquals('/admin/dashboard', $collection->get('admin_dashboard')->getPath(), 'Routes before mounting have the prefix');
+ $this->assertEquals('/admin/users', $collection->get('admin_users')->getPath(), 'Routes after mounting have the prefix');
+ $this->assertEquals('/admin/blog/new', $collection->get('admin_blog_new')->getPath(), 'Sub-collections receive prefix even if mounted before parent prefix');
+ $this->assertEquals('/admin/stats/sales', $collection->get('admin_stats_sales')->getPath(), 'Sub-collections receive prefix if mounted after parent prefix');
+ $this->assertEquals('/admin/imported/foo', $collection->get('imported_route')->getPath(), 'Normal RouteCollections are also prefixed properly');
+ }
+
+ public function testAutomaticRouteNamesDoNotConflict()
+ {
+ $routes = new RouteCollectionBuilder();
+
+ $adminRoutes = $routes->createBuilder();
+ // route 1
+ $adminRoutes->add('/dashboard', '');
+
+ $accountRoutes = $routes->createBuilder();
+ // route 2
+ $accountRoutes->add('/dashboard', '')
+ ->setMethods(array('GET'));
+ // route 3
+ $accountRoutes->add('/dashboard', '')
+ ->setMethods(array('POST'));
+
+ $routes->mount('/admin', $adminRoutes);
+ $routes->mount('/account', $accountRoutes);
+
+ $collection = $routes->build();
+ // there are 2 routes (i.e. with non-conflicting names)
+ $this->assertCount(3, $collection->all());
+ }
+
+ public function testAddsThePrefixOnlyOnceWhenLoadingMultipleCollections()
+ {
+ $firstCollection = new RouteCollection();
+ $firstCollection->add('a', new Route('/a'));
+
+ $secondCollection = new RouteCollection();
+ $secondCollection->add('b', new Route('/b'));
+
+ $loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
+ $loader->expects($this->any())
+ ->method('supports')
+ ->will($this->returnValue(true));
+ $loader
+ ->expects($this->any())
+ ->method('load')
+ ->will($this->returnValue(array($firstCollection, $secondCollection)));
+
+ $routeCollectionBuilder = new RouteCollectionBuilder($loader);
+ $routeCollectionBuilder->import('/directory/recurse/*', '/other/', 'glob');
+ $routes = $routeCollectionBuilder->build()->all();
+
+ $this->assertCount(2, $routes);
+ $this->assertEquals('/other/a', $routes['a']->getPath());
+ $this->assertEquals('/other/b', $routes['b']->getPath());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/RouteCollectionTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/RouteCollectionTest.php
new file mode 100644
index 0000000..83457ff
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/RouteCollectionTest.php
@@ -0,0 +1,305 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Config\Resource\FileResource;
+
+class RouteCollectionTest extends TestCase
+{
+ public function testRoute()
+ {
+ $collection = new RouteCollection();
+ $route = new Route('/foo');
+ $collection->add('foo', $route);
+ $this->assertEquals(array('foo' => $route), $collection->all(), '->add() adds a route');
+ $this->assertEquals($route, $collection->get('foo'), '->get() returns a route by name');
+ $this->assertNull($collection->get('bar'), '->get() returns null if a route does not exist');
+ }
+
+ public function testOverriddenRoute()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/foo'));
+ $collection->add('foo', new Route('/foo1'));
+
+ $this->assertEquals('/foo1', $collection->get('foo')->getPath());
+ }
+
+ public function testDeepOverriddenRoute()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/foo'));
+
+ $collection1 = new RouteCollection();
+ $collection1->add('foo', new Route('/foo1'));
+
+ $collection2 = new RouteCollection();
+ $collection2->add('foo', new Route('/foo2'));
+
+ $collection1->addCollection($collection2);
+ $collection->addCollection($collection1);
+
+ $this->assertEquals('/foo2', $collection1->get('foo')->getPath());
+ $this->assertEquals('/foo2', $collection->get('foo')->getPath());
+ }
+
+ public function testIterator()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/foo'));
+
+ $collection1 = new RouteCollection();
+ $collection1->add('bar', $bar = new Route('/bar'));
+ $collection1->add('foo', $foo = new Route('/foo-new'));
+ $collection->addCollection($collection1);
+ $collection->add('last', $last = new Route('/last'));
+
+ $this->assertInstanceOf('\ArrayIterator', $collection->getIterator());
+ $this->assertSame(array('bar' => $bar, 'foo' => $foo, 'last' => $last), $collection->getIterator()->getArrayCopy());
+ }
+
+ public function testCount()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/foo'));
+
+ $collection1 = new RouteCollection();
+ $collection1->add('bar', new Route('/bar'));
+ $collection->addCollection($collection1);
+
+ $this->assertCount(2, $collection);
+ }
+
+ public function testAddCollection()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/foo'));
+
+ $collection1 = new RouteCollection();
+ $collection1->add('bar', $bar = new Route('/bar'));
+ $collection1->add('foo', $foo = new Route('/foo-new'));
+
+ $collection2 = new RouteCollection();
+ $collection2->add('grandchild', $grandchild = new Route('/grandchild'));
+
+ $collection1->addCollection($collection2);
+ $collection->addCollection($collection1);
+ $collection->add('last', $last = new Route('/last'));
+
+ $this->assertSame(array('bar' => $bar, 'foo' => $foo, 'grandchild' => $grandchild, 'last' => $last), $collection->all(),
+ '->addCollection() imports routes of another collection, overrides if necessary and adds them at the end');
+ }
+
+ public function testAddCollectionWithResources()
+ {
+ $collection = new RouteCollection();
+ $collection->addResource($foo = new FileResource(__DIR__.'/Fixtures/foo.xml'));
+ $collection1 = new RouteCollection();
+ $collection1->addResource($foo1 = new FileResource(__DIR__.'/Fixtures/foo1.xml'));
+ $collection->addCollection($collection1);
+ $this->assertEquals(array($foo, $foo1), $collection->getResources(), '->addCollection() merges resources');
+ }
+
+ public function testAddDefaultsAndRequirementsAndOptions()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', new Route('/{placeholder}'));
+ $collection1 = new RouteCollection();
+ $collection1->add('bar', new Route('/{placeholder}',
+ array('_controller' => 'fixed', 'placeholder' => 'default'), array('placeholder' => '.+'), array('option' => 'value'))
+ );
+ $collection->addCollection($collection1);
+
+ $collection->addDefaults(array('placeholder' => 'new-default'));
+ $this->assertEquals(array('placeholder' => 'new-default'), $collection->get('foo')->getDefaults(), '->addDefaults() adds defaults to all routes');
+ $this->assertEquals(array('_controller' => 'fixed', 'placeholder' => 'new-default'), $collection->get('bar')->getDefaults(),
+ '->addDefaults() adds defaults to all routes and overwrites existing ones');
+
+ $collection->addRequirements(array('placeholder' => '\d+'));
+ $this->assertEquals(array('placeholder' => '\d+'), $collection->get('foo')->getRequirements(), '->addRequirements() adds requirements to all routes');
+ $this->assertEquals(array('placeholder' => '\d+'), $collection->get('bar')->getRequirements(),
+ '->addRequirements() adds requirements to all routes and overwrites existing ones');
+
+ $collection->addOptions(array('option' => 'new-value'));
+ $this->assertEquals(
+ array('option' => 'new-value', 'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler'),
+ $collection->get('bar')->getOptions(), '->addOptions() adds options to all routes and overwrites existing ones'
+ );
+ }
+
+ public function testAddPrefix()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', $foo = new Route('/foo'));
+ $collection2 = new RouteCollection();
+ $collection2->add('bar', $bar = new Route('/bar'));
+ $collection->addCollection($collection2);
+ $collection->addPrefix(' / ');
+ $this->assertSame('/foo', $collection->get('foo')->getPath(), '->addPrefix() trims the prefix and a single slash has no effect');
+ $collection->addPrefix('/{admin}', array('admin' => 'admin'), array('admin' => '\d+'));
+ $this->assertEquals('/{admin}/foo', $collection->get('foo')->getPath(), '->addPrefix() adds a prefix to all routes');
+ $this->assertEquals('/{admin}/bar', $collection->get('bar')->getPath(), '->addPrefix() adds a prefix to all routes');
+ $this->assertEquals(array('admin' => 'admin'), $collection->get('foo')->getDefaults(), '->addPrefix() adds defaults to all routes');
+ $this->assertEquals(array('admin' => 'admin'), $collection->get('bar')->getDefaults(), '->addPrefix() adds defaults to all routes');
+ $this->assertEquals(array('admin' => '\d+'), $collection->get('foo')->getRequirements(), '->addPrefix() adds requirements to all routes');
+ $this->assertEquals(array('admin' => '\d+'), $collection->get('bar')->getRequirements(), '->addPrefix() adds requirements to all routes');
+ $collection->addPrefix('0');
+ $this->assertEquals('/0/{admin}/foo', $collection->get('foo')->getPath(), '->addPrefix() ensures a prefix must start with a slash and must not end with a slash');
+ $collection->addPrefix('/ /');
+ $this->assertSame('/ /0/{admin}/foo', $collection->get('foo')->getPath(), '->addPrefix() can handle spaces if desired');
+ $this->assertSame('/ /0/{admin}/bar', $collection->get('bar')->getPath(), 'the route pattern of an added collection is in synch with the added prefix');
+ }
+
+ public function testAddPrefixOverridesDefaultsAndRequirements()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', $foo = new Route('/foo.{_format}'));
+ $collection->add('bar', $bar = new Route('/bar.{_format}', array(), array('_format' => 'json')));
+ $collection->addPrefix('/admin', array(), array('_format' => 'html'));
+
+ $this->assertEquals('html', $collection->get('foo')->getRequirement('_format'), '->addPrefix() overrides existing requirements');
+ $this->assertEquals('html', $collection->get('bar')->getRequirement('_format'), '->addPrefix() overrides existing requirements');
+ }
+
+ public function testResource()
+ {
+ $collection = new RouteCollection();
+ $collection->addResource($foo = new FileResource(__DIR__.'/Fixtures/foo.xml'));
+ $collection->addResource($bar = new FileResource(__DIR__.'/Fixtures/bar.xml'));
+ $collection->addResource(new FileResource(__DIR__.'/Fixtures/foo.xml'));
+
+ $this->assertEquals(array($foo, $bar), $collection->getResources(),
+ '->addResource() adds a resource and getResources() only returns unique ones by comparing the string representation');
+ }
+
+ public function testUniqueRouteWithGivenName()
+ {
+ $collection1 = new RouteCollection();
+ $collection1->add('foo', new Route('/old'));
+ $collection2 = new RouteCollection();
+ $collection3 = new RouteCollection();
+ $collection3->add('foo', $new = new Route('/new'));
+
+ $collection2->addCollection($collection3);
+ $collection1->addCollection($collection2);
+
+ $this->assertSame($new, $collection1->get('foo'), '->get() returns new route that overrode previous one');
+ // size of 1 because collection1 contains /new but not /old anymore
+ $this->assertCount(1, $collection1->getIterator(), '->addCollection() removes previous routes when adding new routes with the same name');
+ }
+
+ public function testGet()
+ {
+ $collection1 = new RouteCollection();
+ $collection1->add('a', $a = new Route('/a'));
+ $collection2 = new RouteCollection();
+ $collection2->add('b', $b = new Route('/b'));
+ $collection1->addCollection($collection2);
+ $collection1->add('$péß^a|', $c = new Route('/special'));
+
+ $this->assertSame($b, $collection1->get('b'), '->get() returns correct route in child collection');
+ $this->assertSame($c, $collection1->get('$péß^a|'), '->get() can handle special characters');
+ $this->assertNull($collection2->get('a'), '->get() does not return the route defined in parent collection');
+ $this->assertNull($collection1->get('non-existent'), '->get() returns null when route does not exist');
+ $this->assertNull($collection1->get(0), '->get() does not disclose internal child RouteCollection');
+ }
+
+ public function testRemove()
+ {
+ $collection = new RouteCollection();
+ $collection->add('foo', $foo = new Route('/foo'));
+
+ $collection1 = new RouteCollection();
+ $collection1->add('bar', $bar = new Route('/bar'));
+ $collection->addCollection($collection1);
+ $collection->add('last', $last = new Route('/last'));
+
+ $collection->remove('foo');
+ $this->assertSame(array('bar' => $bar, 'last' => $last), $collection->all(), '->remove() can remove a single route');
+ $collection->remove(array('bar', 'last'));
+ $this->assertSame(array(), $collection->all(), '->remove() accepts an array and can remove multiple routes at once');
+ }
+
+ public function testSetHost()
+ {
+ $collection = new RouteCollection();
+ $routea = new Route('/a');
+ $routeb = new Route('/b', array(), array(), array(), '{locale}.example.net');
+ $collection->add('a', $routea);
+ $collection->add('b', $routeb);
+
+ $collection->setHost('{locale}.example.com');
+
+ $this->assertEquals('{locale}.example.com', $routea->getHost());
+ $this->assertEquals('{locale}.example.com', $routeb->getHost());
+ }
+
+ public function testSetCondition()
+ {
+ $collection = new RouteCollection();
+ $routea = new Route('/a');
+ $routeb = new Route('/b', array(), array(), array(), '{locale}.example.net', array(), array(), 'context.getMethod() == "GET"');
+ $collection->add('a', $routea);
+ $collection->add('b', $routeb);
+
+ $collection->setCondition('context.getMethod() == "POST"');
+
+ $this->assertEquals('context.getMethod() == "POST"', $routea->getCondition());
+ $this->assertEquals('context.getMethod() == "POST"', $routeb->getCondition());
+ }
+
+ public function testClone()
+ {
+ $collection = new RouteCollection();
+ $collection->add('a', new Route('/a'));
+ $collection->add('b', new Route('/b', array('placeholder' => 'default'), array('placeholder' => '.+')));
+
+ $clonedCollection = clone $collection;
+
+ $this->assertCount(2, $clonedCollection);
+ $this->assertEquals($collection->get('a'), $clonedCollection->get('a'));
+ $this->assertNotSame($collection->get('a'), $clonedCollection->get('a'));
+ $this->assertEquals($collection->get('b'), $clonedCollection->get('b'));
+ $this->assertNotSame($collection->get('b'), $clonedCollection->get('b'));
+ }
+
+ public function testSetSchemes()
+ {
+ $collection = new RouteCollection();
+ $routea = new Route('/a', array(), array(), array(), '', 'http');
+ $routeb = new Route('/b');
+ $collection->add('a', $routea);
+ $collection->add('b', $routeb);
+
+ $collection->setSchemes(array('http', 'https'));
+
+ $this->assertEquals(array('http', 'https'), $routea->getSchemes());
+ $this->assertEquals(array('http', 'https'), $routeb->getSchemes());
+ }
+
+ public function testSetMethods()
+ {
+ $collection = new RouteCollection();
+ $routea = new Route('/a', array(), array(), array(), '', array(), array('GET', 'POST'));
+ $routeb = new Route('/b');
+ $collection->add('a', $routea);
+ $collection->add('b', $routeb);
+
+ $collection->setMethods('PUT');
+
+ $this->assertEquals(array('PUT'), $routea->getMethods());
+ $this->assertEquals(array('PUT'), $routeb->getMethods());
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/RouteCompilerTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/RouteCompilerTest.php
new file mode 100644
index 0000000..dc304e3
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/RouteCompilerTest.php
@@ -0,0 +1,389 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCompiler;
+
+class RouteCompilerTest extends TestCase
+{
+ /**
+ * @dataProvider provideCompileData
+ */
+ public function testCompile($name, $arguments, $prefix, $regex, $variables, $tokens)
+ {
+ $r = new \ReflectionClass('Symfony\\Component\\Routing\\Route');
+ $route = $r->newInstanceArgs($arguments);
+
+ $compiled = $route->compile();
+ $this->assertEquals($prefix, $compiled->getStaticPrefix(), $name.' (static prefix)');
+ $this->assertEquals($regex, $compiled->getRegex(), $name.' (regex)');
+ $this->assertEquals($variables, $compiled->getVariables(), $name.' (variables)');
+ $this->assertEquals($tokens, $compiled->getTokens(), $name.' (tokens)');
+ }
+
+ public function provideCompileData()
+ {
+ return array(
+ array(
+ 'Static route',
+ array('/foo'),
+ '/foo', '#^/foo$#sD', array(), array(
+ array('text', '/foo'),
+ ),
+ ),
+
+ array(
+ 'Route with a variable',
+ array('/foo/{bar}'),
+ '/foo', '#^/foo/(?P<bar>[^/]++)$#sD', array('bar'), array(
+ array('variable', '/', '[^/]++', 'bar'),
+ array('text', '/foo'),
+ ),
+ ),
+
+ array(
+ 'Route with a variable that has a default value',
+ array('/foo/{bar}', array('bar' => 'bar')),
+ '/foo', '#^/foo(?:/(?P<bar>[^/]++))?$#sD', array('bar'), array(
+ array('variable', '/', '[^/]++', 'bar'),
+ array('text', '/foo'),
+ ),
+ ),
+
+ array(
+ 'Route with several variables',
+ array('/foo/{bar}/{foobar}'),
+ '/foo', '#^/foo/(?P<bar>[^/]++)/(?P<foobar>[^/]++)$#sD', array('bar', 'foobar'), array(
+ array('variable', '/', '[^/]++', 'foobar'),
+ array('variable', '/', '[^/]++', 'bar'),
+ array('text', '/foo'),
+ ),
+ ),
+
+ array(
+ 'Route with several variables that have default values',
+ array('/foo/{bar}/{foobar}', array('bar' => 'bar', 'foobar' => '')),
+ '/foo', '#^/foo(?:/(?P<bar>[^/]++)(?:/(?P<foobar>[^/]++))?)?$#sD', array('bar', 'foobar'), array(
+ array('variable', '/', '[^/]++', 'foobar'),
+ array('variable', '/', '[^/]++', 'bar'),
+ array('text', '/foo'),
+ ),
+ ),
+
+ array(
+ 'Route with several variables but some of them have no default values',
+ array('/foo/{bar}/{foobar}', array('bar' => 'bar')),
+ '/foo', '#^/foo/(?P<bar>[^/]++)/(?P<foobar>[^/]++)$#sD', array('bar', 'foobar'), array(
+ array('variable', '/', '[^/]++', 'foobar'),
+ array('variable', '/', '[^/]++', 'bar'),
+ array('text', '/foo'),
+ ),
+ ),
+
+ array(
+ 'Route with an optional variable as the first segment',
+ array('/{bar}', array('bar' => 'bar')),
+ '', '#^/(?P<bar>[^/]++)?$#sD', array('bar'), array(
+ array('variable', '/', '[^/]++', 'bar'),
+ ),
+ ),
+
+ array(
+ 'Route with a requirement of 0',
+ array('/{bar}', array('bar' => null), array('bar' => '0')),
+ '', '#^/(?P<bar>0)?$#sD', array('bar'), array(
+ array('variable', '/', '0', 'bar'),
+ ),
+ ),
+
+ array(
+ 'Route with an optional variable as the first segment with requirements',
+ array('/{bar}', array('bar' => 'bar'), array('bar' => '(foo|bar)')),
+ '', '#^/(?P<bar>(foo|bar))?$#sD', array('bar'), array(
+ array('variable', '/', '(foo|bar)', 'bar'),
+ ),
+ ),
+
+ array(
+ 'Route with only optional variables',
+ array('/{foo}/{bar}', array('foo' => 'foo', 'bar' => 'bar')),
+ '', '#^/(?P<foo>[^/]++)?(?:/(?P<bar>[^/]++))?$#sD', array('foo', 'bar'), array(
+ array('variable', '/', '[^/]++', 'bar'),
+ array('variable', '/', '[^/]++', 'foo'),
+ ),
+ ),
+
+ array(
+ 'Route with a variable in last position',
+ array('/foo-{bar}'),
+ '/foo-', '#^/foo\-(?P<bar>[^/]++)$#sD', array('bar'), array(
+ array('variable', '-', '[^/]++', 'bar'),
+ array('text', '/foo'),
+ ),
+ ),
+
+ array(
+ 'Route with nested placeholders',
+ array('/{static{var}static}'),
+ '/{static', '#^/\{static(?P<var>[^/]+)static\}$#sD', array('var'), array(
+ array('text', 'static}'),
+ array('variable', '', '[^/]+', 'var'),
+ array('text', '/{static'),
+ ),
+ ),
+
+ array(
+ 'Route without separator between variables',
+ array('/{w}{x}{y}{z}.{_format}', array('z' => 'default-z', '_format' => 'html'), array('y' => '(y|Y)')),
+ '', '#^/(?P<w>[^/\.]+)(?P<x>[^/\.]+)(?P<y>(y|Y))(?:(?P<z>[^/\.]++)(?:\.(?P<_format>[^/]++))?)?$#sD', array('w', 'x', 'y', 'z', '_format'), array(
+ array('variable', '.', '[^/]++', '_format'),
+ array('variable', '', '[^/\.]++', 'z'),
+ array('variable', '', '(y|Y)', 'y'),
+ array('variable', '', '[^/\.]+', 'x'),
+ array('variable', '/', '[^/\.]+', 'w'),
+ ),
+ ),
+
+ array(
+ 'Route with a format',
+ array('/foo/{bar}.{_format}'),
+ '/foo', '#^/foo/(?P<bar>[^/\.]++)\.(?P<_format>[^/]++)$#sD', array('bar', '_format'), array(
+ array('variable', '.', '[^/]++', '_format'),
+ array('variable', '/', '[^/\.]++', 'bar'),
+ array('text', '/foo'),
+ ),
+ ),
+
+ array(
+ 'Static non UTF-8 route',
+ array("/fo\xE9"),
+ "/fo\xE9", "#^/fo\xE9$#sD", array(), array(
+ array('text', "/fo\xE9"),
+ ),
+ ),
+
+ array(
+ 'Route with an explicit UTF-8 requirement',
+ array('/{bar}', array('bar' => null), array('bar' => '.'), array('utf8' => true)),
+ '', '#^/(?P<bar>.)?$#sDu', array('bar'), array(
+ array('variable', '/', '.', 'bar', true),
+ ),
+ ),
+ );
+ }
+
+ /**
+ * @group legacy
+ * @dataProvider provideCompileImplicitUtf8Data
+ * @expectedDeprecation Using UTF-8 route %s without setting the "utf8" option is deprecated %s.
+ */
+ public function testCompileImplicitUtf8Data($name, $arguments, $prefix, $regex, $variables, $tokens, $deprecationType)
+ {
+ $r = new \ReflectionClass('Symfony\\Component\\Routing\\Route');
+ $route = $r->newInstanceArgs($arguments);
+
+ $compiled = $route->compile();
+ $this->assertEquals($prefix, $compiled->getStaticPrefix(), $name.' (static prefix)');
+ $this->assertEquals($regex, $compiled->getRegex(), $name.' (regex)');
+ $this->assertEquals($variables, $compiled->getVariables(), $name.' (variables)');
+ $this->assertEquals($tokens, $compiled->getTokens(), $name.' (tokens)');
+ }
+
+ public function provideCompileImplicitUtf8Data()
+ {
+ return array(
+ array(
+ 'Static UTF-8 route',
+ array('/foé'),
+ '/foé', '#^/foé$#sDu', array(), array(
+ array('text', '/foé'),
+ ),
+ 'patterns',
+ ),
+
+ array(
+ 'Route with an implicit UTF-8 requirement',
+ array('/{bar}', array('bar' => null), array('bar' => 'é')),
+ '', '#^/(?P<bar>é)?$#sDu', array('bar'), array(
+ array('variable', '/', 'é', 'bar', true),
+ ),
+ 'requirements',
+ ),
+
+ array(
+ 'Route with a UTF-8 class requirement',
+ array('/{bar}', array('bar' => null), array('bar' => '\pM')),
+ '', '#^/(?P<bar>\pM)?$#sDu', array('bar'), array(
+ array('variable', '/', '\pM', 'bar', true),
+ ),
+ 'requirements',
+ ),
+
+ array(
+ 'Route with a UTF-8 separator',
+ array('/foo/{bar}§{_format}', array(), array(), array('compiler_class' => Utf8RouteCompiler::class)),
+ '/foo', '#^/foo/(?P<bar>[^/§]++)§(?P<_format>[^/]++)$#sDu', array('bar', '_format'), array(
+ array('variable', '§', '[^/]++', '_format', true),
+ array('variable', '/', '[^/§]++', 'bar', true),
+ array('text', '/foo'),
+ ),
+ 'patterns',
+ ),
+ );
+ }
+
+ /**
+ * @expectedException \LogicException
+ */
+ public function testRouteWithSameVariableTwice()
+ {
+ $route = new Route('/{name}/{name}');
+
+ $compiled = $route->compile();
+ }
+
+ /**
+ * @expectedException \LogicException
+ */
+ public function testRouteCharsetMismatch()
+ {
+ $route = new Route("/\xE9/{bar}", array(), array('bar' => '.'), array('utf8' => true));
+
+ $compiled = $route->compile();
+ }
+
+ /**
+ * @expectedException \LogicException
+ */
+ public function testRequirementCharsetMismatch()
+ {
+ $route = new Route('/foo/{bar}', array(), array('bar' => "\xE9"), array('utf8' => true));
+
+ $compiled = $route->compile();
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testRouteWithFragmentAsPathParameter()
+ {
+ $route = new Route('/{_fragment}');
+
+ $compiled = $route->compile();
+ }
+
+ /**
+ * @dataProvider getVariableNamesStartingWithADigit
+ * @expectedException \DomainException
+ */
+ public function testRouteWithVariableNameStartingWithADigit($name)
+ {
+ $route = new Route('/{'.$name.'}');
+ $route->compile();
+ }
+
+ public function getVariableNamesStartingWithADigit()
+ {
+ return array(
+ array('09'),
+ array('123'),
+ array('1e2'),
+ );
+ }
+
+ /**
+ * @dataProvider provideCompileWithHostData
+ */
+ public function testCompileWithHost($name, $arguments, $prefix, $regex, $variables, $pathVariables, $tokens, $hostRegex, $hostVariables, $hostTokens)
+ {
+ $r = new \ReflectionClass('Symfony\\Component\\Routing\\Route');
+ $route = $r->newInstanceArgs($arguments);
+
+ $compiled = $route->compile();
+ $this->assertEquals($prefix, $compiled->getStaticPrefix(), $name.' (static prefix)');
+ $this->assertEquals($regex, str_replace(array("\n", ' '), '', $compiled->getRegex()), $name.' (regex)');
+ $this->assertEquals($variables, $compiled->getVariables(), $name.' (variables)');
+ $this->assertEquals($pathVariables, $compiled->getPathVariables(), $name.' (path variables)');
+ $this->assertEquals($tokens, $compiled->getTokens(), $name.' (tokens)');
+ $this->assertEquals($hostRegex, str_replace(array("\n", ' '), '', $compiled->getHostRegex()), $name.' (host regex)');
+ $this->assertEquals($hostVariables, $compiled->getHostVariables(), $name.' (host variables)');
+ $this->assertEquals($hostTokens, $compiled->getHostTokens(), $name.' (host tokens)');
+ }
+
+ public function provideCompileWithHostData()
+ {
+ return array(
+ array(
+ 'Route with host pattern',
+ array('/hello', array(), array(), array(), 'www.example.com'),
+ '/hello', '#^/hello$#sD', array(), array(), array(
+ array('text', '/hello'),
+ ),
+ '#^www\.example\.com$#sDi', array(), array(
+ array('text', 'www.example.com'),
+ ),
+ ),
+ array(
+ 'Route with host pattern and some variables',
+ array('/hello/{name}', array(), array(), array(), 'www.example.{tld}'),
+ '/hello', '#^/hello/(?P<name>[^/]++)$#sD', array('tld', 'name'), array('name'), array(
+ array('variable', '/', '[^/]++', 'name'),
+ array('text', '/hello'),
+ ),
+ '#^www\.example\.(?P<tld>[^\.]++)$#sDi', array('tld'), array(
+ array('variable', '.', '[^\.]++', 'tld'),
+ array('text', 'www.example'),
+ ),
+ ),
+ array(
+ 'Route with variable at beginning of host',
+ array('/hello', array(), array(), array(), '{locale}.example.{tld}'),
+ '/hello', '#^/hello$#sD', array('locale', 'tld'), array(), array(
+ array('text', '/hello'),
+ ),
+ '#^(?P<locale>[^\.]++)\.example\.(?P<tld>[^\.]++)$#sDi', array('locale', 'tld'), array(
+ array('variable', '.', '[^\.]++', 'tld'),
+ array('text', '.example'),
+ array('variable', '', '[^\.]++', 'locale'),
+ ),
+ ),
+ array(
+ 'Route with host variables that has a default value',
+ array('/hello', array('locale' => 'a', 'tld' => 'b'), array(), array(), '{locale}.example.{tld}'),
+ '/hello', '#^/hello$#sD', array('locale', 'tld'), array(), array(
+ array('text', '/hello'),
+ ),
+ '#^(?P<locale>[^\.]++)\.example\.(?P<tld>[^\.]++)$#sDi', array('locale', 'tld'), array(
+ array('variable', '.', '[^\.]++', 'tld'),
+ array('text', '.example'),
+ array('variable', '', '[^\.]++', 'locale'),
+ ),
+ ),
+ );
+ }
+
+ /**
+ * @expectedException \DomainException
+ */
+ public function testRouteWithTooLongVariableName()
+ {
+ $route = new Route(sprintf('/{%s}', str_repeat('a', RouteCompiler::VARIABLE_MAXIMUM_LENGTH + 1)));
+ $route->compile();
+ }
+}
+
+class Utf8RouteCompiler extends RouteCompiler
+{
+ const SEPARATORS = '/§';
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/RouteTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/RouteTest.php
new file mode 100644
index 0000000..c7af058
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/RouteTest.php
@@ -0,0 +1,258 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Routing\Route;
+
+class RouteTest extends TestCase
+{
+ public function testConstructor()
+ {
+ $route = new Route('/{foo}', array('foo' => 'bar'), array('foo' => '\d+'), array('foo' => 'bar'), '{locale}.example.com');
+ $this->assertEquals('/{foo}', $route->getPath(), '__construct() takes a path as its first argument');
+ $this->assertEquals(array('foo' => 'bar'), $route->getDefaults(), '__construct() takes defaults as its second argument');
+ $this->assertEquals(array('foo' => '\d+'), $route->getRequirements(), '__construct() takes requirements as its third argument');
+ $this->assertEquals('bar', $route->getOption('foo'), '__construct() takes options as its fourth argument');
+ $this->assertEquals('{locale}.example.com', $route->getHost(), '__construct() takes a host pattern as its fifth argument');
+
+ $route = new Route('/', array(), array(), array(), '', array('Https'), array('POST', 'put'), 'context.getMethod() == "GET"');
+ $this->assertEquals(array('https'), $route->getSchemes(), '__construct() takes schemes as its sixth argument and lowercases it');
+ $this->assertEquals(array('POST', 'PUT'), $route->getMethods(), '__construct() takes methods as its seventh argument and uppercases it');
+ $this->assertEquals('context.getMethod() == "GET"', $route->getCondition(), '__construct() takes a condition as its eight argument');
+
+ $route = new Route('/', array(), array(), array(), '', 'Https', 'Post');
+ $this->assertEquals(array('https'), $route->getSchemes(), '__construct() takes a single scheme as its sixth argument');
+ $this->assertEquals(array('POST'), $route->getMethods(), '__construct() takes a single method as its seventh argument');
+ }
+
+ public function testPath()
+ {
+ $route = new Route('/{foo}');
+ $route->setPath('/{bar}');
+ $this->assertEquals('/{bar}', $route->getPath(), '->setPath() sets the path');
+ $route->setPath('');
+ $this->assertEquals('/', $route->getPath(), '->setPath() adds a / at the beginning of the path if needed');
+ $route->setPath('bar');
+ $this->assertEquals('/bar', $route->getPath(), '->setPath() adds a / at the beginning of the path if needed');
+ $this->assertEquals($route, $route->setPath(''), '->setPath() implements a fluent interface');
+ $route->setPath('//path');
+ $this->assertEquals('/path', $route->getPath(), '->setPath() does not allow two slashes "//" at the beginning of the path as it would be confused with a network path when generating the path from the route');
+ }
+
+ public function testOptions()
+ {
+ $route = new Route('/{foo}');
+ $route->setOptions(array('foo' => 'bar'));
+ $this->assertEquals(array_merge(array(
+ 'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler',
+ ), array('foo' => 'bar')), $route->getOptions(), '->setOptions() sets the options');
+ $this->assertEquals($route, $route->setOptions(array()), '->setOptions() implements a fluent interface');
+
+ $route->setOptions(array('foo' => 'foo'));
+ $route->addOptions(array('bar' => 'bar'));
+ $this->assertEquals($route, $route->addOptions(array()), '->addOptions() implements a fluent interface');
+ $this->assertEquals(array('foo' => 'foo', 'bar' => 'bar', 'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler'), $route->getOptions(), '->addDefaults() keep previous defaults');
+ }
+
+ public function testOption()
+ {
+ $route = new Route('/{foo}');
+ $this->assertFalse($route->hasOption('foo'), '->hasOption() return false if option is not set');
+ $this->assertEquals($route, $route->setOption('foo', 'bar'), '->setOption() implements a fluent interface');
+ $this->assertEquals('bar', $route->getOption('foo'), '->setOption() sets the option');
+ $this->assertTrue($route->hasOption('foo'), '->hasOption() return true if option is set');
+ }
+
+ public function testDefaults()
+ {
+ $route = new Route('/{foo}');
+ $route->setDefaults(array('foo' => 'bar'));
+ $this->assertEquals(array('foo' => 'bar'), $route->getDefaults(), '->setDefaults() sets the defaults');
+ $this->assertEquals($route, $route->setDefaults(array()), '->setDefaults() implements a fluent interface');
+
+ $route->setDefault('foo', 'bar');
+ $this->assertEquals('bar', $route->getDefault('foo'), '->setDefault() sets a default value');
+
+ $route->setDefault('foo2', 'bar2');
+ $this->assertEquals('bar2', $route->getDefault('foo2'), '->getDefault() return the default value');
+ $this->assertNull($route->getDefault('not_defined'), '->getDefault() return null if default value is not set');
+
+ $route->setDefault('_controller', $closure = function () { return 'Hello'; });
+ $this->assertEquals($closure, $route->getDefault('_controller'), '->setDefault() sets a default value');
+
+ $route->setDefaults(array('foo' => 'foo'));
+ $route->addDefaults(array('bar' => 'bar'));
+ $this->assertEquals($route, $route->addDefaults(array()), '->addDefaults() implements a fluent interface');
+ $this->assertEquals(array('foo' => 'foo', 'bar' => 'bar'), $route->getDefaults(), '->addDefaults() keep previous defaults');
+ }
+
+ public function testRequirements()
+ {
+ $route = new Route('/{foo}');
+ $route->setRequirements(array('foo' => '\d+'));
+ $this->assertEquals(array('foo' => '\d+'), $route->getRequirements(), '->setRequirements() sets the requirements');
+ $this->assertEquals('\d+', $route->getRequirement('foo'), '->getRequirement() returns a requirement');
+ $this->assertNull($route->getRequirement('bar'), '->getRequirement() returns null if a requirement is not defined');
+ $route->setRequirements(array('foo' => '^\d+$'));
+ $this->assertEquals('\d+', $route->getRequirement('foo'), '->getRequirement() removes ^ and $ from the path');
+ $this->assertEquals($route, $route->setRequirements(array()), '->setRequirements() implements a fluent interface');
+
+ $route->setRequirements(array('foo' => '\d+'));
+ $route->addRequirements(array('bar' => '\d+'));
+ $this->assertEquals($route, $route->addRequirements(array()), '->addRequirements() implements a fluent interface');
+ $this->assertEquals(array('foo' => '\d+', 'bar' => '\d+'), $route->getRequirements(), '->addRequirement() keep previous requirements');
+ }
+
+ public function testRequirement()
+ {
+ $route = new Route('/{foo}');
+ $this->assertFalse($route->hasRequirement('foo'), '->hasRequirement() return false if requirement is not set');
+ $route->setRequirement('foo', '^\d+$');
+ $this->assertEquals('\d+', $route->getRequirement('foo'), '->setRequirement() removes ^ and $ from the path');
+ $this->assertTrue($route->hasRequirement('foo'), '->hasRequirement() return true if requirement is set');
+ }
+
+ /**
+ * @dataProvider getInvalidRequirements
+ * @expectedException \InvalidArgumentException
+ */
+ public function testSetInvalidRequirement($req)
+ {
+ $route = new Route('/{foo}');
+ $route->setRequirement('foo', $req);
+ }
+
+ public function getInvalidRequirements()
+ {
+ return array(
+ array(''),
+ array(array()),
+ array('^$'),
+ array('^'),
+ array('$'),
+ );
+ }
+
+ public function testHost()
+ {
+ $route = new Route('/');
+ $route->setHost('{locale}.example.net');
+ $this->assertEquals('{locale}.example.net', $route->getHost(), '->setHost() sets the host pattern');
+ }
+
+ public function testScheme()
+ {
+ $route = new Route('/');
+ $this->assertEquals(array(), $route->getSchemes(), 'schemes is initialized with array()');
+ $this->assertFalse($route->hasScheme('http'));
+ $route->setSchemes('hTTp');
+ $this->assertEquals(array('http'), $route->getSchemes(), '->setSchemes() accepts a single scheme string and lowercases it');
+ $this->assertTrue($route->hasScheme('htTp'));
+ $this->assertFalse($route->hasScheme('httpS'));
+ $route->setSchemes(array('HttpS', 'hTTp'));
+ $this->assertEquals(array('https', 'http'), $route->getSchemes(), '->setSchemes() accepts an array of schemes and lowercases them');
+ $this->assertTrue($route->hasScheme('htTp'));
+ $this->assertTrue($route->hasScheme('httpS'));
+ }
+
+ public function testMethod()
+ {
+ $route = new Route('/');
+ $this->assertEquals(array(), $route->getMethods(), 'methods is initialized with array()');
+ $route->setMethods('gEt');
+ $this->assertEquals(array('GET'), $route->getMethods(), '->setMethods() accepts a single method string and uppercases it');
+ $route->setMethods(array('gEt', 'PosT'));
+ $this->assertEquals(array('GET', 'POST'), $route->getMethods(), '->setMethods() accepts an array of methods and uppercases them');
+ }
+
+ public function testCondition()
+ {
+ $route = new Route('/');
+ $this->assertSame('', $route->getCondition());
+ $route->setCondition('context.getMethod() == "GET"');
+ $this->assertSame('context.getMethod() == "GET"', $route->getCondition());
+ }
+
+ public function testCompile()
+ {
+ $route = new Route('/{foo}');
+ $this->assertInstanceOf('Symfony\Component\Routing\CompiledRoute', $compiled = $route->compile(), '->compile() returns a compiled route');
+ $this->assertSame($compiled, $route->compile(), '->compile() only compiled the route once if unchanged');
+ $route->setRequirement('foo', '.*');
+ $this->assertNotSame($compiled, $route->compile(), '->compile() recompiles if the route was modified');
+ }
+
+ public function testSerialize()
+ {
+ $route = new Route('/prefix/{foo}', array('foo' => 'default'), array('foo' => '\d+'));
+
+ $serialized = serialize($route);
+ $unserialized = unserialize($serialized);
+
+ $this->assertEquals($route, $unserialized);
+ $this->assertNotSame($route, $unserialized);
+ }
+
+ /**
+ * Tests that the compiled version is also serialized to prevent the overhead
+ * of compiling it again after unserialize.
+ */
+ public function testSerializeWhenCompiled()
+ {
+ $route = new Route('/prefix/{foo}', array('foo' => 'default'), array('foo' => '\d+'));
+ $route->setHost('{locale}.example.net');
+ $route->compile();
+
+ $serialized = serialize($route);
+ $unserialized = unserialize($serialized);
+
+ $this->assertEquals($route, $unserialized);
+ $this->assertNotSame($route, $unserialized);
+ }
+
+ /**
+ * Tests that unserialization does not fail when the compiled Route is of a
+ * class other than CompiledRoute, such as a subclass of it.
+ */
+ public function testSerializeWhenCompiledWithClass()
+ {
+ $route = new Route('/', array(), array(), array('compiler_class' => '\Symfony\Component\Routing\Tests\Fixtures\CustomRouteCompiler'));
+ $this->assertInstanceOf('\Symfony\Component\Routing\Tests\Fixtures\CustomCompiledRoute', $route->compile(), '->compile() returned a proper route');
+
+ $serialized = serialize($route);
+ try {
+ $unserialized = unserialize($serialized);
+ $this->assertInstanceOf('\Symfony\Component\Routing\Tests\Fixtures\CustomCompiledRoute', $unserialized->compile(), 'the unserialized route compiled successfully');
+ } catch (\Exception $e) {
+ $this->fail('unserializing a route which uses a custom compiled route class');
+ }
+ }
+
+ /**
+ * Tests that the serialized representation of a route in one symfony version
+ * also works in later symfony versions, i.e. the unserialized route is in the
+ * same state as another, semantically equivalent, route.
+ */
+ public function testSerializedRepresentationKeepsWorking()
+ {
+ $serialized = 'C:31:"Symfony\Component\Routing\Route":936:{a:8:{s:4:"path";s:13:"/prefix/{foo}";s:4:"host";s:20:"{locale}.example.net";s:8:"defaults";a:1:{s:3:"foo";s:7:"default";}s:12:"requirements";a:1:{s:3:"foo";s:3:"\d+";}s:7:"options";a:1:{s:14:"compiler_class";s:39:"Symfony\Component\Routing\RouteCompiler";}s:7:"schemes";a:0:{}s:7:"methods";a:0:{}s:8:"compiled";C:39:"Symfony\Component\Routing\CompiledRoute":571:{a:8:{s:4:"vars";a:2:{i:0;s:6:"locale";i:1;s:3:"foo";}s:11:"path_prefix";s:7:"/prefix";s:10:"path_regex";s:31:"#^/prefix(?:/(?P<foo>\d+))?$#sD";s:11:"path_tokens";a:2:{i:0;a:4:{i:0;s:8:"variable";i:1;s:1:"/";i:2;s:3:"\d+";i:3;s:3:"foo";}i:1;a:2:{i:0;s:4:"text";i:1;s:7:"/prefix";}}s:9:"path_vars";a:1:{i:0;s:3:"foo";}s:10:"host_regex";s:40:"#^(?P<locale>[^\.]++)\.example\.net$#sDi";s:11:"host_tokens";a:2:{i:0;a:2:{i:0;s:4:"text";i:1;s:12:".example.net";}i:1;a:4:{i:0;s:8:"variable";i:1;s:0:"";i:2;s:7:"[^\.]++";i:3;s:6:"locale";}}s:9:"host_vars";a:1:{i:0;s:6:"locale";}}}}}';
+ $unserialized = unserialize($serialized);
+
+ $route = new Route('/prefix/{foo}', array('foo' => 'default'), array('foo' => '\d+'));
+ $route->setHost('{locale}.example.net');
+ $route->compile();
+
+ $this->assertEquals($route, $unserialized);
+ $this->assertNotSame($route, $unserialized);
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/RouterTest.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/RouterTest.php
new file mode 100644
index 0000000..3e3d43f
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/Tests/RouterTest.php
@@ -0,0 +1,163 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\Router;
+use Symfony\Component\HttpFoundation\Request;
+
+class RouterTest extends TestCase
+{
+ private $router = null;
+
+ private $loader = null;
+
+ protected function setUp()
+ {
+ $this->loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
+ $this->router = new Router($this->loader, 'routing.yml');
+ }
+
+ public function testSetOptionsWithSupportedOptions()
+ {
+ $this->router->setOptions(array(
+ 'cache_dir' => './cache',
+ 'debug' => true,
+ 'resource_type' => 'ResourceType',
+ ));
+
+ $this->assertSame('./cache', $this->router->getOption('cache_dir'));
+ $this->assertTrue($this->router->getOption('debug'));
+ $this->assertSame('ResourceType', $this->router->getOption('resource_type'));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The Router does not support the following options: "option_foo", "option_bar"
+ */
+ public function testSetOptionsWithUnsupportedOptions()
+ {
+ $this->router->setOptions(array(
+ 'cache_dir' => './cache',
+ 'option_foo' => true,
+ 'option_bar' => 'baz',
+ 'resource_type' => 'ResourceType',
+ ));
+ }
+
+ public function testSetOptionWithSupportedOption()
+ {
+ $this->router->setOption('cache_dir', './cache');
+
+ $this->assertSame('./cache', $this->router->getOption('cache_dir'));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The Router does not support the "option_foo" option
+ */
+ public function testSetOptionWithUnsupportedOption()
+ {
+ $this->router->setOption('option_foo', true);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The Router does not support the "option_foo" option
+ */
+ public function testGetOptionWithUnsupportedOption()
+ {
+ $this->router->getOption('option_foo', true);
+ }
+
+ public function testThatRouteCollectionIsLoaded()
+ {
+ $this->router->setOption('resource_type', 'ResourceType');
+
+ $routeCollection = new RouteCollection();
+
+ $this->loader->expects($this->once())
+ ->method('load')->with('routing.yml', 'ResourceType')
+ ->will($this->returnValue($routeCollection));
+
+ $this->assertSame($routeCollection, $this->router->getRouteCollection());
+ }
+
+ /**
+ * @dataProvider provideMatcherOptionsPreventingCaching
+ */
+ public function testMatcherIsCreatedIfCacheIsNotConfigured($option)
+ {
+ $this->router->setOption($option, null);
+
+ $this->loader->expects($this->once())
+ ->method('load')->with('routing.yml', null)
+ ->will($this->returnValue(new RouteCollection()));
+
+ $this->assertInstanceOf('Symfony\\Component\\Routing\\Matcher\\UrlMatcher', $this->router->getMatcher());
+ }
+
+ public function provideMatcherOptionsPreventingCaching()
+ {
+ return array(
+ array('cache_dir'),
+ array('matcher_cache_class'),
+ );
+ }
+
+ /**
+ * @dataProvider provideGeneratorOptionsPreventingCaching
+ */
+ public function testGeneratorIsCreatedIfCacheIsNotConfigured($option)
+ {
+ $this->router->setOption($option, null);
+
+ $this->loader->expects($this->once())
+ ->method('load')->with('routing.yml', null)
+ ->will($this->returnValue(new RouteCollection()));
+
+ $this->assertInstanceOf('Symfony\\Component\\Routing\\Generator\\UrlGenerator', $this->router->getGenerator());
+ }
+
+ public function provideGeneratorOptionsPreventingCaching()
+ {
+ return array(
+ array('cache_dir'),
+ array('generator_cache_class'),
+ );
+ }
+
+ public function testMatchRequestWithUrlMatcherInterface()
+ {
+ $matcher = $this->getMockBuilder('Symfony\Component\Routing\Matcher\UrlMatcherInterface')->getMock();
+ $matcher->expects($this->once())->method('match');
+
+ $p = new \ReflectionProperty($this->router, 'matcher');
+ $p->setAccessible(true);
+ $p->setValue($this->router, $matcher);
+
+ $this->router->matchRequest(Request::create('/'));
+ }
+
+ public function testMatchRequestWithRequestMatcherInterface()
+ {
+ $matcher = $this->getMockBuilder('Symfony\Component\Routing\Matcher\RequestMatcherInterface')->getMock();
+ $matcher->expects($this->once())->method('matchRequest');
+
+ $p = new \ReflectionProperty($this->router, 'matcher');
+ $p->setAccessible(true);
+ $p->setValue($this->router, $matcher);
+
+ $this->router->matchRequest(Request::create('/'));
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/composer.json b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/composer.json
new file mode 100644
index 0000000..4d820cc
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/composer.json
@@ -0,0 +1,56 @@
+{
+ "name": "symfony/routing",
+ "type": "library",
+ "description": "Symfony Routing Component",
+ "keywords": ["routing", "router", "URL", "URI"],
+ "homepage": "https://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": "^5.5.9|>=7.0.8"
+ },
+ "require-dev": {
+ "symfony/config": "^3.3.1|~4.0",
+ "symfony/http-foundation": "~2.8|~3.0|~4.0",
+ "symfony/yaml": "~3.4|~4.0",
+ "symfony/expression-language": "~2.8|~3.0|~4.0",
+ "symfony/dependency-injection": "~3.3|~4.0",
+ "doctrine/annotations": "~1.0",
+ "doctrine/common": "~2.2",
+ "psr/log": "~1.0"
+ },
+ "conflict": {
+ "symfony/config": "<3.3.1",
+ "symfony/dependency-injection": "<3.3",
+ "symfony/yaml": "<3.4"
+ },
+ "suggest": {
+ "symfony/http-foundation": "For using a Symfony Request object",
+ "symfony/config": "For using the all-in-one router or any loader",
+ "symfony/yaml": "For using the YAML loader",
+ "symfony/expression-language": "For using expression matching",
+ "doctrine/annotations": "For using the annotation loader",
+ "symfony/dependency-injection": "For loading routes from a service"
+ },
+ "autoload": {
+ "psr-4": { "Symfony\\Component\\Routing\\": "" },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.4-dev"
+ }
+ }
+}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/phpunit.xml.dist b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/phpunit.xml.dist
new file mode 100644
index 0000000..bcc0959
--- /dev/null
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/symfony/routing/phpunit.xml.dist
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
+ backupGlobals="false"
+ colors="true"
+ bootstrap="vendor/autoload.php"
+ failOnRisky="true"
+ failOnWarning="true"
+>
+ <php>
+ <ini name="error_reporting" value="-1" />
+ </php>
+
+ <testsuites>
+ <testsuite name="Symfony Routing Component Test Suite">
+ <directory>./Tests/</directory>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist>
+ <directory>./</directory>
+ <exclude>
+ <directory>./Tests</directory>
+ <directory>./vendor</directory>
+ </exclude>
+ </whitelist>
+ </filter>
+</phpunit>