forked from kristjan/cjvt-valency
old files from diploma's poc
This commit is contained in:
parent
d5f5533139
commit
bb0f2f3b3e
35
README.md
35
README.md
|
@ -1 +1,36 @@
|
|||
# cjvt-vezljivost
|
||||
|
||||
## Components
|
||||
|
||||
|
||||
### Database (2 containers)
|
||||
Input:
|
||||
|
||||
* ssj500k.xml
|
||||
* kres.xml
|
||||
* kres_SRL.json
|
||||
|
||||
Intermediate:
|
||||
|
||||
* ssj500k.json
|
||||
* kres.json
|
||||
|
||||
Output:
|
||||
|
||||
* DB containing both corpora (1:1 map of the intermediate json formats)
|
||||
|
||||
|
||||
### Flask backend (1 container)
|
||||
Input: see Database
|
||||
|
||||
API endpoints:
|
||||
|
||||
* GET word list (pre-cached)
|
||||
* GET reduced frames (pre-cached)
|
||||
* POST senses
|
||||
* User auth logic
|
||||
|
||||
|
||||
### Vue frontend (1 container)
|
||||
|
||||
* ngnix server
|
||||
|
|
230
src_diploma/README.md
Normal file
230
src_diploma/README.md
Normal file
|
@ -0,0 +1,230 @@
|
|||
# Izdelava vezljivostnih vzorcev za slovenske glagole #
|
||||
|
||||
Študent: Kristjan Voje
|
||||
|
||||
Mentor: prof. Marko Robnik Šikonja
|
||||
Somentorica: dr. Apolonija Gantar
|
||||
|
||||
### Requirements:
|
||||
|
||||
* Linux (built and tested on Ubuntu 16.04),
|
||||
* python3
|
||||
|
||||
## Quick workspace preparation
|
||||
```bash
|
||||
# Clone the repo.
|
||||
$ git clone https://voje@bitbucket.org/voje/diploma.git
|
||||
|
||||
# Prepare the data.
|
||||
$ cd ./data
|
||||
$ unzip data.zip
|
||||
```
|
||||
|
||||
Virtualenv recommended. `$ sudo pip3 install virtualenv`.
|
||||
```bash
|
||||
$ cd ./script
|
||||
$ virtualenv -p /usr/bin/python3 venv
|
||||
|
||||
# A folder venv with python libraries will appear.
|
||||
# To activate the virtual environment:
|
||||
$ source ./venv/bin/activate
|
||||
|
||||
# To deactivate:
|
||||
$ deactivate
|
||||
```
|
||||
|
||||
Now, to build the python packages:
|
||||
```bash
|
||||
# Polyglot dependencies
|
||||
$ sudo apt-get install libicu-dev
|
||||
# NOTE: installing this broke my Arch system.
|
||||
# If on Arch, use the AUR version (it's supposed to be safe).
|
||||
|
||||
$ cd ./script
|
||||
$ pip3 install -e .
|
||||
|
||||
# Polyglot downloads
|
||||
$ polyglot download morph2.sl
|
||||
```
|
||||
|
||||
To test the installation, fire up a python3 shell (while in virtualenv) and:
|
||||
```python
|
||||
import valency
|
||||
```
|
||||
|
||||
## Nodejs environment
|
||||
There's a compiled front end client in the git repo.
|
||||
In case you want to change anything, you'll need to set up the development environment:
|
||||
|
||||
* install nodejs (default Ubuntu versions are usually behind),
|
||||
* check `$ npm -v`, if you don't have it, install npm,
|
||||
```
|
||||
$ npm install vue-cli
|
||||
$ cd ./vue_frontend
|
||||
$ npm install
|
||||
$ npm run dev # for development
|
||||
$ npm run build # for production
|
||||
```
|
||||
You will also need to change some path variables if you'll want to access the backend api from vue development server.
|
||||
See chapter "Web app deployment".
|
||||
|
||||
## MongoDB
|
||||
### Set up the database on the system
|
||||
[install MongoDB on Linux](https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/)
|
||||
|
||||
> The MongoDB instance stores its data files in /var/lib/mongodb and its log files in /var/log/mongodb by default, and runs using the mongodb user account. You can specify alternate log and data file directories in /etc/mongod.conf. See systemLog.path and storage.dbPath for additional information.
|
||||
>
|
||||
> If you change the user that runs the MongoDB process, you must modify the access control rights to the /var/lib/mongodb and /var/log/mongodb directories to give this user access to these directories.
|
||||
|
||||
#### Check if it's working.
|
||||
```bash
|
||||
$ sudo service mongod start / stop / restart
|
||||
$ tail -n 30 /var/log/mongodb/mongod.log
|
||||
|
||||
# If you want the mongo shell on local machine:
|
||||
$ mongo --host 127.0.0.1:<27017> # Check net.port in /etc/mongod.conf
|
||||
```
|
||||
|
||||
#### Security
|
||||
Create admin and user. Localhost only.
|
||||
[sedurity man](https://docs.mongodb.com/v3.4/tutorial/enable-authentication/)
|
||||
Basically, create an admin user then user that admin to create a normal user.
|
||||
Something like this:
|
||||
```
|
||||
use admin
|
||||
|
||||
db.createUser(
|
||||
{
|
||||
user: "admin_name",
|
||||
pwd: "admin_pass",
|
||||
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
|
||||
}
|
||||
)
|
||||
|
||||
# Restart mongod.
|
||||
|
||||
use texts
|
||||
|
||||
db.createUser(
|
||||
{
|
||||
user: "user_name",
|
||||
pwd: "user_pass",
|
||||
roles: [ { role: "readWrite", db: "texts" } ]
|
||||
}
|
||||
)
|
||||
|
||||
# Restart mongod.
|
||||
|
||||
# Also useful
|
||||
db.dropUser("username")
|
||||
```
|
||||
|
||||
Then go to `/etc/mongod.conf` and add this:
|
||||
Do not use tabs! mongod won't start.
|
||||
```bash
|
||||
security:
|
||||
authorization: enabled
|
||||
```
|
||||
You need to `use <db>`, `db.auth("username", "pass")` to have access.
|
||||
|
||||
#### DB migration
|
||||
I installed mongo on remote with same user accounts as on local.
|
||||
```bash
|
||||
# On local.
|
||||
$ mongodump --db texts --host mongodb1.example.net --port 3017 --username user --password "pass" --out ./file.db
|
||||
|
||||
# Rsync it over to remote.
|
||||
# On remote.
|
||||
# Need to turn off authorization for the drop part.
|
||||
|
||||
$ mongorestore --db texts --drop --port <port> ./<dbfolder>
|
||||
```
|
||||
|
||||
#### DB collections, needed for web app
|
||||
|
||||
* v2_senses,
|
||||
* v2_senses_map,
|
||||
* v2_users,
|
||||
* v2_user_tokens
|
||||
* sskj
|
||||
|
||||
|
||||
## Web app deployment
|
||||
We need to set flask to serve the vuejs frontend:
|
||||
```python
|
||||
# in ./script/flask_app/app.py
|
||||
app = Flask(
|
||||
__name__,
|
||||
static_folder="./vue/dist/static",
|
||||
template_folder="./vue/dist"
|
||||
)
|
||||
```
|
||||
Set the correct CORS options.
|
||||
|
||||
Might need to reinstall the package. Make sure you're in python virtualenv.
|
||||
`$ pip3 install -e .`
|
||||
|
||||
We also need to tell vuejs client to look for the api on server's address.
|
||||
```javascript
|
||||
// in script/vue_frontend/src/main.js
|
||||
api_addr: "http://<my_server_addr>:5004",
|
||||
```
|
||||
Compile frontend client:
|
||||
```bash
|
||||
$ cd ./script/vue_frontend
|
||||
$ npm run build
|
||||
$ rm ../flask_app/vue -rf
|
||||
$ cp ./dist ../flask_app/vue -r
|
||||
```
|
||||
|
||||
After preparing frontend, backend and database, run the command:
|
||||
```bash
|
||||
$ cd ./script
|
||||
$ ./autostart.sh
|
||||
```
|
||||
|
||||
## When fixing things in dev environment:
|
||||
```bash
|
||||
## Backend
|
||||
# git clone everything
|
||||
$ cd script
|
||||
|
||||
# unzip some zipped files
|
||||
$ ./sherpa --unpack
|
||||
|
||||
# virtualenv
|
||||
$ source venv/bin/activate
|
||||
$ pip3 install -e .
|
||||
|
||||
# start a mongod instance
|
||||
$ sudo systemctl start mongod
|
||||
|
||||
# start the backend server
|
||||
$ ./autostart.sh --debug
|
||||
|
||||
# you can watch the logs with
|
||||
$ tail -f log/main.log
|
||||
|
||||
|
||||
## Frontend
|
||||
# set the right config file (path to api)
|
||||
$ ./sherpa --frontend_config dev
|
||||
$ cd vue_frontend
|
||||
$ npm run dev
|
||||
|
||||
|
||||
## Done making changes
|
||||
# build frontend for production with the right config files
|
||||
$ ./sherpa --build_vue
|
||||
|
||||
# if you've made changes to static .pickle files
|
||||
$ ./sherpa --pack
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
68
src_diploma/autostart.sh
Executable file
68
src_diploma/autostart.sh
Executable file
|
@ -0,0 +1,68 @@
|
|||
#!/bin/bash
|
||||
|
||||
# prepare args for app.py
|
||||
datapath="../data"
|
||||
logpath="./log"
|
||||
|
||||
function echo_help() {
|
||||
echo "arguments:
|
||||
--help
|
||||
--rm_pickles (removes .pickle files from ./data/tmp_pickles)
|
||||
--prepare_for_shipment (build frontend, zip some data)
|
||||
--reload_sskj_senses (removes author: SSKJ from db.v2_senses
|
||||
and inserts senses from ./data/no_del_pickles/sskj_sense.pickle)
|
||||
--debug"
|
||||
}
|
||||
|
||||
function rm_pickles () {
|
||||
pickles_path="${datapath}/tmp_pickles"
|
||||
nfiles=$(ls "${pickles_path}" | grep ".pickle" | wc -l)
|
||||
if [[ $nfiles -gt 0 ]]; then
|
||||
echo "Removing:"
|
||||
ls "${pickles_path}"/*.pickle
|
||||
rm "${pickles_path}"/*.pickle
|
||||
else
|
||||
echo "No .pickle files to remove."
|
||||
fi
|
||||
}
|
||||
|
||||
function prepare_for_shipment () {
|
||||
./sherpa.sh --pack
|
||||
./sherpa.sh --build_vue
|
||||
}
|
||||
|
||||
args=""
|
||||
# Parse arguments
|
||||
while [[ "$#" -gt 0 ]]; do
|
||||
key="$1"
|
||||
case "$key" in
|
||||
--help)
|
||||
echo_help
|
||||
exit 0
|
||||
;;
|
||||
--rm_pickles)
|
||||
rm_pickles
|
||||
exit 0
|
||||
;;
|
||||
--prepare_for_shipment)
|
||||
prepare_for_shipment
|
||||
exit 0
|
||||
;;
|
||||
--reload_sskj_senses)
|
||||
args="$args --reload_sskj_senses"
|
||||
shift
|
||||
;;
|
||||
--debug)
|
||||
args="$args --debug"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "Unknown argument: $key"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
|
||||
args="${args} --datapath=${datapath} --logpath=${logpath}"
|
||||
python3 ./flask_app/app.py "$args"
|
473
src_diploma/flask_app/app.py
Normal file
473
src_diploma/flask_app/app.py
Normal file
|
@ -0,0 +1,473 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from flask import Flask, render_template, request, url_for, redirect
|
||||
|
||||
from valency import k_utils
|
||||
from valency.ssj_struct import *
|
||||
from valency.val_struct import *
|
||||
from valency.reduce_functions import *
|
||||
|
||||
import logging
|
||||
import sys
|
||||
import json
|
||||
from flask_cors import CORS
|
||||
import hashlib
|
||||
import uuid
|
||||
import datetime
|
||||
import string
|
||||
import random
|
||||
import smtplib
|
||||
from email.mime.text import MIMEText
|
||||
from copy import deepcopy as DC
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
PORT = 5004
|
||||
args = []
|
||||
|
||||
|
||||
def get_arg(argname):
|
||||
for arg in args:
|
||||
if "--{}".format(argname) in arg:
|
||||
spl = arg.split("=")
|
||||
if len(spl) == 2:
|
||||
return spl[1]
|
||||
else:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
vallex = None
|
||||
# app = Flask(__name__)
|
||||
|
||||
# v2 (serving vuejs frontend)
|
||||
# change api path in vue to localhost:5004
|
||||
app = Flask(
|
||||
__name__,
|
||||
static_folder="./vue/dist/static",
|
||||
template_folder="./vue/dist"
|
||||
)
|
||||
|
||||
# when running vuejs via webpack
|
||||
# CORS(app)
|
||||
CORS(app, resources={r"/api/*": {
|
||||
"origins": "*",
|
||||
}})
|
||||
|
||||
|
||||
# for testing functions
|
||||
@app.route("/test_dev")
|
||||
def test_dev():
|
||||
ret = vallex.test_dev()
|
||||
return(str(ret) or "edit val_struct.py: test_dev()")
|
||||
|
||||
|
||||
@app.route("/")
|
||||
def index():
|
||||
return(render_template("index.html"))
|
||||
|
||||
|
||||
@app.route("/home", defaults={"pathname": ""})
|
||||
@app.route("/home/<path:pathname>")
|
||||
def home(pathname):
|
||||
return redirect(url_for("index"), code=302)
|
||||
|
||||
|
||||
@app.route("/api/words")
|
||||
def api_words():
|
||||
return json.dumps({
|
||||
"sorted_words": vallex.sorted_words,
|
||||
"has_se": vallex.has_se
|
||||
})
|
||||
|
||||
|
||||
@app.route("/api/functors")
|
||||
def api_functors():
|
||||
res = []
|
||||
for key in sorted(vallex.functors_index.keys()):
|
||||
res.append((key, len(vallex.functors_index[key])))
|
||||
return json.dumps(res)
|
||||
|
||||
|
||||
@app.route("/api/register", methods=["POST"])
|
||||
def api_register():
|
||||
USERS_COLL = "v2_users"
|
||||
b = request.get_data()
|
||||
data = json.loads(b.decode())
|
||||
username = data["username"]
|
||||
password = data["password"]
|
||||
email = data["email"]
|
||||
if (
|
||||
username == "" or
|
||||
password == "" or
|
||||
email == ""
|
||||
):
|
||||
return "ERR"
|
||||
existing = list(vallex.db[USERS_COLL].find({
|
||||
"$or": [{"username": username}, {"email": email}]
|
||||
}))
|
||||
if len(existing) > 0:
|
||||
return "ERR: Username or email already exists."
|
||||
entry = {
|
||||
"username": username,
|
||||
"hpass": hashlib.sha256(
|
||||
password.encode("utf-8")).hexdigest(),
|
||||
"email": hashlib.sha256(
|
||||
email.encode("utf-8")).hexdigest()
|
||||
}
|
||||
vallex.db[USERS_COLL].insert(entry)
|
||||
return "OK"
|
||||
|
||||
|
||||
@app.route("/api/login", methods=["POST"])
|
||||
def api_login():
|
||||
USERS_COLL = "v2_users"
|
||||
TOKENS_COLL = "v2_user_tokens"
|
||||
b = request.get_data()
|
||||
data = json.loads(b.decode())
|
||||
username = data["username"]
|
||||
password = data["password"]
|
||||
hpass = hashlib.sha256(password.encode("utf-8")).hexdigest()
|
||||
|
||||
db_user = list(vallex.db[USERS_COLL].find({
|
||||
"username": username,
|
||||
"hpass": hpass
|
||||
}))
|
||||
if len(db_user) == 0:
|
||||
return json.dumps({"token": None})
|
||||
|
||||
# update or create token
|
||||
token = uuid.uuid4().hex
|
||||
token_entry = {
|
||||
"username": username,
|
||||
"date": datetime.datetime.utcnow(),
|
||||
"token": token
|
||||
}
|
||||
vallex.db[TOKENS_COLL].update(
|
||||
{"username": token_entry["username"]},
|
||||
token_entry,
|
||||
upsert=True
|
||||
)
|
||||
return json.dumps({"token": token})
|
||||
|
||||
|
||||
def send_new_pass_mail(recipient, new_pass):
|
||||
# dtime = str(datetime.datetime.now())
|
||||
SENDER = "valencaglagolov@gmail.com"
|
||||
msg = MIMEText(
|
||||
"Pošiljamo vam novo geslo za "
|
||||
"vstop v aplikacijo Vezljivostni vzorci slovenskih glagolov.\n"
|
||||
"Geslo: {}.".format(new_pass)
|
||||
)
|
||||
msg["Subject"] = "Pozabljeno geslo"
|
||||
msg["From"] = SENDER
|
||||
msg["To"] = recipient
|
||||
|
||||
try:
|
||||
server = smtplib.SMTP("smtp.gmail.com", 587)
|
||||
server.ehlo()
|
||||
server.starttls()
|
||||
server.login(
|
||||
SENDER,
|
||||
"rapid limb soapy fermi"
|
||||
)
|
||||
server.sendmail(SENDER, [recipient], msg.as_string())
|
||||
server.close()
|
||||
log.info("Sent new password.")
|
||||
except Error as e:
|
||||
log.error("Sending new password failed")
|
||||
log.error(e)
|
||||
|
||||
|
||||
@app.route("/api/new_pass", methods=["POST"])
|
||||
def api_new_pass():
|
||||
b = request.get_data()
|
||||
data = json.loads(b.decode())
|
||||
username = data["username"]
|
||||
email = data["email"]
|
||||
hemail = hashlib.sha256(email.encode("utf-8")).hexdigest()
|
||||
db_res = list(vallex.db.v2_users.find({
|
||||
"username": username,
|
||||
"email": hemail
|
||||
}))
|
||||
# check if user is valid
|
||||
if len(db_res) == 0:
|
||||
return json.dumps({"confirmation": False})
|
||||
# create a new password
|
||||
new_pass = "".join([random.choice(
|
||||
string.ascii_letters + string.digits) for i in range(10)])
|
||||
# update locally
|
||||
hpass = hashlib.sha256(new_pass.encode("utf-8")).hexdigest()
|
||||
vallex.db.v2_users.update(
|
||||
{
|
||||
"username": username,
|
||||
"email": hemail
|
||||
},
|
||||
{"$set": {
|
||||
"hpass": hpass
|
||||
}}
|
||||
)
|
||||
# send via mail
|
||||
send_new_pass_mail(email, new_pass)
|
||||
return json.dumps({"confirmation": True})
|
||||
|
||||
|
||||
def prepare_frames(ret_frames):
|
||||
# append sentences
|
||||
for frame in ret_frames:
|
||||
frame.sentences = []
|
||||
unique_sids = {".".join(x.split(".")[:-1]): x for x in frame.tids}
|
||||
log.debug(str(unique_sids))
|
||||
frame.sentences = []
|
||||
frame.aggr_sent = {}
|
||||
for sid, tid in unique_sids.items():
|
||||
hwl = vallex.get_token(tid)["lemma"]
|
||||
tmp_idx = len(frame.sentences)
|
||||
if hwl not in frame.aggr_sent:
|
||||
frame.aggr_sent[hwl] = []
|
||||
frame.aggr_sent[hwl].append(tmp_idx)
|
||||
frame.sentences.append(
|
||||
vallex.get_tokenized_sentence(tid)
|
||||
)
|
||||
# return (n-frames, rendered template)
|
||||
# json frames
|
||||
json_ret = {"frames": []}
|
||||
for frame in ret_frames:
|
||||
json_ret["frames"].append(DC(frame.to_json()))
|
||||
return json.dumps(json_ret)
|
||||
|
||||
|
||||
@app.route("/api/frames")
|
||||
def api_get_frames():
|
||||
hw = request.args.get("hw")
|
||||
if hw is None:
|
||||
return json.dumps({"error": "Headword not found."})
|
||||
|
||||
rf_name = request.args.get("rf", "reduce_0") # 2nd is default
|
||||
RF = reduce_functions[rf_name]["f"]
|
||||
entry = vallex.entries[hw]
|
||||
ret_frames = RF(entry.raw_frames, vallex)
|
||||
return prepare_frames(ret_frames)
|
||||
|
||||
|
||||
@app.route("/api/functor-frames")
|
||||
def api_get_functor_frames():
|
||||
functor = request.args.get("functor")
|
||||
if functor is None:
|
||||
return json.dumps({"error": "Missing argument: functor."})
|
||||
rf_name = request.args.get("rf", "reduce_0") # 2nd is default
|
||||
RF = reduce_functions[rf_name]["f"]
|
||||
raw_frames = vallex.functors_index[functor]
|
||||
ret_frames = RF(raw_frames, vallex)
|
||||
return prepare_frames(ret_frames)
|
||||
|
||||
|
||||
def token_to_username(token):
|
||||
COLLNAME = "v2_user_tokens"
|
||||
key = {
|
||||
"token": token
|
||||
}
|
||||
res = list(vallex.db[COLLNAME].find(key))
|
||||
if len(res) != 1:
|
||||
return None
|
||||
username = res[0]["username"]
|
||||
# update deletion interval
|
||||
vallex.db[COLLNAME].update(
|
||||
key, {"$set": {"date": datetime.datetime.utcnow()}})
|
||||
return username
|
||||
|
||||
|
||||
@app.route("/api/token", methods=["POST"])
|
||||
def api_token():
|
||||
# check if token is valid
|
||||
b = request.get_data()
|
||||
data = json.loads(b.decode())
|
||||
token = data.get("token")
|
||||
# user = data.get("user")
|
||||
user = token_to_username(token)
|
||||
confirm = (user is not None)
|
||||
return json.dumps({
|
||||
"confirmation": confirm,
|
||||
"username": user
|
||||
})
|
||||
|
||||
|
||||
@app.route("/api/senses/get")
|
||||
def api_senses_get():
|
||||
# returns senses and mapping for hw
|
||||
hw = request.args.get("hw")
|
||||
senses = list(vallex.db["v2_senses"].find({
|
||||
"hw": hw
|
||||
}))
|
||||
sense_map_query = list(vallex.db["v2_sense_map"].find({
|
||||
"hw": hw
|
||||
}))
|
||||
# aggregation by max date possible on DB side
|
||||
# but no simple way of returning full entries
|
||||
# aggregate hw and ssj_id by max date
|
||||
sense_map_aggr = {}
|
||||
for sm in sense_map_query:
|
||||
key = sm["hw"] + sm["ssj_id"]
|
||||
if key in sense_map_aggr:
|
||||
sense_map_aggr[key] = max(
|
||||
[sm, sense_map_aggr[key]], key=lambda x: x["date"])
|
||||
else:
|
||||
sense_map_aggr[key] = sm
|
||||
sense_map_list = [x[1] for x in sense_map_aggr.items()]
|
||||
sense_map = {}
|
||||
for el in sense_map_list:
|
||||
sense_map[el["ssj_id"]] = el
|
||||
for k, e in sense_map.items():
|
||||
del(e["_id"])
|
||||
del(e["date"])
|
||||
for e in senses:
|
||||
del(e["_id"])
|
||||
if "date" in e:
|
||||
del(e["date"])
|
||||
|
||||
# sort senses: user defined first, sskj second
|
||||
# sskj senses sorted by sskj sense_id
|
||||
user_senses = [s for s in senses if s["author"] != "SSKJ"]
|
||||
sskj_senses = [s for s in senses if s["author"] == "SSKJ"]
|
||||
|
||||
def sorting_helper(sense):
|
||||
arr = sense["sense_id"].split("-")
|
||||
return "{:03d}-{:03d}-{:03d}".format(
|
||||
int(arr[1]), int(arr[2]), int(arr[3]))
|
||||
|
||||
sskj_senses = sorted(sskj_senses, key=sorting_helper)
|
||||
senses = user_senses + sskj_senses
|
||||
|
||||
return json.dumps({
|
||||
"senses": senses,
|
||||
"sense_map": sense_map,
|
||||
})
|
||||
|
||||
|
||||
@app.route("/api/senses/update", methods=["POST"])
|
||||
def api_senses_update():
|
||||
b = request.get_data()
|
||||
data = json.loads(b.decode())
|
||||
token = data.get("token")
|
||||
hw = data.get("hw")
|
||||
sense_map = data.get("sense_map")
|
||||
new_senses = data.get("new_senses")
|
||||
|
||||
username = token_to_username(token)
|
||||
if username is None:
|
||||
log.debug("Not a user.")
|
||||
return "Not a user."
|
||||
|
||||
# store new senses,
|
||||
# create new sense_ids
|
||||
id_map = {}
|
||||
for ns in new_senses:
|
||||
tmp_dt = datetime.datetime.utcnow()
|
||||
new_sense_id = "{}-{}".format(
|
||||
username,
|
||||
hashlib.sha256("{}{}{}".format(
|
||||
username,
|
||||
ns["desc"],
|
||||
str(tmp_dt)
|
||||
).encode("utf-8")).hexdigest()[:10]
|
||||
)
|
||||
frontend_sense_id = ns["sense_id"]
|
||||
ns["sense_id"] = new_sense_id
|
||||
ns["date"] = tmp_dt
|
||||
id_map[frontend_sense_id] = new_sense_id
|
||||
|
||||
# insert into db
|
||||
vallex.db["v2_senses"].insert(ns)
|
||||
|
||||
# replace tmp_id with mongo's _id
|
||||
for ssj_id, el in sense_map.items():
|
||||
sense_id = el["sense_id"]
|
||||
if sense_id in id_map.keys():
|
||||
sense_id = id_map[sense_id]
|
||||
data = {
|
||||
"user": username,
|
||||
"hw": hw,
|
||||
"ssj_id": ssj_id,
|
||||
"sense_id": sense_id,
|
||||
"date": datetime.datetime.utcnow()
|
||||
}
|
||||
# vallex.db["v2_sense_map"].update(key, data, upsert=True)
|
||||
vallex.db["v2_sense_map"].insert(data)
|
||||
return "OK"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Files needed to run:
|
||||
# pre-generated .pickle files in /data/no_del_pickles
|
||||
# temporary .pickle files can speed up startup (/data/tmp_pickles)
|
||||
# main input file: annotated sentences (ssj.xml)
|
||||
ANNOTATED_SSJ_XML_PATH = "/ssj500k-sl.TEI/ssj500k-sl.body.xml"
|
||||
|
||||
# Read arguments from autostart.sh script.
|
||||
for arg in sys.argv:
|
||||
args.extend(arg.split())
|
||||
|
||||
app.debug = get_arg("debug")
|
||||
|
||||
# Set up logging
|
||||
logfile = get_arg("logpath") + "/main.log"
|
||||
logging.basicConfig(filename=logfile, level=logging.DEBUG)
|
||||
|
||||
datapath = get_arg("datapath")
|
||||
if datapath is None:
|
||||
log.error("No path to data.")
|
||||
exit(1)
|
||||
|
||||
# Prepare vallex.
|
||||
vallex = Vallex()
|
||||
|
||||
vallex_pickle_path = datapath + "/tmp_pickles/vallex.pickle"
|
||||
vallex_data = k_utils.pickle_load(vallex_pickle_path)
|
||||
|
||||
if vallex_data is None:
|
||||
log.info("No pickle found, creating vallex_data.")
|
||||
|
||||
# get ssj data from pickle
|
||||
ssj_pickle_path = datapath + "/tmp_pickles/ssj.pickle"
|
||||
ssj = k_utils.pickle_load(ssj_pickle_path)
|
||||
|
||||
if ssj is None:
|
||||
ssj_path = datapath + ANNOTATED_SSJ_XML_PATH
|
||||
log.info("No pickle found, creating ssj pickle from {}.".format(
|
||||
ssj_path))
|
||||
ssj = SsjDict()
|
||||
ssj.read_xml_v2(ssj_path)
|
||||
|
||||
# create fresh pickle
|
||||
k_utils.pickle_dump(ssj, ssj_pickle_path)
|
||||
|
||||
vallex.read_ssj(ssj)
|
||||
vallex_data = {
|
||||
"entries": vallex.entries,
|
||||
"tokens": vallex.tokens
|
||||
}
|
||||
k_utils.pickle_dump(vallex_data, vallex_pickle_path)
|
||||
|
||||
vallex.entries = DC(vallex_data["entries"])
|
||||
vallex.tokens = DC(vallex_data["tokens"])
|
||||
|
||||
# Generate senses and se_list after we've built the vallex object.
|
||||
seqparser_sskj_path = datapath + "/no_del_pickles/sskj_senses.pickle"
|
||||
seqparser_se_list_path = datapath + "/no_del_pickles/se_list.pickle"
|
||||
vallex.process_after_read(
|
||||
seqparser_sskj_path, seqparser_se_list_path,
|
||||
reload_sskj_senses=get_arg("reload_sskj_senses")
|
||||
)
|
||||
|
||||
log.info(
|
||||
"\n[*] Starting the app." +
|
||||
"\n[*] args: {}".format(args) +
|
||||
"\n[*] | logfile: {}".format(logfile) +
|
||||
"\n[*] | debug: {}".format(str(app.debug))
|
||||
)
|
||||
# Run the app.
|
||||
if app.debug:
|
||||
app.run(port=PORT)
|
||||
else:
|
||||
app.run(host="0.0.0.0", port=PORT)
|
587
src_diploma/flask_app/static/lib/bootstrap/css/bootstrap-theme.css
vendored
Normal file
587
src_diploma/flask_app/static/lib/bootstrap/css/bootstrap-theme.css
vendored
Normal file
|
@ -0,0 +1,587 @@
|
|||
/*!
|
||||
* Bootstrap v3.3.7 (http://getbootstrap.com)
|
||||
* Copyright 2011-2016 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*/
|
||||
.btn-default,
|
||||
.btn-primary,
|
||||
.btn-success,
|
||||
.btn-info,
|
||||
.btn-warning,
|
||||
.btn-danger {
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, .2);
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
|
||||
}
|
||||
.btn-default:active,
|
||||
.btn-primary:active,
|
||||
.btn-success:active,
|
||||
.btn-info:active,
|
||||
.btn-warning:active,
|
||||
.btn-danger:active,
|
||||
.btn-default.active,
|
||||
.btn-primary.active,
|
||||
.btn-success.active,
|
||||
.btn-info.active,
|
||||
.btn-warning.active,
|
||||
.btn-danger.active {
|
||||
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
|
||||
box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
|
||||
}
|
||||
.btn-default.disabled,
|
||||
.btn-primary.disabled,
|
||||
.btn-success.disabled,
|
||||
.btn-info.disabled,
|
||||
.btn-warning.disabled,
|
||||
.btn-danger.disabled,
|
||||
.btn-default[disabled],
|
||||
.btn-primary[disabled],
|
||||
.btn-success[disabled],
|
||||
.btn-info[disabled],
|
||||
.btn-warning[disabled],
|
||||
.btn-danger[disabled],
|
||||
fieldset[disabled] .btn-default,
|
||||
fieldset[disabled] .btn-primary,
|
||||
fieldset[disabled] .btn-success,
|
||||
fieldset[disabled] .btn-info,
|
||||
fieldset[disabled] .btn-warning,
|
||||
fieldset[disabled] .btn-danger {
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
.btn-default .badge,
|
||||
.btn-primary .badge,
|
||||
.btn-success .badge,
|
||||
.btn-info .badge,
|
||||
.btn-warning .badge,
|
||||
.btn-danger .badge {
|
||||
text-shadow: none;
|
||||
}
|
||||
.btn:active,
|
||||
.btn.active {
|
||||
background-image: none;
|
||||
}
|
||||
.btn-default {
|
||||
text-shadow: 0 1px 0 #fff;
|
||||
background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);
|
||||
background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0));
|
||||
background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #dbdbdb;
|
||||
border-color: #ccc;
|
||||
}
|
||||
.btn-default:hover,
|
||||
.btn-default:focus {
|
||||
background-color: #e0e0e0;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-default:active,
|
||||
.btn-default.active {
|
||||
background-color: #e0e0e0;
|
||||
border-color: #dbdbdb;
|
||||
}
|
||||
.btn-default.disabled,
|
||||
.btn-default[disabled],
|
||||
fieldset[disabled] .btn-default,
|
||||
.btn-default.disabled:hover,
|
||||
.btn-default[disabled]:hover,
|
||||
fieldset[disabled] .btn-default:hover,
|
||||
.btn-default.disabled:focus,
|
||||
.btn-default[disabled]:focus,
|
||||
fieldset[disabled] .btn-default:focus,
|
||||
.btn-default.disabled.focus,
|
||||
.btn-default[disabled].focus,
|
||||
fieldset[disabled] .btn-default.focus,
|
||||
.btn-default.disabled:active,
|
||||
.btn-default[disabled]:active,
|
||||
fieldset[disabled] .btn-default:active,
|
||||
.btn-default.disabled.active,
|
||||
.btn-default[disabled].active,
|
||||
fieldset[disabled] .btn-default.active {
|
||||
background-color: #e0e0e0;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-primary {
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #245580;
|
||||
}
|
||||
.btn-primary:hover,
|
||||
.btn-primary:focus {
|
||||
background-color: #265a88;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-primary:active,
|
||||
.btn-primary.active {
|
||||
background-color: #265a88;
|
||||
border-color: #245580;
|
||||
}
|
||||
.btn-primary.disabled,
|
||||
.btn-primary[disabled],
|
||||
fieldset[disabled] .btn-primary,
|
||||
.btn-primary.disabled:hover,
|
||||
.btn-primary[disabled]:hover,
|
||||
fieldset[disabled] .btn-primary:hover,
|
||||
.btn-primary.disabled:focus,
|
||||
.btn-primary[disabled]:focus,
|
||||
fieldset[disabled] .btn-primary:focus,
|
||||
.btn-primary.disabled.focus,
|
||||
.btn-primary[disabled].focus,
|
||||
fieldset[disabled] .btn-primary.focus,
|
||||
.btn-primary.disabled:active,
|
||||
.btn-primary[disabled]:active,
|
||||
fieldset[disabled] .btn-primary:active,
|
||||
.btn-primary.disabled.active,
|
||||
.btn-primary[disabled].active,
|
||||
fieldset[disabled] .btn-primary.active {
|
||||
background-color: #265a88;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-success {
|
||||
background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);
|
||||
background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641));
|
||||
background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #3e8f3e;
|
||||
}
|
||||
.btn-success:hover,
|
||||
.btn-success:focus {
|
||||
background-color: #419641;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-success:active,
|
||||
.btn-success.active {
|
||||
background-color: #419641;
|
||||
border-color: #3e8f3e;
|
||||
}
|
||||
.btn-success.disabled,
|
||||
.btn-success[disabled],
|
||||
fieldset[disabled] .btn-success,
|
||||
.btn-success.disabled:hover,
|
||||
.btn-success[disabled]:hover,
|
||||
fieldset[disabled] .btn-success:hover,
|
||||
.btn-success.disabled:focus,
|
||||
.btn-success[disabled]:focus,
|
||||
fieldset[disabled] .btn-success:focus,
|
||||
.btn-success.disabled.focus,
|
||||
.btn-success[disabled].focus,
|
||||
fieldset[disabled] .btn-success.focus,
|
||||
.btn-success.disabled:active,
|
||||
.btn-success[disabled]:active,
|
||||
fieldset[disabled] .btn-success:active,
|
||||
.btn-success.disabled.active,
|
||||
.btn-success[disabled].active,
|
||||
fieldset[disabled] .btn-success.active {
|
||||
background-color: #419641;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-info {
|
||||
background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
|
||||
background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2));
|
||||
background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #28a4c9;
|
||||
}
|
||||
.btn-info:hover,
|
||||
.btn-info:focus {
|
||||
background-color: #2aabd2;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-info:active,
|
||||
.btn-info.active {
|
||||
background-color: #2aabd2;
|
||||
border-color: #28a4c9;
|
||||
}
|
||||
.btn-info.disabled,
|
||||
.btn-info[disabled],
|
||||
fieldset[disabled] .btn-info,
|
||||
.btn-info.disabled:hover,
|
||||
.btn-info[disabled]:hover,
|
||||
fieldset[disabled] .btn-info:hover,
|
||||
.btn-info.disabled:focus,
|
||||
.btn-info[disabled]:focus,
|
||||
fieldset[disabled] .btn-info:focus,
|
||||
.btn-info.disabled.focus,
|
||||
.btn-info[disabled].focus,
|
||||
fieldset[disabled] .btn-info.focus,
|
||||
.btn-info.disabled:active,
|
||||
.btn-info[disabled]:active,
|
||||
fieldset[disabled] .btn-info:active,
|
||||
.btn-info.disabled.active,
|
||||
.btn-info[disabled].active,
|
||||
fieldset[disabled] .btn-info.active {
|
||||
background-color: #2aabd2;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-warning {
|
||||
background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
|
||||
background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316));
|
||||
background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #e38d13;
|
||||
}
|
||||
.btn-warning:hover,
|
||||
.btn-warning:focus {
|
||||
background-color: #eb9316;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-warning:active,
|
||||
.btn-warning.active {
|
||||
background-color: #eb9316;
|
||||
border-color: #e38d13;
|
||||
}
|
||||
.btn-warning.disabled,
|
||||
.btn-warning[disabled],
|
||||
fieldset[disabled] .btn-warning,
|
||||
.btn-warning.disabled:hover,
|
||||
.btn-warning[disabled]:hover,
|
||||
fieldset[disabled] .btn-warning:hover,
|
||||
.btn-warning.disabled:focus,
|
||||
.btn-warning[disabled]:focus,
|
||||
fieldset[disabled] .btn-warning:focus,
|
||||
.btn-warning.disabled.focus,
|
||||
.btn-warning[disabled].focus,
|
||||
fieldset[disabled] .btn-warning.focus,
|
||||
.btn-warning.disabled:active,
|
||||
.btn-warning[disabled]:active,
|
||||
fieldset[disabled] .btn-warning:active,
|
||||
.btn-warning.disabled.active,
|
||||
.btn-warning[disabled].active,
|
||||
fieldset[disabled] .btn-warning.active {
|
||||
background-color: #eb9316;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-danger {
|
||||
background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
|
||||
background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a));
|
||||
background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #b92c28;
|
||||
}
|
||||
.btn-danger:hover,
|
||||
.btn-danger:focus {
|
||||
background-color: #c12e2a;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-danger:active,
|
||||
.btn-danger.active {
|
||||
background-color: #c12e2a;
|
||||
border-color: #b92c28;
|
||||
}
|
||||
.btn-danger.disabled,
|
||||
.btn-danger[disabled],
|
||||
fieldset[disabled] .btn-danger,
|
||||
.btn-danger.disabled:hover,
|
||||
.btn-danger[disabled]:hover,
|
||||
fieldset[disabled] .btn-danger:hover,
|
||||
.btn-danger.disabled:focus,
|
||||
.btn-danger[disabled]:focus,
|
||||
fieldset[disabled] .btn-danger:focus,
|
||||
.btn-danger.disabled.focus,
|
||||
.btn-danger[disabled].focus,
|
||||
fieldset[disabled] .btn-danger.focus,
|
||||
.btn-danger.disabled:active,
|
||||
.btn-danger[disabled]:active,
|
||||
fieldset[disabled] .btn-danger:active,
|
||||
.btn-danger.disabled.active,
|
||||
.btn-danger[disabled].active,
|
||||
fieldset[disabled] .btn-danger.active {
|
||||
background-color: #c12e2a;
|
||||
background-image: none;
|
||||
}
|
||||
.thumbnail,
|
||||
.img-thumbnail {
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
|
||||
}
|
||||
.dropdown-menu > li > a:hover,
|
||||
.dropdown-menu > li > a:focus {
|
||||
background-color: #e8e8e8;
|
||||
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
||||
background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
|
||||
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.dropdown-menu > .active > a,
|
||||
.dropdown-menu > .active > a:hover,
|
||||
.dropdown-menu > .active > a:focus {
|
||||
background-color: #2e6da4;
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.navbar-default {
|
||||
background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%);
|
||||
background-image: -o-linear-gradient(top, #fff 0%, #f8f8f8 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8));
|
||||
background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
|
||||
}
|
||||
.navbar-default .navbar-nav > .open > a,
|
||||
.navbar-default .navbar-nav > .active > a {
|
||||
background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
|
||||
background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2));
|
||||
background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
|
||||
box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
|
||||
}
|
||||
.navbar-brand,
|
||||
.navbar-nav > li > a {
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, .25);
|
||||
}
|
||||
.navbar-inverse {
|
||||
background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);
|
||||
background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222));
|
||||
background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.navbar-inverse .navbar-nav > .open > a,
|
||||
.navbar-inverse .navbar-nav > .active > a {
|
||||
background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);
|
||||
background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f));
|
||||
background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
|
||||
box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
|
||||
}
|
||||
.navbar-inverse .navbar-brand,
|
||||
.navbar-inverse .navbar-nav > li > a {
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, .25);
|
||||
}
|
||||
.navbar-static-top,
|
||||
.navbar-fixed-top,
|
||||
.navbar-fixed-bottom {
|
||||
border-radius: 0;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.navbar .navbar-nav .open .dropdown-menu > .active > a,
|
||||
.navbar .navbar-nav .open .dropdown-menu > .active > a:hover,
|
||||
.navbar .navbar-nav .open .dropdown-menu > .active > a:focus {
|
||||
color: #fff;
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
}
|
||||
.alert {
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, .2);
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
|
||||
}
|
||||
.alert-success {
|
||||
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
|
||||
background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc));
|
||||
background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #b2dba1;
|
||||
}
|
||||
.alert-info {
|
||||
background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
|
||||
background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0));
|
||||
background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #9acfea;
|
||||
}
|
||||
.alert-warning {
|
||||
background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
|
||||
background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0));
|
||||
background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #f5e79e;
|
||||
}
|
||||
.alert-danger {
|
||||
background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
|
||||
background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3));
|
||||
background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #dca7a7;
|
||||
}
|
||||
.progress {
|
||||
background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
|
||||
background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5));
|
||||
background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar {
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-success {
|
||||
background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);
|
||||
background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44));
|
||||
background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-info {
|
||||
background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
|
||||
background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5));
|
||||
background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-warning {
|
||||
background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
|
||||
background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f));
|
||||
background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-danger {
|
||||
background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);
|
||||
background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c));
|
||||
background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-striped {
|
||||
background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
|
||||
background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
|
||||
background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
|
||||
}
|
||||
.list-group {
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
|
||||
}
|
||||
.list-group-item.active,
|
||||
.list-group-item.active:hover,
|
||||
.list-group-item.active:focus {
|
||||
text-shadow: 0 -1px 0 #286090;
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #2b669a;
|
||||
}
|
||||
.list-group-item.active .badge,
|
||||
.list-group-item.active:hover .badge,
|
||||
.list-group-item.active:focus .badge {
|
||||
text-shadow: none;
|
||||
}
|
||||
.panel {
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
|
||||
}
|
||||
.panel-default > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
||||
background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
|
||||
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-primary > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-success > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
|
||||
background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6));
|
||||
background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-info > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
|
||||
background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3));
|
||||
background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-warning > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
|
||||
background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc));
|
||||
background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-danger > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
|
||||
background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc));
|
||||
background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.well {
|
||||
background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
|
||||
background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5));
|
||||
background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #dcdcdc;
|
||||
-webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
|
||||
box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
|
||||
}
|
||||
/*# sourceMappingURL=bootstrap-theme.css.map */
|
File diff suppressed because one or more lines are too long
6
src_diploma/flask_app/static/lib/bootstrap/css/bootstrap-theme.min.css
vendored
Normal file
6
src_diploma/flask_app/static/lib/bootstrap/css/bootstrap-theme.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
6757
src_diploma/flask_app/static/lib/bootstrap/css/bootstrap.css
vendored
Normal file
6757
src_diploma/flask_app/static/lib/bootstrap/css/bootstrap.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
6
src_diploma/flask_app/static/lib/bootstrap/css/bootstrap.min.css
vendored
Normal file
6
src_diploma/flask_app/static/lib/bootstrap/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
|
@ -0,0 +1,288 @@
|
|||
<?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></metadata>
|
||||
<defs>
|
||||
<font id="glyphicons_halflingsregular" horiz-adv-x="1200" >
|
||||
<font-face units-per-em="1200" ascent="960" descent="-240" />
|
||||
<missing-glyph horiz-adv-x="500" />
|
||||
<glyph horiz-adv-x="0" />
|
||||
<glyph horiz-adv-x="400" />
|
||||
<glyph unicode=" " />
|
||||
<glyph unicode="*" d="M600 1100q15 0 34 -1.5t30 -3.5l11 -1q10 -2 17.5 -10.5t7.5 -18.5v-224l158 158q7 7 18 8t19 -6l106 -106q7 -8 6 -19t-8 -18l-158 -158h224q10 0 18.5 -7.5t10.5 -17.5q6 -41 6 -75q0 -15 -1.5 -34t-3.5 -30l-1 -11q-2 -10 -10.5 -17.5t-18.5 -7.5h-224l158 -158 q7 -7 8 -18t-6 -19l-106 -106q-8 -7 -19 -6t-18 8l-158 158v-224q0 -10 -7.5 -18.5t-17.5 -10.5q-41 -6 -75 -6q-15 0 -34 1.5t-30 3.5l-11 1q-10 2 -17.5 10.5t-7.5 18.5v224l-158 -158q-7 -7 -18 -8t-19 6l-106 106q-7 8 -6 19t8 18l158 158h-224q-10 0 -18.5 7.5 t-10.5 17.5q-6 41 -6 75q0 15 1.5 34t3.5 30l1 11q2 10 10.5 17.5t18.5 7.5h224l-158 158q-7 7 -8 18t6 19l106 106q8 7 19 6t18 -8l158 -158v224q0 10 7.5 18.5t17.5 10.5q41 6 75 6z" />
|
||||
<glyph unicode="+" d="M450 1100h200q21 0 35.5 -14.5t14.5 -35.5v-350h350q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-350v-350q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v350h-350q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5 h350v350q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode=" " />
|
||||
<glyph unicode="¥" d="M825 1100h250q10 0 12.5 -5t-5.5 -13l-364 -364q-6 -6 -11 -18h268q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-125v-100h275q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-125v-174q0 -11 -7.5 -18.5t-18.5 -7.5h-148q-11 0 -18.5 7.5t-7.5 18.5v174 h-275q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h125v100h-275q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h118q-5 12 -11 18l-364 364q-8 8 -5.5 13t12.5 5h250q25 0 43 -18l164 -164q8 -8 18 -8t18 8l164 164q18 18 43 18z" />
|
||||
<glyph unicode=" " horiz-adv-x="650" />
|
||||
<glyph unicode=" " horiz-adv-x="1300" />
|
||||
<glyph unicode=" " horiz-adv-x="650" />
|
||||
<glyph unicode=" " horiz-adv-x="1300" />
|
||||
<glyph unicode=" " horiz-adv-x="433" />
|
||||
<glyph unicode=" " horiz-adv-x="325" />
|
||||
<glyph unicode=" " horiz-adv-x="216" />
|
||||
<glyph unicode=" " horiz-adv-x="216" />
|
||||
<glyph unicode=" " horiz-adv-x="162" />
|
||||
<glyph unicode=" " horiz-adv-x="260" />
|
||||
<glyph unicode=" " horiz-adv-x="72" />
|
||||
<glyph unicode=" " horiz-adv-x="260" />
|
||||
<glyph unicode=" " horiz-adv-x="325" />
|
||||
<glyph unicode="€" d="M744 1198q242 0 354 -189q60 -104 66 -209h-181q0 45 -17.5 82.5t-43.5 61.5t-58 40.5t-60.5 24t-51.5 7.5q-19 0 -40.5 -5.5t-49.5 -20.5t-53 -38t-49 -62.5t-39 -89.5h379l-100 -100h-300q-6 -50 -6 -100h406l-100 -100h-300q9 -74 33 -132t52.5 -91t61.5 -54.5t59 -29 t47 -7.5q22 0 50.5 7.5t60.5 24.5t58 41t43.5 61t17.5 80h174q-30 -171 -128 -278q-107 -117 -274 -117q-206 0 -324 158q-36 48 -69 133t-45 204h-217l100 100h112q1 47 6 100h-218l100 100h134q20 87 51 153.5t62 103.5q117 141 297 141z" />
|
||||
<glyph unicode="₽" d="M428 1200h350q67 0 120 -13t86 -31t57 -49.5t35 -56.5t17 -64.5t6.5 -60.5t0.5 -57v-16.5v-16.5q0 -36 -0.5 -57t-6.5 -61t-17 -65t-35 -57t-57 -50.5t-86 -31.5t-120 -13h-178l-2 -100h288q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-138v-175q0 -11 -5.5 -18 t-15.5 -7h-149q-10 0 -17.5 7.5t-7.5 17.5v175h-267q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h117v100h-267q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h117v475q0 10 7.5 17.5t17.5 7.5zM600 1000v-300h203q64 0 86.5 33t22.5 119q0 84 -22.5 116t-86.5 32h-203z" />
|
||||
<glyph unicode="−" d="M250 700h800q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="⌛" d="M1000 1200v-150q0 -21 -14.5 -35.5t-35.5 -14.5h-50v-100q0 -91 -49.5 -165.5t-130.5 -109.5q81 -35 130.5 -109.5t49.5 -165.5v-150h50q21 0 35.5 -14.5t14.5 -35.5v-150h-800v150q0 21 14.5 35.5t35.5 14.5h50v150q0 91 49.5 165.5t130.5 109.5q-81 35 -130.5 109.5 t-49.5 165.5v100h-50q-21 0 -35.5 14.5t-14.5 35.5v150h800zM400 1000v-100q0 -60 32.5 -109.5t87.5 -73.5q28 -12 44 -37t16 -55t-16 -55t-44 -37q-55 -24 -87.5 -73.5t-32.5 -109.5v-150h400v150q0 60 -32.5 109.5t-87.5 73.5q-28 12 -44 37t-16 55t16 55t44 37 q55 24 87.5 73.5t32.5 109.5v100h-400z" />
|
||||
<glyph unicode="◼" horiz-adv-x="500" d="M0 0z" />
|
||||
<glyph unicode="☁" d="M503 1089q110 0 200.5 -59.5t134.5 -156.5q44 14 90 14q120 0 205 -86.5t85 -206.5q0 -121 -85 -207.5t-205 -86.5h-750q-79 0 -135.5 57t-56.5 137q0 69 42.5 122.5t108.5 67.5q-2 12 -2 37q0 153 108 260.5t260 107.5z" />
|
||||
<glyph unicode="⛺" d="M774 1193.5q16 -9.5 20.5 -27t-5.5 -33.5l-136 -187l467 -746h30q20 0 35 -18.5t15 -39.5v-42h-1200v42q0 21 15 39.5t35 18.5h30l468 746l-135 183q-10 16 -5.5 34t20.5 28t34 5.5t28 -20.5l111 -148l112 150q9 16 27 20.5t34 -5zM600 200h377l-182 112l-195 534v-646z " />
|
||||
<glyph unicode="✉" d="M25 1100h1150q10 0 12.5 -5t-5.5 -13l-564 -567q-8 -8 -18 -8t-18 8l-564 567q-8 8 -5.5 13t12.5 5zM18 882l264 -264q8 -8 8 -18t-8 -18l-264 -264q-8 -8 -13 -5.5t-5 12.5v550q0 10 5 12.5t13 -5.5zM918 618l264 264q8 8 13 5.5t5 -12.5v-550q0 -10 -5 -12.5t-13 5.5 l-264 264q-8 8 -8 18t8 18zM818 482l364 -364q8 -8 5.5 -13t-12.5 -5h-1150q-10 0 -12.5 5t5.5 13l364 364q8 8 18 8t18 -8l164 -164q8 -8 18 -8t18 8l164 164q8 8 18 8t18 -8z" />
|
||||
<glyph unicode="✏" d="M1011 1210q19 0 33 -13l153 -153q13 -14 13 -33t-13 -33l-99 -92l-214 214l95 96q13 14 32 14zM1013 800l-615 -614l-214 214l614 614zM317 96l-333 -112l110 335z" />
|
||||
<glyph unicode="" d="M700 650v-550h250q21 0 35.5 -14.5t14.5 -35.5v-50h-800v50q0 21 14.5 35.5t35.5 14.5h250v550l-500 550h1200z" />
|
||||
<glyph unicode="" d="M368 1017l645 163q39 15 63 0t24 -49v-831q0 -55 -41.5 -95.5t-111.5 -63.5q-79 -25 -147 -4.5t-86 75t25.5 111.5t122.5 82q72 24 138 8v521l-600 -155v-606q0 -42 -44 -90t-109 -69q-79 -26 -147 -5.5t-86 75.5t25.5 111.5t122.5 82.5q72 24 138 7v639q0 38 14.5 59 t53.5 34z" />
|
||||
<glyph unicode="" d="M500 1191q100 0 191 -39t156.5 -104.5t104.5 -156.5t39 -191l-1 -2l1 -5q0 -141 -78 -262l275 -274q23 -26 22.5 -44.5t-22.5 -42.5l-59 -58q-26 -20 -46.5 -20t-39.5 20l-275 274q-119 -77 -261 -77l-5 1l-2 -1q-100 0 -191 39t-156.5 104.5t-104.5 156.5t-39 191 t39 191t104.5 156.5t156.5 104.5t191 39zM500 1022q-88 0 -162 -43t-117 -117t-43 -162t43 -162t117 -117t162 -43t162 43t117 117t43 162t-43 162t-117 117t-162 43z" />
|
||||
<glyph unicode="" d="M649 949q48 68 109.5 104t121.5 38.5t118.5 -20t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-150 152.5t-126.5 127.5t-93.5 124.5t-33.5 117.5q0 64 28 123t73 100.5t104 64t119 20 t120.5 -38.5t104.5 -104z" />
|
||||
<glyph unicode="" d="M407 800l131 353q7 19 17.5 19t17.5 -19l129 -353h421q21 0 24 -8.5t-14 -20.5l-342 -249l130 -401q7 -20 -0.5 -25.5t-24.5 6.5l-343 246l-342 -247q-17 -12 -24.5 -6.5t-0.5 25.5l130 400l-347 251q-17 12 -14 20.5t23 8.5h429z" />
|
||||
<glyph unicode="" d="M407 800l131 353q7 19 17.5 19t17.5 -19l129 -353h421q21 0 24 -8.5t-14 -20.5l-342 -249l130 -401q7 -20 -0.5 -25.5t-24.5 6.5l-343 246l-342 -247q-17 -12 -24.5 -6.5t-0.5 25.5l130 400l-347 251q-17 12 -14 20.5t23 8.5h429zM477 700h-240l197 -142l-74 -226 l193 139l195 -140l-74 229l192 140h-234l-78 211z" />
|
||||
<glyph unicode="" d="M600 1200q124 0 212 -88t88 -212v-250q0 -46 -31 -98t-69 -52v-75q0 -10 6 -21.5t15 -17.5l358 -230q9 -5 15 -16.5t6 -21.5v-93q0 -10 -7.5 -17.5t-17.5 -7.5h-1150q-10 0 -17.5 7.5t-7.5 17.5v93q0 10 6 21.5t15 16.5l358 230q9 6 15 17.5t6 21.5v75q-38 0 -69 52 t-31 98v250q0 124 88 212t212 88z" />
|
||||
<glyph unicode="" d="M25 1100h1150q10 0 17.5 -7.5t7.5 -17.5v-1050q0 -10 -7.5 -17.5t-17.5 -7.5h-1150q-10 0 -17.5 7.5t-7.5 17.5v1050q0 10 7.5 17.5t17.5 7.5zM100 1000v-100h100v100h-100zM875 1000h-550q-10 0 -17.5 -7.5t-7.5 -17.5v-350q0 -10 7.5 -17.5t17.5 -7.5h550 q10 0 17.5 7.5t7.5 17.5v350q0 10 -7.5 17.5t-17.5 7.5zM1000 1000v-100h100v100h-100zM100 800v-100h100v100h-100zM1000 800v-100h100v100h-100zM100 600v-100h100v100h-100zM1000 600v-100h100v100h-100zM875 500h-550q-10 0 -17.5 -7.5t-7.5 -17.5v-350q0 -10 7.5 -17.5 t17.5 -7.5h550q10 0 17.5 7.5t7.5 17.5v350q0 10 -7.5 17.5t-17.5 7.5zM100 400v-100h100v100h-100zM1000 400v-100h100v100h-100zM100 200v-100h100v100h-100zM1000 200v-100h100v100h-100z" />
|
||||
<glyph unicode="" d="M50 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM650 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400 q0 21 14.5 35.5t35.5 14.5zM50 500h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM650 500h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M50 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200 q0 21 14.5 35.5t35.5 14.5zM850 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200 q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM850 700h200q21 0 35.5 -14.5t14.5 -35.5v-200 q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 300h200 q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM850 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5 t35.5 14.5z" />
|
||||
<glyph unicode="" d="M50 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 1100h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v200 q0 21 14.5 35.5t35.5 14.5zM50 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 700h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700 q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 300h700q21 0 35.5 -14.5t14.5 -35.5v-200 q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M465 477l571 571q8 8 18 8t17 -8l177 -177q8 -7 8 -17t-8 -18l-783 -784q-7 -8 -17.5 -8t-17.5 8l-384 384q-8 8 -8 18t8 17l177 177q7 8 17 8t18 -8l171 -171q7 -7 18 -7t18 7z" />
|
||||
<glyph unicode="" d="M904 1083l178 -179q8 -8 8 -18.5t-8 -17.5l-267 -268l267 -268q8 -7 8 -17.5t-8 -18.5l-178 -178q-8 -8 -18.5 -8t-17.5 8l-268 267l-268 -267q-7 -8 -17.5 -8t-18.5 8l-178 178q-8 8 -8 18.5t8 17.5l267 268l-267 268q-8 7 -8 17.5t8 18.5l178 178q8 8 18.5 8t17.5 -8 l268 -267l268 268q7 7 17.5 7t18.5 -7z" />
|
||||
<glyph unicode="" d="M507 1177q98 0 187.5 -38.5t154.5 -103.5t103.5 -154.5t38.5 -187.5q0 -141 -78 -262l300 -299q8 -8 8 -18.5t-8 -18.5l-109 -108q-7 -8 -17.5 -8t-18.5 8l-300 299q-119 -77 -261 -77q-98 0 -188 38.5t-154.5 103t-103 154.5t-38.5 188t38.5 187.5t103 154.5 t154.5 103.5t188 38.5zM506.5 1023q-89.5 0 -165.5 -44t-120 -120.5t-44 -166t44 -165.5t120 -120t165.5 -44t166 44t120.5 120t44 165.5t-44 166t-120.5 120.5t-166 44zM425 900h150q10 0 17.5 -7.5t7.5 -17.5v-75h75q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5 t-17.5 -7.5h-75v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-75q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h75v75q0 10 7.5 17.5t17.5 7.5z" />
|
||||
<glyph unicode="" d="M507 1177q98 0 187.5 -38.5t154.5 -103.5t103.5 -154.5t38.5 -187.5q0 -141 -78 -262l300 -299q8 -8 8 -18.5t-8 -18.5l-109 -108q-7 -8 -17.5 -8t-18.5 8l-300 299q-119 -77 -261 -77q-98 0 -188 38.5t-154.5 103t-103 154.5t-38.5 188t38.5 187.5t103 154.5 t154.5 103.5t188 38.5zM506.5 1023q-89.5 0 -165.5 -44t-120 -120.5t-44 -166t44 -165.5t120 -120t165.5 -44t166 44t120.5 120t44 165.5t-44 166t-120.5 120.5t-166 44zM325 800h350q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-350q-10 0 -17.5 7.5 t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
|
||||
<glyph unicode="" d="M550 1200h100q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM800 975v166q167 -62 272 -209.5t105 -331.5q0 -117 -45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5 t-184.5 123t-123 184.5t-45.5 224q0 184 105 331.5t272 209.5v-166q-103 -55 -165 -155t-62 -220q0 -116 57 -214.5t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5q0 120 -62 220t-165 155z" />
|
||||
<glyph unicode="" d="M1025 1200h150q10 0 17.5 -7.5t7.5 -17.5v-1150q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v1150q0 10 7.5 17.5t17.5 7.5zM725 800h150q10 0 17.5 -7.5t7.5 -17.5v-750q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v750 q0 10 7.5 17.5t17.5 7.5zM425 500h150q10 0 17.5 -7.5t7.5 -17.5v-450q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v450q0 10 7.5 17.5t17.5 7.5zM125 300h150q10 0 17.5 -7.5t7.5 -17.5v-250q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5 v250q0 10 7.5 17.5t17.5 7.5z" />
|
||||
<glyph unicode="" d="M600 1174q33 0 74 -5l38 -152l5 -1q49 -14 94 -39l5 -2l134 80q61 -48 104 -105l-80 -134l3 -5q25 -44 39 -93l1 -6l152 -38q5 -43 5 -73q0 -34 -5 -74l-152 -38l-1 -6q-15 -49 -39 -93l-3 -5l80 -134q-48 -61 -104 -105l-134 81l-5 -3q-44 -25 -94 -39l-5 -2l-38 -151 q-43 -5 -74 -5q-33 0 -74 5l-38 151l-5 2q-49 14 -94 39l-5 3l-134 -81q-60 48 -104 105l80 134l-3 5q-25 45 -38 93l-2 6l-151 38q-6 42 -6 74q0 33 6 73l151 38l2 6q13 48 38 93l3 5l-80 134q47 61 105 105l133 -80l5 2q45 25 94 39l5 1l38 152q43 5 74 5zM600 815 q-89 0 -152 -63t-63 -151.5t63 -151.5t152 -63t152 63t63 151.5t-63 151.5t-152 63z" />
|
||||
<glyph unicode="" d="M500 1300h300q41 0 70.5 -29.5t29.5 -70.5v-100h275q10 0 17.5 -7.5t7.5 -17.5v-75h-1100v75q0 10 7.5 17.5t17.5 7.5h275v100q0 41 29.5 70.5t70.5 29.5zM500 1200v-100h300v100h-300zM1100 900v-800q0 -41 -29.5 -70.5t-70.5 -29.5h-700q-41 0 -70.5 29.5t-29.5 70.5 v800h900zM300 800v-700h100v700h-100zM500 800v-700h100v700h-100zM700 800v-700h100v700h-100zM900 800v-700h100v700h-100z" />
|
||||
<glyph unicode="" d="M18 618l620 608q8 7 18.5 7t17.5 -7l608 -608q8 -8 5.5 -13t-12.5 -5h-175v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v375h-300v-375q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v575h-175q-10 0 -12.5 5t5.5 13z" />
|
||||
<glyph unicode="" d="M600 1200v-400q0 -41 29.5 -70.5t70.5 -29.5h300v-650q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v1100q0 21 14.5 35.5t35.5 14.5h450zM1000 800h-250q-21 0 -35.5 14.5t-14.5 35.5v250z" />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM525 900h50q10 0 17.5 -7.5t7.5 -17.5v-275h175q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5z" />
|
||||
<glyph unicode="" d="M1300 0h-538l-41 400h-242l-41 -400h-538l431 1200h209l-21 -300h162l-20 300h208zM515 800l-27 -300h224l-27 300h-170z" />
|
||||
<glyph unicode="" d="M550 1200h200q21 0 35.5 -14.5t14.5 -35.5v-450h191q20 0 25.5 -11.5t-7.5 -27.5l-327 -400q-13 -16 -32 -16t-32 16l-327 400q-13 16 -7.5 27.5t25.5 11.5h191v450q0 21 14.5 35.5t35.5 14.5zM1125 400h50q10 0 17.5 -7.5t7.5 -17.5v-350q0 -10 -7.5 -17.5t-17.5 -7.5 h-1050q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h50q10 0 17.5 -7.5t7.5 -17.5v-175h900v175q0 10 7.5 17.5t17.5 7.5z" />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM525 900h150q10 0 17.5 -7.5t7.5 -17.5v-275h137q21 0 26 -11.5t-8 -27.5l-223 -275q-13 -16 -32 -16t-32 16l-223 275q-13 16 -8 27.5t26 11.5h137v275q0 10 7.5 17.5t17.5 7.5z " />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM632 914l223 -275q13 -16 8 -27.5t-26 -11.5h-137v-275q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v275h-137q-21 0 -26 11.5t8 27.5l223 275q13 16 32 16 t32 -16z" />
|
||||
<glyph unicode="" d="M225 1200h750q10 0 19.5 -7t12.5 -17l186 -652q7 -24 7 -49v-425q0 -12 -4 -27t-9 -17q-12 -6 -37 -6h-1100q-12 0 -27 4t-17 8q-6 13 -6 38l1 425q0 25 7 49l185 652q3 10 12.5 17t19.5 7zM878 1000h-556q-10 0 -19 -7t-11 -18l-87 -450q-2 -11 4 -18t16 -7h150 q10 0 19.5 -7t11.5 -17l38 -152q2 -10 11.5 -17t19.5 -7h250q10 0 19.5 7t11.5 17l38 152q2 10 11.5 17t19.5 7h150q10 0 16 7t4 18l-87 450q-2 11 -11 18t-19 7z" />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM540 820l253 -190q17 -12 17 -30t-17 -30l-253 -190q-16 -12 -28 -6.5t-12 26.5v400q0 21 12 26.5t28 -6.5z" />
|
||||
<glyph unicode="" d="M947 1060l135 135q7 7 12.5 5t5.5 -13v-362q0 -10 -7.5 -17.5t-17.5 -7.5h-362q-11 0 -13 5.5t5 12.5l133 133q-109 76 -238 76q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5h150q0 -117 -45.5 -224 t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5q192 0 347 -117z" />
|
||||
<glyph unicode="" d="M947 1060l135 135q7 7 12.5 5t5.5 -13v-361q0 -11 -7.5 -18.5t-18.5 -7.5h-361q-11 0 -13 5.5t5 12.5l134 134q-110 75 -239 75q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5h-150q0 117 45.5 224t123 184.5t184.5 123t224 45.5q192 0 347 -117zM1027 600h150 q0 -117 -45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5q-192 0 -348 118l-134 -134q-7 -8 -12.5 -5.5t-5.5 12.5v360q0 11 7.5 18.5t18.5 7.5h360q10 0 12.5 -5.5t-5.5 -12.5l-133 -133q110 -76 240 -76q116 0 214.5 57t155.5 155.5t57 214.5z" />
|
||||
<glyph unicode="" d="M125 1200h1050q10 0 17.5 -7.5t7.5 -17.5v-1150q0 -10 -7.5 -17.5t-17.5 -7.5h-1050q-10 0 -17.5 7.5t-7.5 17.5v1150q0 10 7.5 17.5t17.5 7.5zM1075 1000h-850q-10 0 -17.5 -7.5t-7.5 -17.5v-850q0 -10 7.5 -17.5t17.5 -7.5h850q10 0 17.5 7.5t7.5 17.5v850 q0 10 -7.5 17.5t-17.5 7.5zM325 900h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 900h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 700h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 700h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 500h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 500h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 300h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 300h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5z" />
|
||||
<glyph unicode="" d="M900 800v200q0 83 -58.5 141.5t-141.5 58.5h-300q-82 0 -141 -59t-59 -141v-200h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-600q0 -41 29.5 -70.5t70.5 -29.5h900q41 0 70.5 29.5t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5h-100zM400 800v150q0 21 15 35.5t35 14.5h200 q20 0 35 -14.5t15 -35.5v-150h-300z" />
|
||||
<glyph unicode="" d="M125 1100h50q10 0 17.5 -7.5t7.5 -17.5v-1075h-100v1075q0 10 7.5 17.5t17.5 7.5zM1075 1052q4 0 9 -2q16 -6 16 -23v-421q0 -6 -3 -12q-33 -59 -66.5 -99t-65.5 -58t-56.5 -24.5t-52.5 -6.5q-26 0 -57.5 6.5t-52.5 13.5t-60 21q-41 15 -63 22.5t-57.5 15t-65.5 7.5 q-85 0 -160 -57q-7 -5 -15 -5q-6 0 -11 3q-14 7 -14 22v438q22 55 82 98.5t119 46.5q23 2 43 0.5t43 -7t32.5 -8.5t38 -13t32.5 -11q41 -14 63.5 -21t57 -14t63.5 -7q103 0 183 87q7 8 18 8z" />
|
||||
<glyph unicode="" d="M600 1175q116 0 227 -49.5t192.5 -131t131 -192.5t49.5 -227v-300q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v300q0 127 -70.5 231.5t-184.5 161.5t-245 57t-245 -57t-184.5 -161.5t-70.5 -231.5v-300q0 -10 -7.5 -17.5t-17.5 -7.5h-50 q-10 0 -17.5 7.5t-7.5 17.5v300q0 116 49.5 227t131 192.5t192.5 131t227 49.5zM220 500h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14v460q0 8 6 14t14 6zM820 500h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14v460 q0 8 6 14t14 6z" />
|
||||
<glyph unicode="" d="M321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM900 668l120 120q7 7 17 7t17 -7l34 -34q7 -7 7 -17t-7 -17l-120 -120l120 -120q7 -7 7 -17 t-7 -17l-34 -34q-7 -7 -17 -7t-17 7l-120 119l-120 -119q-7 -7 -17 -7t-17 7l-34 34q-7 7 -7 17t7 17l119 120l-119 120q-7 7 -7 17t7 17l34 34q7 8 17 8t17 -8z" />
|
||||
<glyph unicode="" d="M321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM766 900h4q10 -1 16 -10q96 -129 96 -290q0 -154 -90 -281q-6 -9 -17 -10l-3 -1q-9 0 -16 6 l-29 23q-7 7 -8.5 16.5t4.5 17.5q72 103 72 229q0 132 -78 238q-6 8 -4.5 18t9.5 17l29 22q7 5 15 5z" />
|
||||
<glyph unicode="" d="M967 1004h3q11 -1 17 -10q135 -179 135 -396q0 -105 -34 -206.5t-98 -185.5q-7 -9 -17 -10h-3q-9 0 -16 6l-42 34q-8 6 -9 16t5 18q111 150 111 328q0 90 -29.5 176t-84.5 157q-6 9 -5 19t10 16l42 33q7 5 15 5zM321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5 t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM766 900h4q10 -1 16 -10q96 -129 96 -290q0 -154 -90 -281q-6 -9 -17 -10l-3 -1q-9 0 -16 6l-29 23q-7 7 -8.5 16.5t4.5 17.5q72 103 72 229q0 132 -78 238 q-6 8 -4.5 18.5t9.5 16.5l29 22q7 5 15 5z" />
|
||||
<glyph unicode="" d="M500 900h100v-100h-100v-100h-400v-100h-100v600h500v-300zM1200 700h-200v-100h200v-200h-300v300h-200v300h-100v200h600v-500zM100 1100v-300h300v300h-300zM800 1100v-300h300v300h-300zM300 900h-100v100h100v-100zM1000 900h-100v100h100v-100zM300 500h200v-500 h-500v500h200v100h100v-100zM800 300h200v-100h-100v-100h-200v100h-100v100h100v200h-200v100h300v-300zM100 400v-300h300v300h-300zM300 200h-100v100h100v-100zM1200 200h-100v100h100v-100zM700 0h-100v100h100v-100zM1200 0h-300v100h300v-100z" />
|
||||
<glyph unicode="" d="M100 200h-100v1000h100v-1000zM300 200h-100v1000h100v-1000zM700 200h-200v1000h200v-1000zM900 200h-100v1000h100v-1000zM1200 200h-200v1000h200v-1000zM400 0h-300v100h300v-100zM600 0h-100v91h100v-91zM800 0h-100v91h100v-91zM1100 0h-200v91h200v-91z" />
|
||||
<glyph unicode="" d="M500 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-682 682l1 475q0 10 7.5 17.5t17.5 7.5h474zM319.5 1024.5q-29.5 29.5 -71 29.5t-71 -29.5t-29.5 -71.5t29.5 -71.5t71 -29.5t71 29.5t29.5 71.5t-29.5 71.5z" />
|
||||
<glyph unicode="" d="M500 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-682 682l1 475q0 10 7.5 17.5t17.5 7.5h474zM800 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-56 56l424 426l-700 700h150zM319.5 1024.5q-29.5 29.5 -71 29.5t-71 -29.5 t-29.5 -71.5t29.5 -71.5t71 -29.5t71 29.5t29.5 71.5t-29.5 71.5z" />
|
||||
<glyph unicode="" d="M300 1200h825q75 0 75 -75v-900q0 -25 -18 -43l-64 -64q-8 -8 -13 -5.5t-5 12.5v950q0 10 -7.5 17.5t-17.5 7.5h-700q-25 0 -43 -18l-64 -64q-8 -8 -5.5 -13t12.5 -5h700q10 0 17.5 -7.5t7.5 -17.5v-950q0 -10 -7.5 -17.5t-17.5 -7.5h-850q-10 0 -17.5 7.5t-7.5 17.5v975 q0 25 18 43l139 139q18 18 43 18z" />
|
||||
<glyph unicode="" d="M250 1200h800q21 0 35.5 -14.5t14.5 -35.5v-1150l-450 444l-450 -445v1151q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M822 1200h-444q-11 0 -19 -7.5t-9 -17.5l-78 -301q-7 -24 7 -45l57 -108q6 -9 17.5 -15t21.5 -6h450q10 0 21.5 6t17.5 15l62 108q14 21 7 45l-83 301q-1 10 -9 17.5t-19 7.5zM1175 800h-150q-10 0 -21 -6.5t-15 -15.5l-78 -156q-4 -9 -15 -15.5t-21 -6.5h-550 q-10 0 -21 6.5t-15 15.5l-78 156q-4 9 -15 15.5t-21 6.5h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-650q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h750q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5 t7.5 17.5v650q0 10 -7.5 17.5t-17.5 7.5zM850 200h-500q-10 0 -19.5 -7t-11.5 -17l-38 -152q-2 -10 3.5 -17t15.5 -7h600q10 0 15.5 7t3.5 17l-38 152q-2 10 -11.5 17t-19.5 7z" />
|
||||
<glyph unicode="" d="M500 1100h200q56 0 102.5 -20.5t72.5 -50t44 -59t25 -50.5l6 -20h150q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v600q0 41 29.5 70.5t70.5 29.5h150q2 8 6.5 21.5t24 48t45 61t72 48t102.5 21.5zM900 800v-100 h100v100h-100zM600 730q-95 0 -162.5 -67.5t-67.5 -162.5t67.5 -162.5t162.5 -67.5t162.5 67.5t67.5 162.5t-67.5 162.5t-162.5 67.5zM600 603q43 0 73 -30t30 -73t-30 -73t-73 -30t-73 30t-30 73t30 73t73 30z" />
|
||||
<glyph unicode="" d="M681 1199l385 -998q20 -50 60 -92q18 -19 36.5 -29.5t27.5 -11.5l10 -2v-66h-417v66q53 0 75 43.5t5 88.5l-82 222h-391q-58 -145 -92 -234q-11 -34 -6.5 -57t25.5 -37t46 -20t55 -6v-66h-365v66q56 24 84 52q12 12 25 30.5t20 31.5l7 13l399 1006h93zM416 521h340 l-162 457z" />
|
||||
<glyph unicode="" d="M753 641q5 -1 14.5 -4.5t36 -15.5t50.5 -26.5t53.5 -40t50.5 -54.5t35.5 -70t14.5 -87q0 -67 -27.5 -125.5t-71.5 -97.5t-98.5 -66.5t-108.5 -40.5t-102 -13h-500v89q41 7 70.5 32.5t29.5 65.5v827q0 24 -0.5 34t-3.5 24t-8.5 19.5t-17 13.5t-28 12.5t-42.5 11.5v71 l471 -1q57 0 115.5 -20.5t108 -57t80.5 -94t31 -124.5q0 -51 -15.5 -96.5t-38 -74.5t-45 -50.5t-38.5 -30.5zM400 700h139q78 0 130.5 48.5t52.5 122.5q0 41 -8.5 70.5t-29.5 55.5t-62.5 39.5t-103.5 13.5h-118v-350zM400 200h216q80 0 121 50.5t41 130.5q0 90 -62.5 154.5 t-156.5 64.5h-159v-400z" />
|
||||
<glyph unicode="" d="M877 1200l2 -57q-83 -19 -116 -45.5t-40 -66.5l-132 -839q-9 -49 13 -69t96 -26v-97h-500v97q186 16 200 98l173 832q3 17 3 30t-1.5 22.5t-9 17.5t-13.5 12.5t-21.5 10t-26 8.5t-33.5 10q-13 3 -19 5v57h425z" />
|
||||
<glyph unicode="" d="M1300 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-850q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v850h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM175 1000h-75v-800h75l-125 -167l-125 167h75v800h-75l125 167z" />
|
||||
<glyph unicode="" d="M1100 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-650q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v650h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM1167 50l-167 -125v75h-800v-75l-167 125l167 125v-75h800v75z" />
|
||||
<glyph unicode="" d="M50 1100h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 500h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M250 1100h700q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM250 500h700q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M500 950v100q0 21 14.5 35.5t35.5 14.5h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5zM100 650v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000 q-21 0 -35.5 14.5t-14.5 35.5zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5zM0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100 q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5z" />
|
||||
<glyph unicode="" d="M50 1100h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 500h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 1100h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 800h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 500h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 500h800q21 0 35.5 -14.5t14.5 -35.5v-100 q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 200h800 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M400 0h-100v1100h100v-1100zM550 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM550 800h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM267 550l-167 -125v75h-200v100h200v75zM550 500h300q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM550 200h600 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM900 0h-100v1100h100v-1100zM50 800h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM1100 600h200v-100h-200v-75l-167 125l167 125v-75zM50 500h300q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h600 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M75 1000h750q31 0 53 -22t22 -53v-650q0 -31 -22 -53t-53 -22h-750q-31 0 -53 22t-22 53v650q0 31 22 53t53 22zM1200 300l-300 300l300 300v-600z" />
|
||||
<glyph unicode="" d="M44 1100h1112q18 0 31 -13t13 -31v-1012q0 -18 -13 -31t-31 -13h-1112q-18 0 -31 13t-13 31v1012q0 18 13 31t31 13zM100 1000v-737l247 182l298 -131l-74 156l293 318l236 -288v500h-1000zM342 884q56 0 95 -39t39 -94.5t-39 -95t-95 -39.5t-95 39.5t-39 95t39 94.5 t95 39z" />
|
||||
<glyph unicode="" d="M648 1169q117 0 216 -60t156.5 -161t57.5 -218q0 -115 -70 -258q-69 -109 -158 -225.5t-143 -179.5l-54 -62q-9 8 -25.5 24.5t-63.5 67.5t-91 103t-98.5 128t-95.5 148q-60 132 -60 249q0 88 34 169.5t91.5 142t137 96.5t166.5 36zM652.5 974q-91.5 0 -156.5 -65 t-65 -157t65 -156.5t156.5 -64.5t156.5 64.5t65 156.5t-65 157t-156.5 65z" />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 173v854q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57z" />
|
||||
<glyph unicode="" d="M554 1295q21 -72 57.5 -143.5t76 -130t83 -118t82.5 -117t70 -116t49.5 -126t18.5 -136.5q0 -71 -25.5 -135t-68.5 -111t-99 -82t-118.5 -54t-125.5 -23q-84 5 -161.5 34t-139.5 78.5t-99 125t-37 164.5q0 69 18 136.5t49.5 126.5t69.5 116.5t81.5 117.5t83.5 119 t76.5 131t58.5 143zM344 710q-23 -33 -43.5 -70.5t-40.5 -102.5t-17 -123q1 -37 14.5 -69.5t30 -52t41 -37t38.5 -24.5t33 -15q21 -7 32 -1t13 22l6 34q2 10 -2.5 22t-13.5 19q-5 4 -14 12t-29.5 40.5t-32.5 73.5q-26 89 6 271q2 11 -6 11q-8 1 -15 -10z" />
|
||||
<glyph unicode="" d="M1000 1013l108 115q2 1 5 2t13 2t20.5 -1t25 -9.5t28.5 -21.5q22 -22 27 -43t0 -32l-6 -10l-108 -115zM350 1100h400q50 0 105 -13l-187 -187h-368q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v182l200 200v-332 q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5zM1009 803l-362 -362l-161 -50l55 170l355 355z" />
|
||||
<glyph unicode="" d="M350 1100h361q-164 -146 -216 -200h-195q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5l200 153v-103q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5z M824 1073l339 -301q8 -7 8 -17.5t-8 -17.5l-340 -306q-7 -6 -12.5 -4t-6.5 11v203q-26 1 -54.5 0t-78.5 -7.5t-92 -17.5t-86 -35t-70 -57q10 59 33 108t51.5 81.5t65 58.5t68.5 40.5t67 24.5t56 13.5t40 4.5v210q1 10 6.5 12.5t13.5 -4.5z" />
|
||||
<glyph unicode="" d="M350 1100h350q60 0 127 -23l-178 -177h-349q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v69l200 200v-219q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5z M643 639l395 395q7 7 17.5 7t17.5 -7l101 -101q7 -7 7 -17.5t-7 -17.5l-531 -532q-7 -7 -17.5 -7t-17.5 7l-248 248q-7 7 -7 17.5t7 17.5l101 101q7 7 17.5 7t17.5 -7l111 -111q8 -7 18 -7t18 7z" />
|
||||
<glyph unicode="" d="M318 918l264 264q8 8 18 8t18 -8l260 -264q7 -8 4.5 -13t-12.5 -5h-170v-200h200v173q0 10 5 12t13 -5l264 -260q8 -7 8 -17.5t-8 -17.5l-264 -265q-8 -7 -13 -5t-5 12v173h-200v-200h170q10 0 12.5 -5t-4.5 -13l-260 -264q-8 -8 -18 -8t-18 8l-264 264q-8 8 -5.5 13 t12.5 5h175v200h-200v-173q0 -10 -5 -12t-13 5l-264 265q-8 7 -8 17.5t8 17.5l264 260q8 7 13 5t5 -12v-173h200v200h-175q-10 0 -12.5 5t5.5 13z" />
|
||||
<glyph unicode="" d="M250 1100h100q21 0 35.5 -14.5t14.5 -35.5v-438l464 453q15 14 25.5 10t10.5 -25v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v1000q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-438l464 453q15 14 25.5 10t10.5 -25v-438l464 453q15 14 25.5 10t10.5 -25v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5 t-14.5 35.5v1000q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M1200 1050v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -10.5 -25t-25.5 10l-492 480q-15 14 -15 35t15 35l492 480q15 14 25.5 10t10.5 -25v-438l464 453q15 14 25.5 10t10.5 -25z" />
|
||||
<glyph unicode="" d="M243 1074l814 -498q18 -11 18 -26t-18 -26l-814 -498q-18 -11 -30.5 -4t-12.5 28v1000q0 21 12.5 28t30.5 -4z" />
|
||||
<glyph unicode="" d="M250 1000h200q21 0 35.5 -14.5t14.5 -35.5v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5zM650 1000h200q21 0 35.5 -14.5t14.5 -35.5v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v800 q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M1100 950v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5z" />
|
||||
<glyph unicode="" d="M500 612v438q0 21 10.5 25t25.5 -10l492 -480q15 -14 15 -35t-15 -35l-492 -480q-15 -14 -25.5 -10t-10.5 25v438l-464 -453q-15 -14 -25.5 -10t-10.5 25v1000q0 21 10.5 25t25.5 -10z" />
|
||||
<glyph unicode="" d="M1048 1102l100 1q20 0 35 -14.5t15 -35.5l5 -1000q0 -21 -14.5 -35.5t-35.5 -14.5l-100 -1q-21 0 -35.5 14.5t-14.5 35.5l-2 437l-463 -454q-14 -15 -24.5 -10.5t-10.5 25.5l-2 437l-462 -455q-15 -14 -25.5 -9.5t-10.5 24.5l-5 1000q0 21 10.5 25.5t25.5 -10.5l466 -450 l-2 438q0 20 10.5 24.5t25.5 -9.5l466 -451l-2 438q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M850 1100h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438l-464 -453q-15 -14 -25.5 -10t-10.5 25v1000q0 21 10.5 25t25.5 -10l464 -453v438q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M686 1081l501 -540q15 -15 10.5 -26t-26.5 -11h-1042q-22 0 -26.5 11t10.5 26l501 540q15 15 36 15t36 -15zM150 400h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M885 900l-352 -353l352 -353l-197 -198l-552 552l552 550z" />
|
||||
<glyph unicode="" d="M1064 547l-551 -551l-198 198l353 353l-353 353l198 198z" />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM650 900h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-150h-150 q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5t35.5 -14.5h150v-150q0 -21 14.5 -35.5t35.5 -14.5h100q21 0 35.5 14.5t14.5 35.5v150h150q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5h-150v150q0 21 -14.5 35.5t-35.5 14.5z" />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM850 700h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5 t35.5 -14.5h500q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5z" />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM741.5 913q-12.5 0 -21.5 -9l-120 -120l-120 120q-9 9 -21.5 9 t-21.5 -9l-141 -141q-9 -9 -9 -21.5t9 -21.5l120 -120l-120 -120q-9 -9 -9 -21.5t9 -21.5l141 -141q9 -9 21.5 -9t21.5 9l120 120l120 -120q9 -9 21.5 -9t21.5 9l141 141q9 9 9 21.5t-9 21.5l-120 120l120 120q9 9 9 21.5t-9 21.5l-141 141q-9 9 -21.5 9z" />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM546 623l-84 85q-7 7 -17.5 7t-18.5 -7l-139 -139q-7 -8 -7 -18t7 -18 l242 -241q7 -8 17.5 -8t17.5 8l375 375q7 7 7 17.5t-7 18.5l-139 139q-7 7 -17.5 7t-17.5 -7z" />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM588 941q-29 0 -59 -5.5t-63 -20.5t-58 -38.5t-41.5 -63t-16.5 -89.5 q0 -25 20 -25h131q30 -5 35 11q6 20 20.5 28t45.5 8q20 0 31.5 -10.5t11.5 -28.5q0 -23 -7 -34t-26 -18q-1 0 -13.5 -4t-19.5 -7.5t-20 -10.5t-22 -17t-18.5 -24t-15.5 -35t-8 -46q-1 -8 5.5 -16.5t20.5 -8.5h173q7 0 22 8t35 28t37.5 48t29.5 74t12 100q0 47 -17 83 t-42.5 57t-59.5 34.5t-64 18t-59 4.5zM675 400h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5z" />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM675 1000h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5 t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5zM675 700h-250q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h75v-200h-75q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h350q10 0 17.5 7.5t7.5 17.5v50q0 10 -7.5 17.5 t-17.5 7.5h-75v275q0 10 -7.5 17.5t-17.5 7.5z" />
|
||||
<glyph unicode="" d="M525 1200h150q10 0 17.5 -7.5t7.5 -17.5v-194q103 -27 178.5 -102.5t102.5 -178.5h194q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-194q-27 -103 -102.5 -178.5t-178.5 -102.5v-194q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v194 q-103 27 -178.5 102.5t-102.5 178.5h-194q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h194q27 103 102.5 178.5t178.5 102.5v194q0 10 7.5 17.5t17.5 7.5zM700 893v-168q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v168q-68 -23 -119 -74 t-74 -119h168q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-168q23 -68 74 -119t119 -74v168q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-168q68 23 119 74t74 119h-168q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h168 q-23 68 -74 119t-119 74z" />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM759 823l64 -64q7 -7 7 -17.5t-7 -17.5l-124 -124l124 -124q7 -7 7 -17.5t-7 -17.5l-64 -64q-7 -7 -17.5 -7t-17.5 7l-124 124l-124 -124q-7 -7 -17.5 -7t-17.5 7l-64 64 q-7 7 -7 17.5t7 17.5l124 124l-124 124q-7 7 -7 17.5t7 17.5l64 64q7 7 17.5 7t17.5 -7l124 -124l124 124q7 7 17.5 7t17.5 -7z" />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM782 788l106 -106q7 -7 7 -17.5t-7 -17.5l-320 -321q-8 -7 -18 -7t-18 7l-202 203q-8 7 -8 17.5t8 17.5l106 106q7 8 17.5 8t17.5 -8l79 -79l197 197q7 7 17.5 7t17.5 -7z" />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5q0 -120 65 -225 l587 587q-105 65 -225 65zM965 819l-584 -584q104 -62 219 -62q116 0 214.5 57t155.5 155.5t57 214.5q0 115 -62 219z" />
|
||||
<glyph unicode="" d="M39 582l522 427q16 13 27.5 8t11.5 -26v-291h550q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-550v-291q0 -21 -11.5 -26t-27.5 8l-522 427q-16 13 -16 32t16 32z" />
|
||||
<glyph unicode="" d="M639 1009l522 -427q16 -13 16 -32t-16 -32l-522 -427q-16 -13 -27.5 -8t-11.5 26v291h-550q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h550v291q0 21 11.5 26t27.5 -8z" />
|
||||
<glyph unicode="" d="M682 1161l427 -522q13 -16 8 -27.5t-26 -11.5h-291v-550q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v550h-291q-21 0 -26 11.5t8 27.5l427 522q13 16 32 16t32 -16z" />
|
||||
<glyph unicode="" d="M550 1200h200q21 0 35.5 -14.5t14.5 -35.5v-550h291q21 0 26 -11.5t-8 -27.5l-427 -522q-13 -16 -32 -16t-32 16l-427 522q-13 16 -8 27.5t26 11.5h291v550q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M639 1109l522 -427q16 -13 16 -32t-16 -32l-522 -427q-16 -13 -27.5 -8t-11.5 26v291q-94 -2 -182 -20t-170.5 -52t-147 -92.5t-100.5 -135.5q5 105 27 193.5t67.5 167t113 135t167 91.5t225.5 42v262q0 21 11.5 26t27.5 -8z" />
|
||||
<glyph unicode="" d="M850 1200h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94l-249 -249q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l249 249l-94 94q-14 14 -10 24.5t25 10.5zM350 0h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l249 249 q8 7 18 7t18 -7l106 -106q7 -8 7 -18t-7 -18l-249 -249l94 -94q14 -14 10 -24.5t-25 -10.5z" />
|
||||
<glyph unicode="" d="M1014 1120l106 -106q7 -8 7 -18t-7 -18l-249 -249l94 -94q14 -14 10 -24.5t-25 -10.5h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l249 249q8 7 18 7t18 -7zM250 600h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94 l-249 -249q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l249 249l-94 94q-14 14 -10 24.5t25 10.5z" />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM704 900h-208q-20 0 -32 -14.5t-8 -34.5l58 -302q4 -20 21.5 -34.5 t37.5 -14.5h54q20 0 37.5 14.5t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5zM675 400h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5z" />
|
||||
<glyph unicode="" d="M260 1200q9 0 19 -2t15 -4l5 -2q22 -10 44 -23l196 -118q21 -13 36 -24q29 -21 37 -12q11 13 49 35l196 118q22 13 45 23q17 7 38 7q23 0 47 -16.5t37 -33.5l13 -16q14 -21 18 -45l25 -123l8 -44q1 -9 8.5 -14.5t17.5 -5.5h61q10 0 17.5 -7.5t7.5 -17.5v-50 q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 -7.5t-7.5 -17.5v-175h-400v300h-200v-300h-400v175q0 10 -7.5 17.5t-17.5 7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5h61q11 0 18 3t7 8q0 4 9 52l25 128q5 25 19 45q2 3 5 7t13.5 15t21.5 19.5t26.5 15.5 t29.5 7zM915 1079l-166 -162q-7 -7 -5 -12t12 -5h219q10 0 15 7t2 17l-51 149q-3 10 -11 12t-15 -6zM463 917l-177 157q-8 7 -16 5t-11 -12l-51 -143q-3 -10 2 -17t15 -7h231q11 0 12.5 5t-5.5 12zM500 0h-375q-10 0 -17.5 7.5t-7.5 17.5v375h400v-400zM1100 400v-375 q0 -10 -7.5 -17.5t-17.5 -7.5h-375v400h400z" />
|
||||
<glyph unicode="" d="M1165 1190q8 3 21 -6.5t13 -17.5q-2 -178 -24.5 -323.5t-55.5 -245.5t-87 -174.5t-102.5 -118.5t-118 -68.5t-118.5 -33t-120 -4.5t-105 9.5t-90 16.5q-61 12 -78 11q-4 1 -12.5 0t-34 -14.5t-52.5 -40.5l-153 -153q-26 -24 -37 -14.5t-11 43.5q0 64 42 102q8 8 50.5 45 t66.5 58q19 17 35 47t13 61q-9 55 -10 102.5t7 111t37 130t78 129.5q39 51 80 88t89.5 63.5t94.5 45t113.5 36t129 31t157.5 37t182 47.5zM1116 1098q-8 9 -22.5 -3t-45.5 -50q-38 -47 -119 -103.5t-142 -89.5l-62 -33q-56 -30 -102 -57t-104 -68t-102.5 -80.5t-85.5 -91 t-64 -104.5q-24 -56 -31 -86t2 -32t31.5 17.5t55.5 59.5q25 30 94 75.5t125.5 77.5t147.5 81q70 37 118.5 69t102 79.5t99 111t86.5 148.5q22 50 24 60t-6 19z" />
|
||||
<glyph unicode="" d="M653 1231q-39 -67 -54.5 -131t-10.5 -114.5t24.5 -96.5t47.5 -80t63.5 -62.5t68.5 -46.5t65 -30q-4 7 -17.5 35t-18.5 39.5t-17 39.5t-17 43t-13 42t-9.5 44.5t-2 42t4 43t13.5 39t23 38.5q96 -42 165 -107.5t105 -138t52 -156t13 -159t-19 -149.5q-13 -55 -44 -106.5 t-68 -87t-78.5 -64.5t-72.5 -45t-53 -22q-72 -22 -127 -11q-31 6 -13 19q6 3 17 7q13 5 32.5 21t41 44t38.5 63.5t21.5 81.5t-6.5 94.5t-50 107t-104 115.5q10 -104 -0.5 -189t-37 -140.5t-65 -93t-84 -52t-93.5 -11t-95 24.5q-80 36 -131.5 114t-53.5 171q-2 23 0 49.5 t4.5 52.5t13.5 56t27.5 60t46 64.5t69.5 68.5q-8 -53 -5 -102.5t17.5 -90t34 -68.5t44.5 -39t49 -2q31 13 38.5 36t-4.5 55t-29 64.5t-36 75t-26 75.5q-15 85 2 161.5t53.5 128.5t85.5 92.5t93.5 61t81.5 25.5z" />
|
||||
<glyph unicode="" d="M600 1094q82 0 160.5 -22.5t140 -59t116.5 -82.5t94.5 -95t68 -95t42.5 -82.5t14 -57.5t-14 -57.5t-43 -82.5t-68.5 -95t-94.5 -95t-116.5 -82.5t-140 -59t-159.5 -22.5t-159.5 22.5t-140 59t-116.5 82.5t-94.5 95t-68.5 95t-43 82.5t-14 57.5t14 57.5t42.5 82.5t68 95 t94.5 95t116.5 82.5t140 59t160.5 22.5zM888 829q-15 15 -18 12t5 -22q25 -57 25 -119q0 -124 -88 -212t-212 -88t-212 88t-88 212q0 59 23 114q8 19 4.5 22t-17.5 -12q-70 -69 -160 -184q-13 -16 -15 -40.5t9 -42.5q22 -36 47 -71t70 -82t92.5 -81t113 -58.5t133.5 -24.5 t133.5 24t113 58.5t92.5 81.5t70 81.5t47 70.5q11 18 9 42.5t-14 41.5q-90 117 -163 189zM448 727l-35 -36q-15 -15 -19.5 -38.5t4.5 -41.5q37 -68 93 -116q16 -13 38.5 -11t36.5 17l35 34q14 15 12.5 33.5t-16.5 33.5q-44 44 -89 117q-11 18 -28 20t-32 -12z" />
|
||||
<glyph unicode="" d="M592 0h-148l31 120q-91 20 -175.5 68.5t-143.5 106.5t-103.5 119t-66.5 110t-22 76q0 21 14 57.5t42.5 82.5t68 95t94.5 95t116.5 82.5t140 59t160.5 22.5q61 0 126 -15l32 121h148zM944 770l47 181q108 -85 176.5 -192t68.5 -159q0 -26 -19.5 -71t-59.5 -102t-93 -112 t-129 -104.5t-158 -75.5l46 173q77 49 136 117t97 131q11 18 9 42.5t-14 41.5q-54 70 -107 130zM310 824q-70 -69 -160 -184q-13 -16 -15 -40.5t9 -42.5q18 -30 39 -60t57 -70.5t74 -73t90 -61t105 -41.5l41 154q-107 18 -178.5 101.5t-71.5 193.5q0 59 23 114q8 19 4.5 22 t-17.5 -12zM448 727l-35 -36q-15 -15 -19.5 -38.5t4.5 -41.5q37 -68 93 -116q16 -13 38.5 -11t36.5 17l12 11l22 86l-3 4q-44 44 -89 117q-11 18 -28 20t-32 -12z" />
|
||||
<glyph unicode="" d="M-90 100l642 1066q20 31 48 28.5t48 -35.5l642 -1056q21 -32 7.5 -67.5t-50.5 -35.5h-1294q-37 0 -50.5 34t7.5 66zM155 200h345v75q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-75h345l-445 723zM496 700h208q20 0 32 -14.5t8 -34.5l-58 -252 q-4 -20 -21.5 -34.5t-37.5 -14.5h-54q-20 0 -37.5 14.5t-21.5 34.5l-58 252q-4 20 8 34.5t32 14.5z" />
|
||||
<glyph unicode="" d="M650 1200q62 0 106 -44t44 -106v-339l363 -325q15 -14 26 -38.5t11 -44.5v-41q0 -20 -12 -26.5t-29 5.5l-359 249v-263q100 -93 100 -113v-64q0 -21 -13 -29t-32 1l-205 128l-205 -128q-19 -9 -32 -1t-13 29v64q0 20 100 113v263l-359 -249q-17 -12 -29 -5.5t-12 26.5v41 q0 20 11 44.5t26 38.5l363 325v339q0 62 44 106t106 44z" />
|
||||
<glyph unicode="" d="M850 1200h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-150h-1100v150q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-50h500v50q0 21 14.5 35.5t35.5 14.5zM1100 800v-750q0 -21 -14.5 -35.5 t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v750h1100zM100 600v-100h100v100h-100zM300 600v-100h100v100h-100zM500 600v-100h100v100h-100zM700 600v-100h100v100h-100zM900 600v-100h100v100h-100zM100 400v-100h100v100h-100zM300 400v-100h100v100h-100zM500 400 v-100h100v100h-100zM700 400v-100h100v100h-100zM900 400v-100h100v100h-100zM100 200v-100h100v100h-100zM300 200v-100h100v100h-100zM500 200v-100h100v100h-100zM700 200v-100h100v100h-100zM900 200v-100h100v100h-100z" />
|
||||
<glyph unicode="" d="M1135 1165l249 -230q15 -14 15 -35t-15 -35l-249 -230q-14 -14 -24.5 -10t-10.5 25v150h-159l-600 -600h-291q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h209l600 600h241v150q0 21 10.5 25t24.5 -10zM522 819l-141 -141l-122 122h-209q-21 0 -35.5 14.5 t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h291zM1135 565l249 -230q15 -14 15 -35t-15 -35l-249 -230q-14 -14 -24.5 -10t-10.5 25v150h-241l-181 181l141 141l122 -122h159v150q0 21 10.5 25t24.5 -10z" />
|
||||
<glyph unicode="" d="M100 1100h1000q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-596l-304 -300v300h-100q-41 0 -70.5 29.5t-29.5 70.5v600q0 41 29.5 70.5t70.5 29.5z" />
|
||||
<glyph unicode="" d="M150 1200h200q21 0 35.5 -14.5t14.5 -35.5v-250h-300v250q0 21 14.5 35.5t35.5 14.5zM850 1200h200q21 0 35.5 -14.5t14.5 -35.5v-250h-300v250q0 21 14.5 35.5t35.5 14.5zM1100 800v-300q0 -41 -3 -77.5t-15 -89.5t-32 -96t-58 -89t-89 -77t-129 -51t-174 -20t-174 20 t-129 51t-89 77t-58 89t-32 96t-15 89.5t-3 77.5v300h300v-250v-27v-42.5t1.5 -41t5 -38t10 -35t16.5 -30t25.5 -24.5t35 -19t46.5 -12t60 -4t60 4.5t46.5 12.5t35 19.5t25 25.5t17 30.5t10 35t5 38t2 40.5t-0.5 42v25v250h300z" />
|
||||
<glyph unicode="" d="M1100 411l-198 -199l-353 353l-353 -353l-197 199l551 551z" />
|
||||
<glyph unicode="" d="M1101 789l-550 -551l-551 551l198 199l353 -353l353 353z" />
|
||||
<glyph unicode="" d="M404 1000h746q21 0 35.5 -14.5t14.5 -35.5v-551h150q21 0 25 -10.5t-10 -24.5l-230 -249q-14 -15 -35 -15t-35 15l-230 249q-14 14 -10 24.5t25 10.5h150v401h-381zM135 984l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-400h385l215 -200h-750q-21 0 -35.5 14.5 t-14.5 35.5v550h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
|
||||
<glyph unicode="" d="M56 1200h94q17 0 31 -11t18 -27l38 -162h896q24 0 39 -18.5t10 -42.5l-100 -475q-5 -21 -27 -42.5t-55 -21.5h-633l48 -200h535q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-50q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v50h-300v-50 q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v50h-31q-18 0 -32.5 10t-20.5 19l-5 10l-201 961h-54q-20 0 -35 14.5t-15 35.5t15 35.5t35 14.5z" />
|
||||
<glyph unicode="" d="M1200 1000v-100h-1200v100h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500zM0 800h1200v-800h-1200v800z" />
|
||||
<glyph unicode="" d="M200 800l-200 -400v600h200q0 41 29.5 70.5t70.5 29.5h300q42 0 71 -29.5t29 -70.5h500v-200h-1000zM1500 700l-300 -700h-1200l300 700h1200z" />
|
||||
<glyph unicode="" d="M635 1184l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-601h150q21 0 25 -10.5t-10 -24.5l-230 -249q-14 -15 -35 -15t-35 15l-230 249q-14 14 -10 24.5t25 10.5h150v601h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
|
||||
<glyph unicode="" d="M936 864l249 -229q14 -15 14 -35.5t-14 -35.5l-249 -229q-15 -15 -25.5 -10.5t-10.5 24.5v151h-600v-151q0 -20 -10.5 -24.5t-25.5 10.5l-249 229q-14 15 -14 35.5t14 35.5l249 229q15 15 25.5 10.5t10.5 -25.5v-149h600v149q0 21 10.5 25.5t25.5 -10.5z" />
|
||||
<glyph unicode="" d="M1169 400l-172 732q-5 23 -23 45.5t-38 22.5h-672q-20 0 -38 -20t-23 -41l-172 -739h1138zM1100 300h-1000q-41 0 -70.5 -29.5t-29.5 -70.5v-100q0 -41 29.5 -70.5t70.5 -29.5h1000q41 0 70.5 29.5t29.5 70.5v100q0 41 -29.5 70.5t-70.5 29.5zM800 100v100h100v-100h-100 zM1000 100v100h100v-100h-100z" />
|
||||
<glyph unicode="" d="M1150 1100q21 0 35.5 -14.5t14.5 -35.5v-850q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v850q0 21 14.5 35.5t35.5 14.5zM1000 200l-675 200h-38l47 -276q3 -16 -5.5 -20t-29.5 -4h-7h-84q-20 0 -34.5 14t-18.5 35q-55 337 -55 351v250v6q0 16 1 23.5t6.5 14 t17.5 6.5h200l675 250v-850zM0 750v-250q-4 0 -11 0.5t-24 6t-30 15t-24 30t-11 48.5v50q0 26 10.5 46t25 30t29 16t25.5 7z" />
|
||||
<glyph unicode="" d="M553 1200h94q20 0 29 -10.5t3 -29.5l-18 -37q83 -19 144 -82.5t76 -140.5l63 -327l118 -173h17q19 0 33 -14.5t14 -35t-13 -40.5t-31 -27q-8 -4 -23 -9.5t-65 -19.5t-103 -25t-132.5 -20t-158.5 -9q-57 0 -115 5t-104 12t-88.5 15.5t-73.5 17.5t-54.5 16t-35.5 12l-11 4 q-18 8 -31 28t-13 40.5t14 35t33 14.5h17l118 173l63 327q15 77 76 140t144 83l-18 32q-6 19 3.5 32t28.5 13zM498 110q50 -6 102 -6q53 0 102 6q-12 -49 -39.5 -79.5t-62.5 -30.5t-63 30.5t-39 79.5z" />
|
||||
<glyph unicode="" d="M800 946l224 78l-78 -224l234 -45l-180 -155l180 -155l-234 -45l78 -224l-224 78l-45 -234l-155 180l-155 -180l-45 234l-224 -78l78 224l-234 45l180 155l-180 155l234 45l-78 224l224 -78l45 234l155 -180l155 180z" />
|
||||
<glyph unicode="" d="M650 1200h50q40 0 70 -40.5t30 -84.5v-150l-28 -125h328q40 0 70 -40.5t30 -84.5v-100q0 -45 -29 -74l-238 -344q-16 -24 -38 -40.5t-45 -16.5h-250q-7 0 -42 25t-66 50l-31 25h-61q-45 0 -72.5 18t-27.5 57v400q0 36 20 63l145 196l96 198q13 28 37.5 48t51.5 20z M650 1100l-100 -212l-150 -213v-375h100l136 -100h214l250 375v125h-450l50 225v175h-50zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M600 1100h250q23 0 45 -16.5t38 -40.5l238 -344q29 -29 29 -74v-100q0 -44 -30 -84.5t-70 -40.5h-328q28 -118 28 -125v-150q0 -44 -30 -84.5t-70 -40.5h-50q-27 0 -51.5 20t-37.5 48l-96 198l-145 196q-20 27 -20 63v400q0 39 27.5 57t72.5 18h61q124 100 139 100z M50 1000h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5zM636 1000l-136 -100h-100v-375l150 -213l100 -212h50v175l-50 225h450v125l-250 375h-214z" />
|
||||
<glyph unicode="" d="M356 873l363 230q31 16 53 -6l110 -112q13 -13 13.5 -32t-11.5 -34l-84 -121h302q84 0 138 -38t54 -110t-55 -111t-139 -39h-106l-131 -339q-6 -21 -19.5 -41t-28.5 -20h-342q-7 0 -90 81t-83 94v525q0 17 14 35.5t28 28.5zM400 792v-503l100 -89h293l131 339 q6 21 19.5 41t28.5 20h203q21 0 30.5 25t0.5 50t-31 25h-456h-7h-6h-5.5t-6 0.5t-5 1.5t-5 2t-4 2.5t-4 4t-2.5 4.5q-12 25 5 47l146 183l-86 83zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500 q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M475 1103l366 -230q2 -1 6 -3.5t14 -10.5t18 -16.5t14.5 -20t6.5 -22.5v-525q0 -13 -86 -94t-93 -81h-342q-15 0 -28.5 20t-19.5 41l-131 339h-106q-85 0 -139.5 39t-54.5 111t54 110t138 38h302l-85 121q-11 15 -10.5 34t13.5 32l110 112q22 22 53 6zM370 945l146 -183 q17 -22 5 -47q-2 -2 -3.5 -4.5t-4 -4t-4 -2.5t-5 -2t-5 -1.5t-6 -0.5h-6h-6.5h-6h-475v-100h221q15 0 29 -20t20 -41l130 -339h294l106 89v503l-342 236zM1050 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5 v500q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M550 1294q72 0 111 -55t39 -139v-106l339 -131q21 -6 41 -19.5t20 -28.5v-342q0 -7 -81 -90t-94 -83h-525q-17 0 -35.5 14t-28.5 28l-9 14l-230 363q-16 31 6 53l112 110q13 13 32 13.5t34 -11.5l121 -84v302q0 84 38 138t110 54zM600 972v203q0 21 -25 30.5t-50 0.5 t-25 -31v-456v-7v-6v-5.5t-0.5 -6t-1.5 -5t-2 -5t-2.5 -4t-4 -4t-4.5 -2.5q-25 -12 -47 5l-183 146l-83 -86l236 -339h503l89 100v293l-339 131q-21 6 -41 19.5t-20 28.5zM450 200h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M350 1100h500q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5t35.5 -14.5zM600 306v-106q0 -84 -39 -139t-111 -55t-110 54t-38 138v302l-121 -84q-15 -12 -34 -11.5t-32 13.5l-112 110 q-22 22 -6 53l230 363q1 2 3.5 6t10.5 13.5t16.5 17t20 13.5t22.5 6h525q13 0 94 -83t81 -90v-342q0 -15 -20 -28.5t-41 -19.5zM308 900l-236 -339l83 -86l183 146q22 17 47 5q2 -1 4.5 -2.5t4 -4t2.5 -4t2 -5t1.5 -5t0.5 -6v-5.5v-6v-7v-456q0 -22 25 -31t50 0.5t25 30.5 v203q0 15 20 28.5t41 19.5l339 131v293l-89 100h-503z" />
|
||||
<glyph unicode="" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM914 632l-275 223q-16 13 -27.5 8t-11.5 -26v-137h-275 q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h275v-137q0 -21 11.5 -26t27.5 8l275 223q16 13 16 32t-16 32z" />
|
||||
<glyph unicode="" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM561 855l-275 -223q-16 -13 -16 -32t16 -32l275 -223q16 -13 27.5 -8 t11.5 26v137h275q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5h-275v137q0 21 -11.5 26t-27.5 -8z" />
|
||||
<glyph unicode="" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM855 639l-223 275q-13 16 -32 16t-32 -16l-223 -275q-13 -16 -8 -27.5 t26 -11.5h137v-275q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v275h137q21 0 26 11.5t-8 27.5z" />
|
||||
<glyph unicode="" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM675 900h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-275h-137q-21 0 -26 -11.5 t8 -27.5l223 -275q13 -16 32 -16t32 16l223 275q13 16 8 27.5t-26 11.5h-137v275q0 10 -7.5 17.5t-17.5 7.5z" />
|
||||
<glyph unicode="" d="M600 1176q116 0 222.5 -46t184 -123.5t123.5 -184t46 -222.5t-46 -222.5t-123.5 -184t-184 -123.5t-222.5 -46t-222.5 46t-184 123.5t-123.5 184t-46 222.5t46 222.5t123.5 184t184 123.5t222.5 46zM627 1101q-15 -12 -36.5 -20.5t-35.5 -12t-43 -8t-39 -6.5 q-15 -3 -45.5 0t-45.5 -2q-20 -7 -51.5 -26.5t-34.5 -34.5q-3 -11 6.5 -22.5t8.5 -18.5q-3 -34 -27.5 -91t-29.5 -79q-9 -34 5 -93t8 -87q0 -9 17 -44.5t16 -59.5q12 0 23 -5t23.5 -15t19.5 -14q16 -8 33 -15t40.5 -15t34.5 -12q21 -9 52.5 -32t60 -38t57.5 -11 q7 -15 -3 -34t-22.5 -40t-9.5 -38q13 -21 23 -34.5t27.5 -27.5t36.5 -18q0 -7 -3.5 -16t-3.5 -14t5 -17q104 -2 221 112q30 29 46.5 47t34.5 49t21 63q-13 8 -37 8.5t-36 7.5q-15 7 -49.5 15t-51.5 19q-18 0 -41 -0.5t-43 -1.5t-42 -6.5t-38 -16.5q-51 -35 -66 -12 q-4 1 -3.5 25.5t0.5 25.5q-6 13 -26.5 17.5t-24.5 6.5q1 15 -0.5 30.5t-7 28t-18.5 11.5t-31 -21q-23 -25 -42 4q-19 28 -8 58q6 16 22 22q6 -1 26 -1.5t33.5 -4t19.5 -13.5q7 -12 18 -24t21.5 -20.5t20 -15t15.5 -10.5l5 -3q2 12 7.5 30.5t8 34.5t-0.5 32q-3 18 3.5 29 t18 22.5t15.5 24.5q6 14 10.5 35t8 31t15.5 22.5t34 22.5q-6 18 10 36q8 0 24 -1.5t24.5 -1.5t20 4.5t20.5 15.5q-10 23 -31 42.5t-37.5 29.5t-49 27t-43.5 23q0 1 2 8t3 11.5t1.5 10.5t-1 9.5t-4.5 4.5q31 -13 58.5 -14.5t38.5 2.5l12 5q5 28 -9.5 46t-36.5 24t-50 15 t-41 20q-18 -4 -37 0zM613 994q0 -17 8 -42t17 -45t9 -23q-8 1 -39.5 5.5t-52.5 10t-37 16.5q3 11 16 29.5t16 25.5q10 -10 19 -10t14 6t13.5 14.5t16.5 12.5z" />
|
||||
<glyph unicode="" d="M756 1157q164 92 306 -9l-259 -138l145 -232l251 126q6 -89 -34 -156.5t-117 -110.5q-60 -34 -127 -39.5t-126 16.5l-596 -596q-15 -16 -36.5 -16t-36.5 16l-111 110q-15 15 -15 36.5t15 37.5l600 599q-34 101 5.5 201.5t135.5 154.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1220" d="M100 1196h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 1096h-200v-100h200v100zM100 796h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 696h-500v-100h500v100zM100 396h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 296h-300v-100h300v100z " />
|
||||
<glyph unicode="" d="M150 1200h900q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM700 500v-300l-200 -200v500l-350 500h900z" />
|
||||
<glyph unicode="" d="M500 1200h200q41 0 70.5 -29.5t29.5 -70.5v-100h300q41 0 70.5 -29.5t29.5 -70.5v-400h-500v100h-200v-100h-500v400q0 41 29.5 70.5t70.5 29.5h300v100q0 41 29.5 70.5t70.5 29.5zM500 1100v-100h200v100h-200zM1200 400v-200q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5v200h1200z" />
|
||||
<glyph unicode="" d="M50 1200h300q21 0 25 -10.5t-10 -24.5l-94 -94l199 -199q7 -8 7 -18t-7 -18l-106 -106q-8 -7 -18 -7t-18 7l-199 199l-94 -94q-14 -14 -24.5 -10t-10.5 25v300q0 21 14.5 35.5t35.5 14.5zM850 1200h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94 l-199 -199q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l199 199l-94 94q-14 14 -10 24.5t25 10.5zM364 470l106 -106q7 -8 7 -18t-7 -18l-199 -199l94 -94q14 -14 10 -24.5t-25 -10.5h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l199 199 q8 7 18 7t18 -7zM1071 271l94 94q14 14 24.5 10t10.5 -25v-300q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -25 10.5t10 24.5l94 94l-199 199q-7 8 -7 18t7 18l106 106q8 7 18 7t18 -7z" />
|
||||
<glyph unicode="" d="M596 1192q121 0 231.5 -47.5t190 -127t127 -190t47.5 -231.5t-47.5 -231.5t-127 -190.5t-190 -127t-231.5 -47t-231.5 47t-190.5 127t-127 190.5t-47 231.5t47 231.5t127 190t190.5 127t231.5 47.5zM596 1010q-112 0 -207.5 -55.5t-151 -151t-55.5 -207.5t55.5 -207.5 t151 -151t207.5 -55.5t207.5 55.5t151 151t55.5 207.5t-55.5 207.5t-151 151t-207.5 55.5zM454.5 905q22.5 0 38.5 -16t16 -38.5t-16 -39t-38.5 -16.5t-38.5 16.5t-16 39t16 38.5t38.5 16zM754.5 905q22.5 0 38.5 -16t16 -38.5t-16 -39t-38 -16.5q-14 0 -29 10l-55 -145 q17 -23 17 -51q0 -36 -25.5 -61.5t-61.5 -25.5t-61.5 25.5t-25.5 61.5q0 32 20.5 56.5t51.5 29.5l122 126l1 1q-9 14 -9 28q0 23 16 39t38.5 16zM345.5 709q22.5 0 38.5 -16t16 -38.5t-16 -38.5t-38.5 -16t-38.5 16t-16 38.5t16 38.5t38.5 16zM854.5 709q22.5 0 38.5 -16 t16 -38.5t-16 -38.5t-38.5 -16t-38.5 16t-16 38.5t16 38.5t38.5 16z" />
|
||||
<glyph unicode="" d="M546 173l469 470q91 91 99 192q7 98 -52 175.5t-154 94.5q-22 4 -47 4q-34 0 -66.5 -10t-56.5 -23t-55.5 -38t-48 -41.5t-48.5 -47.5q-376 -375 -391 -390q-30 -27 -45 -41.5t-37.5 -41t-32 -46.5t-16 -47.5t-1.5 -56.5q9 -62 53.5 -95t99.5 -33q74 0 125 51l548 548 q36 36 20 75q-7 16 -21.5 26t-32.5 10q-26 0 -50 -23q-13 -12 -39 -38l-341 -338q-15 -15 -35.5 -15.5t-34.5 13.5t-14 34.5t14 34.5q327 333 361 367q35 35 67.5 51.5t78.5 16.5q14 0 29 -1q44 -8 74.5 -35.5t43.5 -68.5q14 -47 2 -96.5t-47 -84.5q-12 -11 -32 -32 t-79.5 -81t-114.5 -115t-124.5 -123.5t-123 -119.5t-96.5 -89t-57 -45q-56 -27 -120 -27q-70 0 -129 32t-93 89q-48 78 -35 173t81 163l511 511q71 72 111 96q91 55 198 55q80 0 152 -33q78 -36 129.5 -103t66.5 -154q17 -93 -11 -183.5t-94 -156.5l-482 -476 q-15 -15 -36 -16t-37 14t-17.5 34t14.5 35z" />
|
||||
<glyph unicode="" d="M649 949q48 68 109.5 104t121.5 38.5t118.5 -20t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-150 152.5t-126.5 127.5t-93.5 124.5t-33.5 117.5q0 64 28 123t73 100.5t104 64t119 20 t120.5 -38.5t104.5 -104zM896 972q-33 0 -64.5 -19t-56.5 -46t-47.5 -53.5t-43.5 -45.5t-37.5 -19t-36 19t-40 45.5t-43 53.5t-54 46t-65.5 19q-67 0 -122.5 -55.5t-55.5 -132.5q0 -23 13.5 -51t46 -65t57.5 -63t76 -75l22 -22q15 -14 44 -44t50.5 -51t46 -44t41 -35t23 -12 t23.5 12t42.5 36t46 44t52.5 52t44 43q4 4 12 13q43 41 63.5 62t52 55t46 55t26 46t11.5 44q0 79 -53 133.5t-120 54.5z" />
|
||||
<glyph unicode="" d="M776.5 1214q93.5 0 159.5 -66l141 -141q66 -66 66 -160q0 -42 -28 -95.5t-62 -87.5l-29 -29q-31 53 -77 99l-18 18l95 95l-247 248l-389 -389l212 -212l-105 -106l-19 18l-141 141q-66 66 -66 159t66 159l283 283q65 66 158.5 66zM600 706l105 105q10 -8 19 -17l141 -141 q66 -66 66 -159t-66 -159l-283 -283q-66 -66 -159 -66t-159 66l-141 141q-66 66 -66 159.5t66 159.5l55 55q29 -55 75 -102l18 -17l-95 -95l247 -248l389 389z" />
|
||||
<glyph unicode="" d="M603 1200q85 0 162 -15t127 -38t79 -48t29 -46v-953q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-41 0 -70.5 29.5t-29.5 70.5v953q0 21 30 46.5t81 48t129 37.5t163 15zM300 1000v-700h600v700h-600zM600 254q-43 0 -73.5 -30.5t-30.5 -73.5t30.5 -73.5t73.5 -30.5t73.5 30.5 t30.5 73.5t-30.5 73.5t-73.5 30.5z" />
|
||||
<glyph unicode="" d="M902 1185l283 -282q15 -15 15 -36t-14.5 -35.5t-35.5 -14.5t-35 15l-36 35l-279 -267v-300l-212 210l-308 -307l-280 -203l203 280l307 308l-210 212h300l267 279l-35 36q-15 14 -15 35t14.5 35.5t35.5 14.5t35 -15z" />
|
||||
<glyph unicode="" d="M700 1248v-78q38 -5 72.5 -14.5t75.5 -31.5t71 -53.5t52 -84t24 -118.5h-159q-4 36 -10.5 59t-21 45t-40 35.5t-64.5 20.5v-307l64 -13q34 -7 64 -16.5t70 -32t67.5 -52.5t47.5 -80t20 -112q0 -139 -89 -224t-244 -97v-77h-100v79q-150 16 -237 103q-40 40 -52.5 93.5 t-15.5 139.5h139q5 -77 48.5 -126t117.5 -65v335l-27 8q-46 14 -79 26.5t-72 36t-63 52t-40 72.5t-16 98q0 70 25 126t67.5 92t94.5 57t110 27v77h100zM600 754v274q-29 -4 -50 -11t-42 -21.5t-31.5 -41.5t-10.5 -65q0 -29 7 -50.5t16.5 -34t28.5 -22.5t31.5 -14t37.5 -10 q9 -3 13 -4zM700 547v-310q22 2 42.5 6.5t45 15.5t41.5 27t29 42t12 59.5t-12.5 59.5t-38 44.5t-53 31t-66.5 24.5z" />
|
||||
<glyph unicode="" d="M561 1197q84 0 160.5 -40t123.5 -109.5t47 -147.5h-153q0 40 -19.5 71.5t-49.5 48.5t-59.5 26t-55.5 9q-37 0 -79 -14.5t-62 -35.5q-41 -44 -41 -101q0 -26 13.5 -63t26.5 -61t37 -66q6 -9 9 -14h241v-100h-197q8 -50 -2.5 -115t-31.5 -95q-45 -62 -99 -112 q34 10 83 17.5t71 7.5q32 1 102 -16t104 -17q83 0 136 30l50 -147q-31 -19 -58 -30.5t-55 -15.5t-42 -4.5t-46 -0.5q-23 0 -76 17t-111 32.5t-96 11.5q-39 -3 -82 -16t-67 -25l-23 -11l-55 145q4 3 16 11t15.5 10.5t13 9t15.5 12t14.5 14t17.5 18.5q48 55 54 126.5 t-30 142.5h-221v100h166q-23 47 -44 104q-7 20 -12 41.5t-6 55.5t6 66.5t29.5 70.5t58.5 71q97 88 263 88z" />
|
||||
<glyph unicode="" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM935 1184l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-900h-200v900h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
|
||||
<glyph unicode="" d="M1000 700h-100v100h-100v-100h-100v500h300v-500zM400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM801 1100v-200h100v200h-100zM1000 350l-200 -250h200v-100h-300v150l200 250h-200v100h300v-150z " />
|
||||
<glyph unicode="" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1000 1050l-200 -250h200v-100h-300v150l200 250h-200v100h300v-150zM1000 0h-100v100h-100v-100h-100v500h300v-500zM801 400v-200h100v200h-100z " />
|
||||
<glyph unicode="" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1000 700h-100v400h-100v100h200v-500zM1100 0h-100v100h-200v400h300v-500zM901 400v-200h100v200h-100z" />
|
||||
<glyph unicode="" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1100 700h-100v100h-200v400h300v-500zM901 1100v-200h100v200h-100zM1000 0h-100v400h-100v100h200v-500z" />
|
||||
<glyph unicode="" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM900 1000h-200v200h200v-200zM1000 700h-300v200h300v-200zM1100 400h-400v200h400v-200zM1200 100h-500v200h500v-200z" />
|
||||
<glyph unicode="" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1200 1000h-500v200h500v-200zM1100 700h-400v200h400v-200zM1000 400h-300v200h300v-200zM900 100h-200v200h200v-200z" />
|
||||
<glyph unicode="" d="M350 1100h400q162 0 256 -93.5t94 -256.5v-400q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5z" />
|
||||
<glyph unicode="" d="M350 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-163 0 -256.5 92.5t-93.5 257.5v400q0 163 94 256.5t256 93.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM440 770l253 -190q17 -12 17 -30t-17 -30l-253 -190q-16 -12 -28 -6.5t-12 26.5v400q0 21 12 26.5t28 -6.5z" />
|
||||
<glyph unicode="" d="M350 1100h400q163 0 256.5 -94t93.5 -256v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 163 92.5 256.5t257.5 93.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM350 700h400q21 0 26.5 -12t-6.5 -28l-190 -253q-12 -17 -30 -17t-30 17l-190 253q-12 16 -6.5 28t26.5 12z" />
|
||||
<glyph unicode="" d="M350 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -163 -92.5 -256.5t-257.5 -93.5h-400q-163 0 -256.5 94t-93.5 256v400q0 165 92.5 257.5t257.5 92.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM580 693l190 -253q12 -16 6.5 -28t-26.5 -12h-400q-21 0 -26.5 12t6.5 28l190 253q12 17 30 17t30 -17z" />
|
||||
<glyph unicode="" d="M550 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h450q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-450q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM338 867l324 -284q16 -14 16 -33t-16 -33l-324 -284q-16 -14 -27 -9t-11 26v150h-250q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h250v150q0 21 11 26t27 -9z" />
|
||||
<glyph unicode="" d="M793 1182l9 -9q8 -10 5 -27q-3 -11 -79 -225.5t-78 -221.5l300 1q24 0 32.5 -17.5t-5.5 -35.5q-1 0 -133.5 -155t-267 -312.5t-138.5 -162.5q-12 -15 -26 -15h-9l-9 8q-9 11 -4 32q2 9 42 123.5t79 224.5l39 110h-302q-23 0 -31 19q-10 21 6 41q75 86 209.5 237.5 t228 257t98.5 111.5q9 16 25 16h9z" />
|
||||
<glyph unicode="" d="M350 1100h400q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-450q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h450q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400 q0 165 92.5 257.5t257.5 92.5zM938 867l324 -284q16 -14 16 -33t-16 -33l-324 -284q-16 -14 -27 -9t-11 26v150h-250q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h250v150q0 21 11 26t27 -9z" />
|
||||
<glyph unicode="" d="M750 1200h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -10.5 -25t-24.5 10l-109 109l-312 -312q-15 -15 -35.5 -15t-35.5 15l-141 141q-15 15 -15 35.5t15 35.5l312 312l-109 109q-14 14 -10 24.5t25 10.5zM456 900h-156q-41 0 -70.5 -29.5t-29.5 -70.5v-500 q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v148l200 200v-298q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5h300z" />
|
||||
<glyph unicode="" d="M600 1186q119 0 227.5 -46.5t187 -125t125 -187t46.5 -227.5t-46.5 -227.5t-125 -187t-187 -125t-227.5 -46.5t-227.5 46.5t-187 125t-125 187t-46.5 227.5t46.5 227.5t125 187t187 125t227.5 46.5zM600 1022q-115 0 -212 -56.5t-153.5 -153.5t-56.5 -212t56.5 -212 t153.5 -153.5t212 -56.5t212 56.5t153.5 153.5t56.5 212t-56.5 212t-153.5 153.5t-212 56.5zM600 794q80 0 137 -57t57 -137t-57 -137t-137 -57t-137 57t-57 137t57 137t137 57z" />
|
||||
<glyph unicode="" d="M450 1200h200q21 0 35.5 -14.5t14.5 -35.5v-350h245q20 0 25 -11t-9 -26l-383 -426q-14 -15 -33.5 -15t-32.5 15l-379 426q-13 15 -8.5 26t25.5 11h250v350q0 21 14.5 35.5t35.5 14.5zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5z M900 200v-50h100v50h-100z" />
|
||||
<glyph unicode="" d="M583 1182l378 -435q14 -15 9 -31t-26 -16h-244v-250q0 -20 -17 -35t-39 -15h-200q-20 0 -32 14.5t-12 35.5v250h-250q-20 0 -25.5 16.5t8.5 31.5l383 431q14 16 33.5 17t33.5 -14zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5z M900 200v-50h100v50h-100z" />
|
||||
<glyph unicode="" d="M396 723l369 369q7 7 17.5 7t17.5 -7l139 -139q7 -8 7 -18.5t-7 -17.5l-525 -525q-7 -8 -17.5 -8t-17.5 8l-292 291q-7 8 -7 18t7 18l139 139q8 7 18.5 7t17.5 -7zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50 h-100z" />
|
||||
<glyph unicode="" d="M135 1023l142 142q14 14 35 14t35 -14l77 -77l-212 -212l-77 76q-14 15 -14 36t14 35zM655 855l210 210q14 14 24.5 10t10.5 -25l-2 -599q-1 -20 -15.5 -35t-35.5 -15l-597 -1q-21 0 -25 10.5t10 24.5l208 208l-154 155l212 212zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5 v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50h-100z" />
|
||||
<glyph unicode="" d="M350 1200l599 -2q20 -1 35 -15.5t15 -35.5l1 -597q0 -21 -10.5 -25t-24.5 10l-208 208l-155 -154l-212 212l155 154l-210 210q-14 14 -10 24.5t25 10.5zM524 512l-76 -77q-15 -14 -36 -14t-35 14l-142 142q-14 14 -14 35t14 35l77 77zM50 300h1000q21 0 35.5 -14.5 t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50h-100z" />
|
||||
<glyph unicode="" d="M1200 103l-483 276l-314 -399v423h-399l1196 796v-1096zM483 424v-230l683 953z" />
|
||||
<glyph unicode="" d="M1100 1000v-850q0 -21 -14.5 -35.5t-35.5 -14.5h-150v400h-700v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200z" />
|
||||
<glyph unicode="" d="M1100 1000l-2 -149l-299 -299l-95 95q-9 9 -21.5 9t-21.5 -9l-149 -147h-312v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM1132 638l106 -106q7 -7 7 -17.5t-7 -17.5l-420 -421q-8 -7 -18 -7 t-18 7l-202 203q-8 7 -8 17.5t8 17.5l106 106q7 8 17.5 8t17.5 -8l79 -79l297 297q7 7 17.5 7t17.5 -7z" />
|
||||
<glyph unicode="" d="M1100 1000v-269l-103 -103l-134 134q-15 15 -33.5 16.5t-34.5 -12.5l-266 -266h-329v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM1202 572l70 -70q15 -15 15 -35.5t-15 -35.5l-131 -131 l131 -131q15 -15 15 -35.5t-15 -35.5l-70 -70q-15 -15 -35.5 -15t-35.5 15l-131 131l-131 -131q-15 -15 -35.5 -15t-35.5 15l-70 70q-15 15 -15 35.5t15 35.5l131 131l-131 131q-15 15 -15 35.5t15 35.5l70 70q15 15 35.5 15t35.5 -15l131 -131l131 131q15 15 35.5 15 t35.5 -15z" />
|
||||
<glyph unicode="" d="M1100 1000v-300h-350q-21 0 -35.5 -14.5t-14.5 -35.5v-150h-500v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM850 600h100q21 0 35.5 -14.5t14.5 -35.5v-250h150q21 0 25 -10.5t-10 -24.5 l-230 -230q-14 -14 -35 -14t-35 14l-230 230q-14 14 -10 24.5t25 10.5h150v250q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M1100 1000v-400l-165 165q-14 15 -35 15t-35 -15l-263 -265h-402v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM935 565l230 -229q14 -15 10 -25.5t-25 -10.5h-150v-250q0 -20 -14.5 -35 t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35v250h-150q-21 0 -25 10.5t10 25.5l230 229q14 15 35 15t35 -15z" />
|
||||
<glyph unicode="" d="M50 1100h1100q21 0 35.5 -14.5t14.5 -35.5v-150h-1200v150q0 21 14.5 35.5t35.5 14.5zM1200 800v-550q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v550h1200zM100 500v-200h400v200h-400z" />
|
||||
<glyph unicode="" d="M935 1165l248 -230q14 -14 14 -35t-14 -35l-248 -230q-14 -14 -24.5 -10t-10.5 25v150h-400v200h400v150q0 21 10.5 25t24.5 -10zM200 800h-50q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v-200zM400 800h-100v200h100v-200zM18 435l247 230 q14 14 24.5 10t10.5 -25v-150h400v-200h-400v-150q0 -21 -10.5 -25t-24.5 10l-247 230q-15 14 -15 35t15 35zM900 300h-100v200h100v-200zM1000 500h51q20 0 34.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-34.5 -14.5h-51v200z" />
|
||||
<glyph unicode="" d="M862 1073l276 116q25 18 43.5 8t18.5 -41v-1106q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v397q-4 1 -11 5t-24 17.5t-30 29t-24 42t-11 56.5v359q0 31 18.5 65t43.5 52zM550 1200q22 0 34.5 -12.5t14.5 -24.5l1 -13v-450q0 -28 -10.5 -59.5 t-25 -56t-29 -45t-25.5 -31.5l-10 -11v-447q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v447q-4 4 -11 11.5t-24 30.5t-30 46t-24 55t-11 60v450q0 2 0.5 5.5t4 12t8.5 15t14.5 12t22.5 5.5q20 0 32.5 -12.5t14.5 -24.5l3 -13v-350h100v350v5.5t2.5 12 t7 15t15 12t25.5 5.5q23 0 35.5 -12.5t13.5 -24.5l1 -13v-350h100v350q0 2 0.5 5.5t3 12t7 15t15 12t24.5 5.5z" />
|
||||
<glyph unicode="" d="M1200 1100v-56q-4 0 -11 -0.5t-24 -3t-30 -7.5t-24 -15t-11 -24v-888q0 -22 25 -34.5t50 -13.5l25 -2v-56h-400v56q75 0 87.5 6.5t12.5 43.5v394h-500v-394q0 -37 12.5 -43.5t87.5 -6.5v-56h-400v56q4 0 11 0.5t24 3t30 7.5t24 15t11 24v888q0 22 -25 34.5t-50 13.5 l-25 2v56h400v-56q-75 0 -87.5 -6.5t-12.5 -43.5v-394h500v394q0 37 -12.5 43.5t-87.5 6.5v56h400z" />
|
||||
<glyph unicode="" d="M675 1000h375q21 0 35.5 -14.5t14.5 -35.5v-150h-105l-295 -98v98l-200 200h-400l100 100h375zM100 900h300q41 0 70.5 -29.5t29.5 -70.5v-500q0 -41 -29.5 -70.5t-70.5 -29.5h-300q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5zM100 800v-200h300v200 h-300zM1100 535l-400 -133v163l400 133v-163zM100 500v-200h300v200h-300zM1100 398v-248q0 -21 -14.5 -35.5t-35.5 -14.5h-375l-100 -100h-375l-100 100h400l200 200h105z" />
|
||||
<glyph unicode="" d="M17 1007l162 162q17 17 40 14t37 -22l139 -194q14 -20 11 -44.5t-20 -41.5l-119 -118q102 -142 228 -268t267 -227l119 118q17 17 42.5 19t44.5 -12l192 -136q19 -14 22.5 -37.5t-13.5 -40.5l-163 -162q-3 -1 -9.5 -1t-29.5 2t-47.5 6t-62.5 14.5t-77.5 26.5t-90 42.5 t-101.5 60t-111 83t-119 108.5q-74 74 -133.5 150.5t-94.5 138.5t-60 119.5t-34.5 100t-15 74.5t-4.5 48z" />
|
||||
<glyph unicode="" d="M600 1100q92 0 175 -10.5t141.5 -27t108.5 -36.5t81.5 -40t53.5 -37t31 -27l9 -10v-200q0 -21 -14.5 -33t-34.5 -9l-202 34q-20 3 -34.5 20t-14.5 38v146q-141 24 -300 24t-300 -24v-146q0 -21 -14.5 -38t-34.5 -20l-202 -34q-20 -3 -34.5 9t-14.5 33v200q3 4 9.5 10.5 t31 26t54 37.5t80.5 39.5t109 37.5t141 26.5t175 10.5zM600 795q56 0 97 -9.5t60 -23.5t30 -28t12 -24l1 -10v-50l365 -303q14 -15 24.5 -40t10.5 -45v-212q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v212q0 20 10.5 45t24.5 40l365 303v50 q0 4 1 10.5t12 23t30 29t60 22.5t97 10z" />
|
||||
<glyph unicode="" d="M1100 700l-200 -200h-600l-200 200v500h200v-200h200v200h200v-200h200v200h200v-500zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-12l137 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5 t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M700 1100h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-1000h300v1000q0 41 -29.5 70.5t-70.5 29.5zM1100 800h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-700h300v700q0 41 -29.5 70.5t-70.5 29.5zM400 0h-300v400q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-400z " />
|
||||
<glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-100h200v-300h-300v100h200v100h-200v300h300v-100zM900 700v-300l-100 -100h-200v500h200z M700 700v-300h100v300h-100z" />
|
||||
<glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 300h-100v200h-100v-200h-100v500h100v-200h100v200h100v-500zM900 700v-300l-100 -100h-200v500h200z M700 700v-300h100v300h-100z" />
|
||||
<glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-300h200v-100h-300v500h300v-100zM900 700h-200v-300h200v-100h-300v500h300v-100z" />
|
||||
<glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 400l-300 150l300 150v-300zM900 550l-300 -150v300z" />
|
||||
<glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM900 300h-700v500h700v-500zM800 700h-130q-38 0 -66.5 -43t-28.5 -108t27 -107t68 -42h130v300zM300 700v-300 h130q41 0 68 42t27 107t-28.5 108t-66.5 43h-130z" />
|
||||
<glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-100h200v-300h-300v100h200v100h-200v300h300v-100zM900 300h-100v400h-100v100h200v-500z M700 300h-100v100h100v-100z" />
|
||||
<glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM300 700h200v-400h-300v500h100v-100zM900 300h-100v400h-100v100h200v-500zM300 600v-200h100v200h-100z M700 300h-100v100h100v-100z" />
|
||||
<glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 500l-199 -200h-100v50l199 200v150h-200v100h300v-300zM900 300h-100v400h-100v100h200v-500zM701 300h-100 v100h100v-100z" />
|
||||
<glyph unicode="" d="M600 1191q120 0 229.5 -47t188.5 -126t126 -188.5t47 -229.5t-47 -229.5t-126 -188.5t-188.5 -126t-229.5 -47t-229.5 47t-188.5 126t-126 188.5t-47 229.5t47 229.5t126 188.5t188.5 126t229.5 47zM600 1021q-114 0 -211 -56.5t-153.5 -153.5t-56.5 -211t56.5 -211 t153.5 -153.5t211 -56.5t211 56.5t153.5 153.5t56.5 211t-56.5 211t-153.5 153.5t-211 56.5zM800 700h-300v-200h300v-100h-300l-100 100v200l100 100h300v-100z" />
|
||||
<glyph unicode="" d="M600 1191q120 0 229.5 -47t188.5 -126t126 -188.5t47 -229.5t-47 -229.5t-126 -188.5t-188.5 -126t-229.5 -47t-229.5 47t-188.5 126t-126 188.5t-47 229.5t47 229.5t126 188.5t188.5 126t229.5 47zM600 1021q-114 0 -211 -56.5t-153.5 -153.5t-56.5 -211t56.5 -211 t153.5 -153.5t211 -56.5t211 56.5t153.5 153.5t56.5 211t-56.5 211t-153.5 153.5t-211 56.5zM800 700v-100l-50 -50l100 -100v-50h-100l-100 100h-150v-100h-100v400h300zM500 700v-100h200v100h-200z" />
|
||||
<glyph unicode="" d="M503 1089q110 0 200.5 -59.5t134.5 -156.5q44 14 90 14q120 0 205 -86.5t85 -207t-85 -207t-205 -86.5h-128v250q0 21 -14.5 35.5t-35.5 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-250h-222q-80 0 -136 57.5t-56 136.5q0 69 43 122.5t108 67.5q-2 19 -2 37q0 100 49 185 t134 134t185 49zM525 500h150q10 0 17.5 -7.5t7.5 -17.5v-275h137q21 0 26 -11.5t-8 -27.5l-223 -244q-13 -16 -32 -16t-32 16l-223 244q-13 16 -8 27.5t26 11.5h137v275q0 10 7.5 17.5t17.5 7.5z" />
|
||||
<glyph unicode="" d="M502 1089q110 0 201 -59.5t135 -156.5q43 15 89 15q121 0 206 -86.5t86 -206.5q0 -99 -60 -181t-150 -110l-378 360q-13 16 -31.5 16t-31.5 -16l-381 -365h-9q-79 0 -135.5 57.5t-56.5 136.5q0 69 43 122.5t108 67.5q-2 19 -2 38q0 100 49 184.5t133.5 134t184.5 49.5z M632 467l223 -228q13 -16 8 -27.5t-26 -11.5h-137v-275q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v275h-137q-21 0 -26 11.5t8 27.5q199 204 223 228q19 19 31.5 19t32.5 -19z" />
|
||||
<glyph unicode="" d="M700 100v100h400l-270 300h170l-270 300h170l-300 333l-300 -333h170l-270 -300h170l-270 -300h400v-100h-50q-21 0 -35.5 -14.5t-14.5 -35.5v-50h400v50q0 21 -14.5 35.5t-35.5 14.5h-50z" />
|
||||
<glyph unicode="" d="M600 1179q94 0 167.5 -56.5t99.5 -145.5q89 -6 150.5 -71.5t61.5 -155.5q0 -61 -29.5 -112.5t-79.5 -82.5q9 -29 9 -55q0 -74 -52.5 -126.5t-126.5 -52.5q-55 0 -100 30v-251q21 0 35.5 -14.5t14.5 -35.5v-50h-300v50q0 21 14.5 35.5t35.5 14.5v251q-45 -30 -100 -30 q-74 0 -126.5 52.5t-52.5 126.5q0 18 4 38q-47 21 -75.5 65t-28.5 97q0 74 52.5 126.5t126.5 52.5q5 0 23 -2q0 2 -1 10t-1 13q0 116 81.5 197.5t197.5 81.5z" />
|
||||
<glyph unicode="" d="M1010 1010q111 -111 150.5 -260.5t0 -299t-150.5 -260.5q-83 -83 -191.5 -126.5t-218.5 -43.5t-218.5 43.5t-191.5 126.5q-111 111 -150.5 260.5t0 299t150.5 260.5q83 83 191.5 126.5t218.5 43.5t218.5 -43.5t191.5 -126.5zM476 1065q-4 0 -8 -1q-121 -34 -209.5 -122.5 t-122.5 -209.5q-4 -12 2.5 -23t18.5 -14l36 -9q3 -1 7 -1q23 0 29 22q27 96 98 166q70 71 166 98q11 3 17.5 13.5t3.5 22.5l-9 35q-3 13 -14 19q-7 4 -15 4zM512 920q-4 0 -9 -2q-80 -24 -138.5 -82.5t-82.5 -138.5q-4 -13 2 -24t19 -14l34 -9q4 -1 8 -1q22 0 28 21 q18 58 58.5 98.5t97.5 58.5q12 3 18 13.5t3 21.5l-9 35q-3 12 -14 19q-7 4 -15 4zM719.5 719.5q-49.5 49.5 -119.5 49.5t-119.5 -49.5t-49.5 -119.5t49.5 -119.5t119.5 -49.5t119.5 49.5t49.5 119.5t-49.5 119.5zM855 551q-22 0 -28 -21q-18 -58 -58.5 -98.5t-98.5 -57.5 q-11 -4 -17 -14.5t-3 -21.5l9 -35q3 -12 14 -19q7 -4 15 -4q4 0 9 2q80 24 138.5 82.5t82.5 138.5q4 13 -2.5 24t-18.5 14l-34 9q-4 1 -8 1zM1000 515q-23 0 -29 -22q-27 -96 -98 -166q-70 -71 -166 -98q-11 -3 -17.5 -13.5t-3.5 -22.5l9 -35q3 -13 14 -19q7 -4 15 -4 q4 0 8 1q121 34 209.5 122.5t122.5 209.5q4 12 -2.5 23t-18.5 14l-36 9q-3 1 -7 1z" />
|
||||
<glyph unicode="" d="M700 800h300v-380h-180v200h-340v-200h-380v755q0 10 7.5 17.5t17.5 7.5h575v-400zM1000 900h-200v200zM700 300h162l-212 -212l-212 212h162v200h100v-200zM520 0h-395q-10 0 -17.5 7.5t-7.5 17.5v395zM1000 220v-195q0 -10 -7.5 -17.5t-17.5 -7.5h-195z" />
|
||||
<glyph unicode="" d="M700 800h300v-520l-350 350l-550 -550v1095q0 10 7.5 17.5t17.5 7.5h575v-400zM1000 900h-200v200zM862 200h-162v-200h-100v200h-162l212 212zM480 0h-355q-10 0 -17.5 7.5t-7.5 17.5v55h380v-80zM1000 80v-55q0 -10 -7.5 -17.5t-17.5 -7.5h-155v80h180z" />
|
||||
<glyph unicode="" d="M1162 800h-162v-200h100l100 -100h-300v300h-162l212 212zM200 800h200q27 0 40 -2t29.5 -10.5t23.5 -30t7 -57.5h300v-100h-600l-200 -350v450h100q0 36 7 57.5t23.5 30t29.5 10.5t40 2zM800 400h240l-240 -400h-800l300 500h500v-100z" />
|
||||
<glyph unicode="" d="M650 1100h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5zM1000 850v150q41 0 70.5 -29.5t29.5 -70.5v-800 q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-1 0 -20 4l246 246l-326 326v324q0 41 29.5 70.5t70.5 29.5v-150q0 -62 44 -106t106 -44h300q62 0 106 44t44 106zM412 250l-212 -212v162h-200v100h200v162z" />
|
||||
<glyph unicode="" d="M450 1100h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5zM800 850v150q41 0 70.5 -29.5t29.5 -70.5v-500 h-200v-300h200q0 -36 -7 -57.5t-23.5 -30t-29.5 -10.5t-40 -2h-600q-41 0 -70.5 29.5t-29.5 70.5v800q0 41 29.5 70.5t70.5 29.5v-150q0 -62 44 -106t106 -44h300q62 0 106 44t44 106zM1212 250l-212 -212v162h-200v100h200v162z" />
|
||||
<glyph unicode="" d="M658 1197l637 -1104q23 -38 7 -65.5t-60 -27.5h-1276q-44 0 -60 27.5t7 65.5l637 1104q22 39 54 39t54 -39zM704 800h-208q-20 0 -32 -14.5t-8 -34.5l58 -302q4 -20 21.5 -34.5t37.5 -14.5h54q20 0 37.5 14.5t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5zM500 300v-100h200 v100h-200z" />
|
||||
<glyph unicode="" d="M425 1100h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM425 800h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5 t17.5 7.5zM825 800h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM25 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150 q0 10 7.5 17.5t17.5 7.5zM425 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM825 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5 v150q0 10 7.5 17.5t17.5 7.5zM25 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM425 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5 t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM825 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
|
||||
<glyph unicode="" d="M700 1200h100v-200h-100v-100h350q62 0 86.5 -39.5t-3.5 -94.5l-66 -132q-41 -83 -81 -134h-772q-40 51 -81 134l-66 132q-28 55 -3.5 94.5t86.5 39.5h350v100h-100v200h100v100h200v-100zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-12l137 -100 h-950l138 100h-13q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M600 1300q40 0 68.5 -29.5t28.5 -70.5h-194q0 41 28.5 70.5t68.5 29.5zM443 1100h314q18 -37 18 -75q0 -8 -3 -25h328q41 0 44.5 -16.5t-30.5 -38.5l-175 -145h-678l-178 145q-34 22 -29 38.5t46 16.5h328q-3 17 -3 25q0 38 18 75zM250 700h700q21 0 35.5 -14.5 t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-150v-200l275 -200h-950l275 200v200h-150q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M600 1181q75 0 128 -53t53 -128t-53 -128t-128 -53t-128 53t-53 128t53 128t128 53zM602 798h46q34 0 55.5 -28.5t21.5 -86.5q0 -76 39 -183h-324q39 107 39 183q0 58 21.5 86.5t56.5 28.5h45zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13 l138 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M600 1300q47 0 92.5 -53.5t71 -123t25.5 -123.5q0 -78 -55.5 -133.5t-133.5 -55.5t-133.5 55.5t-55.5 133.5q0 62 34 143l144 -143l111 111l-163 163q34 26 63 26zM602 798h46q34 0 55.5 -28.5t21.5 -86.5q0 -76 39 -183h-324q39 107 39 183q0 58 21.5 86.5t56.5 28.5h45 zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13l138 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M600 1200l300 -161v-139h-300q0 -57 18.5 -108t50 -91.5t63 -72t70 -67.5t57.5 -61h-530q-60 83 -90.5 177.5t-30.5 178.5t33 164.5t87.5 139.5t126 96.5t145.5 41.5v-98zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13l138 -100h-950l137 100 h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M600 1300q41 0 70.5 -29.5t29.5 -70.5v-78q46 -26 73 -72t27 -100v-50h-400v50q0 54 27 100t73 72v78q0 41 29.5 70.5t70.5 29.5zM400 800h400q54 0 100 -27t72 -73h-172v-100h200v-100h-200v-100h200v-100h-200v-100h200q0 -83 -58.5 -141.5t-141.5 -58.5h-400 q-83 0 -141.5 58.5t-58.5 141.5v400q0 83 58.5 141.5t141.5 58.5z" />
|
||||
<glyph unicode="" d="M150 1100h900q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5zM125 400h950q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-283l224 -224q13 -13 13 -31.5t-13 -32 t-31.5 -13.5t-31.5 13l-88 88h-524l-87 -88q-13 -13 -32 -13t-32 13.5t-13 32t13 31.5l224 224h-289q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM541 300l-100 -100h324l-100 100h-124z" />
|
||||
<glyph unicode="" d="M200 1100h800q83 0 141.5 -58.5t58.5 -141.5v-200h-100q0 41 -29.5 70.5t-70.5 29.5h-250q-41 0 -70.5 -29.5t-29.5 -70.5h-100q0 41 -29.5 70.5t-70.5 29.5h-250q-41 0 -70.5 -29.5t-29.5 -70.5h-100v200q0 83 58.5 141.5t141.5 58.5zM100 600h1000q41 0 70.5 -29.5 t29.5 -70.5v-300h-1200v300q0 41 29.5 70.5t70.5 29.5zM300 100v-50q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v50h200zM1100 100v-50q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v50h200z" />
|
||||
<glyph unicode="" d="M480 1165l682 -683q31 -31 31 -75.5t-31 -75.5l-131 -131h-481l-517 518q-32 31 -32 75.5t32 75.5l295 296q31 31 75.5 31t76.5 -31zM108 794l342 -342l303 304l-341 341zM250 100h800q21 0 35.5 -14.5t14.5 -35.5v-50h-900v50q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M1057 647l-189 506q-8 19 -27.5 33t-40.5 14h-400q-21 0 -40.5 -14t-27.5 -33l-189 -506q-8 -19 1.5 -33t30.5 -14h625v-150q0 -21 14.5 -35.5t35.5 -14.5t35.5 14.5t14.5 35.5v150h125q21 0 30.5 14t1.5 33zM897 0h-595v50q0 21 14.5 35.5t35.5 14.5h50v50 q0 21 14.5 35.5t35.5 14.5h48v300h200v-300h47q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-50z" />
|
||||
<glyph unicode="" d="M900 800h300v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-375v591l-300 300v84q0 10 7.5 17.5t17.5 7.5h375v-400zM1200 900h-200v200zM400 600h300v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-650q-10 0 -17.5 7.5t-7.5 17.5v950q0 10 7.5 17.5t17.5 7.5h375v-400zM700 700h-200v200z " />
|
||||
<glyph unicode="" d="M484 1095h195q75 0 146 -32.5t124 -86t89.5 -122.5t48.5 -142q18 -14 35 -20q31 -10 64.5 6.5t43.5 48.5q10 34 -15 71q-19 27 -9 43q5 8 12.5 11t19 -1t23.5 -16q41 -44 39 -105q-3 -63 -46 -106.5t-104 -43.5h-62q-7 -55 -35 -117t-56 -100l-39 -234q-3 -20 -20 -34.5 t-38 -14.5h-100q-21 0 -33 14.5t-9 34.5l12 70q-49 -14 -91 -14h-195q-24 0 -65 8l-11 -64q-3 -20 -20 -34.5t-38 -14.5h-100q-21 0 -33 14.5t-9 34.5l26 157q-84 74 -128 175l-159 53q-19 7 -33 26t-14 40v50q0 21 14.5 35.5t35.5 14.5h124q11 87 56 166l-111 95 q-16 14 -12.5 23.5t24.5 9.5h203q116 101 250 101zM675 1000h-250q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h250q10 0 17.5 7.5t7.5 17.5v50q0 10 -7.5 17.5t-17.5 7.5z" />
|
||||
<glyph unicode="" d="M641 900l423 247q19 8 42 2.5t37 -21.5l32 -38q14 -15 12.5 -36t-17.5 -34l-139 -120h-390zM50 1100h106q67 0 103 -17t66 -71l102 -212h823q21 0 35.5 -14.5t14.5 -35.5v-50q0 -21 -14 -40t-33 -26l-737 -132q-23 -4 -40 6t-26 25q-42 67 -100 67h-300q-62 0 -106 44 t-44 106v200q0 62 44 106t106 44zM173 928h-80q-19 0 -28 -14t-9 -35v-56q0 -51 42 -51h134q16 0 21.5 8t5.5 24q0 11 -16 45t-27 51q-18 28 -43 28zM550 727q-32 0 -54.5 -22.5t-22.5 -54.5t22.5 -54.5t54.5 -22.5t54.5 22.5t22.5 54.5t-22.5 54.5t-54.5 22.5zM130 389 l152 130q18 19 34 24t31 -3.5t24.5 -17.5t25.5 -28q28 -35 50.5 -51t48.5 -13l63 5l48 -179q13 -61 -3.5 -97.5t-67.5 -79.5l-80 -69q-47 -40 -109 -35.5t-103 51.5l-130 151q-40 47 -35.5 109.5t51.5 102.5zM380 377l-102 -88q-31 -27 2 -65l37 -43q13 -15 27.5 -19.5 t31.5 6.5l61 53q19 16 14 49q-2 20 -12 56t-17 45q-11 12 -19 14t-23 -8z" />
|
||||
<glyph unicode="" d="M625 1200h150q10 0 17.5 -7.5t7.5 -17.5v-109q79 -33 131 -87.5t53 -128.5q1 -46 -15 -84.5t-39 -61t-46 -38t-39 -21.5l-17 -6q6 0 15 -1.5t35 -9t50 -17.5t53 -30t50 -45t35.5 -64t14.5 -84q0 -59 -11.5 -105.5t-28.5 -76.5t-44 -51t-49.5 -31.5t-54.5 -16t-49.5 -6.5 t-43.5 -1v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-100v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-175q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h75v600h-75q-10 0 -17.5 7.5t-7.5 17.5v150 q0 10 7.5 17.5t17.5 7.5h175v75q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-75h100v75q0 10 7.5 17.5t17.5 7.5zM400 900v-200h263q28 0 48.5 10.5t30 25t15 29t5.5 25.5l1 10q0 4 -0.5 11t-6 24t-15 30t-30 24t-48.5 11h-263zM400 500v-200h363q28 0 48.5 10.5 t30 25t15 29t5.5 25.5l1 10q0 4 -0.5 11t-6 24t-15 30t-30 24t-48.5 11h-363z" />
|
||||
<glyph unicode="" d="M212 1198h780q86 0 147 -61t61 -147v-416q0 -51 -18 -142.5t-36 -157.5l-18 -66q-29 -87 -93.5 -146.5t-146.5 -59.5h-572q-82 0 -147 59t-93 147q-8 28 -20 73t-32 143.5t-20 149.5v416q0 86 61 147t147 61zM600 1045q-70 0 -132.5 -11.5t-105.5 -30.5t-78.5 -41.5 t-57 -45t-36 -41t-20.5 -30.5l-6 -12l156 -243h560l156 243q-2 5 -6 12.5t-20 29.5t-36.5 42t-57 44.5t-79 42t-105 29.5t-132.5 12zM762 703h-157l195 261z" />
|
||||
<glyph unicode="" d="M475 1300h150q103 0 189 -86t86 -189v-500q0 -41 -42 -83t-83 -42h-450q-41 0 -83 42t-42 83v500q0 103 86 189t189 86zM700 300v-225q0 -21 -27 -48t-48 -27h-150q-21 0 -48 27t-27 48v225h300z" />
|
||||
<glyph unicode="" d="M475 1300h96q0 -150 89.5 -239.5t239.5 -89.5v-446q0 -41 -42 -83t-83 -42h-450q-41 0 -83 42t-42 83v500q0 103 86 189t189 86zM700 300v-225q0 -21 -27 -48t-48 -27h-150q-21 0 -48 27t-27 48v225h300z" />
|
||||
<glyph unicode="" d="M1294 767l-638 -283l-378 170l-78 -60v-224l100 -150v-199l-150 148l-150 -149v200l100 150v250q0 4 -0.5 10.5t0 9.5t1 8t3 8t6.5 6l47 40l-147 65l642 283zM1000 380l-350 -166l-350 166v147l350 -165l350 165v-147z" />
|
||||
<glyph unicode="" d="M250 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM650 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM1050 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44z" />
|
||||
<glyph unicode="" d="M550 1100q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM550 700q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM550 300q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44z" />
|
||||
<glyph unicode="" d="M125 1100h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM125 700h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5 t17.5 7.5zM125 300h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
|
||||
<glyph unicode="" d="M350 1200h500q162 0 256 -93.5t94 -256.5v-500q0 -165 -93.5 -257.5t-256.5 -92.5h-500q-165 0 -257.5 92.5t-92.5 257.5v500q0 165 92.5 257.5t257.5 92.5zM900 1000h-600q-41 0 -70.5 -29.5t-29.5 -70.5v-600q0 -41 29.5 -70.5t70.5 -29.5h600q41 0 70.5 29.5 t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5zM350 900h500q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -14.5 -35.5t-35.5 -14.5h-500q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 14.5 35.5t35.5 14.5zM400 800v-200h400v200h-400z" />
|
||||
<glyph unicode="" d="M150 1100h1000q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5 t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M650 1187q87 -67 118.5 -156t0 -178t-118.5 -155q-87 66 -118.5 155t0 178t118.5 156zM300 800q124 0 212 -88t88 -212q-124 0 -212 88t-88 212zM1000 800q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM300 500q124 0 212 -88t88 -212q-124 0 -212 88t-88 212z M1000 500q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM700 199v-144q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v142q40 -4 43 -4q17 0 57 6z" />
|
||||
<glyph unicode="" d="M745 878l69 19q25 6 45 -12l298 -295q11 -11 15 -26.5t-2 -30.5q-5 -14 -18 -23.5t-28 -9.5h-8q1 0 1 -13q0 -29 -2 -56t-8.5 -62t-20 -63t-33 -53t-51 -39t-72.5 -14h-146q-184 0 -184 288q0 24 10 47q-20 4 -62 4t-63 -4q11 -24 11 -47q0 -288 -184 -288h-142 q-48 0 -84.5 21t-56 51t-32 71.5t-16 75t-3.5 68.5q0 13 2 13h-7q-15 0 -27.5 9.5t-18.5 23.5q-6 15 -2 30.5t15 25.5l298 296q20 18 46 11l76 -19q20 -5 30.5 -22.5t5.5 -37.5t-22.5 -31t-37.5 -5l-51 12l-182 -193h891l-182 193l-44 -12q-20 -5 -37.5 6t-22.5 31t6 37.5 t31 22.5z" />
|
||||
<glyph unicode="" d="M1200 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-850q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v850h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM500 450h-25q0 15 -4 24.5t-9 14.5t-17 7.5t-20 3t-25 0.5h-100v-425q0 -11 12.5 -17.5t25.5 -7.5h12v-50h-200v50q50 0 50 25v425h-100q-17 0 -25 -0.5t-20 -3t-17 -7.5t-9 -14.5t-4 -24.5h-25v150h500v-150z" />
|
||||
<glyph unicode="" d="M1000 300v50q-25 0 -55 32q-14 14 -25 31t-16 27l-4 11l-289 747h-69l-300 -754q-18 -35 -39 -56q-9 -9 -24.5 -18.5t-26.5 -14.5l-11 -5v-50h273v50q-49 0 -78.5 21.5t-11.5 67.5l69 176h293l61 -166q13 -34 -3.5 -66.5t-55.5 -32.5v-50h312zM412 691l134 342l121 -342 h-255zM1100 150v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5z" />
|
||||
<glyph unicode="" d="M50 1200h1100q21 0 35.5 -14.5t14.5 -35.5v-1100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v1100q0 21 14.5 35.5t35.5 14.5zM611 1118h-70q-13 0 -18 -12l-299 -753q-17 -32 -35 -51q-18 -18 -56 -34q-12 -5 -12 -18v-50q0 -8 5.5 -14t14.5 -6 h273q8 0 14 6t6 14v50q0 8 -6 14t-14 6q-55 0 -71 23q-10 14 0 39l63 163h266l57 -153q11 -31 -6 -55q-12 -17 -36 -17q-8 0 -14 -6t-6 -14v-50q0 -8 6 -14t14 -6h313q8 0 14 6t6 14v50q0 7 -5.5 13t-13.5 7q-17 0 -42 25q-25 27 -40 63h-1l-288 748q-5 12 -19 12zM639 611 h-197l103 264z" />
|
||||
<glyph unicode="" d="M1200 1100h-1200v100h1200v-100zM50 1000h400q21 0 35.5 -14.5t14.5 -35.5v-900q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v900q0 21 14.5 35.5t35.5 14.5zM650 1000h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM700 900v-300h300v300h-300z" />
|
||||
<glyph unicode="" d="M50 1200h400q21 0 35.5 -14.5t14.5 -35.5v-900q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v900q0 21 14.5 35.5t35.5 14.5zM650 700h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400 q0 21 14.5 35.5t35.5 14.5zM700 600v-300h300v300h-300zM1200 0h-1200v100h1200v-100z" />
|
||||
<glyph unicode="" d="M50 1000h400q21 0 35.5 -14.5t14.5 -35.5v-350h100v150q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-150h100v-100h-100v-150q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v150h-100v-350q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5zM700 700v-300h300v300h-300z" />
|
||||
<glyph unicode="" d="M100 0h-100v1200h100v-1200zM250 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM300 1000v-300h300v300h-300zM250 500h900q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M600 1100h150q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-150v-100h450q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5h350v100h-150q-21 0 -35.5 14.5 t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5h150v100h100v-100zM400 1000v-300h300v300h-300z" />
|
||||
<glyph unicode="" d="M1200 0h-100v1200h100v-1200zM550 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM600 1000v-300h300v300h-300zM50 500h900q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M865 565l-494 -494q-23 -23 -41 -23q-14 0 -22 13.5t-8 38.5v1000q0 25 8 38.5t22 13.5q18 0 41 -23l494 -494q14 -14 14 -35t-14 -35z" />
|
||||
<glyph unicode="" d="M335 635l494 494q29 29 50 20.5t21 -49.5v-1000q0 -41 -21 -49.5t-50 20.5l-494 494q-14 14 -14 35t14 35z" />
|
||||
<glyph unicode="" d="M100 900h1000q41 0 49.5 -21t-20.5 -50l-494 -494q-14 -14 -35 -14t-35 14l-494 494q-29 29 -20.5 50t49.5 21z" />
|
||||
<glyph unicode="" d="M635 865l494 -494q29 -29 20.5 -50t-49.5 -21h-1000q-41 0 -49.5 21t20.5 50l494 494q14 14 35 14t35 -14z" />
|
||||
<glyph unicode="" d="M700 741v-182l-692 -323v221l413 193l-413 193v221zM1200 0h-800v200h800v-200z" />
|
||||
<glyph unicode="" d="M1200 900h-200v-100h200v-100h-300v300h200v100h-200v100h300v-300zM0 700h50q0 21 4 37t9.5 26.5t18 17.5t22 11t28.5 5.5t31 2t37 0.5h100v-550q0 -22 -25 -34.5t-50 -13.5l-25 -2v-100h400v100q-4 0 -11 0.5t-24 3t-30 7t-24 15t-11 24.5v550h100q25 0 37 -0.5t31 -2 t28.5 -5.5t22 -11t18 -17.5t9.5 -26.5t4 -37h50v300h-800v-300z" />
|
||||
<glyph unicode="" d="M800 700h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-100v-550q0 -22 25 -34.5t50 -14.5l25 -1v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v550h-100q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h800v-300zM1100 200h-200v-100h200v-100h-300v300h200v100h-200v100h300v-300z" />
|
||||
<glyph unicode="" d="M701 1098h160q16 0 21 -11t-7 -23l-464 -464l464 -464q12 -12 7 -23t-21 -11h-160q-13 0 -23 9l-471 471q-7 8 -7 18t7 18l471 471q10 9 23 9z" />
|
||||
<glyph unicode="" d="M339 1098h160q13 0 23 -9l471 -471q7 -8 7 -18t-7 -18l-471 -471q-10 -9 -23 -9h-160q-16 0 -21 11t7 23l464 464l-464 464q-12 12 -7 23t21 11z" />
|
||||
<glyph unicode="" d="M1087 882q11 -5 11 -21v-160q0 -13 -9 -23l-471 -471q-8 -7 -18 -7t-18 7l-471 471q-9 10 -9 23v160q0 16 11 21t23 -7l464 -464l464 464q12 12 23 7z" />
|
||||
<glyph unicode="" d="M618 993l471 -471q9 -10 9 -23v-160q0 -16 -11 -21t-23 7l-464 464l-464 -464q-12 -12 -23 -7t-11 21v160q0 13 9 23l471 471q8 7 18 7t18 -7z" />
|
||||
<glyph unicode="" d="M1000 1200q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM450 1000h100q21 0 40 -14t26 -33l79 -194q5 1 16 3q34 6 54 9.5t60 7t65.5 1t61 -10t56.5 -23t42.5 -42t29 -64t5 -92t-19.5 -121.5q-1 -7 -3 -19.5t-11 -50t-20.5 -73t-32.5 -81.5t-46.5 -83t-64 -70 t-82.5 -50q-13 -5 -42 -5t-65.5 2.5t-47.5 2.5q-14 0 -49.5 -3.5t-63 -3.5t-43.5 7q-57 25 -104.5 78.5t-75 111.5t-46.5 112t-26 90l-7 35q-15 63 -18 115t4.5 88.5t26 64t39.5 43.5t52 25.5t58.5 13t62.5 2t59.5 -4.5t55.5 -8l-147 192q-12 18 -5.5 30t27.5 12z" />
|
||||
<glyph unicode="🔑" d="M250 1200h600q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-150v-500l-255 -178q-19 -9 -32 -1t-13 29v650h-150q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM400 1100v-100h300v100h-300z" />
|
||||
<glyph unicode="🚪" d="M250 1200h750q39 0 69.5 -40.5t30.5 -84.5v-933l-700 -117v950l600 125h-700v-1000h-100v1025q0 23 15.5 49t34.5 26zM500 525v-100l100 20v100z" />
|
||||
</font>
|
||||
</defs></svg>
|
After Width: | Height: | Size: 106 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
2377
src_diploma/flask_app/static/lib/bootstrap/js/bootstrap.js
vendored
Normal file
2377
src_diploma/flask_app/static/lib/bootstrap/js/bootstrap.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
7
src_diploma/flask_app/static/lib/bootstrap/js/bootstrap.min.js
vendored
Normal file
7
src_diploma/flask_app/static/lib/bootstrap/js/bootstrap.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
13
src_diploma/flask_app/static/lib/bootstrap/js/npm.js
Normal file
13
src_diploma/flask_app/static/lib/bootstrap/js/npm.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
// This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.
|
||||
require('../../js/transition.js')
|
||||
require('../../js/alert.js')
|
||||
require('../../js/button.js')
|
||||
require('../../js/carousel.js')
|
||||
require('../../js/collapse.js')
|
||||
require('../../js/dropdown.js')
|
||||
require('../../js/modal.js')
|
||||
require('../../js/tooltip.js')
|
||||
require('../../js/popover.js')
|
||||
require('../../js/scrollspy.js')
|
||||
require('../../js/tab.js')
|
||||
require('../../js/affix.js')
|
2
src_diploma/flask_app/static/lib/jquery.min.js
vendored
Normal file
2
src_diploma/flask_app/static/lib/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
306
src_diploma/flask_app/static/script.js
Normal file
306
src_diploma/flask_app/static/script.js
Normal file
|
@ -0,0 +1,306 @@
|
|||
var hover_emph = [];
|
||||
var highlight_lock = false;
|
||||
var last_sense_group = "";
|
||||
|
||||
$(document).ready(function() {
|
||||
$.get("/letters", function(data, status) {
|
||||
$("#letters").html(data);
|
||||
});
|
||||
|
||||
$.get("/reduce_functions", function(data, status) {
|
||||
$("#reduce-functions").html(data);
|
||||
$("#reduce-functions input[type=radio]").change(function() {
|
||||
get_frames(
|
||||
$("#chosen-one").text()
|
||||
);
|
||||
})
|
||||
//Click on the first radio button - for 100% up to date with the model.
|
||||
var first_radio = $("#reduce-functions input[type=radio]:first");
|
||||
first_radio.attr("checked", true)
|
||||
get_frames($("#chosen-one").text());
|
||||
});
|
||||
handle_resizing();
|
||||
})
|
||||
|
||||
window.onresize = handle_resizing;
|
||||
|
||||
function view_get_rf() {
|
||||
return $("#reduce-functions").find("input:checked").val();
|
||||
}
|
||||
|
||||
function get_words(letter) {
|
||||
$.get("/words/" + letter, function(data, status){
|
||||
$("#words").html(data);
|
||||
})
|
||||
}
|
||||
|
||||
function get_frames(word, reduce_function=null, modify_view=true, callback=null) {
|
||||
if (word == "") {
|
||||
return
|
||||
}
|
||||
if (reduce_function == null) {
|
||||
reduce_function = view_get_rf();
|
||||
}
|
||||
$("#chosen-one").text(word);
|
||||
var opt_rf = "";
|
||||
if (reduce_function != null) {
|
||||
opt_rf = "&rf=" + reduce_function;
|
||||
}
|
||||
$.get("/frames?hw=" + word + opt_rf, function(data, status) {
|
||||
$("#frames-area").html(data);
|
||||
$("#n-frames").text("število stavčnih vzorcev: " + $(".frame-div").length);
|
||||
|
||||
// Add functor highlighting
|
||||
$(".functor-link")
|
||||
.mouseover(function() {
|
||||
highlight_linked($(this))
|
||||
})
|
||||
.mouseout(unhighlight_linked)
|
||||
.click(function() {
|
||||
toggle_highlight_lock($(this))
|
||||
});
|
||||
// modify sense information div
|
||||
if (modify_view) {
|
||||
$("#word-info-right").html("");
|
||||
$(".frame-sense-id").hide();
|
||||
$(".frame-sense-id").find("input").prop("disabled", true);
|
||||
$(".frame-sense-desc").hide();
|
||||
//$(".frame-sense-desc").find("input").prop("disabled", true);
|
||||
switch (reduce_function) {
|
||||
case "reduce_0":
|
||||
case "reduce_1":
|
||||
break;
|
||||
case "reduce_3":
|
||||
//ssj
|
||||
$(".frame-sense-id").show();
|
||||
$(".frame-sense-desc").show();
|
||||
break;
|
||||
case "reduce_4":
|
||||
//kmeans
|
||||
$(".frame-sense-id").show();
|
||||
break;
|
||||
case "reduce_5":
|
||||
//user
|
||||
user_input_menu(false);
|
||||
$(".frame-sense-id").show();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (callback != null) {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function handle_resizing() {
|
||||
$("#words").height( ($(document).height() - $("#words").position().top) * 0.95 );
|
||||
}
|
||||
|
||||
function highlight_linked(dom_element) {
|
||||
if (highlight_lock) {
|
||||
return;
|
||||
}
|
||||
var frame_div = dom_element.parents(".frame-div");
|
||||
var frame_table = frame_div.find(".frame-table");
|
||||
var frame_sentences = frame_div.find(".frame-sentences");
|
||||
var classes = dom_element.attr("class").split(" ");
|
||||
classes.forEach(function(cls) {
|
||||
if (cls == "functor-link") {
|
||||
return
|
||||
}
|
||||
cls = cls.replace(".", "\\."); //escaping dots!
|
||||
var frame_table_matches = frame_table.find("." + cls);
|
||||
var frame_sentences_matches = frame_sentences.find("." + cls);
|
||||
if (frame_table_matches.length > 0 && frame_sentences_matches.length > 0) {
|
||||
var matches = $.merge(frame_table_matches, frame_sentences_matches);
|
||||
matches.addClass("functor-highlight");
|
||||
hover_emph.push(matches);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function unhighlight_linked() {
|
||||
if (highlight_lock) {
|
||||
return;
|
||||
}
|
||||
hover_emph.forEach(function(el) {
|
||||
el.removeClass("functor-highlight");
|
||||
})
|
||||
hover_emph = [];
|
||||
}
|
||||
|
||||
function toggle_highlight_lock(dom_element) {
|
||||
if (
|
||||
hover_emph.len == 0 ||
|
||||
!dom_element.hasClass("functor-highlight")
|
||||
) {
|
||||
return;
|
||||
}
|
||||
highlight_lock = !highlight_lock;
|
||||
}
|
||||
|
||||
function helper_highlight_ssj_id(pdiv, ssj_ids) {
|
||||
hover_emph = []
|
||||
for (var i=0; i<ssj_ids.length; i++) {
|
||||
ssj_id = ssj_ids[i];
|
||||
ssj_id = ssj_id.replace(".", "\\.");
|
||||
ssj_id = "." + ssj_id;
|
||||
matches = pdiv.find(ssj_id).toArray();
|
||||
if (matches.length > 1) {
|
||||
hover_emph = matches;
|
||||
break;
|
||||
}
|
||||
}
|
||||
hover_emph.forEach(function(element) {
|
||||
$(element).css("color", "red");
|
||||
});
|
||||
}
|
||||
|
||||
function helper_clear_highlight_ssj_id() {
|
||||
hover_emph.forEach(function(element) {
|
||||
$(element).css("color", "");
|
||||
});
|
||||
hover_emph = []
|
||||
}
|
||||
|
||||
function toggle_frame_sentences(el, sign=null) {
|
||||
pdiv = el.parents(".frame-div");
|
||||
fs = pdiv.find(".frame-sentences");
|
||||
sign_element = pdiv.find(".sign-element");
|
||||
if ((sign == "+") || (sign_element.text() == "[+]")) {
|
||||
sign_element.text("[-]");
|
||||
fs.show();
|
||||
} else {
|
||||
sign_element.text("[+]");
|
||||
fs.hide();
|
||||
}
|
||||
}
|
||||
|
||||
function user_input_menu(new_entries) {
|
||||
if (new_entries) {
|
||||
var tmp_sense_group = $("#word-info-right").find("option:selected").text();
|
||||
if (tmp_sense_group != "-- izberi --") {
|
||||
last_sense_group = tmp_sense_group;
|
||||
}
|
||||
$("#word-info-right").html(
|
||||
"<input type=text name='sense_group' \
|
||||
placeholder='ime skupine pomenov' value='" + last_sense_group + "'></input>"
|
||||
);
|
||||
$("#word-info-right").append(
|
||||
"<button onclick='user_input_finish(false)'>prekliči</button>"
|
||||
)
|
||||
$("#word-info-right").append(
|
||||
"<input name='sense_passwd' \
|
||||
type=password placeholder='geslo' value='" + getCookie("sense_passwd") + "'></input>"
|
||||
)
|
||||
$("#word-info-right").append(
|
||||
"<button onclick='user_input_finish(true)'>shrani</button>"
|
||||
)
|
||||
get_frames($("#chosen-one").text(), "reduce_0", false, function() {
|
||||
$(".frame-sense-id").find("input")
|
||||
.prop("disabled", false)
|
||||
.val("");
|
||||
$(".frame-sense-id").show();
|
||||
//$(".frame-sense-desc").find("input").prop("disabled", true);
|
||||
$(".frame-sense-desc").hide();
|
||||
toggle_frame_sentences($(".frame-sense"), "+");
|
||||
//fill input fields with known sense_ids
|
||||
$.get("/get_sense_ids?collname=user_senses&hw=" +
|
||||
$("#chosen-one").text() +
|
||||
"&sg=" + last_sense_group, function(data, status) {
|
||||
data = JSON.parse(data);
|
||||
$(".frame-div").each(function(idx, el) {
|
||||
var jqel = $(el);
|
||||
var ssj_id = jqel.find(".frame-hw-id").text();
|
||||
if (ssj_id in data) {
|
||||
jqel.find("input[name='sense_id']").val(data[ssj_id]);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
$.get("/user_sense_groups/" + $("#chosen-one").text(), function(data, status){
|
||||
$("#word-info-right").html(data);
|
||||
$("#word-info-right").append(
|
||||
"<button onclick='user_input_menu(true)'>novi pomeni</button>"
|
||||
)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function user_input_finish(save) {
|
||||
if (save) {
|
||||
var sense_group = $("input[name='sense_group']").val().applyXSSprotection();
|
||||
var sense_passwd = $("input[name='sense_passwd']").val().applyXSSprotection();
|
||||
setCookie("sense_passwd", sense_passwd, 1);
|
||||
last_sense_group = sense_group;
|
||||
if (sense_group == "") {
|
||||
user_input_finish(false);
|
||||
return;
|
||||
}
|
||||
sense_data = {
|
||||
"headword": $("#chosen-one").text(),
|
||||
"sense_group": sense_group,
|
||||
"sense_passwd": sense_passwd,
|
||||
"entries": {},
|
||||
}
|
||||
$(".frame-div").each(function(index){
|
||||
var sense_id = $(this).find("input[name='sense_id']").val().applyXSSprotection();
|
||||
if (sense_id === "None") {
|
||||
return;
|
||||
}
|
||||
var frame_data = {};
|
||||
ssj_id = $(this).find(".frame-hw-id").text();
|
||||
sense_data["entries"][ssj_id] = sense_id;
|
||||
});
|
||||
if (Object.keys(sense_data["entries"]).length > 0) {
|
||||
$.ajax({
|
||||
method: "POST",
|
||||
url: "/user_senses",
|
||||
data: JSON.stringify(sense_data),
|
||||
async: false,
|
||||
complete: function() {
|
||||
pick_sense_group(sense_group);
|
||||
}
|
||||
});
|
||||
}
|
||||
//pick_sense_group(sense_group);
|
||||
}
|
||||
user_input_menu(false);
|
||||
get_frames($("#chosen-one").text());
|
||||
}
|
||||
|
||||
function pick_sense_group(sense_group, gf=false) {
|
||||
last_sense_group = sense_group;
|
||||
$.get("/pick_sense_group/" + sense_group, function(){
|
||||
if (gf) {
|
||||
get_frames($("#chosen-one").text());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
String.prototype.applyXSSprotection = function(){
|
||||
return this.replace(/</g, "<").replace(/>/g, ">");
|
||||
};
|
||||
|
||||
function setCookie(cname, cvalue, exdays) {
|
||||
var d = new Date();
|
||||
d.setTime(d.getTime() + (exdays*24*60*60*1000));
|
||||
var expires = "expires="+ d.toUTCString();
|
||||
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
|
||||
}
|
||||
|
||||
function getCookie(cname) {
|
||||
var name = cname + "=";
|
||||
var ca = document.cookie.split(';');
|
||||
for(var i = 0; i < ca.length; i++) {
|
||||
var c = ca[i];
|
||||
while (c.charAt(0) == ' ') {
|
||||
c = c.substring(1);
|
||||
}
|
||||
if (c.indexOf(name) == 0) {
|
||||
return c.substring(name.length, c.length);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
205
src_diploma/flask_app/static/style.css
Normal file
205
src_diploma/flask_app/static/style.css
Normal file
|
@ -0,0 +1,205 @@
|
|||
html {
|
||||
height: 95%;
|
||||
}
|
||||
|
||||
body {
|
||||
height: 95%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
/* font-family: "Arial", Helvetica, sans-serif; */
|
||||
background-color: var(--color-1);
|
||||
}
|
||||
|
||||
div {
|
||||
border: 0.0px solid gray;
|
||||
}
|
||||
|
||||
#letters a, #words a, .frame-sentences-wrapper a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#letters a:hover, #words a:hover {
|
||||
color: var(--color-1);
|
||||
}
|
||||
|
||||
.monospace {
|
||||
font-family: "Lucida Console", Monaco, monospace
|
||||
}
|
||||
|
||||
#header h2 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#letters {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-evenly;
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
background-color: var(--color-3);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
#letters span {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
#words {
|
||||
width: 200px;
|
||||
overflow-y: scroll;
|
||||
background-color: var(--color-3);
|
||||
border-radius: 5px;
|
||||
margin: 5px;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
#main-body {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
#main-content {
|
||||
flex-grow: 1;
|
||||
margin: 5px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#reduce-functions {
|
||||
background-color: var(--color-3);
|
||||
padding: 5px;
|
||||
margin-bottom: 5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
#reduce-functions * {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#word-info {
|
||||
background-color: var(--color-4);
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
margin-top: 5px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
#word-info-left {
|
||||
display: inline-block;
|
||||
float: left;
|
||||
margin-right: 50px;
|
||||
}
|
||||
|
||||
#word-info-right {
|
||||
display: inline-block;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#frames-area {
|
||||
flex-grow: 1;
|
||||
background-color: var(--color-2);
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
#words {
|
||||
width: 200px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.frame-sense {
|
||||
display: inline;
|
||||
float: left;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.frame-table {
|
||||
display: inline;
|
||||
float: left;
|
||||
border-collapse: collapse;
|
||||
border: 1px solid;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.frame-table td, th {
|
||||
border-left: 1px solid;
|
||||
border-right: 1px solid;
|
||||
padding: 2px;
|
||||
min-width: 50px;
|
||||
max-width: 100px;
|
||||
max-height: 200px;
|
||||
}
|
||||
|
||||
.frame-sentences-wrapper {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.frame-sentences td {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
/* Hide some data*/
|
||||
/*
|
||||
.frame-table tr:nth-child(2) {
|
||||
display: none;
|
||||
}
|
||||
.frame-table tr:nth-child(3) {
|
||||
display: none;
|
||||
}
|
||||
*/
|
||||
|
||||
.token-div {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.token-div td:nth-child(1) {
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
.hw-highlight {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
.functor-highlight {
|
||||
color: red;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* CSS - Cascading Style Sheet */
|
||||
/* Palette color codes */
|
||||
/* Palette URL: http://paletton.com/#uid=13D0u0k7UUa3cZA5wXlaiQ5cFL3 */
|
||||
|
||||
/* Feel free to copy&paste color codes to your application */
|
||||
|
||||
|
||||
/* As hex codes */
|
||||
|
||||
|
||||
|
||||
|
||||
/* As RGBa codes */
|
||||
|
||||
.rgba-primary-0 { color: rgba(183,206,236,1) } /* Main Primary color */
|
||||
.rgba-primary-1 { color: rgba(228,238,251,1) }
|
||||
.rgba-primary-2 { color: rgba(206,223,245,1) }
|
||||
.rgba-primary-3 { color: rgba(159,188,225,1) }
|
||||
.rgba-primary-4 { color: rgba(135,168,211,1) }
|
||||
|
||||
|
||||
|
||||
/* Generated by Paletton.com © 2002-2014 */
|
||||
/* http://paletton.com */
|
||||
|
||||
:root {
|
||||
--color-0: #B7CEEC;
|
||||
--color-1: #E4EEFB;
|
||||
--color-2: #CEDFF5;
|
||||
--color-3: #9FBCE1;
|
||||
--color-4: #87A8D3;
|
||||
}
|
64
src_diploma/flask_app/templates/frames.html
Normal file
64
src_diploma/flask_app/templates/frames.html
Normal file
|
@ -0,0 +1,64 @@
|
|||
{% for frame in frames %}
|
||||
<div class="frame-div">
|
||||
<div hidden class="frame-hw-id">{{ frame.tids[0] }}</div>
|
||||
<div class="frame-table-wrapper">
|
||||
<table class="frame-table">
|
||||
<tr>
|
||||
{% for slot in frame.slots %}
|
||||
<td><span class="functor-link {{ slot.tids|join(' ') }}">{{ slot.functor }}</span></td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
<tr>
|
||||
{% for slot in frame.slots %}
|
||||
<td title="št. pojavitev/št. povedi">{{ slot.tids|length }}/{{ frame.tids|length }}</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table class="frame-sense">
|
||||
<tr class="frame-sense-id">
|
||||
<td>ID pomena: </td>
|
||||
<td>
|
||||
<input type="text" name="sense_id" value="{{ frame.sense_info.get('sense_id') }}">
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="frame-sense-desc">
|
||||
<td>Opis pomena: </td>
|
||||
<td>
|
||||
<!--input type="text" name="sense_desc" value="{{ frame.sense_info.get('sense_desc') }}"-->
|
||||
<ul>
|
||||
{% set desc_arr = frame.sense_info.get('sense_desc') %}
|
||||
{% if desc_arr is not none %}
|
||||
{% for desc in desc_arr %}
|
||||
<li>{{ desc }}</li>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="frame-sentences-wrapper">
|
||||
<p><a class="monospace sign-element" href="javascript:void(0)" onClick="toggle_frame_sentences($(this))">[+]</a> št. stavkov: {{ frame.tids|length }}</p>
|
||||
<div hidden class="frame-sentences">
|
||||
<table>
|
||||
{% for sentence in frame.sentences %}
|
||||
<tr><td>
|
||||
{% for token in sentence %}
|
||||
{% if token[1]["word"] != None %}
|
||||
{% set hwclass = "" %}
|
||||
{% if token[0] in frame.tids %}
|
||||
{% set hwclass = " hw-highlight" %}
|
||||
{% endif %}
|
||||
<span class="functor-link {{ token[0] }}{{ hwclass }}">{{ token[1]["word"] }} </span>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</td></tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
<hr />
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
40
src_diploma/flask_app/templates/frames_old.html
Normal file
40
src_diploma/flask_app/templates/frames_old.html
Normal file
|
@ -0,0 +1,40 @@
|
|||
{% for frame in frames %}
|
||||
<div class="frame-div">
|
||||
<p>[{% for tid in frame.tids %}
|
||||
<a href="javascript:void(0)" onClick="get_token_info('{{ tid }}', this)">{{ tid }}</a>
|
||||
{% if not loop.last %}
|
||||
,
|
||||
{% endif %}
|
||||
{% endfor %}]</p>
|
||||
|
||||
<table class="frame-table">
|
||||
<tr>
|
||||
{% for slot in frame.slots %}
|
||||
<td class="{{ slot.tids|join(" ") }}">{{ slot.functor }}</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
<tr>
|
||||
{% for slot in frame.slots %}
|
||||
<td>{% for sh in slot.shallows %}
|
||||
{{ sh }}
|
||||
{% if not loop.last %}
|
||||
,
|
||||
{% endif %}
|
||||
{% endfor %}</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
<tr>
|
||||
{% for slot in frame.slots %}
|
||||
<td>{% for tid in slot.tids %}
|
||||
<a href="javascript:void(0)" onClick="get_token_info('{{ tid }}', this)">{{ tid }}</a>
|
||||
{% if not loop.last %}
|
||||
,
|
||||
{% endif %}
|
||||
{% endfor %}</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</table>
|
||||
<div class="token-div"></div>
|
||||
<hr />
|
||||
</div>
|
||||
{% endfor %}
|
37
src_diploma/flask_app/templates/index.html
Normal file
37
src_diploma/flask_app/templates/index.html
Normal file
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<meta charset="utf-8">
|
||||
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='./lib/bootstrap/css/bootstrap.min.css') }}">
|
||||
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='style.css') }}">
|
||||
<head>
|
||||
<title>Leksikon</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id=header>
|
||||
<h2>Leksikon vezljivosti slovenskih glagolov</h2>
|
||||
<div id=letters></div>
|
||||
</div>
|
||||
<div id=main-body>
|
||||
<div id=left>
|
||||
<div id=words></div>
|
||||
</div>
|
||||
<div id=main-content>
|
||||
<div id=reduce-functions></div>
|
||||
<div id=word-info>
|
||||
<div id=word-info-left>
|
||||
<h3 id="chosen-one"></h3>
|
||||
<p><span id="n-frames"></span></p>
|
||||
</div>
|
||||
<div id="word-info-right">
|
||||
<!--button onclick="user_input_menu('new')">debug_button</button-->
|
||||
</div>
|
||||
</div>
|
||||
<div id=frames-area></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="{{ url_for('static', filename='./lib/jquery.min.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='./lib/bootstrap/js/bootstrap.min.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='script.js') }}"></script>
|
||||
</body>
|
||||
</html>
|
5
src_diploma/flask_app/templates/letters.html
Normal file
5
src_diploma/flask_app/templates/letters.html
Normal file
|
@ -0,0 +1,5 @@
|
|||
{% for l in letters %}
|
||||
<span>
|
||||
<a href="javascript:get_words('{{ l[0] }}')">{{ l[0]|upper + "(" + l[1]|string + ")" }}</a>
|
||||
</span>
|
||||
{% endfor %}
|
10
src_diploma/flask_app/templates/reduce_functions.html
Normal file
10
src_diploma/flask_app/templates/reduce_functions.html
Normal file
|
@ -0,0 +1,10 @@
|
|||
<div class="row">
|
||||
<div class="container">
|
||||
<div class="col-sm-2">Način prikaza:</div>
|
||||
<div class="col-sm-10">
|
||||
{% for k, e in reduce_functions.items() | sort(attribute="0") %}
|
||||
<label class=radio-inline title="{{ e['desc'] }}"><input type="radio" name="rf" value="{{ k }}">{{ e["simple_name"] }}</label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
6
src_diploma/flask_app/templates/sense_groups.html
Normal file
6
src_diploma/flask_app/templates/sense_groups.html
Normal file
|
@ -0,0 +1,6 @@
|
|||
<select>
|
||||
<option disabled selected value>-- izberi --</option>
|
||||
{% for sg in sense_groups %}
|
||||
<option {% if sg == state_sense_group %}selected {% endif %}onclick="pick_sense_group('{{ sg }}', true)">{{ sg }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
6
src_diploma/flask_app/templates/tmp.html
Normal file
6
src_diploma/flask_app/templates/tmp.html
Normal file
|
@ -0,0 +1,6 @@
|
|||
|
||||
{% set alphabet = ["A", "B", "C", "Č", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "R", "S", "Š", "T", "U", "V", "Z", "Ž"] %}
|
||||
{% for i in range(0, alphabet|length - 1) %}
|
||||
<span><a href="javascript:get_words('{{ alphabet[i] }}')">{{ alphabet[i] }}</a>, </span>
|
||||
{% endfor %}
|
||||
<a href="javascript:get_words('{{ alphabet[-1] }}')">{{ alphabet[-1] }}</a>
|
16
src_diploma/flask_app/templates/token.html
Normal file
16
src_diploma/flask_app/templates/token.html
Normal file
|
@ -0,0 +1,16 @@
|
|||
<table>
|
||||
<tr>
|
||||
<td>{{ tid }}: </td>
|
||||
<td>{{ token }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Stavek: </td>
|
||||
<td class="token-sentence">{% for token in sentence %}
|
||||
<span title="{{ token[1] }}" class="{{ token[0] }}">{{ token[1]["word"] }}</span>
|
||||
{% endfor %}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>sense_ids: </td>
|
||||
<td>{{ sense_ids }}</td>
|
||||
</tr>
|
||||
</table>
|
12
src_diploma/flask_app/templates/words.html
Normal file
12
src_diploma/flask_app/templates/words.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
<ul>
|
||||
{% for w in words %}
|
||||
<li>
|
||||
<a href="javascript:get_frames('{{ w[0] }}')">{{ w[0] + " (" + w[1]|string + ")" }}
|
||||
{# Star indicates sense data has been preprocessed. #}
|
||||
{% if w[2] %}
|
||||
{{ "*" }}
|
||||
{% endif %}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
1
src_diploma/flask_app/vue/dist/index.html
vendored
Normal file
1
src_diploma/flask_app/vue/dist/index.html
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>vue_frontend</title><link href=/static/css/app.8cc8ad5cf4cf830949529795eff01e7f.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=/static/js/manifest.2ae2e69a05c33dfc65f8.js></script><script type=text/javascript src=/static/js/vendor.3ae5086c460a20dc799c.js></script><script type=text/javascript src=/static/js/app.abe281d88cb13e210c8b.js></script></body></html>
|
8
src_diploma/flask_app/vue/dist/static/css/app.8cc8ad5cf4cf830949529795eff01e7f.css
vendored
Normal file
8
src_diploma/flask_app/vue/dist/static/css/app.8cc8ad5cf4cf830949529795eff01e7f.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
src_diploma/flask_app/vue/dist/static/css/app.8cc8ad5cf4cf830949529795eff01e7f.css.map
vendored
Normal file
1
src_diploma/flask_app/vue/dist/static/css/app.8cc8ad5cf4cf830949529795eff01e7f.css.map
vendored
Normal file
File diff suppressed because one or more lines are too long
2
src_diploma/flask_app/vue/dist/static/js/app.abe281d88cb13e210c8b.js
vendored
Normal file
2
src_diploma/flask_app/vue/dist/static/js/app.abe281d88cb13e210c8b.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
src_diploma/flask_app/vue/dist/static/js/app.abe281d88cb13e210c8b.js.map
vendored
Normal file
1
src_diploma/flask_app/vue/dist/static/js/app.abe281d88cb13e210c8b.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
2
src_diploma/flask_app/vue/dist/static/js/manifest.2ae2e69a05c33dfc65f8.js
vendored
Normal file
2
src_diploma/flask_app/vue/dist/static/js/manifest.2ae2e69a05c33dfc65f8.js
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
!function(r){var n=window.webpackJsonp;window.webpackJsonp=function(e,u,c){for(var f,i,p,a=0,l=[];a<e.length;a++)i=e[a],o[i]&&l.push(o[i][0]),o[i]=0;for(f in u)Object.prototype.hasOwnProperty.call(u,f)&&(r[f]=u[f]);for(n&&n(e,u,c);l.length;)l.shift()();if(c)for(a=0;a<c.length;a++)p=t(t.s=c[a]);return p};var e={},o={2:0};function t(n){if(e[n])return e[n].exports;var o=e[n]={i:n,l:!1,exports:{}};return r[n].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=r,t.c=e,t.d=function(r,n,e){t.o(r,n)||Object.defineProperty(r,n,{configurable:!1,enumerable:!0,get:e})},t.n=function(r){var n=r&&r.__esModule?function(){return r.default}:function(){return r};return t.d(n,"a",n),n},t.o=function(r,n){return Object.prototype.hasOwnProperty.call(r,n)},t.p="/",t.oe=function(r){throw console.error(r),r}}([]);
|
||||
//# sourceMappingURL=manifest.2ae2e69a05c33dfc65f8.js.map
|
1
src_diploma/flask_app/vue/dist/static/js/manifest.2ae2e69a05c33dfc65f8.js.map
vendored
Normal file
1
src_diploma/flask_app/vue/dist/static/js/manifest.2ae2e69a05c33dfc65f8.js.map
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
{"version":3,"sources":["webpack:///webpack/bootstrap 08aa727d7b9c76add5d3"],"names":["parentJsonpFunction","window","chunkIds","moreModules","executeModules","moduleId","chunkId","result","i","resolves","length","installedChunks","push","Object","prototype","hasOwnProperty","call","modules","shift","__webpack_require__","s","installedModules","2","exports","module","l","m","c","d","name","getter","o","defineProperty","configurable","enumerable","get","n","__esModule","object","property","p","oe","err","console","error"],"mappings":"aACA,IAAAA,EAAAC,OAAA,aACAA,OAAA,sBAAAC,EAAAC,EAAAC,GAIA,IADA,IAAAC,EAAAC,EAAAC,EAAAC,EAAA,EAAAC,KACQD,EAAAN,EAAAQ,OAAoBF,IAC5BF,EAAAJ,EAAAM,GACAG,EAAAL,IACAG,EAAAG,KAAAD,EAAAL,GAAA,IAEAK,EAAAL,GAAA,EAEA,IAAAD,KAAAF,EACAU,OAAAC,UAAAC,eAAAC,KAAAb,EAAAE,KACAY,EAAAZ,GAAAF,EAAAE,IAIA,IADAL,KAAAE,EAAAC,EAAAC,GACAK,EAAAC,QACAD,EAAAS,OAAAT,GAEA,GAAAL,EACA,IAAAI,EAAA,EAAYA,EAAAJ,EAAAM,OAA2BF,IACvCD,EAAAY,IAAAC,EAAAhB,EAAAI,IAGA,OAAAD,GAIA,IAAAc,KAGAV,GACAW,EAAA,GAIA,SAAAH,EAAAd,GAGA,GAAAgB,EAAAhB,GACA,OAAAgB,EAAAhB,GAAAkB,QAGA,IAAAC,EAAAH,EAAAhB,IACAG,EAAAH,EACAoB,GAAA,EACAF,YAUA,OANAN,EAAAZ,GAAAW,KAAAQ,EAAAD,QAAAC,IAAAD,QAAAJ,GAGAK,EAAAC,GAAA,EAGAD,EAAAD,QAKAJ,EAAAO,EAAAT,EAGAE,EAAAQ,EAAAN,EAGAF,EAAAS,EAAA,SAAAL,EAAAM,EAAAC,GACAX,EAAAY,EAAAR,EAAAM,IACAhB,OAAAmB,eAAAT,EAAAM,GACAI,cAAA,EACAC,YAAA,EACAC,IAAAL,KAMAX,EAAAiB,EAAA,SAAAZ,GACA,IAAAM,EAAAN,KAAAa,WACA,WAA2B,OAAAb,EAAA,SAC3B,WAAiC,OAAAA,GAEjC,OADAL,EAAAS,EAAAE,EAAA,IAAAA,GACAA,GAIAX,EAAAY,EAAA,SAAAO,EAAAC,GAAsD,OAAA1B,OAAAC,UAAAC,eAAAC,KAAAsB,EAAAC,IAGtDpB,EAAAqB,EAAA,IAGArB,EAAAsB,GAAA,SAAAC,GAA8D,MAApBC,QAAAC,MAAAF,GAAoBA","file":"static/js/manifest.2ae2e69a05c33dfc65f8.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [], result;\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n \t\tif(executeModules) {\n \t\t\tfor(i=0; i < executeModules.length; i++) {\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = executeModules[i]);\n \t\t\t}\n \t\t}\n \t\treturn result;\n \t};\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// objects to store loaded and loading chunks\n \tvar installedChunks = {\n \t\t2: 0\n \t};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n \t// on error function for async loading\n \t__webpack_require__.oe = function(err) { console.error(err); throw err; };\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 08aa727d7b9c76add5d3"],"sourceRoot":""}
|
45
src_diploma/flask_app/vue/dist/static/js/vendor.3ae5086c460a20dc799c.js
vendored
Normal file
45
src_diploma/flask_app/vue/dist/static/js/vendor.3ae5086c460a20dc799c.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
src_diploma/flask_app/vue/dist/static/js/vendor.3ae5086c460a20dc799c.js.map
vendored
Normal file
1
src_diploma/flask_app/vue/dist/static/js/vendor.3ae5086c460a20dc799c.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
28
src_diploma/setup.py
Normal file
28
src_diploma/setup.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
from setuptools import setup
|
||||
|
||||
setup(
|
||||
name='Valency',
|
||||
version='0.1',
|
||||
description='Valency lexicon of slovenian verbs.',
|
||||
url='https://bitbucket.org/voje/diploma',
|
||||
author='Kristjan Voje',
|
||||
author_email='kristjan.voje@gmail.com',
|
||||
license='MIT',
|
||||
packages=['valency'], # where to look for __init__.py
|
||||
install_requires=[
|
||||
'bs4',
|
||||
'requests',
|
||||
'matplotlib',
|
||||
'flask',
|
||||
'nltk',
|
||||
'pymongo',
|
||||
'xmltodict',
|
||||
'scipy',
|
||||
'scikit-learn',
|
||||
'polyglot',
|
||||
'pyicu',
|
||||
'pycld2',
|
||||
'morfessor',
|
||||
'flask-cors',
|
||||
]
|
||||
)
|
101
src_diploma/sherpa.sh
Executable file
101
src_diploma/sherpa.sh
Executable file
|
@ -0,0 +1,101 @@
|
|||
#!/bin/bash
|
||||
|
||||
function echo_help () {
|
||||
echo "
|
||||
sherpa.sh
|
||||
--help
|
||||
--pack (zip watched files)
|
||||
--unpack (unzip watched files)
|
||||
--list (list watched files)
|
||||
--build_vue (requires npm, builds vue_frontend for production)
|
||||
"
|
||||
}
|
||||
|
||||
function frontend_config () {
|
||||
orig_path="$(pwd)"
|
||||
cd ./vue_frontend/config/
|
||||
if [[ $1 == "dev" ]]; then
|
||||
cp config_dev.json config.json
|
||||
elif [[ $1 == "pro" ]]; then
|
||||
cp config_pro.json config.json
|
||||
fi
|
||||
echo "Using config: "
|
||||
cat config.json
|
||||
cd "${orig_path}"
|
||||
}
|
||||
|
||||
function build_vue () {
|
||||
echo "
|
||||
API settings, pick a number:
|
||||
----------------------------
|
||||
1) development (API on localhost)
|
||||
2) production (see conf. files in vue folder for IP settings)
|
||||
"
|
||||
read choice
|
||||
if [ $choice == 1 ]; then
|
||||
frontend_config "dev"
|
||||
elif [ $choice == 2]; then
|
||||
frontend_config "pro"
|
||||
else
|
||||
exit
|
||||
fi
|
||||
orig_path="$(pwd)"
|
||||
cd ./vue_frontend
|
||||
npm run build
|
||||
cd "${orig_path}"
|
||||
if [ -d ./flask_app/vue/dist ]; then
|
||||
rm -r ./flask_app/vue/dist
|
||||
fi
|
||||
cp -r ./vue_frontend/dist/ ./flask_app/vue/
|
||||
}
|
||||
|
||||
function unpack () {
|
||||
orig_path="$(pwd)"
|
||||
cd ../data/
|
||||
unzip ./no_del_pickles.zip
|
||||
cd "$orig_path"
|
||||
}
|
||||
|
||||
function pack () {
|
||||
orig_path="$(pwd)"
|
||||
cd ../data/
|
||||
zip -r no_del_pickles.zip ./no_del_pickles/
|
||||
rm -r ./no_del_pickles
|
||||
cd "$orig_path"
|
||||
}
|
||||
|
||||
if [[ "$#" -eq 0 ]]; then
|
||||
echo_help
|
||||
fi
|
||||
|
||||
while [[ "$#" -gt 0 ]]; do
|
||||
key="$1"
|
||||
case "$key" in
|
||||
--help)
|
||||
echo_help
|
||||
exit 0
|
||||
;;
|
||||
--pack)
|
||||
pack
|
||||
exit 0
|
||||
;;
|
||||
--unpack)
|
||||
unpack
|
||||
exit 0
|
||||
;;
|
||||
--build_vue)
|
||||
build_vue
|
||||
exit 0
|
||||
;;
|
||||
--frontend_config)
|
||||
shift
|
||||
arg1="$1"
|
||||
frontend_config "$arg1"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo_help
|
||||
exit 0
|
||||
shift
|
||||
esac
|
||||
done
|
33
src_diploma/struktura.md
Normal file
33
src_diploma/struktura.md
Normal file
|
@ -0,0 +1,33 @@
|
|||
# Drevesna struktura direktorija:
|
||||
|
||||
* data -- vhodne datoteke (sskj, ssj500k, slownet) (prazno)
|
||||
* script -- izvorna koda
|
||||
* flask_app -- zaledni del, backend
|
||||
* app.py -- vhodna točka (main)
|
||||
* valency -- modul za obdelavo vhodnih korpusov (glavna logika)
|
||||
* seqparser -- orodje za razčlenjevanje vhodnega korpusa v .xml obliki
|
||||
* dictionary_interface.py -- vmesnik za delo s slovarji v MongDB bazi
|
||||
* evaluation.py -- algoritmi za evalvacijo
|
||||
* rand_index()
|
||||
* clustering_purity()
|
||||
* ars() -- adjusted_rand_index sem uvozil iz sklearn.metrics
|
||||
* frame.py -- objekt za valenčni okvir
|
||||
* k_means.py -- algoritem k-voditeljev
|
||||
* k_means()
|
||||
* bkm() -- bisekcijski k-means
|
||||
* silhouette_wrapper -- izračun silhuetne ocene
|
||||
* kmeans_wrapper() -- kliče izbran algoritem k-means z različnimi vrednostmi K,
|
||||
s pomočjo funkcije silhouette_wrapper() izbere najbolj optimalen K
|
||||
* k_utils.py -- podporna orodja
|
||||
* slo_bucket_sort() -- sort za slovenske besede
|
||||
* stem_slo() -- približek korenjenja slovenskih besed
|
||||
* leskFour.py -- implementacija štirih verzij Leskovega algoritma
|
||||
* lesk_nltk()
|
||||
* lesk_sl()
|
||||
* lesk_al()
|
||||
* lesk_ram()
|
||||
* reduce_functions.py -- funkcije za združevanje vezljivostnih vzorcev (uporaljene v aplikaciji)
|
||||
* ssj_struct.py -- vmesni objekt za branje korpusa
|
||||
* sskj_scraper.py -- orodje za zbiranje podatkov iz spletnega SSKJ
|
||||
* val_struct.py() -- objekt, ki predstavlja prebrani korpus
|
||||
* vue_frontend -- uporabniški vmesnik
|
1
src_diploma/valency/.gitignore
vendored
Normal file
1
src_diploma/valency/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
*.pickle
|
0
src_diploma/valency/__init__.py
Normal file
0
src_diploma/valency/__init__.py
Normal file
386
src_diploma/valency/dictionary_interface.py
Normal file
386
src_diploma/valency/dictionary_interface.py
Normal file
|
@ -0,0 +1,386 @@
|
|||
from valency import k_utils
|
||||
import logging
|
||||
from time import time
|
||||
from valency.k_utils import dict_safe_key as dsk
|
||||
from copy import deepcopy as DC
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
# Upper limit for how many senses a lemma can have.
|
||||
GUL = 20
|
||||
SLOWNET_CACHE = "slownet_glosses_cache"
|
||||
|
||||
|
||||
class DictionaryInterface:
|
||||
def __init__(self, vallex, dictionary):
|
||||
self.vallex = vallex
|
||||
self.dictionary = "interface"
|
||||
|
||||
def find(self, lemma):
|
||||
return []
|
||||
|
||||
def contains(self, lemma, upper_limit=GUL):
|
||||
# useless. need to check if sense_glosses returns non empty list
|
||||
res = self.find(lemma)
|
||||
if upper_limit is not None and len(res) > upper_limit:
|
||||
return False
|
||||
return (len(res) is not 0)
|
||||
|
||||
def cached_glosses(self, lemma):
|
||||
# preprocessed self_glosses (not used)
|
||||
res = list(self.vallex.db.cached_glosses.find(
|
||||
{"lemma": lemma, "dictionary": self.dictionary}))
|
||||
if len(res) == 0:
|
||||
return []
|
||||
return res[0]["glosses"]
|
||||
|
||||
def sense_glosses(self, lemma):
|
||||
# array: gloss for each sense
|
||||
# gloss: {"gloss": ["<sense>", ...], "def": ["<sense"], ...}
|
||||
return "dictionary_interface.py: not_yet_implemented"
|
||||
|
||||
# Recursively pull strgins out of a dictionary,
|
||||
# based on a list of keys.
|
||||
# uses self.recursion_buffer
|
||||
def pull_strings_wrapper(self, element, keys):
|
||||
if element is None:
|
||||
return []
|
||||
self.recursion_buffer = []
|
||||
self.pull_strings(element, keys)
|
||||
return self.recursion_buffer[:]
|
||||
|
||||
def pull_strings(self, element, keys):
|
||||
# Recursively pull values out of a dict.
|
||||
# correct key + element as string or list of strings
|
||||
for k, e in element.items():
|
||||
if k not in keys:
|
||||
continue
|
||||
if isinstance(e, dict):
|
||||
self.pull_strings(e, keys)
|
||||
elif isinstance(e, str):
|
||||
self.recursion_buffer.append(e)
|
||||
elif isinstance(e, list):
|
||||
for ee in e:
|
||||
if isinstance(ee, dict):
|
||||
self.pull_strings(ee, keys)
|
||||
elif isinstance(ee, str):
|
||||
self.recursion_buffer.append(ee)
|
||||
|
||||
|
||||
class Sskj(DictionaryInterface):
|
||||
def __init__(self, vallex):
|
||||
super().__init__(vallex, "sskj")
|
||||
|
||||
def find(self, lemma):
|
||||
res = list(self.vallex.db.sskj.find(
|
||||
{"ns0:entry.ns0:form.ns0:orth": lemma}
|
||||
))
|
||||
return res
|
||||
|
||||
def sense_glosses(self, lemma, upper_limit=GUL):
|
||||
entries = self.find(lemma)
|
||||
if upper_limit is not None and len(entries) > upper_limit:
|
||||
log.info("sense_glosses({}): too many sense entries".format(lemma))
|
||||
return []
|
||||
senses = []
|
||||
if len(entries) == 0:
|
||||
return []
|
||||
for e in entries:
|
||||
senses.extend(dsk(
|
||||
e["ns0:entry"], "ns0:sense"))
|
||||
keys = [
|
||||
"ns0:def", "ns0:cit", "ns0:quote",
|
||||
"ns0:gloss", "ns0:sense", "ns0:orth",
|
||||
"ns0:form", "#text"
|
||||
]
|
||||
glosses = []
|
||||
for s in senses:
|
||||
gloss = self.pull_strings_wrapper(s, keys)
|
||||
if len(gloss) == 0:
|
||||
continue
|
||||
glosses.append({
|
||||
"gloss": gloss,
|
||||
"def": self.pull_strings_wrapper(s, ["ns0:sense", "ns0:def"])
|
||||
})
|
||||
return glosses
|
||||
|
||||
|
||||
class SloWnet(DictionaryInterface):
|
||||
def __init__(self, vallex):
|
||||
super().__init__(vallex, "slownet")
|
||||
self.hypernym_buffer = []
|
||||
|
||||
def slo_to_eng(self, lemma):
|
||||
|
||||
def helper_get_eng_lemmas(r):
|
||||
res = []
|
||||
for literal in dsk(r, "SYNONYM"):
|
||||
if literal["@xml:lang"] == "en":
|
||||
for lt in dsk(literal, "LITERAL"):
|
||||
res.append(lt["#text"])
|
||||
return res
|
||||
|
||||
# takes a slo token, returns array of english counterparts
|
||||
results = self.find(lemma)
|
||||
eng_lemmas = []
|
||||
for r in results:
|
||||
eng_lemmas.extend(helper_get_eng_lemmas(r))
|
||||
return eng_lemmas
|
||||
|
||||
def helper_get_hypernyms(self, entry):
|
||||
res = []
|
||||
dd = dsk(entry, "ILR")
|
||||
for d in dd:
|
||||
if d["@type"] == "hypernym":
|
||||
res.append(d["#text"])
|
||||
return res
|
||||
|
||||
def helper_get_en_literals(self, entry):
|
||||
res = []
|
||||
synonyms = dsk(entry, "SYNONYM")
|
||||
for syn in synonyms:
|
||||
if syn["@xml:lang"] == "en":
|
||||
literals = dsk(syn, "LITERAL")
|
||||
for lit in literals:
|
||||
res.append(lit["#text"])
|
||||
return res
|
||||
|
||||
def rek_root_chain(self, slownet_id):
|
||||
entry = self.find_by_id(slownet_id)
|
||||
if entry is None:
|
||||
return []
|
||||
res = self.helper_get_en_literals(entry)
|
||||
for hypernym_id in self.helper_get_hypernyms(slownet_id):
|
||||
res.extend(self.rek_root_chain(hypernym_id))
|
||||
return res
|
||||
|
||||
def root_chain(self, lemma):
|
||||
cached = list(self.vallex.db.cached_root_chains.find({
|
||||
"lemma": lemma
|
||||
}))
|
||||
if cached:
|
||||
return cached[0]["data"]
|
||||
|
||||
res = self.slo_to_eng(lemma)
|
||||
entries = self.find(lemma)
|
||||
start_hypernym_ids = []
|
||||
for ent in entries:
|
||||
start_hypernym_ids.extend(self.helper_get_hypernyms(ent))
|
||||
for shi in start_hypernym_ids:
|
||||
res.extend(self.rek_root_chain(shi))
|
||||
self.vallex.db.cached_root_chains.insert({
|
||||
"lemma": lemma,
|
||||
"data": res
|
||||
})
|
||||
return res
|
||||
|
||||
def find_by_id(self, slownet_id):
|
||||
res = list(self.vallex.db.slownet.find({"ID": slownet_id}))
|
||||
if len(res) == 0:
|
||||
log.error("ID: {} not in db.slownet.".format(slownet_id))
|
||||
return None
|
||||
return res[0]
|
||||
|
||||
def find(self, lemma):
|
||||
return list(self.vallex.db.slownet.find({"slo_lemma": lemma}))
|
||||
"""
|
||||
# elemMatch for array query
|
||||
res = list(self.vallex.db.slownet.find({
|
||||
"SYNONYM": {'$elemMatch': {
|
||||
"LITERAL": {'$elemMatch': {"#text": lemma}}
|
||||
}}
|
||||
}))
|
||||
"""
|
||||
|
||||
def hypernyms(self, slownet_id, level):
|
||||
if level == 3:
|
||||
return
|
||||
elements = list(self.vallex.db.slownet.find({"ID": slownet_id}))
|
||||
if len(elements) == 0:
|
||||
return
|
||||
for e in elements:
|
||||
ei = self.extract_element_info(e)
|
||||
self.hypernym_buffer.append({
|
||||
"def": ei["domain"] + ei["def"],
|
||||
"gloss": ei["domain"] + ei["def"] + ei["usage"]
|
||||
})
|
||||
for ilr in ei["ilr"]:
|
||||
self.hypernyms(ilr, level + 1)
|
||||
|
||||
def extract_element_info(self, e):
|
||||
domain = []
|
||||
dd = dsk(e, "DOMAIN")
|
||||
for d in dd:
|
||||
domain.append(d)
|
||||
definition = []
|
||||
dd = dsk(e, "DEF")
|
||||
for d in dd:
|
||||
if d["@xml:lang"] == "en":
|
||||
definition.append(d["#text"])
|
||||
ilr = []
|
||||
dd = dsk(e, "ILR")
|
||||
for d in dd:
|
||||
if d["@type"] == "hypernym":
|
||||
ilr.append(d["#text"])
|
||||
usage = []
|
||||
dd = dsk(e, "USAGE")
|
||||
for d in dd:
|
||||
if d["@xml:lang"] == "en":
|
||||
usage.append(d["#text"])
|
||||
return {
|
||||
"domain": domain,
|
||||
"def": definition,
|
||||
"ilr": ilr,
|
||||
"usage": usage,
|
||||
}
|
||||
|
||||
def sense_glosses(self, lemma, upper_limit=GUL):
|
||||
# stime = time()
|
||||
|
||||
# caching
|
||||
db_key = {
|
||||
"lemma": lemma,
|
||||
"upper_limit": upper_limit
|
||||
}
|
||||
cache = list(self.vallex.db[SLOWNET_CACHE].find(db_key))
|
||||
if len(cache) > 0:
|
||||
return cache[0]["data"]
|
||||
|
||||
entries = self.find(lemma)
|
||||
if upper_limit is not None and len(entries) > upper_limit:
|
||||
# log.info("sense_glosses({}): too many senses".format(lemma))
|
||||
return []
|
||||
ret_glosses = []
|
||||
for e in entries:
|
||||
defs = []
|
||||
glosses = []
|
||||
self.hypernym_buffer = []
|
||||
ei = self.extract_element_info(e)
|
||||
self.hypernym_buffer.append({
|
||||
"def": ei["domain"] + ei["def"],
|
||||
"gloss": ei["domain"] + ei["def"] + ei["usage"]
|
||||
})
|
||||
for ilr in ei["ilr"]:
|
||||
self.hypernyms(ilr, 1)
|
||||
|
||||
[defs.extend(x["def"]) for x in self.hypernym_buffer]
|
||||
[glosses.extend(x["gloss"]) for x in self.hypernym_buffer]
|
||||
ret_glosses.append({
|
||||
"def": defs,
|
||||
"gloss": glosses,
|
||||
})
|
||||
|
||||
# log.debug("slownet.sense_glosses({}): {:.2f}s".format(
|
||||
# lemma, time() - stime))
|
||||
|
||||
# caching
|
||||
db_entry = {
|
||||
"lemma": db_key["lemma"],
|
||||
"upper_limit": db_key["upper_limit"],
|
||||
"data": ret_glosses
|
||||
}
|
||||
self.vallex.db.slownet_sense_glosses.update(
|
||||
db_key, db_entry, upsert=True
|
||||
)
|
||||
return ret_glosses
|
||||
|
||||
|
||||
class Sskj2(DictionaryInterface):
|
||||
def __init__(self, vallex):
|
||||
super().__init__(vallex, "sskj")
|
||||
|
||||
def find(self, lemma):
|
||||
pos = "glagol"
|
||||
if lemma[-1] == "_":
|
||||
pos = "pridevnik"
|
||||
res = list(self.vallex.db.sskj.find({
|
||||
"izt_clean": lemma,
|
||||
"pos": pos
|
||||
}))
|
||||
return res
|
||||
|
||||
def count_senses(self, lemma):
|
||||
entries = self.find(lemma)
|
||||
if len(entries) == 0:
|
||||
return 0
|
||||
ol = dsk(entries[0], "ol")
|
||||
if len(ol) == 0:
|
||||
return 1
|
||||
return len(ol[0]["li"])
|
||||
|
||||
def sense_glosses(self, lemma, upper_limit=GUL):
|
||||
|
||||
def helper_dict_safe_add(dic, key, el):
|
||||
if key not in dic:
|
||||
dic[key] = []
|
||||
dic[key].append(el)
|
||||
|
||||
def helper_pull_rec(el_lst, res_dct):
|
||||
for el in el_lst:
|
||||
if isinstance(el, dict):
|
||||
if ("@title" in el) and ("#text" in el):
|
||||
helper_dict_safe_add(
|
||||
res_dct, el["@title"], el["#text"])
|
||||
if "span" in el:
|
||||
helper_pull_rec(dsk(el, "span"), res_dct)
|
||||
if ("ol" in el) and ("li" in el["ol"]):
|
||||
helper_pull_rec(el["ol"]["li"], res_dct)
|
||||
if "li" in el:
|
||||
helper_pull_rec(el["li"], res_dct)
|
||||
|
||||
entries = self.find(lemma)
|
||||
if len(entries) == 0:
|
||||
return []
|
||||
if len(entries) > 1:
|
||||
log.warning("{} entries for {} in sskj2.".format(
|
||||
len(entries), lemma))
|
||||
glosses_per_entry = []
|
||||
for idx, entry in enumerate(entries):
|
||||
res_dict = {}
|
||||
if "span" in entry:
|
||||
helper_pull_rec(dsk(entry, "span"), res_dict)
|
||||
# senses
|
||||
res_dict["senses"] = []
|
||||
if ("ol" in entry) and ("li" in entry["ol"]):
|
||||
for el in dsk(entry["ol"], "li"):
|
||||
tmp = {"sskj_sense_id": el["span"][0]}
|
||||
helper_pull_rec(dsk(el, "span"), tmp)
|
||||
helper_pull_rec(dsk(el, "ol"), tmp)
|
||||
res_dict["senses"].append(DC(tmp))
|
||||
|
||||
def helper_create_gloss(dct):
|
||||
keys = ["Razlaga", "Zgled", "Stranska razlaga", "Sopomenka"]
|
||||
ret = []
|
||||
for k in keys:
|
||||
ret.extend(dsk(dct, k))
|
||||
return ret
|
||||
|
||||
glosses = []
|
||||
n_senses = len(res_dict["senses"])
|
||||
if n_senses == 0:
|
||||
glosses.append({
|
||||
"sskj_sense_id": "1-1",
|
||||
"gloss": helper_create_gloss(res_dict),
|
||||
"def": dsk(res_dict, "Razlaga")
|
||||
})
|
||||
return glosses
|
||||
|
||||
for sense in res_dict["senses"]:
|
||||
glosses.append({
|
||||
"sskj_sense_id": "{}-{}".format(
|
||||
sense["sskj_sense_id"], n_senses),
|
||||
"gloss": helper_create_gloss(sense),
|
||||
"def": dsk(sense, "Razlaga")
|
||||
})
|
||||
glosses_per_entry.append(glosses)
|
||||
|
||||
# add entry_id before the_sense id
|
||||
# entry_id-sskj_sense_id-n_senses
|
||||
all_glosses = []
|
||||
for idx, glosses in enumerate(glosses_per_entry):
|
||||
entry_id = idx + 1 # start with 1
|
||||
for gloss in glosses:
|
||||
gloss["sskj_sense_id"] = "{}-{}".format(
|
||||
entry_id, gloss["sskj_sense_id"])
|
||||
all_glosses.append(gloss)
|
||||
return all_glosses
|
96
src_diploma/valency/frame.py
Normal file
96
src_diploma/valency/frame.py
Normal file
|
@ -0,0 +1,96 @@
|
|||
import logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Frame():
|
||||
def __init__(self, tids, deep_links=None, slots=None, hw=None):
|
||||
self.hw = hw
|
||||
self.tids = tids # list of tokens with the same hw_lemma
|
||||
# Each tid = "S123.t123";
|
||||
# you can get sentence with vallex.get_sentence(S123)
|
||||
self.slots = []
|
||||
if slots is None:
|
||||
self.slots = self.init_slots(deep_links)
|
||||
else:
|
||||
self.slots = slots
|
||||
self.sense_info = {}
|
||||
self.sentences = None # Used for passing to view in app.py, get_frames
|
||||
self.aggr_sent = None # Dictionary { hw: self.sentences idx }
|
||||
|
||||
def to_json(self):
|
||||
ret = {
|
||||
"hw": self.hw,
|
||||
"tids": self.tids,
|
||||
"slots": [slot.to_json() for slot in self.slots],
|
||||
"sentences": self.sentences,
|
||||
"aggr_sent": self.aggr_sent,
|
||||
"sense_info": self.sense_info
|
||||
}
|
||||
return ret
|
||||
|
||||
def init_slots(self, deep):
|
||||
slots = []
|
||||
for link in deep:
|
||||
slots.append(Slot(
|
||||
functor=link["functor"],
|
||||
tids=[link["to"]]
|
||||
))
|
||||
return slots
|
||||
|
||||
def sort_slots(self):
|
||||
# ACT, PAT, alphabetically
|
||||
srt1 = [
|
||||
x for x in self.slots
|
||||
if (x.functor == "ACT" or
|
||||
x.functor == "PAT")
|
||||
]
|
||||
srt1 = sorted(srt1, key=lambda x: x.functor)
|
||||
srt2 = [
|
||||
x for x in self.slots
|
||||
if (x.functor != "ACT" and
|
||||
x.functor != "PAT")
|
||||
]
|
||||
srt2 = sorted(srt2, key=lambda x: x.functor)
|
||||
self.slots = (srt1 + srt2)
|
||||
|
||||
def to_string(self):
|
||||
ret = "Frame:\n"
|
||||
ret += "sense_info: {}\n".format(str(self.sense_info))
|
||||
ret += "tids: ["
|
||||
for t in self.tids:
|
||||
ret += (str(t) + ", ")
|
||||
ret += "]\n"
|
||||
if self.slots is not None:
|
||||
ret += "slots:\n"
|
||||
for sl in self.slots:
|
||||
ret += (sl.to_string() + "\n")
|
||||
return ret
|
||||
|
||||
|
||||
class Slot():
|
||||
# Each slot is identified by its functor (ACT, PAT, ...)
|
||||
# It consists of different tokens.
|
||||
def __init__(self, functor, tids=None, count=None):
|
||||
self.functor = functor
|
||||
self.tids = tids or []
|
||||
self.count = count or 1
|
||||
|
||||
def to_string(self):
|
||||
ret = "---- Slot:\n"
|
||||
ret += "functor: {}\n".format(self.functor)
|
||||
ret += "tids: ["
|
||||
for t in self.tids:
|
||||
ret += (str(t) + ", ")
|
||||
ret += "]\n"
|
||||
ret += "]\n"
|
||||
ret += "----\n"
|
||||
return ret
|
||||
|
||||
def to_json(self):
|
||||
ret = {
|
||||
"functor": self.functor,
|
||||
"tids": self.tids,
|
||||
"count": self.count
|
||||
}
|
||||
return ret
|
367
src_diploma/valency/k_utils.py
Normal file
367
src_diploma/valency/k_utils.py
Normal file
|
@ -0,0 +1,367 @@
|
|||
import os
|
||||
import pickle
|
||||
import nltk
|
||||
import random
|
||||
from time import time
|
||||
import string
|
||||
from polyglot.text import Word
|
||||
import logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
sno = nltk.stem.SnowballStemmer("english")
|
||||
|
||||
|
||||
def dict_safe_key(dic, key):
|
||||
# Returns a list, no matter what.
|
||||
# Transform 1 element into a list.
|
||||
# Return key not found as empty list.
|
||||
if (
|
||||
dic is None or
|
||||
key not in dic
|
||||
):
|
||||
return []
|
||||
subdic = dic[key]
|
||||
if not isinstance(subdic, list):
|
||||
return [subdic]
|
||||
return subdic
|
||||
|
||||
|
||||
def pickle_dump(data, path):
|
||||
with open(path, "wb") as file:
|
||||
pickle.dump(data, file)
|
||||
log.info("Dumped data to {}.".format(path))
|
||||
return True
|
||||
|
||||
|
||||
def pickle_load(path):
|
||||
ret = None
|
||||
if os.path.isfile(path):
|
||||
with open(path, "rb") as file:
|
||||
ret = pickle.load(file)
|
||||
log.info("Loaded data from {}.".format(path))
|
||||
return ret # Returns None in case of failure.
|
||||
|
||||
|
||||
# Implemented bucket sort for alphabetically sorting slovenian words.
|
||||
# Bucket sort >>>>>>>>>>>>>>>>>>>>
|
||||
def gen_sbs_alphabet():
|
||||
alphabet = "abcčdefghijklmnoprsštuvzž"
|
||||
return {letter: (idx + 1) for idx, letter in enumerate(alphabet)}
|
||||
|
||||
|
||||
slo_bucket_sort_alphabet = gen_sbs_alphabet()
|
||||
|
||||
|
||||
def slo_bucket_sort(words, key=None):
|
||||
if key is None:
|
||||
def key(x):
|
||||
return x
|
||||
|
||||
def alph_score(word, idx):
|
||||
kword = key(word)
|
||||
if idx >= len(kword):
|
||||
return 0
|
||||
return slo_bucket_sort_alphabet.get(kword[idx]) or 0
|
||||
|
||||
def list_to_bins(words, idx):
|
||||
bins = [[] for i in range(len(slo_bucket_sort_alphabet.keys()) + 1)]
|
||||
for word in words:
|
||||
bins[alph_score(word, idx)].append(word)
|
||||
return bins
|
||||
|
||||
def bins_to_list(bins):
|
||||
lst = []
|
||||
for b in bins:
|
||||
for el in b:
|
||||
lst.append(el)
|
||||
return lst
|
||||
|
||||
maxLen = 0
|
||||
for w in words:
|
||||
if len(key(w)) > maxLen:
|
||||
maxLen = len(key(w))
|
||||
maxIdx = maxLen - 1
|
||||
for idx in range(maxIdx, -1, -1):
|
||||
bins = list_to_bins(words, idx)
|
||||
words = bins_to_list(bins)
|
||||
"""
|
||||
print(idx)
|
||||
def get_letter(idx, word):
|
||||
kword = key(word)
|
||||
if idx < len(kword):
|
||||
return(kword[idx])
|
||||
return "#"
|
||||
print([(word, get_letter(idx, word)) for word in words])
|
||||
"""
|
||||
return words
|
||||
# Bucket sort <<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
def stem_slo(x):
|
||||
# Simplified;
|
||||
# Remove the last syllable.
|
||||
w = Word(x, language="sl").morphemes
|
||||
ret = "".join(w[:-1])
|
||||
return ret
|
||||
|
||||
|
||||
def stem_eng(x):
|
||||
return sno.stem(x)
|
||||
|
||||
|
||||
def tokenize(sentence, min_token_len=3, stem=None):
|
||||
# input: sentence string
|
||||
# output: list of token strings
|
||||
if stem is None:
|
||||
def stem(x):
|
||||
return x
|
||||
all_tokens = []
|
||||
sent_txt = nltk.sent_tokenize(sentence)
|
||||
for sent in sent_txt:
|
||||
tokens = nltk.word_tokenize(sent)
|
||||
all_tokens.extend(tokens)
|
||||
res = []
|
||||
for x in all_tokens:
|
||||
if x in string.punctuation:
|
||||
continue
|
||||
stemmed = stem(x.lower())
|
||||
if len(stemmed) >= min_token_len:
|
||||
res.append(stemmed)
|
||||
return res
|
||||
|
||||
|
||||
def tokenize_multiple(str_list, min_token_len=3, stem=None):
|
||||
# tstart = time()
|
||||
res = []
|
||||
for sentence in str_list:
|
||||
res.extend(tokenize(sentence, min_token_len, stem))
|
||||
# log.debug("tokenize_multiple: {:.2f}s".format(time() - tstart))
|
||||
return res
|
||||
|
||||
|
||||
def t_tokenize():
|
||||
teststring = "This is a test sentence. I hope it works. .. Asdf. asdf ,,,;"
|
||||
print(teststring)
|
||||
res = tokenize(teststring, min_token_len=None)
|
||||
print(res)
|
||||
|
||||
|
||||
def permute_paths(list2d, x=None, y=None, paths=None, current_path=None):
|
||||
# python stuff
|
||||
if x is None:
|
||||
x = -1
|
||||
if paths is None:
|
||||
paths = []
|
||||
if current_path is None:
|
||||
current_path = []
|
||||
|
||||
if x >= len(list2d) - 1:
|
||||
paths.append(current_path)
|
||||
return paths
|
||||
for i in range(len(list2d[x + 1])):
|
||||
tmp_path = current_path + [(x + 1, i)]
|
||||
# Computational complexity peoblem (prune long lists)
|
||||
# len == 12 -> 30%, len == 5 -> 100%
|
||||
# if random.randint(0, 100) <= (100 - 10 * (len(list2d) - 5)):
|
||||
if True:
|
||||
paths = permute_paths(
|
||||
list2d,
|
||||
x + 1,
|
||||
i,
|
||||
paths,
|
||||
tmp_path
|
||||
)
|
||||
return paths
|
||||
|
||||
|
||||
def t_permute_paths():
|
||||
list2d = [
|
||||
["Greta"],
|
||||
["backflips"],
|
||||
["through", "around"],
|
||||
["North Korea", "kindergarten"],
|
||||
["with", "without"],
|
||||
["a"],
|
||||
["bag of", "abundance of"],
|
||||
["bolts", "janitors"]
|
||||
]
|
||||
|
||||
print(list2d)
|
||||
paths = permute_paths(list2d=list2d)
|
||||
for path in paths:
|
||||
print([list2d[p[0]][p[1]] for p in path])
|
||||
|
||||
|
||||
def find_overlaps(list_a, list_b):
|
||||
# Input: two lists.
|
||||
# Output: lists of overlapping elements.
|
||||
dict_a = {}
|
||||
dict_b = {}
|
||||
lists = [list_a, list_b]
|
||||
dicts = [dict_a, dict_b]
|
||||
for lidx in range(len(lists)):
|
||||
for elidx in range(len(lists[lidx])):
|
||||
el = lists[lidx][elidx]
|
||||
if el not in dicts[lidx]:
|
||||
dicts[lidx][el] = []
|
||||
dicts[lidx][el].append(elidx)
|
||||
|
||||
substrings = []
|
||||
|
||||
sda = sorted(dict_a.keys())
|
||||
sdb = sorted(dict_b.keys())
|
||||
|
||||
i_sda = 0
|
||||
i_sdb = 0
|
||||
while ((i_sda < len(sda) and i_sdb < len(sdb))):
|
||||
if sda[i_sda] == sdb[i_sdb]:
|
||||
lia = dict_a[sda[i_sda]]
|
||||
lib = dict_b[sdb[i_sdb]]
|
||||
for llia in lia:
|
||||
for llib in lib:
|
||||
tmp_substr = []
|
||||
ii = 0
|
||||
while (
|
||||
(llia + ii < len(list_a)) and
|
||||
(llib + ii < len(list_b)) and
|
||||
(list_a[llia + ii] == list_b[llib + ii])
|
||||
):
|
||||
tmp_substr.append(list_a[llia + ii])
|
||||
ii += 1
|
||||
ii = 1
|
||||
while (
|
||||
(llia - ii >= 0) and
|
||||
(llib - ii >= 0) and
|
||||
(list_a[llia - ii] == list_b[llib - ii])
|
||||
):
|
||||
tmp_substr.insert(0, list_a[llia - ii])
|
||||
ii += 1
|
||||
substrings.append(tmp_substr)
|
||||
if sda[i_sda] < sdb[i_sdb]:
|
||||
i_sda += 1
|
||||
else:
|
||||
i_sdb += 1
|
||||
|
||||
uniques = set()
|
||||
res = []
|
||||
for ss in substrings:
|
||||
if str(ss) not in uniques:
|
||||
uniques.add(str(ss))
|
||||
res.append(ss)
|
||||
return res
|
||||
|
||||
|
||||
def find_overlaps_str(tokens_a, tokens_b):
|
||||
# Strings only.
|
||||
overlaps = []
|
||||
for N in range(1, 5):
|
||||
ngrams_a = []
|
||||
for i in range(len(tokens_a)):
|
||||
if i + N <= len(tokens_a):
|
||||
ngrams_a.append(tuple(tokens_a[i:i + N]))
|
||||
ngrams_b = []
|
||||
for i in range(len(tokens_b)):
|
||||
if i + N <= len(tokens_b):
|
||||
ngrams_b.append(tuple(tokens_b[i:i + N]))
|
||||
overlaps.extend(list(set(ngrams_a).intersection(set(ngrams_b))))
|
||||
|
||||
res = []
|
||||
for ovl in sorted(overlaps, key=lambda x: len(x), reverse=True):
|
||||
oovl = " ".join(ovl)
|
||||
for r in res:
|
||||
if oovl in r:
|
||||
break
|
||||
else:
|
||||
res.append(oovl)
|
||||
res[:] = [x.split(" ") for x in res]
|
||||
return res
|
||||
|
||||
|
||||
def t_find_overlaps():
|
||||
res = []
|
||||
input_len = [10, 100, 1000, 10000]
|
||||
for ll in input_len:
|
||||
alen = ll + int(ll * random.uniform(0.8, 1))
|
||||
blen = ll + int(ll * random.uniform(0.8, 1))
|
||||
a = [random.randint(0, 100) for x in range(alen)]
|
||||
b = [random.randint(0, 100) for x in range(blen)]
|
||||
tstart = time()
|
||||
find_overlaps(a, b)
|
||||
res.append({
|
||||
"time": time() - tstart,
|
||||
"input_size": ll
|
||||
})
|
||||
"""
|
||||
list_a = [6, 6, 4, 8, 3, 2, 2, 5, 6, 3, 4, 7, 5]
|
||||
list_b = [5, 3, 6, 8, 6, 6, 5, 3, 2, 6, 7, 8, 3, 2, 3, 2, 2, 5]
|
||||
res = find_overlaps(list_a, list_b)
|
||||
"""
|
||||
for r in res:
|
||||
print(r)
|
||||
|
||||
|
||||
def t1_find_overlaps():
|
||||
t1 = "This is a test sentence. I hope it works. .. Asdf. asdf ,,,;"
|
||||
t2 = "this is a seconde sentence. I hope my stuff works."
|
||||
print(t1)
|
||||
print(t2)
|
||||
res = find_overlaps(tokenize(t1), tokenize(t2))
|
||||
for r in res:
|
||||
print(r)
|
||||
|
||||
print()
|
||||
|
||||
res = find_overlaps_str(tokenize(t1), tokenize(t2))
|
||||
for r in res:
|
||||
print(r)
|
||||
|
||||
|
||||
def t_find_overlaps_str():
|
||||
t1 = [
|
||||
'vsa', 'moja', 'možganska', 'beda', 'se', 'združuje',
|
||||
'v', 'dejstvu', 'da', 'sem', 'si', 'čeprav', 'sem', 'pozabil',
|
||||
'ulico', 'zapomnil', 'hišno', 'številko'
|
||||
]
|
||||
t2 = [
|
||||
'narediti', 'doseči', 'da', 'se', 'kaj', 'aktivno', 'ohrani',
|
||||
'v', 'zavesti', 'zapomniti', 'si', 'imena', 'predstavljenih',
|
||||
'gostov', 'dobro', 'natančno', 'slabo', 'si', 'kaj', 'zapomniti',
|
||||
'takega', 'sem', 'si', 'zapomnil', 'zapomnite', 'te', 'prizore'
|
||||
]
|
||||
res = find_overlaps(t1, t2)
|
||||
print(res)
|
||||
|
||||
|
||||
def t_slo_bucket_sort():
|
||||
a1 = []
|
||||
a2 = []
|
||||
with open("./tests/m_besede2.txt") as f:
|
||||
for line in f:
|
||||
a1.append(line.split("\n")[0])
|
||||
a2.append((line.split("\n")[0], random.randint(0, 9)))
|
||||
|
||||
a1 = slo_bucket_sort(a1)
|
||||
a2 = slo_bucket_sort(a2, key=lambda x: x[0])
|
||||
|
||||
check = True
|
||||
for i in range(len(a1)):
|
||||
check &= (a1[i] == a2[i][0])
|
||||
print("{:<10}{:>10}".format(str(a1[i]), str(a2[i])))
|
||||
print(check)
|
||||
|
||||
|
||||
def t1_slo_bucket_sort():
|
||||
words = "_xyz zebra. .bober raca bor borovnica antilopa".split(" ")
|
||||
words.append("test space")
|
||||
words.append("test srrrr")
|
||||
words.append("test saaa")
|
||||
for w in slo_bucket_sort(words):
|
||||
print(w)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# t_find_overlaps()
|
||||
# t1_find_overlaps()
|
||||
# t_tokenize()
|
||||
# t_find_overlaps_str()
|
||||
t1_slo_bucket_sort()
|
247
src_diploma/valency/mongo_tools.py
Normal file
247
src_diploma/valency/mongo_tools.py
Normal file
|
@ -0,0 +1,247 @@
|
|||
import pymongo
|
||||
import xmltodict
|
||||
import xml.etree.ElementTree as ET
|
||||
from time import time
|
||||
import json
|
||||
from valency.sskj_scraper import SskjScraper
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
# Get rid of accented characters.
|
||||
intab = "ÁÉÍÓÚàáäçèéêìíîñòóôöùúüčŔŕ"
|
||||
outtb = "AEIOUaaaceeeiiinoooouuučRr"
|
||||
transtab = str.maketrans(intab, outtb)
|
||||
|
||||
|
||||
def mongo_test():
|
||||
client = pymongo.MongoClient(
|
||||
"mongodb://{}:{}@127.0.0.1:26633/texts".format("kristjan", "simple567")
|
||||
)
|
||||
|
||||
db = client.texts
|
||||
|
||||
coll = db.test
|
||||
|
||||
print(coll.find_one())
|
||||
|
||||
|
||||
def basic_connection(ip_addr=None, port=None):
|
||||
if ip_addr is None:
|
||||
ip_addr = "127.0.0.1"
|
||||
if port is None:
|
||||
port = 26644
|
||||
client = pymongo.MongoClient(
|
||||
"mongodb://{}:{}@{}:{}/texts".format(
|
||||
"kristjan", "simple567", ip_addr, str(port))
|
||||
)
|
||||
err_msg = "OK"
|
||||
try:
|
||||
client.server_info()
|
||||
except pymongo.errors.ServerSelectionTimeoutError as err:
|
||||
err_msg = err
|
||||
return (None, err_msg)
|
||||
db = client.texts
|
||||
return (db, err_msg)
|
||||
|
||||
|
||||
def check_collections(db, coll_names):
|
||||
collections = db.collection_names()
|
||||
for cn in coll_names:
|
||||
if cn not in collections:
|
||||
db.create_collection(cn)
|
||||
|
||||
|
||||
def prepare_user_tokens(db):
|
||||
CNAME = "v2_user_tokens"
|
||||
db[CNAME].drop()
|
||||
db.create_collection(CNAME)
|
||||
EXPIRE = 151200 # 2 days
|
||||
# EXPIRE = 10 # 10 sec
|
||||
db[CNAME].ensure_index("date", expireAfterSeconds=EXPIRE)
|
||||
|
||||
# user this: utc_timestamp = datetime.datetime.utcnow()
|
||||
# user_tokens.insert({
|
||||
# '_id': 'utc_session', "date": utc_timestamp,
|
||||
# "session": "test session"})
|
||||
|
||||
|
||||
def sskj_to_mongo(sskj_path):
|
||||
# Deprecated, use sskj2_to_mongo
|
||||
ns = {"tei": "http://www.tei-c.org/ns/1.0"}
|
||||
ts = time()
|
||||
sskj = ET.parse(sskj_path).getroot()
|
||||
db = basic_connection()
|
||||
col_names = ["sskj"]
|
||||
for cn in col_names:
|
||||
if cn in db.collection_names():
|
||||
db[cn].drop()
|
||||
text = sskj.find("tei:text", ns)
|
||||
body = text.find("tei:body", ns)
|
||||
n_ent = 0
|
||||
for entry in body.findall("tei:entry", ns):
|
||||
n_ent += 1
|
||||
tmpstr = ET.tostring(entry)
|
||||
datachunk = xmltodict.parse(tmpstr)
|
||||
dictchunk = json.loads(json.dumps(datachunk))
|
||||
"""
|
||||
pp = pprint.PrettyPrinter()
|
||||
pp.pprint(dictchunk)
|
||||
"""
|
||||
db.sskj.insert(dictchunk)
|
||||
# iskanje: db.sskj.find({'ns0:entry.ns0:form.ns0:orth':"kaplanček"})
|
||||
print("sskj to mongo: {} entries in {:.2f}s".format(n_ent, time() - ts))
|
||||
|
||||
|
||||
def slownet_to_mongo(slw_path):
|
||||
# .slownet contains the database from .xml file
|
||||
# added toplevel field ["slo_lemma"] for faster querying
|
||||
ts = time()
|
||||
slownet = ET.parse(slw_path).getroot()
|
||||
db = basic_connection()
|
||||
col_names = ["slownet_map", "slownet"]
|
||||
for cn in col_names:
|
||||
if cn in db.collection_names():
|
||||
db[cn].drop()
|
||||
|
||||
slo_to_id = {}
|
||||
for synset in slownet.findall("SYNSET"):
|
||||
tmpstr = ET.tostring(synset)
|
||||
datachunk = xmltodict.parse(tmpstr)
|
||||
dictchunk = json.loads(json.dumps(datachunk))
|
||||
dictchunk = dictchunk["SYNSET"]
|
||||
# pp.pprint(dictchunk)
|
||||
|
||||
# insert into slo_ti_id
|
||||
if "SYNONYM" in dictchunk:
|
||||
synonyms = dictchunk["SYNONYM"]
|
||||
if not isinstance(synonyms, list):
|
||||
synonyms = [synonyms]
|
||||
for syn in synonyms:
|
||||
if syn["@xml:lang"] == "sl":
|
||||
if "LITERAL" in syn:
|
||||
literals = syn["LITERAL"]
|
||||
if not isinstance(literals, list):
|
||||
literals = [literals]
|
||||
for lit in literals:
|
||||
slo_keyword = lit["#text"]
|
||||
if "." in slo_keyword:
|
||||
continue
|
||||
if "slo_lemma" not in dictchunk:
|
||||
dictchunk["slo_lemma"] = []
|
||||
dictchunk["slo_lemma"].append(slo_keyword)
|
||||
db.slownet.insert(dictchunk)
|
||||
|
||||
# pp.pprint(slo_to_id)
|
||||
db.slownet.ensure_index([("id", pymongo.ASCENDING)])
|
||||
db.slo_to_id.insert(slo_to_id)
|
||||
print("sloWNet to mongo in {:.2f}s".format(time() - ts))
|
||||
|
||||
|
||||
def scrape_sskj():
|
||||
# Deprecated!
|
||||
# Walk through keys in slo_to_id and scrape sskj data.
|
||||
client = pymongo.MongoClient(
|
||||
"mongodb://{}:{}@127.0.0.1:26633/texts".format("kristjan", "simple567")
|
||||
)
|
||||
db = client.texts
|
||||
words_list = sorted(db.slo_to_id.find_one())
|
||||
|
||||
print(len(words_list))
|
||||
sscraper = SskjScraper()
|
||||
|
||||
last_word = "nogometaš"
|
||||
db.scraped_sskj.remove({"word": last_word})
|
||||
lock = True
|
||||
for word in words_list:
|
||||
if word == last_word:
|
||||
lock = False
|
||||
|
||||
if not lock:
|
||||
res = sscraper.scrape(word)
|
||||
if len(res) > 0:
|
||||
db.scraped_sskj.insert({"word": word, "bag": res})
|
||||
|
||||
|
||||
def sskj2_to_mongo(sskj2_path):
|
||||
tstart = time()
|
||||
|
||||
db = basic_connection()
|
||||
col_names = ["sskj2"]
|
||||
for cn in col_names:
|
||||
if cn in db.collection_names():
|
||||
db[cn].drop()
|
||||
|
||||
with open(sskj2_path) as f:
|
||||
soup = BeautifulSoup(f.read(), "html.parser")
|
||||
|
||||
divs = soup.find_all("div")
|
||||
for i, div in enumerate(divs):
|
||||
if (i) % 100 == 0:
|
||||
print("{}/{}".format(i, len(divs)))
|
||||
datachunk = xmltodict.parse(str(div))
|
||||
datachunk = datachunk["div"]
|
||||
|
||||
# pos (besedna vrsta)
|
||||
pos_keywords = {
|
||||
"samostalnik": 0,
|
||||
"pridevnik": 0,
|
||||
"glagol": 0,
|
||||
"prislov": 0,
|
||||
"predlog": 0,
|
||||
"členek": 0,
|
||||
"veznik": 0,
|
||||
"medmet": 0,
|
||||
"povedkovnik": 0
|
||||
}
|
||||
for span in div.find_all("span"):
|
||||
attrs = [e for k, e in span.attrs.items()]
|
||||
for attr in attrs:
|
||||
for ak in attr.split(" "):
|
||||
akl = ak.lower()
|
||||
if akl in pos_keywords:
|
||||
pos_keywords[akl] += 1
|
||||
pos = "unknonw"
|
||||
pos_max = 0
|
||||
for k, e in pos_keywords.items():
|
||||
if e > pos_max:
|
||||
pos = k
|
||||
pos_max = e
|
||||
datachunk["pos"] = pos
|
||||
|
||||
# izt_clean
|
||||
izts = div.find_all("span", {"title": "Iztočnica"})
|
||||
if len(izts) == 0:
|
||||
print("Entry {} has no Iztočnica.".format(i))
|
||||
continue
|
||||
izt = ((izts[0].text).translate(transtab)).lower()
|
||||
ispl = izt.split(" ")
|
||||
has_se = False
|
||||
if len(ispl) and ispl[-1] == "se":
|
||||
izt = " ".join(ispl[:-1])
|
||||
has_se = True
|
||||
datachunk["izt_clean"] = izt
|
||||
datachunk["has_se"] = has_se
|
||||
|
||||
dictchunk = json.loads(json.dumps(datachunk))
|
||||
db.sskj.insert(dictchunk)
|
||||
|
||||
db.sskj.create_index([("izt_clean", pymongo.TEXT)])
|
||||
print("sskj2 to mongo: {} entries in {:.2f}s".format(
|
||||
len(divs), time() - tstart))
|
||||
return None
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# slownet_path = "../../data/slownet/slownet-2015-05-07.xml"
|
||||
# slownet_to_mongo(slownet_path)
|
||||
|
||||
# scrape_sskj()
|
||||
|
||||
# sskj_path = "../../data/sskj/sskj.p5.xml"
|
||||
# sskj_to_mongo(sskj_path)
|
||||
|
||||
# first file for testing, the original file takes up most of RAM
|
||||
# sskj2_path = "../../data/sskj/sskj2_200.html"
|
||||
# sskj2_path = "../../data/sskj/sskj2_v1.html"
|
||||
# sskj2_to_mongo(sskj2_path)
|
||||
|
||||
print("nothing here")
|
239
src_diploma/valency/reduce_functions.py
Normal file
239
src_diploma/valency/reduce_functions.py
Normal file
|
@ -0,0 +1,239 @@
|
|||
# Reduction function for frames.
|
||||
# Input: list of Frame objects, output: list of Frame objects.
|
||||
# App uses reduce_0, 1 and 5
|
||||
|
||||
from valency.frame import Frame, Slot
|
||||
from copy import deepcopy as DC
|
||||
import logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
SENSE_UNDEFINED = "nedefinirano"
|
||||
|
||||
|
||||
def sorted_by_len_tids(frames):
|
||||
return sorted(
|
||||
frames,
|
||||
key=lambda x: len(x.tids),
|
||||
reverse=True
|
||||
)
|
||||
|
||||
|
||||
def reduce_0(frames, vallex=None):
|
||||
# new request... frames should be sorded by
|
||||
# functors list (basically reduce_1, just each
|
||||
# sentence gets its own frame)
|
||||
r1_frames = reduce_1(frames)
|
||||
sorting_strings = []
|
||||
separated_frames = []
|
||||
for frame in r1_frames:
|
||||
for tid in frame.tids:
|
||||
tmp_frame = DC(frame)
|
||||
tmp_frame.tids = [tid]
|
||||
separated_frames.append(tmp_frame)
|
||||
sorting_strings.append("".join(
|
||||
[slot.functor for slot in tmp_frame.slots]
|
||||
))
|
||||
permutation = [x for _, x in sorted(
|
||||
zip(sorting_strings, range(len(sorting_strings))))]
|
||||
sorted_sep_frames = [separated_frames[i] for i in permutation]
|
||||
return sorted_sep_frames
|
||||
|
||||
|
||||
def reduce_1(frames, vallex=None):
|
||||
# Combine frames with the same set of functors.
|
||||
# The order of functors is not important.
|
||||
frame_sets = [] # [set of functors, list of frames]
|
||||
for frame in frames:
|
||||
functors = [slot.functor for slot in frame.slots]
|
||||
|
||||
for fs in frame_sets:
|
||||
if set(functors) == set(fs[0]):
|
||||
fs[1].append(frame)
|
||||
break
|
||||
else:
|
||||
# Python for else -> fires if loop has ended.
|
||||
frame_sets.append([functors, [frame]])
|
||||
|
||||
ret_frames = []
|
||||
for fs in frame_sets:
|
||||
tids = []
|
||||
slots = {}
|
||||
# All possible slots in this frame.
|
||||
for functor in fs[0]:
|
||||
slots[functor] = Slot(functor=functor)
|
||||
# Reduce slots from all frames. (Merge ACT from all frames, ...)
|
||||
for frame in fs[1]:
|
||||
tids += frame.tids
|
||||
for sl in frame.slots:
|
||||
slots[sl.functor].tids += sl.tids
|
||||
slots_list = []
|
||||
for k, e in slots.items():
|
||||
slots_list.append(e)
|
||||
rf = Frame(tids=tids, slots=slots_list)
|
||||
rf.sort_slots()
|
||||
ret_frames.append(rf)
|
||||
return sorted_by_len_tids(ret_frames)
|
||||
|
||||
|
||||
def reduce_3(raw_frames, vallex):
|
||||
# sskj simple lesk ids
|
||||
ssj_ids = [frame.tids[0] for frame in raw_frames]
|
||||
db_results = list(vallex.db.sskj_simple_lesk.find(
|
||||
{"ssj_id": {"$in": ssj_ids}}))
|
||||
id_map = {}
|
||||
for entry in db_results:
|
||||
id_map.update({entry["ssj_id"]: {
|
||||
"sense_id": entry.get("sense_id"),
|
||||
"sense_desc": entry.get("sense_desc")
|
||||
}})
|
||||
return frames_from_sense_ids(raw_frames, id_map)
|
||||
|
||||
|
||||
def reduce_4(raw_frames, vallex):
|
||||
# kmeans ids
|
||||
ssj_ids = [frame.tids[0] for frame in raw_frames]
|
||||
db_results = list(vallex.db.kmeans.find(
|
||||
{"ssj_id": {"$in": ssj_ids}}))
|
||||
id_map = {}
|
||||
for entry in db_results:
|
||||
id_map.update({entry["ssj_id"]: {
|
||||
"sense_id": entry["sense_id"]
|
||||
}})
|
||||
return frames_from_sense_ids(raw_frames, id_map)
|
||||
|
||||
|
||||
def reduce_5(raw_frames, vallex):
|
||||
USER_SENSE_COLL = "v2_sense_map"
|
||||
headword = raw_frames[0].hw
|
||||
ssj_ids_full = [frame.tids[0] for frame in raw_frames]
|
||||
# v2_sense_map stores only sentence half of ssj_id
|
||||
ssj_ids = [".".join(ssj_id.split(".")[:-1]) for ssj_id in ssj_ids_full]
|
||||
db_results = list(vallex.db[USER_SENSE_COLL].find({
|
||||
"ssj_id": {"$in": ssj_ids},
|
||||
"hw": headword,
|
||||
}))
|
||||
id_map = {}
|
||||
for entry in db_results:
|
||||
id_map[entry["ssj_id"]] = entry["sense_id"]
|
||||
|
||||
ret_frames = frames_from_sense_ids(raw_frames, id_map)
|
||||
|
||||
# sort: frames with senses to top
|
||||
senses_undefined = []
|
||||
senses_defined = []
|
||||
for frame in ret_frames:
|
||||
if frame.sense_info["sense_id"] == SENSE_UNDEFINED:
|
||||
senses_undefined.append(frame)
|
||||
else:
|
||||
senses_defined.append(frame)
|
||||
ret_frames = senses_defined + senses_undefined
|
||||
|
||||
return ret_frames
|
||||
|
||||
|
||||
def frames_from_sense_ids(raw_frames, id_map):
|
||||
# id map = dict {
|
||||
# ssj_id: sense_id
|
||||
# }
|
||||
# id_dict = dict {
|
||||
# sense_id: [frame, ...]
|
||||
# }
|
||||
id_dict = {}
|
||||
for frame in raw_frames:
|
||||
# long version ssj_id (S123.t12)
|
||||
frame_ssj_id = frame.tids[0]
|
||||
frame_sense_id = id_map.get(frame_ssj_id)
|
||||
if frame_sense_id is None:
|
||||
# try short version ssj_id (S123)
|
||||
frame_ssj_id = ".".join(frame_ssj_id.split(".")[:-1])
|
||||
frame_sense_id = id_map.get(frame_ssj_id)
|
||||
|
||||
# set default if sense_id not found
|
||||
if frame_sense_id is None:
|
||||
frame_sense_id = SENSE_UNDEFINED
|
||||
"""
|
||||
sense_id = id_map.get(frame.tids[0])
|
||||
if sense_id is not None:
|
||||
sense_id = sense_id.get("sense_id")
|
||||
else:
|
||||
sense_id = "nedefinirano"
|
||||
"""
|
||||
if frame_sense_id not in id_dict:
|
||||
id_dict[frame_sense_id] = []
|
||||
id_dict[frame_sense_id].append(DC(frame))
|
||||
|
||||
ret_frames = []
|
||||
for sense_id, frames in id_dict.items():
|
||||
tids = []
|
||||
reduced_slots = []
|
||||
for frame in frames:
|
||||
tids.extend(frame.tids)
|
||||
for slot in frame.slots:
|
||||
# if functor not in reduced slots,
|
||||
# add new slot; else increase count
|
||||
for rslot in reduced_slots:
|
||||
if slot.functor == rslot.functor:
|
||||
rslot.count += 1
|
||||
rslot.tids.extend(slot.tids)
|
||||
break
|
||||
else:
|
||||
# in case for loop didn't match a slot
|
||||
reduced_slots.append(Slot(
|
||||
functor=slot.functor,
|
||||
tids=slot.tids,
|
||||
count=1
|
||||
))
|
||||
reduced_frame = Frame(tids, slots=reduced_slots)
|
||||
id_map_entry = (
|
||||
id_map.get(tids[0]) or
|
||||
id_map.get(".".join(tids[0].split(".")[:-1]))
|
||||
)
|
||||
if id_map_entry is None:
|
||||
reduced_frame.sense_info = {
|
||||
"sense_id": SENSE_UNDEFINED,
|
||||
}
|
||||
else:
|
||||
reduced_frame.sense_info = {
|
||||
"sense_id": id_map_entry
|
||||
}
|
||||
reduced_frame.sort_slots()
|
||||
ret_frames.append(reduced_frame)
|
||||
return ret_frames
|
||||
|
||||
|
||||
reduce_functions = {
|
||||
"reduce_0": {
|
||||
"f": reduce_0,
|
||||
"desc":
|
||||
"Vsaka pojavitev glagola dobi svoj stavčni vzorec.",
|
||||
"simple_name": "posamezni stavki"
|
||||
},
|
||||
"reduce_1": {
|
||||
"f": reduce_1,
|
||||
"desc":
|
||||
"Združevanje stavčnih vzorcev z enako skupino udeleženskih vlog.",
|
||||
"simple_name": "združeni stavki"
|
||||
},
|
||||
"reduce_3": {
|
||||
"f": reduce_3,
|
||||
"desc":
|
||||
"Združevanje stavčnih vzorcev na osnovi pomenov povedi v SSKJ. "
|
||||
"Pomeni so dodeljeni s pomočjo algoritma Simple Lesk.",
|
||||
"simple_name": "SSKJ_pomeni"
|
||||
},
|
||||
"reduce_4": {
|
||||
"f": reduce_4,
|
||||
"desc":
|
||||
"Združevanje stavčnih vzorcev na osnovi pomenov povedi "
|
||||
"s pomočjo algoritma K-Means. Število predvidenih pomenov "
|
||||
"podano na osnovi SSKJ.",
|
||||
"simple_name": "KMeans_pomeni"
|
||||
},
|
||||
"reduce_5": {
|
||||
"f": reduce_5,
|
||||
"desc":
|
||||
"Uporabniško dodeljeni pomeni povedi.",
|
||||
"simple_name": "po meri"
|
||||
}
|
||||
}
|
0
src_diploma/valency/seqparser/__init__.py
Normal file
0
src_diploma/valency/seqparser/__init__.py
Normal file
284
src_diploma/valency/seqparser/seqparser.py
Normal file
284
src_diploma/valency/seqparser/seqparser.py
Normal file
|
@ -0,0 +1,284 @@
|
|||
from bs4 import BeautifulSoup as BS
|
||||
import re
|
||||
from collections import defaultdict
|
||||
from time import time
|
||||
import pickle
|
||||
import json
|
||||
from copy import deepcopy as DC
|
||||
|
||||
# Match sese ordinals (1., 2., ...)
|
||||
rord = re.compile(r"^ *[0-9]+\. *$")
|
||||
|
||||
# Get rid of accented characters.
|
||||
intab = "ÁÉÍÓÚàáäçèéêìíîñòóôöùúüčŔŕ"
|
||||
outtb = "AEIOUaaaceeeiiinoooouuučRr"
|
||||
transtab = str.maketrans(intab, outtb)
|
||||
|
||||
|
||||
class Seqparser:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
# main functions
|
||||
def html_to_raw_pickle(self, sskj_html_filepath, raw_pickle_filepath):
|
||||
entries = dict(self.parse_file(sskj_html_filepath, self.parse_line))
|
||||
print("entries len: " + str(len(entries)))
|
||||
with open(raw_pickle_filepath, "wb") as f:
|
||||
tmpstr = json.dumps(dict(entries))
|
||||
pickle.dump(tmpstr, f)
|
||||
# debugging
|
||||
|
||||
def raw_pickle_to_parsed_pickle(
|
||||
self, raw_pickle_filepath, parsed_pickle_filepath,
|
||||
se_list_filepath
|
||||
):
|
||||
data = self.load_raw_pickle(raw_pickle_filepath)
|
||||
print("raw_pickle data len: " + str(len(data)))
|
||||
se_list = self.gen_se_list(data)
|
||||
print("se_list len: " + str(len(se_list)))
|
||||
with open(se_list_filepath, "wb") as f:
|
||||
pickle.dump(se_list, f)
|
||||
data1 = self.remove_se(data)
|
||||
data2 = self.reorganize(data1, se_list)
|
||||
print("data2 len: " + str(len(data2.keys())))
|
||||
with open(parsed_pickle_filepath, "wb") as f:
|
||||
pickle.dump(data2, f)
|
||||
|
||||
# helper html reading functions
|
||||
def parse_file(self, path, f_parse_line):
|
||||
tstart = time()
|
||||
entries = defaultdict(list)
|
||||
with open(path, "r") as f:
|
||||
for line in f:
|
||||
data = f_parse_line(line)
|
||||
if data is not None:
|
||||
entries[data["izt_clean"]].append(data)
|
||||
print("parse_file({}) in {:.2f}s".format(path, time() - tstart))
|
||||
return entries
|
||||
|
||||
def parse_line(self, line):
|
||||
def helper_bv_set(g_or_p):
|
||||
if g_or_p not in ["G", "P"]:
|
||||
print("Err g_or_p.")
|
||||
exit(1)
|
||||
if data.get("bv") is not None:
|
||||
if data["bv"] != g_or_p:
|
||||
print(str(line))
|
||||
# exit(1)
|
||||
data["bv"] = g_or_p
|
||||
data = {
|
||||
"izt": "",
|
||||
"izt_clean": "",
|
||||
"senses": defaultdict(list)
|
||||
}
|
||||
soup = BS(line, "html.parser")
|
||||
|
||||
current_sense_id = "0"
|
||||
for span in soup.find_all("span"):
|
||||
|
||||
# sense id
|
||||
if span.string is not None:
|
||||
rmatch = rord.match(span.string)
|
||||
if rmatch is not None:
|
||||
current_sense_id = rmatch.group().strip()
|
||||
|
||||
title = span.attrs.get("title")
|
||||
if title is not None:
|
||||
title = title.lower()
|
||||
|
||||
# only verbs and adjectives
|
||||
if "glagol" in title:
|
||||
helper_bv_set("G")
|
||||
data["bv_full"] = title
|
||||
elif "pridevn" in title:
|
||||
helper_bv_set("P")
|
||||
data["bv_full"] = title
|
||||
|
||||
# žšč
|
||||
if title == "iztočnica":
|
||||
data["izt"] = span.string
|
||||
data["izt_clean"] = span.string.translate(transtab).lower()
|
||||
|
||||
# sense description
|
||||
if title == "razlaga" and span.string is not None:
|
||||
data["senses"][current_sense_id].append(
|
||||
("razl", span.string))
|
||||
if "pridevnik od" in span.string:
|
||||
helper_bv_set("P")
|
||||
|
||||
if title == "sopomenka":
|
||||
subspan = span.find_all("a")[0]
|
||||
if subspan.string is not None:
|
||||
data["senses"][current_sense_id].append(
|
||||
("sopo", subspan.string))
|
||||
|
||||
# save verbs and adjectives
|
||||
if (
|
||||
("bv" not in data) or
|
||||
(data["bv"] != "P" and data["bv"] != "G")
|
||||
):
|
||||
return None
|
||||
|
||||
# sanity check
|
||||
if data["bv"] == "P" and " se" in data["izt_clean"]:
|
||||
print(data)
|
||||
exit(1)
|
||||
|
||||
# append _ to adjective keywords
|
||||
if data["bv"] == "P":
|
||||
data["izt_clean"] = data["izt_clean"] + "_"
|
||||
|
||||
# cleanup
|
||||
if "bv" not in data:
|
||||
print("Should not be here (no bv).")
|
||||
exit(1)
|
||||
del(data["bv"])
|
||||
if "bv_full" in data:
|
||||
del(data["bv_full"])
|
||||
|
||||
return data
|
||||
|
||||
# helper functions
|
||||
def load_raw_pickle(self, raw_pickle_filepath):
|
||||
with open(raw_pickle_filepath, "rb") as f:
|
||||
tmpstr = pickle.load(f)
|
||||
return json.loads(tmpstr)
|
||||
|
||||
def helper_loop(self, data, fnc):
|
||||
for k, lst in data.items():
|
||||
for el in lst:
|
||||
fnc(el)
|
||||
|
||||
def gen_se_list(self, data):
|
||||
|
||||
def fnc1(el):
|
||||
ic = el["izt_clean"]
|
||||
if " se" in ic:
|
||||
se_list.append(ic)
|
||||
|
||||
def fnc2(el):
|
||||
ic = el["izt_clean"]
|
||||
if ic in se_pruned:
|
||||
se_pruned.remove(ic)
|
||||
|
||||
# hw entries that only exist with " se"
|
||||
se_list = []
|
||||
self.helper_loop(data, fnc1)
|
||||
se_pruned = set([hw.split(" se")[0] for hw in se_list])
|
||||
self.helper_loop(data, fnc2)
|
||||
return sorted(list(se_pruned))
|
||||
|
||||
def remove_se(self, data):
|
||||
|
||||
def fnc1(el):
|
||||
nel = DC(el)
|
||||
ic = nel["izt_clean"]
|
||||
if " se" in ic:
|
||||
nic = ic.split(" se")[0]
|
||||
nel["izt_clean"] = nic
|
||||
data_new[nel["izt_clean"]].append(nel)
|
||||
|
||||
data_new = defaultdict(list)
|
||||
self.helper_loop(data, fnc1)
|
||||
return dict(data_new)
|
||||
|
||||
def reorganize(self, data, se_list):
|
||||
# some hw entries have several headwords,
|
||||
# some senses have subsenses
|
||||
# index everything, make 1 object per hw
|
||||
|
||||
def helper_prune(sense_str):
|
||||
# remove space padding
|
||||
sense_str = sense_str.strip()
|
||||
|
||||
if len(sense_str) == 1:
|
||||
return sense_str
|
||||
|
||||
# remove banned characters from string ending
|
||||
banned = ": ; . , - ! ?".split(" ")
|
||||
if sense_str[-1] in banned:
|
||||
return sense_str[:-1]
|
||||
|
||||
return sense_str
|
||||
|
||||
data_new = {}
|
||||
for k, lst in data.items():
|
||||
new_el = {
|
||||
"hw": k,
|
||||
"has_se": k in se_list,
|
||||
"senses": []
|
||||
}
|
||||
|
||||
# if there is a single hw entry, hw_id is 0
|
||||
if len(lst) == 1:
|
||||
homonym_id = -1
|
||||
else:
|
||||
homonym_id = 0
|
||||
|
||||
# loop homonyms
|
||||
for el in lst:
|
||||
homonym_id += 1
|
||||
# loop top lvl sense ids
|
||||
for sense_id, sens_lst in el["senses"].items():
|
||||
# loop subsenses
|
||||
for i, sens in enumerate(sens_lst):
|
||||
nsid = sense_id.split(".")[0]
|
||||
if len(sens_lst) == 1:
|
||||
nsid += "-0"
|
||||
else:
|
||||
nsid += ("-" + str(i + 1))
|
||||
new_sense = {
|
||||
"homonym_id": homonym_id,
|
||||
# sense_id: sense_id-subsense_id
|
||||
"sense_id": nsid,
|
||||
"sense_type": sens[0],
|
||||
"sense_desc": helper_prune(sens[1]),
|
||||
}
|
||||
new_el["senses"].append(new_sense)
|
||||
hw = new_el["hw"]
|
||||
if hw in data_new:
|
||||
print("Shouldn't be here.")
|
||||
print(new_el)
|
||||
exit(1)
|
||||
data_new[hw] = DC(new_el)
|
||||
# return data_new
|
||||
|
||||
# check
|
||||
for hw, el in data_new.items():
|
||||
for sens in el["senses"]:
|
||||
if sens["sense_desc"] is None:
|
||||
print(sens)
|
||||
|
||||
return data_new
|
||||
|
||||
|
||||
def plst(lst):
|
||||
for el in lst:
|
||||
print(el)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
datapath = "../../../data"
|
||||
html_filepath = datapath + "/sskj/sskj2_v1.html"
|
||||
raw_pickle_filepath = datapath + "/tmp_pickles/raw_sskj.pickle"
|
||||
parsed_pickle_filepath = datapath + "/no_del_pickles/sskj_senses.pickle"
|
||||
se_list_filepath = datapath + "/no_del_pickles/se_list.pickle"
|
||||
|
||||
p = Seqparser()
|
||||
|
||||
if True:
|
||||
print("html_to_raw_pickle({}, {})".format(
|
||||
html_filepath, raw_pickle_filepath))
|
||||
print("Big file, this might take a while (2 min).")
|
||||
tstart = time()
|
||||
p.html_to_raw_pickle(html_filepath, raw_pickle_filepath)
|
||||
print("Finished in {:.2f}.".format(time() - tstart))
|
||||
|
||||
if True:
|
||||
print("raw_pickle_to_parsed_pickle({}, {}, {})".format(
|
||||
raw_pickle_filepath, parsed_pickle_filepath, se_list_filepath))
|
||||
tstart = time()
|
||||
p.raw_pickle_to_parsed_pickle(
|
||||
raw_pickle_filepath, parsed_pickle_filepath, se_list_filepath)
|
||||
print("Finished in {:.2f}.".format(time() - tstart))
|
||||
print("Done.")
|
218
src_diploma/valency/ssj_struct.py
Normal file
218
src_diploma/valency/ssj_struct.py
Normal file
|
@ -0,0 +1,218 @@
|
|||
import xml.etree.ElementTree as ET
|
||||
from copy import deepcopy as DC
|
||||
from time import time
|
||||
import re
|
||||
import logging
|
||||
import sys
|
||||
import pickle
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
ET.register_namespace("xml", "http://www.w3.org/XML/1998/namespace")
|
||||
XML_ID = "{http://www.w3.org/XML/1998/namespace}id"
|
||||
|
||||
|
||||
# |$ for a default empty match
|
||||
re_int = re.compile(r"t\d+|$")
|
||||
|
||||
|
||||
# For sorting a "s" section in ssj; returns key as integer.
|
||||
# example: "S123.t34" --> 34
|
||||
def re_lmbd(el):
|
||||
s = re_int.findall(el)[0]
|
||||
if len(s) == 0:
|
||||
return 0
|
||||
else:
|
||||
return int(s[1:])
|
||||
|
||||
|
||||
class SsjEntry:
|
||||
def __init__(self, ssj_id, s, deep_links):
|
||||
# See ssj xml structure.
|
||||
self.id = ssj_id
|
||||
self.s = DC(s)
|
||||
self.deep_links = DC(deep_links)
|
||||
|
||||
|
||||
class SsjDict:
|
||||
def __init__(self):
|
||||
self.entries = {}
|
||||
|
||||
"""
|
||||
def read_xml(self, filepath):
|
||||
# No data loss.
|
||||
log.info("SsjDict.read_xml({})".format(filepath))
|
||||
t_start = time()
|
||||
tree = ET.parse(filepath)
|
||||
root = tree.getroot()
|
||||
stats = {
|
||||
"skipped": [],
|
||||
"duplicates": []
|
||||
}
|
||||
|
||||
for s in root.iter("s"):
|
||||
s_id = s.attrib[XML_ID]
|
||||
tokens = {}
|
||||
for token in s:
|
||||
if token.tag == "linkGrp":
|
||||
continue
|
||||
|
||||
if token.tag == "w":
|
||||
tokens[token.attrib[XML_ID]] = {
|
||||
"msd": token.attrib["msd"],
|
||||
"lemma": token.attrib["lemma"],
|
||||
"word": token.text
|
||||
}
|
||||
elif token.tag == "c":
|
||||
tokens[token.attrib[XML_ID]] = {
|
||||
"word": token.text
|
||||
}
|
||||
else:
|
||||
# <S />
|
||||
pass
|
||||
|
||||
linkGrps = s.findall("linkGrp")
|
||||
if len(linkGrps) < 2:
|
||||
# Take only entries with both deep and shallow
|
||||
# syntactic annotation
|
||||
stats["skipped"].append(s_id)
|
||||
continue
|
||||
|
||||
linkG = {}
|
||||
for el in linkGrps:
|
||||
if el.attrib["type"] == "dep":
|
||||
linkG["dep"] = el
|
||||
elif el.attrib["type"] == "SRL":
|
||||
linkG["SRL"] = el
|
||||
else:
|
||||
raise KeyError("Unknown linkGrp.")
|
||||
|
||||
if s_id in self.entries:
|
||||
stats["duplicates"].append(s_id)
|
||||
self.entries[s_id] = SsjEntry(
|
||||
s_id,
|
||||
s.attrib["n"],
|
||||
tokens,
|
||||
create_edge_dict(linkG["dep"]),
|
||||
create_edge_dict(linkG["SRL"])
|
||||
)
|
||||
|
||||
t_end = time()
|
||||
log.info("Time: {}s.".format(t_end - t_start))
|
||||
log.info(
|
||||
"{} duplicates, skipped {} elements (missing linkGrp).".format(
|
||||
len(stats["duplicates"]), len(stats["skipped"]))
|
||||
)
|
||||
"""
|
||||
|
||||
def read_xml_v2(self, filepath):
|
||||
NS_DICT = {
|
||||
"tei": "http://www.tei-c.org/ns/1.0",
|
||||
"xml": "http://www.w3.org/XML/1998/namespace",
|
||||
}
|
||||
|
||||
def ns_prefix(ns):
|
||||
return "{" + NS_DICT[ns] + "}"
|
||||
|
||||
def helper_get_sentence(tree_s):
|
||||
# all w and pc elements
|
||||
ret = []
|
||||
for el in tree_s.iter():
|
||||
if (
|
||||
el.tag == ns_prefix("tei") + "w" or
|
||||
el.tag == ns_prefix("tei") + "pc"
|
||||
):
|
||||
ret.append(el)
|
||||
return ret
|
||||
|
||||
def helper_get_functor_links(tree_s):
|
||||
# links for SRL linkGrp
|
||||
lg = None
|
||||
for linkGrp in tree_s.findall("tei:linkGrp", NS_DICT):
|
||||
if linkGrp.attrib["type"] == "SRL":
|
||||
lg = linkGrp
|
||||
break
|
||||
else:
|
||||
return []
|
||||
ret = []
|
||||
for link in lg:
|
||||
ret.append(link)
|
||||
return ret
|
||||
|
||||
def helper_gen_deep_links(link_list):
|
||||
deep_links = []
|
||||
for link in link_list:
|
||||
deep_links.append({
|
||||
"from": link.attrib["target"].split(" ")[0][1:],
|
||||
"to": link.attrib["target"].split(" ")[1][1:],
|
||||
"functor": link.attrib["ana"].split(":")[1]
|
||||
})
|
||||
return deep_links
|
||||
|
||||
log.info("SsjDict.read_xml({})".format(filepath))
|
||||
t_start = time()
|
||||
stats = {
|
||||
"total_count": 0,
|
||||
"deep_roles_count": 0,
|
||||
"duplicated_sid": 0,
|
||||
}
|
||||
tree = ET.parse(filepath)
|
||||
root = tree.getroot()
|
||||
|
||||
for s in root.findall(".//tei:s", NS_DICT):
|
||||
stats["total_count"] += 1
|
||||
s_id = s.attrib[ns_prefix("xml") + "id"]
|
||||
|
||||
# get_functors (deep semantic roles)
|
||||
functor_links = helper_get_functor_links(s)
|
||||
if len(functor_links) == 0:
|
||||
continue
|
||||
stats["deep_roles_count"] += 1
|
||||
|
||||
# get_sentence
|
||||
tokens = {}
|
||||
for token in helper_get_sentence(s):
|
||||
tid = token.attrib[ns_prefix("xml") + "id"]
|
||||
if token.tag == ns_prefix("tei") + "w":
|
||||
tokens[tid] = {
|
||||
"msd": token.attrib["ana"].split(":")[1],
|
||||
"lemma": token.attrib["lemma"],
|
||||
"word": token.text
|
||||
}
|
||||
elif token.tag == ns_prefix("tei") + "pc":
|
||||
tokens[tid] = {
|
||||
"word": token.text
|
||||
}
|
||||
else:
|
||||
log.warning("Unrecognized sentence element: " + token.tag)
|
||||
exit(1)
|
||||
|
||||
if s_id in self.entries:
|
||||
log.warning("duplicated sentence: " + s_id)
|
||||
stats["duplicated_sid"] += 1
|
||||
continue
|
||||
|
||||
self.entries[s_id] = SsjEntry(
|
||||
s_id,
|
||||
tokens,
|
||||
helper_gen_deep_links(functor_links)
|
||||
)
|
||||
|
||||
t_end = time()
|
||||
log.info("Time: {}s.".format(t_end - t_start))
|
||||
log.info(str(stats))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# testing
|
||||
log.setLevel(logging.DEBUG)
|
||||
|
||||
ch = logging.StreamHandler(sys.stdout)
|
||||
log.addHandler(ch)
|
||||
|
||||
# Load
|
||||
fpath = "../../data/ssj500k-sl.TEI/ssj500k-sl.body.xml"
|
||||
ssj = SsjDict()
|
||||
ssj.read_xml_v2(fpath)
|
||||
with open("ssj_test.pickle", "wb") as file:
|
||||
pickle.dump(ssj, file)
|
47
src_diploma/valency/sskj_scraper.py
Normal file
47
src_diploma/valency/sskj_scraper.py
Normal file
|
@ -0,0 +1,47 @@
|
|||
# Deprecated!
|
||||
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
from time import time
|
||||
from valency import k_utils
|
||||
|
||||
SSKJ_BASE = "http://bos.zrc-sazu.si/cgi/a03.exe?name=sskj_testa&expression="
|
||||
|
||||
|
||||
class SskjScraper:
|
||||
def __init__(self):
|
||||
self.base_url = SSKJ_BASE
|
||||
|
||||
def scrape(self, word):
|
||||
# returns unique set of words
|
||||
soup = BeautifulSoup(
|
||||
requests.get(self.base_url + word).content,
|
||||
"html.parser"
|
||||
)
|
||||
# Check for failure.
|
||||
h2 = soup.find_all("h2")
|
||||
if len(h2) >= 2:
|
||||
# <h2>Zadetkov ni bilo: ...</h2>
|
||||
return []
|
||||
li_elements = soup.find_all('li', class_="nounderline")
|
||||
if len(li_elements) == 0:
|
||||
return []
|
||||
li = li_elements[0]
|
||||
# It was horrible...
|
||||
# <li> ... <li> ... <li> ...</li></li></li>
|
||||
# Parse sequence until you find a sedond <li>
|
||||
txts = []
|
||||
for el in li.find_all():
|
||||
if el.name == "li":
|
||||
break
|
||||
txts.append(el.get_text())
|
||||
print("sskj scraped {}.".format(word))
|
||||
return k_utils.tokenize(txts)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sskjScr = SskjScraper()
|
||||
|
||||
word = "tek"
|
||||
tp = sskjScr.scrape("čaj")
|
||||
print(tp)
|
40
src_diploma/valency/testing_lesk.py
Normal file
40
src_diploma/valency/testing_lesk.py
Normal file
|
@ -0,0 +1,40 @@
|
|||
from valency.val_struct import *
|
||||
from valency.ssj_struct import *
|
||||
from valency import k_utils
|
||||
from valency.lesk import Lesk
|
||||
|
||||
vallex_path = "../../data/vallex.xml"
|
||||
vallex = k_utils.pickle_load(vallex_path)
|
||||
if vallex is None:
|
||||
ssj_path = "../../data/anno_final.conll.xml"
|
||||
# ssj_path = "../../data/ssj500kv1_1-SRL_500_stavkov_2017-04-11.xml"
|
||||
ssj = k_utils.pickle_load(ssj_path)
|
||||
if ssj is None:
|
||||
ssj = SsjDict()
|
||||
ssj.read_xml(ssj_path)
|
||||
k_utils.pickle_dump(ssj, ssj_path)
|
||||
|
||||
vallex = Vallex()
|
||||
vallex.read_ssj(ssj)
|
||||
k_utils.pickle_dump(vallex, vallex_path)
|
||||
|
||||
vallex.process_after_read(False, False)
|
||||
|
||||
random_frame = None
|
||||
lesk = Lesk()
|
||||
successes = 0
|
||||
for k, e in vallex.entries.items():
|
||||
for rf in e.raw_frames:
|
||||
random_frame = rf
|
||||
break
|
||||
print(rf.to_string())
|
||||
print(vallex.get_token(random_frame.tids[0]))
|
||||
print(vallex.get_sentence(random_frame.tids[0]))
|
||||
tid = random_frame.tids[0]
|
||||
token = vallex.get_token(tid)
|
||||
context = vallex.get_context(tid)
|
||||
sense = lesk.lesk(token, context)
|
||||
if sense is not None:
|
||||
successes += 1
|
||||
if successes >= 10:
|
||||
break
|
706
src_diploma/valency/val_struct.py
Normal file
706
src_diploma/valency/val_struct.py
Normal file
|
@ -0,0 +1,706 @@
|
|||
from time import time
|
||||
from copy import deepcopy as DC
|
||||
from valency.frame import Frame
|
||||
from valency.reduce_functions import *
|
||||
from valency.lesk import *
|
||||
from valency import mongo_tools
|
||||
import random
|
||||
import logging
|
||||
from valency.evaluation import Evaluation
|
||||
from valency.dictionary_interface import SloWnet, Sskj2
|
||||
from valency.leskFour import LeskFour
|
||||
from valency.k_kmeans import KmeansClass
|
||||
from valency.ssj_struct import SsjDict, SsjEntry
|
||||
from valency.seqparser.seqparser import Seqparser
|
||||
import pickle
|
||||
import sys
|
||||
import hashlib
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def split_id(myid):
|
||||
tmp = myid.split(".")
|
||||
sid = ".".join(tmp[:-1])
|
||||
tid = tmp[-1]
|
||||
return (sid, tid)
|
||||
|
||||
|
||||
class ValEntry():
|
||||
def __init__(self, hw, frame):
|
||||
self.hw = hw
|
||||
self.raw_frames = [frame]
|
||||
self.has_senses = False
|
||||
|
||||
|
||||
class Vallex():
|
||||
# Main class
|
||||
def __init__(self):
|
||||
# database
|
||||
self.db, err_msg = mongo_tools.basic_connection("127.0.0.1", 26633)
|
||||
if self.db is None:
|
||||
log.error((
|
||||
"Database not connected:"
|
||||
"{}".format(err_msg)
|
||||
))
|
||||
exit(1)
|
||||
mongo_tools.check_collections(self.db, [
|
||||
"v2_users", "v2_senses", "v2_sense_map", "v2_user_tokens"
|
||||
])
|
||||
mongo_tools.prepare_user_tokens(self.db)
|
||||
|
||||
# these 3 might be obsolete for the web app (used for ML)
|
||||
self.db_senses_map = self.db.senses_map3
|
||||
self.slownet_interface = SloWnet(self)
|
||||
self.sskj_interface = Sskj2(self)
|
||||
|
||||
# self.tokens["s0][t0"] = {word, lemma, msd, ...}
|
||||
self.tokens = {}
|
||||
|
||||
# key = verb / adjective headword
|
||||
self.entries = {}
|
||||
|
||||
# For alphabetical indexing in web app.
|
||||
self.sorted_words = {}
|
||||
# words = { first_letter: [hw1, hw2, ... sorted] }
|
||||
self.functors_index = {}
|
||||
self.has_se = [] # list of verbs with "se" ("bati se")
|
||||
|
||||
# Used for ML (deprecated).
|
||||
self.leskFour = LeskFour(self)
|
||||
self.kmeans = KmeansClass(self)
|
||||
self.evaluation = Evaluation(self)
|
||||
self.test_samples = []
|
||||
|
||||
# run self.process_after_read() after initiating Vallex
|
||||
|
||||
def read_ssj(self, ssj):
|
||||
# ssj: object generated with ssj_strict.py.
|
||||
BANNED_HW = ["biti"]
|
||||
stats = {
|
||||
"P_count": 0,
|
||||
"skipped": 0,
|
||||
}
|
||||
log.info("Vallex.read_ssj({}).".format(
|
||||
ssj
|
||||
))
|
||||
t_start = time()
|
||||
for ssj_id, entry in ssj.entries.items():
|
||||
# Read tokens
|
||||
skip_entry = False
|
||||
tmp_tokens = {}
|
||||
for ssj_tid, token in entry.s.items():
|
||||
sid, tid = split_id(ssj_tid)
|
||||
|
||||
# safety checks
|
||||
if tid != "t" and not tid[1:].isdigit():
|
||||
log.warning("dropping SID={} - corrupted keys".format(k))
|
||||
skip_entry = True
|
||||
break
|
||||
if tid in tmp_tokens:
|
||||
log.error(
|
||||
"Vallex.read_ssj(): Duplicated ssj_tid:" + ssj_tid)
|
||||
exit(1)
|
||||
|
||||
tmp_tokens[tid] = DC(token)
|
||||
if skip_entry:
|
||||
continue # skip corrupted keys
|
||||
if sid in self.tokens:
|
||||
log.error("sid duplicate: " + sid)
|
||||
exit(1)
|
||||
self.tokens[sid] = DC(tmp_tokens)
|
||||
|
||||
# Read frame data (each deep link gets its own raw frame).
|
||||
link_map = {}
|
||||
# hw_id: { hw_lemma: lemma, deep: [{functor: fnct, to: to}]}
|
||||
for deep_link in entry.deep_links:
|
||||
hw_id = deep_link["from"]
|
||||
hw_token = self.get_token(hw_id)
|
||||
hw_lemma = hw_token["lemma"]
|
||||
hw_bv = hw_token["msd"][0]
|
||||
if (hw_bv != "G" and hw_bv != "P"):
|
||||
stats["skipped"] += 1
|
||||
log.info("Skipping {}: not a verb or adjective.".format(
|
||||
hw_lemma))
|
||||
continue
|
||||
if hw_bv == "P":
|
||||
hw_lemma = hw_lemma + "_"
|
||||
stats["P_count"] += 1
|
||||
if hw_id in link_map:
|
||||
link_map[hw_id]["deep"].append(deep_link)
|
||||
else:
|
||||
link_map[hw_id] = {
|
||||
"hw_lemma": hw_lemma,
|
||||
"deep": [deep_link]
|
||||
}
|
||||
for hw_id, data in link_map.items():
|
||||
hw_lemma = data["hw_lemma"]
|
||||
raw_frame = Frame(
|
||||
hw=hw_lemma,
|
||||
tids=[hw_id],
|
||||
deep_links=data["deep"],
|
||||
slots=None,
|
||||
)
|
||||
if hw_lemma not in self.entries:
|
||||
self.entries[hw_lemma] = ValEntry(hw_lemma, raw_frame)
|
||||
else:
|
||||
self.entries[hw_lemma].raw_frames.append(raw_frame)
|
||||
|
||||
# cleanup banned
|
||||
for hw in BANNED_HW:
|
||||
if hw in self.entries:
|
||||
del(self.entries[hw])
|
||||
|
||||
t_end = time()
|
||||
log.info("Finished build_from_ssj() in {:.2}s.".format(
|
||||
t_end - t_start
|
||||
))
|
||||
log.info("Vallex has a total of {} key entries.".format(
|
||||
len(self.entries.keys())
|
||||
))
|
||||
log.info("Number of adjectives: {}".format(stats["P_count"]))
|
||||
log.info("Number of skipped (not a verb or adjective): {}".format(
|
||||
stats["skipped"]))
|
||||
# Frames per hw
|
||||
"""
|
||||
for k, e in self.entries.items():
|
||||
print(k + "," + str(len(e.raw_frames)))
|
||||
"""
|
||||
|
||||
def get_token(self, myid):
|
||||
# id = S123.t1
|
||||
sid, tid = split_id(myid)
|
||||
return self.tokens[sid][tid]
|
||||
|
||||
def get_sentence(self, myid):
|
||||
sid, tid = split_id(myid)
|
||||
tmp = []
|
||||
sentence = ""
|
||||
for k, token in self.tokens[sid].items():
|
||||
if (k != "t") and (token["word"] is not None):
|
||||
tmp.append((k, token))
|
||||
for token in sorted(tmp, key=lambda x: int(x[0][1:])):
|
||||
sentence += (token[1]["word"] + " ")
|
||||
return sentence
|
||||
|
||||
def get_tokenized_sentence(self, myid):
|
||||
sid, tid = split_id(myid)
|
||||
tmp = []
|
||||
sentence = []
|
||||
for k, token in self.tokens[sid].items():
|
||||
if k != "t":
|
||||
tmp.append((k, token))
|
||||
for token in sorted(tmp, key=lambda x: int(x[0][1:])):
|
||||
sentence.append((".".join([sid, token[0]]), token[1]))
|
||||
# return [(ssj_id, {word: _, lemma: _, msd: _}), ...]
|
||||
return sentence
|
||||
|
||||
def process_after_read(
|
||||
self, sskj_senses_pickle_path, se_list_pickle_path,
|
||||
reload_sskj_senses
|
||||
):
|
||||
tstart = time()
|
||||
|
||||
# web app: index by hw
|
||||
self.sorted_words = {}
|
||||
self.gen_sorted_words()
|
||||
|
||||
# web app: index by functor
|
||||
self.functors_index = {}
|
||||
self.gen_functors_index()
|
||||
|
||||
# fill db.v2_senses
|
||||
self.has_se = []
|
||||
self.read_seqparser_pickles(
|
||||
sskj_senses_pickle_path, se_list_pickle_path, reload_sskj_senses)
|
||||
|
||||
log.debug(
|
||||
"vallex.process_after_read(): {:.2f}s".format(time() - tstart))
|
||||
|
||||
def gen_sorted_words(self):
|
||||
res = {}
|
||||
for hw, e in self.entries.items():
|
||||
letter = hw[0].lower()
|
||||
n_sent = len(e.raw_frames)
|
||||
if letter not in res:
|
||||
res[letter] = []
|
||||
res[letter].append((hw, n_sent))
|
||||
# sort and add to vallex object
|
||||
self.sorted_words = {}
|
||||
for letter, lst in res.items():
|
||||
self.sorted_words[letter] = k_utils.slo_bucket_sort(
|
||||
lst, key=lambda x: x[0])
|
||||
|
||||
def gen_functors_index(self):
|
||||
for hw, e in self.entries.items():
|
||||
for frame in e.raw_frames:
|
||||
for slot in frame.slots:
|
||||
if slot.functor not in self.functors_index:
|
||||
self.functors_index[slot.functor] = []
|
||||
self.functors_index[slot.functor].append(frame)
|
||||
|
||||
def read_seqparser_pickles(
|
||||
self, sskj_senses_pickle_path, se_list_pickle_path,
|
||||
reload_sskj_senses
|
||||
):
|
||||
log.info("read_seqparser_pickles()")
|
||||
log.info((
|
||||
"Reading list of has_se verbs from {}."
|
||||
"Sskj senses into db.v2_senses from {}."
|
||||
).format(se_list_pickle_path, sskj_senses_pickle_path))
|
||||
AUTHOR_SSKJ = "SSKJ"
|
||||
ERR_MSG = (
|
||||
"Need to generate .pickle files first."
|
||||
"Use: "
|
||||
"$ python3 /script/valency/seqparser/seqparser.py"
|
||||
"Input is /data/sskj_v2.html."
|
||||
)
|
||||
|
||||
# has_se
|
||||
with open(se_list_pickle_path, "rb") as f:
|
||||
self.has_se = pickle.load(f)
|
||||
if self.has_se is None:
|
||||
log.error(ERR_MSG)
|
||||
exit(1)
|
||||
self.has_se = sorted(self.has_se)
|
||||
log.info("Loaded self.has_se (len: {}) from {}.".format(
|
||||
len(self.has_se), se_list_pickle_path))
|
||||
|
||||
# sskj senses
|
||||
if reload_sskj_senses:
|
||||
log.info("Reloading sskj_senses.")
|
||||
reply = self.db.v2_senses.remove({"author": AUTHOR_SSKJ})
|
||||
log.info(reply)
|
||||
|
||||
query = list(self.db.v2_senses.find({"author": AUTHOR_SSKJ}))
|
||||
if len(query) > 0:
|
||||
log.info("Sskj senses already in database.")
|
||||
return
|
||||
tstart = time()
|
||||
data = None
|
||||
with open(sskj_senses_pickle_path, "rb") as f:
|
||||
data = pickle.load(f)
|
||||
if data is None:
|
||||
log.error(ERR_MSG)
|
||||
exit(1)
|
||||
for k, e in data.items():
|
||||
for sense in e["senses"]:
|
||||
db_entry = {
|
||||
"hw": k,
|
||||
"author": AUTHOR_SSKJ,
|
||||
"desc": sense["sense_desc"],
|
||||
# unique id for each sense
|
||||
"sense_id": "{}-{}-{}-{}-{}".format(
|
||||
AUTHOR_SSKJ,
|
||||
sense["homonym_id"],
|
||||
sense["sense_id"],
|
||||
sense["sense_type"],
|
||||
hashlib.sha256(
|
||||
sense["sense_desc"].encode("utf-8")
|
||||
).hexdigest()[:5]
|
||||
)
|
||||
}
|
||||
self.db.v2_senses.insert(db_entry)
|
||||
# print(db_entry)
|
||||
log.info("db.v2_senses prepared in {:.2f}s".format(time() - tstart))
|
||||
|
||||
# Functions below can be used for interactively with flask_api.
|
||||
def test_dev(self):
|
||||
# self.prepare_sskj_senses()
|
||||
hw = "dajati"
|
||||
senses = self.sskj_interface.sense_glosses(hw)
|
||||
return str(senses)
|
||||
|
||||
def calc_senses(self):
|
||||
# self.calc_all_senses(self.leskFour.lesk_nltk)
|
||||
# self.calc_all_senses(self.leskFour.lesk_sl)
|
||||
# self.calc_all_senses(self.leskFour.lesk_al) # cca 8h!
|
||||
# self.calc_all_senses(self.leskFour.lesk_ram)
|
||||
self.calc_all_senses_kmeans(self.kmeans.bisection_kmeans)
|
||||
self.calc_all_senses_kmeans(self.kmeans.normal_kmeans)
|
||||
return "edit val_struct.py: calc_senses()"
|
||||
|
||||
# deprecated functions (used for machine learning experiments)
|
||||
|
||||
def prepare_sskj_senses(self):
|
||||
# obsolete, using read_seqparser_pickles()
|
||||
log.info("prepare_sskj_senses() (db.v2_senses)")
|
||||
query = list(self.db.v2_senses.find({"author": "SSKJ2"}))
|
||||
if len(query) > 0:
|
||||
log.info("Sskj senses already in database.")
|
||||
return
|
||||
tstart = time()
|
||||
log.info("Iterating over {} hw entries:".format(
|
||||
len(self.entries.keys())))
|
||||
for hw, e in self.entries.items():
|
||||
senses = self.sskj_interface.sense_glosses(hw)
|
||||
if len(senses) == 0:
|
||||
continue
|
||||
for sense in senses:
|
||||
# create sense from each description
|
||||
for i, de in enumerate(sense["def"]):
|
||||
sense_def = sense["def"][i]
|
||||
sense_def = sense_def[0].upper() + sense_def[1:]
|
||||
if sense_def[-1] == ":" or sense_def[-1] == ";":
|
||||
sense_def = sense_def[:-1] + "."
|
||||
data = {
|
||||
"hw": hw,
|
||||
"author": "SSKJ2",
|
||||
"desc": sense_def,
|
||||
"sskj_id": sense["sskj_sense_id"],
|
||||
"sskj_desc_id": i
|
||||
}
|
||||
self.db.v2_senses.insert(data)
|
||||
log.info("sskj_senses prepared in {:.2f}s".format(time() - tstart))
|
||||
|
||||
def gen_sskj_sl(self):
|
||||
# Takes about an hour.
|
||||
tstart = time()
|
||||
log.info("Generating new sskj_simple_lesk with Simple Lesk.")
|
||||
for k, e in self.entries.items():
|
||||
self.gen_sskj_sl_one(e.hw)
|
||||
log.debug("gen_sskj_sl in {:.2f}s".format(time() - tstart))
|
||||
|
||||
def gen_sskj_sl_one(self, hw, update_db=True):
|
||||
entry = None
|
||||
ttstart = time()
|
||||
e = self.entries.get(hw)
|
||||
if e is None:
|
||||
return
|
||||
for frame in e.raw_frames:
|
||||
tid = frame.tids[0]
|
||||
sentence = self.get_sentence(tid)
|
||||
res = self.lesk.simple_lesk_sskj(sentence, hw)
|
||||
if res is None:
|
||||
log.debug("headword {} not in sskj".format(hw))
|
||||
continue
|
||||
key = {"ssj_id": tid}
|
||||
entry = {
|
||||
"headword": hw,
|
||||
"ssj_id": tid, # uniqe identifier
|
||||
"sense_id": res[1],
|
||||
# "sense_desc": k_utils.dict_safe_key(res[2], "ns0:def"),
|
||||
"sense_desc": res[2]["def"]
|
||||
}
|
||||
# log.debug(str(res[2]))
|
||||
# log.debug(entry["sense_id"])
|
||||
# log.debug(entry["sense_desc"])
|
||||
if update_db:
|
||||
self.db.sskj_simple_lesk.update(key, entry, upsert=True)
|
||||
log.debug("[*] sskj_ids for {} in {:.2f}s".format(
|
||||
hw, time() - ttstart))
|
||||
|
||||
def get_context(self, myid, radius=None, min_lemma_size=None):
|
||||
radius = radius or 5
|
||||
min_lemma_size = min_lemma_size or 4
|
||||
# gives you the token and 10 of its neighbors
|
||||
sentence = self.get_sentence(myid)
|
||||
sentlen = len(sentence.split(" "))
|
||||
sid, tid = split_id(myid)
|
||||
idx = int(tid[1:])
|
||||
tokens_after = []
|
||||
i = idx
|
||||
while i < sentlen - 1 and len(tokens_after) < radius:
|
||||
i += 1
|
||||
token = self.get_token(sid + ".t" + str(i))
|
||||
if (
|
||||
token is not None and "lemma" in token and
|
||||
len(token["lemma"]) >= min_lemma_size and
|
||||
token["lemma"] != "biti"
|
||||
):
|
||||
tokens_after.append(token)
|
||||
tokens_before = []
|
||||
i = idx
|
||||
while i > 1 and len(tokens_before) < radius:
|
||||
i -= 1
|
||||
token = self.get_token(sid + ".t" + str(i))
|
||||
if (
|
||||
token is not None and "lemma" in token and
|
||||
len(token["lemma"]) >= min_lemma_size and
|
||||
token["lemma"] != "biti"
|
||||
):
|
||||
tokens_before.append(token)
|
||||
tokens = tokens_before + [self.get_token(myid)] + tokens_after
|
||||
# find position of original token:
|
||||
mid_idx = len(tokens_before)
|
||||
return (mid_idx, tokens)
|
||||
|
||||
def get_sense_ids(self, collname, hw, sense_group=None):
|
||||
query = {"headword": hw}
|
||||
if sense_group is not None:
|
||||
query["sense_group"] = sense_group
|
||||
result = list(self.db[collname].find(query))
|
||||
sense_ids = {}
|
||||
for r in result:
|
||||
sense_ids[r["ssj_id"]] = r["sense_id"]
|
||||
return sense_ids
|
||||
|
||||
def t_get_context(self):
|
||||
ii = 10
|
||||
for k, e in self.entries.items():
|
||||
for frame in e.raw_frames:
|
||||
if random.randint(0, 100) > 20:
|
||||
continue
|
||||
ii -= 1
|
||||
if ii <= 0:
|
||||
return
|
||||
|
||||
mytid = frame.tids[0]
|
||||
print()
|
||||
print(mytid)
|
||||
print(self.get_token(mytid))
|
||||
sent = self.get_context(mytid, radius=3, min_lemma_size=4)
|
||||
print("mid: {}".format(sent[0]))
|
||||
for ii in range(len(sent[1])):
|
||||
print("{} -> {}".format(
|
||||
ii, sent[1][ii]))
|
||||
|
||||
def t_simple_lesk_sskj(self):
|
||||
ii = 10
|
||||
for k, e in self.entries.items():
|
||||
if random.randint(0, 100) > 20:
|
||||
continue
|
||||
for frame in e.raw_frames:
|
||||
if random.randint(0, 100) > 20:
|
||||
continue
|
||||
if ii == 0:
|
||||
return
|
||||
ii -= 1
|
||||
|
||||
print("\nTest frame: {}.".format(frame.tids))
|
||||
hw_token = self.get_token(frame.tids[0])
|
||||
print(hw_token)
|
||||
context_sentence = self.get_sentence(frame.tids[0])
|
||||
print(context_sentence)
|
||||
self.lesk.simple_lesk_sskj(
|
||||
context_sentence=context_sentence,
|
||||
word_lemma=hw_token["lemma"]
|
||||
)
|
||||
|
||||
def process_kmeans(self):
|
||||
# Convert words to lemmas, cluseter using k-means.
|
||||
# Number of clusters from sskj.
|
||||
tstart = time()
|
||||
log.info("Processing senses using kmeans.")
|
||||
for k, e in self.entries.items():
|
||||
# Frame start
|
||||
ttstart = time()
|
||||
lemma = e.hw
|
||||
tokenized_sentences = []
|
||||
for frame in e.raw_frames:
|
||||
tid = frame.tids[0]
|
||||
tokenized_sentences.append(self.get_tokenized_sentence(tid))
|
||||
lemmatized_sentences = []
|
||||
for sent in tokenized_sentences:
|
||||
lemmatized = ""
|
||||
for token in sent:
|
||||
if "lemma" in token[1]:
|
||||
lemmatized += (token[1]["lemma"] + " ")
|
||||
lemmatized_sentences.append(lemmatized)
|
||||
lls = len(lemmatized_sentences)
|
||||
# We got the sentences
|
||||
sskj_entry = self.db.sskj.find_one(
|
||||
{"ns0:entry.ns0:form.ns0:orth": lemma})
|
||||
if sskj_entry is None:
|
||||
log.debug("headword {} has no <sense> in sskj".format(lemma))
|
||||
continue
|
||||
n_clusters = 1
|
||||
if "ns0:sense" in sskj_entry["ns0:entry"]:
|
||||
# Guess number of senses based on sskj senses.
|
||||
n_clusters = len(sskj_entry["ns0:entry"]["ns0:sense"])
|
||||
if lls >= n_clusters and n_clusters > 1:
|
||||
labels = k_kmeans.k_means(
|
||||
sentences=lemmatized_sentences,
|
||||
n_clusters=n_clusters
|
||||
)
|
||||
kmeans_ids = [str(x) + "-" + str(lls) for x in labels]
|
||||
elif n_clusters == 1:
|
||||
kmeans_ids = ["1-1" for x in lemmatized_sentences]
|
||||
elif lls < n_clusters:
|
||||
# Each sentence gets its own sense.
|
||||
kmeans_ids = []
|
||||
for i in range(lls):
|
||||
kmeans_ids.append(str(i + 1) + "lt" + str(n_clusters))
|
||||
else:
|
||||
log.error("Shouldn't be here (val_struct: process_kmeans()")
|
||||
exit(1)
|
||||
|
||||
# Feed sense ides of whole frame to database.
|
||||
for i in range(len(e.raw_frames)):
|
||||
tid = e.raw_frames[i].tids[0]
|
||||
key = {"ssj_id": tid}
|
||||
entry = {
|
||||
"headword": lemma,
|
||||
"ssj_id": tid, # unique idenfitier
|
||||
"sense_id": kmeans_ids[i],
|
||||
}
|
||||
self.db.kmeans.update(key, entry, upsert=True)
|
||||
|
||||
log.debug("[*] kemans_ids for {} in {:.2f}s".format(
|
||||
lemma, time() - ttstart))
|
||||
# Frame end
|
||||
log.debug("process_kmeans in {:.2f}s".format(time() - tstart))
|
||||
|
||||
def get_context1(
|
||||
self, mytid, collname, radius=None, min_token_len=3, get_glosses=None
|
||||
):
|
||||
# returns {
|
||||
# "hw": headword lemma and its glosses
|
||||
# "context": a list of lemmas and their glosses around the hw that
|
||||
# have entries in collname dictionary (if get_glosses=True)
|
||||
# }
|
||||
# tstart = time()
|
||||
if get_glosses is None:
|
||||
get_glosses = False
|
||||
if radius is None:
|
||||
radius = 10000
|
||||
if collname == "slownet":
|
||||
dictionary_interface = self.slownet_interface
|
||||
elif collname == "sskj":
|
||||
dictionary_interface = self.sskj_interface
|
||||
else:
|
||||
log.error("argument error: get_context1(collname=<slownet/sskj>)")
|
||||
return []
|
||||
|
||||
sentence = self.get_tokenized_sentence(mytid)
|
||||
# return [(ssj_id, {word: _, lemma: _, msd: _}), ...]
|
||||
hw_idx = -1
|
||||
for i, e in enumerate(sentence):
|
||||
if e[0] == mytid:
|
||||
hw_idx = i
|
||||
hw_lemma = e[1]["lemma"]
|
||||
break
|
||||
|
||||
hw_glosses = dictionary_interface.sense_glosses(hw_lemma)
|
||||
if len(hw_glosses) == 0:
|
||||
log.info("hw: {} has 0 glosses".format(hw_lemma))
|
||||
return {
|
||||
"hw": None,
|
||||
"err": "headword {} has no glosses in {}".format(
|
||||
hw_lemma, collname)
|
||||
}
|
||||
|
||||
tokens_before = []
|
||||
ii = hw_idx - 1
|
||||
while(ii >= 0 and len(tokens_before) < radius):
|
||||
lemma = sentence[ii][1].get("lemma")
|
||||
if (
|
||||
lemma is not None and
|
||||
len(lemma) >= min_token_len
|
||||
):
|
||||
if get_glosses:
|
||||
glosses = dictionary_interface.sense_glosses(lemma)
|
||||
else:
|
||||
glosses = [{"def": "--none--", "gloss": "--none--"}]
|
||||
if len(glosses) > 0:
|
||||
tokens_before.insert(0, {
|
||||
"lemma": lemma,
|
||||
"glosses": glosses
|
||||
})
|
||||
ii -= 1
|
||||
|
||||
tokens_after = []
|
||||
ii = hw_idx + 1
|
||||
while(ii < len(sentence) and len(tokens_after) < radius):
|
||||
lemma = sentence[ii][1].get("lemma")
|
||||
if (
|
||||
lemma is not None and
|
||||
len(lemma) >= min_token_len
|
||||
):
|
||||
if get_glosses:
|
||||
glosses = dictionary_interface.sense_glosses(lemma)
|
||||
else:
|
||||
glosses = [{"def": "--none--", "gloss": "--none--"}]
|
||||
if len(glosses) > 0:
|
||||
tokens_after.append({
|
||||
"lemma": lemma,
|
||||
"glosses": glosses
|
||||
})
|
||||
ii += 1
|
||||
|
||||
# log.debug("context1({}): {:.2f}".format(mytid, time() - tstart))
|
||||
return {
|
||||
"hw": {"lemma": hw_lemma, "glosses": hw_glosses},
|
||||
"context": tokens_before + tokens_after
|
||||
}
|
||||
|
||||
def test_context1(self, mytid, hw=""):
|
||||
res = ""
|
||||
context = self.get_context1(
|
||||
mytid, collname="slownet", radius=2, get_glosses=True)
|
||||
if context["hw"] is None:
|
||||
return context["err"] + "<br><br>"
|
||||
res = "hw: {}<br>sentence: {}<br>".format(
|
||||
hw, self.get_sentence(mytid))
|
||||
tfigf_input = []
|
||||
glosses = [context["hw"]] + context["context"]
|
||||
for e in glosses:
|
||||
res += "--->lemma: {} ({} senses)<br>".format(
|
||||
e["lemma"], len(e["glosses"]))
|
||||
for g in e["glosses"]:
|
||||
res += "{}<br>".format(str(g))
|
||||
tfigf_input.append(" ".join(k_utils.tokenize_multiple(
|
||||
g["gloss"],
|
||||
min_token_len=3,
|
||||
stem=k_utils.stem_eng
|
||||
)))
|
||||
res += "<br><br>"
|
||||
return res
|
||||
|
||||
def calc_all_senses(self, lesk_algorithm):
|
||||
allcount = 0
|
||||
count = 0
|
||||
for k, e in self.entries.items():
|
||||
allcount += len(e.raw_frames)
|
||||
for k, e in self.entries.items():
|
||||
if k == "biti": # skip this huge bag of words
|
||||
continue
|
||||
for frame in e.raw_frames:
|
||||
count += 1
|
||||
if count % 10 == 0:
|
||||
log.info("calc_all_senses: ({}/{})".format(
|
||||
count, allcount))
|
||||
lesk_algorithm(frame.tids[0])
|
||||
return None
|
||||
|
||||
def calc_all_senses_kmeans(self, kmeans_algorithm):
|
||||
tstart = time()
|
||||
allcount = len(self.entries)
|
||||
count = 0
|
||||
avg_times = []
|
||||
for key in self.entries:
|
||||
count += 1
|
||||
if key == "biti":
|
||||
continue
|
||||
# cluster frames of each entry
|
||||
log.info("calc_all_senses_kmeans: ({}/{}) [{}]".format(
|
||||
count, allcount, key))
|
||||
kmeans_algorithm(key)
|
||||
"""
|
||||
try:
|
||||
kmeans_algorithm(key)
|
||||
except ValueError:
|
||||
continue
|
||||
"""
|
||||
avg_times.append(1.0 * (time() - tstart) / count)
|
||||
log.info("avg_time: {:.2f}s".format(avg_times[-1]))
|
||||
log.info("calc_all_senses_kmeans in {:.2f}s.".format(time() - tstart))
|
||||
return None
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
log.setLevel(logging.DEBUG)
|
||||
ch = logging.StreamHandler(sys.stdout)
|
||||
log.addHandler(ch)
|
||||
# run ssj_struct to create a ssj_test.pickle file
|
||||
with open("ssj_test.pickle", "rb") as file:
|
||||
ssj = pickle.load(file)
|
||||
|
||||
vallex = Vallex()
|
||||
vallex.read_ssj(ssj)
|
||||
|
||||
vallex.sorted_words = {}
|
||||
vallex.gen_sorted_words()
|
||||
|
||||
vallex.functors_index = {}
|
||||
vallex.gen_functors_index()
|
12
src_diploma/vue_frontend/.babelrc
Normal file
12
src_diploma/vue_frontend/.babelrc
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"presets": [
|
||||
["env", {
|
||||
"modules": false,
|
||||
"targets": {
|
||||
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
|
||||
}
|
||||
}],
|
||||
"stage-2"
|
||||
],
|
||||
"plugins": ["transform-vue-jsx", "transform-runtime"]
|
||||
}
|
9
src_diploma/vue_frontend/.editorconfig
Normal file
9
src_diploma/vue_frontend/.editorconfig
Normal file
|
@ -0,0 +1,9 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
14
src_diploma/vue_frontend/.gitignore
vendored
Normal file
14
src_diploma/vue_frontend/.gitignore
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
.DS_Store
|
||||
node_modules/
|
||||
/dist/
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
10
src_diploma/vue_frontend/.postcssrc.js
Normal file
10
src_diploma/vue_frontend/.postcssrc.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
// https://github.com/michael-ciniawsky/postcss-load-config
|
||||
|
||||
module.exports = {
|
||||
"plugins": {
|
||||
"postcss-import": {},
|
||||
"postcss-url": {},
|
||||
// to edit target browsers: use "browserslist" field in package.json
|
||||
"autoprefixer": {}
|
||||
}
|
||||
}
|
21
src_diploma/vue_frontend/README.md
Normal file
21
src_diploma/vue_frontend/README.md
Normal file
|
@ -0,0 +1,21 @@
|
|||
# vue_frontend
|
||||
|
||||
> Frontend for Valency App.
|
||||
|
||||
## Build Setup
|
||||
|
||||
``` bash
|
||||
# install dependencies
|
||||
npm install
|
||||
|
||||
# serve with hot reload at localhost:8080
|
||||
npm run dev
|
||||
|
||||
# build for production with minification
|
||||
npm run build
|
||||
|
||||
# build for production and view the bundle analyzer report
|
||||
npm run build --report
|
||||
```
|
||||
|
||||
For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader).
|
41
src_diploma/vue_frontend/build/build.js
Normal file
41
src_diploma/vue_frontend/build/build.js
Normal file
|
@ -0,0 +1,41 @@
|
|||
'use strict'
|
||||
require('./check-versions')()
|
||||
|
||||
process.env.NODE_ENV = 'production'
|
||||
|
||||
const ora = require('ora')
|
||||
const rm = require('rimraf')
|
||||
const path = require('path')
|
||||
const chalk = require('chalk')
|
||||
const webpack = require('webpack')
|
||||
const config = require('../config')
|
||||
const webpackConfig = require('./webpack.prod.conf')
|
||||
|
||||
const spinner = ora('building for production...')
|
||||
spinner.start()
|
||||
|
||||
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
|
||||
if (err) throw err
|
||||
webpack(webpackConfig, (err, stats) => {
|
||||
spinner.stop()
|
||||
if (err) throw err
|
||||
process.stdout.write(stats.toString({
|
||||
colors: true,
|
||||
modules: false,
|
||||
children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
|
||||
chunks: false,
|
||||
chunkModules: false
|
||||
}) + '\n\n')
|
||||
|
||||
if (stats.hasErrors()) {
|
||||
console.log(chalk.red(' Build failed with errors.\n'))
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
console.log(chalk.cyan(' Build complete.\n'))
|
||||
console.log(chalk.yellow(
|
||||
' Tip: built files are meant to be served over an HTTP server.\n' +
|
||||
' Opening index.html over file:// won\'t work.\n'
|
||||
))
|
||||
})
|
||||
})
|
54
src_diploma/vue_frontend/build/check-versions.js
Normal file
54
src_diploma/vue_frontend/build/check-versions.js
Normal file
|
@ -0,0 +1,54 @@
|
|||
'use strict'
|
||||
const chalk = require('chalk')
|
||||
const semver = require('semver')
|
||||
const packageConfig = require('../package.json')
|
||||
const shell = require('shelljs')
|
||||
|
||||
function exec (cmd) {
|
||||
return require('child_process').execSync(cmd).toString().trim()
|
||||
}
|
||||
|
||||
const versionRequirements = [
|
||||
{
|
||||
name: 'node',
|
||||
currentVersion: semver.clean(process.version),
|
||||
versionRequirement: packageConfig.engines.node
|
||||
}
|
||||
]
|
||||
|
||||
if (shell.which('npm')) {
|
||||
versionRequirements.push({
|
||||
name: 'npm',
|
||||
currentVersion: exec('npm --version'),
|
||||
versionRequirement: packageConfig.engines.npm
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = function () {
|
||||
const warnings = []
|
||||
|
||||
for (let i = 0; i < versionRequirements.length; i++) {
|
||||
const mod = versionRequirements[i]
|
||||
|
||||
if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
|
||||
warnings.push(mod.name + ': ' +
|
||||
chalk.red(mod.currentVersion) + ' should be ' +
|
||||
chalk.green(mod.versionRequirement)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (warnings.length) {
|
||||
console.log('')
|
||||
console.log(chalk.yellow('To use this template, you must update following to modules:'))
|
||||
console.log()
|
||||
|
||||
for (let i = 0; i < warnings.length; i++) {
|
||||
const warning = warnings[i]
|
||||
console.log(' ' + warning)
|
||||
}
|
||||
|
||||
console.log()
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
BIN
src_diploma/vue_frontend/build/logo.png
Normal file
BIN
src_diploma/vue_frontend/build/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.7 KiB |
101
src_diploma/vue_frontend/build/utils.js
Normal file
101
src_diploma/vue_frontend/build/utils.js
Normal file
|
@ -0,0 +1,101 @@
|
|||
'use strict'
|
||||
const path = require('path')
|
||||
const config = require('../config')
|
||||
const ExtractTextPlugin = require('extract-text-webpack-plugin')
|
||||
const packageConfig = require('../package.json')
|
||||
|
||||
exports.assetsPath = function (_path) {
|
||||
const assetsSubDirectory = process.env.NODE_ENV === 'production'
|
||||
? config.build.assetsSubDirectory
|
||||
: config.dev.assetsSubDirectory
|
||||
|
||||
return path.posix.join(assetsSubDirectory, _path)
|
||||
}
|
||||
|
||||
exports.cssLoaders = function (options) {
|
||||
options = options || {}
|
||||
|
||||
const cssLoader = {
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
sourceMap: options.sourceMap
|
||||
}
|
||||
}
|
||||
|
||||
const postcssLoader = {
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
sourceMap: options.sourceMap
|
||||
}
|
||||
}
|
||||
|
||||
// generate loader string to be used with extract text plugin
|
||||
function generateLoaders (loader, loaderOptions) {
|
||||
const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
|
||||
|
||||
if (loader) {
|
||||
loaders.push({
|
||||
loader: loader + '-loader',
|
||||
options: Object.assign({}, loaderOptions, {
|
||||
sourceMap: options.sourceMap
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Extract CSS when that option is specified
|
||||
// (which is the case during production build)
|
||||
if (options.extract) {
|
||||
return ExtractTextPlugin.extract({
|
||||
use: loaders,
|
||||
fallback: 'vue-style-loader'
|
||||
})
|
||||
} else {
|
||||
return ['vue-style-loader'].concat(loaders)
|
||||
}
|
||||
}
|
||||
|
||||
// https://vue-loader.vuejs.org/en/configurations/extract-css.html
|
||||
return {
|
||||
css: generateLoaders(),
|
||||
postcss: generateLoaders(),
|
||||
less: generateLoaders('less'),
|
||||
sass: generateLoaders('sass', { indentedSyntax: true }),
|
||||
scss: generateLoaders('sass'),
|
||||
stylus: generateLoaders('stylus'),
|
||||
styl: generateLoaders('stylus')
|
||||
}
|
||||
}
|
||||
|
||||
// Generate loaders for standalone style files (outside of .vue)
|
||||
exports.styleLoaders = function (options) {
|
||||
const output = []
|
||||
const loaders = exports.cssLoaders(options)
|
||||
|
||||
for (const extension in loaders) {
|
||||
const loader = loaders[extension]
|
||||
output.push({
|
||||
test: new RegExp('\\.' + extension + '$'),
|
||||
use: loader
|
||||
})
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
exports.createNotifierCallback = () => {
|
||||
const notifier = require('node-notifier')
|
||||
|
||||
return (severity, errors) => {
|
||||
if (severity !== 'error') return
|
||||
|
||||
const error = errors[0]
|
||||
const filename = error.file && error.file.split('!').pop()
|
||||
|
||||
notifier.notify({
|
||||
title: packageConfig.name,
|
||||
message: severity + ': ' + error.name,
|
||||
subtitle: filename || '',
|
||||
icon: path.join(__dirname, 'logo.png')
|
||||
})
|
||||
}
|
||||
}
|
22
src_diploma/vue_frontend/build/vue-loader.conf.js
Normal file
22
src_diploma/vue_frontend/build/vue-loader.conf.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
'use strict'
|
||||
const utils = require('./utils')
|
||||
const config = require('../config')
|
||||
const isProduction = process.env.NODE_ENV === 'production'
|
||||
const sourceMapEnabled = isProduction
|
||||
? config.build.productionSourceMap
|
||||
: config.dev.cssSourceMap
|
||||
|
||||
module.exports = {
|
||||
loaders: utils.cssLoaders({
|
||||
sourceMap: sourceMapEnabled,
|
||||
extract: isProduction
|
||||
}),
|
||||
cssSourceMap: sourceMapEnabled,
|
||||
cacheBusting: config.dev.cacheBusting,
|
||||
transformToRequire: {
|
||||
video: ['src', 'poster'],
|
||||
source: 'src',
|
||||
img: 'src',
|
||||
image: 'xlink:href'
|
||||
}
|
||||
}
|
82
src_diploma/vue_frontend/build/webpack.base.conf.js
Normal file
82
src_diploma/vue_frontend/build/webpack.base.conf.js
Normal file
|
@ -0,0 +1,82 @@
|
|||
'use strict'
|
||||
const path = require('path')
|
||||
const utils = require('./utils')
|
||||
const config = require('../config')
|
||||
const vueLoaderConfig = require('./vue-loader.conf')
|
||||
|
||||
function resolve (dir) {
|
||||
return path.join(__dirname, '..', dir)
|
||||
}
|
||||
|
||||
|
||||
|
||||
module.exports = {
|
||||
context: path.resolve(__dirname, '../'),
|
||||
entry: {
|
||||
app: './src/main.js'
|
||||
},
|
||||
output: {
|
||||
path: config.build.assetsRoot,
|
||||
filename: '[name].js',
|
||||
publicPath: process.env.NODE_ENV === 'production'
|
||||
? config.build.assetsPublicPath
|
||||
: config.dev.assetsPublicPath
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js', '.vue', '.json'],
|
||||
alias: {
|
||||
'vue$': 'vue/dist/vue.esm.js',
|
||||
'@': resolve('src'),
|
||||
}
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.vue$/,
|
||||
loader: 'vue-loader',
|
||||
options: vueLoaderConfig
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
loader: 'babel-loader',
|
||||
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: utils.assetsPath('img/[name].[hash:7].[ext]')
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: utils.assetsPath('media/[name].[hash:7].[ext]')
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
node: {
|
||||
// prevent webpack from injecting useless setImmediate polyfill because Vue
|
||||
// source contains it (although only uses it if it's native).
|
||||
setImmediate: false,
|
||||
// prevent webpack from injecting mocks to Node native modules
|
||||
// that does not make sense for the client
|
||||
dgram: 'empty',
|
||||
fs: 'empty',
|
||||
net: 'empty',
|
||||
tls: 'empty',
|
||||
child_process: 'empty'
|
||||
}
|
||||
}
|
95
src_diploma/vue_frontend/build/webpack.dev.conf.js
Executable file
95
src_diploma/vue_frontend/build/webpack.dev.conf.js
Executable file
|
@ -0,0 +1,95 @@
|
|||
'use strict'
|
||||
const utils = require('./utils')
|
||||
const webpack = require('webpack')
|
||||
const config = require('../config')
|
||||
const merge = require('webpack-merge')
|
||||
const path = require('path')
|
||||
const baseWebpackConfig = require('./webpack.base.conf')
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
|
||||
const portfinder = require('portfinder')
|
||||
|
||||
const HOST = process.env.HOST
|
||||
const PORT = process.env.PORT && Number(process.env.PORT)
|
||||
|
||||
const devWebpackConfig = merge(baseWebpackConfig, {
|
||||
module: {
|
||||
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
|
||||
},
|
||||
// cheap-module-eval-source-map is faster for development
|
||||
devtool: config.dev.devtool,
|
||||
|
||||
// these devServer options should be customized in /config/index.js
|
||||
devServer: {
|
||||
clientLogLevel: 'warning',
|
||||
historyApiFallback: {
|
||||
rewrites: [
|
||||
{ from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
|
||||
],
|
||||
},
|
||||
hot: true,
|
||||
contentBase: false, // since we use CopyWebpackPlugin.
|
||||
compress: true,
|
||||
host: HOST || config.dev.host,
|
||||
port: PORT || config.dev.port,
|
||||
open: config.dev.autoOpenBrowser,
|
||||
overlay: config.dev.errorOverlay
|
||||
? { warnings: false, errors: true }
|
||||
: false,
|
||||
publicPath: config.dev.assetsPublicPath,
|
||||
proxy: config.dev.proxyTable,
|
||||
quiet: true, // necessary for FriendlyErrorsPlugin
|
||||
watchOptions: {
|
||||
poll: config.dev.poll,
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': require('../config/dev.env')
|
||||
}),
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
|
||||
new webpack.NoEmitOnErrorsPlugin(),
|
||||
// https://github.com/ampedandwired/html-webpack-plugin
|
||||
new HtmlWebpackPlugin({
|
||||
filename: 'index.html',
|
||||
template: 'index.html',
|
||||
inject: true
|
||||
}),
|
||||
// copy custom static assets
|
||||
new CopyWebpackPlugin([
|
||||
{
|
||||
from: path.resolve(__dirname, '../static'),
|
||||
to: config.dev.assetsSubDirectory,
|
||||
ignore: ['.*']
|
||||
}
|
||||
])
|
||||
]
|
||||
})
|
||||
|
||||
module.exports = new Promise((resolve, reject) => {
|
||||
portfinder.basePort = process.env.PORT || config.dev.port
|
||||
portfinder.getPort((err, port) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
} else {
|
||||
// publish the new Port, necessary for e2e tests
|
||||
process.env.PORT = port
|
||||
// add port to devServer config
|
||||
devWebpackConfig.devServer.port = port
|
||||
|
||||
// Add FriendlyErrorsPlugin
|
||||
devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
|
||||
compilationSuccessInfo: {
|
||||
messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
|
||||
},
|
||||
onErrors: config.dev.notifyOnErrors
|
||||
? utils.createNotifierCallback()
|
||||
: undefined
|
||||
}))
|
||||
|
||||
resolve(devWebpackConfig)
|
||||
}
|
||||
})
|
||||
})
|
145
src_diploma/vue_frontend/build/webpack.prod.conf.js
Normal file
145
src_diploma/vue_frontend/build/webpack.prod.conf.js
Normal file
|
@ -0,0 +1,145 @@
|
|||
'use strict'
|
||||
const path = require('path')
|
||||
const utils = require('./utils')
|
||||
const webpack = require('webpack')
|
||||
const config = require('../config')
|
||||
const merge = require('webpack-merge')
|
||||
const baseWebpackConfig = require('./webpack.base.conf')
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||
const ExtractTextPlugin = require('extract-text-webpack-plugin')
|
||||
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
|
||||
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
|
||||
|
||||
const env = require('../config/prod.env')
|
||||
|
||||
const webpackConfig = merge(baseWebpackConfig, {
|
||||
module: {
|
||||
rules: utils.styleLoaders({
|
||||
sourceMap: config.build.productionSourceMap,
|
||||
extract: true,
|
||||
usePostCSS: true
|
||||
})
|
||||
},
|
||||
devtool: config.build.productionSourceMap ? config.build.devtool : false,
|
||||
output: {
|
||||
path: config.build.assetsRoot,
|
||||
filename: utils.assetsPath('js/[name].[chunkhash].js'),
|
||||
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
|
||||
},
|
||||
plugins: [
|
||||
// http://vuejs.github.io/vue-loader/en/workflow/production.html
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': env
|
||||
}),
|
||||
new UglifyJsPlugin({
|
||||
uglifyOptions: {
|
||||
compress: {
|
||||
warnings: false
|
||||
}
|
||||
},
|
||||
sourceMap: config.build.productionSourceMap,
|
||||
parallel: true
|
||||
}),
|
||||
// extract css into its own file
|
||||
new ExtractTextPlugin({
|
||||
filename: utils.assetsPath('css/[name].[contenthash].css'),
|
||||
// Setting the following option to `false` will not extract CSS from codesplit chunks.
|
||||
// Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
|
||||
// It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
|
||||
// increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
|
||||
allChunks: true,
|
||||
}),
|
||||
// Compress extracted CSS. We are using this plugin so that possible
|
||||
// duplicated CSS from different components can be deduped.
|
||||
new OptimizeCSSPlugin({
|
||||
cssProcessorOptions: config.build.productionSourceMap
|
||||
? { safe: true, map: { inline: false } }
|
||||
: { safe: true }
|
||||
}),
|
||||
// generate dist index.html with correct asset hash for caching.
|
||||
// you can customize output by editing /index.html
|
||||
// see https://github.com/ampedandwired/html-webpack-plugin
|
||||
new HtmlWebpackPlugin({
|
||||
filename: config.build.index,
|
||||
template: 'index.html',
|
||||
inject: true,
|
||||
minify: {
|
||||
removeComments: true,
|
||||
collapseWhitespace: true,
|
||||
removeAttributeQuotes: true
|
||||
// more options:
|
||||
// https://github.com/kangax/html-minifier#options-quick-reference
|
||||
},
|
||||
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
|
||||
chunksSortMode: 'dependency'
|
||||
}),
|
||||
// keep module.id stable when vendor modules does not change
|
||||
new webpack.HashedModuleIdsPlugin(),
|
||||
// enable scope hoisting
|
||||
new webpack.optimize.ModuleConcatenationPlugin(),
|
||||
// split vendor js into its own file
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: 'vendor',
|
||||
minChunks (module) {
|
||||
// any required modules inside node_modules are extracted to vendor
|
||||
return (
|
||||
module.resource &&
|
||||
/\.js$/.test(module.resource) &&
|
||||
module.resource.indexOf(
|
||||
path.join(__dirname, '../node_modules')
|
||||
) === 0
|
||||
)
|
||||
}
|
||||
}),
|
||||
// extract webpack runtime and module manifest to its own file in order to
|
||||
// prevent vendor hash from being updated whenever app bundle is updated
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: 'manifest',
|
||||
minChunks: Infinity
|
||||
}),
|
||||
// This instance extracts shared chunks from code splitted chunks and bundles them
|
||||
// in a separate chunk, similar to the vendor chunk
|
||||
// see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: 'app',
|
||||
async: 'vendor-async',
|
||||
children: true,
|
||||
minChunks: 3
|
||||
}),
|
||||
|
||||
// copy custom static assets
|
||||
new CopyWebpackPlugin([
|
||||
{
|
||||
from: path.resolve(__dirname, '../static'),
|
||||
to: config.build.assetsSubDirectory,
|
||||
ignore: ['.*']
|
||||
}
|
||||
])
|
||||
]
|
||||
})
|
||||
|
||||
if (config.build.productionGzip) {
|
||||
const CompressionWebpackPlugin = require('compression-webpack-plugin')
|
||||
|
||||
webpackConfig.plugins.push(
|
||||
new CompressionWebpackPlugin({
|
||||
asset: '[path].gz[query]',
|
||||
algorithm: 'gzip',
|
||||
test: new RegExp(
|
||||
'\\.(' +
|
||||
config.build.productionGzipExtensions.join('|') +
|
||||
')$'
|
||||
),
|
||||
threshold: 10240,
|
||||
minRatio: 0.8
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
if (config.build.bundleAnalyzerReport) {
|
||||
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
|
||||
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
|
||||
}
|
||||
|
||||
module.exports = webpackConfig
|
3
src_diploma/vue_frontend/config/config.json
Normal file
3
src_diploma/vue_frontend/config/config.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"api_addr": "http://localhost:5004"
|
||||
}
|
3
src_diploma/vue_frontend/config/config_dev.json
Normal file
3
src_diploma/vue_frontend/config/config_dev.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"api_addr": "http://localhost:5004"
|
||||
}
|
3
src_diploma/vue_frontend/config/config_pro.json
Normal file
3
src_diploma/vue_frontend/config/config_pro.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"api_addr": "http://193.2.76.103:5004"
|
||||
}
|
7
src_diploma/vue_frontend/config/dev.env.js
Normal file
7
src_diploma/vue_frontend/config/dev.env.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
'use strict'
|
||||
const merge = require('webpack-merge')
|
||||
const prodEnv = require('./prod.env')
|
||||
|
||||
module.exports = merge(prodEnv, {
|
||||
NODE_ENV: '"development"'
|
||||
})
|
69
src_diploma/vue_frontend/config/index.js
Normal file
69
src_diploma/vue_frontend/config/index.js
Normal file
|
@ -0,0 +1,69 @@
|
|||
'use strict'
|
||||
// Template version: 1.3.1
|
||||
// see http://vuejs-templates.github.io/webpack for documentation.
|
||||
|
||||
const path = require('path')
|
||||
|
||||
module.exports = {
|
||||
dev: {
|
||||
|
||||
// Paths
|
||||
assetsSubDirectory: 'static',
|
||||
assetsPublicPath: '/',
|
||||
proxyTable: {},
|
||||
|
||||
// Various Dev Server settings
|
||||
host: 'localhost', // can be overwritten by process.env.HOST
|
||||
port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
|
||||
autoOpenBrowser: false,
|
||||
errorOverlay: true,
|
||||
notifyOnErrors: true,
|
||||
poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
|
||||
|
||||
|
||||
/**
|
||||
* Source Maps
|
||||
*/
|
||||
|
||||
// https://webpack.js.org/configuration/devtool/#development
|
||||
devtool: 'cheap-module-eval-source-map',
|
||||
|
||||
// If you have problems debugging vue-files in devtools,
|
||||
// set this to false - it *may* help
|
||||
// https://vue-loader.vuejs.org/en/options.html#cachebusting
|
||||
cacheBusting: true,
|
||||
|
||||
cssSourceMap: true
|
||||
},
|
||||
|
||||
build: {
|
||||
// Template for index.html
|
||||
index: path.resolve(__dirname, '../dist/index.html'),
|
||||
|
||||
// Paths
|
||||
assetsRoot: path.resolve(__dirname, '../dist'),
|
||||
assetsSubDirectory: 'static',
|
||||
assetsPublicPath: '/',
|
||||
|
||||
/**
|
||||
* Source Maps
|
||||
*/
|
||||
|
||||
productionSourceMap: true,
|
||||
// https://webpack.js.org/configuration/devtool/#production
|
||||
devtool: '#source-map',
|
||||
|
||||
// Gzip off by default as many popular static hosts such as
|
||||
// Surge or Netlify already gzip all static assets for you.
|
||||
// Before setting to `true`, make sure to:
|
||||
// npm install --save-dev compression-webpack-plugin
|
||||
productionGzip: false,
|
||||
productionGzipExtensions: ['js', 'css'],
|
||||
|
||||
// Run the build command with an extra argument to
|
||||
// View the bundle analyzer report after build finishes:
|
||||
// `npm run build --report`
|
||||
// Set to `true` or `false` to always turn it on or off
|
||||
bundleAnalyzerReport: process.env.npm_config_report
|
||||
}
|
||||
}
|
4
src_diploma/vue_frontend/config/prod.env.js
Normal file
4
src_diploma/vue_frontend/config/prod.env.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
'use strict'
|
||||
module.exports = {
|
||||
NODE_ENV: '"production"'
|
||||
}
|
12
src_diploma/vue_frontend/index.html
Normal file
12
src_diploma/vue_frontend/index.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<title>vue_frontend</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
10853
src_diploma/vue_frontend/package-lock.json
generated
Normal file
10853
src_diploma/vue_frontend/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
67
src_diploma/vue_frontend/package.json
Normal file
67
src_diploma/vue_frontend/package.json
Normal file
|
@ -0,0 +1,67 @@
|
|||
{
|
||||
"name": "vue_frontend",
|
||||
"version": "1.0.0",
|
||||
"description": "Frontend for Valency App.",
|
||||
"author": "voje <kristjan.voje@gmail.com>",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
|
||||
"start": "npm run dev",
|
||||
"build": "node build/build.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.18.0",
|
||||
"bootstrap-vue": "^2.0.0-rc.11",
|
||||
"sha256": "^0.2.0",
|
||||
"vue": "^2.5.2",
|
||||
"vue-cookies": "^1.5.6",
|
||||
"vue-router": "^3.0.1",
|
||||
"vue-spinner": "^1.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^7.1.2",
|
||||
"babel-core": "^6.22.1",
|
||||
"babel-helper-vue-jsx-merge-props": "^2.0.3",
|
||||
"babel-loader": "^7.1.1",
|
||||
"babel-plugin-syntax-jsx": "^6.18.0",
|
||||
"babel-plugin-transform-runtime": "^6.22.0",
|
||||
"babel-plugin-transform-vue-jsx": "^3.5.0",
|
||||
"babel-preset-env": "^1.3.2",
|
||||
"babel-preset-stage-2": "^6.22.0",
|
||||
"chalk": "^2.0.1",
|
||||
"copy-webpack-plugin": "^4.0.1",
|
||||
"css-loader": "^0.28.0",
|
||||
"extract-text-webpack-plugin": "^3.0.0",
|
||||
"file-loader": "^1.1.4",
|
||||
"friendly-errors-webpack-plugin": "^1.6.1",
|
||||
"html-webpack-plugin": "^2.30.1",
|
||||
"node-notifier": "^5.1.2",
|
||||
"optimize-css-assets-webpack-plugin": "^3.2.0",
|
||||
"ora": "^1.2.0",
|
||||
"portfinder": "^1.0.13",
|
||||
"postcss-import": "^11.0.0",
|
||||
"postcss-loader": "^2.0.8",
|
||||
"postcss-url": "^7.2.1",
|
||||
"rimraf": "^2.6.0",
|
||||
"semver": "^5.3.0",
|
||||
"shelljs": "^0.7.6",
|
||||
"uglifyjs-webpack-plugin": "^1.1.1",
|
||||
"url-loader": "^0.5.8",
|
||||
"vue-loader": "^13.3.0",
|
||||
"vue-style-loader": "^3.0.1",
|
||||
"vue-template-compiler": "^2.5.2",
|
||||
"webpack": "^3.6.0",
|
||||
"webpack-bundle-analyzer": "^2.9.0",
|
||||
"webpack-dev-server": "^2.9.1",
|
||||
"webpack-merge": "^4.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6.0.0",
|
||||
"npm": ">= 3.0.0"
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not ie <= 8"
|
||||
]
|
||||
}
|
9
src_diploma/vue_frontend/src/App.vue
Normal file
9
src_diploma/vue_frontend/src/App.vue
Normal file
|
@ -0,0 +1,9 @@
|
|||
<template>
|
||||
<router-view/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'App',
|
||||
}
|
||||
</script>
|
206
src_diploma/vue_frontend/src/components/EditSenses.vue
Normal file
206
src_diploma/vue_frontend/src/components/EditSenses.vue
Normal file
|
@ -0,0 +1,206 @@
|
|||
<template>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<p class="pb-0 mb-0">Urejanje pomenov za besedo: <b>{{ hw }}</b>.</p>
|
||||
<p><small>
|
||||
Z miško kliknite na poved, nato kliknite na pomen, ki ga želite dodeliti povedi. Par poved‒pomen bo obarvan z modro. Pare lahko shranite s klikom na gumb "Shrani". Možno je dodajanje poljubnih pomenov.
|
||||
</small></p>
|
||||
<button v-on:click="cancel_all">Prekliči</button>
|
||||
<button v-on:click="save_all">Shrani</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
|
||||
<!-- left column: sentences -->
|
||||
<div class="my-sent col-sm-6">
|
||||
<div
|
||||
v-for="(sentence, ssj_id) in sentences"
|
||||
v-on:click="pick_ssj_id(ssj_id)"
|
||||
class="border rounded my-sentences my-pointer"
|
||||
v-bind:class="{
|
||||
'border-primary': ssj_id === picked_ssj_id
|
||||
}"
|
||||
>
|
||||
<div>
|
||||
<span
|
||||
v-for="(word, index) in sentence.words"
|
||||
v-bind:class="{
|
||||
'text-primary': index === parseInt(sentence.hw_idx)
|
||||
}"
|
||||
>
|
||||
<span v-if="$root.mkspace(index, word)"> </span>{{ word }}
|
||||
</span>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="col-sm-12"><small>
|
||||
<div v-if="ssj_id in local_sense_map">
|
||||
<Sense v-bind:sense="local_sense_map[ssj_id].sense"></Sense>
|
||||
</div>
|
||||
<div v-else>
|
||||
<Sense v-bind:sense="undefined"></Sense>
|
||||
</div>
|
||||
</small></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- right column: senses -->
|
||||
<div class="col-sm-6 border rounded my-div-scroll sticky-top">
|
||||
<div
|
||||
v-for="sense in local_senses"
|
||||
class="my-pointer"
|
||||
v-on:click="picked_sense_id = sense.sense_id"
|
||||
v-bind:class="{
|
||||
'text-primary': sense.sense_id === picked_sense_id
|
||||
}"
|
||||
>
|
||||
<Sense v-bind:sense="sense"></Sense>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<textarea class="my-textarea" v-model="new_sense_desc"></textarea>
|
||||
</div>
|
||||
<div class="col-sm-12">
|
||||
<button v-on:click="new_sense">Dodaj pomen</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Sense from "./Sense"
|
||||
export default {
|
||||
name: "EditSenses",
|
||||
props: ["hw", "sentences", "sens"],
|
||||
components: {
|
||||
Sense: Sense
|
||||
},
|
||||
data () { return {
|
||||
picked_ssj_id: null,
|
||||
picked_sense_id: null,
|
||||
local_senses: [], // make changes on a local copy
|
||||
local_sense_map: {}, // make changes on a local copy
|
||||
new_sense_desc: "",
|
||||
new_senses: [], // only send changes to server
|
||||
delta_sense_map: {}, // only send changes to server
|
||||
}},
|
||||
created: function() {
|
||||
// not sure if needed, maybe move to data()
|
||||
this.local_senses = this.sens.senses
|
||||
var json = JSON.stringify(this.sens.sense_map)
|
||||
this.local_sense_map = JSON.parse(json)
|
||||
for (var ssj_id in this.local_sense_map) {
|
||||
this.local_sense_map[ssj_id].sense = this.sense_id_to_sense(
|
||||
this.local_sense_map[ssj_id].sense_id)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
picked_ssj_id: function() {
|
||||
this.new_link()
|
||||
},
|
||||
picked_sense_id: function() {
|
||||
this.new_link()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
pick_ssj_id: function(ssj_id) {
|
||||
this.picked_ssj_id = ssj_id
|
||||
if (ssj_id in this.local_sense_map) {
|
||||
this.picked_sense_id = this.local_sense_map[ssj_id].sense_id
|
||||
}
|
||||
|
||||
},
|
||||
new_link: function() {
|
||||
if (this.picked_ssj_id === null ||
|
||||
this.picked_sense_id === null) { return }
|
||||
this.local_sense_map[this.picked_ssj_id] = {
|
||||
sense_id: this.picked_sense_id,
|
||||
sense: this.sense_id_to_sense(this.picked_sense_id)
|
||||
}
|
||||
this.delta_sense_map[this.picked_ssj_id] = { sense_id: this.picked_sense_id }
|
||||
},
|
||||
new_sense: function(sense_id) {
|
||||
if (this.new_sense_desc === "") {
|
||||
return
|
||||
}
|
||||
var new_sense = {
|
||||
hw: this.hw,
|
||||
author: this.$root.store.username,
|
||||
desc: this.new_sense_desc,
|
||||
sense_id: "tmp_sense_id" + (new Date().getTime()),
|
||||
}
|
||||
this.local_senses.push(new_sense)
|
||||
this.new_senses.push(new_sense)
|
||||
this.new_sense_desc = ""
|
||||
},
|
||||
sense_id_to_sense: function(sense_id) {
|
||||
for (var i=0; i<this.local_senses.length; i++) {
|
||||
if (this.local_senses[i].sense_id === sense_id) {
|
||||
return this.local_senses[i]
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
},
|
||||
cancel_all: function() {
|
||||
this.$parent.state = "normal"
|
||||
},
|
||||
save_all: function() {
|
||||
const data = {
|
||||
token: this.$root.store.token,
|
||||
hw: this.hw,
|
||||
sense_map: this.delta_sense_map,
|
||||
new_senses: this.new_senses,
|
||||
}
|
||||
var component = this
|
||||
function exit_edit(component) {
|
||||
component.$parent.state = "normal"
|
||||
component.$parent.request_reload = true
|
||||
}
|
||||
|
||||
// don't update if there are no changes
|
||||
if (
|
||||
Object.keys(data.sense_map).length === 0 &&
|
||||
data.new_senses.length === 0
|
||||
) { exit_edit(component); return }
|
||||
|
||||
// exit after update
|
||||
this.$http.post(
|
||||
this.$root.store.api_addr + "/api/senses/update",
|
||||
data,
|
||||
{ headers: {
|
||||
'Content-type': 'application/json',
|
||||
}}
|
||||
).then(function () {
|
||||
exit_edit(component)
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.my-div-scroll {
|
||||
margin-top: 5px;
|
||||
height: 90vh;
|
||||
overflow-y: auto;
|
||||
padding-top: 5px;
|
||||
}
|
||||
.my-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
.my-textarea {
|
||||
width: 100%;
|
||||
}
|
||||
.my-sentences {
|
||||
margin: 5px 0px 20px 0px;
|
||||
padding: 5px;
|
||||
}
|
||||
.my-sent {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.my-sent span {
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
208
src_diploma/vue_frontend/src/components/Frame.vue
Normal file
208
src_diploma/vue_frontend/src/components/Frame.vue
Normal file
|
@ -0,0 +1,208 @@
|
|||
<template>
|
||||
<!-- clicking on empty space clears highlights -->
|
||||
<div v-on:click="clearOnClick" class="container-fluid">
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-sm-7">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
št. povedi: {{ frameData.sentences.length }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--frame slots-->
|
||||
<div class="row my-frames">
|
||||
<div class="col-sm-12">
|
||||
<span v-for="(slot, key) in frameData.slots">
|
||||
<span
|
||||
v-bind:class="{
|
||||
'my-pointer text-danger': hasHoverTid(idx=key),
|
||||
'my-underline text-danger': hasSelTid(idx=key)
|
||||
}"
|
||||
v-on:mouseover="setHid(idx=key)"
|
||||
v-on:mouseleave="setHid()"
|
||||
v-on:click="setSid(idx=key)"
|
||||
>{{ slot.functor }}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--sense information-->
|
||||
<div v-if="$root.store.radio === 'three'" class="col-sm-5">
|
||||
<Sense v-bind:sense="getSense()"></Sense>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--sentences-->
|
||||
<div class="row">
|
||||
<!-- fmode: prikaz->udelezenske vloge (drugacno razvrscanje povedi) -->
|
||||
<div v-if="fmode" class="col-sm-12">
|
||||
<div v-for="hw in getAggrHws()">
|
||||
<blockquote v-for="sentence in getAggrSent(hw)">
|
||||
<span class="text-secondary"> {{ hw }}</span><br>
|
||||
<span
|
||||
v-for="(token, index) in sentence"
|
||||
v-bind:class="{
|
||||
'my-pointer text-danger': hasHoverTid(idx=null, tid=token[0]), 'my-underline text-danger': hasSelTid(idx=null, tid=token[0]),
|
||||
'text-primary': isHw(token[0]),
|
||||
}"
|
||||
v-on:mouseover="setHid(idx=null, tid=token[0])"
|
||||
v-on:mouseleave="setHid()"
|
||||
v-on:click="setSid(idx=null, tid=token[0])"
|
||||
v-bind:title="token[1].msd"
|
||||
><span v-if="$root.mkspace(index, token[1].word)"> </span>{{ token[1].word }}</span>
|
||||
</blockquote>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="col-sm-12">
|
||||
<blockquote v-for="sentence in frameData.sentences">
|
||||
<span
|
||||
v-for="(token, index) in sentence"
|
||||
v-bind:class="{
|
||||
'my-pointer text-danger': hasHoverTid(idx=null, tid=token[0]), 'my-underline text-danger': hasSelTid(idx=null, tid=token[0]),
|
||||
'text-primary': isHw(token[0]),
|
||||
}"
|
||||
v-on:mouseover="setHid(idx=null, tid=token[0])"
|
||||
v-on:mouseleave="setHid()"
|
||||
v-on:click="setSid(idx=null, tid=token[0])"
|
||||
v-bind:title="token[1].msd"
|
||||
><span v-if="$root.mkspace(index, token[1].word)"> </span>{{ token[1].word }}</span>
|
||||
</blockquote>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Sense from "./Sense"
|
||||
export default {
|
||||
name: "Frame",
|
||||
props: {
|
||||
frameData: {},
|
||||
sensData: {},
|
||||
fmode: {
|
||||
default: false,
|
||||
type: Boolean,
|
||||
},
|
||||
},
|
||||
data() { return {
|
||||
hid: null, // hover functor index
|
||||
sid: null, // select functor index (click)
|
||||
}},
|
||||
components: {
|
||||
Sense: Sense
|
||||
},
|
||||
watch: {
|
||||
frameData: function () {
|
||||
this.hid = null,
|
||||
this.sid = null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setHid: function (idx=null, tid=null) {
|
||||
// calling this functoin without parameters
|
||||
// resets hid
|
||||
if (tid === null) {
|
||||
this.hid = idx
|
||||
return
|
||||
}
|
||||
for (var i=0; i<this.frameData.slots.length; i++) {
|
||||
if (this.frameData.slots[i].tids.includes(tid)) {
|
||||
this.hid = i
|
||||
return
|
||||
}
|
||||
}
|
||||
},
|
||||
clearOnClick: function (event) {
|
||||
if (event.target.tagName !== "SPAN") {
|
||||
this.sid = null
|
||||
}
|
||||
},
|
||||
setSid: function (idx=null, tid=null) {
|
||||
this.sid = null
|
||||
if (tid === null) {
|
||||
this.sid = idx
|
||||
return
|
||||
}
|
||||
for (var i=0; i<this.frameData.slots.length; i++) {
|
||||
if (this.frameData.slots[i].tids.includes(tid)) {
|
||||
this.sid = i
|
||||
return
|
||||
}
|
||||
}
|
||||
},
|
||||
hasHoverTid: function(idx=null, tid=null) {
|
||||
if (this.hid === null) {
|
||||
return false
|
||||
}
|
||||
if (tid === null) {
|
||||
if (idx == this.hid) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
return this.frameData.slots[this.hid].tids.includes(tid)
|
||||
},
|
||||
hasSelTid: function (idx=null, tid=null) {
|
||||
if (this.sid === null) {
|
||||
return false
|
||||
}
|
||||
if (tid === null) {
|
||||
if (idx == this.sid) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
return this.frameData.slots[this.sid].tids.includes(tid)
|
||||
},
|
||||
isHw: function (tid) {
|
||||
return this.frameData.tids.includes(tid)
|
||||
},
|
||||
getSense: function () {
|
||||
for (var i in this.sensData.senses) {
|
||||
if (this.sensData.senses[i].sense_id === this.frameData.sense_info.sense_id) {
|
||||
return this.sensData.senses[i]
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
},
|
||||
getAggrHws: function() {
|
||||
return (Object.keys(this.frameData.aggr_sent)).sort()
|
||||
},
|
||||
getAggrSent: function(hw) {
|
||||
var sentences = []
|
||||
for (var i=0; i<this.frameData.aggr_sent[hw].length; i++) {
|
||||
sentences.push(
|
||||
this.frameData.sentences[this.frameData.aggr_sent[hw][i]]
|
||||
)
|
||||
}
|
||||
return sentences
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.my-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
.my-underline {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.my-frames {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
blockquote {
|
||||
background: #ffffff;
|
||||
border-left: 4px solid #ccc;
|
||||
margin: 10px 0px 10px 10px;
|
||||
padding: 0px 0px 0px 5px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
blockquote span {
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
50
src_diploma/vue_frontend/src/components/Home.vue
Normal file
50
src_diploma/vue_frontend/src/components/Home.vue
Normal file
|
@ -0,0 +1,50 @@
|
|||
<template>
|
||||
<div>
|
||||
<p
|
||||
v-if="this.$root.store.api_error !== null"
|
||||
class="text-warning"
|
||||
>
|
||||
api_error: {{ this.$root.store.api_error }}
|
||||
</p>
|
||||
<Nav></Nav>
|
||||
<div class="my-home container-fluid">
|
||||
<div class="row">
|
||||
<div id="serach" class="col-sm-2 border-right fill">
|
||||
<LWords v-if="navSS()"></LWords>
|
||||
<LFunctors v-else></LFunctors>
|
||||
</div>
|
||||
<div class="col-sm-10">
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Nav from "./Nav"
|
||||
import LWords from "./LWords"
|
||||
import LFunctors from "./LFunctors"
|
||||
import MainDispl from "./MainDispl"
|
||||
|
||||
export default {
|
||||
name: 'Home',
|
||||
components: {
|
||||
Nav: Nav,
|
||||
LWords: LWords,
|
||||
LFunctors: LFunctors,
|
||||
MainDispl: MainDispl,
|
||||
},
|
||||
methods: {
|
||||
navSS: function () {
|
||||
return this.$root.storeGet("navSS") === "words"
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.my-home {
|
||||
padding-top: 10px;
|
||||
}
|
||||
</style>
|
51
src_diploma/vue_frontend/src/components/LFunctors.vue
Normal file
51
src_diploma/vue_frontend/src/components/LFunctors.vue
Normal file
|
@ -0,0 +1,51 @@
|
|||
<template>
|
||||
<div>
|
||||
<table>
|
||||
<tr v-for="functor in functors">
|
||||
<td><a href="#" v-on:click="selectFunctor(functor)">{{ functor[0] }}</a></td>
|
||||
<td>({{ functor[1] }})</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "LWords",
|
||||
props: ["appState"],
|
||||
data() {return {
|
||||
functors: []
|
||||
}},
|
||||
methods: {
|
||||
apiGetFunctors: function () {
|
||||
var component = this
|
||||
this.$http.get(this.$root.store.api_addr + "/api/functors")
|
||||
.then(function(response) {
|
||||
component.$root.store.api_error = null
|
||||
component.functors = response.data
|
||||
})
|
||||
.catch(function(error) {
|
||||
component.$root.store.api_error = error
|
||||
})
|
||||
},
|
||||
selectFunctor: function (functor) {
|
||||
this.$router.push({
|
||||
name: "MainDispl",
|
||||
params: {
|
||||
hw: functor[0],
|
||||
fmode: true
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted: function() {
|
||||
this.apiGetFunctors()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
80
src_diploma/vue_frontend/src/components/LWords.vue
Normal file
80
src_diploma/vue_frontend/src/components/LWords.vue
Normal file
|
@ -0,0 +1,80 @@
|
|||
<template>
|
||||
<div>
|
||||
<select v-model="selectedLetter">
|
||||
<option v-for="letter in alphabet" :value="letter">
|
||||
{{ letter.toUpperCase() }} ({{ getNumWords(letter) }})
|
||||
</option>
|
||||
</select>
|
||||
<table>
|
||||
<tr v-for="word in getWords()">
|
||||
<td><a href="#" v-on:click="selectHw(word)">{{ word[0] }}
|
||||
<span v-if="$root.store.has_se.includes(word[0])">se</span>
|
||||
</a></td>
|
||||
<td>({{ word[1] }})</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "LWords",
|
||||
data() {return {
|
||||
alphabet: "abcčdefghijklmnoprsštuvzž",
|
||||
letters: {},
|
||||
selectedLetter: "a"
|
||||
}},
|
||||
methods: {
|
||||
apiGetWords: function() {
|
||||
var component = this
|
||||
this.$http.get(this.$root.storeGet("api_addr") + "/api/words")
|
||||
.then(function(response) {
|
||||
component.$root.store.api_error = null
|
||||
component.$root.store.has_se = response.data["has_se"]
|
||||
component.letters = response.data["sorted_words"]
|
||||
})
|
||||
.catch(function(error) {
|
||||
component.$root.store.api_error = error
|
||||
})
|
||||
},
|
||||
getNumWords: function(letter) {
|
||||
var entry = this.letters[letter]
|
||||
if (entry) {
|
||||
return entry.length
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
},
|
||||
getWords: function() {
|
||||
var entry = this.letters[this.selectedLetter]
|
||||
if (entry) {
|
||||
return entry
|
||||
} else {
|
||||
return []
|
||||
}
|
||||
},
|
||||
selectHw: function(word) {
|
||||
this.$router.push({
|
||||
name: "MainDispl",
|
||||
params: {
|
||||
hw: word[0],
|
||||
fmode: false
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted: function() {
|
||||
this.apiGetWords()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
select {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
120
src_diploma/vue_frontend/src/components/Login.vue
Normal file
120
src_diploma/vue_frontend/src/components/Login.vue
Normal file
|
@ -0,0 +1,120 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="col-sm-2">
|
||||
<a href="#" v-on:click="this.$root.routeBack">Nazaj</a>
|
||||
</div>
|
||||
<div class="ev-login col-sm-4 offset-sm-4">
|
||||
<div class="alert alert-danger" v-if="error">
|
||||
<p>{{ error }}</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input
|
||||
type="text"
|
||||
data-id="login.username"
|
||||
class="form-control js-login__username"
|
||||
placeholder="Uporabnik"
|
||||
v-model="credentials.username"
|
||||
>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input
|
||||
type="password"
|
||||
class="form-control js-login__password "
|
||||
placeholder="Geslo"
|
||||
v-model="credentials.password"
|
||||
>
|
||||
</div>
|
||||
<button
|
||||
data-id="login.submit"
|
||||
class="btn btn-primary solid blank js-login__submit"
|
||||
@click="submit()"
|
||||
>
|
||||
Prijava<i class="fa fa-arrow-circle-o-right"></i>
|
||||
</button>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<router-link to="/new_pass">Ste pozabili geslo?</router-link>
|
||||
<br>
|
||||
<br>
|
||||
Nov uporabnik?
|
||||
<br>
|
||||
<router-link to="/register">Ustvarite nov račun.</router-link>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Login',
|
||||
data () {
|
||||
return {
|
||||
credentials: {
|
||||
username: '',
|
||||
password: ''
|
||||
},
|
||||
loggingIn: false,
|
||||
error: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submit () {
|
||||
this.error = ""
|
||||
//this.loggingIn = true
|
||||
// Auth.login() returns a promise. A redirect will happen on success.
|
||||
// For errors, use .then() to capture the response to output
|
||||
// error_description (if exists) as shown below:
|
||||
/*
|
||||
this.$auth.login(credentials, 'dashboard').then((response) => {
|
||||
this.loggingIn = false
|
||||
this.error = utils.getError(response)
|
||||
})
|
||||
*/
|
||||
|
||||
if ( this.credentials.username === "" ||
|
||||
this.credentials.password === ""
|
||||
) {
|
||||
this.error = "Izpolnite vsa polja."
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
var data = {
|
||||
username: this.credentials.username,
|
||||
password: this.credentials.password
|
||||
}
|
||||
|
||||
var component = this
|
||||
this.$http.post(this.$root.storeGet("api_addr") + "/api/login",
|
||||
data, // the data to post
|
||||
{ headers: {
|
||||
'Content-type': 'application/x-www-form-urlencoded',
|
||||
}
|
||||
})
|
||||
.then(function (response) {
|
||||
component.$root.store.api_error = null
|
||||
var token = response.data.token
|
||||
if (token === null) {
|
||||
component.error = "Napačno uporabniško ime ali geslo."
|
||||
} else {
|
||||
// set cookies (if the page reloads)
|
||||
component.$root.store.username = component.credentials.username
|
||||
component.$root.store.token = token
|
||||
component.$router.go(-1)
|
||||
component.$cookies.set("valency_token", token, 60*60*48)
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
component.$root.store.api_error = err
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ev-login {
|
||||
margin-top: 100px;
|
||||
}
|
||||
</style>
|
256
src_diploma/vue_frontend/src/components/MainDispl.vue
Normal file
256
src_diploma/vue_frontend/src/components/MainDispl.vue
Normal file
|
@ -0,0 +1,256 @@
|
|||
<template>
|
||||
<!--load mode-->
|
||||
<div v-if="show_loader">
|
||||
<pulse-loader :color="loader_color"></pulse-loader>
|
||||
</div>
|
||||
|
||||
<!--edit mode (button: razvrsti po pomenih)-->
|
||||
<div v-else-if="state === 'editing'" class="container-fluid">
|
||||
<EditSenses
|
||||
v-bind:hw="hw"
|
||||
v-bind:sentences="sentences"
|
||||
v-bind:sens="sens"
|
||||
></EditSenses>
|
||||
</div>
|
||||
|
||||
<!--normal mode-->
|
||||
<div v-else class="container-fluid" id="head">
|
||||
|
||||
<!--header (verb/adjective, radio buttons)-->
|
||||
<div class="row">
|
||||
<div class="col-sm-4">
|
||||
<table>
|
||||
<tr><h4 id="main-displ-hw">{{ hw }}
|
||||
<span v-if="$root.store.has_se.includes(hw)">se</span>
|
||||
</h4></tr>
|
||||
<tr>{{ calcPos() }}</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-sm-8">
|
||||
<table>
|
||||
<tr>Združevanje vezljivostnih vzorcev:</tr>
|
||||
<tr>
|
||||
<label class="radio-inline"><input value="one" v-model="$root.store.radio" v-on:change="reload()" checked="" type="radio" name="optradio">posamezne povedi</label>
|
||||
<label class="radio-inline"><input value="two" v-model="$root.store.radio" v-on:change="reload()" type="radio" name="optradio">skupne udeleženske vloge</label>
|
||||
<label v-if="this.$root.store.navSS === 'words'" class="radio-inline"><input value="three" v-model="$root.store.radio" v-on:change="reload()" type="radio" name="optradio">po meri</label>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--frames-->
|
||||
<div v-if="$root.store.radio === 'three'" class="row">
|
||||
<div class="col-sm-4">
|
||||
<button v-on:click="userEdit">razvrsti po pomenih</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" v-for="frame in frames">
|
||||
<Frame
|
||||
v-bind:frameData="frame"
|
||||
v-bind:sensData="sens"
|
||||
v-bind:fmode="fmode">
|
||||
</Frame>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Frame from "./Frame"
|
||||
import EditSenses from "./EditSenses"
|
||||
import PulseLoader from 'vue-spinner/src/PulseLoader.vue'
|
||||
export default {
|
||||
name: "MainDispl",
|
||||
components: {
|
||||
Frame: Frame,
|
||||
EditSenses: EditSenses,
|
||||
PulseLoader: PulseLoader,
|
||||
},
|
||||
props: ["hw", "fmode"],
|
||||
data () { return {
|
||||
frames: [],
|
||||
sentences: {},
|
||||
sens: {
|
||||
senses: [],
|
||||
sense_map: {},
|
||||
},
|
||||
state: "loading", // editing, normal
|
||||
request_reload: false,
|
||||
loader_color: "#007bff",
|
||||
}},
|
||||
created: function () {
|
||||
this.reload()
|
||||
},
|
||||
computed: {
|
||||
show_loader: function () {
|
||||
return this.state === "loading" && this.$root.store.api_error !== null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
hw: function () {
|
||||
this.reload()
|
||||
},
|
||||
frames: function () {
|
||||
this.buildSentences()
|
||||
},
|
||||
request_reload: function () {
|
||||
if (this.request_reload) {
|
||||
this.request_reload = false
|
||||
this.reload()
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getFFrames: function(functor, reduce_fun=null) {
|
||||
// get frames in functor mode
|
||||
if (functor === null || functor === undefined) return
|
||||
if (reduce_fun === null) {
|
||||
switch (this.$root.store.radio) {
|
||||
case "one":
|
||||
reduce_fun = "reduce_0"
|
||||
break
|
||||
case "two":
|
||||
reduce_fun = "reduce_1"
|
||||
break
|
||||
default:
|
||||
reduce_fun = "reduce_0"
|
||||
break
|
||||
}
|
||||
}
|
||||
var component = this
|
||||
this.$http.get(
|
||||
this.$root.storeGet("api_addr") + "/api/functor-frames" +
|
||||
"?functor=" + functor + "&rf=" + reduce_fun)
|
||||
.then(function (response) {
|
||||
component.$root.store.api_error = null
|
||||
component.frames = response.data.frames
|
||||
component.state = "normal"
|
||||
})
|
||||
.catch(function(error) {
|
||||
component.$root.store.api_error = error
|
||||
})
|
||||
},
|
||||
getFrames: function (hw, reduce_fun=null) {
|
||||
if (hw === null || hw === undefined) return
|
||||
if (reduce_fun === null) {
|
||||
switch (this.$root.store.radio) {
|
||||
case "one":
|
||||
reduce_fun = "reduce_0"
|
||||
break
|
||||
case "two":
|
||||
reduce_fun = "reduce_1"
|
||||
break
|
||||
case "three":
|
||||
reduce_fun = "reduce_5"
|
||||
break
|
||||
}
|
||||
}
|
||||
var component = this
|
||||
this.$http.get(
|
||||
this.$root.storeGet("api_addr") + "/api/frames" +
|
||||
"?hw=" + hw + "&rf=" + reduce_fun)
|
||||
.then(function (response) {
|
||||
component.$root.store.api_error = null
|
||||
component.frames = response.data.frames
|
||||
component.state = "normal"
|
||||
})
|
||||
.catch(function(error) {
|
||||
component.$root.store.api_error = error
|
||||
})
|
||||
},
|
||||
buildSentences: function () {
|
||||
if (this.frames.length == 0) {
|
||||
return
|
||||
}
|
||||
this.sentences = {}
|
||||
for (var fi in this.frames) {
|
||||
for (var si in this.frames[fi].sentences) {
|
||||
var sentence = this.frames[fi].sentences[si]
|
||||
// get ssj_id without .t123
|
||||
var ssj_id = sentence[0][0].split(".")
|
||||
ssj_id.splice(-1, 1) // removes last element
|
||||
ssj_id = ssj_id.join(".")
|
||||
var words = []
|
||||
var hw_idx = -1
|
||||
var tmp_hw = this.hw
|
||||
if (tmp_hw[tmp_hw.length - 1] === "_") {
|
||||
tmp_hw = tmp_hw.substr(0, tmp_hw.length - 1)
|
||||
}
|
||||
for (var i in sentence) {
|
||||
words.push(sentence[i][1].word)
|
||||
if (sentence[i][1].lemma === tmp_hw && hw_idx == -1) {
|
||||
hw_idx = i
|
||||
}
|
||||
}
|
||||
this.sentences[ssj_id] = {
|
||||
hw_idx: hw_idx,
|
||||
words: words
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
getSenses: function (hw, callback) {
|
||||
if (hw === null || hw === undefined) {
|
||||
return
|
||||
}
|
||||
var component = this
|
||||
this.$http.get(
|
||||
this.$root.store.api_addr + "/api/senses/get" + "?hw=" + hw)
|
||||
.then(function(response) {
|
||||
// console.log(response.data)
|
||||
component.sens.senses = response.data.senses
|
||||
component.sens.sense_map = response.data.sense_map
|
||||
callback()
|
||||
})
|
||||
},
|
||||
reload: function () {
|
||||
this.state = "loading"
|
||||
this.sentences = {}
|
||||
if (this.$root.store.navSS === "functors") this.getFFrames(this.hw)
|
||||
else {
|
||||
this.getFrames(this.hw)
|
||||
if (this.$root.store.radio === "three") {
|
||||
this.getSenses(this.hw, this.sortBySense)
|
||||
}
|
||||
}
|
||||
this.calcPos()
|
||||
},
|
||||
userEdit: function () {
|
||||
// authenticate the user for this
|
||||
var tthis = this
|
||||
this.$root.checkToken()
|
||||
.then(function (response) {tthis.state = "editing"})
|
||||
.catch(function (err) {alert("Za urejanje je potrebna prijava.")}
|
||||
)
|
||||
},
|
||||
calcPos: function() {
|
||||
var bfmode = this.fmode
|
||||
if (typeof(bfmode) === "string") {
|
||||
bfmode = (bfmode === "true")
|
||||
}
|
||||
if (bfmode) return "udeleženska vloga"
|
||||
else if (this.hw.substr(this.hw.length-1) === "_") return "pridevnik"
|
||||
return "glagol"
|
||||
},
|
||||
sortBySense: function() {
|
||||
// frames with defined senses on top
|
||||
var undefFrames = []
|
||||
var defFrames = []
|
||||
//console.log(Object.keys(this.sens.sense_map))
|
||||
for (var i=0; i<this.frames.length; i++) {
|
||||
var sense_id = this.frames[i].sense_info.sense_id
|
||||
if (sense_id === "nedefinirano") undefFrames.push(this.frames[i])
|
||||
else defFrames.push(this.frames[i])
|
||||
}
|
||||
this.frames = defFrames.concat(undefFrames)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
#main-displ-hw {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
</style>
|
74
src_diploma/vue_frontend/src/components/Nav.vue
Normal file
74
src_diploma/vue_frontend/src/components/Nav.vue
Normal file
|
@ -0,0 +1,74 @@
|
|||
<template>
|
||||
<nav>
|
||||
<b-navbar toggleable="md" type="light" variant="light">
|
||||
<b-navbar-toggle target="nav_collapse"></b-navbar-toggle>
|
||||
<b-navbar-brand>Vezljivostni vzorci slovenskih glagolov</b-navbar-brand>
|
||||
<b-collapse is-nav id="nav_collapse">
|
||||
|
||||
<b-navbar-nav>
|
||||
<b-nav-item-dropdown text="Prikaz" right>
|
||||
<b-dropdown-item v-for="option in search_options"
|
||||
:value="option.val"
|
||||
:key="option.val"
|
||||
v-on:click="setNavSS(option.val)">
|
||||
{{ option.key }}
|
||||
</b-dropdown-item>
|
||||
</b-nav-item-dropdown>
|
||||
</b-navbar-nav>
|
||||
|
||||
<!-- Right aligned nav items -->
|
||||
<b-navbar-nav class="ml-auto" right v-if="this.loggedIn()">
|
||||
<b-nav-item>
|
||||
Uporabnik: {{ this.$root.store.username }}
|
||||
<a href="#" v-on:click="logOut()">(odjava)</a>
|
||||
</b-nav-item>
|
||||
</b-navbar-nav>
|
||||
<b-navbar-nav class="ml-auto" right v-else>
|
||||
<b-nav-item>
|
||||
<router-link to="/register">
|
||||
Registracija
|
||||
</router-link>
|
||||
</b-nav-item>
|
||||
<b-nav-item>
|
||||
<router-link to="/login">
|
||||
Prijava
|
||||
</router-link>
|
||||
</b-nav-item>
|
||||
</b-navbar-nav>
|
||||
|
||||
</b-collapse>
|
||||
</b-navbar>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Nav",
|
||||
props: ["appState"],
|
||||
data() {return {
|
||||
search_options: [
|
||||
{key: "besede", val: "words"},
|
||||
{key: "udeleženske vloge", val: "functors"},
|
||||
],
|
||||
}},
|
||||
methods: {
|
||||
setNavSS(val) {
|
||||
this.$root.store.radio = "one"
|
||||
this.$root.store.navSS = val
|
||||
this.$router.push({
|
||||
name: "Home"
|
||||
})
|
||||
},
|
||||
loggedIn() {
|
||||
return (this.$root.store.token !== null)
|
||||
},
|
||||
logOut() {
|
||||
this.$root.store.token = null
|
||||
this.$root.store.username = null
|
||||
this.$router.push({
|
||||
name: "Home"
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
106
src_diploma/vue_frontend/src/components/NewPass.vue
Normal file
106
src_diploma/vue_frontend/src/components/NewPass.vue
Normal file
|
@ -0,0 +1,106 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="col-sm-2">
|
||||
<a href="#" v-on:click="this.$root.routeBack">Nazaj</a>
|
||||
</div>
|
||||
<div class="ev-login col-sm-4 offset-sm-4">
|
||||
<div class="alert alert-danger" v-if="error">
|
||||
<p>{{ error }}</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input
|
||||
type="text"
|
||||
data-id="login.username"
|
||||
class="form-control js-login__username"
|
||||
placeholder="Uporabnik"
|
||||
v-model="credentials.username"
|
||||
>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input
|
||||
type="email"
|
||||
class="form-control"
|
||||
placeholder="e-pošta"
|
||||
v-model="credentials.email"
|
||||
>
|
||||
</div>
|
||||
<div>
|
||||
<p>Novo geslo bo poslano na vaš e-poštni naslov.</p>
|
||||
</div>
|
||||
<button
|
||||
data-id="new_pass.submit"
|
||||
class="btn btn-primary solid blank js-login__submit"
|
||||
@click="submit()"
|
||||
>
|
||||
Novo geslo<i class="fa fa-arrow-circle-o-right"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'NewPass',
|
||||
data () {
|
||||
return {
|
||||
credentials: {
|
||||
username: '',
|
||||
email: ''
|
||||
},
|
||||
error: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submit () {
|
||||
this.error = ""
|
||||
//this.loggingIn = true
|
||||
// Auth.login() returns a promise. A redirect will happen on success.
|
||||
// For errors, use .then() to capture the response to output
|
||||
// error_description (if exists) as shown below:
|
||||
/*
|
||||
this.$auth.login(credentials, 'dashboard').then((response) => {
|
||||
this.loggingIn = false
|
||||
this.error = utils.getError(response)
|
||||
})
|
||||
*/
|
||||
|
||||
if ( this.credentials.username === "" ||
|
||||
this.credentials.email === ""
|
||||
) {
|
||||
this.error = "Izpolnite vsa polja."
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
var data = {
|
||||
username: this.credentials.username,
|
||||
email: this.credentials.email
|
||||
}
|
||||
|
||||
var component = this
|
||||
this.$http.post(this.$root.storeGet("api_addr") + "/api/new_pass",
|
||||
data, // the data to post
|
||||
{ headers: {
|
||||
'Content-type': 'application/x-www-form-urlencoded',
|
||||
}
|
||||
})
|
||||
.then(function (response) {
|
||||
component.$root.store.api_error = null
|
||||
var confirmation = response.data.confirmation
|
||||
component.$router.push({
|
||||
name: "Home"
|
||||
})
|
||||
})
|
||||
.catch(function (err) {
|
||||
component.$root.store.api_error = err
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ev-login {
|
||||
margin-top: 100px;
|
||||
}
|
||||
</style>
|
138
src_diploma/vue_frontend/src/components/Register.vue
Normal file
138
src_diploma/vue_frontend/src/components/Register.vue
Normal file
|
@ -0,0 +1,138 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="col-sm-2">
|
||||
<a href="#" v-on:click="this.$root.routeBack">Nazaj</a>
|
||||
</div>
|
||||
<div class="ev-login col-sm-4 offset-sm-4">
|
||||
<div class="alert alert-danger" v-if="error">
|
||||
<p>{{ error }}</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control js-login__username"
|
||||
placeholder="Uporabnik"
|
||||
v-model="credentials.username"
|
||||
autocomplete="off"
|
||||
>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input
|
||||
type="email"
|
||||
class="form-control"
|
||||
placeholder="e-pošta"
|
||||
v-model="credentials.email"
|
||||
autocomplete="off"
|
||||
>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input
|
||||
type="password"
|
||||
class="form-control js-login__password "
|
||||
placeholder="Geslo"
|
||||
v-model="credentials.password"
|
||||
autocomplete="off"
|
||||
>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input
|
||||
type="password"
|
||||
class="form-control js-login__password "
|
||||
placeholder="Ponovite geslo."
|
||||
v-model="credentials.snd_password"
|
||||
autocomplete="off"
|
||||
>
|
||||
</div>
|
||||
<button
|
||||
class="btn btn-primary solid blank js-login__submit"
|
||||
@click="submit()"
|
||||
>
|
||||
Registracija<i class="fa fa-arrow-circle-o-right"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Register',
|
||||
data () { return {
|
||||
credentials: {
|
||||
username: "",
|
||||
password: "",
|
||||
snd_password: "",
|
||||
email: ""
|
||||
},
|
||||
error: ""
|
||||
}},
|
||||
methods: {
|
||||
clearFields () {
|
||||
for (var key in this.credentials) {
|
||||
this.credentials[key] = ""
|
||||
}
|
||||
},
|
||||
checkEmail () {
|
||||
// check? ... todo
|
||||
return true
|
||||
},
|
||||
submit () {
|
||||
//console.log(this.credentials.password)
|
||||
//console.log(this.credentials.snd_password)
|
||||
const credentials = {
|
||||
username: this.credentials.username,
|
||||
password: this.credentials.password
|
||||
}
|
||||
|
||||
// check if fields are full
|
||||
for (var key in this.credentials) {
|
||||
if (credentials[key] === "") {
|
||||
this.error = "Izpolnite vsa polja."
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// check e-mail
|
||||
if (!this.checkEmail(this.credentials.email)) {
|
||||
this.error = "Preverite e-poštni naslov."
|
||||
return
|
||||
}
|
||||
|
||||
// check passwords
|
||||
if (this.credentials.password !== this.credentials.snd_password) {
|
||||
this.error = "Gesli se ne ujemata."
|
||||
this.credentials.password = ""
|
||||
this.credentials.snd_password = ""
|
||||
return
|
||||
}
|
||||
|
||||
var component = this
|
||||
const post_data = {
|
||||
username: this.credentials.username,
|
||||
password: this.credentials.password,
|
||||
email: this.credentials.email,
|
||||
}
|
||||
this.$http.post(this.$root.storeGet("api_addr") + "/api/register",
|
||||
post_data, // the data to post
|
||||
{ headers: {
|
||||
'Content-type': 'application/json',
|
||||
}
|
||||
})
|
||||
.then(function (response) {
|
||||
component.$router.push({
|
||||
name: "Home"
|
||||
})
|
||||
})
|
||||
.catch(function (err) {
|
||||
component.$root.store.api_error = err
|
||||
component.error = "Registracija ni uspela."
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ev-login {
|
||||
margin-top: 100px;
|
||||
}
|
||||
</style>
|
48
src_diploma/vue_frontend/src/components/Sense.vue
Normal file
48
src_diploma/vue_frontend/src/components/Sense.vue
Normal file
|
@ -0,0 +1,48 @@
|
|||
<template>
|
||||
<div class="pb-3">
|
||||
<div v-if="sense === undefined">
|
||||
pomen ni definiran
|
||||
</div>
|
||||
<div v-else>
|
||||
<span>{{ sense.desc }}</span>
|
||||
<br>
|
||||
|
||||
<small class="text-secondary">
|
||||
- {{ sense.author }}
|
||||
{{ gen_id() }}
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Sense",
|
||||
props: ["sense"],
|
||||
methods: {
|
||||
gen_id: function() {
|
||||
var id_arr = this.sense.sense_id.split("-")
|
||||
var ret = ""
|
||||
if (this.sense.author === "SSKJ") {
|
||||
if (id_arr[1] !== "0") {
|
||||
ret += ("[" + id_arr[1] + ["] "])
|
||||
}
|
||||
if (id_arr[2] !== "0") {
|
||||
ret += ("pomen " + id_arr[2])
|
||||
if (id_arr[3] !== "0") {
|
||||
ret += ("." + id_arr[3])
|
||||
}
|
||||
}
|
||||
if (id_arr[4] === "sopo") {
|
||||
ret += " (sopomenka)"
|
||||
}
|
||||
}
|
||||
// ret = this.sense.sense_id //debugging
|
||||
if (ret.length > 0) {
|
||||
ret = ": " + ret
|
||||
}
|
||||
return ret
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
140
src_diploma/vue_frontend/src/main.js
Normal file
140
src_diploma/vue_frontend/src/main.js
Normal file
|
@ -0,0 +1,140 @@
|
|||
// The Vue build version to load with the `import` command
|
||||
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
|
||||
import Vue from 'vue'
|
||||
import App from './App'
|
||||
import router from './router'
|
||||
import VueCookies from "vue-cookies"
|
||||
|
||||
// bootstrap
|
||||
import BootstrapVue from "bootstrap-vue"
|
||||
import 'bootstrap/dist/css/bootstrap.css'
|
||||
import 'bootstrap-vue/dist/bootstrap-vue.css'
|
||||
|
||||
// ajax
|
||||
import axios from "axios"
|
||||
|
||||
// config
|
||||
import config_data from "../config/config.json"
|
||||
// console.log(config_data)
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
// cokies
|
||||
Vue.use(VueCookies)
|
||||
|
||||
// bootstrap
|
||||
Vue.use(BootstrapVue)
|
||||
|
||||
// CORS
|
||||
// Vue.$http.headers.common['Access-Control-Allow-Origin'] = true
|
||||
|
||||
Vue.prototype.$http = axios
|
||||
|
||||
// hand-made global storage
|
||||
const store = {
|
||||
api_error: null,
|
||||
api_addr: config_data.api_addr,
|
||||
// api_addr: "http://localhost:5004", // development (webpack)
|
||||
// api_addr: "http://193.2.76.103:5004", // production
|
||||
token: null,
|
||||
username: null,
|
||||
navSS: "words",
|
||||
radio: "one",
|
||||
has_se: [], // used for appending (se) to certain verbs
|
||||
}
|
||||
|
||||
const store_methods = {
|
||||
storeSet: function(key, val) {
|
||||
store[key] = val
|
||||
},
|
||||
storeGet: function(key) {
|
||||
// returns undefined if not in dict.
|
||||
// check if (variable)
|
||||
return store[key]
|
||||
}
|
||||
}
|
||||
|
||||
const login_methods = {
|
||||
checkToken: function () {
|
||||
var tthis = this
|
||||
return new Promise(function (resolve, reject) {
|
||||
if (tthis.store.token === null) {
|
||||
tthis.store.username = null
|
||||
reject(false)
|
||||
}
|
||||
var data = {
|
||||
token: tthis.store.token,
|
||||
user: tthis.store.username
|
||||
}
|
||||
tthis.$http.post(tthis.store.api_addr + "/api/token", data,
|
||||
{ headers: {
|
||||
'Content-type': 'application/x-www-form-urlencoded',
|
||||
}}
|
||||
)
|
||||
.then(function (response) {
|
||||
tthis.store.api_error = null
|
||||
if (response.data.confirmation) {
|
||||
resolve(true)
|
||||
} else {
|
||||
tthis.store.username = null
|
||||
tthis.store.token = null
|
||||
reject(false)
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
tthis.store.api_error = err
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const other_methods = {
|
||||
routeBack: function() {
|
||||
this.$router.go(-1)
|
||||
},
|
||||
mkspace: function (idx, word) {
|
||||
var stopwords = [".", ",", ":", ";"]
|
||||
if (stopwords.includes(word)) return false
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
/* eslint-disable no-new */
|
||||
new Vue({
|
||||
el: '#app',
|
||||
router,
|
||||
components: { App },
|
||||
template: '<App/>',
|
||||
data() { return {
|
||||
store: store,
|
||||
}},
|
||||
methods: Object.assign(store_methods, login_methods, other_methods),
|
||||
beforeCreate: function() {
|
||||
document.title = "Vezljivostni vzorci"
|
||||
if (this.$cookies.isKey("valency_token")) {
|
||||
var cookie_token = this.$cookies.get("valency_token")
|
||||
var data = {
|
||||
token: cookie_token,
|
||||
}
|
||||
var component = this
|
||||
this.$http.post(store.api_addr + "/api/token",
|
||||
data, // the data to post
|
||||
{ headers: {
|
||||
'Content-type': 'application/x-www-form-urlencoded',
|
||||
}
|
||||
})
|
||||
.then(function (response) {
|
||||
if (response.data.confirmation) {
|
||||
store.username = response.data.username
|
||||
store.token = cookie_token
|
||||
} else {
|
||||
this.$cookies.remove("valency_token")
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
store.api_error = err
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
48
src_diploma/vue_frontend/src/router/index.js
Normal file
48
src_diploma/vue_frontend/src/router/index.js
Normal file
|
@ -0,0 +1,48 @@
|
|||
import Vue from 'vue'
|
||||
import Router from 'vue-router'
|
||||
import Home from "@/components/Home"
|
||||
import Login from "@/components/Login"
|
||||
import Register from "@/components/Register"
|
||||
import NewPass from "@/components/NewPass"
|
||||
import MainDispl from "@/components/MainDispl"
|
||||
import EditSenses from "@/components/EditSenses"
|
||||
|
||||
Vue.use(Router)
|
||||
|
||||
export default new Router({
|
||||
mode: "history",
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
redirect: "/home"
|
||||
},
|
||||
{
|
||||
path: "/home",
|
||||
name: "Home",
|
||||
component: Home,
|
||||
children: [
|
||||
{
|
||||
path: "words/:hw",
|
||||
name: "MainDispl",
|
||||
component: MainDispl,
|
||||
props: true,
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
name: 'Login',
|
||||
component: Login
|
||||
},
|
||||
{
|
||||
path: '/register',
|
||||
name: 'Register',
|
||||
component: Register
|
||||
},
|
||||
{
|
||||
path: '/new_pass',
|
||||
name: 'NewPass',
|
||||
component: NewPass
|
||||
}
|
||||
]
|
||||
})
|
0
src_diploma/vue_frontend/static/.gitkeep
Normal file
0
src_diploma/vue_frontend/static/.gitkeep
Normal file
3
src_diploma/vue_frontend/webpack.config.js
Normal file
3
src_diploma/vue_frontend/webpack.config.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
proxy: {
|
||||
'*': 'http://localhost:5004'
|
||||
}
|
Loading…
Reference in New Issue
Block a user