diff --git a/.eslintrc b/.eslintrc index a1f75dd..3c174b3 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,70 +1,70 @@ { - "parserOptions": { - "ecmaVersion": 7, - "sourceType": "module", - "ecmaFeatures": {} - }, - "rules": { - "constructor-super": 2, - "for-direction": 2, - "getter-return": 2, - "no-case-declarations": 2, - "no-class-assign": 2, - "no-compare-neg-zero": 2, - "no-cond-assign": 2, - "no-console": 1, - "no-const-assign": 2, - "no-constant-condition": 2, - "no-control-regex": 1, - "no-debugger": 2, - "no-delete-var": 2, - "no-dupe-args": 2, - "no-dupe-class-members": 2, - "no-dupe-keys": 2, - "no-duplicate-case": 2, - "no-empty": 2, - "no-empty-character-class": 2, - "no-empty-pattern": 2, - "no-ex-assign": 2, - "no-extra-boolean-cast": 2, - "no-extra-semi": 2, - "no-fallthrough": 2, - "no-func-assign": 2, - "no-global-assign": 2, - "no-inner-declarations": 2, - "no-invalid-regexp": 2, - "no-irregular-whitespace": 2, - "no-mixed-spaces-and-tabs": 2, - "no-new-symbol": 2, - "no-obj-calls": 2, - "no-octal": 2, - "no-redeclare": 2, - "no-regex-spaces": 2, - "no-self-assign": 2, - "no-sparse-arrays": 2, - "no-this-before-super": 2, - "no-undef": 2, - "no-unexpected-multiline": 2, - "no-unreachable": 2, - "no-unsafe-finally": 2, - "no-unsafe-negation": 2, - "no-unused-labels": 2, - "no-unused-vars": 2, - "no-useless-escape": 1, - "require-yield": 2, - "use-isnan": 2, - "valid-typeof": 2, - "no-duplicate-imports": 2 - }, - "env": { - "node": true, - "browser": true, - "es6": true - }, - "globals": { - "_": false, - "hljs": false, - "Sortable": false, - "Prism": false - } -} \ No newline at end of file + "parserOptions": { + "ecmaVersion": 7, + "sourceType": "module", + "ecmaFeatures": {} + }, + "rules": { + "constructor-super": 2, + "for-direction": 2, + "getter-return": 2, + "no-case-declarations": 2, + "no-class-assign": 2, + "no-compare-neg-zero": 2, + "no-cond-assign": 2, + "no-console": 1, + "no-const-assign": 2, + "no-constant-condition": 2, + "no-control-regex": 1, + "no-debugger": 2, + "no-delete-var": 2, + "no-dupe-args": 2, + "no-dupe-class-members": 2, + "no-dupe-keys": 2, + "no-duplicate-case": 2, + "no-empty": 2, + "no-empty-character-class": 2, + "no-empty-pattern": 2, + "no-ex-assign": 2, + "no-extra-boolean-cast": 2, + "no-extra-semi": 2, + "no-fallthrough": 2, + "no-func-assign": 2, + "no-global-assign": 2, + "no-inner-declarations": 2, + "no-invalid-regexp": 2, + "no-irregular-whitespace": 2, + "no-mixed-spaces-and-tabs": 2, + "no-new-symbol": 2, + "no-obj-calls": 2, + "no-octal": 2, + "no-redeclare": 2, + "no-regex-spaces": 2, + "no-self-assign": 2, + "no-sparse-arrays": 2, + "no-this-before-super": 2, + "no-undef": 2, + "no-unexpected-multiline": 2, + "no-unreachable": 2, + "no-unsafe-finally": 2, + "no-unsafe-negation": 2, + "no-unused-labels": 2, + "no-unused-vars": 1, + "no-useless-escape": 1, + "require-yield": 2, + "use-isnan": 2, + "valid-typeof": 2, + "no-duplicate-imports": 2 + }, + "env": { + "node": true, + "browser": true, + "es6": true + }, + "globals": { + "_": false, + "hljs": false, + "Sortable": false, + "Prism": false + } +} diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..f967116 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,7 @@ +.babelrc +README.md +*.twig +*.sass +*.json +*.php +*.md diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..951ce9f --- /dev/null +++ b/.prettierrc @@ -0,0 +1,17 @@ + { + "arrowParens": "avoid", + "bracketSpacing": true, + "htmlWhitespaceSensitivity": "css", + "insertPragma": false, + "bracketSameLine": false, + "jsxSingleQuote": true, + "parser": "babel", + "proseWrap": "preserve", + "requirePragma": false, + "semi": true, + "singleQuote": true, + "trailingComma": "none", + "useTabs": true, + "tabWidth": 4, + "printWidth": 90 + } \ No newline at end of file diff --git a/brain/App.inc.php b/brain/App.inc.php deleted file mode 100644 index 0ac8161..0000000 --- a/brain/App.inc.php +++ /dev/null @@ -1,48 +0,0 @@ -add(TwigMiddleware::create($app, $twig)); - //set up routing - $app->get( - "/[{first}[/{second}[/{third}[/{fourth}[/{fifth}]]]]]", - "\RouteControl:get" - ); - $app->post( - "/[{first}[/{second}[/{third}[/{fourth}]]]]", - "\RouteControl:post" - ); - //start the app - - $app->run(); - } -} diff --git a/brain/api/v1/AuthAPI.inc.php b/brain/api/v1/AuthAPI.inc.php deleted file mode 100644 index 8d99ef9..0000000 --- a/brain/api/v1/AuthAPI.inc.php +++ /dev/null @@ -1,74 +0,0 @@ - "Authorized", - "type" => "apiUseAuthorized", - "token" => Session::get("token"), - ]; - } else { - $result = [ - "message" => "Not Authorized", - "type" => "apiUseNotAuthorized", - ]; - } - return $result; - } - - public static function login($body) - { - $result = []; - switch (Auth::login($body)) { - case "no_name": - $result = [ - "message" => "Need to see some id, champ", - "type" => "requestLame", - ]; - break; - case "bad_pass": - $result = [ - "message" => "Check your password, sport", - "type" => "requestLame", - ]; - break; - default: - $result = [ - "message" => "Welcome back", - "type" => "requestGood", - ]; - break; - } - - return $result; - } - - public static function logout($body) - { - Auth::logout($body); - $result = [ - "message" => "Till next time, g.", - "type" => "TASK_LOGOUT", - ]; - return $result; - } - public static function requestSecret($body) - { - $result = Auth::findSecret($body); - return $result; - } - public static function resetPassword($body) - { - $result = Auth::makeNewPassword($body); - return $result; - } -} diff --git a/brain/api/v1/AuthAPI.php b/brain/api/v1/AuthAPI.php new file mode 100644 index 0000000..a95dd47 --- /dev/null +++ b/brain/api/v1/AuthAPI.php @@ -0,0 +1,79 @@ + "Authorized", + "type" => "apiUseAuthorized", + "token" => Session::get("token"), + ]; + } else { + $result = [ + "message" => "Not Authorized", + "type" => "apiUseNotAuthorized", + ]; + } + return $result; + } + + public static function login($body) + { + $result = []; + switch (Auth::login($body)) { + case "no_name": + $result = [ + "message" => "Need to see some id, champ", + "type" => "requestLame", + ]; + break; + case "bad_pass": + $result = [ + "message" => "Check your password, sport", + "type" => "requestLame", + ]; + break; + default: + $result = [ + "message" => "Welcome back", + "type" => "requestGood", + ]; + break; + } + + return $result; + } + + public static function logout($body) + { + Auth::logout($body); + $result = [ + "message" => "Till next time, g.", + "type" => "TASK_LOGOUT", + ]; + return $result; + } + public static function requestSecret($body) + { + $result = Auth::findSecret($body); + return $result; + } + public static function resetPassword($body) + { + $result = Auth::makeNewPassword($body); + return $result; + } +} diff --git a/brain/api/v1/ImagesAPI.inc.php b/brain/api/v1/ImagesAPI.inc.php deleted file mode 100644 index 1bfed8e..0000000 --- a/brain/api/v1/ImagesAPI.inc.php +++ /dev/null @@ -1,76 +0,0 @@ -getUploadedFiles(); - $uploadPath = ""; - $path = date("Y") . "/" . date("m"); - $response = []; - switch ($type) { - case "avatar": - $image = $file["avatar_upload"]; - $uploadPath = "../public/assets/images/user/" . $path; - break; - case "background": - $image = $file["background_upload"]; - $uploadPath = "../public/assets/images/user/" . $path; - break; - default: - $image = $file["post_image"]; - $path = date("Y") . "/" . date("m"); - $uploadPath = "../public/assets/images/blog/" . $path; - break; - } - - $result = FileUploader::uploadFile($uploadPath, $image); - - switch ($type) { - case "avatar": - $response = [ - "message" => "Avatar Added. You look great!", - "type" => "avatarUploaded", - "url" => - "/assets/images/user/" . $path . "/" . $image->getClientFileName(), - ]; - - //update member data - Member::updateData( - "avi", - "/assets/images/user/" . $path . "/" . $image->getClientFileName() - ); - - break; - case "background": - $response = [ - "message" => "Background plugged in. That's nice!", - "type" => "siteBackgroundUploaded", - "url" => - "/assets/images/user/" . $path . "/" . $image->getClientFileName(), - ]; - - //update settings file - Settings::updateGlobalData( - "background", - "/assets/images/user/" . $path . "/" . $image->getClientFileName() - ); - - break; - default: - $response = [ - "message" => "Image Added. Very slick", - "type" => "postImageAdded", - "url" => - "/assets/images/blog/" . $path . "/" . $image->getClientFileName(), - ]; - break; - } - - return $response; - } -} diff --git a/brain/api/v1/ImagesAPI.php b/brain/api/v1/ImagesAPI.php new file mode 100644 index 0000000..4329969 --- /dev/null +++ b/brain/api/v1/ImagesAPI.php @@ -0,0 +1,81 @@ +getUploadedFiles(); + $uploadPath = ""; + $path = date("Y") . "/" . date("m"); + $response = []; + switch ($type) { + case "avatar": + $image = $file["avatar_upload"]; + $uploadPath = "../public/assets/images/user/" . $path; + break; + case "background": + $image = $file["background_upload"]; + $uploadPath = "../public/assets/images/user/" . $path; + break; + default: + $image = $file["post_image"]; + $path = date("Y") . "/" . date("m"); + $uploadPath = "../public/assets/images/blog/" . $path; + break; + } + + $result = FileUploader::uploadFile($uploadPath, $image); + + switch ($type) { + case "avatar": + $response = [ + "message" => "Avatar Added. You look great!", + "type" => "avatarUploaded", + "url" => + "/assets/images/user/" . $path . "/" . $image->getClientFileName(), + ]; + + //update member data + Member::updateData( + "avi", + "/assets/images/user/" . $path . "/" . $image->getClientFileName() + ); + + break; + case "background": + $response = [ + "message" => "Background plugged in. That's nice!", + "type" => "siteBackgroundUploaded", + "url" => + "/assets/images/user/" . $path . "/" . $image->getClientFileName(), + ]; + + //update settings file + Settings::updateGlobalData( + "background", + "/assets/images/user/" . $path . "/" . $image->getClientFileName() + ); + + break; + default: + $response = [ + "message" => "Image Added. Very slick", + "type" => "postImageAdded", + "url" => + "/assets/images/blog/" . $path . "/" . $image->getClientFileName(), + ]; + break; + } + + return $response; + } +} diff --git a/brain/api/v1/InitAPI.inc.php b/brain/api/v1/InitAPI.inc.php deleted file mode 100644 index 871e068..0000000 --- a/brain/api/v1/InitAPI.inc.php +++ /dev/null @@ -1,30 +0,0 @@ - "blogInitFail", "message" => "Site already set up"]; - } else { - switch ($task) { - case "init": - $result = Setup::init($request); - break; - case "restore": - $result = Setup::restore($request); - break; - } - } - - return $result; - } -} diff --git a/brain/api/v1/InitAPI.php b/brain/api/v1/InitAPI.php new file mode 100644 index 0000000..4c67320 --- /dev/null +++ b/brain/api/v1/InitAPI.php @@ -0,0 +1,34 @@ + "blogInitFail", "message" => "Site already set up"]; + } else { + switch ($task) { + case "init": + $result = Setup::init($request); + break; + case "restore": + $result = Setup::restore($request); + break; + } + } + + return $result; + } +} diff --git a/brain/api/v1/MailerAPI.inc.php b/brain/api/v1/MailerAPI.inc.php deleted file mode 100644 index 669a5b5..0000000 --- a/brain/api/v1/MailerAPI.inc.php +++ /dev/null @@ -1,26 +0,0 @@ - "You need to be logged in for this, champ.", - "type" => "MAILER_ERROR", - ]; - } - } else { - } - - return $result; - } -} diff --git a/brain/api/v1/MailerAPI.php b/brain/api/v1/MailerAPI.php new file mode 100644 index 0000000..5eb4c36 --- /dev/null +++ b/brain/api/v1/MailerAPI.php @@ -0,0 +1,31 @@ + "You need to be logged in for this, champ.", + "type" => "MAILER_ERROR", + ]; + } + } else { + } + + return $result; + } +} diff --git a/brain/api/v1/PagesAPI.inc.php b/brain/api/v1/PagesAPI.inc.php deleted file mode 100644 index b8f15f0..0000000 --- a/brain/api/v1/PagesAPI.inc.php +++ /dev/null @@ -1,171 +0,0 @@ -getContents(); - $content = []; - foreach ($pages as $page) { - $entry = [ - "id" => $page["id"], - "uuid" => $page["uuid"], - "title" => $page["title"], - "feature" => $page["feature"], - "path" => $page["path"], - "layout" => $page["layout"], - "tags" => $page["tags"], - "author" => $page["author"], - "created" => $page["created"], - "updated" => $page["updated"], - "deleted" => $page["deleted"], - "menu" => $page["menu"], - "featured" => $page["featured"], - "published" => $page["published"], - "slug" => $page["slug"], - "content" => StringTools::sanitizeContent($page["content"]), - ]; - - array_push($content, $entry); - } - switch ($task) { - case "published": - $published = filter($content, function ($item) { - return $item["published"] == true && $item["deleted"] == false; - }); - - $result = ["pages" => $published, "totalItems" => count($published)]; - break; - case "featured": - $featured = filter($content, function ($item) { - return $item["featured"] == true && $item["deleted"] == false; - }); - - $result = [ - "pages" => $featured, - "totalItems" => count($featured), - ]; - break; - case "menu": - $menu = filter($content, function ($item) { - return $item["menu"] == true && $item["deleted"] == false; - }); - - $result = ["pages" => $menu, "totalItems" => count($menu)]; - break; - case "single": - $uuid = $args["fifth"]; - $page = (new Book("../content/pages"))->findPageById($uuid); - - $entry = [ - "id" => $page["id"], - "uuid" => $page["uuid"], - "title" => $page["title"], - "feature" => $page["feature"], - "path" => $page["path"], - "layout" => $page["layout"], - "tags" => $page["tags"], - "author" => $page["author"], - "created" => $page["created"], - "updated" => $page["updated"], - "deleted" => $page["deleted"], - "menu" => $page["menu"], - "featured" => $page["featured"], - "published" => $page["published"], - "slug" => $page["slug"], - "content" => StringTools::sanitizeContent($page["content"]), - ]; - $result = $entry; - break; - case "tags": - $result = Settings::getTags(); - break; - default: - $result = [ - "message" => "Hm, no task. That's unfortunate", - "type" => "TASK_NONE", - ]; - break; - } - return $result; - } - - public static function handlePageTask($request, $args) - { - $task = $args["fourth"]; - switch ($task) { - case "delete": - case "create": - case "write": - $body = $request->getParsedBody(); - $passed = true; - if (!isset($body["form_token"])) { - $result = [ - "message" => "No form token. Not good, sport.", - "type" => "TASK_FORM_AUTH", - ]; - } else { - if ($body["form_token"] == Session::get("form_token")) { - //TODO: Verify form fields - $keys = [ - "id", - "uuid", - "layout", - "current_title", - "content", - "title", - "created", - "slug", - "tags", - "menu", - "featured", - "published", - "form_token", - "feature_image", - ]; - - foreach ($body as $key => $item) { - if (!in_array($key, $keys)) { - //found unnecessary key, so reject submission - $passed = false; - } - } - if ($passed) { - $result = (new Book())->editPage($task, $request); - } else { - $result = [ - "message" => - "Unneccessary key found. Post not authorized, slick.", - "type" => "TASK_FORM_AUTH", - ]; - } - } else { - $result = [ - "message" => "Form token, auth failed. Uh oh.", - "type" => "TASK_FORM_AUTH", - ]; - } - } - - break; - case "add-entry-image": - $result = ImagesAPI::uploadImage($request); - break; - default: - $result = [ - "message" => "Hm, no task. That's unfortunate", - "type" => "TASK_NONE", - ]; - break; - } - - return $result; - } -} diff --git a/brain/api/v1/PagesAPI.php b/brain/api/v1/PagesAPI.php new file mode 100644 index 0000000..89f1d9f --- /dev/null +++ b/brain/api/v1/PagesAPI.php @@ -0,0 +1,180 @@ +getContents(); + $content = []; + foreach ($pages as $page) { + $entry = [ + "id" => $page["id"], + "uuid" => $page["uuid"], + "title" => $page["title"], + "feature" => $page["feature"], + "path" => $page["path"], + "layout" => $page["layout"], + "tags" => $page["tags"], + "author" => $page["author"], + "created" => $page["created"], + "updated" => $page["updated"], + "deleted" => $page["deleted"], + "menu" => $page["menu"], + "featured" => $page["featured"], + "published" => $page["published"], + "slug" => $page["slug"], + "content" => StringTools::sanitizeContent($page["content"]), + ]; + + array_push($content, $entry); + } + switch ($task) { + case "published": + $published = filter($content, function ($item) { + return $item["published"] == true && $item["deleted"] == false; + }); + + $result = ["pages" => $published, "totalItems" => count($published)]; + break; + case "featured": + $featured = filter($content, function ($item) { + return $item["featured"] == true && $item["deleted"] == false; + }); + + $result = [ + "pages" => $featured, + "totalItems" => count($featured), + ]; + break; + case "menu": + $menu = filter($content, function ($item) { + return $item["menu"] == true && $item["deleted"] == false; + }); + + $result = ["pages" => $menu, "totalItems" => count($menu)]; + break; + case "single": + $uuid = $args["fifth"]; + $page = (new Book("../content/pages"))->findPageById($uuid); + + $entry = [ + "id" => $page["id"], + "uuid" => $page["uuid"], + "title" => $page["title"], + "feature" => $page["feature"], + "path" => $page["path"], + "layout" => $page["layout"], + "tags" => $page["tags"], + "author" => $page["author"], + "created" => $page["created"], + "updated" => $page["updated"], + "deleted" => $page["deleted"], + "menu" => $page["menu"], + "featured" => $page["featured"], + "published" => $page["published"], + "slug" => $page["slug"], + "content" => StringTools::sanitizeContent($page["content"]), + ]; + $result = $entry; + break; + case "tags": + $result = Settings::getTags(); + break; + default: + $result = [ + "message" => "Hm, no task. That's unfortunate", + "type" => "TASK_NONE", + ]; + break; + } + return $result; + } + + public static function handlePageTask($request, $args) + { + $task = $args["fourth"]; + switch ($task) { + case "delete": + case "create": + case "write": + $body = $request->getParsedBody(); + $passed = true; + if (!isset($body["form_token"])) { + $result = [ + "message" => "No form token. Not good, sport.", + "type" => "TASK_FORM_AUTH", + ]; + } else { + if ($body["form_token"] == Session::get("form_token")) { + //TODO: Verify form fields + $keys = [ + "id", + "uuid", + "layout", + "current_title", + "content", + "title", + "created", + "slug", + "tags", + "menu", + "featured", + "published", + "form_token", + "feature_image", + ]; + + foreach ($body as $key => $item) { + if (!in_array($key, $keys)) { + //found unnecessary key, so reject submission + $passed = false; + } + } + if ($passed) { + $result = (new Book())->editPage($task, $request); + } else { + $result = [ + "message" => + "Unneccessary key found. Post not authorized, slick.", + "type" => "TASK_FORM_AUTH", + ]; + } + } else { + $result = [ + "message" => "Form token, auth failed. Uh oh.", + "type" => "TASK_FORM_AUTH", + ]; + } + } + + break; + case "add-entry-image": + $result = ImagesAPI::uploadImage($request); + break; + default: + $result = [ + "message" => "Hm, no task. That's unfortunate", + "type" => "TASK_NONE", + ]; + break; + } + + return $result; + } +} diff --git a/brain/api/v1/SettingsAPI.inc.php b/brain/api/v1/SettingsAPI.inc.php deleted file mode 100644 index 2474ff0..0000000 --- a/brain/api/v1/SettingsAPI.inc.php +++ /dev/null @@ -1,147 +0,0 @@ -getSettings(); - $theme = $settings["global"]["theme"]; - $themeConfig = json_decode( - file_get_contents("../content/themes/" . $theme . "/theme.json"), - true - ); - //check to see if dynamic rendering is active - if ( - isset($settings["global"]["dynamicRender"]) && - $settings["global"]["dynamicRender"] === "true" - ) { - $result = [ - "message" => "Dynamic Render Active! You're good!", - "type" => "RENDER_SUCCESS", - ]; - } else { - $render = new Render(); - if (isset($themeConfig["render"])) { - if (!$themeConfig["render"] || $themeConfig["render"] === "false") { - $render->renderIndex(); - $result = [ - "message" => "Index Rendered. HAND CLAPS", - "type" => "RENDER_SUCCESS", - ]; - } else { - $render->renderTags(); - $render->renderArchive(); - $render->renderPages(); - $result = [ - "message" => "Site Rendered. GOOD EFFORT", - "type" => "RENDER_SUCCESS", - ]; - } - } else { - // just incase the render flag is missing - $render->renderTags(); - $render->renderArchive(); - $render->renderPages(); - $result = [ - "message" => "Site Rendered. GOOD EFFORT", - "type" => "RENDER_SUCCESS", - ]; - } - } - - //if render flag is set and false, just render index page for one page sites - //otherwise, render all pages according to theme template files - - break; - case "add-avatar": - $result = ImagesAPI::uploadImage($request, "avatar"); - break; - case "add-feature-background": - $result = ImagesAPI::uploadImage($request, "background"); - break; - case "sync": - Settings::sync($body); - $result = [ - "message" => "Settings Synced. You're doing great!", - "type" => "settingsUpdated", - ]; - break; - case "nav-sync": - Settings::navSync($body); - $result = [ - "message" => "Navigation updated. Very slick!", - "type" => "menuUpdated", - ]; - break; - default: - $result = [ - "message" => "Hm, no task. That's unfortunate", - "type" => "TASK_NONE", - ]; - break; - } - - return $result; - } - - public static function getInfo($request, $args) - { - $task = $args["fourth"]; - switch ($task) { - case "site": - $config = new Settings(); - $settings = $config->getSettings(); - $data = [ - "title" => $settings["global"]["title"], - "base_url" => $settings["global"]["base_url"], - "description" => $settings["global"]["descriptions"], - ]; - $result = [ - "message" => "Settings Found", - "type" => "GET_SETTINGS", - "data" => $data, - ]; - break; - case "member": - if (Session::active()) { - $member = $member = Session::get("member"); - $data = ["handle" => $member["handle"], "email" => $member["email"]]; - $result = [ - "message" => "Member Info Found", - "type" => "GET_MEMBER_INFO", - "data" => $data, - ]; - } else { - $result = [ - "message" => "Not logged in. C'mon, bruh", - "type" => "TASK_NONE", - ]; - } - break; - default: - $result = [ - "message" => "No Settings found. Frowny Face", - "type" => "TASK_NONE", - ]; - break; - } - return $result; - } - - public static function createBackup() - { - $result = Maintenance::makeBackup(); - return $result; - } -} diff --git a/brain/api/v1/SettingsAPI.php b/brain/api/v1/SettingsAPI.php new file mode 100644 index 0000000..e2e4c7c --- /dev/null +++ b/brain/api/v1/SettingsAPI.php @@ -0,0 +1,154 @@ +getSettings(); + $theme = $settings["global"]["theme"]; + $themeConfig = json_decode( + file_get_contents("../content/themes/" . $theme . "/theme.json"), + true + ); + //check to see if dynamic rendering is active + if ( + isset($settings["global"]["dynamicRender"]) && + $settings["global"]["dynamicRender"] === "true" + ) { + $result = [ + "message" => "Dynamic Render Active! You're good!", + "type" => "RENDER_SUCCESS", + ]; + } else { + $render = new Render(); + if (isset($themeConfig["render"])) { + if (!$themeConfig["render"] || $themeConfig["render"] === "false") { + $render->renderIndex(); + $result = [ + "message" => "Index Rendered. HAND CLAPS", + "type" => "RENDER_SUCCESS", + ]; + } else { + $render->renderTags(); + $render->renderArchive(); + $render->renderPages(); + $result = [ + "message" => "Site Rendered. GOOD EFFORT", + "type" => "RENDER_SUCCESS", + ]; + } + } else { + // just incase the render flag is missing + $render->renderTags(); + $render->renderArchive(); + $render->renderPages(); + $result = [ + "message" => "Site Rendered. GOOD EFFORT", + "type" => "RENDER_SUCCESS", + ]; + } + } + + //if render flag is set and false, just render index page for one page sites + //otherwise, render all pages according to theme template files + + break; + case "add-avatar": + $result = ImagesAPI::uploadImage($request, "avatar"); + break; + case "add-feature-background": + $result = ImagesAPI::uploadImage($request, "background"); + break; + case "sync": + Settings::sync($body); + $result = [ + "message" => "Settings Synced. You're doing great!", + "type" => "settingsUpdated", + ]; + break; + case "nav-sync": + Settings::navSync($body); + $result = [ + "message" => "Navigation updated. Very slick!", + "type" => "menuUpdated", + ]; + break; + default: + $result = [ + "message" => "Hm, no task. That's unfortunate", + "type" => "TASK_NONE", + ]; + break; + } + + return $result; + } + + public static function getInfo($request, $args) + { + $task = $args["fourth"]; + switch ($task) { + case "site": + $config = new Settings(); + $settings = $config->getSettings(); + $data = [ + "title" => $settings["global"]["title"], + "base_url" => $settings["global"]["base_url"], + "description" => $settings["global"]["descriptions"], + ]; + $result = [ + "message" => "Settings Found", + "type" => "GET_SETTINGS", + "data" => $data, + ]; + break; + case "member": + if (Session::active()) { + $member = $member = Session::get("member"); + $data = ["handle" => $member["handle"], "email" => $member["email"]]; + $result = [ + "message" => "Member Info Found", + "type" => "GET_MEMBER_INFO", + "data" => $data, + ]; + } else { + $result = [ + "message" => "Not logged in. C'mon, bruh", + "type" => "TASK_NONE", + ]; + } + break; + default: + $result = [ + "message" => "No Settings found. Frowny Face", + "type" => "TASK_NONE", + ]; + break; + } + return $result; + } + + public static function createBackup() + { + $result = Maintenance::makeBackup(); + return $result; + } +} diff --git a/brain/controller/APIControl.inc.php b/brain/controller/APIControl.inc.php deleted file mode 100644 index 7ecbbee..0000000 --- a/brain/controller/APIControl.inc.php +++ /dev/null @@ -1,227 +0,0 @@ - "API access denied, homie", - "type" => "API_ERROR", - ]; - } - break; - case "settings": - $token = $request->getHeader("fipamo-access-token"); - //Verify token to get site info - if (isset($token[0])) { - if (Session::verifyToken($token[0])) { - $result = SettingsAPI::getInfo($request, $args); - } else { - $result = [ - "message" => "Invalid token, API access denied, homie", - "type" => "API_ERROR", - ]; - } - } else { - $result = [ - "message" => "No token, API access denied, homie", - "type" => "API_ERROR", - ]; - } - break; - case "files": - if (Session::active()) { - if ($args["third"] == "backup") { - $filename = "../config/backups/latest_backup.zip"; - if (file_exists($filename)) { - header("Content-Type: application/zip"); - header( - 'Content-Disposition: attachment; filename="' . - basename($filename) . - '"' - ); - header("Content-Length: " . filesize($filename)); - - flush(); - // return readfile($filename); - //readfile($filename); - // delete file - //unlink($filename); - } - } - } else { - $result = [ - "message" => "API access denied, homie", - "type" => "API_ERROR", - ]; - } - default: - break; - } - - $freshResponse = $response; - - if ($args["third"] == "files") { - $freshResponse - ->getBody() - ->write(file_get_contents("../config/backups/latest_back.zip")); - - $freshResponse->withHeader("Content-Type", "application/zip"); - return $freshResponse->withAddedHeader( - "Content-Disposition", - "attachment; filename=latest_backup.zip" - ); - } else { - $response->getBody()->write(json_encode($result)); - return $response->withHeader("Content-Type", "application/json"); - } - } - public static function post( - ServerRequestInterface $request, - ResponseInterface $response, - array $args - ): ResponseInterface { - $contentType = $request->getHeader("Content-Type"); - switch ($contentType[0]) { - case "application/json": - $body = json_decode(file_get_contents("php://input"), true); - break; - default: - break; - } - - switch (isset($args["third"]) ? $args["third"] : "none") { - case "restore": //move to 'api/auth' - case "init": //move to 'api/auth' - $task = $args["third"]; - $result = InitApi::handleInitTasks( - $task, - $task == "init" ? $body : $request - ); - break; - case "backup": //move to 'api/auth' - $token = $request->getHeader("fipamo-access-token"); - //Verify token for admin tasks - $result = SettingsAPI::createBackup(); - /* - - if (Session::verifyToken($token[0])) { - $result = SettingsAPI::createBackup(); - } else { - $result = [ - "message" => "API access denied, homie", - "type" => "API_ERROR", - ]; - } - */ - break; - case "login": //move to 'api/auth' - //check if request is remote and if so, verify token - if ($body["remote"] || $body["remote"] == "true") { - if (Member::verifyKey($body["key"])) { - $result = AuthAPI::login($body); - } else { - $result = [ - "message" => "API access denied, homie", - "type" => "API_ERROR", - ]; - } - } else { - //request is local, so it's cool - $result = AuthAPI::login($body); - } - - break; - case "logout": //move to 'api/auth' - $result = AuthAPI::logout($body); - break; - case "get-secret": //move to 'api/auth' - $result = AuthAPI::requestSecret($body); - break; - case "reset-password": //move to 'api/auth' - $result = AuthAPI::resetPassword($body); - break; - case "page": - $token = $request->getHeader("fipamo-access-token"); - //Verify token for admin tasks - if (isset($token[0])) { - if (Session::verifyToken($token[0])) { - $result = PagesAPI::handlePageTask($request, $args); - } else { - $result = [ - "message" => "Invalid token, API access denied, homie", - "type" => "API_ERROR", - ]; - } - } else { - $result = [ - "message" => "No token, API access denied, homie", - "type" => "API_ERROR", - ]; - } - - break; - case "settings": - if (isset($body)) { - $postBody = $body; - } else { - $postBody = null; - } - $task = $args["fourth"]; - if ($task == "add-feature-background" || $task == "add-avatar") { - $result = SettingsAPI::handleSettingsTask($request, $args, $postBody); - } else { - $token = $request->getHeader("fipamo-access-token"); - if (Session::verifyToken($token[0])) { - $result = SettingsAPI::handleSettingsTask( - $request, - $args, - $postBody - ); - } else { - $result = [ - "message" => "API access denied, homie", - "type" => "API_ERROR", - ]; - } - } - - break; - case "mailer": - $result = MailerAPI::handleMail($request, $body, $response); - break; - default: - $result = [ - "message" => "Oh, nothing to do. That's unfortunate", - "type" => "TASK_NONE", - ]; - break; - } - - $response->getBody()->write(json_encode($result)); - return $response->withHeader("Content-Type", "application/json"); - } -} diff --git a/brain/controller/APIControl.php b/brain/controller/APIControl.php new file mode 100644 index 0000000..ad20f2b --- /dev/null +++ b/brain/controller/APIControl.php @@ -0,0 +1,232 @@ + "API access denied, homie", + "type" => "API_ERROR", + ]; + } + break; + case "settings": + $token = $request->getHeader("fipamo-access-token"); + //Verify token to get site info + if (isset($token[0])) { + if (Session::verifyToken($token[0])) { + $result = SettingsAPI::getInfo($request, $args); + } else { + $result = [ + "message" => "Invalid token, API access denied, homie", + "type" => "API_ERROR", + ]; + } + } else { + $result = [ + "message" => "No token, API access denied, homie", + "type" => "API_ERROR", + ]; + } + break; + case "files": + if (Session::active()) { + if ($args["third"] == "backup") { + $filename = "../config/backups/latest_backup.zip"; + if (file_exists($filename)) { + header("Content-Type: application/zip"); + header( + 'Content-Disposition: attachment; filename="' . + basename($filename) . + '"' + ); + header("Content-Length: " . filesize($filename)); + + flush(); + // return readfile($filename); + //readfile($filename); + // delete file + //unlink($filename); + } + } + } else { + $result = [ + "message" => "API access denied, homie", + "type" => "API_ERROR", + ]; + } + // no break + default: + break; + } + + $freshResponse = $response; + + if ($args["third"] == "files") { + $freshResponse + ->getBody() + ->write(file_get_contents("../config/backups/latest_back.zip")); + + $freshResponse->withHeader("Content-Type", "application/zip"); + return $freshResponse->withAddedHeader( + "Content-Disposition", + "attachment; filename=latest_backup.zip" + ); + } else { + $response->getBody()->write(json_encode($result)); + return $response->withHeader("Content-Type", "application/json"); + } + } + public static function post( + ServerRequestInterface $request, + ResponseInterface $response, + array $args + ): ResponseInterface { + $contentType = $request->getHeader("Content-Type"); + switch ($contentType[0]) { + case "application/json": + $body = json_decode(file_get_contents("php://input"), true); + break; + default: + break; + } + + switch (isset($args["third"]) ? $args["third"] : "none") { + case "restore": //move to 'api/auth' + case "init": //move to 'api/auth' + $task = $args["third"]; + $result = InitApi::handleInitTasks( + $task, + $task == "init" ? $body : $request + ); + break; + case "backup": //move to 'api/auth' + $token = $request->getHeader("fipamo-access-token"); + //Verify token for admin tasks + $result = SettingsAPI::createBackup(); + /* + + if (Session::verifyToken($token[0])) { + $result = SettingsAPI::createBackup(); + } else { + $result = [ + "message" => "API access denied, homie", + "type" => "API_ERROR", + ]; + } + */ + break; + case "login": //move to 'api/auth' + //check if request is remote and if so, verify token + if ($body["remote"] || $body["remote"] == "true") { + if (Member::verifyKey($body["key"])) { + $result = AuthAPI::login($body); + } else { + $result = [ + "message" => "API access denied, homie", + "type" => "API_ERROR", + ]; + } + } else { + //request is local, so it's cool + $result = AuthAPI::login($body); + } + + break; + case "logout": //move to 'api/auth' + $result = AuthAPI::logout($body); + break; + case "get-secret": //move to 'api/auth' + $result = AuthAPI::requestSecret($body); + break; + case "reset-password": //move to 'api/auth' + $result = AuthAPI::resetPassword($body); + break; + case "page": + $token = $request->getHeader("fipamo-access-token"); + //Verify token for admin tasks + if (isset($token[0])) { + if (Session::verifyToken($token[0])) { + $result = PagesAPI::handlePageTask($request, $args); + } else { + $result = [ + "message" => "Invalid token, API access denied, homie", + "type" => "API_ERROR", + ]; + } + } else { + $result = [ + "message" => "No token, API access denied, homie", + "type" => "API_ERROR", + ]; + } + + break; + case "settings": + if (isset($body)) { + $postBody = $body; + } else { + $postBody = null; + } + $task = $args["fourth"]; + if ($task == "add-feature-background" || $task == "add-avatar") { + $result = SettingsAPI::handleSettingsTask($request, $args, $postBody); + } else { + $token = $request->getHeader("fipamo-access-token"); + if (Session::verifyToken($token[0])) { + $result = SettingsAPI::handleSettingsTask( + $request, + $args, + $postBody + ); + } else { + $result = [ + "message" => "API access denied, homie", + "type" => "API_ERROR", + ]; + } + } + + break; + case "mailer": + $result = MailerAPI::handleMail($request, $body, $response); + break; + default: + $result = [ + "message" => "Oh, nothing to do. That's unfortunate", + "type" => "TASK_NONE", + ]; + break; + } + + $response->getBody()->write(json_encode($result)); + return $response->withHeader("Content-Type", "application/json"); + } +} diff --git a/brain/controller/DashControl.inc.php b/brain/controller/DashControl.inc.php deleted file mode 100644 index 360bedc..0000000 --- a/brain/controller/DashControl.inc.php +++ /dev/null @@ -1,189 +0,0 @@ -getSettings(); - $themes = (new Themes())->getThemes(); //$config->getThemes(); - $template = "dash/settings.twig"; - $member = Session::get("member"); - $form_token = Session::get("form_token"); - $updated = new \Moment\Moment($settings["global"]["last_backup"]); - $pageOptions = [ - "title" => "Dash Settings", - "private" => $settings["global"]["private"], - "renderOnSave" => $settings["global"]["renderOnSave"], - "background" => $settings["global"]["background"], - "member" => $member, - "ftoken" => $form_token, - "siteTitle" => $settings["global"]["title"], - "baseUrl" => $settings["global"]["base_url"], - "desc" => $settings["global"]["descriptions"], - "lastBackup" => $updated->format("Y M D d"), - "currentTheme" => $settings["global"]["theme"], - "themes" => $themes, - "apiStatus" => isset($settings["global"]["externalAPI"]) - ? $settings["global"]["externalAPI"] - : "false", - "dynamicRenderStatus" => isset( - $settings["global"]["dynamicRender"] - ) - ? $settings["global"]["dynamicRender"] - : "false", - "mailOption" => $settings["email"]["active"], - "mailConfig" => $settings["email"], - "status" => Session::active(), - ]; - } else { - header("Location: /dashboard"); - die(); - } - - break; - case "navigation": - if (Session::active()) { - $config = new Settings(); - $settings = $config->getSettings(); - $template = "dash/navigation.twig"; - $pageOptions = [ - "title" => "Edit Dash Navigation", - "status" => Session::active(), - "menu" => $settings["menu"], - ]; - } else { - header("Location: /dashboard"); - die(); - } - break; - case "pages": - if (Session::active()) { - $currentPage = isset($args["fourth"]) ? $args["fourth"] : 1; - $filter = isset($args["third"]) ? $args["third"] : "all"; - $data = (new Book())->getPages($currentPage, 4, $filter); - $template = "dash/book.twig"; - $pageOptions = [ - "entryCount" => $data["entryCount"], - "numOfPages" => $data["numOfPages"], - "currentPage" => $currentPage, - "filter" => $data["paginate"]["sort"], - "stats" => $data["stats"], - "pages" => $data["pages"], - "paginate" => $data["paginate"], - "status" => Session::active(), - ]; - } else { - header("Location: /dashboard"); - die(); - } - break; - case "page": - if (Session::active()) { - $template = "dash/page-edit.twig"; - $mode = $args["third"]; - $uuid = $args["fourth"]; - - switch ($mode) { - case "edit": - $page = (new Book())->findPageById($uuid); - $views = []; - if (str_contains($page["layout"], "index")) { - $views = (new Themes())->getCustomIndex(); - } else { - $views = (new Themes())->getCustomViews(); - } - $pageOptions = [ - "title" => "Fipamo | Edit Page", - "page" => $page, - "mode" => $mode, - "token" => Session::get("form_token"), - "status" => Session::active(), - "views" => $views, - ]; - break; - case "preview": - $config = new Settings(); - $settings = $config->getSettings(); - $loader = new \Twig\Loader\FilesystemLoader( - "../content/themes" - ); - $display = new \Twig\Environment($loader, []); - - $book = new Book(); - $page = $book->findPageById($uuid); - $pageOptions = Sorting::page($page); - $preview = - $settings["global"]["theme"] . - "/" . - $page["layout"] . - ".twig"; - $html = $display->render($preview, $pageOptions); - $response->getBody()->write($html); - return $response; - break; - default: - $pageOptions = [ - "title" => "Fipamo | Create Page", - "token" => Session::get("form_token"), - "mode" => $mode, - "status" => Session::active(), - ]; - break; - } - } else { - header("Location: /dashboard"); - die(); - } - break; - case "logout": - Session::kill(); - header("Location: /dashboard"); - die(); - break; - case "reset-password": - $template = "dash/reset-password.twig"; - $pageOptions = [ - "title" => "Reset Password", - ]; - break; - - default: - $template = "dash/start.twig"; - if (Session::active()) { - $pageOptions = [ - "title" => "Welcome Back", - "status" => Session::active(), - "data" => (new Book())->getPages(1, 4), - ]; - } else { - $pageOptions = [ - "title" => "Welcome to Fipamo", - "status" => Session::active(), - ]; - } - break; - } - } else { - $template = "dash/init.twig"; - $pageOptions = ["title" => "Fipamo Setup"]; - } - - return $view->render($response, $template, $pageOptions); - } -} diff --git a/brain/controller/DashControl.php b/brain/controller/DashControl.php new file mode 100644 index 0000000..c75a724 --- /dev/null +++ b/brain/controller/DashControl.php @@ -0,0 +1,218 @@ +getSettings(); + $themes = (new Themes())->getThemes(); // $config->getThemes(); + $template = 'dash/settings.twig'; + $member = Session::get('member'); + $form_token = Session::get('form_token'); + $updated = new \Moment\Moment($settings['global']['last_backup']); + $pageOptions = [ + 'title' => 'Dash Settings', + 'private' => $settings['global']['private'], + 'renderOnSave' => $settings['global']['renderOnSave'], + 'background' => $settings['global']['background'], + 'member' => $member, + 'ftoken' => $form_token, + 'siteTitle' => $settings['global']['title'], + 'baseUrl' => $settings['global']['base_url'], + 'desc' => $settings['global']['descriptions'], + 'lastBackup' => $updated->format('Y M D d'), + 'currentTheme' => $settings['global']['theme'], + 'themes' => $themes, + 'apiStatus' => isset($settings['global']['externalAPI']) + ? $settings['global']['externalAPI'] + : 'false', + 'dynamicRenderStatus' => isset( + $settings['global']['dynamicRender'] + ) + ? $settings['global']['dynamicRender'] + : 'false', + 'mailOption' => $settings['email']['active'], + 'mailConfig' => $settings['email'], + 'status' => Session::active(), + ]; + } else { + header('Location: /dashboard'); + exit(); + } + + break; + case 'navigation': + if (Session::active()) { + $config = new Settings(); + $settings = $config->getSettings(); + $template = 'dash/navigation.twig'; + $pageOptions = [ + 'title' => 'Edit Dash Navigation', + 'status' => Session::active(), + 'menu' => $settings['menu'], + ]; + } else { + header('Location: /dashboard'); + exit(); + } + break; + case 'pages': + if (Session::active()) { + $currentPage = isset($args['fourth']) ? $args['fourth'] : 1; + $filter = isset($args['third']) ? $args['third'] : 'all'; + $data = (new Book())->getPages($currentPage, 4, $filter); + $template = 'dash/book.twig'; + $pageOptions = [ + 'title' => 'Contents', + 'entryCount' => $data['entryCount'], + 'numOfPages' => $data['numOfPages'], + 'currentPage' => $currentPage, + 'filter' => $data['paginate']['sort'], + 'stats' => $data['stats'], + 'pages' => $data['pages'], + 'paginate' => $data['paginate'], + 'status' => Session::active(), + ]; + } else { + header('Location: /dashboard'); + exit(); + } + break; + case 'page': + if (Session::active()) { + $template = 'dash/page-edit.twig'; + $mode = $args['third']; + $uuid = $args['fourth']; + + switch ($mode) { + case 'edit': + $page = (new Book())->findPageById($uuid); + $views = []; + if (str_contains($page['layout'], 'index')) { + $views = (new Themes())->getCustomIndex(); + } else { + $views = (new Themes())->getCustomViews(); + } + + $imageList = explode(',', $page['feature']); + $fileList = explode(',', $page['files']); + + $images = []; + $files = []; + foreach ($imageList as $item) { + $image = trim($item); + if (!empty($image)) { + array_push($images, $image); + } + } + + foreach ($fileList as $item) { + $file = trim($item); + if (!empty($file)) { + array_push($files, $file); + } + } + + $pageOptions = [ + 'title' => 'Fipamo | Edit Page', + 'page' => $page, + 'mode' => $mode, + 'token' => Session::get('form_token'), + 'status' => Session::active(), + 'images' => $images, + 'files' => $files, + 'views' => $views, + ]; + break; + case 'preview': + $config = new Settings(); + $settings = $config->getSettings(); + $loader = new \Twig\Loader\FilesystemLoader( + '../content/themes' + ); + $display = new \Twig\Environment($loader, []); + + $book = new Book(); + $page = $book->findPageById($uuid); + $pageOptions = Sorting::page($page); + $preview = + $settings['global']['theme']. + '/'. + $page['layout']. + '.twig'; + $html = $display->render($preview, $pageOptions); + $response->getBody()->write($html); + + return $response; + break; + default: + $pageOptions = [ + 'title' => 'Fipamo | Create Page', + 'token' => Session::get('form_token'), + 'mode' => $mode, + 'status' => Session::active(), + ]; + break; + } + } else { + header('Location: /dashboard'); + exit(); + } + break; + case 'logout': + Session::kill(); + header('Location: /dashboard'); + exit(); + break; + case 'reset-password': + $template = 'dash/reset-password.twig'; + $pageOptions = [ + 'title' => 'Reset Password', + ]; + break; + default: + $template = 'dash/start.twig'; + if (Session::active()) { + $pageOptions = [ + 'title' => 'Welcome Back', + 'status' => Session::active(), + 'data' => (new Book())->getPages(1, 4), + ]; + } else { + $pageOptions = [ + 'title' => 'Welcome to Fipamo', + 'status' => Session::active(), + ]; + } + break; + } + } else { + $template = 'dash/init.twig'; + $pageOptions = ['title' => 'Fipamo Setup']; + } + + return $view->render($response, $template, $pageOptions); + } +} diff --git a/brain/controller/IndexControl.inc.php b/brain/controller/IndexControl.inc.php deleted file mode 100644 index 615c4e6..0000000 --- a/brain/controller/IndexControl.inc.php +++ /dev/null @@ -1,107 +0,0 @@ -getSettings(); - $view = Twig::fromRequest($request); - //checks dynamic render flag for site render status - if ($settings["global"]["dynamicRender"]) { - if ($settings["global"]["dynamicRender"] == "true") { - $loader = new \Twig\Loader\FilesystemLoader("../content/themes"); - $display = new \Twig\Environment($loader, []); - $template = ""; - $pageOptions = []; - - $pageInfo = [ - "keywords" => isset($settings["global"]["keywords"]) - ? $settings["global"]["keywords"] - : "fipamo, blog, jamstack, php, markdown, js", - "description" => $settings["global"]["descriptions"], - "image" => - $settings["global"]["base_url"] . $settings["global"]["background"], - "baseURL" => $settings["global"]["base_url"], - ]; - - if (isset($args["first"])) { - switch ($args["first"]) { - case "tags": - $template = $settings["global"]["theme"] . "/tags.twig"; - $tag = trim($args["second"]); - $taglist = Sorting::tags(); - $item = find($taglist, ["tag_name" => $tag]); - $pageOptions = [ - "title" => "Pages Tagged as " . $item["tag_name"], - "background" => $pageInfo["image"], - "tag_list" => $item["pages"], - "info" => $pageInfo, - "menu" => $settings["menu"], - "dynamicRender" => $settings["global"]["dynamicRender"], - ]; - break; - case "archives": - $archive = Sorting::archive(); - $template = $settings["global"]["theme"] . "/archive.twig"; - $pageOptions = [ - "title" => "Archive", - "background" => $pageInfo["image"], - "archives" => $archive, - "info" => $pageInfo, - "menu" => $settings["menu"], - "dynamicRender" => $settings["global"]["dynamicRender"], - ]; - - break; - default: - //check if page is a menu item, if not render along path as usual - $page = []; - $book = new Book(); - if (is_numeric($args["first"])) { - $page = $book->findPageBySlug($args["third"]); - } else { - $page = $book->findPageBySlug($args["first"]); - } - $template = - $settings["global"]["theme"] . "/" . $page["layout"] . ".twig"; - $pageOptions = Sorting::page($page); - - break; - } - } else { - //index - $template = - $settings["global"]["theme"] . "/" . $page["layout"] . ".twig"; - $book = new Book(""); - $page = $book->findPageBySlug(); - $pageOptions = Sorting::page($page); - } - - $html = $display->render($template, $pageOptions); - $response->getBody()->write($html); - return $response; - } else { - //if dynamic flag is false, load up html - $view = Twig::fromRequest($request); - $html = file_get_contents("../public/index.html"); - $response->getBody()->write($html); - return $response; - } - } else { - //if flag is not present, default to static html - $view = Twig::fromRequest($request); - $html = file_get_contents("../public/index.html"); - $response->getBody()->write($html); - return $response; - } - } -} diff --git a/brain/controller/IndexControl.php b/brain/controller/IndexControl.php new file mode 100644 index 0000000..07fab53 --- /dev/null +++ b/brain/controller/IndexControl.php @@ -0,0 +1,113 @@ +getSettings(); + $view = Twig::fromRequest($request); + //checks dynamic render flag for site render status + if ($settings["global"]["dynamicRender"]) { + if ($settings["global"]["dynamicRender"] == "true") { + $loader = new \Twig\Loader\FilesystemLoader("../content/themes"); + $display = new \Twig\Environment($loader, []); + $template = ""; + $pageOptions = []; + + $pageInfo = [ + "keywords" => isset($settings["global"]["keywords"]) + ? $settings["global"]["keywords"] + : "fipamo, blog, jamstack, php, markdown, js", + "description" => $settings["global"]["descriptions"], + "image" => + $settings["global"]["base_url"] . $settings["global"]["background"], + "baseURL" => $settings["global"]["base_url"], + ]; + + if (isset($args["first"])) { + switch ($args["first"]) { + case "tags": + $template = $settings["global"]["theme"] . "/tags.twig"; + $tag = trim($args["second"]); + $taglist = Sorting::tags(); + $item = find($taglist, ["tag_name" => $tag]); + $pageOptions = [ + "title" => "Pages Tagged as " . $item["tag_name"], + "background" => $pageInfo["image"], + "tag_list" => $item["pages"], + "info" => $pageInfo, + "menu" => $settings["menu"], + "dynamicRender" => $settings["global"]["dynamicRender"], + ]; + break; + case "archives": + $archive = Sorting::archive(); + $template = $settings["global"]["theme"] . "/archive.twig"; + $pageOptions = [ + "title" => "Archive", + "background" => $pageInfo["image"], + "archives" => $archive, + "info" => $pageInfo, + "menu" => $settings["menu"], + "dynamicRender" => $settings["global"]["dynamicRender"], + ]; + + break; + default: + //check if page is a menu item, if not render along path as usual + $page = []; + $book = new Book(); + if (is_numeric($args["first"])) { + $page = $book->findPageBySlug($args["third"]); + } else { + $page = $book->findPageBySlug($args["first"]); + } + $template = + $settings["global"]["theme"] . "/" . $page["layout"] . ".twig"; + $pageOptions = Sorting::page($page); + + break; + } + } else { + //index + $template = + $settings["global"]["theme"] . "/" . $page["layout"] . ".twig"; + $book = new Book(""); + $page = $book->findPageBySlug(); + $pageOptions = Sorting::page($page); + } + + $html = $display->render($template, $pageOptions); + $response->getBody()->write($html); + return $response; + } else { + //if dynamic flag is false, load up html + $view = Twig::fromRequest($request); + $html = file_get_contents("../public/index.html"); + $response->getBody()->write($html); + return $response; + } + } else { + //if flag is not present, default to static html + $view = Twig::fromRequest($request); + $html = file_get_contents("../public/index.html"); + $response->getBody()->write($html); + return $response; + } + } +} diff --git a/brain/controller/RouteControl.inc.php b/brain/controller/RouteControl.inc.php deleted file mode 100644 index b207b1f..0000000 --- a/brain/controller/RouteControl.inc.php +++ /dev/null @@ -1,44 +0,0 @@ -secret; - } - - public static function status() - { - $result = ""; - if (Session::active()) { - $result = true; - } else { - $result = false; - } - return $result; - } - - public static function login($who) - { - //grab member list - $folks = (new Settings())->getFolks(); - $found = find($folks, ["handle" => $who["handle"]]); - - if ($found) { - //name is found, verify password - if (password_verify($who["password"], $found["password"])) { - $member = [ - "handle" => $found["handle"], - "email" => $found["email"], - "role" => $found["role"], - "avatar" => $found["avi"], - "key" => $found["key"], - ]; - - $token = Token::create( - $found["key"], - $found["secret"], - time() + 3600, - "localhost" - ); //expires in an hour - - $form_token = md5(uniqid(microtime(), true)); - Session::start(); - Session::set("member", $member); - Session::set("token", $token); - Session::set("form_token", $form_token); - - $result = "good_login"; - } else { - $result = "bad_pass"; - } - } else { - //if name is not found - $result = "no_name"; - } - return $result; - } - - public static function findSecret($data) - { - $result = []; - $folks = (new Settings())->getFolks(); - - if ( - !empty($data["email"]) && - filter_var($data["email"], FILTER_VALIDATE_EMAIL) - ) { - $found = find($folks, ["email" => $data["email"]]); - if ($found) { - //if email is cool, check mail relay status - //if set up, send secret there, if not just return it - $config = new Settings(); - $settings = $config->getSettings(); - $email = $settings["email"]["active"]; - if ($email != "option-none") { - $data["mail_task"] = "SEND_SECRET"; - $data["secret"] = $found["secret"]; - $result = Mailer::sendmail($data); - } else { - $result = [ - "message" => "Valid email, but no email set up!", - "type" => "secretFound", - "secret" => $found["secret"], - ]; - } - } else { - $result = [ - "message" => "No valid email, no goodies, pleighboi", - "type" => "secretNotFound", - ]; - } - } else { - $result = [ - "message" => "Aye, this address is not right, slick.", - "type" => "secretNotFound", - ]; - } - - return $result; - } - - public static function makeNewPassword($data) - { - //check if passwordsmatch - if ($data["newPass"] == $data["newPassConfirm"]) { - //verify secret - $folks = (new Settings())->getFolks(); - $found = find($folks, ["secret" => $data["secret"]]); - if ($found) { - //create new pass and secret key, then update file - $hash = password_hash($data["newPass"], PASSWORD_DEFAULT); - $freshSecret = StringTools::randomString(12); - Member::updateData("password", $hash, $data["secret"]); - Member::updateData("secret", $freshSecret, $data["secret"]); - $result = [ - "message" => "Password Updated. Very nice!", - "type" => "passCreated", - ]; - } else { - $result = [ - "message" => "Secret key is invalid. Try to retrieve it again", - "type" => "passNotCreated", - ]; - } - } else { - $result = [ - "message" => "Passwords don't match. Try it again.", - "type" => "passNotCreated", - ]; - } - - return $result; - } - - public static function logout() - { - Session::kill(); - } -} diff --git a/brain/data/Auth.php b/brain/data/Auth.php new file mode 100644 index 0000000..fa2444c --- /dev/null +++ b/brain/data/Auth.php @@ -0,0 +1,159 @@ +secret; + } + + public static function status() + { + $result = ""; + if (Session::active()) { + $result = true; + } else { + $result = false; + } + return $result; + } + + public static function login($who) + { + //grab member list + $folks = (new Settings())->getFolks(); + $found = find($folks, ["handle" => $who["handle"]]); + + if ($found) { + //name is found, verify password + if (password_verify($who["password"], $found["password"])) { + $member = [ + "handle" => $found["handle"], + "email" => $found["email"], + "role" => $found["role"], + "avatar" => $found["avi"], + "key" => $found["key"], + ]; + + $token = Token::create( + $found["key"], + $found["secret"], + time() + 3600, + "localhost" + ); //expires in an hour + + $form_token = md5(uniqid(microtime(), true)); + Session::start(); + Session::set("member", $member); + Session::set("token", $token); + Session::set("form_token", $form_token); + + $result = "good_login"; + } else { + $result = "bad_pass"; + } + } else { + //if name is not found + $result = "no_name"; + } + return $result; + } + + public static function findSecret($data) + { + $result = []; + $folks = (new Settings())->getFolks(); + + if ( + !empty($data["email"]) && + filter_var($data["email"], FILTER_VALIDATE_EMAIL) + ) { + $found = find($folks, ["email" => $data["email"]]); + if ($found) { + //if email is cool, check mail relay status + //if set up, send secret there, if not just return it + $config = new Settings(); + $settings = $config->getSettings(); + $email = $settings["email"]["active"]; + if ($email != "option-none") { + $data["mail_task"] = "SEND_SECRET"; + $data["secret"] = $found["secret"]; + $result = Mailer::sendmail($data); + } else { + $result = [ + "message" => "Valid email, but no email set up!", + "type" => "secretFound", + "secret" => $found["secret"], + ]; + } + } else { + $result = [ + "message" => "No valid email, no goodies, pleighboi", + "type" => "secretNotFound", + ]; + } + } else { + $result = [ + "message" => "Aye, this address is not right, slick.", + "type" => "secretNotFound", + ]; + } + + return $result; + } + + public static function makeNewPassword($data) + { + //check if passwordsmatch + if ($data["newPass"] == $data["newPassConfirm"]) { + //verify secret + $folks = (new Settings())->getFolks(); + $found = find($folks, ["secret" => $data["secret"]]); + if ($found) { + //create new pass and secret key, then update file + $hash = password_hash($data["newPass"], PASSWORD_DEFAULT); + $freshSecret = StringTools::randomString(12); + Member::updateData("password", $hash, $data["secret"]); + Member::updateData("secret", $freshSecret, $data["secret"]); + $result = [ + "message" => "Password Updated. Very nice!", + "type" => "passCreated", + ]; + } else { + $result = [ + "message" => "Secret key is invalid. Try to retrieve it again", + "type" => "passNotCreated", + ]; + } + } else { + $result = [ + "message" => "Passwords don't match. Try it again.", + "type" => "passNotCreated", + ]; + } + + return $result; + } + + public static function logout() + { + Session::kill(); + } +} diff --git a/brain/data/Book.inc.php b/brain/data/Book.inc.php deleted file mode 100644 index e9cec78..0000000 --- a/brain/data/Book.inc.php +++ /dev/null @@ -1,265 +0,0 @@ -getContents(); - $page = find($content, ["uuid" => $uuid]); - return $page; - } - - public function findPageBySlug(string $slug = null) - { - $content = $this->getContents(); - if (isset($slug)) { - $page = find($content, ["slug" => $slug]); - } else { - $page = find($content, ["layout" => "index"]); - } - - return $page; - } - - public function editPage($task, $request) - { - $content = $this->getContents(); - if ($task == "delete") { - //$parsed = json_decode(file_get_contents("php://input"), true); - //$body = find($content, ["uuid" => $parsed["id"]]); - $body = $request->getParsedBody(); - } else { - $body = $request->getParsedBody(); - } - - $page = find($content, ["uuid" => $body["uuid"]]); - $image = $request->getUploadedFiles(); - $member = Session::get("member"); - - if ($task != "create") { - $path = - date("Y", date($page["rawCreated"])) . - "/" . - date("m", date($page["rawCreated"])); - } else { - $path = date("Y") . "/" . date("m"); - } - - if (isset($image["feature_image"])) { - if ($task != "create") { - $feature = - "/assets/images/blog/" . - $path . - "/" . - $image["feature_image"]->getClientFileName(); - } else { - $feature = - "/assets/images/blog/" . - $path . - "/" . - $image["feature_image"]->getClientFileName(); - } - - FileUploader::uploadFile( - "../public/assets/images/blog/" . $path . "/", - $image["feature_image"] - ); - } else { - if (isset($body["feature_image"])) { - $url = explode("/", $body["feature_image"]); - $feature = - "/" . - $url[3] . - "/" . - $url[4] . - "/" . - $url[5] . - "/" . - $url[6] . - "/" . - $url[7] . - "/" . - $url[8]; - } else { - $task == "create" ? ($feature = "") : ($feature = $body["feature"]); - } - } - - if ($task == "delete") { - $deleted = "true"; - $body["menu"] = "false"; - $body["published"] = "false"; - $body["featured"] = "false"; - } else { - $deleted = isset($page["deleted"]) ? $page["deleted"] : "false"; - } - - $created = - $task != "create" - ? new \Moment\Moment($page["rawCreated"]) - : new \Moment\Moment(); - $updated = new \Moment\Moment(); - - //grab current index from settings and update - $id = $task != "create" ? $body["id"] : Settings::getCurrentIndex(); - $uuid = $task != "create" ? $body["uuid"] : StringTools::createUUID(); - // now that variables are done, set to body object and then convert to markdown to save - - $body["id"] = $id; - $body["uuid"] = $uuid; - $body["feature"] = $feature; - $body["path"] = $path; - $body["author"] = $member["handle"]; - $body["created"] = $created->format("Y-m-d\TH:i:sP"); - $body["updated"] = $updated->format("Y-m-d\TH:i:sP"); - $body["deleted"] = $deleted; - - $write = DocTools::objectToMD($body); - - // if layout is index, change path to file - - if ($body["layout"] == "index") { - $writePath = "../content/pages/start/index.md"; - } else { - $writePath = "../content/pages/" . $path . "/" . $body["slug"] . ".md"; - } - - $status = DocTools::writePages($task, $path, $writePath, $write); - - if ($status) { - $config = new Settings(); - $settings = $config->getSettings(); - $message = ""; - - if ( - $settings["global"]["renderOnSave"] == "true" && - $settings["global"]["dynamicRender"] == "false" - ) { - $render = new Render(); - $render->renderTags(); - $render->renderArchive(); - $render->renderPages(); - $message = "Filed edited and rendered. NOICE."; - } else { - $message = "File edited. Nice work"; - } - - $response = [ - "message" => $message, - "type" => $task == "write" ? "postUpdated" : "postAdded", - "id" => $uuid, - ]; - - //TODO: When form submission is successful, make new form token - //Session token doesn't reset on the front end, so turning this off for now - //$form_token = md5(uniqid(microtime(), true)); - //Session::set("form_token", $form_token); - - //once saved, update menu - $body["path"] = $path; - Settings::updateMenu($body); - Settings::updateTags(); - //if new page added, update current index in Settings file - if ($task == "create") { - Settings::updateIndex(); - } - } else { - $response = [ - "message" => "Uh oh. File save problem. Don't panic", - "type" => "postError", - "id" => $uuid, - ]; - } - - return $response; - } - - public function getPages(int $page, int $limit, string $sort = null) - { - $content = $this->getContents(); - - $published = filter($content, function ($item) { - return $item["published"] == true && $item["deleted"] == false; - }); - $deleted = filter($content, function ($item) { - return $item["deleted"] == true; - }); - - //$all = $content; - $all = filter($content, function ($item) { - return $item["deleted"] == false; - }); - $filter = isset($sort) ? $sort : "all"; - switch ($filter) { - case "published": - $filtered = $published; - break; - case "deleted": - $filtered = $deleted; - break; - default: - $filtered = $all; - break; - } - $numOfPages = ceil(count($filtered) / ($limit + 1)); - $folder = []; - - if (count($filtered) != 0) { - if (count($filtered) < $limit) { - $limit = count($filtered) - 1; - } - $range = $page * $limit - $limit; - - if ($range != 0) { - $range = $range + 1; - } - for ($i = 0; $i <= $limit; $i++) { - if (isset($filtered[$i + $range])) { - array_push($folder, $filtered[$i + $range]); - } else { - //chill out - } - } - } - - $prev = $page - 1; - if ($prev <= 0) { - $prev = $numOfPages; - } - - $next = $page + 1; - if ($next > $numOfPages) { - $next = 1; - } - - return [ - "pages" => $folder, - "numOfPages" => $numOfPages, - "entryCount" => count($filtered), - "paginate" => [ - "sort" => $sort, - "nextPage" => $next, - "prevPage" => $prev, - ], - "stats" => [ - "all" => count($all), - "published" => count($published), - "deleted" => count($deleted), - ], - ]; - } - public function getContents() - { - //test new contents data class - //$new = (new Contents("../content/pages"))->getAll(); - $contents = (new Contents("../content/pages"))->getAll(); - return $contents; - } -} diff --git a/brain/data/Book.php b/brain/data/Book.php new file mode 100644 index 0000000..237f66a --- /dev/null +++ b/brain/data/Book.php @@ -0,0 +1,298 @@ +getContents(); + $page = find($content, ['uuid' => $uuid]); + + return $page; + } + + public function findPageBySlug(string $slug = null) + { + $content = $this->getContents(); + if (isset($slug)) { + $page = find($content, ['slug' => $slug]); + } else { + $page = find($content, ['layout' => 'index']); + } + + return $page; + } + + public function editPage($task, $request) + { + $content = $this->getContents(); + if ($task == 'delete') { + // $parsed = json_decode(file_get_contents("php://input"), true); + // $body = find($content, ["uuid" => $parsed["id"]]); + $body = $request->getParsedBody(); + } else { + $body = $request->getParsedBody(); + } + + $page = find($content, ['uuid' => $body['uuid']]); + $files = $request->getUploadedFiles(); + + $member = Session::get('member'); + + if ($task != 'create') { + $path = + date('Y', date($page['rawCreated'])). + '/'. + date('m', date($page['rawCreated'])); + } else { + $path = date('Y').'/'.date('m'); + } + + $page_feature = ''; + $page_files = ''; + + if (isset($files['page_files'])) { + $imageList = ''; + $fileList = ''; + // var_dump($files["page_files"] ); + foreach ($files['page_files'] as $file) { + $type = $file->getClientMediaType(); + switch ($type) { + case 'image/jpeg': + case 'image/png': + case 'image/gif': + case 'image/svg': + $imagesPath = '/assets/images/blog/'.$path.'/'; + $imageList = + $imageList.$imagesPath.urlencode($file->getClientFileName()).', '; + + FileUploader::uploadFile( + '../public/assets/images/blog/'.$path.'/', + $file + ); + break; + case 'video/mp4': + $videosPath = '/assets/video/blog/'.$path.'/'; + $imageList = + $imageList.$videosPath.urlencode($file->getClientFileName()).', '; + + FileUploader::uploadFile( + '../public/assets/video/blog/'.$path.'/', + $file + ); + break; + case 'audio/mpeg': + $soundPath = '/assets/sound/blog/'.$path.'/'; + $fileList = $fileList.$soundPath.urlencode($file->getClientFileName()).', '; + + FileUploader::uploadFile( + '../public/assets/sound/blog/'.$path.'/', + $file + ); + break; + case 'application/pdf': + case 'text/plain': + case 'text/rtf': + $docPath = '/assets/docs/blog/'.$path.'/'; + $fileList = $fileList.$docPath.urlencode($file->getClientFileName()).', '; + + FileUploader::uploadFile( + '../public/assets/docs/blog/'.$path.'/', + $file + ); + break; + } + } + $page_feature = $imageList; + $page_files = $fileList; + } else { + // if no files, just reset string from page object + $page_feature = $page['feature']; + $page_files = $page['files']; + } + + if ($task == 'delete') { + $deleted = 'true'; + $body['menu'] = 'false'; + $body['published'] = 'false'; + $body['featured'] = 'false'; + } else { + $deleted = isset($page['deleted']) ? $page['deleted'] : 'false'; + } + + $created = + $task != 'create' + ? new \Moment\Moment($page['rawCreated']) + : new \Moment\Moment(); + $updated = new \Moment\Moment(); + + // grab current index from settings and update + $id = $task != 'create' ? $body['id'] : Settings::getCurrentIndex(); + $uuid = $task != 'create' ? $body['uuid'] : StringTools::createUUID(); + // now that variables are done, set to body object and then convert to markdown to save + + $body['id'] = $id; + $body['uuid'] = $uuid; + $body['feature'] = $page_feature; + $body['files'] = $page_files; + $body['path'] = $path; + $body['author'] = $member['handle']; + $body['created'] = $created->format("Y-m-d\TH:i:sP"); + $body['updated'] = $updated->format("Y-m-d\TH:i:sP"); + $body['deleted'] = $deleted; + + $write = DocTools::objectToMD($body); + + // if layout is index, change path to file + + if ($body['layout'] == 'index') { + $writePath = '../content/pages/start/index.md'; + } else { + $writePath = '../content/pages/'.$path.'/'.$body['slug'].'.md'; + } + + $status = DocTools::writePages($task, $path, $writePath, $write); + + if ($status) { + $config = new Settings(); + $settings = $config->getSettings(); + $message = ''; + + if ( + $settings['global']['renderOnSave'] == 'true' && + $settings['global']['dynamicRender'] == 'false' + ) { + $render = new Render(); + $render->renderTags(); + $render->renderArchive(); + $render->renderPages(); + $message = 'Filed edited and rendered. NOICE.'; + } else { + $message = 'File edited. Nice work'; + } + + $response = [ + 'message' => $message, + 'type' => $task == 'write' ? 'postUpdated' : 'postAdded', + 'id' => $uuid, + ]; + + // TODO: When form submission is successful, make new form token + // Session token doesn't reset on the front end, so turning this off for now + // $form_token = md5(uniqid(microtime(), true)); + // Session::set("form_token", $form_token); + + // once saved, update menu + $body['path'] = $path; + Settings::updateMenu($body); + Settings::updateTags(); + // if new page added, update current index in Settings file + if ($task == 'create') { + Settings::updateIndex(); + } + } else { + $response = [ + 'message' => "Uh oh. File save problem. Don't panic", + 'type' => 'postError', + 'id' => $uuid, + ]; + } + + return $response; + } + + public function getPages(int $page, int $limit, string $sort = null) + { + $content = $this->getContents(); + + $published = filter($content, function ($item) { + return $item['published'] == true && $item['deleted'] == false; + }); + $deleted = filter($content, function ($item) { + return $item['deleted'] == true; + }); + + // $all = $content; + $all = filter($content, function ($item) { + return $item['deleted'] == false; + }); + $filter = isset($sort) ? $sort : 'all'; + switch ($filter) { + case 'published': + $filtered = $published; + break; + case 'deleted': + $filtered = $deleted; + break; + default: + $filtered = $all; + break; + } + $numOfPages = ceil(count($filtered) / ($limit + 1)); + $folder = []; + + if (count($filtered) != 0) { + if (count($filtered) < $limit) { + $limit = count($filtered) - 1; + } + $range = $page * $limit - $limit; + + if ($range != 0) { + $range = $range + 1; + } + for ($i = 0; $i <= $limit; ++$i) { + if (isset($filtered[$i + $range])) { + array_push($folder, $filtered[$i + $range]); + } else { + // chill out + } + } + } + + $prev = $page - 1; + if ($prev <= 0) { + $prev = $numOfPages; + } + + $next = $page + 1; + if ($next > $numOfPages) { + $next = 1; + } + + return [ + 'pages' => $folder, + 'numOfPages' => $numOfPages, + 'entryCount' => count($filtered), + 'paginate' => [ + 'sort' => $sort, + 'nextPage' => $next, + 'prevPage' => $prev, + ], + 'stats' => [ + 'all' => count($all), + 'published' => count($published), + 'deleted' => count($deleted), + ], + ]; + } + + public function getContents() + { + // test new contents data class + // $new = (new Contents("../content/pages"))->getAll(); + $contents = (new Contents('../content/pages'))->getAll(); + + return $contents; + } +} diff --git a/brain/data/Contents.inc.php b/brain/data/Contents.inc.php deleted file mode 100644 index 010e1d7..0000000 --- a/brain/data/Contents.inc.php +++ /dev/null @@ -1,144 +0,0 @@ -read($folder); - } - public function read($folder) - { - $folders = glob("$folder/*", GLOB_ONLYDIR); - foreach ($folders as $folder) { - //$this->files[] = $folder . "/"; - $this->read($folder); - } - $files = array_filter(glob("$folder/*md"), "is_file"); - foreach ($files as $file) { - $this->files[] = $file; - } - } - - function getAll() - { - $environment = new Environment($this->config); - $environment->addExtension(new CommonMarkCoreExtension()); - - // Add the extension - $environment->addExtension(new FrontMatterExtension()); - - //Add Strikethrough rendering - $environment->addExtension(new StrikethroughExtension()); - - //add attributes to elements in markdown - $environment->addExtension(new AttributesExtension()); - - // Instantiate the converter engine and start converting some Markdown! - $converter = new MarkdownConverter($environment); - - $contents = []; - foreach ($this->files as $file) { - //get meta and html from file - $result = $converter->convertToHtml(file_get_contents($file)); - $meta = []; - if ($result instanceof RenderedContentWithFrontMatter) { - $meta = $result->getFrontMatter(); - } - - //get raw markdown from file - $frontMatterExtension = new FrontMatterExtension(); - $parsed = $frontMatterExtension - ->getFrontMatterParser() - ->parse(file_get_contents($file)); - - //never trust the front end. clean it up - - $builder = new SanitizerBuilder(); - $builder->registerExtension(new BasicExtension()); - $builder->registerExtension(new IframeExtension()); - - //relative-a and relative-image - $builder->registerExtension( - new \HtmlSanitizer\Extension\Relative\A\AExtension() - ); - $builder->registerExtension( - new \HtmlSanitizer\Extension\Relative\Image\ImageExtension() - ); - - $detergent = [ - "extensions" => ["basic", "relative-a", "relative-image", "iframe"], - "tags" => [ - "div" => [ - "allowed_attributes" => ["class", "title"], - ], - "img" => [ - "allowed_attributes" => ["src", "alt", "title", "class"], - ], - "iframe" => [ - "allowed_attributes" => ["height", "width", "title", "src"], - ], - ], - ]; - - $sanitizer = $builder->build($detergent); - - $scrubbed = $sanitizer->sanitize($result->getContent()); - - //sort attributes into page object - $page = [ - "id" => $meta["id"], - "uuid" => $meta["uuid"], - "title" => $meta["title"], - "feature" => $meta["feature"], - "path" => $meta["path"], - "layout" => $meta["layout"], - "tags" => $meta["tags"], - "author" => $meta["author"], - "created" => date("Y M D d", $meta["created"]), - "updated" => date("Y M D d", $meta["updated"]), - "rawCreated" => $meta["created"], - "rawUpdated" => $meta["updated"], - "createdYear" => date("Y", $meta["created"]), - "createdMonth" => date("m", $meta["created"]), - "deleted" => $meta["deleted"], - "menu" => $meta["menu"], - "featured" => $meta["featured"], - "published" => $meta["published"], - "slug" => $meta["slug"], - "filePath" => $file, - "content" => $parsed->getContent(), - "html" => $scrubbed, - ]; - //checks for duplicates - $uuid = $meta["uuid"]; - $found = current( - array_filter($contents, function ($item) use ($uuid) { - return isset($item["uuid"]) && $uuid == $item["uuid"]; - }) - ); - - // if uuid is not present, add it - if (!$found) { - array_push($contents, $page); - } - } - $contents = orderBy($contents, ["id"], ["desc"]); - return $contents; - } -} diff --git a/brain/data/Contents.php b/brain/data/Contents.php new file mode 100644 index 0000000..9fd6b41 --- /dev/null +++ b/brain/data/Contents.php @@ -0,0 +1,178 @@ +read($folder); + } + public function read($folder) + { + $folders = glob("$folder/*", GLOB_ONLYDIR); + foreach ($folders as $folder) { + //$this->files[] = $folder . "/"; + $this->read($folder); + } + $files = array_filter(glob("$folder/*md"), "is_file"); + foreach ($files as $file) { + $this->files[] = $file; + } + } + + public function getAll() + { + $environment = new Environment($this->config); + $environment->addExtension(new CommonMarkCoreExtension()); + + // Add the extension + $environment->addExtension(new FrontMatterExtension()); + + //Add Strikethrough rendering + $environment->addExtension(new StrikethroughExtension()); + + //add attributes to elements in markdown + $environment->addExtension(new AttributesExtension()); + + // Instantiate the converter engine and start converting some Markdown! + $converter = new MarkdownConverter($environment); + + $contents = []; + foreach ($this->files as $file) { + //get meta and html from file + $result = $converter->convertToHtml(file_get_contents($file)); + $meta = []; + if ($result instanceof RenderedContentWithFrontMatter) { + $meta = $result->getFrontMatter(); + } + + //get raw markdown from file + $frontMatterExtension = new FrontMatterExtension(); + $parsed = $frontMatterExtension + ->getFrontMatterParser() + ->parse(file_get_contents($file)); + + //never trust the front end. clean it up + //add what sanitizer extensions we need manually + $builder = new SanitizerBuilder(); + $builder->registerExtension(new BasicExtension()); + $builder->registerExtension(new IframeExtension()); + $builder->registerExtension(new ListExtension()); + + //relative-a and relative-image + $builder->registerExtension( + new \HtmlSanitizer\Extension\Relative\A\AExtension() + ); + $builder->registerExtension( + new \HtmlSanitizer\Extension\Relative\Image\ImageExtension() + ); + + $detergent = [ + "extensions" => ["basic", "list","relative-a", "relative-image", "iframe"], + "tags" => [ + "div" => [ + "allowed_attributes" => ["class", "title", "id", "style"], + ], + "img" => [ + "allowed_attributes" => ["src", "alt", "title", "class"], + ], + "iframe" => [ + "allowed_attributes" => ["height", "width", "title", "src"], + ], + ], + ]; + + $sanitizer = $builder->build($detergent); + + $scrubbed = $sanitizer->sanitize($result->getContent()); + $featureList = explode(",", $meta["feature"]); + $docs = ''; + if (isset($meta["files"])) { + $fileList = explode(",", $meta["files"]); + $docs = $meta["files"]; + } else { + $fileList = []; + $docs = ''; + } + + $media = []; + $files = []; + foreach ($featureList as $file) { + $item = trim($file); + $ext = pathinfo($item, PATHINFO_EXTENSION); + if ($item != null || $item != "") { + array_push($media, ["file" => $item, "type" => trim($ext)]); + } + } + + foreach ($fileList as $file) { + $item = trim($file); + $ext = pathinfo($item, PATHINFO_EXTENSION); + if ($item != null || $item != "") { + array_push($files, ["file" => $item, "type" => trim($ext)]); + } + } + + //sort attributes into page object + $page = [ + "id" => $meta["id"], + "uuid" => $meta["uuid"], + "title" => $meta["title"], + "feature" => $meta["feature"], + "files" => $docs, + "path" => $meta["path"], + "layout" => $meta["layout"], + "tags" => $meta["tags"], + "author" => $meta["author"], + "created" => date("Y M D d", $meta["created"]), + "updated" => date("Y M D d", $meta["updated"]), + "rawCreated" => $meta["created"], + "rawUpdated" => $meta["updated"], + "createdYear" => date("Y", $meta["created"]), + "createdMonth" => date("m", $meta["created"]), + "deleted" => $meta["deleted"], + "menu" => $meta["menu"], + "featured" => $meta["featured"], + "published" => $meta["published"], + "slug" => $meta["slug"], + "filePath" => $file, + "content" => $parsed->getContent(), + "html" => $scrubbed, + "media" => $media, + "docs" => $files + ]; + //checks for duplicates + $uuid = $meta["uuid"]; + $found = current( + array_filter($contents, function ($item) use ($uuid) { + return isset($item["uuid"]) && $uuid == $item["uuid"]; + }) + ); + + // if uuid is not present, add it + if (!$found) { + array_push($contents, $page); + } + } + $contents = orderBy($contents, ["id"], ["desc"]); + return $contents; + } +} diff --git a/brain/data/Member.inc.php b/brain/data/Member.inc.php deleted file mode 100644 index b163366..0000000 --- a/brain/data/Member.inc.php +++ /dev/null @@ -1,55 +0,0 @@ -getFolks(); - $found = find($folks, ["key" => $key]); - if ($found) { - return true; - } else { - return false; - } - } else { - return false; - } - } - - public static function updateData(string $key, string $data, $secret = null) - { - $folks = (new Settings())->getFolks(); - if (isset($secret)) { - $found = find($folks, ["secret" => $secret]); - } else { - $member = Session::get("member"); - $found = find($folks, ["handle" => $member["handle"]]); - } - $found[$key] = $data; - //record time updated - $updated = new \Moment\Moment(); - $found["updated"] = $updated->format("Y-m-d\TH:i:sP"); - $newFolks = []; - array_push($newFolks, $found); - //save updated file - DocTools::writeSettings("../config/folks.json", $newFolks); - //update member data in session - - if (!isset($secret)) { - $member = [ - "handle" => $found["handle"], - "email" => $found["email"], - "role" => $found["role"], - "avatar" => $found["avi"], - "key" => $found["key"], - ]; - Session::set("member", $member); - } - } -} diff --git a/brain/data/Member.php b/brain/data/Member.php new file mode 100644 index 0000000..00e342f --- /dev/null +++ b/brain/data/Member.php @@ -0,0 +1,62 @@ +getFolks(); + $found = find($folks, ["key" => $key]); + if ($found) { + return true; + } else { + return false; + } + } else { + return false; + } + } + + public static function updateData(string $key, string $data, $secret = null) + { + $folks = (new Settings())->getFolks(); + if (isset($secret)) { + $found = find($folks, ["secret" => $secret]); + } else { + $member = Session::get("member"); + $found = find($folks, ["handle" => $member["handle"]]); + } + $found[$key] = $data; + //record time updated + $updated = new \Moment\Moment(); + $found["updated"] = $updated->format("Y-m-d\TH:i:sP"); + $newFolks = []; + array_push($newFolks, $found); + //save updated file + DocTools::writeSettings("../config/folks.json", $newFolks); + //update member data in session + + if (!isset($secret)) { + $member = [ + "handle" => $found["handle"], + "email" => $found["email"], + "role" => $found["role"], + "avatar" => $found["avi"], + "key" => $found["key"], + ]; + Session::set("member", $member); + } + } +} diff --git a/brain/data/Render.inc.php b/brain/data/Render.inc.php deleted file mode 100644 index 3c85a2a..0000000 --- a/brain/data/Render.inc.php +++ /dev/null @@ -1,179 +0,0 @@ -loader = new \Twig\Loader\FilesystemLoader("../content/themes"); - $this->twig = new \Twig\Environment($this->loader, []); - $settings = $config->getSettings(); - $this->menu = $settings["menu"]; - $this->theme = $settings["global"]["theme"]; - $this->pageInfo = [ - "keywords" => isset($settings["global"]["keywords"]) - ? $settings["global"]["keywords"] - : "fipamo, blog, jamstack, php, markdown, js", - "description" => $settings["global"]["descriptions"], - "image" => - $settings["global"]["base_url"] . $settings["global"]["background"], - "baseURL" => $settings["global"]["base_url"], - ]; - //move global theme image assets to public folder - foreach ( - new DirectoryIterator( - "../content/themes/" . $this->theme . "/assets/images/global/" - ) - as $file - ) { - if ($file->isDot()) { - continue; - } - if (!is_file("../public/assets/images/global/" . $file->getFileName())) { - copy( - "../content/themes/" . - $this->theme . - "/assets/images/global/" . - $file->getFileName(), - "../public/assets/images/global/" . $file->getFileName() - ); - } else { - //image is already there, so chill - } - //print $file->getFilename() . "\n"; - } - - //copy current theme assets to public - if (is_file("../public/assets/css/base.css")) { - unlink("../public/assets/css/base.css"); - } - copy( - "../content/themes/" . $this->theme . "/assets/css/base.css", - "../public/assets/css/base.css" - ); - if (is_file("../public/assets/scripts/start.min.js")) { - unlink("../public/assets/scripts/start.min.js"); - } - copy( - "../content/themes/" . $this->theme . "/assets/scripts/start.min.js", - "../public/assets/scripts/start.min.js" - ); - } - - public function renderPages() - { - $pages = (new Book())->getContents(); - $recent = []; - $featured = []; - $limit = 4; - foreach ($pages as $page) { - $pageOptions = Sorting::page($page); - - $layout = $page["layout"]; - //new pages have no layout, so defautl for now - if ($layout == "" || $layout == null) { - $layout = "page"; - } - - $template = $this->theme . "/" . $layout . ".twig"; - if (str_contains($page["layout"], "index")) { - $location = "../public/index.html"; - $dir = null; - } else { - // if page is a menu item, render the page on public root - if ($page["menu"] == "true") { - $location = "../public/" . $page["slug"] . ".html"; - $dir = "../public/"; - } else { - $location = - "../public/" . $page["path"] . "/" . $page["slug"] . ".html"; - $dir = "../public/" . $page["path"]; - } - } - - $html = $this->twig->render($template, $pageOptions); - DocTools::writeHTML($location, $html, $dir); - } - } - - public function renderArchive() - { - $archive = Sorting::archive(); - $template = $this->theme . "/archive.twig"; - $pageOptions = [ - "title" => "Archive", - "background" => $this->pageInfo["image"], - "archives" => $archive, - "info" => $this->pageInfo, - "menu" => $this->menu, - ]; - - $html = $this->twig->render($template, $pageOptions); - $location = "../public/archives.html"; - DocTools::writeHTML($location, $html); - } - - public function renderTags() - { - $list = Sorting::tags(); - foreach ($list as $item) { - $template = $this->theme . "/tags.twig"; - $pageOptions = [ - "title" => "Pages Tagged as " . $item["tag_name"], - "background" => $this->pageInfo["image"], - "tag_list" => $item["pages"], - "info" => $this->pageInfo, - "menu" => $this->menu, - ]; - - $html = $this->twig->render($template, $pageOptions); - - $location = "../public/tags/" . $item["slug"] . ".html"; - - //if tags folder doesn't exist, make it - if (!is_dir("../public/tags")) { - mkdir("../public/tags", 0755, true); - } else { - } - - if (!is_file($location)) { - file_put_contents($location, $html); - } else { - ($new = fopen($location, "w")) or die("Unable to open file!"); - fwrite($new, $html); - fclose($new); - } - } - } - - public function renderIndex() - { - //TODO: Need to fix this to account for new index templating system - $pages = (new Book())->getContents(); - $index = find($pages, ["layout" => "index"]); - $template = $this->theme . "/index.twig"; - $location = "../public/index.html"; - $dir = null; - - $meta = [ - "who" => $index["author"], - "when" => $index["created"], - ]; - - $pageOptions = [ - "title" => $index["title"], - "background" => $index["feature"], - "meta" => $meta, - ]; - - $html = $this->twig->render($template, $pageOptions); - DocTools::writeHTML($location, $html, $dir); - } -} diff --git a/brain/data/Render.php b/brain/data/Render.php new file mode 100644 index 0000000..9fecabe --- /dev/null +++ b/brain/data/Render.php @@ -0,0 +1,206 @@ +getSettings(); + $this->menu = $settings["menu"]; + $this->theme = $settings["global"]["theme"]; + $this->loader = new \Twig\Loader\FilesystemLoader("../content/themes/" . $this->theme); + $this->twig = new \Twig\Environment($this->loader, []); + $this->pageInfo = [ + "keywords" => isset($settings["global"]["keywords"]) + ? $settings["global"]["keywords"] + : "fipamo, blog, jamstack, php, markdown, js", + "description" => $settings["global"]["descriptions"], + "image" => + $settings["global"]["base_url"] . $settings["global"]["background"], + "baseURL" => $settings["global"]["base_url"], + ]; + //move global theme image assets to public folder + foreach ( + new \DirectoryIterator("../content/themes/" . $this->theme . "/assets/images/global/") as $file + ) { + if ($file->isDot()) { + continue; + } + if (!is_file("../public/assets/images/global/" . $file->getFileName())) { + copy( + "../content/themes/" . + $this->theme . + "/assets/images/global/" . + $file->getFileName(), + "../public/assets/images/global/" . $file->getFileName() + ); + } else { + //image is already there, so chill + } + //print $file->getFilename() . "\n"; + } + + //copy current theme assets to public + + //clear files in css and scripts folder + $styles = glob('../public/assets/css/*'); // get all file names + foreach ($styles as $file) { // iterate files + if (is_file($file)) { + //don't erase dashboard css + if (!$file == '../public/assets/css/dash.css') { + unlink($file); // delete file + } + } + } + + $scripts = glob('../public/assets/scripts/*'); // get all file names + foreach ($scripts as $file) { // iterate files + if (is_file($file)) { + if (!$file == "../public/assets/scripts/Start.js") { + unlink($file); // delete file + } + } + } + //copy theme assets to public + $newcss = glob("../content/themes/" . $this->theme . "/assets/css/*"); + foreach ($newcss as $file) { // iterate files + if (is_file($file)) { + $path = explode("/", $file); + copy($file, "../public/assets/css/" . $path[6]); + } + } + $newjs = glob("../content/themes/" . $this->theme . "/assets/scripts/*"); + foreach ($newjs as $file) { // iterate files + if (is_file($file)) { + $path = explode("/", $file); + copy($file, "../public/assets/scripts/" . $path[6]); + } + } + } + + public function renderPages() + { + $pages = (new Book())->getContents(); + $recent = []; + $featured = []; + $limit = 4; + foreach ($pages as $page) { + $pageOptions = Sorting::page($page); + + $layout = $page["layout"]; + //new pages have no layout, so defautl for now + if ($layout == "" || $layout == null) { + $layout = "page"; + } + + $template = $layout . ".twig"; + if (str_contains($page["layout"], "index")) { + $location = "../public/index.html"; + $dir = null; + } else { + // if page is a menu item, render the page on public root + if ($page["menu"] == "true") { + $location = "../public/" . $page["slug"] . ".html"; + $dir = "../public/"; + } else { + $location = + "../public/" . $page["path"] . "/" . $page["slug"] . ".html"; + $dir = "../public/" . $page["path"]; + } + } + + $html = $this->twig->render($template, $pageOptions); + DocTools::writeHTML($location, $html, $dir); + } + } + + public function renderArchive() + { + $archive = Sorting::archive(); + $template = "archive.twig"; + $pageOptions = [ + "title" => "Archive", + "background" => $this->pageInfo["image"], + "archives" => $archive, + "info" => $this->pageInfo, + "menu" => $this->menu, + ]; + + $html = $this->twig->render($template, $pageOptions); + $location = "../public/archives.html"; + DocTools::writeHTML($location, $html); + } + + public function renderTags() + { + $list = Sorting::tags(); + foreach ($list as $item) { + $template = "tags.twig"; + $pageOptions = [ + "title" => "Pages Tagged as " . $item["tag_name"], + "background" => $this->pageInfo["image"], + "tag_list" => $item["pages"], + "info" => $this->pageInfo, + "menu" => $this->menu, + ]; + + $html = $this->twig->render($template, $pageOptions); + + $location = "../public/tags/" . $item["slug"] . ".html"; + + //if tags folder doesn't exist, make it + if (!is_dir("../public/tags")) { + mkdir("../public/tags", 0755, true); + } else { + } + + if (!is_file($location)) { + file_put_contents($location, $html); + } else { + ($new = fopen($location, "w")) or die("Unable to open file!"); + fwrite($new, $html); + fclose($new); + } + } + } + + public function renderIndex() + { + //TODO: Need to fix this to account for new index templating system + $pages = (new Book())->getContents(); + $index = find($pages, ["layout" => "index"]); + $template = "index.twig"; + $location = "../public/index.html"; + $dir = null; + + $meta = [ + "who" => $index["author"], + "when" => $index["created"], + ]; + + $pageOptions = [ + "title" => $index["title"], + "background" => $index["feature"], + "meta" => $meta, + ]; + + $html = $this->twig->render($template, $pageOptions); + DocTools::writeHTML($location, $html, $dir); + } +} diff --git a/brain/data/Session.inc.php b/brain/data/Session.inc.php deleted file mode 100644 index f5063c9..0000000 --- a/brain/data/Session.inc.php +++ /dev/null @@ -1,90 +0,0 @@ - "", - "token" => "", - "form_token" => "", - ]; - public static function start() - { - if (!is_file(self::$file)) { - file_put_contents(self::$file, json_encode(self::$data)); - } else { - ($new = fopen(self::$file, "w")) or die("Unable to open file!"); - fwrite($new, json_encode(self::$data)); - fclose($new); - } - } - - public static function active() - { - if (!is_file(self::$file)) { - return false; - } else { - $data = json_decode(file_get_contents(self::$file), true); - if ($data["member"] != null) { - $secret = (new Settings())->getFolks("secret"); - if ($secret == null) { - return false; - } else { - if ( - Token::validate($data["token"], $secret) && - Token::validateExpiration($data["token"], $secret) - ) { - return true; - } else { - return false; - } - } - } else { - return false; - } - } - } - - public static function verifyToken($token) - { - $data = json_decode(file_get_contents(self::$file), true); - if ($data["member"] != null) { - $secret = (new Settings())->getFolks("secret"); - if ( - Token::validate($token, $secret) && - Token::validateExpiration($token, $secret) - ) { - return true; - } else { - return false; - } - } else { - return false; - } - } - - public static function set($key, $value) - { - $data = json_decode(file_get_contents(self::$file), true); - $data[$key] = $value; - ($fresh = fopen(self::$file, "w")) or die("Unable to open file!"); - fwrite($fresh, json_encode($data)); - fclose($fresh); - } - - public static function get($key) - { - $data = json_decode(file_get_contents(self::$file), true); - - return $data[$key]; - } - - public static function kill() - { - ($fresh = fopen(self::$file, "w")) or die("Unable to open file!"); - fwrite($fresh, json_encode(self::$data)); - fclose($fresh); - } -} diff --git a/brain/data/Session.php b/brain/data/Session.php new file mode 100644 index 0000000..b4a0561 --- /dev/null +++ b/brain/data/Session.php @@ -0,0 +1,94 @@ + "", + "token" => "", + "form_token" => "", + ]; + public static function start() + { + if (!is_file(self::$file)) { + file_put_contents(self::$file, json_encode(self::$data)); + } else { + ($new = fopen(self::$file, "w")) or die("Unable to open file!"); + fwrite($new, json_encode(self::$data)); + fclose($new); + } + } + + public static function active() + { + if (!is_file(self::$file)) { + return false; + } else { + $data = json_decode(file_get_contents(self::$file), true); + if ($data["member"] != null) { + $secret = (new Settings())->getFolks("secret"); + if ($secret == null) { + return false; + } else { + if ( + Token::validate($data["token"], $secret) && + Token::validateExpiration($data["token"], $secret) + ) { + return true; + } else { + return false; + } + } + } else { + return false; + } + } + } + + public static function verifyToken($token) + { + $data = json_decode(file_get_contents(self::$file), true); + if ($data["member"] != null) { + $secret = (new Settings())->getFolks("secret"); + if ( + Token::validate($token, $secret) && + Token::validateExpiration($token, $secret) + ) { + return true; + } else { + return false; + } + } else { + return false; + } + } + + public static function set($key, $value) + { + $data = json_decode(file_get_contents(self::$file), true); + $data[$key] = $value; + ($fresh = fopen(self::$file, "w")) or die("Unable to open file!"); + fwrite($fresh, json_encode($data)); + fclose($fresh); + } + + public static function get($key) + { + $data = json_decode(file_get_contents(self::$file), true); + + return $data[$key]; + } + + public static function kill() + { + ($fresh = fopen(self::$file, "w")) or die("Unable to open file!"); + fwrite($fresh, json_encode(self::$data)); + fclose($fresh); + } +} diff --git a/brain/data/Settings.inc.php b/brain/data/Settings.inc.php deleted file mode 100644 index ff25452..0000000 --- a/brain/data/Settings.inc.php +++ /dev/null @@ -1,169 +0,0 @@ -folks = json_decode(file_get_contents("../config/folks.json"), true); - self::$tags = json_decode(file_get_contents("../config/tags.json"), true); - self::$settings = json_decode( - file_get_contents("../config/settings.json"), - true - ); - } - - public static function sync($data) - { - $settings = self::$settings; - $settings["global"]["base_url"] = $data["global"]["base_url"]; - $settings["global"]["title"] = $data["global"]["title"]; - $settings["global"]["descriptions"] = $data["global"]["descriptions"]; - $settings["global"]["base_url"] = $data["global"]["base_url"]; - $settings["global"]["private"] = $data["global"]["private"]; - $settings["global"]["renderOnSave"] = $data["global"]["renderOnSave"]; - $settings["global"]["theme"] = $data["global"]["theme"]; - $settings["global"]["externalAPI"] = $data["global"]["externalAPI"]; - $settings["global"]["dynamicRender"] = $data["global"]["dynamicRender"]; - - Member::updateData("handle", $data["member"]["handle"]); - Member::updateData("email", $data["member"]["email"]); - - $settings["email"]["active"] = $data["email"]["active"]; - $settings["email"]["smtp"] = $data["email"]["smtp"]; - $settings["email"]["mailgun"] = $data["email"]["mailgun"]; - - DocTools::writeSettings("../config/settings.json", $settings); - } - - public static function navSync($data) - { - $settings = self::$settings; - - $remove = $data["remove"]; - //if remove contains id, find nav item page and set menu to false - if ($remove != null || $remove != "") { - $page = (new Book("../content/pages"))->findPageById($remove); - $page["menu"] = "false"; - $page["published"] - ? ($page["published"] = "true") - : ($page["published"] = "false"); - $page["featured"] - ? ($page["featured"] = "true") - : ($page["featured"] = "false"); - $page["deleted"] - ? ($page["deleted"] = "true") - : ($page["deleted"] = "false"); - $updated = new \Moment\Moment(); - $created = new \Moment\Moment($page["rawCreated"]); - $page["created"] = $created->format("Y-m-d\TH:i:sP"); - $page["updated"] = $updated->format("Y-m-d\TH:i:sP"); - - $md = DocTools::objectToMD($page); - - if ($page["layout"] == "index") { - $writePath = "../content/pages/start/index.md"; - } else { - $writePath = - "../content/pages/" . $page["path"] . "/" . $page["slug"] . ".md"; - } - - DocTools::writePages("write", $page["path"], $writePath, $md); - } - - $settings["menu"] = []; - $items = $data["menu"]; - foreach ($items as $item) { - array_push($settings["menu"], [ - "title" => $item["title"], - "id" => $item["id"], - "uuid" => $item["uuid"], - "slug" => $item["slug"], - "path" => $item["path"], - ]); - } - - DocTools::writeSettings("../config/settings.json", $settings); - } - - public function getFolks($key = null) - { - if (isset($key)) { - $member = Session::get("member"); - $found = find($this->folks, ["handle" => $member["handle"]]); - if ($found) { - return $found[$key]; - } - } else { - return $this->folks; - } - } - - public function getSettings($key = null) - { - return self::$settings; - } - - public static function getTags() - { - return self::$tags; - } - - public static function updateGlobalData($key, $data) - { - $settings = self::$settings; - $settings["global"][$key] = $data; - DocTools::writeSettings("../config/settings.json", $settings); - } - - public static function getCurrentIndex() - { - $settings = self::$settings; - return $settings["library_stats"]["current_index"]; - } - - public static function updateIndex() - { - $settings = self::$settings; - - $settings["library_stats"]["current_index"] = - $settings["library_stats"]["current_index"] + 1; - - DocTools::writeSettings("../config/settings.json", $settings); - } - - public static function updateMenu($body) - { - $settings = self::$settings; - //$menu = $settings["menu"]; - $item = [ - "title" => $body["title"], - "id" => $body["id"], - "uuid" => $body["uuid"], - "slug" => $body["slug"], - "path" => $body["path"], - ]; - if ($body["menu"] == "true") { - if (!find($settings["menu"], ["uuid" => $item["uuid"]])) { - array_push($settings["menu"], $item); - } - } else { - if (find($settings["menu"], ["uuid" => $item["uuid"]])) { - pull($settings["menu"], $item); - } - } - DocTools::writeSettings("../config/settings.json", $settings); - } - - public static function updateTags() - { - $tags = Sorting::tags(); - DocTools::writeSettings("../config/tags.json", $tags); - } -} diff --git a/brain/data/Settings.php b/brain/data/Settings.php new file mode 100644 index 0000000..71b3c21 --- /dev/null +++ b/brain/data/Settings.php @@ -0,0 +1,177 @@ +folks = json_decode(file_get_contents("../config/folks.json"), true); + self::$tags = json_decode(file_get_contents("../config/tags.json"), true); + self::$settings = json_decode( + file_get_contents("../config/settings.json"), + true + ); + } + + public static function sync($data) + { + $settings = self::$settings; + $settings["global"]["base_url"] = $data["global"]["base_url"]; + $settings["global"]["title"] = $data["global"]["title"]; + $settings["global"]["descriptions"] = $data["global"]["descriptions"]; + $settings["global"]["base_url"] = $data["global"]["base_url"]; + $settings["global"]["private"] = $data["global"]["private"]; + $settings["global"]["renderOnSave"] = $data["global"]["renderOnSave"]; + $settings["global"]["theme"] = $data["global"]["theme"]; + $settings["global"]["externalAPI"] = $data["global"]["externalAPI"]; + $settings["global"]["dynamicRender"] = $data["global"]["dynamicRender"]; + + Member::updateData("handle", $data["member"]["handle"]); + Member::updateData("email", $data["member"]["email"]); + + $settings["email"]["active"] = $data["email"]["active"]; + $settings["email"]["smtp"] = $data["email"]["smtp"]; + $settings["email"]["mailgun"] = $data["email"]["mailgun"]; + + DocTools::writeSettings("../config/settings.json", $settings); + } + + public static function navSync($data) + { + $settings = self::$settings; + + $remove = $data["remove"]; + //if remove contains id, find nav item page and set menu to false + if ($remove != null || $remove != "") { + $page = (new Book("../content/pages"))->findPageById($remove); + $page["menu"] = "false"; + $page["published"] + ? ($page["published"] = "true") + : ($page["published"] = "false"); + $page["featured"] + ? ($page["featured"] = "true") + : ($page["featured"] = "false"); + $page["deleted"] + ? ($page["deleted"] = "true") + : ($page["deleted"] = "false"); + $updated = new \Moment\Moment(); + $created = new \Moment\Moment($page["rawCreated"]); + $page["created"] = $created->format("Y-m-d\TH:i:sP"); + $page["updated"] = $updated->format("Y-m-d\TH:i:sP"); + + $md = DocTools::objectToMD($page); + + if ($page["layout"] == "index") { + $writePath = "../content/pages/start/index.md"; + } else { + $writePath = + "../content/pages/" . $page["path"] . "/" . $page["slug"] . ".md"; + } + + DocTools::writePages("write", $page["path"], $writePath, $md); + } + + $settings["menu"] = []; + $items = $data["menu"]; + foreach ($items as $item) { + array_push($settings["menu"], [ + "title" => $item["title"], + "id" => $item["id"], + "uuid" => $item["uuid"], + "slug" => $item["slug"], + "path" => $item["path"], + ]); + } + + DocTools::writeSettings("../config/settings.json", $settings); + } + + public function getFolks($key = null) + { + if (isset($key)) { + $member = Session::get("member"); + $found = find($this->folks, ["handle" => $member["handle"]]); + if ($found) { + return $found[$key]; + } + } else { + return $this->folks; + } + } + + public function getSettings($key = null) + { + return self::$settings; + } + + public static function getTags() + { + return self::$tags; + } + + public static function updateGlobalData($key, $data) + { + $settings = self::$settings; + $settings["global"][$key] = $data; + DocTools::writeSettings("../config/settings.json", $settings); + } + + public static function getCurrentIndex() + { + $settings = self::$settings; + return $settings["library_stats"]["current_index"]; + } + + public static function updateIndex() + { + $settings = self::$settings; + + $settings["library_stats"]["current_index"] = + $settings["library_stats"]["current_index"] + 1; + + DocTools::writeSettings("../config/settings.json", $settings); + } + + public static function updateMenu($body) + { + $settings = self::$settings; + //$menu = $settings["menu"]; + $item = [ + "title" => $body["title"], + "id" => $body["id"], + "uuid" => $body["uuid"], + "slug" => $body["slug"], + "path" => $body["path"], + ]; + if ($body["menu"] == "true") { + if (!find($settings["menu"], ["uuid" => $item["uuid"]])) { + array_push($settings["menu"], $item); + } + } else { + if (find($settings["menu"], ["uuid" => $item["uuid"]])) { + pull($settings["menu"], $item); + } + } + DocTools::writeSettings("../config/settings.json", $settings); + } + + public static function updateTags() + { + $tags = Sorting::tags(); + DocTools::writeSettings("../config/tags.json", $tags); + } +} diff --git a/brain/data/Themes.inc.php b/brain/data/Themes.inc.php deleted file mode 100644 index 6ad02fb..0000000 --- a/brain/data/Themes.inc.php +++ /dev/null @@ -1,60 +0,0 @@ -themes, - json_decode(file_get_contents($theme . "/theme.json"), true) - ); - } - } - - public function getThemes() - { - return $this->themes; - } - - public function getCustomIndex() - { - $settings = (new Settings())->getSettings(); - $currentTheme = $settings["global"]["theme"]; - $folder = "../content/themes/" . $currentTheme; - $files = array_filter(glob("$folder/*twig"), "is_file"); - $views = []; - - foreach ($files as $file) { - $path = explode("/", $file); - $fileName = $path[4]; - if (str_contains($fileName, "index")) { - $page = explode(".", $fileName); - $views[] = $page[0]; - } - } - return $views; - } - - public function getCustomViews() - { - $settings = (new Settings())->getSettings(); - $currentTheme = $settings["global"]["theme"]; - $folder = "../content/themes/" . $currentTheme; - $files = array_filter(glob("$folder/*twig"), "is_file"); - $views = []; - - foreach ($files as $file) { - $path = explode("/", $file); - $fileName = $path[4]; - if (str_contains($fileName, "page")) { - $page = explode(".", $fileName); - $views[] = $page[0]; - } - } - return $views; - } -} diff --git a/brain/data/Themes.php b/brain/data/Themes.php new file mode 100644 index 0000000..3c15bf4 --- /dev/null +++ b/brain/data/Themes.php @@ -0,0 +1,64 @@ +themes, + json_decode(file_get_contents($theme . "/theme.json"), true) + ); + } + } + + public function getThemes() + { + return $this->themes; + } + + public function getCustomIndex() + { + $settings = (new Settings())->getSettings(); + $currentTheme = $settings["global"]["theme"]; + $folder = "../content/themes/" . $currentTheme; + $files = array_filter(glob("$folder/*twig"), "is_file"); + $views = []; + + foreach ($files as $file) { + $path = explode("/", $file); + $fileName = $path[4]; + if (str_contains($fileName, "index")) { + $page = explode(".", $fileName); + $views[] = $page[0]; + } + } + return $views; + } + + public function getCustomViews() + { + $settings = (new Settings())->getSettings(); + $currentTheme = $settings["global"]["theme"]; + $folder = "../content/themes/" . $currentTheme; + $files = array_filter(glob("$folder/*twig"), "is_file"); + $views = []; + + foreach ($files as $file) { + $path = explode("/", $file); + $fileName = $path[4]; + if (str_contains($fileName, "page")) { + $page = explode(".", $fileName); + $views[] = $page[0]; + } + } + return $views; + } +} diff --git a/brain/init/App.php b/brain/init/App.php new file mode 100644 index 0000000..7c8cb5e --- /dev/null +++ b/brain/init/App.php @@ -0,0 +1,36 @@ +add(TwigMiddleware::create($app, $twig)); + //set up routing + $app->get( + "/[{first}[/{second}[/{third}[/{fourth}[/{fifth}]]]]]", + "brain\controller\RouteControl:get" + ); + $app->post( + "/[{first}[/{second}[/{third}[/{fourth}]]]]", + "brain\controller\RouteControl:post" + ); + //start the app + + $app->run(); + } +} diff --git a/brain/utility/DocTools.inc.php b/brain/utility/DocTools.inc.php deleted file mode 100644 index e28197f..0000000 --- a/brain/utility/DocTools.inc.php +++ /dev/null @@ -1,140 +0,0 @@ -getClientFileName(), $directory); - //$extension = pathinfo($file->getClientFilename(), PATHINFO_EXTENSION); - - // see http://php.net/manual/en/function.random-bytes.php - //$basename = bin2hex(random_bytes(8)); - //$filename = sprintf("%s.%0.8s", $basename, $extension); - - //echo "**FILE** " . $file->getClientFileName(); - - $file->moveTo($directory . "/" . $file->getClientFileName()); - } catch (RuntimeException $e) { - echo "ERROR " . $e->getMessage(); - - //echo "failed to upload image: " . $e->getMessage(); - //throw new Error("Failed to upload image file"); - } - } -} diff --git a/brain/utility/FileUploader.php b/brain/utility/FileUploader.php new file mode 100644 index 0000000..c40b2a5 --- /dev/null +++ b/brain/utility/FileUploader.php @@ -0,0 +1,32 @@ +getClientFileName(), $directory); + // $extension = pathinfo($file->getClientFilename(), PATHINFO_EXTENSION); + + // see http://php.net/manual/en/function.random-bytes.php + // $basename = bin2hex(random_bytes(8)); + // $filename = sprintf("%s.%0.8s", $basename, $extension); + + // echo "**FILE** " . $file->getClientFileName(); + + $file->moveTo($directory.'/'.urlencode($file->getClientFileName())); + } catch (RuntimeException $e) { + echo 'ERROR '.$e->getMessage(); + + // echo "failed to upload image: " . $e->getMessage(); + // throw new Error("Failed to upload image file"); + } + } +} diff --git a/brain/utility/HandleCors.inc.php b/brain/utility/HandleCors.php similarity index 97% rename from brain/utility/HandleCors.inc.php rename to brain/utility/HandleCors.php index 86fa7b0..7082fdd 100644 --- a/brain/utility/HandleCors.inc.php +++ b/brain/utility/HandleCors.php @@ -1,6 +1,10 @@ getSettings(); - $mailConfig = $settings["email"]; - $mail = new PHPMailer(); - - switch ($body["mail_task"]) { - case "TESTING": - $html = - "

Hi! It's Fipamo!


" . - "It's just a test
" . - $body["content"]; - $member = Session::get("member"); - $mail->addAddress($member["email"], ""); //pull email address from current user - $mail->Subject = "A test email"; - break; - case "SEND_SECRET": - $html = - "

Hi! It's Fipamo!


" . - "This is your secret key.

" . - "

" . - $body["secret"] . - "

" . - "
Use this key to reset your password."; - $mail->addAddress($body["email"], ""); //pull email address from current user - $mail->Subject = "Shhhh! It's a secret!"; - break; - default: - return $result = [ - "type" => "noMailService", - "message" => "Mail task is undefined. What are you doing??", - ]; - break; - } - - //set values based on current active protocol - switch ($mailConfig["active"]) { - case "option-smtp": - $mail->setFrom($mailConfig["smtp"]["email"], "System Email"); - $mail->Host = "playvicio.us"; - $mail->Username = $mailConfig["smtp"]["email"]; - $mail->Password = $mailConfig["smtp"]["password"]; - - break; - case "option-mg": - $mail->setFrom($mailConfig["mailgun"]["domain"], "No Reply"); - $mail->Host = "smtp.mailgun.org"; - $mail->Username = $mailConfig["mailgun"]["domain"]; - $mail->Password = $mailConfig["mailgun"]["key"]; - break; - default: - //no mail service - return $result = [ - "type" => "noMailService", - "message" => "Mail is not configured. Handle that.", - ]; - break; - } - - $mail->Body = $html; - $mail->IsHTML(true); - $mail->isSMTP(); - $mail->SMTPAuth = true; - $mail->SMTPSecure = "ssl"; - $mail->Port = 465; - - // Uncomment for debug info - //$mail->SMTPDebug = 4; - - /* Finally send the mail. */ - try { - $mail->send(); - $result = ["type" => "mailSent", "message" => "Message Away!"]; - } catch (Exception $e) { - //echo $e->errorMessage(); - $result = [ - "type" => "mailNotSent", - "message" => "Message Not Away!", - "error" => $e->errorMessage(), - ]; - } - - return $result; - } -} \ No newline at end of file diff --git a/brain/utility/Mailer.php b/brain/utility/Mailer.php new file mode 100644 index 0000000..81bec42 --- /dev/null +++ b/brain/utility/Mailer.php @@ -0,0 +1,98 @@ +getSettings(); + $mailConfig = $settings["email"]; + $mail = new PHPMailer(); + + switch ($body["mail_task"]) { + case "TESTING": + $html = + "

Hi! It's Fipamo!


" . + "It's just a test
" . + $body["content"]; + $member = Session::get("member"); + $mail->addAddress($member["email"], ""); //pull email address from current user + $mail->Subject = "A test email"; + break; + case "SEND_SECRET": + $html = + "

Hi! It's Fipamo!


" . + "This is your secret key.

" . + "

" . + $body["secret"] . + "

" . + "
Use this key to reset your password."; + $mail->addAddress($body["email"], ""); //pull email address from current user + $mail->Subject = "Shhhh! It's a secret!"; + break; + default: + return $result = [ + "type" => "noMailService", + "message" => "Mail task is undefined. What are you doing??", + ]; + break; + } + + //set values based on current active protocol + switch ($mailConfig["active"]) { + case "option-smtp": + $mail->setFrom($mailConfig["smtp"]["email"], "System Email"); + $mail->Host = "playvicio.us"; + $mail->Username = $mailConfig["smtp"]["email"]; + $mail->Password = $mailConfig["smtp"]["password"]; + + break; + case "option-mg": + $mail->setFrom($mailConfig["mailgun"]["domain"], "No Reply"); + $mail->Host = "smtp.mailgun.org"; + $mail->Username = $mailConfig["mailgun"]["domain"]; + $mail->Password = $mailConfig["mailgun"]["key"]; + break; + default: + //no mail service + return $result = [ + "type" => "noMailService", + "message" => "Mail is not configured. Handle that.", + ]; + break; + } + + $mail->Body = $html; + $mail->IsHTML(true); + $mail->isSMTP(); + $mail->SMTPAuth = true; + $mail->SMTPSecure = "ssl"; + $mail->Port = 465; + + // Uncomment for debug info + //$mail->SMTPDebug = 4; + + /* Finally send the mail. */ + try { + $mail->send(); + $result = ["type" => "mailSent", "message" => "Message Away!"]; + } catch (Exception $e) { + //echo $e->errorMessage(); + $result = [ + "type" => "mailNotSent", + "message" => "Message Not Away!", + "error" => $e->errorMessage(), + ]; + } + + return $result; + } +} diff --git a/brain/utility/Maintenance.inc.php b/brain/utility/Maintenance.inc.php deleted file mode 100644 index 2697e3e..0000000 --- a/brain/utility/Maintenance.inc.php +++ /dev/null @@ -1,99 +0,0 @@ -open( - "../config/backups/latest_back.zip", - ZipArchive::CREATE | ZipArchive::OVERWRITE - ); - //gather data and path info for md pages - $pagePath = "../content/pages"; - $yearPaths = glob($pagePath . "/*", GLOB_ONLYDIR); - foreach ($yearPaths as $years) { - $year = explode("/", $years); - //grap the index and save it - if (trim($year[3]) == "start") { - $options = [ - "add_path" => "content/pages/" . $year[3] . "/", - "remove_all_path" => true, - ]; - $zip->addGlob($years . "/*.md", GLOB_BRACE, $options); - } - $monthsPath = glob($pagePath . "/" . $year[3] . "/*", GLOB_ONLYDIR); - foreach ($monthsPath as $months) { - $month = explode("/", $months); - //once info is collected, add md pages to zip - $options = [ - "add_path" => "content/pages/" . $year[3] . "/" . $month[4] . "/", - "remove_all_path" => true, - ]; - $zip->addGlob($months . "/*.md", GLOB_BRACE, $options); - } - } - - //gather data and path info for blog images - $blogImagesPath = "../public/assets/images/blog"; - $yearPaths = glob($blogImagesPath . "/*", GLOB_ONLYDIR); - foreach ($yearPaths as $years) { - $year = explode("/", $years); - $monthsPath = glob($blogImagesPath . "/" . $year[5] . "/*", GLOB_ONLYDIR); - foreach ($monthsPath as $months) { - $month = explode("/", $months); - //once info is collected, add images pages to zip - $options = [ - "add_path" => - "public/assets/images/blog/" . $year[5] . "/" . $month[6] . "/", - "remove_all_path" => true, - ]; - $zip->addGlob($months . "/*.*", GLOB_BRACE, $options); - } - } - - //gather data and path info for user images - $userImagesPath = "../public/assets/images/user"; - $yearPaths = glob($userImagesPath . "/*", GLOB_ONLYDIR); - foreach ($yearPaths as $years) { - $year = explode("/", $years); - $monthsPath = glob($userImagesPath . "/" . $year[5] . "/*", GLOB_ONLYDIR); - foreach ($monthsPath as $months) { - $month = explode("/", $months); - //once info is collected, add images pages to zip - $options = [ - "add_path" => - "public/assets/images/user/" . $year[5] . "/" . $month[6] . "/", - "remove_all_path" => true, - ]; - $zip->addGlob($months . "/*.*", GLOB_BRACE, $options); - } - } - - //add directory for settings and save them - $zip->addEmptyDir("settings"); - $zip->addFile("../config/settings.json", "settings/settings.json"); - $zip->addFile("../config/folks.json", "settings/folks.json"); - $zip->addFile("../config/tags.json", "settings/tags.json"); - //save zip file - $zip->close(); - - //update settings file with latest back up date - $updated = new \Moment\Moment(); - Settings::updateGlobalData( - "last_backup", - $updated->format("Y-m-d\TH:i:sP") - ); - - $result = ["message" => "Backup created. THIS IS A SAFE SPACE!"]; - return $result; - } -} diff --git a/brain/utility/Maintenance.php b/brain/utility/Maintenance.php new file mode 100644 index 0000000..63bed09 --- /dev/null +++ b/brain/utility/Maintenance.php @@ -0,0 +1,104 @@ +open( + "../config/backups/latest_back.zip", + \ZipArchive::CREATE | \ZipArchive::OVERWRITE + ); + //gather data and path info for md pages + $pagePath = "../content/pages"; + $yearPaths = glob($pagePath . "/*", GLOB_ONLYDIR); + foreach ($yearPaths as $years) { + $year = explode("/", $years); + //grap the index and save it + if (trim($year[3]) == "start") { + $options = [ + "add_path" => "content/pages/" . $year[3] . "/", + "remove_all_path" => true, + ]; + $zip->addGlob($years . "/*.md", GLOB_BRACE, $options); + } + $monthsPath = glob($pagePath . "/" . $year[3] . "/*", GLOB_ONLYDIR); + foreach ($monthsPath as $months) { + $month = explode("/", $months); + //once info is collected, add md pages to zip + $options = [ + "add_path" => "content/pages/" . $year[3] . "/" . $month[4] . "/", + "remove_all_path" => true, + ]; + $zip->addGlob($months . "/*.md", GLOB_BRACE, $options); + } + } + + //gather data and path info for blog images + $blogImagesPath = "../public/assets/images/blog"; + $yearPaths = glob($blogImagesPath . "/*", GLOB_ONLYDIR); + foreach ($yearPaths as $years) { + $year = explode("/", $years); + $monthsPath = glob($blogImagesPath . "/" . $year[5] . "/*", GLOB_ONLYDIR); + foreach ($monthsPath as $months) { + $month = explode("/", $months); + //once info is collected, add images pages to zip + $options = [ + "add_path" => + "public/assets/images/blog/" . $year[5] . "/" . $month[6] . "/", + "remove_all_path" => true, + ]; + $zip->addGlob($months . "/*.*", GLOB_BRACE, $options); + } + } + + //gather data and path info for user images + $userImagesPath = "../public/assets/images/user"; + $yearPaths = glob($userImagesPath . "/*", GLOB_ONLYDIR); + foreach ($yearPaths as $years) { + $year = explode("/", $years); + $monthsPath = glob($userImagesPath . "/" . $year[5] . "/*", GLOB_ONLYDIR); + foreach ($monthsPath as $months) { + $month = explode("/", $months); + //once info is collected, add images pages to zip + $options = [ + "add_path" => + "public/assets/images/user/" . $year[5] . "/" . $month[6] . "/", + "remove_all_path" => true, + ]; + $zip->addGlob($months . "/*.*", GLOB_BRACE, $options); + } + } + + //add directory for settings and save them + $zip->addEmptyDir("settings"); + $zip->addFile("../config/settings.json", "settings/settings.json"); + $zip->addFile("../config/folks.json", "settings/folks.json"); + $zip->addFile("../config/tags.json", "settings/tags.json"); + //save zip file + $zip->close(); + + //update settings file with latest back up date + $updated = new \Moment\Moment(); + Settings::updateGlobalData( + "last_backup", + $updated->format("Y-m-d\TH:i:sP") + ); + + $result = ["message" => "Backup created. THIS IS A SAFE SPACE!"]; + return $result; + } +} diff --git a/brain/utility/Setup.inc.php b/brain/utility/Setup.inc.php deleted file mode 100644 index 5f09f47..0000000 --- a/brain/utility/Setup.inc.php +++ /dev/null @@ -1,223 +0,0 @@ -getParsedBody(); - $handle = $body["new_member_handle"]; - $email = $body["new_member_email"]; - $pass = $body["new_member_pass"]; - $title = $body["new_member_title"]; - - $now = new \Moment\Moment(); - //setup folks config - $hash = password_hash($pass, PASSWORD_DEFAULT); - $newFolks[0]["id"] = 0; - $newFolks[0]["handle"] = $handle; - $newFolks[0]["email"] = $email; - $newFolks[0]["password"] = $hash; - $newFolks[0]["key"] = password_hash($email, PASSWORD_DEFAULT); - $newFolks[0]["secret"] = StringTools::randomString(12); - $newFolks[0]["role"] = "hnic"; - $newFolks[0]["created"] = $now->format("Y-m-d\TH:i:sP"); - $newFolks[0]["updated"] = $now->format("Y-m-d\TH:i:sP"); - //set up settings config - $newSettings["global"]["title"] = $title; - - //create index file - //$rightNow = $now->format("Y-m-d\TH:i:sP"); - //var_dump($now->format("Y-m-d\TH:i:sP")); - $index = [ - "id" => 1, - "uuid" => StringTools::createUUID(), - "title" => "FIRST!", - "feature" => "/assets/images/global/default-bg.jpg", - "path" => "content/pages/start", - "layout" => "index", - "tags" => "start, welcome", - "author" => $handle, - "created" => $now->format("Y-m-d\TH:i:sP"), - "updated" => $now->format("Y-m-d\TH:i:sP"), - "deleted" => "false", - "slug" => "first", - "menu" => "false", - "featured" => "false", - "published" => "true", - "content" => - "# F**k Yes \n\nIf you're seeing this, you're up and running. NICE WORK!\n\nFrom here, feel free to start dropping pages to your heart's content.\n\nFor some tips about using Fipamo, check out the ![docs](https://code.playvicio.us/Are0h/Fipamo/wiki/02-Usage)\n\nAll good? Feel free to edit this page to whatever you want!\n\nYOU'RE THE CAPTAIN NOW.", - ]; - - $freshIndex = DocTools::objectToMD($index); - - //once all files created, write down - - DocTools::writeSettings("../config/settings.json", $newSettings); - DocTools::writeSettings("../config/folks.json", $newFolks); - DocTools::writeSettings("../config/tags.json", []); - DocTools::writePages( - "create", - "start", - "../content/pages/start/index.md", - $freshIndex - ); - - //if there is an older session file, get rid of it - if (is_file("../content/.session")) { - unlink("../content/.session"); - } - - $result = ["type" => "blogInitGood", "message" => "Site Created"]; - - return $result; - } - - public static function restore($request) - { - $result = [ - "type" => "requestLame", - "message" => "Still working on it.", - ]; - $body = $request->getParsedBody(); - - $backup = $request->getUploadedFiles(); - $file = $backup["backup-upload"]; - $size = $file->getSize(); - $name = $file->getClientFileName(); - - //park it so it can be read - $file->moveTo("../content" . "/" . $name); - - //open it and get files to verify user - $zip = new ZipArchive(); - if ($zip->open("../content" . "/" . $name) === true) { - $folks = json_decode($zip->getFromName("settings/folks.json"), true); - $found = find($folks, ["handle" => $body["restore_member_handle"]]); - - //if member is found in back up, check pass - if ($found) { - if (password_verify($body["restore_member_pass"], $found["password"])) { - //backup verified, restore site - - //set new secret key for older folks configs - $newFolks = []; - if (!isset($found["secret"])) { - $found["secret"] = StringTools::randomString(12); - } - array_push($newFolks, $found); - //dump files in folder - $zip->extractTo("../content"); - - //move to appropriate spots - /* - rename( - "../content/settings/settings.json", - "../config/settings.json" - ); - */ - - //load up old config file - $newConfig = json_decode( - file_get_contents("../content/settings/settings.json"), - true - ); - //check for key, add if not there - if (!isset($newConfig["global"]["externalAPI"])) { - $newConfig["global"]["externalAPI"] = "false"; - } - //write new config file - DocTools::writeSettings("../config/settings.json", $newConfig); - - //rename("../content/settings/folks.json", "../config/folks.json"); - DocTools::writeSettings("../config/folks.json", $newFolks); - - rename("../content/settings/tags.json", "../config/tags.json"); - - //images path for blog and user - $blogImagePath = "../public/assets/images/blog"; - $userImagePath = "../public/assets/images/user"; - - //check to see if image dirs are empty, if not chill - if ($globs = glob($blogImagePath . "/*")) { - //directory not empty, relax - } else { - rename("../content/public/assets/images/blog", $blogImagePath); - } - - if ($globs = glob($userImagePath . "/*")) { - //directory not empty, relax - } else { - rename("../content/public/assets/images/user", $userImagePath); - } - - rename("../content/content/pages/", "../content/pages"); - - //legacy check for old file structure - if (is_file("../content/pages/index.md")) { - if (!is_dir("../content/pages/start")) { - //Directory does not exist, so lets create it. - mkdir("../content/pages/start", 0755, true); - //move start page to appropriate spot - rename( - "../content/pages/index.md", - "../content/pages/start/index.md" - ); - } - } else { - //chill - } - - //clean up - - DocTools::deleteFolder("../content/settings"); - DocTools::deleteFolder("../content/public"); - DocTools::deleteFolder("../content/content"); - $result = [ - "type" => "requestGood", - "message" => "Site Restored! Redirecting", - ]; - } else { - $result = [ - "type" => "requestLame", - "message" => "Check that password, champ.", - ]; - } - } else { - $result = [ - "type" => "requestLame", - "message" => "No member found by that name, hoss", - ]; - } - - $zip->close(); - $zipPath = "../content/" . $name; - //trash zip when done - unlink($zipPath); - } else { - $result = [ - "type" => "requestLame", - "message" => "Could not open backup. RATS!", - ]; - } - return $result; - } -} diff --git a/brain/utility/Setup.php b/brain/utility/Setup.php new file mode 100644 index 0000000..20909c0 --- /dev/null +++ b/brain/utility/Setup.php @@ -0,0 +1,229 @@ +getParsedBody(); + $handle = $body["new_member_handle"]; + $email = $body["new_member_email"]; + $pass = $body["new_member_pass"]; + $title = $body["new_member_title"]; + + $now = new \Moment\Moment(); + //setup folks config + $hash = password_hash($pass, PASSWORD_DEFAULT); + $newFolks[0]["id"] = 0; + $newFolks[0]["handle"] = $handle; + $newFolks[0]["email"] = $email; + $newFolks[0]["password"] = $hash; + $newFolks[0]["key"] = password_hash($email, PASSWORD_DEFAULT); + $newFolks[0]["secret"] = StringTools::randomString(12); + $newFolks[0]["role"] = "hnic"; + $newFolks[0]["created"] = $now->format("Y-m-d\TH:i:sP"); + $newFolks[0]["updated"] = $now->format("Y-m-d\TH:i:sP"); + //set up settings config + $newSettings["global"]["title"] = $title; + + //create index file + //$rightNow = $now->format("Y-m-d\TH:i:sP"); + //var_dump($now->format("Y-m-d\TH:i:sP")); + $index = [ + "id" => 1, + "uuid" => StringTools::createUUID(), + "title" => "FIRST!", + "feature" => "/assets/images/global/default-bg.jpg", + "files" => "", + "path" => "content/pages/start", + "layout" => "index", + "tags" => "start, welcome", + "author" => $handle, + "created" => $now->format("Y-m-d\TH:i:sP"), + "updated" => $now->format("Y-m-d\TH:i:sP"), + "deleted" => "false", + "slug" => "first", + "menu" => "false", + "featured" => "false", + "published" => "true", + "content" => + "# F**k Yes \n\nIf you're seeing this, you're up and running. NICE WORK!\n\nFrom here, feel free to start dropping pages to your heart's content.\n\nFor some tips about using Fipamo, check out the ![docs](https://code.playvicio.us/Are0h/Fipamo/wiki/02-Usage)\n\nAll good? Feel free to edit this page to whatever you want!\n\nYOU'RE THE CAPTAIN NOW.", + ]; + + $freshIndex = DocTools::objectToMD($index); + + //once all files created, write down + + DocTools::writeSettings("../config/settings.json", $newSettings); + DocTools::writeSettings("../config/folks.json", $newFolks); + DocTools::writeSettings("../config/tags.json", []); + DocTools::writePages( + "create", + "start", + "../content/pages/start/index.md", + $freshIndex + ); + + //if there is an older session file, get rid of it + if (is_file("../content/.session")) { + unlink("../content/.session"); + } + + $result = ["type" => "blogInitGood", "message" => "Site Created"]; + + return $result; + } + + public static function restore($request) + { + $result = [ + "type" => "requestLame", + "message" => "Still working on it.", + ]; + $body = $request->getParsedBody(); + + $backup = $request->getUploadedFiles(); + $file = $backup["backup-upload"]; + //NOTE: If this fails check 'post_max_size' in php.ini + $size = $file->getSize(); + $name = $file->getClientFileName(); + + //park it so it can be read + $file->moveTo("../content" . "/" . $name); + + //open it and get files to verify user + $zip = new \ZipArchive(); + if ($zip->open("../content" . "/" . $name) === true) { + $folks = json_decode($zip->getFromName("settings/folks.json"), true); + $found = find($folks, ["handle" => $body["restore_member_handle"]]); + + //if member is found in back up, check pass + if ($found) { + if (password_verify($body["restore_member_pass"], $found["password"])) { + //backup verified, restore site + + //set new secret key for older folks configs + $newFolks = []; + if (!isset($found["secret"])) { + $found["secret"] = StringTools::randomString(12); + } + array_push($newFolks, $found); + //dump files in folder + $zip->extractTo("../content"); + + //move to appropriate spots + /* + rename( + "../content/settings/settings.json", + "../config/settings.json" + ); + */ + + //load up old config file + $newConfig = json_decode( + file_get_contents("../content/settings/settings.json"), + true + ); + //check for key, add if not there + if (!isset($newConfig["global"]["externalAPI"])) { + $newConfig["global"]["externalAPI"] = "false"; + } + //write new config file + DocTools::writeSettings("../config/settings.json", $newConfig); + + //rename("../content/settings/folks.json", "../config/folks.json"); + DocTools::writeSettings("../config/folks.json", $newFolks); + + rename("../content/settings/tags.json", "../config/tags.json"); + + //images path for blog and user + $blogImagePath = "../public/assets/images/blog"; + $userImagePath = "../public/assets/images/user"; + + //check to see if image dirs are empty, if not chill + if ($globs = glob($blogImagePath . "/*")) { + //directory not empty, relax + } else { + rename("../content/public/assets/images/blog", $blogImagePath); + } + + if ($globs = glob($userImagePath . "/*")) { + //directory not empty, relax + } else { + rename("../content/public/assets/images/user", $userImagePath); + } + + rename("../content/content/pages/", "../content/pages"); + + //legacy check for old file structure + if (is_file("../content/pages/index.md")) { + if (!is_dir("../content/pages/start")) { + //Directory does not exist, so lets create it. + mkdir("../content/pages/start", 0755, true); + //move start page to appropriate spot + rename( + "../content/pages/index.md", + "../content/pages/start/index.md" + ); + } + } else { + //chill + } + + //clean up + + DocTools::deleteFolder("../content/settings"); + DocTools::deleteFolder("../content/public"); + DocTools::deleteFolder("../content/content"); + $result = [ + "type" => "requestGood", + "message" => "Site Restored! Redirecting", + ]; + } else { + $result = [ + "type" => "requestLame", + "message" => "Check that password, champ.", + ]; + } + } else { + $result = [ + "type" => "requestLame", + "message" => "No member found by that name, hoss", + ]; + } + + $zip->close(); + $zipPath = "../content/" . $name; + //trash zip when done + unlink($zipPath); + } else { + $result = [ + "type" => "requestLame", + "message" => "Could not open backup. RATS!", + ]; + } + return $result; + } +} diff --git a/brain/utility/Sorting.inc.php b/brain/utility/Sorting.inc.php deleted file mode 100644 index 70ee2a1..0000000 --- a/brain/utility/Sorting.inc.php +++ /dev/null @@ -1,238 +0,0 @@ -getContents(); - foreach ($pages as $page) { - $temp = []; - $temp = explode(",", $page["tags"]); - foreach ($temp as $tag) { - $label = trim($tag); - if (!find(self::$_tags, ["tag_name" => $label])) { - array_push(self::$_tags, [ - "tag_name" => $label, - "slug" => StringTools::safeString($label), - "pages" => self::tagPages($label, $pages), - ]); - } - } - } - - return self::$_tags; - } - - private static function tagPages($tag, $pages) - { - $tagged = []; - foreach ($pages as $page) { - if (strpos($page["tags"], $tag) !== false) { - array_push($tagged, [ - "title" => $page["title"], - "slug" => $page["slug"], - "path" => $page["path"], - "feature" => $page["feature"], - ]); - } - } - - return $tagged; - } - - public static function archive() - { - $pages = (new Book("../content/pages"))->getContents(); - $years = []; - $archive = []; - foreach ($pages as $page) { - //$year = date("Y", date($page["rawCreated"])); - $date = explode("/", $page["path"]); - //echo $page["title"] . " : " . $year . "\n"; - if (!find($years, ["year" => trim($date[0])])) { - $findPages = filter($pages, ["createdYear" => trim($date[0])]); - //var_dump($findPages); - array_push($years, [ - "year" => trim($date[0]), - "count" => count($findPages), - ]); - } - } - foreach ($years as $year) { - $sorted = []; - $filtered = filter($pages, ["createdYear" => $year["year"]]); - - foreach ($filtered as $obj) { - $month = date("m", date($obj["rawCreated"])); - if (!find($sorted, ["month" => $month])) { - $perMonth = filter($pages, [ - "path" => $year["year"] . "/" . $month, - "deleted" => false, - "published" => true, - "layout" => "page", - ]); - array_push($sorted, [ - "month" => $month, - "full_month" => date("F", date($obj["rawCreated"])), - "count" => count($perMonth), - "pages" => $perMonth, - ]); - } - } - array_push(self::$_archive, [ - "year" => $year["year"], - "year_data" => $sorted, - ]); - } - return self::$_archive; - } - - public static function page($page) - { - $config = new Settings(); - $settings = $config->getSettings(); - $pageOption = []; - - $pageInfo = [ - "keywords" => isset($settings["global"]["keywords"]) - ? $settings["global"]["keywords"] - : "fipamo, blog, jamstack, php, markdown, js", - "description" => $settings["global"]["descriptions"], - "image" => - $settings["global"]["base_url"] . $settings["global"]["background"], - "baseURL" => $settings["global"]["base_url"], - ]; - - $taglist = explode(",", $page["tags"]); - $tags = []; - foreach ($taglist as $tag) { - $label = trim($tag); - array_push($tags, [ - "label" => $label . " ", - "slug" => StringTools::safeString($label), - ]); - } - - $meta = [ - "who" => $page["author"], - "when" => $page["created"], - "tags" => $tags, - ]; - - //render markdown content and clean it - $parser = new Parser(); - $rendered = $parser->parse($page["content"]); - $sanitizer = HtmlSanitizer\Sanitizer::create([ - "extensions" => ["basic", "image", "list", "code"], - "tags" => [ - "img" => [ - "allowed_attributes" => ["src", "alt", "title", "class"], - "allowed_hosts" => null, - ], - ], - ]); - - $preclean = $sanitizer->sanitize($rendered->getContent()); - - //just clean renderd string for now, Sanitize doesn't like relative img urls - //so another option is needed - $cleaned = strip_tags($rendered->getContent(), [ - "a", - "br", - "p", - "strong", - "br", - "img", - "iframe", - "ul", - "li", - "i", - "em", - "h1", - "h2", - "h3", - "pre", - "code", - ]); - //$cleaned = preg_replace('/(?:\r\n|[\r\n]){2,}/', "\n\n", $cleaned); - //$cleaned = html_entity_decode($cleaned, ENT_QUOTES, "UTF-8"); - - //if page feature isn't empty, replace page info meta image - if ($page["feature"] != "" || $page["feature"] != null) { - $pageInfo["image"] = $pageInfo["baseURL"] . $page["feature"]; - } - - if ($page["layout"] == "index") { - //$template = $this->theme . "/index.twig"; - //$location = "../public/index.html"; - //$dir = null; - - $recent = []; - $featured = []; - $limit = 4; - $pages = (new Book())->getContents(); - foreach ($pages as $item) { - if ( - !$item["deleted"] && - $item["published"] && - $item["menu"] != "true" - ) { - if (count($recent) < $limit) { - array_push($recent, [ - "path" => $item["path"], - "slug" => $item["slug"], - "title" => $item["title"], - "feature" => $item["feature"], - ]); - } - - if ($item["featured"] == true) { - if (count($featured) < $limit) { - array_push($featured, [ - "path" => $item["path"], - "slug" => $item["slug"], - "title" => $item["title"], - "feature" => $item["feature"], - ]); - } - } - } - } - - $pageOptions = [ - "title" => $page["title"], - "background" => $page["feature"], - "content" => $page["html"], //$cleaned, - "meta" => $meta, - "recent" => $recent, - "featured" => $featured, - "info" => $pageInfo, - "menu" => $settings["menu"], - "dynamicRender" => $settings["global"]["dynamicRender"], - ]; - } else { - //$template = $this->theme . "/page.twig"; - //$location = "../public/" . $page["path"] . "/" . $page["slug"] . ".html"; - //$dir = "../public/" . $page["path"]; - $pageOptions = [ - "title" => $page["title"], - "background" => $page["feature"], - "content" => $page["html"], //$cleaned, - "meta" => $meta, - "info" => $pageInfo, - "menu" => $settings["menu"], - "dynamicRender" => $settings["global"]["dynamicRender"], - ]; - } - return $pageOptions; - } -} diff --git a/brain/utility/Sorting.php b/brain/utility/Sorting.php new file mode 100644 index 0000000..15f2800 --- /dev/null +++ b/brain/utility/Sorting.php @@ -0,0 +1,248 @@ +getContents(); + foreach ($pages as $page) { + $temp = []; + $temp = explode(",", $page["tags"]); + foreach ($temp as $tag) { + $label = trim($tag); + if (!find(self::$_tags, ["tag_name" => $label])) { + array_push(self::$_tags, [ + "tag_name" => $label, + "slug" => StringTools::safeString($label), + "pages" => self::tagPages($label, $pages), + ]); + } + } + } + + return self::$_tags; + } + + private static function tagPages($tag, $pages) + { + $tagged = []; + foreach ($pages as $page) { + if (strpos($page["tags"], $tag) !== false) { + array_push($tagged, [ + "title" => $page["title"], + "slug" => $page["slug"], + "path" => $page["path"], + "feature" => $page["feature"], + ]); + } + } + + return $tagged; + } + + public static function archive() + { + $pages = (new Book("../content/pages"))->getContents(); + $years = []; + $archive = []; + foreach ($pages as $page) { + //$year = date("Y", date($page["rawCreated"])); + $date = explode("/", $page["path"]); + //echo $page["title"] . " : " . $year . "\n"; + if (!find($years, ["year" => trim($date[0])])) { + $findPages = filter($pages, ["createdYear" => trim($date[0])]); + //var_dump($findPages); + array_push($years, [ + "year" => trim($date[0]), + "count" => count($findPages), + ]); + } + } + foreach ($years as $year) { + $sorted = []; + $filtered = filter($pages, ["createdYear" => $year["year"]]); + + foreach ($filtered as $obj) { + $month = date("m", date($obj["rawCreated"])); + if (!find($sorted, ["month" => $month])) { + $perMonth = filter($pages, [ + "path" => $year["year"] . "/" . $month, + "deleted" => false, + "published" => true, + "layout" => "page", + ]); + array_push($sorted, [ + "month" => $month, + "full_month" => date("F", date($obj["rawCreated"])), + "count" => count($perMonth), + "pages" => $perMonth, + ]); + } + } + array_push(self::$_archive, [ + "year" => $year["year"], + "year_data" => $sorted, + ]); + } + return self::$_archive; + } + + public static function page($page) + { + $config = new Settings(); + $settings = $config->getSettings(); + $pageOption = []; + + $pageInfo = [ + "keywords" => isset($settings["global"]["keywords"]) + ? $settings["global"]["keywords"] + : "fipamo, blog, jamstack, php, markdown, js", + "description" => $settings["global"]["descriptions"], + "image" => + $settings["global"]["base_url"] . $settings["global"]["background"], + "baseURL" => $settings["global"]["base_url"], + ]; + + $taglist = explode(",", $page["tags"]); + $tags = []; + foreach ($taglist as $tag) { + $label = trim($tag); + array_push($tags, [ + "label" => $label . " ", + "slug" => StringTools::safeString($label), + ]); + } + + $meta = [ + "who" => $page["author"], + "when" => $page["created"], + "tags" => $tags, + ]; + + //render markdown content and clean it + $parser = new Parser(); + $rendered = $parser->parse($page["content"]); + $sanitizer = \HtmlSanitizer\Sanitizer::create([ + "extensions" => ["basic", "image", "list", "code"], + "tags" => [ + "img" => [ + "allowed_attributes" => ["src", "alt", "title", "class"], + "allowed_hosts" => null, + ], + ], + ]); + + $preclean = $sanitizer->sanitize($rendered->getContent()); + + //just clean renderd string for now, Sanitize doesn't like relative img urls + //so another option is needed + $cleaned = strip_tags($rendered->getContent(), [ + "a", + "br", + "p", + "strong", + "br", + "img", + "iframe", + "ul", + "li", + "i", + "em", + "h1", + "h2", + "h3", + "pre", + "code", + ]); + //$cleaned = preg_replace('/(?:\r\n|[\r\n]){2,}/', "\n\n", $cleaned); + //$cleaned = html_entity_decode($cleaned, ENT_QUOTES, "UTF-8"); + + //if page feature isn't empty, replace page info meta image + if ($page["feature"] != "" || $page["feature"] != null) { + $pageInfo["image"] = $pageInfo["baseURL"] . $page["feature"]; + } + + if ($page["layout"] == "index") { + //$template = $this->theme . "/index.twig"; + //$location = "../public/index.html"; + //$dir = null; + + $recent = []; + $featured = []; + $limit = 4; + $pages = (new Book())->getContents(); + foreach ($pages as $item) { + if ( + !$item["deleted"] && + $item["published"] && + $item["menu"] != "true" + ) { + if (count($recent) < $limit) { + array_push($recent, [ + "path" => $item["path"], + "slug" => $item["slug"], + "title" => $item["title"], + "feature" => $item["feature"], + ]); + } + + if ($item["featured"] == true) { + if (count($featured) < $limit) { + array_push($featured, [ + "path" => $item["path"], + "slug" => $item["slug"], + "title" => $item["title"], + "feature" => $item["feature"], + ]); + } + } + } + } + + $pageOptions = [ + "title" => $page["title"], + "background" => $page["feature"], + "content" => $page["html"], //$cleaned, + "meta" => $meta, + "recent" => $recent, + "featured" => $featured, + "info" => $pageInfo, + "menu" => $settings["menu"], + "dynamicRender" => $settings["global"]["dynamicRender"], + "media" => $page["media"], + "files" => $page["docs"], + ]; + } else { + //$template = $this->theme . "/page.twig"; + //$location = "../public/" . $page["path"] . "/" . $page["slug"] . ".html"; + //$dir = "../public/" . $page["path"]; + $pageOptions = [ + "title" => $page["title"], + "background" => $page["feature"], + "content" => $page["html"], //$cleaned, + "meta" => $meta, + "info" => $pageInfo, + "menu" => $settings["menu"], + "dynamicRender" => $settings["global"]["dynamicRender"], + "media" => $page["media"], + "files" => $page["docs"], + ]; + } + return $pageOptions; + } +} diff --git a/brain/utility/StringTools.inc.php b/brain/utility/StringTools.inc.php deleted file mode 100644 index 2c16ae7..0000000 --- a/brain/utility/StringTools.inc.php +++ /dev/null @@ -1,130 +0,0 @@ -parse($entry); - $sanitizer = HtmlSanitizer\Sanitizer::create([ - "extensions" => ["basic", "image", "list", "code"], - "tags" => [ - "img" => [ - "allowed_attributes" => ["src", "alt", "title", "class"], - "allowed_hosts" => null, - ], - ], - ]); - - $preclean = $sanitizer->sanitize($rendered->getContent()); - - $cleaned = strip_tags($rendered->getContent(), [ - "a", - "br", - "p", - "strong", - "br", - "img", - "iframe", - "ul", - "li", - "i", - "h1", - "h2", - "h3", - "pre", - "code", - ]); - - return $cleaned; - } - - public static function safeString($string) - { - return strtolower( - trim( - preg_replace( - "~[^0-9a-z]+~i", - "_", - html_entity_decode( - preg_replace( - "~&([a-z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i", - '$1', - htmlentities($string, ENT_QUOTES, "UTF-8") - ), - ENT_QUOTES, - "UTF-8" - ) - ), - "-" - ) - ); - } - - public static function randomString(int $length) - { - $alphanum = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - $special = '*&!@%^#$'; - $alphabet = $alphanum . $special; - $random = openssl_random_pseudo_bytes($length); - $alphabet_length = strlen($alphabet); - $string = ""; - for ($i = 0; $i < $length; ++$i) { - $string .= $alphabet[ord($random[$i]) % $alphabet_length]; - } - - //secret needs to be a valid token - if ($length == 12) { - try { - $secret = Token::create(12, $string, time() + 3600, "localhost"); - return $string; - } catch (BuildException $e) { - //bad secret, so try agiain - //echo "BAD STRING"; - return self::randomString(12); - } - - if (Token::validate($key, $string)) { - return $string; - } else { - return self::randomString(12); - } - } - } - - private static function checkSpecial($string) - { - $specials = ["*", "&", "!", "@", "%", "^", "#", "$"]; - $valid = false; - foreach ($specials as $item) { - if (strpos($string, $item)) { - return $valid = true; - } - } - return $valid; - } -} diff --git a/brain/utility/StringTools.php b/brain/utility/StringTools.php new file mode 100644 index 0000000..f39ae12 --- /dev/null +++ b/brain/utility/StringTools.php @@ -0,0 +1,132 @@ +parse($entry); + $sanitizer = HtmlSanitizer\Sanitizer::create([ + "extensions" => ["basic", "image", "list", "code"], + "tags" => [ + "img" => [ + "allowed_attributes" => ["src", "alt", "title", "class"], + "allowed_hosts" => null, + ], + ], + ]); + + $preclean = $sanitizer->sanitize($rendered->getContent()); + + $cleaned = strip_tags($rendered->getContent(), [ + "a", + "br", + "p", + "strong", + "br", + "img", + "iframe", + "ul", + "li", + "i", + "h1", + "h2", + "h3", + "pre", + "code", + ]); + + return $cleaned; + } + + public static function safeString($string) + { + return strtolower( + trim( + preg_replace( + "~[^0-9a-z]+~i", + "_", + html_entity_decode( + preg_replace( + "~&([a-z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i", + '$1', + htmlentities($string, ENT_QUOTES, "UTF-8") + ), + ENT_QUOTES, + "UTF-8" + ) + ), + "-" + ) + ); + } + + public static function randomString(int $length) + { + $alphanum = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + $special = '*&!@%^#$'; + $alphabet = $alphanum . $special; + $random = openssl_random_pseudo_bytes($length); + $alphabet_length = strlen($alphabet); + $string = ""; + for ($i = 0; $i < $length; ++$i) { + $string .= $alphabet[ord($random[$i]) % $alphabet_length]; + } + + //secret needs to be a valid token + if ($length == 12) { + try { + $secret = Token::create(12, $string, time() + 3600, "localhost"); + return $string; + } catch (BuildException $e) { + //bad secret, so try agiain + //echo "BAD STRING"; + return self::randomString(12); + } + + if (Token::validate($key, $string)) { + return $string; + } else { + return self::randomString(12); + } + } + } + + private static function checkSpecial($string) + { + $specials = ["*", "&", "!", "@", "%", "^", "#", "$"]; + $valid = false; + foreach ($specials as $item) { + if (strpos($string, $item)) { + return $valid = true; + } + } + return $valid; + } +} diff --git a/brain/views/dash/book.twig b/brain/views/dash/book.twig index 5cb33c5..813b291 100644 --- a/brain/views/dash/book.twig +++ b/brain/views/dash/book.twig @@ -5,7 +5,7 @@ {% endblock %} {% block stylesheets %} - + {% endblock %} {% block mainContent %} @@ -45,58 +45,36 @@
{% for page in pages %} - -
- - - + + + {% else %} + +
+ +
+ {{ include("dash/partials/recent-options.twig") }} +
+
+
+ {% endif %} + {% endfor %} {% if numOfPages > 1 %}
diff --git a/brain/views/dash/forms/login.twig b/brain/views/dash/forms/login.twig index aa31550..2a8792d 100644 --- a/brain/views/dash/forms/login.twig +++ b/brain/views/dash/forms/login.twig @@ -1,7 +1,7 @@
-
- +
+
+
+ +
+ IMAGES AND VIDEO +
+ {% if media|length > 1 %} + {% for item in media %} + {% if item.type == "mp4"%} +
+ {% else %} +
+ {% endif %} + {% endfor %} + {% else %} + {% if media[0] != '' %} + {% if media[0].type == "mp4"%} +
+ {% else %} +
+ {% endif %} + {% else %} + {% endif %} + {% endif %} + +
+ FILES +
+ {% if files|length > 1 %} + {% for item in files %} + {% if item.type == "mp3"%} +
+ {% else %} +
+ {% endif %} + {% endfor %} + {% else %} + {% if files[0] != '' %} + {% if files[0].type == "mp3"%} +
+ {% else %} +
+ {% endif %} + {% else %} + + {% endif %} + {% endif %} + +
+
+ +
{% endif %}
@@ -95,7 +153,7 @@ {{ updated }} - +
@@ -119,5 +177,5 @@ {% endblock %} {% block javascripts %} - + {% endblock %} \ No newline at end of file diff --git a/brain/views/dash/partials/index.twig b/brain/views/dash/partials/index.twig index 7f26de9..01fe989 100644 --- a/brain/views/dash/partials/index.twig +++ b/brain/views/dash/partials/index.twig @@ -25,53 +25,30 @@
{% if data["entryCount"] != 0 %} {% for page in data['pages'] %} - - -
- {% if page.menu == 'true' %} - {% set menu = "true" %} - {% else %} - {% set menu = "false" %} - {% endif %} - {% if page.published == 'true' %} - {% set published = "true" %} - {% else %} - {% set published = "false" %} - {% endif %} - {% if page.featured == 'true' %} - {% set featured = "true" %} - {% else %} - {% set featured = "false" %} - {% endif %} -
- - - - - -
-
- - {{ page.updated }} - -
+ {% if page.media[0].type == 'mp4' %} -
-
+ + + + {{ include("dash/partials/recent-options.twig") }} + + + {% else %} + + + + {{ include("dash/partials/recent-options.twig") }} + + {% endif %} + {% endfor %} {% else %} There are no pages diff --git a/brain/views/dash/partials/recent-options.twig b/brain/views/dash/partials/recent-options.twig new file mode 100644 index 0000000..c7e8096 --- /dev/null +++ b/brain/views/dash/partials/recent-options.twig @@ -0,0 +1,42 @@ +
+ {% if page.menu == 'true' %} + {% set menu = "true" %} + {% else %} + {% set menu = "false" %} + {% endif %} + {% if page.published == 'true' %} + {% set published = "true" %} + {% else %} + {% set published = "false" %} + {% endif %} + {% if page.featured == 'true' %} + {% set featured = "true" %} + {% else %} + {% set featured = "false" %} + {% endif %} +
+ + + + + +
+
+ + {{ page.updated }} + +
+ +
\ No newline at end of file diff --git a/brain/views/dash/start.twig b/brain/views/dash/start.twig index da57bd8..aff4004 100644 --- a/brain/views/dash/start.twig +++ b/brain/views/dash/start.twig @@ -5,7 +5,7 @@ {% endblock %} {% block stylesheets %} - + {% endblock %} {% block mainContent %} @@ -23,5 +23,5 @@ {% endblock %} {% block javascripts %} - + {% endblock %} \ No newline at end of file diff --git a/composer.json b/composer.json index 25e5c5d..1881c97 100644 --- a/composer.json +++ b/composer.json @@ -9,6 +9,11 @@ "homepage": "https://roiskinda.cool" } ], + "autoload": { + "psr-4": { + "brain\\":"brain" + } + }, "support": { "source": "https://code.playvicio.us/Are0h/Fipamo", "wiki": "https://code.playvicio.us/Are0h/Fipamo/wiki/_pages", diff --git a/content/themes/fipamo-default/archive.twig b/content/themes/fipamo-default/archive.twig index 45ff5c1..681596e 100644 --- a/content/themes/fipamo-default/archive.twig +++ b/content/themes/fipamo-default/archive.twig @@ -1,4 +1,4 @@ -{% extends "fipamo-default/frame.twig" %} +{% extends "frame.twig" %} {% block title %} {{ title }} diff --git a/content/themes/fipamo-default/assets/css/base.css b/content/themes/fipamo-default/assets/css/base.css index a1a08e0..ff391d5 100644 --- a/content/themes/fipamo-default/assets/css/base.css +++ b/content/themes/fipamo-default/assets/css/base.css @@ -1,31 +1,32 @@ -/** -------------------------------- --- Typography -------------------------------- -**/ -/** -------------------------------- --- Colors -------------------------------- -**/ -/** -------------------------------- --- Mixins -------------------------------- -**/ -/** -------------------------------- --- Normalize -------------------------------- -**/ +h1, h2, h3 { + color: #ebe5d4; +} + +h1 { + font-size: 2em; + font-weight: 400; +} + +h2 { + font-size: 1.75em; + font-weight: 400; +} + +h3 { + font-size: 1.5em; + font-weight: 300; +} + html { line-height: 1.15; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; } + body { margin: 0; } + article, aside, footer, @@ -34,62 +35,75 @@ nav, section { display: block; } + h1 { font-size: 2em; margin: 0.67em 0; line-height: 1em; } + figcaption, figure, main { display: block; } + figure { margin: 1em 40px; } + hr { box-sizing: content-box; height: 0; overflow: visible; } + pre { font-family: monospace, monospace; font-size: 1em; } + a { background-color: transparent; -webkit-text-decoration-skip: objects; } + a:active, a:hover { outline-width: 0; } + abbr[title] { border-bottom: none; text-decoration: underline; text-decoration: underline dotted; } + b, strong { font-weight: inherit; font-weight: bolder; } -code, + kbd, samp { font-family: monospace, monospace; font-size: 1em; } + dfn { font-style: italic; } + mark { background-color: #ff0; color: #000; } + small { font-size: 80%; } + sub, sup { font-size: 60%; @@ -97,31 +111,38 @@ sup { position: relative; vertical-align: baseline; } + sub { bottom: -0.25em; } + sup { top: -0.55em; - background: #bdcbdb; + background: #151d26; color: #151d26; border-radius: 2px; padding: 0 2px 0 2px; margin: 0 2px 0 0; } + audio, video { display: inline-block; } + audio:not([controls]) { display: none; height: 0; } + img { border-style: none; } + svg:not(:root) { overflow: hidden; } + button, input, optgroup, @@ -132,38 +153,44 @@ textarea { line-height: 1.15; margin: 0; } + button, input { overflow: visible; } + button, select { text-transform: none; } -button, -html [type="button"], -[type="reset"], -[type="submit"] { + +button, html [type=button], +[type=reset], +[type=submit] { -webkit-appearance: button; } -[type="button"]::-moz-focus-inner, -[type="reset"]::-moz-focus-inner, -[type="submit"]::-moz-focus-inner, + +[type=button]::-moz-focus-inner, +[type=reset]::-moz-focus-inner, +[type=submit]::-moz-focus-inner, button::-moz-focus-inner { border-style: none; padding: 0; } -[type="button"]:-moz-focusring, -[type="reset"]:-moz-focusring, -[type="submit"]:-moz-focusring, + +[type=button]:-moz-focusring, +[type=reset]:-moz-focusring, +[type=submit]:-moz-focusring, button:-moz-focusring { outline: 1px dotted ButtonText; } + fieldset { border: 1px solid #c0c0c0; margin: 0 2px; padding: 0.35em 0.625em 0.75em; } + legend { box-sizing: border-box; color: inherit; @@ -172,55 +199,143 @@ legend { padding: 0; white-space: normal; } + progress { display: inline-block; vertical-align: baseline; } + textarea { overflow: auto; } -[type="checkbox"], -[type="radio"] { + +[type=checkbox], +[type=radio] { box-sizing: border-box; padding: 0; } -[type="number"]::-webkit-inner-spin-button, -[type="number"]::-webkit-outer-spin-button { + +[type=number]::-webkit-inner-spin-button, +[type=number]::-webkit-outer-spin-button { height: auto; } -[type="search"] { + +[type=search] { -webkit-appearance: textfield; outline-offset: -2px; } -[type="search"]::-webkit-search-cancel-button, -[type="search"]::-webkit-search-decoration { + +[type=search]::-webkit-search-cancel-button, +[type=search]::-webkit-search-decoration { -webkit-appearance: none; } + ::-webkit-file-upload-button { -webkit-appearance: button; font: inherit; } + details, menu { display: block; } + summary { display: list-item; } + canvas { display: inline-block; } + template { display: none; } + [hidden] { display: none; } -/** -------------------------------- --- Main Structure -------------------------------- -**/ + +form { + display: inline-block; +} +form a { + color: #151d26; +} +form p { + background: #e8c33e; + color: #151d26; + padding: 5px; + display: block; + border-radius: 5px; + text-align: left; +} + +input[type=email], input[type=password], input[type=text] { + border: 0; + border-radius: 5px; + padding: 5px; + margin: 10px 5px 0 0; + font: 18px Helvetica, Arial, sans-serif; + display: inline-block; + background: #151d26; + color: #e8c33e; +} + +textarea { + border: 0; + border-radius: 3px; + color: #ebe5d4; + font: 15px Helvetica, Arial, sans-serif; + background: #151d26; +} + +button, input[type=submit] { + background: #7ED07E; + color: #151d26; + font: 20px Helvetica, Arial, sans-serif; + border-radius: 5px; + position: relative; + cursor: pointer; + border: 0; + padding: 10px 0 5px 0; + -moz-transition: all 0.3s linear; + -webkit-transition: all 0.3s linear; + -o-transition: all 0.3s linear; + transition: all 0.3s linear; +} + +select { + font: 14px Helvetica, Arial, sans-serif; + border: 1px solid #FC6399; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + color: #151d26; +} + +::-webkit-input-placeholder { + font: 25px Helvetica, Arial, sans-serif; + color: #ebe5d4; +} + +:-moz-placeholder { + /* Firefox 18- */ + font: 25px Helvetica, Arial, sans-serif; + color: #ebe5d4; +} + +::-moz-placeholder { + /* Firefox 19+ */ + font: 15px Helvetica, Arial, sans-serif; + color: #ebe5d4; +} + +:-ms-input-placeholder { + font: 25px Helvetica, Arial, sans-serif; + color: #ebe5d4; +} + html { margin: 0; padding: 0; @@ -229,6 +344,7 @@ html { overflow: hidden; font: 400 1.2em/1.4em Helvetica, Arial, sans-serif; } + body { background: #ebe5d4; margin: 0; @@ -240,51 +356,79 @@ body { overflow-y: scroll; overflow-x: hidden; } + a { color: #151d26; text-decoration: none; - border-bottom: 1px solid #7ed07e; - -moz-transition: all 0.2s linear; - -webkit-transition: all 0.2s linear; - -o-transition: all 0.2s linear; - transition: all 0.2s linear; + border-bottom: 1px solid #7ED07E; } a:hover { - border-bottom: 1px solid #fc6399; + border-bottom: 1px solid #FC6399; } + code { background: #32302f; - color: #7ed07e; + color: #7ED07E; border-radius: 3px; padding: 3px; } + pre { background: #32302f; - color: #7ed07e; + color: #7ED07E; border-radius: 3px; padding: 3px; } -pre code { - color: #fc6399; + +code { + color: #FC6399; background: none; } + svg.icons { width: 25px; fill: #ebe5d4; } + header { background: #151d26; height: 90%; width: 100%; border-top: #ebe5d4 3px solid; } +header #media { + width: 100%; + height: 90%; + position: absolute; +} +header #media .slide { + -moz-transition: all 0.7s linear; + -webkit-transition: all 0.7s linear; + -o-transition: all 0.7s linear; + transition: all 0.7s linear; + width: 100%; + height: 100%; + position: absolute; +} +header #media .hide { + opacity: 0; +} +header #media .show { + opacity: 1; +} +header #media video { + width: 100%; + height: 100%; + object-fit: cover; +} header nav { width: 97%; margin: 10px auto; + z-index: 1000; + position: relative; color: #151d26; } -header nav .left, -header nav .right { +header nav .left, header nav .right { width: 50%; display: inline-block; vertical-align: top; @@ -302,7 +446,7 @@ header nav .right { text-align: right; } header nav .right a.menu-link { - background: #fc6399; + background: #FC6399; margin-bottom: 4px; padding: 3px; border-radius: 2px; @@ -311,8 +455,9 @@ header nav .right a.menu-link { border-bottom: none; } header nav .right a.menu-link:hover { - background: #feb1cc; + background: #FC6399; } + .container { z-index: 2; background: #ebe5d4; @@ -331,57 +476,47 @@ header nav .right a.menu-link:hover { color: #32302f; margin: 0 auto; } -.container article .index, -.container article .page { +.container article .index, .container article .page { padding: 0 0 15px 0; } -.container article .index img, -.container article .page img { +.container article .index img, .container article .page img { display: block; width: 100%; } -.container article .index h1, -.container article .page h1 { +.container article .index h1, .container article .page h1 { color: #151d26; } -.container article .index p, -.container article .page p { +.container article .index p, .container article .page p { font: 300 1.25em/1.6em Helvetica, Arial, sans-serif; } -.container article .index .meta, -.container article .page .meta { +.container article .index .meta, .container article .page .meta { font: 500 0.8em/1.3em Helvetica, Arial, sans-serif; padding: 5px 0 0 0; border-top: 1px solid #151d26; - background: #ede8d8; + background: #ebe5d4; } -.container article .index .meta a, -.container article .page .meta a { +.container article .index .meta a, .container article .page .meta a { font-size: 0.8em; font-weight: 400; } -.container article .index .archive-item, -.container article .page .archive-item { +.container article .index .archive-item, .container article .page .archive-item { padding: 15px 0 20px 0; } -.container article .index .archive-item span.year, -.container article .page .archive-item span.year { +.container article .index .archive-item span.year, .container article .page .archive-item span.year { font-size: 1.5em; font-weight: 500; padding: 5px; display: block; color: #151d26; } -.container article .index .archive-item .archive-month, -.container article .page .archive-item .archive-month { +.container article .index .archive-item .archive-month, .container article .page .archive-item .archive-month { display: inline-block; vertical-align: top; width: 30%; padding: 5px; } -.container article .index .archive-item .archive-month span.month, -.container article .page .archive-item .archive-month span.month { - color: #fc6399; +.container article .index .archive-item .archive-month span.month, .container article .page .archive-item .archive-month span.month { + color: #FC6399; font-size: 1.5em; font-weight: 300; padding: 5px; @@ -394,35 +529,31 @@ header nav .right a.menu-link:hover { .container section a { color: #ebe5d4; } -.container section .index-lists, -.container section .page-title { +.container section .index-lists, .container section .page-title { max-width: 840px; width: 80%; margin: 0 auto; padding: 20px 0 0 0; } -.container section .index-lists span, -.container section .page-title span { - font: 600 2em/1.5 Helvetica, Arial, sans-serif; - color: #ebe5d4; +.container section .index-lists span, .container section .page-title span { + font-size: 2em; + color: #FC6399; + font-weight: 400; } -.container section .index-lists .recent, -.container section .page-title .recent, -.container section .index-lists .featured, -.container section .page-title .featured { +.container section .index-lists .recent, .container section .index-lists .featured, .container section .page-title .recent, .container section .page-title .featured { display: inline-block; width: 50%; vertical-align: top; } -.container section .index-lists label, -.container section .page-title label { +.container section .index-lists label, .container section .page-title label { background: #32302f; color: #ebe5d4; font-size: 1.5em; line-height: 1.3; } + footer { - background: #e4dcc5; + background: #ebe5d4; padding: 10px; color: #151d26; font-size: 0.8em; @@ -435,121 +566,44 @@ footer .inner { max-width: 840px; } footer .inner a { - color: #fc6399; + color: #FC6399; } -@media only screen and (max-width: 640px) { - header nav { - width: 98%; - } - header span { - font-size: 2.5em; - } - .container article .index .archive-item .archive-month, - .container article .page .archive-item .archive-month { - width: 45%; - } + +header nav { + width: 98%; } -@media only screen and (max-width: 480px) { - header nav { - width: 96%; - } - .container article .index, - .container article .page { - margin: 0; - } - .container article .index p, - .container article .page p { - font: 300 1em/1.6em Helvetica, Arial, sans-serif; - } - .container section .index-lists .recent, - .container section .index-lists .featured { - width: 100% !important; - } +header span { + font-size: 2.5em; } -@media only screen and (max-width: 375px) { - header nav { - width: 95%; - } - .container article .index, - .container article .page { - margin: 0; - } - .container article .index p, - .container article .page p { - font: 300 0.9em/1.7em Helvetica, Arial, sans-serif; - } - .container article .index .archive-item .archive-month, - .container article .page .archive-item .archive-month { - width: 95%; - } +header .container article .index .archive-item .archive-month, header .container article .page .archive-item .archive-month { + width: 45%; } -/** -------------------------------- --- Forms -------------------------------- -**/ -form { - display: inline-block; + +header nav { + width: 96%; } -input[type=email], -input[type=password], -input[type=text] { - border: 0; - border-radius: 5px; - padding: 5px; - margin: 10px 5px 0 0; - font: 15px 'RobotoMono'; - display: inline-block; +header .container article .index, header .container article .page { + margin: 0; } -textarea { - border: 0; - border-radius: 3px; - color: $type02; - font: 15px 'RobotoMono'; +header .container article .index p, header .container article .page p { + font: 300 1em/1.6em Helvetica, Arial, sans-serif; } -button, -input[type=submit] { - background: #fc6399; - color: #ebe5d4; - font: 14px Helvetica, Arial, sans-serif; - border-radius: 5px; - position: relative; - cursor: pointer; - border: 0; - padding: 5px 5px 0 5px; - -moz-transition: all 0.3s linear; - -webkit-transition: all 0.3s linear; - -o-transition: all 0.3s linear; - transition: all 0.3s linear; +header .container section .index-lists .recent, header .container section .index-lists .featured { + width: 100% !important; } -button:hover, -input[type=submit]:hover { - background: #fc7ca9; + +header nav { + width: 95%; } -select { - font: 14px 'RobotoMono'; - border: 1px solid #fc6399; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - color: #151d26; + +.container article .index, .container article .page { + margin: 0; } -::-webkit-input-placeholder { - font: 14px 'RobotoMono'; - color: #837e7c; +.container article .index p, .container article .page p { + font: 300 0.9em/1.7em Helvetica, Arial, sans-serif; } -:-moz-placeholder { -/* Firefox 18- */ - font: 14px 'RobotoMono'; - color: #837e7c; +.container article .index .archive-item .archive-month, .container article .page .archive-item .archive-month { + width: 95%; } -::-moz-placeholder { -/* Firefox 19+ */ - font: 14px 'RobotoMono'; - color: #837e7c; -} -:-ms-input-placeholder { - font: 14px 'RobotoMono'; - color: #837e7c; -} -/*# sourceMappingURL=base.css.map */ \ No newline at end of file + +/*# sourceMappingURL=base.css.map */ diff --git a/content/themes/fipamo-default/assets/css/base.css.map b/content/themes/fipamo-default/assets/css/base.css.map index d9e5fd2..fb355de 100644 --- a/content/themes/fipamo-default/assets/css/base.css.map +++ b/content/themes/fipamo-default/assets/css/base.css.map @@ -1 +1 @@ -{"version":3,"sources":["../../../styles/base.styl","../../../styles/_normalize.styl","../../../styles/_structure.styl","../../../styles/_mixins.styl","../../../styles/_forms.styl"],"names":[],"mappings":"AACA;;;;;AAQA;;;;;AAQA;;;;;AAQA;;;;;ACzBA;EACI,aAAY,KAAZ;EACA,sBAAqB,KAArB;EACA,0BAAyB,KAAzB;;AAEJ;EACI,QAAO,EAAP;;AAEJ;AACA;AACA;AACA;AACA;AACA;EACI,SAAQ,MAAR;;AAEJ;EACI,WAAU,IAAV;EACA,QAAO,SAAP;EACA,aAAY,IAAZ;;AAEJ;AACA;AACA;EACI,SAAQ,MAAR;;AAEJ;EACI,QAAO,SAAP;;AAEJ;EACI,YAAW,YAAX;EACA,QAAO,EAAP;EACA,UAAS,QAAT;;AAEJ;EACI,aAAqB,qBAArB;EACA,WAAU,IAAV;;AACJ;EACI,kBAAiB,YAAjB;EACA,8BAA6B,QAA7B;;AAEJ;AACA;EACI,eAAc,EAAd;;AAEJ;EACI,eAAc,KAAd;EACA,iBAAgB,UAAhB;EACA,iBAAgB,iBAAhB;;AAEJ;AACA;EACI,aAAY,QAAZ;EACA,aAAY,OAAZ;;AAEJ;AACA;AACA;EACI,aAAqB,qBAArB;EACA,WAAU,IAAV;;AAEJ;EACI,YAAW,OAAX;;AAEJ;EACI,kBAAiB,KAAjB;EACA,OAAM,KAAN;;AAEJ;EACI,WAAU,IAAV;;AAEJ;AACA;EACI,WAAU,IAAV;EACA,aAAY,EAAZ;EACA,UAAS,SAAT;EACA,gBAAe,SAAf;;AAEJ;EACI,QAAO,QAAP;;AAEJ;EACI,KAAI,QAAJ;EACA,YAAW,QAAX;EACA,OAAM,QAAN;EACA,eAAe,IAAf;EACA,SAAQ,YAAR;EACA,QAAQ,UAAR;;AAEJ;AACA;EACI,SAAQ,aAAR;;AAGA;EACI,SAAQ,KAAR;EACA,QAAO,EAAP;;AAER;EACI,cAAa,KAAb;;AAGA;EACI,UAAS,OAAT;;AAER;AACA;AACA;AACA;AACA;EACI,aAAY,WAAZ;EACA,WAAU,KAAV;EACA,aAAY,KAAZ;EACA,QAAO,EAAP;;AAEJ;AACA;EACI,UAAS,QAAT;;AAEJ;AACA;EACI,gBAAe,KAAf;;AAEJ;AAAQ;AACR;AACA;EACI,oBAAmB,OAAnB;;AAEJ;AACA;AACA;AACA;EACI,cAAa,KAAb;EACA,SAAQ,EAAR;;AAEJ;AACA;AACA;AACA;EACI,SAAQ,sBAAR;;AAEJ;EACI,QAAO,kBAAP;EACA,QAAO,MAAP;EACA,SAAQ,sBAAR;;AAEJ;EACI,YAAW,WAAX;EACA,OAAM,QAAN;EACA,SAAQ,MAAR;EACA,WAAU,KAAV;EACA,SAAQ,EAAR;EACA,aAAY,OAAZ;;AAEJ;EACI,SAAQ,aAAR;EACA,gBAAe,SAAf;;AAEJ;EACI,UAAS,KAAT;;AAEJ;AACA;EACI,YAAW,WAAX;EACA,SAAQ,EAAR;;AAEJ;AACA;EACI,QAAO,KAAP;;AAEJ;EACI,oBAAmB,UAAnB;EACA,gBAAe,KAAf;;AAEJ;AACA;EACI,oBAAmB,KAAnB;;AAEJ;EACI,oBAAmB,OAAnB;EACA,MAAK,QAAL;;AAEJ;AACA;EACI,SAAQ,MAAR;;AAEJ;EACI,SAAQ,UAAR;;AAEJ;EACI,SAAQ,aAAR;;AAEJ;EACI,SAAQ,KAAR;;AAEJ;EACI,SAAQ,KAAR;;ADpKJ;;;;;AEhCA;EACI,QAAO,EAAP;EACA,SAAQ,EAAR;EACA,OAAM,KAAN;EACA,QAAO,KAAP;EACA,UAAS,OAAT;EACA,MAAK,6CAAL;;AAEJ;EACI,YAAW,QAAX;EACA,QAAO,EAAP;EACA,SAAQ,EAAR;EACA,aAAY,IAAZ;EACA,iBAAgB,YAAhB;EACA,QAAO,KAAP;EACA,OAAM,KAAN;EACA,YAAW,OAAX;EACA,YAAW,OAAX;;AAEJ;EACE,OAAM,QAAN;EACA,iBAAgB,KAAhB;EACA,eAAc,kBAAd;ECjBD,iBAAgB,gBAAhB;EACA,oBAAmB,gBAAnB;EACA,eAAc,gBAAd;EACA,YAAW,gBAAX;;ADgBC;EACE,eAAc,kBAAd;;AAEJ;EACE,YAAW,QAAX;EACA,OAAM,QAAN;EACA,eAAc,IAAd;EACA,SAAQ,IAAR;;AAEF;EACE,YAAW,QAAX;EACA,OAAM,QAAN;EACA,eAAc,IAAd;EACA,SAAQ,IAAR;;AACA;EACE,OAAM,QAAN;EACA,YAAW,KAAX;;AAEJ;EACE,OAAM,KAAN;EACA,MAAK,QAAL;;AAEF;EACE,YAAW,QAAX;EACA,QAAO,IAAP;EACA,OAAM,KAAN;EACA,YAAW,kBAAX;;AACA;EACE,OAAM,IAAN;EACA,QAAO,UAAP;EACA,OAAM,QAAN;;AACA;AAAM;EACJ,OAAM,IAAN;EACA,SAAQ,aAAR;EACA,gBAAe,IAAf;;AAEA;EACE,eAAc,KAAd;EACA,QAAO,WAAP;EACA,SAAQ,MAAR;;AACA;EACE,OAAM,KAAN;EACA,eAAc,KAAd;;AACN;EACE,YAAW,MAAX;;AACA;EACE,YAAW,QAAX;EACA,eAAc,IAAd;EACA,SAAQ,IAAR;EACA,eAAc,IAAd;EACA,SAAQ,aAAR;EACA,WAAU,MAAV;EACA,eAAc,KAAd;;AACA;EACE,YAAwB,QAAxB;;AAIV;EACI,SAAQ,EAAR;EACA,YAAW,QAAX;EACA,aAAY,KAAZ;EACA,aAAY,QAAZ;EACA,OAAM,KAAN;EAEA,OAAM,QAAN;;AACA;EACE,UAAS,SAAT;EACA,OAAO,IAAP;EACA,QAAO,IAAP;EACA,WAAU,MAAV;EAEA,YAAW,QAAX;EACA,gBAAe,IAAf;EACA,OAAM,QAAN;EACA,QAAO,OAAP;;AAGA;AAAQ;EACN,SAAQ,WAAR;;AACA;;EACE,SAAQ,MAAR;EACA,OAAM,KAAN;;AACF;;EACE,OAAM,QAAN;;AACF;;EACE,MAAK,8CAAL;;AAEF;;EACI,MAAK,6CAAL;EACA,SAAQ,UAAR;EACA,YAAW,kBAAX;EACA,YAAoB,QAApB;;AACA;;EACE,WAAW,MAAX;EACA,aAAY,IAAZ;;AAEN;;EACE,SAAQ,cAAR;;AACA;;EACE,WAAU,MAAV;EACA,aAAY,IAAZ;EACA,SAAQ,IAAR;EACA,SAAQ,MAAR;EACA,OAAM,QAAN;;AACF;;EACE,SAAQ,aAAR;EACA,gBAAe,IAAf;EACA,OAAM,IAAN;EACA,SAAQ,IAAR;;AACA;;EACE,OAAM,QAAN;EACA,WAAU,MAAV;EACA,aAAY,IAAZ;EACA,SAAQ,IAAR;EACA,SAAQ,MAAR;;AACV;EACE,SAAQ,WAAR;EACA,YAAW,QAAX;;AACA;EACE,OAAM,QAAN;;AACF;AAAc;EACZ,WAAU,MAAV;EAGA,OAAM,IAAN;EACA,QAAO,OAAP;EACA,SAAQ,WAAR;;AAJA;;ECrIP,MAAM,yCAAN;EACA,OAAO,QAAP;;ADyIO;AAAS;;;EACP,SAAQ,aAAR;EACA,OAAM,IAAN;EACA,gBAAe,IAAf;;AACF;;EACE,YAAW,QAAX;EACA,OAAM,QAAN;EACA,WAAU,MAAV;EACA,aAAY,IAAZ;;AAKR;EACE,YAAoB,QAApB;EACA,SAAQ,KAAR;EACA,OAAM,QAAN;EACA,WAAU,MAAV;EACA,aAAY,IAAZ;EACA,QAAO,MAAP;;AACA;EACE,QAAO,UAAP;EACA,OAAM,IAAN;EACA,WAAU,MAAV;;AACA;EACE,OAAM,QAAN;;AASgC;AAEpC;IACI,OAAM,IAAN;;AACJ;IACE,WAAU,MAAV;;AAKI;;IACE,OAAM,IAAN;;;AAE4B;AAEpC;IACI,OAAM,IAAN;;AAGF;AAAQ;IACN,QAAO,EAAP;;AACA;;IACE,MAAK,2CAAL;;AAGF;AAAS;IACP,OAAM,gBAAN;;;AAG8B;AAElC;IACE,OAAM,IAAN;;AAGA;AAAQ;IACN,QAAO,EAAP;;AACA;;IACE,MAAK,6CAAL;;AAEA;;IACE,OAAM,IAAN;;;AF3Ld;;;;;AIxCA;EACI,SAAQ,aAAR;;AAEJ;AAAmB;AAAsB;EACrC,QAAO,EAAP;EACA,eAAc,IAAd;EACA,SAAQ,IAAR;EACA,QAAO,aAAP;EACA,MAAK,kBAAL;EACA,SAAQ,aAAR;;AAEJ;EACI,QAAO,EAAP;EACA,eAAc,IAAd;EACA,OAAM,QAAN;EACA,MAAK,kBAAL;;AAEJ;AAAQ;EACJ,YAAW,QAAX;EACA,OAAM,QAAN;EACA,MAAK,kCAAL;EACA,eAAc,IAAd;EACA,UAAS,SAAT;EACA,QAAO,QAAP;EACA,QAAO,EAAP;EACA,SAAQ,cAAR;EDpBH,iBAAgB,gBAAhB;EACA,oBAAmB,gBAAnB;EACA,eAAc,gBAAd;EACA,YAAW,gBAAX;;ACmBG;;EACI,YAAW,QAAX;;AAER;EACI,MAAK,kBAAL;EACA,QAAO,kBAAP;EACA,oBAAmB,KAAnB;EACA,iBAAgB,KAAhB;EACA,YAAW,KAAX;EAEA,OAAM,QAAN;;AAEJ;EACI,MAAK,kBAAL;EACA,OAAM,QAAN;;AAEJ;AACI;EACA,MAAK,kBAAL;EACA,OAAM,QAAN;;AAEJ;AACI;EACA,MAAK,kBAAL;EACA,OAAM,QAAN;;AAEJ;EACI,MAAK,kBAAL;EACA,OAAM,QAAN","file":"base.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../../../styles/_typography.sass","../../../styles/_normalize.sass","../../../styles/_colors.sass","../../../styles/_forms.sass","../../../styles/_mixins.sass","../../../styles/_structure.sass"],"names":[],"mappings":"AAGA;EACI;;;AAEJ;EACI;EACA;;;AAEJ;EACI;EACA;;;AAEJ;EACI;EACA;;;AChBJ;EACI;EACA;EACA;;;AAEJ;EACI;;;AAEJ;AAAA;AAAA;AAAA;AAAA;AAAA;EAMI;;;AAEJ;EACI;EACA;EACA;;;AAEJ;AAAA;AAAA;EAGI;;;AAEJ;EACI;;;AAEJ;EACI;EACA;EACA;;;AAEJ;EACI;EACA;;;AACJ;EACI;EACA;;;AAEJ;AAAA;EAEI;;;AAEJ;EACI;EACA;EACA;;;AAEJ;AAAA;EAEI;EACA;;;AAGJ;AAAA;EAEI;EACA;;;AAEJ;EACI;;;AAEJ;EACI;EACA;;;AAEJ;EACI;;;AAEJ;AAAA;EAEI;EACA;EACA;EACA;;;AAEJ;EACI;;;AAEJ;EACI;EACA,YCnFM;EDoFN,OCpFM;EDqFN;EACA;EACA;;;AAEJ;AAAA;EAEI;;;AAGA;EACI;EACA;;;AAER;EACI;;;AAGA;EACI;;;AAER;AAAA;AAAA;AAAA;AAAA;EAKI;EACA;EACA;EACA;;;AAEJ;AAAA;EAEI;;;AAEJ;AAAA;EAEI;;;AAEJ;AAAA;AAAA;EAGI;;;AAEJ;AAAA;AAAA;AAAA;EAII;EACA;;;AAEJ;AAAA;AAAA;AAAA;EAII;;;AAEJ;EACI;EACA;EACA;;;AAEJ;EACI;EACA;EACA;EACA;EACA;EACA;;;AAEJ;EACI;EACA;;;AAEJ;EACI;;;AAEJ;AAAA;EAEI;EACA;;;AAEJ;AAAA;EAEI;;;AAEJ;EACI;EACA;;;AAEJ;AAAA;EAEI;;;AAEJ;EACI;EACA;;;AAEJ;AAAA;EAEI;;;AAEJ;EACI;;;AAEJ;EACI;;;AAEJ;EACI;;;AAEJ;EACI;;;AEpMJ;EACI;;AACA;EACI,ODHE;;ACIN;EACI,YDHI;ECIJ,ODNE;ECOF;EACA;EACA;EACA;;;AAER;EACI;EACA;EACA;EACA;EACA;EACA;EACA,YDnBM;ECoBN,ODlBQ;;;ACoBZ;EACI;EACA;EACA,ODrBK;ECsBL;EACA,YD3BM;;;AC6BV;EACI,YD3BS;EC4BT,OD/BM;ECgCN;EACA;EACA;EACA;EACA;EACA;ECjCH;EACA;EACA;EACA;;;ADiCD;EACI;EACA;EACA;EACA;EACA;EACA,OD9CM;;;ACgDV;EACI;EACA,OD9CK;;;ACgDT;AACI;EACA;EACA,ODnDK;;;ACqDT;AACI;EACA;EACA,ODxDK;;;AC0DT;EACI;EACA,OD5DK;;;AGJT;EACE;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE,YHLO;EGMP;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE,OHpBQ;EGqBR;EACA;;AAEA;EACE;;;AAEJ;EACE,YHvBO;EGwBP,OH1BW;EG2BX;EACA;;;AAEF;EACE,YH7BO;EG8BP,OHhCW;EGiCX;EACA;;;AACF;EACE,OHtCW;EGuCX;;;AAEF;EACE;EACA,MHxCO;;;AG0CT;EACE,YH/CQ;EGgDR;EACA;EACA;;AACA;EACE;EACA;EACA;;AACA;EDnDH;EACA;EACA;EACA;ECkDK;EACA;EACA;;AACF;EACE;;AACF;EACE;;AACF;EACE;EACA;EACA;;AACJ;EACE;EACA;EACA;EACA;EACA,OHzEM;;AG0EN;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AACA;EACE;EACA;;AACN;EACE;;AACA;EACE,YHxFK;EGyFL;EACA;EACA;EACA;EACA;EACA;;AACA;EACE,YHhGG;;;AGoGb;EACE;EACA,YHnGO;EGoGP;EACA;EACA;EAEA,OHvGO;;AGwGP;EACE;EACA;EACA;EACA;EAEA,YH/GK;EGgHL;EACA,OHhHK;EGiHL;;AAGA;EACE;;AACA;EACE;EACA;;AACF;EACE,OH/HE;;AGgIJ;EACE;;AAEF;EACI;EACA;EACA;EACA,YHnID;;AGoIC;EACE;EACA;;AAEN;EACE;;AACA;EACE;EACA;EACA;EACA;EACA,OHnJA;;AGoJF;EACE;EACA;EACA;EACA;;AACA;EACE,OHzJC;EG0JD;EACA;EACA;EACA;;AACV;EACE;EACA,YHjKM;;AGkKN;EACE,OH/JG;;AGgKL;EACE;EAKA;EACA;EACA;;AANA;EACE;EACA,OHvKK;EGwKL;;AAIF;EACE;EACA;EACA;;AACF;EACE,YH7KC;EG8KD,OH/KC;EGgLD;EACA;;;AAKR;EACE,YHvLO;EGwLP;EACA,OH7LQ;EG8LR;EACA;EACA;;AACA;EACE;EACA;EACA;;AACA;EACE,OHrMO;;;AG4MX;EACI;;AACJ;EACE;;AAKM;EACE;;;AAIV;EACI;;AAGA;EACE;;AACA;EACE;;AAGF;EACE;;;AAKR;EACE;;;AAGA;EACE;;AACA;EACE;;AAEA;EACE","file":"base.css"} \ No newline at end of file diff --git a/content/themes/fipamo-default/assets/images/global/fipamo-logo.svg b/content/themes/fipamo-default/assets/images/global/the-logo.svg similarity index 100% rename from content/themes/fipamo-default/assets/images/global/fipamo-logo.svg rename to content/themes/fipamo-default/assets/images/global/the-logo.svg diff --git a/content/themes/fipamo-default/assets/scripts/Start.js b/content/themes/fipamo-default/assets/scripts/Start.js new file mode 100644 index 0000000..cda5f3b --- /dev/null +++ b/content/themes/fipamo-default/assets/scripts/Start.js @@ -0,0 +1,2 @@ +(()=>{class t{constructor(){this.start()}start(){console.log("Connected like F.E.")}}document.addEventListener("DOMContentLoaded",(function(){new t}),!1)})(); +//# sourceMappingURL=Start.js.map diff --git a/content/themes/fipamo-default/assets/scripts/Start.js.map b/content/themes/fipamo-default/assets/scripts/Start.js.map new file mode 100644 index 0000000..f163a50 --- /dev/null +++ b/content/themes/fipamo-default/assets/scripts/Start.js.map @@ -0,0 +1 @@ +{"mappings":"4BAKIA,KAAKC,QAEPA,QACEC,QAAQC,IAAI,wBCNhBC,SAASC,iBACP,oBACA,WACa,IAAIC,KAEjB","sources":["src/themes/theme-fipamo-default/com/Base.js","src/themes/theme-fipamo-default/com/Start.js"],"sourcesContent":["export default class Base {\n //--------------------------\n // constructor\n //--------------------------\n constructor() {\n this.start();\n }\n start() {\n console.log(\"Connected like F.E.\");\n }\n //--------------------------\n // methods\n //--------------------------\n\n //--------------------------\n // event handlers\n //--------------------------\n}\n","import Base from \"./Base.js\";\n\ndocument.addEventListener(\n \"DOMContentLoaded\",\n function () {\n var base = new Base();\n },\n false\n);\n"],"names":["this","start","console","log","document","addEventListener","$b8d4b81eabebe07b$export$2e2bcd8739ae039"],"version":3,"file":"Start.js.map"} \ No newline at end of file diff --git a/content/themes/fipamo-default/assets/scripts/ThemeStart.js b/content/themes/fipamo-default/assets/scripts/ThemeStart.js new file mode 100644 index 0000000..a113cdb --- /dev/null +++ b/content/themes/fipamo-default/assets/scripts/ThemeStart.js @@ -0,0 +1,583 @@ +// modules are defined as an array +// [ module function, map of requires ] +// +// map of requires is short require name -> numeric require +// +// anything defined in a previous bundle is accessed via the +// orig method which is the require for previous bundles + +(function (modules, entry, mainEntry, parcelRequireName, globalName) { + /* eslint-disable no-undef */ + var globalObject = + typeof globalThis !== 'undefined' + ? globalThis + : typeof self !== 'undefined' + ? self + : typeof window !== 'undefined' + ? window + : typeof global !== 'undefined' + ? global + : {}; + /* eslint-enable no-undef */ + + // Save the require from previous bundle to this closure if any + var previousRequire = + typeof globalObject[parcelRequireName] === 'function' && + globalObject[parcelRequireName]; + + var cache = previousRequire.cache || {}; + // Do not use `require` to prevent Webpack from trying to bundle this call + var nodeRequire = + typeof module !== 'undefined' && + typeof module.require === 'function' && + module.require.bind(module); + + function newRequire(name, jumped) { + if (!cache[name]) { + if (!modules[name]) { + // if we cannot find the module within our internal map or + // cache jump to the current global require ie. the last bundle + // that was added to the page. + var currentRequire = + typeof globalObject[parcelRequireName] === 'function' && + globalObject[parcelRequireName]; + if (!jumped && currentRequire) { + return currentRequire(name, true); + } + + // If there are other bundles on this page the require from the + // previous one is saved to 'previousRequire'. Repeat this as + // many times as there are bundles until the module is found or + // we exhaust the require chain. + if (previousRequire) { + return previousRequire(name, true); + } + + // Try the node require function if it exists. + if (nodeRequire && typeof name === 'string') { + return nodeRequire(name); + } + + var err = new Error("Cannot find module '" + name + "'"); + err.code = 'MODULE_NOT_FOUND'; + throw err; + } + + localRequire.resolve = resolve; + localRequire.cache = {}; + + var module = (cache[name] = new newRequire.Module(name)); + + modules[name][0].call( + module.exports, + localRequire, + module, + module.exports, + this + ); + } + + return cache[name].exports; + + function localRequire(x) { + var res = localRequire.resolve(x); + return res === false ? {} : newRequire(res); + } + + function resolve(x) { + var id = modules[name][1][x]; + return id != null ? id : x; + } + } + + function Module(moduleName) { + this.id = moduleName; + this.bundle = newRequire; + this.exports = {}; + } + + newRequire.isParcelRequire = true; + newRequire.Module = Module; + newRequire.modules = modules; + newRequire.cache = cache; + newRequire.parent = previousRequire; + newRequire.register = function (id, exports) { + modules[id] = [ + function (require, module) { + module.exports = exports; + }, + {}, + ]; + }; + + Object.defineProperty(newRequire, 'root', { + get: function () { + return globalObject[parcelRequireName]; + }, + }); + + globalObject[parcelRequireName] = newRequire; + + for (var i = 0; i < entry.length; i++) { + newRequire(entry[i]); + } + + if (mainEntry) { + // Expose entry point to Node, AMD or browser globals + // Based on https://github.com/ForbesLindesay/umd/blob/master/template.js + var mainExports = newRequire(mainEntry); + + // CommonJS + if (typeof exports === 'object' && typeof module !== 'undefined') { + module.exports = mainExports; + + // RequireJS + } else if (typeof define === 'function' && define.amd) { + define(function () { + return mainExports; + }); + + // + \ No newline at end of file diff --git a/content/themes/fipamo-default/index.twig b/content/themes/fipamo-default/index.twig index 6c355cd..11cba2f 100644 --- a/content/themes/fipamo-default/index.twig +++ b/content/themes/fipamo-default/index.twig @@ -1,4 +1,4 @@ -{% extends "fipamo-default/frame.twig" %} +{% extends "frame.twig" %} {% block title %} {{ title }} @@ -39,6 +39,7 @@ {% else %} {{item.title}}
{% endif %} + {% else %} {{item.title}}
{% endif %} diff --git a/content/themes/fipamo-default/page-custom.twig b/content/themes/fipamo-default/page-custom.twig index db2d69e..4cd7edf 100644 --- a/content/themes/fipamo-default/page-custom.twig +++ b/content/themes/fipamo-default/page-custom.twig @@ -1,4 +1,4 @@ -{% extends "fipamo-default/frame.twig" %} +{% extends "frame.twig" %} {% block title %} {{ title }} @@ -12,7 +12,7 @@
- THIS IS A CUSTOM TEMPLATE
+ [CUSTOM PAGE BRUH]

{{content | raw}}

@@ -20,7 +20,7 @@ tags: {% for tag in meta['tags'] %} {% if dynamicRender is defined %} - {% if dynamicRender == 'true' %} + {% if dynamicRender == 'false' %} {{ tag.label }} {% else %} {{ tag.label }} @@ -28,7 +28,6 @@ {% else %} {{ tag.label }} {% endif %} - {% endfor %}
diff --git a/content/themes/fipamo-default/page.twig b/content/themes/fipamo-default/page.twig index 541b55e..e44d36a 100644 --- a/content/themes/fipamo-default/page.twig +++ b/content/themes/fipamo-default/page.twig @@ -1,4 +1,4 @@ -{% extends "fipamo-default/frame.twig" %} +{% extends "frame.twig" %} {% block title %} {{ title }} @@ -19,7 +19,7 @@ tags: {% for tag in meta['tags'] %} {% if dynamicRender is defined %} - {% if dynamicRender == 'false' %} + {% if dynamicRender == 'true' %} {{ tag.label }} {% else %} {{ tag.label }} @@ -27,7 +27,6 @@ {% else %} {{ tag.label }} {% endif %} - {% endfor %}
diff --git a/content/themes/fipamo-default/tags.twig b/content/themes/fipamo-default/tags.twig index 66b2644..baa6694 100644 --- a/content/themes/fipamo-default/tags.twig +++ b/content/themes/fipamo-default/tags.twig @@ -1,4 +1,4 @@ -{% extends "fipamo-default/frame.twig" %} +{% extends "frame.twig" %} {% block title %} {{ title }} @@ -23,7 +23,6 @@ {% else %} {{tag.title}}
{% endif %} - {% endfor %} diff --git a/package-lock.json b/package-lock.json index f1ff9ca..d89382b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,9 +25,10 @@ "devDependencies": { "@babel/preset-env": "^7.16.5", "babel-cli": "^6.26.0", - "eslint": "^8.5.0", + "eslint": "^8.11.0", "eslint-plugin-babel": "^5.3.1", - "parcel": "^2.0.1" + "parcel": "^2.0.1", + "prettier": "^2.6.0" } }, "node_modules/@babel/code-frame": { @@ -1819,15 +1820,15 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", - "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", + "integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.2.0", + "espree": "^9.3.1", "globals": "^13.9.0", - "ignore": "^4.0.6", + "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.0.4", @@ -1838,9 +1839,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", - "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", + "version": "13.13.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", + "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", "dependencies": { "type-fest": "^0.20.2" }, @@ -1851,14 +1852,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@eslint/eslintrc/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "engines": { - "node": ">= 4" - } - }, "node_modules/@eslint/eslintrc/node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -3908,14 +3901,6 @@ "resolved": "https://registry.npmjs.org/animejs/-/animejs-3.2.1.tgz", "integrity": "sha512-sWno3ugFryK5nhiDm/2BKeFCpZv7vzerWUcUPyAZLDhMek3+S/p418ldZJbJXo5ZUOpfm2kP2XRO4NJcULMy9A==" }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "engines": { - "node": ">=6" - } - }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -6618,17 +6603,6 @@ "node": ">= 0.8" } }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, "node_modules/entities": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", @@ -6755,23 +6729,22 @@ } }, "node_modules/eslint": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.5.0.tgz", - "integrity": "sha512-tVGSkgNbOfiHyVte8bCM8OmX+xG9PzVG/B4UCF60zx7j61WIVY/AqJECDgpLD4DbbESD0e174gOg3ZlrX15GDg==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.11.0.tgz", + "integrity": "sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA==", "dependencies": { - "@eslint/eslintrc": "^1.0.5", + "@eslint/eslintrc": "^1.2.1", "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", - "enquirer": "^2.3.5", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.0", + "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.1.0", - "espree": "^9.2.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.1", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -6779,7 +6752,7 @@ "functional-red-black-tree": "^1.0.1", "glob-parent": "^6.0.1", "globals": "^13.6.0", - "ignore": "^4.0.6", + "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", @@ -6790,9 +6763,7 @@ "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "progress": "^2.0.0", "regexpp": "^3.2.0", - "semver": "^7.2.1", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", "text-table": "^0.2.0", @@ -6947,9 +6918,9 @@ } }, "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz", - "integrity": "sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -6959,9 +6930,9 @@ } }, "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", - "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -7007,14 +6978,6 @@ "node": ">=8" } }, - "node_modules/eslint/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "engines": { - "node": ">= 4" - } - }, "node_modules/eslint/node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -7078,20 +7041,6 @@ "node": ">= 0.8.0" } }, - "node_modules/eslint/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/eslint/node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -7170,13 +7119,13 @@ } }, "node_modules/espree": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.2.0.tgz", - "integrity": "sha512-oP3utRkynpZWF/F2x/HZJ+AGtnIclaR7z1pYPxy7NYM2fSO6LgK/Rkny8anRSPK/VwEA1eqm2squui0T7ZMOBg==", + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", + "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", "dependencies": { - "acorn": "^8.6.0", + "acorn": "^8.7.0", "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^3.1.0" + "eslint-visitor-keys": "^3.3.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -7194,9 +7143,9 @@ } }, "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", - "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -8505,7 +8454,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true, "engines": { "node": ">= 4" } @@ -9627,6 +9575,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -11558,6 +11507,21 @@ "node": ">=0.10.0" } }, + "node_modules/prettier": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.0.tgz", + "integrity": "sha512-m2FgJibYrBGGgQXNzfd0PuDGShJgRavjUoRCw1mZERIWVSXF0iLzLm+aOqTAbLnC3n6JzUhAA8uZnFVghHJ86A==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/prismjs": { "version": "1.25.0", "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.25.0.tgz", @@ -11586,14 +11550,6 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -14376,7 +14332,8 @@ "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, "node_modules/yaml": { "version": "1.10.2", @@ -15645,15 +15602,15 @@ } }, "@eslint/eslintrc": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", - "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", + "integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==", "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.2.0", + "espree": "^9.3.1", "globals": "^13.9.0", - "ignore": "^4.0.6", + "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.0.4", @@ -15661,18 +15618,13 @@ }, "dependencies": { "globals": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", - "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", + "version": "13.13.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", + "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", "requires": { "type-fest": "^0.20.2" } }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" - }, "type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -17091,11 +17043,6 @@ "resolved": "https://registry.npmjs.org/animejs/-/animejs-3.2.1.tgz", "integrity": "sha512-sWno3ugFryK5nhiDm/2BKeFCpZv7vzerWUcUPyAZLDhMek3+S/p418ldZJbJXo5ZUOpfm2kP2XRO4NJcULMy9A==" }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" - }, "ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -19391,14 +19338,6 @@ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", "dev": true }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "requires": { - "ansi-colors": "^4.1.1" - } - }, "entities": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", @@ -19497,23 +19436,22 @@ } }, "eslint": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.5.0.tgz", - "integrity": "sha512-tVGSkgNbOfiHyVte8bCM8OmX+xG9PzVG/B4UCF60zx7j61WIVY/AqJECDgpLD4DbbESD0e174gOg3ZlrX15GDg==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.11.0.tgz", + "integrity": "sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA==", "requires": { - "@eslint/eslintrc": "^1.0.5", + "@eslint/eslintrc": "^1.2.1", "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", - "enquirer": "^2.3.5", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.0", + "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.1.0", - "espree": "^9.2.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.1", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -19521,7 +19459,7 @@ "functional-red-black-tree": "^1.0.1", "glob-parent": "^6.0.1", "globals": "^13.6.0", - "ignore": "^4.0.6", + "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", @@ -19532,9 +19470,7 @@ "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "progress": "^2.0.0", "regexpp": "^3.2.0", - "semver": "^7.2.1", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", "text-table": "^0.2.0", @@ -19592,18 +19528,18 @@ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" }, "eslint-scope": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz", - "integrity": "sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", "requires": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "eslint-visitor-keys": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", - "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==" + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==" }, "estraverse": { "version": "5.3.0", @@ -19631,11 +19567,6 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" - }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -19681,14 +19612,6 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "requires": { - "lru-cache": "^6.0.0" - } - }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -19779,13 +19702,13 @@ "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==" }, "espree": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.2.0.tgz", - "integrity": "sha512-oP3utRkynpZWF/F2x/HZJ+AGtnIclaR7z1pYPxy7NYM2fSO6LgK/Rkny8anRSPK/VwEA1eqm2squui0T7ZMOBg==", + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", + "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", "requires": { - "acorn": "^8.6.0", + "acorn": "^8.7.0", "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^3.1.0" + "eslint-visitor-keys": "^3.3.0" }, "dependencies": { "acorn": { @@ -19794,9 +19717,9 @@ "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==" }, "eslint-visitor-keys": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", - "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==" + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==" } } }, @@ -20802,8 +20725,7 @@ "ignore": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==" }, "immutable": { "version": "4.0.0", @@ -21658,6 +21580,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, "requires": { "yallist": "^4.0.0" } @@ -23110,6 +23033,12 @@ "dev": true, "optional": true }, + "prettier": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.0.tgz", + "integrity": "sha512-m2FgJibYrBGGgQXNzfd0PuDGShJgRavjUoRCw1mZERIWVSXF0iLzLm+aOqTAbLnC3n6JzUhAA8uZnFVghHJ86A==", + "dev": true + }, "prismjs": { "version": "1.25.0", "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.25.0.tgz", @@ -23132,11 +23061,6 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" - }, "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -25353,7 +25277,8 @@ "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, "yaml": { "version": "1.10.2", diff --git a/package.json b/package.json index 309a3f8..bba2011 100644 --- a/package.json +++ b/package.json @@ -10,9 +10,10 @@ "devDependencies": { "@babel/preset-env": "^7.16.5", "babel-cli": "^6.26.0", - "eslint": "^8.5.0", + "eslint": "^8.11.0", "eslint-plugin-babel": "^5.3.1", - "parcel": "^2.0.1" + "parcel": "^2.0.1", + "prettier": "^2.6.0" }, "dependencies": { "@babel/core": "^7.16.5", diff --git a/public/assets/css/dash.css b/public/assets/css/dash.css index 9629434..5c567e0 100644 --- a/public/assets/css/dash.css +++ b/public/assets/css/dash.css @@ -1912,6 +1912,7 @@ a { font: 300 1em Helvetica, Arial, sans-serif; color: #b2cce5; text-decoration: underline; + transition: all 0.2s linear; } svg.icons { @@ -1953,21 +1954,8 @@ svg.icons { -moz-animation: spin 2s linear infinite; animation: spin 2s linear infinite; } -@-moz-keyframes spin { - 100% { - -moz-transform: rotate(360deg); - } -} -@-webkit-keyframes spin { - 100% { - -webkit-transform: rotate(360deg); - } -} @keyframes spin { - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } + transform: rotate(360deg); } #notifications #notifyMessage .notify-icon { background: #32302f; @@ -2057,10 +2045,7 @@ svg.icons { border-radius: 50px; } .main-container section header #wrapper #right #dash-menu a button svg { - -moz-transition: all 0.1s linear; - -webkit-transition: all 0.1s linear; - -o-transition: all 0.1s linear; - transition: all 0.1s linear; + transition: all 0.2s linear; width: 40px; height: 20px; fill: #EFEBE3; @@ -2270,15 +2255,12 @@ svg.icons { margin-left: 10px; } #dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list .recent-header .index-header-right a button svg { - -moz-transition: all 0.1s linear; - -webkit-transition: all 0.1s linear; - -o-transition: all 0.1s linear; - transition: all 0.1s linear; + transition: all 0.2s linear; width: 40px; height: 20px; fill: #EFEBE3; } -#dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link { +#dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link, #dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-video-link { font-size: 1.5em; font-weight: 300; display: inline-block; @@ -2286,8 +2268,15 @@ svg.icons { vertical-align: top; text-decoration: none; position: relative; + overflow: hidden; } -#dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link label { +#dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link .post-video, #dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-video-link .post-video { + width: 100%; + height: 100%; + object-fit: cover; + position: absolute; +} +#dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link label, #dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-video-link label { font-size: 1.4em; font-weight: 700; color: #EFEBE3; @@ -2301,53 +2290,53 @@ svg.icons { top: 35%; text-shadow: 2px 2px 0 #32302f; } -#dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link div#options { +#dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link div#options, #dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-video-link div#options { width: 100%; position: absolute; bottom: 0; border-radius: 0 0 3px 3px; background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.65) 100%); } -#dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link div#options #option-left { +#dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link div#options #option-left, #dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-video-link div#options #option-left { display: inline-block; vertical-align: top; width: 50%; position: relative; background: none; } -#dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link div#options #option-left button { +#dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link div#options #option-left button, #dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-video-link div#options #option-left button { border-radius: 3px; background: #1D3040; margin: 0 0 10px 10px; } -#dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link div#options #option-left button svg { +#dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link div#options #option-left button svg, #dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-video-link div#options #option-left button svg { width: 40px; height: 20px; fill: #b2cce5; } -#dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link div#options #option-left .item-options { +#dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link div#options #option-left .item-options, #dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-video-link div#options #option-left .item-options { border-radius: 3px; margin: 5px; display: inline-block; } -#dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link div#options #option-left button[data-active=false] { +#dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link div#options #option-left button[data-active=false], #dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-video-link div#options #option-left button[data-active=false] { background: #1D3040; } -#dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link div#options #option-left button[data-active=false] svg { +#dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link div#options #option-left button[data-active=false] svg, #dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-video-link div#options #option-left button[data-active=false] svg { fill: #b2cce5; } -#dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link div#options #option-left button[data-active=true] { +#dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link div#options #option-left button[data-active=true], #dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-video-link div#options #option-left button[data-active=true] { background: #f5ab35; } -#dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link div#options #option-left button[data-active=true] svg { +#dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link div#options #option-left button[data-active=true] svg, #dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-video-link div#options #option-left button[data-active=true] svg { fill: #1D3040; } -#dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link div#options #option-right { +#dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link div#options #option-right, #dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-video-link div#options #option-right { display: inline-block; width: 50%; text-align: right; } -#dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link div#options #option-right span { +#dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link div#options #option-right span, #dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-video-link div#options #option-right span { font-weight: bold; display: block; background: #EFEBE3; @@ -2845,9 +2834,6 @@ button, input[type=submit] { cursor: pointer; border: 0; padding: 10px 0 5px 0; - -moz-transition: all 0.3s linear; - -webkit-transition: all 0.3s linear; - -o-transition: all 0.3s linear; transition: all 0.3s linear; } @@ -2911,7 +2897,8 @@ select { margin-left: 10px; width: 55px; } -#post-index #post-index-wrapper #post-index-header #post-index-header-right a button svg { +#post-index #post-index-wrapper #post-index-header #post-index-header-right a svg { + transition: all 0.1s linear; width: 20px; height: 17px; fill: #EFEBE3; @@ -2942,13 +2929,17 @@ select { vertical-align: top; width: 100%; } -#post-index #post-index-wrapper #posts-list a.page-link div.page-bg { +#post-index #post-index-wrapper #posts-list a.page-link div.page-bg, #post-index #post-index-wrapper #posts-list a.page-link div.page-video { width: 100%; height: 350px; background-color: #fc6399; position: relative; } -#post-index #post-index-wrapper #posts-list a.page-link div.page-bg label { +#post-index #post-index-wrapper #posts-list a.page-link div.page-bg video, #post-index #post-index-wrapper #posts-list a.page-link div.page-video video { + width: 100%; + position: absolute; +} +#post-index #post-index-wrapper #posts-list a.page-link div.page-bg label, #post-index #post-index-wrapper #posts-list a.page-link div.page-video label { font-size: 2em; font-weight: 700; color: #EFEBE3; @@ -2961,9 +2952,8 @@ select { position: relative; top: 35%; text-shadow: 2px 2px 0 #32302f; - text-shadow: 2px 2px 0 #32302f; } -#post-index #post-index-wrapper #posts-list a.page-link div.page-bg #meta { +#post-index #post-index-wrapper #posts-list a.page-link div.page-bg #meta, #post-index #post-index-wrapper #posts-list a.page-link div.page-video #meta { width: 100%; background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.65) 100%); border-radius: 3px; @@ -2972,51 +2962,52 @@ select { position: absolute; padding: 0 0 20px 0; } -#post-index #post-index-wrapper #posts-list a.page-link div.page-bg #meta #options { +#post-index #post-index-wrapper #posts-list a.page-link div.page-bg #meta #options, #post-index #post-index-wrapper #posts-list a.page-link div.page-video #meta #options { width: 100%; bottom: 0; position: absolute; } -#post-index #post-index-wrapper #posts-list a.page-link div.page-bg #meta #options #option-left { +#post-index #post-index-wrapper #posts-list a.page-link div.page-bg #meta #options #option-left, #post-index #post-index-wrapper #posts-list a.page-link div.page-video #meta #options #option-left { display: inline-block; vertical-align: top; width: 50%; position: relative; background: none; } -#post-index #post-index-wrapper #posts-list a.page-link div.page-bg #meta #options #option-left button { +#post-index #post-index-wrapper #posts-list a.page-link div.page-bg #meta #options #option-left button, #post-index #post-index-wrapper #posts-list a.page-link div.page-video #meta #options #option-left button { border-radius: 3px; background: #1D3040; margin: 0 0 10px 10px; } -#post-index #post-index-wrapper #posts-list a.page-link div.page-bg #meta #options #option-left button svg { +#post-index #post-index-wrapper #posts-list a.page-link div.page-bg #meta #options #option-left svg, #post-index #post-index-wrapper #posts-list a.page-link div.page-video #meta #options #option-left svg { + transition: all 0.2s linear; width: 40px; height: 20px; fill: #b2cce5; } -#post-index #post-index-wrapper #posts-list a.page-link div.page-bg #meta #options #option-left .item-options { +#post-index #post-index-wrapper #posts-list a.page-link div.page-bg #meta #options #option-left .item-options, #post-index #post-index-wrapper #posts-list a.page-link div.page-video #meta #options #option-left .item-options { border-radius: 3px; margin: 5px; display: inline-block; } -#post-index #post-index-wrapper #posts-list a.page-link div.page-bg #meta #options #option-left button[data-active=false] { +#post-index #post-index-wrapper #posts-list a.page-link div.page-bg #meta #options #option-left button[data-active=false], #post-index #post-index-wrapper #posts-list a.page-link div.page-video #meta #options #option-left button[data-active=false] { background: #1D3040; } -#post-index #post-index-wrapper #posts-list a.page-link div.page-bg #meta #options #option-left button[data-active=false] svg { +#post-index #post-index-wrapper #posts-list a.page-link div.page-bg #meta #options #option-left button[data-active=false] svg, #post-index #post-index-wrapper #posts-list a.page-link div.page-video #meta #options #option-left button[data-active=false] svg { fill: #b2cce5; } -#post-index #post-index-wrapper #posts-list a.page-link div.page-bg #meta #options #option-left button[data-active=true] { +#post-index #post-index-wrapper #posts-list a.page-link div.page-bg #meta #options #option-left button[data-active=true], #post-index #post-index-wrapper #posts-list a.page-link div.page-video #meta #options #option-left button[data-active=true] { background: #f5ab35; } -#post-index #post-index-wrapper #posts-list a.page-link div.page-bg #meta #options #option-left button[data-active=true] svg { +#post-index #post-index-wrapper #posts-list a.page-link div.page-bg #meta #options #option-left button[data-active=true] svg, #post-index #post-index-wrapper #posts-list a.page-link div.page-video #meta #options #option-left button[data-active=true] svg { fill: #1D3040; } -#post-index #post-index-wrapper #posts-list a.page-link div.page-bg #meta #options #option-right { +#post-index #post-index-wrapper #posts-list a.page-link div.page-bg #meta #options #option-right, #post-index #post-index-wrapper #posts-list a.page-link div.page-video #meta #options #option-right { display: inline-block; width: 50%; text-align: right; } -#post-index #post-index-wrapper #posts-list a.page-link div.page-bg #meta #options #option-right span { +#post-index #post-index-wrapper #posts-list a.page-link div.page-bg #meta #options #option-right span, #post-index #post-index-wrapper #posts-list a.page-link div.page-video #meta #options #option-right span { font-weight: bold; display: block; background: #EFEBE3; @@ -3138,13 +3129,6 @@ select { #post-edit-index #post-edit-index-wrapper #post-header #post-header-wrapper #post-meta #post-options button { width: 25%; height: 45px; - -moz-transition: all 0.3s linear; - -webkit-transition: all 0.3s linear; - -o-transition: all 0.3s linear; - transition: all 0.3s linear; - -moz-transition: all 0.3s linear; - -webkit-transition: all 0.3s linear; - -o-transition: all 0.3s linear; transition: all 0.3s linear; margin: 0; border-radius: 0; @@ -3164,41 +3148,88 @@ select { #post-edit-index #post-edit-index-wrapper #post-header #post-header-wrapper #post-meta #post-options button[data-active=true] svg { fill: #1D3040; } -#post-edit-index #post-edit-index-wrapper #post-header #post-header-wrapper #post-meta #featured-image-upload, #post-edit-index #post-edit-index-wrapper #post-header #post-header-wrapper #post-meta #post-image-upload { +#post-edit-index #post-edit-index-wrapper #post-header #post-header-wrapper #post-meta #page-files-upload, #post-edit-index #post-edit-index-wrapper #post-header #post-header-wrapper #post-meta #post-image-upload { display: none; } #post-edit-index #post-edit-index-wrapper #post-feature { width: 100%; } -#post-edit-index #post-edit-index-wrapper #post-feature #featured-image-drop { +#post-edit-index #post-edit-index-wrapper #post-feature #page-file-manager { + background: #f5ab35; + width: 100%; + min-height: 300px; +} +#post-edit-index #post-edit-index-wrapper #post-feature #page-file-manager #page-file-wrapper { + width: 100%; + max-width: 900px; + padding: 10px; + margin: 0 auto; + font-weight: bold; + font-color: #1D3040; + font-size: 1em; +} +#post-edit-index #post-edit-index-wrapper #post-feature #page-file-manager #page-file-wrapper #page-file-drop { display: flex; align-items: center; justify-content: center; width: 100%; - min-height: 200px; - background: black; + min-height: 100px; + background: #EFEBE3; color: #1D3040; vertical-align: middle; - font-family: "Lucida Console", Monaco, monospace; + border-radius: 5px; + margin: 0 0 10px 0; } -#post-edit-index #post-edit-index-wrapper #post-feature #featured-image-drop label { +#post-edit-index #post-edit-index-wrapper #post-feature #page-file-manager #page-file-wrapper #page-file-drop label { cursor: pointer; + font-weight: 600px; + text-transform: capitalize; } -#post-edit-index #post-edit-index-wrapper #post-feature #featured-image-drop img { +#post-edit-index #post-edit-index-wrapper #post-feature #page-file-manager #page-file-wrapper #page-file-drop img { width: 100%; margin: 0; padding: 0; } -#post-edit-index #post-edit-index-wrapper #post-feature #featured-new-image-btn { - position: absolute; - margin: 20px; +#post-edit-index #post-edit-index-wrapper #post-feature #page-file-manager #page-file-wrapper #page-images-list, #post-edit-index #post-edit-index-wrapper #post-feature #page-file-manager #page-file-wrapper #page-files-list { + padding: 10px 0 0 0; } -#post-edit-index #post-edit-index-wrapper #post-feature #featured-new-image-btn #new-feature-upload { - padding-top: 4px; - background: #EFEBE3; +#post-edit-index #post-edit-index-wrapper #post-feature #page-file-manager #page-file-wrapper #page-images-list .img-item, #post-edit-index #post-edit-index-wrapper #post-feature #page-file-manager #page-file-wrapper #page-files-list .img-item { + height: 150px; + width: 23.8%; + border-radius: 3px; + margin: 0 10px 10px 0; + display: inline-block; + cursor: pointer; } -#post-edit-index #post-edit-index-wrapper #post-feature #featured-new-image-btn #new-feature-upload svg { - fill: #fc6399; +#post-edit-index #post-edit-index-wrapper #post-feature #page-file-manager #page-file-wrapper #page-images-list .audio-item, #post-edit-index #post-edit-index-wrapper #post-feature #page-file-manager #page-file-wrapper #page-files-list .audio-item { + height: 150px; + width: 23.8%; + border-radius: 3px; + margin: 0 10px 10px 0; + display: inline-block; + cursor: pointer; + background: #1D3040; + background: url("/assets/images/global/upload-audio.png") no-repeat center center/cover; +} +#post-edit-index #post-edit-index-wrapper #post-feature #page-file-manager #page-file-wrapper #page-images-list .video-item, #post-edit-index #post-edit-index-wrapper #post-feature #page-file-manager #page-file-wrapper #page-files-list .video-item { + height: 150px; + width: 23.8%; + border-radius: 3px; + margin: 0 10px 10px 0; + display: inline-block; + cursor: pointer; + background: #1D3040; + background: url("/assets/images/global/upload-video.png") no-repeat center center/cover; +} +#post-edit-index #post-edit-index-wrapper #post-feature #page-file-manager #page-file-wrapper #page-images-list .file-item, #post-edit-index #post-edit-index-wrapper #post-feature #page-file-manager #page-file-wrapper #page-files-list .file-item { + height: 150px; + width: 23.8%; + border-radius: 3px; + margin: 0 10px 10px 0; + display: inline-block; + cursor: pointer; + background: #1D3040; + background: url("/assets/images/global/upload-doc.png") no-repeat center center/cover; } #post-edit-index #post-edit-index-wrapper #edit-post { width: 100%; @@ -3216,7 +3247,6 @@ select { border-color: #fc6399; } #post-edit-index #post-edit-index-wrapper #edit-post #edit-post-wrapper #edit, #post-edit-index #post-edit-index-wrapper #edit-post #edit-post-wrapper #highlight { - /* Both elements need the same text and space styling so they are directly on top of each other */ border: 0; width: 100%; min-height: 300px; @@ -3248,6 +3278,28 @@ select { #post-edit-index #post-edit-index-wrapper #edit-post #edit-post-wrapper #highlight { z-index: 0; } +#post-edit-index #post-edit-index-wrapper #edit-post #edit-post-wrapper #highlight pre { + margin: 0; +} +#post-edit-index #post-edit-index-wrapper #edit-post #edit-post-wrapper #highlight pre code { + font-family: "Lucida Console", Monaco, monospace; + padding: 5px; + border-radius: 5px; + line-height: 1.6em; + font-size: 1.25em; + color: #fde3a7; + word-wrap: normal; + white-space: pre-wrap; + line-break: normal; + -webkit-line-break: normal; + -o-line-break: normal; + -moz-line-break: normal; + display: inline-block; + width: 100%; + max-width: 900px; + min-height: 200px; + caret-color: #fc6399; +} @media only screen and (max-width: 800px) { #post-edit-index #post-edit-index-wrapper #post-header #post-title #post-date { @@ -3630,9 +3682,6 @@ select { background: #b2cce5; width: 10%; height: 39px; - -moz-transition: all 0.3s linear; - -webkit-transition: all 0.3s linear; - -o-transition: all 0.3s linear; transition: all 0.3s linear; margin: 0; border-radius: 0; diff --git a/public/assets/images/global/the-logo.svg b/public/assets/images/global/the-logo.svg new file mode 100644 index 0000000..f8d21b5 --- /dev/null +++ b/public/assets/images/global/the-logo.svg @@ -0,0 +1,33 @@ + + + + + diff --git a/public/assets/images/global/upload-audio.png b/public/assets/images/global/upload-audio.png new file mode 100644 index 0000000..137cd0c Binary files /dev/null and b/public/assets/images/global/upload-audio.png differ diff --git a/public/assets/images/global/upload-doc.png b/public/assets/images/global/upload-doc.png new file mode 100644 index 0000000..b6d8acb Binary files /dev/null and b/public/assets/images/global/upload-doc.png differ diff --git a/public/assets/images/global/upload-video.png b/public/assets/images/global/upload-video.png new file mode 100644 index 0000000..96b9a5d Binary files /dev/null and b/public/assets/images/global/upload-video.png differ diff --git a/public/assets/scripts/Start.js b/public/assets/scripts/Start.js index 30cdd87..cda5f3b 100644 --- a/public/assets/scripts/Start.js +++ b/public/assets/scripts/Start.js @@ -1,8 +1,2 @@ -(()=>{function e(e){return e&&e.__esModule?e.default:e}var t="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:{};const n="POST",r="json",a="x-www-form-urlencoded",i="/api/v1/status",o="/api/v1/settings/publish",s="/api/v1/mailer",l="/api/v1/login",u="writeSettings",d="publishSite",c="createNewPage",g="editPage",p="deletePage",h="getSiteSettings",m="getMemberInfo";class f{constructor(e=null,t=null){this.percentComplete=0,this.baseURL=null,this.progressBar=t,this.status=!1,e&&(this.baseURL=e),this._request(this.baseURL?this.baseURL+i:i).then((e=>{"apiUseAuthorized"===e.type&&(this.token=e.token)}))}login(e){return new Promise(((t,a)=>{this.baseURL?e.remote=!0:e.remote=!1,this.key?e.key=this.key:e.key=null,this._request(this.baseURL?this.baseURL+l:l,"getAuthStatus",n,r,e).then((e=>{t(e)})).catch((e=>{a(e)}))}))}sync(e,t){return new Promise(((a,i)=>{let o="";switch(e){case"syncSite":o="/api/v1/settings/sync";break;case"syncNav":o="/api/v1/settings/nav-sync"}this._request(this.baseURL?this.baseURL+o:o,u,n,r,t).then((e=>{a(e)})).catch((e=>{i(e)}))}))}publish(e){return new Promise(((t,a)=>{this._request(this.baseURL?this.baseURL+o:o,d,n,r,e).then((e=>{t(e)})).catch((e=>{a(e)}))}))}pageActions(e,t){let r,i,o;switch(e){case c:r="/api/v1/page/create",i=c,o=a;break;case g:r="/api/v1/page/write",i=g,o=a;break;case p:r="/api/v1/page/delete",i=p,o=a}return this.baseURL?t.remote=!0:t.remote=!1,new Promise(((e,a)=>{this._request(this.baseURL?this.baseURL+r:r,i,n,o,t).then((t=>{e(t)})).catch((e=>{a(e)}))}))}sendMail(e){return new Promise(((t,a)=>{this._request(this.baseURL?this.baseURL+s:s,"sendMail",n,r,e).then((e=>{t(e)})).catch((e=>{a(e)}))}))}getInfo(e){let t,n;return"site"==e?(t="/api/v1/settings/site",n=h):(t="/api/v1/settings/member",n=m),new Promise(((e,r)=>{this._request(this.baseURL?this.baseURL+t:t,n).then((t=>{e(t)})).catch((e=>{r(e)}))}))}_request(e,t,i="GET",o="json",s=null){var l=this;return new Promise((function(f,v){var y=new XMLHttpRequest;if(y.upload.addEventListener("progress",(e=>l.handleLoadProgress(e,l.progressBar))),y.open(i,e,!0),y.onload=()=>{if(200==y.status){let e=JSON.parse(y.response);f(e)}else{let e=JSON.parse(y.response);v(e)}},"PUT"==i||i==n)switch(t!==u&&t!==g&&t!==c&&t!==p&&t!==d&&"reIndexPages"!==t||y.setRequestHeader("fipamo-access-token",l.token),o){case r:y.setRequestHeader("Content-type","application/"+o),y.send(JSON.stringify(s));break;case a:y.send(s)}else t!==h&&t!==m||y.setRequestHeader("fipamo-access-token",l.token),y.send()}))}handleLoadProgress(e,t){let n=Math.ceil(e.loaded/e.total*100);null!=t&&(t.style.width=n+"%")}}const v="POST",y="json",b="x-www-form-urlencoded",E="/api/v1/status",w="uploadFiles";class k{constructor(e=null,t=null,n=null){this.percentComplete=0,this.token=null,this.baseURL=null,this.progressBar=n,this.key=null,t&&(this.key=t),e&&(this.baseURL=e),this._request(this.baseURL?this.baseURL+E+"?key="+this.key:"/api/v1/status?key="+this.key).then((e=>{"apiUseAuthorized"===e.type&&(this.token=e.token)}))}create(e){return new Promise(((t,n)=>{this._request("/api/v1/init","blogInit",v,y,e).then((e=>{t(e)})).catch((e=>{n(e)}))}))}restore(e){return new Promise(((t,n)=>{var r;r=new FormData(e),this._request("/api/v1/restore","restoreBackup","POST","x-www-form-urlencoded",r).then((e=>{t(e)})).catch((e=>{n(e)}))}))}backup(){return new Promise(((e,t)=>{var n;n={task:"create_backup"},this._request("/api/v1/backup","createBackup","POST","json",n).then((t=>{e(t)})).catch((e=>{t(e)}))}))}secret(e){return new Promise(((t,n)=>{this._request("/api/v1/get-secret","retrieveSecret",v,y,e).then((e=>{t(e)})).catch((e=>{n(e)}))}))}newPass(e){return new Promise(((t,n)=>{this._request("/api/v1/reset-password","resetPassword",v,y,e).then((e=>{t(e)})).catch((e=>{n(e)}))}))}imageUpload(e,t){return new Promise(((n,r)=>{let a="";switch(e){case"avatar-upload":a="/api/v1/settings/add-avatar";break;case"background-upload":a="/api/v1/settings/add-feature-background";break;default:a="/api/v1/page/add-entry-image"}var i=new FormData;this.baseURL?(i.append("key",this.key),i.append("remote",!0)):i.append("remote",!1);for(var o=0;o{n(e)})).catch((e=>{r(e)}))}))}_request(e,t,n="GET",r="json",a=null){var i=this;return new Promise((function(o,s){var l=new XMLHttpRequest;if(l.upload.addEventListener("progress",(e=>i.handleLoadProgress(e,i.progressBar))),l.open(n,e,!0),l.onload=()=>{if(200==l.status){let e=JSON.parse(l.response);o(e)}else{let e=JSON.parse(l.response);s(e)}},"PUT"==n||n==v)switch(t===w&&l.setRequestHeader("fipamo-access-token",i.token),r){case y:l.setRequestHeader("Content-type","application/"+r),l.send(JSON.stringify(a));break;case b:l.send(a)}else l.send()}))}handleLoadProgress(e,t){let n=Math.ceil(e.loaded/e.total*100);null!=t&&(t.style.width=n+"%")}}const I="requestLame",S="postUpdated";new class{};var x=class{constructor(){}cleanString(e){return e.replace(/(^\-+|[^a-zA-Z0-9\/_| -]+|\-+$)/g,"").toLowerCase().replace(/[\/_| -]+/g,"-")}decodeHTML(e,t){var n=0,r=0,a=!1;void 0===t&&(t=2),e=e.toString().replace(/</g,"<").replace(/>/g,">");var i={ENT_NOQUOTES:0,ENT_HTML_QUOTE_SINGLE:1,ENT_HTML_QUOTE_DOUBLE:2,ENT_COMPAT:2,ENT_QUOTES:3,ENT_IGNORE:4};if(0===t&&(a=!0),"number"!=typeof t){for(t=[].concat(t),r=0;r{let r=new FormData,a=document.createElement("textarea");a.innerHTML=document.getElementById("highlight-content").innerHTML;let i=a.value;if(i=i.replace(/<\/?span[^>]*>/g,""),i=i.replace(/<\/?br[^>]*>/g,"\n"),r.append("id",document.getElementById("post-edit-index").getAttribute("data-index")),r.append("uuid",document.getElementById("post-edit-index").getAttribute("data-uuid")),r.append("layout",document.getElementById("post-edit-index").getAttribute("data-layout")),r.append("current_title",document.getElementById("post-edit-index").getAttribute("data-slug")),r.append("content",i),r.append("title",document.getElementById("post_title").value),r.append("created",document.getElementById("post-date").getAttribute("data-raw")),r.append("slug",(new x).cleanString(document.getElementById("post_title").value)),r.append("tags",document.getElementById("post_tags").value),r.append("menu",document.getElementById("option-menu-pin").getAttribute("data-active")),r.append("featured",document.getElementById("option-feature").getAttribute("data-active")),r.append("published",document.getElementById("option-published").getAttribute("data-active")),r.append("layout",document.getElementById("page-templates").value),r.append("form_token",document.getElementById("form_token").value),null!=e||null!=e)e.type.match("image.*")?r.append("feature_image",e,e.name):n("Not an image file");else if(document.getElementById("featured-image")){var o=document.getElementById("featured-image").src;null!=o||null!=o?r.append("feature_image",o):r.append("feature_image",null)}t(r)}))}}const T="editorDelete",_="editorUploadImage",A="editorSave",B="editorUpdate";new class{};var D=["borderBottomWidth","borderLeftWidth","borderRightWidth","borderTopStyle","borderRightStyle","borderBottomStyle","borderLeftStyle","borderTopWidth","boxSizing","fontFamily","fontSize","fontWeight","height","letterSpacing","lineHeight","marginBottom","marginLeft","marginRight","marginTop","outlineWidth","overflow","overflowX","overflowY","paddingBottom","paddingLeft","paddingRight","paddingTop","textAlign","textOverflow","textTransform","whiteSpace","wordBreak","wordWrap"],L=function(e,t){var n,r,a,i=document.createElement("div");return n=t,r={position:"absolute",left:-9999,top:0,zIndex:-2e3},"TEXTAREA"===e.tagName&&D.push("width"),D.forEach((function(t){r[t]=getComputedStyle(e)[t]})),a=r,Object.keys(a).forEach((function(e){i.style[e]=a[e]})),i.innerHTML=n,e.parentNode.insertBefore(i,e.nextSibling),{rect:function(){var e=i.ownerDocument.getElementById("caret-position-marker"),t={left:e.offsetLeft,top:e.offsetTop,height:e.offsetHeight};return i.parentNode.removeChild(i),t}}};function C(e){return(C="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var O=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.customPos,n=e.iframe,r=e.noShadowCaret;return n?{iframe:n,window:n.contentWindow,document:n.contentDocument||n.contentWindow.document,noShadowCaret:r,customPos:t}:{window:window,document:document,noShadowCaret:r,customPos:t}},M=function(e){return"object"===C(e)&&null!==e},N=function(e,t){var n=function(){return e.selectionStart},r=function(r){var a=function(e){return e.replace(/<|>|`|"|&/g,"?").replace(/\r\n|\r|\n/g,"
")};(t.customPos||0===t.customPos)&&(r=t.customPos);var i=void 0===r?n():r,o=e.value.slice(0,i),s=e.value.slice(i),l=''.concat(a(o),"");l+='|',l+=''.concat(a(s),"");var u=L(e,l).rect();return u.pos=n(),u};return{getPos:n,setPos:function(t){return e.setSelectionRange(t,t),e},getOffset:function(n){var a=function(e,t){var n=t&&t.window||window,r=t&&t.document||document,a=e.getBoundingClientRect(),i=r.documentElement,o=n.pageXOffset||i.scrollLeft,s=n.pageYOffset||i.scrollTop;return{top:a.top+s,left:a.left+o}}(e),i=r(n);return{top:a.top+i.top+t.document.body.scrollTop,left:a.left+i.left+t.document.body.scrollLeft,height:i.height}},getPosition:r}},R=function(e,t){return function(e){return!!(e.contentEditable?"true"===e.contentEditable:"true"===e.getAttribute("contenteditable"))}(e)?function(e,t){var n=function(){var n=r(),a={height:0,left:0,right:0};if(!n)return a;var i=t.customPos||0===t.customPos;if(n.endOffset-1>0&&n.endContainer!==e||i){var o=n.cloneRange(),s=i?t.customPos:n.endOffset;o.setStart(n.endContainer,s-1<0?0:s-1),o.setEnd(n.endContainer,s);var l=o.getBoundingClientRect();a={height:l.height,left:l.left+l.width,top:l.top},o.detach()}if((!a||a&&0===a.height)&&!t.noShadowCaret){var u=n.cloneRange(),d=t.document.createTextNode("|");u.insertNode(d),u.selectNode(d);var c=u.getBoundingClientRect();a={height:c.height,left:c.left,top:c.top},d.parentNode.removeChild(d),u.detach()}if(a){var g=t.document.documentElement;a.top+=t.window.pageYOffset-(g.clientTop||0),a.left+=t.window.pageXOffset-(g.clientLeft||0)}return a},r=function(){if(t.window.getSelection){var e=t.window.getSelection();return e.rangeCount>0?e.getRangeAt(0):null}},a=function(){var t=r(),n=t.cloneRange();n.selectNodeContents(e),n.setEnd(t.endContainer,t.endOffset);var a=n.toString().length;return n.detach(),a};return{getPos:a,setPos:function(n){var r=t.window.getSelection();if(r){var a=0,i=!1;!function e(o,s){for(var l=0;l=o){i=!0;var d=t.document.createRange();d.setStart(u,o-a),r.removeAllRanges(),r.addRange(d);break}a+=u.length}else e(n,u)}}(n,e)}return e},getPosition:function(){var r=n(),i=a(),o=e.getBoundingClientRect(),s=o.top+t.document.body.scrollTop,l=o.left+t.document.body.scrollLeft;return r.left-=l,r.top-=s,r.pos=i,r},getOffset:n,getRange:r}}(e,t):N(e,t)};var U=class{constructor(){this.listeners=new Map}addListener(e,t){this.listeners.has(e)||this.listeners.set(e,[]),this.listeners.get(e).push(t)}removeListener(e,t){var n,r=this.listeners.get(e);return!!(r&&r.length&&(n=r.reduce(((e,n,r)=>"function"==typeof n&&n===t?e=r:e),-1))>-1)&&(r.splice(n,1),this.listeners.set(e,r),!0)}emitEvent(e,...t){var n=this.listeners.get(e);return!(!n||!n.length)&&(n.forEach((e=>{e(...t)})),!0)}},H={},F=function(e){var t=/\blang(?:uage)?-([\w-]+)\b/i,n=0,r={},a={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function e(t){return t instanceof i?new i(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/=c.reach);I+=k.value.length,k=k.next){var S=k.value;if(t.length>e.length)return;if(!(S instanceof i)){var x,P=1;if(y){if(!(x=o(w,I,e,v)))break;var T=x.index,_=x.index+x[0].length,A=I;for(A+=k.value.length;T>=A;)A+=(k=k.next).value.length;if(I=A-=k.value.length,k.value instanceof i)continue;for(var B=k;B!==t.tail&&(A<_||"string"==typeof B.value);B=B.next)P++,A+=B.value.length;P--,S=e.slice(I,A),x.index-=I}else if(!(x=o(w,0,S,v)))continue;T=x.index;var D=x[0],L=S.slice(0,T),C=S.slice(T+D.length),O=I+S.length;c&&O>c.reach&&(c.reach=O);var M=k.prev;if(L&&(M=u(t,M,L),I+=L.length),d(t,M,P),k=u(t,M,new i(g,f?a.tokenize(D,f):D,b,D)),C&&u(t,k,C),P>1){var N={cause:g+","+h,reach:O};s(e,t,n,k.prev,I,N),c&&N.reach>c.reach&&(c.reach=N.reach)}}}}}}function l(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function u(e,t,n){var r=t.next,a={value:n,prev:t,next:r};return t.next=a,r.prev=a,e.length++,a}function d(e,t,n){for(var r=t.next,a=0;a"+i.content+""},!e.document)return e.addEventListener?(a.disableWorkerMessageHandler||e.addEventListener("message",(function(t){var n=JSON.parse(t.data),r=n.language,i=n.code,o=n.immediateClose;e.postMessage(a.highlight(i,a.languages[r],r)),o&&e.close()}),!1),a):a;var c=a.util.currentScript();function g(){a.manual||a.highlightAll()}if(c&&(a.filename=c.src,c.hasAttribute("data-manual")&&(a.manual=!0)),!a.manual){var p=document.readyState;"loading"===p||"interactive"===p&&c&&c.defer?document.addEventListener("DOMContentLoaded",g):window.requestAnimationFrame?window.requestAnimationFrame(g):window.setTimeout(g,16)}return a}("undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{});H&&(H=F),void 0!==t&&(t.Prism=F),Prism.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.languages.markup.doctype.inside["internal-subset"].inside=Prism.languages.markup,Prism.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(Prism.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^$)/i,lookbehind:!0,inside:Prism.languages[t]},n.cdata=/^$/i;var r={"included-cdata":{pattern://i,inside:n}};r["language-"+t]={pattern:/[\s\S]+/,inside:Prism.languages[t]};var a={};a[e]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:r},Prism.languages.insertBefore("markup","cdata",a)}}),Object.defineProperty(Prism.languages.markup.tag,"addAttribute",{value:function(e,t){Prism.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:Prism.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup,Prism.languages.xml=Prism.languages.extend("markup",{}),Prism.languages.ssml=Prism.languages.xml,Prism.languages.atom=Prism.languages.xml,Prism.languages.rss=Prism.languages.xml,function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(//g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,a=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return r})),i=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"font-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+a+i+"(?:"+a+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+a+i+")(?:"+a+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+a+")"+i+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+a+"$"),inside:{"table-header":{pattern:RegExp(r),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)|_(?:(?!_))+_)+__\b|\*\*(?:(?!\*)|\*(?:(?!\*))+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)|__(?:(?!_))+__)+_\b|\*(?:(?!\*)|\*\*(?:(?!\*))+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~))+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\]))+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\]))+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,r=t.length;n",quot:'"'},l=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(Prism);var q=class extends U{constructor(t,n){super(),document.getElementById("edit").addEventListener("input",(n=>{let r=document.querySelector("#highlight-content");this.textEditor=t;let a=n.target.value;r.innerHTML=a.replace(new RegExp("&","g"),"&").replace(new RegExp("<","g"),"<");let i=document.getElementById("highlight").offsetHeight;document.getElementById("edit-post-wrapper").style.height=i+"px",n.target.style.height=i+30+"px",e(H).highlightElement(r)})),document.getElementById("edit").addEventListener("scroll",(e=>{let t=document.querySelector("#highlight");t.scrollTop=e.scrollTop,t.scrollLeft=e.scrollLeft})),document.getElementById("edit").dispatchEvent(new Event("input")),this.setInputs(),window.addEventListener("scroll",(()=>{var e=n;window.pageYOffset+5>=e?document.getElementById("edit-control").style.position="fixed":document.getElementById("edit-control").style.position="relative"}))}setInputs(){for(var e=document.querySelectorAll(".editor-button"),t=0,n=e.length;tthis.handleEditorOption(e)),!1)}notify(e,t){switch(e){case S:document.getElementById("submit-update").classList.add("icon-hide"),document.getElementById("submit-good").classList.remove("icon-hide"),document.getElementById("edit-update").classList.remove("submit-start"),document.getElementById("edit-update").classList.add("submit-cool"),setTimeout((()=>{document.getElementById("submit-update").classList.remove("icon-hide"),document.getElementById("submit-good").classList.add("icon-hide"),document.getElementById("edit-update").classList.add("submit-start"),document.getElementById("edit-update").classList.remove("submit-cool")}),2e3);break;case"postAdded":break;case _:{let e=this.textEditor.value.length,n=this.textEditor.selectionStart,r=this.textEditor.selectionEnd,a="![image alt text]("+t+")";this.textEditor.value=this.textEditor.value.substring(0,n)+a+this.textEditor.value.substring(r,e),document.getElementById("edit").dispatchEvent(new Event("input"));break}}}handleEditorOption(e){e.preventDefault();let t=this.textEditor.value.length,n=this.textEditor.selectionStart,r=this.textEditor.selectionEnd,a=this.textEditor.value.substring(n,r),i="";switch(e.target.id){case"edit-bold":i="**"+a+"**",this.textEditor.value=this.textEditor.value.substring(0,n)+i+this.textEditor.value.substring(r,t);break;case"edit-italic":i="*"+a+"*",this.textEditor.value=this.textEditor.value.substring(0,n)+i+this.textEditor.value.substring(r,t);break;case"edit-strikethrough":i="~~"+a+"~~",this.textEditor.value=this.textEditor.value.substring(0,n)+i+this.textEditor.value.substring(r,t);break;case"edit-header1":i="# "+a+"\n",this.textEditor.value=this.textEditor.value.substring(0,n)+i+this.textEditor.value.substring(r,t);break;case"edit-header2":i="## "+a+"\n",this.textEditor.value=this.textEditor.value.substring(0,n)+i+this.textEditor.value.substring(r,t);break;case"edit-header3":i="### "+a+"\n",this.textEditor.value=this.textEditor.value.substring(0,n)+i+this.textEditor.value.substring(r,t);break;case"edit-link":i="["+a+"]("+prompt("Let's get that url, boss").toLowerCase()+")",this.textEditor.value=this.textEditor.value.substring(0,n)+i+this.textEditor.value.substring(r,t);break;case"edit-image":this.caretPos=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};M(t)&&(n=t,t=null);var r=O(n),a=R(e,r);return t||0===t?a.setPos(t):a.getPosition()}(this.textEditor).pos,this.emitEvent(_);break;case"submit-save":case"edit-save":this.emitEvent(A);break;case"submit-update":case"edit-update":this.emitEvent(B);break;case"edit-delete":this.emitEvent(T)}document.getElementById("edit").dispatchEvent(new Event("input"))}},X={update:null,begin:null,loopBegin:null,changeBegin:null,change:null,changeComplete:null,loopComplete:null,complete:null,loop:1,direction:"normal",autoplay:!0,timelineOffset:0},j={duration:1e3,delay:0,endDelay:0,easing:"easeOutElastic(1, .5)",round:0},Y=["translateX","translateY","translateZ","rotate","rotateX","rotateY","rotateZ","scale","scaleX","scaleY","scaleZ","skew","skewX","skewY","perspective","matrix","matrix3d"],W={CSS:{},springs:{}};function $(e,t,n){return Math.min(Math.max(e,t),n)}function z(e,t){return e.indexOf(t)>-1}function G(e,t){return e.apply(null,t)}var Q={arr:function(e){return Array.isArray(e)},obj:function(e){return z(Object.prototype.toString.call(e),"Object")},pth:function(e){return Q.obj(e)&&e.hasOwnProperty("totalLength")},svg:function(e){return e instanceof SVGElement},inp:function(e){return e instanceof HTMLInputElement},dom:function(e){return e.nodeType||Q.svg(e)},str:function(e){return"string"==typeof e},fnc:function(e){return"function"==typeof e},und:function(e){return void 0===e},nil:function(e){return Q.und(e)||null===e},hex:function(e){return/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(e)},rgb:function(e){return/^rgb/.test(e)},hsl:function(e){return/^hsl/.test(e)},col:function(e){return Q.hex(e)||Q.rgb(e)||Q.hsl(e)},key:function(e){return!X.hasOwnProperty(e)&&!j.hasOwnProperty(e)&&"targets"!==e&&"keyframes"!==e}};function V(e){var t=/\(([^)]+)\)/.exec(e);return t?t[1].split(",").map((function(e){return parseFloat(e)})):[]}function J(e,t){var n=V(e),r=$(Q.und(n[0])?1:n[0],.1,100),a=$(Q.und(n[1])?100:n[1],.1,100),i=$(Q.und(n[2])?10:n[2],.1,100),o=$(Q.und(n[3])?0:n[3],.1,100),s=Math.sqrt(a/r),l=i/(2*Math.sqrt(a*r)),u=l<1?s*Math.sqrt(1-l*l):0,d=l<1?(l*s-o)/u:-o+s;function c(e){var n=t?t*e/1e3:e;return n=l<1?Math.exp(-n*l*s)*(1*Math.cos(u*n)+d*Math.sin(u*n)):(1+d*n)*Math.exp(-n*s),0===e||1===e?e:1-n}return t?c:function(){var t=W.springs[e];if(t)return t;for(var n=1/6,r=0,a=0;;)if(1===c(r+=n)){if(++a>=16)break}else a=0;var i=r*n*1e3;return W.springs[e]=i,i}}function Z(e){return void 0===e&&(e=10),function(t){return Math.ceil($(t,1e-6,1)*e)*(1/e)}}var K,ee,te=function(){var e=.1;function t(e,t){return 1-3*t+3*e}function n(e,t){return 3*t-6*e}function r(e){return 3*e}function a(e,a,i){return((t(a,i)*e+n(a,i))*e+r(a))*e}function i(e,a,i){return 3*t(a,i)*e*e+2*n(a,i)*e+r(a)}return function(t,n,r,o){if(0<=t&&t<=1&&0<=r&&r<=1){var s=new Float32Array(11);if(t!==n||r!==o)for(var l=0;l<11;++l)s[l]=a(l*e,t,r);return function(e){return t===n&&r===o||0===e||1===e?e:a(u(e),n,o)}}function u(n){for(var o=0,l=1;10!==l&&s[l]<=n;++l)o+=e;--l;var u=o+(n-s[l])/(s[l+1]-s[l])*e,d=i(u,t,r);return d>=.001?function(e,t,n,r){for(var o=0;o<4;++o){var s=i(t,n,r);if(0===s)return t;t-=(a(t,n,r)-e)/s}return t}(n,u,t,r):0===d?u:function(e,t,n,r,i){var o,s,l=0;do{(o=a(s=t+(n-t)/2,r,i)-e)>0?n=s:t=s}while(Math.abs(o)>1e-7&&++l<10);return s}(n,o,o+e,t,r)}}}(),ne=(K={linear:function(){return function(e){return e}}},ee={Sine:function(){return function(e){return 1-Math.cos(e*Math.PI/2)}},Circ:function(){return function(e){return 1-Math.sqrt(1-e*e)}},Back:function(){return function(e){return e*e*(3*e-2)}},Bounce:function(){return function(e){for(var t,n=4;e<((t=Math.pow(2,--n))-1)/11;);return 1/Math.pow(4,3-n)-7.5625*Math.pow((3*t-2)/22-e,2)}},Elastic:function(e,t){void 0===e&&(e=1),void 0===t&&(t=.5);var n=$(e,1,10),r=$(t,.1,2);return function(e){return 0===e||1===e?e:-n*Math.pow(2,10*(e-1))*Math.sin((e-1-r/(2*Math.PI)*Math.asin(1/n))*(2*Math.PI)/r)}}},["Quad","Cubic","Quart","Quint","Expo"].forEach((function(e,t){ee[e]=function(){return function(e){return Math.pow(e,t+2)}}})),Object.keys(ee).forEach((function(e){var t=ee[e];K["easeIn"+e]=t,K["easeOut"+e]=function(e,n){return function(r){return 1-t(e,n)(1-r)}},K["easeInOut"+e]=function(e,n){return function(r){return r<.5?t(e,n)(2*r)/2:1-t(e,n)(-2*r+2)/2}},K["easeOutIn"+e]=function(e,n){return function(r){return r<.5?(1-t(e,n)(1-2*r))/2:(t(e,n)(2*r-1)+1)/2}}})),K);function re(e,t){if(Q.fnc(e))return e;var n=e.split("(")[0],r=ne[n],a=V(e);switch(n){case"spring":return J(e,t);case"cubicBezier":return G(te,a);case"steps":return G(Z,a);default:return G(r,a)}}function ae(e){try{return document.querySelectorAll(e)}catch(e){return}}function ie(e,t){for(var n=e.length,r=arguments.length>=2?arguments[1]:void 0,a=[],i=0;i1&&(n-=1),n<1/6?e+6*(t-e)*n:n<.5?t:n<2/3?e+(t-e)*(2/3-n)*6:e}if(0==o)t=n=r=s;else{var d=s<.5?s*(1+o):s+o-s*o,c=2*s-d;t=u(c,d,i+1/3),n=u(c,d,i),r=u(c,d,i-1/3)}return"rgba("+255*t+","+255*n+","+255*r+","+l+")"}(e):void 0;var t,n}function pe(e){var t=/[+-]?\d*\.?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?(%|px|pt|em|rem|in|cm|mm|ex|ch|pc|vw|vh|vmin|vmax|deg|rad|turn)?$/.exec(e);if(t)return t[1]}function he(e,t){return Q.fnc(e)?e(t.target,t.id,t.total):e}function me(e,t){return e.getAttribute(t)}function fe(e,t,n){if(le([n,"deg","rad","turn"],pe(t)))return t;var r=W.CSS[t+n];if(!Q.und(r))return r;var a=document.createElement(e.tagName),i=e.parentNode&&e.parentNode!==document?e.parentNode:document.body;i.appendChild(a),a.style.position="absolute",a.style.width=100+n;var o=100/a.offsetWidth;i.removeChild(a);var s=o*parseFloat(t);return W.CSS[t+n]=s,s}function ve(e,t,n){if(t in e.style){var r=t.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase(),a=e.style[t]||getComputedStyle(e).getPropertyValue(r)||"0";return n?fe(e,a,n):a}}function ye(e,t){return Q.dom(e)&&!Q.inp(e)&&(!Q.nil(me(e,t))||Q.svg(e)&&e[t])?"attribute":Q.dom(e)&&le(Y,t)?"transform":Q.dom(e)&&"transform"!==t&&ve(e,t)?"css":null!=e[t]?"object":void 0}function be(e){if(Q.dom(e)){for(var t,n=e.style.transform||"",r=/(\w+)\(([^)]*)\)/g,a=new Map;t=r.exec(n);)a.set(t[1],t[2]);return a}}function Ee(e,t,n,r){var a=z(t,"scale")?1:0+function(e){return z(e,"translate")||"perspective"===e?"px":z(e,"rotate")||z(e,"skew")?"deg":void 0}(t),i=be(e).get(t)||a;return n&&(n.transforms.list.set(t,i),n.transforms.last=t),r?fe(e,i,r):i}function we(e,t,n,r){switch(ye(e,t)){case"transform":return Ee(e,t,r,n);case"css":return ve(e,t,n);case"attribute":return me(e,t);default:return e[t]||0}}function ke(e,t){var n=/^(\*=|\+=|-=)/.exec(e);if(!n)return e;var r=pe(e)||0,a=parseFloat(t),i=parseFloat(e.replace(n[0],""));switch(n[0][0]){case"+":return a+i+r;case"-":return a-i+r;case"*":return a*i+r}}function Ie(e,t){if(Q.col(e))return ge(e);if(/\s/g.test(e))return e;var n=pe(e),r=n?e.substr(0,e.length-n.length):e;return t?r+t:r}function Se(e,t){return Math.sqrt(Math.pow(t.x-e.x,2)+Math.pow(t.y-e.y,2))}function xe(e){for(var t,n=e.points,r=0,a=0;a0&&(r+=Se(t,i)),t=i}return r}function Pe(e){if(e.getTotalLength)return e.getTotalLength();switch(e.tagName.toLowerCase()){case"circle":return function(e){return 2*Math.PI*me(e,"r")}(e);case"rect":return function(e){return 2*me(e,"width")+2*me(e,"height")}(e);case"line":return function(e){return Se({x:me(e,"x1"),y:me(e,"y1")},{x:me(e,"x2"),y:me(e,"y2")})}(e);case"polyline":return xe(e);case"polygon":return function(e){var t=e.points;return xe(e)+Se(t.getItem(t.numberOfItems-1),t.getItem(0))}(e)}}function Te(e,t){var n=t||{},r=n.el||function(e){for(var t=e.parentNode;Q.svg(t)&&Q.svg(t.parentNode);)t=t.parentNode;return t}(e),a=r.getBoundingClientRect(),i=me(r,"viewBox"),o=a.width,s=a.height,l=n.viewBox||(i?i.split(" "):[0,0,o,s]);return{el:r,viewBox:l,x:l[0]/1,y:l[1]/1,w:o,h:s,vW:l[2],vH:l[3]}}function _e(e,t,n){function r(n){void 0===n&&(n=0);var r=t+n>=1?t+n:0;return e.el.getPointAtLength(r)}var a=Te(e.el,e.svg),i=r(),o=r(-1),s=r(1),l=n?1:a.w/a.vW,u=n?1:a.h/a.vH;switch(e.property){case"x":return(i.x-a.x)*l;case"y":return(i.y-a.y)*u;case"angle":return 180*Math.atan2(s.y-o.y,s.x-o.x)/Math.PI}}function Ae(e,t){var n=/[+-]?\d*\.?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?/g,r=Ie(Q.pth(e)?e.totalLength:e,t)+"";return{original:r,numbers:r.match(n)?r.match(n).map(Number):[0],strings:Q.str(e)||t?r.split(n):[]}}function Be(e){return ie(e?oe(Q.arr(e)?e.map(se):se(e)):[],(function(e,t,n){return n.indexOf(e)===t}))}function De(e){var t=Be(e);return t.map((function(e,n){return{target:e,id:n,total:t.length,transforms:{list:be(e)}}}))}function Le(e,t){var n=ue(t);if(/^spring/.test(n.easing)&&(n.duration=J(n.easing)),Q.arr(e)){var r=e.length;2===r&&!Q.obj(e[0])?e={value:e}:Q.fnc(t.duration)||(n.duration=t.duration/r)}var a=Q.arr(e)?e:[e];return a.map((function(e,n){var r=Q.obj(e)&&!Q.pth(e)?e:{value:e};return Q.und(r.delay)&&(r.delay=n?0:t.delay),Q.und(r.endDelay)&&(r.endDelay=n===a.length-1?t.endDelay:0),r})).map((function(e){return ce(e,n)}))}function Ce(e,t){var n=[],r=t.keyframes;for(var a in r&&(t=ce(function(e){for(var t=ie(oe(e.map((function(e){return Object.keys(e)}))),(function(e){return Q.key(e)})).reduce((function(e,t){return e.indexOf(t)<0&&e.push(t),e}),[]),n={},r=function(r){var a=t[r];n[a]=e.map((function(e){var t={};for(var n in e)Q.key(n)?n==a&&(t.value=e[n]):t[n]=e[n];return t}))},a=0;a0?requestAnimationFrame(t):void 0}return"undefined"!=typeof document&&document.addEventListener("visibilitychange",(function(){je.suspendWhenDocumentHidden&&(Xe()?e=cancelAnimationFrame(e):(Fe.forEach((function(e){return e._onDocumentVisibility()})),qe()))})),function(){e||Xe()&&je.suspendWhenDocumentHidden||!(Fe.length>0)||(e=requestAnimationFrame(t))}}();function Xe(){return!!document&&document.hidden}function je(e){void 0===e&&(e={});var t,n=0,r=0,a=0,i=0,o=null;function s(e){var t=window.Promise&&new Promise((function(e){return o=e}));return e.finished=t,t}var l=function(e){var t=de(X,e),n=de(j,e),r=Ce(n,e),a=De(e.targets),i=Re(a,r),o=Ue(i,n),s=He;return He++,ce(t,{id:s,children:[],animatables:a,animations:i,duration:o.duration,delay:o.delay,endDelay:o.endDelay})}(e);s(l);function u(){var e=l.direction;"alternate"!==e&&(l.direction="normal"!==e?"normal":"reverse"),l.reversed=!l.reversed,t.forEach((function(e){return e.reversed=l.reversed}))}function d(e){return l.reversed?l.duration-e:e}function c(){n=0,r=d(l.currentTime)*(1/je.speed)}function g(e,t){t&&t.seek(e-t.timelineOffset)}function p(e){for(var t=0,n=l.animations,r=n.length;t2||(y=Math.round(y*p)/p)),h.push(y)}var w=g.length;if(w){f=g[0];for(var k=0;k0&&(l.began=!0,h("begin")),!l.loopBegan&&l.currentTime>0&&(l.loopBegan=!0,h("loopBegin")),v<=m&&0!==l.currentTime&&p(0),(v>=f&&l.currentTime!==c||!c)&&p(c),v>m&&v=c&&(r=0,l.remaining&&!0!==l.remaining&&l.remaining--,l.remaining?(n=a,h("loopComplete"),l.loopBegan=!1,"alternate"===l.direction&&u()):(l.paused=!0,l.completed||(l.completed=!0,h("loopComplete"),h("complete"),!l.passThrough&&"Promise"in window&&(o(),s(l)))))}return l.reset=function(){var e=l.direction;l.passThrough=!1,l.currentTime=0,l.progress=0,l.paused=!0,l.began=!1,l.loopBegan=!1,l.changeBegan=!1,l.completed=!1,l.changeCompleted=!1,l.reversePlayback=!1,l.reversed="reverse"===e,l.remaining=l.loop,t=l.children;for(var n=i=t.length;n--;)l.children[n].reset();(l.reversed&&!0!==l.loop||"alternate"===e&&1===l.loop)&&l.remaining++,p(l.reversed?l.duration:0)},l._onDocumentVisibility=c,l.set=function(e,t){return Ne(e,t),l},l.tick=function(e){a=e,n||(n=a),m((a+(r-n))*je.speed)},l.seek=function(e){m(d(e))},l.pause=function(){l.paused=!0,c()},l.play=function(){l.paused&&(l.completed&&l.reset(),l.paused=!1,Fe.push(l),c(),qe())},l.reverse=function(){u(),l.completed=!l.reversed,c()},l.restart=function(){l.reset(),l.play()},l.remove=function(e){We(Be(e),l)},l.reset(),l.autoplay&&l.play(),l}function Ye(e,t){for(var n=t.length;n--;)le(e,t[n].animatable.target)&&t.splice(n,1)}function We(e,t){var n=t.animations,r=t.children;Ye(e,n);for(var a=r.length;a--;){var i=r[a],o=i.animations;Ye(e,o),o.length||i.children.length||r.splice(a,1)}n.length||r.length||t.pause()}je.version="3.2.1",je.speed=1,je.suspendWhenDocumentHidden=!0,je.running=Fe,je.remove=function(e){for(var t=Be(e),n=Fe.length;n--;){We(t,Fe[n])}},je.get=we,je.set=Ne,je.convertPx=fe,je.path=function(e,t){var n=Q.str(e)?ae(e)[0]:e,r=t||100;return function(e){return{property:e,el:n,svg:Te(n),totalLength:Pe(n)*(r/100)}}},je.setDashoffset=function(e){var t=Pe(e);return e.setAttribute("stroke-dasharray",t),t},je.stagger=function(e,t){void 0===t&&(t={});var n=t.direction||"normal",r=t.easing?re(t.easing):null,a=t.grid,i=t.axis,o=t.from||0,s="first"===o,l="center"===o,u="last"===o,d=Q.arr(e),c=d?parseFloat(e[0]):parseFloat(e),g=d?parseFloat(e[1]):0,p=pe(d?e[1]:e)||0,h=t.start||0+(d?c:0),m=[],f=0;return function(e,t,v){if(s&&(o=0),l&&(o=(v-1)/2),u&&(o=v-1),!m.length){for(var y=0;y-1&&Fe.splice(a,1);for(var s=0;s{$e({targets:Ge,rotateX:"0",easing:"easeInOutQuint",duration:700}),$e({targets:Ve,backgroundColor:n,easing:"easeInOutQuint",duration:700,complete:()=>{setTimeout((()=>{null!==t&&$e({targets:Ge,rotateX:"-120",easing:"easeInOutQuint",duration:700,complete:()=>{$e({targets:ze,marginTop:"-55",easing:"easeInOutQuint",delay:700,duration:50})}})}),1e3)}})}})}}const nt=new tt;class rt{constructor(){this.processing=!1;let e=this;this.admin=new f(null,document.getElementById("notify-progress")),this.mm=new k(null,null,document.getElementById("notify-progress")),this.urlPieces=document.URL.split("/"),this.post=[],this.postID=null,this.postUUID=null,this.postLayout=null,document.getElementById("post-edit-index").getAttribute("data-index")&&(this.postID=document.getElementById("post-edit-index").getAttribute("data-index"),this.postUUID=document.getElementById("post-edit-index").getAttribute("data-uuid"),this.postLayout=document.getElementById("post-edit-index").getAttribute("data-layout")),document.getElementById("edit")&&(this.editor=new q(document.getElementById("edit"),document.getElementById("header").offsetHeight+document.getElementById("post-header").offsetHeight+document.getElementById("post-feature").offsetHeight),this.editor.addListener(T,(()=>this.handleEditorOptions(T)),!1),this.editor.addListener(_,(()=>this.handleEditorOptions(_)),!1),this.editor.addListener(B,(()=>this.handleEditorOptions(B)),!1),this.editor.addListener(A,(()=>this.handleEditorOptions(A)),!1),document.getElementById("post-image-upload").addEventListener("change",(t=>{e.handleImageUpload(t.target.id,t.target.files)}),!1),this.start())}start(){if(document.getElementById("featured-image-drop")){document.getElementById("featured-image-drop").addEventListener("dragover",this.handleImageActions,!1),document.getElementById("featured-image-drop").addEventListener("drop",this.handleImageActions,!1),document.getElementById("featured-image-upload").addEventListener("change",(e=>this.handleImageActions(e)),!1),document.getElementById("new-feature-upload")&&document.getElementById("new-feature-upload").addEventListener("click",(()=>{document.getElementById("featured-image-upload").click()}));for(var e=document.querySelectorAll(".post-option-btn"),t=0,n=e.length;tthis.handlePostOptions(e)),!1)}}handlePostOptions(e){let t=null;switch(e.target.id){case"option-page-icon":case"option-menu-pin":t=document.getElementById("option-menu-pin");break;case"option-feature-icon":case"option-feature":t=document.getElementById("option-feature");break;case"option-published-icon":case"option-published":t=document.getElementById("option-published")}if(null!=t){"false"==t.getAttribute("data-active")?t.setAttribute("data-active","true"):t.setAttribute("data-active","false")}}handleEditorOptions(e){if(this.processing)return;let t=this;switch(e){case A:case B:var n="";n=e===A?c:g,(new P).collectInfo(document.getElementById("featured-image-upload").files[0]).then((e=>{t.processing=!0,nt.alert("Writing down changes",null),t.admin.pageActions(n,e).then((e=>{t.processing=!1,"postError"===e.type||"apiUseNotAuthorized"===e.type?nt.alert(e.message,!1):e.type===S?nt.alert(e.message,!0):(nt.alert(e.message,!0),window.location="/dashboard/page/edit/"+e.id)})).catch((e=>{t.processing=!1,nt.alert(e,!1)}))}));break;case T:if("index"===this.postLayout)return void nt.alert("Index cannot be deleted",!1);confirm("AYE! You know you're deleting this post, right?")&&(new P).collectInfo(document.getElementById("featured-image-upload").files[0]).then((e=>{t.processing=!0,this.admin.pageActions(p,e).then((()=>{t.processing=!1,window.location="/dashboard/pages"})).catch((e=>{t.processing=!1,nt.alert(e,!1)}))})).catch((()=>{}));break;case _:document.getElementById("post-image-upload").click()}}handleImageActions(e){switch(e.stopPropagation(),e.preventDefault(),e.type){case"dragover":e.dataTransfer.dropEffect="copy";break;case"change":case"drop":"drop"==e.type?rt.uploadFiles=e.dataTransfer.files:rt.uploadFiles=e.target.files;for(var t,n=0;t=rt.uploadFiles[n];n++)if(t.type.match("image.*")){var r=new FileReader;r.onload=function(e){return function(t){var n=document.createElement("img");n.src=t.target.result,n.title=escape(e.name),document.createElement("div").innerHTML=[''].join(""),document.getElementById("featured-image-drop").innerHTML="",document.getElementById("featured-image-drop").appendChild(n)}}(t),r.readAsDataURL(t)}else alert("This is not an image. \nBad user. BAD.")}}handleImageUpload(e,t){let n=this;nt.alert("Uploading Image",null),n.mm.imageUpload(e,t).then((e=>{"postImageAdded"==e.type?(n.editor.notify(_,e.url),nt.alert("Image Added to Entry",!0)):nt.alert("Uh oh. Image not added",!1)})).catch((()=>{nt.alert("Uh oh. Image not added",!1)}))}}rt.uploadFiles=[];class at{constructor(e){this.currentPage=null,this.choosePage(e),this.start()}start(){}choosePage(e){switch(this.currentPage="",e){case"edit":case"add":this.currentPage=new rt}}}class it{constructor(){}getInfo(){let e=document.getElementById("settings-handle").value,t=document.getElementById("settings-email").value,n=document.getElementById("settings-url").value,r=document.getElementById("settings-title").value,a=document.getElementById("settings-desc").value,i=document.getElementById("render-toggle").getAttribute("data-render"),o=document.getElementById("background").src,s="",l=document.querySelectorAll(".theme-select"),u=document.getElementById("smtp-domain").value,d=document.getElementById("smtp-email").value,c=document.getElementById("smtp-pass").value,g=document.getElementById("mg-domain").value,p=document.getElementById("mg-key").value,h="",m=document.querySelectorAll(".mail-option"),f=document.getElementById("api-access-toggle").getAttribute("data-enabled"),v=document.getElementById("dynamic-render-toggle").getAttribute("data-enabled");var y,b;for(y=0,b=l.length;y{ot.alert(e.message,!0)})).catch((e=>{ot.alert(e.message,!1)}))}testMail(){(new f).sendMail({content:"This is a test email",mail_task:"TESTING"}).then((e=>{ot.alert(e.message,!0)})).catch((e=>{ot.alert(e.message,!1)}))}}const lt=new tt;class ut{constructor(){this.processing=!1,this.start(),this.admin=new f(null),this.mm=new k(null,null)}start(){let e=this;document.getElementById("save-toggle").addEventListener("click",(()=>(new it).getInfo().then((t=>{lt.alert("Saving Settings",null),e.admin.sync("syncSite",t).then((e=>{e.type,lt.alert(e.message,!0)}))})).catch((()=>{})))),document.getElementById("avatar").addEventListener("click",(()=>{document.getElementById("avatar-upload").click()})),document.getElementById("background").addEventListener("click",(()=>{document.getElementById("background-upload").click()})),document.getElementById("avatar-upload").addEventListener("change",(t=>{e.handleImageUpload(t.target.id,t.target.files)}),!1),document.getElementById("background-upload").addEventListener("change",(t=>{e.handleImageUpload(t.target.id,t.target.files)}),!1);var t=document.getElementById("api-access-toggle"),n=document.getElementById("api-status");t.addEventListener("click",(e=>{e.stopPropagation(),e.preventDefault(),"false"==t.getAttribute("data-enabled")?(t.setAttribute("data-enabled","true"),n.innerHTML="EXTERNAL API ACCESS IS ENABLED"):(t.setAttribute("data-enabled","false"),n.innerHTML="EXTERNAL API ACCESS IS NOT ENABLED")}));var r=document.getElementById("dynamic-render-toggle"),a=document.getElementById("dynamic-render-status");r.addEventListener("click",(e=>{e.stopPropagation(),e.preventDefault(),"false"==r.getAttribute("data-enabled")?(r.setAttribute("data-enabled","true"),a.innerHTML="DYNAMIC PAGE RENDERING"):(r.setAttribute("data-enabled","false"),a.innerHTML="STATIC PAGE RENDERING")})),document.getElementById("send-mail").addEventListener("click",(e=>this.handleMailer(e))),document.getElementById("publish-pages").addEventListener("click",(e=>this.handlePublished(e))),document.getElementById("render-toggle").addEventListener("click",(e=>this.toggleRender(e))),document.getElementById("render-toggle-icon").addEventListener("click",(e=>this.toggleRender(e)));let i=document.querySelectorAll(".theme-select");for(var o=0,s=i.length;othis.handleThemes(e)));let l=document.querySelectorAll(".mail-option");for(o=0,s=l.length;othis.handleMailOptions(e)));document.getElementById("create-backup").addEventListener("click",(e=>this.handleBackup(e)))}togglePrivacy(e){e.stopPropagation(),e.preventDefault(),"false"==e.target.getAttribute("data-private")?(e.target.setAttribute("data-private","true"),e.target.innerHTML="SITE IS PUBLIC"):(e.target.setAttribute("data-private","false"),e.target.innerHTML="SITE IS PRIVATE")}toggleRender(e){e.stopPropagation(),e.preventDefault();let t=document.getElementById("render-toggle");"false"==t.getAttribute("data-render")?t.setAttribute("data-render","true"):t.setAttribute("data-render","false")}handleMailer(){(new st).testMail()}handleThemes(e){e.stopPropagation(),e.preventDefault();let t=document.querySelectorAll(".theme-select");for(var n=0,r=t.length;n{"avatarUploaded"==e.type?(lt.alert(e.message,!0),document.getElementById("avatar").src=e.url):(lt.alert(e.message,!0),document.getElementById("background").src=e.url)})).catch((()=>{}))}handlePublished(e){if(this.processing)return;e.preventDefault(),e.stopPropagation();let t=this;this.processing=!0,lt.alert("Publishing site...",null),this.admin.publish({task:"PUBLISH_ALL"}).then((e=>{t.processing=!1,lt.alert(e.message,!0)})).catch((e=>{t.processing=!1,lt.alert(e,!1)}))}handleBackup(e){e.preventDefault(),e.stopPropagation(),lt.alert("Creating backup",null),this.mm.backup().then((e=>{lt.alert(e.message,!0)})).catch((e=>{lt.alert(e,!1)}))}handleReindex(e){if(this.processing)return;let t=this;e.preventDefault(),e.stopPropagation();this.processing=!0,lt.alert("Cleaning up page indexes",null),this.admin.handleReindex({task:"cleanup pages indexes"}).then((e=>{t.processing=!1,lt.alert(e.message,!0)})).catch((e=>{t.processing=!1,lt.alert(e,!1)}))}}class dt{constructor(){}syncMenu(){let e=[],t=document.getElementById("nav-pages").children;for(let n=0;n - * @author owenm - * @license MIT - */function ct(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function gt(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}function vt(e){if("undefined"!=typeof window&&window.navigator)return!!navigator.userAgent.match(e)}var yt=vt(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i),bt=vt(/Edge/i),Et=vt(/firefox/i),wt=vt(/safari/i)&&!vt(/chrome/i)&&!vt(/android/i),kt=vt(/iP(ad|od|hone)/i),It=vt(/chrome/i)&&vt(/android/i),St={capture:!1,passive:!1};function xt(e,t,n){e.addEventListener(t,n,!yt&&St)}function Pt(e,t,n){e.removeEventListener(t,n,!yt&&St)}function Tt(e,t){if(t){if(">"===t[0]&&(t=t.substring(1)),e)try{if(e.matches)return e.matches(t);if(e.msMatchesSelector)return e.msMatchesSelector(t);if(e.webkitMatchesSelector)return e.webkitMatchesSelector(t)}catch(e){return!1}return!1}}function _t(e){return e.host&&e!==document&&e.host.nodeType?e.host:e.parentNode}function At(e,t,n,r){if(e){n=n||document;do{if(null!=t&&(">"===t[0]?e.parentNode===n&&Tt(e,t):Tt(e,t))||r&&e===n)return e;if(e===n)break}while(e=_t(e))}return null}var Bt,Dt=/\s+/g;function Lt(e,t,n){if(e&&t)if(e.classList)e.classList[n?"add":"remove"](t);else{var r=(" "+e.className+" ").replace(Dt," ").replace(" "+t+" "," ");e.className=(r+(n?" "+t:"")).replace(Dt," ")}}function Ct(e,t,n){var r=e&&e.style;if(r){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(e,""):e.currentStyle&&(n=e.currentStyle),void 0===t?n:n[t];t in r||-1!==t.indexOf("webkit")||(t="-webkit-"+t),r[t]=n+("string"==typeof n?"":"px")}}function Ot(e,t){var n="";if("string"==typeof e)n=e;else do{var r=Ct(e,"transform");r&&"none"!==r&&(n=r+" "+n)}while(!t&&(e=e.parentNode));var a=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix||window.MSCSSMatrix;return a&&new a(n)}function Mt(e,t,n){if(e){var r=e.getElementsByTagName(t),a=0,i=r.length;if(n)for(;a=i:a<=i))return r;if(r===Nt())break;r=jt(r,!1)}return!1}function Ht(e,t,n,r){for(var a=0,i=0,o=e.children;i2&&void 0!==arguments[2]?arguments[2]:{},r=n.evt,a=ft(n,en);Zt.pluginEvent.bind(Gn)(e,t,gt({dragEl:rn,parentEl:an,ghostEl:on,rootEl:sn,nextEl:ln,lastDownEl:un,cloneEl:dn,cloneHidden:cn,dragStarted:Sn,putSortable:vn,activeSortable:Gn.active,originalEvent:r,oldIndex:gn,oldDraggableIndex:hn,newIndex:pn,newDraggableIndex:mn,hideGhostForTarget:Yn,unhideGhostForTarget:Wn,cloneNowHidden:function(){cn=!0},cloneNowShown:function(){cn=!1},dispatchSortableEvent:function(e){nn({sortable:t,name:e,originalEvent:r})}},a))};function nn(e){Kt(gt({putSortable:vn,cloneEl:dn,targetEl:rn,rootEl:sn,oldIndex:gn,oldDraggableIndex:hn,newIndex:pn,newDraggableIndex:mn},e))}var rn,an,on,sn,ln,un,dn,cn,gn,pn,hn,mn,fn,vn,yn,bn,En,wn,kn,In,Sn,xn,Pn,Tn,_n,An=!1,Bn=!1,Dn=[],Ln=!1,Cn=!1,On=[],Mn=!1,Nn=[],Rn="undefined"!=typeof document,Un=kt,Hn=bt||yt?"cssFloat":"float",Fn=Rn&&!It&&!kt&&"draggable"in document.createElement("div"),qn=function(){if(Rn){if(yt)return!1;var e=document.createElement("x");return e.style.cssText="pointer-events:auto","auto"===e.style.pointerEvents}}(),Xn=function(e,t){var n=Ct(e),r=parseInt(n.width)-parseInt(n.paddingLeft)-parseInt(n.paddingRight)-parseInt(n.borderLeftWidth)-parseInt(n.borderRightWidth),a=Ht(e,0,t),i=Ht(e,1,t),o=a&&Ct(a),s=i&&Ct(i),l=o&&parseInt(o.marginLeft)+parseInt(o.marginRight)+Rt(a).width,u=s&&parseInt(s.marginLeft)+parseInt(s.marginRight)+Rt(i).width;if("flex"===n.display)return"column"===n.flexDirection||"column-reverse"===n.flexDirection?"vertical":"horizontal";if("grid"===n.display)return n.gridTemplateColumns.split(" ").length<=1?"vertical":"horizontal";if(a&&o.float&&"none"!==o.float){var d="left"===o.float?"left":"right";return!i||"both"!==s.clear&&s.clear!==d?"horizontal":"vertical"}return a&&("block"===o.display||"flex"===o.display||"table"===o.display||"grid"===o.display||l>=r&&"none"===n[Hn]||i&&"none"===n[Hn]&&l+u>r)?"vertical":"horizontal"},jn=function(e){function t(e,n){return function(r,a,i,o){var s=r.options.group.name&&a.options.group.name&&r.options.group.name===a.options.group.name;if(null==e&&(n||s))return!0;if(null==e||!1===e)return!1;if(n&&"clone"===e)return e;if("function"==typeof e)return t(e(r,a,i,o),n)(r,a,i,o);var l=(n?r:a).options.group.name;return!0===e||"string"==typeof e&&e===l||e.join&&e.indexOf(l)>-1}}var n={},r=e.group;r&&"object"==pt(r)||(r={name:r}),n.name=r.name,n.checkPull=t(r.pull,!0),n.checkPut=t(r.put),n.revertClone=r.revertClone,e.group=n},Yn=function(){!qn&&on&&Ct(on,"display","none")},Wn=function(){!qn&&on&&Ct(on,"display","")};Rn&&document.addEventListener("click",(function(e){if(Bn)return e.preventDefault(),e.stopPropagation&&e.stopPropagation(),e.stopImmediatePropagation&&e.stopImmediatePropagation(),Bn=!1,!1}),!0);var $n=function(e){if(rn){e=e.touches?e.touches[0]:e;var t=(a=e.clientX,i=e.clientY,Dn.some((function(e){var t=e[Gt].options.emptyInsertThreshold;if(t&&!Ft(e)){var n=Rt(e),r=a>=n.left-t&&a<=n.right+t,s=i>=n.top-t&&i<=n.bottom+t;return r&&s?o=e:void 0}})),o);if(t){var n={};for(var r in e)e.hasOwnProperty(r)&&(n[r]=e[r]);n.target=n.rootEl=t,n.preventDefault=void 0,n.stopPropagation=void 0,t[Gt]._onDragOver(n)}}var a,i,o},zn=function(e){rn&&rn.parentNode[Gt]._isOutsideThisEl(e.target)};function Gn(e,t){if(!e||!e.nodeType||1!==e.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(e));this.el=e,this.options=t=mt({},t),e[Gt]=this;var n={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(e.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return Xn(e,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(e,t){e.setData("Text",t.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==Gn.supportPointer&&"PointerEvent"in window&&!wt,emptyInsertThreshold:5};for(var r in Zt.initializePlugins(this,e,n),n)!(r in t)&&(t[r]=n[r]);for(var a in jn(t),this)"_"===a.charAt(0)&&"function"==typeof this[a]&&(this[a]=this[a].bind(this));this.nativeDraggable=!t.forceFallback&&Fn,this.nativeDraggable&&(this.options.touchStartThreshold=1),t.supportPointer?xt(e,"pointerdown",this._onTapStart):(xt(e,"mousedown",this._onTapStart),xt(e,"touchstart",this._onTapStart)),this.nativeDraggable&&(xt(e,"dragover",this),xt(e,"dragenter",this)),Dn.push(this.el),t.store&&t.store.get&&this.sort(t.store.get(this)||[]),mt(this,Qt())}function Qn(e,t,n,r,a,i,o,s){var l,u,d=e[Gt],c=d.options.onMove;return!window.CustomEvent||yt||bt?(l=document.createEvent("Event")).initEvent("move",!0,!0):l=new CustomEvent("move",{bubbles:!0,cancelable:!0}),l.to=t,l.from=e,l.dragged=n,l.draggedRect=r,l.related=a||t,l.relatedRect=i||Rt(t),l.willInsertAfter=s,l.originalEvent=o,e.dispatchEvent(l),c&&(u=c.call(d,l,o)),u}function Vn(e){e.draggable=!1}function Jn(){Mn=!1}function Zn(e){for(var t=e.tagName+e.className+e.src+e.href+e.textContent,n=t.length,r=0;n--;)r+=t.charCodeAt(n);return r.toString(36)}function Kn(e){return setTimeout(e,0)}function er(e){return clearTimeout(e)}Gn.prototype={constructor:Gn,_isOutsideThisEl:function(e){this.el.contains(e)||e===this.el||(xn=null)},_getDirection:function(e,t){return"function"==typeof this.options.direction?this.options.direction.call(this,e,t,rn):this.options.direction},_onTapStart:function(e){if(e.cancelable){var t=this,n=this.el,r=this.options,a=r.preventOnFilter,i=e.type,o=e.touches&&e.touches[0]||e.pointerType&&"touch"===e.pointerType&&e,s=(o||e).target,l=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||s,u=r.filter;if(function(e){Nn.length=0;var t=e.getElementsByTagName("input"),n=t.length;for(;n--;){var r=t[n];r.checked&&Nn.push(r)}}(n),!rn&&!(/mousedown|pointerdown/.test(i)&&0!==e.button||r.disabled)&&!l.isContentEditable&&(this.nativeDraggable||!wt||!s||"SELECT"!==s.tagName.toUpperCase())&&!((s=At(s,r.draggable,n,!1))&&s.animated||un===s)){if(gn=qt(s),hn=qt(s,r.draggable),"function"==typeof u){if(u.call(this,e,s,this))return nn({sortable:t,rootEl:l,name:"filter",targetEl:s,toEl:n,fromEl:n}),tn("filter",t,{evt:e}),void(a&&e.cancelable&&e.preventDefault())}else if(u&&(u=u.split(",").some((function(r){if(r=At(l,r.trim(),n,!1))return nn({sortable:t,rootEl:r,name:"filter",targetEl:s,fromEl:n,toEl:n}),tn("filter",t,{evt:e}),!0}))))return void(a&&e.cancelable&&e.preventDefault());r.handle&&!At(l,r.handle,n,!1)||this._prepareDragStart(e,o,s)}}},_prepareDragStart:function(e,t,n){var r,a=this,i=a.el,o=a.options,s=i.ownerDocument;if(n&&!rn&&n.parentNode===i){var l=Rt(n);if(sn=i,an=(rn=n).parentNode,ln=rn.nextSibling,un=n,fn=o.group,Gn.dragged=rn,yn={target:rn,clientX:(t||e).clientX,clientY:(t||e).clientY},kn=yn.clientX-l.left,In=yn.clientY-l.top,this._lastX=(t||e).clientX,this._lastY=(t||e).clientY,rn.style["will-change"]="all",r=function(){tn("delayEnded",a,{evt:e}),Gn.eventCanceled?a._onDrop():(a._disableDelayedDragEvents(),!Et&&a.nativeDraggable&&(rn.draggable=!0),a._triggerDragStart(e,t),nn({sortable:a,name:"choose",originalEvent:e}),Lt(rn,o.chosenClass,!0))},o.ignore.split(",").forEach((function(e){Mt(rn,e.trim(),Vn)})),xt(s,"dragover",$n),xt(s,"mousemove",$n),xt(s,"touchmove",$n),xt(s,"mouseup",a._onDrop),xt(s,"touchend",a._onDrop),xt(s,"touchcancel",a._onDrop),Et&&this.nativeDraggable&&(this.options.touchStartThreshold=4,rn.draggable=!0),tn("delayStart",this,{evt:e}),!o.delay||o.delayOnTouchOnly&&!t||this.nativeDraggable&&(bt||yt))r();else{if(Gn.eventCanceled)return void this._onDrop();xt(s,"mouseup",a._disableDelayedDrag),xt(s,"touchend",a._disableDelayedDrag),xt(s,"touchcancel",a._disableDelayedDrag),xt(s,"mousemove",a._delayedDragTouchMoveHandler),xt(s,"touchmove",a._delayedDragTouchMoveHandler),o.supportPointer&&xt(s,"pointermove",a._delayedDragTouchMoveHandler),a._dragStartTimer=setTimeout(r,o.delay)}}},_delayedDragTouchMoveHandler:function(e){var t=e.touches?e.touches[0]:e;Math.max(Math.abs(t.clientX-this._lastX),Math.abs(t.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){rn&&Vn(rn),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var e=this.el.ownerDocument;Pt(e,"mouseup",this._disableDelayedDrag),Pt(e,"touchend",this._disableDelayedDrag),Pt(e,"touchcancel",this._disableDelayedDrag),Pt(e,"mousemove",this._delayedDragTouchMoveHandler),Pt(e,"touchmove",this._delayedDragTouchMoveHandler),Pt(e,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(e,t){t=t||"touch"==e.pointerType&&e,!this.nativeDraggable||t?this.options.supportPointer?xt(document,"pointermove",this._onTouchMove):xt(document,t?"touchmove":"mousemove",this._onTouchMove):(xt(rn,"dragend",this),xt(sn,"dragstart",this._onDragStart));try{document.selection?Kn((function(){document.selection.empty()})):window.getSelection().removeAllRanges()}catch(e){}},_dragStarted:function(e,t){if(An=!1,sn&&rn){tn("dragStarted",this,{evt:t}),this.nativeDraggable&&xt(document,"dragover",zn);var n=this.options;!e&&Lt(rn,n.dragClass,!1),Lt(rn,n.ghostClass,!0),Gn.active=this,e&&this._appendGhost(),nn({sortable:this,name:"start",originalEvent:t})}else this._nulling()},_emulateDragOver:function(){if(bn){this._lastX=bn.clientX,this._lastY=bn.clientY,Yn();for(var e=document.elementFromPoint(bn.clientX,bn.clientY),t=e;e&&e.shadowRoot&&(e=e.shadowRoot.elementFromPoint(bn.clientX,bn.clientY))!==t;)t=e;if(rn.parentNode[Gt]._isOutsideThisEl(e),t)do{if(t[Gt]){if(t[Gt]._onDragOver({clientX:bn.clientX,clientY:bn.clientY,target:e,rootEl:t})&&!this.options.dragoverBubble)break}e=t}while(t=t.parentNode);Wn()}},_onTouchMove:function(e){if(yn){var t=this.options,n=t.fallbackTolerance,r=t.fallbackOffset,a=e.touches?e.touches[0]:e,i=on&&Ot(on,!0),o=on&&i&&i.a,s=on&&i&&i.d,l=Un&&_n&&Xt(_n),u=(a.clientX-yn.clientX+r.x)/(o||1)+(l?l[0]-On[0]:0)/(o||1),d=(a.clientY-yn.clientY+r.y)/(s||1)+(l?l[1]-On[1]:0)/(s||1);if(!Gn.active&&!An){if(n&&Math.max(Math.abs(a.clientX-this._lastX),Math.abs(a.clientY-this._lastY))r.right+a||e.clientX<=r.right&&e.clientY>r.bottom&&e.clientX>=r.left:e.clientX>r.right&&e.clientY>r.top||e.clientX<=r.right&&e.clientY>r.bottom+a}(e,a,this)&&!m.animated){if(m===rn)return D(!1);if(m&&i===e.target&&(o=m),o&&(n=Rt(o)),!1!==Qn(sn,i,rn,t,o,n,e,!!o))return B(),i.appendChild(rn),an=i,L(),D(!0)}else if(m&&function(e,t,n){var r=Rt(Ht(n.el,0,n.options,!0)),a=10;return t?e.clientXd+u*i/2:lc-Tn)return-Pn}else if(l>d+u*(1-a)/2&&lc-u*i/2))return l>d+u/2?1:-1;return 0}(e,o,n,a,w?1:s.swapThreshold,null==s.invertedSwapThreshold?s.swapThreshold:s.invertedSwapThreshold,Cn,xn===o),0!==v){var x=qt(rn);do{x-=v,b=an.children[x]}while(b&&("none"===Ct(b,"display")||b===on))}if(0===v||b===o)return D(!1);xn=o,Pn=v;var P=o.nextElementSibling,T=!1,_=Qn(sn,i,rn,t,o,n,e,T=1===v);if(!1!==_)return 1!==_&&-1!==_||(T=1===_),Mn=!0,setTimeout(Jn,30),B(),T&&!P?i.appendChild(rn):o.parentNode.insertBefore(rn,T?P:o),I&&$t(I,0,S-I.scrollTop),an=rn.parentNode,void 0===y||Cn||(Tn=Math.abs(y-Rt(o)[k])),L(),D(!0)}if(i.contains(rn))return D(!1)}return!1}function A(s,l){tn(s,p,gt({evt:e,isOwner:d,axis:a?"vertical":"horizontal",revert:r,dragRect:t,targetRect:n,canSort:c,fromSortable:g,target:o,completed:D,onMove:function(n,r){return Qn(sn,i,rn,t,n,Rt(n),e,r)},changed:L},l))}function B(){A("dragOverAnimationCapture"),p.captureAnimationState(),p!==g&&g.captureAnimationState()}function D(t){return A("dragOverCompleted",{insertion:t}),t&&(d?u._hideClone():u._showClone(p),p!==g&&(Lt(rn,vn?vn.options.ghostClass:u.options.ghostClass,!1),Lt(rn,s.ghostClass,!0)),vn!==p&&p!==Gn.active?vn=p:p===Gn.active&&vn&&(vn=null),g===p&&(p._ignoreWhileAnimating=o),p.animateAll((function(){A("dragOverAnimationComplete"),p._ignoreWhileAnimating=null})),p!==g&&(g.animateAll(),g._ignoreWhileAnimating=null)),(o===rn&&!rn.animated||o===i&&!o.animated)&&(xn=null),s.dragoverBubble||e.rootEl||o===document||(rn.parentNode[Gt]._isOutsideThisEl(e.target),!t&&$n(e)),!s.dragoverBubble&&e.stopPropagation&&e.stopPropagation(),h=!0}function L(){pn=qt(rn),mn=qt(rn,s.draggable),nn({sortable:p,name:"change",toEl:i,newIndex:pn,newDraggableIndex:mn,originalEvent:e})}},_ignoreWhileAnimating:null,_offMoveEvents:function(){Pt(document,"mousemove",this._onTouchMove),Pt(document,"touchmove",this._onTouchMove),Pt(document,"pointermove",this._onTouchMove),Pt(document,"dragover",$n),Pt(document,"mousemove",$n),Pt(document,"touchmove",$n)},_offUpEvents:function(){var e=this.el.ownerDocument;Pt(e,"mouseup",this._onDrop),Pt(e,"touchend",this._onDrop),Pt(e,"pointerup",this._onDrop),Pt(e,"touchcancel",this._onDrop),Pt(document,"selectstart",this)},_onDrop:function(e){var t=this.el,n=this.options;pn=qt(rn),mn=qt(rn,n.draggable),tn("drop",this,{evt:e}),an=rn&&rn.parentNode,pn=qt(rn),mn=qt(rn,n.draggable),Gn.eventCanceled||(An=!1,Cn=!1,Ln=!1,clearInterval(this._loopId),clearTimeout(this._dragStartTimer),er(this.cloneId),er(this._dragStartId),this.nativeDraggable&&(Pt(document,"drop",this),Pt(t,"dragstart",this._onDragStart)),this._offMoveEvents(),this._offUpEvents(),wt&&Ct(document.body,"user-select",""),Ct(rn,"transform",""),e&&(Sn&&(e.cancelable&&e.preventDefault(),!n.dropBubble&&e.stopPropagation()),on&&on.parentNode&&on.parentNode.removeChild(on),(sn===an||vn&&"clone"!==vn.lastPutMode)&&dn&&dn.parentNode&&dn.parentNode.removeChild(dn),rn&&(this.nativeDraggable&&Pt(rn,"dragend",this),Vn(rn),rn.style["will-change"]="",Sn&&!An&&Lt(rn,vn?vn.options.ghostClass:this.options.ghostClass,!1),Lt(rn,this.options.chosenClass,!1),nn({sortable:this,name:"unchoose",toEl:an,newIndex:null,newDraggableIndex:null,originalEvent:e}),sn!==an?(pn>=0&&(nn({rootEl:an,name:"add",toEl:an,fromEl:sn,originalEvent:e}),nn({sortable:this,name:"remove",toEl:an,originalEvent:e}),nn({rootEl:an,name:"sort",toEl:an,fromEl:sn,originalEvent:e}),nn({sortable:this,name:"sort",toEl:an,originalEvent:e})),vn&&vn.save()):pn!==gn&&pn>=0&&(nn({sortable:this,name:"update",toEl:an,originalEvent:e}),nn({sortable:this,name:"sort",toEl:an,originalEvent:e})),Gn.active&&(null!=pn&&-1!==pn||(pn=gn,mn=hn),nn({sortable:this,name:"end",toEl:an,originalEvent:e}),this.save())))),this._nulling()},_nulling:function(){tn("nulling",this),sn=rn=an=on=ln=dn=un=cn=yn=bn=Sn=pn=mn=gn=hn=xn=Pn=vn=fn=Gn.dragged=Gn.ghost=Gn.clone=Gn.active=null,Nn.forEach((function(e){e.checked=!0})),Nn.length=En=wn=0},handleEvent:function(e){switch(e.type){case"drop":case"dragend":this._onDrop(e);break;case"dragenter":case"dragover":rn&&(this._onDragOver(e),function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="move");e.cancelable&&e.preventDefault()}(e));break;case"selectstart":e.preventDefault()}},toArray:function(){for(var e,t=[],n=this.el.children,r=0,a=n.length,i=this.options;r{(new dt).syncMenu().then((t=>{fr.alert("Updating Menu",null),e.admin.sync("syncNav",t).then((e=>{e.type,fr.alert(e.message,!0)}))}))}});for(var t=document.querySelectorAll(".nav-btn"),n=0,r=t.length;nthis.handleNavButton(e)),!1)}handleNavButton(e){if(this.processing)return;let t="",n=this;switch(e.target.id){case"remove-item":t=e.target.getAttribute("data-id"),(new dt).removeItem(t),(new dt).syncMenu().then((t=>{t.remove=e.target.getAttribute("data-uuid"),fr.alert("Editing Menu",null),n.processing=!0,n.admin.syncNav(t).then((e=>{n.processing=!1,e.type,fr.alert(e.message,!0)}))}));break;case"edit-item":n.processing=!1,window.location="/dashboard/page/edit/"+e.target.getAttribute("data-id")}}}class yr{constructor(){this.currentDisplay="",this.urlPieces=document.URL.split("/"),this.chooseDisplay(this.urlPieces[4],this.urlPieces[5])}start(){}chooseDisplay(e,t){switch(this.currentDisplay="",e){case"page":this.currentDisplay=new at(t);break;case"settings":this.currentDisplay=new ut;break;case"navigation":this.currentDisplay=new vr}this.start()}}const br=new class{constructor(){}imgLoad(e){return new Promise((function(t,n){var r=new XMLHttpRequest;r.open("GET",e),r.responseType="blob",r.onload=function(){200===r.status?t(r.response):n(new Error("Image didn't load successfully; error code:"+r.statusText))},r.onerror=function(){n(new Error("There was a network error."))},r.send()}))}loadImage(e){let t=this;return new Promise((function(n,r){(new Image).crossOrigin="",t.imgLoad(e).then((function(e){var t=window.URL.createObjectURL(e);n(t)}),(function(e){r(e)}))}))}formDataToJSON(e){let t={};return new FormData(e).forEach(((e,n)=>{t.hasOwnProperty(n)?(Array.isArray(t[n])||(t[n]=[t[n]]),t[n].push(e)):t[n]=e})),t}},Er=new tt;class wr{constructor(){this.processing=!1,this.start()}start(){if(document.getElementById("dash-form")||document.getElementById("dash-init")){var e=document.getElementsByClassName("init-option");for(let t=0;tthis.handleOptions(e)));document.getElementById("dash-form")?document.getElementById("login-btn").addEventListener("click",(e=>this.handleLogin(e))):(document.getElementById("init-blog").addEventListener("click",(e=>this.handleSetup(e))),document.getElementById("blog-restore").addEventListener("click",(e=>this.handleRestore(e))))}else document.getElementById("dash-reset")?(document.getElementById("get-secret-btn").addEventListener("click",(e=>this.handleReset(e))),document.getElementById("reset-btn").addEventListener("click",(e=>this.handleReset(e)))):new yr}handleLogin(e){if(this.processing)return;let t=this;e.stopPropagation(),e.preventDefault();let n=br.formDataToJSON(document.getElementById("login"));Er.alert("Looking, hold up",null);let r=new f;this.processing=!0,r.login(n).then((n=>{t.processing=!1,n.type===I?Er.alert(n.message,!1):(Er.alert(n.message,!0),e.target.innerHTML=n.message,setTimeout((()=>{window.location="/dashboard"}),500))})).catch((e=>{t.processing=!1,Er.alert(e,!1)}))}handleSetup(e){if(this.processing)return;let t=this;e.stopPropagation(),e.preventDefault();let n=br.formDataToJSON(document.getElementById("init-form")),r=new k;this.processing=!0,r.create(n).then((e=>{"blogInitLame"===e.type?(t.processing=!1,Er.alert(e.message,!1)):(t.processing=!1,Er.alert(e.message,!0),setTimeout((()=>{window.location="/dashboard"}),700))})).catch((e=>{t.processing=!1,Er.alert(e,!1)}))}handleRestore(e){if(this.processing)return;let t=this;e.stopPropagation(),e.preventDefault();let n=new k;var r=document.getElementById("init-restore");this.processing=!0,n.restore(r).then((e=>{e.type===I?(t.processing=!1,Er.alert(e.message,!1)):(t.processing=!1,Er.alert(e.message,!0),setTimeout((()=>{window.location="/dashboard"}),1500))})).catch((e=>{t.processing=!1,Er.alert(e,!1)}))}handleReset(e){e.stopPropagation(),e.preventDefault();let t=this,n=new k;if("get-secret-btn"==e.target.id){let e={email:document.getElementById("email").value,task:"retrieveSecret"};this.processing=!0,n.secret(e).then((e=>{t.processing=!1,e.secret?(document.getElementById("secret").value=e.secret,Er.alert(e.message,!0)):"mailSent"==e.type?Er.alert(e.message,!0):Er.alert(e.message,!1)})).catch((e=>{t.processing=!1,Er.alert(e,!1)}))}else{let e={newPass:document.getElementById("new_password").value,newPassConfirm:document.getElementById("new_password2").value,secret:document.getElementById("secret").value};n.newPass(e).then((e=>{t.processing=!1,"passNotCreated"==e.type?Er.alert(e.message,!1):(Er.alert(e.message,!0),setTimeout((()=>{window.location="/dashboard"}),1e3))})).catch((e=>{t.processing=!1,Er.alert(e,!1)}))}}handleOptions(e){e.stopPropagation(),e.preventDefault();let t=document.getElementById("dash-init"),n=document.getElementById("dash-restore");"init-switch-restore"===e.target.id?(t.style.display="none",t.style.visibility="hidden",n.style.display="flex",n.style.visibility="visible"):(t.style.display="flex",t.style.visibility="visible",n.style.display="none",n.style.visibility="hidden")}}document.addEventListener("DOMContentLoaded",(function(){new wr}),!1)})(); +(()=>{class t{constructor(){this.start()}start(){console.log("Connected like F.E.")}}document.addEventListener("DOMContentLoaded",(function(){new t}),!1)})(); //# sourceMappingURL=Start.js.map diff --git a/public/assets/scripts/dash.min.js b/public/assets/scripts/dash.min.js deleted file mode 100644 index a28ae4d..0000000 --- a/public/assets/scripts/dash.min.js +++ /dev/null @@ -1,11 +0,0 @@ -!function(){"use strict";function e(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function t(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:null;e(this,t),this.percentComplete=0,this.baseURL=null,this.status=!1,r&&(this.baseURL=r),this._request(this.baseURL?this.baseURL+c:c).then((function(e){e.type===I&&(n.token=e.token)}))}return n(t,[{key:"login",value:function(e){var t=this;return new Promise((function(n,r){t.baseURL?e.remote=!0:e.remote=!1,t.key?e.key=t.key:e.key=null,t._request(t.baseURL?t.baseURL+p:p,"getAuthStatus",s,l,e).then((function(e){n(e)})).catch((function(e){r(e)}))}))}},{key:"sync",value:function(e,t){var n=this;return new Promise((function(r,o){var i="";switch(e){case"syncSite":i="/api/v1/settings/sync";break;case"syncNav":i="/api/v1/settings/nav-sync"}n._request(n.baseURL?n.baseURL+i:i,h,s,l,t).then((function(e){r(e)})).catch((function(e){o(e)}))}))}},{key:"publish",value:function(e){var t=this;return new Promise((function(n,r){t._request(t.baseURL?t.baseURL+d:d,g,s,l,e).then((function(e){n(e)})).catch((function(e){r(e)}))}))}},{key:"pageActions",value:function(e,t){var n,r,o,i=this;switch(e){case m:n="/api/v1/page/create",r=m,o=u;break;case v:n="/api/v1/page/write",r=v,o=u;break;case y:n="/api/v1/page/delete",r=y,o=l}return this.baseURL?t.remote=!0:t.remote=!1,new Promise((function(e,a){i._request(i.baseURL?i.baseURL+n:n,r,s,o,t).then((function(t){e(t)})).catch((function(e){a(e)}))}))}},{key:"sendMail",value:function(e){var t=this;return new Promise((function(n,r){t._request(t.baseURL?t.baseURL+f:f,"sendMail",s,l,e).then((function(e){n(e)})).catch((function(e){r(e)}))}))}},{key:"getInfo",value:function(e){var t,n,r=this;return"site"==e?(t="/api/v1/settings/site",n=w):(t="/api/v1/settings/member",n=E),new Promise((function(e,o){r._request(r.baseURL?r.baseURL+t:t,n).then((function(t){e(t)})).catch((function(e){o(e)}))}))}},{key:"_request",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"GET",r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:l,o=arguments.length>4&&void 0!==arguments[4]?arguments[4]:null,i=this;return new Promise((function(a,c){var d=new XMLHttpRequest;if(d.upload.onprogress=i.handleLoadProgress,d.open(n,e,!0),d.onload=function(){if(200==d.status){var e=JSON.parse(d.response);a(e)}else{var t=JSON.parse(d.response);c(t)}},"PUT"==n||n==s)switch(t!==h&&t!==v&&t!==m&&t!==y&&t!==g&&t!==b||d.setRequestHeader("fipamo-access-token",i.token),r){case l:d.setRequestHeader("Content-type","application/"+r),d.send(JSON.stringify(o));break;case u:d.send(o)}else t!==w&&t!==E||d.setRequestHeader("fipamo-access-token",i.token),d.send()}))}},{key:"handleLoadProgress",value:function(e){this.percentComplete=Math.ceil(e.loaded/e.total*100)}}]),t}(),S="POST",T="json",D="x-www-form-urlencoded",P="/api/v1/status",B="uploadFiles",x="apiUseAuthorized",_=function(){function t(){var n=this,r=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;e(this,t),this.percentComplete=0,this.token=null,this.baseURL=null,this.key=null,o&&(this.key=o),r&&(this.baseURL=r),this._request(this.baseURL?this.baseURL+P+"?key="+this.key:P+"?key="+this.key).then((function(e){e.type===x&&(n.token=e.token)}))}return n(t,[{key:"create",value:function(e){var t=this;return new Promise((function(n,r){t._request("/api/v1/init","blogInit",S,T,e).then((function(e){n(e)})).catch((function(e){r(e)}))}))}},{key:"restore",value:function(e){var t=this;return new Promise((function(n,r){var o;o=new FormData(e),t._request("/api/v1/restore","restoreBackup","POST","x-www-form-urlencoded",o).then((function(e){n(e)})).catch((function(e){r(e)}))}))}},{key:"backup",value:function(){var e=this;return new Promise((function(t,n){var r;r={task:"create_backup"},e._request("/api/v1/backup","createBackup","POST","json",r).then((function(e){t(e)})).catch((function(e){n(e)}))}))}},{key:"secret",value:function(e){var t=this;return new Promise((function(n,r){t._request("/api/v1/get-secret","retrieveSecret",S,T,e).then((function(e){n(e)})).catch((function(e){r(e)}))}))}},{key:"newPass",value:function(e){var t=this;return new Promise((function(n,r){t._request("/api/v1/reset-password","resetPassword",S,T,e).then((function(e){n(e)})).catch((function(e){r(e)}))}))}},{key:"imageUpload",value:function(e,t){var n=this;return new Promise((function(r,o){var i="";switch(e){case"avatar-upload":i="/api/v1/settings/add-avatar";break;case"background-upload":i="/api/v1/settings/add-feature-background";break;default:i="/api/v1/page/add-entry-image"}var a=new FormData;n.baseURL?(a.append("key",n.key),a.append("remote",!0)):a.append("remote",!1);for(var s=0;s2&&void 0!==arguments[2]?arguments[2]:"GET",r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:T,o=arguments.length>4&&void 0!==arguments[4]?arguments[4]:null,i=this;return new Promise((function(a,s){var l=new XMLHttpRequest;if(l.upload.onprogress=i.handleLoadProgress,l.open(n,e,!0),l.onload=function(){if(200==l.status){var e=JSON.parse(l.response);a(e)}else{var t=JSON.parse(l.response);s(t)}},"PUT"==n||n==S)switch(t===B&&l.setRequestHeader("fipamo-access-token",i.token),r){case T:l.setRequestHeader("Content-type","application/"+r),l.send(JSON.stringify(o));break;case D:l.send(o)}else l.send()}))}},{key:"handleLoadProgress",value:function(e){this.percentComplete=Math.ceil(e.loaded/e.total*100)}}]),t}(),A=function(){function t(){e(this,t)}return n(t,[{key:"imgLoad",value:function(e){return new Promise((function(t,n){var r=new XMLHttpRequest;r.open("GET",e),r.responseType="blob",r.onload=function(){200===r.status?t(r.response):n(new Error("Image didn't load successfully; error code:"+r.statusText))},r.onerror=function(){n(new Error("There was a network error."))},r.send()}))}},{key:"loadImage",value:function(e){var t=this;return new Promise((function(n,r){(new Image).crossOrigin="",t.imgLoad(e).then((function(e){var t=window.URL.createObjectURL(e);n(t)}),(function(e){r(e)}))}))}},{key:"formDataToJSON",value:function(e){var t={};return new FormData(e).forEach((function(e,n){t.hasOwnProperty(n)?(Array.isArray(t[n])||(t[n]=[t[n]]),t[n].push(e)):t[n]=e})),t}}]),t}(),O="requestLame",L="postUpdated";new function t(){e(this,t)};var C=function(){function t(){e(this,t)}return n(t,[{key:"cleanString",value:function(e){return e.replace(/(^\-+|[^a-zA-Z0-9\/_| -]+|\-+$)/g,"").toLowerCase().replace(/[\/_| -]+/g,"-")}},{key:"decodeHTML",value:function(e,t){var n=0,r=0,o=!1;void 0===t&&(t=2),e=e.toString().replace(/</g,"<").replace(/>/g,">");var i={ENT_NOQUOTES:0,ENT_HTML_QUOTE_SINGLE:1,ENT_HTML_QUOTE_DOUBLE:2,ENT_COMPAT:2,ENT_QUOTES:3,ENT_IGNORE:4};if(0===t&&(o=!0),"number"!=typeof t){for(t=[].concat(t),r=0;r]*>/g,"\n"),r.append("id",document.getElementById("post-edit-index").getAttribute("data-index")),r.append("uuid",document.getElementById("post-edit-index").getAttribute("data-uuid")),r.append("layout",document.getElementById("post-edit-index").getAttribute("data-layout")),r.append("current_title",document.getElementById("post-edit-index").getAttribute("data-slug")),r.append("content",i),r.append("title",document.getElementById("post_title").value),r.append("created",document.getElementById("post-date").getAttribute("data-raw")),r.append("slug",(new C).cleanString(document.getElementById("post_title").value)),r.append("tags",document.getElementById("post_tags").value),r.append("menu",document.getElementById("option-menu-pin").getAttribute("data-active")),r.append("featured",document.getElementById("option-feature").getAttribute("data-active")),r.append("published",document.getElementById("option-published").getAttribute("data-active")),r.append("layout",document.getElementById("page-templates").value),r.append("form_token",document.getElementById("form_token").value),null!=e||null!=e)e.type.match("image.*")?r.append("feature_image",e,e.name):n("Not an image file");else if(document.getElementById("featured-image")){var a=document.getElementById("featured-image").src;null!=a||null!=a?r.append("feature_image",a):r.append("feature_image",null)}t(r)}))}}]),t}(),N="editorDelete",R="editorUploadImage",U="editorSave",H="editorUpdate";new function t(){e(this,t)};var X=["borderBottomWidth","borderLeftWidth","borderRightWidth","borderTopStyle","borderRightStyle","borderBottomStyle","borderLeftStyle","borderTopWidth","boxSizing","fontFamily","fontSize","fontWeight","height","letterSpacing","lineHeight","marginBottom","marginLeft","marginRight","marginTop","outlineWidth","overflow","overflowX","overflowY","paddingBottom","paddingLeft","paddingRight","paddingTop","textAlign","textOverflow","textTransform","whiteSpace","wordBreak","wordWrap"],F=function(e,t){var n=document.createElement("div");return function(t){var r=function(){var t={position:"absolute",left:-9999,top:0,zIndex:-2e3};return"TEXTAREA"===e.tagName&&X.push("width"),X.forEach((function(n){t[n]=getComputedStyle(e)[n]})),t}();Object.keys(r).forEach((function(e){n.style[e]=r[e]})),n.innerHTML=t,e.parentNode.insertBefore(n,e.nextSibling)}(t),{rect:function(){var e=n.ownerDocument.getElementById("caret-position-marker"),t={left:e.offsetLeft,top:e.offsetTop,height:e.offsetHeight};return n.parentNode.removeChild(n),t}}};function Y(e){return Y="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Y(e)}var q=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.customPos,n=e.iframe,r=e.noShadowCaret;return n?{iframe:n,window:n.contentWindow,document:n.contentDocument||n.contentWindow.document,noShadowCaret:r,customPos:t}:{window:window,document:document,noShadowCaret:r,customPos:t}},j=function(e){return"object"===Y(e)&&null!==e},W=function(e,t){var n=function(){return e.selectionStart},r=function(r){var o=function(e){return e.replace(/<|>|`|"|&/g,"?").replace(/\r\n|\r|\n/g,"
")};(t.customPos||0===t.customPos)&&(r=t.customPos);var i=void 0===r?n():r,a=e.value.slice(0,i),s=e.value.slice(i),l=''.concat(o(a),"");l+='|',l+=''.concat(o(s),"");var u=F(e,l).rect();return u.pos=n(),u};return{getPos:n,setPos:function(t){return e.setSelectionRange(t,t),e},getOffset:function(n){var o=function(e,t){var n=t&&t.window||window,r=t&&t.document||document,o=e.getBoundingClientRect(),i=r.documentElement,a=n.pageXOffset||i.scrollLeft,s=n.pageYOffset||i.scrollTop;return{top:o.top+s,left:o.left+a}}(e),i=r(n);return{top:o.top+i.top+t.document.body.scrollTop,left:o.left+i.left+t.document.body.scrollLeft,height:i.height}},getPosition:r}},z=function(e,t){return function(e){return!!(e.contentEditable?"true"===e.contentEditable:"true"===e.getAttribute("contenteditable"))}(e)?function(e,t){var n=function(){var n=r(),o={height:0,left:0,right:0};if(!n)return o;var i=t.customPos||0===t.customPos;if(n.endOffset-1>0&&n.endContainer!==e||i){var a=n.cloneRange(),s=i?t.customPos:n.endOffset;a.setStart(n.endContainer,s-1<0?0:s-1),a.setEnd(n.endContainer,s);var l=a.getBoundingClientRect();o={height:l.height,left:l.left+l.width,top:l.top},a.detach()}if((!o||o&&0===o.height)&&!t.noShadowCaret){var u=n.cloneRange(),c=t.document.createTextNode("|");u.insertNode(c),u.selectNode(c);var d=u.getBoundingClientRect();o={height:d.height,left:d.left,top:d.top},c.parentNode.removeChild(c),u.detach()}if(o){var f=t.document.documentElement;o.top+=t.window.pageYOffset-(f.clientTop||0),o.left+=t.window.pageXOffset-(f.clientLeft||0)}return o},r=function(){if(t.window.getSelection){var e=t.window.getSelection();return e.rangeCount>0?e.getRangeAt(0):null}},o=function(){var t=r(),n=t.cloneRange();n.selectNodeContents(e),n.setEnd(t.endContainer,t.endOffset);var o=n.toString().length;return n.detach(),o};return{getPos:o,setPos:function(n){var r=t.window.getSelection();if(r){var o=0,i=!1;!function e(a,s){for(var l=0;l=a){i=!0;var c=t.document.createRange();c.setStart(u,a-o),r.removeAllRanges(),r.addRange(c);break}o+=u.length}else e(n,u)}}(n,e)}return e},getPosition:function(){var r=n(),i=o(),a=e.getBoundingClientRect(),s=a.top+t.document.body.scrollTop,l=a.left+t.document.body.scrollLeft;return r.left-=l,r.top-=s,r.pos=i,r},getOffset:n,getRange:r}}(e,t):W(e,t)},G=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=n;j(t)&&(r=t,t=null);var o=q(r),i=z(e,o);return t||0===t?i.setPos(t):i.getPosition()},Q=function(){function t(){e(this,t),this.listeners=new Map}return n(t,[{key:"addListener",value:function(e,t){this.listeners.has(e)||this.listeners.set(e,[]),this.listeners.get(e).push(t)}},{key:"removeListener",value:function(e,t){var n,r=this.listeners.get(e);return!!(r&&r.length&&(n=r.reduce((function(e,n,r){return"function"==typeof n&&n===t?e=r:e}),-1))>-1)&&(r.splice(n,1),this.listeners.set(e,r),!0)}},{key:"emitEvent",value:function(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r/g)>-1){var r=G(e.textEditor).pos;G(e.textEditor,r)}}))}},{key:"refresh",value:function(){var e=this.textEditor.innerText;e=e.replace(new RegExp("\r?\n","g"),"
");var t=document.createElement("div");t.innerText=e,this.textEditor.innerHTML=t.innerText,this.textEditor.style.maxWidth="900px"}},{key:"notify",value:function(e,t){switch(e){case L:document.getElementById("submit-update").classList.add("icon-hide"),document.getElementById("submit-good").classList.remove("icon-hide"),document.getElementById("edit-update").classList.remove("submit-start"),document.getElementById("edit-update").classList.add("submit-cool"),setTimeout((function(){document.getElementById("submit-update").classList.remove("icon-hide"),document.getElementById("submit-good").classList.add("icon-hide"),document.getElementById("edit-update").classList.add("submit-start"),document.getElementById("edit-update").classList.remove("submit-cool")}),2e3);break;case"postAdded":break;case R:var n,r;G(this.textEditor,this.caretPos),(n=window.getSelection()).rangeCount&&((r=n.getRangeAt(0)).deleteContents(),r.insertNode(document.createTextNode("![image alt text]("+t+" 'image title')"))),this.refresh()}}},{key:"handleEditorOption",value:function(e){var t,n,r;if(e.preventDefault(),(t=window.getSelection()).rangeCount)switch(n=t.getRangeAt(0),r=t.getRangeAt(0).toString(),n.deleteContents(),e.target.id){case"edit-bold":n.insertNode(document.createTextNode("**"+r+"**"));break;case"edit-italic":n.insertNode(document.createTextNode("*"+r+"*"));break;case"edit-strikethrough":n.insertNode(document.createTextNode(""+r+""));break;case"edit-header1":n.insertNode(document.createTextNode("# "+r+"\n"));break;case"edit-header2":n.insertNode(document.createTextNode("## "+r+"\n"));break;case"edit-header3":n.insertNode(document.createTextNode("### "+r+"\n"));break;case"edit-image":this.caretPos=G(this.textEditor).pos,this.emitEvent(R);break;case"submit-save":case"edit-save":this.emitEvent(U);break;case"submit-update":case"edit-update":this.emitEvent(H);break;case"edit-link":n.insertNode(document.createTextNode("["+r+"](PASTE URL HERE)"));break;case"edit-delete":this.emitEvent(N)}}}]),i}(Q),J={update:null,begin:null,loopBegin:null,changeBegin:null,change:null,changeComplete:null,loopComplete:null,complete:null,loop:1,direction:"normal",autoplay:!0,timelineOffset:0},Z={duration:1e3,delay:0,endDelay:0,easing:"easeOutElastic(1, .5)",round:0},K=["translateX","translateY","translateZ","rotate","rotateX","rotateY","rotateZ","scale","scaleX","scaleY","scaleZ","skew","skewX","skewY","perspective","matrix","matrix3d"],ee={CSS:{},springs:{}};function te(e,t,n){return Math.min(Math.max(e,t),n)}function ne(e,t){return e.indexOf(t)>-1}function re(e,t){return e.apply(null,t)}var oe={arr:function(e){return Array.isArray(e)},obj:function(e){return ne(Object.prototype.toString.call(e),"Object")},pth:function(e){return oe.obj(e)&&e.hasOwnProperty("totalLength")},svg:function(e){return e instanceof SVGElement},inp:function(e){return e instanceof HTMLInputElement},dom:function(e){return e.nodeType||oe.svg(e)},str:function(e){return"string"==typeof e},fnc:function(e){return"function"==typeof e},und:function(e){return void 0===e},nil:function(e){return oe.und(e)||null===e},hex:function(e){return/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(e)},rgb:function(e){return/^rgb/.test(e)},hsl:function(e){return/^hsl/.test(e)},col:function(e){return oe.hex(e)||oe.rgb(e)||oe.hsl(e)},key:function(e){return!J.hasOwnProperty(e)&&!Z.hasOwnProperty(e)&&"targets"!==e&&"keyframes"!==e}};function ie(e){var t=/\(([^)]+)\)/.exec(e);return t?t[1].split(",").map((function(e){return parseFloat(e)})):[]}function ae(e,t){var n=ie(e),r=te(oe.und(n[0])?1:n[0],.1,100),o=te(oe.und(n[1])?100:n[1],.1,100),i=te(oe.und(n[2])?10:n[2],.1,100),a=te(oe.und(n[3])?0:n[3],.1,100),s=Math.sqrt(o/r),l=i/(2*Math.sqrt(o*r)),u=l<1?s*Math.sqrt(1-l*l):0,c=l<1?(l*s-a)/u:-a+s;function d(e){var n=t?t*e/1e3:e;return n=l<1?Math.exp(-n*l*s)*(1*Math.cos(u*n)+c*Math.sin(u*n)):(1+c*n)*Math.exp(-n*s),0===e||1===e?e:1-n}return t?d:function(){var t=ee.springs[e];if(t)return t;for(var n=1/6,r=0,o=0;;)if(1===d(r+=n)){if(++o>=16)break}else o=0;var i=r*n*1e3;return ee.springs[e]=i,i}}function se(e){return void 0===e&&(e=10),function(t){return Math.ceil(te(t,1e-6,1)*e)*(1/e)}}var le,ue,ce=function(){var e=.1;function t(e,t){return 1-3*t+3*e}function n(e,t){return 3*t-6*e}function r(e){return 3*e}function o(e,o,i){return((t(o,i)*e+n(o,i))*e+r(o))*e}function i(e,o,i){return 3*t(o,i)*e*e+2*n(o,i)*e+r(o)}return function(t,n,r,a){if(0<=t&&t<=1&&0<=r&&r<=1){var s=new Float32Array(11);if(t!==n||r!==a)for(var l=0;l<11;++l)s[l]=o(l*e,t,r);return function(e){return t===n&&r===a||0===e||1===e?e:o(u(e),n,a)}}function u(n){for(var a=0,l=1;10!==l&&s[l]<=n;++l)a+=e;--l;var u=a+(n-s[l])/(s[l+1]-s[l])*e,c=i(u,t,r);return c>=.001?function(e,t,n,r){for(var a=0;a<4;++a){var s=i(t,n,r);if(0===s)return t;t-=(o(t,n,r)-e)/s}return t}(n,u,t,r):0===c?u:function(e,t,n,r,i){var a,s,l=0;do{(a=o(s=t+(n-t)/2,r,i)-e)>0?n=s:t=s}while(Math.abs(a)>1e-7&&++l<10);return s}(n,a,a+e,t,r)}}}(),de=(le={linear:function(){return function(e){return e}}},ue={Sine:function(){return function(e){return 1-Math.cos(e*Math.PI/2)}},Circ:function(){return function(e){return 1-Math.sqrt(1-e*e)}},Back:function(){return function(e){return e*e*(3*e-2)}},Bounce:function(){return function(e){for(var t,n=4;e<((t=Math.pow(2,--n))-1)/11;);return 1/Math.pow(4,3-n)-7.5625*Math.pow((3*t-2)/22-e,2)}},Elastic:function(e,t){void 0===e&&(e=1),void 0===t&&(t=.5);var n=te(e,1,10),r=te(t,.1,2);return function(e){return 0===e||1===e?e:-n*Math.pow(2,10*(e-1))*Math.sin((e-1-r/(2*Math.PI)*Math.asin(1/n))*(2*Math.PI)/r)}}},["Quad","Cubic","Quart","Quint","Expo"].forEach((function(e,t){ue[e]=function(){return function(e){return Math.pow(e,t+2)}}})),Object.keys(ue).forEach((function(e){var t=ue[e];le["easeIn"+e]=t,le["easeOut"+e]=function(e,n){return function(r){return 1-t(e,n)(1-r)}},le["easeInOut"+e]=function(e,n){return function(r){return r<.5?t(e,n)(2*r)/2:1-t(e,n)(-2*r+2)/2}},le["easeOutIn"+e]=function(e,n){return function(r){return r<.5?(1-t(e,n)(1-2*r))/2:(t(e,n)(2*r-1)+1)/2}}})),le);function fe(e,t){if(oe.fnc(e))return e;var n=e.split("(")[0],r=de[n],o=ie(e);switch(n){case"spring":return ae(e,t);case"cubicBezier":return re(ce,o);case"steps":return re(se,o);default:return re(r,o)}}function pe(e){try{return document.querySelectorAll(e)}catch(e){return}}function he(e,t){for(var n=e.length,r=arguments.length>=2?t:void 0,o=[],i=0;i1&&(n-=1),n<1/6?e+6*(t-e)*n:n<.5?t:n<2/3?e+(t-e)*(2/3-n)*6:e}if(0==a)t=n=r=s;else{var c=s<.5?s*(1+a):s+a-s*a,d=2*s-c;t=u(d,c,i+1/3),n=u(d,c,i),r=u(d,c,i-1/3)}return"rgba("+255*t+","+255*n+","+255*r+","+l+")"}(e):void 0;var t,n}function Ie(e){var t=/[+-]?\d*\.?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?(%|px|pt|em|rem|in|cm|mm|ex|ch|pc|vw|vh|vmin|vmax|deg|rad|turn)?$/.exec(e);if(t)return t[1]}function ke(e,t){return oe.fnc(e)?e(t.target,t.id,t.total):e}function Se(e,t){return e.getAttribute(t)}function Te(e,t,n){if(ve([n,"deg","rad","turn"],Ie(t)))return t;var r=ee.CSS[t+n];if(!oe.und(r))return r;var o=document.createElement(e.tagName),i=e.parentNode&&e.parentNode!==document?e.parentNode:document.body;i.appendChild(o),o.style.position="absolute",o.style.width=100+n;var a=100/o.offsetWidth;i.removeChild(o);var s=a*parseFloat(t);return ee.CSS[t+n]=s,s}function De(e,t,n){if(t in e.style){var r=t.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase(),o=e.style[t]||getComputedStyle(e).getPropertyValue(r)||"0";return n?Te(e,o,n):o}}function Pe(e,t){return oe.dom(e)&&!oe.inp(e)&&(!oe.nil(Se(e,t))||oe.svg(e)&&e[t])?"attribute":oe.dom(e)&&ve(K,t)?"transform":oe.dom(e)&&"transform"!==t&&De(e,t)?"css":null!=e[t]?"object":void 0}function Be(e){if(oe.dom(e)){for(var t,n=e.style.transform||"",r=/(\w+)\(([^)]*)\)/g,o=new Map;t=r.exec(n);)o.set(t[1],t[2]);return o}}function xe(e,t,n,r){var o=ne(t,"scale")?1:0+function(e){return ne(e,"translate")||"perspective"===e?"px":ne(e,"rotate")||ne(e,"skew")?"deg":void 0}(t),i=Be(e).get(t)||o;return n&&(n.transforms.list.set(t,i),n.transforms.last=t),r?Te(e,i,r):i}function _e(e,t,n,r){switch(Pe(e,t)){case"transform":return xe(e,t,r,n);case"css":return De(e,t,n);case"attribute":return Se(e,t);default:return e[t]||0}}function Ae(e,t){var n=/^(\*=|\+=|-=)/.exec(e);if(!n)return e;var r=Ie(e)||0,o=parseFloat(t),i=parseFloat(e.replace(n[0],""));switch(n[0][0]){case"+":return o+i+r;case"-":return o-i+r;case"*":return o*i+r}}function Oe(e,t){if(oe.col(e))return Ee(e);if(/\s/g.test(e))return e;var n=Ie(e),r=n?e.substr(0,e.length-n.length):e;return t?r+t:r}function Le(e,t){return Math.sqrt(Math.pow(t.x-e.x,2)+Math.pow(t.y-e.y,2))}function Ce(e){for(var t,n=e.points,r=0,o=0;o0&&(r+=Le(t,i)),t=i}return r}function Me(e){if(e.getTotalLength)return e.getTotalLength();switch(e.tagName.toLowerCase()){case"circle":return function(e){return 2*Math.PI*Se(e,"r")}(e);case"rect":return function(e){return 2*Se(e,"width")+2*Se(e,"height")}(e);case"line":return function(e){return Le({x:Se(e,"x1"),y:Se(e,"y1")},{x:Se(e,"x2"),y:Se(e,"y2")})}(e);case"polyline":return Ce(e);case"polygon":return function(e){var t=e.points;return Ce(e)+Le(t.getItem(t.numberOfItems-1),t.getItem(0))}(e)}}function Ne(e,t){var n=t||{},r=n.el||function(e){for(var t=e.parentNode;oe.svg(t)&&oe.svg(t.parentNode);)t=t.parentNode;return t}(e),o=r.getBoundingClientRect(),i=Se(r,"viewBox"),a=o.width,s=o.height,l=n.viewBox||(i?i.split(" "):[0,0,a,s]);return{el:r,viewBox:l,x:l[0]/1,y:l[1]/1,w:a,h:s,vW:l[2],vH:l[3]}}function Re(e,t,n){function r(n){void 0===n&&(n=0);var r=t+n>=1?t+n:0;return e.el.getPointAtLength(r)}var o=Ne(e.el,e.svg),i=r(),a=r(-1),s=r(1),l=n?1:o.w/o.vW,u=n?1:o.h/o.vH;switch(e.property){case"x":return(i.x-o.x)*l;case"y":return(i.y-o.y)*u;case"angle":return 180*Math.atan2(s.y-a.y,s.x-a.x)/Math.PI}}function Ue(e,t){var n=/[+-]?\d*\.?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?/g,r=Oe(oe.pth(e)?e.totalLength:e,t)+"";return{original:r,numbers:r.match(n)?r.match(n).map(Number):[0],strings:oe.str(e)||t?r.split(n):[]}}function He(e){return he(e?ge(oe.arr(e)?e.map(me):me(e)):[],(function(e,t,n){return n.indexOf(e)===t}))}function Xe(e){var t=He(e);return t.map((function(e,n){return{target:e,id:n,total:t.length,transforms:{list:Be(e)}}}))}function Fe(e,t){var n=ye(t);if(/^spring/.test(n.easing)&&(n.duration=ae(n.easing)),oe.arr(e)){var r=e.length;2===r&&!oe.obj(e[0])?e={value:e}:oe.fnc(t.duration)||(n.duration=t.duration/r)}var o=oe.arr(e)?e:[e];return o.map((function(e,n){var r=oe.obj(e)&&!oe.pth(e)?e:{value:e};return oe.und(r.delay)&&(r.delay=n?0:t.delay),oe.und(r.endDelay)&&(r.endDelay=n===o.length-1?t.endDelay:0),r})).map((function(e){return we(e,n)}))}function Ye(e,t){var n=[],r=t.keyframes;for(var o in r&&(t=we(function(e){for(var t=he(ge(e.map((function(e){return Object.keys(e)}))),(function(e){return oe.key(e)})).reduce((function(e,t){return e.indexOf(t)<0&&e.push(t),e}),[]),n={},r=function(r){var o=t[r];n[o]=e.map((function(e){var t={};for(var n in e)oe.key(n)?n==o&&(t.value=e[n]):t[n]=e[n];return t}))},o=0;o0?requestAnimationFrame(t):void 0}return"undefined"!=typeof document&&document.addEventListener("visibilitychange",(function(){Ze.suspendWhenDocumentHidden&&($e()?e=cancelAnimationFrame(e):(Ve.forEach((function(e){return e._onDocumentVisibility()})),Je()))})),function(){e||$e()&&Ze.suspendWhenDocumentHidden||!(Ve.length>0)||(e=requestAnimationFrame(t))}}();function $e(){return!!document&&document.hidden}function Ze(e){void 0===e&&(e={});var t,n=0,r=0,o=0,i=0,a=null;function s(e){var t=window.Promise&&new Promise((function(e){return a=e}));return e.finished=t,t}var l=function(e){var t=be(J,e),n=be(Z,e),r=Ye(n,e),o=Xe(e.targets),i=ze(o,r),a=Ge(i,n),s=Qe;return Qe++,we(t,{id:s,children:[],animatables:o,animations:i,duration:a.duration,delay:a.delay,endDelay:a.endDelay})}(e);function u(){var e=l.direction;"alternate"!==e&&(l.direction="normal"!==e?"normal":"reverse"),l.reversed=!l.reversed,t.forEach((function(e){return e.reversed=l.reversed}))}function c(e){return l.reversed?l.duration-e:e}function d(){n=0,r=c(l.currentTime)*(1/Ze.speed)}function f(e,t){t&&t.seek(e-t.timelineOffset)}function p(e){ -for(var t=0,n=l.animations,r=n.length;t2||(y=Math.round(y*p)/p)),h.push(y)}var E=f.length;if(E){m=f[0];for(var I=0;I0&&(l.began=!0,h("begin")),!l.loopBegan&&l.currentTime>0&&(l.loopBegan=!0,h("loopBegin")),v<=g&&0!==l.currentTime&&p(0),(v>=m&&l.currentTime!==d||!d)&&p(d),v>g&&v=d&&(r=0,l.remaining&&!0!==l.remaining&&l.remaining--,l.remaining?(n=o,h("loopComplete"),l.loopBegan=!1,"alternate"===l.direction&&u()):(l.paused=!0,l.completed||(l.completed=!0,h("loopComplete"),h("complete"),!l.passThrough&&"Promise"in window&&(a(),s(l)))))}return s(l),l.reset=function(){var e=l.direction;l.passThrough=!1,l.currentTime=0,l.progress=0,l.paused=!0,l.began=!1,l.loopBegan=!1,l.changeBegan=!1,l.completed=!1,l.changeCompleted=!1,l.reversePlayback=!1,l.reversed="reverse"===e,l.remaining=l.loop,t=l.children;for(var n=i=t.length;n--;)l.children[n].reset();(l.reversed&&!0!==l.loop||"alternate"===e&&1===l.loop)&&l.remaining++,p(l.reversed?l.duration:0)},l._onDocumentVisibility=d,l.set=function(e,t){return We(e,t),l},l.tick=function(e){o=e,n||(n=o),g((o+(r-n))*Ze.speed)},l.seek=function(e){g(c(e))},l.pause=function(){l.paused=!0,d()},l.play=function(){l.paused&&(l.completed&&l.reset(),l.paused=!1,Ve.push(l),d(),Je())},l.reverse=function(){u(),l.completed=!l.reversed,d()},l.restart=function(){l.reset(),l.play()},l.remove=function(e){et(He(e),l)},l.reset(),l.autoplay&&l.play(),l}function Ke(e,t){for(var n=t.length;n--;)ve(e,t[n].animatable.target)&&t.splice(n,1)}function et(e,t){var n=t.animations,r=t.children;Ke(e,n);for(var o=r.length;o--;){var i=r[o],a=i.animations;Ke(e,a),a.length||i.children.length||r.splice(o,1)}n.length||r.length||t.pause()}Ze.version="3.2.1",Ze.speed=1,Ze.suspendWhenDocumentHidden=!0,Ze.running=Ve,Ze.remove=function(e){for(var t=He(e),n=Ve.length;n--;){et(t,Ve[n])}},Ze.get=_e,Ze.set=We,Ze.convertPx=Te,Ze.path=function(e,t){var n=oe.str(e)?pe(e)[0]:e,r=t||100;return function(e){return{property:e,el:n,svg:Ne(n),totalLength:Me(n)*(r/100)}}},Ze.setDashoffset=function(e){var t=Me(e);return e.setAttribute("stroke-dasharray",t),t},Ze.stagger=function(e,t){void 0===t&&(t={});var n=t.direction||"normal",r=t.easing?fe(t.easing):null,o=t.grid,i=t.axis,a=t.from||0,s="first"===a,l="center"===a,u="last"===a,c=oe.arr(e),d=c?parseFloat(e[0]):parseFloat(e),f=c?parseFloat(e[1]):0,p=Ie(c?e[1]:e)||0,h=t.start||0+(c?d:0),g=[],m=0;return function(e,t,v){if(s&&(a=0),l&&(a=(v-1)/2),u&&(a=v-1),!g.length){for(var y=0;y-1&&Ve.splice(o,1);for(var s=0;s'].join(""),document.getElementById("featured-image-drop").innerHTML="",document.getElementById("featured-image-drop").appendChild(n)}}(n),o.readAsDataURL(n)}}}},{key:"handleImageUpload",value:function(e,t){var n=this;lt.alert("Uploading Image",null),n.mm.imageUpload(e,t).then((function(e){"postImageAdded"==e.type?(n.editor.notify(R,e.url),lt.alert("Image Added to Entry",!0)):lt.alert("Uh oh. Image not added",!1)})).catch((function(){lt.alert("Uh oh. Image not added",!1)}))}}]),t}();ut.uploadFiles=[];var ct=function(){function t(n){e(this,t),this.currentPage=null,this.choosePage(n),this.start()}return n(t,[{key:"start",value:function(){}},{key:"choosePage",value:function(e){switch(this.currentPage="",e){case"edit":case"add":this.currentPage=new ut}}}]),t}(),dt=function(){function t(){e(this,t)}return n(t,[{key:"getInfo",value:function(){var e,t,n=document.getElementById("settings-handle").value,r=document.getElementById("settings-email").value,o=document.getElementById("settings-url").value,i=document.getElementById("settings-title").value,a=document.getElementById("settings-desc").value,s=document.getElementById("render-toggle").getAttribute("data-render"),l=document.getElementById("background").src,u="",c=document.querySelectorAll(".theme-select"),d=document.getElementById("smtp-domain").value,f=document.getElementById("smtp-email").value,p=document.getElementById("smtp-pass").value,h=document.getElementById("mg-domain").value,g=document.getElementById("mg-key").value,m="",v=document.querySelectorAll(".mail-option"),y=document.getElementById("api-access-toggle").getAttribute("data-enabled"),b=document.getElementById("dynamic-render-toggle").getAttribute("data-enabled");for(e=0,t=c.length;e - * @author owenm - * @license MIT - */ -function vt(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function yt(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function kt(e){if("undefined"!=typeof window&&window.navigator)return!!navigator.userAgent.match(e)}var St=kt(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i),Tt=kt(/Edge/i),Dt=kt(/firefox/i),Pt=kt(/safari/i)&&!kt(/chrome/i)&&!kt(/android/i),Bt=kt(/iP(ad|od|hone)/i),xt=kt(/chrome/i)&&kt(/android/i),_t={capture:!1,passive:!1};function At(e,t,n){e.addEventListener(t,n,!St&&_t)}function Ot(e,t,n){e.removeEventListener(t,n,!St&&_t)}function Lt(e,t){if(t){if(">"===t[0]&&(t=t.substring(1)),e)try{if(e.matches)return e.matches(t);if(e.msMatchesSelector)return e.msMatchesSelector(t);if(e.webkitMatchesSelector)return e.webkitMatchesSelector(t)}catch(e){return!1}return!1}}function Ct(e){return e.host&&e!==document&&e.host.nodeType?e.host:e.parentNode}function Mt(e,t,n,r){if(e){n=n||document;do{if(null!=t&&(">"===t[0]?e.parentNode===n&&Lt(e,t):Lt(e,t))||r&&e===n)return e;if(e===n)break}while(e=Ct(e))}return null}var Nt,Rt=/\s+/g;function Ut(e,t,n){if(e&&t)if(e.classList)e.classList[n?"add":"remove"](t);else{var r=(" "+e.className+" ").replace(Rt," ").replace(" "+t+" "," ");e.className=(r+(n?" "+t:"")).replace(Rt," ")}}function Ht(e,t,n){var r=e&&e.style;if(r){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(e,""):e.currentStyle&&(n=e.currentStyle),void 0===t?n:n[t];t in r||-1!==t.indexOf("webkit")||(t="-webkit-"+t),r[t]=n+("string"==typeof n?"":"px")}}function Xt(e,t){var n="";if("string"==typeof e)n=e;else do{var r=Ht(e,"transform");r&&"none"!==r&&(n=r+" "+n)}while(!t&&(e=e.parentNode));var o=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix||window.MSCSSMatrix;return o&&new o(n)}function Ft(e,t,n){if(e){var r=e.getElementsByTagName(t),o=0,i=r.length;if(n)for(;o=i:o<=i))return r;if(r===Yt())break;r=Vt(r,!1)}return!1}function Wt(e,t,n,r){for(var o=0,i=0,a=e.children;i2&&void 0!==arguments[2]?arguments[2]:{},r=n.evt,o=It(n,an);on.pluginEvent.bind(Kn)(e,t,yt({dragEl:un,parentEl:cn,ghostEl:dn,rootEl:fn,nextEl:pn,lastDownEl:hn,cloneEl:gn,cloneHidden:mn,dragStarted:xn,putSortable:In,activeSortable:Kn.active,originalEvent:r,oldIndex:vn,oldDraggableIndex:bn,newIndex:yn,newDraggableIndex:wn,hideGhostForTarget:Vn,unhideGhostForTarget:Jn,cloneNowHidden:function(){mn=!0},cloneNowShown:function(){mn=!1},dispatchSortableEvent:function(e){ln({sortable:t,name:e,originalEvent:r})}},o))};function ln(e){!function(e){var t=e.sortable,n=e.rootEl,r=e.name,o=e.targetEl,i=e.cloneEl,a=e.toEl,s=e.fromEl,l=e.oldIndex,u=e.newIndex,c=e.oldDraggableIndex,d=e.newDraggableIndex,f=e.originalEvent,p=e.putSortable,h=e.extraEventProperties;if(t=t||n&&n[en]){var g,m=t.options,v="on"+r.charAt(0).toUpperCase()+r.substr(1);!window.CustomEvent||St||Tt?(g=document.createEvent("Event")).initEvent(r,!0,!0):g=new CustomEvent(r,{bubbles:!0,cancelable:!0}),g.to=a||n,g.from=s||n,g.item=o||n,g.clone=i,g.oldIndex=l,g.newIndex=u,g.oldDraggableIndex=c,g.newDraggableIndex=d,g.originalEvent=f,g.pullMode=p?p.lastPutMode:void 0;var y=yt(yt({},h),on.getEventProperties(r,t));for(var b in y)g[b]=y[b];n&&n.dispatchEvent(g),m[v]&&m[v].call(t,g)}}(yt({putSortable:In,cloneEl:gn,targetEl:un,rootEl:fn,oldIndex:vn,oldDraggableIndex:bn,newIndex:yn,newDraggableIndex:wn},e))}var un,cn,dn,fn,pn,hn,gn,mn,vn,yn,bn,wn,En,In,kn,Sn,Tn,Dn,Pn,Bn,xn,_n,An,On,Ln,Cn=!1,Mn=!1,Nn=[],Rn=!1,Un=!1,Hn=[],Xn=!1,Fn=[],Yn="undefined"!=typeof document,qn=Bt,jn=Tt||St?"cssFloat":"float",Wn=Yn&&!xt&&!Bt&&"draggable"in document.createElement("div"),zn=function(){if(Yn){if(St)return!1;var e=document.createElement("x");return e.style.cssText="pointer-events:auto","auto"===e.style.pointerEvents}}(),Gn=function(e,t){var n=Ht(e),r=parseInt(n.width)-parseInt(n.paddingLeft)-parseInt(n.paddingRight)-parseInt(n.borderLeftWidth)-parseInt(n.borderRightWidth),o=Wt(e,0,t),i=Wt(e,1,t),a=o&&Ht(o),s=i&&Ht(i),l=a&&parseInt(a.marginLeft)+parseInt(a.marginRight)+qt(o).width,u=s&&parseInt(s.marginLeft)+parseInt(s.marginRight)+qt(i).width;if("flex"===n.display)return"column"===n.flexDirection||"column-reverse"===n.flexDirection?"vertical":"horizontal";if("grid"===n.display)return n.gridTemplateColumns.split(" ").length<=1?"vertical":"horizontal";if(o&&a.float&&"none"!==a.float){var c="left"===a.float?"left":"right";return!i||"both"!==s.clear&&s.clear!==c?"horizontal":"vertical"}return o&&("block"===a.display||"flex"===a.display||"table"===a.display||"grid"===a.display||l>=r&&"none"===n[jn]||i&&"none"===n[jn]&&l+u>r)?"vertical":"horizontal"},Qn=function(e){function t(e,n){return function(r,o,i,a){var s=r.options.group.name&&o.options.group.name&&r.options.group.name===o.options.group.name;if(null==e&&(n||s))return!0;if(null==e||!1===e)return!1;if(n&&"clone"===e)return e;if("function"==typeof e)return t(e(r,o,i,a),n)(r,o,i,a);var l=(n?r:o).options.group.name;return!0===e||"string"==typeof e&&e===l||e.join&&e.indexOf(l)>-1}}var n={},r=e.group;r&&"object"==bt(r)||(r={name:r}),n.name=r.name,n.checkPull=t(r.pull,!0),n.checkPut=t(r.put),n.revertClone=r.revertClone,e.group=n},Vn=function(){!zn&&dn&&Ht(dn,"display","none")},Jn=function(){!zn&&dn&&Ht(dn,"display","")};Yn&&document.addEventListener("click",(function(e){if(Mn)return e.preventDefault(),e.stopPropagation&&e.stopPropagation(),e.stopImmediatePropagation&&e.stopImmediatePropagation(),Mn=!1,!1}),!0);var $n=function(e){if(un){e=e.touches?e.touches[0]:e;var t=(o=e.clientX,i=e.clientY,Nn.some((function(e){var t=e[en].options.emptyInsertThreshold;if(t&&!zt(e)){var n=qt(e),r=o>=n.left-t&&o<=n.right+t,s=i>=n.top-t&&i<=n.bottom+t;return r&&s?a=e:void 0}})),a);if(t){var n={};for(var r in e)e.hasOwnProperty(r)&&(n[r]=e[r]);n.target=n.rootEl=t,n.preventDefault=void 0,n.stopPropagation=void 0,t[en]._onDragOver(n)}}var o,i,a},Zn=function(e){un&&un.parentNode[en]._isOutsideThisEl(e.target)};function Kn(e,t){if(!e||!e.nodeType||1!==e.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(e));this.el=e,this.options=t=Et({},t),e[en]=this;var n={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(e.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return Gn(e,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(e,t){e.setData("Text",t.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==Kn.supportPointer&&"PointerEvent"in window&&!Pt,emptyInsertThreshold:5};for(var r in on.initializePlugins(this,e,n),n)!(r in t)&&(t[r]=n[r]);for(var o in Qn(t),this)"_"===o.charAt(0)&&"function"==typeof this[o]&&(this[o]=this[o].bind(this));this.nativeDraggable=!t.forceFallback&&Wn,this.nativeDraggable&&(this.options.touchStartThreshold=1),t.supportPointer?At(e,"pointerdown",this._onTapStart):(At(e,"mousedown",this._onTapStart),At(e,"touchstart",this._onTapStart)),this.nativeDraggable&&(At(e,"dragover",this),At(e,"dragenter",this)),Nn.push(this.el),t.store&&t.store.get&&this.sort(t.store.get(this)||[]),Et(this,tn())}function er(e,t,n,r,o,i,a,s){var l,u,c=e[en],d=c.options.onMove;return!window.CustomEvent||St||Tt?(l=document.createEvent("Event")).initEvent("move",!0,!0):l=new CustomEvent("move",{bubbles:!0,cancelable:!0}),l.to=t,l.from=e,l.dragged=n,l.draggedRect=r,l.related=o||t,l.relatedRect=i||qt(t),l.willInsertAfter=s,l.originalEvent=a,e.dispatchEvent(l),d&&(u=d.call(c,l,a)),u}function tr(e){e.draggable=!1}function nr(){Xn=!1}function rr(e){for(var t=e.tagName+e.className+e.src+e.href+e.textContent,n=t.length,r=0;n--;)r+=t.charCodeAt(n);return r.toString(36)}function or(e){return setTimeout(e,0)}function ir(e){return clearTimeout(e)}Kn.prototype={constructor:Kn,_isOutsideThisEl:function(e){this.el.contains(e)||e===this.el||(_n=null)},_getDirection:function(e,t){return"function"==typeof this.options.direction?this.options.direction.call(this,e,t,un):this.options.direction},_onTapStart:function(e){if(e.cancelable){var t=this,n=this.el,r=this.options,o=r.preventOnFilter,i=e.type,a=e.touches&&e.touches[0]||e.pointerType&&"touch"===e.pointerType&&e,s=(a||e).target,l=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||s,u=r.filter;if(function(e){Fn.length=0;var t=e.getElementsByTagName("input"),n=t.length;for(;n--;){var r=t[n];r.checked&&Fn.push(r)}}(n),!un&&!(/mousedown|pointerdown/.test(i)&&0!==e.button||r.disabled)&&!l.isContentEditable&&(this.nativeDraggable||!Pt||!s||"SELECT"!==s.tagName.toUpperCase())&&!((s=Mt(s,r.draggable,n,!1))&&s.animated||hn===s)){if(vn=Gt(s),bn=Gt(s,r.draggable),"function"==typeof u){if(u.call(this,e,s,this))return ln({sortable:t,rootEl:l,name:"filter",targetEl:s,toEl:n,fromEl:n}),sn("filter",t,{evt:e}),void(o&&e.cancelable&&e.preventDefault())}else if(u&&(u=u.split(",").some((function(r){if(r=Mt(l,r.trim(),n,!1))return ln({sortable:t,rootEl:r,name:"filter",targetEl:s,fromEl:n,toEl:n}),sn("filter",t,{evt:e}),!0}))))return void(o&&e.cancelable&&e.preventDefault());r.handle&&!Mt(l,r.handle,n,!1)||this._prepareDragStart(e,a,s)}}},_prepareDragStart:function(e,t,n){var r,o=this,i=o.el,a=o.options,s=i.ownerDocument;if(n&&!un&&n.parentNode===i){var l=qt(n);if(fn=i,cn=(un=n).parentNode,pn=un.nextSibling,hn=n,En=a.group,Kn.dragged=un,kn={target:un,clientX:(t||e).clientX,clientY:(t||e).clientY},Pn=kn.clientX-l.left,Bn=kn.clientY-l.top,this._lastX=(t||e).clientX,this._lastY=(t||e).clientY,un.style["will-change"]="all",r=function(){sn("delayEnded",o,{evt:e}),Kn.eventCanceled?o._onDrop():(o._disableDelayedDragEvents(),!Dt&&o.nativeDraggable&&(un.draggable=!0),o._triggerDragStart(e,t),ln({sortable:o,name:"choose",originalEvent:e}),Ut(un,a.chosenClass,!0))},a.ignore.split(",").forEach((function(e){Ft(un,e.trim(),tr)})),At(s,"dragover",$n),At(s,"mousemove",$n),At(s,"touchmove",$n),At(s,"mouseup",o._onDrop),At(s,"touchend",o._onDrop),At(s,"touchcancel",o._onDrop),Dt&&this.nativeDraggable&&(this.options.touchStartThreshold=4,un.draggable=!0),sn("delayStart",this,{evt:e}),!a.delay||a.delayOnTouchOnly&&!t||this.nativeDraggable&&(Tt||St))r();else{if(Kn.eventCanceled)return void this._onDrop();At(s,"mouseup",o._disableDelayedDrag),At(s,"touchend",o._disableDelayedDrag),At(s,"touchcancel",o._disableDelayedDrag),At(s,"mousemove",o._delayedDragTouchMoveHandler),At(s,"touchmove",o._delayedDragTouchMoveHandler),a.supportPointer&&At(s,"pointermove",o._delayedDragTouchMoveHandler),o._dragStartTimer=setTimeout(r,a.delay)}}},_delayedDragTouchMoveHandler:function(e){var t=e.touches?e.touches[0]:e;Math.max(Math.abs(t.clientX-this._lastX),Math.abs(t.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){un&&tr(un),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var e=this.el.ownerDocument;Ot(e,"mouseup",this._disableDelayedDrag),Ot(e,"touchend",this._disableDelayedDrag),Ot(e,"touchcancel",this._disableDelayedDrag),Ot(e,"mousemove",this._delayedDragTouchMoveHandler),Ot(e,"touchmove",this._delayedDragTouchMoveHandler),Ot(e,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(e,t){t=t||"touch"==e.pointerType&&e,!this.nativeDraggable||t?this.options.supportPointer?At(document,"pointermove",this._onTouchMove):At(document,t?"touchmove":"mousemove",this._onTouchMove):(At(un,"dragend",this),At(fn,"dragstart",this._onDragStart));try{document.selection?or((function(){document.selection.empty()})):window.getSelection().removeAllRanges()}catch(e){}},_dragStarted:function(e,t){if(Cn=!1,fn&&un){sn("dragStarted",this,{evt:t}),this.nativeDraggable&&At(document,"dragover",Zn);var n=this.options;!e&&Ut(un,n.dragClass,!1),Ut(un,n.ghostClass,!0),Kn.active=this,e&&this._appendGhost(),ln({sortable:this,name:"start",originalEvent:t})}else this._nulling()},_emulateDragOver:function(){if(Sn){this._lastX=Sn.clientX,this._lastY=Sn.clientY,Vn();for(var e=document.elementFromPoint(Sn.clientX,Sn.clientY),t=e;e&&e.shadowRoot&&(e=e.shadowRoot.elementFromPoint(Sn.clientX,Sn.clientY))!==t;)t=e;if(un.parentNode[en]._isOutsideThisEl(e),t)do{if(t[en]){if(t[en]._onDragOver({clientX:Sn.clientX,clientY:Sn.clientY,target:e,rootEl:t})&&!this.options.dragoverBubble)break}e=t}while(t=t.parentNode);Jn()}},_onTouchMove:function(e){if(kn){var t=this.options,n=t.fallbackTolerance,r=t.fallbackOffset,o=e.touches?e.touches[0]:e,i=dn&&Xt(dn,!0),a=dn&&i&&i.a,s=dn&&i&&i.d,l=qn&&Ln&&Qt(Ln),u=(o.clientX-kn.clientX+r.x)/(a||1)+(l?l[0]-Hn[0]:0)/(a||1),c=(o.clientY-kn.clientY+r.y)/(s||1)+(l?l[1]-Hn[1]:0)/(s||1);if(!Kn.active&&!Cn){if(n&&Math.max(Math.abs(o.clientX-this._lastX),Math.abs(o.clientY-this._lastY))r.right+o||e.clientX<=r.right&&e.clientY>r.bottom&&e.clientX>=r.left:e.clientX>r.right&&e.clientY>r.top||e.clientX<=r.right&&e.clientY>r.bottom+o}(e,o,this)&&!g.animated){if(g===un)return A(!1);if(g&&i===e.target&&(a=g),a&&(n=qt(a)),!1!==er(fn,i,un,t,a,n,e,!!a))return _(),i.appendChild(un),cn=i,O(),A(!0)}else if(g&&function(e,t,n){var r=qt(Wt(n.el,0,n.options,!0)),o=10;return t?e.clientXc+u*i/2:ld-On)return-An}else if(l>c+u*(1-o)/2&&ld-u*i/2))return l>c+u/2?1:-1;return 0}(e,a,n,o,E?1:s.swapThreshold,null==s.invertedSwapThreshold?s.swapThreshold:s.invertedSwapThreshold,Un,_n===a),0!==v){var T=Gt(un);do{T-=v,b=cn.children[T]}while(b&&("none"===Ht(b,"display")||b===dn))}if(0===v||b===a)return A(!1);_n=a,An=v;var D=a.nextElementSibling,P=!1,B=er(fn,i,un,t,a,n,e,P=1===v);if(!1!==B)return 1!==B&&-1!==B||(P=1===B),Xn=!0,setTimeout(nr,30),_(),P&&!D?i.appendChild(un):a.parentNode.insertBefore(un,P?D:a),k&&Zt(k,0,S-k.scrollTop),cn=un.parentNode,void 0===y||Un||(On=Math.abs(y-qt(a)[I])),O(),A(!0)}if(i.contains(un))return A(!1)}return!1}function x(s,l){sn(s,p,yt({evt:e,isOwner:c,axis:o?"vertical":"horizontal",revert:r,dragRect:t,targetRect:n,canSort:d,fromSortable:f,target:a,completed:A,onMove:function(n,r){return er(fn,i,un,t,n,qt(n),e,r)},changed:O},l))}function _(){x("dragOverAnimationCapture"),p.captureAnimationState(),p!==f&&f.captureAnimationState()}function A(t){return x("dragOverCompleted",{insertion:t}),t&&(c?u._hideClone():u._showClone(p),p!==f&&(Ut(un,In?In.options.ghostClass:u.options.ghostClass,!1),Ut(un,s.ghostClass,!0)),In!==p&&p!==Kn.active?In=p:p===Kn.active&&In&&(In=null),f===p&&(p._ignoreWhileAnimating=a),p.animateAll((function(){x("dragOverAnimationComplete"),p._ignoreWhileAnimating=null})),p!==f&&(f.animateAll(),f._ignoreWhileAnimating=null)),(a===un&&!un.animated||a===i&&!a.animated)&&(_n=null),s.dragoverBubble||e.rootEl||a===document||(un.parentNode[en]._isOutsideThisEl(e.target),!t&&$n(e)),!s.dragoverBubble&&e.stopPropagation&&e.stopPropagation(),h=!0}function O(){yn=Gt(un),wn=Gt(un,s.draggable),ln({sortable:p,name:"change",toEl:i,newIndex:yn,newDraggableIndex:wn,originalEvent:e})}},_ignoreWhileAnimating:null,_offMoveEvents:function(){Ot(document,"mousemove",this._onTouchMove),Ot(document,"touchmove",this._onTouchMove),Ot(document,"pointermove",this._onTouchMove),Ot(document,"dragover",$n),Ot(document,"mousemove",$n),Ot(document,"touchmove",$n)},_offUpEvents:function(){var e=this.el.ownerDocument;Ot(e,"mouseup",this._onDrop),Ot(e,"touchend",this._onDrop),Ot(e,"pointerup",this._onDrop),Ot(e,"touchcancel",this._onDrop),Ot(document,"selectstart",this)},_onDrop:function(e){var t=this.el,n=this.options;yn=Gt(un),wn=Gt(un,n.draggable),sn("drop",this,{evt:e}),cn=un&&un.parentNode,yn=Gt(un),wn=Gt(un,n.draggable),Kn.eventCanceled||(Cn=!1,Un=!1,Rn=!1,clearInterval(this._loopId),clearTimeout(this._dragStartTimer),ir(this.cloneId),ir(this._dragStartId),this.nativeDraggable&&(Ot(document,"drop",this),Ot(t,"dragstart",this._onDragStart)),this._offMoveEvents(),this._offUpEvents(),Pt&&Ht(document.body,"user-select",""),Ht(un,"transform",""),e&&(xn&&(e.cancelable&&e.preventDefault(),!n.dropBubble&&e.stopPropagation()),dn&&dn.parentNode&&dn.parentNode.removeChild(dn),(fn===cn||In&&"clone"!==In.lastPutMode)&&gn&&gn.parentNode&&gn.parentNode.removeChild(gn),un&&(this.nativeDraggable&&Ot(un,"dragend",this),tr(un),un.style["will-change"]="",xn&&!Cn&&Ut(un,In?In.options.ghostClass:this.options.ghostClass,!1),Ut(un,this.options.chosenClass,!1),ln({sortable:this,name:"unchoose",toEl:cn,newIndex:null,newDraggableIndex:null,originalEvent:e}),fn!==cn?(yn>=0&&(ln({rootEl:cn,name:"add",toEl:cn,fromEl:fn,originalEvent:e}),ln({sortable:this,name:"remove",toEl:cn,originalEvent:e}),ln({rootEl:cn,name:"sort",toEl:cn,fromEl:fn,originalEvent:e}),ln({sortable:this,name:"sort",toEl:cn,originalEvent:e})),In&&In.save()):yn!==vn&&yn>=0&&(ln({sortable:this,name:"update",toEl:cn,originalEvent:e}),ln({sortable:this,name:"sort",toEl:cn,originalEvent:e})),Kn.active&&(null!=yn&&-1!==yn||(yn=vn,wn=bn),ln({sortable:this,name:"end",toEl:cn,originalEvent:e}),this.save())))),this._nulling()},_nulling:function(){sn("nulling",this),fn=un=cn=dn=pn=gn=hn=mn=kn=Sn=xn=yn=wn=vn=bn=_n=An=In=En=Kn.dragged=Kn.ghost=Kn.clone=Kn.active=null,Fn.forEach((function(e){e.checked=!0})),Fn.length=Tn=Dn=0},handleEvent:function(e){switch(e.type){case"drop":case"dragend":this._onDrop(e);break;case"dragenter":case"dragover":un&&(this._onDragOver(e),function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="move");e.cancelable&&e.preventDefault()}(e));break;case"selectstart":e.preventDefault()}},toArray:function(){for(var e,t=[],n=this.el.children,r=0,o=n.length,i=this.options;r this.handleFileActions(e), false); + this.upload.addEventListener('drop', e => this.handleFileActions(e), false); + this.input.addEventListener('change', e => this.handleFileActions(e), false); + + Sortable.create(this.imageList, { + onUpdate: e => { + notify.alert('REINDEXING FILES', null); + let currentFiles = []; //store current list + let items = e.target.children; + for (let index = 0; index < items.length; index++) { + var item = items[index]; + let url = ''; + if (item.className == 'img-item') { + url = item.style.backgroundImage.slice(4, -1).replace(/"/g, ''); + } else { + url = item.getAttribute('data-source'); + } + + currentFiles.push({ + earl: url + }); + } + this.reindexFiles(currentFiles, 0); + } + }); + + Sortable.create(this.fileList, { + onUpdate: e => { + notify.alert('REINDEXING FILES', null); + let currentFiles = []; + let items = e.target.children; + for (let index = 0; index < items.length; index++) { + var item = items[index]; + let url = item.getAttribute('data-source'); + currentFiles.push({ + earl: url + }); + } + this.reindexFiles(currentFiles, 0); + } + }); + } + + getFiles() { + return this.files; + } + + reindexFiles(sortOrder, step) { + let count = sortOrder.length; + if (step == 0) this.files = []; + var utils = new DataUtils(); + var path = sortOrder[step].earl.split('/'); + utils.imgLoad(sortOrder[step].earl).then(blob => { + var fresh = new File([blob], path[6], { type: blob.type }); + this.files.push(fresh); + if (this.files.length <= count - 1) { + this.reindexFiles(sortOrder, ++step); + } else { + notify.alert('FILES READY TO UPLOAD', true); + } + }); + } + + sortFiles(files) { + var self = this; + this.files = []; //clear files array + this.imageList.innerHTML = ''; + this.fileList.innerHTML = ''; + for (var i = 0, file; (file = files[i]); i++) { + var reader = new FileReader(); + // Closure to capture the file information + + reader.onload = (theFile => { + return function (f) { + // sort files + switch (theFile.type) { + case 'image/jpg': + case 'image/jpeg': + case 'image/gif': + case 'image/svg': + case 'image/png': + //create element and add to list + var image = document.createElement('img'); + image.src = f.target.result; + image.title = escape(theFile.name); + var span = document.createElement('div'); + span.style.background = + 'url(' + + f.target.result + + ') no-repeat center center / cover'; + span.className = 'img-item'; + image.setAttribute('id', i); + self.storage.push([ + { + id: 'page_image' + i, + data: f.target.result, + type: theFile.type, + name: escape(theFile.name) + } + ]); + self.imageList.appendChild(span); + //add to files list + self.files.push(theFile); + + break; + case 'video/mp4': + var video = document.createElement('div'); + video.className = 'video-item'; + video.setAttribute('data-source', f.target.result); + self.imageList.appendChild(video); + self.files.push(theFile); + break; + case 'audio/mpeg': + var sound = document.createElement('div'); + sound.className = 'audio-item'; + sound.setAttribute('data-source', f.target.result); + self.fileList.appendChild(sound); + self.files.push(theFile); + break; + case 'application/pdf': + case 'text/plain': + case 'text/rtf': + var file = document.createElement('div'); + file.className = 'file-item'; + file.setAttribute('data-source', f.target.result); + self.fileList.appendChild(file); + self.files.push(theFile); + break; + } + }; + })(file); + // Read in the image file as a data URL. + reader.readAsDataURL(file); + } + } + + //-------------------------- + // event handlers + //-------------------------- + handleFileActions(e) { + e.stopPropagation(); + e.preventDefault(); + let self = this; + let rawList = []; + let sortedList = []; + let notOnTheList = []; + + switch (e.type) { + case 'dragover': + e.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy. + break; + case 'change': + case 'drop': + e.type == 'drop' + ? (rawList = e.dataTransfer.files) + : (rawList = e.target.files); + for (var i = 0, f; (f = rawList[i]); i++) { + // check witch files are cool to upload + if (this.accetableFiles.includes(f.type)) { + sortedList.push(f); + } else { + notOnTheList.push(f); + } + } + //send for sorting + self.sortFiles(sortedList); + break; + } + } +}