add web challenge
30
web/web_toy_workshop/Dockerfile
Normal file
@@ -0,0 +1,30 @@
|
||||
FROM node:current-buster-slim
|
||||
|
||||
# Install packages
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y wget supervisor gnupg \
|
||||
&& wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
|
||||
&& sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y google-chrome-stable fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf libxss1 libxshmfence-dev \
|
||||
--no-install-recommends \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Setup app
|
||||
RUN mkdir -p /app
|
||||
|
||||
# Add application
|
||||
WORKDIR /app
|
||||
COPY challenge .
|
||||
|
||||
# Install dependencies
|
||||
RUN yarn
|
||||
|
||||
# Setup superivsord
|
||||
COPY config/supervisord.conf /etc/supervisord.conf
|
||||
|
||||
# Expose the port node-js is reachable on
|
||||
EXPOSE 1337
|
||||
|
||||
# Start the node-js application
|
||||
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"]
|
||||
4
web/web_toy_workshop/build-docker.sh
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
docker rm -f web_toy_workshop
|
||||
docker build -t web_toy_workshop .
|
||||
docker run --name=web_toy_workshop --rm -p1337:1337 -it web_toy_workshop
|
||||
41
web/web_toy_workshop/challenge/bot.js
Normal file
@@ -0,0 +1,41 @@
|
||||
const puppeteer = require('puppeteer');
|
||||
|
||||
const browser_options = {
|
||||
headless: true,
|
||||
args: [
|
||||
'--no-sandbox',
|
||||
'--disable-background-networking',
|
||||
'--disable-default-apps',
|
||||
'--disable-extensions',
|
||||
'--disable-gpu',
|
||||
'--disable-sync',
|
||||
'--disable-translate',
|
||||
'--hide-scrollbars',
|
||||
'--metrics-recording-only',
|
||||
'--mute-audio',
|
||||
'--no-first-run',
|
||||
'--safebrowsing-disable-auto-update',
|
||||
'--js-flags=--noexpose_wasm,--jitless'
|
||||
]
|
||||
};
|
||||
|
||||
const cookies = [{
|
||||
'name': 'flag',
|
||||
'value': 'HTB{f4k3_fl4g_f0r_t3st1ng}'
|
||||
}];
|
||||
|
||||
|
||||
const readQueries = async (db) => {
|
||||
const browser = await puppeteer.launch(browser_options);
|
||||
let context = await browser.createIncognitoBrowserContext();
|
||||
let page = await context.newPage();
|
||||
await page.goto('http://127.0.0.1:1337/');
|
||||
await page.setCookie(...cookies);
|
||||
await page.goto('http://127.0.0.1:1337/queries', {
|
||||
waitUntil: 'networkidle2'
|
||||
});
|
||||
await browser.close();
|
||||
await db.migrate();
|
||||
};
|
||||
|
||||
module.exports = { readQueries };
|
||||
48
web/web_toy_workshop/challenge/database.js
Normal file
@@ -0,0 +1,48 @@
|
||||
const sqlite = require('sqlite-async');
|
||||
|
||||
class Database {
|
||||
constructor(db_file) {
|
||||
this.db_file = db_file;
|
||||
this.db = undefined;
|
||||
}
|
||||
|
||||
async connect() {
|
||||
this.db = await sqlite.open(this.db_file);
|
||||
}
|
||||
async migrate() {
|
||||
return this.db.exec(`
|
||||
DROP TABLE IF EXISTS queries;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS queries (
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
query VARCHAR(500) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
`);
|
||||
}
|
||||
|
||||
async addQuery(query) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
let stmt = await this.db.prepare('INSERT INTO queries (query) VALUES (?)');
|
||||
resolve(await stmt.run(query));
|
||||
} catch(e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async getQueries() {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
let stmt = await this.db.prepare('SELECT * FROM queries');
|
||||
resolve(await stmt.all());
|
||||
} catch(e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = Database;
|
||||
27
web/web_toy_workshop/challenge/index.js
Normal file
@@ -0,0 +1,27 @@
|
||||
const express = require('express');
|
||||
const app = express();
|
||||
const path = require('path');
|
||||
const routes = require('./routes');
|
||||
const Database = require('./database');
|
||||
|
||||
const db = new Database('toy_workshop.db');
|
||||
|
||||
app.use(express.json());
|
||||
|
||||
app.set("view engine", "hbs");
|
||||
app.set('views', './views');
|
||||
app.use('/static', express.static(path.resolve('static')));
|
||||
|
||||
app.use(routes(db));
|
||||
|
||||
app.all('*', (req, res) => {
|
||||
return res.status(404).send({
|
||||
message: '404 page not found'
|
||||
});
|
||||
});
|
||||
|
||||
(async () => {
|
||||
await db.connect();
|
||||
await db.migrate();
|
||||
app.listen(1337, '0.0.0.0', () => console.log('Listening on port 1337'));
|
||||
})();
|
||||
25
web/web_toy_workshop/challenge/package.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "web_toy_workshop",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "node index.js"
|
||||
},
|
||||
"keywords": [],
|
||||
"authors": [
|
||||
"rayhan0x01",
|
||||
"Makelaris",
|
||||
"Makelaris jr"
|
||||
],
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"express": "^4.17.1",
|
||||
"sqlite-async": "^1.1.1",
|
||||
"puppeteer": "^11.0.0",
|
||||
"hbs": "^4.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"nodemon": "^1.19.1"
|
||||
}
|
||||
}
|
||||
39
web/web_toy_workshop/challenge/routes/index.js
Normal file
@@ -0,0 +1,39 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const bot = require('../bot');
|
||||
|
||||
let db;
|
||||
|
||||
const response = data => ({ message: data });
|
||||
|
||||
router.get('/', (req, res) => {
|
||||
return res.render('index');
|
||||
});
|
||||
|
||||
router.post('/api/submit', async (req, res) => {
|
||||
|
||||
const { query } = req.body;
|
||||
if(query){
|
||||
return db.addQuery(query)
|
||||
.then(() => {
|
||||
bot.readQueries(db);
|
||||
res.send(response('Your message is delivered successfully!'));
|
||||
});
|
||||
}
|
||||
return res.status(403).send(response('Please write your query first!'));
|
||||
});
|
||||
|
||||
router.get('/queries', async (req, res, next) => {
|
||||
if(req.ip != '127.0.0.1') return res.redirect('/');
|
||||
|
||||
return db.getQueries()
|
||||
.then(queries => {
|
||||
res.render('queries', { queries });
|
||||
})
|
||||
.catch(() => res.status(500).send(response('Something went wrong!')));
|
||||
});
|
||||
|
||||
module.exports = database => {
|
||||
db = database;
|
||||
return router;
|
||||
};
|
||||
BIN
web/web_toy_workshop/challenge/static/audio/audio.mp3
Normal file
12
web/web_toy_workshop/challenge/static/css/bootstrap.min.css
vendored
Normal file
189
web/web_toy_workshop/challenge/static/css/dashboard.css
Normal file
@@ -0,0 +1,189 @@
|
||||
/* @import url('https://fonts.googleapis.com/css2?family=VT323&display=swap'); */
|
||||
@import url('https://fonts.googleapis.com/css2?family=Caveat&display=swap');
|
||||
|
||||
|
||||
body {
|
||||
font-family: 'Caveat', cursive;
|
||||
font-size: 18pt;
|
||||
color: #fff;
|
||||
background-color: #c09277;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
min-height: 800px;
|
||||
max-height: 800px;
|
||||
}
|
||||
p {
|
||||
text-align: center;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.main-logo {
|
||||
display: flex;
|
||||
min-width: 150px;
|
||||
width: 150px;
|
||||
margin: 0 auto;
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.login-form {
|
||||
display: flex;
|
||||
min-width: 400px;
|
||||
width: 400px;
|
||||
margin: 0 auto;
|
||||
margin-top: 20px;
|
||||
flex-direction: column;
|
||||
}
|
||||
.login-form>input {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
.submit-btns {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
.submit-btns>button {
|
||||
width: 45%;
|
||||
}
|
||||
.submit-btn.is-primary {
|
||||
background-color: #ca8055 !important;
|
||||
border-color: #f4b798 !important;
|
||||
}
|
||||
.submit-btn.is-primary::after {
|
||||
box-shadow:inset -4px -4px #a86136 !important;
|
||||
}
|
||||
.submit-btn.is-primary:hover::after {
|
||||
box-shadow:inset -6px -6px #a86136 !important;
|
||||
}
|
||||
.submit-btn.is-primary:focus {
|
||||
box-shadow:0 0 0 3px transparent !important;
|
||||
}
|
||||
|
||||
|
||||
/* query-msg */
|
||||
|
||||
#resp-msg {
|
||||
display: none;
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
.alert {
|
||||
position: relative;
|
||||
padding: .50rem 1.25rem;
|
||||
margin-bottom: 1rem;
|
||||
border: 1px solid transparent;
|
||||
border-radius: .25rem;
|
||||
}
|
||||
.alert-success {
|
||||
color: #155724;
|
||||
background-color: #d4edda;
|
||||
border-color: #c3e6cb;
|
||||
}
|
||||
.alert-danger {
|
||||
color: #721c24;
|
||||
background-color: #f8d7da;
|
||||
border-color: #f5c6cb;
|
||||
}
|
||||
.alert-info {
|
||||
color: #0c5460;
|
||||
background-color: #d1ecf1;
|
||||
border-color: #bee5eb;
|
||||
}
|
||||
|
||||
.login-frame {
|
||||
position: relative;
|
||||
background-color: #a27256;
|
||||
min-height: 380px;
|
||||
width: 480px;
|
||||
margin: 0 auto;
|
||||
padding-top: 10px;
|
||||
margin-top: 40px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.login-frame::before{
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -40px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
background: #925f41;
|
||||
}
|
||||
|
||||
.login-frame::after{
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -40px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
background: #925f41;
|
||||
}
|
||||
|
||||
.pb-3 {
|
||||
display: block;
|
||||
padding-bottom: 30px;
|
||||
}
|
||||
|
||||
#fireplace {
|
||||
position: absolute;
|
||||
bottom: -5px;
|
||||
left: 5%;
|
||||
height: 250px;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
@media (max-height: 800px){
|
||||
body {
|
||||
overflow: scroll;
|
||||
}
|
||||
#fireplace {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.dash-frame {
|
||||
position: relative;
|
||||
background-color: #a27256;
|
||||
width: 480px;
|
||||
margin: 0 auto;
|
||||
padding-top: 10px;
|
||||
margin-top: 40px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
|
||||
.dash-frame::before{
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -40px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
background: #925f41;
|
||||
}
|
||||
|
||||
.dash-frame::after{
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -40px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
background: #925f41;
|
||||
}
|
||||
|
||||
@media (max-height: 800px){
|
||||
body {
|
||||
overflow: scroll;
|
||||
}
|
||||
#fireplace {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-height: 660px){
|
||||
body {
|
||||
overflow: scroll;
|
||||
}
|
||||
#fireplace {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
706
web/web_toy_workshop/challenge/static/css/index.css
Normal file
@@ -0,0 +1,706 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=Mountains+of+Christmas&display=swap');
|
||||
|
||||
body {
|
||||
background: #111;
|
||||
background-size: 100%;
|
||||
height: 100%;
|
||||
width:100%;
|
||||
overflow: scroll;
|
||||
margin: 0;
|
||||
min-width: 1300px !important;
|
||||
font-family: 'Mountains of Christmas', cursive;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
/***************************
|
||||
|
||||
The DIV for the SVG wall. As I want the snow to show through the windows, I need to place this layer with a higher z-index then Miss Tiff's snow ---> https://codepen.io/tmrDevelops/pen/PPgjwz
|
||||
|
||||
***************************/
|
||||
#Workshop_Back {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 779px;
|
||||
margin: 0;
|
||||
z-index: 200;
|
||||
min-width: 1300px;
|
||||
}
|
||||
|
||||
#Workshop_Animations {
|
||||
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 712px;
|
||||
margin: 0;
|
||||
z-index: 3000;
|
||||
}
|
||||
|
||||
|
||||
#Candy_Gears {position:absolute;width:100%;height:100%;margin:0;z-index:999999999999;}
|
||||
/***************************
|
||||
|
||||
Styles for the SVG Wall. Created the wall in illustrator and then knocked out the window panes so the snow (and other festive surprises) would show through.
|
||||
|
||||
***************************/
|
||||
|
||||
#Workshop_Wall {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.Workshop_Wall_0{fill:#c09277;}
|
||||
.Workshop_Wall_1{fill:#8C5A3C;}
|
||||
.Workshop_Wall_2{fill:#60462F;}
|
||||
.Workshop_Wall_3{fill:#B96636;}
|
||||
.Workshop_Wall_4{fill:#D3814D;}
|
||||
.Workshop_Wall_5{fill:#B0581F;}
|
||||
.Workshop_Wall_6{fill:#DE1516;}
|
||||
.Workshop_Wall_7{fill:#F4F4F4;}
|
||||
.Workshop_Wall_8{fill:#BD0302;}
|
||||
.Workshop_Wall_9{fill:#C1652F;}
|
||||
.Workshop_Wall_10{fill:#C66225;}
|
||||
.Workshop_Wall_11{fill:#1F01FB;}
|
||||
.Workshop_Wall_12{fill:#AD7964;}
|
||||
.Workshop_Wall_13{fill:#9E99BC;}
|
||||
.Workshop_Wall_14{fill:#8587AC;}
|
||||
.Workshop_Wall_15{fill:#A58175;}
|
||||
|
||||
/***************************
|
||||
|
||||
Snow. Positioned layer using a low z-index in the very back.
|
||||
|
||||
***************************/
|
||||
|
||||
#tiffany_snow {
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 100;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
||||
#Front_Elves {position:absolute;width:100%;height:100%;margin:0;z-index:9000;}
|
||||
|
||||
.elves_front0{fill:#815330;}
|
||||
.elves_front1{fill:#654227;}
|
||||
.elves_front2{fill:#F9FAF8;}
|
||||
.elves_front3{fill:#757578;}
|
||||
.elves_front4{fill:#6A8F27;}
|
||||
.elves_front5{fill:#DA4937;}
|
||||
.elves_front6{fill:#924493;}
|
||||
.elves_front7{fill:#4BB882;}
|
||||
.elves_front8{fill:#06AAE9;}
|
||||
.elves_front9{fill:#FCDD03;}
|
||||
.elves_front10{fill:#E91D25;}
|
||||
.elves_front11{fill:#CB1A22;}
|
||||
.elves_front12{fill:#5B5A5C;}
|
||||
.elves_front13{fill:#3CB34B;}
|
||||
.elves_front14{fill:#E4C184;}
|
||||
|
||||
|
||||
|
||||
/***************************
|
||||
|
||||
Santa Magic Machine
|
||||
|
||||
***************************/
|
||||
|
||||
#Toy-A-Matic {position:absolute;width:100%;height:621px;margin:0;z-index:6000}
|
||||
#Santa_Factory {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
margin: 0 0 0 0;
|
||||
overflow: hidden;
|
||||
background-color: #815330;
|
||||
|
||||
}
|
||||
|
||||
.Santa_Magical_Toy_Machine {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
margin-top: 0px;
|
||||
height: 578px;
|
||||
z-index: 2000;
|
||||
}
|
||||
.Santa_Magical_Toy_Machine:active .trash-in, .Santa_Magical_Toy_Machine:active .toy-out, .Santa_Magical_Toy_Machine:active .conveyor:before {
|
||||
animation-play-state: paused;
|
||||
}
|
||||
.factory {
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 9000;
|
||||
}
|
||||
.converter {
|
||||
width: 20vw;
|
||||
min-width: 200px;
|
||||
height: 100%;
|
||||
animation: 3s magic_Border infinite;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
|
||||
}
|
||||
.converter .attention {
|
||||
width: 18vw;
|
||||
opacity: 0.5;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 0;
|
||||
animation: attention 10s infinite ease;
|
||||
}
|
||||
|
||||
/***************************
|
||||
|
||||
Recycle Presents. The CSS swap is triggered by the JS. The background of the divs are just swapped out to create this incredible holiday illusion.
|
||||
|
||||
***************************/
|
||||
|
||||
.ChristmasPresents {
|
||||
display: none;
|
||||
}
|
||||
.ChristmasPresents.active {
|
||||
display: block;
|
||||
}
|
||||
.ChristmasPresents:nth-child(1) .trash-in{
|
||||
background-image: url(/static/images/bin2.png)
|
||||
}
|
||||
.ChristmasPresents:nth-child(1) .toy-out {
|
||||
background-image: url(/static/images/trainset.png)
|
||||
}
|
||||
.ChristmasPresents:nth-child(2) .trash-in{
|
||||
background-image: url(/static/images/bin2.png)
|
||||
}
|
||||
.ChristmasPresents:nth-child(2) .toy-out {
|
||||
background-image: url(/static/images/bearset.png)
|
||||
}
|
||||
.ChristmasPresents:nth-child(3) .trash-in{
|
||||
background-image: url(/static/images/bin2.png)
|
||||
}
|
||||
.ChristmasPresents:nth-child(3) .toy-out {
|
||||
background-image: url(/static/images/gameset.png)
|
||||
}
|
||||
|
||||
.ChristmasPresents:nth-child(4) .trash-in{
|
||||
background-image: url(/static/images/bin2.png)
|
||||
}
|
||||
.ChristmasPresents:nth-child(4) .toy-out {
|
||||
background-image: url(/static/images/ballset.png)
|
||||
}
|
||||
.ChristmasPresents:nth-child(5) .trash-in{
|
||||
background-image: url(/static/images/bin2.png)
|
||||
}
|
||||
.ChristmasPresents:nth-child(5) .toy-out {
|
||||
background-image: url(/static/images/bearset.png)
|
||||
}
|
||||
|
||||
.ChristmasPresents .item {
|
||||
margin-left: -20vw;
|
||||
width: 200px;
|
||||
max-width: 200px;
|
||||
height: 50%;
|
||||
max-height: 300px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: bottom left;
|
||||
background-size: contain;
|
||||
}
|
||||
.ChristmasPresents .trash-in{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
|
||||
bottom: 18px;
|
||||
animation: input-slide 10s infinite linear;
|
||||
}
|
||||
.ChristmasPresents .toy-out {
|
||||
position: absolute;
|
||||
bottom: 18px;
|
||||
animation: output-slide 10s infinite linear;
|
||||
}
|
||||
.conveyor {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 12px;
|
||||
width: 100%;
|
||||
min-width: 1300px;
|
||||
background: #3e3e66;
|
||||
}
|
||||
.conveyor:before {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
right: 0;
|
||||
width: 430vw;
|
||||
background: repeating-linear-gradient(90deg, #3e3e66 0, #3e3e66 20px, transparent 20px, transparent 30px);
|
||||
height: 6px;
|
||||
animation: conveyor 10s infinite linear;
|
||||
}
|
||||
@keyframes input-slide {
|
||||
0% {
|
||||
visibility: visible;
|
||||
}
|
||||
50%, 100% {
|
||||
visibility: hidden;
|
||||
}
|
||||
100% {
|
||||
transform: translateX(130vw);
|
||||
}
|
||||
}
|
||||
@keyframes output-slide {
|
||||
0%, 49% {
|
||||
visibility: hidden;
|
||||
}
|
||||
50% {
|
||||
visibility: visible;
|
||||
}
|
||||
100% {
|
||||
transform: translateX(130vw);
|
||||
}
|
||||
}
|
||||
@keyframes conveyor {
|
||||
100% {
|
||||
transform: translateX(130vw);
|
||||
}
|
||||
}
|
||||
@keyframes attention {
|
||||
0%, 48%, 52%, 100% {
|
||||
opacity: 0;
|
||||
}
|
||||
50% {
|
||||
opacity: 1;
|
||||
transform: scale(1.2);
|
||||
}
|
||||
}
|
||||
|
||||
#Left_Cane {
|
||||
transform: translateY(5px);
|
||||
animation: leftcane 3s ease infinite;
|
||||
animation-delay: 1.5s;
|
||||
}
|
||||
@keyframes rightcane {
|
||||
50% {
|
||||
transform: translateY(-30px);
|
||||
}
|
||||
}
|
||||
#Right_Cane {
|
||||
transform: translateY(10px);
|
||||
animation: rightcane 3s ease infinite;
|
||||
}
|
||||
@keyframes leftcane {
|
||||
50% {
|
||||
transform: translateY(-20px);
|
||||
}
|
||||
}
|
||||
.Candy_Cane_Magic {
|
||||
position: absolute;
|
||||
width:100%;
|
||||
height:100%;
|
||||
margin:0;
|
||||
|
||||
overflow:hidden;
|
||||
background:rgba(0,116,38,0.5);
|
||||
animation: 3s Magic_Border infinite;
|
||||
|
||||
}
|
||||
.magic_stripe {
|
||||
height: 100%;
|
||||
width: 3%;
|
||||
max-width:15px;
|
||||
position: absolute;
|
||||
-webkit-animation: toy_magic 4s infinite alternate;
|
||||
animation: toy_magic 4s infinite alternate;
|
||||
}
|
||||
@-webkit-keyframes toy_magic {
|
||||
100% {
|
||||
top: 100%;
|
||||
}
|
||||
}
|
||||
@keyframes toy_magic {
|
||||
100% {
|
||||
top: 100%;
|
||||
}
|
||||
}
|
||||
.magic_stripe:nth-child(1) {
|
||||
left: 41%;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
top: -100%;
|
||||
-webkit-animation-delay: 0.1s;
|
||||
animation-delay: 0.1s;
|
||||
}
|
||||
.magic_stripe:nth-child(2) {
|
||||
left: 23%;
|
||||
background: rgba(254,0,4,0.8);
|
||||
top: -100%;
|
||||
-webkit-animation-delay: 0.2s;
|
||||
animation-delay: 0.2s;
|
||||
}
|
||||
.magic_stripe:nth-child(3) {
|
||||
left: 34%;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
top: -100%;
|
||||
-webkit-animation-delay: 0.3s;
|
||||
animation-delay: 0.3s;
|
||||
}
|
||||
.magic_stripe:nth-child(4) {
|
||||
left: 39%;
|
||||
background: rgba(254,0,4,0.8);
|
||||
top: -100%;
|
||||
-webkit-animation-delay: 0.4s;
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
.magic_stripe:nth-child(5) {
|
||||
left: 51%;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
top: -100%;
|
||||
-webkit-animation-delay: 0.5s;
|
||||
animation-delay: 0.5s;
|
||||
}
|
||||
.magic_stripe:nth-child(6) {
|
||||
left: 42%;
|
||||
background: rgba(254,0,4,0.8);
|
||||
top: -100%;
|
||||
-webkit-animation-delay: 0.6s;
|
||||
animation-delay: 0.6s;
|
||||
}
|
||||
.magic_stripe:nth-child(7) {
|
||||
left: 93%;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
top: -100%;
|
||||
-webkit-animation-delay: 0.7s;
|
||||
animation-delay: 0.7s;
|
||||
}
|
||||
.magic_stripe:nth-child(8) {
|
||||
left: 20%;
|
||||
background: rgba(254,0,4,0.8);
|
||||
top: -100%;
|
||||
-webkit-animation-delay: 0.8s;
|
||||
animation-delay: 0.8s;
|
||||
}
|
||||
.magic_stripe:nth-child(9) {
|
||||
left: 23%;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
top: -100%;
|
||||
-webkit-animation-delay: 0.9s;
|
||||
animation-delay: 0.9s;
|
||||
}
|
||||
.magic_stripe:nth-child(10) {
|
||||
left: 50%;
|
||||
background: rgba(254,0,4,0.8);
|
||||
top: -100%;
|
||||
-webkit-animation-delay: 1s;
|
||||
animation-delay: 1s;
|
||||
}
|
||||
.magic_stripe:nth-child(11) {
|
||||
left: 75%;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
top: -100%;
|
||||
-webkit-animation-delay: 1.1s;
|
||||
animation-delay: 1.1s;
|
||||
}
|
||||
.magic_stripe:nth-child(12) {
|
||||
left: 37%;
|
||||
background: rgba(254,0,4,0.8);
|
||||
top: -100%;
|
||||
-webkit-animation-delay: 1.2s;
|
||||
animation-delay: 1.2s;
|
||||
}
|
||||
.magic_stripe:nth-child(13) {
|
||||
left: 40%;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
top: -100%;
|
||||
-webkit-animation-delay: 1.3s;
|
||||
animation-delay: 1.3s;
|
||||
}
|
||||
.magic_stripe:nth-child(14) {
|
||||
left: 90%;
|
||||
background: rgba(254,0,4,0.8);
|
||||
top: -100%;
|
||||
-webkit-animation-delay: 1.4s;
|
||||
animation-delay: 1.4s;
|
||||
}
|
||||
.magic_stripe:nth-child(15) {
|
||||
left: 92%;
|
||||
background: rgba(254,0,4,0.8);
|
||||
top: -100%;
|
||||
-webkit-animation-delay: 1.5s;
|
||||
animation-delay: 1.5s;
|
||||
}
|
||||
.magic_stripe:nth-child(16) {
|
||||
left: 80%;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
top: -100%;
|
||||
-webkit-animation-delay: 1.6s;
|
||||
animation-delay: 1.6s;
|
||||
}
|
||||
.magic_stripe:nth-child(17) {
|
||||
left: 5%;
|
||||
background: rgba(254,0,4,0.8);
|
||||
top: -100%;
|
||||
-webkit-animation-delay: 1.7s;
|
||||
animation-delay: 1.7s;
|
||||
}
|
||||
.magic_stripe:nth-child(18) {
|
||||
left: 79%;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
top: -100%;
|
||||
-webkit-animation-delay: 1.8s;
|
||||
animation-delay: 1.8s;
|
||||
}
|
||||
.magic_stripe:nth-child(19) {
|
||||
left: 20%;
|
||||
background: rgba(254,0,4,0.8);
|
||||
top: -100%;
|
||||
-webkit-animation-delay: 1.9s;
|
||||
animation-delay: 1.9s;
|
||||
}
|
||||
.magic_stripe:nth-child(20) {
|
||||
left: 11%;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
top: -100%;
|
||||
-webkit-animation-delay: 2s;
|
||||
animation-delay: 2s;
|
||||
}
|
||||
.magic_stripe:nth-child(21) {
|
||||
left: 14%;
|
||||
background: rgba(254,0,4,0.8);
|
||||
top: -100%;
|
||||
-webkit-animation-delay: 2.1s;
|
||||
animation-delay: 2.1s;
|
||||
}
|
||||
.magic_stripe:nth-child(22) {
|
||||
left: 58%;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
top: -100%;
|
||||
-webkit-animation-delay: 2.2s;
|
||||
animation-delay: 2.2s;
|
||||
}
|
||||
.magic_stripe:nth-child(23) {
|
||||
left: 51%;
|
||||
background: rgba(254,0,4,0.8);
|
||||
top: -100%;
|
||||
-webkit-animation-delay: 2.3s;
|
||||
animation-delay: 2.3s;
|
||||
}
|
||||
.magic_stripe:nth-child(24) {
|
||||
left: 27%;
|
||||
background: rgba(254,0,4,0.8);
|
||||
top: -100%;
|
||||
-webkit-animation-delay: 2.4s;
|
||||
animation-delay: 2.4s;
|
||||
}
|
||||
.magic_stripe:nth-child(25) {
|
||||
left: 34%;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
top: -100%;
|
||||
-webkit-animation-delay: 2.5s;
|
||||
animation-delay: 2.5s;
|
||||
}
|
||||
|
||||
.Candy_Cane_Machine {
|
||||
-webkit-animation: 2s wobble infinite;
|
||||
animation: 2s wobble infinite;
|
||||
}
|
||||
.magic_border {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
animation: 3s Magic_Border infinite;
|
||||
|
||||
}
|
||||
@-webkit-keyframes Magic_Border {
|
||||
0% {
|
||||
outline: 10px dashed red;
|
||||
box-shadow: 0 0 0 10px green;
|
||||
}
|
||||
50% {
|
||||
outline: 10px dashed green;
|
||||
box-shadow: 0 0 0 10px red;
|
||||
}
|
||||
100% {
|
||||
outline: 10px dashed red;
|
||||
box-shadow: 0 0 0 10px green;
|
||||
}
|
||||
}
|
||||
@keyframes Magic_Border {
|
||||
0% {
|
||||
outline: 10px dashed red;
|
||||
box-shadow: 0 0 0 10px green;
|
||||
}
|
||||
50% {
|
||||
outline: 10px dashed green;
|
||||
box-shadow: 0 0 0 10px red;
|
||||
}
|
||||
100% {
|
||||
outline: 10px dashed red;
|
||||
box-shadow: 0 0 0 10px green;
|
||||
}
|
||||
}
|
||||
|
||||
#elf_small_stack {animation: whiz; }
|
||||
|
||||
|
||||
@keyframes whiz {
|
||||
0% {
|
||||
left: 250%;
|
||||
}
|
||||
100% {
|
||||
left: -250%;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes whiz {
|
||||
0% {
|
||||
left: 250%;
|
||||
}
|
||||
100% {
|
||||
left: -250%;
|
||||
}
|
||||
}
|
||||
/* SVG Candy Cane Stripes CSS */
|
||||
|
||||
.Red_Candy_Stripe{fill:#E11F26;}
|
||||
.White_Candy Stripe {fill:#F6F6F0;}
|
||||
|
||||
/* SVG Elfs with Presents Fills CSS */
|
||||
|
||||
.Elves_with_Presents_0{fill:#EAB67D;}
|
||||
.Elves_with_Presents_1{fill:#D18654;}
|
||||
.Elves_with_Presents_2{fill:#F7C992;}
|
||||
.Elves_with_Presents_3{fill:#303030;}
|
||||
.Elves_with_Presents_4{fill:#FF9494;}
|
||||
.Elves_with_Presents_5{fill:#B1C927;}
|
||||
.Elves_with_Presents_6{fill:#A8B523;}
|
||||
.Elves_with_Presents_7{fill:#DB2E2A;}
|
||||
.Elves_with_Presents_8{fill:#56B3BF;}
|
||||
.Elves_with_Presents_9{fill:#F9BD6E;}
|
||||
.Elves_with_Presents_10{fill:#FFA6C6;}
|
||||
.Elves_with_Presents_11{fill:#FF8DBB;}
|
||||
.Elves_with_Presents_12{fill:#EA98B9;}
|
||||
.Elves_with_Presents_13{fill:#FFBC6C;}
|
||||
.Elves_with_Presents_14{fill:#FFD19F;}
|
||||
.Elves_with_Presents_15{fill:#97DDC2;}
|
||||
.Elves_with_Presents_16{fill:#EAA459;}
|
||||
.Elves_with_Presents_17{fill:#7EC4A8;}
|
||||
.Elves_with_Presents_18{fill:#C72E6F;}
|
||||
.Elves_with_Presents_19{fill:#AD175F;}
|
||||
.Elves_with_Presents_20{fill:#EA78B4;}
|
||||
.Elves_with_Presents_21{fill:#991111;}
|
||||
.Elves_with_Presents_22{fill:#FFE7CF;}
|
||||
.Elves_with_Presents_23{fill:#AD1212;}
|
||||
.Elves_with_Presents_24{fill:#C11F1F;}
|
||||
.Elves_with_Presents_25{fill:#302E2E;}
|
||||
.Elves_with_Presents_26{fill:#8BE2E8;}
|
||||
.Elves_with_Presents_27{fill:#4DA6AD;}
|
||||
.Elves_with_Presents_28{fill:#FFC91F;}
|
||||
.Elves_with_Presents_29{fill:#EFB614;}
|
||||
.Elves_with_Presents_30{fill:#8F76AD;}
|
||||
.Elves_with_Presents_31{fill:#B8DB49;}
|
||||
.Elves_with_Presents_32{fill:#AFC457;}
|
||||
.Elves_with_Presents_33{fill:#A1BC2E;}
|
||||
.Elves_with_Presents_34{fill:#A2BC35;}
|
||||
.Elves_with_Presents_35{fill:#F991AC;}
|
||||
.Elves_with_Presents_36{fill:#FFD2E0;}
|
||||
.Elves_with_Presents_37{fill:#F9CDDB;}
|
||||
.Elves_with_Presents_38{fill:#AA62B7;}
|
||||
.Elves_with_Presents_39{fill:#FF648D;}
|
||||
.Elves_with_Presents_40{fill:#C92323;}
|
||||
.Elves_with_Presents_41{fill:#EDD1B7;}
|
||||
.Elves_with_Presents_42{fill:#515050;}
|
||||
|
||||
|
||||
|
||||
/* ===================================================*
|
||||
|
||||
."". ."",
|
||||
| | / /
|
||||
| | / /
|
||||
| | / /
|
||||
| |/ ;-._
|
||||
} ` _/ / ;
|
||||
| /` ) / / PEACE and LOVE
|
||||
| / /_/\_/\
|
||||
|/ / | Mark in New Orleans
|
||||
( ' \ '- |
|
||||
\ `. /
|
||||
| |
|
||||
| |
|
||||
|
||||
|
||||
|
||||
/* ===================================================*/
|
||||
|
||||
.login_frame {
|
||||
position: absolute;
|
||||
right: 140px;
|
||||
top: 0px;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.login_frame img {
|
||||
position: absolute;
|
||||
height: 120px;
|
||||
top: 6px;
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
#mainwrapper {
|
||||
position: relative;
|
||||
height: 730px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#padding {
|
||||
position: absolute;
|
||||
height: 40%;
|
||||
width: 100%;
|
||||
background-color: #c09277;
|
||||
z-index: 199;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
|
||||
.sm-fw {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
#resp-msg {
|
||||
margin: 0;
|
||||
margin-top: 15px;
|
||||
padding: 5px;
|
||||
font-size: 20px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
@media (min-height: 800px) {
|
||||
body{
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
@media (max-height: 800px) {
|
||||
#padding{
|
||||
display:none;
|
||||
}
|
||||
}
|
||||
@media (max-width: 800px) {
|
||||
body{
|
||||
overflow-x:scroll;
|
||||
}
|
||||
#padding{
|
||||
display: block;
|
||||
width: 1300px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
* Remodal - v1.1.1
|
||||
* Responsive, lightweight, fast, synchronized with CSS animations, fully customizable modal window plugin with declarative configuration and hash tracking.
|
||||
* http://vodkabears.github.io/remodal/
|
||||
*
|
||||
* Made by Ilya Makarov
|
||||
* Under MIT License
|
||||
*/
|
||||
|
||||
/* ==========================================================================
|
||||
Remodal's default mobile first theme
|
||||
========================================================================== */
|
||||
|
||||
/* Default theme styles for the background */
|
||||
|
||||
.remodal-bg.remodal-is-opening,
|
||||
.remodal-bg.remodal-is-opened {
|
||||
-webkit-filter: blur(3px);
|
||||
filter: blur(3px);
|
||||
}
|
||||
|
||||
/* Default theme styles of the overlay */
|
||||
|
||||
.remodal-overlay {
|
||||
background: rgba(43, 46, 56, 0.9);
|
||||
}
|
||||
|
||||
.remodal-overlay.remodal-is-opening,
|
||||
.remodal-overlay.remodal-is-closing {
|
||||
-webkit-animation-duration: 0.3s;
|
||||
animation-duration: 0.3s;
|
||||
-webkit-animation-fill-mode: forwards;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
.remodal-overlay.remodal-is-opening {
|
||||
-webkit-animation-name: remodal-overlay-opening-keyframes;
|
||||
animation-name: remodal-overlay-opening-keyframes;
|
||||
}
|
||||
|
||||
.remodal-overlay.remodal-is-closing {
|
||||
-webkit-animation-name: remodal-overlay-closing-keyframes;
|
||||
animation-name: remodal-overlay-closing-keyframes;
|
||||
}
|
||||
|
||||
/* Default theme styles of the wrapper */
|
||||
|
||||
.remodal-wrapper {
|
||||
padding: 10px 10px 0;
|
||||
}
|
||||
|
||||
/* Default theme styles of the modal dialog */
|
||||
|
||||
.remodal {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
padding: 25px;
|
||||
|
||||
-webkit-transform: translate3d(0, 0, 0);
|
||||
transform: translate3d(0, 0, 0);
|
||||
|
||||
color: #2b2e38;
|
||||
background: #c09277;
|
||||
}
|
||||
|
||||
.remodal.remodal-is-opening,
|
||||
.remodal.remodal-is-closing {
|
||||
-webkit-animation-duration: 0.3s;
|
||||
animation-duration: 0.3s;
|
||||
-webkit-animation-fill-mode: forwards;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
.remodal.remodal-is-opening {
|
||||
-webkit-animation-name: remodal-opening-keyframes;
|
||||
animation-name: remodal-opening-keyframes;
|
||||
}
|
||||
|
||||
.remodal.remodal-is-closing {
|
||||
-webkit-animation-name: remodal-closing-keyframes;
|
||||
animation-name: remodal-closing-keyframes;
|
||||
}
|
||||
|
||||
/* Vertical align of the modal dialog */
|
||||
|
||||
.remodal,
|
||||
.remodal-wrapper:after {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/* Close button */
|
||||
|
||||
.remodal-close {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
display: block;
|
||||
overflow: visible;
|
||||
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
cursor: pointer;
|
||||
-webkit-transition: color 0.2s;
|
||||
transition: color 0.2s;
|
||||
text-decoration: none;
|
||||
|
||||
color: #95979c;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.remodal-close:hover,
|
||||
.remodal-close:focus {
|
||||
color: #2b2e38;
|
||||
}
|
||||
|
||||
.remodal-close:before {
|
||||
font-family: Arial, "Helvetica CY", "Nimbus Sans L", sans-serif !important;
|
||||
font-size: 25px;
|
||||
line-height: 35px;
|
||||
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
display: block;
|
||||
|
||||
width: 35px;
|
||||
|
||||
content: "\00d7";
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Dialog buttons */
|
||||
|
||||
.remodal-confirm,
|
||||
.remodal-cancel {
|
||||
font: inherit;
|
||||
|
||||
display: inline-block;
|
||||
overflow: visible;
|
||||
|
||||
min-width: 110px;
|
||||
margin: 0;
|
||||
padding: 12px 0;
|
||||
|
||||
cursor: pointer;
|
||||
-webkit-transition: background 0.2s;
|
||||
transition: background 0.2s;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
text-decoration: none;
|
||||
|
||||
border: 0;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.remodal-confirm {
|
||||
color: #fff;
|
||||
background: #81c784;
|
||||
}
|
||||
|
||||
.remodal-confirm:hover,
|
||||
.remodal-confirm:focus {
|
||||
background: #66bb6a;
|
||||
}
|
||||
|
||||
.remodal-cancel {
|
||||
color: #fff;
|
||||
background: #e57373;
|
||||
}
|
||||
|
||||
.remodal-cancel:hover,
|
||||
.remodal-cancel:focus {
|
||||
background: #ef5350;
|
||||
}
|
||||
|
||||
/* Remove inner padding and border in Firefox 4+ for the button tag. */
|
||||
|
||||
.remodal-confirm::-moz-focus-inner,
|
||||
.remodal-cancel::-moz-focus-inner,
|
||||
.remodal-close::-moz-focus-inner {
|
||||
padding: 0;
|
||||
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/* Keyframes
|
||||
========================================================================== */
|
||||
|
||||
@-webkit-keyframes remodal-opening-keyframes {
|
||||
from {
|
||||
-webkit-transform: scale(1.05);
|
||||
transform: scale(1.05);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
-webkit-transform: none;
|
||||
transform: none;
|
||||
|
||||
opacity: 1;
|
||||
|
||||
-webkit-filter: blur(0);
|
||||
filter: blur(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes remodal-opening-keyframes {
|
||||
from {
|
||||
-webkit-transform: scale(1.05);
|
||||
transform: scale(1.05);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
-webkit-transform: none;
|
||||
transform: none;
|
||||
|
||||
opacity: 1;
|
||||
|
||||
-webkit-filter: blur(0);
|
||||
filter: blur(0);
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes remodal-closing-keyframes {
|
||||
from {
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
to {
|
||||
-webkit-transform: scale(0.95);
|
||||
transform: scale(0.95);
|
||||
|
||||
opacity: 0;
|
||||
|
||||
-webkit-filter: blur(0);
|
||||
filter: blur(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes remodal-closing-keyframes {
|
||||
from {
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
to {
|
||||
-webkit-transform: scale(0.95);
|
||||
transform: scale(0.95);
|
||||
|
||||
opacity: 0;
|
||||
|
||||
-webkit-filter: blur(0);
|
||||
filter: blur(0);
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes remodal-overlay-opening-keyframes {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes remodal-overlay-opening-keyframes {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes remodal-overlay-closing-keyframes {
|
||||
from {
|
||||
opacity: 1;
|
||||
}
|
||||
to {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes remodal-overlay-closing-keyframes {
|
||||
from {
|
||||
opacity: 1;
|
||||
}
|
||||
to {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Media queries
|
||||
========================================================================== */
|
||||
|
||||
@media only screen and (min-width: 641px) {
|
||||
.remodal {
|
||||
max-width: 700px;
|
||||
}
|
||||
}
|
||||
|
||||
/* IE8
|
||||
========================================================================== */
|
||||
|
||||
.lt-ie9 .remodal-overlay {
|
||||
background: #2b2e38;
|
||||
}
|
||||
|
||||
.lt-ie9 .remodal {
|
||||
width: 700px;
|
||||
}
|
||||
93
web/web_toy_workshop/challenge/static/css/remodal.css
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Remodal - v1.1.1
|
||||
* Responsive, lightweight, fast, synchronized with CSS animations, fully customizable modal window plugin with declarative configuration and hash tracking.
|
||||
* http://vodkabears.github.io/remodal/
|
||||
*
|
||||
* Made by Ilya Makarov
|
||||
* Under MIT License
|
||||
*/
|
||||
|
||||
/* ==========================================================================
|
||||
Remodal's necessary styles
|
||||
========================================================================== */
|
||||
|
||||
/* Hide scroll bar */
|
||||
|
||||
html.remodal-is-locked {
|
||||
overflow: hidden;
|
||||
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
|
||||
/* Anti FOUC */
|
||||
|
||||
.remodal,
|
||||
[data-remodal-id] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Necessary styles of the overlay */
|
||||
|
||||
.remodal-overlay {
|
||||
position: fixed;
|
||||
z-index: 9999;
|
||||
top: -5000px;
|
||||
right: -5000px;
|
||||
bottom: -5000px;
|
||||
left: -5000px;
|
||||
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Necessary styles of the wrapper */
|
||||
|
||||
.remodal-wrapper {
|
||||
position: fixed;
|
||||
z-index: 10000;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
|
||||
display: none;
|
||||
overflow: auto;
|
||||
|
||||
text-align: center;
|
||||
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.remodal-wrapper:after {
|
||||
display: inline-block;
|
||||
|
||||
height: 100%;
|
||||
margin-left: -0.05em;
|
||||
|
||||
content: "";
|
||||
}
|
||||
|
||||
/* Fix iPad, iPhone glitches */
|
||||
|
||||
.remodal-overlay,
|
||||
.remodal-wrapper {
|
||||
-webkit-backface-visibility: hidden;
|
||||
backface-visibility: hidden;
|
||||
}
|
||||
|
||||
/* Necessary styles of the modal dialog */
|
||||
|
||||
.remodal {
|
||||
position: relative;
|
||||
|
||||
outline: none;
|
||||
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-ms-text-size-adjust: 100%;
|
||||
text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
.remodal-is-initialized {
|
||||
/* Disable Anti-FOUC */
|
||||
display: inline-block;
|
||||
}
|
||||
BIN
web/web_toy_workshop/challenge/static/images/ballset.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
web/web_toy_workshop/challenge/static/images/ballset.png~
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
web/web_toy_workshop/challenge/static/images/bayblade.png~
Normal file
|
After Width: | Height: | Size: 467 KiB |
BIN
web/web_toy_workshop/challenge/static/images/bearset.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
web/web_toy_workshop/challenge/static/images/bearset.png~
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
web/web_toy_workshop/challenge/static/images/bin2.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
web/web_toy_workshop/challenge/static/images/bin2.png~
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
web/web_toy_workshop/challenge/static/images/cflower.png
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
web/web_toy_workshop/challenge/static/images/elf1.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
web/web_toy_workshop/challenge/static/images/elf2.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
web/web_toy_workshop/challenge/static/images/gameset.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
web/web_toy_workshop/challenge/static/images/gameset.png~
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
web/web_toy_workshop/challenge/static/images/logo.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
web/web_toy_workshop/challenge/static/images/santa-loading.gif
Normal file
|
After Width: | Height: | Size: 231 KiB |
BIN
web/web_toy_workshop/challenge/static/images/sign_post.png
Executable file
|
After Width: | Height: | Size: 13 KiB |
BIN
web/web_toy_workshop/challenge/static/images/trainset.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
web/web_toy_workshop/challenge/static/images/trainset.png~
Normal file
|
After Width: | Height: | Size: 18 KiB |
6
web/web_toy_workshop/challenge/static/js/bootstrap.min.js
vendored
Normal file
89
web/web_toy_workshop/challenge/static/js/conveyor.js
Normal file
@@ -0,0 +1,89 @@
|
||||
// Conveyor inspired from https://codepen.io/dariocorsi/pen/yOOBJK
|
||||
|
||||
var inputItem = document.getElementsByClassName('trash-in')[0];
|
||||
var outputItem = document.getElementsByClassName('toy-out')[0];
|
||||
|
||||
var index = 0;
|
||||
|
||||
var ChristmasPresents = document.getElementsByClassName('ChristmasPresents');
|
||||
|
||||
function cycleChristmasPresents(){
|
||||
setInterval(function(){
|
||||
|
||||
for (var i = 0; i < ChristmasPresents.length; ++i){
|
||||
ChristmasPresents[i].classList.remove('active');
|
||||
ChristmasPresents[i].classList.remove('active');
|
||||
};
|
||||
|
||||
ChristmasPresents[index].classList.add('active');
|
||||
ChristmasPresents[index].classList.add('active');
|
||||
|
||||
if(index < ChristmasPresents.length -1 ){
|
||||
index = index + 1;
|
||||
} else{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
console.log('index', index);
|
||||
}, 10000);
|
||||
};
|
||||
|
||||
cycleChristmasPresents();
|
||||
// JavaScript Document
|
||||
var c = document.getElementById('tiffany_snow'),
|
||||
$c = c.getContext("2d");
|
||||
var w = c.width = window.innerWidth,
|
||||
h = c.height = window.innerHeight;
|
||||
|
||||
Snowy();
|
||||
function Snowy() {
|
||||
var snow, arr = [];
|
||||
var num = 600, tsc = 1, sp = 1;
|
||||
var sc = 1.3, t = 0, mv = 20, min = 1;
|
||||
for (var i = 0; i < num; ++i) {
|
||||
snow = new Flake();
|
||||
snow.y = Math.random() * (h + 50);
|
||||
snow.x = Math.random() * w;
|
||||
snow.t = Math.random() * (Math.PI * 2);
|
||||
snow.sz = (100 / (10 + (Math.random() * 100))) * sc;
|
||||
snow.sp = (Math.pow(snow.sz * .8, 2) * .15) * sp;
|
||||
snow.sp = snow.sp < min ? min : snow.sp;
|
||||
arr.push(snow);
|
||||
}
|
||||
go();
|
||||
function go(){
|
||||
window.requestAnimationFrame(go);
|
||||
$c.clearRect(0, 0, w, h);
|
||||
$c.fillStyle = 'hsla(242, 95%, 3%, 1)';
|
||||
$c.fillRect(0, 0, w, h);
|
||||
$c.fill();
|
||||
for (var i = 0; i < arr.length; ++i) {
|
||||
f = arr[i];
|
||||
f.t += .05;
|
||||
f.t = f.t >= Math.PI * 2 ? 0 : f.t;
|
||||
f.y += f.sp;
|
||||
f.x += Math.sin(f.t * tsc) * (f.sz * .3);
|
||||
if (f.y > h + 50) f.y = -10 - Math.random() * mv;
|
||||
if (f.x > w + mv) f.x = - mv;
|
||||
if (f.x < - mv) f.x = w + mv;
|
||||
f.draw();}
|
||||
}
|
||||
function Flake() {
|
||||
this.draw = function() {
|
||||
this.g = $c.createRadialGradient(this.x, this.y, 0, this.x, this.y, this.sz);
|
||||
this.g.addColorStop(0, 'hsla(255,255%,255%,1)');
|
||||
this.g.addColorStop(1, 'hsla(255,255%,255%,0)');
|
||||
$c.moveTo(this.x, this.y);
|
||||
$c.fillStyle = this.g;
|
||||
$c.beginPath();
|
||||
$c.arc(this.x, this.y, this.sz, 0, Math.PI * 2, true);
|
||||
$c.fill();}
|
||||
}
|
||||
}
|
||||
/*________________________________________*/
|
||||
// window.addEventListener('resize', function(){
|
||||
// c.width = w = window.innerWidth;
|
||||
// c.height = h = window.innerHeight;
|
||||
// }, false);
|
||||
|
||||
|
||||
53
web/web_toy_workshop/challenge/static/js/index.js
Normal file
@@ -0,0 +1,53 @@
|
||||
$(document).ready(() => {
|
||||
$('#submit-btn').on('click', submit);
|
||||
});
|
||||
|
||||
const elf_info = (elf_id) => {
|
||||
inst = $('[data-remodal-id=modal]').remodal();
|
||||
inst.open();
|
||||
$('#elfavatar').attr('src',`/static/images/elf${elf_id}.png`);
|
||||
$('#elfname').text((elf_id == 1) ? 'Lhoris Farrie' : 'Ievis Chaeqirelle');
|
||||
}
|
||||
|
||||
const submit = async () => {
|
||||
$('#submit-btn').prop('disabled', true);
|
||||
|
||||
// prepare alert
|
||||
let card = $('#resp-msg');
|
||||
card.attr('class', 'alert alert-info');
|
||||
card.hide();
|
||||
|
||||
// validate
|
||||
let query = $('#query').val();
|
||||
if ($.trim(query) === '') {
|
||||
$('#submit-btn').prop('disabled', false);
|
||||
card.text('Please input your query first!');
|
||||
card.attr('class', 'alert alert-danger');
|
||||
card.show();
|
||||
return;
|
||||
}
|
||||
|
||||
await fetch('/api/submit', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({query: query}),
|
||||
})
|
||||
.then((response) => response.json()
|
||||
.then((resp) => {
|
||||
card.attr('class', 'alert alert-danger');
|
||||
if (response.status == 200) {
|
||||
card.attr('class', 'alert alert-success');
|
||||
}
|
||||
card.text(resp.message);
|
||||
card.show();
|
||||
}))
|
||||
.catch((error) => {
|
||||
card.text(error);
|
||||
card.attr('class', 'alert alert-danger');
|
||||
card.show();
|
||||
});
|
||||
|
||||
$('#submit-btn').prop('disabled', false);
|
||||
}
|
||||
2
web/web_toy_workshop/challenge/static/js/jquery-3.6.0.min.js
vendored
Normal file
10
web/web_toy_workshop/challenge/static/js/remodal.min.js
vendored
Normal file
1464
web/web_toy_workshop/challenge/views/index.hbs
Normal file
23
web/web_toy_workshop/challenge/views/queries.hbs
Normal file
@@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Toy Workshop</title>
|
||||
<link rel="icon" href="/static/images/logo.png" />
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/nes-core.min.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/dashboard.css" />
|
||||
</head>
|
||||
<body>
|
||||
<img src="/static/images/cflower.png" class="main-logo" />
|
||||
<p class="pb-3">Welcome back, admin!</p>
|
||||
<div class="dash-frame">
|
||||
{{#each queries}}
|
||||
<p>{{{this.query}}}</p>
|
||||
{{else}}
|
||||
<p class="empty">No content</p>
|
||||
{{/each}}
|
||||
</div>
|
||||
</body>
|
||||
<script type="text/javascript" src="/static/js/jquery-3.6.0.min.js"></script>
|
||||
<script type="text/javascript" src="/static/js/auth.js"></script>
|
||||
</html>
|
||||
15
web/web_toy_workshop/config/supervisord.conf
Normal file
@@ -0,0 +1,15 @@
|
||||
[supervisord]
|
||||
user=root
|
||||
nodaemon=true
|
||||
logfile=/dev/null
|
||||
logfile_maxbytes=0
|
||||
pidfile=/run/supervisord.pid
|
||||
|
||||
[program:node]
|
||||
directory=/app
|
||||
command=npm start
|
||||
autostart=true
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||