diff --git a/.gitignore b/.gitignore
index 2fe5e8a..5871a61 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,6 @@
[Dd]esktop.ini
.DS_Store
/public/robots.txt
+/lib/index-dev
+/.debug
+/config/config.ini
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..525bff2
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "lib/index"]
+ path = lib/index
+ url = https://git.flash.moe/flash/index.git
diff --git a/config/config.example.ini b/config/config.example.ini
new file mode 100644
index 0000000..e69de29
diff --git a/hanyuu.php b/hanyuu.php
new file mode 100644
index 0000000..7bdf9b6
--- /dev/null
+++ b/hanyuu.php
@@ -0,0 +1,46 @@
+Hanyuu is sad.');
+});
+
+$hau = new HanyuuContext(ArrayConfig::open(HAU_DIR_CONFIG . '/config.ini'));
+$hau->connectDb();
diff --git a/lib/index b/lib/index
new file mode 160000
index 0000000..f8c6602
--- /dev/null
+++ b/lib/index
@@ -0,0 +1 @@
+Subproject commit f8c6602ab953491a3e540d1ab9c77f2d885ee120
diff --git a/public/index.php b/public/index.php
index 2f51e59..b118c11 100644
--- a/public/index.php
+++ b/public/index.php
@@ -1,6 +1,9 @@
-
-
=ucfirst(explode('.', $_SERVER['HTTP_HOST'])[1]);?> ID
-
- Under Construction
-
-
+setUpHttp();
+$hau->dispatchHttp($request);
diff --git a/src/Config/ArrayConfig.php b/src/Config/ArrayConfig.php
new file mode 100644
index 0000000..c0431a8
--- /dev/null
+++ b/src/Config/ArrayConfig.php
@@ -0,0 +1,78 @@
+config;
+
+ while(count($parts) > 1) {
+ $part = array_pop($parts);
+ if(!array_key_exists($part, $value))
+ break;
+ $value = $value[$part];
+ }
+
+ if($parts[0] === '')
+ return $value;
+
+ return $value[$parts[0]] ?? null;
+ }
+
+ public function getValue(string $name, string $type = IConfig::T_ANY, $default = null): mixed {
+ if(array_key_exists($name, $this->cache))
+ $value = $this->cache[$name];
+ else {
+ $this->cache[$name] = $value = $this->getRaw($name);
+ $this->exists[$name] = $value !== null;
+ }
+
+ if($type !== IConfig::T_ANY && CfgTools::type($value) !== $type)
+ $value = null;
+
+ return $value ?? $default ?? CfgTools::default($type);
+ }
+
+ public function hasValue(string $name): bool {
+ if(array_key_exists($name, $this->exists))
+ return $this->exists[$name];
+
+ $exists = array_key_exists($name, $this->cache)
+ || $this->getRaw($name) !== null;
+
+ return $this->exists[$name] = $exists;
+ }
+
+ public static function open(string $path): self {
+ $parsed = parse_ini_file($path, true, self::SCANNER_MODE);
+ if($parsed === false)
+ throw new InvalidArgumentException('Unable to parse configuration file in $path.');
+
+ return new static($parsed);
+ }
+
+ public static function from(string $string): self {
+ $parsed = parse_ini_string($string, true, self::SCANNER_MODE);
+ if($parsed === false)
+ throw new InvalidArgumentException('Unable to parse configuration string in $string.');
+
+ return new static($parsed);
+ }
+}
diff --git a/src/Config/CfgTools.php b/src/Config/CfgTools.php
new file mode 100644
index 0000000..8aba0bc
--- /dev/null
+++ b/src/Config/CfgTools.php
@@ -0,0 +1,27 @@
+ null,
+ IConfig::T_STR => '',
+ IConfig::T_INT => 0,
+ IConfig::T_BOOL => false,
+ IConfig::T_ARR => [],
+ ];
+
+ public static function default(string $type) {
+ return self::DEFAULTS[$type] ?? null;
+ }
+}
diff --git a/src/Config/IConfig.php b/src/Config/IConfig.php
new file mode 100644
index 0000000..c8f2b32
--- /dev/null
+++ b/src/Config/IConfig.php
@@ -0,0 +1,14 @@
+config = $config;
+ $this->prefix = $prefix;
+ }
+
+ private function getName(string $name): string {
+ return $this->prefix . $name;
+ }
+
+ public function scopeTo(string $prefix): IConfig {
+ return $this->config->scopeTo($this->getName($prefix));
+ }
+
+ public function getValue(string $name, string $type = IConfig::T_ANY, $default = null): mixed {
+ return $this->config->getValue($this->getName($name), $type, $default);
+ }
+
+ public function hasValue(string $name): bool {
+ return $this->config->hasValue($this->getName($name));
+ }
+}
diff --git a/src/HanyuuContext.php b/src/HanyuuContext.php
new file mode 100644
index 0000000..bc0bf6e
--- /dev/null
+++ b/src/HanyuuContext.php
@@ -0,0 +1,81 @@
+config = $config;
+ }
+
+ public function connectDb(?IDbConnection $dbConn = null): void {
+ $dbConn ??= DbTools::create($this->config->getValue('database:dsn', IConfig::T_STR, 'null'));
+ $dbConn->execute(self::DB_INIT);
+ $this->dbConn = $dbConn;
+ }
+
+ public function getDb(): IDbConnection {
+ return $this->dbConn;
+ }
+
+ public function getDbQueryCount(): int {
+ $result = $this->dbConn->query('SHOW SESSION STATUS LIKE "Questions"');
+ return $result->next() ? $result->getInteger(0) : 0;
+ }
+
+ public function setUpHttp(): void {
+ $this->router = new HttpFx;
+ $this->router->use('/', function($response) {
+ $response->setPoweredBy('Hanyuu');
+ });
+
+ $this->registerErrorPages();
+ $this->registerHttpRoutes();
+ }
+
+ public function dispatchHttp(?HttpRequest $request = null): void {
+ $this->router->dispatch($request);
+ }
+
+ private function registerErrorPages(): void {
+ /*$this->router->addErrorHandler(400, function($response) {
+ $response->setContent(Template::renderRaw('errors.400'));
+ });
+ $this->router->addErrorHandler(403, function($response) {
+ $response->setContent(Template::renderRaw('errors.403'));
+ });
+ $this->router->addErrorHandler(404, function($response) {
+ $response->setContent(Template::renderRaw('errors.404'));
+ });
+ $this->router->addErrorHandler(500, function($response) {
+ $response->setContent(file_get_contents(MSZ_TEMPLATES . '/500.html'));
+ });
+ $this->router->addErrorHandler(503, function($response) {
+ $response->setContent(file_get_contents(MSZ_TEMPLATES . '/503.html'));
+ });*/
+ }
+
+ private function registerHttpRoutes(): void {
+ $this->router->get('/', function($response, $request) {
+ $siteName = $this->config->getValue('site:name', IConfig::T_STR, 'Hanyuu');
+
+ return "\r\n"
+ . "{$siteName} ID\r\n"
+ . "\r\n"
+ . " Under Construction
\r\n"
+ . " \r\n"
+ . "\r\n";
+ });
+ }
+}