Prepare for 2.0.0 release
This commit is contained in:
parent
f947c51a79
commit
8a0cb391fe
139 changed files with 44117 additions and 6310 deletions
40
CHANGELOG.md
Normal file
40
CHANGELOG.md
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
# CHANGELOG
|
||||||
|
|
||||||
|
## 2.0.0 - UNRELEASED
|
||||||
|
* Replace material design with bootstrap4 theme
|
||||||
|
* Update deployment and release documentation and examples
|
||||||
|
* Update dependencies and force PHP 7.3
|
||||||
|
* Add fallback for values for `env` file
|
||||||
|
|
||||||
|
## 1.2.4 - 2019/01/18
|
||||||
|
* No info text
|
||||||
|
|
||||||
|
## 1.2.3 - 2019/01/18
|
||||||
|
* No info text
|
||||||
|
|
||||||
|
## 1.2.2 - 2018/09/01
|
||||||
|
* No info text
|
||||||
|
|
||||||
|
## 1.2.1 - 2018/06/04
|
||||||
|
* No info text
|
||||||
|
|
||||||
|
## 1.2.0 - 2018/06/04
|
||||||
|
* No info text
|
||||||
|
|
||||||
|
## 1.1.1 - 2018/05/04
|
||||||
|
* No info text
|
||||||
|
|
||||||
|
## 1.1.0 - 2018/05/04
|
||||||
|
* No info text
|
||||||
|
|
||||||
|
## 1.0.3 - 2018/04/04
|
||||||
|
* No info text
|
||||||
|
|
||||||
|
## 1.0.2 - 2018/04/04
|
||||||
|
* No info text
|
||||||
|
|
||||||
|
## 1.0.1 - 2018/04/03
|
||||||
|
* No info text
|
||||||
|
|
||||||
|
## 1.0.0 - 2018/04/03
|
||||||
|
* No info text
|
218
README.md
218
README.md
|
@ -1,118 +1,156 @@
|
||||||
# README
|
# README
|
||||||
|
|
||||||
**ts3web** is a web interface for any TeamSpeak 3 Server used with serverQuery login.
|
**ts3web** is a web interface for any TeamSpeak 3 Server used with serverQuery login. Sources can be viewed
|
||||||
|
[here](https://git.myservermanager.com/alexander.schaeferdiek/ts3web).
|
||||||
|
|
||||||
This web interface aims to be as simple as possible. The minimalistic approach is intentional.
|
This web interface aims to be as simple as possible. The minimalistic approach is intentional.
|
||||||
|
|
||||||
If you like to help (to translate or implement features), open an issue first. If possible, you should use existing code to implement new features. PRs will be merged after a code review.
|
Feel free to submit pull requests if you like to help.
|
||||||
|
|
||||||
Features which are currently not supported:
|
Features which are currently **not supported**:
|
||||||
|
|
||||||
* Permissions Management (except for viewing)
|
* modify permissions (only viewing)
|
||||||
* File Management (except for viewing)
|
* modify files (only viewing)
|
||||||
|
|
||||||
|
**ts3web** can be deployed in different ways. See below for more information. For each deployment type a running
|
||||||
|
TeamSpeak 3 server is a prerequisite (except for the `docker-compose.yml` type which will start also the server if
|
||||||
|
needed).
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
The main configuration file is the `env` file located in `config/`. There's an example file called `env.example` which you
|
The main configuration file is the `env` file located in `config/`. There's an example file called `env.example`
|
||||||
need to copy to `config/env`.
|
which you can copy to `config/env`. Defaults will assume you're running your TeamSpeak server on `localhost` with
|
||||||
|
default port. Docker deployments can host bind this file into the container directly and just maintain the `env` file.
|
||||||
|
|
||||||
**Information for docker users**: it's possible to have the `env` file persistent and not within the container so
|
## Usage with docker-compose
|
||||||
that rebuilding the image isn't required. Create a host volume `/path/from/host/env` and map it to
|
|
||||||
`/var/www/html/application/config/env`. Changes will show up after restarting the container.
|
|
||||||
|
|
||||||
## Install / Deployment
|
The recommended way is to use docker-compose. The `network_mode = "host"` is required in order to show correct IP
|
||||||
|
addresses of connected users.
|
||||||
|
|
||||||
You can either use docker or manual deployment. Please read the following section carefully.
|
1. The web interface will not be able to use `localhost` as TeamSpeak 3 server address because it's not available in a
|
||||||
|
docker container not using the `host` network. Thus the`whitelist.txt` **must** include your public TeamSpeak 3 server
|
||||||
|
IP for this example setup.
|
||||||
|
2. The public address also has to match the environment variable `teamspeak_host=your-public-address` within
|
||||||
|
the `env` file referenced in the example `docker-compose`.
|
||||||
|
|
||||||
### Automatic installation and deployment with docker or docker-compose
|
```
|
||||||
|
version: '2'
|
||||||
|
networks:
|
||||||
|
teamspeak:
|
||||||
|
external: false
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
container_name: teamspeak_app
|
||||||
|
image: teamspeak:latest
|
||||||
|
volumes:
|
||||||
|
- ./app:/var/ts3server
|
||||||
|
- ./whitelist.txt:/whitelist.txt
|
||||||
|
ports:
|
||||||
|
- 10011:10011
|
||||||
|
- 30033:30033
|
||||||
|
- 9987:9987/udp
|
||||||
|
environment:
|
||||||
|
- TS3SERVER_LICENSE=accept
|
||||||
|
- TS3SERVER_IP_WHITELIST=/whitelist.txt
|
||||||
|
restart: always
|
||||||
|
network_mode: "host"
|
||||||
|
web:
|
||||||
|
container_name: teamspeak_web
|
||||||
|
image: teamspeak_web:latest
|
||||||
|
volumes:
|
||||||
|
- ./env:/var/www/html/application/config/env
|
||||||
|
ports:
|
||||||
|
- 127.0.0.1:8181:80
|
||||||
|
depends_on:
|
||||||
|
- app
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
- teamspeak
|
||||||
|
```
|
||||||
|
|
||||||
##### Install
|
Now execute `docker-compose up -d` to start those containers. If you like to update, do `docker-compose down`,
|
||||||
|
`docker-compose pull` and then `docker-compose up -d` again.
|
||||||
|
|
||||||
###### docker
|
Your TeamSpeak 3 Server will be available under `public-server-ip:9987`. The web interface will be available on
|
||||||
|
`127.0.0.1:8181`. You need to add a reverse proxy and probably you also want SSL configured if you expose it via domain.
|
||||||
|
For testing purposes, change `- 127.0.0.1:8181:80` to `- 8181:80`. The web interface will then be available under
|
||||||
|
`public-server-ip:8181`. This is **not recommended**! Secure your setup properly via reverse proxy and SSL.
|
||||||
|
|
||||||
* Clone repository
|
## Usage as single docker container
|
||||||
* Copy either `config/env.example` to `config/env` and adjust to your needs or make it persistent outside if the container. To do so take a look at the configuration section first). Ensure that if you share the same docker network, the environment variable `teamspeak_default_host` should be the name of your teamspeak docker container.
|
|
||||||
* Build the docker image from the project home with `docker build -t teamspeak_web:latest -f docker/Dockerfile .`
|
* Copy `env.example` to `env` and adjust to your needs. It's recommended to make it persistent outside of the container.
|
||||||
* Create a container with the image, e.g. `docker run --name teamspeak_web -p 8181:80 slimblog_app:latest`. Make sure that if teamspeak and ts3web share the same docker instance they should be put into one network and the subnet **needs be added to teamspeak's query whitelist**. The web interface won't work otherwise.
|
* Create a container with the image, e.g. `docker run --name teamspeak_web -v ./env:/var/www/html/application/config/env -p 8181:80 varakh/ts3web:latest`.
|
||||||
|
* Make sure that if teamspeak and ts3web share the same docker instance they should be put into one network and the subnet **needs be added to teamspeak's query whitelist**.
|
||||||
* Point your browser to `8181` to see the web interface.
|
* Point your browser to `8181` to see the web interface.
|
||||||
|
|
||||||
###### docker-compose
|
## Usage as native application
|
||||||
|
**Prerequisite**: `php`, `composer` and probably `php-fpm` installed on the server.
|
||||||
There's an example `docker-compose.yml` in the `docker-compose/` directory.
|
|
||||||
|
|
||||||
* Adjust `docker-compose/env` if you need to change something.
|
|
||||||
* Build the docker image from the project home with `docker build -t teamspeak_web:latest -f docker/Dockerfile .`
|
|
||||||
* Change directory to `docker-compose/` folder
|
|
||||||
* Execute `docker-compose up -d`
|
|
||||||
* Point your browser to `8080` to see the web interface.
|
|
||||||
|
|
||||||
##### Upgrade
|
|
||||||
|
|
||||||
###### docker
|
|
||||||
|
|
||||||
* Change directory to project home
|
|
||||||
* `git pull`
|
|
||||||
* Build the docker image from the project home with `docker build -t teamspeak_web:latest -f docker/Dockerfile .`
|
|
||||||
* Re-create app container with latest image
|
|
||||||
|
|
||||||
###### docker-compose
|
|
||||||
|
|
||||||
* Change directory to project home
|
|
||||||
* `git pull`
|
|
||||||
* Build the docker image from the project home with `docker build -t teamspeak_web:latest -f docker/Dockerfile .`
|
|
||||||
* Change directory to `docker-compose/` folder
|
|
||||||
* Execute `docker-compose down`
|
|
||||||
* Execute `docker-compose up -d`
|
|
||||||
|
|
||||||
### Manual installation and deployment
|
|
||||||
|
|
||||||
#### Install
|
|
||||||
|
|
||||||
|
To install:
|
||||||
* Clone repository
|
* Clone repository
|
||||||
* Install composer
|
|
||||||
* Change directory to project home
|
* Change directory to project home
|
||||||
* Execute `composer install`
|
* Execute `composer install`
|
||||||
* `composer install`
|
* `composer install`
|
||||||
|
* Use a web server or run directly via PHP server: `php -S localhost:8080 -t public public/index.php` (point browser to [localhost:8080](http://localhost:8080))
|
||||||
|
|
||||||
#### Web server
|
To upgrade:
|
||||||
* Configure nginx or apache.
|
|
||||||
* Point your document root to `public/`.
|
|
||||||
* Example `nginx.conf`:
|
|
||||||
|
|
||||||
```
|
|
||||||
root .../public;
|
|
||||||
index index.php;
|
|
||||||
|
|
||||||
rewrite_log on;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
try_files $uri $uri/ @ee;
|
|
||||||
}
|
|
||||||
|
|
||||||
location @ee {
|
|
||||||
rewrite ^(.*) /index.php?$1 last;
|
|
||||||
}
|
|
||||||
|
|
||||||
# php fpm
|
|
||||||
location ~ \.php$ {
|
|
||||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
|
||||||
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
|
|
||||||
include fastcgi_params;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
* Everything should be up and running. Point your browser to `8080` to see the web interface.
|
|
||||||
|
|
||||||
#### Upgrade
|
|
||||||
|
|
||||||
* Change directory to project home
|
* Change directory to project home
|
||||||
* `git pull`
|
* `git pull`
|
||||||
* `composer update`
|
* `composer update`
|
||||||
|
|
||||||
### Contributions & Development
|
## Web server setup
|
||||||
* Follow manual install guide but use the internal server with `php -S localhost:8080 -t public public/index.php`
|
* Example `nginx.conf` for **standalone** deployment without SSL:
|
||||||
* Point browser to [localhost:8080](http://localhost:8080)
|
|
||||||
|
|
||||||
#### Helpers
|
```
|
||||||
|
root .../public;
|
||||||
|
index index.php;
|
||||||
|
|
||||||
|
rewrite_log on;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ @ee;
|
||||||
|
}
|
||||||
|
|
||||||
|
location @ee {
|
||||||
|
rewrite ^(.*) /index.php?$1 last;
|
||||||
|
}
|
||||||
|
|
||||||
|
# php fpm
|
||||||
|
location ~ \.php$ {
|
||||||
|
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||||
|
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
|
||||||
|
include fastcgi_params;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
* Example `nginx.conf` as **reverse proxy** with SSL:
|
||||||
|
|
||||||
|
```
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
server_name teamspeak.domain.tld;
|
||||||
|
|
||||||
|
ssl on;
|
||||||
|
ssl_certificate fullchain.pem;
|
||||||
|
ssl_certificate_key privkey.pem;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://localhost:8181;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Forwarded-For $remote_addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
### Release
|
||||||
|
* Set a date in the `CHANGELOG.md` file
|
||||||
|
* Build the docker image from the project home with `docker build -t varakh/ts3web:latest -f docker/Dockerfile .` and publish it
|
||||||
|
* Tag the release git commit and create a new release in the VCS web interface
|
||||||
|
|
||||||
|
### Helpers
|
||||||
|
|
||||||
Attributes can be defined when including `table`, `keyvalues` and `form` templates of twig. This helps to generate tables and forms without the need to specify all attributes.
|
Attributes can be defined when including `table`, `keyvalues` and `form` templates of twig. This helps to generate tables and forms without the need to specify all attributes.
|
||||||
|
|
||||||
|
@ -126,11 +164,13 @@ attributesEditable // define editable attributes in the key value view
|
||||||
fields // define fields for a form
|
fields // define fields for a form
|
||||||
```
|
```
|
||||||
|
|
||||||
See example usage in the folder `View/material`.
|
See example usage in the folder `View/bootstrap4`.
|
||||||
|
|
||||||
#### Translations
|
### Translations
|
||||||
- This app uses Symfony Translator. It's bootstrapped in `Util\BootstrapHelper` and locales are placed under `data/locale/`. Adjust to your needs or help translating.
|
- This app uses Symfony Translator. It's bootstrapped in `Util\BootstrapHelper` and locales are placed under `data/locale/`. Adjust to your needs or help translating.
|
||||||
- Form fields (name/id should be the same) are also translated. For a field named `content` or `ConT enT` translate `form_field_content`.
|
- Form fields (name/id should be the same) are also translated. For a field named `content` or `ConT enT` translate `form_field_content`.
|
||||||
|
|
||||||
#### Theme
|
### Theme
|
||||||
Themes can be chosen in the `env` file by editing the `theme` variable. Templates are mapped to the corresponding view folder in `src/View/<themeName>`. `.css`, `.js` and other style files like `.ttf` or `.woff2` for fonts should be placed in `public/theme/<themeName>` and accessed accordingly. See an example in `src/View/boostrap4/layout.twig`.
|
Themes can be chosen in the `env` file by editing the `theme` variable. Templates are mapped to the corresponding view
|
||||||
|
folder in `src/View/<themeName>`. `.css`, `.js` and other style files like `.ttf` or `.woff2` for fonts should be placed
|
||||||
|
in `public/theme/<themeName>` and accessed accordingly. See an example in `src/View/boostrap4/layout.twig`.
|
|
@ -1,30 +1,33 @@
|
||||||
{
|
{
|
||||||
"require": {
|
"require": {
|
||||||
"slim/slim": "^3.0",
|
"php": ">= 7.3",
|
||||||
"monolog/monolog": "^1.18",
|
"slim/slim": "^3.0",
|
||||||
"slim/twig-view": "^2.1",
|
"monolog/monolog": "^1.18",
|
||||||
"slim/flash": "^0.1.0",
|
"slim/twig-view": "^2.1",
|
||||||
"wixel/gump": "^1.3",
|
"slim/flash": "^0.1.0",
|
||||||
"symfony/translation": "^3.1",
|
"wixel/gump": "^1.3",
|
||||||
"symfony/twig-bridge": "^3.1",
|
"symfony/translation": "^3.1",
|
||||||
"symfony/yaml": "*",
|
"symfony/twig-bridge": "^3.1",
|
||||||
"vlucas/phpdotenv": "^2.3",
|
"symfony/yaml": "*",
|
||||||
"jeremykendall/slim-auth": "dev-slim-3.x",
|
"vlucas/phpdotenv": "^2.3",
|
||||||
"par0noid/ts3admin": "^1.0",
|
"jeremykendall/slim-auth": "dev-slim-3.x",
|
||||||
"nesbot/carbon": "^1.25",
|
"par0noid/ts3admin": "^1.0",
|
||||||
"bryanjhv/slim-session": "^3.5",
|
"nesbot/carbon": "^2.0.0",
|
||||||
"symfony/filesystem": "^4.0",
|
"bryanjhv/slim-session": "^3.5",
|
||||||
"symfony/finder": "^4.0"
|
"symfony/filesystem": "^4.0",
|
||||||
},
|
"symfony/finder": "^4.0"
|
||||||
"config": {
|
},
|
||||||
"bin-dir": "bin/"
|
"config": {
|
||||||
},
|
"bin-dir": "bin/"
|
||||||
"autoload": {
|
},
|
||||||
"classmap": [
|
"autoload": {
|
||||||
"src/",
|
"classmap": [
|
||||||
"config/",
|
"src/",
|
||||||
"data/",
|
"config/",
|
||||||
"vendor/"
|
"data/",
|
||||||
]
|
"vendor/"
|
||||||
}
|
]
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
67
config/EnvConstants.php
Normal file
67
config/EnvConstants.php
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class EnvConstants
|
||||||
|
*/
|
||||||
|
class EnvConstants
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Default env file loaded
|
||||||
|
*/
|
||||||
|
const ENV_FILE_DEFAULT = "env.default";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom env file
|
||||||
|
*/
|
||||||
|
const ENV_FILE_CUSTOM = "env";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Site title
|
||||||
|
*/
|
||||||
|
const SITE_TITLE = "site_title";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Site language
|
||||||
|
*/
|
||||||
|
const SITE_LANGUAGE = "site_language";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Site date format
|
||||||
|
*/
|
||||||
|
const SITE_DATE_FORMAT = "site_date_format";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* THeme
|
||||||
|
*/
|
||||||
|
const THEME = "theme";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache
|
||||||
|
*/
|
||||||
|
const THEME_CACHE = "theme_cache";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TeamSpeak host
|
||||||
|
*/
|
||||||
|
const TEAMSPEAK_HOST = "teamspeak_host";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TeamSpeak query port
|
||||||
|
*/
|
||||||
|
const TEAMSPEAK_QUERY_PORT = "teamspeak_query_port";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TeamSpeak default user
|
||||||
|
*/
|
||||||
|
const TEAMSPEAK_USER = "teamspeak_user";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log name
|
||||||
|
*/
|
||||||
|
const LOG_NAME = "log_name";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log level
|
||||||
|
*/
|
||||||
|
const LOG_LEVEL = "log_level";
|
||||||
|
}
|
17
config/env.default
Normal file
17
config/env.default
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# site
|
||||||
|
site_title="Teamspeak 3 Web"
|
||||||
|
site_language="en" # values: each yml you specified in data/locale/
|
||||||
|
site_date_format="d.m.Y H:i:s" # values: all possible for Date::class
|
||||||
|
|
||||||
|
# theme
|
||||||
|
theme="bootstrap4" # values: material (foldernames are used to determine theme in src/View/)
|
||||||
|
theme_cache=false # values: true|false (cache view/twig. makes it faster, disable for debug)
|
||||||
|
|
||||||
|
# teamspeak
|
||||||
|
teamspeak_host="localhost" # 'localhost' or 'name_of_docker_container' if running locally
|
||||||
|
teamspeak_query_port=10011
|
||||||
|
teamspeak_user="serveradmin"
|
||||||
|
|
||||||
|
# log
|
||||||
|
log_name="ts3web" # values: all strings
|
||||||
|
log_level="INFO" # values: DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL, ALERT, EMERGENCY
|
|
@ -4,13 +4,13 @@ site_language="en" # values: each yml you specified in data/locale/
|
||||||
site_date_format="d.m.Y H:i:s" # values: all possible for Date::class
|
site_date_format="d.m.Y H:i:s" # values: all possible for Date::class
|
||||||
|
|
||||||
# theme
|
# theme
|
||||||
theme="material" # values: material (foldernames are used to determine theme in src/View/)
|
theme="bootstrap4" # values: bootstrap4 (foldernames are used to determine theme in src/View/)
|
||||||
theme_cache=false # values: true|false (cache view/twig. makes it faster, disable for debug)
|
theme_cache=false # values: true|false (cache view/twig. makes it faster, disable for debug)
|
||||||
|
|
||||||
# teamspeak
|
# teamspeak
|
||||||
teamspeak_default_host="localhost" # 'localhost' or 'name_of_docker_container' if running locally
|
teamspeak_host="localhost" # 'localhost' or 'name_of_docker_container' if running locally
|
||||||
teamspeak_default_query_port=10011
|
teamspeak_query_port=10011
|
||||||
teamspeak_default_user="serveradmin"
|
teamspeak_user="serveradmin"
|
||||||
|
|
||||||
# log
|
# log
|
||||||
log_name="ts3web" # values: all strings
|
log_name="ts3web" # values: all strings
|
||||||
|
|
|
@ -8,16 +8,21 @@ error.500.content: "Internal application error."
|
||||||
error.500.title: "500"
|
error.500.title: "500"
|
||||||
login.flash.success: "Logged in as %username% successfully."
|
login.flash.success: "Logged in as %username% successfully."
|
||||||
login.flash.wrong_credentials: "Cannot login. Wrong credentials."
|
login.flash.wrong_credentials: "Cannot login. Wrong credentials."
|
||||||
login.form.button: "Login"
|
login.form.button: "Sign in"
|
||||||
|
login.form.host: "Host"
|
||||||
|
login.form.username: "User"
|
||||||
|
login.form.password: "Password"
|
||||||
login.form.password.placeholder: "Password"
|
login.form.password.placeholder: "Password"
|
||||||
login.form.username.placeholder: "Username"
|
login.form.username.placeholder: "Username"
|
||||||
log.internal.application.error: "Internal application error."
|
log.internal.application.error: "Internal application error."
|
||||||
login.title: "Login"
|
login.title: "Please login"
|
||||||
logout.flash.success: "Logged out successfully."
|
logout.flash.success: "Logged out successfully."
|
||||||
logout.title: "Logout"
|
logout.title: "Logout"
|
||||||
menu.currentlyloggedin: "Logged in as: %username%"
|
menu.currentlyloggedin: "%username%"
|
||||||
menu.login: "Login"
|
menu.login: "Login"
|
||||||
menu.logout: "Logout"
|
menu.logout: "Logout"
|
||||||
|
menu.servers.select: "Select a server"
|
||||||
|
menu.servers.deselect: "Deselect server"
|
||||||
mismatch: "There is no validation rule for %field%."
|
mismatch: "There is no validation rule for %field%."
|
||||||
no_entities.message: "Nothing to show."
|
no_entities.message: "Nothing to show."
|
||||||
validate_alpha_dash: "The %field% field may only contain alpha characters and dashes."
|
validate_alpha_dash: "The %field% field may only contain alpha characters and dashes."
|
||||||
|
@ -155,6 +160,8 @@ channel_info.h.details: "Details"
|
||||||
channel_info.h.clients: "Clients"
|
channel_info.h.clients: "Clients"
|
||||||
channel_info.send: "Send a message"
|
channel_info.send: "Send a message"
|
||||||
channel_info.send.message: "Message"
|
channel_info.send.message: "Message"
|
||||||
|
channel_info.client: "Client"
|
||||||
|
channel_info.files.delete: "Delete"
|
||||||
|
|
||||||
# groups
|
# groups
|
||||||
groups.delete: "Delete"
|
groups.delete: "Delete"
|
||||||
|
@ -175,6 +182,8 @@ channelgroups.delete: "Delete"
|
||||||
channelgroup_info.h.clients: "Clients"
|
channelgroup_info.h.clients: "Clients"
|
||||||
channelgroup_info.h.permissions: "Permissions"
|
channelgroup_info.h.permissions: "Permissions"
|
||||||
channelgroup_info.remove: "Remove"
|
channelgroup_info.remove: "Remove"
|
||||||
|
channelgroup_info.client: "Client"
|
||||||
|
channelgroup_info.channel: "Channel"
|
||||||
|
|
||||||
# server group info
|
# server group info
|
||||||
servergroup_info.h.clients_add: "Add"
|
servergroup_info.h.clients_add: "Add"
|
||||||
|
@ -201,6 +210,8 @@ client_info.send: "Send a message"
|
||||||
client_info.send.subject: "Subject"
|
client_info.send.subject: "Subject"
|
||||||
client_info.send.message: "Message"
|
client_info.send.message: "Message"
|
||||||
client_info.sent.success: "Sent message to client %cldbid%."
|
client_info.sent.success: "Sent message to client %cldbid%."
|
||||||
|
client_info.channel: "Channel"
|
||||||
|
client_info.channelgroup: "Channelgroup"
|
||||||
|
|
||||||
# online info
|
# online info
|
||||||
online_info.h.actions: "Actions"
|
online_info.h.actions: "Actions"
|
||||||
|
@ -229,6 +240,8 @@ online.send.message: "Message"
|
||||||
online.poked.success: "Poked client %clid%."
|
online.poked.success: "Poked client %clid%."
|
||||||
online.kicked.success: "Kicked client %clid%."
|
online.kicked.success: "Kicked client %clid%."
|
||||||
online.banned.success: "Banned client %clid%."
|
online.banned.success: "Banned client %clid%."
|
||||||
|
online.client: "Client"
|
||||||
|
online.channel: "Channel"
|
||||||
|
|
||||||
# tokens
|
# tokens
|
||||||
tokens.delete: "Delete"
|
tokens.delete: "Delete"
|
||||||
|
|
|
@ -4,13 +4,13 @@ site_language="en" # values: each yml you specified in data/locale/
|
||||||
site_date_format="d.m.Y H:i:s" # values: all possible for Date::class
|
site_date_format="d.m.Y H:i:s" # values: all possible for Date::class
|
||||||
|
|
||||||
# theme
|
# theme
|
||||||
theme="material" # values: material (foldernames are used to determine theme in src/View/)
|
theme="bootstrap4" # values: bootstrap4 (foldernames are used to determine theme in src/View/)
|
||||||
theme_cache=false # values: true|false (cache view/twig. makes it faster, disable for debug)
|
theme_cache=false # values: true|false (cache view/twig. makes it faster, disable for debug)
|
||||||
|
|
||||||
# teamspeak
|
# teamspeak
|
||||||
teamspeak_default_host="teamspeak_app" # 'localhost' or 'name_of_docker_container' if running locally
|
teamspeak_host="teamspeak_app" # 'localhost' or 'name_of_docker_container' if running locally
|
||||||
teamspeak_default_query_port=10011
|
teamspeak_query_port=10011
|
||||||
teamspeak_default_user="serveradmin"
|
teamspeak_user="serveradmin"
|
||||||
|
|
||||||
# log
|
# log
|
||||||
log_name="ts3web" # values: all strings
|
log_name="ts3web" # values: all strings
|
||||||
|
|
|
@ -49,8 +49,8 @@ $container['translator'] = function () use ($translator) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// date
|
// date
|
||||||
Carbon::setLocale(getenv('site_language'));
|
Carbon::setLocale(getenv(EnvConstants::SITE_LANGUAGE));
|
||||||
Carbon::setToStringFormat(getenv('site_date_format'));
|
Carbon::setToStringFormat(getenv(EnvConstants::SITE_DATE_FORMAT));
|
||||||
|
|
||||||
// logger
|
// logger
|
||||||
try {
|
try {
|
||||||
|
@ -70,7 +70,8 @@ $container['ts'] = function () use ($logger) {
|
||||||
|
|
||||||
// auth
|
// auth
|
||||||
$container['authAdapter'] = function ($container) {
|
$container['authAdapter'] = function ($container) {
|
||||||
$adapter = new TSAuthAdapter(getenv('teamspeak_default_host'), getenv('teamspeak_default_query_port'), $container['logger'], $container['ts']);
|
$adapter = new TSAuthAdapter(getenv(EnvConstants::TEAMSPEAK_HOST),
|
||||||
|
getenv(EnvConstants::TEAMSPEAK_QUERY_PORT), $container['logger'], $container['ts']);
|
||||||
return $adapter;
|
return $adapter;
|
||||||
};
|
};
|
||||||
$container['acl'] = function () {
|
$container['acl'] = function () {
|
||||||
|
@ -94,10 +95,9 @@ $container['flash'] = function () {
|
||||||
return new Slim\Flash\Messages;
|
return new Slim\Flash\Messages;
|
||||||
};
|
};
|
||||||
$container['view'] = function ($container) use ($app) {
|
$container['view'] = function ($container) use ($app) {
|
||||||
// theme
|
$themeDir = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'View' . DIRECTORY_SEPARATOR . getenv(EnvConstants::THEME);
|
||||||
$themeDir = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'View' . DIRECTORY_SEPARATOR . getenv('theme');
|
|
||||||
|
|
||||||
if (!empty(getenv('theme_cache')) && getenv('theme_cache') == 'true') {
|
if (!empty(getenv(EnvConstants::THEME_CACHE) && getenv(EnvConstants::THEME_CACHE) == 'true')) {
|
||||||
$themeCacheDir = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'cache';
|
$themeCacheDir = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'cache';
|
||||||
} else {
|
} else {
|
||||||
$themeCacheDir = false;
|
$themeCacheDir = false;
|
||||||
|
@ -121,7 +121,7 @@ $container['view'] = function ($container) use ($app) {
|
||||||
|
|
||||||
// translation
|
// translation
|
||||||
$view->addExtension(new \Symfony\Bridge\Twig\Extension\TranslationExtension($container['translator']));
|
$view->addExtension(new \Symfony\Bridge\Twig\Extension\TranslationExtension($container['translator']));
|
||||||
$view->getEnvironment()->getExtension('Twig_Extension_Core')->setDateFormat(getenv('site_date_format'));
|
$view->getEnvironment()->getExtension('Twig_Extension_Core')->setDateFormat(getenv(EnvConstants::SITE_DATE_FORMAT));
|
||||||
|
|
||||||
// env
|
// env
|
||||||
$view->getEnvironment()->addFunction(new Twig_SimpleFunction('getenv', function($value) {
|
$view->getEnvironment()->addFunction(new Twig_SimpleFunction('getenv', function($value) {
|
||||||
|
|
8981
public/theme/bootstrap4/css/bootstrap.css
vendored
Normal file
8981
public/theme/bootstrap4/css/bootstrap.css
vendored
Normal file
File diff suppressed because it is too large
Load diff
1
public/theme/bootstrap4/css/bootstrap.css.map
Normal file
1
public/theme/bootstrap4/css/bootstrap.css.map
Normal file
File diff suppressed because one or more lines are too long
7
public/theme/bootstrap4/css/bootstrap.min.css
vendored
Normal file
7
public/theme/bootstrap4/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
public/theme/bootstrap4/css/bootstrap.min.css.map
Normal file
1
public/theme/bootstrap4/css/bootstrap.min.css.map
Normal file
File diff suppressed because one or more lines are too long
57
public/theme/bootstrap4/css/custom.css
Normal file
57
public/theme/bootstrap4/css/custom.css
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
html {
|
||||||
|
position: relative;
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
padding-top: 5rem;
|
||||||
|
margin-bottom: 60px; /* Margin bottom by footer height */
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 992px) {
|
||||||
|
body {
|
||||||
|
padding-top: 56px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
display: block;
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mainContainer {
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 60px;
|
||||||
|
line-height: 60px;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer > .container {
|
||||||
|
padding-right: 15px;
|
||||||
|
padding-left: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
border-left: 10px solid #ccc;
|
||||||
|
margin: 1.5em 10px;
|
||||||
|
padding: 0.5em 10px;
|
||||||
|
quotes: "\201C""\201D""\2018""\2019";
|
||||||
|
}
|
||||||
|
blockquote:before {
|
||||||
|
color: #ccc;
|
||||||
|
content: open-quote;
|
||||||
|
font-size: 4em;
|
||||||
|
line-height: 0.1em;
|
||||||
|
margin-right: 0.25em;
|
||||||
|
vertical-align: -0.4em;
|
||||||
|
}
|
||||||
|
blockquote p {
|
||||||
|
display: inline;
|
||||||
|
}
|
2337
public/theme/bootstrap4/css/font-awesome.css
vendored
Normal file
2337
public/theme/bootstrap4/css/font-awesome.css
vendored
Normal file
File diff suppressed because it is too large
Load diff
4
public/theme/bootstrap4/css/font-awesome.min.css
vendored
Normal file
4
public/theme/bootstrap4/css/font-awesome.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
public/theme/bootstrap4/css/jquery.modal.min.css
vendored
Normal file
1
public/theme/bootstrap4/css/jquery.modal.min.css
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
.blocker{position:fixed;top:0;right:0;bottom:0;left:0;width:100%;height:100%;overflow:auto;z-index:1;padding:20px;box-sizing:border-box;background-color:#000;background-color:rgba(0,0,0,0.75);text-align:center}.blocker:before{content:"";display:inline-block;height:100%;vertical-align:middle;margin-right:-0.05em}.blocker.behind{background-color:transparent}.modal{display:none;vertical-align:middle;position:relative;z-index:2;max-width:500px;box-sizing:border-box;width:90%;background:#fff;padding:15px 30px;-webkit-border-radius:8px;-moz-border-radius:8px;-o-border-radius:8px;-ms-border-radius:8px;border-radius:8px;-webkit-box-shadow:0 0 10px #000;-moz-box-shadow:0 0 10px #000;-o-box-shadow:0 0 10px #000;-ms-box-shadow:0 0 10px #000;box-shadow:0 0 10px #000;text-align:left}.modal a.close-modal{position:absolute;top:-12.5px;right:-12.5px;display:block;width:30px;height:30px;text-indent:-9999px;background-size:contain;background-repeat:no-repeat;background-position:center center;background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAAAAXNSR0IArs4c6QAAA3hJREFUaAXlm8+K00Acx7MiCIJH/yw+gA9g25O49SL4AO3Bp1jw5NvktC+wF88qevK4BU97EmzxUBCEolK/n5gp3W6TTJPfpNPNF37MNsl85/vN/DaTmU6PknC4K+pniqeKJ3k8UnkvDxXJzzy+q/yaxxeVHxW/FNHjgRSeKt4rFoplzaAuHHDBGR2eS9G54reirsmienDCTRt7xwsp+KAoEmt9nLaGitZxrBbPFNaGfPloGw2t4JVamSt8xYW6Dg1oCYo3Yv+rCGViV160oMkcd8SYKnYV1Nb1aEOjCe6L5ZOiLfF120EjWhuBu3YIZt1NQmujnk5F4MgOpURzLfAwOBSTmzp3fpDxuI/pabxpqOoz2r2HLAb0GMbZKlNV5/Hg9XJypguryA7lPF5KMdTZQzHjqxNPhWhzIuAruOl1eNqKEx1tSh5rfbxdw7mOxCq4qS68ZTjKS1YVvilu559vWvFHhh4rZrdyZ69Vmpgdj8fJbDZLJpNJ0uv1cnr/gjrUhQMuI+ANjyuwftQ0bbL6Erp0mM/ny8Fg4M3LtdRxgMtKl3jwmIHVxYXChFy94/Rmpa/pTbNUhstKV+4Rr8lLQ9KlUvJKLyG8yvQ2s9SBy1Jb7jV5a0yapfF6apaZLjLLcWtd4sNrmJUMHyM+1xibTjH82Zh01TNlhsrOhdKTe00uAzZQmN6+KW+sDa/JD2PSVQ873m29yf+1Q9VDzfEYlHi1G5LKBBWZbtEsHbFwb1oYDwr1ZiF/2bnCSg1OBE/pfr9/bWx26UxJL3ONPISOLKUvQza0LZUxSKyjpdTGa/vDEr25rddbMM0Q3O6Lx3rqFvU+x6UrRKQY7tyrZecmD9FODy8uLizTmilwNj0kraNcAJhOp5aGVwsAGD5VmJBrWWbJSgWT9zrzWepQF47RaGSiKfeGx6Szi3gzmX/HHbihwBser4B9UJYpFBNX4R6vTn3VQnez0SymnrHQMsRYGTr1dSk34ljRqS/EMd2pLQ8YBp3a1PLfcqCpo8gtHkZFHKkTX6fs3MY0blKnth66rKCnU0VRGu37ONrQaA4eZDFtWAu2fXj9zjFkxTBOo8F7t926gTp/83Kyzzcy2kZD6xiqxTYnHLRFm3vHiRSwNSjkz3hoIzo8lCKWUlg/YtGs7tObunDAZfpDLbfEI15zsEIY3U/x/gHHc/G1zltnAgAAAABJRU5ErkJggg==')}.modal-spinner{display:none;position:fixed;top:50%;left:50%;transform:translateY(-50%) translateX(-50%);padding:12px 16px;border-radius:5px;background-color:#111;height:20px}.modal-spinner>div{border-radius:100px;background-color:#fff;height:20px;width:2px;margin:0 1px;display:inline-block;-webkit-animation:sk-stretchdelay 1.2s infinite ease-in-out;animation:sk-stretchdelay 1.2s infinite ease-in-out}.modal-spinner .rect2{-webkit-animation-delay:-1.1s;animation-delay:-1.1s}.modal-spinner .rect3{-webkit-animation-delay:-1.0s;animation-delay:-1.0s}.modal-spinner .rect4{-webkit-animation-delay:-0.9s;animation-delay:-0.9s}@-webkit-keyframes sk-stretchdelay{0%,40%,100%{-webkit-transform:scaleY(0.5)}20%{-webkit-transform:scaleY(1.0)}}@keyframes sk-stretchdelay{0%,40%,100%{transform:scaleY(0.5);-webkit-transform:scaleY(0.5)}20%{transform:scaleY(1.0);-webkit-transform:scaleY(1.0)}}
|
BIN
public/theme/bootstrap4/fonts/FontAwesome.otf
Normal file
BIN
public/theme/bootstrap4/fonts/FontAwesome.otf
Normal file
Binary file not shown.
BIN
public/theme/bootstrap4/fonts/fontawesome-webfont.eot
Normal file
BIN
public/theme/bootstrap4/fonts/fontawesome-webfont.eot
Normal file
Binary file not shown.
2671
public/theme/bootstrap4/fonts/fontawesome-webfont.svg
Normal file
2671
public/theme/bootstrap4/fonts/fontawesome-webfont.svg
Normal file
File diff suppressed because it is too large
Load diff
After Width: | Height: | Size: 434 KiB |
BIN
public/theme/bootstrap4/fonts/fontawesome-webfont.ttf
Normal file
BIN
public/theme/bootstrap4/fonts/fontawesome-webfont.ttf
Normal file
Binary file not shown.
BIN
public/theme/bootstrap4/fonts/fontawesome-webfont.woff
Normal file
BIN
public/theme/bootstrap4/fonts/fontawesome-webfont.woff
Normal file
Binary file not shown.
BIN
public/theme/bootstrap4/fonts/fontawesome-webfont.woff2
Normal file
BIN
public/theme/bootstrap4/fonts/fontawesome-webfont.woff2
Normal file
Binary file not shown.
6444
public/theme/bootstrap4/js/bootstrap.bundle.js
vendored
Normal file
6444
public/theme/bootstrap4/js/bootstrap.bundle.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
1
public/theme/bootstrap4/js/bootstrap.bundle.js.map
Normal file
1
public/theme/bootstrap4/js/bootstrap.bundle.js.map
Normal file
File diff suppressed because one or more lines are too long
7
public/theme/bootstrap4/js/bootstrap.bundle.min.js
vendored
Normal file
7
public/theme/bootstrap4/js/bootstrap.bundle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
public/theme/bootstrap4/js/bootstrap.bundle.min.js.map
Normal file
1
public/theme/bootstrap4/js/bootstrap.bundle.min.js.map
Normal file
File diff suppressed because one or more lines are too long
3927
public/theme/bootstrap4/js/bootstrap.js
vendored
Normal file
3927
public/theme/bootstrap4/js/bootstrap.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
1
public/theme/bootstrap4/js/bootstrap.js.map
Normal file
1
public/theme/bootstrap4/js/bootstrap.js.map
Normal file
File diff suppressed because one or more lines are too long
7
public/theme/bootstrap4/js/bootstrap.min.js
vendored
Normal file
7
public/theme/bootstrap4/js/bootstrap.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
public/theme/bootstrap4/js/bootstrap.min.js.map
Normal file
1
public/theme/bootstrap4/js/bootstrap.min.js.map
Normal file
File diff suppressed because one or more lines are too long
10364
public/theme/bootstrap4/js/jquery.js
vendored
Normal file
10364
public/theme/bootstrap4/js/jquery.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
2
public/theme/bootstrap4/js/jquery.min.js
vendored
Normal file
2
public/theme/bootstrap4/js/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
public/theme/bootstrap4/js/jquery.min.map
Normal file
1
public/theme/bootstrap4/js/jquery.min.map
Normal file
File diff suppressed because one or more lines are too long
5
public/theme/bootstrap4/js/jquery.modal.min.js
vendored
Normal file
5
public/theme/bootstrap4/js/jquery.modal.min.js
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
/*
|
||||||
|
A simple jQuery modal (http://github.com/kylefox/jquery-modal)
|
||||||
|
Version 0.9.1
|
||||||
|
*/
|
||||||
|
!function(o){"object"==typeof module&&"object"==typeof module.exports?o(require("jquery"),window,document):o(jQuery,window,document)}(function(o,t,i,e){var s=[],l=function(){return s.length?s[s.length-1]:null},n=function(){var o,t=!1;for(o=s.length-1;o>=0;o--)s[o].$blocker&&(s[o].$blocker.toggleClass("current",!t).toggleClass("behind",t),t=!0)};o.modal=function(t,i){var e,n;if(this.$body=o("body"),this.options=o.extend({},o.modal.defaults,i),this.options.doFade=!isNaN(parseInt(this.options.fadeDuration,10)),this.$blocker=null,this.options.closeExisting)for(;o.modal.isActive();)o.modal.close();if(s.push(this),t.is("a"))if(n=t.attr("href"),this.anchor=t,/^#/.test(n)){if(this.$elm=o(n),1!==this.$elm.length)return null;this.$body.append(this.$elm),this.open()}else this.$elm=o("<div>"),this.$body.append(this.$elm),e=function(o,t){t.elm.remove()},this.showSpinner(),t.trigger(o.modal.AJAX_SEND),o.get(n).done(function(i){if(o.modal.isActive()){t.trigger(o.modal.AJAX_SUCCESS);var s=l();s.$elm.empty().append(i).on(o.modal.CLOSE,e),s.hideSpinner(),s.open(),t.trigger(o.modal.AJAX_COMPLETE)}}).fail(function(){t.trigger(o.modal.AJAX_FAIL);var i=l();i.hideSpinner(),s.pop(),t.trigger(o.modal.AJAX_COMPLETE)});else this.$elm=t,this.anchor=t,this.$body.append(this.$elm),this.open()},o.modal.prototype={constructor:o.modal,open:function(){var t=this;this.block(),this.anchor.blur(),this.options.doFade?setTimeout(function(){t.show()},this.options.fadeDuration*this.options.fadeDelay):this.show(),o(i).off("keydown.modal").on("keydown.modal",function(o){var t=l();27===o.which&&t.options.escapeClose&&t.close()}),this.options.clickClose&&this.$blocker.click(function(t){t.target===this&&o.modal.close()})},close:function(){s.pop(),this.unblock(),this.hide(),o.modal.isActive()||o(i).off("keydown.modal")},block:function(){this.$elm.trigger(o.modal.BEFORE_BLOCK,[this._ctx()]),this.$body.css("overflow","hidden"),this.$blocker=o('<div class="'+this.options.blockerClass+' blocker current"></div>').appendTo(this.$body),n(),this.options.doFade&&this.$blocker.css("opacity",0).animate({opacity:1},this.options.fadeDuration),this.$elm.trigger(o.modal.BLOCK,[this._ctx()])},unblock:function(t){!t&&this.options.doFade?this.$blocker.fadeOut(this.options.fadeDuration,this.unblock.bind(this,!0)):(this.$blocker.children().appendTo(this.$body),this.$blocker.remove(),this.$blocker=null,n(),o.modal.isActive()||this.$body.css("overflow",""))},show:function(){this.$elm.trigger(o.modal.BEFORE_OPEN,[this._ctx()]),this.options.showClose&&(this.closeButton=o('<a href="#close-modal" rel="modal:close" class="close-modal '+this.options.closeClass+'">'+this.options.closeText+"</a>"),this.$elm.append(this.closeButton)),this.$elm.addClass(this.options.modalClass).appendTo(this.$blocker),this.options.doFade?this.$elm.css({opacity:0,display:"inline-block"}).animate({opacity:1},this.options.fadeDuration):this.$elm.css("display","inline-block"),this.$elm.trigger(o.modal.OPEN,[this._ctx()])},hide:function(){this.$elm.trigger(o.modal.BEFORE_CLOSE,[this._ctx()]),this.closeButton&&this.closeButton.remove();var t=this;this.options.doFade?this.$elm.fadeOut(this.options.fadeDuration,function(){t.$elm.trigger(o.modal.AFTER_CLOSE,[t._ctx()])}):this.$elm.hide(0,function(){t.$elm.trigger(o.modal.AFTER_CLOSE,[t._ctx()])}),this.$elm.trigger(o.modal.CLOSE,[this._ctx()])},showSpinner:function(){this.options.showSpinner&&(this.spinner=this.spinner||o('<div class="'+this.options.modalClass+'-spinner"></div>').append(this.options.spinnerHtml),this.$body.append(this.spinner),this.spinner.show())},hideSpinner:function(){this.spinner&&this.spinner.remove()},_ctx:function(){return{elm:this.$elm,$elm:this.$elm,$blocker:this.$blocker,options:this.options}}},o.modal.close=function(t){if(o.modal.isActive()){t&&t.preventDefault();var i=l();return i.close(),i.$elm}},o.modal.isActive=function(){return s.length>0},o.modal.getCurrent=l,o.modal.defaults={closeExisting:!0,escapeClose:!0,clickClose:!0,closeText:"Close",closeClass:"",modalClass:"modal",blockerClass:"jquery-modal",spinnerHtml:'<div class="rect1"></div><div class="rect2"></div><div class="rect3"></div><div class="rect4"></div>',showSpinner:!0,showClose:!0,fadeDuration:null,fadeDelay:1},o.modal.BEFORE_BLOCK="modal:before-block",o.modal.BLOCK="modal:block",o.modal.BEFORE_OPEN="modal:before-open",o.modal.OPEN="modal:open",o.modal.BEFORE_CLOSE="modal:before-close",o.modal.CLOSE="modal:close",o.modal.AFTER_CLOSE="modal:after-close",o.modal.AJAX_SEND="modal:ajax:send",o.modal.AJAX_SUCCESS="modal:ajax:success",o.modal.AJAX_FAIL="modal:ajax:fail",o.modal.AJAX_COMPLETE="modal:ajax:complete",o.fn.modal=function(t){return 1===this.length&&new o.modal(this,t),this},o(i).on("click.modal",'a[rel~="modal:close"]',o.modal.close),o(i).on("click.modal",'a[rel~="modal:open"]',function(t){t.preventDefault(),o(this).modal()})});
|
8269
public/theme/bootstrap4/js/jquery.slim.js
Normal file
8269
public/theme/bootstrap4/js/jquery.slim.js
Normal file
File diff suppressed because it is too large
Load diff
2
public/theme/bootstrap4/js/jquery.slim.min.js
vendored
Normal file
2
public/theme/bootstrap4/js/jquery.slim.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
public/theme/bootstrap4/js/jquery.slim.min.map
Normal file
1
public/theme/bootstrap4/js/jquery.slim.min.map
Normal file
File diff suppressed because one or more lines are too long
|
@ -1,23 +0,0 @@
|
||||||
/* fallback */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Material Icons';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 400;
|
|
||||||
src: url('../fonts/MaterialIcons.woff2') format('woff2');
|
|
||||||
}
|
|
||||||
|
|
||||||
.material-icons {
|
|
||||||
font-family: 'Material Icons';
|
|
||||||
font-weight: normal;
|
|
||||||
font-style: normal;
|
|
||||||
font-size: 24px;
|
|
||||||
line-height: 1;
|
|
||||||
letter-spacing: normal;
|
|
||||||
text-transform: none;
|
|
||||||
display: inline-block;
|
|
||||||
white-space: nowrap;
|
|
||||||
word-wrap: normal;
|
|
||||||
direction: ltr;
|
|
||||||
-webkit-font-feature-settings: 'liga';
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
}
|
|
3426
public/theme/material/css/bootstrap-material-design.css
vendored
3426
public/theme/material/css/bootstrap-material-design.css
vendored
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
6
public/theme/material/css/bootstrap.min.css
vendored
6
public/theme/material/css/bootstrap.min.css
vendored
File diff suppressed because one or more lines are too long
|
@ -1,400 +0,0 @@
|
||||||
/* START: for rendering within block you should keep the following */
|
|
||||||
img {
|
|
||||||
max-width: 100%;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
/* END: for rendering within block you should keep the following */
|
|
||||||
|
|
||||||
/* Sticky footer styles */
|
|
||||||
html {
|
|
||||||
position: relative;
|
|
||||||
min-height: 100%;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
/* Margin bottom by footer height */
|
|
||||||
margin-bottom: 60px;
|
|
||||||
}
|
|
||||||
.footer {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
width: 100%;
|
|
||||||
/* Set the fixed height of the footer here */
|
|
||||||
height: 10px;
|
|
||||||
line-height: 60px; /* Vertically center the text there */
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
}
|
|
||||||
|
|
||||||
* {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header-panel {
|
|
||||||
background-color: #009587;
|
|
||||||
height: 90px;
|
|
||||||
position: relative;
|
|
||||||
z-index: 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header-panel div {
|
|
||||||
position: relative;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header-panel h1 {
|
|
||||||
color: #FFF;
|
|
||||||
/*font-size: 20px;*/
|
|
||||||
/*font-weight: 400;*/
|
|
||||||
position: absolute;
|
|
||||||
bottom: 10px;
|
|
||||||
padding-left: 35px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header-panel h1 a, a:active, a:visited, a:focus, a:hover {
|
|
||||||
color: #FFF;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu {
|
|
||||||
overflow: auto;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu a, a:hover, a:focus {
|
|
||||||
color: #009688;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:active, a:visited, a:focus, a:hover {
|
|
||||||
color: #009688;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu, .menu * {
|
|
||||||
-webkit-user-select: none;
|
|
||||||
-moz-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu ul {
|
|
||||||
padding: 0;
|
|
||||||
margin: 7px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu ul li {
|
|
||||||
list-style: none;
|
|
||||||
padding: 20px 0 20px 20px;
|
|
||||||
font-size: 15px;
|
|
||||||
font-weight: normal;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu ul li.active {
|
|
||||||
background-color: #dedede;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu ul li a {
|
|
||||||
color: rgb(51, 51, 51);
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pages {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
z-index: 4;
|
|
||||||
padding: 0;
|
|
||||||
overflow: auto;
|
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pages > div {
|
|
||||||
padding: 0 5px;
|
|
||||||
padding-top: 64px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pages .header {
|
|
||||||
color: rgb(82, 101, 162);
|
|
||||||
/*font-size: 24px;*/
|
|
||||||
/*font-weight: normal;*/
|
|
||||||
/*margin-top: 5px;*/
|
|
||||||
/*margin-bottom: 60px;*/
|
|
||||||
/*letter-spacing: 1.20000004768372px;*/
|
|
||||||
}
|
|
||||||
|
|
||||||
.page {
|
|
||||||
transform: translateY(1080px);
|
|
||||||
transition: transform 0 linear;
|
|
||||||
display: none;
|
|
||||||
opacity: 0;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page.active {
|
|
||||||
transform: translateY(0px);
|
|
||||||
transition: all 0.3s ease-out;
|
|
||||||
display: block;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.opensource {
|
|
||||||
color: rgba(0, 0, 0, 0.62);
|
|
||||||
position: fixed;
|
|
||||||
margin-top: 50px;
|
|
||||||
margin-left: 50px;
|
|
||||||
z-index: 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
#source-modal h4 {
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
#paypal .btn {
|
|
||||||
padding: 5px 30px 6px 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#paypal input {
|
|
||||||
background: transparent;
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cbwrapper div {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cbwrapper div:nth-child(2) {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
#carbonads, #fakecb {
|
|
||||||
border: 1px solid #d5d5d5;
|
|
||||||
font-size: 11px;
|
|
||||||
line-height: 15px;
|
|
||||||
overflow: hidden;
|
|
||||||
width: 340px;
|
|
||||||
padding: 20px;
|
|
||||||
margin: auto;
|
|
||||||
height: 142px;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#carbonads .carbon-img {
|
|
||||||
float: left;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
#carbonads .carbon-text, #carbonads .carbon-poweredby {
|
|
||||||
float: left;
|
|
||||||
width: 150px;
|
|
||||||
padding: 0 10px 10px 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#carbonads .carbon-text:hover, #carbonads .carbon-poweredby:hover {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#carbonads .carbon-poweredby {
|
|
||||||
color: #9D9D9D;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*#checkbox .sample1 label {*/
|
|
||||||
/*font-weight: bold;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*#checkbox .hint {*/
|
|
||||||
/*padding-left: 45px;*/
|
|
||||||
/*padding-top: 20px;*/
|
|
||||||
/*font-weight: 400;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*#checkbox .sample1 {*/
|
|
||||||
/*padding-bottom: 20px;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*#checkbox h2 {*/
|
|
||||||
/*font-size: 18.7199993133545px;*/
|
|
||||||
/*font-weight: bold;*/
|
|
||||||
/*margin-bottom: 30px;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*#checkbox .sample2 {*/
|
|
||||||
/*width: 300px;*/
|
|
||||||
/*clear: both;*/
|
|
||||||
/*font-weight: 400;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*#checkbox .sample2 {*/
|
|
||||||
/*padding: 10px 0;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*#checkbox .sample2 .text {*/
|
|
||||||
/*display: inline-block;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*#checkbox .sample2 .checkbox {*/
|
|
||||||
/*float: right;*/
|
|
||||||
/*margin: 0;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*#progress-bar h2 {*/
|
|
||||||
/*font-size: 18.7199993133545px;*/
|
|
||||||
/*font-weight: bold;*/
|
|
||||||
/*margin-bottom: 30px;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*#dialog h2 {*/
|
|
||||||
/*padding: 14px;*/
|
|
||||||
/*margin: 0;*/
|
|
||||||
/*font-size: 16px;*/
|
|
||||||
/*font-weight: 400;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*#shadow h2 {*/
|
|
||||||
/*padding: 14px;*/
|
|
||||||
/*margin: 0;*/
|
|
||||||
/*font-size: 16px;*/
|
|
||||||
/*font-weight: 400;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
#shadow .sample {
|
|
||||||
width: 100px;
|
|
||||||
height: 100px;
|
|
||||||
margin: 16px;
|
|
||||||
padding: 16px;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
#shadow-sample2 {
|
|
||||||
display: inline-block;
|
|
||||||
width: 100px;
|
|
||||||
height: 100px;
|
|
||||||
margin: 16px;
|
|
||||||
padding: 16px;
|
|
||||||
cursor: pointer;
|
|
||||||
-webkit-user-select: none;
|
|
||||||
-moz-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#shadow-sample3 {
|
|
||||||
display: inline-block;
|
|
||||||
width: 100px;
|
|
||||||
height: 100px;
|
|
||||||
margin: 16px;
|
|
||||||
padding: 16px;
|
|
||||||
border-radius: 100px;
|
|
||||||
cursor: pointer;
|
|
||||||
-webkit-user-select: none;
|
|
||||||
-moz-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*#radio-button h2 {*/
|
|
||||||
/*font-size: 18.7199993133545px;*/
|
|
||||||
/*font-weight: bold;*/
|
|
||||||
/*margin-bottom: 30px;*/
|
|
||||||
/*margin-top: 50px;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*#radio-button .radio {*/
|
|
||||||
/*margin: 20px 10px;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*#input h2 {*/
|
|
||||||
/*padding: 14px;*/
|
|
||||||
/*font-size: 16px;*/
|
|
||||||
/*font-weight: 400;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
#input .inputs {
|
|
||||||
width: 80%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*#input .form-group {*/
|
|
||||||
/*margin: 30px 0;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*#slider .sample1, #slider .sample2 {*/
|
|
||||||
/*padding: 20px 0;*/
|
|
||||||
/*background-color: #f0f0f0;*/
|
|
||||||
/*margin-bottom: 20px;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
#slider .sample2 {
|
|
||||||
height: 150px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*#slider .sample2 .slider {*/
|
|
||||||
/*margin: 0 40px;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*#slider h2 {*/
|
|
||||||
/*padding: 14px;*/
|
|
||||||
/*margin: 0;*/
|
|
||||||
/*font-size: 16px;*/
|
|
||||||
/*font-weight: 400;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*#slider .slider {*/
|
|
||||||
/*margin: 15px;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*#button h2 {*/
|
|
||||||
/*padding: 14px;*/
|
|
||||||
/*margin: 0;*/
|
|
||||||
/*font-size: 16px;*/
|
|
||||||
/*font-weight: 400;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*#floating-action-button .btn {*/
|
|
||||||
/*margin: 20px;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*#floating-action-button h2 {*/
|
|
||||||
/*padding: 14px;*/
|
|
||||||
/*margin: 0;*/
|
|
||||||
/*font-size: 16px;*/
|
|
||||||
/*font-weight: 400;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*#dropdown h2 {*/
|
|
||||||
/*padding: 14px;*/
|
|
||||||
/*margin: 0;*/
|
|
||||||
/*font-size: 16px;*/
|
|
||||||
/*font-weight: 400;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*#dropdown .dropdown {*/
|
|
||||||
/*font-size: 30px;*/
|
|
||||||
/*padding: 20px;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*#dropdown-menu h2 {*/
|
|
||||||
/*padding: 14px;*/
|
|
||||||
/*margin: 0;*/
|
|
||||||
/*font-size: 16px;*/
|
|
||||||
/*font-weight: 400;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*#dropdown-menu .sample {*/
|
|
||||||
/*width: 200px;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*#dropdown-menu .form-group {*/
|
|
||||||
/*margin: 30px 0;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*#toggle-button h2 {*/
|
|
||||||
/*font-size: 18.7199993133545px;*/
|
|
||||||
/*font-weight: bold;*/
|
|
||||||
/*margin-bottom: 30px;*/
|
|
||||||
/*margin-top: 50px;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*#toggle-button .togglebutton label {*/
|
|
||||||
/*margin: 20px 10px;*/
|
|
||||||
/*width: 200px;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*#toggle-button .togglebutton .toggle {*/
|
|
||||||
/*float: right;*/
|
|
||||||
/*}*/
|
|
|
@ -1,124 +0,0 @@
|
||||||
.dropdownjs {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.dropdownjs * {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
.dropdownjs > input {
|
|
||||||
width: 100%;
|
|
||||||
padding-right: 30px;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
.dropdownjs > input.focus ~ ul {
|
|
||||||
-webkit-transform: scale(1);
|
|
||||||
-ms-transform: scale(1);
|
|
||||||
transform: scale(1);
|
|
||||||
}
|
|
||||||
.dropdownjs > ul {
|
|
||||||
position: absolute;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
min-width: 200px;
|
|
||||||
-webkit-transform: scale(0);
|
|
||||||
-ms-transform: scale(0);
|
|
||||||
transform: scale(0);
|
|
||||||
z-index: 10000;
|
|
||||||
}
|
|
||||||
.dropdownjs > ul[placement=top-left] {
|
|
||||||
-webkit-transform-origin: bottom left;
|
|
||||||
-ms-transform-origin: bottom left;
|
|
||||||
transform-origin: bottom left;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
.dropdownjs > ul[placement=bottom-left] {
|
|
||||||
-webkit-transform-origin: top left;
|
|
||||||
-ms-transform-origin: top left;
|
|
||||||
transform-origin: top left;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
.dropdownjs > ul > li {
|
|
||||||
list-style: none;
|
|
||||||
padding: 10px 20px;
|
|
||||||
}
|
|
||||||
.dropdownjs > ul > li.dropdownjs-add {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
.dropdownjs > ul > li.dropdownjs-add > input {
|
|
||||||
border: 0;
|
|
||||||
padding: 10px 20px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Theme */
|
|
||||||
.dropdownjs > input[readonly] {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
select[data-dropdownjs][disabled] + .dropdownjs > input[readonly] {
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
.dropdownjs > ul {
|
|
||||||
background: #FFF;
|
|
||||||
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.12), 0 1px 6px rgba(0, 0, 0, 0.12);
|
|
||||||
-webkit-transition: -webkit-transform 0.2s ease-out;
|
|
||||||
transition: transform 0.2s ease-out;
|
|
||||||
padding: 10px;
|
|
||||||
overflow: auto;
|
|
||||||
max-width: 500px;
|
|
||||||
}
|
|
||||||
.dropdownjs > ul > li {
|
|
||||||
cursor: pointer;
|
|
||||||
word-wrap: break-word;
|
|
||||||
}
|
|
||||||
.dropdownjs > ul > li.selected,
|
|
||||||
.dropdownjs > ul > li:active {
|
|
||||||
background-color: #eaeaea;
|
|
||||||
}
|
|
||||||
.dropdownjs > ul > li:focus {
|
|
||||||
outline: 0;
|
|
||||||
outline: 1px solid #d4d4d4;
|
|
||||||
}
|
|
||||||
.dropdownjs > ul > li > .close:before {
|
|
||||||
content: "\00d7";
|
|
||||||
display: block;
|
|
||||||
position: absolute;
|
|
||||||
right: 15px;
|
|
||||||
float: right;
|
|
||||||
font-size: 21px;
|
|
||||||
font-weight: 700;
|
|
||||||
line-height: 1;
|
|
||||||
color: #000;
|
|
||||||
text-shadow: 0 1px 0 #fff;
|
|
||||||
opacity: .6;
|
|
||||||
}
|
|
||||||
.dropdownjs > ul > li:hover > .close:hover:before {
|
|
||||||
opacity: .9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rtl .dropdownjs > input{
|
|
||||||
padding-right: 0;
|
|
||||||
padding-left: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rtl .dropdownjs > ul[placement=top-right] {
|
|
||||||
-webkit-transform-origin: bottom right;
|
|
||||||
-ms-transform-origin: bottom right;
|
|
||||||
transform-origin: bottom right;
|
|
||||||
bottom: 0;
|
|
||||||
left: auto;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
.rtl .dropdownjs > ul[placement=bottom-right] {
|
|
||||||
-webkit-transform-origin: top right;
|
|
||||||
-ms-transform-origin: top right;
|
|
||||||
transform-origin: top right;
|
|
||||||
top: 0;
|
|
||||||
left: auto;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
.rtl .dropdownjs > ul > li > .close:before {
|
|
||||||
right: auto;
|
|
||||||
left: 15px;
|
|
||||||
float: left;
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
.withripple {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.ripple-container {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
z-index: 1;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
border-radius: inherit;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
.ripple {
|
|
||||||
position: absolute;
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
margin-left: -10px;
|
|
||||||
margin-top: -10px;
|
|
||||||
border-radius: 100%;
|
|
||||||
background-color: #000;
|
|
||||||
background-color: rgba(0, 0, 0, 0.05);
|
|
||||||
-webkit-transform: scale(1);
|
|
||||||
-ms-transform: scale(1);
|
|
||||||
-o-transform: scale(1);
|
|
||||||
transform: scale(1);
|
|
||||||
-webkit-transform-origin: 50%;
|
|
||||||
-ms-transform-origin: 50%;
|
|
||||||
-o-transform-origin: 50%;
|
|
||||||
transform-origin: 50%;
|
|
||||||
opacity: 0;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
.ripple.ripple-on {
|
|
||||||
-webkit-transition: opacity 0.15s ease-in 0s, -webkit-transform 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.1s;
|
|
||||||
-o-transition: opacity 0.15s ease-in 0s, -o-transform 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.1s;
|
|
||||||
transition: opacity 0.15s ease-in 0s, transform 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.1s;
|
|
||||||
opacity: 0.1;
|
|
||||||
}
|
|
||||||
.ripple.ripple-out {
|
|
||||||
-webkit-transition: opacity 0.1s linear 0s !important;
|
|
||||||
-o-transition: opacity 0.1s linear 0s !important;
|
|
||||||
transition: opacity 0.1s linear 0s !important;
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
/*# sourceMappingURL=ripples.css.map */
|
|
|
@ -1 +0,0 @@
|
||||||
{"version":3,"sources":["/less/ripples.less","ripples.css"],"names":[],"mappings":"AAAA;EACI,mBAAA;CCCH;ADCD;EACI,mBAAA;EACA,OAAA;EACA,QAAA;EACA,WAAA;EACA,YAAA;EACA,aAAA;EACA,iBAAA;EACA,uBAAA;EACA,qBAAA;CCCH;ADCD;EACI,mBAAA;EACA,YAAA;EACA,aAAA;EACA,mBAAA;EACA,kBAAA;EACA,oBAAA;EACA,uBAAA;EACA,sCAAA;EACA,4BAAA;MAAA,wBAAA;OAAA,uBAAA;UAAA,oBAAA;EACA,8BAAA;MAAA,0BAAA;OAAA,yBAAA;UAAA,sBAAA;EACA,WAAA;EACA,qBAAA;CCCH;ADCD;EACI,uGAAA;OAAA,6FAAA;UAAA,uFAAA;EACA,aAAA;CCCH;ADCD;EACI,sDAAA;OAAA,iDAAA;UAAA,8CAAA;EACA,WAAA;CCCH","file":"ripples.css","sourcesContent":[".withripple {\n position: relative;\n}\n.ripple-container {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1;\n width: 100%;\n height: 100%;\n overflow: hidden;\n border-radius: inherit;\n pointer-events: none;\n}\n.ripple {\n position: absolute;\n width: 20px;\n height: 20px;\n margin-left: -10px;\n margin-top: -10px;\n border-radius: 100%;\n background-color: #000; // fallback color\n background-color: rgba(0,0,0,0.05);\n transform: scale(1);\n transform-origin: 50%;\n opacity: 0;\n pointer-events: none;\n}\n.ripple.ripple-on {\n transition: opacity 0.15s ease-in 0s, transform 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.1s;\n opacity: 0.1;\n}\n.ripple.ripple-out {\n transition: opacity 0.1s linear 0s !important;\n opacity: 0;\n}\n",".withripple {\n position: relative;\n}\n.ripple-container {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1;\n width: 100%;\n height: 100%;\n overflow: hidden;\n border-radius: inherit;\n pointer-events: none;\n}\n.ripple {\n position: absolute;\n width: 20px;\n height: 20px;\n margin-left: -10px;\n margin-top: -10px;\n border-radius: 100%;\n background-color: #000;\n background-color: rgba(0, 0, 0, 0.05);\n transform: scale(1);\n transform-origin: 50%;\n opacity: 0;\n pointer-events: none;\n}\n.ripple.ripple-on {\n transition: opacity 0.15s ease-in 0s, transform 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.1s;\n opacity: 0.1;\n}\n.ripple.ripple-out {\n transition: opacity 0.1s linear 0s !important;\n opacity: 0;\n}\n/*# sourceMappingURL=ripples.css.map */"]}
|
|
2
public/theme/material/css/ripples.min.css
vendored
2
public/theme/material/css/ripples.min.css
vendored
|
@ -1,2 +0,0 @@
|
||||||
.withripple{position:relative}.ripple-container{position:absolute;top:0;left:0;z-index:1;width:100%;height:100%;overflow:hidden;border-radius:inherit;pointer-events:none}.ripple{position:absolute;width:20px;height:20px;margin-left:-10px;margin-top:-10px;border-radius:100%;background-color:#000;background-color:rgba(0,0,0,.05);-webkit-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1);-webkit-transform-origin:50%;-ms-transform-origin:50%;-o-transform-origin:50%;transform-origin:50%;opacity:0;pointer-events:none}.ripple.ripple-on{-webkit-transition:opacity .15s ease-in 0s,-webkit-transform .5s cubic-bezier(.4,0,.2,1) .1s;-o-transition:opacity .15s ease-in 0s,-o-transform .5s cubic-bezier(.4,0,.2,1) .1s;transition:opacity .15s ease-in 0s,transform .5s cubic-bezier(.4,0,.2,1) .1s;opacity:.1}.ripple.ripple-out{-webkit-transition:opacity .1s linear 0s!important;-o-transition:opacity .1s linear 0s!important;transition:opacity .1s linear 0s!important;opacity:0}
|
|
||||||
/*# sourceMappingURL=ripples.min.css.map */
|
|
|
@ -1 +0,0 @@
|
||||||
{"version":3,"sources":["less/ripples.less"],"names":[],"mappings":"AAAA,YACI,SAAA,SAEJ,kBACI,SAAA,SACA,IAAA,EACA,KAAA,EACA,QAAA,EACA,MAAA,KACA,OAAA,KACA,SAAA,OACA,cAAA,QACA,eAAA,KAEJ,QACI,SAAA,SACA,MAAA,KACA,OAAA,KACA,YAAA,MACA,WAAA,MACA,cAAA,KACA,iBAAA,KACA,iBAAA,gBACA,kBAAA,SAAA,cAAA,SAAA,aAAA,SAAA,UAAA,SACA,yBAAA,IAAA,qBAAA,IAAA,oBAAA,IAAA,iBAAA,IACA,QAAA,EACA,eAAA,KAEJ,kBACI,mBAAA,QAAA,KAAA,QAAA,GAAA,kBAAA,IAAA,wBAAA,IAAA,cAAA,QAAA,KAAA,QAAA,GAAA,aAAA,IAAA,wBAAA,IAAA,WAAA,QAAA,KAAA,QAAA,GAAA,UAAA,IAAA,wBAAA,IACA,QAAA,GAEJ,mBACI,mBAAA,QAAA,IAAA,OAAA,aAAA,cAAA,QAAA,IAAA,OAAA,aAAA,WAAA,QAAA,IAAA,OAAA,aACA,QAAA"}
|
|
|
@ -1,224 +0,0 @@
|
||||||
/* cyrillic-ext */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 300;
|
|
||||||
src: local('Roboto Light'), local('Roboto-Light'), url(../fonts/roboto/0eC6fl06luXEYWpBSJvXCBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
|
|
||||||
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
|
|
||||||
}
|
|
||||||
/* cyrillic */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 300;
|
|
||||||
src: local('Roboto Light'), local('Roboto-Light'), url(../fonts/roboto/Fl4y0QdOxyyTHEGMXX8kcRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
|
|
||||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
|
||||||
}
|
|
||||||
/* greek-ext */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 300;
|
|
||||||
src: local('Roboto Light'), local('Roboto-Light'), url(../fonts/roboto/-L14Jk06m6pUHB-5mXQQnRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
|
|
||||||
unicode-range: U+1F00-1FFF;
|
|
||||||
}
|
|
||||||
/* greek */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 300;
|
|
||||||
src: local('Roboto Light'), local('Roboto-Light'), url(../fonts/roboto/I3S1wsgSg9YCurV6PUkTORJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
|
|
||||||
unicode-range: U+0370-03FF;
|
|
||||||
}
|
|
||||||
/* vietnamese */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 300;
|
|
||||||
src: local('Roboto Light'), local('Roboto-Light'), url(../fonts/roboto/NYDWBdD4gIq26G5XYbHsFBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
|
|
||||||
unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB;
|
|
||||||
}
|
|
||||||
/* latin-ext */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 300;
|
|
||||||
src: local('Roboto Light'), local('Roboto-Light'), url(../fonts/roboto/Pru33qjShpZSmG3z6VYwnRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
|
|
||||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
|
|
||||||
}
|
|
||||||
/* latin */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 300;
|
|
||||||
src: local('Roboto Light'), local('Roboto-Light'), url(../fonts/roboto/Hgo13k-tfSpn0qi1SFdUfVtXRa8TVwTICgirnJhmVJw.woff2) format('woff2');
|
|
||||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
|
|
||||||
}
|
|
||||||
/* cyrillic-ext */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 400;
|
|
||||||
src: local('Roboto'), local('Roboto-Regular'), url(../fonts/roboto/ek4gzZ-GeXAPcSbHtCeQI_esZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
|
|
||||||
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
|
|
||||||
}
|
|
||||||
/* cyrillic */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 400;
|
|
||||||
src: local('Roboto'), local('Roboto-Regular'), url(../fonts/roboto/mErvLBYg_cXG3rLvUsKT_fesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
|
|
||||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
|
||||||
}
|
|
||||||
/* greek-ext */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 400;
|
|
||||||
src: local('Roboto'), local('Roboto-Regular'), url(../fonts/roboto/-2n2p-_Y08sg57CNWQfKNvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
|
|
||||||
unicode-range: U+1F00-1FFF;
|
|
||||||
}
|
|
||||||
/* greek */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 400;
|
|
||||||
src: local('Roboto'), local('Roboto-Regular'), url(../fonts/roboto/u0TOpm082MNkS5K0Q4rhqvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
|
|
||||||
unicode-range: U+0370-03FF;
|
|
||||||
}
|
|
||||||
/* vietnamese */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 400;
|
|
||||||
src: local('Roboto'), local('Roboto-Regular'), url(../fonts/roboto/NdF9MtnOpLzo-noMoG0miPesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
|
|
||||||
unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB;
|
|
||||||
}
|
|
||||||
/* latin-ext */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 400;
|
|
||||||
src: local('Roboto'), local('Roboto-Regular'), url(../fonts/roboto/Fcx7Wwv8OzT71A3E1XOAjvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
|
|
||||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
|
|
||||||
}
|
|
||||||
/* latin */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 400;
|
|
||||||
src: local('Roboto'), local('Roboto-Regular'), url(../fonts/roboto/CWB0XYA8bzo0kSThX0UTuA.woff2) format('woff2');
|
|
||||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
|
|
||||||
}
|
|
||||||
/* cyrillic-ext */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 500;
|
|
||||||
src: local('Roboto Medium'), local('Roboto-Medium'), url(../fonts/roboto/ZLqKeelYbATG60EpZBSDyxJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
|
|
||||||
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
|
|
||||||
}
|
|
||||||
/* cyrillic */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 500;
|
|
||||||
src: local('Roboto Medium'), local('Roboto-Medium'), url(../fonts/roboto/oHi30kwQWvpCWqAhzHcCSBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
|
|
||||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
|
||||||
}
|
|
||||||
/* greek-ext */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 500;
|
|
||||||
src: local('Roboto Medium'), local('Roboto-Medium'), url(../fonts/roboto/rGvHdJnr2l75qb0YND9NyBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
|
|
||||||
unicode-range: U+1F00-1FFF;
|
|
||||||
}
|
|
||||||
/* greek */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 500;
|
|
||||||
src: local('Roboto Medium'), local('Roboto-Medium'), url(../fonts/roboto/mx9Uck6uB63VIKFYnEMXrRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
|
|
||||||
unicode-range: U+0370-03FF;
|
|
||||||
}
|
|
||||||
/* vietnamese */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 500;
|
|
||||||
src: local('Roboto Medium'), local('Roboto-Medium'), url(../fonts/roboto/mbmhprMH69Zi6eEPBYVFhRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
|
|
||||||
unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB;
|
|
||||||
}
|
|
||||||
/* latin-ext */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 500;
|
|
||||||
src: local('Roboto Medium'), local('Roboto-Medium'), url(../fonts/roboto/oOeFwZNlrTefzLYmlVV1UBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
|
|
||||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
|
|
||||||
}
|
|
||||||
/* latin */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 500;
|
|
||||||
src: local('Roboto Medium'), local('Roboto-Medium'), url(../fonts/roboto/RxZJdnzeo3R5zSexge8UUVtXRa8TVwTICgirnJhmVJw.woff2) format('woff2');
|
|
||||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
|
|
||||||
}
|
|
||||||
/* cyrillic-ext */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 700;
|
|
||||||
src: local('Roboto Bold'), local('Roboto-Bold'), url(../fonts/roboto/77FXFjRbGzN4aCrSFhlh3hJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
|
|
||||||
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
|
|
||||||
}
|
|
||||||
/* cyrillic */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 700;
|
|
||||||
src: local('Roboto Bold'), local('Roboto-Bold'), url(../fonts/roboto/isZ-wbCXNKAbnjo6_TwHThJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
|
|
||||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
|
||||||
}
|
|
||||||
/* greek-ext */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 700;
|
|
||||||
src: local('Roboto Bold'), local('Roboto-Bold'), url(../fonts/roboto/UX6i4JxQDm3fVTc1CPuwqhJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
|
|
||||||
unicode-range: U+1F00-1FFF;
|
|
||||||
}
|
|
||||||
/* greek */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 700;
|
|
||||||
src: local('Roboto Bold'), local('Roboto-Bold'), url(../fonts/roboto/jSN2CGVDbcVyCnfJfjSdfBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
|
|
||||||
unicode-range: U+0370-03FF;
|
|
||||||
}
|
|
||||||
/* vietnamese */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 700;
|
|
||||||
src: local('Roboto Bold'), local('Roboto-Bold'), url(../fonts/roboto/PwZc-YbIL414wB9rB1IAPRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
|
|
||||||
unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB;
|
|
||||||
}
|
|
||||||
/* latin-ext */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 700;
|
|
||||||
src: local('Roboto Bold'), local('Roboto-Bold'), url(../fonts/roboto/97uahxiqZRoncBaCEI3aWxJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
|
|
||||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
|
|
||||||
}
|
|
||||||
/* latin */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 700;
|
|
||||||
src: local('Roboto Bold'), local('Roboto-Bold'), url(../fonts/roboto/d-6IYplOFocCacKzxwXSOFtXRa8TVwTICgirnJhmVJw.woff2) format('woff2');
|
|
||||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
|
|
||||||
}
|
|
|
@ -1,90 +0,0 @@
|
||||||
/* line 2, ../sass/_sortable.sass */
|
|
||||||
table[data-sortable] {
|
|
||||||
border-collapse: collapse;
|
|
||||||
border-spacing: 0;
|
|
||||||
}
|
|
||||||
/* line 6, ../sass/_sortable.sass */
|
|
||||||
table[data-sortable] th {
|
|
||||||
vertical-align: bottom;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
/* line 10, ../sass/_sortable.sass */
|
|
||||||
table[data-sortable] th, table[data-sortable] td {
|
|
||||||
text-align: left;
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
/* line 14, ../sass/_sortable.sass */
|
|
||||||
table[data-sortable] th:not([data-sortable="false"]) {
|
|
||||||
-webkit-user-select: none;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-ms-user-select: none;
|
|
||||||
-o-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
|
||||||
-webkit-touch-callout: none;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
/* line 26, ../sass/_sortable.sass */
|
|
||||||
table[data-sortable] th:after {
|
|
||||||
content: "";
|
|
||||||
visibility: hidden;
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: inherit;
|
|
||||||
height: 0;
|
|
||||||
width: 0;
|
|
||||||
border-width: 5px;
|
|
||||||
border-style: solid;
|
|
||||||
border-color: transparent;
|
|
||||||
margin-right: 1px;
|
|
||||||
margin-left: 10px;
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
/* line 40, ../sass/_sortable.sass */
|
|
||||||
table[data-sortable] th[data-sorted="true"]:after {
|
|
||||||
visibility: visible;
|
|
||||||
}
|
|
||||||
/* line 43, ../sass/_sortable.sass */
|
|
||||||
table[data-sortable] th[data-sorted-direction="descending"]:after {
|
|
||||||
border-top-color: inherit;
|
|
||||||
margin-top: 8px;
|
|
||||||
}
|
|
||||||
/* line 47, ../sass/_sortable.sass */
|
|
||||||
table[data-sortable] th[data-sorted-direction="ascending"]:after {
|
|
||||||
border-bottom-color: inherit;
|
|
||||||
margin-top: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* line 5, ../sass/sortable-theme-bootstrap.sass */
|
|
||||||
table[data-sortable].sortable-theme-bootstrap {
|
|
||||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 20px;
|
|
||||||
color: #333333;
|
|
||||||
background: white;
|
|
||||||
}
|
|
||||||
/* line 12, ../sass/sortable-theme-bootstrap.sass */
|
|
||||||
table[data-sortable].sortable-theme-bootstrap thead th {
|
|
||||||
border-bottom: 2px solid #e0e0e0;
|
|
||||||
}
|
|
||||||
/* line 15, ../sass/sortable-theme-bootstrap.sass */
|
|
||||||
table[data-sortable].sortable-theme-bootstrap tbody td {
|
|
||||||
border-top: 1px solid #e0e0e0;
|
|
||||||
}
|
|
||||||
/* line 18, ../sass/sortable-theme-bootstrap.sass */
|
|
||||||
table[data-sortable].sortable-theme-bootstrap th[data-sorted="true"] {
|
|
||||||
color: #3a87ad;
|
|
||||||
background: #d9edf7;
|
|
||||||
border-bottom-color: #bce8f1;
|
|
||||||
}
|
|
||||||
/* line 23, ../sass/sortable-theme-bootstrap.sass */
|
|
||||||
table[data-sortable].sortable-theme-bootstrap th[data-sorted="true"][data-sorted-direction="descending"]:after {
|
|
||||||
border-top-color: #3a87ad;
|
|
||||||
}
|
|
||||||
/* line 26, ../sass/sortable-theme-bootstrap.sass */
|
|
||||||
table[data-sortable].sortable-theme-bootstrap th[data-sorted="true"][data-sorted-direction="ascending"]:after {
|
|
||||||
border-bottom-color: #3a87ad;
|
|
||||||
}
|
|
||||||
/* line 31, ../sass/sortable-theme-bootstrap.sass */
|
|
||||||
table[data-sortable].sortable-theme-bootstrap.sortable-theme-bootstrap-striped tbody > tr:nth-child(odd) > td {
|
|
||||||
background-color: #f9f9f9;
|
|
||||||
}
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
7
public/theme/material/js/bootstrap.min.js
vendored
7
public/theme/material/js/bootstrap.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -1,2 +0,0 @@
|
||||||
$.material.init();
|
|
||||||
$("#dropdown-menu select").dropdown();
|
|
|
@ -1,431 +0,0 @@
|
||||||
/* globals jQuery, window, document */
|
|
||||||
|
|
||||||
(function (factory) {
|
|
||||||
if (typeof define === 'function' && define.amd) {
|
|
||||||
// AMD. Register as an anonymous module.
|
|
||||||
define(['jquery'], factory);
|
|
||||||
} else if (typeof exports === 'object') {
|
|
||||||
// Node/CommonJS
|
|
||||||
module.exports = factory(require('jquery'));
|
|
||||||
} else {
|
|
||||||
// Browser globals
|
|
||||||
factory(jQuery);
|
|
||||||
}
|
|
||||||
}(function($) {
|
|
||||||
|
|
||||||
var methods = {
|
|
||||||
options : {
|
|
||||||
"optionClass": "",
|
|
||||||
"dropdownClass": "",
|
|
||||||
"autoinit": false,
|
|
||||||
"callback": false,
|
|
||||||
"onSelected": false,
|
|
||||||
"destroy": function(element) {
|
|
||||||
this.destroy(element);
|
|
||||||
},
|
|
||||||
"dynamicOptLabel": "Add a new option..."
|
|
||||||
},
|
|
||||||
init: function(options) {
|
|
||||||
|
|
||||||
// Apply user options if user has defined some
|
|
||||||
if (options) {
|
|
||||||
options = $.extend(methods.options, options);
|
|
||||||
} else {
|
|
||||||
options = methods.options;
|
|
||||||
}
|
|
||||||
|
|
||||||
function initElement($select) {
|
|
||||||
// Don't do anything if this is not a select or if this select was already initialized
|
|
||||||
if ($select.data("dropdownjs") || !$select.is("select")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is it a multi select?
|
|
||||||
var multi = $select.attr("multiple");
|
|
||||||
|
|
||||||
// Does it allow to create new options dynamically?
|
|
||||||
var dynamicOptions = $select.attr("data-dynamic-opts"),
|
|
||||||
$dynamicInput = $();
|
|
||||||
|
|
||||||
// Create the dropdown wrapper
|
|
||||||
var $dropdown = $("<div></div>");
|
|
||||||
$dropdown.addClass("dropdownjs").addClass(options.dropdownClass);
|
|
||||||
$dropdown.data("select", $select);
|
|
||||||
|
|
||||||
// Create the fake input used as "select" element and cache it as $input
|
|
||||||
var $input = $("<input type=text readonly class=fakeinput>");
|
|
||||||
if ($.material) { $input.data("mdproc", true); }
|
|
||||||
// Append it to the dropdown wrapper
|
|
||||||
$dropdown.append($input);
|
|
||||||
|
|
||||||
// Create the UL that will be used as dropdown and cache it AS $ul
|
|
||||||
var $ul = $("<ul></ul>");
|
|
||||||
$ul.data("select", $select);
|
|
||||||
|
|
||||||
// Append it to the dropdown
|
|
||||||
$dropdown.append($ul);
|
|
||||||
|
|
||||||
// Transfer the placeholder attribute
|
|
||||||
$input.attr("placeholder", $select.attr("placeholder"));
|
|
||||||
|
|
||||||
// Loop trough options and transfer them to the dropdown menu
|
|
||||||
$select.find("option").each(function() {
|
|
||||||
// Cache $(this)
|
|
||||||
var $this = $(this);
|
|
||||||
methods._addOption($ul, $this);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// If this select allows dynamic options add the widget
|
|
||||||
if (dynamicOptions) {
|
|
||||||
$dynamicInput = $("<li class=dropdownjs-add></li>");
|
|
||||||
$dynamicInput.append("<input>");
|
|
||||||
$dynamicInput.find("input").attr("placeholder", options.dynamicOptLabel);
|
|
||||||
$ul.append($dynamicInput);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Cache the dropdown options
|
|
||||||
var selectOptions = $dropdown.find("li");
|
|
||||||
|
|
||||||
// If is a single select, selected the first one or the last with selected attribute
|
|
||||||
if (!multi) {
|
|
||||||
var $selected;
|
|
||||||
if ($select.find(":selected").length) {
|
|
||||||
$selected = $select.find(":selected").last();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$selected = $select.find("option, li").first();
|
|
||||||
// $selected = $select.find("option").first();
|
|
||||||
}
|
|
||||||
methods._select($dropdown, $selected);
|
|
||||||
} else {
|
|
||||||
var selectors = [], val = $select.val()
|
|
||||||
for (var i in val) {
|
|
||||||
selectors.push(val[i]);
|
|
||||||
}
|
|
||||||
if (selectors.length > 0) {
|
|
||||||
var $target = $dropdown.find(function() { return $.inArray($(this).data("value"), selectors) !== -1; });
|
|
||||||
$target.removeClass("selected");
|
|
||||||
methods._select($dropdown, $target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transfer the classes of the select to the input dropdown
|
|
||||||
$input.addClass($select[0].className);
|
|
||||||
|
|
||||||
// Hide the old and ugly select
|
|
||||||
$select.hide().attr("data-dropdownjs", true);
|
|
||||||
|
|
||||||
// Bring to life our awesome dropdownjs
|
|
||||||
$select.after($dropdown);
|
|
||||||
|
|
||||||
// Call the callback
|
|
||||||
if (options.callback) {
|
|
||||||
options.callback($dropdown);
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------//
|
|
||||||
// DROPDOWN EVENTS //
|
|
||||||
//---------------------------------------//
|
|
||||||
|
|
||||||
// On click, set the clicked one as selected
|
|
||||||
$ul.on("click", "li:not(.dropdownjs-add)", function(e) {
|
|
||||||
methods._select($dropdown, $(this));
|
|
||||||
// trigger change event, if declared on the original selector
|
|
||||||
$select.change();
|
|
||||||
});
|
|
||||||
$ul.on("keydown", "li:not(.dropdownjs-add)", function(e) {
|
|
||||||
if (e.which === 27) {
|
|
||||||
$(".dropdownjs > ul > li").attr("tabindex", -1);
|
|
||||||
return $input.removeClass("focus").blur();
|
|
||||||
}
|
|
||||||
if (e.which === 32 && !$(e.target).is("input")) {
|
|
||||||
methods._select($dropdown, $(this));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$ul.on("focus", "li:not(.dropdownjs-add)", function() {
|
|
||||||
if ($select.is(":disabled")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$input.addClass("focus");
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add new options when the widget is used
|
|
||||||
if (dynamicOptions && dynamicOptions.length) {
|
|
||||||
$dynamicInput.on("keydown", function(e) {
|
|
||||||
if(e.which !== 13) return;
|
|
||||||
var $option = $("<option>"),
|
|
||||||
val = $dynamicInput.find("input").val();
|
|
||||||
$dynamicInput.find("input").val("");
|
|
||||||
|
|
||||||
$option.attr("value", val);
|
|
||||||
$option.text(val);
|
|
||||||
$select.append($option);
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listen for new added options and update dropdown if needed
|
|
||||||
$select.on("DOMNodeInserted", function(e) {
|
|
||||||
var $this = $(e.target);
|
|
||||||
if (!$this.val().length) return;
|
|
||||||
|
|
||||||
methods._addOption($ul, $this);
|
|
||||||
$ul.find("li").not(".dropdownjs-add").attr("tabindex", 0);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
$select.on("DOMNodeRemoved", function(e) {
|
|
||||||
var deletedValue = $(e.target).attr('value');
|
|
||||||
$ul.find("li").filter(function() { return $(this).data("value") === deletedValue; }).remove();
|
|
||||||
var $selected;
|
|
||||||
|
|
||||||
setTimeout(function () {
|
|
||||||
if ($select.find(":selected").length) {
|
|
||||||
$selected = $select.find(":selected").last();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$selected = $select.find("option, li").first();
|
|
||||||
}
|
|
||||||
methods._select($dropdown, $selected);
|
|
||||||
}, 100);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update dropdown when using val, need to use .val("value").trigger("change");
|
|
||||||
$select.on("change", function(e) {
|
|
||||||
var $this = $(e.target);
|
|
||||||
|
|
||||||
if (!multi) {
|
|
||||||
var $selected;
|
|
||||||
if ($select.find(":selected").length) {
|
|
||||||
$selected = $select.find(":selected").last();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$selected = $select.find("option, li").first();
|
|
||||||
}
|
|
||||||
methods._select($dropdown, $selected);
|
|
||||||
} else {
|
|
||||||
var target = $select.find(":selected"),
|
|
||||||
values = $(this).val();
|
|
||||||
// Unselect all options
|
|
||||||
selectOptions.removeClass("selected");
|
|
||||||
// Select options
|
|
||||||
target.each(function () {
|
|
||||||
var selected = selectOptions.filter(function() { return $.inArray($(this).data("value"), values) !== -1; });
|
|
||||||
selected.addClass("selected");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Used to make the dropdown menu more dropdown-ish
|
|
||||||
$input.on("click focus", function(e) {
|
|
||||||
e.stopPropagation();
|
|
||||||
if ($select.is(":disabled")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$(".dropdownjs > ul > li").attr("tabindex", -1);
|
|
||||||
$(".dropdownjs > input").not($(this)).removeClass("focus").blur();
|
|
||||||
|
|
||||||
$(".dropdownjs > ul > li").not(".dropdownjs-add").attr("tabindex", 0);
|
|
||||||
|
|
||||||
// Set height of the dropdown
|
|
||||||
var coords = {
|
|
||||||
top: $(this).offset().top - $(document).scrollTop(),
|
|
||||||
left: $(this).offset().left - $(document).scrollLeft(),
|
|
||||||
bottom: $(window).height() - ($(this).offset().top - $(document).scrollTop()),
|
|
||||||
right: $(window).width() - ($(this).offset().left - $(document).scrollLeft())
|
|
||||||
};
|
|
||||||
|
|
||||||
var height = coords.bottom;
|
|
||||||
|
|
||||||
// Decide if place the dropdown below or above the input
|
|
||||||
if (height < 200 && coords.top > coords.bottom) {
|
|
||||||
height = coords.top;
|
|
||||||
$ul.attr("placement", $("body").hasClass("rtl") ? "top-right" : "top-left");
|
|
||||||
} else {
|
|
||||||
$ul.attr("placement", $("body").hasClass("rtl") ? "bottom-right" : "bottom-left");
|
|
||||||
}
|
|
||||||
|
|
||||||
$(this).next("ul").css("max-height", height - 20);
|
|
||||||
$(this).addClass("focus");
|
|
||||||
});
|
|
||||||
// Close every dropdown on click outside
|
|
||||||
$(document).on("click", function(e) {
|
|
||||||
|
|
||||||
// Don't close the multi dropdown if user is clicking inside it
|
|
||||||
if (multi && $(e.target).parents(".dropdownjs").length) return;
|
|
||||||
|
|
||||||
// Don't close the dropdown if user is clicking inside the dynamic-opts widget
|
|
||||||
if ($(e.target).parents(".dropdownjs-add").length || $(e.target).is(".dropdownjs-add")) return;
|
|
||||||
|
|
||||||
// Close opened dropdowns
|
|
||||||
$(".dropdownjs > ul > li").attr("tabindex", -1);
|
|
||||||
if ($(e.target).hasClass('disabled')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$input.removeClass("focus");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.autoinit) {
|
|
||||||
$(document).on("DOMNodeInserted", function(e) {
|
|
||||||
var $this = $(e.target);
|
|
||||||
if (!$this.is("select")) {
|
|
||||||
$this = $this.find('select');
|
|
||||||
}
|
|
||||||
$this.each(function() {
|
|
||||||
if ($(this).is(options.autoinit)) {
|
|
||||||
initElement($(this));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loop trough elements
|
|
||||||
$(this).each(function() {
|
|
||||||
initElement($(this));
|
|
||||||
});
|
|
||||||
},
|
|
||||||
select: function(target) {
|
|
||||||
var $target = $(this).find(function() { return $(this).data("value") === target; });
|
|
||||||
methods._select($(this), $target);
|
|
||||||
},
|
|
||||||
_select: function($dropdown, $target) {
|
|
||||||
|
|
||||||
if ($target.is(".dropdownjs-add")) return;
|
|
||||||
|
|
||||||
// Get dropdown's elements
|
|
||||||
var $select = $dropdown.data("select"),
|
|
||||||
$input = $dropdown.find("input.fakeinput");
|
|
||||||
// Is it a multi select?
|
|
||||||
var multi = $select.attr("multiple");
|
|
||||||
|
|
||||||
// Cache the dropdown options
|
|
||||||
var selectOptions = $dropdown.find("li");
|
|
||||||
|
|
||||||
// Behavior for multiple select
|
|
||||||
if (multi) {
|
|
||||||
// Toggle option state
|
|
||||||
$target.toggleClass("selected");
|
|
||||||
// Toggle selection of the clicked option in native select
|
|
||||||
$target.each(function(){
|
|
||||||
var value = $(this).prop("tagName") === "OPTION" ? $(this).val() : $(this).data("value"),
|
|
||||||
$selected = $select.find("[value=\"" + value + "\"]");
|
|
||||||
$selected.prop("selected", $(this).hasClass("selected"));
|
|
||||||
});
|
|
||||||
// Add or remove the value from the input
|
|
||||||
var text = [];
|
|
||||||
selectOptions.each(function() {
|
|
||||||
if ($(this).hasClass("selected")) {
|
|
||||||
text.push($(this).text());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$input.val(text.join(", "));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Behavior for single select
|
|
||||||
if (!multi) {
|
|
||||||
if ($target.hasClass("disabled")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Unselect options except the one that will be selected
|
|
||||||
if ($target.is("li")) {
|
|
||||||
selectOptions.not($target).removeClass("selected");
|
|
||||||
}
|
|
||||||
// Select the selected option
|
|
||||||
$target.addClass("selected");
|
|
||||||
// Set the value to the input
|
|
||||||
$input.val($target.text().trim());
|
|
||||||
var value = $target.prop("tagName") === "OPTION" ? $target.val() : $target.data("value");
|
|
||||||
// When val is set below on $select, it will fire change event,
|
|
||||||
// which ends up back here, make sure to not end up in an infinite loop.
|
|
||||||
// This is done last so text input is initialized on first load when condition is true.
|
|
||||||
if (value === $select.val()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Set the value to the native select
|
|
||||||
$select.val(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is used only if Material Design for Bootstrap is selected
|
|
||||||
if ($.material) {
|
|
||||||
if ($input.val().trim()) {
|
|
||||||
$select.removeClass("empty");
|
|
||||||
} else {
|
|
||||||
$select.addClass("empty");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call the callback
|
|
||||||
if (this.options.onSelected) {
|
|
||||||
this.options.onSelected($target.data("value"));
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
_addOption: function($ul, $this) {
|
|
||||||
// Create the option
|
|
||||||
var $option = $("<li></li>");
|
|
||||||
|
|
||||||
// Style the option
|
|
||||||
$option.addClass(this.options.optionClass);
|
|
||||||
|
|
||||||
// If the option has some text then transfer it
|
|
||||||
if ($this.text()) {
|
|
||||||
$option.text($this.text());
|
|
||||||
}
|
|
||||||
// Otherwise set the empty label and set it as an empty option
|
|
||||||
else {
|
|
||||||
$option.html(" ");
|
|
||||||
}
|
|
||||||
// Set the value of the option
|
|
||||||
$option.data("value", $this.val());
|
|
||||||
|
|
||||||
// Will user be able to remove this option?
|
|
||||||
if ($ul.data("select").attr("data-dynamic-opts")) {
|
|
||||||
$option.append("<span class=close></span>");
|
|
||||||
$option.find(".close").on("click", function() {
|
|
||||||
$option.remove();
|
|
||||||
$this.remove();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ss it selected?
|
|
||||||
if ($this.prop("selected")) {
|
|
||||||
$option.attr("selected", true);
|
|
||||||
$option.addClass("selected");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this.prop("disabled")) {
|
|
||||||
$option.addClass("disabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append option to our dropdown
|
|
||||||
if ($ul.find(".dropdownjs-add").length) {
|
|
||||||
$ul.find(".dropdownjs-add").before($option);
|
|
||||||
} else {
|
|
||||||
$ul.append($option);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
destroy: function($e) {
|
|
||||||
$($e).show().removeAttr('data-dropdownjs').next('.dropdownjs').remove();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$.fn.dropdown = function(params) {
|
|
||||||
if( typeof methods[params] == 'function' ) methods[params](this);
|
|
||||||
if (methods[params]) {
|
|
||||||
return methods[params].apply(this, Array.prototype.slice.call(arguments,1));
|
|
||||||
} else if (typeof params === "object" | !params) {
|
|
||||||
return methods.init.apply(this, arguments);
|
|
||||||
} else {
|
|
||||||
$.error("Method " + params + " does not exists on jQuery.dropdown");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}));
|
|
||||||
|
|
6
public/theme/material/js/jquery.min.js
vendored
6
public/theme/material/js/jquery.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -1,31 +0,0 @@
|
||||||
/*
|
|
||||||
|
|
||||||
$.Link (part of noUiSlider) - WTFPL */
|
|
||||||
(function(c){function m(a,c,d){if((a[c]||a[d])&&a[c]===a[d])throw Error("(Link) '"+c+"' can't match '"+d+"'.'");}function r(a){void 0===a&&(a={});if("object"!==typeof a)throw Error("(Format) 'format' option must be an object.");var h={};c(u).each(function(c,n){if(void 0===a[n])h[n]=A[c];else if(typeof a[n]===typeof A[c]){if("decimals"===n&&(0>a[n]||7<a[n]))throw Error("(Format) 'format.decimals' option must be between 0 and 7.");h[n]=a[n]}else throw Error("(Format) 'format."+n+"' must be a "+typeof A[c]+
|
|
||||||
".");});m(h,"mark","thousand");m(h,"prefix","negative");m(h,"prefix","negativeBefore");this.r=h}function k(a,h){"object"!==typeof a&&c.error("(Link) Initialize with an object.");return new k.prototype.p(a.target||function(){},a.method,a.format||{},h)}var u="decimals mark thousand prefix postfix encoder decoder negative negativeBefore to from".split(" "),A=[2,".","","","",function(a){return a},function(a){return a},"-","",function(a){return a},function(a){return a}];r.prototype.a=function(a){return this.r[a]};
|
|
||||||
r.prototype.L=function(a){function c(a){return a.split("").reverse().join("")}a=this.a("encoder")(a);var d=this.a("decimals"),n="",k="",m="",r="";0===parseFloat(a.toFixed(d))&&(a="0");0>a&&(n=this.a("negative"),k=this.a("negativeBefore"));a=Math.abs(a).toFixed(d).toString();a=a.split(".");this.a("thousand")?(m=c(a[0]).match(/.{1,3}/g),m=c(m.join(c(this.a("thousand"))))):m=a[0];this.a("mark")&&1<a.length&&(r=this.a("mark")+a[1]);return this.a("to")(k+this.a("prefix")+n+m+r+this.a("postfix"))};r.prototype.w=
|
|
||||||
function(a){function c(a){return a.replace(/[\-\/\\\^$*+?.()|\[\]{}]/g,"\\$&")}var d;if(null===a||void 0===a)return!1;a=this.a("from")(a);a=a.toString();d=a.replace(RegExp("^"+c(this.a("negativeBefore"))),"");a!==d?(a=d,d="-"):d="";a=a.replace(RegExp("^"+c(this.a("prefix"))),"");this.a("negative")&&(d="",a=a.replace(RegExp("^"+c(this.a("negative"))),"-"));a=a.replace(RegExp(c(this.a("postfix"))+"$"),"").replace(RegExp(c(this.a("thousand")),"g"),"").replace(this.a("mark"),".");a=this.a("decoder")(parseFloat(d+
|
|
||||||
a));return isNaN(a)?!1:a};k.prototype.K=function(a,h){this.method=h||"html";this.j=c(a.replace("-tooltip-","")||"<div/>")[0]};k.prototype.H=function(a){this.method="val";this.j=document.createElement("input");this.j.name=a;this.j.type="hidden"};k.prototype.G=function(a){function h(a,c){return[c?null:a,c?a:null]}var d=this;this.method="val";this.target=a.on("change",function(a){d.B.val(h(c(a.target).val(),d.t),{link:d,set:!0})})};k.prototype.p=function(a,h,d,k){this.g=d;this.update=!k;if("string"===
|
|
||||||
typeof a&&0===a.indexOf("-tooltip-"))this.K(a,h);else if("string"===typeof a&&0!==a.indexOf("-"))this.H(a);else if("function"===typeof a)this.target=!1,this.method=a;else{if(a instanceof c||c.zepto&&c.zepto.isZ(a)){if(!h){if(a.is("input, select, textarea")){this.G(a);return}h="html"}if("function"===typeof h||"string"===typeof h&&a[h]){this.method=h;this.target=a;return}}throw new RangeError("(Link) Invalid Link.");}};k.prototype.write=function(a,c,d,k){if(!this.update||!1!==k)if(this.u=a,this.F=a=
|
|
||||||
this.format(a),"function"===typeof this.method)this.method.call(this.target[0]||d[0],a,c,d);else this.target[this.method](a,c,d)};k.prototype.q=function(a){this.g=new r(c.extend({},a,this.g instanceof r?this.g.r:this.g))};k.prototype.J=function(a){this.B=a};k.prototype.I=function(a){this.t=a};k.prototype.format=function(a){return this.g.L(a)};k.prototype.A=function(a){return this.g.w(a)};k.prototype.p.prototype=k.prototype;c.Link=k})(window.jQuery||window.Zepto);/*
|
|
||||||
|
|
||||||
$.fn.noUiSlider - WTFPL - refreshless.com/nouislider/ */
|
|
||||||
(function(c){function m(e){return"number"===typeof e&&!isNaN(e)&&isFinite(e)}function r(e){return c.isArray(e)?e:[e]}function k(e,b){e.addClass(b);setTimeout(function(){e.removeClass(b)},300)}function u(e,b){return 100*b/(e[1]-e[0])}function A(e,b){if(b>=e.d.slice(-1)[0])return 100;for(var a=1,c,f,d;b>=e.d[a];)a++;c=e.d[a-1];f=e.d[a];d=e.c[a-1];c=[c,f];return d+u(c,0>c[0]?b+Math.abs(c[0]):b-c[0])/(100/(e.c[a]-d))}function a(e,b){if(100<=b)return e.d.slice(-1)[0];for(var a=1,c,f,d;b>=e.c[a];)a++;c=
|
|
||||||
e.d[a-1];f=e.d[a];d=e.c[a-1];c=[c,f];return 100/(e.c[a]-d)*(b-d)*(c[1]-c[0])/100+c[0]}function h(a,b){for(var c=1,g;(a.dir?100-b:b)>=a.c[c];)c++;if(a.m)return g=a.c[c-1],c=a.c[c],b-g>(c-g)/2?c:g;a.h[c-1]?(g=a.h[c-1],c=a.c[c-1]+Math.round((b-a.c[c-1])/g)*g):c=b;return c}function d(a,b){if(!m(b))throw Error("noUiSlider: 'step' is not numeric.");a.h[0]=b}function n(a,b){if("object"!==typeof b||c.isArray(b))throw Error("noUiSlider: 'range' is not an object.");if(void 0===b.min||void 0===b.max)throw Error("noUiSlider: Missing 'min' or 'max' in 'range'.");
|
|
||||||
c.each(b,function(b,g){var d;"number"===typeof g&&(g=[g]);if(!c.isArray(g))throw Error("noUiSlider: 'range' contains invalid value.");d="min"===b?0:"max"===b?100:parseFloat(b);if(!m(d)||!m(g[0]))throw Error("noUiSlider: 'range' value isn't numeric.");a.c.push(d);a.d.push(g[0]);d?a.h.push(isNaN(g[1])?!1:g[1]):isNaN(g[1])||(a.h[0]=g[1])});c.each(a.h,function(b,c){if(!c)return!0;a.h[b]=u([a.d[b],a.d[b+1]],c)/(100/(a.c[b+1]-a.c[b]))})}function E(a,b){"number"===typeof b&&(b=[b]);if(!c.isArray(b)||!b.length||
|
|
||||||
2<b.length)throw Error("noUiSlider: 'start' option is incorrect.");a.b=b.length;a.start=b}function I(a,b){a.m=b;if("boolean"!==typeof b)throw Error("noUiSlider: 'snap' option must be a boolean.");}function J(a,b){if("lower"===b&&1===a.b)a.i=1;else if("upper"===b&&1===a.b)a.i=2;else if(!0===b&&2===a.b)a.i=3;else if(!1===b)a.i=0;else throw Error("noUiSlider: 'connect' option doesn't match handle count.");}function D(a,b){switch(b){case "horizontal":a.k=0;break;case "vertical":a.k=1;break;default:throw Error("noUiSlider: 'orientation' option is invalid.");
|
|
||||||
}}function K(a,b){if(2<a.c.length)throw Error("noUiSlider: 'margin' option is only supported on linear sliders.");a.margin=u(a.d,b);if(!m(b))throw Error("noUiSlider: 'margin' option must be numeric.");}function L(a,b){switch(b){case "ltr":a.dir=0;break;case "rtl":a.dir=1;a.i=[0,2,1,3][a.i];break;default:throw Error("noUiSlider: 'direction' option was not recognized.");}}function M(a,b){if("string"!==typeof b)throw Error("noUiSlider: 'behaviour' must be a string containing options.");var c=0<=b.indexOf("snap");
|
|
||||||
a.n={s:0<=b.indexOf("tap")||c,extend:0<=b.indexOf("extend"),v:0<=b.indexOf("drag"),fixed:0<=b.indexOf("fixed"),m:c}}function N(a,b,d){a.o=[b.lower,b.upper];a.g=b.format;c.each(a.o,function(a,e){if(!c.isArray(e))throw Error("noUiSlider: 'serialization."+(a?"upper":"lower")+"' must be an array.");c.each(e,function(){if(!(this instanceof c.Link))throw Error("noUiSlider: 'serialization."+(a?"upper":"lower")+"' can only contain Link instances.");this.I(a);this.J(d);this.q(b.format)})});a.dir&&1<a.b&&a.o.reverse()}
|
|
||||||
function O(a,b){var f={c:[],d:[],h:[!1],margin:0},g;g={step:{e:!1,f:d},start:{e:!0,f:E},connect:{e:!0,f:J},direction:{e:!0,f:L},range:{e:!0,f:n},snap:{e:!1,f:I},orientation:{e:!1,f:D},margin:{e:!1,f:K},behaviour:{e:!0,f:M},serialization:{e:!0,f:N}};a=c.extend({connect:!1,direction:"ltr",behaviour:"tap",orientation:"horizontal"},a);a.serialization=c.extend({lower:[],upper:[],format:{}},a.serialization);c.each(g,function(c,d){if(void 0===a[c]){if(d.e)throw Error("noUiSlider: '"+c+"' is required.");
|
|
||||||
return!0}d.f(f,a[c],b)});f.style=f.k?"top":"left";return f}function P(a,b){var d=c("<div><div/></div>").addClass(f[2]),g=["-lower","-upper"];a.dir&&g.reverse();d.children().addClass(f[3]+" "+f[3]+g[b]);return d}function Q(a,b){b.j&&(b=new c.Link({target:c(b.j).clone().appendTo(a),method:b.method,format:b.g},!0));return b}function R(a,b){var d,f=[];for(d=0;d<a.b;d++){var k=f,h=d,m=a.o[d],n=b[d].children(),r=a.g,s=void 0,v=[],s=new c.Link({},!0);s.q(r);v.push(s);for(s=0;s<m.length;s++)v.push(Q(n,m[s]));
|
|
||||||
k[h]=v}return f}function S(a,b,c){switch(a){case 1:b.addClass(f[7]);c[0].addClass(f[6]);break;case 3:c[1].addClass(f[6]);case 2:c[0].addClass(f[7]);case 0:b.addClass(f[6])}}function T(a,b){var c,d=[];for(c=0;c<a.b;c++)d.push(P(a,c).appendTo(b));return d}function U(a,b){b.addClass([f[0],f[8+a.dir],f[4+a.k]].join(" "));return c("<div/>").appendTo(b).addClass(f[1])}function V(d,b,m){function g(){return t[["width","height"][b.k]]()}function n(a){var b,c=[q.val()];for(b=0;b<a.length;b++)q.trigger(a[b],
|
|
||||||
c)}function u(d,p,e){var g=d[0]!==l[0][0]?1:0,H=x[0]+b.margin,k=x[1]-b.margin;e&&1<l.length&&(p=g?Math.max(p,H):Math.min(p,k));100>p&&(p=h(b,p));p=Math.max(Math.min(parseFloat(p.toFixed(7)),100),0);if(p===x[g])return 1===l.length?!1:p===H||p===k?0:!1;d.css(b.style,p+"%");d.is(":first-child")&&d.toggleClass(f[17],50<p);x[g]=p;b.dir&&(p=100-p);c(y[g]).each(function(){this.write(a(b,p),d.children(),q)});return!0}function B(a,b,c){c||k(q,f[14]);u(a,b,!1);n(["slide","set","change"])}function w(a,c,d,e){a=
|
|
||||||
a.replace(/\s/g,".nui ")+".nui";c.on(a,function(a){var c=q.attr("disabled");if(q.hasClass(f[14])||void 0!==c&&null!==c)return!1;a.preventDefault();var c=0===a.type.indexOf("touch"),p=0===a.type.indexOf("mouse"),F=0===a.type.indexOf("pointer"),g,k,l=a;0===a.type.indexOf("MSPointer")&&(F=!0);a.originalEvent&&(a=a.originalEvent);c&&(g=a.changedTouches[0].pageX,k=a.changedTouches[0].pageY);if(p||F)F||void 0!==window.pageXOffset||(window.pageXOffset=document.documentElement.scrollLeft,window.pageYOffset=
|
|
||||||
document.documentElement.scrollTop),g=a.clientX+window.pageXOffset,k=a.clientY+window.pageYOffset;l.C=[g,k];l.cursor=p;a=l;a.l=a.C[b.k];d(a,e)})}function C(a,c){var b=c.b||l,d,e=!1,e=100*(a.l-c.start)/g(),f=b[0][0]!==l[0][0]?1:0;var k=c.D;d=e+k[0];e+=k[1];1<b.length?(0>d&&(e+=Math.abs(d)),100<e&&(d-=e-100),d=[Math.max(Math.min(d,100),0),Math.max(Math.min(e,100),0)]):d=[d,e];e=u(b[0],d[f],1===b.length);1<b.length&&(e=u(b[1],d[f?0:1],!1)||e);e&&n(["slide"])}function s(a){c("."+f[15]).removeClass(f[15]);
|
|
||||||
a.cursor&&c("body").css("cursor","").off(".nui");G.off(".nui");q.removeClass(f[12]);n(["set","change"])}function v(a,b){1===b.b.length&&b.b[0].children().addClass(f[15]);a.stopPropagation();w(z.move,G,C,{start:a.l,b:b.b,D:[x[0],x[l.length-1]]});w(z.end,G,s,null);a.cursor&&(c("body").css("cursor",c(a.target).css("cursor")),1<l.length&&q.addClass(f[12]),c("body").on("selectstart.nui",!1))}function D(a){var d=a.l,e=0;a.stopPropagation();c.each(l,function(){e+=this.offset()[b.style]});e=d<e/2||1===l.length?
|
|
||||||
0:1;d-=t.offset()[b.style];d=100*d/g();B(l[e],d,b.n.m);b.n.m&&v(a,{b:[l[e]]})}function E(a){var c=(a=a.l<t.offset()[b.style])?0:100;a=a?0:l.length-1;B(l[a],c,!1)}var q=c(d),x=[-1,-1],t,y,l;if(q.hasClass(f[0]))throw Error("Slider was already initialized.");t=U(b,q);l=T(b,t);y=R(b,l);S(b.i,q,l);(function(a){var b;if(!a.fixed)for(b=0;b<l.length;b++)w(z.start,l[b].children(),v,{b:[l[b]]});a.s&&w(z.start,t,D,{b:l});a.extend&&(q.addClass(f[16]),a.s&&w(z.start,q,E,{b:l}));a.v&&(b=t.find("."+f[7]).addClass(f[10]),
|
|
||||||
a.fixed&&(b=b.add(t.children().not(b).children())),w(z.start,b,v,{b:l}))})(b.n);d.vSet=function(){var a=Array.prototype.slice.call(arguments,0),d,e,g,h,m,s,t=r(a[0]);"object"===typeof a[1]?(d=a[1].set,e=a[1].link,g=a[1].update,h=a[1].animate):!0===a[1]&&(d=!0);b.dir&&1<b.b&&t.reverse();h&&k(q,f[14]);a=1<l.length?3:1;1===t.length&&(a=1);for(m=0;m<a;m++)h=e||y[m%2][0],h=h.A(t[m%2]),!1!==h&&(h=A(b,h),b.dir&&(h=100-h),!0!==u(l[m%2],h,!0)&&c(y[m%2]).each(function(a){if(!a)return s=this.u,!0;this.write(s,
|
|
||||||
l[m%2].children(),q,g)}));!0===d&&n(["set"]);return this};d.vGet=function(){var a,c=[];for(a=0;a<b.b;a++)c[a]=y[a][0].F;return 1===c.length?c[0]:b.dir?c.reverse():c};d.destroy=function(){c.each(y,function(){c.each(this,function(){this.target&&this.target.off(".nui")})});c(this).off(".nui").removeClass(f.join(" ")).empty();return m};q.val(b.start)}function W(a){if(!this.length)throw Error("noUiSlider: Can't initialize slider on empty selection.");var b=O(a,this);return this.each(function(){V(this,
|
|
||||||
b,a)})}function X(a){return this.each(function(){var b=c(this).val(),d=this.destroy(),f=c.extend({},d,a);c(this).noUiSlider(f);d.start===f.start&&c(this).val(b)})}function B(){return this[0][arguments.length?"vSet":"vGet"].apply(this[0],arguments)}var G=c(document),C=c.fn.val,z=window.navigator.pointerEnabled?{start:"pointerdown",move:"pointermove",end:"pointerup"}:window.navigator.msPointerEnabled?{start:"MSPointerDown",move:"MSPointerMove",end:"MSPointerUp"}:{start:"mousedown touchstart",move:"mousemove touchmove",
|
|
||||||
end:"mouseup touchend"},f="noUi-target noUi-base noUi-origin noUi-handle noUi-horizontal noUi-vertical noUi-background noUi-connect noUi-ltr noUi-rtl noUi-dragable noUi-state-drag noUi-state-tap noUi-active noUi-extended noUi-stacking".split(" ");c.fn.val=function(){var a=arguments,b=c(this[0]);return arguments.length?this.each(function(){(c(this).hasClass(f[0])?B:C).apply(c(this),a)}):(b.hasClass(f[0])?B:C).call(b)};c.noUiSlider={Link:c.Link};c.fn.noUiSlider=function(a,b){return(b?X:W).call(this,
|
|
||||||
a)}})(window.jQuery||window.Zepto);
|
|
|
@ -1,352 +0,0 @@
|
||||||
/* globals jQuery */
|
|
||||||
|
|
||||||
(function ($) {
|
|
||||||
// Selector to select only not already processed elements
|
|
||||||
$.expr[":"].notmdproc = function (obj) {
|
|
||||||
if ($(obj).data("mdproc")) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function _isChar(evt) {
|
|
||||||
if (typeof evt.which == "undefined") {
|
|
||||||
return true;
|
|
||||||
} else if (typeof evt.which == "number" && evt.which > 0) {
|
|
||||||
return (
|
|
||||||
!evt.ctrlKey
|
|
||||||
&& !evt.metaKey
|
|
||||||
&& !evt.altKey
|
|
||||||
&& evt.which != 8 // backspace
|
|
||||||
&& evt.which != 9 // tab
|
|
||||||
&& evt.which != 13 // enter
|
|
||||||
&& evt.which != 16 // shift
|
|
||||||
&& evt.which != 17 // ctrl
|
|
||||||
&& evt.which != 20 // caps lock
|
|
||||||
&& evt.which != 27 // escape
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function _addFormGroupFocus(element) {
|
|
||||||
var $element = $(element);
|
|
||||||
if (!$element.prop('disabled')) { // this is showing as undefined on chrome but works fine on firefox??
|
|
||||||
$element.closest(".form-group").addClass("is-focused");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function _toggleDisabledState($element, state) {
|
|
||||||
var $target;
|
|
||||||
if ($element.hasClass('checkbox-inline') || $element.hasClass('radio-inline')) {
|
|
||||||
$target = $element;
|
|
||||||
} else {
|
|
||||||
$target = $element.closest('.checkbox').length ? $element.closest('.checkbox') : $element.closest('.radio');
|
|
||||||
}
|
|
||||||
return $target.toggleClass('disabled', state);
|
|
||||||
}
|
|
||||||
|
|
||||||
function _toggleTypeFocus($input) {
|
|
||||||
var disabledToggleType = false;
|
|
||||||
if ($input.is($.material.options.checkboxElements) || $input.is($.material.options.radioElements)) {
|
|
||||||
disabledToggleType = true;
|
|
||||||
}
|
|
||||||
$input.closest('label').hover(function () {
|
|
||||||
var $i = $(this).find('input');
|
|
||||||
var isDisabled = $i.prop('disabled'); // hack because the _addFormGroupFocus() wasn't identifying the property on chrome
|
|
||||||
if (disabledToggleType) {
|
|
||||||
_toggleDisabledState($(this), isDisabled);
|
|
||||||
}
|
|
||||||
if (!isDisabled) {
|
|
||||||
_addFormGroupFocus($i); // need to find the input so we can check disablement
|
|
||||||
}
|
|
||||||
},
|
|
||||||
function () {
|
|
||||||
_removeFormGroupFocus($(this).find('input'));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function _removeFormGroupFocus(element) {
|
|
||||||
$(element).closest(".form-group").removeClass("is-focused"); // remove class from form-group
|
|
||||||
}
|
|
||||||
|
|
||||||
$.material = {
|
|
||||||
"options": {
|
|
||||||
// These options set what will be started by $.material.init()
|
|
||||||
"validate": true,
|
|
||||||
"input": true,
|
|
||||||
"ripples": true,
|
|
||||||
"checkbox": true,
|
|
||||||
"togglebutton": true,
|
|
||||||
"radio": true,
|
|
||||||
"arrive": true,
|
|
||||||
"autofill": false,
|
|
||||||
|
|
||||||
"withRipples": [
|
|
||||||
".btn:not(.btn-link)",
|
|
||||||
".card-image",
|
|
||||||
".navbar a:not(.withoutripple)",
|
|
||||||
".dropdown-menu a",
|
|
||||||
".nav-tabs a:not(.withoutripple)",
|
|
||||||
".withripple",
|
|
||||||
".pagination li:not(.active):not(.disabled) a:not(.withoutripple)"
|
|
||||||
].join(","),
|
|
||||||
"inputElements": "input.form-control, textarea.form-control, select.form-control",
|
|
||||||
"checkboxElements": ".checkbox > label > input[type=checkbox], label.checkbox-inline > input[type=checkbox]",
|
|
||||||
"togglebuttonElements": ".togglebutton > label > input[type=checkbox]",
|
|
||||||
"radioElements": ".radio > label > input[type=radio], label.radio-inline > input[type=radio]"
|
|
||||||
},
|
|
||||||
"checkbox": function (selector) {
|
|
||||||
// Add fake-checkbox to material checkboxes
|
|
||||||
var $input = $((selector) ? selector : this.options.checkboxElements)
|
|
||||||
.filter(":notmdproc")
|
|
||||||
.data("mdproc", true)
|
|
||||||
.after("<span class='checkbox-material'><span class='check'></span></span>");
|
|
||||||
|
|
||||||
_toggleTypeFocus($input);
|
|
||||||
},
|
|
||||||
"togglebutton": function (selector) {
|
|
||||||
// Add fake-checkbox to material checkboxes
|
|
||||||
var $input = $((selector) ? selector : this.options.togglebuttonElements)
|
|
||||||
.filter(":notmdproc")
|
|
||||||
.data("mdproc", true)
|
|
||||||
.after("<span class='toggle'></span>");
|
|
||||||
|
|
||||||
_toggleTypeFocus($input);
|
|
||||||
},
|
|
||||||
"radio": function (selector) {
|
|
||||||
// Add fake-radio to material radios
|
|
||||||
var $input = $((selector) ? selector : this.options.radioElements)
|
|
||||||
.filter(":notmdproc")
|
|
||||||
.data("mdproc", true)
|
|
||||||
.after("<span class='circle'></span><span class='check'></span>");
|
|
||||||
|
|
||||||
_toggleTypeFocus($input);
|
|
||||||
},
|
|
||||||
"input": function (selector) {
|
|
||||||
$((selector) ? selector : this.options.inputElements)
|
|
||||||
.filter(":notmdproc")
|
|
||||||
.data("mdproc", true)
|
|
||||||
.each(function () {
|
|
||||||
var $input = $(this);
|
|
||||||
|
|
||||||
// Requires form-group standard markup (will add it if necessary)
|
|
||||||
var $formGroup = $input.closest(".form-group"); // note that form-group may be grandparent in the case of an input-group
|
|
||||||
if ($formGroup.length === 0 && $input.attr('type') !== "hidden" && !$input.attr('hidden')) {
|
|
||||||
$input.wrap("<div class='form-group'></div>");
|
|
||||||
$formGroup = $input.closest(".form-group"); // find node after attached (otherwise additional attachments don't work)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Legacy - Add hint label if using the old shorthand data-hint attribute on the input
|
|
||||||
if ($input.attr("data-hint")) {
|
|
||||||
$input.after("<p class='help-block'>" + $input.attr("data-hint") + "</p>");
|
|
||||||
$input.removeAttr("data-hint");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Legacy - Change input-sm/lg to form-group-sm/lg instead (preferred standard and simpler css/less variants)
|
|
||||||
var legacySizes = {
|
|
||||||
"input-lg": "form-group-lg",
|
|
||||||
"input-sm": "form-group-sm"
|
|
||||||
};
|
|
||||||
$.each(legacySizes, function (legacySize, standardSize) {
|
|
||||||
if ($input.hasClass(legacySize)) {
|
|
||||||
$input.removeClass(legacySize);
|
|
||||||
$formGroup.addClass(standardSize);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Legacy - Add label-floating if using old shorthand <input class="floating-label" placeholder="foo">
|
|
||||||
if ($input.hasClass("floating-label")) {
|
|
||||||
var placeholder = $input.attr("placeholder");
|
|
||||||
$input.attr("placeholder", null).removeClass("floating-label");
|
|
||||||
var id = $input.attr("id");
|
|
||||||
var forAttribute = "";
|
|
||||||
if (id) {
|
|
||||||
forAttribute = "for='" + id + "'";
|
|
||||||
}
|
|
||||||
$formGroup.addClass("label-floating");
|
|
||||||
$input.after("<label " + forAttribute + "class='control-label'>" + placeholder + "</label>");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set as empty if is empty (damn I must improve this...)
|
|
||||||
if ($input.val() === null || $input.val() == "undefined" || $input.val() === "") {
|
|
||||||
$formGroup.addClass("is-empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Support for file input
|
|
||||||
if ($formGroup.find("input[type=file]").length > 0) {
|
|
||||||
$formGroup.addClass("is-fileinput");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
"attachInputEventHandlers": function () {
|
|
||||||
var validate = this.options.validate;
|
|
||||||
|
|
||||||
$(document)
|
|
||||||
.on("keydown paste", ".form-control", function (e) {
|
|
||||||
if (_isChar(e)) {
|
|
||||||
$(this).closest(".form-group").removeClass("is-empty");
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.on("keyup change", ".form-control", function () {
|
|
||||||
var $input = $(this);
|
|
||||||
var $formGroup = $input.closest(".form-group");
|
|
||||||
var isValid = (typeof $input[0].checkValidity === "undefined" || $input[0].checkValidity());
|
|
||||||
|
|
||||||
if ($input.val() === "") {
|
|
||||||
$formGroup.addClass("is-empty");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$formGroup.removeClass("is-empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validation events do not bubble, so they must be attached directly to the input: http://jsfiddle.net/PEpRM/1/
|
|
||||||
// Further, even the bind method is being caught, but since we are already calling #checkValidity here, just alter
|
|
||||||
// the form-group on change.
|
|
||||||
//
|
|
||||||
// NOTE: I'm not sure we should be intervening regarding validation, this seems better as a README and snippet of code.
|
|
||||||
// BUT, I've left it here for backwards compatibility.
|
|
||||||
if (validate) {
|
|
||||||
if (isValid) {
|
|
||||||
$formGroup.removeClass("has-error");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$formGroup.addClass("has-error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.on("focus", ".form-control, .form-group.is-fileinput", function () {
|
|
||||||
_addFormGroupFocus(this);
|
|
||||||
})
|
|
||||||
.on("blur", ".form-control, .form-group.is-fileinput", function () {
|
|
||||||
_removeFormGroupFocus(this);
|
|
||||||
})
|
|
||||||
// make sure empty is added back when there is a programmatic value change.
|
|
||||||
// NOTE: programmatic changing of value using $.val() must trigger the change event i.e. $.val('x').trigger('change')
|
|
||||||
.on("change", ".form-group input", function () {
|
|
||||||
var $input = $(this);
|
|
||||||
if ($input.attr("type") == "file") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var $formGroup = $input.closest(".form-group");
|
|
||||||
var value = $input.val();
|
|
||||||
if (value) {
|
|
||||||
$formGroup.removeClass("is-empty");
|
|
||||||
} else {
|
|
||||||
$formGroup.addClass("is-empty");
|
|
||||||
}
|
|
||||||
})
|
|
||||||
// set the fileinput readonly field with the name of the file
|
|
||||||
.on("change", ".form-group.is-fileinput input[type='file']", function () {
|
|
||||||
var $input = $(this);
|
|
||||||
var $formGroup = $input.closest(".form-group");
|
|
||||||
var value = "";
|
|
||||||
$.each(this.files, function (i, file) {
|
|
||||||
value += file.name + ", ";
|
|
||||||
});
|
|
||||||
value = value.substring(0, value.length - 2);
|
|
||||||
if (value) {
|
|
||||||
$formGroup.removeClass("is-empty");
|
|
||||||
} else {
|
|
||||||
$formGroup.addClass("is-empty");
|
|
||||||
}
|
|
||||||
$formGroup.find("input.form-control[readonly]").val(value);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
"ripples": function (selector) {
|
|
||||||
$((selector) ? selector : this.options.withRipples).ripples();
|
|
||||||
},
|
|
||||||
"autofill": function () {
|
|
||||||
// This part of code will detect autofill when the page is loading (username and password inputs for example)
|
|
||||||
var loading = setInterval(function () {
|
|
||||||
$("input[type!=checkbox]").each(function () {
|
|
||||||
var $this = $(this);
|
|
||||||
if ($this.val() && $this.val() !== $this.attr("value")) {
|
|
||||||
$this.trigger("change");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 100);
|
|
||||||
|
|
||||||
// After 10 seconds we are quite sure all the needed inputs are autofilled then we can stop checking them
|
|
||||||
setTimeout(function () {
|
|
||||||
clearInterval(loading);
|
|
||||||
}, 10000);
|
|
||||||
},
|
|
||||||
"attachAutofillEventHandlers": function () {
|
|
||||||
// Listen on inputs of the focused form (because user can select from the autofill dropdown only when the input has focus)
|
|
||||||
var focused;
|
|
||||||
$(document)
|
|
||||||
.on("focus", "input", function () {
|
|
||||||
var $inputs = $(this).parents("form").find("input").not("[type=file]");
|
|
||||||
focused = setInterval(function () {
|
|
||||||
$inputs.each(function () {
|
|
||||||
var $this = $(this);
|
|
||||||
if ($this.val() !== $this.attr("value")) {
|
|
||||||
$this.trigger("change");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 100);
|
|
||||||
})
|
|
||||||
.on("blur", ".form-group input", function () {
|
|
||||||
clearInterval(focused);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
"init": function (options) {
|
|
||||||
this.options = $.extend({}, this.options, options);
|
|
||||||
var $document = $(document);
|
|
||||||
|
|
||||||
if ($.fn.ripples && this.options.ripples) {
|
|
||||||
this.ripples();
|
|
||||||
}
|
|
||||||
if (this.options.input) {
|
|
||||||
this.input();
|
|
||||||
this.attachInputEventHandlers();
|
|
||||||
}
|
|
||||||
if (this.options.checkbox) {
|
|
||||||
this.checkbox();
|
|
||||||
}
|
|
||||||
if (this.options.togglebutton) {
|
|
||||||
this.togglebutton();
|
|
||||||
}
|
|
||||||
if (this.options.radio) {
|
|
||||||
this.radio();
|
|
||||||
}
|
|
||||||
if (this.options.autofill) {
|
|
||||||
this.autofill();
|
|
||||||
this.attachAutofillEventHandlers();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (document.arrive && this.options.arrive) {
|
|
||||||
if ($.fn.ripples && this.options.ripples) {
|
|
||||||
$document.arrive(this.options.withRipples, function () {
|
|
||||||
$.material.ripples($(this));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (this.options.input) {
|
|
||||||
$document.arrive(this.options.inputElements, function () {
|
|
||||||
$.material.input($(this));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (this.options.checkbox) {
|
|
||||||
$document.arrive(this.options.checkboxElements, function () {
|
|
||||||
$.material.checkbox($(this));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (this.options.radio) {
|
|
||||||
$document.arrive(this.options.radioElements, function () {
|
|
||||||
$.material.radio($(this));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (this.options.togglebutton) {
|
|
||||||
$document.arrive(this.options.togglebuttonElements, function () {
|
|
||||||
$.material.togglebutton($(this));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
})(jQuery);
|
|
2
public/theme/material/js/material.min.js
vendored
2
public/theme/material/js/material.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,324 +0,0 @@
|
||||||
/* Copyright 2014+, Federico Zivolo, LICENSE at https://github.com/FezVrasta/bootstrap-material-design/blob/master/LICENSE.md */
|
|
||||||
/* globals jQuery, navigator */
|
|
||||||
|
|
||||||
(function($, window, document, undefined) {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define the name of the plugin
|
|
||||||
*/
|
|
||||||
var ripples = "ripples";
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an instance of the plugin
|
|
||||||
*/
|
|
||||||
var self = null;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define the defaults of the plugin
|
|
||||||
*/
|
|
||||||
var defaults = {};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the main plugin function
|
|
||||||
*/
|
|
||||||
function Ripples(element, options) {
|
|
||||||
self = this;
|
|
||||||
|
|
||||||
this.element = $(element);
|
|
||||||
|
|
||||||
this.options = $.extend({}, defaults, options);
|
|
||||||
|
|
||||||
this._defaults = defaults;
|
|
||||||
this._name = ripples;
|
|
||||||
|
|
||||||
this.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the plugin
|
|
||||||
*/
|
|
||||||
Ripples.prototype.init = function() {
|
|
||||||
var $element = this.element;
|
|
||||||
|
|
||||||
$element.on("mousedown touchstart", function(event) {
|
|
||||||
/**
|
|
||||||
* Verify if the user is just touching on a device and return if so
|
|
||||||
*/
|
|
||||||
if(self.isTouch() && event.type === "mousedown") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify if the current element already has a ripple wrapper element and
|
|
||||||
* creates if it doesn't
|
|
||||||
*/
|
|
||||||
if(!($element.find(".ripple-container").length)) {
|
|
||||||
$element.append("<div class=\"ripple-container\"></div>");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find the ripple wrapper
|
|
||||||
*/
|
|
||||||
var $wrapper = $element.children(".ripple-container");
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get relY and relX positions
|
|
||||||
*/
|
|
||||||
var relY = self.getRelY($wrapper, event);
|
|
||||||
var relX = self.getRelX($wrapper, event);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If relY and/or relX are false, return the event
|
|
||||||
*/
|
|
||||||
if(!relY && !relX) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the ripple color
|
|
||||||
*/
|
|
||||||
var rippleColor = self.getRipplesColor($element);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the ripple element
|
|
||||||
*/
|
|
||||||
var $ripple = $("<div></div>");
|
|
||||||
|
|
||||||
$ripple
|
|
||||||
.addClass("ripple")
|
|
||||||
.css({
|
|
||||||
"left": relX,
|
|
||||||
"top": relY,
|
|
||||||
"background-color": rippleColor
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Append the ripple to the wrapper
|
|
||||||
*/
|
|
||||||
$wrapper.append($ripple);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make sure the ripple has the styles applied (ugly hack but it works)
|
|
||||||
*/
|
|
||||||
(function() { return window.getComputedStyle($ripple[0]).opacity; })();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Turn on the ripple animation
|
|
||||||
*/
|
|
||||||
self.rippleOn($element, $ripple);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call the rippleEnd function when the transition "on" ends
|
|
||||||
*/
|
|
||||||
setTimeout(function() {
|
|
||||||
self.rippleEnd($ripple);
|
|
||||||
}, 500);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Detect when the user leaves the element
|
|
||||||
*/
|
|
||||||
$element.on("mouseup mouseleave touchend", function() {
|
|
||||||
$ripple.data("mousedown", "off");
|
|
||||||
|
|
||||||
if($ripple.data("animating") === "off") {
|
|
||||||
self.rippleOut($ripple);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the new size based on the element height/width and the ripple width
|
|
||||||
*/
|
|
||||||
Ripples.prototype.getNewSize = function($element, $ripple) {
|
|
||||||
|
|
||||||
return (Math.max($element.outerWidth(), $element.outerHeight()) / $ripple.outerWidth()) * 2.5;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the relX
|
|
||||||
*/
|
|
||||||
Ripples.prototype.getRelX = function($wrapper, event) {
|
|
||||||
var wrapperOffset = $wrapper.offset();
|
|
||||||
|
|
||||||
if(!self.isTouch()) {
|
|
||||||
/**
|
|
||||||
* Get the mouse position relative to the ripple wrapper
|
|
||||||
*/
|
|
||||||
return event.pageX - wrapperOffset.left;
|
|
||||||
} else {
|
|
||||||
/**
|
|
||||||
* Make sure the user is using only one finger and then get the touch
|
|
||||||
* position relative to the ripple wrapper
|
|
||||||
*/
|
|
||||||
event = event.originalEvent;
|
|
||||||
|
|
||||||
if(event.touches.length === 1) {
|
|
||||||
return event.touches[0].pageX - wrapperOffset.left;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the relY
|
|
||||||
*/
|
|
||||||
Ripples.prototype.getRelY = function($wrapper, event) {
|
|
||||||
var wrapperOffset = $wrapper.offset();
|
|
||||||
|
|
||||||
if(!self.isTouch()) {
|
|
||||||
/**
|
|
||||||
* Get the mouse position relative to the ripple wrapper
|
|
||||||
*/
|
|
||||||
return event.pageY - wrapperOffset.top;
|
|
||||||
} else {
|
|
||||||
/**
|
|
||||||
* Make sure the user is using only one finger and then get the touch
|
|
||||||
* position relative to the ripple wrapper
|
|
||||||
*/
|
|
||||||
event = event.originalEvent;
|
|
||||||
|
|
||||||
if(event.touches.length === 1) {
|
|
||||||
return event.touches[0].pageY - wrapperOffset.top;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the ripple color
|
|
||||||
*/
|
|
||||||
Ripples.prototype.getRipplesColor = function($element) {
|
|
||||||
|
|
||||||
var color = $element.data("ripple-color") ? $element.data("ripple-color") : window.getComputedStyle($element[0]).color;
|
|
||||||
|
|
||||||
return color;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify if the client browser has transistion support
|
|
||||||
*/
|
|
||||||
Ripples.prototype.hasTransitionSupport = function() {
|
|
||||||
var thisBody = document.body || document.documentElement;
|
|
||||||
var thisStyle = thisBody.style;
|
|
||||||
|
|
||||||
var support = (
|
|
||||||
thisStyle.transition !== undefined ||
|
|
||||||
thisStyle.WebkitTransition !== undefined ||
|
|
||||||
thisStyle.MozTransition !== undefined ||
|
|
||||||
thisStyle.MsTransition !== undefined ||
|
|
||||||
thisStyle.OTransition !== undefined
|
|
||||||
);
|
|
||||||
|
|
||||||
return support;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify if the client is using a mobile device
|
|
||||||
*/
|
|
||||||
Ripples.prototype.isTouch = function() {
|
|
||||||
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* End the animation of the ripple
|
|
||||||
*/
|
|
||||||
Ripples.prototype.rippleEnd = function($ripple) {
|
|
||||||
$ripple.data("animating", "off");
|
|
||||||
|
|
||||||
if($ripple.data("mousedown") === "off") {
|
|
||||||
self.rippleOut($ripple);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Turn off the ripple effect
|
|
||||||
*/
|
|
||||||
Ripples.prototype.rippleOut = function($ripple) {
|
|
||||||
$ripple.off();
|
|
||||||
|
|
||||||
if(self.hasTransitionSupport()) {
|
|
||||||
$ripple.addClass("ripple-out");
|
|
||||||
} else {
|
|
||||||
$ripple.animate({"opacity": 0}, 100, function() {
|
|
||||||
$ripple.trigger("transitionend");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
$ripple.on("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function() {
|
|
||||||
$ripple.remove();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Turn on the ripple effect
|
|
||||||
*/
|
|
||||||
Ripples.prototype.rippleOn = function($element, $ripple) {
|
|
||||||
var size = self.getNewSize($element, $ripple);
|
|
||||||
|
|
||||||
if(self.hasTransitionSupport()) {
|
|
||||||
$ripple
|
|
||||||
.css({
|
|
||||||
"-ms-transform": "scale(" + size + ")",
|
|
||||||
"-moz-transform": "scale(" + size + ")",
|
|
||||||
"-webkit-transform": "scale(" + size + ")",
|
|
||||||
"transform": "scale(" + size + ")"
|
|
||||||
})
|
|
||||||
.addClass("ripple-on")
|
|
||||||
.data("animating", "on")
|
|
||||||
.data("mousedown", "on");
|
|
||||||
} else {
|
|
||||||
$ripple.animate({
|
|
||||||
"width": Math.max($element.outerWidth(), $element.outerHeight()) * 2,
|
|
||||||
"height": Math.max($element.outerWidth(), $element.outerHeight()) * 2,
|
|
||||||
"margin-left": Math.max($element.outerWidth(), $element.outerHeight()) * (-1),
|
|
||||||
"margin-top": Math.max($element.outerWidth(), $element.outerHeight()) * (-1),
|
|
||||||
"opacity": 0.2
|
|
||||||
}, 500, function() {
|
|
||||||
$ripple.trigger("transitionend");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the jquery plugin function
|
|
||||||
*/
|
|
||||||
$.fn.ripples = function(options) {
|
|
||||||
return this.each(function() {
|
|
||||||
if(!$.data(this, "plugin_" + ripples)) {
|
|
||||||
$.data(this, "plugin_" + ripples, new Ripples(this, options));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
})(jQuery, window, document);
|
|
2
public/theme/material/js/ripples.min.js
vendored
2
public/theme/material/js/ripples.min.js
vendored
|
@ -1,2 +0,0 @@
|
||||||
!function(a,b,c,d){"use strict";function e(b,c){g=this,this.element=a(b),this.options=a.extend({},h,c),this._defaults=h,this._name=f,this.init()}var f="ripples",g=null,h={};e.prototype.init=function(){var c=this.element;c.on("mousedown touchstart",function(d){if(!g.isTouch()||"mousedown"!==d.type){c.find(".ripple-container").length||c.append('<div class="ripple-container"></div>');var e=c.children(".ripple-container"),f=g.getRelY(e,d),h=g.getRelX(e,d);if(f||h){var i=g.getRipplesColor(c),j=a("<div></div>");j.addClass("ripple").css({left:h,top:f,"background-color":i}),e.append(j),function(){return b.getComputedStyle(j[0]).opacity}(),g.rippleOn(c,j),setTimeout(function(){g.rippleEnd(j)},500),c.on("mouseup mouseleave touchend",function(){j.data("mousedown","off"),"off"===j.data("animating")&&g.rippleOut(j)})}}})},e.prototype.getNewSize=function(a,b){return Math.max(a.outerWidth(),a.outerHeight())/b.outerWidth()*2.5},e.prototype.getRelX=function(a,b){var c=a.offset();return g.isTouch()?(b=b.originalEvent,1===b.touches.length?b.touches[0].pageX-c.left:!1):b.pageX-c.left},e.prototype.getRelY=function(a,b){var c=a.offset();return g.isTouch()?(b=b.originalEvent,1===b.touches.length?b.touches[0].pageY-c.top:!1):b.pageY-c.top},e.prototype.getRipplesColor=function(a){var c=a.data("ripple-color")?a.data("ripple-color"):b.getComputedStyle(a[0]).color;return c},e.prototype.hasTransitionSupport=function(){var a=c.body||c.documentElement,b=a.style,e=b.transition!==d||b.WebkitTransition!==d||b.MozTransition!==d||b.MsTransition!==d||b.OTransition!==d;return e},e.prototype.isTouch=function(){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)},e.prototype.rippleEnd=function(a){a.data("animating","off"),"off"===a.data("mousedown")&&g.rippleOut(a)},e.prototype.rippleOut=function(a){a.off(),g.hasTransitionSupport()?a.addClass("ripple-out"):a.animate({opacity:0},100,function(){a.trigger("transitionend")}),a.on("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd",function(){a.remove()})},e.prototype.rippleOn=function(a,b){var c=g.getNewSize(a,b);g.hasTransitionSupport()?b.css({"-ms-transform":"scale("+c+")","-moz-transform":"scale("+c+")","-webkit-transform":"scale("+c+")",transform:"scale("+c+")"}).addClass("ripple-on").data("animating","on").data("mousedown","on"):b.animate({width:2*Math.max(a.outerWidth(),a.outerHeight()),height:2*Math.max(a.outerWidth(),a.outerHeight()),"margin-left":-1*Math.max(a.outerWidth(),a.outerHeight()),"margin-top":-1*Math.max(a.outerWidth(),a.outerHeight()),opacity:.2},500,function(){b.trigger("transitionend")})},a.fn.ripples=function(b){return this.each(function(){a.data(this,"plugin_"+f)||a.data(this,"plugin_"+f,new e(this,b))})}}(jQuery,window,document);
|
|
||||||
//# sourceMappingURL=ripples.min.js.map
|
|
|
@ -1 +0,0 @@
|
||||||
{"version":3,"sources":["ripples.js"],"names":["$","window","document","undefined","Ripples","element","options","self","this","extend","defaults","_defaults","_name","ripples","init","prototype","$element","on","event","isTouch","type","find","append","$wrapper","children","relY","getRelY","relX","getRelX","rippleColor","getRipplesColor","$ripple","addClass","css","left","top","background-color","getComputedStyle","opacity","rippleOn","setTimeout","rippleEnd","data","rippleOut","getNewSize","Math","max","outerWidth","outerHeight","wrapperOffset","offset","originalEvent","touches","length","pageX","pageY","color","hasTransitionSupport","thisBody","body","documentElement","thisStyle","style","support","transition","WebkitTransition","MozTransition","MsTransition","OTransition","test","navigator","userAgent","off","animate","trigger","remove","size","-ms-transform","-moz-transform","-webkit-transform","transform","width","height","margin-left","margin-top","fn","each","jQuery"],"mappings":"CAGA,SAAUA,EAAGC,EAAQC,EAAUC,GAE7B,YAuBA,SAASC,GAAQC,EAASC,GACxBC,EAAOC,KAEPA,KAAKH,QAAUL,EAAEK,GAEjBG,KAAKF,QAAUN,EAAES,UAAWC,EAAUJ,GAEtCE,KAAKG,UAAYD,EACjBF,KAAKI,MAAQC,EAEbL,KAAKM,OA5BP,GAAID,GAAU,UAMVN,EAAO,KAMPG,IAuBJN,GAAQW,UAAUD,KAAO,WACvB,GAAIE,GAAYR,KAAKH,OAErBW,GAASC,GAAG,uBAAwB,SAASC,GAI3C,IAAGX,EAAKY,WAA4B,cAAfD,EAAME,KAA3B,CASKJ,EAASK,KAAK,qBAA2B,QAC5CL,EAASM,OAAO,uCAOlB,IAAIC,GAAWP,EAASQ,SAAS,qBAM7BC,EAAOlB,EAAKmB,QAAQH,EAAUL,GAC9BS,EAAOpB,EAAKqB,QAAQL,EAAUL,EAMlC,IAAIO,GAASE,EAAb,CAQA,GAAIE,GAActB,EAAKuB,gBAAgBd,GAMnCe,EAAU/B,EAAE,cAEhB+B,GACCC,SAAS,UACTC,KACCC,KAAQP,EACRQ,IAAOV,EACPW,mBAAoBP,IAOtBN,EAASD,OAAOS,GAMhB,WAAc,MAAO9B,GAAOoC,iBAAiBN,EAAQ,IAAIO,WAMzD/B,EAAKgC,SAASvB,EAAUe,GAMxBS,WAAW,WACTjC,EAAKkC,UAAUV,IACd,KAMHf,EAASC,GAAG,8BAA+B,WACzCc,EAAQW,KAAK,YAAa,OAEO,QAA9BX,EAAQW,KAAK,cACdnC,EAAKoC,UAAUZ,UAWvB3B,EAAQW,UAAU6B,WAAa,SAAS5B,EAAUe,GAEhD,MAAQc,MAAKC,IAAI9B,EAAS+B,aAAc/B,EAASgC,eAAiBjB,EAAQgB,aAAgB,KAO5F3C,EAAQW,UAAUa,QAAU,SAASL,EAAWL,GAC9C,GAAI+B,GAAgB1B,EAAS2B,QAE7B,OAAI3C,GAAKY,WAUPD,EAAQA,EAAMiC,cAEc,IAAzBjC,EAAMkC,QAAQC,OACRnC,EAAMkC,QAAQ,GAAGE,MAAQL,EAAcf,MAGzC,GAZAhB,EAAMoC,MAAQL,EAAcf,MAoBvC9B,EAAQW,UAAUW,QAAU,SAASH,EAAUL,GAC7C,GAAI+B,GAAgB1B,EAAS2B,QAE7B,OAAI3C,GAAKY,WAUPD,EAAQA,EAAMiC,cAEc,IAAzBjC,EAAMkC,QAAQC,OACRnC,EAAMkC,QAAQ,GAAGG,MAAQN,EAAcd,KAGzC,GAZAjB,EAAMqC,MAAQN,EAAcd,KAoBvC/B,EAAQW,UAAUe,gBAAkB,SAASd,GAE3C,GAAIwC,GAAQxC,EAAS0B,KAAK,gBAAkB1B,EAAS0B,KAAK,gBAAkBzC,EAAOoC,iBAAiBrB,EAAS,IAAIwC,KAEjH,OAAOA,IAOTpD,EAAQW,UAAU0C,qBAAuB,WACvC,GAAIC,GAAYxD,EAASyD,MAAQzD,EAAS0D,gBACtCC,EAAYH,EAASI,MAErBC,EACFF,EAAUG,aAAe7D,GACzB0D,EAAUI,mBAAqB9D,GAC/B0D,EAAUK,gBAAkB/D,GAC5B0D,EAAUM,eAAiBhE,GAC3B0D,EAAUO,cAAgBjE,CAG5B,OAAO4D,IAOT3D,EAAQW,UAAUI,QAAU,WAC1B,MAAO,iEAAiEkD,KAAKC,UAAUC,YAOzFnE,EAAQW,UAAU0B,UAAY,SAASV,GACrCA,EAAQW,KAAK,YAAa,OAEO,QAA9BX,EAAQW,KAAK,cACdnC,EAAKoC,UAAUZ,IAQnB3B,EAAQW,UAAU4B,UAAY,SAASZ,GACrCA,EAAQyC,MAELjE,EAAKkD,uBACN1B,EAAQC,SAAS,cAEjBD,EAAQ0C,SAASnC,QAAW,GAAI,IAAK,WACnCP,EAAQ2C,QAAQ,mBAIpB3C,EAAQd,GAAG,mEAAoE,WAC7Ec,EAAQ4C,YAQZvE,EAAQW,UAAUwB,SAAW,SAASvB,EAAUe,GAC9C,GAAI6C,GAAOrE,EAAKqC,WAAW5B,EAAUe,EAElCxB,GAAKkD,uBACN1B,EACCE,KACC4C,gBAAiB,SAAWD,EAAO,IACnCE,iBAAkB,SAAWF,EAAO,IACpCG,oBAAqB,SAAWH,EAAO,IACvCI,UAAa,SAAWJ,EAAO,MAEhC5C,SAAS,aACTU,KAAK,YAAa,MAClBA,KAAK,YAAa,MAEnBX,EAAQ0C,SACNQ,MAAmE,EAA1DpC,KAAKC,IAAI9B,EAAS+B,aAAc/B,EAASgC,eAClDkC,OAAoE,EAA1DrC,KAAKC,IAAI9B,EAAS+B,aAAc/B,EAASgC,eACnDmC,cAAyE,GAA1DtC,KAAKC,IAAI9B,EAAS+B,aAAc/B,EAASgC,eACxDoC,aAAwE,GAA1DvC,KAAKC,IAAI9B,EAAS+B,aAAc/B,EAASgC,eACvDV,QAAW,IACV,IAAK,WACNP,EAAQ2C,QAAQ,oBAStB1E,EAAEqF,GAAGxE,QAAU,SAASP,GACtB,MAAOE,MAAK8E,KAAK,WACXtF,EAAE0C,KAAKlC,KAAM,UAAYK,IAC3Bb,EAAE0C,KAAKlC,KAAM,UAAYK,EAAS,GAAIT,GAAQI,KAAMF,QAKzDiF,OAAQtF,OAAQC","file":"ripples.min.js"}
|
|
|
@ -15,6 +15,7 @@ final class ServerSelectAction extends AbstractAction
|
||||||
|
|
||||||
$this->session->set('sid', $sid);
|
$this->session->set('sid', $sid);
|
||||||
$this->session->set('sname', $this->ts->getInstance()->getElement('data', $dataResult)['virtualserver_name']);
|
$this->session->set('sname', $this->ts->getInstance()->getElement('data', $dataResult)['virtualserver_name']);
|
||||||
|
$this->session->set('sport', $this->ts->getInstance()->getElement('data', $dataResult)['virtualserver_port']);
|
||||||
|
|
||||||
$this->flash->addMessage('success', $this->translator->trans('done'));
|
$this->flash->addMessage('success', $this->translator->trans('done'));
|
||||||
return $response->withRedirect('/servers');
|
return $response->withRedirect('/servers');
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Dotenv\Dotenv;
|
use Dotenv\Dotenv;
|
||||||
|
use Monolog\Handler\ErrorLogHandler;
|
||||||
|
use Monolog\Handler\StreamHandler;
|
||||||
use Monolog\Logger;
|
use Monolog\Logger;
|
||||||
|
use Monolog\Processor\UidProcessor;
|
||||||
use Symfony\Component\Translation\Loader\YamlFileLoader;
|
use Symfony\Component\Translation\Loader\YamlFileLoader;
|
||||||
use Symfony\Component\Translation\MessageSelector;
|
use Symfony\Component\Translation\MessageSelector;
|
||||||
use Symfony\Component\Translation\Translator;
|
use Symfony\Component\Translation\Translator;
|
||||||
|
@ -17,34 +20,20 @@ class BootstrapHelper
|
||||||
public static function bootEnvironment()
|
public static function bootEnvironment()
|
||||||
{
|
{
|
||||||
$envPath = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'config';
|
$envPath = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'config';
|
||||||
$envFile = 'env';
|
|
||||||
|
|
||||||
$exists = is_file($envPath . DIRECTORY_SEPARATOR . $envFile);
|
$defaultEnv = new Dotenv($envPath, EnvConstants::ENV_FILE_DEFAULT);
|
||||||
if (!$exists) {
|
$defaultEnvRes = $defaultEnv->load();
|
||||||
die('Configure your environment in ' . $envPath . '.');
|
|
||||||
} else {
|
|
||||||
$env = new Dotenv($envPath, $envFile);
|
|
||||||
$res = $env->load();
|
|
||||||
|
|
||||||
try {
|
$envFile = $envPath . DIRECTORY_SEPARATOR . EnvConstants::ENV_FILE_CUSTOM;
|
||||||
$env->required([
|
$envRes = [];
|
||||||
'site_title',
|
if (file_exists($envFile)) {
|
||||||
'site_language',
|
$env = new Dotenv($envPath, EnvConstants::ENV_FILE_CUSTOM);
|
||||||
'site_date_format',
|
$envRes = $env->load();
|
||||||
'theme',
|
|
||||||
'theme_cache',
|
|
||||||
'teamspeak_default_host',
|
|
||||||
'teamspeak_default_query_port',
|
|
||||||
'teamspeak_default_user',
|
|
||||||
'log_name',
|
|
||||||
'log_level'
|
|
||||||
]);
|
|
||||||
} catch (\Dotenv\Exception\ValidationException $e) {
|
|
||||||
die($e->getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
return $res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$res = array_merge_recursive($defaultEnvRes, $envRes);
|
||||||
|
|
||||||
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,7 +43,7 @@ class BootstrapHelper
|
||||||
*/
|
*/
|
||||||
public static function bootTranslator()
|
public static function bootTranslator()
|
||||||
{
|
{
|
||||||
$translator = new Translator(getenv('site_language'), new MessageSelector());
|
$translator = new Translator(getenv(EnvConstants::SITE_LANGUAGE), new MessageSelector());
|
||||||
$translator->addLoader('yaml', new YamlFileLoader());
|
$translator->addLoader('yaml', new YamlFileLoader());
|
||||||
|
|
||||||
$localeDir = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'locale';
|
$localeDir = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'locale';
|
||||||
|
@ -64,7 +53,7 @@ class BootstrapHelper
|
||||||
$translator->addResource('yaml', $locale, basename($locale, '.yml'));
|
$translator->addResource('yaml', $locale, basename($locale, '.yml'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$translator->setFallbackLocales([getenv('site_language'), 'en']);
|
$translator->setFallbackLocales([getenv(EnvConstants::SITE_LANGUAGE), 'en']);
|
||||||
|
|
||||||
return $translator;
|
return $translator;
|
||||||
}
|
}
|
||||||
|
@ -72,13 +61,13 @@ class BootstrapHelper
|
||||||
/**
|
/**
|
||||||
* Bootstrap logger
|
* Bootstrap logger
|
||||||
*
|
*
|
||||||
* @return \Monolog\Logger
|
* @return Logger
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static function bootLogger()
|
public static function bootLogger()
|
||||||
{
|
{
|
||||||
$logName = getenv('log_name');
|
$logName = getenv(EnvConstants::LOG_NAME);
|
||||||
$logLevel = getenv('log_level');
|
$logLevel = getenv(EnvConstants::LOG_LEVEL);
|
||||||
|
|
||||||
switch ($logLevel) {
|
switch ($logLevel) {
|
||||||
case 'DEBUG':
|
case 'DEBUG':
|
||||||
|
@ -110,11 +99,11 @@ class BootstrapHelper
|
||||||
}
|
}
|
||||||
|
|
||||||
$logger = new Monolog\Logger($logName);
|
$logger = new Monolog\Logger($logName);
|
||||||
$logger->pushProcessor(new \Monolog\Processor\UidProcessor());
|
$logger->pushProcessor(new UidProcessor());
|
||||||
$logger->pushHandler(new \Monolog\Handler\ErrorLogHandler(NULL, $logLevelTranslated));
|
$logger->pushHandler(new ErrorLogHandler(NULL, $logLevelTranslated));
|
||||||
|
|
||||||
$logPath = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'log' . DIRECTORY_SEPARATOR . 'application.log';
|
$logPath = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'log' . DIRECTORY_SEPARATOR . 'application.log';
|
||||||
$logger->pushHandler(new \Monolog\Handler\StreamHandler($logPath, $logLevelTranslated));
|
$logger->pushHandler(new StreamHandler($logPath, $logLevelTranslated));
|
||||||
|
|
||||||
return $logger;
|
return $logger;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
class TS3AdminProxy
|
class TS3AdminProxy
|
||||||
{
|
{
|
||||||
private $object;
|
private $object;
|
||||||
|
@ -8,7 +10,7 @@ class TS3AdminProxy
|
||||||
/**
|
/**
|
||||||
* TS3AdminProxy constructor.
|
* TS3AdminProxy constructor.
|
||||||
* @param ts3admin $object
|
* @param ts3admin $object
|
||||||
* @param $logger \Psr\Log\LoggerInterface
|
* @param $logger LoggerInterface
|
||||||
*/
|
*/
|
||||||
public function __construct(ts3admin $object, $logger) {
|
public function __construct(ts3admin $object, $logger) {
|
||||||
$this->object = $object;
|
$this->object = $object;
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
class TSInstance
|
class TSInstance
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -18,7 +20,7 @@ class TSInstance
|
||||||
private $queryPort;
|
private $queryPort;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Psr\Log\LoggerInterface
|
* @var LoggerInterface
|
||||||
*/
|
*/
|
||||||
private $logger;
|
private $logger;
|
||||||
|
|
||||||
|
@ -30,8 +32,8 @@ class TSInstance
|
||||||
{
|
{
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
|
|
||||||
$this->host = getenv('teamspeak_default_host');
|
$this->host = getenv(EnvConstants::TEAMSPEAK_HOST);
|
||||||
$this->queryPort = getenv('teamspeak_default_query_port');
|
$this->queryPort = getenv(EnvConstants::TEAMSPEAK_QUERY_PORT);
|
||||||
|
|
||||||
$ts = new ts3admin($this->host, $this->queryPort);
|
$ts = new ts3admin($this->host, $this->queryPort);
|
||||||
$ts = new TS3AdminProxy($ts, $logger);
|
$ts = new TS3AdminProxy($ts, $logger);
|
||||||
|
|
|
@ -163,7 +163,6 @@ class Validator extends GUMP
|
||||||
case 'validate_set_min_len':
|
case 'validate_set_min_len':
|
||||||
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $this->translator->trans('form_field_' . strtolower(str_replace([' '], '', $field))), '%param%' => $param]);
|
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $this->translator->trans('form_field_' . strtolower(str_replace([' '], '', $field))), '%param%' => $param]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => $param]);
|
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => $param]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{% extends 'layout.twig' %}
|
{% extends 'layout.twig' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1 class="header">{{ title }}</h1>
|
<h3>{{ title }}</h3>
|
||||||
{% if data|length > 0 %}
|
{% if data|length > 0 %}
|
||||||
{% include 'table.twig' with {'data': data,
|
{% include 'table.twig' with {'data': data,
|
||||||
'filters': [
|
'filters': [
|
||||||
|
@ -11,7 +11,7 @@
|
||||||
'additional_links': [
|
'additional_links': [
|
||||||
{
|
{
|
||||||
'header_label': 'bans.delete'|trans,
|
'header_label': 'bans.delete'|trans,
|
||||||
'label': '<i class="material-icons">delete</i>',
|
'label': '<i class="fa fa-trash"></i>',
|
||||||
'uri': '/bans/delete/' ~ sid,
|
'uri': '/bans/delete/' ~ sid,
|
||||||
'uri_param': 'banid'
|
'uri_param': 'banid'
|
||||||
}
|
}
|
|
@ -1,14 +1,14 @@
|
||||||
{% extends 'layout.twig' %}
|
{% extends 'layout.twig' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1 class="header">{{ title }}</h1>
|
<h3>{{ title }}</h3>
|
||||||
|
|
||||||
<h2 class="header">{% trans %}channel_info.h.actions{% endtrans %}</h2>
|
<h5>{% trans %}channel_info.h.actions{% endtrans %}</h5>
|
||||||
{% include 'form.twig' with {
|
{% include 'form.twig' with {
|
||||||
'fields': [
|
'fields': [
|
||||||
{
|
{
|
||||||
'header_label': 'channel_info.send'|trans,
|
'header_label': 'channel_info.send'|trans,
|
||||||
'label': '<i class="material-icons">check_circle</i>',
|
'label': '<i class="fa fa-check"></i>',
|
||||||
'uri': '/channels/send/' ~ sid ~ '/' ~ cid,
|
'uri': '/channels/send/' ~ sid ~ '/' ~ cid,
|
||||||
'uri_method': 'post',
|
'uri_method': 'post',
|
||||||
'fields': [
|
'fields': [
|
||||||
|
@ -18,42 +18,58 @@
|
||||||
} %}
|
} %}
|
||||||
|
|
||||||
{% if clients|length > 0 %}
|
{% if clients|length > 0 %}
|
||||||
<h2 class="header">{% trans %}channel_info.h.clients{% endtrans %}</h2>
|
<h5>{% trans %}channel_info.h.clients{% endtrans %}</h5>
|
||||||
{% include 'table.twig' with {'data': clients,
|
{% include 'table.twig' with {'data': clients,
|
||||||
'hiddenDependingOnAttribute': [{'key': 'client_type', 'values': ['1']}],
|
'hiddenDependingOnAttribute': [{'key': 'client_type', 'values': ['1']}],
|
||||||
|
'hiddenColumns': ['clid', 'cid', 'client_type', 'client_database_id'],
|
||||||
'links': [
|
'links': [
|
||||||
{'key': 'clid', 'uri': '/online/' ~ sid},
|
{'key': 'client_nickname', 'uri': '/online/' ~ sid, 'uri_param': 'clid'},
|
||||||
{'key': 'client_database_id', 'uri': '/clients/' ~ sid, 'uri_param': 'client_database_id'}
|
],
|
||||||
]} %}
|
'additional_links': [
|
||||||
|
{
|
||||||
|
'header_label': 'channel_info.client'|trans,
|
||||||
|
'label': '<i class="fa fa-user-plus"></i>',
|
||||||
|
'uri': '/clients/' ~ sid,
|
||||||
|
'uri_param': 'client_database_id'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
} %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if files|length > 0 %}
|
{% if files|length > 0 %}
|
||||||
<h2 class="header">{% trans %}channel_info.h.files{% endtrans %}</h2>
|
<h5>{% trans %}channel_info.h.files{% endtrans %}</h5>
|
||||||
{% include 'files.twig' with {'data': files} %}
|
{% include 'table.twig' with {'data': files,
|
||||||
|
'filters': [
|
||||||
|
{'key': 'datetime', 'apply': 'timestamp'},
|
||||||
|
{'key': 'size', 'apply': 'file'},
|
||||||
|
],
|
||||||
|
'hiddenColumns': ['cid', 'type']
|
||||||
|
} %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<h2 class="header">{% trans %}channel_info.h.details{% endtrans %}</h2>
|
<h5>{% trans %}channel_info.h.details{% endtrans %}</h5>
|
||||||
{% include 'keyvalue.twig' with {'data': channel,
|
{% include 'keyvalue.twig' with {'data': channel,
|
||||||
'attributesEditable': [
|
'attributesEditable': [
|
||||||
{'key': 'channel_name', 'type': 'text', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="material-icons">check_circle</i>'},
|
{'key': 'channel_name', 'type': 'text', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="fa fa-check"></i>'},
|
||||||
{'key': 'channel_topic', 'type': 'text', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="material-icons">check_circle</i>'},
|
{'key': 'channel_topic', 'type': 'text', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="fa fa-check"></i>'},
|
||||||
{'key': 'channel_description', 'type': 'text', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="material-icons">check_circle</i>'},
|
{'key': 'channel_description', 'type': 'text', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="fa fa-check"></i>'},
|
||||||
{'key': 'channel_password', 'type': 'text', 'blank': true,'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="material-icons">check_circle</i>'},
|
{'key': 'channel_password', 'type': 'text', 'blank': true,'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="fa fa-check"></i>'},
|
||||||
{'key': 'channel_maxclients', 'type': 'number', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="material-icons">check_circle</i>'},
|
{'key': 'channel_maxclients', 'type': 'number', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="fa fa-check"></i>'},
|
||||||
{'key': 'channel_flag_maxclients_unlimited', 'type': 'checkbox', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="material-icons">check_circle</i>'},
|
{'key': 'channel_flag_maxclients_unlimited', 'type': 'checkbox', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="fa fa-check"></i>'},
|
||||||
{'key': 'channel_maxfamilyclients', 'type': 'number', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="material-icons">check_circle</i>'},
|
{'key': 'channel_maxfamilyclients', 'type': 'number', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="fa fa-check"></i>'},
|
||||||
{'key': 'channel_flag_maxfamilyclients_unlimited', 'type': 'checkbox', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="material-icons">check_circle</i>'},
|
{'key': 'channel_flag_maxfamilyclients_unlimited', 'type': 'checkbox', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="fa fa-check"></i>'},
|
||||||
{'key': 'channel_flag_maxfamilyclients_inherited', 'type': 'checkbox', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="material-icons">check_circle</i>'},
|
{'key': 'channel_flag_maxfamilyclients_inherited', 'type': 'checkbox', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="fa fa-check"></i>'},
|
||||||
{'key': 'channel_flag_permanent', 'type': 'checkbox', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="material-icons">check_circle</i>'},
|
{'key': 'channel_flag_permanent', 'type': 'checkbox', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="fa fa-check"></i>'},
|
||||||
{'key': 'channel_flag_semi_permanent', 'type': 'checkbox', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="material-icons">check_circle</i>'},
|
{'key': 'channel_flag_semi_permanent', 'type': 'checkbox', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="fa fa-check"></i>'},
|
||||||
{'key': 'channel_flag_default', 'type': 'checkbox', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="material-icons">check_circle</i>'},
|
{'key': 'channel_flag_default', 'type': 'checkbox', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="fa fa-check"></i>'},
|
||||||
{'key': 'channel_order', 'type': 'number', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="material-icons">check_circle</i>'},
|
{'key': 'channel_order', 'type': 'number', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="fa fa-check"></i>'},
|
||||||
{'key': 'channel_needed_talk_power', 'type': 'number', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="material-icons">check_circle</i>'},
|
{'key': 'channel_needed_talk_power', 'type': 'number', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="fa fa-check"></i>'},
|
||||||
{'key': 'channel_name_phonetic', 'type': 'text', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="material-icons">check_circle</i>'},
|
{'key': 'channel_name_phonetic', 'type': 'text', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="fa fa-check"></i>'},
|
||||||
{'key': 'channel_codec', 'type': 'select', 'options': codecs, 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="material-icons">check_circle</i>'},
|
{'key': 'channel_codec', 'type': 'select', 'options': codecs, 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="fa fa-check"></i>'},
|
||||||
{'key': 'channel_codec_quality', 'type': 'select', 'options': codecsquality, 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="material-icons">check_circle</i>'},
|
{'key': 'channel_codec_quality', 'type': 'select', 'options': codecsquality, 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="fa fa-check"></i>'},
|
||||||
{'key': 'channel_codec_is_unencrypted', 'type': 'checkbox', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="material-icons">check_circle</i>'},
|
{'key': 'channel_codec_is_unencrypted', 'type': 'checkbox', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="fa fa-check"></i>'},
|
||||||
{'key': 'channel_icon_id', 'type': 'number', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="material-icons">check_circle</i>'},
|
{'key': 'channel_icon_id', 'type': 'number', 'uri': '/channels/edit/' ~ sid ~ '/' ~ cid , 'uri_method': 'post', 'submit_label': '<i class="fa fa-check"></i>'},
|
||||||
]
|
]
|
||||||
} %}
|
} %}
|
||||||
{% endblock %}
|
{% endblock %}
|
36
src/View/bootstrap4/channelgroup_info.twig
Normal file
36
src/View/bootstrap4/channelgroup_info.twig
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{% extends 'layout.twig' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h3>{{ title }}</h3>
|
||||||
|
|
||||||
|
{% if clients|length > 0 %}
|
||||||
|
<h5>{% trans %}channelgroup_info.h.clients{% endtrans %}</h5>
|
||||||
|
{% include 'table.twig' with {'data': clients,
|
||||||
|
'links': [
|
||||||
|
{'key': 'cldbid', 'uri': '/clients/' ~ sid, 'uri_param': 'cldbid'},
|
||||||
|
{'key': 'cid', 'uri': '/channels/' ~ sid, 'uri_param': 'cid'}
|
||||||
|
],
|
||||||
|
'hiddenColumns': ['cgid', 'cid', 'cldbid'],
|
||||||
|
'additional_links': [
|
||||||
|
{
|
||||||
|
'header_label': 'channelgroup_info.client'|trans,
|
||||||
|
'label': '<i class="fa fa-user-plus"></i>',
|
||||||
|
'uri': '/clients/' ~ sid,
|
||||||
|
'uri_param': 'cldbid'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'header_label': 'channelgroup_info.channel'|trans,
|
||||||
|
'label': '<i class="fa fa-tv"></i>',
|
||||||
|
'uri': '/channels/' ~ sid,
|
||||||
|
'uri_param': 'cid'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
} %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if permissions|length > 0 %}
|
||||||
|
<h5>{% trans %}channelgroup_info.h.permissions{% endtrans %}</h5>
|
||||||
|
{% include 'table.twig' with {'data': permissions} %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endblock %}
|
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue