Commit 2912e253 authored by Manoj Kumar's avatar Manoj Kumar

Merge branch 'master' of http://gitlab.sliit.lk/2020_077/2020_077 into thavananthan_dev

parents e3fdcb59 ccc9483a
/node_modules
package-lock.json
.vscode/settings.json
.idea
\ No newline at end of file
.idea
dataq/mask_rcnn_coco.h5
/venv
/dataq/images
*.jpg
.ipynb_checkpoints
/dataq/object_detection
/dataq/models
/dataq/training
*.record
/dataq/faster_rcnn_inception_v2_coco_2018_01_28
/dataq/inference_graph
/dataset
/dataq/__pycache__
/textvoice/__pycache__
/reveng/core/__pycache__
/reveng/output
*.pyc
dataq/utils.zip
This diff is collapsed.
import shutil
from flask import send_file
from reveng.processInput import checkCommon, processInput
from flask import Flask, render_template, request, redirect
import json
import sys
import os
REVENG_DIR = os.path.dirname(os.path.abspath(__file__))
TEMPLATE = os.path.join(REVENG_DIR, "\\templates")
STATIC = os.path.join(REVENG_DIR, "\\static")
app = Flask(__name__)
app.config["DEBUG"] = True
@app.route('/test', methods=['GET'])
def testApi():
return "<h1>The API is working</h1>"
##DATAQ
# route to redirect Home page
@app.route('/')
def home():
return render_template('homePage.html')
@app.route('/cam')
def openCam():
os.system('python dataq\detect.py')
## END DATAQ
# route to redirect About Us page
@app.route('/about')
def about():
return render_template('about.html')
# route to redirect Text Translation page
@app.route('/tts')
def textToSignLanguage():
return render_template('index.html')
# route to display GIF image to the user
@app.route('/tts/response/', methods=['POST'])
def response():
clearoutputfolder()
message = request.get_json()
responseGIF = processInput(message['message'])
return send_file(responseGIF, mimetype='image/gif')
# clear the OUTPUT folder after displaying the GIF image
def clearoutputfolder():
folder = os.path.join(os.path.dirname(__file__), 'reveng\output')
for filename in os.listdir(folder):
file_path = os.path.join(folder, filename)
try:
if os.path.isfile(file_path) or os.path.islink(file_path):
os.unlink(file_path)
elif os.path.isdir(file_path):
shutil.rmtree(file_path)
except Exception as e:
print('Failed to delete %s. Reason: %s' % (file_path, e))
# route to redirect Sign Translation page
@app.route('/textToSign')
def textToSignEngine():
return render_template('textToSign.html')
# route to redirect Contact Us page
@app.route('/contact')
def contactUs():
return render_template('contactUs.html')
# for testing purpose
@app.route('/signToText')
def signToTextEngine():
return render_template('signToText.html')
host = "localhost"
app.run(host=host, port=3000)
if __name__ == "__main__":
app.run(debug=True)
# This file is for Frontends ###################33
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('homePage.html')
@app.route('/about')
def about():
return render_template('about.html')
@app.route('/signToText')
def signToTextEngine():
return render_template('signToText.html')
@app.route('/textToSign')
def textToSignEngine():
return render_template('textToSign.html')
@app.route('/textToSign/response/', methods=['POST'])
def response():
return render_template('about.html')
@app.route('/contactUs')
def contactUs():
return render_template('contactUs.html')
if __name__ == "__main__":
app.run(debug=True)
DATA AQUISITION
More to come...!
please wait
\ No newline at end of file
Run the detect.py
# 2020_077
# component for data aquisition
# component for data aquisition
# D. Manoj Kumar | IT17050272
#
# IT17050272 11-05-2020 #2, Created
#
import os,cv2, keras, json
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
print('Start of the file')
with open('labels_tesla.json') as labels_tesla:
tesla = json.load(labels_tesla)
data = pd.DataFrame(tesla)
labels = data['Label']
\ No newline at end of file
###
# The detect.py file is created to detect the images through the web-camera
# @author Manoj Kumar | IT17050272
# @version 1.0
# @since 2020-09-12
###
#imports
import numpy as np
import os
import sys
import tensorflow as tf
import cv2
from distutils.version import StrictVersion
from PIL import Image
from tensorflow import keras
sys.path.append('.')
from translation.modelUp import sign_predict
from object_detection.utils import label_map_util
from object_detection.utils import visualization_utils as vis_util
#Set Base Path
PATH = os.path.dirname(os.path.abspath(__file__))
#Check TensorFlow version
if StrictVersion(tf.__version__) < StrictVersion('1.15.3'):
raise ImportError('Please upgrade your TensorFlow installation to v1.15.3 or later!')
# Set Model Paths
MODEL_NAME = PATH +'\inference_graph'
PATH_TO_FROZEN_GRAPH = MODEL_NAME + '\\frozen_inference_graph.pb'
PATH_TO_LABELS = os.path.join(PATH +'\\training','labelmap.pbtxt')
#load tensorflow model to memory
detection_graph = tf.Graph()
with detection_graph.as_default():
od_graph_def = tf.compat.v1.GraphDef()
with tf.compat.v2.io.gfile.GFile(PATH_TO_FROZEN_GRAPH, 'rb') as fid:
serialized_graph = fid.read()
od_graph_def.ParseFromString(serialized_graph)
tf.import_graph_def(od_graph_def, name='')
#map labels
category_index = label_map_util.create_category_index_from_labelmap(PATH_TO_LABELS, use_display_name=True)
#run inference for a single frame
def run_inference_for_single_image(image, graph):
if 'detection_masks' in tensor_dict:
# The following processing is only for single image
detection_boxes = tf.squeeze(tensor_dict['detection_boxes'], [0])
detection_masks = tf.squeeze(tensor_dict['detection_masks'], [0])
# Reframe is required to translate mask from box coordinates to image coordinates and fit the image size.
real_num_detection = tf.cast(tensor_dict['num_detections'][0], tf.int32)
detection_boxes = tf.slice(detection_boxes, [0, 0], [real_num_detection, -1])
detection_masks_reframed = utils_ops.reframe_box_masks_to_image_masks(detection_masks, detection_boxes, image.shape[0], image.shape[1])
detection_masks_reframed = tf.cast(tf.greater(detection_masks_reframed, 0.5), tf.uint8)
# Follow the convention by adding back the batch dimension
tensor_dict['detection_masks'] = tf.expand_dims(detection_masks_reframed, 0)
image_tensor = tf.compat.v1.get_default_graph().get_tensor_by_name('image_tensor:0')
# Run inference
output_dict = sess.run(tensor_dict,
feed_dict={image_tensor: np.expand_dims(image, 0)})
# outputs are float32 numpy arrays
output_dict['num_detections'] = int(output_dict['num_detections'][0])
output_dict['detection_classes'] = output_dict['detection_classes'][0].astype(np.uint8)
output_dict['detection_boxes'] = output_dict['detection_boxes'][0]
output_dict['detection_scores'] = output_dict['detection_scores'][0]
if 'detection_masks' in output_dict:
output_dict['detection_masks'] = output_dict['detection_masks'][0]
return output_dict
#initialize camera
cap = cv2.VideoCapture(0)
try:
with detection_graph.as_default():
with tf.compat.v1.Session() as sess:
# Get handles to input and output tensors
ops = tf.compat.v1.get_default_graph().get_operations()
all_tensor_names = {output.name for op in ops for output in op.outputs}
tensor_dict = {}
key_detections = [
'num_detections', 'detection_boxes', 'detection_scores',
'detection_classes', 'detection_masks'
]
for key in key_detections:
tensor_name = key + ':0'
if tensor_name in all_tensor_names:
tensor_dict[key] = tf.compat.v1.get_default_graph().get_tensor_by_name(
tensor_name)
while True:
ret, image_np = cap.read()
# Expand dimensions since the model expects images to have shape: [1, None, None, 3]
image_np_expanded = np.expand_dims(image_np, axis=0)
# Actual detection.
output_dict = run_inference_for_single_image(image_np, detection_graph)
# Visualization of the results of a detection.
vis_util.visualize_boxes_and_labels_on_image_array(
image_np,
output_dict['detection_boxes'],
output_dict['detection_classes'],
output_dict['detection_scores'],
category_index,
instance_masks=output_dict.get('detection_masks'),
use_normalized_coordinates=True,
line_thickness=8)
score = round(100*output_dict['detection_scores'][0])
#send the request to translation component here
###
# I will be sending a POST request to u. a hand picture
if score > 80:
print(image_np_expanded.shape)
# sign_predict(image_np) <-- still under development
#waiting for the API on that component to be built
# end send request
## Press Q to close the camera
cv2.imshow('Hand Detector. Press Q to close', cv2.resize(image_np, (800, 600)))
if cv2.waitKey(25) & 0xFF == ord('q'):
cap.release()
cv2.destroyAllWindows()
break
except Exception as e:
print(e)
cap.release()
\ No newline at end of file
# Faster R-CNN with Inception v2, configured for Oxford-IIIT Pets Dataset.
# Users should configure the fine_tune_checkpoint field in the train config as
# well as the label_map_path and input_path fields in the train_input_reader and
# eval_input_reader. Search for "PATH_TO_BE_CONFIGURED" to find the fields that
# should be configured.
model {
faster_rcnn {
num_classes: 1
image_resizer {
keep_aspect_ratio_resizer {
min_dimension: 600
max_dimension: 1024
}
}
feature_extractor {
type: 'faster_rcnn_inception_v2'
first_stage_features_stride: 16
}
first_stage_anchor_generator {
grid_anchor_generator {
scales: [0.25, 0.5, 1.0, 2.0]
aspect_ratios: [0.5, 1.0, 2.0]
height_stride: 16
width_stride: 16
}
}
first_stage_box_predictor_conv_hyperparams {
op: CONV
regularizer {
l2_regularizer {
weight: 0.0
}
}
initializer {
truncated_normal_initializer {
stddev: 0.01
}
}
}
first_stage_nms_score_threshold: 0.0
first_stage_nms_iou_threshold: 0.7
first_stage_max_proposals: 300
first_stage_localization_loss_weight: 2.0
first_stage_objectness_loss_weight: 1.0
initial_crop_size: 14
maxpool_kernel_size: 2
maxpool_stride: 2
second_stage_box_predictor {
mask_rcnn_box_predictor {
use_dropout: false
dropout_keep_probability: 1.0
fc_hyperparams {
op: FC
regularizer {
l2_regularizer {
weight: 0.0
}
}
initializer {
variance_scaling_initializer {
factor: 1.0
uniform: true
mode: FAN_AVG
}
}
}
}
}
second_stage_post_processing {
batch_non_max_suppression {
score_threshold: 0.0
iou_threshold: 0.6
max_detections_per_class: 100
max_total_detections: 300
}
score_converter: SOFTMAX
}
second_stage_localization_loss_weight: 2.0
second_stage_classification_loss_weight: 1.0
}
}
train_config: {
batch_size: 1
optimizer {
momentum_optimizer: {
learning_rate: {
manual_step_learning_rate {
initial_learning_rate: 0.0002
schedule {
step: 900000
learning_rate: .00002
}
schedule {
step: 1200000
learning_rate: .000002
}
}
}
momentum_optimizer_value: 0.9
}
use_moving_average: false
}
gradient_clipping_by_norm: 10.0
fine_tune_checkpoint: "D:/manobran technologies/SLIIT 4th/cdap/2020_077/dataq/object_detection/faster_rcnn_inception_v2_coco_2018_01_28/model.ckpt"
from_detection_checkpoint: true
load_all_detection_checkpoint_vars: true
# Note: The below line limits the training process to 200K steps, which we
# empirically found to be sufficient enough to train the pets dataset. This
# effectively bypasses the learning rate schedule (the learning rate will
# never decay). Remove the below line to train indefinitely.
num_steps: 200000
data_augmentation_options {
random_horizontal_flip {
}
}
}
train_input_reader: {
tf_record_input_reader {
input_path: "D:/manobran technologies/SLIIT 4th/cdap/2020_077/dataq/train.record"
}
label_map_path: "D:/manobran technologies/SLIIT 4th/cdap/2020_077/dataq/training/labelmap.pbtxt"
}
eval_config: {
metrics_set: "coco_detection_metrics"
num_examples: 1101
}
eval_input_reader: {
tf_record_input_reader {
input_path: "D:/manobran technologies/SLIIT 4th/cdap/2020_077/dataq/test.record"
}
label_map_path: "D:/manobran technologies/SLIIT 4th/cdap/2020_077/dataq/training/labelmap.pbtxt"
shuffle: false
num_readers: 1
}
This diff is collapsed.
###
# * The xml_to_csv.py file
# *
# * @author Manoj Kumar | IT17050272
# * @version 1.0
# * @since 2020-09-23
###
#imports
import os
import glob
import pandas as pd
import xml.etree.ElementTree as ET
#converter *.xml file to *.csv
def xml_to_csv(path):
xml_list = []
#Check all XML files in current directory
for xml_file in glob.glob(path + '/*.xml'):
tree = ET.parse(xml_file)
root = tree.getroot()
for member in root.findall('object'):
value = (root.find('filename').text,
int(root.find('size')[0].text),
int(root.find('size')[1].text),
member[0].text,
int(member[4][0].text),
int(member[4][1].text),
int(member[4][2].text),
int(member[4][3].text)
)
xml_list.append(value)
#predefined column name
column_name = ['filename', 'width', 'height', 'class', 'xmin', 'ymin', 'xmax', 'ymax']
xml_df = pd.DataFrame(xml_list, columns=column_name)
return xml_df
def converter():
#check directories : train and test
for directory in ['train','test']:
image_path = os.path.join(os.getcwd(), 'images/{}'.format(directory))
xml_df = xml_to_csv(image_path)
xml_df.to_csv('images/{}_labels.csv'.format(directory), index=None)
print('Successfully converted xml to csv.')
#main method
converter()
......@@ -10,7 +10,14 @@
const socket = io.connect('http://localhost:5000');
socket.on('image',(data)=>{
console.log('data',data);
})
});
function callGoogle(){
window.open('/google')
}
</script>
<button onclick="callGoogle()">
google
</button>
</body>
</html>
\ No newline at end of file
{
"name": "2020_077",
"version": "1.0.0",
"description": "Web based Sign Language to Text Translator using ML ",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "http://gitlab.sliit.lk/2020_077/2020_077"
},
"author": "Eventors 4.0",
"license": "ISC",
"dependencies": {
"express": "^4.17.1",
"nodemon": "^2.0.3",
"python-shell": "^1.0.8",
"socket.io": "^2.3.0"
}
}
# 2020_077
# component for converting text input to SSL
# G.M.A.S. Bastiansz | IT17143950
#from reveng.processInput import processInput
from reveng.processSentence import processCommonSentence
from reveng.processWord import processWord
from reveng.getImages import getImagesCommonSentence
from reveng.getImages import getImagesCommonWord
from reveng.getImages import getImagesRareWord
from reveng.checkCommon import checkInJson
###
# This file is used as a main file for the user-inputs which have same words/sentences
# appears in common.json file
# @author Amashi Bastiansz | IT17143950
# @version 1.2
# @since 2020-07-30
###
import json
import os
from reveng.processWord import processWord
from reveng.processSentence import processCommonSentence, processRareSentence
REVENG = os.path.dirname(os.path.abspath(__file__))
jsonPath = os.path.join(REVENG, 'common.json')
def checkInJson(message):
###
# This method is used to create a GIF image for the user-input which is similar
# with a sentence appears in common.json file
# Also, this method is used to create a GIF image for the user-input which is similar
# with a word appears in common.json file
###
# convert user-input into lowercase
message = message.lower()
with open(jsonPath) as jsonfile:
data = json.load(jsonfile)
sentences = data['sentences']
common_sentences = sentences['common_sentences']
english_common_sentences = common_sentences['english']
words = data['words']
common = words['common_words']
englishwords = common['english']
alphabets = data['alphabet']
english_alphabet = alphabets['english']
# compare the user-entered text with common sentences section in common.json file and create GIF
if message in english_common_sentences:
somegif = processCommonSentence(message)
return somegif
else:
commonwords = []
uncommonWords = []
for item in message:
if item in englishwords:
commonwords.append(item)
else:
uncommonWords.append(item)
# compare the user-entered text with common words section in common.json file and create GIF
if message in englishwords:
somegif = processWord(message)
return somegif
else:
somegif = "no gif"
print("Call Rare methods here...")
{
"sentences": {
"common_sentences": {
"english": [
"how are you",
"good morning",
"good afternoon",
"good evening",
"good night",
"thank you",
"may be"
]
}
},
"words": {
"common_words": {
"english": [
"ayubowan",
"good",
"morning",
"afternoon",
"evening",
"night",
"name",
"sorry",
"understand",
"yes",
"no",
"bad",
"easy",
"hard",
"difficult",
"new",
"old",
"i",
"me",
"you",
"deaf",
"hearing",
"dirty",
"clean",
"beautiful",
"translator",
"interpreter",
"ugly",
"money",
"true",
"truth",
"lie",
"false",
"same",
"different",
"slow",
"many",
"few",
"all",
"speak",
"talk",
"teach",
"learn",
"go",
"come",
"finish",
"can",
"cannot"
]
}
},
"alphabet": {
"english": [
"a",
"b",
"c",
"d",
"e",
"f",
"g",
"h",
"i",
"j",
"k",
"l",
"m",
"n",
"o",
"p",
"q",
"r",
"s",
"t",
"u",
"v",
"w",
"x",
"y",
"z"
]
}
}
\ No newline at end of file
{
"sentences": {
"common_sentences": {
"english": [
"how are you",
"good morning",
"good afternoon",
"good evening",
"good night",
"nice to meet you",
"i love you",
"thank you",
"dont understand",
"what is your name",
"i am deaf",
"are you deaf or hearing",
"you and i are same",
"i am being truthful",
"what time",
"how did you learn sign language",
"what time will you go",
"what did you say",
"where do you work",
"sinhala and tamil new year",
"when is poya day"
]
}
},
"words": {
"common_words": {
"english": [
"welcome",
"name",
"sorry",
"understand",
"yes",
"no",
"maybe",
"good",
"bad",
"easy",
"hard",
"difficult",
"new",
"old",
"i",
"me",
"you",
"deaf",
"hearing",
"dirty",
"clean",
"beautiful",
"ugly",
"money",
"true",
"lie",
"many",
"few",
"all",
"talk",
"teach",
"learn",
"go",
"come",
"finish",
"eat",
"like",
"want",
"love",
"play",
"make",
"have",
"sit",
"work",
"rest",
"ask",
"think",
"forget",
"look",
"change",
"help",
"who",
"what",
"where",
"when",
"why",
"how",
"how many",
"happy",
"sad",
"angry",
"sleepy",
"surprise",
"calm",
"bore",
"scare",
"nervous",
"laugh",
"lazy",
"ayubowan",
"afternoon"
]
}
},
"alphabet": {
"english": [
"a",
"b",
"c",
"d",
"e",
"f",
"g",
"h",
"i",
"j",
"k",
"l",
"m",
"n",
"o",
"p",
"q",
"r",
"s",
"t",
"u",
"v",
"w",
"x",
"y",
"z"
]
}
}
{
"type": "service_account",
"project_id": "storage-9eed9",
"private_key_id": "54ccd5c32b946fc4acdd4b7ba6b523174570c353",
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDJvxRS4KefjqDt\nyrTW+Xq2L3AvmXmujR/nz+ttMzN+5/UrpjpnowpiEZ0eTydeH541OzZLx3woHlih\neJ6SHBevgvdOjjTXjuIlNyqfYlyS+Tfzn3jJ4o6/OidRWq6v51taJ0uSMDi4i1bh\nsigMbXyik17QIKOHEZFM1dptkiOSmxZ75v3s3oQXgVCAPKQvTMXfkfXTOv91nw0z\npo2n5p2pjyAFt/kWh6Z9SHEr8RRS3nNyRo4f/VQtt3h0TfzOr4WU/t015uTC3hSv\nm6/CmlHPBRmXt4f4Eae0Wo4BMcPmyVimt4oc7QZnr4IWOEpnd/m+I8B3CdenKzzZ\nzfnNqwCLAgMBAAECggEAPCvP6XoUtIuLJvEW56kn9s+GQ8QgHTX9JpwGSR8ExFx1\nbKva7o8bqS08sc4E3VdLze+XnZllR+fpIlvB260iSVgj35udWg9FFrlx7nCdUL6g\n9/n/wiLe1V0IXgTQZil4PxbKPNNCD5SLeKw0sqQzEKAonqWlcEMGlaaQy65TCsXL\nU6HpIwWrh6NEWP7qoIp60i0VFrBW3skV/45V3ZZW5HpZkUD+jvS98zd9OU6YOTFU\n4fETtUoy8QaaOS7qM3oA2KdC4Wv4ihofyWtnCoJTEheN6HwcCbj711trCODuyNUi\nC0FfHKcJOx37PMuRNI4JFKaBmd0qD7p/sXwORx2EHQKBgQD9+oHzwfsa6EgYm23y\nurq/HU6omBi1ambVIQM9jFWHbKg9kjDoYRlYmXA3XFcrofiPerSOei2+uJefXHbq\nvRIVJ/sBWSlj6DNJMzkLWpJdeO6QBNxQ5sAlkMpfc70yH9meo3Z+5gldR7LDpAdX\n8WricnnSyDX6a5QSOok/G7pUFQKBgQDLWiWAtYkROJ3gFOi8IvEvLI8n6FlSau7Q\nNkHhBtaNsPUiLFnt01jTkkVbbU+QRq/4IgFJxz+ofAajvtMhQZR6AsIGxailnCCB\nYEbYKrFyqF4+Sq9pd42XAtLs6ca+iFPSZOmrSQouLNN6LladL2V3tN00089ab0iQ\n5zaj2goKHwKBgQCqoqayna5Wap8doTeib+BNzKPvU5iuMhl6sd5aeLFx9gemrlSb\nm7kKtLQXDbwnPYAg7cDnRKD9VUnRMK9YkMTYX+8c/cl4LSZf1MFLpoNVt40YR5u5\n4v5PftLohHsldQ6hrZNMOMMr36L0HH0uka1NDLpaalcRsztdb+SL+NYb7QKBgQC4\ng8GHujD3CVJnY1GSdHo3/cyfv3pdCF5NWw4H6zZ/NtQW//tRivYMc6qvPM528Uz2\nb5SPp1WhwXgc2CenA2SAGUSI9I0ESFhOTFe8CXEdwpxRFV946Vv2bD+LbMxDUlwM\nijhkjU/Jei8hrC43TixZpCkbqB17x4ImyUWRA2UcrQKBgFzox3Z22ueE8GcVDQOx\nwcDer+9kAC3vZ+H/hAuV+Cm3Nl0qZWLAy+ELzcNGWaGBoHKXuJlFqPUgkv3q1L7j\naR4f8w4NPcUmUk0L9VUYq0lsBvq1WRZU/wiDm12HOA9U/sH0A4PDp3IZEJ2wJIx9\nAZkkcFY2m1DORiq8wQnQXzns\n-----END PRIVATE KEY-----\n",
"client_email": "firebase-adminsdk-sstjw@storage-9eed9.iam.gserviceaccount.com",
"client_id": "100932427645847514490",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-sstjw%40storage-9eed9.iam.gserviceaccount.com"
}
{
"type": "service_account",
"project_id": "storage-9eed9",
"private_key_id": "54ccd5c32b946fc4acdd4b7ba6b523174570c353",
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDJvxRS4KefjqDt\nyrTW+Xq2L3AvmXmujR/nz+ttMzN+5/UrpjpnowpiEZ0eTydeH541OzZLx3woHlih\neJ6SHBevgvdOjjTXjuIlNyqfYlyS+Tfzn3jJ4o6/OidRWq6v51taJ0uSMDi4i1bh\nsigMbXyik17QIKOHEZFM1dptkiOSmxZ75v3s3oQXgVCAPKQvTMXfkfXTOv91nw0z\npo2n5p2pjyAFt/kWh6Z9SHEr8RRS3nNyRo4f/VQtt3h0TfzOr4WU/t015uTC3hSv\nm6/CmlHPBRmXt4f4Eae0Wo4BMcPmyVimt4oc7QZnr4IWOEpnd/m+I8B3CdenKzzZ\nzfnNqwCLAgMBAAECggEAPCvP6XoUtIuLJvEW56kn9s+GQ8QgHTX9JpwGSR8ExFx1\nbKva7o8bqS08sc4E3VdLze+XnZllR+fpIlvB260iSVgj35udWg9FFrlx7nCdUL6g\n9/n/wiLe1V0IXgTQZil4PxbKPNNCD5SLeKw0sqQzEKAonqWlcEMGlaaQy65TCsXL\nU6HpIwWrh6NEWP7qoIp60i0VFrBW3skV/45V3ZZW5HpZkUD+jvS98zd9OU6YOTFU\n4fETtUoy8QaaOS7qM3oA2KdC4Wv4ihofyWtnCoJTEheN6HwcCbj711trCODuyNUi\nC0FfHKcJOx37PMuRNI4JFKaBmd0qD7p/sXwORx2EHQKBgQD9+oHzwfsa6EgYm23y\nurq/HU6omBi1ambVIQM9jFWHbKg9kjDoYRlYmXA3XFcrofiPerSOei2+uJefXHbq\nvRIVJ/sBWSlj6DNJMzkLWpJdeO6QBNxQ5sAlkMpfc70yH9meo3Z+5gldR7LDpAdX\n8WricnnSyDX6a5QSOok/G7pUFQKBgQDLWiWAtYkROJ3gFOi8IvEvLI8n6FlSau7Q\nNkHhBtaNsPUiLFnt01jTkkVbbU+QRq/4IgFJxz+ofAajvtMhQZR6AsIGxailnCCB\nYEbYKrFyqF4+Sq9pd42XAtLs6ca+iFPSZOmrSQouLNN6LladL2V3tN00089ab0iQ\n5zaj2goKHwKBgQCqoqayna5Wap8doTeib+BNzKPvU5iuMhl6sd5aeLFx9gemrlSb\nm7kKtLQXDbwnPYAg7cDnRKD9VUnRMK9YkMTYX+8c/cl4LSZf1MFLpoNVt40YR5u5\n4v5PftLohHsldQ6hrZNMOMMr36L0HH0uka1NDLpaalcRsztdb+SL+NYb7QKBgQC4\ng8GHujD3CVJnY1GSdHo3/cyfv3pdCF5NWw4H6zZ/NtQW//tRivYMc6qvPM528Uz2\nb5SPp1WhwXgc2CenA2SAGUSI9I0ESFhOTFe8CXEdwpxRFV946Vv2bD+LbMxDUlwM\nijhkjU/Jei8hrC43TixZpCkbqB17x4ImyUWRA2UcrQKBgFzox3Z22ueE8GcVDQOx\nwcDer+9kAC3vZ+H/hAuV+Cm3Nl0qZWLAy+ELzcNGWaGBoHKXuJlFqPUgkv3q1L7j\naR4f8w4NPcUmUk0L9VUYq0lsBvq1WRZU/wiDm12HOA9U/sH0A4PDp3IZEJ2wJIx9\nAZkkcFY2m1DORiq8wQnQXzns\n-----END PRIVATE KEY-----\n",
"client_email": "firebase-adminsdk-sstjw@storage-9eed9.iam.gserviceaccount.com",
"client_id": "100932427645847514490",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-sstjw%40storage-9eed9.iam.gserviceaccount.com"
}
###
# This file is used to create firbase configuration for the application
# Each application has unique firbase configuration.
# @author Amashi Bastiansz | IT17143950
# @version 1.0
# @since 2020-08-13
###
import json
import os
import firebase_admin
import datetime
import requests
import io
from firebase_admin import credentials
from firebase_admin import storage
import pyrebase
PATH = os.path.dirname(os.path.abspath(__file__))
JSON = os.path.join(PATH, 'credentials.json')
cred = credentials.Certificate(JSON)
app = firebase_admin.initialize_app(
cred,
{
'storageBucket': 'storage-9eed9.appspot.com',
},
name='storage')
bucket = storage.bucket(app=app)
config = {
"apiKey": "AIzaSyBEV4qObNECL9Lz-_RTOM2YLEMo5Ux7Yhk",
"authDomain": "storage-9eed9.firebaseapp.com",
"databaseURL": "https://storage-9eed9.firebaseio.com",
"projectId": "storage-9eed9",
"storageBucket": "storage-9eed9.appspot.com",
"messagingSenderId": "613478230434",
"serviceAccount": JSON
}
firebase = pyrebase.initialize_app(config)
store = firebase.storage()
def getStorageInstance():
###
# This method is used to redirect to the firebase cloud storage
# @return Firebase Cloud Storage
###
return store
###
# This file is used to fetch images of the hand signs from the system database
# @author Amashi Bastiansz | IT17143950
# @version 1.6
# @since 2020-08-30
###
import json
import os
import datetime
import requests
import io
import PIL.Image as pigm
from firebase_admin import storage
from reveng.firebaseConfig import getStorageInstance
from reveng.gifMaker import generateGIF
from gcloud.storage.blob import Blob
Blob.generate_signed_url
store = getStorageInstance()
def getImagesCommonWord(message):
###
# This method is used to select hand signs for user-entered text
# These hand signs are for the words in the common_word section in the
# common.json file
# @return call to generateGIF() method with selected hand images
###
images = store.child().list_files()
imageRes = []
for i in images:
if i.name.startswith(message):
print("image name =" + i.name)
imageRes.append(i)
sendingToGIF = []
for i in imageRes:
url = i.generate_signed_url(datetime.timedelta(300), method='GET')
response = requests.get(url)
images = io.BytesIO(response.content)
img = pigm.open(images)
sendingToGIF.append(img)
return generateGIF(sendingToGIF)
def getImagesForCommonWord(message):
###
# This method is used to select hand signs for user-entered text
# These hand signs are for the words in the common_word section in the
# common.json file
# This method is specifically made for the words which may have more than one hand sign
# in the sign language (the words which are need multiple signs to show one verbal word)
# @return call to generateGIF() method with selected hand images
###
images = store.child().list_files()
imageRes = []
for i in images:
if i.name.startswith(message) and len(i.name) > 8:
print("common image name =" + i.name)
imageRes.append(i)
returnArr = []
for i in imageRes:
url = i.generate_signed_url(datetime.timedelta(300), method='GET')
response = requests.get(url)
images = io.BytesIO(response.content)
img = pigm.open(images)
returnArr.append(img)
return returnArr
def getImagesForRareWord(message):
###
# This method is used to select hand signs for user-entered text
# which is not appeared in common.json file
# @return call to generateGIF() method with selected hand images
###
images = store.child().list_files()
imageRes = []
for i in images:
if i.name.startswith(message) and len(i.name) < 8:
print("rare image name =" + i.name)
imageRes.append(i)
returnArr = []
for i in imageRes:
url = i.generate_signed_url(datetime.timedelta(300), method='GET')
response = requests.get(url)
images = io.BytesIO(response.content)
img = pigm.open(images)
returnArr.append(img)
return returnArr
def getImagesRareWord(message):
###
# This method is used to select hand signs for user-entered text
# which is not appeared in common.json file
# @return call to generateGIF() method with selected hand images
###
images = store.child().list_files()
imageRes = []
sendingToGIF = 0
for i in images:
if i.name == message + ".jpg":
print("image name =" + i.name)
imageRes.append(i)
for i in imageRes:
url = i.generate_signed_url(datetime.timedelta(300), method='GET')
response = requests.get(url)
images = io.BytesIO(response.content)
img = pigm.open(images)
sendingToGIF = img
return sendingToGIF
def getImagesCommonSentence(sentence):
###
# This method is used to select hand signs for user-entered sentence
# These hand signs are for the sentences in the common_sentence section in the
# common.json file
# @return call to generateGIF() method with selected hand images
###
sendingToGIF = []
imageRes = []
images = store.child().list_files()
for i in images:
for word in sentence:
if i.name.startswith(word) and len(i.name) > 8:
print(i.name)
print("image name =" + i.name)
imageRes.append(i)
print(imageRes)
for i in imageRes:
url = i.generate_signed_url(datetime.timedelta(300), method='GET')
response = requests.get(url)
imagesfromFirebase = io.BytesIO(response.content)
img = pigm.open(imagesfromFirebase)
sendingToGIF.append(img)
print("Type of array ", type(sendingToGIF))
return generateGIF(sendingToGIF)
###
# This file is used to display the created GIF to user
# This file is still at TESTING PHASE
# @author Amashi Bastiansz | IT17143950
# @version 1.2
# @since 2020-10-01
###
import os
import urllib.request
from flask import flash, request, redirect, url_for, Flask, render_template
from werkzeug.utils import secure_filename
from reveng.gifDisplayMain import main
# system will only allows to display files with below extensions
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])
app = Flask(__name__)
def allowed_file(filename):
###
# This method is used check the extension of selected file
# @return the extension to check whether it is allowed
###
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/', methods=['POST'])
def upload_image():
###
# This method is used upload the selected file to the exact folder
# after checking whether the extensions are matched.
# @return redirect to upload.html
###
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file']
if file.filename == '':
flash('No image selected for uploading')
return redirect(request.url)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(main.config['UPLOAD_FOLDER'], filename))
flash('Image successfully uploaded and displayed')
return render_template('upload.html', filename=filename)
else:
flash('Allowed image types are -> png, jpg, jpeg, gif')
return redirect(request.url)
@app.route('/display/<filename>')
def display_image(filename):
###
# This method is used display the uploaded file back to the user
# @return display the file in the interface
###
return redirect(url_for('static', filename='uploads/' + filename), code=301)
if __name__ == "__main__":
app.secret_key = "secret key"
app.run(debug=True)
###
# This file is used to display the created GIF to the user on the interface
# Still in TESTING phase
# @author Amashi Bastiansz | IT17143950
# @version 1.5
# @since 2020-10-01
###
from flask import Flask
main = Flask(__name__)
# create and initialize a new folder to upload created GIFS
UPLOAD_FOLDER = 'static/uploads/'
main.secret_key = "secret key"
main.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
main.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
###
# This file is used to:
# generate a GIF image
# send the generated GIF to the folder
# delete the GIF from cache
# @author Amashi Bastiansz | IT17143950
# @version 1.5
# @since 2020-10-01
###
import imageio
import os
import string
import random
import cv2
import PIL.Image as pigm
import PIL.GifImagePlugin as gifHandler
PATH = os.path.dirname(os.path.abspath(__file__))
gifName = ''.join(random.choices(string.ascii_uppercase +
string.digits, k=15))
def generateGIF(images):
###
# This method is used to generate a path for the created GIF image
# @return the generated GIF path
###
gifPath = os.path.join(PATH + "\\output\\" + gifName + '.gif')
imageio.mimwrite(gifPath, images, duration=0.5)
print(gifPath)
return gifPath
def sendGIF():
###
# This method is used to send the generated GIF to the exact folder to store it
###
x = imageio.mimread(os.path.join(PATH + "\\output\\" + gifName + '.gif'))
return x
def deleteFromCache():
###
# This method is used to delete the generated GIF from cache after uploading it to
# the exact project folder
# @return call to generateGIF() method with selected hand images
###
os.remove(os.path.join(PATH + "\\output\\" + gifName + '.gif'))
###
# This file is used to process the user-entered input
# Through the methods in this file, the system will apply different Tokenization techniques
# (in NLP) in order to make the input more identifiable
# @author Amashi Bastiansz | IT17143950
# @version 1.4
# @since 2020-07-15
###
import os
import json
import datetime
import requests
import io
import PIL.Image as pigm
from reveng.firebaseConfig import getStorageInstance
from reveng.checkCommon import checkInJson
from reveng.processSentence import processCommonSentence
from reveng.getImages import getImagesForCommonWord, getImagesForRareWord
from reveng.gifMaker import generateGIF
def checkCommon(message):
###
#This method is used to return the checkInJson() method in checkCommon.py file
###
return checkInJson(message)
# initialize the variable, store to get the Firebase configuration
store = getStorageInstance()
REVENG = os.path.dirname(os.path.abspath(__file__))
jsonPath = os.path.join(REVENG, 'common.json')
def checkInCommonSentence(sentence):
###
# This method is used to compare the user-input with common_sentence
# section in common.json file
#If a similar setence appear in common_sentence section in common.json
# file the method will return true
###
with open(jsonPath) as jsonfile:
data = json.load(jsonfile)
sentences = data['sentences']
common_sentences = sentences['common_sentences']
english_common_sentences = common_sentences['english']
if sentence in english_common_sentences:
print("In common sentences")
return True
else:
return False
def checkInCommonWord(word):
###
# This method is used to compare the user-input with common_words
# section in common.json file
# If a similar setence appear in common_word section in common.json
# file the method will return true
###
with open(jsonPath) as jsonfile:
data = json.load(jsonfile)
words = data['words']
common = words['common_words']
englishwords = common['english']
if word in englishwords:
return True
else:
return False
def processInput(message):
###
# This method is used to send the fetched hand images to generateGIF()
# method to create the final GIF image
###
message = message.lower()
if len(message.split(" ")) >= 2:
if checkInCommonSentence(message):
return processCommonSentence(message)
else:
imageArray = []
sendingToGIF = []
images = store.child().list_files()
for i in images:
for item in message.split(" "):
if checkInCommonWord(item):
if i.name.startswith(item):
print("image name =" + i.name)
imageArray.append(i)
break
else:
for letter in list(item):
print("Length ", len(i.name))
if i.name.startswith(letter) and len(i.name) < 9:
print("image name =" + i.name)
imageArray.append(i)
break
for i in imageArray:
url = i.generate_signed_url(
datetime.timedelta(300), method='GET')
response = requests.get(url)
imagesfromFirebase = io.BytesIO(response.content)
img = pigm.open(imagesfromFirebase)
sendingToGIF.append(img)
return generateGIF(sendingToGIF)
###
# This file is used to check a user-entered sentence with json file
# and return the relevant GIF image
# @author Amashi Bastiansz | IT17143950
# @version 2.0
# @since 2020-07-15
###
import json
import os
from reveng.getImages import getImagesCommonSentence
REVENG = os.path.dirname(os.path.abspath(__file__))
def processCommonSentence(message):
###
# This method is used to process a sentence which has similar sentences in common.json file
# and to return the GIF
###
splitMessage = message.split(" ")
gif = getImagesCommonSentence(splitMessage)
return gif
def processRareSentence(message):
###
# This method is used to process a sentence which does not have similar sentences in common.json file
#and to return the GIF
###
splitMessage = message.split(" ")
gif = getImagesCommonSentence(splitMessage)
return gif
html {
background-color: white;
color: black;
}
h1 {
color: black;
margin-bottom: 0;
margin-top: 0;
text-align: center;
font-size: 40px;
}
h3 {
color: black;
font-size: 20px;
margin-top: 3px;
text-align: center;
}
#chatbox {
background-color: white;
margin-left: auto;
margin-right: auto;
width: 40%;
margin-top: 60px;
}
#userInput {
margin-left: auto;
margin-right: auto;
width: 40%;
margin-top: 60px;
}
#textInput {
width: 87%;
border: none;
border-bottom: 1px solid #009688;
font-family: monospace;
font-size: 17px;
}
#buttonInput {
padding: 3px;
font-family: monospace;
font-size: 17px;
background-color: white;
color: green;
border-color: green;
border-radius: 2px;
}
#buttonInput :hover {
background-color: green;
color: white;
}
.userText {
color: black;
font-family: monospace;
font-size: 17px;
text-align: right;
line-height: 30px;
}
.userText span {
background-color: #009688;
padding: 10px;
border-radius: 2px;
}
.botText {
color: black;
font-family: monospace;
font-size: 17px;
text-align: left;
line-height: 30px;
}
.botText span {
background-color: white;
padding: 10px;
border-radius: 2px;
color: black;
}
#tidbit {
position: absolute;
bottom: 0;
right: 0;
width: 300px;
}
<!--
* The file is to create a form for Text to SSL Translator
* For TESTING purposes
*
* @author Amashi Bastiansz | IT17143950
* @version 1.0
* @since 2020-05-31
-->
<!DOCTYPE html>
<html>
<head>
<link
rel="stylesheet"
type="text/css"
href="{{url_for('static', filename='styles/style.css')}}"
/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<h1 style="color: black">Text to SSL Translator</h1>
<div>
<div id="chatbox">
<p class="botText">
<span
>Welcome to Text to Sign Convertor.
<br />
Enter the sentence you need to translate into SSL</span
>
</p>
</div>
<form action="" method="POST" id="form">
<div id="userInput">
<input
id="textInput"
name="msg"
maxlength="50"
placeholder="Enter text here"
/>
<br /><br />
<button id="buttonInput" type="submit">TRANSLATE</button>
</div>
</form>
<p id="req"></p>
<img src="{{ user_image }}" alt="User Image" />
</div>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script>
$("#textInput").keypress(function (e) {
if (e.which == 13) {
getResponseSign();
}
});
$("#buttonInput").click(function () {
getResponseSign();
});
$("#form").on("submit", function (e) {
var message = $("#textInput").val();
e.preventDefault();
$.ajax({
url: "http://127.0.0.1:3000/tts/response/",
data: JSON.stringify({ message: message }),
method: "POST",
contentType: "application/json",
success: function (message) {
var text = $("#textInput").val();
var userHtml = '<p class="userText"><span>' + text + "</span></p>";
$("#textInput").val("");
$("#chatbox").append(userHtml);
document
.getElementById("userInput")
.scrollIntoView({ block: "start", behavior: "smooth" });
},
});
});
</script>
</body>
</html>
<!--
* The file is to create a form for uploading and display files
* For TESTING purposes
*
* @author Amashi Bastiansz | IT17143950
* @version 1.0
* @since 2020-10-01
-->
<!doctype html>
<html>
<head>
<title>Python Flask File Upload Example</title>
</head>
<body>
<h2>Select a file to upload</h2>
<p>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul class=flashes>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
</p>
{% if filename %}
<div>
<img src="{{ url_for('display_image', filename=filename) }}">
</div>
{% endif %}
<form method="post" action="/" enctype="multipart/form-data">
<dl>
<p>
<input type="file" name="file" autocomplete="off" required>
</p>
</dl>
<p>
<input type="submit" value="Submit">
</p>
</form>
</body>
</html>
/**
* IT17050272 01-05-2020 #1, Created
* IT17050272 14-05-2020 #2, Modified
*
*/
const express = require('express');
const app = express();
const path = require('path');
const server = require('http').Server(app);
const io = require('socket.io')(server);
const cv = require('opencv4nodejs');
const port = process.env.PORT || 5000;
const video = new cv.VideoCapture(0);
app.get("/", (req, res) => {
res.sendFile(path.join(__dirname,'index.html'));
});
setInterval(()=>{
io.emit('image','sample')
},200)
server.listen(port, () => {
console.log(`Server running on port ${port}`);
});
// app.get('/test', function (req, res) {
// console.log('Server working');
// res.status(200).json({
// "server_status": "OK"
// })
// })
// //version 01
// app.get('/dalembert', callD_almbert);
// function callD_almbert(req, res) {
// var spawn = require('child_process').spawn;
// console.log('Creating spawn');
// var filePath = "./test-python-module/google.py";
// var process = spawn('python', [filePath,
// "https://www.google.com"
// ]);
// console.log('request ok!');
// process.stdout.on('data',function(data){
// res.send(data.toString());
// });
// }
// // end of version 01
// //version 02 - python script
// var pythonShell = require('python-shell');
// app.get('/dalembert/shell', callD_almbert2);
// function callD_almbert2(req, res) {
// var options = {
// args: [
// req.query.funds,
// req.query.size,
// req.query.count,
// req.query.sims
// ]
// }
// pythonShell.PythonShell.run('./test-python-module/d_alembert.py',options,function(err,data){
// if(err)
// res.send(err);
// res.status(200).json({
// "data":data
// })
// })
// }
//read from camera
This diff is collapsed.
This diff is collapsed.
(function ($) {
'use strict';
// Preloader js
$(window).on('load', function () {
$('.preloader').fadeOut(700);
});
// Sticky Menu
$(window).scroll(function () {
var height = $('.top-header').innerHeight();
if ($('header').offset().top > 10) {
$('.top-header').addClass('hide');
$('.navigation').addClass('nav-bg');
$('.navigation').css('margin-top', '-' + height + 'px');
} else {
$('.top-header').removeClass('hide');
$('.navigation').removeClass('nav-bg');
$('.navigation').css('margin-top', '-' + 0 + 'px');
}
});
// Background-images
$('[data-background]').each(function () {
$(this).css({
'background-image': 'url(' + $(this).data('background') + ')'
});
});
//Hero Slider
$('.hero-slider').slick({
autoplay: true,
autoplaySpeed: 7500,
pauseOnFocus: false,
pauseOnHover: false,
infinite: true,
arrows: true,
fade: true,
prevArrow: '<button type=\'button\' class=\'prevArrow\'><i class=\'ti-angle-left\'></i></button>',
nextArrow: '<button type=\'button\' class=\'nextArrow\'><i class=\'ti-angle-right\'></i></button>',
dots: true
});
$('.hero-slider').slickAnimation();
// venobox popup
$(document).ready(function () {
$('.venobox').venobox();
});
// filter
$(document).ready(function () {
var containerEl = document.querySelector('.filtr-container');
var filterizd;
if (containerEl) {
filterizd = $('.filtr-container').filterizr({});
}
//Active changer
$('.filter-controls li').on('click', function () {
$('.filter-controls li').removeClass('active');
$(this).addClass('active');
});
});
// Count Up
function counter() {
var oTop;
if ($('.count').length !== 0) {
oTop = $('.count').offset().top - window.innerHeight;
}
if ($(window).scrollTop() > oTop) {
$('.count').each(function () {
var $this = $(this),
countTo = $this.attr('data-count');
$({
countNum: $this.text()
}).animate({
countNum: countTo
}, {
duration: 1000,
easing: 'swing',
step: function () {
$this.text(Math.floor(this.countNum));
},
complete: function () {
$this.text(this.countNum);
}
});
});
}
}
$(window).on('scroll', function () {
counter();
});
})(jQuery);
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
<!DOCTYPE html>
<html lang="zxx">
<head>
<meta charset="utf-8">
<title>EasyTalk</title>
<!-- mobile responsive meta -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<!-- ** Plugins Needed for the Project ** -->
<!-- Bootstrap -->
<link rel="stylesheet" href="static/plugins/bootstrap/bootstrap.min.css">
<!-- slick slider -->
<link rel="stylesheet" href="static/plugins/slick/slick.css">
<!-- themefy-icon -->
<link rel="stylesheet" href="static/plugins/themify-icons/themify-icons.css">
<!-- animation css -->
<link rel="stylesheet" href="static/plugins/animate/animate.css">
<!-- aos -->
<link rel="stylesheet" href="static/plugins/aos/aos.css">
<!-- venobox popup -->
<link rel="stylesheet" href="static/plugins/venobox/venobox.css">
<!-- Main Stylesheet -->
<link href="static/css/style.css" rel="stylesheet">
<!--Favicon-->
<link rel="shortcut icon" href="static/images/favicon.png" type="image/x-icon">
<link rel="icon" href="static/images/favicon.png" type="image/x-icon">
</head>
<body>
<!-- header -->
<header class="fixed-top">
<!-- navbar -->
<div class="navigation w-100">
<div class="container">
<nav class="navbar navbar-expand-lg navbar-dark p-0">
<a class="navbar-brand" href="/"><img src="static/images/EasyTalkLogo.png" alt="logo"></a>
<button class="navbar-toggler rounded-0" type="button" data-toggle="collapse" data-target="#navigation"
aria-controls="navigation" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navigation">
<ul class="navbar-nav ml-auto text-center">
<li class="nav-item @@home">
<a class="nav-link" href="/">Home</a>
</li>
<li class="nav-item active">
<a class="nav-link" href="about">About</a>
</li>
<li class="nav-item dropdown view">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
Translators
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="signToText">SSL to English Translator</a>
<a class="dropdown-item" href="textToSign">English to SSL Translator</a>
</div>
</li>
<li class="nav-item @@contact">
<a class="nav-link" href="contactUs">Contact Us</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
</header>
<!-- /header -->
<!-- page title -->
<section class="page-title-section overlay" data-background="static/images/backgrounds/page-title.jpg">
<div class="container">
<div class="row">
<div class="col-md-8">
<ul class="list-inline custom-breadcrumb">
<li class="list-inline-item"><a class="h2 text-primary font-secondary" href="about">About Us</a></li>
<li class="list-inline-item text-white h3 font-secondary @@nasted"></li>
</ul>
<p class="text-lighten">Our courses offer a good compromise between the continuous assessment favoured by some universities and the emphasis placed on final exams by others.</p>
</div>
</div>
</div>
</section>
<!-- /page title -->
<!-- about -->
<section class="section">
<div class="container">
<div class="row">
<div class="col-12">
<img class="img-fluid w-100 mb-4" src="static/images/about/about-page.jpg" alt="about image">
<h2 class="section-title">ABOUT OUR JOURNY</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et.dolore magna aliqua. Ut enim ad minim veniam, quis nostrud. Lorem ipsum dolor sit amet consectetur, adipisicing elit. Saepe ipsa illo quod veritatis, magni debitis fugiat dolore voluptates! Consequatur, aliquid. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat perferendis sint optio similique. Et amet magni facilis vero corporis quos.</p>
<p>exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ipsum a, facere fugit error accusamus est officiis vero in, nostrum laboriosam corrupti explicabo, cumque repudiandae deleniti perspiciatis quae consectetur enim. Laboriosam!</p>
</div>
</div>
</div>
</section>
<!-- /about -->
<!-- footer -->
<footer>
<!-- copyright -->
<div class="copyright py-4 bg-footer">
<div class="container">
<div class="row">
<div class="col-sm-7 text-sm-left text-center">
<p class="mb-0">Copyright
<script>
var CurrentYear = new Date().getFullYear()
document.write(CurrentYear)
</script>
© eventors-inc</p>
</div>
<div class="col-sm-5 text-sm-right text-center">
<ul class="list-inline">
<li class="list-inline-item"><a class="d-inline-block p-2" href="#"><i class="ti-facebook text-primary"></i></a></li>
<li class="list-inline-item"><a class="d-inline-block p-2" href="#"><i class="ti-twitter-alt text-primary"></i></a></li>
<li class="list-inline-item"><a class="d-inline-block p-2" href="#"><i class="ti-linkedin text-primary"></i></a></li>
<li class="list-inline-item"><a class="d-inline-block p-2" href="#"><i class="ti-instagram text-primary"></i></a></li>
</ul>
</div>
</div>
</div>
</div>
</footer>
<!-- /footer -->
<!-- jQuery -->
<script src="static/plugins/jQuery/jquery.min.js"></script>
<!-- Bootstrap JS -->
<script src="static/plugins/bootstrap/bootstrap.min.js"></script>
<!-- slick slider -->
<script src="static/plugins/slick/slick.min.js"></script>
<!-- aos -->
<script src="static/plugins/aos/aos.js"></script>
<!-- venobox popup -->
<script src="static/plugins/venobox/venobox.min.js"></script>
<!-- filter -->
<script src="static/plugins/filterizr/jquery.filterizr.min.js"></script>
<!-- Main Script -->
<script src="static/js/script.js"></script>
</body>
</html>
\ No newline at end of file
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('homePage.html')
@app.route('/about')
def about():
return render_template('about.html')
@app.route('/signToText')
def signToTextEngine():
return render_template('signToText.html')
@app.route('/textToSign')
def textToSignEngine():
return render_template('textToSign.html')
@app.route('/contactUs')
def contactUs():
return render_template('contactUs.html')
if __name__ == "__main__":
app.run(debug=True)
<!DOCTYPE html>
<html lang="zxx">
<head>
<meta charset="utf-8">
<title>EasyTalk</title>
<!-- mobile responsive meta -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<!-- ** Plugins Needed for the Project ** -->
<!-- Bootstrap -->
<link rel="stylesheet" href="static/plugins/bootstrap/bootstrap.min.css">
<!-- slick slider -->
<link rel="stylesheet" href="static/plugins/slick/slick.css">
<!-- themefy-icon -->
<link rel="stylesheet" href="static/plugins/themify-icons/themify-icons.css">
<!-- animation css -->
<link rel="stylesheet" href="static/plugins/animate/animate.css">
<!-- aos -->
<link rel="stylesheet" href="static/plugins/aos/aos.css">
<!-- venobox popup -->
<link rel="stylesheet" href="static/plugins/venobox/venobox.css">
<!-- Main Stylesheet -->
<link href="static/css/style.css" rel="stylesheet">
<!--Favicon-->
<link rel="shortcut icon" href="static/images/favicon.png" type="image/x-icon">
<link rel="icon" href="static/images/favicon.png" type="image/x-icon">
</head>
<body>
<!-- header -->
<header class="fixed-top">
<!-- navbar -->
<div class="navigation w-100">
<div class="container">
<nav class="navbar navbar-expand-lg navbar-dark p-0">
<a class="navbar-brand" href="/"><img src="static/images/EasyTalkLogo.png" alt="logo"></a>
<button class="navbar-toggler rounded-0" type="button" data-toggle="collapse" data-target="#navigation"
aria-controls="navigation" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navigation">
<ul class="navbar-nav ml-auto text-center">
<li class="nav-item @@home">
<a class="nav-link" href="/">Home</a>
</li>
<li class="nav-item @@about">
<a class="nav-link" href="about">About</a>
</li>
<li class="nav-item dropdown view">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
Translators
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="signToText">SSL to English Translator</a>
<a class="dropdown-item" href="textToSign">English to SSL Translator</a>
</div>
</li>
<li class="nav-item active">
<a class="nav-link" href="contactUs">Contact Us</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
</header>
<!-- /header -->
<!-- page title -->
<section class="page-title-section overlay" data-background="static/images/backgrounds/page-title.jpg">
<div class="container">
<div class="row">
<div class="col-md-8">
<ul class="list-inline custom-breadcrumb">
<li class="list-inline-item"><a class="h2 text-primary font-secondary" href="contactUs">Contact Us</a></li>
<li class="list-inline-item text-white h3 font-secondary @@nasted"></li>
</ul>
<p class="text-lighten">Do you have other questions? Don't worry, there aren't any dumb questions. Just fill out the form below and we'll get back to you as soon as possible.</p>
</div>
</div>
</div>
</section>
<!-- /page title -->
<!-- contact -->
<section class="section bg-gray">
<div class="container">
<div class="row">
<div class="col-lg-12">
<h2 class="section-title">Contact Us</h2>
</div>
</div>
<div class="row">
<div class="col-lg-7 mb-4 mb-lg-0">
<form action="#">
<input type="text" class="form-control mb-3" id="name" name="name" placeholder="Your Name">
<input type="email" class="form-control mb-3" id="mail" name="mail" placeholder="Your Email">
<input type="text" class="form-control mb-3" id="subject" name="subject" placeholder="Subject">
<textarea name="message" id="message" class="form-control mb-3" placeholder="Your Message"></textarea>
<button type="submit" value="send" class="btn btn-primary">SEND MESSAGE</button>
</form>
</div>
<div class="col-lg-5">
<p class="mb-5">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Velit recusandae voluptates doloremque veniam temporibus porro culpa ipsa, nisi soluta minima saepe laboriosam debitis nesciunt. Dolore, labore. Accusamus nulla sed cum aliquid exercitationem debitis error harum porro maxime quo iusto aliquam dicta modi earum fugiat, vel possimus commodi, deleniti et veniam, fuga ipsum praesentium. Odit unde optio nulla ipsum quae obcaecati! Quod esse natus quibusdam asperiores quam vel, tempore itaque architecto ducimus expedita</p>
<a href="tel:+8802057843248" class="text-color h5 d-block">+880 20 5784 3248</a>
<a href="mailto:yourmail@email.com" class="mb-5 text-color h5 d-block">yourmail@email.com</a>
<p>71 Shelton Street<br>London WC2H 9JQ England</p>
</div>
</div>
</div>
</section>
<!-- /contact -->
<!-- footer -->
<footer>
<!-- copyright -->
<div class="copyright py-4 bg-footer">
<div class="container">
<div class="row">
<div class="col-sm-7 text-sm-left text-center">
<p class="mb-0">Copyright
<script>
var CurrentYear = new Date().getFullYear()
document.write(CurrentYear)
</script>
© eventors-inc</p>
</div>
<div class="col-sm-5 text-sm-right text-center">
<ul class="list-inline">
<li class="list-inline-item"><a class="d-inline-block p-2" href="#"><i class="ti-facebook text-primary"></i></a></li>
<li class="list-inline-item"><a class="d-inline-block p-2" href="#"><i class="ti-twitter-alt text-primary"></i></a></li>
<li class="list-inline-item"><a class="d-inline-block p-2" href="#"><i class="ti-linkedin text-primary"></i></a></li>
<li class="list-inline-item"><a class="d-inline-block p-2" href="#"><i class="ti-instagram text-primary"></i></a></li>
</ul>
</div>
</div>
</div>
</div>
</footer>
<!-- /footer -->
<!-- jQuery -->
<script src="static/plugins/jQuery/jquery.min.js"></script>
<!-- Bootstrap JS -->
<script src="static/plugins/bootstrap/bootstrap.min.js"></script>
<!-- slick slider -->
<script src="static/plugins/slick/slick.min.js"></script>
<!-- aos -->
<script src="static/plugins/aos/aos.js"></script>
<!-- venobox popup -->
<script src="static/plugins/venobox/venobox.min.js"></script>
<!-- filter -->
<script src="static/plugins/filterizr/jquery.filterizr.min.js"></script>
<!-- Main Script -->
<script src="static/js/script.js"></script>
</body>
</html>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
<!DOCTYPE html>
<html lang="zxx">
<head>
<meta charset="utf-8">
<title>EasyTalk</title>
<!-- mobile responsive meta -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<!-- ** Plugins Needed for the Project ** -->
<!-- Bootstrap -->
<link rel="stylesheet" href="static/plugins/bootstrap/bootstrap.min.css">
<!-- slick slider -->
<link rel="stylesheet" href="static/plugins/slick/slick.css">
<!-- themefy-icon -->
<link rel="stylesheet" href="static/plugins/themify-icons/themify-icons.css">
<!-- animation css -->
<link rel="stylesheet" href="static/plugins/animate/animate.css">
<!-- aos -->
<link rel="stylesheet" href="static/plugins/aos/aos.css">
<!-- venobox popup -->
<link rel="stylesheet" href="static/plugins/venobox/venobox.css">
<!-- Main Stylesheet -->
<link href="static/css/style.css" rel="stylesheet">
<!--Favicon-->
<link rel="shortcut icon" href="static/images/favicon.png" type="image/x-icon">
<link rel="icon" href="static/images/favicon.png" type="image/x-icon">
</head>
<body>
<!-- header -->
<header class="fixed-top">
<!-- navbar -->
<div class="navigation w-100">
<div class="container">
<nav class="navbar navbar-expand-lg navbar-dark p-0">
<a class="navbar-brand" href="/"><img src="static/images/EasyTalkLogo.png" alt="logo"></a>
<button class="navbar-toggler rounded-0" type="button" data-toggle="collapse" data-target="#navigation"
aria-controls="navigation" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navigation">
<ul class="navbar-nav ml-auto text-center">
<li class="nav-item @@home">
<a class="nav-link" href="/">Home</a>
</li>
<li class="nav-item @@about">
<a class="nav-link" href="about">About</a>
</li>
<li class="nav-item dropdown view">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
Translators
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="signToText">SSL to English Translator</a>
<a class="dropdown-item" href="textToSign">English to SSL Translator</a>
</div>
</li>
<li class="nav-item active">
<a class="nav-link" href="contactUs">Contact Us</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
</header>
<!-- /header -->
<!-- hero slider -->
<section class="hero-section overlay bg-cover" data-background="static/images/banner/banner-1.jpg">
<div class="container">
<div class="hero-slider">
<!-- slider item -->
<div class="hero-slider-item">
<div class="row">
<div class="col-md-8">
<h1 class="text-white" data-animation-out="fadeOutRight" data-delay-out="5" data-duration-in=".3" data-animation-in="fadeInLeft" data-delay-in=".1">Your bright future is our mission</h1>
<p class="text-muted mb-4" data-animation-out="fadeOutRight" data-delay-out="5" data-duration-in=".3" data-animation-in="fadeInLeft" data-delay-in=".4">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor
incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exer</p>
<a href="contact.html" class="btn btn-primary" data-animation-out="fadeOutRight" data-delay-out="5" data-duration-in=".3" data-animation-in="fadeInLeft" data-delay-in=".7">Apply now</a>
</div>
</div>
</div>
<!-- slider item -->
<div class="hero-slider-item">
<div class="row">
<div class="col-md-8">
<h1 class="text-white" data-animation-out="fadeOutUp" data-delay-out="5" data-duration-in=".3" data-animation-in="fadeInDown" data-delay-in=".1">Your bright future is our mission</h1>
<p class="text-muted mb-4" data-animation-out="fadeOutUp" data-delay-out="5" data-duration-in=".3" data-animation-in="fadeInDown" data-delay-in=".4">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor
incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exer</p>
<a href="contact.html" class="btn btn-primary" data-animation-out="fadeOutUp" data-delay-out="5" data-duration-in=".3" data-animation-in="fadeInDown" data-delay-in=".7">Apply now</a>
</div>
</div>
</div>
<!-- slider item -->
<div class="hero-slider-item">
<div class="row">
<div class="col-md-8">
<h1 class="text-white" data-animation-out="fadeOutDown" data-delay-out="5" data-duration-in=".3" data-animation-in="fadeInUp" data-delay-in=".1">Your bright future is our mission</h1>
<p class="text-muted mb-4" data-animation-out="fadeOutDown" data-delay-out="5" data-duration-in=".3" data-animation-in="fadeInUp" data-delay-in=".4">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor
incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exer</p>
<a href="contact.html" class="btn btn-primary" data-animation-out="fadeOutDown" data-delay-out="5" data-duration-in=".3" data-animation-in="zoomIn" data-delay-in=".7">Apply now</a>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- /hero slider -->
<!-- jQuery -->
<script src="static/plugins/jQuery/jquery.min.js"></script>
<!-- Bootstrap JS -->
<script src="static/plugins/bootstrap/bootstrap.min.js"></script>
<!-- slick slider -->
<script src="static/plugins/slick/slick.min.js"></script>
<!-- aos -->
<script src="static/plugins/aos/aos.js"></script>
<!-- venobox popup -->
<script src="static/plugins/venobox/venobox.min.js"></script>
<!-- filter -->
<script src="static/plugins/filterizr/jquery.filterizr.min.js"></script>
<!-- Main Script -->
<script src="static/js/script.js"></script>
</body>
</html>
\ No newline at end of file
(function ($) {
'use strict';
// Preloader js
$(window).on('load', function () {
$('.preloader').fadeOut(700);
});
// Sticky Menu
$(window).scroll(function () {
var height = $('.top-header').innerHeight();
if ($('header').offset().top > 10) {
$('.top-header').addClass('hide');
$('.navigation').addClass('nav-bg');
$('.navigation').css('margin-top', '-' + height + 'px');
} else {
$('.top-header').removeClass('hide');
$('.navigation').removeClass('nav-bg');
$('.navigation').css('margin-top', '-' + 0 + 'px');
}
});
// Background-images
$('[data-background]').each(function () {
$(this).css({
'background-image': 'url(' + $(this).data('background') + ')'
});
});
//Hero Slider
$('.hero-slider').slick({
autoplay: true,
autoplaySpeed: 7500,
pauseOnFocus: false,
pauseOnHover: false,
infinite: true,
arrows: true,
fade: true,
prevArrow: '<button type=\'button\' class=\'prevArrow\'><i class=\'ti-angle-left\'></i></button>',
nextArrow: '<button type=\'button\' class=\'nextArrow\'><i class=\'ti-angle-right\'></i></button>',
dots: true
});
$('.hero-slider').slickAnimation();
// venobox popup
$(document).ready(function () {
$('.venobox').venobox();
});
// filter
$(document).ready(function () {
var containerEl = document.querySelector('.filtr-container');
var filterizd;
if (containerEl) {
filterizd = $('.filtr-container').filterizr({});
}
//Active changer
$('.filter-controls li').on('click', function () {
$('.filter-controls li').removeClass('active');
$(this).addClass('active');
});
});
// Count Up
function counter() {
var oTop;
if ($('.count').length !== 0) {
oTop = $('.count').offset().top - window.innerHeight;
}
if ($(window).scrollTop() > oTop) {
$('.count').each(function () {
var $this = $(this),
countTo = $this.attr('data-count');
$({
countNum: $this.text()
}).animate({
countNum: countTo
}, {
duration: 1000,
easing: 'swing',
step: function () {
$this.text(Math.floor(this.countNum));
},
complete: function () {
$this.text(this.countNum);
}
});
});
}
}
$(window).on('scroll', function () {
counter();
});
})(jQuery);
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
window.marker = null;
function initialize() {
var map;
var latitude = $('#map_canvas').attr('data-latitude');
var longitude = $('#map_canvas').attr('data-longitude');
var nottingham = new google.maps.LatLng(latitude, longitude);
var style = [{
"featureType": "landscape",
"stylers": [{
"hue": "#FFAD00"
},
{
"saturation": 50.2
},
{
"lightness": -34.8
},
{
"gamma": 1
}
]
},
{
"featureType": "road.highway",
"stylers": [{
"hue": "#FFAD00"
},
{
"saturation": -19.8
},
{
"lightness": -1.8
},
{
"gamma": 1
}
]
},
{
"featureType": "road.arterial",
"stylers": [{
"hue": "#FFAD00"
},
{
"saturation": 72.4
},
{
"lightness": -32.6
},
{
"gamma": 1
}
]
},
{
"featureType": "road.local",
"stylers": [{
"hue": "#FFAD00"
},
{
"saturation": 74.4
},
{
"lightness": -18
},
{
"gamma": 1
}
]
},
{
"featureType": "water",
"stylers": [{
"hue": "#00FFA6"
},
{
"saturation": -63.2
},
{
"lightness": 38
},
{
"gamma": 1
}
]
},
{
"featureType": "poi",
"stylers": [{
"hue": "#FFC300"
},
{
"saturation": 54.2
},
{
"lightness": -14.4
},
{
"gamma": 1
}
]
}
];
var mapOptions = {
center: nottingham,
mapTypeId: google.maps.MapTypeId.ROADMAP,
backgroundColor: "#000",
zoom: 15,
panControl: false,
zoomControl: true,
mapTypeControl: false,
scaleControl: false,
streetViewControl: false,
overviewMapControl: false,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.LARGE
}
}
map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
var mapType = new google.maps.StyledMapType(style, {
name: "Grayscale"
});
map.mapTypes.set('grey', mapType);
map.setMapTypeId('grey');
var marker_image = 'plugins/google-map/images/marker.png';
var pinIcon = new google.maps.MarkerImage(marker_image, null, null, null, new google.maps.Size(37, 55));
marker = new google.maps.Marker({
position: nottingham,
map: map,
icon: pinIcon,
title: 'Shoper'
});
}
var map = document.getElementById('map_canvas');
if (map != null) {
google.maps.event.addDomListener(window, 'load', initialize);
}
\ No newline at end of file
This diff is collapsed.
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Generated by Fontastic.me</metadata>
<defs>
<font id="slick" horiz-adv-x="512">
<font-face font-family="slick" units-per-em="512" ascent="480" descent="-32"/>
<missing-glyph horiz-adv-x="512" />
<glyph unicode="&#8594;" d="M241 113l130 130c4 4 6 8 6 13 0 5-2 9-6 13l-130 130c-3 3-7 5-12 5-5 0-10-2-13-5l-29-30c-4-3-6-7-6-12 0-5 2-10 6-13l87-88-87-88c-4-3-6-8-6-13 0-5 2-9 6-12l29-30c3-3 8-5 13-5 5 0 9 2 12 5z m234 143c0-40-9-77-29-110-20-34-46-60-80-80-33-20-70-29-110-29-40 0-77 9-110 29-34 20-60 46-80 80-20 33-29 70-29 110 0 40 9 77 29 110 20 34 46 60 80 80 33 20 70 29 110 29 40 0 77-9 110-29 34-20 60-46 80-80 20-33 29-70 29-110z"/>
<glyph unicode="&#8592;" d="M296 113l29 30c4 3 6 7 6 12 0 5-2 10-6 13l-87 88 87 88c4 3 6 8 6 13 0 5-2 9-6 12l-29 30c-3 3-8 5-13 5-5 0-9-2-12-5l-130-130c-4-4-6-8-6-13 0-5 2-9 6-13l130-130c3-3 7-5 12-5 5 0 10 2 13 5z m179 143c0-40-9-77-29-110-20-34-46-60-80-80-33-20-70-29-110-29-40 0-77 9-110 29-34 20-60 46-80 80-20 33-29 70-29 110 0 40 9 77 29 110 20 34 46 60 80 80 33 20 70 29 110 29 40 0 77-9 110-29 34-20 60-46 80-80 20-33 29-70 29-110z"/>
<glyph unicode="&#8226;" d="M475 256c0-40-9-77-29-110-20-34-46-60-80-80-33-20-70-29-110-29-40 0-77 9-110 29-34 20-60 46-80 80-20 33-29 70-29 110 0 40 9 77 29 110 20 34 46 60 80 80 33 20 70 29 110 29 40 0 77-9 110-29 34-20 60-46 80-80 20-33 29-70 29-110z"/>
<glyph unicode="&#97;" d="M475 439l0-128c0-5-1-9-5-13-4-4-8-5-13-5l-128 0c-8 0-13 3-17 11-3 7-2 14 4 20l40 39c-28 26-62 39-100 39-20 0-39-4-57-11-18-8-33-18-46-32-14-13-24-28-32-46-7-18-11-37-11-57 0-20 4-39 11-57 8-18 18-33 32-46 13-14 28-24 46-32 18-7 37-11 57-11 23 0 44 5 64 15 20 9 38 23 51 42 2 1 4 3 7 3 3 0 5-1 7-3l39-39c2-2 3-3 3-6 0-2-1-4-2-6-21-25-46-45-76-59-29-14-60-20-93-20-30 0-58 5-85 17-27 12-51 27-70 47-20 19-35 43-47 70-12 27-17 55-17 85 0 30 5 58 17 85 12 27 27 51 47 70 19 20 43 35 70 47 27 12 55 17 85 17 28 0 55-5 81-15 26-11 50-26 70-45l37 37c6 6 12 7 20 4 8-4 11-9 11-17z"/>
</font></defs></svg>
/* Slider */
.slick-slider
{
position: relative;
display: block;
box-sizing: border-box;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-touch-callout: none;
-khtml-user-select: none;
-ms-touch-action: pan-y;
touch-action: pan-y;
-webkit-tap-highlight-color: transparent;
}
.slick-list
{
position: relative;
display: block;
overflow: hidden;
margin: 0;
padding: 0;
}
.slick-list:focus
{
outline: none;
}
.slick-list.dragging
{
cursor: pointer;
cursor: hand;
}
.slick-slider .slick-track,
.slick-slider .slick-list
{
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
-o-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
.slick-track
{
position: relative;
top: 0;
left: 0;
display: block;
margin-left: auto;
margin-right: auto;
}
.slick-track:before,
.slick-track:after
{
display: table;
content: '';
}
.slick-track:after
{
clear: both;
}
.slick-loading .slick-track
{
visibility: hidden;
}
.slick-slide
{
display: none;
float: left;
height: 100%;
min-height: 1px;
}
[dir='rtl'] .slick-slide
{
float: right;
}
.slick-slide img
{
display: block;
}
.slick-slide.slick-loading img
{
display: none;
}
.slick-slide.dragging img
{
pointer-events: none;
}
.slick-initialized .slick-slide
{
display: block;
}
.slick-loading .slick-slide
{
visibility: hidden;
}
.slick-vertical .slick-slide
{
display: block;
height: auto;
border: 1px solid transparent;
}
.slick-arrow.slick-hidden {
display: none;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment