Compare commits
112 Commits
58c5c57cc3
...
master
Author | SHA1 | Date | |
---|---|---|---|
ac751f5f28
|
|||
a1aecdf3e2
|
|||
a747ef0129
|
|||
80aa487e7e
|
|||
5048abc3e6
|
|||
afd34e9b4e
|
|||
a81ce8a922
|
|||
9d25befeba
|
|||
5d9f7e3997
|
|||
ecfae3e01a
|
|||
9e6c93ba95
|
|||
231dd959af
|
|||
5607425bde
|
|||
ac99d29109
|
|||
d4f0044656
|
|||
9d455bdcf7
|
|||
3b39ae0470
|
|||
9551f661c1
|
|||
c02b40071f
|
|||
a0dc0e01f3
|
|||
8876f07ac6
|
|||
2ac78ef539
|
|||
56cef79880
|
|||
aa5753cc82
|
|||
4dcb6b6ebe
|
|||
22946bc031
|
|||
e2ce420764
|
|||
7583883d64
|
|||
fb5bde70ef
|
|||
5e2a386b15
|
|||
75d052af88
|
|||
87cd634613
|
|||
48a34d5acf
|
|||
05ca3574b0
|
|||
739c2b79e9
|
|||
6e7ded098b
|
|||
64d4d326b7
|
|||
fdba9f1ae7
|
|||
27032f433a
|
|||
0c8a6c410d
|
|||
3f340d57fc
|
|||
995cc32578
|
|||
5f5b443df7
|
|||
e5366171fd
|
|||
1c650fbb64
|
|||
a784d44d16
|
|||
e27aa8969f
|
|||
433ad39a08
|
|||
e78324e92a
|
|||
5ceb315b6c
|
|||
58a4701ba3
|
|||
a1f677ff9b
|
|||
ebb6a4721a
|
|||
625dfeb79f
|
|||
427d4e2500
|
|||
bdf5121d71
|
|||
16e07e0a53
|
|||
d43dbe7c1c
|
|||
0e3aaafc2f
|
|||
0ed9aef8d0
|
|||
b7ac751b10
|
|||
400edc9b38
|
|||
a2a747c489
|
|||
5f87596b2f
|
|||
606899494c
|
|||
08761f991b
|
|||
275b2f83b7
|
|||
5c46e01a7f
|
|||
8312c5e54e
|
|||
bcf14cc604
|
|||
b8df8a8d4d
|
|||
e7bbacd59e
|
|||
a1c307df64
|
|||
54eab9cd4a
|
|||
51d047be86
|
|||
9fab41ae2a
|
|||
1c85d0b3cd
|
|||
e39547e77e
|
|||
10aae0a9f2
|
|||
e5c0eae622
|
|||
2120fc8c4d
|
|||
c5612ba108
|
|||
90e5ddee96
|
|||
7fa9bbca77
|
|||
0e325bfbca
|
|||
252fab0084
|
|||
b11660329b
|
|||
0ff04a5ecd
|
|||
a7df7a64f0
|
|||
90f3709f4b
|
|||
842e1994bd
|
|||
2a8eb7013d
|
|||
2c254b1a3e
|
|||
74215ba317
|
|||
f9b31ef296
|
|||
f50d0203e5
|
|||
7359f4c00d
|
|||
a83b61c264
|
|||
a6849c201a
|
|||
6fa1c5ca95
|
|||
2c44584c81
|
|||
374ea35e42
|
|||
2b13367970
|
|||
64454ddee7
|
|||
78d6383b15
|
|||
a29f28c11d
|
|||
b8e8f212d6
|
|||
b56dd305c1
|
|||
cf828164c3
|
|||
75d5f8c6c3
|
|||
3e42869bbb
|
|||
46b6cb678e
|
60
colors.md
Normal file
60
colors.md
Normal file
@ -0,0 +1,60 @@
|
||||
Colors
|
||||
|
||||
### Sunbaked Mint
|
||||
HEX: #80e8d4
|
||||
RGB: 128, 232, 212
|
||||
CMYK: 43, 0, 25, 0
|
||||
|
||||
|
||||
### Honey Dijon
|
||||
HEX: #e2ae61
|
||||
RGB: 226, 174, 97
|
||||
CMYK: 1, 32, 72, 0
|
||||
|
||||
|
||||
### Ultimate Gray
|
||||
HEX: #97999b
|
||||
RGB: 151, 153, 155
|
||||
CMYK (approximation): 44, 35, 34, 1
|
||||
|
||||
|
||||
### Frosty Blue
|
||||
HEX: #bcddfc
|
||||
RGB: 188, 221, 252
|
||||
CMYK: 23, 5, 0, 0
|
||||
|
||||
|
||||
### Electric Tangerine
|
||||
HEX: #ff825c
|
||||
RGB: 255, 130, 92
|
||||
CMYK: 0, 61, 64, 0
|
||||
|
||||
|
||||
### Holo Lilac
|
||||
HEX: #c5d2fe
|
||||
RGB: 197, 210, 254
|
||||
CMYK: 22, 17, 0, 0
|
||||
|
||||
|
||||
### Poppy Sunset
|
||||
HEX: #ee645b
|
||||
RGB: 238, 100, 91
|
||||
CMYK: 2, 76, 62, 0
|
||||
|
||||
|
||||
### Lime Nouveau
|
||||
HEX: #cddf8b
|
||||
RGB: 205, 223, 139
|
||||
CMYK: 22, 1, 58, 5
|
||||
|
||||
|
||||
### Very Peri
|
||||
HEX: #6667ab
|
||||
RGB: 102, 103, 171
|
||||
CMYK (approximation): 40, 40, 0, 33
|
||||
|
||||
|
||||
### Classic Blue
|
||||
HEX: #0f4c81
|
||||
RGB: 15, 76, 129
|
||||
CMYK (approximation): 99, 76, 24, 8
|
@ -5,9 +5,9 @@ sed -i "/^GIT_HASH=\".*\"/ s//GIT_HASH=\"${SHORT_HASH}\"/" .env
|
||||
|
||||
DIRTY_STATE=$(git diff --stat)
|
||||
if [ -n "$DIRTY_STATE" ]; then
|
||||
sed -i "/^GIT_DIRTY_STATE=.*/ s//GIT_TAG=true/" .env
|
||||
sed -i "/^GIT_DIRTY_STATE=.*/ s//GIT_DIRTY_STATE=true/" .env
|
||||
else
|
||||
sed -i "/^GIT_DIRTY_STATE=.*/ s//GIT_TAG=false/" .env
|
||||
sed -i "/^GIT_DIRTY_STATE=.*/ s//GIT_DIRTY_STATE=false/" .env
|
||||
fi
|
||||
|
||||
GIT_TAG=$(git tag --points-at HEAD)
|
||||
|
@ -5,17 +5,21 @@ sed -i "/^GIT_HASH=\".*\"/ s//GIT_HASH=\"${SHORT_HASH}\"/" .env
|
||||
|
||||
DIRTY_STATE=$(git diff --stat)
|
||||
if [ -n "$DIRTY_STATE" ]; then
|
||||
sed -i "/^GIT_DIRTY_STATE=.*/ s//GIT_TAG=true/" .env
|
||||
sed -i "/^GIT_DIRTY_STATE=.*/ s//GIT_DIRTY_STATE=true/" .env
|
||||
else
|
||||
sed -i "/^GIT_DIRTY_STATE=.*/ s//GIT_TAG=false/" .env
|
||||
sed -i "/^GIT_DIRTY_STATE=.*/ s//GIT_DIRTY_STATE=false/" .env
|
||||
fi
|
||||
|
||||
SHORT_HASH=$(git rev-parse --short HEAD)
|
||||
sed -i "/^GIT_HASH=\".*\"/ s//GIT_HASH=\"${SHORT_HASH}\"/" .env
|
||||
|
||||
GIT_TAG=$(git tag --points-at HEAD)
|
||||
if [ -n "$GIT_TAG" ]; then
|
||||
sed -i "/^GIT_TAG=\".*\"/ s//GIT_TAG=\"${GIT_TAG}\"/" .env
|
||||
else
|
||||
sed -i "/^GIT_TAG=\".*\"/ s//GIT_TAG=\"\"/" .env
|
||||
fi
|
||||
|
||||
GIT_BRANCH=$(git branch --show-current)
|
||||
if [ -n "$GIT_BRANCH" ]; then
|
||||
sed -i "/^GIT_BRANCH=\".*\"/ s//GIT_BRANCH=\"${GIT_BRANCH}\"/" .env
|
||||
else
|
||||
sed -i "/^GIT_BRANCH=\".*\"/ s//GIT_BRANCH=\"\"/" .env
|
||||
fi
|
||||
|
@ -1,25 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
SHORT_HASH=$(git rev-parse --short HEAD)
|
||||
sed -i "/^GIT_HASH=\".*\"/ s//GIT_HASH=\"${SHORT_HASH}\"/" .env
|
||||
|
||||
DIRTY_STATE=$(git diff --stat)
|
||||
if [ -n "$DIRTY_STATE" ]; then
|
||||
sed -i "/^GIT_DIRTY_STATE=.*/ s//GIT_TAG=true/" .env
|
||||
else
|
||||
sed -i "/^GIT_DIRTY_STATE=.*/ s//GIT_TAG=false/" .env
|
||||
fi
|
||||
|
||||
GIT_TAG=$(git tag --points-at HEAD)
|
||||
if [ -n "$GIT_TAG" ]; then
|
||||
sed -i "/^GIT_TAG=\".*\"/ s//GIT_TAG=\"${GIT_TAG}\"/" .env
|
||||
else
|
||||
sed -i "/^GIT_TAG=\".*\"/ s//GIT_TAG=\"\"/" .env
|
||||
fi
|
||||
|
||||
GIT_BRANCH=$(git branch --show-current)
|
||||
if [ -n "$GIT_BRANCH" ]; then
|
||||
sed -i "/^GIT_BRANCH=\".*\"/ s//GIT_BRANCH=\"${GIT_BRANCH}\"/" .env
|
||||
else
|
||||
sed -i "/^GIT_BRANCH=\".*\"/ s//GIT_BRANCH=\"\"/" .env
|
||||
fi
|
32
git-hooks/pre-commit
Normal file
32
git-hooks/pre-commit
Normal file
@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# get bash colors and styles here:
|
||||
# http://misc.flogisoft.com/bash/tip_colors_and_formatting
|
||||
C_RESET='\e[0m'
|
||||
C_RED='\e[31m'
|
||||
C_GREEN='\e[32m'
|
||||
C_YELLOW='\e[33m'
|
||||
|
||||
function __run() #(step, name, cmd)
|
||||
{
|
||||
local color output exitcode
|
||||
|
||||
printf "${C_YELLOW}[%s]${C_RESET} %-20s" "$1" "$2"
|
||||
output=$(eval "$3" 2>&1)
|
||||
exitcode=$?
|
||||
|
||||
if [[ 0 == $exitcode || 130 == $exitcode ]]; then
|
||||
echo -e "${C_GREEN}OK!${C_RESET}"
|
||||
else
|
||||
echo -e "${C_RED}NOK!${C_RESET}\n\n$output"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
modified="git diff --diff-filter=M --name-only --cached | grep \".php$\""
|
||||
ignore="resources/lang,resources/views,bootstrap/helpers,database/migrations,bin"
|
||||
phpcs="vendor/bin/phpcs --report=code --colors --report-width=80 --ignore=${ignore}"
|
||||
|
||||
__run "1/2" "php lint" "${modified} | xargs -r php -l"
|
||||
__run "2/2" "code sniffer" "${modified} | xargs -r ${phpcs}"
|
||||
# __run "3/3" "phpstan" "${modified} | xargs -r vendor/bin/phpstan analyse"
|
@ -4,11 +4,12 @@ APP_KEY=base64:hSCTwZ507IdKQ5QJHJ+mQw0DSMgDdAspasjwHCdiB8Y=
|
||||
APP_DEBUG=true
|
||||
APP_DOMAIN=localhost
|
||||
APP_URL="https://${APP_DOMAIN}"
|
||||
APP_UID_BYTES=8
|
||||
ADMIN_EMAIL=""
|
||||
|
||||
GIT_HASH="00000000"
|
||||
GIT_TAG="x.x.x"
|
||||
GIT_BRANCH="master"
|
||||
GIT_DIRTY_STATE=false
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
LOG_DEPRECATIONS_CHANNEL=null
|
||||
@ -27,27 +28,42 @@ FILESYSTEM_DRIVER=local
|
||||
QUEUE_CONNECTION=sync
|
||||
SESSION_DRIVER=database
|
||||
SESSION_LIFETIME=120
|
||||
#SESSION_STORE=redis
|
||||
#SESSION_DOMAIN="${APP_DOMAIN}"
|
||||
#SESSION_SECURE_COOKIE=true
|
||||
|
||||
MEMCACHED_HOST=memcached
|
||||
MEMCACHED_HOST=memcache
|
||||
|
||||
REDIS_HOST=redis
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_MAILER=smtp
|
||||
MAIL_HOST=mailpit
|
||||
MAIL_PORT=1025
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
MAIL_FROM_ADDRESS="hello@${APP_DOMAIN}"
|
||||
MAIL_FROM_NAME="${APP_NAME}"
|
||||
|
||||
SCOUT_DRIVER=meilisearch
|
||||
SCOUT_PREFIX=
|
||||
SCOUT_QUEUE=false
|
||||
MEILISEARCH_HOST=http://localhost:7700
|
||||
MEILISEARCH_KEY=
|
||||
MEILISEARCH_PRIVATE_KEY=
|
||||
MEILISEARCH_PUBLIC_KEY=
|
||||
|
||||
MAIL_MAILER=smtp
|
||||
MAIL_HOST=mailhog
|
||||
MAIL_PORT=1125
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
MAIL_FROM_ADDRESS="no-reply@${APP_DOMAIN}"
|
||||
MAIL_FROM_NAME="${APP_NAME}"
|
||||
GOOGLE_GEOCODE_API_KEY=
|
||||
|
||||
MINIO_USERNAME=
|
||||
MINIO_PASSWORD=
|
||||
MINIO_DEFAULT_REGION=us-west-1
|
||||
MINIO_BUCKET=
|
||||
MINIO_URL=
|
||||
MINIO_ENDPOINT=
|
||||
MINIO_USE_PATH_STYLE_ENDPOINT=false
|
||||
|
||||
AWS_ACCESS_KEY_ID=
|
||||
AWS_SECRET_ACCESS_KEY=
|
||||
@ -58,8 +74,14 @@ AWS_USE_PATH_STYLE_ENDPOINT=false
|
||||
PUSHER_APP_ID=
|
||||
PUSHER_APP_KEY=
|
||||
PUSHER_APP_SECRET=
|
||||
PUSHER_HOST=
|
||||
PUSHER_PORT=443
|
||||
PUSHER_SCHEME=https
|
||||
PUSHER_APP_CLUSTER=mt1
|
||||
|
||||
VITE_SSL_KEY_FILE_PATH="/code/docker/configs/nginx/ssls/${APP_DOMAIN}/${APP_DOMAIN}.key"
|
||||
VITE_SSL_CERT_FILE_PATH="/code/docker/configs/nginx/ssls/${APP_DOMAIN}/${APP_DOMAIN}.crt"
|
||||
|
||||
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
||||
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||
MIX_PUSHER_HOST="${PUSHER_HOST}"
|
||||
@ -81,3 +103,13 @@ INTEGRITY_HASH_WEBMANIFEST_JSON=""
|
||||
INTEGRITY_HASH_MIX_MANIFEST_JSON=""
|
||||
INTEGRITY_HASH_APP_CSS=""
|
||||
INTEGRITY_HASH_APP_JS=""
|
||||
|
||||
## Clockwork debug helpers
|
||||
## default values are set, except for the main enable switch
|
||||
CLOCKWORK_ENABLE=true
|
||||
CLOCKWORK_WEB=true
|
||||
CLOCKWORK_AUTHENTICATION=false
|
||||
#CLOCKWORK_AUTHENTICATION_PASSWORD=VerySecretPassword
|
||||
CLOCKWORK_CACHE_COLLECT_VALUES=true
|
||||
#CLOCKWORK_DATABASE_SLOW_THRESHOLD= # time in miliseconds
|
||||
#CLOCKWORK_REQUESTS_SLOW_THRESHOLD= # time in miliseconds
|
||||
|
36
src/.phpcs.xml
Normal file
36
src/.phpcs.xml
Normal file
@ -0,0 +1,36 @@
|
||||
<?xml version="1.0"?>
|
||||
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="PSR2" xsi:noNamespaceSchemaLocation="vendor/slevomat/coding-standard">
|
||||
<description>PHP Codesniffer ruleset for this project</description>
|
||||
|
||||
<arg name="basepath" value="."/>
|
||||
<arg name="parallel" value="4"/>
|
||||
<arg name="report" value="full"/>
|
||||
<arg name="extensions" value="php"/>
|
||||
<arg name="colors"/>
|
||||
<arg name="no-cache"/>
|
||||
<arg value="nps"/>
|
||||
|
||||
<ini name="memory_limit" value="64M"/>
|
||||
|
||||
<autoload>./vendor/autoload.php</autoload>
|
||||
|
||||
<file>./app/Models</file>
|
||||
<file>./config</file>
|
||||
<file>./database</file>
|
||||
<file>./helpers</file>
|
||||
<file>./lang</file>
|
||||
<file>./resources/views</file>
|
||||
<file>./routes</file>
|
||||
|
||||
<exclude-pattern>*/vendor/*</exclude-pattern>
|
||||
|
||||
<!-- Don't hide tokenizer exceptions -->
|
||||
<rule ref="Internal.Tokenizer.Exception">
|
||||
<type>error</type>
|
||||
</rule>
|
||||
|
||||
<!-- Include all sniffs in the PSR-2 standard -->
|
||||
<rule ref="PSR2">
|
||||
<exclude name="Generic.Files.LineLength.TooLong"/>
|
||||
</rule>
|
||||
</ruleset>
|
6
src/.well-known/security.txt
Normal file
6
src/.well-known/security.txt
Normal file
@ -0,0 +1,6 @@
|
||||
Contact: mailto:person@domain.com
|
||||
Contact: https://twitter.com/person
|
||||
Expires: 2024-09-14T14:00:00.000Z
|
||||
Encryption: https://keybase.io/person
|
||||
Encryption: https://domain.com/pgp-key.txt
|
||||
Preferred-Languages: en
|
26
src/CHANGELOG.md
Normal file
26
src/CHANGELOG.md
Normal file
@ -0,0 +1,26 @@
|
||||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
### Added
|
||||
-
|
||||
|
||||
### Changed
|
||||
-
|
||||
|
||||
### Removed
|
||||
-
|
||||
|
||||
|
||||
## [1.0.0] - 20XX-01-01
|
||||
### Added
|
||||
-
|
||||
|
||||
### Changed
|
||||
-
|
||||
|
||||
### Removed
|
||||
-
|
30
src/SECURITY.md
Normal file
30
src/SECURITY.md
Normal file
@ -0,0 +1,30 @@
|
||||
<!-- AUTO-GENERATED, DO NOT EDIT! -->
|
||||
<!-- Please edit the original at https://github.com/ory/meta/blob/master/templates/repository/common/SECURITY.md -->
|
||||
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
|
||||
- [Security Policy](#security-policy)
|
||||
- [Supported Versions](#supported-versions)
|
||||
- [Reporting a Vulnerability](#reporting-a-vulnerability)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
We release patches for security vulnerabilities. Which versions are eligible for
|
||||
receiving such patches depends on the CVSS v3.0 Rating:
|
||||
|
||||
| CVSS v3.0 | Supported Versions |
|
||||
| --------- | ----------------------------------------- |
|
||||
| 9.0-10.0 | Releases within the previous three months |
|
||||
| 4.0-8.9 | Most recent release |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Please report (suspected) security vulnerabilities to
|
||||
**[security@ory.sh](mailto:security@ory.sh)**. You will receive a response from
|
||||
us within 48 hours. If the issue is confirmed, we will release a patch as soon
|
||||
as possible depending on complexity but historically within a few days.
|
28
src/app/Actions/Chained/GenerateProfilePhoto.php
Normal file
28
src/app/Actions/Chained/GenerateProfilePhoto.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Chained;
|
||||
|
||||
use App\Models\User;
|
||||
use Closure;
|
||||
|
||||
class GenerateProfilePhoto
|
||||
{
|
||||
/**
|
||||
* Generates a profile photo for a user and saves it
|
||||
* to disk.
|
||||
*
|
||||
* @package App\Actions\Chained\GenerateProfilePhoto
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @param \Closure $next
|
||||
*
|
||||
* @return \App\Models\User
|
||||
*/
|
||||
public function __invoke(User $user, Closure $next): User
|
||||
{
|
||||
//
|
||||
|
||||
return $next($user);
|
||||
}
|
||||
}
|
62
src/app/Console/Commands/CreateUser.php
Normal file
62
src/app/Console/Commands/CreateUser.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class CreateUser extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'user:create {--e|email= : The email address of the user}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Create a new user';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$email = trim($this->option('email'));
|
||||
|
||||
$name = $this->ask("Please provide a name");
|
||||
$surname = $this->ask("Please provide a surname");
|
||||
|
||||
if (empty($email)) {
|
||||
$email = $this->ask("Please provide an email address");
|
||||
}
|
||||
|
||||
if (empty($password)) {
|
||||
// TODO: have a way to hide the input and do a confirm password input
|
||||
$password = $this->secret("Please provide a password");
|
||||
}
|
||||
|
||||
try {
|
||||
User::create([
|
||||
'name' => trim($name),
|
||||
'surname' => trim($surname),
|
||||
'email' => trim($email),
|
||||
'password' => Hash::make(trim($password)),
|
||||
]);
|
||||
|
||||
$this->info("$email created successfully.");
|
||||
return Command::SUCCESS;
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Unable to create your user.');
|
||||
$this->line($e->getMessage());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
@ -52,7 +52,7 @@ class ResetPassword extends Command
|
||||
$column = 'email';
|
||||
$value = $email;
|
||||
} else {
|
||||
$column = strtolower($this->choice('What column would you like to search by?', ['ID', 'Email']));
|
||||
$column = strtolower($this->choice('What database column would you like to search by?', ['ID', 'Email']));
|
||||
$value = $this->ask("Please provide an $column to search for");
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@ class ResetPassword extends Command
|
||||
try {
|
||||
$user->update(['password' => Hash::make($password)]);
|
||||
$this->info("User {$user->id} ({$user->email}) password update successful!");
|
||||
return 0;
|
||||
return Command::SUCCESS;
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Unable to set the password!');
|
||||
$this->line($e->getMessage());
|
||||
|
83
src/app/Console/Commands/TranslationCheckerCommand.php
Normal file
83
src/app/Console/Commands/TranslationCheckerCommand.php
Normal file
@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class TranslationCheckerCommand extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'i18n:check-json {--l|locale= : The source of truth locale}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Uses one JSON file as the source of truth to check other lang files against.';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$masterLocale = 'en';
|
||||
if (!empty($this->option('locale'))) {
|
||||
$masterLocale = trim($this->option('locale'));
|
||||
}
|
||||
|
||||
$langDir = base_path('lang');
|
||||
$langFiles = scandir($langDir);
|
||||
$bigCount = count($langFiles);
|
||||
for ($i = 0; $i < $bigCount; $i++) {
|
||||
if (! preg_match('/.*\.json$/', $langFiles[$i]) || "{$masterLocale}.json" === $langFiles[$i]) {
|
||||
unset($langFiles[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
$langFilesCount = count($langFiles);
|
||||
$this->info("Checking {$langFilesCount} file(s) against {$masterLocale}...");
|
||||
|
||||
$masterLocaleTranslations = translations(base_path("lang/{$masterLocale}.json"));
|
||||
|
||||
foreach ($langFiles as $localeFile) {
|
||||
$otherLocaleTranslations = translations(base_path("lang/{$localeFile}"));
|
||||
$counts = 0;
|
||||
$mergedTranslations = $this->recursiveMergeArray($masterLocaleTranslations, $otherLocaleTranslations, $counts);
|
||||
file_put_contents(base_path("lang/{$localeFile}"), json_encode($mergedTranslations, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT));
|
||||
$this->info("{$localeFile} had {$counts} missing translations.");
|
||||
}
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
|
||||
public function recursiveMergeArray(array $firstArray, array $secondArray, int &$counts)
|
||||
{
|
||||
$mergedArray = $secondArray;
|
||||
foreach ($firstArray as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
if (!array_key_exists($key, $secondArray)) {
|
||||
$mergedArray[$key] = $value;
|
||||
} else {
|
||||
$subDiff = $this->recursiveMergeArray($value, $secondArray[$key], $counts);
|
||||
if (!empty($subDiff)) {
|
||||
$mergedArray[$key] = $subDiff;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!array_key_exists($key, $secondArray)) {
|
||||
$counts++;
|
||||
$mergedArray[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $mergedArray;
|
||||
}
|
||||
}
|
@ -2,21 +2,14 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Inertia\Response;
|
||||
use Jenssegers\Agent\Agent;
|
||||
use Laravel\Fortify\Features;
|
||||
use Laravel\Jetstream\Http\Controllers\Inertia\Concerns\ConfirmsTwoFactorAuthentication;
|
||||
use Laravel\Jetstream\Http\Controllers\Inertia\UserProfileController as JetstreamUserProfileController;
|
||||
use Laravel\Jetstream\Jetstream;
|
||||
|
||||
class UserProfileController extends Controller
|
||||
class UserProfileController extends JetstreamUserProfileController
|
||||
{
|
||||
use ConfirmsTwoFactorAuthentication;
|
||||
|
||||
/**
|
||||
* Show the general profile settings screen.
|
||||
*
|
||||
@ -36,56 +29,4 @@ class UserProfileController extends Controller
|
||||
'timezones' => timezone_identifiers_list(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current sessions.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
public function sessions(Request $request): Collection
|
||||
{
|
||||
if (config('session.driver') !== 'database') {
|
||||
return collect();
|
||||
}
|
||||
|
||||
return collect(
|
||||
DB::connection(config('session.connection'))->table(config('session.table', 'sessions'))
|
||||
->where('user_id', $request->user()->getAuthIdentifier())
|
||||
->orderBy('last_activity', 'desc')
|
||||
->get()
|
||||
)->map(function ($session) use ($request) {
|
||||
$agent = $this->createAgent($session);
|
||||
|
||||
return (object) [
|
||||
'agent' => [
|
||||
'is_desktop' => $agent->isDesktop(),
|
||||
'platform' => $agent->platform(),
|
||||
'browser' => $agent->browser(),
|
||||
],
|
||||
'ip_address' => $session->ip_address,
|
||||
'is_current_device' => $session->id === $request->session()->getId(),
|
||||
'last_active' => Carbon::createFromTimestamp($session->last_activity)->diffForHumans(),
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new agent instance from the given session.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param mixed $session
|
||||
*
|
||||
* @return \Jenssegers\Agent\Agent
|
||||
*/
|
||||
protected function createAgent($session): Agent
|
||||
{
|
||||
return tap(new Agent, function ($agent) use ($session) {
|
||||
$agent->setUserAgent($session->user_agent);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
33
src/app/Http/Kernel.php
Normal file
33
src/app/Http/Kernel.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http;
|
||||
|
||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||
|
||||
class Kernel extends HttpKernel
|
||||
{
|
||||
//...
|
||||
|
||||
/**
|
||||
* The application's route middleware groups.
|
||||
*
|
||||
* @var array<string, array<int, class-string|string>>
|
||||
*/
|
||||
protected $middlewareGroups = [
|
||||
'web' => [
|
||||
//...
|
||||
\Illuminate\Session\Middleware\StartSession::class,
|
||||
\App\Http\Middleware\SetLocale::class,
|
||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||
//...
|
||||
],
|
||||
|
||||
'admin' => [
|
||||
//...
|
||||
\Laravel\Jetstream\Http\Middleware\ShareInertiaData::class,
|
||||
\App\Http\Middleware\SetLocale::class,
|
||||
\App\Http\Middleware\AuthorizeAdmin::class,
|
||||
//...
|
||||
],
|
||||
];
|
||||
}
|
@ -5,22 +5,20 @@ namespace App\Http\Middleware;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CheckCustomSessionData
|
||||
class AuthorizeAdmin
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
|
||||
*
|
||||
* @return mixed
|
||||
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
if ((! session()->has('thing') || empty(session('thing'))) && $request->user()) {
|
||||
session()->put('thing', $request->user()->thing);
|
||||
if ($request->user()->email !== env('ADMIN_EMAIL')) {
|
||||
abort(HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
return $next($request);
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Models\Language;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Middleware;
|
||||
|
||||
@ -41,19 +42,58 @@ class HandleInertiaRequests extends Middleware
|
||||
*/
|
||||
public function share(Request $request): array
|
||||
{
|
||||
$localeFields = ['locale_name', 'iso_code', 'name', 'localized_name'];
|
||||
$currentLocale = $request->session()->get('locale', null);
|
||||
if (is_null($currentLocale)) {
|
||||
$currentLocale = Language::where(['locale_name' => 'en', 'iso_code' => 'en_US'])->get($localeFields)[0]->toArray();
|
||||
$request->session()->put('locale', [
|
||||
'locale_name' => $currentLocale['locale_name'],
|
||||
'iso_code' => $currentLocale['iso_code'],
|
||||
'name' => $currentLocale['name'],
|
||||
'localized_name' => $currentLocale['localized_name'],
|
||||
]);
|
||||
}
|
||||
$localeFilePath = base_path("lang/{$currentLocale['locale_name']}.json");
|
||||
|
||||
$notifications = [];
|
||||
$notificationsCount = count($notifications);
|
||||
$unreadNotifications = false;
|
||||
if (! is_null($request->user())) {
|
||||
$notifications = $request->user()->notifications;
|
||||
$notificationsCount = count($notifications);
|
||||
for ($i = 0; $i < $notificationsCount; $i++) {
|
||||
$newData = $notifications[$i]->data;
|
||||
$createdAt = carbon($notifications[$i]->created_at);
|
||||
$dateFormat = 'F j';
|
||||
if (!$createdAt->is(gmdate('Y'))) {
|
||||
$dateFormat = 'F j, Y';
|
||||
}
|
||||
$newData['created_at_date'] = $createdAt->copy()->format($dateFormat);
|
||||
$newData['created_at_time'] = $createdAt->copy()->format('H:i');
|
||||
$notifications[$i]->data = $newData;
|
||||
}
|
||||
if (count($request->user()->unreadNotifications) > 0) {
|
||||
$unreadNotifications = true;
|
||||
}
|
||||
}
|
||||
|
||||
return array_merge(parent::share($request), [
|
||||
'app_name' => config('app.name'),
|
||||
$additionalData = [
|
||||
'appName' => config('app.name'),
|
||||
|
||||
'availableLocales' => Language::get($localeFields),
|
||||
'currentLocale' => $currentLocale,
|
||||
'language' => translations($localeFilePath),
|
||||
|
||||
'notifications' => $notifications,
|
||||
'unreadNotifications' => $unreadNotifications,
|
||||
]);
|
||||
];
|
||||
|
||||
if (! is_null($request->user())) {
|
||||
if ($request->user()->email === env('ADMIN_EMAIL')) {
|
||||
$additionalData['is_admin_user'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return array_merge(parent::share($request), $additionalData);
|
||||
}
|
||||
}
|
||||
|
29
src/app/Http/Middleware/SetLocale.php
Normal file
29
src/app/Http/Middleware/SetLocale.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class SetLocale
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @package App\Http\Middleware\SetLocale
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
|
||||
*
|
||||
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
if (session()->has('locale')) {
|
||||
app()->setLocale(session('locale')['locale']);
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
@ -29,6 +29,10 @@ class SuccessfulLogin
|
||||
public function handle(Login $event): void
|
||||
{
|
||||
Session::put('timezone_name', $event->user->timezone_name);
|
||||
|
||||
// TODO: this may need to be reworked so that the language is stored
|
||||
// in a cookie and attempted to be retrieved from there
|
||||
// first before pulling from the database.
|
||||
Session::put('language', $event->user->language->locale);
|
||||
|
||||
// Optionally log the info
|
||||
|
@ -3,7 +3,6 @@
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Traits\FormattedAddressTrait;
|
||||
use App\Models\Traits\HasUidTrait;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
@ -14,18 +13,11 @@ class Address extends Model
|
||||
{
|
||||
use FormattedAddressTrait;
|
||||
use HasFactory;
|
||||
use HasUidTrait;
|
||||
use Prunable;
|
||||
|
||||
/** @var string */
|
||||
protected $table = 'addresses';
|
||||
|
||||
/** @var string */
|
||||
protected $keyType = 'string';
|
||||
|
||||
/** @var bool */
|
||||
public $incrementing = false;
|
||||
|
||||
/** @var array */
|
||||
protected $fillable = [
|
||||
'addressable_type',
|
||||
|
51
src/app/Models/Casts/MoneyCastable.php
Normal file
51
src/app/Models/Casts/MoneyCastable.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Casts;
|
||||
|
||||
use Brick\Money\Money;
|
||||
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class MoneyCastable implements CastsAttributes
|
||||
{
|
||||
/**
|
||||
* Get the value from the database and modify it to casted type
|
||||
* before returning.
|
||||
*
|
||||
* @package App\Models\Casts\MoneyCastable
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model The Model that is being used
|
||||
* @param string $key The attribute key
|
||||
* @param mixed $value The value stored in the database
|
||||
* @param array $attributes The array of model attributes
|
||||
*
|
||||
* @return \Brick\Money\Money
|
||||
*/
|
||||
public function get(Model $model, string $key, $value, array $attributes): Money
|
||||
{
|
||||
return Money::ofMinor($attributes['amount'], $attributes['currency']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the data .
|
||||
*
|
||||
* @package App\Models\Casts\MoneyCastable
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model The Model that is being used
|
||||
* @param string $key The attribute key
|
||||
* @param mixed $value The value stored in the database
|
||||
* @param array $attributes The array of model attributes
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function set(Model $model, string $key, $value, array $attributes)
|
||||
{
|
||||
if (! $value instanceof Money) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
return $value->getMinorAmount()->toInt();
|
||||
}
|
||||
}
|
117
src/app/Models/Language.php
Normal file
117
src/app/Models/Language.php
Normal file
@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Prunable;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Language extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use Prunable;
|
||||
use SoftDeletes;
|
||||
|
||||
/** @var string */
|
||||
protected $table = 'languages';
|
||||
|
||||
/** @var array<int,string> */
|
||||
protected $fillable = [
|
||||
'locale_name',
|
||||
'iso_code',
|
||||
'name',
|
||||
'localized_name',
|
||||
];
|
||||
|
||||
/**
|
||||
|--------------------------------------------------------------------------
|
||||
| Class Constants
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
*/
|
||||
|
||||
//
|
||||
|
||||
/**
|
||||
|--------------------------------------------------------------------------
|
||||
| Custom/Private Methods
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the prunable model query.
|
||||
*
|
||||
* @package App\Models\Language
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function prunable(): Builder
|
||||
{
|
||||
//return static::where('deleted_at', '<=', now()->subMonth());
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the model for pruning.
|
||||
*
|
||||
* @package App\Models\Language
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function pruning(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
|--------------------------------------------------------------------------
|
||||
| Accessors
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
*/
|
||||
|
||||
//
|
||||
|
||||
/**
|
||||
|--------------------------------------------------------------------------
|
||||
| Mutators
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
*/
|
||||
|
||||
//
|
||||
|
||||
/**
|
||||
|--------------------------------------------------------------------------
|
||||
| Scopes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
*/
|
||||
|
||||
//
|
||||
|
||||
/**
|
||||
|--------------------------------------------------------------------------
|
||||
| Relationships
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
*/
|
||||
|
||||
/**
|
||||
* User relationship.
|
||||
*
|
||||
* @package App\Models\Language
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function users(): HasMany
|
||||
{
|
||||
return $this->hasMany(User::class);
|
||||
}
|
||||
}
|
23
src/app/Models/Scopes/OnTeamScope.php
Normal file
23
src/app/Models/Scopes/OnTeamScope.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Scopes;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Scope;
|
||||
|
||||
class OnTeamScope implements Scope
|
||||
{
|
||||
/**
|
||||
* Apply the scope to a given Eloquent query builder.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $builder
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function apply(Builder $builder, Model $model): void
|
||||
{
|
||||
$builder->where('current_team_id', );
|
||||
}
|
||||
}
|
@ -2,19 +2,24 @@
|
||||
|
||||
namespace App\Models\Traits;
|
||||
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
|
||||
trait FormattedPhoneTrait
|
||||
{
|
||||
/**
|
||||
* Format a phone number to be human readable.
|
||||
*
|
||||
* @package Namespace\App\Contact
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @return string
|
||||
* @return void
|
||||
*/
|
||||
public function getPhoneNumberAttribute(): string
|
||||
protected function phoneNumber(): Attribute
|
||||
{
|
||||
$phoneLength = strlen($this->phone);
|
||||
$phoneNumber = preg_replace('//', '', $this->phone);
|
||||
return Attribute::make(
|
||||
get: function (mixed $value, array $attributes) {
|
||||
$phoneLength = strlen($attributes['phone_number']);
|
||||
$phoneNumber = preg_replace('/[^0-9]/', '', $attributes['phone_number']);
|
||||
|
||||
if ($phoneLength > 10) {
|
||||
$countryCode = substr($phoneNumber, 0, $phoneLength - 10);
|
||||
@ -37,19 +42,10 @@ trait FormattedPhoneTrait
|
||||
}
|
||||
|
||||
return $phoneNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all non-numeric characters from the phone number.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPhoneNumberAttribute($value): void
|
||||
{
|
||||
$this->attributes['phone'] = preg_replace('/[^0-9]/', '', $value);
|
||||
},
|
||||
set: function (mixed $value) {
|
||||
return preg_replace('/[^0-9]/', '', $value);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
88
src/app/Models/Traits/HasProfilePhoto.php
Normal file
88
src/app/Models/Traits/HasProfilePhoto.php
Normal file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace Laravel\Jetstream;
|
||||
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
trait HasProfilePhoto
|
||||
{
|
||||
/**
|
||||
* Update the user's profile photo.
|
||||
*
|
||||
* @param \Illuminate\Http\UploadedFile $photo
|
||||
* @param string $storagePath
|
||||
* @return void
|
||||
*/
|
||||
public function updateProfilePhoto(UploadedFile $photo, $storagePath = 'profile-photos')
|
||||
{
|
||||
tap($this->profile_photo_path, function ($previous) use ($photo, $storagePath) {
|
||||
$this->forceFill([
|
||||
'profile_photo_path' => $photo->storePublicly(
|
||||
$storagePath, ['disk' => $this->profilePhotoDisk()]
|
||||
),
|
||||
])->save();
|
||||
|
||||
if ($previous) {
|
||||
Storage::disk($this->profilePhotoDisk())->delete($previous);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the user's profile photo.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function deleteProfilePhoto()
|
||||
{
|
||||
if (! Features::managesProfilePhotos()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_null($this->profile_photo_path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Storage::disk($this->profilePhotoDisk())->delete($this->profile_photo_path);
|
||||
|
||||
$this->forceFill([
|
||||
'profile_photo_path' => null,
|
||||
])->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URL to the user's profile photo.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Casts\Attribute
|
||||
*/
|
||||
public function profilePhotoUrl(): Attribute
|
||||
{
|
||||
return Attribute::get(function () {
|
||||
return $this->profile_photo_path
|
||||
? Storage::disk($this->profilePhotoDisk())->url($this->profile_photo_path)
|
||||
: $this->defaultProfilePhotoUrl();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default profile photo URL if no profile photo has been uploaded.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function defaultProfilePhotoUrl()
|
||||
{
|
||||
return 'https://avatars.test/avatar?size=256';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the disk that profile photos should be stored on.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function profilePhotoDisk()
|
||||
{
|
||||
return isset($_ENV['VAPOR_ARTIFACT_NAME']) ? 's3' : config('jetstream.profile_photo_disk', 'public');
|
||||
}
|
||||
}
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Traits\HasUidTrait;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Prunable;
|
||||
@ -20,7 +19,6 @@ class User extends Authenticatable
|
||||
use HasFactory;
|
||||
use HasProfilePhoto;
|
||||
use HasTeams;
|
||||
use HasUidTrait;
|
||||
use Notifiable;
|
||||
use Prunable;
|
||||
use TwoFactorAuthenticatable;
|
||||
@ -39,6 +37,7 @@ class User extends Authenticatable
|
||||
'name',
|
||||
'surname',
|
||||
'timezone_name',
|
||||
'language_id',
|
||||
'current_team_id',
|
||||
'profile_photo_path',
|
||||
'email',
|
||||
@ -185,4 +184,17 @@ class User extends Authenticatable
|
||||
{
|
||||
return $this->morphOne(Address::class, 'addressable');
|
||||
}
|
||||
|
||||
/**
|
||||
* Language relationship.
|
||||
*
|
||||
* @package App\Models\User
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function language(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Language::class);
|
||||
}
|
||||
}
|
||||
|
125
src/app/Observers/UserObserver.php
Normal file
125
src/app/Observers/UserObserver.php
Normal file
@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
namespace App\Observers;
|
||||
|
||||
use App\Models\User;
|
||||
|
||||
class UserObserver
|
||||
{
|
||||
/**
|
||||
* Handle events after all transactions are committed.
|
||||
*
|
||||
* @package App\Observers\UserObserver
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $afterCommit = true;
|
||||
|
||||
/**
|
||||
* Handle the User "retrieve" event.
|
||||
*
|
||||
* @package App\Observers\UserObserver
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function retrieved(User $user)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the User "saving" event.
|
||||
* This may apply as either a create
|
||||
* or an update event.
|
||||
*
|
||||
* @package App\Observers\UserObserver
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function saving(User $user)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the User "created" event.
|
||||
*
|
||||
* @package App\Observers\UserObserver
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function created(User $user)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the User "updated" event.
|
||||
*
|
||||
* @package App\Observers\UserObserver
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function updated(User $user)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the User "deleted" event.
|
||||
*
|
||||
* @package App\Observers\UserObserver
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function deleted(User $user)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the User "restored" event.
|
||||
*
|
||||
* @package App\Observers\UserObserver
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function restored(User $user)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the User "forceDeleted" event.
|
||||
*
|
||||
* @package App\Observers\UserObserver
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function forceDeleted(User $user)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@ class AppServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
//
|
||||
Model::preventSilentlyDiscardingAttributes($this->app->isLocal());
|
||||
}
|
||||
|
||||
/**
|
||||
|
31
src/app/Providers/AuthServiceProvider.php
Normal file
31
src/app/Providers/AuthServiceProvider.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Models\PersonalAccessToken;
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
use Laravel\Sanctum\Sanctum;
|
||||
|
||||
class AuthServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The policy mappings for the application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $policies = [
|
||||
//...
|
||||
];
|
||||
|
||||
/**
|
||||
* Register any authentication / authorization services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->registerPolicies();
|
||||
|
||||
Sanctum::usePersonalAccessTokenModel(PersonalAccessToken::class);
|
||||
}
|
||||
}
|
@ -1,4 +1,94 @@
|
||||
{
|
||||
//...
|
||||
"require": {
|
||||
//..
|
||||
|
||||
// Laravel provided stuff
|
||||
"laravel/cashier": "", // fluent interface to Stripe
|
||||
"laravel/horizon": "", // dashboard and configuration for Laravel queues
|
||||
"laravel/telescope": "", // debugging tool from Laravel for Laravel
|
||||
|
||||
"laravel/scout": "", // full-text search to Eloquent models
|
||||
"meilisearch/meilisearch-php": "", // use Meilisearch for Scout funtionality
|
||||
"http-interop/http-factory-guzzle": "", // use Meilisearch for Scout funtionality
|
||||
"dwarfdk/laravel-meilitools": "", // additional tools for Meilisearch (https://github.com/dwarfhq/laravel-meilitools)
|
||||
|
||||
// Roles / Permissions
|
||||
"spatie/laravel-permission": "",
|
||||
"zizaco/entrust": "",
|
||||
|
||||
// Security stuff
|
||||
"abuseipdb/laravel": "", // API to check an IP for abusive behavior with option to report IP for abusive behavior
|
||||
|
||||
// Options/Flags
|
||||
"spatie/laravel-model-flags": "", // add a simple true/false flag to any model
|
||||
|
||||
// SDKs
|
||||
"aws/aws-sdk-php-laravel": "", // interact with S3 or S3-compatible storage
|
||||
"propaganistas/laravel-phone": "", // uses Google's libphonenumber API to (try to) sanely handle phone numbers
|
||||
"vladimir-yuldashev/laravel-queue-rabbitmq": "", // Interface with RabbitMQ servers
|
||||
"grimzy/laravel-mysql-spatial": "", // Adds Geo-spatial column support for MySQL (WARNING: only works with Laravel v8 or lower)
|
||||
"matanyadaev/laravel-eloquent-spatial": "", // Adds Geo-spatial column support for MySQL
|
||||
"irazasyed/telegram-bot-sdk": "", // unofficial Telegram Bot API/SDK
|
||||
"torann/geoip": "", // support for multiple GeoIP services
|
||||
"coderjerk/nasa-php": "", // NASA API integrations
|
||||
|
||||
// File management
|
||||
"czim/laravel-paperclip": "", // attach files to an Eloquent model
|
||||
|
||||
// Media (image/video/audio) Management
|
||||
"intervention/image": "", // image manipulation
|
||||
"intervention/imagecache": "", // caching for intervention/image
|
||||
"spatie/laravel-medialibrary": "", // manage a small or large amount of media smartly
|
||||
"spatie/laravel-image-optimizer": "", // optimize png, jpg, svg, and gif
|
||||
"unisharp/laravel-filemanager": "", // File manager (including uploads)
|
||||
"pbmedia/laravel-ffmpeg": "", // Integration with FFMpeg
|
||||
"maestroerror/php-heic-to-jpg": "", // Use Go(?) to convert HEIC/HEIF to JPEG
|
||||
|
||||
// Localization
|
||||
"mcamara/laravel-localization": "", // localization that also handles route translations
|
||||
"barryvdh/laravel-translation-manager": "", // self-evident
|
||||
|
||||
// PDF stuff
|
||||
"creagia/laravel-sign-pad": "", // allows signatures on documents
|
||||
|
||||
// Geo-spatial
|
||||
"brick/geo": "", // GIS geometry library
|
||||
"stevebauman/location": "", // retrieve a user's location by their IP address
|
||||
|
||||
// Websockets
|
||||
"beyondcode/laravel-websockets": "", // use websockets in the same laravel application
|
||||
|
||||
// Helpers/Generators
|
||||
"infyomlabs/laravel-calendar-events": "", // help with handling future dates without having to store records in the database
|
||||
"lab404/laravel-impersonate": "", // Impersonate other users in your application
|
||||
"kitloong/laravel-migrations-generator": "", // create migrations based on your existing database
|
||||
"spatie/laravel-sitemap": "", // generate site maps
|
||||
"artesaos/seotools": "", // automatic SEO tools
|
||||
"eumanito/php-capitalize-names": "", // Capitalize names with funky rules
|
||||
"robinvdvleuten/ulid": "", // Universally Unique Lexicographically Sortable Identifier (ULID)
|
||||
|
||||
// Others/uncategorized
|
||||
"appstract/laravel-opcache": "", // provides artisan commands to interact with opcache (not sure if site-specific)
|
||||
"brick/math": "", // arbitrary-precision arithmetic library
|
||||
"brick/money": "", // money and currency library
|
||||
|
||||
"protonemedia/laravel-verify-new-email": "", // must verify new email address before email update will be completed
|
||||
"protonemedia/inertiajs-tables-laravel-query-builder": "", // datatables for InertiaJS/Vue and Laravel
|
||||
|
||||
"ikechukwukalu/requirepin": "", // use password/pin protection for routes
|
||||
|
||||
"doctrine/dbal": "", // useful for artisan db:show
|
||||
},
|
||||
"require-dev": {
|
||||
//..
|
||||
"itsgoingd/clockwork": "",
|
||||
"phpstan/phpstan": "",
|
||||
"psalm/plugin-laravel": "",
|
||||
"vimeo/psalm": "",
|
||||
"slevomat/coding-standard": "^8.5", // additional coding standards to match Laravel
|
||||
"squizlabs/php_codesniffer": "^3.7"
|
||||
},
|
||||
//...
|
||||
"autoload": {
|
||||
//...,
|
||||
|
@ -2,9 +2,11 @@
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\Language;
|
||||
use App\Models\Team;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
use Laravel\Jetstream\Features;
|
||||
|
||||
@ -31,6 +33,7 @@ class UserFactory extends Factory
|
||||
'email' => $this->faker->unique()->safeEmail(),
|
||||
'email_verified_at' => now(),
|
||||
'timezone_name' => $this->faker->timezone(),
|
||||
'language_id' => Language::all()->random()->id,
|
||||
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
|
||||
'remember_token' => Str::random(10),
|
||||
];
|
||||
@ -69,4 +72,25 @@ class UserFactory extends Factory
|
||||
'ownedTeams'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the user should have an avatar image.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function withAvatar()
|
||||
{
|
||||
if (! Features::enabled(Features::profilePhotos())) {
|
||||
return $this->state([]);
|
||||
}
|
||||
|
||||
$imageUrl = 'https://avatars.test/';
|
||||
$imageContents = file_get_contents($imageUrl);
|
||||
$imageName = md5($imageContents) . '.jpg';
|
||||
Storage::put("public/avatars/{$imageName}", $imageContents);
|
||||
|
||||
return $this->state([
|
||||
'profile_photo_path' => "avatars/{$imageName}"
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('languages', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('locale_name')->index();
|
||||
$table->string('iso_code')->unique();
|
||||
$table->string('name');
|
||||
$table->string('localized_name');
|
||||
$table->timestamp('created_at')->useCurrent();
|
||||
$table->timestamp('updated_at')->nullable()->useCurrentOnUpdate();
|
||||
$table->softDeletes();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('languages');
|
||||
}
|
||||
};
|
@ -14,13 +14,14 @@ return new class extends Migration
|
||||
public function up()
|
||||
{
|
||||
Schema::create('users', function (Blueprint $table) {
|
||||
$table->string('id', 64)->primary();
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->string('surname');
|
||||
$table->string('email')->unique();
|
||||
$table->timestamp('email_verified_at')->nullable();
|
||||
$table->string('timezone_name')->default('UTC');
|
||||
$table->string('current_team_id', 64)->nullable();
|
||||
$table->foreignId('language_id');
|
||||
$table->foreignId('current_team_id')->nullable();
|
||||
$table->string('profile_photo_path', 2048)->nullable();
|
||||
$table->string('password');
|
||||
$table->text('two_factor_secret')->nullable();
|
@ -15,12 +15,12 @@ return new class extends Migration
|
||||
{
|
||||
Schema::create('sessions', function (Blueprint $table) {
|
||||
$table->string('id')->primary();
|
||||
$table->string('user_id', 64);
|
||||
$table->foreignId('user_id')->nullable()->index();
|
||||
$table->string('ip_address', 45)->nullable();
|
||||
$table->text('user_agent')->nullable()->index();
|
||||
$table->text('payload');
|
||||
$table->integer('last_activity')->index();
|
||||
$table->timestamp('vr_last_activity_at')->virtualAs('FROM_UNIXTIME(last_activity)');
|
||||
$table->timestamp('vrt_last_activity_at')->virtualAs('FROM_UNIXTIME(last_activity)');
|
||||
});
|
||||
}
|
||||
|
@ -14,8 +14,8 @@ return new class extends Migration
|
||||
public function up()
|
||||
{
|
||||
Schema::create('addresses', function (Blueprint $table) {
|
||||
$table->string('id', 64)->primary();
|
||||
$table->uuidMorphs('addressable');
|
||||
$table->id();
|
||||
$table->morphs('addressable');
|
||||
$table->string('street');
|
||||
$table->string('unit')->nullable();
|
||||
$table->string('city');
|
||||
|
@ -14,16 +14,11 @@ return new class extends Migration
|
||||
public function up()
|
||||
{
|
||||
Schema::create('address_user', function (Blueprint $table) {
|
||||
$table->string('address_id', 64);
|
||||
$table->string('user_id', 64);
|
||||
|
||||
$table->foreign('address_id')
|
||||
->references('id')->on('addresss')
|
||||
->cascadeOnUpdate()->cascadeOnDelete();
|
||||
|
||||
$table->foreign('user_id')
|
||||
->references('id')->on('users')
|
||||
->cascadeOnUpdate()->cascadeOnDelete();
|
||||
$table->id();
|
||||
$table->foreignId('address_id')->constrained()->cascadeOnUpdate()->cascadeOnDelete();
|
||||
$table->foreignId('user_id')->constrained()->cascadeOnUpdate()->cascadeOnDelete();
|
||||
$table->timestamp('created_at')->useCurrent();
|
||||
$table->timestamp('updated_at')->nullable()->useCurrentOnUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -16,55 +16,18 @@ class LanguageSeeder extends Seeder
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$languages = [
|
||||
[
|
||||
'iso_code' => 'en_US',
|
||||
'locale' => 'en',
|
||||
'country_code' => 'US',
|
||||
'title' => 'English',
|
||||
'title_localized' => 'English',
|
||||
],
|
||||
[
|
||||
'iso_code' => 'de_DE',
|
||||
'locale' => 'de',
|
||||
'country_code' => 'DE',
|
||||
'title' => 'German',
|
||||
'title_localized' => 'Deutsch',
|
||||
],
|
||||
[
|
||||
'iso_code' => 'fr_FR',
|
||||
'locale' => 'fr',
|
||||
'country_code' => 'FR',
|
||||
'title' => 'French',
|
||||
'title_localized' => 'Français',
|
||||
],
|
||||
[
|
||||
'iso_code' => 'es_SP',
|
||||
'locale' => 'es',
|
||||
'country_code' => 'SP',
|
||||
'title' => 'Spanish',
|
||||
'title_localized' => 'Español',
|
||||
],
|
||||
[
|
||||
'iso_code' => 'jp_JP',
|
||||
'locale' => 'jp',
|
||||
'country_code' => 'JP',
|
||||
'title' => 'Japanese',
|
||||
'title_localized' => '日本',
|
||||
],
|
||||
[
|
||||
'iso_code' => 'zh_TW',
|
||||
'locale' => 'zh',
|
||||
'country_code' => 'TW',
|
||||
'title' => 'Taiwanese',
|
||||
'title_localized' => '台湾',
|
||||
],
|
||||
$languagesData = [
|
||||
['locale' => 'en', 'iso_code' => 'en_US', 'name' => 'English', 'localized_name' => 'English (US)'],
|
||||
['locale' => 'de', 'iso_code' => 'de_DE', 'name' => 'German', 'localized_name' => 'Deutsch'],
|
||||
['locale' => 'fr', 'iso_code' => 'fr_FR', 'name' => 'French', 'localized_name' => 'Français'],
|
||||
['locale' => 'jp', 'iso_code' => 'jp_JP', 'name' => 'Japanese', 'localized_name' => '日本'],
|
||||
['locale' => 'mx', 'iso_code' => 'es_MX', 'name' => 'Spanish', 'localized_name' => 'Español'],
|
||||
];
|
||||
|
||||
$startTime = Carbon::now();
|
||||
$offset = 0;
|
||||
|
||||
foreach ($languages as $language) {
|
||||
foreach ($languagesData as $language) {
|
||||
$datetime = $startTime->copy()->addMinute($offset)->toDateTimeString();
|
||||
$offset++;
|
||||
$language['created_at'] = $datetime;
|
||||
|
@ -1,5 +1,15 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Cache TTL (Time-To-Live)
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here is a collection of intervals in seconds that are commong to use
|
||||
| when caching, but written as a more human-friendly phrase.
|
||||
|
|
||||
*/
|
||||
|
||||
define('CACHE_TTL_FIVE_MINUTES', 300);
|
||||
define('CACHE_TTL_FIFTEEN_MINUTES', 900);
|
||||
|
||||
|
@ -1,5 +1,15 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| HTTP Status Codes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here is a collection of HTTP status codes and a corresponding string
|
||||
| that is human-friendly and easy to remember.
|
||||
|
|
||||
*/
|
||||
|
||||
$httpCodes = [
|
||||
// 100's (informational / "hold on")
|
||||
100 => 'HTTP_CONTINUE',
|
||||
@ -14,6 +24,7 @@ $httpCodes = [
|
||||
204 => 'HTTP_NO_CONTENT',
|
||||
205 => 'HTTP_RESET_CONTENT',
|
||||
206 => 'HTTP_PARTIAL_CONTENT',
|
||||
218 => 'HTTP_THIS_IS_FINE', // Apache specific
|
||||
|
||||
// 300's (redirections / "go away")
|
||||
300 => 'HTTP_MULTIPLE_CHOICE',
|
||||
@ -47,12 +58,14 @@ $httpCodes = [
|
||||
236 => 'HTTP_UPGRADE_REQUIRED',
|
||||
428 => 'HTTP_PRECONDITION_REQUIRED',
|
||||
429 => 'HTTP_TOO_MANY_REQUESTS',
|
||||
444 => 'HTTP_NO_RESPONSE', // Nginx specific, used internally to return no info and close connection immediately
|
||||
451 => 'HTTP_GAG_ORDER',
|
||||
|
||||
// 500's (server-level problem, process died or configuration is incorrect / "server screwed up")
|
||||
500 => 'HTTP_SERVER_ERROR',
|
||||
501 => 'HTTP_NOT_IMPLEMENTED',
|
||||
503 => 'HTTP_UNAVAILABLE',
|
||||
529 => 'HTTP_SITE_OVERLOADED', // Qualys specific, API response to indicate server resources are over capacity
|
||||
530 => 'HTTP_SUSPENDED',
|
||||
];
|
||||
|
||||
|
76
src/helpers/functions/date_and_time.php
Normal file
76
src/helpers/functions/date_and_time.php
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
|--------------------------------------------------------------------------
|
||||
| Global Date/Time Functions
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This is a home for functions that don't belong to any one class and
|
||||
| that should be available anywhere in the application.
|
||||
|
|
||||
*/
|
||||
|
||||
if (! function_exists('secondsToTime')) {
|
||||
/**
|
||||
* Convert seconds to hour:minute:second with hour being omitted
|
||||
* if the amount of seconds is less than an hour.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param datatype $seconds
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function secondsToTime($seconds): string
|
||||
{
|
||||
$seconds = intval($seconds);
|
||||
if ($seconds >= 3600) {
|
||||
return sprintf('%02d:%02d:%02d', ($seconds / 3600), (($seconds / 60) % 60), ($seconds % 60));
|
||||
}
|
||||
|
||||
return sprintf('%02d:%02d', (($seconds / 60) % 60), ($seconds % 60));
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('minutesToTime')) {
|
||||
/**
|
||||
* Convert minutes to HH:MM
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param datatype $minutes
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function minutesToTime($minutes): string
|
||||
{
|
||||
$minutes = intval($minutes);
|
||||
|
||||
return sprintf('%d:%02d', floor($minutes / 60), ($minutes % 60));
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('jddayofweek')) {
|
||||
/**
|
||||
* Returns the day of the week. Can return a string or an integer depending on the mode.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param int|null $intDay
|
||||
* @param int $mode
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function jddayofweek(?int $intDay = null, int $mode = 0): string
|
||||
{
|
||||
if (is_null($intDay)) {
|
||||
$intDay = date('l');
|
||||
}
|
||||
|
||||
if ($mode === 0) {
|
||||
return $intDay;
|
||||
}
|
||||
|
||||
return ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][$intDay];
|
||||
}
|
||||
}
|
233
src/helpers/functions/distances.php
Normal file
233
src/helpers/functions/distances.php
Normal file
@ -0,0 +1,233 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
|--------------------------------------------------------------------------
|
||||
| Global Distance Functions
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This is a home for functions that don't belong to any one class and
|
||||
| that should be available anywhere in the application.
|
||||
|
|
||||
*/
|
||||
|
||||
/**
|
||||
|--------------------------------------------------------------------------
|
||||
| Metric functions
|
||||
|--------------------------------------------------------------------------
|
||||
| Functions that convert from metric to imperial or from a smaller
|
||||
| metric unit to a larger one.
|
||||
|
|
||||
*/
|
||||
|
||||
if (! function_exists('centimeters2Inches')) {
|
||||
/**
|
||||
* Convert from centimeters to inches.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param float|int|string $centimeters
|
||||
* @param int $precision
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
function centimeters2Inches($centimeters, int $preceision = 1): float
|
||||
{
|
||||
return round(($centimeters / 2.54), $preceision);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('centimeters2Feet')) {
|
||||
/**
|
||||
* Convert from centimeters to inches.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param float|int|string $centimeters
|
||||
* @param int $precision
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
function centimeters2Feet($centimeters, int $preceision = 1): float
|
||||
{
|
||||
return round((($centimeters / 2.54) * 12), $preceision);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('centimeters2Meters')) {
|
||||
/**
|
||||
* Convert from centimeters to meters.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param float|int|string $centimeters
|
||||
* @param int $precision
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
function centimeters2Meters($centimeters, int $preceision = 1): float
|
||||
{
|
||||
return round(($centimeters / 100), $preceision);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('centimeters2Yards')) {
|
||||
/**
|
||||
* Convert from centimeters to yards.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param float|int|string $centimeters
|
||||
* @param int $precision
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
function centimeters2Yards($centimeters, int $preceision = 1): float
|
||||
{
|
||||
return round(($centimeters / 91.44), $preceision);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('meters2Miles')) {
|
||||
/**
|
||||
* Convert from meters to miles.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param float|int|string $meters
|
||||
* @param int $precision
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
function meters2Miles($meters, int $preceision = 1): float
|
||||
{
|
||||
return round(($meters * 0.00062137), $preceision);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('kilometers2Miles')) {
|
||||
/**
|
||||
* Convert from kilometers to meters.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param float|int|string $kilometers
|
||||
* @param int $precision
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
function kilometers2Miles($kilometers, int $preceision = 1): float
|
||||
{
|
||||
return round(($kilometers * 1.609), $preceision);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('meters2Kilometers')) {
|
||||
/**
|
||||
* Convert from meters to kilometers.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param float|int|string $meters
|
||||
* @param int $precision
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
function meters2Kilometers($meters, int $preceision = 1): float
|
||||
{
|
||||
return round(($meters / 1000), $preceision);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('millimeters2Inches')) {
|
||||
/**
|
||||
* Convert from millimeters to inches.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param float|int|string $millimeters
|
||||
* @param int $precision
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
function millimeters2Inches($millimeters, int $preceision = 1): float
|
||||
{
|
||||
return round(($millimeters / 25.4), $preceision);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|--------------------------------------------------------------------------
|
||||
| Imperial functions
|
||||
|--------------------------------------------------------------------------
|
||||
| Functions that convert from imperial to metric or from a smaller
|
||||
| imperial unit to a larger one.
|
||||
|
|
||||
*/
|
||||
|
||||
if (! function_exists('inches2Millimeters')) {
|
||||
/**
|
||||
* Convert from inches to millimeters.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param float|int|string $inches
|
||||
* @param int $precision
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
function inches2Millimeters($inches, int $preceision = 1): float
|
||||
{
|
||||
return round(($inches * 2.54), $preceision);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('inches2Meters')) {
|
||||
/**
|
||||
* Convert from inches to meters.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param float|int|string $inches
|
||||
* @param int $precision
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
function inches2Meters($inches, int $preceision = 1): float
|
||||
{
|
||||
return round(($inches / 39.37), $preceision);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('inches2Yards')) {
|
||||
/**
|
||||
* Convert from inches to yards.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param float|int|string $inches
|
||||
* @param int $precision
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
function inches2Yards($inches, int $preceision = 1): float
|
||||
{
|
||||
return round(($inches / 36), $preceision);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('inches2Feet')) {
|
||||
/**
|
||||
* Convert from inches to feet.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param float|int|string $inches
|
||||
* @param int $precision
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
function inches2Feet($inches, int $preceision = 1): float
|
||||
{
|
||||
return round(($inches * 12), $preceision);
|
||||
}
|
||||
}
|
29
src/helpers/functions/strings.php
Normal file
29
src/helpers/functions/strings.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
// phpcs:ignore
|
||||
/**
|
||||
|--------------------------------------------------------------------------
|
||||
| Global String Functions
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This is a home for functions that don't belong to any one class and
|
||||
| that should be available anywhere in the application.
|
||||
|
|
||||
*/
|
||||
|
||||
if (! function_exists('snake2Title')) {
|
||||
/**
|
||||
* Convert a snake case string to a title with spaces
|
||||
* and every word capitalized.
|
||||
*
|
||||
* @param string $snakeSlug A snake case string, commonly a slug
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function snake2Title(string $snakeSlug): string
|
||||
{
|
||||
$output = preg_replace('/\_/', ' ', $snakeSlug);
|
||||
return ucwords($output);
|
||||
}
|
||||
}
|
45
src/helpers/functions/temperatures.php
Normal file
45
src/helpers/functions/temperatures.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
|--------------------------------------------------------------------------
|
||||
| Global Temperature Functions
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This is a home for functions that don't belong to any one class and
|
||||
| that should be available anywhere in the application.
|
||||
|
|
||||
*/
|
||||
|
||||
if (! function_exists('celsius2Fahrenheit')) {
|
||||
/**
|
||||
* Convert from celsius to fahrenheit.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param float|int|string $celsius
|
||||
* @param int $precision
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
function celsius2Fahrenheit($celsius, int $preceision = 0): float
|
||||
{
|
||||
return round((($celsius * (9/5)) + 32), $preceision);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('fahrenheit2Celsius')) {
|
||||
/**
|
||||
* Convert from fahrenheit to celsius.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param float|int|string $fahrenheit
|
||||
* @param int $precision
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
function fahrenheit2Celsius($fahrenheit, int $preceision = 1): float
|
||||
{
|
||||
return round(($fahrenheit - 32 * (5/9)), $preceision);
|
||||
}
|
||||
}
|
@ -1,20 +1,86 @@
|
||||
<?php
|
||||
|
||||
if (! function_exists('snake2Title')) {
|
||||
require_once "functions/strings.php";
|
||||
require_once "functions/date_and_time.php";
|
||||
require_once "functions/distances.php";
|
||||
require_once "functions/temperatures.php";
|
||||
|
||||
/**
|
||||
|--------------------------------------------------------------------------
|
||||
| Global Functions
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This is a home for functions that don't belong to any one class and
|
||||
| that should be available anywhere in the application.
|
||||
|
|
||||
*/
|
||||
|
||||
if (! function_exists('clamp')) {
|
||||
/**
|
||||
* Convert a snake case string to a title with spaces
|
||||
* and every word capitalized.
|
||||
* Ensure a numerical value is between two bounds.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param string $stakeSlug A snake case string, commonly a slug
|
||||
* @param int|float|string $number The value to be clamped between two other values.
|
||||
* @param int|float|string $minNumber The miminum value for clamping bounds.
|
||||
* @param int|float|string $maxNumber The maximum value for clamping bounds.
|
||||
*
|
||||
* @throws \Exception
|
||||
*
|
||||
* @return int|float
|
||||
*/
|
||||
function clamp($number, $minNumber, $maxNumber)
|
||||
{
|
||||
if (! is_numeric($number)) {
|
||||
throw new Exception('Clamp number must be numeric in value.');
|
||||
}
|
||||
|
||||
if (! is_numeric($minNumber)) {
|
||||
throw new Exception('Clamped minimum number must be numeric in value.');
|
||||
}
|
||||
|
||||
if (! is_numeric($maxNumber)) {
|
||||
throw new Exception('Clamped maximum number must be numeric in value.');
|
||||
}
|
||||
|
||||
$returnValue = $number;
|
||||
if ($minNumber >= $number) {
|
||||
$returnValue = $minNumber;
|
||||
}
|
||||
|
||||
if ($maxNumber <= $number) {
|
||||
$returnValue = $maxNumber;
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('humanBytes')) {
|
||||
/**
|
||||
* Convert bytes to a human-friendly format.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param int|string $number
|
||||
* @param int|string|null $precision Decimal places to show (optional)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function snake2Title(string $snakeSlug): string
|
||||
function humanBytes($number, $precision = null): string
|
||||
{
|
||||
$output = preg_replace('/\_/', ' ', $snakeSlug);
|
||||
return ucwords($output);
|
||||
if (empty($number)) {
|
||||
return '0 B';
|
||||
}
|
||||
|
||||
static $units = ['B', 'KB', 'MB', 'GB'];
|
||||
static $bytePreceision = [0, 0, 1, 2];
|
||||
$divisor = 1024;
|
||||
|
||||
for ($i = 0; $number / $divisor >= 0.9 && $i < 4; $i++) {
|
||||
$number /= $divisor;
|
||||
}
|
||||
return round($number, is_null($precision) ? $bytePreceision[$i] : $precision) . $units[$i];
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,28 +106,50 @@ if (! function_exists('carbon')) {
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('jddayofweek')) {
|
||||
if (! function_exists('translations')) {
|
||||
/**
|
||||
* Returns the day of the week. Can return a string or an integer depending on the mode.
|
||||
* Loads translations from a JSON file.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param int|null $intDay
|
||||
* @param int $mode
|
||||
* @param string $jsonFilePath
|
||||
*
|
||||
* @return string
|
||||
* @return array
|
||||
*/
|
||||
function jddayofweek(?int $intDay = null, int $mode = 0): string
|
||||
function translations(string $jsonFilePath): array
|
||||
{
|
||||
if (is_null($intDay)) {
|
||||
$intDay = date('l');
|
||||
if (! file_exists($jsonFilePath)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if ($mode === 0) {
|
||||
return $intDay;
|
||||
$payload = [];
|
||||
$jsonData = json_decode(file_get_contents($jsonFilePath), true);
|
||||
|
||||
switch (json_last_error()) {
|
||||
case JSON_ERROR_NONE:
|
||||
$payload = $jsonData;
|
||||
break;
|
||||
case JSON_ERROR_DEPTH:
|
||||
throw new \Exception('Maximum stack depth exceeded');
|
||||
break;
|
||||
case JSON_ERROR_STATE_MISMATCH:
|
||||
throw new \Exception('Underflow or the modes mismatch');
|
||||
break;
|
||||
case JSON_ERROR_CTRL_CHAR:
|
||||
throw new \Exception('Unexpected control character found');
|
||||
break;
|
||||
case JSON_ERROR_SYNTAX:
|
||||
throw new \Exception('Syntax error, malformed JSON');
|
||||
break;
|
||||
case JSON_ERROR_UTF8:
|
||||
throw new \Exception('Malformed UTF-8 characters, possibly incorrectly encoded');
|
||||
break;
|
||||
default:
|
||||
throw new \Exception('Generic or unknown JSON error while decoding');
|
||||
break;
|
||||
}
|
||||
|
||||
return ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][$intDay];
|
||||
return $payload;
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,25 +172,25 @@ if (! function_exists('is_serialized')) {
|
||||
}
|
||||
|
||||
$data = trim($data);
|
||||
if ('N;' === $data) {
|
||||
if ($data === 'N;') {
|
||||
return true;
|
||||
}
|
||||
if (strlen($data) < 4) {
|
||||
return false;
|
||||
}
|
||||
if (':' !== $data[1]) {
|
||||
if ($data[1] !== ':') {
|
||||
return false;
|
||||
}
|
||||
if ($strict) {
|
||||
$lastc = substr($data, -1);
|
||||
if (';' !== $lastc && '}' !== $lastc) {
|
||||
if ($lastc !== ';' && $lastc !== '}') {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$semicolon = strpos($data, ';');
|
||||
$brace = strpos($data, '}');
|
||||
// Either ; or } must exist.
|
||||
if (!$semicolon && !$brace) {
|
||||
if (! $semicolon && ! $brace) {
|
||||
return false;
|
||||
}
|
||||
// But neither must be in the first X characters.
|
||||
@ -117,10 +205,10 @@ if (! function_exists('is_serialized')) {
|
||||
switch ($token) {
|
||||
case 's':
|
||||
if ($strict) {
|
||||
if ('"' !== substr($data, -2, 1)) {
|
||||
if (substr($data, -2, 1) !== '"') {
|
||||
return false;
|
||||
}
|
||||
} elseif (!strpos($data, '"')) {
|
||||
} elseif (! strpos($data, '"')) {
|
||||
return false;
|
||||
}
|
||||
// Or else fall through.
|
||||
@ -148,132 +236,19 @@ if (! function_exists('maybe_unserialize')) {
|
||||
*
|
||||
* @param mixed $data
|
||||
*
|
||||
* @return mixed
|
||||
* @return array|string|bool
|
||||
*/
|
||||
function maybe_unserialize($data)
|
||||
{
|
||||
if (is_serialized($data)) { // Don't attempt to unserialize data that wasn't serialized going in.
|
||||
return @unserialize(trim($data));
|
||||
if (! is_string($data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$data = trim($data);
|
||||
// Don't attempt to unserialize data that wasn't serialized going in.
|
||||
if (is_serialized($data)) {
|
||||
return unserialize(trim($data));
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('cel2Fah')) {
|
||||
/**
|
||||
* Convert from celsius to fahrenheit.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param float|int|string $celsius
|
||||
* @param int $precision
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
function cel2Fah($celsius, int $preceision = 0): float
|
||||
{
|
||||
return round((($celsius * (9/5)) + 32), $preceision);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('fah2Cel')) {
|
||||
/**
|
||||
* Convert from fahrenheit to celsius.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param float|int|string $fahrenheit
|
||||
* @param int $precision
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
function fah2Cel($fahrenheit, int $preceision = 1): float
|
||||
{
|
||||
return round(($fahrenheit - 32 * (5/9)), $preceision);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('meters2Miles')) {
|
||||
/**
|
||||
* Convert from meters to miles.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param float|int|string $meters
|
||||
* @param int $precision
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
function meters2Miles($meters, int $preceision = 1): float
|
||||
{
|
||||
return round(($meters * 0.00062137), $preceision);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('kilometers2Miles')) {
|
||||
/**
|
||||
* Convert from kilometers to meters.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param float|int|string $kilometers
|
||||
* @param int $precision
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
function kilometers2Miles($kilometers, int $preceision = 1): float
|
||||
{
|
||||
return round(($kilometers * 1.609), $preceision);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('m2Km')) {
|
||||
/**
|
||||
* Convert from meters to kilometers.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param float|int|string $meters
|
||||
* @param int $precision
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
function m2Km($meters, int $preceision = 1): float
|
||||
{
|
||||
return round(($meters / 1000), $preceision);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('mm2Inches')) {
|
||||
/**
|
||||
* Convert from milimeters to inches.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param float|int|string $milimeters
|
||||
* @param int $precision
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
function mm2Inches($milimeters, int $preceision = 1): float
|
||||
{
|
||||
return round(($milimeters / 25.4), $preceision);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('pa2Mbar')) {
|
||||
/**
|
||||
* Convert from pascals to milibars.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param float|int|string $pascals
|
||||
* @param int $precision
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
function pa2Mbar($pascals, int $preceision = 1): float
|
||||
{
|
||||
return round(($pascals / 100), $preceision);
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,88 @@
|
||||
{
|
||||
"key": "translation that has :attribute in the string."
|
||||
"titles": {
|
||||
"welcome": "Welcome",
|
||||
"dashboard": "Dashboard",
|
||||
"secure_area": "Secure Area",
|
||||
"forgot_password": "Forgot Password",
|
||||
"my_profile": "My Profile",
|
||||
"edit_profile": "Edit Profile",
|
||||
"log_in": "Log In To Your Account",
|
||||
"register": "Register A New Account",
|
||||
"reset_password": "Reset Password",
|
||||
"two_factor_confirmation": "Two-factor Confirmation",
|
||||
"verify_email": "Email Verification"
|
||||
},
|
||||
"labels": {
|
||||
"type": "Type",
|
||||
"none": "None",
|
||||
"title": "Title",
|
||||
"name": "Name",
|
||||
"created_at": "Created At",
|
||||
"updated_at": "Updated At",
|
||||
"actions": "Actions",
|
||||
"email": "Email",
|
||||
"timezone_name": "Timezone",
|
||||
"language": "Language",
|
||||
"password": "Password",
|
||||
"confirm_password": "Confirm Password",
|
||||
"current_password": "Current Password",
|
||||
"remember_me": "Remember me",
|
||||
"first_name": "First Name",
|
||||
"last_name": "Surname",
|
||||
"forgot_password": "Forgot your password?",
|
||||
"already_registered": "Already registered?",
|
||||
"code": "Code",
|
||||
"recovery_code": "Recovery Code",
|
||||
"use_recovery_code": "Use a recovery code",
|
||||
"use_authentication_code": "Use an authentication code",
|
||||
"email_verification": "Email Verification",
|
||||
"user": "User",
|
||||
"optional": "optional"
|
||||
},
|
||||
"actions": {
|
||||
"save": "Save",
|
||||
"update": "Update",
|
||||
"edit": "Edit",
|
||||
"delete": "Delete",
|
||||
"confirm": "Confirm",
|
||||
"log_in": "Log in",
|
||||
"log_out": "Log Out",
|
||||
"register": "Register",
|
||||
"edit_profile": "Edit Profile",
|
||||
"confirm_password": "Confirm Password",
|
||||
"reset_password": "Reset Password",
|
||||
"email_password_reset_link": "Email Password Reset Link",
|
||||
"resend_verification_email": "Resend Verification Email"
|
||||
},
|
||||
"nav": {
|
||||
"manage_team": "Manage Team",
|
||||
"team_settings": "Team Settings",
|
||||
"create_new_team": "Create New Team",
|
||||
"switch_teams": "Switch Teams",
|
||||
"manage_account": "Manage Account",
|
||||
"profile": "My Profile",
|
||||
"admin_settings": "Admin Settings",
|
||||
"api_tokens": "API Tokens"
|
||||
},
|
||||
"pagination": {
|
||||
"show_from_to_count": "Showing :from to :to of :count results"
|
||||
},
|
||||
"notifications": {
|
||||
"saved": "Saved.",
|
||||
"verified": "Verified!",
|
||||
"unverified": "Unverified.",
|
||||
"new_email_verification_sent": "A new verification link has been sent to the email address you provided in your profile settings."
|
||||
},
|
||||
"pages": {
|
||||
"profile": {
|
||||
"titles": {
|
||||
"update_password": "Update Your Password"
|
||||
},
|
||||
"text_blocks": {
|
||||
"unverified_message": "Please verify your account.",
|
||||
"verified_message": "Thanks for being amazing.",
|
||||
"secure_password": "Ensure your account is using a long, random password to stay secure."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,34 +1,32 @@
|
||||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "npm run development",
|
||||
"development": "mix",
|
||||
"watch": "mix watch",
|
||||
"watch-poll": "mix watch -- --watch-options-poll=1000",
|
||||
"hot": "mix watch --hot",
|
||||
"prod": "npm run production",
|
||||
"production": "mix --production"
|
||||
"dev": "vite",
|
||||
"build": "vite build"
|
||||
},
|
||||
"devDependencies": {
|
||||
"laravel-mix": "^6.0.43",
|
||||
"@vitejs/plugin-vue": "^3.0.0",
|
||||
"laravel-vite-plugin": "^0.6.0",
|
||||
"postcss": "^8.4.14",
|
||||
"postcss-import": "^14.1.0",
|
||||
"vue-loader": "^17.0.0"
|
||||
"vite": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@inertiajs/inertia": "^0.11.0",
|
||||
"@inertiajs/inertia-vue3": "^0.6.0",
|
||||
"@inertiajs/progress": "^0.2.7",
|
||||
"@tailwindcss/forms": "^0.5.2",
|
||||
"@tailwindcss/aspect-ratio": "^0.4.0",
|
||||
"@tailwindcss/line-clamp": "^0.4.2",
|
||||
"@tailwindcss/typography": "^0.5.2",
|
||||
"@vueuse/core": "^8.5.0",
|
||||
"@vueuse/core": "^8.7.5",
|
||||
"apexcharts": "^3.35.5",
|
||||
"axios": "^0.27.2",
|
||||
"dayjs": "^1.11.2",
|
||||
"daisyui": "^2.29.0",
|
||||
"dayjs": "^1.11.3",
|
||||
"laravel-vue-i18n": "^1.4.3",
|
||||
"lodash": "^4.17.21",
|
||||
"notiwind": "^1.2.5",
|
||||
"tailwindcss": "^3.0.24",
|
||||
"tailwindcss": "^3.1.0",
|
||||
"tailwindcss-neu": "^0.2.1",
|
||||
"vue": "^3.2.36"
|
||||
"vue": "^3.2.37"
|
||||
}
|
||||
}
|
218
src/phpcs.xml
Normal file
218
src/phpcs.xml
Normal file
@ -0,0 +1,218 @@
|
||||
<?xml version="1.0"?>
|
||||
<ruleset name="Laravel Standards" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="vendor/squizlabs/php_codesniffer/phpcs.xsd">
|
||||
<description>PHP Codesniffer ruleset to follow Laravel's coding style</description>
|
||||
<rule ref="Generic.Classes.DuplicateClassName">
|
||||
<exclude name="Generic.CodeAnalysis.EmptyStatement.DetectedIf"/>
|
||||
</rule>
|
||||
<rule ref="Generic.CodeAnalysis.EmptyStatement"/>
|
||||
<rule ref="Generic.CodeAnalysis.ForLoopShouldBeWhileLoop"/>
|
||||
<rule ref="Generic.CodeAnalysis.ForLoopWithTestFunctionCall"/>
|
||||
<rule ref="Generic.CodeAnalysis.JumbledIncrementer"/>
|
||||
<rule ref="Generic.CodeAnalysis.UnconditionalIfStatement"/>
|
||||
<rule ref="Generic.CodeAnalysis.UnnecessaryFinalModifier"/>
|
||||
<rule ref="Generic.CodeAnalysis.UnusedFunctionParameter">
|
||||
<exclude-pattern>/app/Http/Resources/*\.php</exclude-pattern>
|
||||
<exclude-pattern>/routes/*\.php</exclude-pattern>
|
||||
</rule>
|
||||
<rule ref="Generic.CodeAnalysis.UselessOverridingMethod"/>
|
||||
<rule ref="Generic.Commenting.DocComment">
|
||||
<exclude name="Generic.Commenting.DocComment.ContentAfterOpen"/>
|
||||
<exclude name="Generic.Commenting.DocComment.ContentBeforeClose"/>
|
||||
<exclude name="Generic.Commenting.DocComment.MissingShort"/>
|
||||
<exclude name="Generic.Commenting.DocComment.NonParamGroup"/>
|
||||
<exclude name="Generic.Commenting.DocComment.ParamNotFirst"/>
|
||||
<exclude name="Generic.Commenting.DocComment.TagValueIndent"/>
|
||||
</rule>
|
||||
<rule ref="Generic.ControlStructures.InlineControlStructure"/>
|
||||
<rule ref="Generic.Files.ByteOrderMark"/>
|
||||
<rule ref="Generic.Files.LineEndings">
|
||||
<exclude name="Generic.Files.LineEndings.InvalidEOLChar"/>
|
||||
</rule>
|
||||
<rule ref="Generic.Formatting.DisallowMultipleStatements"/>
|
||||
<rule ref="Generic.Formatting.SpaceAfterCast"/>
|
||||
<rule ref="Generic.Formatting.SpaceAfterNot"/>
|
||||
<rule ref="Generic.Functions.CallTimePassByReference"/>
|
||||
<rule ref="Generic.Functions.FunctionCallArgumentSpacing"/>
|
||||
<rule ref="Generic.Functions.OpeningFunctionBraceBsdAllman"/>
|
||||
<rule ref="Generic.Metrics.CyclomaticComplexity">
|
||||
<properties>
|
||||
<property name="complexity" value="20"/>
|
||||
<property name="absoluteComplexity" value="25"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="Generic.Metrics.NestingLevel">
|
||||
<properties>
|
||||
<property name="nestingLevel" value="5"/>
|
||||
<property name="absoluteNestingLevel" value="15"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="Generic.NamingConventions.ConstructorName"/>
|
||||
<rule ref="Generic.NamingConventions.CamelCapsFunctionName">
|
||||
<exclude-pattern>/helpers/global_functions\.php</exclude-pattern>
|
||||
<exclude-pattern>/tests/*</exclude-pattern>
|
||||
</rule>
|
||||
<rule ref="Generic.PHP.LowerCaseConstant"/>
|
||||
<rule ref="Generic.PHP.DeprecatedFunctions"/>
|
||||
<rule ref="Generic.PHP.DisallowShortOpenTag"/>
|
||||
<rule ref="Generic.PHP.ForbiddenFunctions"/>
|
||||
<rule ref="Generic.PHP.NoSilencedErrors"/>
|
||||
<rule ref="Generic.WhiteSpace.DisallowTabIndent"/>
|
||||
<rule ref="Generic.WhiteSpace.ScopeIndent">
|
||||
<properties>
|
||||
<property name="indent" value="4"/>
|
||||
<property name="tabIndent" value="true"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="MySource.PHP.EvalObjectFactory"/>
|
||||
<rule ref="PSR1.Classes.ClassDeclaration"/>
|
||||
<rule ref="PSR1.Files.SideEffects">
|
||||
<exclude-pattern>*/artisan</exclude-pattern>
|
||||
</rule>
|
||||
<rule ref="PSR1.Files.SideEffects"/>
|
||||
<rule ref="PSR2.Classes.ClassDeclaration"/>
|
||||
<rule ref="PSR2.Classes.PropertyDeclaration"/>
|
||||
<rule ref="PSR2.ControlStructures.ControlStructureSpacing"/>
|
||||
<rule ref="PSR2.ControlStructures.ElseIfDeclaration"/>
|
||||
<rule ref="PSR2.ControlStructures.SwitchDeclaration"/>
|
||||
<rule ref="PSR2.Files.EndFileNewline"/>
|
||||
<rule ref="PSR2.Methods.MethodDeclaration"/>
|
||||
<rule ref="PSR2.Namespaces.NamespaceDeclaration"/>
|
||||
<rule ref="PSR2.Namespaces.UseDeclaration"/>
|
||||
<rule ref="PSR1">
|
||||
<exclude-pattern>*\.php</exclude-pattern>
|
||||
<exclude name="PSR1.Methods.CamelCapsMethodName.NotCamelCaps"/>
|
||||
|
||||
<exclude-pattern>database/*</exclude-pattern>
|
||||
</rule>
|
||||
<rule ref="PSR2">
|
||||
<exclude name="PSR2.ControlStructures.SwitchDeclaration.BodyOnNextLineCASE" />
|
||||
<properties>
|
||||
<property name="lineLimit" value="130"/>
|
||||
<property name="absoluteLineLimit" value="135"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="Squiz.Arrays.ArrayDeclaration">
|
||||
<exclude name="Squiz.Arrays.ArrayDeclaration.ValueNotAligned" />
|
||||
<exclude name="Squiz.Arrays.ArrayDeclaration.KeyNotAligned" />
|
||||
<exclude name="Squiz.Arrays.ArrayDeclaration.DoubleArrowNotAligned" />
|
||||
<exclude name="Squiz.Arrays.ArrayDeclaration.ValueNotAligned" />
|
||||
<exclude name="Squiz.Arrays.ArrayDeclaration.CloseBraceNotAligned" />
|
||||
<exclude name="Squiz.Arrays.ArrayDeclaration.ValueNoNewline" />
|
||||
<exclude name="Squiz.Arrays.ArrayDeclaration.MultiLineNotAllowed" />
|
||||
<exclude name="Squiz.Arrays.ArrayDeclaration.SingleLineNotAllowed" />
|
||||
<exclude name="Squiz.Arrays.ArrayDeclaration.IndexNoNewline" />
|
||||
<exclude name="Squiz.Arrays.ArrayDeclaration.CloseBraceNewLine" />
|
||||
<exclude name="Squiz.Functions.MultiLineFunctionDeclaration.NewlineBeforeOpenBrace" />
|
||||
<exclude name="Squiz.Arrays.ArrayDeclaration.NoKeySpecified" />
|
||||
<exclude name="Squiz.Arrays.ArrayDeclaration.KeySpecified" />
|
||||
</rule>
|
||||
<rule ref="Squiz.PHP.CommentedOutCode"/>
|
||||
<rule ref="Squiz.PHP.DisallowSizeFunctionsInLoops"/>
|
||||
<rule ref="Squiz.PHP.DiscouragedFunctions">
|
||||
<properties>
|
||||
<property name="error" value="true"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="Squiz.PHP.Eval"/>
|
||||
<rule ref="Squiz.PHP.GlobalKeyword"/>
|
||||
<rule ref="Squiz.PHP.Heredoc"/>
|
||||
<rule ref="Squiz.PHP.LowercasePHPFunctions"/>
|
||||
<rule ref="Squiz.PHP.NonExecutableCode"/>
|
||||
<rule ref="Squiz.Scope.MemberVarScope"/>
|
||||
<rule ref="Squiz.Scope.MethodScope"/>
|
||||
<rule ref="Squiz.Scope.StaticThisUsage"/>
|
||||
<rule ref="Squiz.WhiteSpace.CastSpacing"/>
|
||||
<rule ref="Squiz.WhiteSpace.ControlStructureSpacing"/>
|
||||
<rule ref="Squiz.WhiteSpace.LanguageConstructSpacing"/>
|
||||
<rule ref="Squiz.WhiteSpace.LogicalOperatorSpacing"/>
|
||||
<rule ref="Squiz.WhiteSpace.ObjectOperatorSpacing">
|
||||
<properties>
|
||||
<property name="ignoreNewlines" value="true"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="Squiz.WhiteSpace.OperatorSpacing">
|
||||
<properties>
|
||||
<property name="ignoreNewlines" value="true"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="Squiz.WhiteSpace.PropertyLabelSpacing"/>
|
||||
<rule ref="Squiz.WhiteSpace.ScopeClosingBrace"/>
|
||||
<rule ref="Squiz.WhiteSpace.ScopeKeywordSpacing"/>
|
||||
<rule ref="Squiz.WhiteSpace.SemicolonSpacing"/>
|
||||
<rule ref="Squiz.Strings.DoubleQuoteUsage.NotRequired"/>
|
||||
<rule ref="Zend.Files.ClosingTag"/>
|
||||
|
||||
<!-- Custom Sniffs -->
|
||||
<rule ref="SlevomatCodingStandard.Namespaces.UnusedUses">
|
||||
<properties>
|
||||
<property name="searchAnnotations" value="true"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="SlevomatCodingStandard.Namespaces.UseFromSameNamespace"/>
|
||||
<rule ref="SlevomatCodingStandard.Namespaces.AlphabeticallySortedUses">
|
||||
<properties>
|
||||
<property name="caseSensitive" value="true"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="SlevomatCodingStandard.Namespaces.FullyQualifiedClassNameInAnnotation"/>
|
||||
<rule ref="SlevomatCodingStandard.PHP.UselessSemicolon"/>
|
||||
<rule ref="SlevomatCodingStandard.Classes.MethodSpacing">
|
||||
<properties>
|
||||
<property name="minLinesCount" value="1"/>
|
||||
<property name="maxLinesCount" value="1"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="SlevomatCodingStandard.Functions.ArrowFunctionDeclaration">
|
||||
<properties>
|
||||
<property name="spacesCountAfterKeyword" value="1"/>
|
||||
<property name="spacesCountBeforeArrow" value="1"/>
|
||||
<property name="spacesCountAfterArrow" value="1"/>
|
||||
<property name="allowMultiLine" value="true"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="SlevomatCodingStandard.Files.TypeNameMatchesFileName">
|
||||
<properties>
|
||||
<property name="rootNamespaces" type="array">
|
||||
<element key="app" value="App"/>
|
||||
<element key="database/factories" value="Database\Factories"/>
|
||||
<element key="database/seeders" value="Database\Seeders"/>
|
||||
<element key="tests" value="Tests"/>
|
||||
</property>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="SlevomatCodingStandard.Files.TypeNameMatchesFileName">
|
||||
<exclude-pattern>/database/schema/*</exclude-pattern>
|
||||
<exclude-pattern>/database/migrations/*</exclude-pattern>
|
||||
</rule>
|
||||
|
||||
<file>./app</file>
|
||||
<file>./config</file>
|
||||
<file>./resources</file>
|
||||
<file>./routes</file>
|
||||
<file>./tests</file>
|
||||
|
||||
<exclude-pattern>*/.phpstorm.meta.php</exclude-pattern>
|
||||
<exclude-pattern>*/_ide_helper.php</exclude-pattern>
|
||||
<exclude-pattern>*/cache/*</exclude-pattern>
|
||||
<exclude-pattern>*/config/*</exclude-pattern>
|
||||
<exclude-pattern>*/database/*</exclude-pattern>
|
||||
<exclude-pattern>*/docs/*</exclude-pattern>
|
||||
<exclude-pattern>*/migrations/*</exclude-pattern>
|
||||
<exclude-pattern>*/storage/*</exclude-pattern>
|
||||
<exclude-pattern>*/public/index.php</exclude-pattern>
|
||||
<exclude-pattern>*/resources/lang/*</exclude-pattern>
|
||||
<exclude-pattern>*/vendor/*</exclude-pattern>
|
||||
<exclude-pattern>*/*.js</exclude-pattern>
|
||||
<exclude-pattern>*/*.css</exclude-pattern>
|
||||
<exclude-pattern>*/*.xml</exclude-pattern>
|
||||
<exclude-pattern>*/*.blade.php</exclude-pattern>
|
||||
<exclude-pattern>*/autoload.php</exclude-pattern>
|
||||
<exclude-pattern>*/Console/Kernel.php</exclude-pattern>
|
||||
<exclude-pattern>*/Exceptions/Handler.php</exclude-pattern>
|
||||
<exclude-pattern>*/Http/Kernel.php</exclude-pattern>
|
||||
|
||||
<arg name="basepath" value="."/>
|
||||
<arg name="colors"/>
|
||||
<arg value="nspv"/>
|
||||
<ini name="memory_limit" value="128M"/>
|
||||
</ruleset>
|
6
src/postcss.config.js
Normal file
6
src/postcss.config.js
Normal file
@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
};
|
BIN
src/public/fonts/BarlowCondensed/BarlowCondensed-Bold.woff2
Normal file
BIN
src/public/fonts/BarlowCondensed/BarlowCondensed-Bold.woff2
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/public/fonts/BarlowCondensed/BarlowCondensed-Italic.woff2
Normal file
BIN
src/public/fonts/BarlowCondensed/BarlowCondensed-Italic.woff2
Normal file
Binary file not shown.
BIN
src/public/fonts/BarlowCondensed/BarlowCondensed-Medium.woff2
Normal file
BIN
src/public/fonts/BarlowCondensed/BarlowCondensed-Medium.woff2
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/public/fonts/BarlowCondensed/BarlowCondensed-Regular.woff2
Normal file
BIN
src/public/fonts/BarlowCondensed/BarlowCondensed-Regular.woff2
Normal file
Binary file not shown.
BIN
src/public/fonts/BarlowCondensed/BarlowCondensed-SemiBold.woff2
Normal file
BIN
src/public/fonts/BarlowCondensed/BarlowCondensed-SemiBold.woff2
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/public/fonts/Lato/Lato-Bold.woff2
Normal file
BIN
src/public/fonts/Lato/Lato-Bold.woff2
Normal file
Binary file not shown.
BIN
src/public/fonts/Lato/Lato-BoldItalic.woff2
Normal file
BIN
src/public/fonts/Lato/Lato-BoldItalic.woff2
Normal file
Binary file not shown.
BIN
src/public/fonts/Lato/Lato-Italic.woff2
Normal file
BIN
src/public/fonts/Lato/Lato-Italic.woff2
Normal file
Binary file not shown.
BIN
src/public/fonts/Lato/Lato-Regular.woff2
Normal file
BIN
src/public/fonts/Lato/Lato-Regular.woff2
Normal file
Binary file not shown.
BIN
src/public/fonts/Lato/Lato-Semibold.woff2
Normal file
BIN
src/public/fonts/Lato/Lato-Semibold.woff2
Normal file
Binary file not shown.
BIN
src/public/fonts/Lato/Lato-SemiboldItalic.woff2
Normal file
BIN
src/public/fonts/Lato/Lato-SemiboldItalic.woff2
Normal file
Binary file not shown.
94
src/public/fonts/Lato/OFL.txt
Normal file
94
src/public/fonts/Lato/OFL.txt
Normal file
@ -0,0 +1,94 @@
|
||||
Copyright (c) 2010-2015, Łukasz Dziedzic (dziedzic@typoland.com),
|
||||
with Reserved Font Name Lato.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
BIN
src/public/fonts/Montserrat/Montserrat-Bold.woff2
Normal file
BIN
src/public/fonts/Montserrat/Montserrat-Bold.woff2
Normal file
Binary file not shown.
BIN
src/public/fonts/Montserrat/Montserrat-BoldItalic.woff2
Normal file
BIN
src/public/fonts/Montserrat/Montserrat-BoldItalic.woff2
Normal file
Binary file not shown.
BIN
src/public/fonts/Montserrat/Montserrat-Italic.woff2
Normal file
BIN
src/public/fonts/Montserrat/Montserrat-Italic.woff2
Normal file
Binary file not shown.
BIN
src/public/fonts/Montserrat/Montserrat-Medium.woff2
Normal file
BIN
src/public/fonts/Montserrat/Montserrat-Medium.woff2
Normal file
Binary file not shown.
BIN
src/public/fonts/Montserrat/Montserrat-MediumItalic.woff2
Normal file
BIN
src/public/fonts/Montserrat/Montserrat-MediumItalic.woff2
Normal file
Binary file not shown.
BIN
src/public/fonts/Montserrat/Montserrat-Regular.woff2
Normal file
BIN
src/public/fonts/Montserrat/Montserrat-Regular.woff2
Normal file
Binary file not shown.
BIN
src/public/fonts/Montserrat/Montserrat-SemiBold.woff2
Normal file
BIN
src/public/fonts/Montserrat/Montserrat-SemiBold.woff2
Normal file
Binary file not shown.
BIN
src/public/fonts/Montserrat/Montserrat-SemiBoldItalic.woff2
Normal file
BIN
src/public/fonts/Montserrat/Montserrat-SemiBoldItalic.woff2
Normal file
Binary file not shown.
93
src/public/fonts/Nunito/OFL.txt
Normal file
93
src/public/fonts/Nunito/OFL.txt
Normal file
@ -0,0 +1,93 @@
|
||||
Copyright 2014 The Nunito Project Authors (https://github.com/googlefonts/nunito)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
93
src/public/fonts/PoiretOne/OFL.txt
Normal file
93
src/public/fonts/PoiretOne/OFL.txt
Normal file
@ -0,0 +1,93 @@
|
||||
Copyright (c) 2011, Denis Masharov (denis.masharov@gmail.com)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
95
src/public/fonts/Raleway/OFL.txt
Normal file
95
src/public/fonts/Raleway/OFL.txt
Normal file
@ -0,0 +1,95 @@
|
||||
Copyright (c) 2010, Matt McInerney (matt@pixelspread.com),
|
||||
Copyright (c) 2011, Pablo Impallari (www.impallari.com|impallari@gmail.com),
|
||||
Copyright (c) 2011, Rodrigo Fuenzalida (www.rfuenzalida.com|hello@rfuenzalida.com), with Reserved Font Name Raleway
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
BIN
src/public/fonts/Raleway/Raleway-Bold.woff2
Normal file
BIN
src/public/fonts/Raleway/Raleway-Bold.woff2
Normal file
Binary file not shown.
BIN
src/public/fonts/Raleway/Raleway-BoldItalic.woff2
Normal file
BIN
src/public/fonts/Raleway/Raleway-BoldItalic.woff2
Normal file
Binary file not shown.
BIN
src/public/fonts/Raleway/Raleway-Italic-VariableFont_wght.woff2
Normal file
BIN
src/public/fonts/Raleway/Raleway-Italic-VariableFont_wght.woff2
Normal file
Binary file not shown.
BIN
src/public/fonts/Raleway/Raleway-Italic.woff2
Normal file
BIN
src/public/fonts/Raleway/Raleway-Italic.woff2
Normal file
Binary file not shown.
BIN
src/public/fonts/Raleway/Raleway-Regular.woff2
Normal file
BIN
src/public/fonts/Raleway/Raleway-Regular.woff2
Normal file
Binary file not shown.
BIN
src/public/fonts/Raleway/Raleway-SemiBold.woff2
Normal file
BIN
src/public/fonts/Raleway/Raleway-SemiBold.woff2
Normal file
Binary file not shown.
BIN
src/public/fonts/Raleway/Raleway-SemiBoldItalic.woff2
Normal file
BIN
src/public/fonts/Raleway/Raleway-SemiBoldItalic.woff2
Normal file
Binary file not shown.
BIN
src/public/fonts/Raleway/Raleway-VariableFont_wght.woff2
Normal file
BIN
src/public/fonts/Raleway/Raleway-VariableFont_wght.woff2
Normal file
Binary file not shown.
202
src/public/fonts/RobotoMono/LICENSE.txt
Normal file
202
src/public/fonts/RobotoMono/LICENSE.txt
Normal file
@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
93
src/public/fonts/VictorMono/LICENSE
Normal file
93
src/public/fonts/VictorMono/LICENSE
Normal file
@ -0,0 +1,93 @@
|
||||
Copyright (c) 2021, Rune Bjørnerås (https://github.com/rubjo)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
@ -6,6 +6,13 @@
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
/** **/
|
||||
@keyframes disco {
|
||||
from { transform: translateY(-50%) rotate(0deg); }
|
||||
to { transform: translateY(-50%) rotate(360deg); }
|
||||
}
|
||||
/** **/
|
||||
|
||||
.animate-removeRow {
|
||||
animation-name: removeRow;
|
||||
animation-fill-mode: forwards;
|
||||
|
59
src/resources/css/animations/bubbleup.css
Normal file
59
src/resources/css/animations/bubbleup.css
Normal file
@ -0,0 +1,59 @@
|
||||
/**
|
||||
<div class="bubbles-container">
|
||||
<div class="bubbles">
|
||||
<span class="animate-bubble" style="style="--i:(random value between 1 and 15);"></span>
|
||||
<span class="animate-bubble" style="style="--i:(random value between 1 and 15);"></span>
|
||||
<span class="animate-bubble" style="style="--i:(random value between 1 and 15);"></span>
|
||||
<span class="animate-bubble" style="style="--i:(random value between 1 and 15);"></span>
|
||||
<span class="animate-bubble" style="style="--i:(random value between 1 and 15);"></span>
|
||||
</div>
|
||||
</div>
|
||||
**/
|
||||
|
||||
.bubbles-container {
|
||||
background: hsl(216, 57.1%, 11%);
|
||||
min-height: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.bubbles {
|
||||
position: relative;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.bubbles span {
|
||||
border-radius: 50%;
|
||||
height: 30px;
|
||||
margin: 0 4px;
|
||||
position: relative;
|
||||
width: 30px;
|
||||
/*animation: bubble 15s linear infinite;*/
|
||||
/*animation-name: bubbleup;
|
||||
animation-timing-function: linear;
|
||||
animation-iteration-count: infinite;
|
||||
animation-duration: calc(300s / calc(var(--i) * 5));*/
|
||||
}
|
||||
|
||||
.bubbles span:nth-child(odd) {
|
||||
background: hsl(191, 66.8%, 58.6%);
|
||||
box-shadow: 0 0 0 10px hsla(191, 66.8%, 58.6%, 0.3), 0 0 50px hsl(191, 66.8%, 58.6%), 0 0 100px hsl(191, 66.8%, 58.6%);
|
||||
}
|
||||
|
||||
.bubbles span:nth-child(even) {
|
||||
background: hsl(339, 100%, 58.8%);
|
||||
box-shadow: 0 0 0 10px hsla(339, 100%, 58.8%, 0.3), 0 0 50px hsl(339, 100%, 58.8%), 0 0 100px hsl(339, 100%, 58.8%);
|
||||
}
|
||||
|
||||
.animate-bubble {
|
||||
animation-name: bubbleup;
|
||||
animation-duration: calc(300s / calc(var(--i) * 5));
|
||||
animation-timing-function: linear;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
@keyframes bubbleup {
|
||||
0% { transform: translateY(100px) scale(0); }
|
||||
100% { transform: translateY(-100px) scale(1); }
|
||||
}
|
30
src/resources/css/animations/ripple.css
Normal file
30
src/resources/css/animations/ripple.css
Normal file
@ -0,0 +1,30 @@
|
||||
:root {
|
||||
--ripple-color: #fff;
|
||||
--ripple-radius: 9999px;
|
||||
--ripple-duration: 600ms;
|
||||
--ripple-timing-function: linear;
|
||||
}
|
||||
|
||||
.ripple {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.ripple span {
|
||||
position: absolute;
|
||||
border-radius: var(--ripple-radius);
|
||||
opacity: 0.5;
|
||||
background: var(--ripple-color);
|
||||
transform: scale(0);
|
||||
animation: ripple var(--ripple-duration) var(--ripple-timing-function);
|
||||
}
|
||||
|
||||
@keyframes ripple {
|
||||
to {
|
||||
transform: scale(4);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
@ -2,11 +2,12 @@
|
||||
@import 'tailwindcss/components';
|
||||
@import 'tailwindcss/utilities';
|
||||
|
||||
@import 'extends/grid.css';
|
||||
|
||||
@import 'variables.css';
|
||||
@import 'utilities.css';
|
||||
@import 'animations.css';
|
||||
|
||||
@import 'extends/grid.css';
|
||||
|
||||
@import 'typography/font-faces.css';
|
||||
@import 'typography/text-shadows.css';
|
||||
|
||||
@ -25,25 +26,80 @@
|
||||
@import 'components/navbars.css';
|
||||
@import 'components/pagination.css';
|
||||
|
||||
:root {
|
||||
--primary-text-color: hsl(0, 90.4%, 59.2%);
|
||||
--primary-text-color-gradient-start: hsl(270, 66.9%, 47.5%);
|
||||
--primary-text-color-gradient-end: hsl(330, 100%, 50%);
|
||||
|
||||
--text-info-color: hsl(191, 82%, 50%);
|
||||
--text-info-color-gradient-start: hsl(227, 100%, 56.5%);
|
||||
--text-info-color-gradient-end: hsl(191, 98.2%, 56.1%);
|
||||
|
||||
--text-success-color: hsl(86, 81.4%, 46.3%);
|
||||
--text-success-color-gradient-start: hsl(133, 76.5%, 38.4%);
|
||||
--text-success-color-gradient-end: hsl(72, 81.1%, 52.4%);
|
||||
|
||||
--text-warning-color: hsl(47, 96.2%, 59.2%);
|
||||
--text-warning-color-gradient-start: hsl(0, 90.4%, 59.2%);
|
||||
--text-warning-color-gradient-end: hsl(47, 96.2%, 59.2%);
|
||||
|
||||
--text-danger-color: hsl(0, 95%, 47.1%);
|
||||
--text-danger-color-gradient-start: hsl(0, 92.8%, 43.5%);
|
||||
--text-danger-color-gradient-end: hsl(344, 100%, 70%);
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion) {
|
||||
*, *::before, *::after {
|
||||
animation-duration: 0s !important;
|
||||
/* additional recommendation */
|
||||
transition: none !important;
|
||||
scroll-behavior: auto !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
background-image: linear-gradient(100deg, hsl(0, 0%, 98%), hsl(240, 5.9%, 90%));
|
||||
color: hsl(240, 5.9%, 10%);
|
||||
/*color: lch(8.35%, 2.25, 285.92);*/
|
||||
-webkit-font-smoothing: antialiased;
|
||||
min-height: 100dvh;
|
||||
overflow: auto;
|
||||
scrollbar-gutter: stable both-edges;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-size: 1.25rem;
|
||||
line-height: 1.1;
|
||||
|
||||
/* these will clamp the width between the two values
|
||||
and keep it at 90% of the max when between them */
|
||||
max-width: clamp(320px, 90%, 1280px);
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
html, body {
|
||||
transition-duration: 0.05s;
|
||||
transition-timing-function: ease-in-out;
|
||||
}
|
||||
|
||||
html, body {
|
||||
transition-property: background, color;
|
||||
transition-timing-function: ease-in-out;
|
||||
}
|
||||
|
||||
button, a {
|
||||
transition-property: all;
|
||||
}
|
||||
|
||||
nav {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
vertical-align: middle;
|
||||
font-style: italic;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
shape-margin: 0.75rem;
|
||||
}
|
||||
|
||||
@media (max-width: 1023px) {
|
||||
.grid-container {
|
||||
@apply grid-cols-1;
|
||||
|
@ -0,0 +1 @@
|
||||
.accordian {}
|
||||
|
@ -0,0 +1 @@
|
||||
.alert {}
|
||||
|
@ -0,0 +1 @@
|
||||
.breadcrumbs {}
|
||||
|
@ -0,0 +1,3 @@
|
||||
.modal {}
|
||||
|
||||
.dialog {}
|
||||
|
@ -0,0 +1 @@
|
||||
.navbar {}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user