mirror of
https://github.com/HaschekSolutions/pictshare.git
synced 2025-11-12 19:26:21 +00:00
Compare commits
210 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc1eca4014 | ||
|
|
fc9a7d3072 | ||
|
|
67fba8e66b | ||
|
|
7f18a193d4 | ||
|
|
090f452585 | ||
|
|
819c25374c | ||
|
|
2388f68d5d | ||
|
|
3fe84a63a4 | ||
|
|
774c8e0112 | ||
|
|
63132e1cfb | ||
|
|
d349ee8fc6 | ||
|
|
5c3ee9e159 | ||
|
|
cea501d854 | ||
|
|
a1bc5b5fa5 | ||
|
|
d3d5d1c385 | ||
|
|
f000404d5a | ||
|
|
c777cd62ab | ||
|
|
06a524ca2f | ||
|
|
2712946287 | ||
|
|
fffcb13ac9 | ||
|
|
307243a5bf | ||
|
|
61acb5420b | ||
|
|
cccb80de03 | ||
|
|
d0deb6f6c9 | ||
|
|
e551ef2bb2 | ||
|
|
21aa1fbb7d | ||
|
|
4c1124da07 | ||
|
|
19d7cb060e | ||
|
|
c90a716d45 | ||
|
|
4fbf8b31a2 | ||
|
|
422c17eb65 | ||
|
|
70cdcf5dcf | ||
|
|
7b4b27098d | ||
|
|
2362af1e8c | ||
|
|
28f5677247 | ||
|
|
8c2702be96 | ||
|
|
452db23c57 | ||
|
|
c6baa6edfa | ||
|
|
74ccf9f626 | ||
|
|
56f89d5610 | ||
|
|
0ea4b3c160 | ||
|
|
93d78d44fe | ||
|
|
7dac978d16 | ||
|
|
312f18ade2 | ||
|
|
cb2d17411c | ||
|
|
9a4a20fb41 | ||
|
|
72394f17ba | ||
|
|
240c7359a8 | ||
|
|
9d8d5f3d36 | ||
|
|
25b39bbd86 | ||
|
|
4964967524 | ||
|
|
bfb43ab856 | ||
|
|
03464199ee | ||
|
|
96e73e2baf | ||
|
|
6ad94f2063 | ||
|
|
45b2e11729 | ||
|
|
c7f8f37c62 | ||
|
|
6f540ad27e | ||
|
|
ef1a1ecaff | ||
|
|
be5f601866 | ||
|
|
45d933ebf0 | ||
|
|
a145ca88cc | ||
|
|
cf0effd0e8 | ||
|
|
8ee26e6922 | ||
|
|
9d1a4db4d2 | ||
|
|
adb1c468cd | ||
|
|
d6f3b7b5df | ||
|
|
33b08f378d | ||
|
|
31d2712733 | ||
|
|
9200d3d93c | ||
|
|
b669e69511 | ||
|
|
f0cfdeb650 | ||
|
|
99d9542b80 | ||
|
|
b65186f77f | ||
|
|
3ee37fe3a2 | ||
|
|
5ecf80bce1 | ||
|
|
5a5c4a0334 | ||
|
|
7c7358af9c | ||
|
|
ebc4ebda03 | ||
|
|
a4dc4366ba | ||
|
|
ea40ffbc46 | ||
|
|
9a7fadb231 | ||
|
|
199f162fdf | ||
|
|
70c06cfa5c | ||
|
|
520099be96 | ||
|
|
5cf9b86868 | ||
|
|
03d4875e92 | ||
|
|
726c77effb | ||
|
|
68de83b46a | ||
|
|
77d4023f00 | ||
|
|
0119368376 | ||
|
|
166ff1da1b | ||
|
|
7727fc9ea4 | ||
|
|
8de53d1ea7 | ||
|
|
0250b6a577 | ||
|
|
e13f4816fb | ||
|
|
75784174fa | ||
|
|
6d504f3a48 | ||
|
|
3a6c987347 | ||
|
|
5861e73848 | ||
|
|
a2b7feb6f9 | ||
|
|
dce00906ec | ||
|
|
ceffa04b6e | ||
|
|
984246912c | ||
|
|
3a8ac33dd1 | ||
|
|
7e28024d32 | ||
|
|
b149fe88cb | ||
|
|
3a27592d58 | ||
|
|
80e210af86 | ||
|
|
220a3103fa | ||
|
|
6ec765024e | ||
|
|
6c556e921f | ||
|
|
3a90787091 | ||
|
|
c4087c1e84 | ||
|
|
76c0f6cec1 | ||
|
|
f01b685820 | ||
|
|
e022227617 | ||
|
|
2fc56d438d | ||
|
|
fb50f23e19 | ||
|
|
40c53173ca | ||
|
|
30c78ab7da | ||
|
|
5e59d7e80d | ||
|
|
dd0d274ab1 | ||
|
|
3c7e8bea7c | ||
|
|
1a46209bfe | ||
|
|
ad04aeb5b6 | ||
|
|
bbb0b5b111 | ||
|
|
a19d0a3d48 | ||
|
|
63fe1b3edd | ||
|
|
b9e42d0f31 | ||
|
|
021fbad811 | ||
|
|
6cab15f8e7 | ||
|
|
f863045fcf | ||
|
|
87fa55eae8 | ||
|
|
6806e4a15a | ||
|
|
82f97479ff | ||
|
|
75124102cb | ||
|
|
515e034d91 | ||
|
|
2a628e7d7a | ||
|
|
8e3cf866a6 | ||
|
|
6adb557693 | ||
|
|
c178f3af44 | ||
|
|
8da3573ffb | ||
|
|
5f5b836a22 | ||
|
|
17974088bc | ||
|
|
4d5d57df8a | ||
|
|
71df6a54c4 | ||
|
|
4a5e29e7c1 | ||
|
|
9d2bf6a931 | ||
|
|
66eebd1445 | ||
|
|
38f6b1c22f | ||
|
|
263f0b762b | ||
|
|
9f9449a58d | ||
|
|
1cb8e28be7 | ||
|
|
37e0ae26f8 | ||
|
|
d41e06efa0 | ||
|
|
772860e186 | ||
|
|
5cc690bbee | ||
|
|
b2a7c778d8 | ||
|
|
771ec3305e | ||
|
|
f4cea4ce08 | ||
|
|
66570c54d8 | ||
|
|
ee0000bf59 | ||
|
|
5d6b57cabc | ||
|
|
b3e777baa3 | ||
|
|
fb25657d2f | ||
|
|
a58de1f02e | ||
|
|
3e6cfdfed6 | ||
|
|
7170825166 | ||
|
|
2e6a3313a6 | ||
|
|
b0eafc9474 | ||
|
|
d3efbb0d99 | ||
|
|
c5715182c0 | ||
|
|
f7adc73a86 | ||
|
|
d25d562598 | ||
|
|
28937f4270 | ||
|
|
b50e522c0d | ||
|
|
5fb9d21016 | ||
|
|
66fc8aff14 | ||
|
|
b6609b1df2 | ||
|
|
c649233835 | ||
|
|
35ba2c991a | ||
|
|
0210507c22 | ||
|
|
b66a1f2a55 | ||
|
|
bf13df48aa | ||
|
|
4183b1a2db | ||
|
|
e922f9c907 | ||
|
|
801b4acd9d | ||
|
|
aa75c56364 | ||
|
|
b6612cd838 | ||
|
|
3345eb399c | ||
|
|
63a28b8b4b | ||
|
|
3e63da324c | ||
|
|
47545e5702 | ||
|
|
0fe80b29b8 | ||
|
|
0b981d52a6 | ||
|
|
16688fae3c | ||
|
|
00580d8bcc | ||
|
|
56654e1ff4 | ||
|
|
24411dfe93 | ||
|
|
479798a1d2 | ||
|
|
75cde97ae9 | ||
|
|
8f1a4f3af9 | ||
|
|
7adf83cb3a | ||
|
|
d292bbf6bd | ||
|
|
15af093b27 | ||
|
|
e9c6795d7d | ||
|
|
977d3f6bda | ||
|
|
e57360bcfc | ||
|
|
8586775116 |
7
.dockerignore
Normal file
7
.dockerignore
Normal file
@@ -0,0 +1,7 @@
|
||||
tmp/*
|
||||
inc/config.inc.php
|
||||
data/*
|
||||
lib/vendor
|
||||
bin
|
||||
.git
|
||||
.github
|
||||
59
.github/workflows/build-docker.yml
vendored
Normal file
59
.github/workflows/build-docker.yml
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*.*.*"
|
||||
pull_request:
|
||||
branches:
|
||||
- "master"
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
# list of Docker images to use as base name for tags
|
||||
images: |
|
||||
hascheksolutions/pictshare
|
||||
ghcr.io/hascheksolutions/pictshare
|
||||
# generate Docker tags based on the following events/attributes
|
||||
tags: |
|
||||
type=schedule
|
||||
type=ref,event=branch
|
||||
type=ref,event=pr
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
type=sha
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Login to Docker Hub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
- name: Login to GHCR
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: docker/Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1 +1,4 @@
|
||||
test.php
|
||||
test.php
|
||||
notice.txt
|
||||
lib/vendor
|
||||
.vscode
|
||||
3
CHANGELOG.md
Normal file
3
CHANGELOG.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# V2.0.0 (Nov 2023)
|
||||
- Pushed current release to version 2.0
|
||||
- Updated CI to include versions
|
||||
1
LICENSE
1
LICENSE
@@ -199,4 +199,3 @@
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
|
||||
460
README.md
460
README.md
@@ -1,319 +1,141 @@
|
||||
# PictShare
|
||||
**[Live Demo](https://www.pictshare.net)**
|
||||
PictShare is a multi lingual, open source image hosting service with a simple resizing and upload API that you can host yourself.
|
||||
|
||||
---
|
||||
[](https://github.com/chrisiaut/pictshare/blob/master/LICENSE)
|
||||
|
||||
|
||||

|
||||
|
||||
Table of contents
|
||||
=================
|
||||
* [Installation](#installation)
|
||||
* [Docker](#docker)
|
||||
* [On nginx](#on-nginx)
|
||||
* [Docker Compose With Prebuild Image by hascheksolutions](#docker-compose-with-prebuild-image-by-hascheksolutions)
|
||||
* [Why would I want to host my own images?](#why-would-i-want-to-host-my-own-images)
|
||||
* [Features](#features)
|
||||
* [Smart query system](#smart-query-system)
|
||||
* [Available options](#available-options)
|
||||
* [How does the external-upload-API work?](#how-does-the-external-upload-api-work)
|
||||
* [Upload from external URL](#upload-from-external-url)
|
||||
* [Example:](#example)
|
||||
* [Upload via POST](#upload-via-post)
|
||||
* [Upload from base64 string](#upload-from-base64-string)
|
||||
* [Restriction settings](#restriction-settings)
|
||||
* [UPLOAD_CODE](#upload_code)
|
||||
* [IMAGE_CHANGE_CODE](#image_change_code)
|
||||
* [Security and privacy](#security-and-privacy)
|
||||
* [Requirements](#requirements)
|
||||
* [Upgrading](#upgrading)
|
||||
* [Addons](#addons)
|
||||
* [Traffic analysis](#traffic-analysis)
|
||||
* [Coming soon](#coming-soon)
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
### Docker
|
||||
The fastest way to deploy PictShare is via the [official Docker repo](https://hub.docker.com/r/hascheksolutions/pictshare/)
|
||||
- [Source code & more examples](https://github.com/HaschekSolutions/PictShare-Docker)
|
||||
|
||||
```bash
|
||||
docker run -d -p 80:80 -e "TITLE=My own PictShare" hascheksolutions/pictshare
|
||||
```
|
||||
|
||||
[](https://www.pictshare.net/8a1dec0973.mp4)
|
||||
|
||||
### Docker Compose With Prebuild Image by hascheksolutions
|
||||
|
||||
Run container by docker-compose:
|
||||
- First, install docker compose:
|
||||
[Docker official docs](https://docs.docker.com/compose/install/)
|
||||
- Pull docker-compose file:
|
||||
```bash
|
||||
wget https://raw.githubusercontent.com/chrisiaut/pictshare/master/docker-compose.yml
|
||||
```
|
||||
- Edit docker-compose file:
|
||||
```bash
|
||||
vi docker-compose.yml
|
||||
```
|
||||
- Run container by docker-compose:
|
||||
```bash
|
||||
docker-compose up
|
||||
```
|
||||
|
||||
By using this compose file, you should know that:
|
||||
- Will make a directory "volumes" in the same directory where compose file is.
|
||||
- Change `AUTOUPDATE` to false from true by defalt.
|
||||
- And...it is highly recommended to build your own image.
|
||||
|
||||
### Without Docker
|
||||
|
||||
- Make sure you have PHP5 GD libraries installed: ```apt-get install php5-gd```
|
||||
- Unpack the [PictShare zip](https://github.com/chrisiaut/pictshare/archive/master.zip)
|
||||
- Rename /inc/example.config.inc.php to /inc/config.inc.php
|
||||
- ```chmod +x bin/ffmpeg``` if you want to be able to use mp4 uploads
|
||||
- The provided ffmpeg binary (bin/ffmpeg) is from [here](http://johnvansickle.com/ffmpeg/) and it's a 64bit linux executable. If you need a different one, load yours and overwrite the one provided
|
||||
- (optional) You can and should put a [nginx](https://www.nginx.com/) proxy before the Apache server. That thing is just insanely fast with static content like images.
|
||||
- (optional) To secure your traffic I'd highly recommend getting an [SSL Cert](https://letsencrypt.org/) for your server if you don't already have one.
|
||||
|
||||
## Why would I want to host my own images?
|
||||
If you own a server (even a home server) you can host your own PictShare instance so you have full control over your content and can delete images hasslefree.
|
||||
|
||||
If you're an **app developer** or **sysadmin** you can use it for a centralized image hosting. With the simple upload API you can upload images to your PictShare instance and get a nice short URL
|
||||
|
||||
If you're a blogger like myself, you can use it as storage for your images so the images will still work even if you change blog providers or servers
|
||||
|
||||
## Features
|
||||
- Uploads without logins or validation (that's a good thing, right?)
|
||||
- Simple API to upload any image from remote servers to your instance [via URL](#upload-from-url) and [via Base64](#upload-from-base64-string)
|
||||
- 100% file based - no database needed
|
||||
- Simple album functions with embedding support
|
||||
- Converts gif to (much smaller) MP4
|
||||
- MP4 resizing
|
||||
- PictShare removes all exif data so you can upload photos from your phone and all GPS tags and camera model info get wiped
|
||||
- Smart [resize, filter and rotation](#smart-query-system) features
|
||||
- Generate gradients by specifying only a size. eg: https://pictshare.net/800x200
|
||||
- Duplicates don't take up space. If the exact same images is uploaded twice, the second upload will link to the first
|
||||
- You can control who can upload images or use filters/resizes by defining an [upload-code](#restriction-settings)
|
||||
- You can set a code in your ```/inc/config.inc.php``` (MASTER_DELETE_CODE) that, if appended to any URL of an Image, will delete the image and all cached versions of it from the server
|
||||
- Detailed traffic and view statistics of your images via [Pictshare stats](https://github.com/chrisiaut/pictshare_stats)
|
||||
- For more configuration possibilities check out the ```/inc/example.config.inc.php``` file
|
||||
|
||||
## Smart query system
|
||||
PictShare images can be changed after upload just by modifying the URL. It works like this:
|
||||
|
||||
<span style="color:blue">https://base.domain</span>/<span style="color:red"><options></span>/<span style="color:green"><image></span>
|
||||
|
||||
For example: https://pictshare.net/100x100/negative/b260e36b60.jpg will show you the uploaded Image ```b260e36b60.jpg``` but resize it to 100x100 pixels and apply the "negative" filter. The original image will stay untouched.
|
||||
|
||||
### Available options
|
||||
Original URL: ```https://www.pictshare.net/b260e36b60.jpg```
|
||||
|
||||
Note: If an option needs a value it works like this: ```optionname_value```. Eg: ```pixelate_10```
|
||||
If there is some option that's not recognized by PictShare it's simply ignored, so this will work: https://www.pictshare.net/pictshare-is-awesome/b260e36b60.jpg and also even this will work: https://www.pictshare.net/b260e36b60.jpg/how-can-this-still/work/
|
||||
|
||||
|
||||
| Option | Parameter | Example URL | Result |
|
||||
| ------------- | ------------------- | ---------------------- | ----------- |
|
||||
**Resizing** | | | |
|
||||
<width>**x**<height> | -none- | https://pictshare.net/20x20/b260e36b60.jpg |  |
|
||||
forcesize | -none- | https://pictshare.net/100x400/forcesize/b260e36b60.jpg |  |
|
||||
**Albums** | | | |
|
||||
just add multiple image hashes | -none- | https://www.pictshare.net/b260e36b60.jpg/32c9cf77c5.jpg/163484b6b1.jpg | Takes the **images** you put in the URL and makes an album out of them. All filters are supported!
|
||||
embed | -none- | https://www.pictshare.net/b260e36b60.jpg/32c9cf77c5.jpg/163484b6b1.jpg/embed | Renders the album without CSS and with transparent background so you can embed them easily
|
||||
responsive | -none- | https://www.pictshare.net/b260e36b60.jpg/32c9cf77c5.jpg/163484b6b1.jpg/responsive | Renders all images responsive (max-width 100%) according to screen size
|
||||
<width>**x**<height> | -none- | https://www.pictshare.net/b260e36b60.jpg/32c9cf77c5.jpg/163484b6b1.jpg/150x150 | Sets the size for the thumbnails in the album
|
||||
forcesize | -none- | https://www.pictshare.net/b260e36b60.jpg/32c9cf77c5.jpg/163484b6b1.jpg/100x300/forcesize | Forces thumbnail sizes to the values you provided
|
||||
**GIF to mp4** | | |
|
||||
mp4 | -none- | https://www.pictshare.net/mp4/102687fe65.gif | Converts gif to mp4 and displays as that. Note that you can't include that mp4 in an img tag
|
||||
raw | -none- | https://www.pictshare.net/mp4/raw/102687fe65.gif | Renders the converted mp4 directly. Use with /mp4/
|
||||
preview | -none- | https://www.pictshare.net/mp4/preview/102687fe65.gif | Renders the first frame of generated MP4 as JPEG. Use with /mp4/
|
||||
**MP4 options** | | |
|
||||
-none- | -none- | https://www.pictshare.net/65714d22f0.mp4 | Renders the mp4 embedded in a simple HTML template. This link can't be embedded into video tags, use /raw/ instead if you want to embed
|
||||
raw | -none- | https://www.pictshare.net/raw/65714d22f0.mp4 | Renders the mp4 video directly so you can link it
|
||||
preview | -none- | https://www.pictshare.net/preview/65714d22f0.mp4 | Renders the first frame of the MP4 as an JPEG image
|
||||
**Rotating** | | |
|
||||
left | -none- | https://pictshare.net/left/b260e36b60.jpg | 
|
||||
right | -none- | https://pictshare.net/right/b260e36b60.jpg | 
|
||||
upside | -none- | https://pictshare.net/upside/b260e36b60.jpg | 
|
||||
**Filters** | | |
|
||||
negative | -none- | https://pictshare.net/negative/b260e36b60.jpg | 
|
||||
grayscale | -none- | https://pictshare.net/grayscale/b260e36b60.jpg | 
|
||||
brightness | -255 to 255 | https://pictshare.net/brightness_100/b260e36b60.jpg | 
|
||||
edgedetect | -none- | https://pictshare.net/edgedetect/b260e36b60.jpg | 
|
||||
smooth | -10 to 2048 | https://pictshare.net/smooth_3/b260e36b60.jpg | 
|
||||
contrast | -100 to 100 | https://pictshare.net/contrast_40/b260e36b60.jpg | 
|
||||
pixelate | 0 to 100 | https://pictshare.net/pixelate_10/b260e36b60.jpg | 
|
||||
blur | -none- or 0 to 5 | https://pictshare.net/blur/b260e36b60.jpg | 
|
||||
sepia | -none- | https://pictshare.net/sepia/b260e36b60.jpg | 
|
||||
sharpen | -none- | https://pictshare.net/sharpen/b260e36b60.jpg | 
|
||||
emboss | -none- | https://pictshare.net/emboss/b260e36b60.jpg | 
|
||||
cool | -none- | https://pictshare.net/cool/b260e36b60.jpg | 
|
||||
light | -none- | https://pictshare.net/light/b260e36b60.jpg | 
|
||||
aqua | -none- | https://pictshare.net/aqua/b260e36b60.jpg | 
|
||||
fuzzy | -none- | https://pictshare.net/fuzzy/b260e36b60.jpg | 
|
||||
boost | -none- | https://pictshare.net/boost/b260e36b60.jpg | 
|
||||
gray | -none- | https://pictshare.net/gray/b260e36b60.jpg | 
|
||||
|
||||
You can also combine as many options as you want. Even multiple times! Want your image to be negative, resized, grayscale , with increased brightness and negate it again? No problem: https://pictshare.net/500x500/grayscale/negative/brightness_100/negative/b260e36b60.jpg
|
||||
|
||||
## How does the external-upload-API work?
|
||||
|
||||
### Upload from external URL
|
||||
PictShare has a simple REST API to upload remote pictures. The API can be accessed via the backend.php file like this:
|
||||
|
||||
```https://pictshare.net/backend.php?getimage=<URL of the image you want to upload>```.
|
||||
|
||||
#### Example:
|
||||
|
||||
Request: ```https://pictshare.net/backend.php?getimage=https://www.0xf.at/css/imgs/logo.png```
|
||||
|
||||
The server will answer with the file name and the server path in JSON:
|
||||
|
||||
```json
|
||||
{"status":"OK","type":"png","hash":"10ba188162.png","url":"https:\/\/pictshare.net\/10ba188162.png"}
|
||||
```
|
||||
|
||||
### Upload via POST
|
||||
|
||||
Send a POST request to ```https://pictshare.net/backend.php``` and send the image in the variable ```postimage```.
|
||||
|
||||
Server will return JSON of uploaded data like this:
|
||||
|
||||
```json
|
||||
{"status":"OK","type":"png","hash":"2f18a052c4.png","url":"https:\/\/pictshare.net\/2f18a052c4.png","domain":"https:\/\/pictshare.net\/"}
|
||||
```
|
||||
|
||||
### Upload from base64 string
|
||||
|
||||
Just send a POST request to ```https://pictshare.net/backend.php``` and send your image in base64 as the variable name ```base64```
|
||||
|
||||
Server will automatically try to guess the file type (which should work in 90% of the cases) and if it can't figure it out it'll just upload it as png.
|
||||
|
||||
## Restriction settings
|
||||
In your ```config.inc.php``` there are two values to be set: ```UPLOAD_CODE``` and ```IMAGE_CHANGE_CODE```
|
||||
|
||||
Both can be set to strings or multiple strings semi;colon;separated. If there is a semicolon in the string, any of the elements will work
|
||||
|
||||
### UPLOAD_CODE
|
||||
If set, will show users a code field in the upload form. If it doesn't match your setting, files won't be uploaded.
|
||||
|
||||
If enabled, the Upload API will need the variable ```upload_code``` via GET (eg: ```https://pictshare.net/backend.php?getimage=https://www.0xf.at/css/imgs/logo.png&upload_code=YourUploadCodeHere```)
|
||||
|
||||
### IMAGE_CHANGE_CODE
|
||||
If set,the [options](#available-options) will only work if the URL got the code in it. You can provide the code as option ```changecode_YourChangeCode```
|
||||
|
||||
For example: If enabled the image ```https://www.pictshare.net/negative/b260e36b60.jpg``` won't show the negative version but the original.
|
||||
If you access the image with the code like this: ```https://www.pictshare.net/changecode_YourChangeCode/b260e36b60.jpg``` it gets cached on the server so the next time someone requests the link without providing the change-code, they'll see the inverted image (because you just created it before by accessing the image with the code)
|
||||
|
||||
## Security and privacy
|
||||
- By hosting your own images you can delete them any time you want
|
||||
- You can enable or disable upload logging. Don't want to know who uploaded stuff? Just change the setting in inc/config.inc.php
|
||||
- No exif data is stored on the server, all jpegs get cleaned on upload
|
||||
- You have full control over your data. PictShare doesn't need remote libaries or tracking crap
|
||||
|
||||
## Scaling
|
||||
You can use **Backblaze Buckets** for storage of images so you can use multiple instances of PictShare and if the image is not found on the instance, it will look in the bucket.
|
||||
|
||||
Just add your credentials to the config.inc.php file as described in the ```example.config.inc.php``` file.
|
||||
|
||||
## Requirements
|
||||
- Apache or Nginx Webserver with PHP
|
||||
- PHP 5 GD library
|
||||
- A domain or sub-domain since PictShare can't be run from a subfolder of some other domain
|
||||
|
||||
## nginx config
|
||||
This is a simple config file that should make PictShare work on nginx
|
||||
|
||||
- Install php fpm: ```apt-get install php-fpm```
|
||||
- Install php Graphics libraries: ```apt-get install php-gd```
|
||||
|
||||
```
|
||||
server {
|
||||
listen 80 default_server;
|
||||
server_name your.awesome.domain.name;
|
||||
|
||||
root /var/www/pictshare; # or where ever you put it
|
||||
index index.php;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?url=$request_uri; # instead of htaccess mod_rewrite
|
||||
}
|
||||
|
||||
location ~ \.php {
|
||||
fastcgi_pass unix:/var/run/php5-fpm.sock;
|
||||
fastcgi_index index.php;
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_param PATH_INFO $fastcgi_script_name;
|
||||
}
|
||||
|
||||
location ~ /(upload|tmp|bin) {
|
||||
deny all;
|
||||
return 404;
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## Apache config
|
||||
This is a simple vHost config that should make PictShare work on Apache2.
|
||||
|
||||
- Install php5: ```apt-get install php5 libapache2-mod-php5```
|
||||
- Install php Graphics libraries: ```apt-get install php5-gd```
|
||||
- enable mod_rewrite
|
||||
|
||||
```
|
||||
<VirtualHost *:80 >
|
||||
ServerAdmin webmaster@sub.domain.tld
|
||||
ServerName sub.domain.tld
|
||||
ServerAlias sub.domain.tld
|
||||
DocumentRoot /var/www/html
|
||||
|
||||
<Directory /var/www/html/>
|
||||
Options Indexes FollowSymLinks MultiViews
|
||||
AllowOverride All
|
||||
Order allow,deny
|
||||
Allow from All
|
||||
</Directory>
|
||||
ErrorLog ${APACHE_LOG_DIR}/error.log
|
||||
LogLevel warn
|
||||
CustomLog ${APACHE_LOG_DIR}/access.log combined
|
||||
</VirtualHost>
|
||||
```
|
||||
|
||||
|
||||
## Upgrading
|
||||
- Just re-download the [PictShare zip](https://github.com/chrisiaut/pictshare/archive/master.zip) file and extract and overwrite existing pictshare files. Uploads and config won't be affected.
|
||||
- Check if your ```/inc/config.inc.php``` file has all settings required by the ```/inc/example.config.inc.php``` since new options might get added in new versions
|
||||
|
||||
Or use these commands:
|
||||
|
||||
```bash
|
||||
# to be run from the directory where your pictshare directory sits in
|
||||
git clone https://github.com/chrisiaut/pictshare.git temp
|
||||
cp -r temp/* pictshare/.
|
||||
rm -rf temp
|
||||
```
|
||||
|
||||
## Addons
|
||||
- Chrome Browser extension: https://chrome.google.com/webstore/detail/pictshare-1-click-imagesc/mgomffcdpnohakmlhhjmiemlolonpafc
|
||||
- Source: https://github.com/chrisiaut/PictShare-Chrome-extension
|
||||
- Plugin to upload images with ShareX: https://github.com/ShareX/CustomUploaders/blob/master/pictshare.net.sxcu
|
||||
|
||||
## Traffic analysis
|
||||
See [Pictshare stats](https://github.com/chrisiaut/pictshare_stats)
|
||||
|
||||
## Coming soon
|
||||
- Delete codes for every uploaded image so users can delete images if no longer needed
|
||||
- Albums
|
||||
|
||||
---
|
||||
Design (c) by [Bernhard Moser](mailto://bernhard.moser91@gmail.com)
|
||||
|
||||
This is a [HASCHEK SOLUTIONS](https://haschek.solutions) project
|
||||
|
||||
[](https://haschek.solutions)
|
||||
<p align="center">
|
||||
<a href="" rel="noopener">
|
||||
<img height=200px src="./css/imgs/logo/logo.svg" alt="PictShare logo">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<h1 align="center">PictShare</h1>
|
||||
|
||||
<h4 align="center">https://pictshare.net</h4>
|
||||
|
||||
<div align="center">
|
||||
|
||||
|
||||

|
||||
[](https://hub.docker.com/r/hascheksolutions/pictshare)
|
||||
]
|
||||
[](https://github.com/HaschekSolutions/pictshare/blob/master/LICENSE)
|
||||
[](https://hits.seeyoufarm.com)
|
||||
[](https://github.com/HaschekSolutions/pictshare)
|
||||
|
||||
#### Host your own `images` `gifs` `mp4s` `text bins` and stay in control
|
||||
|
||||
</div>
|
||||
|
||||
-----------------------------------------
|
||||
<center>
|
||||
|
||||
<p align="center">
|
||||
<img src="https://www.pictshare.net/39928d8239.gif" alt="PictShare demo">
|
||||
</p>
|
||||
|
||||
Table of contents
|
||||
=================
|
||||
* [Quick Start](#quickstart)
|
||||
* [Features](#features)
|
||||
* [Installation](/rtfm/INSTALL.md)
|
||||
* [Configuration](/rtfm/CONFIG.md)
|
||||
* [Docker](/rtfm/DOCKER.md)
|
||||
* [API](/rtfm/API.md)
|
||||
* [Addons and integration](/rtfm/INTEGRATIONS.md)
|
||||
* [Development roadmap](#development-roadmap)
|
||||
|
||||
---
|
||||
|
||||
## Quickstart
|
||||
|
||||
```bash
|
||||
docker run -d -p 8080:80 --name=pictshare ghcr.io/hascheksolutions/pictshare
|
||||
```
|
||||
|
||||
Then open http://localhost:8080 in your browser
|
||||
|
||||
## New Features
|
||||
|
||||
- Generate identicons based on strings in the URL [example1](https://pictshare.net/identicon/example1) [example2](https://pictshare.net/identicon/example2)
|
||||
- Generate placeholder images by specifying the size in the URL. [example](https://pictshare.net/placeholder/555x250/color-white-blue)
|
||||
- Added support for external storage
|
||||
- [Encryption of files in external storage](/rtfm/ENCRYPTION.md)
|
||||
- Added text hosting (like pastebin)
|
||||
- Added URL shortening
|
||||
- Added WebP to images (and automatic conversion from jpg, png to webp if the requesting browser supports it)
|
||||
- Massive code rework. Actually we designed it from the ground up to be more modular and easier to debug
|
||||
|
||||
# Features
|
||||
|
||||
- Selfhostable
|
||||
- [Simple upload API](/rtfm/API.md)
|
||||
- 100% file based - no database needed
|
||||
- [Scalable hosting](/rtfm/SCALING.md)
|
||||
- Many [Filters](/rtfm/IMAGEFILTERS.md) for images
|
||||
- GIF to MP4 conversion
|
||||
- JPG, PNG to WEBP conversion
|
||||
- MP4 resizing
|
||||
- PictShare removes all exif data so you can upload photos from your phone and all GPS tags and camera model info get wiped
|
||||
- Change and resize your images and videos just by editing the URL
|
||||
- Duplicates don't take up space. If the exact same file is uploaded twice, the second upload will link to the first
|
||||
- Many [configuration options](/rtfm/CONFIG.md)
|
||||
- Full control over your data. Delete images with individual and global delete codes
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Development roadmap
|
||||
|
||||
- [x] Duplicate detection
|
||||
- [x] Write permission detection
|
||||
- [x] Delete codes for every uploaded file
|
||||
- [x] Upload via link/url
|
||||
- [x] Upload via base64
|
||||
- [ ] Autodestruct for every uploaded file
|
||||
|
||||
### Config options
|
||||
|
||||
Read [here](/rtfm/CONFIG.md) what those options do
|
||||
|
||||
- [x] ALT_FOLDER
|
||||
- [x] URL (instead of FORCE_DOMAIN but mandatory)
|
||||
- [x] LOG_UPLOADER
|
||||
- [x] FFMPEG_BINARY
|
||||
- [x] PNG_COMPRESSION
|
||||
- [x] JPEG_COMPRESSION
|
||||
- [x] WEBP_COMPRESSION
|
||||
- [x] MASTER_DELETE_CODE
|
||||
- [x] MASTER_DELETE_IP
|
||||
- [x] UPLOAD_FORM_LOCATION
|
||||
- [x] S3 Backend
|
||||
- [x] UPLOAD_CODE
|
||||
- [ ] UPLOAD_QUOTA
|
||||
- [ ] LOW_PROFILE
|
||||
- [ ] IMAGE_CHANGE_CODE
|
||||
- [ ] MAX_RESIZED_IMAGES
|
||||
- [ ] ALLOW_BLOATING
|
||||
|
||||
### Image hosting
|
||||
- [x] Resizing
|
||||
- [x] Filters
|
||||
- [x] Gif to mp4 conversion
|
||||
- [x] Upload of images
|
||||
|
||||
### Text file hosting
|
||||
- [x] Upload of text files
|
||||
- [x] Render template for text files
|
||||
- [x] Raw data view
|
||||
- [x] Downloadable
|
||||
|
||||
### URL shortening
|
||||
- [ ] Upload of links to shorten
|
||||
|
||||
### MP4 hosting
|
||||
- [x] Resizing
|
||||
- [x] Preview image generation
|
||||
- [x] Upload of videos
|
||||
- [x] Automatic conversion if not mobile friendly or wrong encoder used
|
||||
- [x] Render template for videos
|
||||
|
||||
|
||||
---
|
||||
|
||||
This is a [HASCHEK SOLUTIONS](https://haschek.solutions) project
|
||||
|
||||
[](https://haschek.solutions)
|
||||
|
||||
11
SECURITY.md
Normal file
11
SECURITY.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
PictShare uses rolling releases so the latest version is the only supported one.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Reports can be made as issues in this repo or in confidence via christian@haschek.at
|
||||
|
||||
Pull requests welcome
|
||||
125
api/base64.php
Normal file
125
api/base64.php
Normal file
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
// basic path definitions
|
||||
define('DS', DIRECTORY_SEPARATOR);
|
||||
define('ROOT', dirname(__FILE__).'/..');
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
//loading default settings if exist
|
||||
if(!file_exists(ROOT.DS.'inc'.DS.'config.inc.php'))
|
||||
exit('Rename /inc/example.config.inc.php to /inc/config.inc.php first!');
|
||||
include_once(ROOT.DS.'inc'.DS.'config.inc.php');
|
||||
|
||||
//loading core and controllers
|
||||
include_once(ROOT . DS . 'inc' . DS. 'core.php');
|
||||
//load external things if existing
|
||||
if(file_exists(ROOT.'/lib/vendor/autoload.php'))
|
||||
require ROOT.'/lib/vendor/autoload.php';
|
||||
loadAllContentControllers();
|
||||
|
||||
// check if client has permission to upload
|
||||
executeUploadPermission();
|
||||
|
||||
// check write permissions first
|
||||
if(!isFolderWritable(getDataDir()))
|
||||
exit(json_encode(array('status'=>'err','reason'=>'Data directory not writable')));
|
||||
else if(!isFolderWritable(ROOT.DS.'tmp'))
|
||||
exit(json_encode(array('status'=>'err','reason'=>'Temp directory not writable')));
|
||||
|
||||
$hash = sanatizeString(trim($_REQUEST['hash']))?sanatizeString(trim($_REQUEST['hash'])):false;
|
||||
|
||||
// check for POSTed text
|
||||
if($_REQUEST['base64'])
|
||||
{
|
||||
$data = $_REQUEST['base64'];
|
||||
$format = $_REQUEST['format'];
|
||||
|
||||
$tmpfile = ROOT.DS.'tmp'.DS.md5(rand(0,10000).time()).time();
|
||||
|
||||
base64ToFile($data, $tmpfile);
|
||||
|
||||
|
||||
//get the file type
|
||||
$type = getTypeOfFile($tmpfile);
|
||||
|
||||
//check for duplicates
|
||||
$sha1 = sha1_file($tmpfile);
|
||||
$ehash = sha1Exists($sha1);
|
||||
if($ehash && file_exists(getDataDir().DS.$ehash.DS.$ehash))
|
||||
exit(json_encode(array('status'=>'ok','hash'=>$ehash,'filetype'=>$type,'url'=>getURL().$ehash)));
|
||||
|
||||
|
||||
|
||||
//cross check filetype for controllers
|
||||
//
|
||||
//image?
|
||||
if(in_array($type,(new ImageController)->getRegisteredExtensions()))
|
||||
{
|
||||
$answer = (new ImageController())->handleUpload($tmpfile,$hash);
|
||||
}
|
||||
//or, a text
|
||||
else if($type=='text')
|
||||
{
|
||||
$answer = (new TextController())->handleUpload($tmpfile,$hash);
|
||||
}
|
||||
//or, a video
|
||||
else if(in_array($type,(new VideoController)->getRegisteredExtensions()))
|
||||
{
|
||||
$answer = (new VideoController())->handleUpload($tmpfile,$hash);
|
||||
}
|
||||
|
||||
if(!$answer)
|
||||
$answer = array('status'=>'err','reason'=>'Unsupported filetype','filetype'=>$type);
|
||||
|
||||
if($answer['hash'] && $answer['status']=='ok')
|
||||
{
|
||||
$answer['filetype'] = $type;
|
||||
//add this sha1 to the list
|
||||
addSha1($answer['hash'],$sha1);
|
||||
|
||||
if(getDeleteCodeOfHash($answer['hash']))
|
||||
{
|
||||
$answer['delete_code'] = getDeleteCodeOfHash($answer['hash']);
|
||||
$answer['delete_url'] = getURL().'delete_'.getDeleteCodeOfHash($answer['hash']).'/'.$answer['hash'];
|
||||
}
|
||||
|
||||
storageControllerUpload($answer['hash']);
|
||||
}
|
||||
|
||||
echo json_encode($answer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function base64_to_type($base64_string)
|
||||
{
|
||||
$data = explode(',', $base64_string);
|
||||
$data = $data[1];
|
||||
|
||||
$data = str_replace(' ','+',$data);
|
||||
$data = base64_decode($data);
|
||||
|
||||
$info = getimagesizefromstring($data);
|
||||
|
||||
|
||||
|
||||
trigger_error("########## FILETYPE: ".$info['mime']);
|
||||
|
||||
|
||||
$f = finfo_open();
|
||||
$type = finfo_buffer($f, $data, FILEINFO_MIME_TYPE);
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
function base64ToFile($base64_string, $output_file)
|
||||
{
|
||||
$data = explode(',', $base64_string);
|
||||
$data = $data[1];
|
||||
$data = str_replace(' ','+',$data);
|
||||
$data = base64_decode($data);
|
||||
$ifp = fopen( $output_file, 'wb' );
|
||||
fwrite( $ifp, $data );
|
||||
fclose( $ifp );
|
||||
}
|
||||
128
api/geturl.php
Normal file
128
api/geturl.php
Normal file
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
// basic path definitions
|
||||
define('DS', DIRECTORY_SEPARATOR);
|
||||
define('ROOT', dirname(__FILE__).'/..');
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
//loading default settings if exist
|
||||
if(!file_exists(ROOT.DS.'inc'.DS.'config.inc.php'))
|
||||
exit('Rename /inc/example.config.inc.php to /inc/config.inc.php first!');
|
||||
include_once(ROOT.DS.'inc'.DS.'config.inc.php');
|
||||
|
||||
//loading core and controllers
|
||||
include_once(ROOT . DS . 'inc' . DS. 'core.php');
|
||||
//load external things if existing
|
||||
if(file_exists(ROOT.'/lib/vendor/autoload.php'))
|
||||
require ROOT.'/lib/vendor/autoload.php';
|
||||
loadAllContentControllers();
|
||||
|
||||
// check if client has permission to upload
|
||||
executeUploadPermission();
|
||||
|
||||
// check write permissions first
|
||||
if(!isFolderWritable(getDataDir()))
|
||||
exit(json_encode(array('status'=>'err','reason'=>'Data directory not writable')));
|
||||
else if(!isFolderWritable(ROOT.DS.'tmp'))
|
||||
exit(json_encode(array('status'=>'err','reason'=>'Temp directory not writable')));
|
||||
|
||||
$hash = sanatizeString(trim($_REQUEST['hash']))?sanatizeString(trim($_REQUEST['hash'])):false;
|
||||
|
||||
$url = trim($_REQUEST['url']);
|
||||
|
||||
if(checkURLForPrivateIPRange($url))
|
||||
exit(json_encode(array('status'=>'err','reason'=>'Private IP range')));
|
||||
|
||||
if(!$url || !startsWith($url, 'http'))
|
||||
exit(json_encode(array('status'=>'err','reason'=>'Invalid URL')));
|
||||
|
||||
//@todo: let user decide max upload size via config and set php_ini var
|
||||
else if(remote_filesize($url)*0.000001 > 20)
|
||||
exit(json_encode(array('status'=>'err','reason'=>'File too big. 20MB max')));
|
||||
|
||||
$name = basename($url);
|
||||
$tmpfile = ROOT.DS.'tmp'.DS.$name;
|
||||
|
||||
$context = stream_context_create(
|
||||
array(
|
||||
"http" => array(
|
||||
"follow_location" => false,
|
||||
),
|
||||
)
|
||||
);
|
||||
file_put_contents($tmpfile,file_get_contents($url, false, $context));
|
||||
|
||||
$type = getTypeOfFile($tmpfile);
|
||||
|
||||
//check for duplicates
|
||||
$sha1 = sha1_file($tmpfile);
|
||||
$ehash = sha1Exists($sha1);
|
||||
if($ehash && file_exists(getDataDir().DS.$ehash.DS.$ehash))
|
||||
exit(json_encode(array('status'=>'ok','hash'=>$ehash,'filetype'=>$type,'url'=>getURL().$ehash)));
|
||||
|
||||
//cross check filetype for controllers
|
||||
//
|
||||
//image?
|
||||
if(in_array($type,(new ImageController)->getRegisteredExtensions()))
|
||||
{
|
||||
$answer = (new ImageController())->handleUpload($tmpfile,$hash);
|
||||
}
|
||||
//or, a text
|
||||
else if($type=='text')
|
||||
{
|
||||
$answer = (new TextController())->handleUpload($tmpfile,$hash);
|
||||
}
|
||||
//or, a video
|
||||
else if(in_array($type,(new VideoController)->getRegisteredExtensions()))
|
||||
{
|
||||
$answer = (new VideoController())->handleUpload($tmpfile,$hash);
|
||||
}
|
||||
|
||||
if(!$answer)
|
||||
$answer = array('status'=>'err','reason'=>'Unsupported filetype','filetype'=>$type);
|
||||
|
||||
if($answer['hash'] && $answer['status']=='ok')
|
||||
{
|
||||
$answer['filetype'] = $type;
|
||||
//add this sha1 to the list
|
||||
addSha1($answer['hash'],$sha1);
|
||||
|
||||
if(getDeleteCodeOfHash($answer['hash']))
|
||||
{
|
||||
$answer['delete_code'] = getDeleteCodeOfHash($answer['hash']);
|
||||
$answer['delete_url'] = getURL().'delete_'.getDeleteCodeOfHash($answer['hash']).'/'.$answer['hash'];
|
||||
}
|
||||
|
||||
|
||||
storageControllerUpload($answer['hash']);
|
||||
}
|
||||
|
||||
if($answer['hash'] && $answer['status']=='ok')
|
||||
{
|
||||
//add this sha1 to the list
|
||||
addSha1($answer['hash'],$sha1);
|
||||
|
||||
if(getDeleteCodeOfHash($answer['hash']))
|
||||
{
|
||||
$answer['delete_code'] = getDeleteCodeOfHash($answer['hash']);
|
||||
$answer['delete_url'] = getURL().'delete_'.getDeleteCodeOfHash($answer['hash']).'/'.$answer['hash'];
|
||||
}
|
||||
|
||||
storageControllerUpload($answer['hash']);
|
||||
}
|
||||
|
||||
echo json_encode($answer);
|
||||
|
||||
|
||||
|
||||
function remote_filesize($url) {
|
||||
static $regex = '/^Content-Length: *+\K\d++$/im';
|
||||
if (!$fp = @fopen($url, 'rb'))
|
||||
return false;
|
||||
if (
|
||||
isset($http_response_header) &&
|
||||
preg_match($regex, implode("\n", $http_response_header), $matches)
|
||||
)
|
||||
return (int)$matches[0];
|
||||
return strlen(stream_get_contents($fp));
|
||||
}
|
||||
53
api/info.php
Normal file
53
api/info.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
// basic path definitions
|
||||
define('DS', DIRECTORY_SEPARATOR);
|
||||
define('ROOT', dirname(__FILE__).'/..');
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
//loading default settings if exist
|
||||
if(!file_exists(ROOT.DS.'inc'.DS.'config.inc.php'))
|
||||
exit('Rename /inc/example.config.inc.php to /inc/config.inc.php first!');
|
||||
include_once(ROOT.DS.'inc'.DS.'config.inc.php');
|
||||
|
||||
//loading core and controllers
|
||||
include_once(ROOT . DS . 'inc' . DS. 'core.php');
|
||||
//load external things if existing
|
||||
if(file_exists(ROOT.'/lib/vendor/autoload.php'))
|
||||
require ROOT.'/lib/vendor/autoload.php';
|
||||
|
||||
if($_REQUEST['ip']=='pls') exit(getUserIP());
|
||||
|
||||
loadAllContentControllers();
|
||||
|
||||
$hash = $_REQUEST['hash'];
|
||||
|
||||
if(!isExistingHash($hash))
|
||||
{
|
||||
exit(json_encode(array('status'=>'err','reason'=>'File not found')));
|
||||
}
|
||||
else
|
||||
{
|
||||
$answer = getInfoAboutHash($hash);
|
||||
$answer['status'] = 'ok';
|
||||
exit(json_encode($answer));
|
||||
}
|
||||
|
||||
|
||||
function getInfoAboutHash($hash)
|
||||
{
|
||||
$file = getDataDir().DS.$hash.DS.$hash;
|
||||
if(!file_exists($file))
|
||||
return array('status'=>'err','reason'=>'File not found');
|
||||
$size = filesize($file);
|
||||
$size_hr = renderSize($size);
|
||||
$content_type = exec("file -bi " . escapeshellarg($file));
|
||||
if($content_type && strpos($content_type,'/')!==false && strpos($content_type,';')!==false)
|
||||
{
|
||||
$type = $content_type;
|
||||
$c = explode(';',$type);
|
||||
$type = $c[0];
|
||||
}
|
||||
|
||||
return array('hash'=>$hash,'size_bytes'=>$size,'size_interpreted'=>$size_hr,'type'=>$type,'type_interpreted'=>getTypeOfFile($file));
|
||||
}
|
||||
47
api/pastebin.php
Normal file
47
api/pastebin.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
// basic path definitions
|
||||
define('DS', DIRECTORY_SEPARATOR);
|
||||
define('ROOT', dirname(__FILE__).'/..');
|
||||
|
||||
//loading default settings if exist
|
||||
if(!file_exists(ROOT.DS.'inc'.DS.'config.inc.php'))
|
||||
exit('Rename /inc/example.config.inc.php to /inc/config.inc.php first!');
|
||||
include_once(ROOT.DS.'inc'.DS.'config.inc.php');
|
||||
|
||||
//loading core and controllers
|
||||
include_once(ROOT . DS . 'inc' . DS. 'core.php');
|
||||
//load external things if existing
|
||||
if(file_exists(ROOT.'/lib/vendor/autoload.php'))
|
||||
require ROOT.'/lib/vendor/autoload.php';
|
||||
$controllers = loadAllContentControllers();
|
||||
if(!in_array('TextController',$controllers))
|
||||
exit(json_encode(array('status'=>'err','reason'=>'Text controller not enabled')));
|
||||
|
||||
// check if client has permission to upload
|
||||
executeUploadPermission();
|
||||
|
||||
// check write permissions first
|
||||
if(!isFolderWritable(getDataDir()))
|
||||
exit(json_encode(array('status'=>'err','reason'=>'Data directory not writable')));
|
||||
else if(!isFolderWritable(ROOT.DS.'tmp'))
|
||||
exit(json_encode(array('status'=>'err','reason'=>'Temp directory not writable')));
|
||||
|
||||
// check for POSTed text
|
||||
if($_REQUEST['api_paste_code'])
|
||||
{
|
||||
$hash = getNewHash('txt',$length=10);
|
||||
$tmpfile = ROOT.DS.'tmp'.DS.$hash;
|
||||
file_put_contents($tmpfile,$_REQUEST['api_paste_code']);
|
||||
|
||||
//check if this exact paste already exists
|
||||
$sha1 = sha1_file($tmpfile);
|
||||
$sha_hash = sha1Exists($sha1);
|
||||
if($sha_hash)
|
||||
exit(getURL().$sha_hash);
|
||||
|
||||
$answer = (new TextController())->handleUpload($tmpfile,$hash);
|
||||
if($answer['hash'] && $answer['status']=='ok')
|
||||
addSha1($answer['hash'],$sha1);
|
||||
|
||||
echo getURL().$hash;
|
||||
}
|
||||
98
api/upload.php
Normal file
98
api/upload.php
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
// basic path definitions
|
||||
define('DS', DIRECTORY_SEPARATOR);
|
||||
define('ROOT', dirname(__FILE__).DS.'..');
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
//loading default settings if exist
|
||||
if(!file_exists(ROOT.DS.'inc'.DS.'config.inc.php'))
|
||||
exit('Rename /inc/example.config.inc.php to /inc/config.inc.php first!');
|
||||
include_once(ROOT.DS.'inc'.DS.'config.inc.php');
|
||||
|
||||
//loading core and controllers
|
||||
include_once(ROOT . DS . 'inc' . DS. 'core.php');
|
||||
//load external things if existing
|
||||
if(file_exists(ROOT.'/lib/vendor/autoload.php'))
|
||||
require ROOT.'/lib/vendor/autoload.php';
|
||||
$allowedcontentcontrollers = loadAllContentControllers();
|
||||
|
||||
// check write permissions first
|
||||
if(!isFolderWritable(getDataDir()))
|
||||
exit(json_encode(array('status'=>'err','reason'=>'Data directory not writable')));
|
||||
else if(!isFolderWritable(ROOT.DS.'tmp'))
|
||||
exit(json_encode(array('status'=>'err','reason'=>'Temp directory not writable')));
|
||||
|
||||
// check if client has permission to upload
|
||||
executeUploadPermission();
|
||||
|
||||
if(isset($_REQUEST['hash']))
|
||||
$hash = sanatizeString(trim($_REQUEST['hash']));
|
||||
else
|
||||
$hash = false;
|
||||
|
||||
// check for POST upload
|
||||
if ($_FILES['file']["error"] == UPLOAD_ERR_OK)
|
||||
{
|
||||
//get the file type
|
||||
$type = getTypeOfFile($_FILES['file']["tmp_name"]);
|
||||
|
||||
//check for duplicates
|
||||
$sha1 = sha1_file($_FILES['file']["tmp_name"]);
|
||||
$ehash = sha1Exists($sha1);
|
||||
if($ehash && file_exists(getDataDir().DS.$ehash.DS.$ehash))
|
||||
exit(json_encode(array('status'=>'ok','hash'=>$ehash,'filetype'=>$type,'url'=>getURL().$ehash)));
|
||||
|
||||
//cross check filetype for controllers
|
||||
//
|
||||
//image?
|
||||
|
||||
foreach($allowedcontentcontrollers as $cc)
|
||||
{
|
||||
if(in_array($type,(new $cc)->getRegisteredExtensions()))
|
||||
{
|
||||
$answer = (new $cc())->handleUpload($_FILES['file']['tmp_name'],$hash);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if(in_array($type,(new ImageController)->getRegisteredExtensions()))
|
||||
{
|
||||
$answer = (new ImageController())->handleUpload($_FILES['file']['tmp_name'],$hash);
|
||||
}
|
||||
|
||||
//or, a text
|
||||
else if($type=='text')
|
||||
{
|
||||
$answer = (new TextController())->handleUpload($_FILES['file']['tmp_name'],$hash);
|
||||
}
|
||||
//or, a video
|
||||
else if(in_array($type,(new VideoController)->getRegisteredExtensions()))
|
||||
{
|
||||
$answer = (new VideoController())->handleUpload($_FILES['file']['tmp_name'],$hash);
|
||||
}
|
||||
*/
|
||||
if(!$answer)
|
||||
$answer = array('status'=>'err','reason'=>'Unsupported filetype: '.$type,'filetype'=>$type);
|
||||
|
||||
if($answer['hash'] && $answer['status']=='ok')
|
||||
{
|
||||
$answer['filetype'] = $type;
|
||||
//add this sha1 to the list
|
||||
addSha1($answer['hash'],$sha1);
|
||||
|
||||
if(getDeleteCodeOfHash($answer['hash']))
|
||||
{
|
||||
$answer['delete_code'] = getDeleteCodeOfHash($answer['hash']);
|
||||
$answer['delete_url'] = getURL().'delete_'.getDeleteCodeOfHash($answer['hash']).'/'.$answer['hash'];
|
||||
}
|
||||
|
||||
|
||||
storageControllerUpload($answer['hash']);
|
||||
}
|
||||
|
||||
echo json_encode($answer);
|
||||
}
|
||||
else
|
||||
exit(json_encode(array('status'=>'err','reason'=>'Upload error')));
|
||||
54
backend.php
54
backend.php
@@ -1,54 +0,0 @@
|
||||
<?php
|
||||
session_cache_limiter("public");
|
||||
$expiry = 90; //days
|
||||
session_cache_expire($expiry * 24 * 60);
|
||||
session_start();
|
||||
define('DS', DIRECTORY_SEPARATOR);
|
||||
define('ROOT', dirname(__FILE__));
|
||||
define('PATH',((dirname($_SERVER['PHP_SELF'])=='/'||dirname($_SERVER['PHP_SELF'])=='\\'||dirname($_SERVER['PHP_SELF'])=='/index.php'||dirname($_SERVER['PHP_SELF'])=='/backend.php')?'/':dirname($_SERVER['PHP_SELF']).'/'));
|
||||
|
||||
if(!file_exists(ROOT.DS.'inc'.DS.'config.inc.php'))
|
||||
exit('Rename /inc/example.config.inc.php to /inc/config.inc.php first!');
|
||||
include_once(ROOT.DS.'inc'.DS.'config.inc.php');
|
||||
|
||||
if(FORCE_DOMAIN)
|
||||
define('DOMAINPATH',FORCE_DOMAIN);
|
||||
else
|
||||
define('DOMAINPATH',(isset($_SERVER['HTTPS'])?'https':'http').'://'.$_SERVER['HTTP_HOST']);
|
||||
error_reporting(E_ALL & ~E_NOTICE);
|
||||
if(SHOW_ERRORS)
|
||||
ini_set('display_errors','On');
|
||||
else ini_set('display_errors','Off');
|
||||
|
||||
include_once(ROOT.DS.'inc'.DS.'core.php');
|
||||
|
||||
$pm = new PictshareModel();
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
if(UPLOAD_CODE!=false && !$pm->uploadCodeExists($_REQUEST['upload_code']))
|
||||
exit(json_encode(array('status'=>'ERR','reason'=>'Wrong upload code provided')));
|
||||
|
||||
if($_REQUEST['getimage'])
|
||||
{
|
||||
$url = $_REQUEST['getimage'];
|
||||
|
||||
echo json_encode($pm->uploadImageFromURL($url));
|
||||
}
|
||||
else if($_FILES['postimage'])
|
||||
{
|
||||
$image = $_FILES['postimage'];
|
||||
echo json_encode($pm->processSingleUpload($file,'postimage'));
|
||||
}
|
||||
else if($_REQUEST['base64'])
|
||||
{
|
||||
$data = $_REQUEST['base64'];
|
||||
$format = $_REQUEST['format'];
|
||||
echo json_encode($pm->uploadImageFromBase64($data,$format));
|
||||
}
|
||||
else if($_REQUEST['geturlinfo'])
|
||||
echo json_encode($pm->getURLInfo($_REQUEST['geturlinfo']));
|
||||
else if($_REQUEST['a']=='oembed')
|
||||
echo json_encode($pm->oembed($_REQUEST['url'],$_REQUEST['t']));
|
||||
else
|
||||
echo json_encode(array('status'=>'ERR','reason'=>'NO_VALID_COMMAND'));
|
||||
BIN
bin/ffmpeg
BIN
bin/ffmpeg
Binary file not shown.
Binary file not shown.
@@ -1,280 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Backblaze B2 wrapper without external depenecies
|
||||
*
|
||||
* @author Christian Haschek <christian@haschek.at>
|
||||
*/
|
||||
|
||||
class Backblaze
|
||||
{
|
||||
private $token;
|
||||
private $apiURL;
|
||||
private $bucket;
|
||||
private $dlURL;
|
||||
private $ulURL;
|
||||
private $ulToken;
|
||||
private $bucket_name;
|
||||
private $files;
|
||||
|
||||
function __construct()
|
||||
{
|
||||
if( BACKBLAZE !== true || !defined('BACKBLAZE_ID') || !defined('BACKBLAZE_KEY') || !defined('BACKBLAZE_BUCKET_ID'))
|
||||
return;
|
||||
$this->authorize();
|
||||
$this->bucket = BACKBLAZE_BUCKET_ID;
|
||||
$this->bucket_name = (( defined('BACKBLAZE_BUCKET_NAME') && BACKBLAZE_BUCKET_NAME != "")?BACKBLAZE_BUCKET_NAME:$this->bucketIdToName($bucket));
|
||||
}
|
||||
|
||||
function authorize()
|
||||
{
|
||||
$account_id = BACKBLAZE_ID; // Obtained from your B2 account page
|
||||
$application_key = BACKBLAZE_KEY; // Obtained from your B2 account page
|
||||
$credentials = base64_encode($account_id . ":" . $application_key);
|
||||
$url = "https://api.backblazeb2.com/b2api/v1/b2_authorize_account";
|
||||
|
||||
$session = curl_init($url);
|
||||
|
||||
// Add headers
|
||||
$headers = array();
|
||||
$headers[] = "Accept: application/json";
|
||||
$headers[] = "Authorization: Basic " . $credentials;
|
||||
curl_setopt($session, CURLOPT_HTTPHEADER, $headers); // Add headers
|
||||
|
||||
curl_setopt($session, CURLOPT_HTTPGET, true); // HTTP GET
|
||||
curl_setopt($session, CURLOPT_RETURNTRANSFER, true); // Receive server response
|
||||
$server_output = curl_exec($session);
|
||||
curl_close ($session);
|
||||
$data = json_decode($server_output,true);
|
||||
|
||||
$this->token = $data['authorizationToken'];
|
||||
$this->apiURL = $data['apiUrl'];
|
||||
$this->dlURL = $data['downloadUrl'];
|
||||
}
|
||||
|
||||
function upload($hash)
|
||||
{
|
||||
if(!$this->ulURL)
|
||||
$this->getUploadInfo();
|
||||
$file_name = $hash;
|
||||
$my_file = ROOT.DS.'upload'.DS.$hash.DS.$hash;
|
||||
$handle = fopen($my_file, 'r');
|
||||
$read_file = fread($handle,filesize($my_file));
|
||||
|
||||
$upload_url = $this->ulURL; // Provided by b2_get_upload_url
|
||||
$upload_auth_token = $this->ulToken; // Provided by b2_get_upload_url
|
||||
$bucket_id = $this->bucket; // The ID of the bucket
|
||||
$content_type = "text/plain";
|
||||
$sha1_of_file_data = sha1_file($my_file);
|
||||
|
||||
$session = curl_init($upload_url);
|
||||
|
||||
// Add read file as post field
|
||||
curl_setopt($session, CURLOPT_POSTFIELDS, $read_file);
|
||||
|
||||
// Add headers
|
||||
$headers = array();
|
||||
$headers[] = "Authorization: " . $upload_auth_token;
|
||||
$headers[] = "X-Bz-File-Name: " . $file_name;
|
||||
$headers[] = "Content-Type: " . $content_type;
|
||||
$headers[] = "X-Bz-Content-Sha1: " . $sha1_of_file_data;
|
||||
curl_setopt($session, CURLOPT_HTTPHEADER, $headers);
|
||||
|
||||
curl_setopt($session, CURLOPT_POST, true); // HTTP POST
|
||||
curl_setopt($session, CURLOPT_RETURNTRANSFER, true); // Receive server response
|
||||
$server_output = curl_exec($session); // Let's do this!
|
||||
curl_close ($session); // Clean up
|
||||
//var_dump($server_output); // Tell me about the rabbits, George!
|
||||
}
|
||||
|
||||
function getUploadInfo()
|
||||
{
|
||||
$api_url = $this->apiURL; // From b2_authorize_account call
|
||||
$auth_token = $this->token; // From b2_authorize_account call
|
||||
$bucket_id = $this->bucket; // The ID of the bucket you want to upload to
|
||||
|
||||
$session = curl_init($api_url . "/b2api/v1/b2_get_upload_url");
|
||||
|
||||
// Add post fields
|
||||
$data = array("bucketId" => $bucket_id);
|
||||
$post_fields = json_encode($data);
|
||||
curl_setopt($session, CURLOPT_POSTFIELDS, $post_fields);
|
||||
|
||||
// Add headers
|
||||
$headers = array();
|
||||
$headers[] = "Authorization: " . $auth_token;
|
||||
curl_setopt($session, CURLOPT_HTTPHEADER, $headers);
|
||||
|
||||
curl_setopt($session, CURLOPT_POST, true); // HTTP POST
|
||||
curl_setopt($session, CURLOPT_RETURNTRANSFER, true); // Receive server response
|
||||
$server_output = curl_exec($session); // Let's do this!
|
||||
curl_close ($session); // Clean up
|
||||
$data = json_decode($server_output,true); // Tell me about the rabbits, George!
|
||||
$this->ulURL = $data['uploadUrl'];
|
||||
//var_dump("upload url at load: ".$data['uploadUrl']);
|
||||
$this->ulToken = $data['authorizationToken'];
|
||||
|
||||
//var_dump($data);
|
||||
}
|
||||
|
||||
function download($hash)
|
||||
{
|
||||
if(file_exists(ROOT.DS.'upload'.DS.$hash.DS.$hash)) return false;
|
||||
$download_url = $this->dlURL; // From b2_authorize_account call
|
||||
$bucket_name = $this->bucket_name; // The NAME of the bucket you want to download from
|
||||
$file_name = $hash; // The name of the file you want to download
|
||||
$auth_token = $this->token; // From b2_authorize_account call
|
||||
$uri = $download_url . "/file/" . $bucket_name . "/" . $file_name;
|
||||
|
||||
$session = curl_init($uri);
|
||||
|
||||
// Add headers
|
||||
$headers = array();
|
||||
$headers[] = "Authorization: " . $auth_token;
|
||||
curl_setopt($session, CURLOPT_HTTPHEADER, $headers);
|
||||
|
||||
curl_setopt($session, CURLOPT_HTTPGET, true); // HTTP POST
|
||||
curl_setopt($session, CURLOPT_RETURNTRANSFER, true); // Receive server response
|
||||
$server_output = curl_exec($session); // Let's do this!
|
||||
curl_close ($session); // Clean up
|
||||
$is_binary = preg_match('~[^\x20-\x7E\t\r\n]~', $server_output); // Tell me about the rabbits, George!
|
||||
if(!$is_binary) return false;
|
||||
|
||||
mkdir(ROOT.DS.'upload'.DS.$hash);
|
||||
$file = ROOT.DS.'upload'.DS.$hash.DS.$hash;
|
||||
|
||||
file_put_contents($file, $server_output);
|
||||
return true;
|
||||
}
|
||||
|
||||
function bucketIdToName($bucket)
|
||||
{
|
||||
$api_url = $this->apiURL; // From b2_authorize_account call
|
||||
$auth_token = $this->token; // From b2_authorize_account call
|
||||
$account_id = BACKBLAZE_ID;
|
||||
|
||||
$session = curl_init($api_url . "/b2api/v1/b2_list_buckets");
|
||||
|
||||
// Add post fields
|
||||
$data = array("accountId" => $account_id);
|
||||
$post_fields = json_encode($data);
|
||||
curl_setopt($session, CURLOPT_POSTFIELDS, $post_fields);
|
||||
|
||||
// Add headers
|
||||
$headers = array();
|
||||
$headers[] = "Authorization: " . $auth_token;
|
||||
curl_setopt($session, CURLOPT_HTTPHEADER, $headers);
|
||||
|
||||
curl_setopt($session, CURLOPT_POST, true); // HTTP POST
|
||||
curl_setopt($session, CURLOPT_RETURNTRANSFER, true); // Receive server response
|
||||
$server_output = curl_exec($session); // Let's do this!
|
||||
curl_close ($session); // Clean up
|
||||
$data = json_decode($server_output,true); // Tell me about the rabbits, George!
|
||||
if(is_array($data))
|
||||
foreach($data['buckets'] as $bucket)
|
||||
{
|
||||
if($bucket['bucketId']==$this->bucket) return $bucket['bucketName'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function deleteFile($hash,$file_id=false)
|
||||
{
|
||||
$api_url = $this->apiURL; // From b2_authorize_account call
|
||||
$auth_token = $this->token; // From b2_authorize_account call
|
||||
$file_name = $hash; // The file name of the file you want to delete
|
||||
if(!$file_id)
|
||||
$file_id = $this->fileExistsInBucket($hash);
|
||||
|
||||
$session = curl_init($api_url . "/b2api/v1/b2_delete_file_version");
|
||||
|
||||
// Add post fields
|
||||
$data = array("fileId" => $file_id, "fileName" => $file_name);
|
||||
$post_fields = json_encode($data);
|
||||
curl_setopt($session, CURLOPT_POSTFIELDS, $post_fields);
|
||||
|
||||
// Add headers
|
||||
$headers = array();
|
||||
$headers[] = "Authorization: " . $auth_token;
|
||||
curl_setopt($session, CURLOPT_HTTPHEADER, $headers);
|
||||
|
||||
curl_setopt($session, CURLOPT_POST, true); // HTTP POST
|
||||
curl_setopt($session, CURLOPT_RETURNTRANSFER, true); // Receive server response
|
||||
$server_output = curl_exec($session); // Let's do this!
|
||||
curl_close ($session); // Clean up
|
||||
}
|
||||
|
||||
function fileExistsInBucket($hash)
|
||||
{
|
||||
$api_url = $this->apiURL; // From b2_authorize_account call
|
||||
$auth_token = $this->token; // From b2_authorize_account call
|
||||
$bucket_id = $this->bucket; // The ID of the bucket
|
||||
|
||||
$session = curl_init($api_url . "/b2api/v1/b2_list_file_names");
|
||||
|
||||
// Add post fields
|
||||
$data = array("bucketId" => $bucket_id,
|
||||
"startFileName" => $hash);
|
||||
$post_fields = json_encode($data);
|
||||
curl_setopt($session, CURLOPT_POSTFIELDS, $post_fields);
|
||||
|
||||
// Add headers
|
||||
$headers = array();
|
||||
$headers[] = "Authorization: " . $auth_token;
|
||||
curl_setopt($session, CURLOPT_HTTPHEADER, $headers);
|
||||
|
||||
curl_setopt($session, CURLOPT_POST, true); // HTTP POST
|
||||
curl_setopt($session, CURLOPT_RETURNTRANSFER, true); // Receive server response
|
||||
$server_output = curl_exec($session); // Let's do this!
|
||||
curl_close ($session); // Clean up
|
||||
$data = json_decode($server_output,true);
|
||||
|
||||
foreach($data['files'] as $file)
|
||||
{
|
||||
//it's either the first one or it doesn't exist
|
||||
if($file['fileName']==$hash)
|
||||
return $file['fileId'];
|
||||
else return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function getAllFilesInBucket($startFileName=null)
|
||||
{
|
||||
$api_url = $this->apiURL; // From b2_authorize_account call
|
||||
$auth_token = $this->token; // From b2_authorize_account call
|
||||
$bucket_id = $this->bucket; // The ID of the bucket
|
||||
|
||||
$session = curl_init($api_url . "/b2api/v1/b2_list_file_names");
|
||||
|
||||
// Add post fields
|
||||
$data = array("bucketId" => $bucket_id,
|
||||
"startFileName" => $startFileName);
|
||||
$post_fields = json_encode($data);
|
||||
curl_setopt($session, CURLOPT_POSTFIELDS, $post_fields);
|
||||
|
||||
// Add headers
|
||||
$headers = array();
|
||||
$headers[] = "Authorization: " . $auth_token;
|
||||
curl_setopt($session, CURLOPT_HTTPHEADER, $headers);
|
||||
|
||||
curl_setopt($session, CURLOPT_POST, true); // HTTP POST
|
||||
curl_setopt($session, CURLOPT_RETURNTRANSFER, true); // Receive server response
|
||||
$server_output = curl_exec($session); // Let's do this!
|
||||
curl_close ($session); // Clean up
|
||||
$data = json_decode($server_output,true);
|
||||
|
||||
foreach($data['files'] as $file)
|
||||
{
|
||||
$name = $file['fileName'];
|
||||
$id = $file['fileId'];
|
||||
$this->files[$name] = $id;
|
||||
}
|
||||
|
||||
if($data['nextFileName'])
|
||||
$this->getAllFilesInBucket($data['nextFileName']);
|
||||
|
||||
return $this->files;
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
<?php
|
||||
|
||||
class Crypto
|
||||
{
|
||||
function encrypt($inputfile,$outputfile)
|
||||
{
|
||||
if(!file_exists($inputfile)) return;
|
||||
$data = base64_encode(file_get_contents($inputfile));
|
||||
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
|
||||
$ciphertext = sodium_crypto_secretbox($data, $nonce, ENCRYPTION_KEY);
|
||||
$encoded = base64_encode($nonce . $ciphertext);
|
||||
file_put_contents($outputfile,$encoded);
|
||||
}
|
||||
|
||||
function decrypt($inputfile,$outputfile)
|
||||
{
|
||||
if(!file_exists($inputfile)) return;
|
||||
$decoded = base64_decode(file_get_contents($inputfile));
|
||||
$nonce = mb_substr($decoded, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
|
||||
$ciphertext = mb_substr($decoded, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');
|
||||
$plaintext = sodium_crypto_secretbox_open($ciphertext, $nonce, ENCRYPTION_KEY);
|
||||
file_put_contents($outputfile,base64_decode($plaintext));
|
||||
}
|
||||
}
|
||||
@@ -1,220 +0,0 @@
|
||||
<?php
|
||||
|
||||
class Filter
|
||||
{
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
|
||||
private $image;
|
||||
|
||||
/**
|
||||
* Directory for image assets.
|
||||
* @var string
|
||||
*/
|
||||
|
||||
private $assetDirectory;
|
||||
|
||||
/**
|
||||
* run constructor
|
||||
* @param resource &$image GD image resource
|
||||
*/
|
||||
|
||||
public function __construct(&$image)
|
||||
{
|
||||
$this->image = $image;
|
||||
|
||||
$this->assetDirectory = dirname(dirname(dirname(__FILE__))) . '/assets/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current image resource
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
|
||||
public function getImage()
|
||||
{
|
||||
return $this->image;
|
||||
}
|
||||
|
||||
public function bubbles()
|
||||
{
|
||||
$dest = imagecreatefromjpeg($this->assetDirectory . "pattern4.jpg");
|
||||
|
||||
$x = imagesx($this->image);
|
||||
$y = imagesy($this->image);
|
||||
|
||||
$x2 = imagesx($dest);
|
||||
$y2 = imagesy($dest);
|
||||
|
||||
$thumb = imagecreatetruecolor($x, $y);
|
||||
imagecopyresampled($thumb, $dest, 0, 0, 0, 0, $x, $y, $x2, $y2);
|
||||
|
||||
imagecopymerge($this->image, $thumb, 0, 0, 0, 0, $x, $y, 20);
|
||||
imagefilter($this->image, IMG_FILTER_BRIGHTNESS, 40);
|
||||
imagefilter($this->image, IMG_FILTER_CONTRAST, -10);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function colorise()
|
||||
{
|
||||
$dest = imagecreatefromjpeg($this->assetDirectory . "pattern5.jpg");
|
||||
|
||||
$x = imagesx($this->image);
|
||||
$y = imagesy($this->image);
|
||||
|
||||
$x2 = imagesx($dest);
|
||||
$y2 = imagesy($dest);
|
||||
|
||||
$thumb = imagecreatetruecolor($x, $y);
|
||||
imagecopyresampled($thumb, $dest, 0, 0, 0, 0, $x, $y, $x2, $y2);
|
||||
|
||||
imagecopymerge($this->image, $thumb, 0, 0, 0, 0, $x, $y, 40);
|
||||
imagefilter($this->image, IMG_FILTER_CONTRAST, -25);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function sepia()
|
||||
{
|
||||
imagefilter($this->image, IMG_FILTER_GRAYSCALE);
|
||||
imagefilter($this->image, IMG_FILTER_COLORIZE, 100, 50, 0);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function sharpen()
|
||||
{
|
||||
$gaussian = array(
|
||||
array(1.0, 1.0, 1.0),
|
||||
array(1.0, -7.0, 1.0),
|
||||
array(1.0, 1.0, 1.0)
|
||||
);
|
||||
imageconvolution($this->image, $gaussian, 1, 4);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function emboss()
|
||||
{
|
||||
$gaussian = array(
|
||||
array(-2.0, -1.0, 0.0),
|
||||
array(-1.0, 1.0, 1.0),
|
||||
array(0.0, 1.0, 2.0)
|
||||
);
|
||||
|
||||
imageconvolution($this->image, $gaussian, 1, 5);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function cool()
|
||||
{
|
||||
imagefilter($this->image, IMG_FILTER_MEAN_REMOVAL);
|
||||
imagefilter($this->image, IMG_FILTER_CONTRAST, -50);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function old2()
|
||||
{
|
||||
$dest = imagecreatefromjpeg($this->assetDirectory . "pattern1.jpg");
|
||||
|
||||
$x = imagesx($this->image);
|
||||
$y = imagesy($this->image);
|
||||
|
||||
$x2 = imagesx($dest);
|
||||
$y2 = imagesy($dest);
|
||||
|
||||
$thumb = imagecreatetruecolor($x, $y);
|
||||
imagecopyresampled($thumb, $dest, 0, 0, 0, 0, $x, $y, $x2, $y2);
|
||||
|
||||
imagecopymerge($this->image, $thumb, 0, 0, 0, 0, $x, $y, 40);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function old3()
|
||||
{
|
||||
imagefilter($this->image, IMG_FILTER_CONTRAST, -30);
|
||||
|
||||
$dest = imagecreatefromjpeg($this->assetDirectory . "pattern3.jpg");
|
||||
|
||||
$x = imagesx($this->image);
|
||||
$y = imagesy($this->image);
|
||||
|
||||
$x2 = imagesx($dest);
|
||||
$y2 = imagesy($dest);
|
||||
|
||||
$thumb = imagecreatetruecolor($x, $y);
|
||||
imagecopyresampled($thumb, $dest, 0, 0, 0, 0, $x, $y, $x2, $y2);
|
||||
|
||||
imagecopymerge($this->image, $thumb, 0, 0, 0, 0, $x, $y, 50);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function old()
|
||||
{
|
||||
$dest = imagecreatefromjpeg($this->assetDirectory . "bg1.jpg");
|
||||
|
||||
$x = imagesx($this->image);
|
||||
$y = imagesy($this->image);
|
||||
|
||||
$x2 = imagesx($dest);
|
||||
$y2 = imagesy($dest);
|
||||
|
||||
$thumb = imagecreatetruecolor($x, $y);
|
||||
imagecopyresampled($thumb, $dest, 0, 0, 0, 0, $x, $y, $x2, $y2);
|
||||
|
||||
imagecopymerge($this->image, $thumb, 0, 0, 0, 0, $x, $y, 30);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function light()
|
||||
{
|
||||
imagefilter($this->image, IMG_FILTER_BRIGHTNESS, 10);
|
||||
imagefilter($this->image, IMG_FILTER_COLORIZE, 100, 50, 0, 10);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function aqua()
|
||||
{
|
||||
imagefilter($this->image, IMG_FILTER_COLORIZE, 0, 70, 0, 30);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function fuzzy()
|
||||
{
|
||||
$gaussian = array(
|
||||
array(1.0, 1.0, 1.0),
|
||||
array(1.0, 1.0, 1.0),
|
||||
array(1.0, 1.0, 1.0)
|
||||
);
|
||||
|
||||
imageconvolution($this->image, $gaussian, 9, 20);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function boost()
|
||||
{
|
||||
imagefilter($this->image, IMG_FILTER_CONTRAST, -35);
|
||||
imagefilter($this->image, IMG_FILTER_BRIGHTNESS, 10);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function gray()
|
||||
{
|
||||
imagefilter($this->image, IMG_FILTER_CONTRAST, -60);
|
||||
imagefilter($this->image, IMG_FILTER_GRAYSCALE);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
<?php
|
||||
|
||||
class HTML {
|
||||
|
||||
/*
|
||||
* Characters that will pass:
|
||||
* a-z
|
||||
* A-Z
|
||||
* 0-9
|
||||
* .
|
||||
* _
|
||||
* -
|
||||
*/
|
||||
function sanatizeString($string)
|
||||
{
|
||||
return preg_replace("/[^a-zA-Z0-9._\-]+/", "", $string);
|
||||
}
|
||||
|
||||
function renderSize($byte)
|
||||
{
|
||||
if($byte < 1024) {
|
||||
$result = round($byte, 2). ' Byte';
|
||||
}elseif($byte < pow(1024, 2)) {
|
||||
$result = round($byte/1024, 2).' KB';
|
||||
}elseif($byte >= pow(1024, 2) and $byte < pow(1024, 3)) {
|
||||
$result = round($byte/pow(1024, 2), 2).' MB';
|
||||
}elseif($byte >= pow(1024, 3) and $byte < pow(1024, 4)) {
|
||||
$result = round($byte/pow(1024, 3), 2).' GB';
|
||||
}elseif($byte >= pow(1024, 4) and $byte < pow(1024, 5)) {
|
||||
$result = round($byte/pow(1024, 4), 2).' TB';
|
||||
}elseif($byte >= pow(1024, 5) and $byte < pow(1024, 6)) {
|
||||
$result = round($byte/pow(1024, 5), 2).' PB';
|
||||
}elseif($byte >= pow(1024, 6) and $byte < pow(1024, 7)) {
|
||||
$result = round($byte/pow(1024, 6), 2).' EB';
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,215 +0,0 @@
|
||||
<?php
|
||||
|
||||
class Image
|
||||
{
|
||||
function rotate(&$im,$direction)
|
||||
{
|
||||
switch($direction)
|
||||
{
|
||||
case 'upside': $angle = 180;break;
|
||||
case 'left': $angle = 90;break;
|
||||
case 'right': $angle = -90;break;
|
||||
default: $angle = 0;break;
|
||||
}
|
||||
|
||||
$im = imagerotate($im,$angle,0);
|
||||
}
|
||||
|
||||
function forceResize(&$img,$size)
|
||||
{
|
||||
$pm = new PictshareModel();
|
||||
|
||||
$sd = $pm->sizeStringToWidthHeight($size);
|
||||
$maxwidth = $sd['width'];
|
||||
$maxheight = $sd['height'];
|
||||
|
||||
|
||||
|
||||
$width = imagesx($img);
|
||||
$height = imagesy($img);
|
||||
|
||||
$maxwidth = ($maxwidth>$width?$width:$maxwidth);
|
||||
$maxheight = ($maxheight>$height?$height:$maxheight);
|
||||
|
||||
|
||||
$dst_img = imagecreatetruecolor($maxwidth, $maxheight);
|
||||
$src_img = $img;
|
||||
|
||||
$palsize = ImageColorsTotal($img);
|
||||
for ($i = 0; $i < $palsize; $i++)
|
||||
{
|
||||
$colors = ImageColorsForIndex($img, $i);
|
||||
ImageColorAllocate($dst_img, $colors['red'], $colors['green'], $colors['blue']);
|
||||
}
|
||||
|
||||
imagefill($dst_img, 0, 0, IMG_COLOR_TRANSPARENT);
|
||||
imagesavealpha($dst_img,true);
|
||||
imagealphablending($dst_img, true);
|
||||
|
||||
$width_new = $height * $maxwidth / $maxheight;
|
||||
$height_new = $width * $maxheight / $maxwidth;
|
||||
//if the new width is greater than the actual width of the image, then the height is too large and the rest cut off, or vice versa
|
||||
if($width_new > $width){
|
||||
//cut point by height
|
||||
$h_point = (($height - $height_new) / 2);
|
||||
//copy image
|
||||
imagecopyresampled($dst_img, $src_img, 0, 0, 0, $h_point, $maxwidth, $maxheight, $width, $height_new);
|
||||
}else{
|
||||
//cut point by width
|
||||
$w_point = (($width - $width_new) / 2);
|
||||
imagecopyresampled($dst_img, $src_img, 0, 0, $w_point, 0, $maxwidth, $maxheight, $width_new, $height);
|
||||
}
|
||||
|
||||
$img = $dst_img;
|
||||
}
|
||||
|
||||
/**
|
||||
* From: https://stackoverflow.com/questions/4590441/php-thumbnail-image-resizing-with-proportions
|
||||
*/
|
||||
function resize(&$img,$size)
|
||||
{
|
||||
$pm = new PictshareModel();
|
||||
|
||||
$sd = $pm->sizeStringToWidthHeight($size);
|
||||
$maxwidth = $sd['width'];
|
||||
$maxheight = $sd['height'];
|
||||
|
||||
$width = imagesx($img);
|
||||
$height = imagesy($img);
|
||||
|
||||
if(!ALLOW_BLOATING)
|
||||
{
|
||||
if($maxwidth>$width)$maxwidth = $width;
|
||||
if($maxheight>$height)$maxheight = $height;
|
||||
}
|
||||
|
||||
if ($height > $width)
|
||||
{
|
||||
$ratio = $maxheight / $height;
|
||||
$newheight = $maxheight;
|
||||
$newwidth = $width * $ratio;
|
||||
}
|
||||
else
|
||||
{
|
||||
$ratio = $maxwidth / $width;
|
||||
$newwidth = $maxwidth;
|
||||
$newheight = $height * $ratio;
|
||||
}
|
||||
|
||||
$newimg = imagecreatetruecolor($newwidth,$newheight);
|
||||
|
||||
$palsize = ImageColorsTotal($img);
|
||||
for ($i = 0; $i < $palsize; $i++)
|
||||
{
|
||||
$colors = ImageColorsForIndex($img, $i);
|
||||
ImageColorAllocate($newimg, $colors['red'], $colors['green'], $colors['blue']);
|
||||
}
|
||||
|
||||
imagefill($newimg, 0, 0, IMG_COLOR_TRANSPARENT);
|
||||
imagesavealpha($newimg,true);
|
||||
imagealphablending($newimg, true);
|
||||
|
||||
imagecopyresampled($newimg, $img, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
|
||||
|
||||
$img = $newimg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strong Blur
|
||||
*
|
||||
* @param resource $gdImageResource
|
||||
* @param int $blurFactor optional
|
||||
* This is the strength of the blur
|
||||
* 0 = no blur, 3 = default, anything over 5 is extremely blurred
|
||||
* @return GD image resource
|
||||
* @author Martijn Frazer, idea based on http://stackoverflow.com/a/20264482
|
||||
*/
|
||||
function blur(&$gdImageResource, $blurFactor = 3)
|
||||
{
|
||||
if(!$blurFactor)
|
||||
$blurFactor = 3;
|
||||
if($blurFactor>6)
|
||||
$blurFactor = 6;
|
||||
else if($blurFactor<0)
|
||||
$blurFactor = 0;
|
||||
// blurFactor has to be an integer
|
||||
$blurFactor = round($blurFactor);
|
||||
|
||||
$originalWidth = imagesx($gdImageResource);
|
||||
$originalHeight = imagesy($gdImageResource);
|
||||
|
||||
$smallestWidth = ceil($originalWidth * pow(0.5, $blurFactor));
|
||||
$smallestHeight = ceil($originalHeight * pow(0.5, $blurFactor));
|
||||
|
||||
// for the first run, the previous image is the original input
|
||||
$prevImage = $gdImageResource;
|
||||
$prevWidth = $originalWidth;
|
||||
$prevHeight = $originalHeight;
|
||||
|
||||
// scale way down and gradually scale back up, blurring all the way
|
||||
for($i = 0; $i < $blurFactor; $i += 1)
|
||||
{
|
||||
// determine dimensions of next image
|
||||
$nextWidth = $smallestWidth * pow(2, $i);
|
||||
$nextHeight = $smallestHeight * pow(2, $i);
|
||||
|
||||
// resize previous image to next size
|
||||
$nextImage = imagecreatetruecolor($nextWidth, $nextHeight);
|
||||
imagecopyresized($nextImage, $prevImage, 0, 0, 0, 0,
|
||||
$nextWidth, $nextHeight, $prevWidth, $prevHeight);
|
||||
|
||||
// apply blur filter
|
||||
imagefilter($nextImage, IMG_FILTER_GAUSSIAN_BLUR);
|
||||
|
||||
// now the new image becomes the previous image for the next step
|
||||
$prevImage = $nextImage;
|
||||
$prevWidth = $nextWidth;
|
||||
$prevHeight = $nextHeight;
|
||||
}
|
||||
|
||||
// scale back to original size and blur one more time
|
||||
imagecopyresized($gdImageResource, $nextImage,
|
||||
0, 0, 0, 0, $originalWidth, $originalHeight, $nextWidth, $nextHeight);
|
||||
imagefilter($gdImageResource, IMG_FILTER_GAUSSIAN_BLUR);
|
||||
|
||||
// clean up
|
||||
imagedestroy($prevImage);
|
||||
|
||||
// return result
|
||||
return $gdImageResource;
|
||||
}
|
||||
|
||||
function filter(&$im,$vars)
|
||||
{
|
||||
|
||||
foreach($vars as $var)
|
||||
{
|
||||
if(strpos($var,'_'))
|
||||
{
|
||||
$a = explode('_',$var);
|
||||
$var = $a[0];
|
||||
$val = $a[1];
|
||||
}
|
||||
switch($var)
|
||||
{
|
||||
case 'negative': imagefilter($im,IMG_FILTER_NEGATE); break;
|
||||
case 'grayscale': imagefilter($im,IMG_FILTER_GRAYSCALE); break;
|
||||
case 'brightness': imagefilter($im,IMG_FILTER_BRIGHTNESS,$val); break;
|
||||
case 'edgedetect': imagefilter($im,IMG_FILTER_EDGEDETECT); break;
|
||||
case 'smooth': imagefilter($im,IMG_FILTER_SMOOTH,$val); break;
|
||||
case 'contrast': imagefilter($im,IMG_FILTER_CONTRAST,$val); break;
|
||||
case 'pixelate': imagefilter($im,IMG_FILTER_PIXELATE,$val); break;
|
||||
case 'blur': $this->blur($im,$val); break;
|
||||
case 'sepia': (new Filter($im))->sepia()->getImage();break;
|
||||
case 'sharpen':(new Filter($im))->sharpen()->getImage();break;
|
||||
case 'emboss':(new Filter($im))->emboss()->getImage();break;
|
||||
case 'cool':(new Filter($im))->cool()->getImage();break;
|
||||
case 'light':(new Filter($im))->light()->getImage();break;
|
||||
case 'aqua':(new Filter($im))->aqua()->getImage();break;
|
||||
case 'fuzzy':(new Filter($im))->fuzzy()->getImage();break;
|
||||
case 'boost':(new Filter($im))->boost()->getImage();break;
|
||||
case 'gray':(new Filter($im))->gray()->getImage();break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Model class for all models
|
||||
*
|
||||
* @author Christian
|
||||
*/
|
||||
class Model// extends SQLQuery
|
||||
{
|
||||
protected $_model;
|
||||
|
||||
function __construct($id=0)
|
||||
{
|
||||
$this->_model = substr(get_class($this),0,-5);
|
||||
$this->_table = strtolower($this->_model);
|
||||
$this->_id = $id;
|
||||
}
|
||||
|
||||
function __destruct()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
29
cli.php
29
cli.php
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
define('DS', DIRECTORY_SEPARATOR);
|
||||
define('ROOT', dirname(__FILE__));
|
||||
define('CLI', true);
|
||||
define('PATH',((dirname($_SERVER['PHP_SELF'])=='/'||dirname($_SERVER['PHP_SELF'])=='\\'||dirname($_SERVER['PHP_SELF'])=='/index.php'||dirname($_SERVER['PHP_SELF'])=='/backend.php')?'/':dirname($_SERVER['PHP_SELF']).'/'));
|
||||
|
||||
if(!file_exists(ROOT.DS.'inc'.DS.'config.inc.php'))
|
||||
exit('Rename /inc/example.config.inc.php to /inc/config.inc.php first!');
|
||||
include_once(ROOT.DS.'inc'.DS.'config.inc.php');
|
||||
|
||||
if(FORCE_DOMAIN)
|
||||
define('DOMAINPATH',FORCE_DOMAIN);
|
||||
else
|
||||
define('DOMAINPATH',(isset($_SERVER['HTTPS'])?'https':'http').'://'.$_SERVER['HTTP_HOST']);
|
||||
error_reporting(E_ALL & ~E_NOTICE);
|
||||
if(SHOW_ERRORS)
|
||||
ini_set('display_errors','On');
|
||||
else ini_set('display_errors','Off');
|
||||
include_once(ROOT.DS.'inc'.DS.'core.php');
|
||||
|
||||
$action = $argv[2];
|
||||
$params = $argv;
|
||||
|
||||
//lose first param (self name)
|
||||
array_shift($params);
|
||||
|
||||
$model = new PictshareModel();
|
||||
$model->backend($params);
|
||||
38
content-controllers/identicon/identicon.controller.php
Normal file
38
content-controllers/identicon/identicon.controller.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
use Bitverse\Identicon\Identicon;
|
||||
use Bitverse\Identicon\Color\Color;
|
||||
use Bitverse\Identicon\Generator\RingsGenerator;
|
||||
use Bitverse\Identicon\Preprocessor\MD5Preprocessor;
|
||||
|
||||
class IdenticonController implements ContentController
|
||||
{
|
||||
public const ctype = 'dynamic';
|
||||
|
||||
//returns all extensions registered by this type of content
|
||||
public function getRegisteredExtensions(){return array('identicon');}
|
||||
|
||||
public function handleHash($hash,$url)
|
||||
{
|
||||
unset($url[array_search('identicon',$url)]);
|
||||
$url = array_values($url);
|
||||
|
||||
|
||||
$generator = new RingsGenerator();
|
||||
$generator->setBackgroundColor(Color::parseHex('#EEEEEE'));
|
||||
|
||||
$identicon = new Identicon(new MD5Preprocessor(), $generator);
|
||||
|
||||
$icon = $identicon->getIcon($url[0]);
|
||||
|
||||
header('Content-type: image/svg+xml');
|
||||
echo $icon;
|
||||
}
|
||||
|
||||
public function handleUpload($tmpfile,$hash=false)
|
||||
{
|
||||
return array('status'=>'err','hash'=>$hash,'reason'=>'Cannot upload to Identicons');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
0
content-controllers/image/conversion.php
Normal file
0
content-controllers/image/conversion.php
Normal file
278
content-controllers/image/filters.php
Normal file
278
content-controllers/image/filters.php
Normal file
@@ -0,0 +1,278 @@
|
||||
<?php
|
||||
|
||||
function getFilters()
|
||||
{
|
||||
return get_class_methods('Filter');
|
||||
}
|
||||
|
||||
class Filter {
|
||||
public function sepia($im,$val) {
|
||||
|
||||
imagefilter($im, IMG_FILTER_GRAYSCALE);
|
||||
imagefilter($im, IMG_FILTER_COLORIZE, 100, 50, 0);
|
||||
|
||||
return $im;
|
||||
}
|
||||
public function sepia2($im,$val) {
|
||||
imagefilter($im, IMG_FILTER_GRAYSCALE);
|
||||
imagefilter($im, IMG_FILTER_BRIGHTNESS, -10);
|
||||
imagefilter($im, IMG_FILTER_CONTRAST, -20);
|
||||
imagefilter($im, IMG_FILTER_COLORIZE, 60, 30, -15);
|
||||
return $im;
|
||||
}
|
||||
public function sharpen($im,$val) {
|
||||
|
||||
$gaussian = array(
|
||||
array(1.0, 1.0, 1.0),
|
||||
array(1.0, -7.0, 1.0),
|
||||
array(1.0, 1.0, 1.0)
|
||||
);
|
||||
imageconvolution($im, $gaussian, 1, 4);
|
||||
|
||||
return $im;
|
||||
}
|
||||
public function emboss($im,$val) {
|
||||
|
||||
$gaussian = array(
|
||||
array(-2.0, -1.0, 0.0),
|
||||
array(-1.0, 1.0, 1.0),
|
||||
array(0.0, 1.0, 2.0)
|
||||
);
|
||||
|
||||
imageconvolution($im, $gaussian, 1, 5);
|
||||
|
||||
return $im;
|
||||
}
|
||||
public function cool($im,$val) {
|
||||
|
||||
imagefilter($im, IMG_FILTER_MEAN_REMOVAL);
|
||||
imagefilter($im, IMG_FILTER_CONTRAST, -50);
|
||||
|
||||
return $im;
|
||||
}
|
||||
public function light($im,$val) {
|
||||
|
||||
imagefilter($im, IMG_FILTER_BRIGHTNESS, 10);
|
||||
imagefilter($im, IMG_FILTER_COLORIZE, 100, 50, 0, 10);
|
||||
|
||||
return $im;
|
||||
}
|
||||
public function aqua($im,$val) {
|
||||
|
||||
imagefilter($im, IMG_FILTER_COLORIZE, 0, 70, 0, 30);
|
||||
|
||||
return $im;
|
||||
}
|
||||
public function fuzzy($im,$val) {
|
||||
|
||||
$gaussian = array(
|
||||
array(1.0, 1.0, 1.0),
|
||||
array(1.0, 1.0, 1.0),
|
||||
array(1.0, 1.0, 1.0)
|
||||
);
|
||||
imageconvolution($im, $gaussian, 9, 20);
|
||||
|
||||
return $im;
|
||||
}
|
||||
public function boost($im,$val) {
|
||||
|
||||
imagefilter($im, IMG_FILTER_CONTRAST, -35);
|
||||
imagefilter($im, IMG_FILTER_BRIGHTNESS, 10);
|
||||
|
||||
return $im;
|
||||
}
|
||||
public function boost2($im,$val) {
|
||||
imagefilter( $im, IMG_FILTER_CONTRAST, -35);
|
||||
imagefilter( $im, IMG_FILTER_COLORIZE, 25, 25, 25);
|
||||
return $im;
|
||||
}
|
||||
public function gray($im,$val) {
|
||||
|
||||
imagefilter($im, IMG_FILTER_CONTRAST, -60);
|
||||
imagefilter($im, IMG_FILTER_GRAYSCALE);
|
||||
|
||||
return $im;
|
||||
}
|
||||
public function antique($im,$val) {
|
||||
imagefilter($im, IMG_FILTER_BRIGHTNESS, 0);
|
||||
imagefilter($im, IMG_FILTER_CONTRAST, -30);
|
||||
imagefilter($im, IMG_FILTER_COLORIZE, 75, 50, 25);
|
||||
return $im;
|
||||
}
|
||||
public function blackwhite($im,$val) {
|
||||
imagefilter($im, IMG_FILTER_GRAYSCALE);
|
||||
imagefilter($im, IMG_FILTER_BRIGHTNESS, 10);
|
||||
imagefilter($im, IMG_FILTER_CONTRAST, -20);
|
||||
return $im;
|
||||
}
|
||||
public function vintage($im,$val) {
|
||||
imagefilter($im, IMG_FILTER_BRIGHTNESS, 10);
|
||||
imagefilter($im, IMG_FILTER_GRAYSCALE);
|
||||
imagefilter($im, IMG_FILTER_COLORIZE, 40, 10, -15);
|
||||
return $im;
|
||||
}
|
||||
|
||||
public function concentrate($im,$val) {
|
||||
imagefilter($im, IMG_FILTER_GAUSSIAN_BLUR);
|
||||
imagefilter($im, IMG_FILTER_SMOOTH, -10);
|
||||
return $im;
|
||||
}
|
||||
|
||||
public function hermajesty($im,$val) {
|
||||
imagefilter($im, IMG_FILTER_BRIGHTNESS, -10);
|
||||
imagefilter($im, IMG_FILTER_CONTRAST, -5);
|
||||
imagefilter($im, IMG_FILTER_COLORIZE, 80, 0, 60);
|
||||
return $im;
|
||||
}
|
||||
public function everglow($im,$val) {
|
||||
imagefilter($im, IMG_FILTER_BRIGHTNESS, -30);
|
||||
imagefilter($im, IMG_FILTER_CONTRAST, -5);
|
||||
imagefilter($im, IMG_FILTER_COLORIZE, 30, 30, 0);
|
||||
return $im;
|
||||
}
|
||||
public function freshblue($im,$val) {
|
||||
imagefilter($im, IMG_FILTER_CONTRAST, -5);
|
||||
imagefilter($im, IMG_FILTER_COLORIZE, 20, 0, 80, 60);
|
||||
return $im;
|
||||
}
|
||||
public function tender($im,$val) {
|
||||
imagefilter($im, IMG_FILTER_CONTRAST, 5);
|
||||
imagefilter($im, IMG_FILTER_COLORIZE, 80, 20, 40, 50);
|
||||
imagefilter($im, IMG_FILTER_COLORIZE, 0, 40, 40, 100);
|
||||
imagefilter($im, IMG_FILTER_SELECTIVE_BLUR);
|
||||
return $im;
|
||||
}
|
||||
public function dream($im,$val) {
|
||||
imagefilter($im, IMG_FILTER_COLORIZE, 150, 0, 0, 50);
|
||||
imagefilter($im, IMG_FILTER_NEGATE);
|
||||
imagefilter($im, IMG_FILTER_COLORIZE, 0, 50, 0, 50);
|
||||
imagefilter($im, IMG_FILTER_NEGATE);
|
||||
imagefilter($im, IMG_FILTER_GAUSSIAN_BLUR);
|
||||
return $im;
|
||||
}
|
||||
public function frozen($im,$val) {
|
||||
imagefilter($im, IMG_FILTER_BRIGHTNESS, -15);
|
||||
imagefilter($im, IMG_FILTER_COLORIZE, 0, 0, 100, 50);
|
||||
imagefilter($im, IMG_FILTER_COLORIZE, 0, 0, 100, 50);
|
||||
imagefilter($im, IMG_FILTER_GAUSSIAN_BLUR);
|
||||
return $im;
|
||||
}
|
||||
public function forest($im,$val) {
|
||||
imagefilter($im, IMG_FILTER_COLORIZE, 0, 0, 150, 50);
|
||||
imagefilter($im, IMG_FILTER_NEGATE);
|
||||
imagefilter($im, IMG_FILTER_COLORIZE, 0, 0, 150, 50);
|
||||
imagefilter($im, IMG_FILTER_NEGATE);
|
||||
imagefilter($im, IMG_FILTER_SMOOTH, 10);
|
||||
return $im;
|
||||
}
|
||||
public function rain($im,$val) {
|
||||
imagefilter($im, IMG_FILTER_GAUSSIAN_BLUR);
|
||||
imagefilter($im, IMG_FILTER_MEAN_REMOVAL);
|
||||
imagefilter($im, IMG_FILTER_NEGATE);
|
||||
imagefilter($im, IMG_FILTER_COLORIZE, 0, 80, 50, 50);
|
||||
imagefilter($im, IMG_FILTER_NEGATE);
|
||||
imagefilter($im, IMG_FILTER_SMOOTH, 10);
|
||||
return $im;
|
||||
}
|
||||
public function orangepeel($im,$val) {
|
||||
imagefilter($im, IMG_FILTER_COLORIZE, 100, 20, -50, 20);
|
||||
imagefilter($im, IMG_FILTER_SMOOTH, 10);
|
||||
imagefilter($im, IMG_FILTER_BRIGHTNESS, -10);
|
||||
imagefilter($im, IMG_FILTER_CONTRAST, 10);
|
||||
imagegammacorrect($im, 1, 1.2 );
|
||||
return $im;
|
||||
}
|
||||
public function darken($im,$val) {
|
||||
imagefilter($im, IMG_FILTER_GRAYSCALE);
|
||||
imagefilter($im, IMG_FILTER_BRIGHTNESS, -50);
|
||||
return $im;
|
||||
}
|
||||
public function summer($im,$val) {
|
||||
imagefilter($im, IMG_FILTER_COLORIZE, 0, 150, 0, 50);
|
||||
imagefilter($im, IMG_FILTER_NEGATE);
|
||||
imagefilter($im, IMG_FILTER_COLORIZE, 25, 50, 0, 50);
|
||||
imagefilter($im, IMG_FILTER_NEGATE);
|
||||
return $im;
|
||||
}
|
||||
public function retro($im,$val) {
|
||||
imagefilter($im, IMG_FILTER_GRAYSCALE);
|
||||
imagefilter($im, IMG_FILTER_COLORIZE, 100, 25, 25, 50);
|
||||
return $im;
|
||||
}
|
||||
public function country($im,$val) {
|
||||
imagefilter($im, IMG_FILTER_BRIGHTNESS, -30);
|
||||
imagefilter($im, IMG_FILTER_COLORIZE, 50, 50, 50, 50);
|
||||
imagegammacorrect($im, 1, 0.3);
|
||||
return $im;
|
||||
}
|
||||
public function washed($im,$val) {
|
||||
imagefilter($im, IMG_FILTER_BRIGHTNESS, 30);
|
||||
imagefilter($im, IMG_FILTER_NEGATE);
|
||||
imagefilter($im, IMG_FILTER_COLORIZE, -50, 0, 20, 50);
|
||||
imagefilter($im, IMG_FILTER_NEGATE );
|
||||
imagefilter($im, IMG_FILTER_BRIGHTNESS, 10);
|
||||
imagegammacorrect($im, 1, 1.2);
|
||||
return $im;
|
||||
}
|
||||
|
||||
public function pixelate($im,$val) {
|
||||
if($val==null) $val = 10;
|
||||
imagefilter($im,IMG_FILTER_PIXELATE,$val);
|
||||
return $im;
|
||||
}
|
||||
|
||||
public function blur($im,$blurFactor)
|
||||
{
|
||||
if(!$blurFactor)
|
||||
$blurFactor = 3;
|
||||
if($blurFactor>6)
|
||||
$blurFactor = 6;
|
||||
else if($blurFactor<0)
|
||||
$blurFactor = 0;
|
||||
// blurFactor has to be an integer
|
||||
$blurFactor = round($blurFactor);
|
||||
|
||||
$originalWidth = imagesx($im);
|
||||
$originalHeight = imagesy($im);
|
||||
|
||||
$smallestWidth = ceil($originalWidth * pow(0.5, $blurFactor));
|
||||
$smallestHeight = ceil($originalHeight * pow(0.5, $blurFactor));
|
||||
|
||||
// for the first run, the previous image is the original input
|
||||
$prevImage = $im;
|
||||
$prevWidth = $originalWidth;
|
||||
$prevHeight = $originalHeight;
|
||||
|
||||
// scale way down and gradually scale back up, blurring all the way
|
||||
for($i = 0; $i < $blurFactor; $i += 1)
|
||||
{
|
||||
// determine dimensions of next image
|
||||
$nextWidth = $smallestWidth * pow(2, $i);
|
||||
$nextHeight = $smallestHeight * pow(2, $i);
|
||||
|
||||
// resize previous image to next size
|
||||
$nextImage = imagecreatetruecolor($nextWidth, $nextHeight);
|
||||
imagecopyresized($nextImage, $prevImage, 0, 0, 0, 0,
|
||||
$nextWidth, $nextHeight, $prevWidth, $prevHeight);
|
||||
|
||||
// apply blur filter
|
||||
imagefilter($nextImage, IMG_FILTER_GAUSSIAN_BLUR);
|
||||
|
||||
// now the new image becomes the previous image for the next step
|
||||
$prevImage = $nextImage;
|
||||
$prevWidth = $nextWidth;
|
||||
$prevHeight = $nextHeight;
|
||||
}
|
||||
|
||||
// scale back to original size and blur one more time
|
||||
imagecopyresized($im, $nextImage,
|
||||
0, 0, 0, 0, $originalWidth, $originalHeight, $nextWidth, $nextHeight);
|
||||
imagefilter($im, IMG_FILTER_GAUSSIAN_BLUR);
|
||||
|
||||
// clean up
|
||||
imagedestroy($prevImage);
|
||||
|
||||
// return result
|
||||
return $im;
|
||||
}
|
||||
}
|
||||
330
content-controllers/image/image.controller.php
Normal file
330
content-controllers/image/image.controller.php
Normal file
@@ -0,0 +1,330 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @Todo:
|
||||
* - Resizing
|
||||
* - Filters
|
||||
* - Conversion gif to mp4
|
||||
* - Conversion jpg,png to webp
|
||||
*/
|
||||
|
||||
class ImageController implements ContentController
|
||||
{
|
||||
public const ctype = 'static';
|
||||
//returns all extensions registered by this type of content
|
||||
public function getRegisteredExtensions(){return array('png','bmp','gif','jpg','jpeg','x-png','webp');}
|
||||
|
||||
public function handleUpload($tmpfile,$hash=false)
|
||||
{
|
||||
$type = exif_imagetype($tmpfile); //http://www.php.net/manual/en/function.exif-imagetype.php
|
||||
switch($type)
|
||||
{
|
||||
case 1: $ext = 'gif';break; //gif
|
||||
case 3: $ext = 'png';break; // png
|
||||
case 6: $ext = 'bmp';break; // bmp
|
||||
case 17: $ext = 'ico';break; // ico
|
||||
case 18: $ext = 'webp';break; // webp
|
||||
|
||||
case 2:
|
||||
//we clean up exif data of JPGs so GPS and other data is removed
|
||||
$res = imagecreatefromjpeg($tmpfile);
|
||||
|
||||
// rotate based on EXIF Orientation
|
||||
$exif = exif_read_data($tmpfile);
|
||||
if (!empty($exif['Orientation'])) {
|
||||
switch ($exif['Orientation']) {
|
||||
case 2:
|
||||
imageflip($res, IMG_FLIP_HORIZONTAL);
|
||||
case 1:
|
||||
// Nothing to do
|
||||
break;
|
||||
|
||||
case 4:
|
||||
imageflip($res, IMG_FLIP_HORIZONTAL);
|
||||
// Also rotate
|
||||
case 3:
|
||||
$res = imagerotate($res, 180, 0);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
imageflip($res, IMG_FLIP_VERTICAL);
|
||||
// Also rotate
|
||||
case 6:
|
||||
$res = imagerotate($res, -90, 0);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
imageflip($res, IMG_FLIP_VERTICAL);
|
||||
// Also rotate
|
||||
case 8:
|
||||
$res = imagerotate($res, 90, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
imagejpeg($res, $tmpfile, (defined('JPEG_COMPRESSION')?JPEG_COMPRESSION:90));
|
||||
$ext = 'jpg';
|
||||
break;
|
||||
|
||||
default:
|
||||
return array('status'=>'err','reason'=>'Not a valid image');
|
||||
}
|
||||
|
||||
if($hash===false)
|
||||
{
|
||||
$hash = getNewHash($ext,6);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!endswith($hash,'.'.$ext))
|
||||
$hash.='.'.$ext;
|
||||
if(isExistingHash($hash))
|
||||
return array('status'=>'err','hash'=>$hash,'reason'=>'Custom hash already exists');
|
||||
}
|
||||
|
||||
storeFile($tmpfile,$hash,true);
|
||||
|
||||
return array('status'=>'ok','hash'=>$hash,'url'=>getURL().$hash);
|
||||
}
|
||||
|
||||
public function handleHash($hash,$url)
|
||||
{
|
||||
$path = getDataDir().DS.$hash.DS.$hash;
|
||||
$type = getExtensionOfFilename($hash);
|
||||
|
||||
//get all our sub files where all the good functions lie
|
||||
include_once(dirname(__FILE__).DS.'resize.php');
|
||||
include_once(dirname(__FILE__).DS.'filters.php');
|
||||
include_once(dirname(__FILE__).DS.'conversion.php');
|
||||
|
||||
//don't do this if it's a gif because PHP can't handle animated gifs
|
||||
if($type!='gif')
|
||||
{
|
||||
$filters = getFilters();
|
||||
foreach($url as $u)
|
||||
{
|
||||
if(isSize($u))
|
||||
$modifiers['size'] = $u;
|
||||
else if(isRotation($u))
|
||||
$modifiers['rotation'] = $u;
|
||||
else // check for filters
|
||||
{
|
||||
foreach($filters as $filter)
|
||||
{
|
||||
if(startsWith($u,$filter) && ($u==$filter || startsWith($u,$filter.'_')))
|
||||
{
|
||||
$a = explode('_',$u);
|
||||
$value = $a[1];
|
||||
if(is_numeric($value))
|
||||
$modifiers['filters'][] = array('filter'=>$filter,'value'=>$value);
|
||||
else
|
||||
$modifiers['filters'][] = array('filter'=>$filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( (in_array('webp',$url) && $type!='webp') || ( $this->shouldAlwaysBeWebp() && ($type=='jpg' || $type=='png') ) )
|
||||
$modifiers['webp'] = true;
|
||||
if(in_array('forcesize',$url) && $modifiers['size'])
|
||||
$modifiers['forcesize'] = true;
|
||||
}
|
||||
else //gif
|
||||
{
|
||||
if(in_array('mp4',$url))
|
||||
$modifiers['mp4']=true;
|
||||
}
|
||||
|
||||
if($modifiers)
|
||||
{
|
||||
//why in gods name would you use http build query here???
|
||||
//well we want a unique filename for every modied image
|
||||
//so if we take all parameters in key=>value form and hash it
|
||||
//we get one nice little hash for every eventuality
|
||||
$modhash = md5(http_build_query($modifiers,'',','));
|
||||
$newpath = getDataDir().DS.$hash.DS.$modhash.'_'.$hash;
|
||||
$im = $this->getObjOfImage($path);
|
||||
$f = new Filter();
|
||||
|
||||
if(!file_exists($newpath))
|
||||
{
|
||||
foreach($modifiers as $mod => $val)
|
||||
{
|
||||
switch($mod)
|
||||
{
|
||||
case 'filters':
|
||||
foreach($val as $fd)
|
||||
{
|
||||
$filter = $fd['filter'];
|
||||
$value = $fd['value'];
|
||||
$im = $f->$filter($im,$value);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'size':
|
||||
($modifiers['forcesize']?forceResize($im,$val):resize($im,$val));
|
||||
break;
|
||||
|
||||
case 'rotation':
|
||||
rotate($im,$val);
|
||||
break;
|
||||
|
||||
case 'webp':
|
||||
$type = 'webp';
|
||||
break;
|
||||
|
||||
case 'mp4':
|
||||
$mp4path = getDataDir().DS.$hash.DS.$hash.'mp4';
|
||||
if(!file_exists($mp4path))
|
||||
$this->gifToMP4($path,$mp4path);
|
||||
$path = $mp4path;
|
||||
|
||||
if(in_array('raw',$url))
|
||||
(new VideoController())->serveMP4($path,$hash);
|
||||
else if(in_array('preview',$url))
|
||||
{
|
||||
$preview = $path.'_preview.jpg';
|
||||
if(!file_exists($preview))
|
||||
{
|
||||
(new VideoController())->saveFirstFrameOfMP4($path,$preview);
|
||||
}
|
||||
|
||||
header ("Content-type: image/jpeg");
|
||||
readfile($preview);
|
||||
exit;
|
||||
}
|
||||
else if(in_array('download',$url))
|
||||
{
|
||||
if (file_exists($path)) {
|
||||
header('Content-Description: File Transfer');
|
||||
header('Content-Type: application/octet-stream');
|
||||
header('Content-Disposition: attachment; filename="'.basename($path).'"');
|
||||
header('Expires: 0');
|
||||
header('Cache-Control: must-revalidate');
|
||||
header('Pragma: public');
|
||||
header('Content-Length: ' . filesize($path));
|
||||
readfile($path);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$data = array('url'=>implode('/',$url),'hash'=>$hash,'filesize'=>renderSize(filesize($path)));
|
||||
renderTemplate('video',$data);
|
||||
exit;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$this->saveObjOfImage($im,$newpath,$type);
|
||||
}
|
||||
else if($modifiers['webp'])
|
||||
{
|
||||
$type = 'webp';
|
||||
}
|
||||
$path = $newpath;
|
||||
|
||||
}
|
||||
|
||||
switch($type)
|
||||
{
|
||||
case 'jpeg':
|
||||
case 'jpg':
|
||||
header ("Content-type: image/jpeg");
|
||||
header ("Last-Modified: ".gmdate('D, d M Y H:i:s ', filemtime($path)) . 'GMT');
|
||||
header ("ETag: $hash");
|
||||
header('Cache-control: public, max-age=31536000');
|
||||
readfile($path);
|
||||
break;
|
||||
|
||||
case 'png':
|
||||
header ("Content-type: image/png");
|
||||
header ("Last-Modified: ".gmdate('D, d M Y H:i:s ', filemtime($path)) . 'GMT');
|
||||
header ("ETag: $hash");
|
||||
header('Cache-control: public, max-age=31536000');
|
||||
readfile($path);
|
||||
break;
|
||||
|
||||
case 'gif':
|
||||
header ("Content-type: image/gif");
|
||||
header ("Last-Modified: ".gmdate('D, d M Y H:i:s ', filemtime($path)) . 'GMT');
|
||||
header ("ETag: $hash");
|
||||
header('Cache-control: public, max-age=31536000');
|
||||
readfile($path);
|
||||
break;
|
||||
|
||||
case 'webp':
|
||||
header ("Content-type: image/webp");
|
||||
header ("Last-Modified: ".gmdate('D, d M Y H:i:s ', filemtime($path)) . 'GMT');
|
||||
header ("ETag: $hash");
|
||||
header('Cache-control: public, max-age=31536000');
|
||||
readfile($path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function getObjOfImage($path)
|
||||
{
|
||||
return imagecreatefromstring(file_get_contents($path));
|
||||
}
|
||||
|
||||
function gifToMP4($gifpath,$target)
|
||||
{
|
||||
$bin = escapeshellcmd(FFMPEG_BINARY);
|
||||
$file = escapeshellarg($gifpath);
|
||||
|
||||
if(!file_exists($target)) //simple caching.. have to think of something better
|
||||
{
|
||||
$cmd = "$bin -f gif -y -i $file -vcodec libx264 -an -profile:v baseline -level 3.0 -pix_fmt yuv420p -vf \"scale=trunc(iw/2)*2:trunc(ih/2)*2\" -f mp4 $target";
|
||||
system($cmd);
|
||||
}
|
||||
|
||||
return $target;
|
||||
}
|
||||
|
||||
function saveObjOfImage($im,$path,$type)
|
||||
{
|
||||
$tmppath = '/tmp/'.getNewHash($type,12);
|
||||
switch($type)
|
||||
{
|
||||
case 'jpeg':
|
||||
case 'jpg':
|
||||
imagejpeg($im,$tmppath,(defined('JPEG_COMPRESSION')?JPEG_COMPRESSION:90));
|
||||
break;
|
||||
|
||||
case 'png':
|
||||
imagepng($im,$tmppath,(defined('PNG_COMPRESSION')?PNG_COMPRESSION:6));
|
||||
break;
|
||||
|
||||
case 'webp':
|
||||
imagepalettetotruecolor($im);
|
||||
imagealphablending($im, true);
|
||||
imagewebp($im,$tmppath,(defined('WEBP_COMPRESSION')?WEBP_COMPRESSION:80));
|
||||
break;
|
||||
}
|
||||
|
||||
if(file_exists($tmppath) && filesize($tmppath)>0)
|
||||
{
|
||||
rename($tmppath,$path);
|
||||
return $im;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
function shouldAlwaysBeWebp()
|
||||
{
|
||||
//sanity check
|
||||
if(!$_SERVER['HTTP_ACCEPT']) return false;
|
||||
|
||||
if(defined('ALWAYS_WEBP') && ALWAYS_WEBP && strpos( $_SERVER['HTTP_ACCEPT'], 'image/webp' ) !== false )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
120
content-controllers/image/resize.php
Normal file
120
content-controllers/image/resize.php
Normal file
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
function isRotation($var)
|
||||
{
|
||||
switch($var)
|
||||
{
|
||||
case 'upside':
|
||||
case 'left':
|
||||
case 'right': return true;
|
||||
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
function rotate(&$im,$direction)
|
||||
{
|
||||
switch($direction)
|
||||
{
|
||||
case 'upside': $angle = 180;break;
|
||||
case 'left': $angle = 90;break;
|
||||
case 'right': $angle = -90;break;
|
||||
default: $angle = 0;break;
|
||||
}
|
||||
|
||||
$im = imagerotate($im,$angle,0);
|
||||
}
|
||||
|
||||
function forceResize(&$img,$size)
|
||||
{
|
||||
$sd = sizeStringToWidthHeight($size);
|
||||
$maxwidth = $sd['width'];
|
||||
$maxheight = $sd['height'];
|
||||
|
||||
|
||||
$width = imagesx($img);
|
||||
$height = imagesy($img);
|
||||
|
||||
$maxwidth = ($maxwidth>$width?$width:$maxwidth);
|
||||
$maxheight = ($maxheight>$height?$height:$maxheight);
|
||||
|
||||
|
||||
$dst_img = imagecreatetruecolor($maxwidth, $maxheight);
|
||||
$src_img = $img;
|
||||
|
||||
$palsize = ImageColorsTotal($img);
|
||||
for ($i = 0; $i < $palsize; $i++)
|
||||
{
|
||||
$colors = ImageColorsForIndex($img, $i);
|
||||
ImageColorAllocate($dst_img, $colors['red'], $colors['green'], $colors['blue']);
|
||||
}
|
||||
|
||||
imagefill($dst_img, 0, 0, IMG_COLOR_TRANSPARENT);
|
||||
imagesavealpha($dst_img,true);
|
||||
imagealphablending($dst_img, true);
|
||||
|
||||
$width_new = $height * $maxwidth / $maxheight;
|
||||
$height_new = $width * $maxheight / $maxwidth;
|
||||
//if the new width is greater than the actual width of the image, then the height is too large and the rest cut off, or vice versa
|
||||
if($width_new > $width){
|
||||
//cut point by height
|
||||
$h_point = (($height - $height_new) / 2);
|
||||
//copy image
|
||||
imagecopyresampled($dst_img, $src_img, 0, 0, 0, $h_point, $maxwidth, $maxheight, $width, $height_new);
|
||||
}else{
|
||||
//cut point by width
|
||||
$w_point = (($width - $width_new) / 2);
|
||||
imagecopyresampled($dst_img, $src_img, 0, 0, $w_point, 0, $maxwidth, $maxheight, $width_new, $height);
|
||||
}
|
||||
|
||||
$img = $dst_img;
|
||||
}
|
||||
|
||||
/**
|
||||
* From: https://stackoverflow.com/questions/4590441/php-thumbnail-image-resizing-with-proportions
|
||||
*/
|
||||
function resize(&$img,$size)
|
||||
{
|
||||
$sd = sizeStringToWidthHeight($size);
|
||||
$maxwidth = $sd['width'];
|
||||
$maxheight = $sd['height'];
|
||||
|
||||
$width = imagesx($img);
|
||||
$height = imagesy($img);
|
||||
|
||||
if(defined('ALLOW_BLOATING') && !ALLOW_BLOATING)
|
||||
{
|
||||
if($maxwidth>$width)$maxwidth = $width;
|
||||
if($maxheight>$height)$maxheight = $height;
|
||||
}
|
||||
|
||||
if ($height > $width)
|
||||
{
|
||||
$ratio = $maxheight / $height;
|
||||
$newheight = intval($maxheight);
|
||||
$newwidth = intval($width * $ratio) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
$ratio = $maxwidth / $width;
|
||||
$newwidth = intval($maxwidth) ;
|
||||
$newheight = intval($height * $ratio);
|
||||
}
|
||||
|
||||
$newimg = imagecreatetruecolor($newwidth,$newheight);
|
||||
|
||||
$palsize = ImageColorsTotal($img);
|
||||
for ($i = 0; $i < $palsize; $i++)
|
||||
{
|
||||
$colors = ImageColorsForIndex($img, $i);
|
||||
ImageColorAllocate($newimg, $colors['red'], $colors['green'], $colors['blue']);
|
||||
}
|
||||
|
||||
imagefill($newimg, 0, 0, IMG_COLOR_TRANSPARENT);
|
||||
imagesavealpha($newimg,true);
|
||||
imagealphablending($newimg, true);
|
||||
|
||||
imagecopyresampled($newimg, $img, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
|
||||
|
||||
$img = $newimg;
|
||||
}
|
||||
Binary file not shown.
52
content-controllers/placeholder/placeholder.controller.php
Normal file
52
content-controllers/placeholder/placeholder.controller.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
class PlaceholderController implements ContentController
|
||||
{
|
||||
public const ctype = 'dynamic';
|
||||
|
||||
//returns all extensions registered by this type of content
|
||||
public function getRegisteredExtensions(){return array('placeholder');}
|
||||
|
||||
public function handleHash($hash,$url)
|
||||
{
|
||||
$path = getDataDir().DS.$hash.DS.$hash;
|
||||
|
||||
include_once(dirname(__FILE__).DS.'placeholdergenerator.php');
|
||||
$pg = new PlaceholderGenerator();
|
||||
|
||||
foreach($url as $u)
|
||||
{
|
||||
if(isSize($u))
|
||||
$modifiers['size'] = $u;
|
||||
if(startsWith($u,'color-'))
|
||||
{
|
||||
$u = substr($u,6);
|
||||
$colors = explode('-',$u);
|
||||
foreach($colors as $c)
|
||||
if(isColor($c))
|
||||
$modifiers['colors'][] = (ctype_xdigit($c)?$c:color_name_to_hex($c));
|
||||
|
||||
if(count($modifiers['colors'])>4)
|
||||
$modifiers['colors'] = array_slice($modifiers['colors'],0,4);
|
||||
}
|
||||
}
|
||||
|
||||
$img = $pg->generateImage($modifiers);
|
||||
|
||||
$img = $pg->gradient($img, $modifiers['colors']);
|
||||
$img = $pg->addSizeText($img,$modifiers);
|
||||
|
||||
header ("Content-type: image/jpeg");
|
||||
header ("ETag: $hash");
|
||||
header('Cache-control: public, max-age=31536000');
|
||||
|
||||
imagejpeg($img,null,(defined('JPEG_COMPRESSION')?JPEG_COMPRESSION:90));
|
||||
}
|
||||
|
||||
public function handleUpload($tmpfile,$hash=false)
|
||||
{
|
||||
return array('status'=>'err','hash'=>$hash,'reason'=>'Cannot upload to placeholder image');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
88
content-controllers/placeholder/placeholdergenerator.php
Normal file
88
content-controllers/placeholder/placeholdergenerator.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
class PlaceholderGenerator {
|
||||
|
||||
function generateImage($modifiers)
|
||||
{
|
||||
$size = ($modifiers['size']?:'800x600');
|
||||
|
||||
$sd = sizeStringToWidthHeight($size);
|
||||
$width = $sd['width'];
|
||||
$height = $sd['height'];
|
||||
|
||||
$im = imagecreatetruecolor($width, $height);
|
||||
|
||||
return $im;
|
||||
}
|
||||
|
||||
function addSizeText($im,$modifiers)
|
||||
{
|
||||
$size = imagesx($im).'x'.imagesy($im);
|
||||
$text = $size;
|
||||
//add the size as text in the center of the image
|
||||
$textcolor = imagecolorallocate($im, 0, 0, 0);
|
||||
$font = dirname(__FILE__).DS.'fonts/RonysiswadiArchitect5-1GErv.ttf';
|
||||
//calculate the size of the text to make sure it will alway be visible
|
||||
$fontsize = 20;
|
||||
$textsize = imagettfbbox($fontsize, 0, $font, $text);
|
||||
$scaleX = imagesx($im) / ($textsize[2] - $textsize[0] + 25);
|
||||
$scaleY = imagesy($im) / ($textsize[1] - $textsize[7] + 25);
|
||||
|
||||
$scale = min($scaleX,$scaleY);
|
||||
|
||||
$fontsize = 20 * $scale;
|
||||
$textsize = imagettfbbox($fontsize, 0, $font, $text);
|
||||
$textwidth = $textsize[2] - $textsize[0];
|
||||
$textheight = $textsize[1] - $textsize[7];
|
||||
|
||||
if($textwidth > imagesx($im) || $textheight > imagesy($im))
|
||||
return $im;
|
||||
|
||||
$x = intval((imagesx($im) - $textwidth) / 2);
|
||||
$y = intval((imagesy($im) - $textheight) / 2 + $textheight);
|
||||
imagettftext($im, $fontsize, 0, $x, $y, $textcolor, $font, $text);
|
||||
|
||||
return $im;
|
||||
}
|
||||
|
||||
function gradient($im, $c) {
|
||||
|
||||
$w = imagesx($im);
|
||||
$h = imagesy($im);
|
||||
|
||||
if(!$c[0]) $c = ['ffffff','ffffff','ffffff','ffffff'];
|
||||
else if(!$c[1]) $c = [$c[0],$c[0],$c[0],$c[0]];
|
||||
else if(!$c[2]) $c = [$c[0],$c[0],$c[1],$c[1]];
|
||||
else if(!$c[3]) $c = [$c[0],$c[1],$c[2],$c[0]];
|
||||
|
||||
for($i=0;$i<=3;$i++) {
|
||||
$c[$i]=$this->hex2rgb($c[$i]);
|
||||
}
|
||||
|
||||
$rgb=$c[0]; // start with top left color
|
||||
for($x=0;$x<=$w;$x++) { // loop columns
|
||||
for($y=0;$y<=$h;$y++) { // loop rows
|
||||
// set pixel color
|
||||
$col=imagecolorallocate($im,intval($rgb[0]),intval($rgb[1]),intval($rgb[2]));
|
||||
imagesetpixel($im,$x-1,$y-1,$col);
|
||||
// calculate new color
|
||||
for($i=0;$i<=2;$i++) {
|
||||
$rgb[$i]=
|
||||
$c[0][$i]*(($w-$x)*($h-$y)/($w*$h)) +
|
||||
$c[1][$i]*($x *($h-$y)/($w*$h)) +
|
||||
$c[2][$i]*(($w-$x)*$y /($w*$h)) +
|
||||
$c[3][$i]*($x *$y /($w*$h));
|
||||
}
|
||||
}
|
||||
}
|
||||
return $im;
|
||||
}
|
||||
|
||||
function hex2rgb($hex)
|
||||
{
|
||||
$rgb[0]=hexdec(substr($hex,0,2));
|
||||
$rgb[1]=hexdec(substr($hex,2,2));
|
||||
$rgb[2]=hexdec(substr($hex,4,2));
|
||||
return($rgb);
|
||||
}
|
||||
}
|
||||
60
content-controllers/text/text.controller.php
Normal file
60
content-controllers/text/text.controller.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
class TextController implements ContentController
|
||||
{
|
||||
public const ctype = 'static';
|
||||
|
||||
//returns all extensions registered by this type of content
|
||||
public function getRegisteredExtensions(){return array('txt','text','csv');}
|
||||
|
||||
public function handleHash($hash,$url)
|
||||
{
|
||||
$path = getDataDir().DS.$hash.DS.$hash;
|
||||
|
||||
if(in_array('raw',$url))
|
||||
{
|
||||
header('Content-Type: text/plain; charset=utf-8');
|
||||
echo file_get_contents($path);
|
||||
}
|
||||
else if(in_array('download',$url))
|
||||
{
|
||||
if (file_exists($path)) {
|
||||
header('Content-Description: File Transfer');
|
||||
header('Content-Type: application/octet-stream');
|
||||
header('Content-Disposition: attachment; filename="'.basename($path).'"');
|
||||
header('Expires: 0');
|
||||
header('Cache-Control: must-revalidate');
|
||||
header('Pragma: public');
|
||||
header('Content-Length: ' . filesize($path));
|
||||
readfile($path);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
else
|
||||
renderTemplate('text',array('hash'=>$hash,'content'=>htmlentities(file_get_contents($path))));
|
||||
}
|
||||
|
||||
public function handleUpload($tmpfile,$hash=false)
|
||||
{
|
||||
if($hash===false)
|
||||
{
|
||||
$hash = getNewHash('txt',6);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!endswith($hash,'.txt'))
|
||||
$hash.='.txt';
|
||||
if(isExistingHash($hash))
|
||||
return array('status'=>'err','hash'=>$hash,'reason'=>'Custom hash already exists');
|
||||
}
|
||||
|
||||
storeFile($tmpfile,$hash,true);
|
||||
|
||||
return array('status'=>'ok','hash'=>$hash,'url'=>getURL().$hash);
|
||||
}
|
||||
|
||||
function getTypeOfText($hash)
|
||||
{
|
||||
return file_get_contents(getDataDir().DS.$hash.DS.'type');
|
||||
}
|
||||
}
|
||||
11
content-controllers/url/url.controller.php
Normal file
11
content-controllers/url/url.controller.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
class UrlController implements ContentController
|
||||
{
|
||||
public const ctype = 'static';
|
||||
|
||||
//returns all extensions registered by this type of content
|
||||
public function getRegisteredExtensions(){return array('url');}
|
||||
public function handleHash($hash,$url){}
|
||||
public function handleUpload($tmpfile,$hash=false){}
|
||||
}
|
||||
217
content-controllers/video/video.controller.php
Normal file
217
content-controllers/video/video.controller.php
Normal file
@@ -0,0 +1,217 @@
|
||||
<?php
|
||||
|
||||
class VideoController implements ContentController
|
||||
{
|
||||
public const ctype = 'static';
|
||||
|
||||
//returns all extensions registered by this type of content
|
||||
public function getRegisteredExtensions(){return array('mp4');}
|
||||
|
||||
public function handleHash($hash,$url)
|
||||
{
|
||||
$path = getDataDir().DS.$hash.DS.$hash;
|
||||
|
||||
//@todo: - resize by changing $path
|
||||
|
||||
//check if video should be resized
|
||||
foreach($url as $u)
|
||||
if(isSize($u)==true)
|
||||
$size = $u;
|
||||
if($size)
|
||||
{
|
||||
$s = sizeStringToWidthHeight($size);
|
||||
$width = $s['width'];
|
||||
$newpath = getDataDir().DS.$hash.DS.$width.'_'.$hash;
|
||||
if(!file_exists($newpath))
|
||||
$this->resize($path,$newpath,$width);
|
||||
$path = $newpath;
|
||||
}
|
||||
|
||||
|
||||
if(in_array('raw',$url))
|
||||
$this->serveMP4($path,$hash);
|
||||
else if(in_array('preview',$url))
|
||||
{
|
||||
$preview = $path.'_preview.jpg';
|
||||
if(!file_exists($preview))
|
||||
{
|
||||
$this->saveFirstFrameOfMP4($path,$preview);
|
||||
}
|
||||
|
||||
header ("Content-type: image/jpeg");
|
||||
readfile($preview);
|
||||
|
||||
}
|
||||
else if(in_array('download',$url))
|
||||
{
|
||||
if (file_exists($path)) {
|
||||
header('Content-Description: File Transfer');
|
||||
header('Content-Type: application/octet-stream');
|
||||
header('Content-Disposition: attachment; filename="'.basename($path).'"');
|
||||
header('Expires: 0');
|
||||
header('Cache-Control: must-revalidate');
|
||||
header('Pragma: public');
|
||||
header('Content-Length: ' . filesize($path));
|
||||
readfile($path);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$data = array('url'=>implode('/',$url),'hash'=>$hash,'filesize'=>renderSize(filesize($path)));
|
||||
renderTemplate('video',$data);
|
||||
}
|
||||
}
|
||||
|
||||
public function handleUpload($tmpfile,$hash=false)
|
||||
{
|
||||
if($hash===false)
|
||||
$hash = getNewHash('mp4',6);
|
||||
else
|
||||
{
|
||||
$hash.='.mp4';
|
||||
if(isExistingHash($hash))
|
||||
return array('status'=>'err','hash'=>$hash,'reason'=>'Custom hash already exists');
|
||||
}
|
||||
|
||||
$file = storeFile($tmpfile,$hash,true);
|
||||
|
||||
if(!$this->rightEncodedMP4($file))
|
||||
system("nohup php ".ROOT.DS.'tools'.DS.'re-encode_mp4.php force '.$hash." > /dev/null 2> /dev/null &");
|
||||
|
||||
return array('status'=>'ok','hash'=>$hash,'url'=>getURL().$hash);
|
||||
}
|
||||
|
||||
|
||||
//via gist: https://gist.github.com/codler/3906826
|
||||
function serveMP4($path,$hash)
|
||||
{
|
||||
if ($fp = fopen($path, "rb"))
|
||||
{
|
||||
$size = filesize($path);
|
||||
$length = $size;
|
||||
$start = 0;
|
||||
$end = $size - 1;
|
||||
header('Content-type: video/mp4');
|
||||
header('Cache-control: public, max-age=31536000');
|
||||
header("Accept-Ranges: 0-$length");
|
||||
if (isset($_SERVER['HTTP_RANGE'])) {
|
||||
$c_start = $start;
|
||||
$c_end = $end;
|
||||
list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
|
||||
if (strpos($range, ',') !== false) {
|
||||
header('HTTP/1.1 416 Requested Range Not Satisfiable');
|
||||
header("Content-Range: bytes $start-$end/$size");
|
||||
exit;
|
||||
}
|
||||
if ($range == '-') {
|
||||
$c_start = $size - substr($range, 1);
|
||||
} else {
|
||||
$range = explode('-', $range);
|
||||
$c_start = $range[0];
|
||||
$c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $size;
|
||||
}
|
||||
$c_end = ($c_end > $end) ? $end : $c_end;
|
||||
if ($c_start > $c_end || $c_start > $size - 1 || $c_end >= $size) {
|
||||
header('HTTP/1.1 416 Requested Range Not Satisfiable');
|
||||
header("Content-Range: bytes $start-$end/$size");
|
||||
exit;
|
||||
}
|
||||
$start = $c_start;
|
||||
$end = $c_end;
|
||||
$length = $end - $start + 1;
|
||||
fseek($fp, $start);
|
||||
header('HTTP/1.1 206 Partial Content');
|
||||
}
|
||||
header("Content-Range: bytes $start-$end/$size");
|
||||
header("Content-Length: ".$length);
|
||||
$buffer = 1024 * 8;
|
||||
while(!feof($fp) && ($p = ftell($fp)) <= $end) {
|
||||
if ($p + $buffer > $end) {
|
||||
$buffer = $end - $p + 1;
|
||||
}
|
||||
set_time_limit(0);
|
||||
echo fread($fp, $buffer);
|
||||
flush();
|
||||
}
|
||||
fclose($fp);
|
||||
exit();
|
||||
} else die('file not found');
|
||||
}
|
||||
|
||||
function isProperMP4($filename)
|
||||
{
|
||||
$file = escapeshellarg($filename);
|
||||
$tmp = ROOT.DS.'tmp'.DS.md5(time()+rand(1,10000)).'.'.rand(1,10000).'.log';
|
||||
$bin = escapeshellcmd(FFMPEG_BINARY);
|
||||
|
||||
|
||||
|
||||
$cmd = "$bin -i $file > $tmp 2>> $tmp";
|
||||
|
||||
system($cmd);
|
||||
|
||||
//var_dump(system( "$bin -i $file "));
|
||||
|
||||
$answer = file($tmp);
|
||||
unlink($tmp);
|
||||
$ismp4 = false;
|
||||
if(is_array($answer))
|
||||
foreach($answer as $line)
|
||||
{
|
||||
$line = trim($line);
|
||||
if(strpos($line,'Duration: 00:00:00')) return false;
|
||||
if(strpos($line, 'Video: h264'))
|
||||
$ismp4 = true;
|
||||
}
|
||||
|
||||
return $ismp4;
|
||||
}
|
||||
|
||||
function rightEncodedMP4($file)
|
||||
{
|
||||
$hash = md5($file);
|
||||
$cmd = FFMPEG_BINARY." -i $file -hide_banner 2> ".ROOT.DS.'tmp'.DS.$hash.'.txt';
|
||||
system($cmd);
|
||||
$results = file(ROOT.DS.'tmp'.DS.$hash.'.txt');
|
||||
foreach($results as $l)
|
||||
{
|
||||
$elements = explode(':',trim($l));
|
||||
$key=trim(array_shift($elements));
|
||||
$value = trim(implode(':',$elements));
|
||||
if($key=='encoder')
|
||||
{
|
||||
if(startsWith(strtolower($value),'lav'))
|
||||
{
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
}
|
||||
unlink(ROOT.DS.'tmp'.DS.$hash.'.txt');
|
||||
return false;
|
||||
}
|
||||
|
||||
function saveFirstFrameOfMP4($path,$target)
|
||||
{
|
||||
$bin = escapeshellcmd(FFMPEG_BINARY);
|
||||
$file = escapeshellarg($path);
|
||||
$cmd = "$bin -y -i $file -vframes 1 -f image2 $target";
|
||||
|
||||
system($cmd);
|
||||
}
|
||||
|
||||
function resize($in,$out,$width)
|
||||
{
|
||||
$file = escapeshellarg($in);
|
||||
$tmp = '/dev/null';
|
||||
$bin = escapeshellcmd(FFMPEG_BINARY);
|
||||
|
||||
$addition = '-c:v libx264 -profile:v baseline -level 3.0 -pix_fmt yuv420p';
|
||||
$height = 'trunc(ow/a/2)*2';
|
||||
|
||||
$cmd = "$bin -i $file -y -vf scale=\"$width:$height\" $addition $out";
|
||||
system($cmd);
|
||||
|
||||
return (file_exists($out) && filesize($out)>0);
|
||||
}
|
||||
}
|
||||
388
css/dropzone.css
Normal file
388
css/dropzone.css
Normal file
@@ -0,0 +1,388 @@
|
||||
/*
|
||||
* The MIT License
|
||||
* Copyright (c) 2012 Matias Meno <m@tias.me>
|
||||
*/
|
||||
@-webkit-keyframes passing-through {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(40px);
|
||||
-moz-transform: translateY(40px);
|
||||
-ms-transform: translateY(40px);
|
||||
-o-transform: translateY(40px);
|
||||
transform: translateY(40px); }
|
||||
30%, 70% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0px);
|
||||
-moz-transform: translateY(0px);
|
||||
-ms-transform: translateY(0px);
|
||||
-o-transform: translateY(0px);
|
||||
transform: translateY(0px); }
|
||||
100% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(-40px);
|
||||
-moz-transform: translateY(-40px);
|
||||
-ms-transform: translateY(-40px);
|
||||
-o-transform: translateY(-40px);
|
||||
transform: translateY(-40px); } }
|
||||
@-moz-keyframes passing-through {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(40px);
|
||||
-moz-transform: translateY(40px);
|
||||
-ms-transform: translateY(40px);
|
||||
-o-transform: translateY(40px);
|
||||
transform: translateY(40px); }
|
||||
30%, 70% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0px);
|
||||
-moz-transform: translateY(0px);
|
||||
-ms-transform: translateY(0px);
|
||||
-o-transform: translateY(0px);
|
||||
transform: translateY(0px); }
|
||||
100% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(-40px);
|
||||
-moz-transform: translateY(-40px);
|
||||
-ms-transform: translateY(-40px);
|
||||
-o-transform: translateY(-40px);
|
||||
transform: translateY(-40px); } }
|
||||
@keyframes passing-through {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(40px);
|
||||
-moz-transform: translateY(40px);
|
||||
-ms-transform: translateY(40px);
|
||||
-o-transform: translateY(40px);
|
||||
transform: translateY(40px); }
|
||||
30%, 70% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0px);
|
||||
-moz-transform: translateY(0px);
|
||||
-ms-transform: translateY(0px);
|
||||
-o-transform: translateY(0px);
|
||||
transform: translateY(0px); }
|
||||
100% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(-40px);
|
||||
-moz-transform: translateY(-40px);
|
||||
-ms-transform: translateY(-40px);
|
||||
-o-transform: translateY(-40px);
|
||||
transform: translateY(-40px); } }
|
||||
@-webkit-keyframes slide-in {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(40px);
|
||||
-moz-transform: translateY(40px);
|
||||
-ms-transform: translateY(40px);
|
||||
-o-transform: translateY(40px);
|
||||
transform: translateY(40px); }
|
||||
30% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0px);
|
||||
-moz-transform: translateY(0px);
|
||||
-ms-transform: translateY(0px);
|
||||
-o-transform: translateY(0px);
|
||||
transform: translateY(0px); } }
|
||||
@-moz-keyframes slide-in {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(40px);
|
||||
-moz-transform: translateY(40px);
|
||||
-ms-transform: translateY(40px);
|
||||
-o-transform: translateY(40px);
|
||||
transform: translateY(40px); }
|
||||
30% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0px);
|
||||
-moz-transform: translateY(0px);
|
||||
-ms-transform: translateY(0px);
|
||||
-o-transform: translateY(0px);
|
||||
transform: translateY(0px); } }
|
||||
@keyframes slide-in {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(40px);
|
||||
-moz-transform: translateY(40px);
|
||||
-ms-transform: translateY(40px);
|
||||
-o-transform: translateY(40px);
|
||||
transform: translateY(40px); }
|
||||
30% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0px);
|
||||
-moz-transform: translateY(0px);
|
||||
-ms-transform: translateY(0px);
|
||||
-o-transform: translateY(0px);
|
||||
transform: translateY(0px); } }
|
||||
@-webkit-keyframes pulse {
|
||||
0% {
|
||||
-webkit-transform: scale(1);
|
||||
-moz-transform: scale(1);
|
||||
-ms-transform: scale(1);
|
||||
-o-transform: scale(1);
|
||||
transform: scale(1); }
|
||||
10% {
|
||||
-webkit-transform: scale(1.1);
|
||||
-moz-transform: scale(1.1);
|
||||
-ms-transform: scale(1.1);
|
||||
-o-transform: scale(1.1);
|
||||
transform: scale(1.1); }
|
||||
20% {
|
||||
-webkit-transform: scale(1);
|
||||
-moz-transform: scale(1);
|
||||
-ms-transform: scale(1);
|
||||
-o-transform: scale(1);
|
||||
transform: scale(1); } }
|
||||
@-moz-keyframes pulse {
|
||||
0% {
|
||||
-webkit-transform: scale(1);
|
||||
-moz-transform: scale(1);
|
||||
-ms-transform: scale(1);
|
||||
-o-transform: scale(1);
|
||||
transform: scale(1); }
|
||||
10% {
|
||||
-webkit-transform: scale(1.1);
|
||||
-moz-transform: scale(1.1);
|
||||
-ms-transform: scale(1.1);
|
||||
-o-transform: scale(1.1);
|
||||
transform: scale(1.1); }
|
||||
20% {
|
||||
-webkit-transform: scale(1);
|
||||
-moz-transform: scale(1);
|
||||
-ms-transform: scale(1);
|
||||
-o-transform: scale(1);
|
||||
transform: scale(1); } }
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
-webkit-transform: scale(1);
|
||||
-moz-transform: scale(1);
|
||||
-ms-transform: scale(1);
|
||||
-o-transform: scale(1);
|
||||
transform: scale(1); }
|
||||
10% {
|
||||
-webkit-transform: scale(1.1);
|
||||
-moz-transform: scale(1.1);
|
||||
-ms-transform: scale(1.1);
|
||||
-o-transform: scale(1.1);
|
||||
transform: scale(1.1); }
|
||||
20% {
|
||||
-webkit-transform: scale(1);
|
||||
-moz-transform: scale(1);
|
||||
-ms-transform: scale(1);
|
||||
-o-transform: scale(1);
|
||||
transform: scale(1); } }
|
||||
.dropzone, .dropzone * {
|
||||
box-sizing: border-box; }
|
||||
|
||||
.dropzone {
|
||||
min-height: 150px;
|
||||
border: 2px solid rgba(0, 0, 0, 0.3);
|
||||
background: white;
|
||||
padding: 20px 20px; }
|
||||
.dropzone.dz-clickable {
|
||||
cursor: pointer; }
|
||||
.dropzone.dz-clickable * {
|
||||
cursor: default; }
|
||||
.dropzone.dz-clickable .dz-message, .dropzone.dz-clickable .dz-message * {
|
||||
cursor: pointer; }
|
||||
.dropzone.dz-started .dz-message {
|
||||
display: none; }
|
||||
.dropzone.dz-drag-hover {
|
||||
border-style: solid; }
|
||||
.dropzone.dz-drag-hover .dz-message {
|
||||
opacity: 0.5; }
|
||||
.dropzone .dz-message {
|
||||
text-align: center;
|
||||
margin: 2em 0; }
|
||||
.dropzone .dz-preview {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
margin: 16px;
|
||||
min-height: 100px; }
|
||||
.dropzone .dz-preview:hover {
|
||||
z-index: 1000; }
|
||||
.dropzone .dz-preview:hover .dz-details {
|
||||
opacity: 1; }
|
||||
.dropzone .dz-preview.dz-file-preview .dz-image {
|
||||
border-radius: 20px;
|
||||
background: #999;
|
||||
background: linear-gradient(to bottom, #eee, #ddd); }
|
||||
.dropzone .dz-preview.dz-file-preview .dz-details {
|
||||
opacity: 1; }
|
||||
.dropzone .dz-preview.dz-image-preview {
|
||||
background: white; }
|
||||
.dropzone .dz-preview.dz-image-preview .dz-details {
|
||||
-webkit-transition: opacity 0.2s linear;
|
||||
-moz-transition: opacity 0.2s linear;
|
||||
-ms-transition: opacity 0.2s linear;
|
||||
-o-transition: opacity 0.2s linear;
|
||||
transition: opacity 0.2s linear; }
|
||||
.dropzone .dz-preview .dz-remove {
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
border: none; }
|
||||
.dropzone .dz-preview .dz-remove:hover {
|
||||
text-decoration: underline; }
|
||||
.dropzone .dz-preview:hover .dz-details {
|
||||
opacity: 1; }
|
||||
.dropzone .dz-preview .dz-details {
|
||||
z-index: 20;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
opacity: 0;
|
||||
font-size: 13px;
|
||||
min-width: 100%;
|
||||
max-width: 100%;
|
||||
padding: 2em 1em;
|
||||
text-align: center;
|
||||
color: rgba(0, 0, 0, 0.9);
|
||||
line-height: 150%; }
|
||||
.dropzone .dz-preview .dz-details .dz-size {
|
||||
margin-bottom: 1em;
|
||||
font-size: 16px; }
|
||||
.dropzone .dz-preview .dz-details .dz-filename {
|
||||
white-space: nowrap; }
|
||||
.dropzone .dz-preview .dz-details .dz-filename:hover span {
|
||||
border: 1px solid rgba(200, 200, 200, 0.8);
|
||||
background-color: rgba(255, 255, 255, 0.8); }
|
||||
.dropzone .dz-preview .dz-details .dz-filename:not(:hover) {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis; }
|
||||
.dropzone .dz-preview .dz-details .dz-filename:not(:hover) span {
|
||||
border: 1px solid transparent; }
|
||||
.dropzone .dz-preview .dz-details .dz-filename span, .dropzone .dz-preview .dz-details .dz-size span {
|
||||
background-color: rgba(255, 255, 255, 0.4);
|
||||
padding: 0 0.4em;
|
||||
border-radius: 3px; }
|
||||
.dropzone .dz-preview:hover .dz-image img {
|
||||
-webkit-transform: scale(1.05, 1.05);
|
||||
-moz-transform: scale(1.05, 1.05);
|
||||
-ms-transform: scale(1.05, 1.05);
|
||||
-o-transform: scale(1.05, 1.05);
|
||||
transform: scale(1.05, 1.05);
|
||||
-webkit-filter: blur(8px);
|
||||
filter: blur(8px); }
|
||||
.dropzone .dz-preview .dz-image {
|
||||
border-radius: 20px;
|
||||
overflow: hidden;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
position: relative;
|
||||
display: block;
|
||||
z-index: 10; }
|
||||
.dropzone .dz-preview .dz-image img {
|
||||
display: block; }
|
||||
.dropzone .dz-preview.dz-success .dz-success-mark {
|
||||
-webkit-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
|
||||
-moz-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
|
||||
-ms-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
|
||||
-o-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
|
||||
animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1); }
|
||||
.dropzone .dz-preview.dz-error .dz-error-mark {
|
||||
opacity: 1;
|
||||
-webkit-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
|
||||
-moz-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
|
||||
-ms-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
|
||||
-o-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
|
||||
animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1); }
|
||||
.dropzone .dz-preview .dz-success-mark, .dropzone .dz-preview .dz-error-mark {
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
z-index: 500;
|
||||
position: absolute;
|
||||
display: block;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-left: -27px;
|
||||
margin-top: -27px; }
|
||||
.dropzone .dz-preview .dz-success-mark svg, .dropzone .dz-preview .dz-error-mark svg {
|
||||
display: block;
|
||||
width: 54px;
|
||||
height: 54px; }
|
||||
.dropzone .dz-preview.dz-processing .dz-progress {
|
||||
opacity: 1;
|
||||
-webkit-transition: all 0.2s linear;
|
||||
-moz-transition: all 0.2s linear;
|
||||
-ms-transition: all 0.2s linear;
|
||||
-o-transition: all 0.2s linear;
|
||||
transition: all 0.2s linear; }
|
||||
.dropzone .dz-preview.dz-complete .dz-progress {
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 0.4s ease-in;
|
||||
-moz-transition: opacity 0.4s ease-in;
|
||||
-ms-transition: opacity 0.4s ease-in;
|
||||
-o-transition: opacity 0.4s ease-in;
|
||||
transition: opacity 0.4s ease-in; }
|
||||
.dropzone .dz-preview:not(.dz-processing) .dz-progress {
|
||||
-webkit-animation: pulse 6s ease infinite;
|
||||
-moz-animation: pulse 6s ease infinite;
|
||||
-ms-animation: pulse 6s ease infinite;
|
||||
-o-animation: pulse 6s ease infinite;
|
||||
animation: pulse 6s ease infinite; }
|
||||
.dropzone .dz-preview .dz-progress {
|
||||
opacity: 1;
|
||||
z-index: 1000;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
height: 16px;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
margin-top: -8px;
|
||||
width: 80px;
|
||||
margin-left: -40px;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
-webkit-transform: scale(1);
|
||||
border-radius: 8px;
|
||||
overflow: hidden; }
|
||||
.dropzone .dz-preview .dz-progress .dz-upload {
|
||||
background: #333;
|
||||
background: linear-gradient(to bottom, #666, #444);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 0;
|
||||
-webkit-transition: width 300ms ease-in-out;
|
||||
-moz-transition: width 300ms ease-in-out;
|
||||
-ms-transition: width 300ms ease-in-out;
|
||||
-o-transition: width 300ms ease-in-out;
|
||||
transition: width 300ms ease-in-out; }
|
||||
.dropzone .dz-preview.dz-error .dz-error-message {
|
||||
display: block; }
|
||||
.dropzone .dz-preview.dz-error:hover .dz-error-message {
|
||||
opacity: 1;
|
||||
pointer-events: auto; }
|
||||
.dropzone .dz-preview .dz-error-message {
|
||||
pointer-events: none;
|
||||
z-index: 1000;
|
||||
position: absolute;
|
||||
display: block;
|
||||
display: none;
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 0.3s ease;
|
||||
-moz-transition: opacity 0.3s ease;
|
||||
-ms-transition: opacity 0.3s ease;
|
||||
-o-transition: opacity 0.3s ease;
|
||||
transition: opacity 0.3s ease;
|
||||
border-radius: 8px;
|
||||
font-size: 13px;
|
||||
top: 130px;
|
||||
left: -10px;
|
||||
width: 140px;
|
||||
background: #be2626;
|
||||
background: linear-gradient(to bottom, #be2626, #a92222);
|
||||
padding: 0.5em 1.2em;
|
||||
color: white; }
|
||||
.dropzone .dz-preview .dz-error-message:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
left: 64px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-bottom: 6px solid #be2626; }
|
||||
1
css/imgs/logo/logo.svg
Normal file
1
css/imgs/logo/logo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2" viewBox="0 0 318.8 194"><circle cx="97" cy="97" r="97" style="fill:url(#a)"/><path d="M97.3 6.8c50 0 90.5 40.3 90.5 90s-40.5 90-90.5 90-90.5-40.3-90.5-90 40.5-90 90.5-90Zm69.8 140.7a85.2 85.2 0 0 0 16.6-50.6A86.2 86.2 0 0 0 97.3 11 86.2 86.2 0 0 0 11 96.9c0 17 5 32.8 13.5 46.2 36.3-67.4 36.2-74.7 45.3-74.7 8.8 0 10.3 7.6 43.3 71.4 16.7-25.9 18.9-30.4 24.3-30.4 6.7 0 8 5 29.7 38Zm-29.3-68.2a10.6 10.6 0 1 1 0 21.2 10.6 10.6 0 0 1 0-21.2Z" style="fill:url(#b)"/><path d="M253 37.1a33 33 0 1 1 10.4 27l-69.7 26.1-6.4-28.5L253 37.1Z" style="fill:url(#c)"/><path d="M263.4 129.3a32.9 32.9 0 0 1 55.4 24.2 33 33 0 0 1-65.8 3.2l-65.6-24.8 6.4-28.9 69.6 26.3Z" style="fill:url(#d)"/><defs><radialGradient id="a" cx="0" cy="0" r="1" gradientTransform="matrix(79 0 0 -73 97.3 77.6)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#867278;stop-opacity:1"/><stop offset=".5" style="stop-color:#5c4955;stop-opacity:1"/><stop offset="1" style="stop-color:#433545;stop-opacity:1"/></radialGradient><radialGradient id="c" cx="0" cy="0" r="1" gradientTransform="matrix(55 0 0 -55 253 48.6)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#867278;stop-opacity:1"/><stop offset=".5" style="stop-color:#5c4955;stop-opacity:1"/><stop offset="1" style="stop-color:#433545;stop-opacity:1"/></radialGradient><radialGradient id="d" cx="0" cy="0" r="1" gradientTransform="matrix(55 0 0 -56 253.1 144.8)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#867278;stop-opacity:1"/><stop offset=".5" style="stop-color:#5c4955;stop-opacity:1"/><stop offset="1" style="stop-color:#433545;stop-opacity:1"/></radialGradient><linearGradient id="b" x1="0" x2="1" y1="0" y2="0" gradientTransform="matrix(97 0 0 97 53.6 97)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#40a1d4;stop-opacity:1"/><stop offset="1" style="stop-color:#2971c2;stop-opacity:1"/></linearGradient></defs></svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
@@ -25,4 +25,11 @@ body {
|
||||
background: rgba(245, 245, 245, .8);
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.05);
|
||||
box-shadow: inset 0 1px 1px rgba(0,0,0,.05);
|
||||
}
|
||||
|
||||
.box__dragndrop,
|
||||
.box__uploading,
|
||||
.box__success,
|
||||
.box__error {
|
||||
display: none;
|
||||
}
|
||||
4
upload/.gitignore → data/.gitignore
vendored
4
upload/.gitignore → data/.gitignore
vendored
@@ -1,6 +1,4 @@
|
||||
# Ignore everything in this directory
|
||||
*
|
||||
# Except this file
|
||||
!.gitignore
|
||||
# And except deletecodes folder
|
||||
!deletecodes
|
||||
!.gitignore
|
||||
@@ -1,24 +0,0 @@
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
pictshare:
|
||||
restart: always
|
||||
image: hascheksolutions/pictshare:latest
|
||||
volumes:
|
||||
- ./volumes/upload:/usr/share/nginx/html/upload
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
environment:
|
||||
- TITLE=
|
||||
- AUTOUPDATE=false
|
||||
- MAXUPLOADSIZE=
|
||||
- MASTERDELETECODE=
|
||||
- BLOATING=
|
||||
- UPLOADCODE=
|
||||
- UPLOADPATH=
|
||||
- IMAGECHANGECODE=
|
||||
- LOGUPLOADER=
|
||||
- MAXRESIZEDIMAGES=
|
||||
- DOMAIN=
|
||||
- SHOWERRORS=
|
||||
69
docker/Dockerfile
Normal file
69
docker/Dockerfile
Normal file
@@ -0,0 +1,69 @@
|
||||
FROM alpine:3.18
|
||||
|
||||
RUN apk add --no-cache bash socat wget curl nginx file ffmpeg unzip zlib redis \
|
||||
php82-fileinfo \
|
||||
php82-session \
|
||||
php \
|
||||
php-curl \
|
||||
php-openssl \
|
||||
php-mbstring \
|
||||
php-json \
|
||||
php-gd \
|
||||
php-dom \
|
||||
php-fpm \
|
||||
php82 \
|
||||
php82-pdo \
|
||||
php82-exif \
|
||||
php82-curl \
|
||||
php82-gd \
|
||||
php82-json \
|
||||
php82-phar \
|
||||
php82-fpm \
|
||||
php82-openssl \
|
||||
php82-ctype \
|
||||
php82-opcache \
|
||||
php82-mbstring \
|
||||
php82-sodium \
|
||||
php82-xml \
|
||||
php82-ftp \
|
||||
php82-simplexml \
|
||||
php82-session \
|
||||
php82-fileinfo \
|
||||
php82-pcntl \
|
||||
php82-pecl-redis
|
||||
|
||||
RUN ln -s /usr/bin/php82 /usr/bin/php
|
||||
|
||||
RUN curl -sS https://getcomposer.org/installer | /usr/bin/php -- --install-dir=/usr/bin --filename=composer
|
||||
RUN mkdir -p /var/www
|
||||
WORKDIR /var/www
|
||||
|
||||
ADD . /var/www/.
|
||||
|
||||
ADD docker/rootfs/start.sh /etc/start.sh
|
||||
RUN chmod +x /etc/start.sh
|
||||
|
||||
# Composer intall
|
||||
WORKDIR /var/www/lib
|
||||
RUN composer install --no-dev --no-interaction --no-progress --optimize-autoloader
|
||||
|
||||
# nginx stuff
|
||||
WORKDIR /var/www
|
||||
ADD docker/rootfs/nginx.conf /etc/nginx/http.d/default.conf
|
||||
RUN mkdir -p /run/nginx
|
||||
RUN mkdir -p /var/log/nginx
|
||||
RUN sed -i 's/nobody/nginx/g' /etc/php82/php-fpm.d/www.conf
|
||||
|
||||
# Since requests can trigger conversion, let's give the server enough time to respond
|
||||
RUN sed -i "/max_execution_time/c\max_execution_time=3600" /etc/php82/php.ini
|
||||
RUN sed -i "/max_input_time/c\max_input_time=3600" /etc/php82/php.ini
|
||||
|
||||
WORKDIR /var/www/
|
||||
|
||||
# Volumes to mount
|
||||
#VOLUME /var/lib/influxdb
|
||||
VOLUME /var/www/data
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
ENTRYPOINT ["/etc/start.sh"]
|
||||
73
docker/rootfs/nginx.conf
Normal file
73
docker/rootfs/nginx.conf
Normal file
@@ -0,0 +1,73 @@
|
||||
server {
|
||||
listen 80 default_server;
|
||||
|
||||
set $base /var/www;
|
||||
root /var/www/;
|
||||
|
||||
index index.php;
|
||||
|
||||
client_max_body_size 50M;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?url=$request_uri;
|
||||
}
|
||||
|
||||
location ~ /(data|tmp|bin|content-controllers|inc|interfaces|storage-controllers|templates|tools|docker) {
|
||||
deny all;
|
||||
return 404;
|
||||
}
|
||||
|
||||
# logging
|
||||
access_log /var/log/nginx/pictshare/access.log;
|
||||
error_log /var/log/nginx/pictshare/error.log warn;
|
||||
|
||||
location ~ \.php$ {
|
||||
# 404
|
||||
try_files $fastcgi_script_name =404;
|
||||
|
||||
# default fastcgi_params
|
||||
include fastcgi_params;
|
||||
|
||||
# fastcgi settings
|
||||
fastcgi_pass 127.0.0.1:9000;
|
||||
fastcgi_index index.php;
|
||||
fastcgi_buffers 8 16k;
|
||||
fastcgi_buffer_size 32k;
|
||||
fastcgi_max_temp_file_size 0; # caching files to disk while uploading. this will help low-memory devices
|
||||
fastcgi_read_timeout 1d; # we set the timeout to 1 day so big uploads and have enough time to be delivered
|
||||
fastcgi_send_timeout 1d; # it's especially important if you want to use storage controllers like S3 or FTP
|
||||
fastcgi_request_buffering off; # disabbling buffering which will send the uploaded data right to PHP
|
||||
|
||||
# fastcgi params
|
||||
fastcgi_param DOCUMENT_ROOT $realpath_root;
|
||||
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
|
||||
fastcgi_param PHP_ADMIN_VALUE "open_basedir=$base/:/usr/lib/php/:/tmp/";
|
||||
}
|
||||
|
||||
location /favicon.ico {
|
||||
log_not_found off;
|
||||
}
|
||||
|
||||
# security headers
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header Referrer-Policy "no-referrer-when-downgrade" always;
|
||||
add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
|
||||
|
||||
# svg, fonts
|
||||
location ~* \.(?:svgz?|ttf|ttc|otf|eot|woff2?)$ {
|
||||
add_header Access-Control-Allow-Origin "*";
|
||||
expires 7d;
|
||||
access_log off;
|
||||
}
|
||||
|
||||
# gzip
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_proxied any;
|
||||
gzip_comp_level 6;
|
||||
gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss application/atom+xml image/svg+xml;
|
||||
|
||||
}
|
||||
96
docker/rootfs/start.sh
Normal file
96
docker/rootfs/start.sh
Normal file
@@ -0,0 +1,96 @@
|
||||
#!/bin/bash
|
||||
|
||||
######### functions
|
||||
|
||||
_maxUploadSize() {
|
||||
echo "[i] Setting uploadsize to ${MAX_UPLOAD_SIZE}M"
|
||||
|
||||
sed -i "/post_max_size/c\post_max_size=${MAX_UPLOAD_SIZE}M" /etc/php82/php.ini
|
||||
sed -i "/upload_max_filesize/c\upload_max_filesize=${MAX_UPLOAD_SIZE}M" /etc/php82/php.ini
|
||||
|
||||
# set error reporting no notices, no warnings
|
||||
sed -i "/^error_reporting/c\error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT & ~E_WARNING & ~E_NOTICE" /etc/php82/php.ini
|
||||
|
||||
sed -i -e "s/50M/${MAX_UPLOAD_SIZE}M/g" /etc/nginx/http.d/default.conf
|
||||
|
||||
MAX_RAM=$((MAX_UPLOAD_SIZE + 30)) # 30megs more than the upload size
|
||||
echo "[i] Also changing memory limit of PHP to ${MAX_RAM}M"
|
||||
sed -i -e "s/128M/${MAX_RAM}M/g" /etc/php82/php.ini
|
||||
sed -i "/memory_limit/c\memory_limit=${MAX_RAM}M" /etc/php82/php.ini
|
||||
}
|
||||
|
||||
_filePermissions() {
|
||||
chown -R nginx:nginx /var/www
|
||||
touch data/sha1.csv
|
||||
chown nginx:nginx data/sha1.csv
|
||||
}
|
||||
|
||||
_buildConfig() {
|
||||
echo "<?php"
|
||||
echo "define('URL', '${URL:-}');"
|
||||
echo "define('TITLE', '${TITLE:-PictShare}');"
|
||||
echo "define('ALLOWED_SUBNET', '${ALLOWED_SUBNET:-}');"
|
||||
echo "define('CONTENTCONTROLLERS', '${CONTENTCONTROLLERS:-}');"
|
||||
echo "define('MASTER_DELETE_CODE', '${MASTER_DELETE_CODE:-}');"
|
||||
echo "define('MASTER_DELETE_IP', '${MASTER_DELETE_IP:-}');"
|
||||
echo "define('UPLOAD_FORM_LOCATION', '${UPLOAD_FORM_LOCATION:-}');"
|
||||
echo "define('UPLOAD_CODE', '${UPLOAD_CODE:-}');"
|
||||
echo "define('LOG_UPLOADER', ${LOG_UPLOADER:-false});"
|
||||
echo "define('MAX_RESIZED_IMAGES',${MAX_RESIZED_IMAGES:--1});"
|
||||
echo "define('ALLOW_BLOATING', ${ALLOW_BLOATING:-false});"
|
||||
echo "define('SHOW_ERRORS', ${SHOW_ERRORS:-false});"
|
||||
echo "define('JPEG_COMPRESSION', ${JPEG_COMPRESSION:-90});"
|
||||
echo "define('PNG_COMPRESSION', ${PNG_COMPRESSION:-6});"
|
||||
echo "define('ALT_FOLDER', '${ALT_FOLDER:-}');"
|
||||
echo "define('S3_BUCKET', '${S3_BUCKET:-}');"
|
||||
echo "define('S3_ACCESS_KEY', '${S3_ACCESS_KEY:-}');"
|
||||
echo "define('S3_SECRET_KEY', '${S3_SECRET_KEY:-}');"
|
||||
echo "define('S3_ENDPOINT', '${S3_ENDPOINT:-}');"
|
||||
echo "define('S3_REGION', '${S3_REGION:-}');"
|
||||
echo "define('FTP_SERVER', '${FTP_SERVER:-}');"
|
||||
echo "define('FTP_PORT', ${FTP_PORT:-21});"
|
||||
echo "define('FTP_USER', '${FTP_USER:-}');"
|
||||
echo "define('FTP_PASS', '${FTP_PASS:-}');"
|
||||
echo "define('FTP_PASSIVEMODE', ${FTP_PASSIVEMODE:-true});"
|
||||
echo "define('FTP_SSL', ${FTP_SSL:-false});"
|
||||
echo "define('FTP_BASEDIR', '${FTP_BASEDIR:-}');"
|
||||
echo "define('ENCRYPTION_KEY', '${ENCRYPTION_KEY:-}');"
|
||||
echo "define('FFMPEG_BINARY', '${FFMPEG_BINARY:-/usr/bin/ffmpeg}');"
|
||||
echo "define('ALWAYS_WEBP', ${ALWAYS_WEBP:-false});"
|
||||
echo "define('ALLOWED_DOMAINS', '${ALLOWED_DOMAINS:-}');"
|
||||
echo "define('SPLIT_DATA_DIR', ${SPLIT_DATA_DIR:-false});"
|
||||
}
|
||||
|
||||
|
||||
|
||||
######### main
|
||||
|
||||
echo 'Starting Pictshare'
|
||||
|
||||
cd /var/www/
|
||||
|
||||
if [[ ${MAX_UPLOAD_SIZE:=100} =~ ^[0-9]+$ ]]; then
|
||||
_maxUploadSize
|
||||
fi
|
||||
|
||||
# run _filePermissions function unless SKIP_FILEPERMISSIONS is set to true
|
||||
if [[ ${SKIP_FILEPERMISSIONS:=false} != true ]]; then
|
||||
_filePermissions
|
||||
fi
|
||||
|
||||
echo ' [+] Starting php'
|
||||
php-fpm82
|
||||
|
||||
echo ' [+] Creating config'
|
||||
|
||||
_buildConfig > inc/config.inc.php
|
||||
|
||||
echo ' [+] Starting nginx'
|
||||
|
||||
mkdir -p /var/log/nginx/pictshare
|
||||
touch /var/log/nginx/pictshare/access.log
|
||||
touch /var/log/nginx/pictshare/error.log
|
||||
|
||||
nginx
|
||||
|
||||
tail -f /var/log/nginx/pictshare/*.log
|
||||
1
inc/.gitignore
vendored
1
inc/.gitignore
vendored
@@ -1,2 +1 @@
|
||||
# don#t track the active config
|
||||
config.inc.php
|
||||
1540
inc/core.php
1540
inc/core.php
File diff suppressed because it is too large
Load Diff
85
inc/encryption.php
Normal file
85
inc/encryption.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
class Encryption{
|
||||
|
||||
/**
|
||||
* $key must have been generated at some point with: random_bytes(SODIUM_CRYPTO_SECRETBOX_KEYBYTES)
|
||||
*/
|
||||
function encryptText($text,$key)
|
||||
{
|
||||
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
|
||||
$ciphertext = sodium_crypto_secretbox($text, $nonce, $key);
|
||||
$encoded = base64_encode($nonce . $ciphertext);
|
||||
return $encoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* $key must have been generated at some point with: random_bytes(SODIUM_CRYPTO_SECRETBOX_KEYBYTES)
|
||||
*/
|
||||
function decryptText($encoded,$key)
|
||||
{
|
||||
$decoded = base64_decode($encoded);
|
||||
$nonce = mb_substr($decoded, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
|
||||
|
||||
|
||||
$ciphertext = mb_substr($decoded, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');
|
||||
$plaintext = sodium_crypto_secretbox_open($ciphertext, $nonce, $key);
|
||||
return $plaintext;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* $key must have been generated at some point with: sodium_crypto_secretstream_xchacha20poly1305_keygen();
|
||||
*/
|
||||
function encryptFile($infile,$enc_outfile,$key)
|
||||
{
|
||||
$chunk_size = 4096;
|
||||
|
||||
$fd_in = fopen($infile, 'rb');
|
||||
$fd_out = fopen($enc_outfile, 'wb');
|
||||
|
||||
list($stream, $header) = sodium_crypto_secretstream_xchacha20poly1305_init_push($key);
|
||||
|
||||
fwrite($fd_out, $header);
|
||||
|
||||
$tag = SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_MESSAGE;
|
||||
do {
|
||||
$chunk = fread($fd_in, $chunk_size);
|
||||
if (feof($fd_in)) {
|
||||
$tag = SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL;
|
||||
}
|
||||
$encrypted_chunk = sodium_crypto_secretstream_xchacha20poly1305_push($stream, $chunk, '', $tag);
|
||||
fwrite($fd_out, $encrypted_chunk);
|
||||
} while ($tag !== SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL);
|
||||
|
||||
fclose($fd_out);
|
||||
fclose($fd_in);
|
||||
}
|
||||
|
||||
/**
|
||||
* $key must have been generated at some point with: sodium_crypto_secretstream_xchacha20poly1305_keygen();
|
||||
*/
|
||||
function decryptFile($enc_infile,$outfile,$key)
|
||||
{
|
||||
$fd_in = fopen($enc_infile, 'rb');
|
||||
$fd_out = fopen($outfile, 'wb');
|
||||
$chunk_size = 4096;
|
||||
|
||||
$header = fread($fd_in, SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES);
|
||||
|
||||
$stream = sodium_crypto_secretstream_xchacha20poly1305_init_pull($header, $key);
|
||||
do {
|
||||
$chunk = fread($fd_in, $chunk_size + SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES);
|
||||
list($decrypted_chunk, $tag) = sodium_crypto_secretstream_xchacha20poly1305_pull($stream, $chunk);
|
||||
fwrite($fd_out, $decrypted_chunk);
|
||||
} while (!feof($fd_in) && $tag !== SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL);
|
||||
$ok = feof($fd_in);
|
||||
|
||||
fclose($fd_out);
|
||||
fclose($fd_in);
|
||||
|
||||
if (!$ok) {
|
||||
die('Invalid/corrupted input');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,97 +1,25 @@
|
||||
<?php
|
||||
|
||||
//Set title for your image and mp4 hosting service
|
||||
define('TITLE', 'PictShare');
|
||||
|
||||
// PNG level from 0 (largest file) to
|
||||
// 9 (smallest file). Note that this doesn't affect
|
||||
// quality, only file size and CPU
|
||||
define('PNG_COMPRESSION', 6);
|
||||
|
||||
// JPG compression percenage from 0 (smallest file, worst quality)
|
||||
// to 100 (large file, best quality)
|
||||
define('JPEG_COMPRESSION', 90);
|
||||
|
||||
//If set, can be added to any image URL to delete the image and all versions of the image
|
||||
//Must be longer than 10 characters
|
||||
//Usage example:
|
||||
// image: https://pictshare.net/b260e36b60.jpg
|
||||
// to delete it, access https://pictshare.net/delete_YOURMASTERDELETECODE/b260e36b60.jpg
|
||||
// Will render one last time, if refreshed won't be on the server anymore
|
||||
define('MASTER_DELETE_CODE', false);
|
||||
|
||||
//if set, the IP, hostname or every device in the IP range (CIDR naming) will be allowed to delete images
|
||||
//by supplying the parameter "delete"
|
||||
//use multiple ips/hostnames/ranges: semicolon seperated
|
||||
//examples:
|
||||
//======
|
||||
//ip: define('MASTER_DELETE_IP', '8.8.8.8');
|
||||
//hostname: define('MASTER_DELETE_IP', 'home.example.com');
|
||||
//ip range: define('MASTER_DELETE_IP', '192.168.0.0/24'); //all IPs from 192.168.0.0 to 192.168.0.255 can delete
|
||||
//multiple: define('MASTER_DELETE_IP', '192.168.0.0/24;my.home.net;4.4.2.2');
|
||||
define('MASTER_DELETE_IP', false);
|
||||
|
||||
//If set, upload form will only be shown on that location
|
||||
//eg: define('UPLOAD_FORM_LOCATION', 'secret/upload'); then the upload form will only be visible
|
||||
//from http://your.domain/secret/upload
|
||||
define('UPLOAD_FORM_LOCATION', false);
|
||||
|
||||
//If set to true, the only page that will be rendered is the upload form
|
||||
//if a wrong link is provided, 404 will be shown instead of the error page
|
||||
//It's meant to be used to hide the fact that you're using pictshare and your site just looks like a content server
|
||||
//use in combination with UPLOAD_FORM_LOCATION for maximum sneakiness
|
||||
define('LOW_PROFILE', false);
|
||||
|
||||
//if set to a string, this string must be provided before upload.
|
||||
//you can set multiple codes by;separating;them;with;semicolons
|
||||
//if set to false, everybody can upload
|
||||
//for API uploads, the GET Variable 'upload_code' must be provided
|
||||
define('UPLOAD_CODE', false);
|
||||
|
||||
//if set to a string, this string must be provided in the URL to use any options (filters, resizes, etc..)
|
||||
//you can set multiple codes by;separating;them;with;semicolons
|
||||
//if set to false, everybody can use options on all images
|
||||
//if image change code is not provided but the requested image (with options) already exists, it will render to the user just fine
|
||||
define('IMAGE_CHANGE_CODE', false);
|
||||
|
||||
// shall we log all uploaders IP addresses?
|
||||
define('LOG_UPLOADER', true);
|
||||
|
||||
//how many resizes may one image have?
|
||||
//-1 = infinite
|
||||
//0 = none
|
||||
define('MAX_RESIZED_IMAGES',20);
|
||||
|
||||
//when the user requests a resize. Can the resized image be bigger than the original?
|
||||
define('ALLOW_BLOATING', false);
|
||||
|
||||
//Force a specific domain for this server. If set to false, will autodetect.
|
||||
//Format: https://your.domain.name/
|
||||
define('FORCE_DOMAIN', false);
|
||||
|
||||
//Shall errors be displayed to the user?
|
||||
//For dev environments: true, in production: false
|
||||
define('SHOW_ERRORS', false);
|
||||
|
||||
|
||||
//for scalability reasons you might want to upload images to cloud providers
|
||||
//remove comments to use
|
||||
|
||||
/* BACKBLAZE B2 */
|
||||
/* You can find your info here: https://secure.backblaze.com/b2_buckets.htm */
|
||||
//define('BACKBLAZE',true); //true=>use backblaze false=>don't
|
||||
//define('BACKBLAZE_ID','');
|
||||
//define('BACKBLAZE_KEY', '');
|
||||
//define('BACKBLAZE_BUCKET_ID', '');
|
||||
//define('BACKBLAZE_BUCKET_NAME', '');
|
||||
//define('BACKBLAZE_AUTODOWNLOAD', true); //if true, will download images from backblaze if not found local
|
||||
//define('BACKBLAZE_AUTOUPLOAD', true); //if true, will upload images to backblaze when they are uploaded to pictshare
|
||||
//define('BACKBLAZE_AUTODELETE', true); //if true, will delete images from backblaze if they are deleted from pictshare
|
||||
|
||||
//If you have a NAS or some cifs or nfs mounted drive, you can specify this here as a folder
|
||||
//if a requested hash is not found locally, its looked up on this location. This allows for mounted external spaces
|
||||
//or just backups on a second drive.
|
||||
//Also new hashes will be uploaded there (just the originals, not resizes)
|
||||
//value should be a path **without tailing slash**!
|
||||
|
||||
define('ALT_FOLDER','/mnt');
|
||||
<?php
|
||||
/**
|
||||
* All settings that are uncommented are mandatory
|
||||
* Others optional
|
||||
*
|
||||
* For all possible config options, check https://github.com/HaschekSolutions/pictshare/blob/master/rtfm/CONFIG.md
|
||||
* or /rtfm/CONFIG.md in your installation
|
||||
*/
|
||||
|
||||
//Use a specific domain for links presented to the user
|
||||
//Format: https://your.domain.name/
|
||||
// MUST HAVE TAILING /
|
||||
define('URL','https://dev.pictshare.net/');
|
||||
|
||||
//define('JPEG_COMPRESSION', 90);
|
||||
//define('FFMPEG_BINARY','');
|
||||
//define('ALT_FOLDER','/ftp/pictshare');
|
||||
//define('ALLOWED_SUBNET','192.168.0.0/24');
|
||||
|
||||
//S3 settings
|
||||
//
|
||||
//define('S3_BUCKET','bucketname');
|
||||
//define('S3_ACCESS_KEY','');
|
||||
//define('S3_SECRET_KEY','');
|
||||
//define('S3_ENDPOINT','http://localhost:9000'); //optional, only if you're using S3 compatible storage like Minio
|
||||
31
index.php
31
index.php
@@ -1,27 +1,22 @@
|
||||
<?php
|
||||
session_cache_limiter("public");
|
||||
$expiry = 90; //days
|
||||
session_cache_expire($expiry * 24 * 60);
|
||||
session_start();
|
||||
// basic path definitions
|
||||
define('DS', DIRECTORY_SEPARATOR);
|
||||
define('ROOT', dirname(__FILE__));
|
||||
define('PATH',((dirname($_SERVER['PHP_SELF'])=='/'||dirname($_SERVER['PHP_SELF'])=='\\'||dirname($_SERVER['PHP_SELF'])=='/index.php'||dirname($_SERVER['PHP_SELF'])=='/backend.php')?'/':dirname($_SERVER['PHP_SELF']).'/'));
|
||||
|
||||
//loading default settings if exist
|
||||
if(!file_exists(ROOT.DS.'inc'.DS.'config.inc.php'))
|
||||
exit('Rename /inc/example.config.inc.php to /inc/config.inc.php first!');
|
||||
include_once(ROOT.DS.'inc'.DS.'config.inc.php');
|
||||
|
||||
if(FORCE_DOMAIN)
|
||||
define('DOMAINPATH',FORCE_DOMAIN);
|
||||
else
|
||||
define('DOMAINPATH',(($_SERVER['HTTPS'])?'https':'http').'://'.$_SERVER['HTTP_HOST']);
|
||||
error_reporting(E_ALL & ~E_NOTICE);
|
||||
if(SHOW_ERRORS)
|
||||
ini_set('display_errors','On');
|
||||
else ini_set('display_errors','Off');
|
||||
|
||||
//loading core and controllers
|
||||
include_once(ROOT.DS.'inc'.DS.'core.php');
|
||||
$url = $_GET['url'];
|
||||
removeMagicQuotes();
|
||||
$GLOBALS['params'] = explode('/', $_GET['url']);
|
||||
callHook();
|
||||
loadAllContentControllers();
|
||||
|
||||
//load external things if existing
|
||||
if(file_exists(ROOT.'/lib/vendor/autoload.php'))
|
||||
require ROOT.'/lib/vendor/autoload.php';
|
||||
|
||||
|
||||
//send the URL to the architect. It'll know what to do
|
||||
$url = $_GET['url']?$_GET['url']:ltrim($_SERVER['REQUEST_URI'],'/');
|
||||
architect($url);
|
||||
45
interfaces/contentcontroller.interface.php
Normal file
45
interfaces/contentcontroller.interface.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Content controller interface for new content types
|
||||
*/
|
||||
|
||||
interface ContentController
|
||||
{
|
||||
/**
|
||||
* When implementing a new content controller, you must specify a constant with the name of "ctype"
|
||||
* This constant will be used to distinguish static controllers (which have files on disk) from dynamic ones (which don't, like the placeholder controller)
|
||||
*
|
||||
* Possible values: 'static' or 'dynamic'
|
||||
*/
|
||||
//const ctype = 'static';
|
||||
|
||||
/** This method will return all file extensions that will be associated with this content type
|
||||
* for example 'pdf' but it could be anything really. You just need a way later to confirm that a type is what it says it is
|
||||
*
|
||||
*
|
||||
* @return array the extensions of files associated with this controller. eg. return array('pdf');
|
||||
*/
|
||||
public function getRegisteredExtensions();
|
||||
|
||||
/** This method will be called whenever the system has to find out if a user requested (existing) hash
|
||||
* belongs to this controller.
|
||||
* In here the content should be rendered or processed like resized or something.
|
||||
* You can decide what it does by working with the $url array which gives you every element in the URL
|
||||
* Does not need to return anything for example you can just set the header and print your data right away
|
||||
*
|
||||
* @param string $hash the hash (with extension eg '5saB2.pdf') of the file this controller will work with
|
||||
* @param array $url contains all URL elements exploded with '/' so you can do your magic.
|
||||
*/
|
||||
public function handleHash($hash,$url);
|
||||
|
||||
/** This method will be called if the upload script detects the content of a newly uploaded file as one of the
|
||||
* extensions registered at "getRegisteredExtensions".
|
||||
* For Example if someone uploads a PDF and getRegisteredExtensions has registered "pdf", then this method of this
|
||||
* controller will be called
|
||||
*
|
||||
* @param string $tmpfile is the location on disk of the temp file that was uploaded. It is your job to put it somewhere, your handleHash method will find it again
|
||||
* @param array $hash (optional) if you want your upload to have a certain hash then add it here. This allows for user chosen hashes
|
||||
*/
|
||||
public function handleUpload($tmpfile,$hash=false);
|
||||
}
|
||||
69
interfaces/storagecontroller.interface.php
Normal file
69
interfaces/storagecontroller.interface.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/**
|
||||
* StorageController interface
|
||||
*
|
||||
* Must be implemented by all storage systems
|
||||
*/
|
||||
|
||||
interface StorageController
|
||||
{
|
||||
/**
|
||||
* Checks if this storage system is enabled.
|
||||
* For example check if all depenencies are met
|
||||
* or config vars are set
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function isEnabled();
|
||||
|
||||
/**
|
||||
* Is fired whenever a hash is not found locally
|
||||
* Use this to look in your storage system for the file
|
||||
*
|
||||
* @param string $hash is the hash of the file requested
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function hashExists($hash);
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of all items in this storage controller
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getItems();
|
||||
|
||||
/**
|
||||
* If a file does exist in this storage system, then this method should
|
||||
* get the file and put it in the default data directory
|
||||
*
|
||||
* The file should be placed in /data/$hash/$hash where the first $hash is obviously
|
||||
* a folder that you might have to create first before putting the file in
|
||||
*
|
||||
* @param string $hash is the hash of the file that should be pulled from this storage system
|
||||
* @param string $location is the location where the downloaded file should be placed
|
||||
*
|
||||
* @return bool true if successful
|
||||
*/
|
||||
function pullFile($hash,$location);
|
||||
|
||||
/**
|
||||
* Whenever a new file is uploaded this method will be called
|
||||
* You should then upload it or do whatever your storage system is meant to do with new files
|
||||
*
|
||||
* @param string $hash is the hash of the new file. The file path of this file is always getDataDir().DS.$hash.DS.$hash
|
||||
*
|
||||
* @return bool true if successful
|
||||
*/
|
||||
function pushFile($source,$hash);
|
||||
|
||||
/**
|
||||
* If deletion of a file is requested, this method is called
|
||||
*
|
||||
* @param string $hash is the hash of the file. Delete this hash from your storage system
|
||||
*
|
||||
* @return bool true if successful
|
||||
*/
|
||||
function deleteFile($hash);
|
||||
}
|
||||
3530
js/dropzone.js
Normal file
3530
js/dropzone.js
Normal file
File diff suppressed because it is too large
Load Diff
2
js/highlight.pack.js
Normal file
2
js/highlight.pack.js
Normal file
File diff suppressed because one or more lines are too long
40
js/pictshare.js
Normal file
40
js/pictshare.js
Normal file
@@ -0,0 +1,40 @@
|
||||
Dropzone.autoDiscover = false;
|
||||
|
||||
$(function () {
|
||||
var myDropzone = new Dropzone("#dropzone");
|
||||
//console.log(myDropzone.options);
|
||||
if (maxUploadFileSize !== undefined)
|
||||
myDropzone.options.maxFilesize = maxUploadFileSize;
|
||||
myDropzone.options.timeout = 0,
|
||||
myDropzone.on("sending", function(file, xhr, formData) {
|
||||
if(document.getElementById("uploadcode"))
|
||||
formData.append("uploadcode", document.getElementById("uploadcode").value);
|
||||
});
|
||||
myDropzone.on('error', function(file, response) {
|
||||
alert("Error: "+response.reason);
|
||||
});
|
||||
myDropzone.on("success", function (file, response) {
|
||||
console.log("raw response: " + response);
|
||||
if (response == null || response == "null")
|
||||
$("#uploadinfo").append("<div class='alert alert-danger' role='alert'><strong>Error uploading " + file.name + "</strong><br/>Reason is unknown :(</div>")
|
||||
else {
|
||||
var o = response;
|
||||
if (o.status == 'ok')
|
||||
$("#uploadinfo").append("<div class='alert alert-success' role='alert'><strong>" + file.name + "</strong> uploaded as <a target='_blank' href='/" + o.hash + "'>" + o.hash + "</a><br/>URL: <a target='_blank' href='" + o.url + "'>" + o.url + "</a> <button class='btn btn-xs' onClick='navigator.clipboard.writeText(\"" + o.url + "\");'>Copy URL</button></div>")
|
||||
else if (o.status == 'err')
|
||||
$("#uploadinfo").append("<div class='alert alert-danger' role='alert'><strong>Error uploading " + file.name + "</strong><br/>Reason: " + o.reason + "</div>")
|
||||
console.log(o)
|
||||
}
|
||||
});
|
||||
|
||||
document.onpaste = function (event) {
|
||||
var items = (event.clipboardData || event.originalEvent.clipboardData).items;
|
||||
for (index in items) {
|
||||
var item = items[index];
|
||||
if (item.kind === 'file') {
|
||||
// adds the file to your dropzone instance
|
||||
myDropzone.addFile(item.getAsFile())
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
99
js/styles/a11y-dark.css
Normal file
99
js/styles/a11y-dark.css
Normal file
@@ -0,0 +1,99 @@
|
||||
/* a11y-dark theme */
|
||||
/* Based on the Tomorrow Night Eighties theme: https://github.com/isagalaev/highlight.js/blob/master/src/styles/tomorrow-night-eighties.css */
|
||||
/* @author: ericwbailey */
|
||||
|
||||
/* Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #d4d0ab;
|
||||
}
|
||||
|
||||
/* Red */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-regexp,
|
||||
.hljs-deletion {
|
||||
color: #ffa07a;
|
||||
}
|
||||
|
||||
/* Orange */
|
||||
.hljs-number,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params,
|
||||
.hljs-meta,
|
||||
.hljs-link {
|
||||
color: #f5ab35;
|
||||
}
|
||||
|
||||
/* Yellow */
|
||||
.hljs-attribute {
|
||||
color: #ffd700;
|
||||
}
|
||||
|
||||
/* Green */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-addition {
|
||||
color: #abe338;
|
||||
}
|
||||
|
||||
/* Blue */
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #00e0e0;
|
||||
}
|
||||
|
||||
/* Purple */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #dcc6e0;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #2b2b2b;
|
||||
color: #f8f8f2;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@media screen and (-ms-high-contrast: active) {
|
||||
.hljs-addition,
|
||||
.hljs-attribute,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-bullet,
|
||||
.hljs-comment,
|
||||
.hljs-link,
|
||||
.hljs-literal,
|
||||
.hljs-meta,
|
||||
.hljs-number,
|
||||
.hljs-params,
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-type,
|
||||
.hljs-quote {
|
||||
color: highlight;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
99
js/styles/a11y-light.css
Normal file
99
js/styles/a11y-light.css
Normal file
@@ -0,0 +1,99 @@
|
||||
/* a11y-light theme */
|
||||
/* Based on the Tomorrow Night Eighties theme: https://github.com/isagalaev/highlight.js/blob/master/src/styles/tomorrow-night-eighties.css */
|
||||
/* @author: ericwbailey */
|
||||
|
||||
/* Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #696969;
|
||||
}
|
||||
|
||||
/* Red */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-regexp,
|
||||
.hljs-deletion {
|
||||
color: #d91e18;
|
||||
}
|
||||
|
||||
/* Orange */
|
||||
.hljs-number,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params,
|
||||
.hljs-meta,
|
||||
.hljs-link {
|
||||
color: #aa5d00;
|
||||
}
|
||||
|
||||
/* Yellow */
|
||||
.hljs-attribute {
|
||||
color: #aa5d00;
|
||||
}
|
||||
|
||||
/* Green */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-addition {
|
||||
color: #008000;
|
||||
}
|
||||
|
||||
/* Blue */
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #007faa;
|
||||
}
|
||||
|
||||
/* Purple */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #7928a1;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #fefefe;
|
||||
color: #545454;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@media screen and (-ms-high-contrast: active) {
|
||||
.hljs-addition,
|
||||
.hljs-attribute,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-bullet,
|
||||
.hljs-comment,
|
||||
.hljs-link,
|
||||
.hljs-literal,
|
||||
.hljs-meta,
|
||||
.hljs-number,
|
||||
.hljs-params,
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-type,
|
||||
.hljs-quote {
|
||||
color: highlight;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
108
js/styles/agate.css
Normal file
108
js/styles/agate.css
Normal file
@@ -0,0 +1,108 @@
|
||||
/*!
|
||||
* Agate by Taufik Nurrohman <https://github.com/tovic>
|
||||
* ----------------------------------------------------
|
||||
*
|
||||
* #ade5fc
|
||||
* #a2fca2
|
||||
* #c6b4f0
|
||||
* #d36363
|
||||
* #fcc28c
|
||||
* #fc9b9b
|
||||
* #ffa
|
||||
* #fff
|
||||
* #333
|
||||
* #62c8f3
|
||||
* #888
|
||||
*
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #333;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.hljs-name,
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-code,
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-tag {
|
||||
color: #62c8f3;
|
||||
}
|
||||
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #ade5fc;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-bullet {
|
||||
color: #a2fca2;
|
||||
}
|
||||
|
||||
.hljs-type,
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-attribute,
|
||||
.hljs-quote,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name {
|
||||
color: #ffa;
|
||||
}
|
||||
|
||||
.hljs-number,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #d36363;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-literal {
|
||||
color: #fcc28c;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-deletion,
|
||||
.hljs-code {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.hljs-regexp,
|
||||
.hljs-link {
|
||||
color: #c6b4f0;
|
||||
}
|
||||
|
||||
.hljs-meta {
|
||||
color: #fc9b9b;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
background-color: #fc9b9b;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
background-color: #a2fca2;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.hljs a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.hljs a:focus,
|
||||
.hljs a:hover {
|
||||
color: inherit;
|
||||
text-decoration: underline;
|
||||
}
|
||||
89
js/styles/an-old-hope.css
Normal file
89
js/styles/an-old-hope.css
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
|
||||
An Old Hope – Star Wars Syntax (c) Gustavo Costa <gusbemacbe@gmail.com>
|
||||
Original theme - Ocean Dark Theme – by https://github.com/gavsiu
|
||||
Based on Jesse Leite's Atom syntax theme 'An Old Hope' – https://github.com/JesseLeite/an-old-hope-syntax-atom
|
||||
|
||||
*/
|
||||
|
||||
/* Death Star Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote
|
||||
{
|
||||
color: #B6B18B;
|
||||
}
|
||||
|
||||
/* Darth Vader */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-regexp,
|
||||
.hljs-deletion
|
||||
{
|
||||
color: #EB3C54;
|
||||
}
|
||||
|
||||
/* Threepio */
|
||||
.hljs-number,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params,
|
||||
.hljs-meta,
|
||||
.hljs-link
|
||||
{
|
||||
color: #E7CE56;
|
||||
}
|
||||
|
||||
/* Luke Skywalker */
|
||||
.hljs-attribute
|
||||
{
|
||||
color: #EE7C2B;
|
||||
}
|
||||
|
||||
/* Obi Wan Kenobi */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-addition
|
||||
{
|
||||
color: #4FB4D7;
|
||||
}
|
||||
|
||||
/* Yoda */
|
||||
.hljs-title,
|
||||
.hljs-section
|
||||
{
|
||||
color: #78BB65;
|
||||
}
|
||||
|
||||
/* Mace Windu */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag
|
||||
{
|
||||
color: #B45EA4;
|
||||
}
|
||||
|
||||
/* Millenium Falcon */
|
||||
.hljs
|
||||
{
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #1C1D21;
|
||||
color: #c0c5ce;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-emphasis
|
||||
{
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong
|
||||
{
|
||||
font-weight: bold;
|
||||
}
|
||||
66
js/styles/androidstudio.css
Normal file
66
js/styles/androidstudio.css
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
Date: 24 Fev 2015
|
||||
Author: Pedro Oliveira <kanytu@gmail . com>
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
color: #a9b7c6;
|
||||
background: #282b2e;
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-number,
|
||||
.hljs-literal,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #6897BB;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-deletion {
|
||||
color: #cc7832;
|
||||
}
|
||||
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-link {
|
||||
color: #629755;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #808080;
|
||||
}
|
||||
|
||||
.hljs-meta {
|
||||
color: #bbb529;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-attribute,
|
||||
.hljs-addition {
|
||||
color: #6A8759;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-title,
|
||||
.hljs-type {
|
||||
color: #ffc66d;
|
||||
}
|
||||
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #e8bf6a;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
88
js/styles/arduino-light.css
Normal file
88
js/styles/arduino-light.css
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
|
||||
Arduino® Light Theme - Stefania Mellai <s.mellai@arduino.cc>
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #FFFFFF;
|
||||
}
|
||||
|
||||
.hljs,
|
||||
.hljs-subst {
|
||||
color: #434f54;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-attribute,
|
||||
.hljs-selector-tag,
|
||||
.hljs-doctag,
|
||||
.hljs-name {
|
||||
color: #00979D;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-literal,
|
||||
.hljs-bullet,
|
||||
.hljs-code,
|
||||
.hljs-addition {
|
||||
color: #D35400;
|
||||
}
|
||||
|
||||
.hljs-regexp,
|
||||
.hljs-symbol,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-link,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo {
|
||||
color: #00979D;
|
||||
}
|
||||
|
||||
.hljs-type,
|
||||
.hljs-string,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-quote,
|
||||
.hljs-template-tag,
|
||||
.hljs-deletion {
|
||||
color: #005C5F;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #880000;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-comment {
|
||||
color: rgba(149,165,166,.8);
|
||||
}
|
||||
|
||||
.hljs-meta-keyword {
|
||||
color: #728E00;
|
||||
}
|
||||
|
||||
.hljs-meta {
|
||||
color: #728E00;
|
||||
color: #434f54;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-function {
|
||||
color: #728E00;
|
||||
}
|
||||
|
||||
.hljs-number {
|
||||
color: #8A7B52;
|
||||
}
|
||||
73
js/styles/arta.css
Normal file
73
js/styles/arta.css
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
Date: 17.V.2011
|
||||
Author: pumbur <pumbur@pumbur.net>
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #222;
|
||||
}
|
||||
|
||||
.hljs,
|
||||
.hljs-subst {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.hljs-section {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote,
|
||||
.hljs-meta {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-regexp {
|
||||
color: #ffcc33;
|
||||
}
|
||||
|
||||
.hljs-number,
|
||||
.hljs-addition {
|
||||
color: #00cc66;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-link {
|
||||
color: #32aaee;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #6644aa;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-variable,
|
||||
.hljs-deletion,
|
||||
.hljs-template-tag {
|
||||
color: #bb1166;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-doctag,
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
45
js/styles/ascetic.css
Normal file
45
js/styles/ascetic.css
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
|
||||
Original style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org>
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: white;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-section,
|
||||
.hljs-addition,
|
||||
.hljs-attribute,
|
||||
.hljs-link {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote,
|
||||
.hljs-meta,
|
||||
.hljs-deletion {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-section,
|
||||
.hljs-name,
|
||||
.hljs-type,
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
83
js/styles/atelier-cave-dark.css
Normal file
83
js/styles/atelier-cave-dark.css
Normal file
@@ -0,0 +1,83 @@
|
||||
/* Base16 Atelier Cave Dark - Theme */
|
||||
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave) */
|
||||
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
|
||||
|
||||
/* Atelier-Cave Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #7e7887;
|
||||
}
|
||||
|
||||
/* Atelier-Cave Red */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #be4678;
|
||||
}
|
||||
|
||||
/* Atelier-Cave Orange */
|
||||
.hljs-number,
|
||||
.hljs-meta,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params {
|
||||
color: #aa573c;
|
||||
}
|
||||
|
||||
/* Atelier-Cave Green */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #2a9292;
|
||||
}
|
||||
|
||||
/* Atelier-Cave Blue */
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #576ddb;
|
||||
}
|
||||
|
||||
/* Atelier-Cave Purple */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #955ae7;
|
||||
}
|
||||
|
||||
.hljs-deletion,
|
||||
.hljs-addition {
|
||||
color: #19171c;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
background-color: #be4678;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
background-color: #2a9292;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #19171c;
|
||||
color: #8b8792;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
85
js/styles/atelier-cave-light.css
Normal file
85
js/styles/atelier-cave-light.css
Normal file
@@ -0,0 +1,85 @@
|
||||
/* Base16 Atelier Cave Light - Theme */
|
||||
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave) */
|
||||
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
|
||||
|
||||
/* Atelier-Cave Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #655f6d;
|
||||
}
|
||||
|
||||
/* Atelier-Cave Red */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-name,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #be4678;
|
||||
}
|
||||
|
||||
/* Atelier-Cave Orange */
|
||||
.hljs-number,
|
||||
.hljs-meta,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params {
|
||||
color: #aa573c;
|
||||
}
|
||||
|
||||
/* Atelier-Cave Green */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #2a9292;
|
||||
}
|
||||
|
||||
/* Atelier-Cave Blue */
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #576ddb;
|
||||
}
|
||||
|
||||
/* Atelier-Cave Purple */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #955ae7;
|
||||
}
|
||||
|
||||
.hljs-deletion,
|
||||
.hljs-addition {
|
||||
color: #19171c;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
background-color: #be4678;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
background-color: #2a9292;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #efecf4;
|
||||
color: #585260;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
69
js/styles/atelier-dune-dark.css
Normal file
69
js/styles/atelier-dune-dark.css
Normal file
@@ -0,0 +1,69 @@
|
||||
/* Base16 Atelier Dune Dark - Theme */
|
||||
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune) */
|
||||
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
|
||||
|
||||
/* Atelier-Dune Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #999580;
|
||||
}
|
||||
|
||||
/* Atelier-Dune Red */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #d73737;
|
||||
}
|
||||
|
||||
/* Atelier-Dune Orange */
|
||||
.hljs-number,
|
||||
.hljs-meta,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params {
|
||||
color: #b65611;
|
||||
}
|
||||
|
||||
/* Atelier-Dune Green */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #60ac39;
|
||||
}
|
||||
|
||||
/* Atelier-Dune Blue */
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #6684e1;
|
||||
}
|
||||
|
||||
/* Atelier-Dune Purple */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #b854d4;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #20201d;
|
||||
color: #a6a28c;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
69
js/styles/atelier-dune-light.css
Normal file
69
js/styles/atelier-dune-light.css
Normal file
@@ -0,0 +1,69 @@
|
||||
/* Base16 Atelier Dune Light - Theme */
|
||||
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune) */
|
||||
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
|
||||
|
||||
/* Atelier-Dune Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #7d7a68;
|
||||
}
|
||||
|
||||
/* Atelier-Dune Red */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #d73737;
|
||||
}
|
||||
|
||||
/* Atelier-Dune Orange */
|
||||
.hljs-number,
|
||||
.hljs-meta,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params {
|
||||
color: #b65611;
|
||||
}
|
||||
|
||||
/* Atelier-Dune Green */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #60ac39;
|
||||
}
|
||||
|
||||
/* Atelier-Dune Blue */
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #6684e1;
|
||||
}
|
||||
|
||||
/* Atelier-Dune Purple */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #b854d4;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #fefbec;
|
||||
color: #6e6b5e;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
84
js/styles/atelier-estuary-dark.css
Normal file
84
js/styles/atelier-estuary-dark.css
Normal file
@@ -0,0 +1,84 @@
|
||||
/* Base16 Atelier Estuary Dark - Theme */
|
||||
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/estuary) */
|
||||
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
|
||||
|
||||
/* Atelier-Estuary Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #878573;
|
||||
}
|
||||
|
||||
/* Atelier-Estuary Red */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #ba6236;
|
||||
}
|
||||
|
||||
/* Atelier-Estuary Orange */
|
||||
.hljs-number,
|
||||
.hljs-meta,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params {
|
||||
color: #ae7313;
|
||||
}
|
||||
|
||||
/* Atelier-Estuary Green */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #7d9726;
|
||||
}
|
||||
|
||||
/* Atelier-Estuary Blue */
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #36a166;
|
||||
}
|
||||
|
||||
/* Atelier-Estuary Purple */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #5f9182;
|
||||
}
|
||||
|
||||
.hljs-deletion,
|
||||
.hljs-addition {
|
||||
color: #22221b;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
background-color: #ba6236;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
background-color: #7d9726;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #22221b;
|
||||
color: #929181;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
84
js/styles/atelier-estuary-light.css
Normal file
84
js/styles/atelier-estuary-light.css
Normal file
@@ -0,0 +1,84 @@
|
||||
/* Base16 Atelier Estuary Light - Theme */
|
||||
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/estuary) */
|
||||
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
|
||||
|
||||
/* Atelier-Estuary Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #6c6b5a;
|
||||
}
|
||||
|
||||
/* Atelier-Estuary Red */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #ba6236;
|
||||
}
|
||||
|
||||
/* Atelier-Estuary Orange */
|
||||
.hljs-number,
|
||||
.hljs-meta,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params {
|
||||
color: #ae7313;
|
||||
}
|
||||
|
||||
/* Atelier-Estuary Green */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #7d9726;
|
||||
}
|
||||
|
||||
/* Atelier-Estuary Blue */
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #36a166;
|
||||
}
|
||||
|
||||
/* Atelier-Estuary Purple */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #5f9182;
|
||||
}
|
||||
|
||||
.hljs-deletion,
|
||||
.hljs-addition {
|
||||
color: #22221b;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
background-color: #ba6236;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
background-color: #7d9726;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #f4f3ec;
|
||||
color: #5f5e4e;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
69
js/styles/atelier-forest-dark.css
Normal file
69
js/styles/atelier-forest-dark.css
Normal file
@@ -0,0 +1,69 @@
|
||||
/* Base16 Atelier Forest Dark - Theme */
|
||||
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/forest) */
|
||||
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
|
||||
|
||||
/* Atelier-Forest Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #9c9491;
|
||||
}
|
||||
|
||||
/* Atelier-Forest Red */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #f22c40;
|
||||
}
|
||||
|
||||
/* Atelier-Forest Orange */
|
||||
.hljs-number,
|
||||
.hljs-meta,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params {
|
||||
color: #df5320;
|
||||
}
|
||||
|
||||
/* Atelier-Forest Green */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #7b9726;
|
||||
}
|
||||
|
||||
/* Atelier-Forest Blue */
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #407ee7;
|
||||
}
|
||||
|
||||
/* Atelier-Forest Purple */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #6666ea;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #1b1918;
|
||||
color: #a8a19f;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
69
js/styles/atelier-forest-light.css
Normal file
69
js/styles/atelier-forest-light.css
Normal file
@@ -0,0 +1,69 @@
|
||||
/* Base16 Atelier Forest Light - Theme */
|
||||
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/forest) */
|
||||
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
|
||||
|
||||
/* Atelier-Forest Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #766e6b;
|
||||
}
|
||||
|
||||
/* Atelier-Forest Red */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #f22c40;
|
||||
}
|
||||
|
||||
/* Atelier-Forest Orange */
|
||||
.hljs-number,
|
||||
.hljs-meta,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params {
|
||||
color: #df5320;
|
||||
}
|
||||
|
||||
/* Atelier-Forest Green */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #7b9726;
|
||||
}
|
||||
|
||||
/* Atelier-Forest Blue */
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #407ee7;
|
||||
}
|
||||
|
||||
/* Atelier-Forest Purple */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #6666ea;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #f1efee;
|
||||
color: #68615e;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
69
js/styles/atelier-heath-dark.css
Normal file
69
js/styles/atelier-heath-dark.css
Normal file
@@ -0,0 +1,69 @@
|
||||
/* Base16 Atelier Heath Dark - Theme */
|
||||
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/heath) */
|
||||
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
|
||||
|
||||
/* Atelier-Heath Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #9e8f9e;
|
||||
}
|
||||
|
||||
/* Atelier-Heath Red */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #ca402b;
|
||||
}
|
||||
|
||||
/* Atelier-Heath Orange */
|
||||
.hljs-number,
|
||||
.hljs-meta,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params {
|
||||
color: #a65926;
|
||||
}
|
||||
|
||||
/* Atelier-Heath Green */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #918b3b;
|
||||
}
|
||||
|
||||
/* Atelier-Heath Blue */
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #516aec;
|
||||
}
|
||||
|
||||
/* Atelier-Heath Purple */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #7b59c0;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #1b181b;
|
||||
color: #ab9bab;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
69
js/styles/atelier-heath-light.css
Normal file
69
js/styles/atelier-heath-light.css
Normal file
@@ -0,0 +1,69 @@
|
||||
/* Base16 Atelier Heath Light - Theme */
|
||||
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/heath) */
|
||||
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
|
||||
|
||||
/* Atelier-Heath Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #776977;
|
||||
}
|
||||
|
||||
/* Atelier-Heath Red */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #ca402b;
|
||||
}
|
||||
|
||||
/* Atelier-Heath Orange */
|
||||
.hljs-number,
|
||||
.hljs-meta,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params {
|
||||
color: #a65926;
|
||||
}
|
||||
|
||||
/* Atelier-Heath Green */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #918b3b;
|
||||
}
|
||||
|
||||
/* Atelier-Heath Blue */
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #516aec;
|
||||
}
|
||||
|
||||
/* Atelier-Heath Purple */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #7b59c0;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #f7f3f7;
|
||||
color: #695d69;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
69
js/styles/atelier-lakeside-dark.css
Normal file
69
js/styles/atelier-lakeside-dark.css
Normal file
@@ -0,0 +1,69 @@
|
||||
/* Base16 Atelier Lakeside Dark - Theme */
|
||||
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/lakeside) */
|
||||
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
|
||||
|
||||
/* Atelier-Lakeside Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #7195a8;
|
||||
}
|
||||
|
||||
/* Atelier-Lakeside Red */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #d22d72;
|
||||
}
|
||||
|
||||
/* Atelier-Lakeside Orange */
|
||||
.hljs-number,
|
||||
.hljs-meta,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params {
|
||||
color: #935c25;
|
||||
}
|
||||
|
||||
/* Atelier-Lakeside Green */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #568c3b;
|
||||
}
|
||||
|
||||
/* Atelier-Lakeside Blue */
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #257fad;
|
||||
}
|
||||
|
||||
/* Atelier-Lakeside Purple */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #6b6bb8;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #161b1d;
|
||||
color: #7ea2b4;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
69
js/styles/atelier-lakeside-light.css
Normal file
69
js/styles/atelier-lakeside-light.css
Normal file
@@ -0,0 +1,69 @@
|
||||
/* Base16 Atelier Lakeside Light - Theme */
|
||||
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/lakeside) */
|
||||
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
|
||||
|
||||
/* Atelier-Lakeside Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #5a7b8c;
|
||||
}
|
||||
|
||||
/* Atelier-Lakeside Red */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #d22d72;
|
||||
}
|
||||
|
||||
/* Atelier-Lakeside Orange */
|
||||
.hljs-number,
|
||||
.hljs-meta,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params {
|
||||
color: #935c25;
|
||||
}
|
||||
|
||||
/* Atelier-Lakeside Green */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #568c3b;
|
||||
}
|
||||
|
||||
/* Atelier-Lakeside Blue */
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #257fad;
|
||||
}
|
||||
|
||||
/* Atelier-Lakeside Purple */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #6b6bb8;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #ebf8ff;
|
||||
color: #516d7b;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
84
js/styles/atelier-plateau-dark.css
Normal file
84
js/styles/atelier-plateau-dark.css
Normal file
@@ -0,0 +1,84 @@
|
||||
/* Base16 Atelier Plateau Dark - Theme */
|
||||
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/plateau) */
|
||||
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
|
||||
|
||||
/* Atelier-Plateau Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #7e7777;
|
||||
}
|
||||
|
||||
/* Atelier-Plateau Red */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #ca4949;
|
||||
}
|
||||
|
||||
/* Atelier-Plateau Orange */
|
||||
.hljs-number,
|
||||
.hljs-meta,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params {
|
||||
color: #b45a3c;
|
||||
}
|
||||
|
||||
/* Atelier-Plateau Green */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #4b8b8b;
|
||||
}
|
||||
|
||||
/* Atelier-Plateau Blue */
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #7272ca;
|
||||
}
|
||||
|
||||
/* Atelier-Plateau Purple */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #8464c4;
|
||||
}
|
||||
|
||||
.hljs-deletion,
|
||||
.hljs-addition {
|
||||
color: #1b1818;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
background-color: #ca4949;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
background-color: #4b8b8b;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #1b1818;
|
||||
color: #8a8585;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
84
js/styles/atelier-plateau-light.css
Normal file
84
js/styles/atelier-plateau-light.css
Normal file
@@ -0,0 +1,84 @@
|
||||
/* Base16 Atelier Plateau Light - Theme */
|
||||
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/plateau) */
|
||||
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
|
||||
|
||||
/* Atelier-Plateau Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #655d5d;
|
||||
}
|
||||
|
||||
/* Atelier-Plateau Red */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #ca4949;
|
||||
}
|
||||
|
||||
/* Atelier-Plateau Orange */
|
||||
.hljs-number,
|
||||
.hljs-meta,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params {
|
||||
color: #b45a3c;
|
||||
}
|
||||
|
||||
/* Atelier-Plateau Green */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #4b8b8b;
|
||||
}
|
||||
|
||||
/* Atelier-Plateau Blue */
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #7272ca;
|
||||
}
|
||||
|
||||
/* Atelier-Plateau Purple */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #8464c4;
|
||||
}
|
||||
|
||||
.hljs-deletion,
|
||||
.hljs-addition {
|
||||
color: #1b1818;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
background-color: #ca4949;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
background-color: #4b8b8b;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #f4ecec;
|
||||
color: #585050;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
84
js/styles/atelier-savanna-dark.css
Normal file
84
js/styles/atelier-savanna-dark.css
Normal file
@@ -0,0 +1,84 @@
|
||||
/* Base16 Atelier Savanna Dark - Theme */
|
||||
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/savanna) */
|
||||
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
|
||||
|
||||
/* Atelier-Savanna Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #78877d;
|
||||
}
|
||||
|
||||
/* Atelier-Savanna Red */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #b16139;
|
||||
}
|
||||
|
||||
/* Atelier-Savanna Orange */
|
||||
.hljs-number,
|
||||
.hljs-meta,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params {
|
||||
color: #9f713c;
|
||||
}
|
||||
|
||||
/* Atelier-Savanna Green */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #489963;
|
||||
}
|
||||
|
||||
/* Atelier-Savanna Blue */
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #478c90;
|
||||
}
|
||||
|
||||
/* Atelier-Savanna Purple */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #55859b;
|
||||
}
|
||||
|
||||
.hljs-deletion,
|
||||
.hljs-addition {
|
||||
color: #171c19;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
background-color: #b16139;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
background-color: #489963;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #171c19;
|
||||
color: #87928a;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
84
js/styles/atelier-savanna-light.css
Normal file
84
js/styles/atelier-savanna-light.css
Normal file
@@ -0,0 +1,84 @@
|
||||
/* Base16 Atelier Savanna Light - Theme */
|
||||
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/savanna) */
|
||||
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
|
||||
|
||||
/* Atelier-Savanna Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #5f6d64;
|
||||
}
|
||||
|
||||
/* Atelier-Savanna Red */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #b16139;
|
||||
}
|
||||
|
||||
/* Atelier-Savanna Orange */
|
||||
.hljs-number,
|
||||
.hljs-meta,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params {
|
||||
color: #9f713c;
|
||||
}
|
||||
|
||||
/* Atelier-Savanna Green */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #489963;
|
||||
}
|
||||
|
||||
/* Atelier-Savanna Blue */
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #478c90;
|
||||
}
|
||||
|
||||
/* Atelier-Savanna Purple */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #55859b;
|
||||
}
|
||||
|
||||
.hljs-deletion,
|
||||
.hljs-addition {
|
||||
color: #171c19;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
background-color: #b16139;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
background-color: #489963;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #ecf4ee;
|
||||
color: #526057;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
69
js/styles/atelier-seaside-dark.css
Normal file
69
js/styles/atelier-seaside-dark.css
Normal file
@@ -0,0 +1,69 @@
|
||||
/* Base16 Atelier Seaside Dark - Theme */
|
||||
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/seaside) */
|
||||
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
|
||||
|
||||
/* Atelier-Seaside Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #809980;
|
||||
}
|
||||
|
||||
/* Atelier-Seaside Red */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #e6193c;
|
||||
}
|
||||
|
||||
/* Atelier-Seaside Orange */
|
||||
.hljs-number,
|
||||
.hljs-meta,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params {
|
||||
color: #87711d;
|
||||
}
|
||||
|
||||
/* Atelier-Seaside Green */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #29a329;
|
||||
}
|
||||
|
||||
/* Atelier-Seaside Blue */
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #3d62f5;
|
||||
}
|
||||
|
||||
/* Atelier-Seaside Purple */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #ad2bee;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #131513;
|
||||
color: #8ca68c;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
69
js/styles/atelier-seaside-light.css
Normal file
69
js/styles/atelier-seaside-light.css
Normal file
@@ -0,0 +1,69 @@
|
||||
/* Base16 Atelier Seaside Light - Theme */
|
||||
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/seaside) */
|
||||
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
|
||||
|
||||
/* Atelier-Seaside Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #687d68;
|
||||
}
|
||||
|
||||
/* Atelier-Seaside Red */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #e6193c;
|
||||
}
|
||||
|
||||
/* Atelier-Seaside Orange */
|
||||
.hljs-number,
|
||||
.hljs-meta,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params {
|
||||
color: #87711d;
|
||||
}
|
||||
|
||||
/* Atelier-Seaside Green */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #29a329;
|
||||
}
|
||||
|
||||
/* Atelier-Seaside Blue */
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #3d62f5;
|
||||
}
|
||||
|
||||
/* Atelier-Seaside Purple */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #ad2bee;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #f4fbf4;
|
||||
color: #5e6e5e;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
69
js/styles/atelier-sulphurpool-dark.css
Normal file
69
js/styles/atelier-sulphurpool-dark.css
Normal file
@@ -0,0 +1,69 @@
|
||||
/* Base16 Atelier Sulphurpool Dark - Theme */
|
||||
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/sulphurpool) */
|
||||
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
|
||||
|
||||
/* Atelier-Sulphurpool Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #898ea4;
|
||||
}
|
||||
|
||||
/* Atelier-Sulphurpool Red */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #c94922;
|
||||
}
|
||||
|
||||
/* Atelier-Sulphurpool Orange */
|
||||
.hljs-number,
|
||||
.hljs-meta,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params {
|
||||
color: #c76b29;
|
||||
}
|
||||
|
||||
/* Atelier-Sulphurpool Green */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #ac9739;
|
||||
}
|
||||
|
||||
/* Atelier-Sulphurpool Blue */
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #3d8fd1;
|
||||
}
|
||||
|
||||
/* Atelier-Sulphurpool Purple */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #6679cc;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #202746;
|
||||
color: #979db4;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
69
js/styles/atelier-sulphurpool-light.css
Normal file
69
js/styles/atelier-sulphurpool-light.css
Normal file
@@ -0,0 +1,69 @@
|
||||
/* Base16 Atelier Sulphurpool Light - Theme */
|
||||
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/sulphurpool) */
|
||||
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
|
||||
|
||||
/* Atelier-Sulphurpool Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #6b7394;
|
||||
}
|
||||
|
||||
/* Atelier-Sulphurpool Red */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #c94922;
|
||||
}
|
||||
|
||||
/* Atelier-Sulphurpool Orange */
|
||||
.hljs-number,
|
||||
.hljs-meta,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params {
|
||||
color: #c76b29;
|
||||
}
|
||||
|
||||
/* Atelier-Sulphurpool Green */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #ac9739;
|
||||
}
|
||||
|
||||
/* Atelier-Sulphurpool Blue */
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #3d8fd1;
|
||||
}
|
||||
|
||||
/* Atelier-Sulphurpool Purple */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #6679cc;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #f5f7ff;
|
||||
color: #5e6687;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
77
js/styles/atom-one-dark-reasonable.css
Normal file
77
js/styles/atom-one-dark-reasonable.css
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
|
||||
Atom One Dark With support for ReasonML by Gidi Morris, based off work by Daniel Gamage
|
||||
|
||||
Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax
|
||||
|
||||
*/
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
line-height: 1.3em;
|
||||
color: #abb2bf;
|
||||
background: #282c34;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.hljs-keyword, .hljs-operator {
|
||||
color: #F92672;
|
||||
}
|
||||
.hljs-pattern-match {
|
||||
color: #F92672;
|
||||
}
|
||||
.hljs-pattern-match .hljs-constructor {
|
||||
color: #61aeee;
|
||||
}
|
||||
.hljs-function {
|
||||
color: #61aeee;
|
||||
}
|
||||
.hljs-function .hljs-params {
|
||||
color: #A6E22E;
|
||||
}
|
||||
.hljs-function .hljs-params .hljs-typing {
|
||||
color: #FD971F;
|
||||
}
|
||||
.hljs-module-access .hljs-module {
|
||||
color: #7e57c2;
|
||||
}
|
||||
.hljs-constructor {
|
||||
color: #e2b93d;
|
||||
}
|
||||
.hljs-constructor .hljs-string {
|
||||
color: #9CCC65;
|
||||
}
|
||||
.hljs-comment, .hljs-quote {
|
||||
color: #b18eb1;
|
||||
font-style: italic;
|
||||
}
|
||||
.hljs-doctag, .hljs-formula {
|
||||
color: #c678dd;
|
||||
}
|
||||
.hljs-section, .hljs-name, .hljs-selector-tag, .hljs-deletion, .hljs-subst {
|
||||
color: #e06c75;
|
||||
}
|
||||
.hljs-literal {
|
||||
color: #56b6c2;
|
||||
}
|
||||
.hljs-string, .hljs-regexp, .hljs-addition, .hljs-attribute, .hljs-meta-string {
|
||||
color: #98c379;
|
||||
}
|
||||
.hljs-built_in, .hljs-class .hljs-title {
|
||||
color: #e6c07b;
|
||||
}
|
||||
.hljs-attr, .hljs-variable, .hljs-template-variable, .hljs-type, .hljs-selector-class, .hljs-selector-attr, .hljs-selector-pseudo, .hljs-number {
|
||||
color: #d19a66;
|
||||
}
|
||||
.hljs-symbol, .hljs-bullet, .hljs-link, .hljs-meta, .hljs-selector-id, .hljs-title {
|
||||
color: #61aeee;
|
||||
}
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
96
js/styles/atom-one-dark.css
Normal file
96
js/styles/atom-one-dark.css
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
|
||||
Atom One Dark by Daniel Gamage
|
||||
Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax
|
||||
|
||||
base: #282c34
|
||||
mono-1: #abb2bf
|
||||
mono-2: #818896
|
||||
mono-3: #5c6370
|
||||
hue-1: #56b6c2
|
||||
hue-2: #61aeee
|
||||
hue-3: #c678dd
|
||||
hue-4: #98c379
|
||||
hue-5: #e06c75
|
||||
hue-5-2: #be5046
|
||||
hue-6: #d19a66
|
||||
hue-6-2: #e6c07b
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
color: #abb2bf;
|
||||
background: #282c34;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #5c6370;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-doctag,
|
||||
.hljs-keyword,
|
||||
.hljs-formula {
|
||||
color: #c678dd;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-name,
|
||||
.hljs-selector-tag,
|
||||
.hljs-deletion,
|
||||
.hljs-subst {
|
||||
color: #e06c75;
|
||||
}
|
||||
|
||||
.hljs-literal {
|
||||
color: #56b6c2;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-regexp,
|
||||
.hljs-addition,
|
||||
.hljs-attribute,
|
||||
.hljs-meta-string {
|
||||
color: #98c379;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-class .hljs-title {
|
||||
color: #e6c07b;
|
||||
}
|
||||
|
||||
.hljs-attr,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-type,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo,
|
||||
.hljs-number {
|
||||
color: #d19a66;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-link,
|
||||
.hljs-meta,
|
||||
.hljs-selector-id,
|
||||
.hljs-title {
|
||||
color: #61aeee;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
96
js/styles/atom-one-light.css
Normal file
96
js/styles/atom-one-light.css
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
|
||||
Atom One Light by Daniel Gamage
|
||||
Original One Light Syntax theme from https://github.com/atom/one-light-syntax
|
||||
|
||||
base: #fafafa
|
||||
mono-1: #383a42
|
||||
mono-2: #686b77
|
||||
mono-3: #a0a1a7
|
||||
hue-1: #0184bb
|
||||
hue-2: #4078f2
|
||||
hue-3: #a626a4
|
||||
hue-4: #50a14f
|
||||
hue-5: #e45649
|
||||
hue-5-2: #c91243
|
||||
hue-6: #986801
|
||||
hue-6-2: #c18401
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
color: #383a42;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #a0a1a7;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-doctag,
|
||||
.hljs-keyword,
|
||||
.hljs-formula {
|
||||
color: #a626a4;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-name,
|
||||
.hljs-selector-tag,
|
||||
.hljs-deletion,
|
||||
.hljs-subst {
|
||||
color: #e45649;
|
||||
}
|
||||
|
||||
.hljs-literal {
|
||||
color: #0184bb;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-regexp,
|
||||
.hljs-addition,
|
||||
.hljs-attribute,
|
||||
.hljs-meta-string {
|
||||
color: #50a14f;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-class .hljs-title {
|
||||
color: #c18401;
|
||||
}
|
||||
|
||||
.hljs-attr,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-type,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo,
|
||||
.hljs-number {
|
||||
color: #986801;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-link,
|
||||
.hljs-meta,
|
||||
.hljs-selector-id,
|
||||
.hljs-title {
|
||||
color: #4078f2;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
64
js/styles/brown-paper.css
Normal file
64
js/styles/brown-paper.css
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
|
||||
Brown Paper style from goldblog.com.ua (c) Zaripov Yura <yur4ik7@ukr.net>
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background:#b7a68e url(./brown-papersq.png);
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-literal {
|
||||
color:#005599;
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
.hljs,
|
||||
.hljs-subst {
|
||||
color: #363c69;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-type,
|
||||
.hljs-attribute,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-built_in,
|
||||
.hljs-addition,
|
||||
.hljs-variable,
|
||||
.hljs-template-tag,
|
||||
.hljs-template-variable,
|
||||
.hljs-link,
|
||||
.hljs-name {
|
||||
color: #2c009f;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote,
|
||||
.hljs-meta,
|
||||
.hljs-deletion {
|
||||
color: #802022;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-literal,
|
||||
.hljs-doctag,
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-type,
|
||||
.hljs-name,
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
BIN
js/styles/brown-papersq.png
Normal file
BIN
js/styles/brown-papersq.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
60
js/styles/codepen-embed.css
Normal file
60
js/styles/codepen-embed.css
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
codepen.io Embed Theme
|
||||
Author: Justin Perry <http://github.com/ourmaninamsterdam>
|
||||
Original theme - https://github.com/chriskempson/tomorrow-theme
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #222;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-tag,
|
||||
.hljs-regexp,
|
||||
.hljs-meta,
|
||||
.hljs-number,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-params,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-link,
|
||||
.hljs-deletion {
|
||||
color: #ab875d;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-title,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-type,
|
||||
.hljs-attribute {
|
||||
color: #9b869b;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-addition {
|
||||
color: #8f9c6c;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
71
js/styles/color-brewer.css
Normal file
71
js/styles/color-brewer.css
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
|
||||
Colorbrewer theme
|
||||
Original: https://github.com/mbostock/colorbrewer-theme (c) Mike Bostock <mike@ocks.org>
|
||||
Ported by Fabrício Tavares de Oliveira
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.hljs,
|
||||
.hljs-subst {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-meta,
|
||||
.hljs-symbol,
|
||||
.hljs-template-tag,
|
||||
.hljs-template-variable,
|
||||
.hljs-addition {
|
||||
color: #756bb1;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #636363;
|
||||
}
|
||||
|
||||
.hljs-number,
|
||||
.hljs-regexp,
|
||||
.hljs-literal,
|
||||
.hljs-bullet,
|
||||
.hljs-link {
|
||||
color: #31a354;
|
||||
}
|
||||
|
||||
.hljs-deletion,
|
||||
.hljs-variable {
|
||||
color: #88f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-built_in,
|
||||
.hljs-doctag,
|
||||
.hljs-type,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-strong {
|
||||
color: #3182bd;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-attribute {
|
||||
color: #e6550d;
|
||||
}
|
||||
77
js/styles/darcula.css
Normal file
77
js/styles/darcula.css
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
|
||||
Darcula color scheme from the JetBrains family of IDEs
|
||||
|
||||
*/
|
||||
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #2b2b2b;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
color: #bababa;
|
||||
}
|
||||
|
||||
.hljs-strong,
|
||||
.hljs-emphasis {
|
||||
color: #a8a8a2;
|
||||
}
|
||||
|
||||
.hljs-bullet,
|
||||
.hljs-quote,
|
||||
.hljs-link,
|
||||
.hljs-number,
|
||||
.hljs-regexp,
|
||||
.hljs-literal {
|
||||
color: #6896ba;
|
||||
}
|
||||
|
||||
.hljs-code,
|
||||
.hljs-selector-class {
|
||||
color: #a6e22e;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-section,
|
||||
.hljs-attribute,
|
||||
.hljs-name,
|
||||
.hljs-variable {
|
||||
color: #cb7832;
|
||||
}
|
||||
|
||||
.hljs-params {
|
||||
color: #b9b9b9;
|
||||
}
|
||||
|
||||
.hljs-string {
|
||||
color: #6a8759;
|
||||
}
|
||||
|
||||
.hljs-subst,
|
||||
.hljs-type,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-symbol,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo,
|
||||
.hljs-template-tag,
|
||||
.hljs-template-variable,
|
||||
.hljs-addition {
|
||||
color: #e0c46c;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-deletion,
|
||||
.hljs-meta {
|
||||
color: #7f7f7f;
|
||||
}
|
||||
63
js/styles/dark.css
Normal file
63
js/styles/dark.css
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
|
||||
Dark style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org>
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #444;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-literal,
|
||||
.hljs-section,
|
||||
.hljs-link {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.hljs,
|
||||
.hljs-subst {
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-title,
|
||||
.hljs-name,
|
||||
.hljs-type,
|
||||
.hljs-attribute,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-built_in,
|
||||
.hljs-addition,
|
||||
.hljs-variable,
|
||||
.hljs-template-tag,
|
||||
.hljs-template-variable {
|
||||
color: #d88;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote,
|
||||
.hljs-deletion,
|
||||
.hljs-meta {
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-literal,
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-doctag,
|
||||
.hljs-type,
|
||||
.hljs-name,
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
6
js/styles/darkula.css
Normal file
6
js/styles/darkula.css
Normal file
@@ -0,0 +1,6 @@
|
||||
/*
|
||||
Deprecated due to a typo in the name and left here for compatibility purpose only.
|
||||
Please use darcula.css instead.
|
||||
*/
|
||||
|
||||
@import url('darcula.css');
|
||||
99
js/styles/default.css
Normal file
99
js/styles/default.css
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
|
||||
Original highlight.js style (c) Ivan Sagalaev <maniac@softwaremaniacs.org>
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #F0F0F0;
|
||||
}
|
||||
|
||||
|
||||
/* Base color: saturation 0; */
|
||||
|
||||
.hljs,
|
||||
.hljs-subst {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
.hljs-comment {
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-attribute,
|
||||
.hljs-selector-tag,
|
||||
.hljs-meta-keyword,
|
||||
.hljs-doctag,
|
||||
.hljs-name {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
/* User color: hue: 0 */
|
||||
|
||||
.hljs-type,
|
||||
.hljs-string,
|
||||
.hljs-number,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-quote,
|
||||
.hljs-template-tag,
|
||||
.hljs-deletion {
|
||||
color: #880000;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #880000;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-regexp,
|
||||
.hljs-symbol,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-link,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo {
|
||||
color: #BC6060;
|
||||
}
|
||||
|
||||
|
||||
/* Language color: hue: 90; */
|
||||
|
||||
.hljs-literal {
|
||||
color: #78A960;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-bullet,
|
||||
.hljs-code,
|
||||
.hljs-addition {
|
||||
color: #397300;
|
||||
}
|
||||
|
||||
|
||||
/* Meta color: hue: 200 */
|
||||
|
||||
.hljs-meta {
|
||||
color: #1f7199;
|
||||
}
|
||||
|
||||
.hljs-meta-string {
|
||||
color: #4d99bf;
|
||||
}
|
||||
|
||||
|
||||
/* Misc effects */
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
97
js/styles/docco.css
Normal file
97
js/styles/docco.css
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
Docco style used in http://jashkenas.github.com/docco/ converted by Simon Madine (@thingsinjars)
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
color: #000;
|
||||
background: #f8f8ff;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #408080;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-literal,
|
||||
.hljs-subst {
|
||||
color: #954121;
|
||||
}
|
||||
|
||||
.hljs-number {
|
||||
color: #40a070;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-doctag {
|
||||
color: #219161;
|
||||
}
|
||||
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-section,
|
||||
.hljs-type {
|
||||
color: #19469d;
|
||||
}
|
||||
|
||||
.hljs-params {
|
||||
color: #00f;
|
||||
}
|
||||
|
||||
.hljs-title {
|
||||
color: #458;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-attribute {
|
||||
color: #000080;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.hljs-variable,
|
||||
.hljs-template-variable {
|
||||
color: #008080;
|
||||
}
|
||||
|
||||
.hljs-regexp,
|
||||
.hljs-link {
|
||||
color: #b68;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #990073;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name {
|
||||
color: #0086b3;
|
||||
}
|
||||
|
||||
.hljs-meta {
|
||||
color: #999;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
background: #fdd;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
background: #dfd;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
76
js/styles/dracula.css
Normal file
76
js/styles/dracula.css
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
|
||||
Dracula Theme v1.2.0
|
||||
|
||||
https://github.com/zenorocha/dracula-theme
|
||||
|
||||
Copyright 2015, All rights reserved
|
||||
|
||||
Code licensed under the MIT license
|
||||
http://zenorocha.mit-license.org
|
||||
|
||||
@author Éverton Ribeiro <nuxlli@gmail.com>
|
||||
@author Zeno Rocha <hi@zenorocha.com>
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #282a36;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-literal,
|
||||
.hljs-section,
|
||||
.hljs-link {
|
||||
color: #8be9fd;
|
||||
}
|
||||
|
||||
.hljs-function .hljs-keyword {
|
||||
color: #ff79c6;
|
||||
}
|
||||
|
||||
.hljs,
|
||||
.hljs-subst {
|
||||
color: #f8f8f2;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-title,
|
||||
.hljs-name,
|
||||
.hljs-type,
|
||||
.hljs-attribute,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-addition,
|
||||
.hljs-variable,
|
||||
.hljs-template-tag,
|
||||
.hljs-template-variable {
|
||||
color: #f1fa8c;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote,
|
||||
.hljs-deletion,
|
||||
.hljs-meta {
|
||||
color: #6272a4;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-literal,
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-doctag,
|
||||
.hljs-type,
|
||||
.hljs-name,
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
71
js/styles/far.css
Normal file
71
js/styles/far.css
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
|
||||
FAR Style (c) MajestiC <majestic2k@gmail.com>
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #000080;
|
||||
}
|
||||
|
||||
.hljs,
|
||||
.hljs-subst {
|
||||
color: #0ff;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-attribute,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-template-tag,
|
||||
.hljs-template-variable,
|
||||
.hljs-addition {
|
||||
color: #ff0;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-section,
|
||||
.hljs-type,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-variable {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote,
|
||||
.hljs-doctag,
|
||||
.hljs-deletion {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.hljs-number,
|
||||
.hljs-regexp,
|
||||
.hljs-literal,
|
||||
.hljs-link {
|
||||
color: #0f0;
|
||||
}
|
||||
|
||||
.hljs-meta {
|
||||
color: #008080;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-name,
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
88
js/styles/foundation.css
vendored
Normal file
88
js/styles/foundation.css
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
Description: Foundation 4 docs style for highlight.js
|
||||
Author: Dan Allen <dan.j.allen@gmail.com>
|
||||
Website: http://foundation.zurb.com/docs/
|
||||
Version: 1.0
|
||||
Date: 2013-04-02
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #eee; color: black;
|
||||
}
|
||||
|
||||
.hljs-link,
|
||||
.hljs-emphasis,
|
||||
.hljs-attribute,
|
||||
.hljs-addition {
|
||||
color: #070;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong,
|
||||
.hljs-string,
|
||||
.hljs-deletion {
|
||||
color: #d14;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-quote,
|
||||
.hljs-comment {
|
||||
color: #998;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-title {
|
||||
color: #900;
|
||||
}
|
||||
|
||||
.hljs-class .hljs-title,
|
||||
.hljs-type {
|
||||
color: #458;
|
||||
}
|
||||
|
||||
.hljs-variable,
|
||||
.hljs-template-variable {
|
||||
color: #336699;
|
||||
}
|
||||
|
||||
.hljs-bullet {
|
||||
color: #997700;
|
||||
}
|
||||
|
||||
.hljs-meta {
|
||||
color: #3344bb;
|
||||
}
|
||||
|
||||
.hljs-code,
|
||||
.hljs-number,
|
||||
.hljs-literal,
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #099;
|
||||
}
|
||||
|
||||
.hljs-regexp {
|
||||
background-color: #fff0ff;
|
||||
color: #880088;
|
||||
}
|
||||
|
||||
.hljs-symbol {
|
||||
color: #990073;
|
||||
}
|
||||
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #007700;
|
||||
}
|
||||
71
js/styles/github-gist.css
Normal file
71
js/styles/github-gist.css
Normal file
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* GitHub Gist Theme
|
||||
* Author : Louis Barranqueiro - https://github.com/LouisBarranqueiro
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
background: white;
|
||||
padding: 0.5em;
|
||||
color: #333333;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-meta {
|
||||
color: #969896;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-strong,
|
||||
.hljs-emphasis,
|
||||
.hljs-quote {
|
||||
color: #df5000;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-type {
|
||||
color: #a71d5d;
|
||||
}
|
||||
|
||||
.hljs-literal,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-attribute {
|
||||
color: #0086b3;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-name {
|
||||
color: #63a35c;
|
||||
}
|
||||
|
||||
.hljs-tag {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-attr,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo {
|
||||
color: #795da3;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
color: #55a532;
|
||||
background-color: #eaffea;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
color: #bd2c00;
|
||||
background-color: #ffecec;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
99
js/styles/github.css
Normal file
99
js/styles/github.css
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
|
||||
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
color: #333;
|
||||
background: #f8f8f8;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #998;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-subst {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-number,
|
||||
.hljs-literal,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-tag .hljs-attr {
|
||||
color: #008080;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-doctag {
|
||||
color: #d14;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-selector-id {
|
||||
color: #900;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-subst {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.hljs-type,
|
||||
.hljs-class .hljs-title {
|
||||
color: #458;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-attribute {
|
||||
color: #000080;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.hljs-regexp,
|
||||
.hljs-link {
|
||||
color: #009926;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #990073;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name {
|
||||
color: #0086b3;
|
||||
}
|
||||
|
||||
.hljs-meta {
|
||||
color: #999;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
background: #fdd;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
background: #dfd;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
78
js/styles/gml.css
Normal file
78
js/styles/gml.css
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
|
||||
GML Theme - Meseta <meseta@gmail.com>
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #222222;
|
||||
color: #C0C0C0;
|
||||
}
|
||||
|
||||
.hljs-keywords {
|
||||
color: #FFB871;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-built_in {
|
||||
color: #FFB871;
|
||||
}
|
||||
|
||||
.hljs-literal {
|
||||
color: #FF8080;
|
||||
}
|
||||
|
||||
.hljs-symbol {
|
||||
color: #58E55A;
|
||||
}
|
||||
|
||||
.hljs-comment {
|
||||
color: #5B995B;
|
||||
}
|
||||
|
||||
.hljs-string {
|
||||
color: #FFFF00;
|
||||
}
|
||||
|
||||
.hljs-number {
|
||||
color: #FF8080;
|
||||
}
|
||||
|
||||
.hljs-attribute,
|
||||
.hljs-selector-tag,
|
||||
.hljs-doctag,
|
||||
.hljs-name,
|
||||
.hljs-bullet,
|
||||
.hljs-code,
|
||||
.hljs-addition,
|
||||
.hljs-regexp,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-link,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo,
|
||||
.hljs-type,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-quote,
|
||||
.hljs-template-tag,
|
||||
.hljs-deletion,
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-function,
|
||||
.hljs-meta-keyword,
|
||||
.hljs-meta,
|
||||
.hljs-subst {
|
||||
color: #C0C0C0;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
89
js/styles/googlecode.css
Normal file
89
js/styles/googlecode.css
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
|
||||
Google Code style (c) Aahan Krish <geekpanth3r@gmail.com>
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: white;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #800;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-section,
|
||||
.hljs-title,
|
||||
.hljs-name {
|
||||
color: #008;
|
||||
}
|
||||
|
||||
.hljs-variable,
|
||||
.hljs-template-variable {
|
||||
color: #660;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo,
|
||||
.hljs-regexp {
|
||||
color: #080;
|
||||
}
|
||||
|
||||
.hljs-literal,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-meta,
|
||||
.hljs-number,
|
||||
.hljs-link {
|
||||
color: #066;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-doctag,
|
||||
.hljs-type,
|
||||
.hljs-attr,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-params {
|
||||
color: #606;
|
||||
}
|
||||
|
||||
.hljs-attribute,
|
||||
.hljs-subst {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.hljs-formula {
|
||||
background-color: #eee;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #9B703F
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
background-color: #baeeba;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
background-color: #ffc8bd;
|
||||
}
|
||||
|
||||
.hljs-doctag,
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
101
js/styles/grayscale.css
Normal file
101
js/styles/grayscale.css
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
|
||||
grayscale style (c) MY Sun <simonmysun@gmail.com>
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
color: #333;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #777;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-subst {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-number,
|
||||
.hljs-literal {
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-doctag,
|
||||
.hljs-formula {
|
||||
color: #333;
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAYAAACp8Z5+AAAAJ0lEQVQIW2O8e/fufwYGBgZBQUEQxcCIIfDu3Tuwivfv30NUoAsAALHpFMMLqZlPAAAAAElFTkSuQmCC) repeat;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-selector-id {
|
||||
color: #000;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-subst {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.hljs-class .hljs-title,
|
||||
.hljs-type,
|
||||
.hljs-name {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-tag {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.hljs-regexp {
|
||||
color: #333;
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAICAYAAADA+m62AAAAPUlEQVQYV2NkQAN37979r6yszIgujiIAU4RNMVwhuiQ6H6wQl3XI4oy4FMHcCJPHcDS6J2A2EqUQpJhohQDexSef15DBCwAAAABJRU5ErkJggg==) repeat;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-link {
|
||||
color: #000;
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAKElEQVQIW2NkQAO7d+/+z4gsBhJwdXVlhAvCBECKwIIwAbhKZBUwBQA6hBpm5efZsgAAAABJRU5ErkJggg==) repeat;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name {
|
||||
color: #000;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.hljs-meta {
|
||||
color: #999;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
color: #fff;
|
||||
background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAADCAYAAABS3WWCAAAAE0lEQVQIW2MMDQ39zzhz5kwIAQAyxweWgUHd1AAAAABJRU5ErkJggg==) repeat;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
color: #000;
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAALUlEQVQYV2N89+7dfwYk8P79ewZBQUFkIQZGOiu6e/cuiptQHAPl0NtNxAQBAM97Oejj3Dg7AAAAAElFTkSuQmCC) repeat;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
108
js/styles/gruvbox-dark.css
Normal file
108
js/styles/gruvbox-dark.css
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
|
||||
Gruvbox style (dark) (c) Pavel Pertsev (original style at https://github.com/morhetz/gruvbox)
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #282828;
|
||||
}
|
||||
|
||||
.hljs,
|
||||
.hljs-subst {
|
||||
color: #ebdbb2;
|
||||
}
|
||||
|
||||
/* Gruvbox Red */
|
||||
.hljs-deletion,
|
||||
.hljs-formula,
|
||||
.hljs-keyword,
|
||||
.hljs-link,
|
||||
.hljs-selector-tag {
|
||||
color: #fb4934;
|
||||
}
|
||||
|
||||
/* Gruvbox Blue */
|
||||
.hljs-built_in,
|
||||
.hljs-emphasis,
|
||||
.hljs-name,
|
||||
.hljs-quote,
|
||||
.hljs-strong,
|
||||
.hljs-title,
|
||||
.hljs-variable {
|
||||
color: #83a598;
|
||||
}
|
||||
|
||||
/* Gruvbox Yellow */
|
||||
.hljs-attr,
|
||||
.hljs-params,
|
||||
.hljs-template-tag,
|
||||
.hljs-type {
|
||||
color: #fabd2f;
|
||||
}
|
||||
|
||||
/* Gruvbox Purple */
|
||||
.hljs-builtin-name,
|
||||
.hljs-doctag,
|
||||
.hljs-literal,
|
||||
.hljs-number {
|
||||
color: #8f3f71;
|
||||
}
|
||||
|
||||
/* Gruvbox Orange */
|
||||
.hljs-code,
|
||||
.hljs-meta,
|
||||
.hljs-regexp,
|
||||
.hljs-selector-id,
|
||||
.hljs-template-variable {
|
||||
color: #fe8019;
|
||||
}
|
||||
|
||||
/* Gruvbox Green */
|
||||
.hljs-addition,
|
||||
.hljs-meta-string,
|
||||
.hljs-section,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-class,
|
||||
.hljs-string,
|
||||
.hljs-symbol {
|
||||
color: #b8bb26;
|
||||
}
|
||||
|
||||
/* Gruvbox Aqua */
|
||||
.hljs-attribute,
|
||||
.hljs-bullet,
|
||||
.hljs-class,
|
||||
.hljs-function,
|
||||
.hljs-function .hljs-keyword,
|
||||
.hljs-meta-keyword,
|
||||
.hljs-selector-pseudo,
|
||||
.hljs-tag {
|
||||
color: #8ec07c;
|
||||
}
|
||||
|
||||
/* Gruvbox Gray */
|
||||
.hljs-comment {
|
||||
color: #928374;
|
||||
}
|
||||
|
||||
/* Gruvbox Purple */
|
||||
.hljs-link_label,
|
||||
.hljs-literal,
|
||||
.hljs-number {
|
||||
color: #d3869b;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-strong,
|
||||
.hljs-tag {
|
||||
font-weight: bold;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user