diff --git a/README.md b/README.md index fbf20a8..4f423fb 100644 --- a/README.md +++ b/README.md @@ -15,11 +15,14 @@ The interface runs in docker and requires the host to have installed wireguard, * docker # Installation + +## Docker ```bash docker run -d \ --cap-add NET_ADMIN \ --name wireguard-manager \ --net host \ +-p "51800-51900:51800-51900/udp" \ -v wireguard-manager:/config \ -e PORT="8888" \ -e ADMIN_USERNAME="admin" \ @@ -27,11 +30,47 @@ docker run -d \ perara/wireguard-manager ``` +## Docker-compose +```yaml + wireguard: + container_name: wireguard-manager + image: perara/wireguard-manager + cap_add: + - NET_ADMIN + ports: + - 51800:51900/udp + - 8888:8888 + volumes: + - ./ops/wireguard/_data:/config + environment: + HOST: 0.0.0.0 + PORT: 8888 + ADMIN_PASSWORD: admin + ADMIN_USERNAME: admin + WEB_CONCURRENCY: 1 +``` + +# Environment variables +| Environment | Description | Recommended | +|------------------|--------------------------------------------------------------------------|-------------| +| GUNICORN_CONF | Location of custom gunicorn configuration | default | +| WORKERS_PER_CORE | How many concurrent workers should there be per available core (Gunicorn | default | +| WEB_CONCURRENCY | The number of worker processes for handling requests. (Gunicorn) | 1 | +| HOST | 0.0.0.0 or unix:/tmp/gunicorn.sock if reverse proxy. Remember to mount | 0.0.0.0 | +| PORT | The port to use if running with IP host bind | 80 | +| LOG_LEVEL | Logging level of gunicorn/python | info | +| ADMIN_USERNAME | Default admin username on database creation | admin | +| ADMIN_PASSWORD | Default admin password on database creation | admin | # Usage When docker container is started, go to http://localhost:80 +# Reverse Proxy +Use jwilder/nginx-proxy or similar. + # Showcase +![Illustration](docs/images/0.png) + ![Illustration](docs/images/1.png) ![Illustration](docs/images/2.png) @@ -40,6 +79,14 @@ When docker container is started, go to http://localhost:80 ![Illustration](docs/images/4.png) +![Illustration](docs/images/5.png) + +![Illustration](docs/images/6.png) + +![Illustration](docs/images/7.png) + +![Illustration](docs/images/8.png) + # Roadmap * Eventual bugfixes * Improve Auth diff --git a/docs/images/0.png b/docs/images/0.png new file mode 100644 index 0000000..6a30d18 Binary files /dev/null and b/docs/images/0.png differ diff --git a/docs/images/1.png b/docs/images/1.png index c672cf1..595a993 100644 Binary files a/docs/images/1.png and b/docs/images/1.png differ diff --git a/docs/images/2.png b/docs/images/2.png index 2112c61..184cc0b 100644 Binary files a/docs/images/2.png and b/docs/images/2.png differ diff --git a/docs/images/3.png b/docs/images/3.png index af8607d..0f8f42a 100644 Binary files a/docs/images/3.png and b/docs/images/3.png differ diff --git a/docs/images/4.png b/docs/images/4.png index 0d6629c..22c4609 100644 Binary files a/docs/images/4.png and b/docs/images/4.png differ diff --git a/docs/images/5.png b/docs/images/5.png new file mode 100644 index 0000000..a79ee62 Binary files /dev/null and b/docs/images/5.png differ diff --git a/docs/images/6.png b/docs/images/6.png new file mode 100644 index 0000000..9eda05e Binary files /dev/null and b/docs/images/6.png differ diff --git a/docs/images/7.png b/docs/images/7.png new file mode 100644 index 0000000..88490f2 Binary files /dev/null and b/docs/images/7.png differ diff --git a/docs/images/8.png b/docs/images/8.png new file mode 100644 index 0000000..f826213 Binary files /dev/null and b/docs/images/8.png differ diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..45eea79 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,25 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "@angular/cdk": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-9.2.0.tgz", + "integrity": "sha512-jeeznvNDpR9POuxzz8Y0zFvMynG9HCJo3ZPTqOjlOq8Lj8876+rLsHDvKEMeLdwlkdi1EweYJW1CLQzI+TwqDA==", + "requires": { + "parse5": "^5.0.0" + } + }, + "@angular/flex-layout": { + "version": "9.0.0-beta.29", + "resolved": "https://registry.npmjs.org/@angular/flex-layout/-/flex-layout-9.0.0-beta.29.tgz", + "integrity": "sha512-93sxR+kYfYMOdnlWL0Q77FZ428gg8XnBu0YZm6GsCdkw/vLggIT/G1ZAqHlCPIODt6pxmCJ5KXh4ShvniIYDsA==" + }, + "parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "optional": true + } + } +} diff --git a/wg_dashboard_backend/database.py b/wg_dashboard_backend/database.py new file mode 100644 index 0000000..b22a012 --- /dev/null +++ b/wg_dashboard_backend/database.py @@ -0,0 +1,13 @@ +import sqlalchemy +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import sessionmaker +import const + +engine = sqlalchemy.create_engine( + const.DATABASE_URL, connect_args={"check_same_thread": False} +) + + +SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) + +Base = declarative_base() diff --git a/wg_dashboard_backend/db/user.py b/wg_dashboard_backend/db/user.py index e7b7513..b5f5509 100644 --- a/wg_dashboard_backend/db/user.py +++ b/wg_dashboard_backend/db/user.py @@ -6,16 +6,8 @@ from passlib.context import CryptContext import schemas -pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") -def verify_password(plain_password, hashed_password): - return pwd_context.verify(plain_password, hashed_password) - - -def get_password_hash(password): - return pwd_context.hash(password) - def update_user(sess: Session, form_data: schemas.UserInDB): user = get_user_by_name(sess, form_data.username) diff --git a/wg_dashboard_backend/db/wireguard.py b/wg_dashboard_backend/db/wireguard.py index fa4a437..4be3eef 100644 --- a/wg_dashboard_backend/db/wireguard.py +++ b/wg_dashboard_backend/db/wireguard.py @@ -5,7 +5,7 @@ import typing import const import script.wireguard from sqlalchemy import exists -from sqlalchemy.orm import Session +from sqlalchemy.orm import Session, joinedload import util import models import schemas @@ -17,43 +17,9 @@ _LOGGER.setLevel(logging.DEBUG) def start_client(sess: Session, peer: schemas.WGPeer): db_peer: models.WGPeer = peer_query_get_by_address(sess, peer.address, peer.server).one() - client_file = os.path.join(const.CLIENT_DIR(db_peer.server_ref.interface), str(db_peer.id) + ".conf") + client_file = os.path.join(const.CLIENT_DIR(db_peer.server.interface), str(db_peer.id) + ".conf") import subprocess output = subprocess.check_output(const.CMD_WG_QUICK + ["up", client_file], stderr=subprocess.STDOUT) - print(output) - - -def server_generate_config(sess: Session, server: schemas.WGServer): - db_server: models.WGServer = server_query_get_by_interface(sess, server.interface).one() - - result = util.jinja_env.get_template("server.j2").render( - data=db_server - ) - - interface = db_server.interface - server_file = const.SERVER_FILE(interface) - - with open(server_file, "w+") as f: - f.write(result) - os.chmod(server_file, 0o600) - - return result - - -def peer_generate_config(sess: Session, peer: schemas.WGPeer): - db_peer: models.WGPeer = peer_query_get_by_address(sess, peer.address, peer.server).one() - - result = util.jinja_env.get_template("peer.j2").render( - data=db_peer - ) - - peer_file = const.PEER_FILE(db_peer) - - with open(peer_file, "w+") as f: - f.write(result) - os.chmod(peer_file, 0o600) - - return result def peer_query_get_by_address(sess: Session, address: str, server: str): @@ -62,42 +28,6 @@ def peer_query_get_by_address(sess: Session, address: str, server: str): .filter(models.WGPeer.server == server) -def peer_insert(sess: Session, peer: schemas.WGPeer) -> schemas.WGPeer: - db_server: models.WGServer = server_query_get_by_interface(sess, peer.server).one() - db_peer = models.WGPeer(**peer.dict()) - address_space = set(ipaddress.ip_network(db_server.address, strict=False).hosts()) - occupied_space = set() - for p in db_server.peers: - try: - occupied_space.add(ipaddress.ip_address(p.address.split("/")[0])) - except ValueError as e: - print(e) - pass # Ignore invalid addresses. These are out of address_space - - address_space -= occupied_space - - # Select first available address - db_peer.address = str(list(address_space).pop(0)) + "/32" - - # Private public key generation - private_key, public_key = script.wireguard.generate_keys() - db_peer.private_key = private_key - db_peer.public_key = public_key - - # Set 0.0.0.0/0, ::/0 as default allowed ips - db_peer.allowed_ips = ', '.join(const.PEER_DEFAULT_ALLOWED_IPS) - - # Set unnamed - db_peer.name = "Unnamed" - - db_peer.dns = db_server.endpoint - - sess.add(db_peer) - sess.commit() - - return peer.from_orm(db_peer) - - def peer_dns_set(sess: Session, peer: schemas.WGPeer) -> schemas.WGPeer: db_peer: models.WGPeer = peer_query_get_by_address(sess, peer.address, peer.server).one() db_peer.dns = peer.dns @@ -109,14 +39,11 @@ def peer_dns_set(sess: Session, peer: schemas.WGPeer) -> schemas.WGPeer: def peer_remove(sess: Session, peer: schemas.WGPeer) -> bool: - db_peers: models.WGPeer = peer_query_get_by_address(sess, peer.address, peer.server).all() + db_peers = peer.filter_query(sess).all() + for db_peer in db_peers: sess.delete(db_peer) sess.commit() - try: - os.remove(const.PEER_FILE(db_peer)) - except: - pass return True @@ -181,17 +108,6 @@ def server_get_all(sess: Session) -> typing.List[schemas.WGServer]: return [schemas.WGServer.from_orm(db_interface) for db_interface in db_interfaces] -def server_add(sess: Session, server: schemas.WGServer) -> schemas.WGServer: - if sess.query(exists().where(models.WGServer.interface == server.interface)).scalar(): - raise ValueError("The server interface %s already exists in the database" % server.interface) - - db_server = server.convert() - sess.add(db_server) - sess.commit() - - return server.from_orm(db_server) - - def server_remove(sess: Session, server: schemas.WGServer) -> bool: db_server = server_query_get_by_interface(sess, server.interface).one() if db_server is None: diff --git a/wg_dashboard_backend/main.py b/wg_dashboard_backend/main.py index fbbb68d..a32fe81 100644 --- a/wg_dashboard_backend/main.py +++ b/wg_dashboard_backend/main.py @@ -1,7 +1,11 @@ import logging import os - from sqlalchemy_utils import database_exists +from starlette.middleware.base import BaseHTTPMiddleware + +import middleware +from database import engine, SessionLocal +from routers.v1 import user, server, peer, wg logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) @@ -13,404 +17,91 @@ if not logger.hasHandlers(): import pkg_resources import uvicorn as uvicorn from fastapi.staticfiles import StaticFiles -import databases -from sqlalchemy.orm import sessionmaker, Session -from starlette.responses import FileResponse, JSONResponse -import sqlalchemy -import const -from datetime import datetime, timedelta -import db.wireguard -import db.user -import jwt -from fastapi import Depends, FastAPI, HTTPException, status -from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm -from jwt import PyJWTError -import script.wireguard -import typing -import models -import schemas - -database = databases.Database(const.DATABASE_URL) +from sqlalchemy.orm import Session +from starlette.responses import FileResponse +from fastapi import Depends, FastAPI -engine = sqlalchemy.create_engine( - const.DATABASE_URL, connect_args={"check_same_thread": False} -) +import models -oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/token") -SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) app = FastAPI() +app.add_middleware(BaseHTTPMiddleware, dispatch=middleware.db_session_middleware) + +if not database_exists(engine.url): + models.Base.metadata.create_all(engine) + # Create default user + _db: Session = SessionLocal() + _db.add(models.User( + username=os.getenv("ADMIN_USERNAME", "admin"), + password=middleware.get_password_hash(os.getenv("ADMIN_PASSWORD", "admin")), + full_name="Admin", + role="admin", + email="" + )) + _db.commit() + _db.close() + + +app.include_router( + user.router, + prefix="/api/v1", + tags=["user"], + dependencies=[], + responses={404: {"description": "Not found"}} +) -# Dependency -def get_db(): - try: - db = SessionLocal() - yield db - finally: - db.close() - - -def create_access_token(*, data: dict, expires_delta: timedelta = None): - to_encode = data.copy() - if expires_delta: - expire = datetime.utcnow() + expires_delta - else: - expire = datetime.utcnow() + timedelta(minutes=15) - to_encode.update({"exp": expire}) - encoded_jwt = jwt.encode(to_encode, const.SECRET_KEY, algorithm=const.ALGORITHM) - return encoded_jwt - - -def auth(token: str = Depends(oauth2_scheme), sess: Session = Depends(get_db)): - credentials_exception = HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, - detail="Could not validate credentials", - headers={"WWW-Authenticate": "Bearer"}, - ) - - try: - payload = jwt.decode(token, const.SECRET_KEY, algorithms=[const.ALGORITHM]) - username: str = payload.get("sub") - if username is None: - raise credentials_exception - - except PyJWTError: - raise credentials_exception - user = db.user.get_user_by_name(sess, username) - if user is None: - raise credentials_exception - return user - - -@app.get("/api/logout") -def logout(user: schemas.User = Depends(auth)): - # TODO - return {} - - -@app.post("/api/user/edit", response_model=schemas.User) -def edit(form_data: schemas.UserInDB, user: schemas.User = Depends(auth), sess: Session = Depends(get_db)): - - form_data.password = db.user.get_password_hash(form_data.password) - - db_user = db.user.update_user(sess, form_data) - - return schemas.User.from_orm(db_user) - - -@app.post("/api/login", response_model=schemas.Token) -def login(form_data: OAuth2PasswordRequestForm = Depends(), sess: Session = Depends(get_db)): - user = db.user.authenticate_user(sess, form_data.username, form_data.password) - - if not user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, - detail="Incorrect username or password", - headers={"WWW-Authenticate": "Bearer"}, - ) - - # Create token - access_token_expires = timedelta(minutes=const.ACCESS_TOKEN_EXPIRE_MINUTES) - access_token = create_access_token( - data={"sub": user.username}, expires_delta=access_token_expires - ) - - return {"access_token": access_token, "token_type": "bearer", "user": schemas.User.from_orm(user)} - - -# @app.post("/wg/update/", response_model=List[schemas.WireGuard]) - -@app.get("/api/wg/server/all", response_model=typing.List[schemas.WGServer]) -def get_interfaces( - sess: Session = Depends(get_db), - user: schemas.User = Depends(auth) -): - interfaces = db.wireguard.server_get_all(sess) - for iface in interfaces: - iface.is_running = script.wireguard.is_running(iface) - return interfaces +app.include_router( + server.router, + prefix="/api/v1/server", + tags=["server"], + dependencies=[Depends(middleware.auth)], + responses={404: {"description": "Not found"}} +) -@app.post("/api/wg/server/add", response_model=schemas.WGServer) -def add_interface( - form_data: schemas.WGServer, - sess: Session = Depends(get_db), - user: schemas.User = Depends(auth) -): - if form_data.interface is None or form_data.listen_port is None or form_data.address is None: - raise HTTPException(status_code=400, - detail="Interface, Listen-Port and Address must be included in the schema.") +app.include_router( + peer.router, + prefix="/api/v1/peer", + tags=["peer"], + dependencies=[Depends(middleware.auth)], + responses={404: {"description": "Not found"}} +) - try: - form_data.post_up = form_data.post_up if form_data.post_up != "" else const.DEFAULT_POST_UP - form_data.post_down = form_data.post_up if form_data.post_up != "" else const.DEFAULT_POST_UP - wg_server = db.wireguard.server_add(sess, form_data) +app.include_router( + wg.router, + prefix="/api/v1/wg", + tags=["wg"], + dependencies=[Depends(middleware.auth)], + responses={404: {"description": "Not found"}} +) - # Public/Private key - private_key, public_key = script.wireguard.generate_keys() - wg_server.private_key = private_key - wg_server.public_key = public_key - db.wireguard.server_key_pair_set(sess, wg_server) - db.wireguard.server_generate_config(sess, wg_server) - - return wg_server - except ValueError as e: - raise HTTPException(status_code=400, detail=str(e)) - - -@app.post("/api/wg/server/edit", response_model=schemas.WGServer) -def edit_server( - data: dict, sess: Session = Depends(get_db), - user: schemas.User = Depends(auth) -): - interface = data["interface"] - server = schemas.WGServer(**data["server"]) - - # Stop if running - old = schemas.WGServer(interface=interface) - - if script.wireguard.is_running(old): - script.wireguard.stop_interface(old) - - fields = set(old.__fields__) - {"peers", "is_running"} - if not db.wireguard.server_update_field(sess, interface, server, fields): - raise HTTPException(400, detail="Were not able to edit %s" % old.interface) - - script.wireguard.start_interface(server) - - return server - - -@app.get("/api/wg/generate_keypair", response_model=schemas.KeyPair) -def generate_key_pair( - user: schemas.User = Depends(auth) -): - private_key, public_key = script.wireguard.generate_keys() - return schemas.KeyPair( - private_key=private_key, - public_key=public_key - ) - - -@app.get("/api/wg/generate_psk", response_model=schemas.PSK) -def generate_psk(user: schemas.User = Depends(auth)): - return schemas.PSK( - psk=script.wireguard.generate_psk() - ) - - -@app.post("/api/wg/server/stop", response_model=schemas.WGServer) -def start_server( - form_data: schemas.WGServer, - user: schemas.User = Depends(auth) -): - script.wireguard.stop_interface(form_data) - form_data.is_running = script.wireguard.is_running(form_data) - return form_data - - -@app.post("/api/wg/server/start", response_model=schemas.WGServer) -def start_server( - form_data: schemas.WGServer, - sess: Session = Depends(get_db), - user: schemas.User = Depends(auth) -): - db.wireguard.server_generate_config(sess, form_data) - script.wireguard.start_interface(form_data) - form_data.is_running = script.wireguard.is_running(form_data) - return form_data - - -@app.post("/api/wg/server/restart", response_model=schemas.WGServer) -def start_server( - form_data: schemas.WGServer, - sess: Session = Depends(get_db), - user: schemas.User = Depends(auth) -): - db.wireguard.server_generate_config(sess, form_data) - script.wireguard.restart_interface(form_data) - form_data.is_running = script.wireguard.is_running(form_data) - return form_data - - -@app.post("/api/wg/server/delete", response_model=schemas.WGServer) -def delete_server( - form_data: schemas.WGServer, - sess: Session = Depends(get_db), - user: schemas.User = Depends(auth) -): - # Stop if running - if script.wireguard.is_running(form_data): - script.wireguard.stop_interface(form_data) - - if not db.wireguard.server_remove(sess, form_data): - raise HTTPException(400, detail="Were not able to delete %s" % form_data.interface) - return form_data - - -@app.post("/api/wg/server/peer/add", response_model=schemas.WGPeer) -def add_peer( - form_data: schemas.WGServer, - sess: Session = Depends(get_db), - user: schemas.User = Depends(auth) -): - wg_peer = schemas.WGPeer(server=form_data.interface) - - # Insert initial peer - wg_peer = db.wireguard.peer_insert(sess, wg_peer) - - # If server is running. Add peer - if script.wireguard.is_running(form_data): - script.wireguard.add_peer(form_data, wg_peer) - - db.wireguard.peer_generate_config(sess, wg_peer) - - return wg_peer - - -@app.post("/api/wg/server/peer/delete", response_model=schemas.WGPeer) -def delete_peer( - form_data: schemas.WGPeer, - sess: Session = Depends(get_db), - user: schemas.User = Depends(auth) -): - if not db.wireguard.peer_remove(sess, form_data): - raise HTTPException(400, detail="Were not able to delete peer %s (%s)" % (form_data.name, form_data.public_key)) - - server = schemas.WGServer(interface=form_data.server) - if script.wireguard.is_running(server): - script.wireguard.remove_peer(server, form_data) - - return form_data - - -@app.post("/api/wg/server/peer/edit", response_model=schemas.WGPeer) -def edit_peer( - form_data: schemas.WGPeer, - sess: Session = Depends(get_db), - user: schemas.User = Depends(auth) -): - wg_peer = db.wireguard.peer_update(sess, form_data) - db.wireguard.peer_generate_config(sess, wg_peer) - - return wg_peer - - -@app.post("/api/wg/server/stats") -def edit_peer( - form_data: schemas.WGServer, - user: schemas.User = Depends(auth) -): - stats = script.wireguard.get_stats(form_data) - return JSONResponse(content=stats) - - -@app.post("/api/wg/server/peer/config", response_model=schemas.WGPeerConfig) -def config_peer( - form_data: schemas.WGPeer, - sess: Session = Depends(get_db), - user: schemas.User = Depends(auth) -): - db_peer = db.wireguard.peer_query_get_by_address(sess, form_data.address, form_data.server).one() - - with open(const.PEER_FILE(db_peer), "r") as f: - conf_file = f.read() - - return schemas.WGPeerConfig(config=conf_file) - - -@app.post("/api/wg/server/config", response_model=schemas.WGPeerConfig) -def config_server( - form_data: schemas.WGServer, - user: schemas.User = Depends(auth) -): - with open(const.SERVER_FILE(form_data.interface), "r") as f: - conf_file = f.read() - - return schemas.WGPeerConfig(config=conf_file) +@app.get("/", include_in_schema=True) +def root(): + return FileResponse('build/index.html') -@app.post("/api/users/create/") -def create_user( - form_data: schemas.UserInDB, - sess: Session = Depends(get_db), - user: schemas.User = Depends(auth) -): - user = db.user.get_user_by_name(sess, form_data.username) - # User already exists - if user: - if not db.user.authenticate_user(sess, form_data.username, form_data.password): - raise HTTPException(status_code=401, detail="Incorrect password") +app.mount("/", StaticFiles(directory=pkg_resources.resource_filename(__name__, 'build')), name="static") - else: - # Create the user - if not db.user.create_user(sess, models.User( - username=form_data.username, - password=form_data.password, - full_name=form_data.full_name, - email=form_data.email, - role=form_data.role, - )): - raise HTTPException(status_code=400, detail="Could not create user") - return login_for_access_token(OAuth2PasswordRequestForm( - username=form_data.username, - password=form_data.password, - scope="" - ), sess) @app.on_event("startup") async def startup(): - await database.connect() - - # TODO - Fix - if not database_exists(engine.url): - models.Base.metadata.create_all(engine) - # Create default user - _db: Session = SessionLocal() - _db.add(models.User( - username=os.getenv("ADMIN_USERNAME", "admin"), - password=db.user.get_password_hash(os.getenv("ADMIN_PASSWORD", "admin")), - full_name="Admin", - role="admin", - email="" - )) - _db.commit() - _db.close() - - + pass @app.on_event("shutdown") async def shutdown(): - await database.disconnect() + pass -@app.get("/", include_in_schema=True) -def root(): - return FileResponse('build/index.html') - - -app.mount("/", StaticFiles(directory=pkg_resources.resource_filename(__name__, 'build')), name="static") - - -# @app.get("/") -# async def read_root(): -# return {"Hello": "World"} - - -@app.get("/items/{item_id}") -def read_item(item_id: int, q: str = None): - return {"item_id": item_id, "q": q} - if __name__ == "__main__": - async def main(): + """async def main(): if not script.wireguard.is_installed(): print("NOT INSTALLED!") exit(0) @@ -507,11 +198,6 @@ if __name__ == "__main__": script.wireguard.add_peer(wg_interface, wg_peer) script.wireguard.remove_peer(wg_interface, wg_peer) - db.wireguard.start_client(sess, wg_peer) - - - # loop = asyncio.get_event_loop() - # loop.create_task(main()) - # asyncio.get_event_loop().run_forever() + db.wireguard.start_client(sess, wg_peer)""" uvicorn.run("__main__:app", reload=True) diff --git a/wg_dashboard_backend/middleware.py b/wg_dashboard_backend/middleware.py new file mode 100644 index 0000000..708decb --- /dev/null +++ b/wg_dashboard_backend/middleware.py @@ -0,0 +1,81 @@ +from datetime import timedelta, datetime + +import jwt +from fastapi import Depends, HTTPException +from fastapi.security import OAuth2PasswordBearer +from jwt import PyJWTError +from passlib.context import CryptContext +from sqlalchemy.orm import Session +from starlette import status +from starlette.requests import Request +from starlette.responses import Response + +import const +import schemas +from database import SessionLocal +import db.user + +oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/login", auto_error=False) +pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") + + +def get_password_hash(password): + return pwd_context.hash(password) + + +def verify_password(plain_password, hashed_password): + return pwd_context.verify(plain_password, hashed_password) + + +async def db_session_middleware(request: Request, call_next): + response = Response("Internal server error (Database error)", status_code=500) + try: + request.state.db = SessionLocal() + response = await call_next(request) + finally: + request.state.db.close() + return response + + +# NON MIDDLEWARE MIDDLEWARISH THING + + +# Dependency +def get_db(request: Request): + return request.state.db + + +def create_access_token(*, data: dict, expires_delta: timedelta = None): + to_encode = data.copy() + if expires_delta: + expire = datetime.utcnow() + expires_delta + else: + expire = datetime.utcnow() + timedelta(minutes=15) + to_encode.update({"exp": expire}) + encoded_jwt = jwt.encode(to_encode, const.SECRET_KEY, algorithm=const.ALGORITHM) + return encoded_jwt + + +def auth(token: str = Depends(oauth2_scheme), sess: Session = Depends(get_db)): + + credentials_exception = HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="Could not validate credentials", + headers={"WWW-Authenticate": "Bearer"}, + ) + + try: + payload = jwt.decode(token, const.SECRET_KEY, algorithms=[const.ALGORITHM]) + username: str = payload.get("sub") + if username is None: + raise credentials_exception + + except PyJWTError: + raise credentials_exception + user = schemas.User.from_orm( + schemas.UserInDB(username=username, password="").from_db(sess) + ) + if user is None: + raise credentials_exception + return user + diff --git a/wg_dashboard_backend/models.py b/wg_dashboard_backend/models.py index 54b2812..1869381 100644 --- a/wg_dashboard_backend/models.py +++ b/wg_dashboard_backend/models.py @@ -1,9 +1,8 @@ import sqlalchemy from sqlalchemy import Integer, Column -from sqlalchemy.ext.declarative import declarative_base -from sqlalchemy.orm import relationship +from sqlalchemy.orm import relationship, backref -Base = declarative_base() +from database import Base class User(Base): @@ -17,21 +16,6 @@ class User(Base): role = Column(sqlalchemy.String) -class WGPeer(Base): - __tablename__ = "peer" - - id = Column(Integer, primary_key=True, index=True) - name = Column(sqlalchemy.String, default="Unnamed") - address = Column(sqlalchemy.String) - public_key = Column(sqlalchemy.String) - private_key = Column(sqlalchemy.String) - dns = Column(sqlalchemy.String) - allowed_ips = Column(sqlalchemy.String) - - server = Column(Integer, sqlalchemy.ForeignKey('server.interface')) - server_ref = relationship("WGServer", backref="server") - - class WGServer(Base): __tablename__ = "server" @@ -46,7 +30,25 @@ class WGServer(Base): post_up = Column(sqlalchemy.String) post_down = Column(sqlalchemy.String) - is_running = Column(sqlalchemy.Boolean) + configuration = Column(sqlalchemy.Text) + + peers = relationship("WGPeer", cascade="all, delete", passive_deletes=True, lazy="joined") + + +class WGPeer(Base): + __tablename__ = "peer" + + id = Column(Integer, primary_key=True, index=True) + name = Column(sqlalchemy.String, default="Unnamed") + address = Column(sqlalchemy.String) + public_key = Column(sqlalchemy.String) + private_key = Column(sqlalchemy.String) + dns = Column(sqlalchemy.String) + allowed_ips = Column(sqlalchemy.String) + + server_id = Column(Integer, sqlalchemy.ForeignKey('server.id', ondelete="CASCADE", onupdate="CASCADE")) + server = relationship("WGServer", backref=backref("server")) + configuration = Column(sqlalchemy.Text) + - peers = relationship("WGPeer", backref="peer") diff --git a/wg_dashboard_backend/requirements.txt b/wg_dashboard_backend/requirements.txt index 620f65a..299dd4a 100644 --- a/wg_dashboard_backend/requirements.txt +++ b/wg_dashboard_backend/requirements.txt @@ -10,3 +10,4 @@ bcrypt python-multipart jinja2 sqlalchemy_utils +requests diff --git a/wg_dashboard_frontend/src/app/pages/dashboard/add-server/add-server.component.scss b/wg_dashboard_backend/routers/__init__.py similarity index 100% rename from wg_dashboard_frontend/src/app/pages/dashboard/add-server/add-server.component.scss rename to wg_dashboard_backend/routers/__init__.py diff --git a/wg_dashboard_frontend/src/app/pages/dashboard/server/server.component.scss b/wg_dashboard_backend/routers/v1/__init__.py similarity index 100% rename from wg_dashboard_frontend/src/app/pages/dashboard/server/server.component.scss rename to wg_dashboard_backend/routers/v1/__init__.py diff --git a/wg_dashboard_backend/routers/v1/peer.py b/wg_dashboard_backend/routers/v1/peer.py new file mode 100644 index 0000000..5de21e1 --- /dev/null +++ b/wg_dashboard_backend/routers/v1/peer.py @@ -0,0 +1,95 @@ +import ipaddress + +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session + +import const +import models +import schemas +import middleware +import db.wireguard +import script.wireguard + +router = APIRouter() + + +@router.post("/add", response_model=schemas.WGPeer) +def add_peer( + peer_add: schemas.WGPeerAdd, + sess: Session = Depends(middleware.get_db) +): + server = schemas.WGServer(interface=peer_add.server_interface).from_db(sess) + peer = schemas.WGPeer(server_id=server.id) + + address_space = set(ipaddress.ip_network(server.address, strict=False).hosts()) + occupied_space = set() + for p in server.peers: + try: + occupied_space.add(ipaddress.ip_address(p.address.split("/")[0])) + except ValueError as e: + pass # Ignore invalid addresses. These are out of address_space + + address_space -= occupied_space + + # Select first available address + peer.address = str(list(sorted(address_space)).pop(0)) + "/32" + + # Private public key generation + keys = script.wireguard.generate_keys() + peer.private_key = keys["private_key"] + peer.public_key = keys["public_key"] + + # Set 0.0.0.0/0, ::/0 as default allowed ips + peer.allowed_ips = ', '.join(const.PEER_DEFAULT_ALLOWED_IPS) + + # Set unnamed + peer.name = "Unnamed" + + peer.dns = server.endpoint + + peer.configuration = script.wireguard.generate_config(dict( + peer=peer, + server=server + )) + + peer.sync(sess) + + # If server is running. Add peer + if script.wireguard.is_running(server): + script.wireguard.add_peer(server, peer) + + return peer + + +@router.post("/delete", response_model=schemas.WGPeer) +def delete_peer( + peer: schemas.WGPeer, + sess: Session = Depends(middleware.get_db) +): + peer.from_db(sess) # Sync full object + + if not db.wireguard.peer_remove(sess, peer): + raise HTTPException(400, detail="Were not able to delete peer %s (%s)" % (peer.name, peer.public_key)) + + server = schemas.WGServer(interface=peer.server_id) + if script.wireguard.is_running(server): + script.wireguard.remove_peer(server, peer) + + return peer + + +@router.post("/edit", response_model=schemas.WGPeer) +def edit_peer( + peer: schemas.WGPeer, + sess: Session = Depends(middleware.get_db) +): + server = schemas.WGServer(interface="")\ + .from_orm(sess.query(models.WGServer).filter_by(id=peer.server_id).one()) + + peer.configuration = script.wireguard.generate_config(dict( + peer=peer, + server=server + )) + peer.sync(sess) + + return peer diff --git a/wg_dashboard_backend/routers/v1/server.py b/wg_dashboard_backend/routers/v1/server.py new file mode 100644 index 0000000..031183b --- /dev/null +++ b/wg_dashboard_backend/routers/v1/server.py @@ -0,0 +1,138 @@ +import tempfile +from os.path import exists + +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session +from starlette.responses import JSONResponse + +import const +import schemas +import middleware +import db.wireguard +import script.wireguard +import typing + +router = APIRouter() + + +@router.get("/all", response_model=typing.List[schemas.WGServer]) +def servers_all( + sess: Session = Depends(middleware.get_db) +): + interfaces = db.wireguard.server_get_all(sess) + for iface in interfaces: + iface.is_running = script.wireguard.is_running(iface) + + return interfaces + + +@router.post("/add", response_model=schemas.WGServer) +def add_interface( + server: schemas.WGServerAdd, + sess: Session = Depends(middleware.get_db) +): + server.post_up = server.post_up if server.post_up != "" else const.DEFAULT_POST_UP + server.post_down = server.post_up if server.post_up != "" else const.DEFAULT_POST_DOWN + + # Public/Private key + try: + + if server.filter_query(sess).count() != 0: + raise HTTPException(status_code=400, detail="The server interface %s already exists in the database" % server.interface) + + keys = script.wireguard.generate_keys() + server.private_key = keys["private_key"] + server.public_key = keys["public_key"] + server.configuration = script.wireguard.generate_config(server) + + server.sync(sess) + except ValueError as e: + raise HTTPException(status_code=400, detail=str(e)) + + return server + + +@router.post("/stop", response_model=schemas.WGServer) +def start_server( + form_data: schemas.WGServer +): + script.wireguard.stop_interface(form_data) + form_data.is_running = script.wireguard.is_running(form_data) + return form_data + + +@router.post("/start", response_model=schemas.WGServer) +def start_server( + server: schemas.WGServer, + sess: Session = Depends(middleware.get_db) +): + script.wireguard.start_interface(server) + server.is_running = script.wireguard.is_running(server) + server.sync(sess) + return server + + +@router.post("/restart", response_model=schemas.WGServer) +def restart_server( + server: schemas.WGServer, + sess: Session = Depends(middleware.get_db) +): + script.wireguard.restart_interface(server) + server.is_running = script.wireguard.is_running(server) + server.sync(sess) + + return server + + +@router.post("/delete", response_model=schemas.WGServer) +def delete_server( + form_data: schemas.WGServer, + sess: Session = Depends(middleware.get_db) +): + # Stop if running + if script.wireguard.is_running(form_data): + script.wireguard.stop_interface(form_data) + + if not db.wireguard.server_remove(sess, form_data): + raise HTTPException(400, detail="Were not able to delete %s" % form_data.interface) + return form_data + + +@router.post("/stats", dependencies=[Depends(middleware.auth)]) +def stats_server(server: schemas.WGServer): + stats = script.wireguard.get_stats(server) + return JSONResponse(content=stats) + + +@router.post("/edit", response_model=schemas.WGServer) +def edit_server( + data: dict, sess: Session = Depends(middleware.get_db) +): + interface = data["interface"] + old = schemas.WGServer(interface=interface).from_db(sess) + + # Stop if running + if script.wireguard.is_running(old): + script.wireguard.stop_interface(old) + + # Update server + server = schemas.WGServer(**data["server"]) + server.configuration = script.wireguard.generate_config(server) + server = old.update(sess, new=server) + + # Update peers + for peer_data in server.peers: + peer = schemas.WGPeer(**peer_data) + peer.configuration = script.wireguard.generate_config(dict( + peer=peer, + server=server + )) + peer.sync(sess) + + script.wireguard.start_interface(server) + server.is_running = script.wireguard.is_running(server) + server.sync(sess) + server.from_db(sess) + + return server + diff --git a/wg_dashboard_backend/routers/v1/user.py b/wg_dashboard_backend/routers/v1/user.py new file mode 100644 index 0000000..0ad8a46 --- /dev/null +++ b/wg_dashboard_backend/routers/v1/user.py @@ -0,0 +1,86 @@ +from datetime import timedelta + +from fastapi import APIRouter, HTTPException, Depends, Form +from sqlalchemy.orm import Session +from starlette import status + +import const +import db.user +import middleware +import models +import schemas + +router = APIRouter() + + +@router.get("/logout") +def logout(user: schemas.User = Depends(middleware.auth)): + return dict(message="ok") + + +@router.post("/user/edit", response_model=schemas.User) +def edit(form_data: schemas.UserInDB, + user: schemas.UserInDB = Depends(middleware.auth), + sess: Session = Depends(middleware.get_db) + ): + form_data.password = middleware.get_password_hash(form_data.password) + form_data.sync(sess) + return form_data + + +@router.post("/login", response_model=schemas.Token) +def login(*, username: str = Form(...), password: str = Form(...), sess: Session = Depends(middleware.get_db)): + user: schemas.UserInDB = schemas.UserInDB(username=username, password="").from_db(sess) + + # Verify password + if not user or not middleware.verify_password(password, user.password): + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="Incorrect username or password", + headers={"WWW-Authenticate": "Bearer"}, + ) + + # Create token + access_token_expires = timedelta(minutes=const.ACCESS_TOKEN_EXPIRE_MINUTES) + access_token = middleware.create_access_token( + data={"sub": user.username}, expires_delta=access_token_expires + ) + + return schemas.Token( + access_token=access_token, + token_type="bearer", + user=schemas.User(**user.dict()) + ) + + +@router.post("/users/create/") +def create_user( + form_data: schemas.UserInDB, + sess: Session = Depends(middleware.get_db), + user: schemas.User = Depends(middleware.auth) +): + user = db.user.get_user_by_name(sess, form_data.username) + + # User already exists + if user: + if not db.user.authenticate_user(sess, form_data.username, form_data.password): + raise HTTPException(status_code=401, detail="Incorrect password") + + else: + + # Create the user + if not db.user.create_user(sess, models.User( + username=form_data.username, + password=form_data.password, + full_name=form_data.full_name, + email=form_data.email, + role=form_data.role, + )): + raise HTTPException(status_code=400, detail="Could not create user") + + return login_for_access_token(OAuth2PasswordRequestForm( + username=form_data.username, + password=form_data.password, + scope="" + ), sess) + diff --git a/wg_dashboard_backend/routers/v1/wg.py b/wg_dashboard_backend/routers/v1/wg.py new file mode 100644 index 0000000..a7005e2 --- /dev/null +++ b/wg_dashboard_backend/routers/v1/wg.py @@ -0,0 +1,25 @@ +from fastapi import APIRouter + +import middleware +import schemas +import script.wireguard + +router = APIRouter() + + +@router.get("/generate_psk", response_model=schemas.PSK) +def generate_psk(): + return schemas.PSK( + psk=script.wireguard.generate_psk() + ) + + +@router.get("/generate_keypair", response_model=schemas.KeyPair) +def generate_key_pair(): + keys = script.wireguard.generate_keys() + private_key = keys["private_key"] + public_key = keys["public_key"] + return schemas.KeyPair( + private_key=private_key, + public_key=public_key + ) diff --git a/wg_dashboard_backend/schemas.py b/wg_dashboard_backend/schemas.py index 7d60b32..8730465 100644 --- a/wg_dashboard_backend/schemas.py +++ b/wg_dashboard_backend/schemas.py @@ -1,62 +1,147 @@ +import pydantic from pydantic import BaseModel, typing - +from sqlalchemy.orm import Session, Query +from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound +import logging import models +_LOGGER = logging.getLogger(__name__) + + +class GenericModel(BaseModel): + + class Meta: + model = None + key = None + excludes = {"id"} + + class Config: + orm_mode = True + + def _ensure_orm(self): + if not self.Config and not self.Config.orm_mode and not self.Meta.model and not self.Meta.key: + raise NotImplementedError("Incorrect configuration Config.orm_mode must be enabled and Meta.model must be " + "set to a sqlalchemy model. Additional Meta.key must be set to bind model and schema") + + def filter_query(self, sess) -> Query: + query = sess.query(self.Meta.model).filter_by(**{ + self.Meta.key: getattr(self, self.Meta.key) + }) + + return query + + def update(self, sess: Session, new): + self._ensure_orm() + + self.filter_query(sess).update(new.dict(include=self.columns())) + + sess.commit() + + for k, v in new.dict().items(): + try: + setattr(self, k, v) + except ValueError: + pass + + return self + + def columns(self, no_exclude=False): + cols = set([x for x in dir(self.Meta.model) if not x.startswith("_")]) + #cols = set([str(x).replace(f"{self.Meta.model.__table__.name}.", "") for x in self.Meta.model.__table__.columns]) + return cols if no_exclude else cols - self.Meta.excludes + + def sync(self, sess: Session): + self._ensure_orm() + + # Count existing + n_results = self.filter_query(sess).count() + if n_results == 0: + # Insert, does not exists at all. + # Convert from schema to model + dbm = self.Meta.model(**self.dict()) + sess.add(dbm) + else: + self.filter_query(sess).update(self.dict(include=self.columns())) + + sess.commit() + + def from_db(self, sess: Session): + self._ensure_orm() + + try: + db_item = self.filter_query(sess).one() -class User(BaseModel): - username: str = None + for c in self.columns(no_exclude=True): + try: + setattr(self, c, getattr(db_item, c)) + except ValueError as e: + pass + return self + except MultipleResultsFound as e: + _LOGGER.exception(e) + except NoResultFound as e: + _LOGGER.exception(e) + + _LOGGER.warning("We did not find any records in the database that corresponds to the model. This means you " + "are trying to fetch a unsaved schema!") + return None + + +class User(GenericModel): + id: int = None + username: str email: str = None full_name: str = None role: str = None - class Config: - orm_mode = True + class Meta: + model = models.User + key = "username" + excludes = {"id"} class UserInDB(User): password: str - class Config: - orm_mode = True - -class Token(BaseModel): +class Token(GenericModel): access_token: str token_type: str user: User - class Config: - orm_mode = True - -class WGPeer(BaseModel): +class WGPeer(GenericModel): + id: int = None name: str = None address: str = None private_key: str = None public_key: str = None - server: str + server_id: str dns: str = None allowed_ips: str = None - # TODO missing stuff + configuration: str = None - class Config: - orm_mode = True + class Meta: + model = models.WGPeer + key = "address" + excludes = {"id"} -class WGPeerConfig(BaseModel): +class WGPeerConfig(GenericModel): config: str -class KeyPair(BaseModel): +class KeyPair(GenericModel): public_key: str private_key: str -class PSK(BaseModel): +class PSK(GenericModel): psk: str -class WGServer(BaseModel): +class WGServer(GenericModel): + id: int = None address: str = None interface: str listen_port: int = None @@ -65,17 +150,28 @@ class WGServer(BaseModel): public_key: str = None shared_key: str = None is_running: bool = None - + configuration: str = None post_up: str = None post_down: str = None - peers: typing.List[WGPeer] = None + peers: pydantic.typing.List['WGPeer'] = [] - class Config: - orm_mode = True + class Meta: + model = models.WGServer + key = "interface" + excludes = {"id", "peers"} def convert(self): self.peers = [] if not self.peers else self.peers return models.WGServer(**self.dict(exclude={"is_running"})) +class WGServerAdd(WGServer): + address: str + interface: str + listen_port: int + + +class WGPeerAdd(GenericModel): + server_interface: str + diff --git a/wg_dashboard_backend/script/wireguard.py b/wg_dashboard_backend/script/wireguard.py index 81fcdcc..3f57687 100644 --- a/wg_dashboard_backend/script/wireguard.py +++ b/wg_dashboard_backend/script/wireguard.py @@ -1,10 +1,16 @@ import logging import subprocess +import tempfile + +import typing + import const import schemas import os import re +import util + _LOGGER = logging.getLogger(__name__) @@ -20,6 +26,21 @@ class WGPermissionsError(Exception): pass +class TempServerFile(): + def __init__(self, server: schemas.WGServer): + self.server = server + self.td = tempfile.TemporaryDirectory(prefix="wg_man_") + self.server_file = os.path.join(self.td.name, f"{server.interface}.conf") + + def __enter__(self): + with open(self.server_file, "w+") as f: + f.write(self.server.configuration) + return self.server_file + + def __exit__(self, type, value, traceback): + self.td.cleanup() + + def _run_wg(server: schemas.WGServer, command): try: output = subprocess.check_output(const.CMD_WG_COMMAND + command, stderr=subprocess.STDOUT) @@ -28,19 +49,25 @@ def _run_wg(server: schemas.WGServer, command): if b'Operation not permitted' in e.output: raise WGPermissionsError("The user has insufficientt permissions for interface %s" % server.interface) + def is_installed(): output = subprocess.check_output(const.CMD_WG_COMMAND) return output == b'' or b'interface' in output -def generate_keys(): - +def generate_keys() -> typing.Dict[str, str]: private_key = subprocess.check_output(const.CMD_WG_COMMAND + ["genkey"]) public_key = subprocess.check_output( const.CMD_WG_COMMAND + ["pubkey"], input=private_key ) - return private_key.decode("utf-8").strip(), public_key.decode("utf-8").strip() + + private_key = private_key.decode("utf-8").strip() + public_key = public_key.decode("utf-8").strip() + return dict( + private_key=private_key, + public_key=public_key + ) def generate_psk(): @@ -48,32 +75,28 @@ def generate_psk(): def start_interface(server: schemas.WGServer): - server_file = os.path.join(const.SERVER_DIR(server.interface), server.interface + ".conf") - - try: - print(*const.CMD_WG_QUICK, "up", server_file) - output = subprocess.check_output(const.CMD_WG_QUICK + ["up", server_file], stderr=subprocess.STDOUT) - return output - except Exception as e: - - if b'already exists' in e.output: - raise WGAlreadyStartedError("The wireguard device %s is already started." % server.interface) + with TempServerFile(server) as server_file: + try: + #print(*const.CMD_WG_QUICK, "up", server_file) + output = subprocess.check_output(const.CMD_WG_QUICK + ["up", server_file], stderr=subprocess.STDOUT) + return output + except Exception as e: + if b'already exists' in e.output: + raise WGAlreadyStartedError("The wireguard device %s is already started." % server.interface) def stop_interface(server: schemas.WGServer): - server_file = os.path.join(const.SERVER_DIR(server.interface), server.interface + ".conf") + with TempServerFile(server) as server_file: + try: + output = subprocess.check_output(const.CMD_WG_QUICK + ["down", server_file], stderr=subprocess.STDOUT) + return output + except Exception as e: - try: - output = subprocess.check_output(const.CMD_WG_QUICK + ["down", server_file], stderr=subprocess.STDOUT) - return output - except Exception as e: - - if b'is not a WireGuard interface' in e.output: - raise WGAlreadyStoppedError("The wireguard device %s is already stopped." % server.interface) + if b'is not a WireGuard interface' in e.output: + raise WGAlreadyStoppedError("The wireguard device %s is already stopped." % server.interface) def restart_interface(server: schemas.WGServer): - try: stop_interface(server) except WGAlreadyStoppedError: @@ -82,7 +105,6 @@ def restart_interface(server: schemas.WGServer): def is_running(server: schemas.WGServer): - try: output = _run_wg(server, ["show", server.interface]) if output is None: @@ -158,3 +180,29 @@ def get_stats(server: schemas.WGServer): except Exception as e: _LOGGER.exception(e) return [] + + +def move_server_dir(interface, interface1): + old_server_dir = const.SERVER_DIR(interface) + old_server_file = const.SERVER_FILE(interface) + new_server_dir = const.SERVER_DIR(interface1) + new_server_file = old_server_file.replace(f"{interface}.conf", f"{interface1}.conf") + + os.rename(old_server_file, new_server_file) + os.rename(old_server_dir, new_server_dir) + + +def generate_config(obj: typing.Union[typing.Dict[schemas.WGPeer, schemas.WGServer], schemas.WGServer]): + if isinstance(obj, dict) and "server" in obj and "peer" in obj: + template = "peer.j2" + elif isinstance(obj, schemas.WGServer): + template = "server.j2" + else: + raise ValueError("Incorrect input type. Should be WGPeer or WGServer") + + result = util.jinja_env.get_template(template).render( + data=obj + ) + + return result + diff --git a/wg_dashboard_backend/templates/peer.j2 b/wg_dashboard_backend/templates/peer.j2 index af27739..fdd19a5 100644 --- a/wg_dashboard_backend/templates/peer.j2 +++ b/wg_dashboard_backend/templates/peer.j2 @@ -1,12 +1,12 @@ [Interface] -Address = {{ data.address.replace("/32", "/24") }} -PrivateKey = {{ data.private_key }} -DNS = {{ data.dns }} +Address = {{ data.peer.address.replace("/32", "/24") }} +PrivateKey = {{ data.peer.private_key }} +DNS = {{ data.peer.dns }} [Peer] -PublicKey = {{ data.server_ref.public_key }} -AllowedIPs = {{ data.allowed_ips }} -Endpoint = {{ data.server_ref.endpoint }}:{{ data.server_ref.listen_port }} -{% if data.preshared_key %} - PresharedKey = {{ data.server_ref.preshared_key }} +PublicKey = {{ data.server.public_key }} +AllowedIPs = {{ data.peer.allowed_ips }} +Endpoint = {{ data.server.endpoint }}:{{ data.server.listen_port }} +{% if data.server.shared_key %} +PresharedKey = {{ data.server.shared_key }} {% endif %} diff --git a/wg_dashboard_backend/tests/__init__.py b/wg_dashboard_backend/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/wg_dashboard_backend/tests/database.db b/wg_dashboard_backend/tests/database.db new file mode 100644 index 0000000..aa69cf4 Binary files /dev/null and b/wg_dashboard_backend/tests/database.db differ diff --git a/wg_dashboard_backend/tests/test_pytest.py b/wg_dashboard_backend/tests/test_pytest.py new file mode 100644 index 0000000..1d0dcfe --- /dev/null +++ b/wg_dashboard_backend/tests/test_pytest.py @@ -0,0 +1,80 @@ +import warnings + +import schemas +from database import SessionLocal + +with warnings.catch_warnings(): + warnings.filterwarnings("ignore",category=DeprecationWarning) + + +from main import app +from fastapi.testclient import TestClient + + +client = TestClient(app) + +sess = SessionLocal() + +username = "admin" +password = "admin" +token_headers = {} + +def test_logout_without_auth(): + response = client.get("/api/logout") + assert response.status_code == 401 + #assert response.json() == dict(message="ok") + + +def test_login_missing_username(): + response = client.post("/api/login", json=dict( + password=password + )) + assert response.status_code == 422 + + +def test_login_missing_password(): + + response = client.post("/api/login", json=dict( + password=password + )) + assert response.status_code == 422 + + +def test_login(): + + response = client.post("/api/login", json=dict( + username=username, + password=password + ) + ) + assert response.status_code == 200 # Must have status code 200 + assert "user" in response.json() + assert "token_type" in response.json() + assert "access_token" in response.json() + token_headers["Authorization"] = response.json()["token_type"] + " " + response.json()["access_token"] + return response + + +def test_logout_with_auth(): + response = client.get("/api/logout", headers=token_headers) + assert response.status_code == 200 + + +def test_user_edit(): + + user = schemas.UserInDB( + username="test", + password="test", + full_name="test", + email="test", + role="test" + ) + + user.sync(sess=sess) + + db_user = user.from_db(sess) + #print(db_user.username) + + + + diff --git a/wg_dashboard_frontend/angular.json b/wg_dashboard_frontend/angular.json index 40fc696..e2d1284 100644 --- a/wg_dashboard_frontend/angular.json +++ b/wg_dashboard_frontend/angular.json @@ -22,11 +22,9 @@ ], "styles": [ "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css", - "src/theme/styles.scss", - "node_modules/bootstrap/dist/css/bootstrap.min.css" + "src/theme/styles.scss" ], "scripts": [ - "node_modules/material-design-lite/material.js" ] }, "configurations": { @@ -105,4 +103,4 @@ "prefix": "app" } } -} \ No newline at end of file +} diff --git a/wg_dashboard_frontend/browserslist b/wg_dashboard_frontend/browserslist deleted file mode 100644 index 8084853..0000000 --- a/wg_dashboard_frontend/browserslist +++ /dev/null @@ -1,12 +0,0 @@ -# This file is used by the build system to adjust CSS and JS output to support the specified browsers below. -# For additional information regarding the format and rule options, please see: -# https://github.com/browserslist/browserslist#queries - -# You can see what browsers were selected by your queries by running: -# npx browserslist - -> 0.5% -last 2 versions -Firefox ESR -not dead -not IE 9-11 # For IE 9-11 support, remove 'not'. \ No newline at end of file diff --git a/wg_dashboard_frontend/package-lock.json b/wg_dashboard_frontend/package-lock.json index 93c2e00..9934e5e 100644 --- a/wg_dashboard_frontend/package-lock.json +++ b/wg_dashboard_frontend/package-lock.json @@ -5,12 +5,12 @@ "requires": true, "dependencies": { "@angular-devkit/architect": { - "version": "0.901.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.901.0.tgz", - "integrity": "sha512-SlqEBkPrT40zMCy5344AsUqC76pEPCaGPaAkCIvadaz2dC9vNMzQrvubCPJHViD/TumkSX1kYmLS3iYASVM9GQ==", + "version": "0.901.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.901.1.tgz", + "integrity": "sha512-foWDAurMfBDYLAJxHpTFkJBub1c2A8+eWHbBjgqIHmT8xadnE7t8nSA9XDl+k/kIoWw/qFU+6IttPirudYc/vw==", "dev": true, "requires": { - "@angular-devkit/core": "9.1.0", + "@angular-devkit/core": "9.1.1", "rxjs": "6.5.4" }, "dependencies": { @@ -26,21 +26,21 @@ } }, "@angular-devkit/build-angular": { - "version": "0.901.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.901.0.tgz", - "integrity": "sha512-ftJVNlKvIomqRfr5jFVraPqlLSUJu8YyVbFv/aCsvhNpuZGkYpTOMoJDwyywdslSTH608BIoU63IAnIz9PwUdw==", + "version": "0.901.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.901.1.tgz", + "integrity": "sha512-6uEvo5htsJoxQHBVwHOGmM6YWq5q6m9UWMv/ughlek0RtSLFfOt9TZQ/yQHgtGQsCQvscD/jBzVoD0zD5Ax/SQ==", "dev": true, "requires": { - "@angular-devkit/architect": "0.901.0", - "@angular-devkit/build-optimizer": "0.901.0", - "@angular-devkit/build-webpack": "0.901.0", - "@angular-devkit/core": "9.1.0", + "@angular-devkit/architect": "0.901.1", + "@angular-devkit/build-optimizer": "0.901.1", + "@angular-devkit/build-webpack": "0.901.1", + "@angular-devkit/core": "9.1.1", "@babel/core": "7.9.0", "@babel/generator": "7.9.3", "@babel/preset-env": "7.9.0", "@babel/template": "7.8.6", "@jsdevtools/coverage-istanbul-loader": "3.0.3", - "@ngtools/webpack": "9.1.0", + "@ngtools/webpack": "9.1.1", "ajv": "6.12.0", "autoprefixer": "9.7.4", "babel-loader": "8.0.6", @@ -82,7 +82,7 @@ "style-loader": "1.1.3", "stylus": "0.54.7", "stylus-loader": "3.0.2", - "terser": "4.6.7", + "terser": "4.6.10", "terser-webpack-plugin": "2.3.5", "tree-kill": "1.2.2", "webpack": "4.42.0", @@ -94,6 +94,84 @@ "worker-plugin": "4.0.2" }, "dependencies": { + "@babel/core": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", + "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.0", + "@babel/helper-module-transforms": "^7.9.0", + "@babel/helpers": "^7.9.0", + "@babel/parser": "^7.9.0", + "@babel/template": "^7.8.6", + "@babel/traverse": "^7.9.0", + "@babel/types": "^7.9.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.9.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.3.tgz", + "integrity": "sha512-RpxM252EYsz9qLUIq6F7YJyK1sv0wWDBFuztfDGWaQKzHjqDHysxSiRUpA/X9jmfqo+WzkAVKFaUily5h+gDCQ==", + "dev": true, + "requires": { + "@babel/types": "^7.9.0", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "parse5": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", + "dev": true + }, "rxjs": { "version": "6.5.4", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", @@ -102,30 +180,44 @@ "requires": { "tslib": "^1.9.0" } + }, + "semver": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.1.3.tgz", + "integrity": "sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA==", + "dev": true } } }, "@angular-devkit/build-optimizer": { - "version": "0.901.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.901.0.tgz", - "integrity": "sha512-Y9sz8uf2zjilhPUVYb0K9Mio6c1d5c+csuDc15CCKzELXJwyyDxilIFgn6Eu+edM0HNQGzbIwkjy4DkR9mtuTQ==", + "version": "0.901.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.901.1.tgz", + "integrity": "sha512-o0A9CcyDQSUnC5CQIKf92VH8amIYRYrMgLf2kdhSMcy0QV+rEJyN81dSvwX/Yxgnr9NbWEAQg7jnyKk06vfhOw==", "dev": true, "requires": { "loader-utils": "2.0.0", "source-map": "0.7.3", "tslib": "1.11.1", - "typescript": "3.8.3", + "typescript": "3.6.5", "webpack-sources": "1.4.3" + }, + "dependencies": { + "typescript": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.5.tgz", + "integrity": "sha512-BEjlc0Z06ORZKbtcxGrIvvwYs5hAnuo6TKdNFL55frVDlB+na3z5bsLhFaIxmT+dPWgBIjMo6aNnTOgHHmHgiQ==", + "dev": true + } } }, "@angular-devkit/build-webpack": { - "version": "0.901.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.901.0.tgz", - "integrity": "sha512-Oze0VzIvHnoW12C80fiNH4HBu/GWmhJPXdNA7nRkU/tBQlIKnfngf8rQ0QbgecN2qdEXQpZJsP/XclTi3zugsg==", + "version": "0.901.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.901.1.tgz", + "integrity": "sha512-9oNI+wPSk8yECy+f0EebfMx4PH3uDJRrifYZAxcr84IpzEbpfpRuYhE3ecwqd7k0zu2Kdjw1uUrGxBuH4/sbGg==", "dev": true, "requires": { - "@angular-devkit/architect": "0.901.0", - "@angular-devkit/core": "9.1.0", + "@angular-devkit/architect": "0.901.1", + "@angular-devkit/core": "9.1.1", "rxjs": "6.5.4" }, "dependencies": { @@ -141,9 +233,9 @@ } }, "@angular-devkit/core": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-9.1.0.tgz", - "integrity": "sha512-vHTsrB4JaVUQ95FRnKrgo79Y3F6FokImrZdrmwkQmwAThpjXeXmpUEKZS+ZSTFRgesjiIysVGOFijARP4BQ7Bg==", + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-9.1.1.tgz", + "integrity": "sha512-57MNew2u1QwVb69jxZyhXgdW9kqcGyWyRy2ui/hWCkWLg7RumWtyypmdTs89FNExB4HqtXlQ2eO3JZxfs7QR3w==", "dev": true, "requires": { "ajv": "6.12.0", @@ -161,16 +253,22 @@ "requires": { "tslib": "^1.9.0" } + }, + "tslib": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", + "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==", + "dev": true } } }, "@angular-devkit/schematics": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-9.1.0.tgz", - "integrity": "sha512-cb9PSvskMwWlL54fPfCcpJoyNDWAX6Wo7CzL5qpIB2cJCPLAuyfRUYYrkO77YUST+n2HvypHz0cZ5SNGMfaaBQ==", + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-9.1.1.tgz", + "integrity": "sha512-6wx2HcvafHvEjEa1tjDzW2hXrOiSE8ALqJUArb3+NoO1BDM42aGcqyPo0ODzKtDk12CgSsFXdNKRpQ5AmpSPtw==", "dev": true, "requires": { - "@angular-devkit/core": "9.1.0", + "@angular-devkit/core": "9.1.1", "ora": "4.0.3", "rxjs": "6.5.4" }, @@ -183,6 +281,12 @@ "requires": { "tslib": "^1.9.0" } + }, + "tslib": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", + "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==", + "dev": true } } }, @@ -197,14 +301,6 @@ "integrity": "sha512-jeeznvNDpR9POuxzz8Y0zFvMynG9HCJo3ZPTqOjlOq8Lj8876+rLsHDvKEMeLdwlkdi1EweYJW1CLQzI+TwqDA==", "requires": { "parse5": "^5.0.0" - }, - "dependencies": { - "parse5": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", - "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", - "optional": true - } } }, "@angular/cli": { @@ -235,12 +331,61 @@ "uuid": "7.0.2" }, "dependencies": { + "@angular-devkit/architect": { + "version": "0.901.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.901.0.tgz", + "integrity": "sha512-SlqEBkPrT40zMCy5344AsUqC76pEPCaGPaAkCIvadaz2dC9vNMzQrvubCPJHViD/TumkSX1kYmLS3iYASVM9GQ==", + "dev": true, + "requires": { + "@angular-devkit/core": "9.1.0", + "rxjs": "6.5.4" + } + }, + "@angular-devkit/core": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-9.1.0.tgz", + "integrity": "sha512-vHTsrB4JaVUQ95FRnKrgo79Y3F6FokImrZdrmwkQmwAThpjXeXmpUEKZS+ZSTFRgesjiIysVGOFijARP4BQ7Bg==", + "dev": true, + "requires": { + "ajv": "6.12.0", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", + "rxjs": "6.5.4", + "source-map": "0.7.3" + } + }, + "@angular-devkit/schematics": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-9.1.0.tgz", + "integrity": "sha512-cb9PSvskMwWlL54fPfCcpJoyNDWAX6Wo7CzL5qpIB2cJCPLAuyfRUYYrkO77YUST+n2HvypHz0cZ5SNGMfaaBQ==", + "dev": true, + "requires": { + "@angular-devkit/core": "9.1.0", + "ora": "4.0.3", + "rxjs": "6.5.4" + } + }, "ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true }, + "rxjs": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", + "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "semver": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.1.3.tgz", + "integrity": "sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA==", + "dev": true + }, "uuid": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.2.tgz", @@ -279,115 +424,6 @@ "yargs": "15.3.0" }, "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -399,66 +435,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "yargs": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.0.tgz", - "integrity": "sha512-g/QCnmjgOl1YJjGsnUg2SatC7NUYEiLXJqxNOQU9qSpjzGtGXda9b+OKccr1kLTy8BN9yqEyqfq5lxlwdc13TA==", - "dev": true, - "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.0" - } - }, - "yargs-parser": { - "version": "18.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.2.tgz", - "integrity": "sha512-hlIPNR3IzC1YuL1c2UwwDKpXlNFBqD1Fswwh1khz5+d8Cq/8yc/Mn0i+rQXduu8hcrFKvO7Eryk+09NecTQAAQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } } } }, @@ -491,203 +467,6 @@ "@babel/core": "7.8.3", "glob": "7.1.2", "yargs": "15.3.0" - }, - "dependencies": { - "@babel/core": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.3.tgz", - "integrity": "sha512-4XFkf8AwyrEG7Ziu3L2L0Cv+WyY47Tcsp70JFmpftbAA1K7YL/sgE9jh9HyNj08Y/U50ItUchpN0w6HxAoX1rA==", - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.3", - "@babel/helpers": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.3", - "@babel/types": "^7.8.3", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.0", - "lodash": "^4.17.13", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - } - }, - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" - }, - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - }, - "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "yargs": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.0.tgz", - "integrity": "sha512-g/QCnmjgOl1YJjGsnUg2SatC7NUYEiLXJqxNOQU9qSpjzGtGXda9b+OKccr1kLTy8BN9yqEyqfq5lxlwdc13TA==", - "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.0" - } - }, - "yargs-parser": { - "version": "18.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.2.tgz", - "integrity": "sha512-hlIPNR3IzC1YuL1c2UwwDKpXlNFBqD1Fswwh1khz5+d8Cq/8yc/Mn0i+rQXduu8hcrFKvO7Eryk+09NecTQAAQ==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } } }, "@angular/material": { @@ -727,60 +506,43 @@ "browserslist": "^4.9.1", "invariant": "^2.2.4", "semver": "^5.5.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } } }, "@babel/core": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", - "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", - "dev": true, + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.3.tgz", + "integrity": "sha512-4XFkf8AwyrEG7Ziu3L2L0Cv+WyY47Tcsp70JFmpftbAA1K7YL/sgE9jh9HyNj08Y/U50ItUchpN0w6HxAoX1rA==", "requires": { "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.0", - "@babel/helper-module-transforms": "^7.9.0", - "@babel/helpers": "^7.9.0", - "@babel/parser": "^7.9.0", - "@babel/template": "^7.8.6", - "@babel/traverse": "^7.9.0", - "@babel/types": "^7.9.0", + "@babel/generator": "^7.8.3", + "@babel/helpers": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.1", - "json5": "^2.1.2", + "json5": "^2.1.0", "lodash": "^4.17.13", "resolve": "^1.3.2", "semver": "^5.4.1", "source-map": "^0.5.0" }, "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" } } }, "@babel/generator": { - "version": "7.9.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.3.tgz", - "integrity": "sha512-RpxM252EYsz9qLUIq6F7YJyK1sv0wWDBFuztfDGWaQKzHjqDHysxSiRUpA/X9jmfqo+WzkAVKFaUily5h+gDCQ==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.5.tgz", + "integrity": "sha512-GbNIxVB3ZJe3tLeDm1HSn2AhuD/mVcyLDpgtLXa5tplmWrJdF/elxB56XNqCuD6szyNkDi6wuoKXln3QeBmCHQ==", "requires": { - "@babel/types": "^7.9.0", + "@babel/types": "^7.9.5", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -823,14 +585,6 @@ "invariant": "^2.2.4", "levenary": "^1.1.1", "semver": "^5.5.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } } }, "@babel/helper-create-regexp-features-plugin": { @@ -866,13 +620,13 @@ } }, "@babel/helper-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", - "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", "requires": { "@babel/helper-get-function-arity": "^7.8.3", "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/types": "^7.9.5" } }, "@babel/helper-get-function-arity": { @@ -993,9 +747,9 @@ } }, "@babel/helper-validator-identifier": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz", - "integrity": "sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw==" + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", + "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==" }, "@babel/helper-wrap-function": { "version": "7.8.3", @@ -1027,6 +781,52 @@ "@babel/helper-validator-identifier": "^7.9.0", "chalk": "^2.0.0", "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } } }, "@babel/parser": { @@ -1086,13 +886,14 @@ } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.0.tgz", - "integrity": "sha512-UgqBv6bjq4fDb8uku9f+wcm1J7YxJ5nT7WO/jBr0cl0PLKb7t1O6RNR1kZbjgx2LQtsDI9hwoQVmn0yhXeQyow==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.5.tgz", + "integrity": "sha512-VP2oXvAf7KCYTthbUHwBlewbl1Iq059f6seJGsxMizaCdgHIeczOr7FBqELhSqfkIl04Fi8okzWzl63UKbQmmg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0" + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-transform-parameters": "^7.9.5" } }, "@babel/plugin-proposal-optional-catch-binding": { @@ -1246,14 +1047,14 @@ } }, "@babel/plugin-transform-classes": { - "version": "7.9.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.9.2.tgz", - "integrity": "sha512-TC2p3bPzsfvSsqBZo0kJnuelnoK9O3welkUpqSqBQuBF6R5MN2rysopri8kNvtlGIb2jmUO7i15IooAZJjZuMQ==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.9.5.tgz", + "integrity": "sha512-x2kZoIuLC//O5iA7PEvecB105o7TLzZo8ofBVhP79N+DO3jaX+KYfww9TQcfBEZD0nikNyYcGB1IKtRq36rdmg==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.8.3", "@babel/helper-define-map": "^7.8.3", - "@babel/helper-function-name": "^7.8.3", + "@babel/helper-function-name": "^7.9.5", "@babel/helper-optimise-call-expression": "^7.8.3", "@babel/helper-plugin-utils": "^7.8.3", "@babel/helper-replace-supers": "^7.8.6", @@ -1271,9 +1072,9 @@ } }, "@babel/plugin-transform-destructuring": { - "version": "7.8.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.8.8.tgz", - "integrity": "sha512-eRJu4Vs2rmttFCdhPUM3bV0Yo/xPSdPw6ML9KHs/bjB4bLA5HXlbvYXPOD5yASodGod+krjYx21xm1QmL8dCJQ==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.9.5.tgz", + "integrity": "sha512-j3OEsGel8nHL/iusv/mRd5fYZ3DrOxWC82x0ogmdN/vHfAP4MYw+AFKYanzWlktNwikKvlzUV//afBW5FTp17Q==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" @@ -1419,9 +1220,9 @@ } }, "@babel/plugin-transform-parameters": { - "version": "7.9.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.9.3.tgz", - "integrity": "sha512-fzrQFQhp7mIhOzmOtPiKffvCYQSK10NR8t6BBz2yPbeUHb9OLW8RZGtgDRBn8z2hGcwvKDL3vC7ojPTLNxmqEg==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.9.5.tgz", + "integrity": "sha512-0+1FhHnMfj6lIIhVvS4KGQJeuhe1GI//h5uptK4PvLt+BGBxsoUJbd3/IW002yk//6sZPlFgsG1hY6OHLcy6kA==", "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.8.3", @@ -1578,14 +1379,6 @@ "invariant": "^2.2.2", "levenary": "^1.1.1", "semver": "^5.5.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } } }, "@babel/preset-modules": { @@ -1621,27 +1414,27 @@ } }, "@babel/traverse": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.0.tgz", - "integrity": "sha512-jAZQj0+kn4WTHO5dUZkZKhbFrqZE7K5LAQ5JysMnmvGij+wOdr+8lWqPeW0BcF4wFwrEXXtdGO7wcV6YPJcf3w==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.5.tgz", + "integrity": "sha512-c4gH3jsvSuGUezlP6rzSJ6jf8fYjLj3hsMZRx/nX0h+fmHN0w+ekubRrHPqnMec0meycA2nwCsJ7dC8IPem2FQ==", "requires": { "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.0", - "@babel/helper-function-name": "^7.8.3", + "@babel/generator": "^7.9.5", + "@babel/helper-function-name": "^7.9.5", "@babel/helper-split-export-declaration": "^7.8.3", "@babel/parser": "^7.9.0", - "@babel/types": "^7.9.0", + "@babel/types": "^7.9.5", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz", - "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", "requires": { - "@babel/helper-validator-identifier": "^7.9.0", + "@babel/helper-validator-identifier": "^7.9.5", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } @@ -1658,12 +1451,6 @@ "tsutils": "^3.5.0" }, "dependencies": { - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, "tsutils": { "version": "3.17.1", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", @@ -1727,18 +1514,13 @@ } } }, - "@ng-bootstrap/ng-bootstrap": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-6.0.2.tgz", - "integrity": "sha512-8+Dz8GN15zneIA4+mQ7b1j5O+oHsFdhTYQVDGk6eAazHeqrFD0+o8N+pLZL2PZlf98WcHFmXIOqKXrBD8iLl1g==" - }, "@ngtools/webpack": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-9.1.0.tgz", - "integrity": "sha512-kQ+1N/F+5tuUXiiaoqJwhcOIM0I93EEvF3xwpTLRm91wl2i8R1261LvsD/uQPrgLrZNGR6eFhFF1Izn2PnIjQA==", + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-9.1.1.tgz", + "integrity": "sha512-4RPlk6aIlYhk9isTvXbMaA2G0LhxOzcZ+2iG7zV9Yj/Vm8+lrRexpQ/kC/Dh0GI/oCtKIkVpUzx5LTozYeTLdQ==", "dev": true, "requires": { - "@angular-devkit/core": "9.1.0", + "@angular-devkit/core": "9.1.1", "enhanced-resolve": "4.1.1", "rxjs": "6.5.4", "webpack-sources": "1.4.3" @@ -1832,9 +1614,9 @@ } }, "@npmcli/promise-spawn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-1.1.0.tgz", - "integrity": "sha512-FwbuYN9KXBkloLeIR3xRgI8dyOdfK/KzaJlChszNuwmUXD1lHXfLlSeo4n4KrKt2udIK9K9/TzlnyCA3ubM2fA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-1.2.0.tgz", + "integrity": "sha512-nFtqjVETliApiRdjbYwKwhlSHx2ZMagyj5b9YbNt0BWeeOVxJd47ZVE2u16vxDHyTOZvk+YLV7INwfAE9a2uow==", "dev": true, "requires": { "infer-owner": "^1.0.4" @@ -1848,6 +1630,41 @@ "requires": { "@angular-devkit/core": "9.1.0", "@angular-devkit/schematics": "9.1.0" + }, + "dependencies": { + "@angular-devkit/core": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-9.1.0.tgz", + "integrity": "sha512-vHTsrB4JaVUQ95FRnKrgo79Y3F6FokImrZdrmwkQmwAThpjXeXmpUEKZS+ZSTFRgesjiIysVGOFijARP4BQ7Bg==", + "dev": true, + "requires": { + "ajv": "6.12.0", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", + "rxjs": "6.5.4", + "source-map": "0.7.3" + } + }, + "@angular-devkit/schematics": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-9.1.0.tgz", + "integrity": "sha512-cb9PSvskMwWlL54fPfCcpJoyNDWAX6Wo7CzL5qpIB2cJCPLAuyfRUYYrkO77YUST+n2HvypHz0cZ5SNGMfaaBQ==", + "dev": true, + "requires": { + "@angular-devkit/core": "9.1.0", + "ora": "4.0.3", + "rxjs": "6.5.4" + } + }, + "rxjs": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", + "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + } } }, "@schematics/update": { @@ -1867,6 +1684,30 @@ "semver-intersect": "1.4.0" }, "dependencies": { + "@angular-devkit/core": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-9.1.0.tgz", + "integrity": "sha512-vHTsrB4JaVUQ95FRnKrgo79Y3F6FokImrZdrmwkQmwAThpjXeXmpUEKZS+ZSTFRgesjiIysVGOFijARP4BQ7Bg==", + "dev": true, + "requires": { + "ajv": "6.12.0", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", + "rxjs": "6.5.4", + "source-map": "0.7.3" + } + }, + "@angular-devkit/schematics": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-9.1.0.tgz", + "integrity": "sha512-cb9PSvskMwWlL54fPfCcpJoyNDWAX6Wo7CzL5qpIB2cJCPLAuyfRUYYrkO77YUST+n2HvypHz0cZ5SNGMfaaBQ==", + "dev": true, + "requires": { + "@angular-devkit/core": "9.1.0", + "ora": "4.0.3", + "rxjs": "6.5.4" + } + }, "rxjs": { "version": "6.5.4", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", @@ -1875,6 +1716,12 @@ "requires": { "tslib": "^1.9.0" } + }, + "semver": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.1.3.tgz", + "integrity": "sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA==", + "dev": true } } }, @@ -1889,278 +1736,12 @@ "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" }, - "@types/d3": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/@types/d3/-/d3-5.7.2.tgz", - "integrity": "sha512-7/wClB8ycneWGy3jdvLfXKTd5SoTg9hji7IdJ0RuO9xTY54YpJ8zlcFADcXhY1J3kCBwxp+/1jeN6a5OMwgYOw==", - "dev": true, - "requires": { - "@types/d3-array": "^1", - "@types/d3-axis": "*", - "@types/d3-brush": "*", - "@types/d3-chord": "*", - "@types/d3-collection": "*", - "@types/d3-color": "*", - "@types/d3-contour": "*", - "@types/d3-dispatch": "*", - "@types/d3-drag": "*", - "@types/d3-dsv": "*", - "@types/d3-ease": "*", - "@types/d3-fetch": "*", - "@types/d3-force": "*", - "@types/d3-format": "*", - "@types/d3-geo": "*", - "@types/d3-hierarchy": "*", - "@types/d3-interpolate": "*", - "@types/d3-path": "*", - "@types/d3-polygon": "*", - "@types/d3-quadtree": "*", - "@types/d3-random": "*", - "@types/d3-scale": "*", - "@types/d3-scale-chromatic": "*", - "@types/d3-selection": "*", - "@types/d3-shape": "*", - "@types/d3-time": "*", - "@types/d3-time-format": "*", - "@types/d3-timer": "*", - "@types/d3-transition": "*", - "@types/d3-voronoi": "*", - "@types/d3-zoom": "*" - } - }, - "@types/d3-array": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-1.2.7.tgz", - "integrity": "sha512-51vHWuUyDOi+8XuwPrTw3cFqyh2Slg9y8COYkRfjCPG9TfYqY0hoNPzv/8BrcAy0FeQBzqEo/D/8Nk2caOQJnA==", - "dev": true - }, - "@types/d3-axis": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-1.0.12.tgz", - "integrity": "sha512-BZISgSD5M8TgURyNtcPAmUB9sk490CO1Thb6/gIn0WZTt3Y50IssX+2Z0vTccoqZksUDTep0b+o4ofXslvNbqg==", - "dev": true, - "requires": { - "@types/d3-selection": "*" - } - }, - "@types/d3-brush": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-1.1.0.tgz", - "integrity": "sha512-yz5Y94XpUARimOlLk+RWM1cZh1FrtmSGOyDQfCArsMa6kAnhjF3EserSTDnHAuVuNATMoTIOPHa7pjG2iTkPYA==", - "dev": true, - "requires": { - "@types/d3-selection": "*" - } - }, - "@types/d3-chord": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-1.0.9.tgz", - "integrity": "sha512-UA6lI9CVW5cT5Ku/RV4hxoFn4mKySHm7HEgodtfRthAj1lt9rKZEPon58vyYfk+HIAm33DtJJgZwMXy2QgyPXw==", - "dev": true - }, - "@types/d3-collection": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-collection/-/d3-collection-1.0.8.tgz", - "integrity": "sha512-y5lGlazdc0HNO0F3UUX2DPE7OmYvd9Kcym4hXwrJcNUkDaypR5pX+apuMikl9LfTxKItJsY9KYvzBulpCKyvuQ==", - "dev": true - }, - "@types/d3-color": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-1.2.2.tgz", - "integrity": "sha512-6pBxzJ8ZP3dYEQ4YjQ+NVbQaOflfgXq/JbDiS99oLobM2o72uAST4q6yPxHv6FOTCRC/n35ktuo8pvw/S4M7sw==", - "dev": true - }, - "@types/d3-contour": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-1.3.0.tgz", - "integrity": "sha512-AUCUIjEnC5lCGBM9hS+MryRaFLIrPls4Rbv6ktqbd+TK/RXZPwOy9rtBWmGpbeXcSOYCJTUDwNJuEnmYPJRxHQ==", - "dev": true, - "requires": { - "@types/d3-array": "*", - "@types/geojson": "*" - } - }, - "@types/d3-dispatch": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-1.0.7.tgz", - "integrity": "sha512-M+z84G7UKwK6hEPnGCSccOg8zJ3Nk2hgDQ9sCstHXgsFU0sMxlIZVKqKB5oxUDbALqQG6ucg0G9e8cmOSlishg==", - "dev": true - }, - "@types/d3-drag": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-1.2.3.tgz", - "integrity": "sha512-rWB5SPvkYVxW3sqUxHOJUZwifD0KqvKwvt1bhNqcLpW6Azsd0BJgRNcyVW8GAferaAk5r8dzeZnf9zKlg9+xMQ==", - "dev": true, - "requires": { - "@types/d3-selection": "*" - } - }, - "@types/d3-dsv": { - "version": "1.0.36", - "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-1.0.36.tgz", - "integrity": "sha512-jbIWQ27QJcBNMZbQv0NSQMHnBDCmxghAxePxgyiPH1XPCRkOsTBei7jcdi3fDrUCGpCV3lKrSZFSlOkhUQVClA==", - "dev": true - }, - "@types/d3-ease": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-1.0.9.tgz", - "integrity": "sha512-U5ADevQ+W6fy32FVZZC9EXallcV/Mi12A5Tkd0My5MrC7T8soMQEhlDAg88XUWm0zoCQlB4XV0en/24LvuDB4Q==", - "dev": true - }, - "@types/d3-fetch": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-1.1.5.tgz", - "integrity": "sha512-o9c0ItT5/Gl3wbNuVpzRnYX1t3RghzeWAjHUVLuyZJudiTxC4f/fC0ZPFWLQ2lVY8pAMmxpV8TJ6ETYCgPeI3A==", - "dev": true, - "requires": { - "@types/d3-dsv": "*" - } - }, - "@types/d3-force": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-1.2.1.tgz", - "integrity": "sha512-jqK+I36uz4kTBjyk39meed5y31Ab+tXYN/x1dn3nZEus9yOHCLc+VrcIYLc/aSQ0Y7tMPRlIhLetulME76EiiA==", - "dev": true - }, - "@types/d3-format": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-1.3.1.tgz", - "integrity": "sha512-KAWvReOKMDreaAwOjdfQMm0HjcUMlQG47GwqdVKgmm20vTd2pucj0a70c3gUSHrnsmo6H2AMrkBsZU2UhJLq8A==", - "dev": true - }, - "@types/d3-geo": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-1.11.1.tgz", - "integrity": "sha512-Ox8WWOG3igDRoep/dNsGbOiSJYdUG3ew/6z0ETvHyAtXZVBjOE0S96zSSmzgl0gqQ3RdZjn2eeJOj9oRcMZPkQ==", - "dev": true, - "requires": { - "@types/geojson": "*" - } - }, - "@types/d3-hierarchy": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-1.1.6.tgz", - "integrity": "sha512-vvSaIDf/Ov0o3KwMT+1M8+WbnnlRiGjlGD5uvk83a1mPCTd/E5x12bUJ/oP55+wUY/4Kb5kc67rVpVGJ2KUHxg==", - "dev": true - }, - "@types/d3-interpolate": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-1.3.1.tgz", - "integrity": "sha512-z8Zmi08XVwe8e62vP6wcA+CNuRhpuUU5XPEfqpG0hRypDE5BWNthQHB1UNWWDB7ojCbGaN4qBdsWp5kWxhT1IQ==", - "dev": true, - "requires": { - "@types/d3-color": "*" - } - }, - "@types/d3-path": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-1.0.8.tgz", - "integrity": "sha512-AZGHWslq/oApTAHu9+yH/Bnk63y9oFOMROtqPAtxl5uB6qm1x2lueWdVEjsjjV3Qc2+QfuzKIwIR5MvVBakfzA==", - "dev": true - }, - "@types/d3-polygon": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-1.0.7.tgz", - "integrity": "sha512-Xuw0eSjQQKs8jTiNbntWH0S+Xp+JyhqxmQ0YAQ3rDu6c3kKMFfgsaGN7Jv5u3zG6yVX/AsLP/Xs/QRjmi9g43Q==", - "dev": true - }, - "@types/d3-quadtree": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-1.0.7.tgz", - "integrity": "sha512-0ajFawWicfjsaCLh6NzxOyVDYhQAmMFbsiI3MPGLInorauHFEh9/Cl6UHNf+kt/J1jfoxKY/ZJaKAoDpbvde5Q==", - "dev": true - }, - "@types/d3-random": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-1.1.2.tgz", - "integrity": "sha512-Jui+Zn28pQw/3EayPKaN4c/PqTvqNbIPjHkgIIFnxne1FdwNjfHtAIsZIBMKlquQNrrMjFzCrlF2gPs3xckqaA==", - "dev": true - }, - "@types/d3-scale": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-2.2.0.tgz", - "integrity": "sha512-oQFanN0/PiR2oySHfj+zAAkK1/p4LD32Nt1TMVmzk+bYHk7vgIg/iTXQWitp1cIkDw4LMdcgvO63wL+mNs47YA==", - "dev": true, - "requires": { - "@types/d3-time": "*" - } - }, - "@types/d3-scale-chromatic": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-1.3.1.tgz", - "integrity": "sha512-Ny3rLbV5tnmqgW7w/poCcef4kXP8mHPo/p8EjTS5d9OUk8MlqAeRaM8eF7Vyv7QMLiIXNE94Pa1cMLSPkXQBoQ==", - "dev": true - }, - "@types/d3-selection": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-1.4.1.tgz", - "integrity": "sha512-bv8IfFYo/xG6dxri9OwDnK3yCagYPeRIjTlrcdYJSx+FDWlCeBDepIHUpqROmhPtZ53jyna0aUajZRk0I3rXNA==", - "dev": true - }, - "@types/d3-shape": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-1.3.2.tgz", - "integrity": "sha512-LtD8EaNYCaBRzHzaAiIPrfcL3DdIysc81dkGlQvv7WQP3+YXV7b0JJTtR1U3bzeRieS603KF4wUo+ZkJVenh8w==", - "dev": true, - "requires": { - "@types/d3-path": "*" - } - }, - "@types/d3-time": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-1.0.10.tgz", - "integrity": "sha512-aKf62rRQafDQmSiv1NylKhIMmznsjRN+MnXRXTqHoqm0U/UZzVpdrtRnSIfdiLS616OuC1soYeX1dBg2n1u8Xw==", - "dev": true - }, - "@types/d3-time-format": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-2.1.1.tgz", - "integrity": "sha512-tJSyXta8ZyJ52wDDHA96JEsvkbL6jl7wowGmuf45+fAkj5Y+SQOnz0N7/H68OWmPshPsAaWMQh+GAws44IzH3g==", - "dev": true - }, - "@types/d3-timer": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-1.0.9.tgz", - "integrity": "sha512-WvfJ3LFxBbWjqRGz9n7GJt08RrTHPJDVsIwwoCMROlqF+iDacYiAFjf9oqnq0mXpb2juA2N/qjKP+MKdal3YNQ==", - "dev": true - }, - "@types/d3-transition": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-1.1.6.tgz", - "integrity": "sha512-/F+O2r4oz4G9ATIH3cuSCMGphAnl7VDx7SbENEK0NlI/FE8Jx2oiIrv0uTrpg7yF/AmuWbqp7AGdEHAPIh24Gg==", - "dev": true, - "requires": { - "@types/d3-selection": "*" - } - }, - "@types/d3-voronoi": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/@types/d3-voronoi/-/d3-voronoi-1.1.9.tgz", - "integrity": "sha512-DExNQkaHd1F3dFPvGA/Aw2NGyjMln6E9QzsiqOcBgnE+VInYnFBHBBySbZQts6z6xD+5jTfKCP7M4OqMyVjdwQ==", - "dev": true - }, - "@types/d3-zoom": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-1.7.4.tgz", - "integrity": "sha512-5jnFo/itYhJeB2khO/lKe730kW/h2EbKMOvY0uNp3+7NdPm4w63DwPEMxifQZ7n902xGYK5DdU67FmToSoy4VA==", - "dev": true, - "requires": { - "@types/d3-interpolate": "*", - "@types/d3-selection": "*" - } - }, "@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", "dev": true }, - "@types/geojson": { - "version": "7946.0.7", - "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.7.tgz", - "integrity": "sha512-wE2v81i4C4Ol09RtsWFAqg3BUitWbHSpSlIo+bNdsCJijO9sjme+zm+73ZMCa/qMC8UEERxzGbvmr1cffo2SiQ==", - "dev": true - }, "@types/glob": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", @@ -2172,12 +1753,6 @@ "@types/node": "*" } }, - "@types/material-design-lite": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/@types/material-design-lite/-/material-design-lite-1.1.15.tgz", - "integrity": "sha512-F7yNGnXQM3YwMEsdmLviRA1OeSoUWQCA/CXdCGkZx3rlPuHawgRIz58J2iArY8mxdDLMPExmnel9YQGKvXQfGg==", - "dev": true - }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", @@ -2191,9 +1766,9 @@ "dev": true }, "@types/node": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.11.0.tgz", - "integrity": "sha512-uM4mnmsIIPK/yeO+42F2RQhGUIs39K2RFmugcJANppXe6J1nvH87PvzPZYpza7Xhhs8Yn9yIAVdLZ84z61+0xQ==", + "version": "13.11.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.11.1.tgz", + "integrity": "sha512-eWQGP3qtxwL8FGneRrC5DwrJLGN4/dH1clNTuLfN81HCrxVtxRjygDTUoZJ5ASlDEeo0ppYFQjQIlXhtXpOn6g==", "dev": true }, "@types/normalize-package-data": { @@ -2202,23 +1777,6 @@ "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", "dev": true }, - "@types/nvd3": { - "version": "1.8.40", - "resolved": "https://registry.npmjs.org/@types/nvd3/-/nvd3-1.8.40.tgz", - "integrity": "sha512-RtiK1DgLNh1snOOwuPMm4qWTwWOcGQiu69Yvb9hFuiInBfDdlqwWeci6i7l0vzUZn6XpKCLR54JveVdAPApYSg==", - "dev": true, - "requires": { - "@types/d3": "^3" - }, - "dependencies": { - "@types/d3": { - "version": "3.5.43", - "resolved": "https://registry.npmjs.org/@types/d3/-/d3-3.5.43.tgz", - "integrity": "sha512-t9ZmXOcpVxywRw86YtIC54g7M9puRh8hFedRvVfHKf5YyOP6pSxA0TvpXpfseXSCInoW4P7bggTrSDiUOs4g5w==", - "dev": true - } - } - }, "@types/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", @@ -2532,6 +2090,7 @@ "version": "6.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", + "dev": true, "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -2563,6 +2122,11 @@ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "dev": true }, + "angular-material-dynamic-themes": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/angular-material-dynamic-themes/-/angular-material-dynamic-themes-1.0.4.tgz", + "integrity": "sha512-5oW++xtLOAYyLGUN5o/KUKhWhkoQwpr3G9xMXepJV0fbezr7R7GDR+wzJNxOCY8BbiWvNO6S2AHG2s7dpCqykQ==" + }, "angularx-qrcode": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/angularx-qrcode/-/angularx-qrcode-2.1.0.tgz", @@ -2602,17 +2166,17 @@ "dev": true }, "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" }, "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "requires": { - "color-convert": "^1.9.0" + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" } }, "anymatch": { @@ -2660,6 +2224,14 @@ "dev": true, "requires": { "sprintf-js": "~1.0.2" + }, + "dependencies": { + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + } } }, "aria-query": { @@ -2739,6 +2311,7 @@ "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, "requires": { "safer-buffer": "~2.1.0" } @@ -2784,7 +2357,8 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true }, "assign-symbols": { "version": "1.0.0", @@ -2834,12 +2408,14 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true }, "atob": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true }, "autoprefixer": { "version": "9.7.4", @@ -2854,17 +2430,71 @@ "num2fraction": "^1.2.2", "postcss": "^7.0.26", "postcss-value-parser": "^4.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true }, "aws4": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", - "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==" + "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==", + "dev": true }, "axobject-query": { "version": "2.0.2", @@ -3011,6 +2641,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, "requires": { "tweetnacl": "^0.14.3" } @@ -3027,16 +2658,6 @@ "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", "dev": true }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, "block-stream": { "version": "0.0.9", "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", @@ -3049,7 +2670,8 @@ "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true }, "bn.js": { "version": "4.11.8", @@ -3124,11 +2746,6 @@ "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", "dev": true }, - "bootstrap": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.4.1.tgz", - "integrity": "sha512-tbx5cHubwE6e2ZG7nqM3g/FZ5PQEDMWmMGNrCUBVRPHXTJaH7CBDdsLeu3eCh3B1tzAxTnAbtmrzvWEvT2NNEA==" - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3245,6 +2862,14 @@ "base64-js": "^1.0.2", "ieee754": "^1.1.4", "isarray": "^1.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } } }, "buffer-from": { @@ -3314,6 +2939,20 @@ "unique-filename": "^1.1.1" }, "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -3408,9 +3047,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001038", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001038.tgz", - "integrity": "sha512-zii9quPo96XfOiRD4TrfYGs+QsGZpb2cGiMAzPjtf/hpFgB6zCPZgJb7I1+EATeMw/o+lG8FyRAnI+CWStHcaQ==", + "version": "1.0.30001040", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001040.tgz", + "integrity": "sha512-Ep0tEPeI5wCvmJNrXjE3etgfI+lkl1fTDU6Y3ZH1mhrjkPlVI9W4pcKbMo+BQLpEWKVYYp2EmYaRsqpPC3k7lQ==", "dev": true }, "canonical-path": { @@ -3422,7 +3061,8 @@ "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true }, "ccount": { "version": "1.0.5", @@ -3431,13 +3071,13 @@ "dev": true }, "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, "character-entities": { @@ -3572,9 +3212,9 @@ } }, "cli-spinners": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.2.0.tgz", - "integrity": "sha512-tgU3fKwzYjiLEQgPMD9Jt+JjHVL9kW93FiIMX/l7rivvOD4/LL0Mf7gda3+4U2KJBloybwgj5KEoQgGRioMiKQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.3.0.tgz", + "integrity": "sha512-Xs2Hf2nzrvJMFKimOR7YR0QwZ8fc0u98kdtwN1eNAZzNQgH3vK2pXzff6GJtKh7S5hoJ87ECiAiZFS2fb5Ii2w==", "dev": true }, "cli-width": { @@ -3584,37 +3224,19 @@ "dev": true }, "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "dev": true, + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" } }, "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", "dev": true }, "clone-deep": { @@ -3646,6 +3268,58 @@ "@types/q": "^1.5.1", "chalk": "^2.4.1", "q": "^1.1.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "code-point-at": { @@ -3676,12 +3350,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true - }, - "sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "dev": true } } }, @@ -3709,20 +3377,37 @@ "requires": { "color-convert": "^1.9.1", "color-string": "^1.5.2" + }, + "dependencies": { + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + } } }, "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "requires": { - "color-name": "1.1.3" + "color-name": "~1.1.4" } }, "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "color-string": { "version": "1.5.3", @@ -3738,6 +3423,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -3745,7 +3431,8 @@ "commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true }, "commondir": { "version": "1.0.1", @@ -3890,6 +3577,20 @@ "run-queue": "^1.0.0" }, "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -3961,6 +3662,20 @@ "pkg-dir": "^3.0.0" } }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "json5": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", @@ -3981,21 +3696,6 @@ "json5": "^1.0.1" } }, - "p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -4053,7 +3753,8 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true }, "cosmiconfig": { "version": "5.2.1", @@ -4115,14 +3816,6 @@ "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } } }, "crypto-browserify": { @@ -4148,6 +3841,7 @@ "version": "2.2.4", "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", + "dev": true, "requires": { "inherits": "^2.0.3", "source-map": "^0.6.1", @@ -4158,7 +3852,8 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } } }, @@ -4355,294 +4050,30 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.6.tgz", "integrity": "sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", - "dev": true, - "requires": { - "array-find-index": "^1.0.1" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "d3": { - "version": "5.15.1", - "resolved": "https://registry.npmjs.org/d3/-/d3-5.15.1.tgz", - "integrity": "sha512-Xu9gT6Lm0jH3wWJJSRomFwqnGGi3YAfWIfxNFl4++YVgYOjo3F8V2idAG3nJBgpZOkD0/RHPZX6F4k6tzgOvYw==", - "requires": { - "d3-array": "1", - "d3-axis": "1", - "d3-brush": "1", - "d3-chord": "1", - "d3-collection": "1", - "d3-color": "1", - "d3-contour": "1", - "d3-dispatch": "1", - "d3-drag": "1", - "d3-dsv": "1", - "d3-ease": "1", - "d3-fetch": "1", - "d3-force": "1", - "d3-format": "1", - "d3-geo": "1", - "d3-hierarchy": "1", - "d3-interpolate": "1", - "d3-path": "1", - "d3-polygon": "1", - "d3-quadtree": "1", - "d3-random": "1", - "d3-scale": "2", - "d3-scale-chromatic": "1", - "d3-selection": "1", - "d3-shape": "1", - "d3-time": "1", - "d3-time-format": "2", - "d3-timer": "1", - "d3-transition": "1", - "d3-voronoi": "1", - "d3-zoom": "1" - } - }, - "d3-array": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz", - "integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==" - }, - "d3-axis": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-1.0.12.tgz", - "integrity": "sha512-ejINPfPSNdGFKEOAtnBtdkpr24c4d4jsei6Lg98mxf424ivoDP2956/5HDpIAtmHo85lqT4pruy+zEgvRUBqaQ==" - }, - "d3-brush": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-1.1.5.tgz", - "integrity": "sha512-rEaJ5gHlgLxXugWjIkolTA0OyMvw8UWU1imYXy1v642XyyswmI1ybKOv05Ft+ewq+TFmdliD3VuK0pRp1VT/5A==", - "requires": { - "d3-dispatch": "1", - "d3-drag": "1", - "d3-interpolate": "1", - "d3-selection": "1", - "d3-transition": "1" - } - }, - "d3-chord": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-1.0.6.tgz", - "integrity": "sha512-JXA2Dro1Fxw9rJe33Uv+Ckr5IrAa74TlfDEhE/jfLOaXegMQFQTAgAw9WnZL8+HxVBRXaRGCkrNU7pJeylRIuA==", - "requires": { - "d3-array": "1", - "d3-path": "1" - } - }, - "d3-collection": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/d3-collection/-/d3-collection-1.0.7.tgz", - "integrity": "sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A==" - }, - "d3-color": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.0.tgz", - "integrity": "sha512-TzNPeJy2+iEepfiL92LAAB7fvnp/dV2YwANPVHdDWmYMm23qIJBYww3qT8I8C1wXrmrg4UWs7BKc2tKIgyjzHg==" - }, - "d3-contour": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-1.3.2.tgz", - "integrity": "sha512-hoPp4K/rJCu0ladiH6zmJUEz6+u3lgR+GSm/QdM2BBvDraU39Vr7YdDCicJcxP1z8i9B/2dJLgDC1NcvlF8WCg==", - "requires": { - "d3-array": "^1.1.1" - } - }, - "d3-dispatch": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.6.tgz", - "integrity": "sha512-fVjoElzjhCEy+Hbn8KygnmMS7Or0a9sI2UzGwoB7cCtvI1XpVN9GpoYlnb3xt2YV66oXYb1fLJ8GMvP4hdU1RA==" - }, - "d3-drag": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.5.tgz", - "integrity": "sha512-rD1ohlkKQwMZYkQlYVCrSFxsWPzI97+W+PaEIBNTMxRuxz9RF0Hi5nJWHGVJ3Om9d2fRTe1yOBINJyy/ahV95w==", - "requires": { - "d3-dispatch": "1", - "d3-selection": "1" - } - }, - "d3-dsv": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-1.2.0.tgz", - "integrity": "sha512-9yVlqvZcSOMhCYzniHE7EVUws7Fa1zgw+/EAV2BxJoG3ME19V6BQFBwI855XQDsxyOuG7NibqRMTtiF/Qup46g==", - "requires": { - "commander": "2", - "iconv-lite": "0.4", - "rw": "1" - } - }, - "d3-ease": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.6.tgz", - "integrity": "sha512-SZ/lVU7LRXafqp7XtIcBdxnWl8yyLpgOmzAk0mWBI9gXNzLDx5ybZgnRbH9dN/yY5tzVBqCQ9avltSnqVwessQ==" - }, - "d3-fetch": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-1.1.2.tgz", - "integrity": "sha512-S2loaQCV/ZeyTyIF2oP8D1K9Z4QizUzW7cWeAOAS4U88qOt3Ucf6GsmgthuYSdyB2HyEm4CeGvkQxWsmInsIVA==", - "requires": { - "d3-dsv": "1" - } - }, - "d3-force": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-1.2.1.tgz", - "integrity": "sha512-HHvehyaiUlVo5CxBJ0yF/xny4xoaxFxDnBXNvNcfW9adORGZfyNF1dj6DGLKyk4Yh3brP/1h3rnDzdIAwL08zg==", - "requires": { - "d3-collection": "1", - "d3-dispatch": "1", - "d3-quadtree": "1", - "d3-timer": "1" - } - }, - "d3-format": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.4.tgz", - "integrity": "sha512-TWks25e7t8/cqctxCmxpUuzZN11QxIA7YrMbram94zMQ0PXjE4LVIMe/f6a4+xxL8HQ3OsAFULOINQi1pE62Aw==" - }, - "d3-geo": { - "version": "1.11.9", - "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.11.9.tgz", - "integrity": "sha512-9edcH6J3s/Aa3KJITWqFJbyB/8q3mMlA9Fi7z6yy+FAYMnRaxmC7jBhUnsINxVWD14GmqX3DK8uk7nV6/Ekt4A==", - "requires": { - "d3-array": "1" - } - }, - "d3-hierarchy": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.9.tgz", - "integrity": "sha512-j8tPxlqh1srJHAtxfvOUwKNYJkQuBFdM1+JAUfq6xqH5eAqf93L7oG1NVqDa4CpFZNvnNKtCYEUC8KY9yEn9lQ==" - }, - "d3-interpolate": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.4.0.tgz", - "integrity": "sha512-V9znK0zc3jOPV4VD2zZn0sDhZU3WAE2bmlxdIwwQPPzPjvyLkd8B3JUVdS1IDUFDkWZ72c9qnv1GK2ZagTZ8EA==", - "requires": { - "d3-color": "1" - } - }, - "d3-path": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", - "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==" - }, - "d3-polygon": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-1.0.6.tgz", - "integrity": "sha512-k+RF7WvI08PC8reEoXa/w2nSg5AUMTi+peBD9cmFc+0ixHfbs4QmxxkarVal1IkVkgxVuk9JSHhJURHiyHKAuQ==" - }, - "d3-quadtree": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-1.0.7.tgz", - "integrity": "sha512-RKPAeXnkC59IDGD0Wu5mANy0Q2V28L+fNe65pOCXVdVuTJS3WPKaJlFHer32Rbh9gIo9qMuJXio8ra4+YmIymA==" - }, - "d3-random": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-1.1.2.tgz", - "integrity": "sha512-6AK5BNpIFqP+cx/sreKzNjWbwZQCSUatxq+pPRmFIQaWuoD+NrbVWw7YWpHiXpCQ/NanKdtGDuB+VQcZDaEmYQ==" - }, - "d3-scale": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-2.2.2.tgz", - "integrity": "sha512-LbeEvGgIb8UMcAa0EATLNX0lelKWGYDQiPdHj+gLblGVhGLyNbaCn3EvrJf0A3Y/uOOU5aD6MTh5ZFCdEwGiCw==", - "requires": { - "d3-array": "^1.2.0", - "d3-collection": "1", - "d3-format": "1", - "d3-interpolate": "1", - "d3-time": "1", - "d3-time-format": "2" - } - }, - "d3-scale-chromatic": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-1.5.0.tgz", - "integrity": "sha512-ACcL46DYImpRFMBcpk9HhtIyC7bTBR4fNOPxwVSl0LfulDAwyiHyPOTqcDG1+t5d4P9W7t/2NAuWu59aKko/cg==", - "requires": { - "d3-color": "1", - "d3-interpolate": "1" - } - }, - "d3-selection": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.4.1.tgz", - "integrity": "sha512-BTIbRjv/m5rcVTfBs4AMBLKs4x8XaaLkwm28KWu9S2vKNqXkXt2AH2Qf0sdPZHjFxcWg/YL53zcqAz+3g4/7PA==" - }, - "d3-shape": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", - "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", - "requires": { - "d3-path": "1" - } - }, - "d3-time": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz", - "integrity": "sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA==" - }, - "d3-time-format": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.2.3.tgz", - "integrity": "sha512-RAHNnD8+XvC4Zc4d2A56Uw0yJoM7bsvOlJR33bclxq399Rak/b9bhvu/InjxdWhPtkgU53JJcleJTGkNRnN6IA==", - "requires": { - "d3-time": "1" + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, - "d3-timer": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.10.tgz", - "integrity": "sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw==" - }, - "d3-transition": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-1.3.2.tgz", - "integrity": "sha512-sc0gRU4PFqZ47lPVHloMn9tlPcv8jxgOQg+0zjhfZXMQuvppjG6YuwdMBE0TuqCZjeJkLecku/l9R0JPcRhaDA==", + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, "requires": { - "d3-color": "1", - "d3-dispatch": "1", - "d3-ease": "1", - "d3-interpolate": "1", - "d3-selection": "^1.1.0", - "d3-timer": "1" + "array-find-index": "^1.0.1" } }, - "d3-voronoi": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/d3-voronoi/-/d3-voronoi-1.1.4.tgz", - "integrity": "sha512-dArJ32hchFsrQ8uMiTBLq256MpnZjeuBtdHpaDlYuQyjU0CVzCJl/BVW+SkszaAeH95D/8gxqAhgx0ouAWAfRg==" - }, - "d3-zoom": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-1.8.3.tgz", - "integrity": "sha512-VoLXTK4wvy1a0JpH2Il+F2CiOhVu7VRXWF5M/LroMIh3/zBAC3WAt7QoIvPibOavVo20hN6/37vwAsdBejLyKQ==", - "requires": { - "d3-dispatch": "1", - "d3-drag": "1", - "d3-interpolate": "1", - "d3-selection": "1", - "d3-transition": "1" - } + "cyclist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", + "dev": true }, "damerau-levenshtein": { "version": "1.0.6", @@ -4654,6 +4085,7 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, "requires": { "assert-plus": "^1.0.0" } @@ -4690,7 +4122,8 @@ "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true }, "deep-equal": { "version": "1.1.1", @@ -4723,14 +4156,6 @@ "dev": true, "requires": { "clone": "^1.0.2" - }, - "dependencies": { - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "dev": true - } } }, "define-properties": { @@ -4832,6 +4257,22 @@ "dev": true, "requires": { "glob": "^7.1.3" + }, + "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } } } } @@ -4839,7 +4280,8 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true }, "delegates": { "version": "1.0.0", @@ -5045,6 +4487,7 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -5057,9 +4500,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.395", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.395.tgz", - "integrity": "sha512-kdn2cX6hZXDdz/O2Q8tZscITlsSv1a/7bOq/fQs7QAJ9iaRlnhZPccarNhxZv1tXgmgwCnKp/1lJNYLOG8Dxiw==", + "version": "1.3.401", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.401.tgz", + "integrity": "sha512-9tvSOS1++0EQP0tkgyD8KJergVZsld1/UqOusZVTbx9MWZHw5NCezkOjIQ5YWeB45jKdQerDfRrt28HwidI9Ow==", "dev": true }, "elliptic": { @@ -5413,7 +4856,8 @@ "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true }, "extend-shallow": { "version": "3.0.2", @@ -5515,12 +4959,14 @@ "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true }, "fast-deep-equal": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", - "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==" + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "dev": true }, "fast-glob": { "version": "3.2.2", @@ -5560,7 +5006,8 @@ "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true }, "fastparse": { "version": "1.1.2", @@ -5620,13 +5067,6 @@ "schema-utils": "^2.6.5" } }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -5679,25 +5119,6 @@ "pkg-dir": "^4.1.0" }, "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, "make-dir": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.2.tgz", @@ -5707,36 +5128,6 @@ "semver": "^6.0.0" } }, - "p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, "pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -5755,12 +5146,12 @@ } }, "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "requires": { - "locate-path": "^2.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" } }, "flat-cache": { @@ -5774,6 +5165,20 @@ "write": "1.0.3" }, "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "rimraf": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", @@ -5830,12 +5235,14 @@ "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true }, "form-data": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", @@ -5929,6 +5336,20 @@ "rimraf": "2" }, "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -5962,6 +5383,12 @@ "wide-align": "^1.1.0" }, "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, "is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", @@ -5981,6 +5408,15 @@ "is-fullwidth-code-point": "^1.0.0", "strip-ansi": "^3.0.0" } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } } } }, @@ -5999,10 +5435,9 @@ "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==" }, "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-stdin": { "version": "4.0.1", @@ -6029,15 +5464,15 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, "requires": { "assert-plus": "^1.0.0" } }, "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -6141,19 +5576,6 @@ "minimist": "^1.2.5" } }, - "goog-webfont-dl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/goog-webfont-dl/-/goog-webfont-dl-1.0.3.tgz", - "integrity": "sha512-LpzLB5rOBiSG/HA3J9nXZ6of9vJLxqS4WqZ6+KgJg8+zra8tyFPBdpd+erDl1XEvBJPYpJ32/Ygu8shp0b5/rg==", - "requires": { - "bluebird": "^3.5.5", - "commander": "^2.20.0", - "css": "^2.2.4", - "lodash": "^4.17.11", - "mkdirp": "^0.5.1", - "request": "^2.88.0" - } - }, "graceful-fs": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", @@ -6174,12 +5596,14 @@ "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true }, "har-validator": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, "requires": { "ajv": "^6.5.5", "har-schema": "^2.0.0" @@ -6207,12 +5631,21 @@ "dev": true, "requires": { "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + } } }, "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true }, "has-symbols": { "version": "1.0.1", @@ -6476,6 +5909,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, "requires": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -6511,6 +5945,7 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" } @@ -6611,141 +6046,57 @@ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true }, - "indexes-of": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true - }, - "inquirer": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz", - "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "chalk": "^3.0.0", - "cli-cursor": "^3.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.15", - "mute-stream": "0.0.8", - "run-async": "^2.4.0", - "rxjs": "^6.5.3", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "dev": true + }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "inquirer": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz", + "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "cli-cursor": "^3.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.5.3", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" } }, "internal-ip": { @@ -6799,11 +6150,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", "integrity": "sha1-sBMHyym2GKHtJux56RH4A8TaAEA=" - }, - "sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==" } } }, @@ -7005,9 +6351,9 @@ "dev": true }, "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, "is-glob": { "version": "4.0.1", @@ -7141,7 +6487,8 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true }, "is-utf8": { "version": "0.2.1", @@ -7174,10 +6521,9 @@ "dev": true }, "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" }, "isexe": { "version": "2.0.0", @@ -7194,7 +6540,8 @@ "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true }, "istanbul-lib-coverage": { "version": "3.0.0", @@ -7233,23 +6580,6 @@ "requires": { "merge-stream": "^2.0.0", "supports-color": "^7.0.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } } }, "js-base64": { @@ -7298,17 +6628,20 @@ "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true }, "json3": { "version": "3.3.3", @@ -7317,9 +6650,9 @@ "dev": true }, "json5": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.2.tgz", - "integrity": "sha512-MoUOQ4WdiN3yxhm7NEVJSJrieAo5hNSLQ5sj05OTRHPL9HOBy8u4Bu88jsC1jvqAdN+E1bJmsUcZH+1HQxliqQ==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", "requires": { "minimist": "^1.2.5" } @@ -7343,6 +6676,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -7404,6 +6738,12 @@ "tslib": "^1.10.0" }, "dependencies": { + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "dev": true + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -7424,6 +6764,12 @@ "pify": "^4.0.1" }, "dependencies": { + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "dev": true + }, "json5": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", @@ -7525,13 +6871,11 @@ } }, "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "p-locate": "^4.1.0" } }, "lodash": { @@ -7564,6 +6908,58 @@ "dev": true, "requires": { "chalk": "^2.4.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "loglevel": { @@ -7631,14 +7027,6 @@ "requires": { "pify": "^4.0.1", "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } } }, "make-error": { @@ -7718,11 +7106,6 @@ "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", "dev": true }, - "material-design-lite": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/material-design-lite/-/material-design-lite-1.3.0.tgz", - "integrity": "sha1-0ATOP+6Zoe63Sni4oyUTSl8RcdM=" - }, "material-icons": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/material-icons/-/material-icons-0.3.1.tgz", @@ -7970,12 +7353,14 @@ "mime-db": { "version": "1.43.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", - "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==" + "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==", + "dev": true }, "mime-types": { "version": "2.1.26", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", + "dev": true, "requires": { "mime-db": "1.43.0" } @@ -8205,6 +7590,7 @@ "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, "requires": { "minimist": "^1.2.5" } @@ -8223,6 +7609,20 @@ "run-queue": "^1.0.3" }, "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -8298,6 +7698,11 @@ "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", "dev": true }, + "ngx-cookie-service": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/ngx-cookie-service/-/ngx-cookie-service-3.0.4.tgz", + "integrity": "sha512-g4KHpCWL2EtKatWqn8lz/DdyMQO8sDS7BNwCSvxF1ETTW5DPJnbdEwCjSdm84MmfqBh6JdgvoQd//rOxH5EbgQ==" + }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -8337,6 +7742,22 @@ "dev": true, "requires": { "glob": "^7.1.3" + }, + "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } } }, "semver": { @@ -8428,6 +7849,12 @@ "true-case-path": "^1.0.2" }, "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", @@ -8467,6 +7894,15 @@ "yallist": "^2.1.2" } }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", @@ -8507,12 +7943,6 @@ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true } } }, @@ -8556,6 +7986,14 @@ "dev": true, "requires": { "semver": "^7.1.1" + }, + "dependencies": { + "semver": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.2.1.tgz", + "integrity": "sha512-aHhm1pD02jXXkyIpq25qBZjr3CQgg8KST8uX0OWXch3xE6jw+1bfbWnCjzMwojsTquroUmKFHNzU6x26mEiRxw==", + "dev": true + } } }, "npm-normalize-package-bin": { @@ -8573,6 +8011,14 @@ "hosted-git-info": "^3.0.2", "semver": "^7.0.0", "validate-npm-package-name": "^3.0.0" + }, + "dependencies": { + "semver": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.2.1.tgz", + "integrity": "sha512-aHhm1pD02jXXkyIpq25qBZjr3CQgg8KST8uX0OWXch3xE6jw+1bfbWnCjzMwojsTquroUmKFHNzU6x26mEiRxw==", + "dev": true + } } }, "npm-packlist": { @@ -8585,6 +8031,22 @@ "ignore-walk": "^3.0.3", "npm-bundled": "^1.1.1", "npm-normalize-package-bin": "^1.0.1" + }, + "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } } }, "npm-pick-manifest": { @@ -8596,6 +8058,14 @@ "npm-install-checks": "^4.0.0", "npm-package-arg": "^8.0.0", "semver": "^7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.2.1.tgz", + "integrity": "sha512-aHhm1pD02jXXkyIpq25qBZjr3CQgg8KST8uX0OWXch3xE6jw+1bfbWnCjzMwojsTquroUmKFHNzU6x26mEiRxw==", + "dev": true + } } }, "npm-registry-fetch": { @@ -8656,15 +8126,11 @@ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true }, - "nvd3": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/nvd3/-/nvd3-1.8.6.tgz", - "integrity": "sha1-LT66dL8zNjtRAevx0JPFmlOuc8Q=" - }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true }, "object-assign": { "version": "4.1.1", @@ -8840,85 +8306,18 @@ }, "ora": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/ora/-/ora-4.0.3.tgz", - "integrity": "sha512-fnDebVFyz309A73cqCipVL1fBZewq4vwgSHfxh43vVy31mbyoQ8sCH3Oeaog/owYOs/lLlGVPCISQonTneg6Pg==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.2.0", - "is-interactive": "^1.0.0", - "log-symbols": "^3.0.0", - "mute-stream": "0.0.8", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "resolved": "https://registry.npmjs.org/ora/-/ora-4.0.3.tgz", + "integrity": "sha512-fnDebVFyz309A73cqCipVL1fBZewq4vwgSHfxh43vVy31mbyoQ8sCH3Oeaog/owYOs/lLlGVPCISQonTneg6Pg==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.2.0", + "is-interactive": "^1.0.0", + "log-symbols": "^3.0.0", + "mute-stream": "0.0.8", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" } }, "original": { @@ -8994,21 +8393,19 @@ "dev": true }, "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "requires": { - "p-try": "^1.0.0" + "p-try": "^2.0.0" } }, "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "requires": { - "p-limit": "^1.1.0" + "p-limit": "^2.2.0" } }, "p-map": { @@ -9030,10 +8427,9 @@ } }, "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, "pacote": { "version": "11.1.4", @@ -9066,6 +8462,20 @@ "which": "^2.0.2" }, "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -9081,6 +8491,12 @@ "glob": "^7.1.3" } }, + "semver": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.2.1.tgz", + "integrity": "sha512-aHhm1pD02jXXkyIpq25qBZjr3CQgg8KST8uX0OWXch3xE6jw+1bfbWnCjzMwojsTquroUmKFHNzU6x26mEiRxw==", + "dev": true + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -9165,10 +8581,10 @@ } }, "parse5": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", - "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", - "dev": true + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "optional": true }, "parseurl": { "version": "1.3.3", @@ -9195,9 +8611,9 @@ "dev": true }, "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" }, "path-is-absolute": { "version": "1.0.1", @@ -9260,7 +8676,8 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true }, "picomatch": { "version": "2.2.2", @@ -9317,15 +8734,6 @@ "path-exists": "^3.0.0" } }, - "p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, "p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", @@ -9335,10 +8743,10 @@ "p-limit": "^2.0.0" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true } } @@ -9350,6 +8758,57 @@ "dev": true, "requires": { "find-up": "^2.1.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } } }, "pngjs": { @@ -9396,6 +8855,58 @@ "supports-color": "^6.1.0" }, "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -9975,6 +9486,47 @@ "postcss": "^7.0.7" }, "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, "log-symbols": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", @@ -9983,6 +9535,15 @@ "requires": { "chalk": "^2.0.1" } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } } } }, @@ -10002,12 +9563,12 @@ } }, "postcss-sass": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/postcss-sass/-/postcss-sass-0.4.2.tgz", - "integrity": "sha512-hcRgnd91OQ6Ot9R90PE/khUDCJHG8Uxxd3F7Y0+9VHjBiJgNv7sK5FxyHMCBtoLmmkzVbSj3M3OlqUfLJpq0CQ==", + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/postcss-sass/-/postcss-sass-0.4.4.tgz", + "integrity": "sha512-BYxnVYx4mQooOhr+zer0qWbSPYnarAy8ZT7hAQtbxtgVf8gy+LSLT/hHGe35h14/pZDTw1DsxdbrwxBN++H+fg==", "dev": true, "requires": { - "gonzales-pe": "^4.2.4", + "gonzales-pe": "^4.3.0", "postcss": "^7.0.21" } }, @@ -10206,7 +9767,8 @@ "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true }, "public-encrypt": { "version": "4.0.3", @@ -10258,7 +9820,8 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true }, "q": { "version": "1.5.1", @@ -10282,6 +9845,14 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, "cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", @@ -10292,6 +9863,19 @@ "wrap-ansi": "^5.1.0" } }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", @@ -10305,15 +9889,10 @@ "locate-path": "^3.0.0" } }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" }, "locate-path": { "version": "3.0.0", @@ -10324,14 +9903,6 @@ "path-exists": "^3.0.0" } }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, "p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", @@ -10340,15 +9911,10 @@ "p-limit": "^2.0.0" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" }, "string-width": { "version": "3.1.0", @@ -10409,7 +9975,8 @@ "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true }, "query-string": { "version": "4.3.4", @@ -10647,6 +10214,14 @@ "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } } }, "readdir-scoped-modules": { @@ -10878,6 +10453,7 @@ "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -10907,10 +10483,9 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" }, "requires-port": { "version": "1.0.0", @@ -10944,7 +10519,8 @@ "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true }, "restore-cursor": { "version": "3.1.0", @@ -10993,6 +10569,22 @@ "dev": true, "requires": { "glob": "^7.1.3" + }, + "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } } }, "ripemd160": { @@ -11038,11 +10630,6 @@ "aproba": "^1.1.1" } }, - "rw": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=" - }, "rxjs": { "version": "6.5.5", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz", @@ -11068,7 +10655,8 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true }, "sass": { "version": "1.26.3", @@ -11091,6 +10679,12 @@ "yargs": "^7.0.0" }, "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, "camelcase": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", @@ -11108,6 +10702,12 @@ "wrap-ansi": "^2.0.0" } }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, "invert-kv": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", @@ -11141,6 +10741,12 @@ "lcid": "^1.0.0" } }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -11152,12 +10758,31 @@ "strip-ansi": "^3.0.0" } }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, "which-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", "dev": true }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + } + }, "y18n": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", @@ -11290,10 +10915,9 @@ } }, "semver": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.1.3.tgz", - "integrity": "sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA==", - "dev": true + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" }, "semver-dsl": { "version": "1.0.1", @@ -11302,14 +10926,6 @@ "dev": true, "requires": { "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } } }, "semver-intersect": { @@ -11319,14 +10935,6 @@ "dev": true, "requires": { "semver": "^5.0.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } } }, "send": { @@ -11561,6 +11169,38 @@ "ansi-styles": "^3.2.0", "astral-regex": "^1.0.0", "is-fullwidth-code-point": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + } } }, "smart-buffer": { @@ -11819,6 +11459,7 @@ "version": "0.5.3", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, "requires": { "atob": "^2.1.2", "decode-uri-component": "^0.2.0", @@ -11848,7 +11489,8 @@ "source-map-url": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true }, "sourcemap-codec": { "version": "1.4.8", @@ -11899,9 +11541,9 @@ "dev": true }, "spdy": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.1.tgz", - "integrity": "sha512-HeZS3PBdMA+sZSu0qwpCxl3DeALD5ASx8pAX0jZdKXSpPWbQ6SYGnlg3BBmYLx5LtiZrmkAZfErCm2oECBcioA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", "dev": true, "requires": { "debug": "^4.1.0", @@ -11951,6 +11593,58 @@ "dev": true, "requires": { "chalk": "^2.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "split-string": { @@ -11963,15 +11657,15 @@ } }, "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==" }, "sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -12087,36 +11781,19 @@ "dev": true }, "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" } }, "string.prototype.trimend": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.0.tgz", - "integrity": "sha512-EEJnGqa/xNfIg05SxiPSqRS7S9qwDhYts1TSLR1BQfYUfPe1stofgGKvwERK9+9yf+PpfBMlpBaCHucXGPQfUA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", + "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", "dev": true, "requires": { "define-properties": "^1.1.3", @@ -12146,9 +11823,9 @@ } }, "string.prototype.trimstart": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.0.tgz", - "integrity": "sha512-iCP8g01NFYiiBOnwG1Xc3WZLyoo+RuBymwIlWncShXDDJYWN6DbnM3odslBJdgCdRlq94B5s63NWAZlcn2CS4w==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", + "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", "dev": true, "requires": { "define-properties": "^1.1.3", @@ -12177,12 +11854,11 @@ } }, "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "^5.0.0" } }, "strip-bom": { @@ -12327,11 +12003,14 @@ "write-file-atomic": "^3.0.3" }, "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } }, "array-union": { "version": "2.1.0", @@ -12340,13 +12019,13 @@ "dev": true }, "autoprefixer": { - "version": "9.7.5", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.5.tgz", - "integrity": "sha512-URo6Zvt7VYifomeAfJlMFnYDhow1rk2bufwkbamPEAtQFcL11moLk4PnR7n9vlu7M+BkXAZkHFA0mIcY7tjQFg==", + "version": "9.7.6", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.6.tgz", + "integrity": "sha512-F7cYpbN7uVVhACZTeeIeealwdGM6wMtfWARVLTy5xmKtgVdBNJvbDRoCK3YO1orcs7gv/KwYlb3iXwu9Ug9BkQ==", "dev": true, "requires": { - "browserslist": "^4.11.0", - "caniuse-lite": "^1.0.30001036", + "browserslist": "^4.11.1", + "caniuse-lite": "^1.0.30001039", "chalk": "^2.4.2", "normalize-range": "^0.1.2", "num2fraction": "^1.2.2", @@ -12378,50 +12057,19 @@ "quick-lru": "^4.0.1" } }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "requires": { - "color-name": "~1.1.4" + "color-name": "1.1.3" } }, "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, "cosmiconfig": { @@ -12446,16 +12094,6 @@ "path-type": "^4.0.0" } }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, "get-stdin": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz", @@ -12477,9 +12115,9 @@ } }, "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, "ignore": { @@ -12506,21 +12144,6 @@ } } }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, "map-obj": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.1.0.tgz", @@ -12556,30 +12179,6 @@ "picomatch": "^2.0.5" } }, - "p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, "parse-json": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", @@ -12592,12 +12191,6 @@ "lines-and-columns": "^1.1.6" } }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -12657,26 +12250,6 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, - "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, "strip-indent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", @@ -12686,6 +12259,15 @@ "min-indent": "^1.0.0" } }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, "trim-newlines": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.0.tgz", @@ -12697,16 +12279,6 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true - }, - "yargs-parser": { - "version": "18.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.2.tgz", - "integrity": "sha512-hlIPNR3IzC1YuL1c2UwwDKpXlNFBqD1Fswwh1khz5+d8Cq/8yc/Mn0i+rQXduu8hcrFKvO7Eryk+09NecTQAAQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } } } }, @@ -12772,6 +12344,20 @@ "ms": "2.0.0" } }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -12829,11 +12415,12 @@ } }, "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, "requires": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" } }, "svg-tags": { @@ -12861,6 +12448,58 @@ "stable": "^0.1.8", "unquote": "~1.1.1", "util.promisify": "~1.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "symbol-observable": { @@ -12893,6 +12532,12 @@ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", "dev": true }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -12944,9 +12589,9 @@ } }, "terser": { - "version": "4.6.7", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.7.tgz", - "integrity": "sha512-fmr7M1f7DBly5cX2+rFDvmGBAaaZyPrHYK4mMdHEDAdNTqXSZgSOfqsfGq2HqPGT/1V0foZZuCZFx8CHKgAk3g==", + "version": "4.6.10", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.10.tgz", + "integrity": "sha512-qbF/3UOo11Hggsbsqm2hPa6+L4w7bkr+09FNseEe8xrcVD3APGLFqE+Oz1ZKAxjYnFsj80rLOfgAtJ0LNJjtTA==", "dev": true, "requires": { "commander": "^2.20.0", @@ -13005,21 +12650,20 @@ "unique-filename": "^1.1.1" } }, - "p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "dev": true, "requires": { - "p-try": "^2.0.0" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -13155,6 +12799,7 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, "requires": { "psl": "^1.1.28", "punycode": "^2.1.1" @@ -13238,11 +12883,55 @@ "tsutils": "^2.29.0" }, "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } } } }, @@ -13341,6 +13030,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, "requires": { "safe-buffer": "^5.0.1" } @@ -13348,7 +13038,8 @@ "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true }, "type-fest": { "version": "0.11.0", @@ -13611,6 +13302,12 @@ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true } } }, @@ -13624,6 +13321,7 @@ "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, "requires": { "punycode": "^2.1.0" } @@ -13631,7 +13329,8 @@ "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true }, "url": { "version": "0.11.0", @@ -13720,7 +13419,8 @@ "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true }, "v8-compile-cache": { "version": "2.1.0", @@ -13763,6 +13463,7 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -13930,7 +13631,6 @@ "dev": true, "optional": true, "requires": { - "bindings": "^1.5.0", "nan": "^2.12.1", "node-pre-gyp": "*" }, @@ -14612,6 +14312,20 @@ "pkg-dir": "^3.0.0" } }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "is-wsl": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", @@ -14774,6 +14488,12 @@ "yargs": "12.0.5" }, "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, "anymatch": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", @@ -14839,6 +14559,34 @@ "upath": "^1.1.1" } }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", @@ -14860,6 +14608,15 @@ "to-regex-range": "^2.1.0" } }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, "fsevents": { "version": "1.2.12", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.12.tgz", @@ -14867,7 +14624,6 @@ "dev": true, "optional": true, "requires": { - "bindings": "^1.5.0", "nan": "^2.12.1", "node-pre-gyp": "*" }, @@ -15411,6 +15167,18 @@ } } }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, "is-absolute-url": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", @@ -15426,6 +15194,12 @@ "binary-extensions": "^1.0.0" } }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", @@ -15444,6 +15218,31 @@ "is-buffer": "^1.1.5" } }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, "readdirp": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", @@ -15455,6 +15254,12 @@ "readable-stream": "^2.0.2" } }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, "schema-utils": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", @@ -15472,6 +15277,42 @@ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, "supports-color": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", @@ -15490,6 +15331,68 @@ "is-number": "^3.0.0", "repeat-string": "^1.6.1" } + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "yargs": { + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } } } }, @@ -15583,6 +15486,39 @@ "dev": true, "requires": { "string-width": "^1.0.2 || 2" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } } }, "worker-farm": { @@ -15626,35 +15562,13 @@ } }, "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" } }, "wrappy": { @@ -15725,75 +15639,27 @@ } }, "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", - "dev": true, + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.0.tgz", + "integrity": "sha512-g/QCnmjgOl1YJjGsnUg2SatC7NUYEiLXJqxNOQU9qSpjzGtGXda9b+OKccr1kLTy8BN9yqEyqfq5lxlwdc13TA==", "requires": { - "cliui": "^4.0.0", + "cliui": "^6.0.0", "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", + "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", - "string-width": "^2.0.0", + "string-width": "^4.2.0", "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - } + "y18n": "^4.0.0", + "yargs-parser": "^18.1.0" } }, "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", - "dev": true, + "version": "18.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.2.tgz", + "integrity": "sha512-hlIPNR3IzC1YuL1c2UwwDKpXlNFBqD1Fswwh1khz5+d8Cq/8yc/Mn0i+rQXduu8hcrFKvO7Eryk+09NecTQAAQ==", "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" diff --git a/wg_dashboard_frontend/package.json b/wg_dashboard_frontend/package.json index 9c34b6a..9dc3cf6 100644 --- a/wg_dashboard_frontend/package.json +++ b/wg_dashboard_frontend/package.json @@ -40,32 +40,26 @@ "@angular/platform-browser": "9.1.0", "@angular/platform-browser-dynamic": "9.1.0", "@angular/router": "9.1.0", - "@ng-bootstrap/ng-bootstrap": "^6.0.2", + "angular-material-dynamic-themes": "^1.0.4", "angularx-qrcode": "^2.1.0", - "bootstrap": "^4.4.1", "classlist.js": "1.1.20150312", "core-js": "3.6.4", - "d3": "5.15.1", - "goog-webfont-dl": "^1.0.3", "hammerjs": "^2.0.8", "ip-cidr": "^2.0.10", - "material-design-lite": "1.3.0", "material-icons": "^0.3.1", - "nvd3": "1.8.6", + "ngx-cookie-service": "^3.0.4", "rxjs": "6.5.5", "tslib": "^1.10.0", "web-animations-js": "^2.3.2", "zone.js": "^0.10.3" }, "devDependencies": { + "@angular-devkit/schematics": "^9.1.1", "@angular-devkit/build-angular": "~0.901.0", "@angular/cli": "9.1.0", "@angular/compiler-cli": "9.1.0", "@angular/language-service": "9.1.0", - "@types/d3": "^5.7.2", - "@types/material-design-lite": "1.1.15", "@types/node": "^13.11.0", - "@types/nvd3": "1.8.40", "codelyzer": "^5.1.2", "node-sass": "4.13.1", "pre-commit": "1.2.2", diff --git a/wg_dashboard_frontend/src/app/app-routing.module.ts b/wg_dashboard_frontend/src/app/app-routing.module.ts index 5f8e5c9..455eaf3 100644 --- a/wg_dashboard_frontend/src/app/app-routing.module.ts +++ b/wg_dashboard_frontend/src/app/app-routing.module.ts @@ -1,10 +1,8 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; -import {LayoutModule} from "./layout/layout.module"; - -import {ErrorComponent} from "./page/error"; - +import { LayoutModule } from './layout/layout.module'; +import { ErrorComponent } from './page/error'; @NgModule({ imports: [ @@ -13,7 +11,6 @@ import {ErrorComponent} from "./page/error"; { path: '', redirectTo: 'app/dashboard', pathMatch: 'full' }, { path: 'page', loadChildren: () => import('./page/page.module').then(m => m.PageModule) }, - /*{ path: 'app', component: LayoutComponent, children: [ //{ path: 'dashboard', component: DashboardComponent, pathMatch: 'full', canActivate: [AuthGuard]}, @@ -29,7 +26,7 @@ import {ErrorComponent} from "./page/error"; { path: 'edit', component: EditComponent, pathMatch: 'full', canActivate: [AuthGuard]}, ] },*/ - { path: '**', redirectTo: '/page/404'}, + { path: '**', redirectTo: '/page/404' }, ], { useHash: true }, @@ -39,3 +36,4 @@ import {ErrorComponent} from "./page/error"; exports: [RouterModule], }) export class AppRoutingModule {} + diff --git a/wg_dashboard_frontend/src/app/app.component.ts b/wg_dashboard_frontend/src/app/app.component.ts index 339dc7e..d0cfefa 100644 --- a/wg_dashboard_frontend/src/app/app.component.ts +++ b/wg_dashboard_frontend/src/app/app.component.ts @@ -1,15 +1,68 @@ -import { Component } from '@angular/core'; -import {AuthService} from "@services/*"; +import {Component, HostBinding} from '@angular/core'; +import { AuthService } from '@services/*'; +import {OverlayContainer} from "@angular/cdk/overlay"; +import {DataService} from "./services/data.service"; +import {CookieService} from "ngx-cookie-service"; + +const THEME_DARKNESS_SUFFIX = `-dark`; @Component({ selector: 'app-root', template: ``, }) export class AppComponent { + @HostBinding('class') activeThemeCssClass: string; + isThemeDark = false; + activeTheme: string; + + constructor( + private auth: + AuthService, + private overlayContainer: OverlayContainer, + private comm: DataService, + private cookieService: CookieService + ) { + auth.init(); + + this.comm.on("changeTheme").subscribe( (data: { + theme: any, + darkMode: boolean + }) => { + this.setActiveTheme(data.theme.theme, /* darkness: */ data.darkMode) + }); + + if(this.cookieService.check("currentTheme")){ + this.setActiveTheme( + JSON.parse(this.cookieService.get("currentTheme")).theme, + (this.cookieService.get("darkMode") === 'true') + ); + + } + + + + - constructor(private auth: AuthService) { - auth.init() } + setActiveTheme(theme: string, darkness: boolean = null) { + if (darkness === null) + darkness = this.isThemeDark; + else if (this.isThemeDark === darkness) { + if (this.activeTheme === theme) return + } else + this.isThemeDark = darkness; + + this.activeTheme = theme; + const cssClass = darkness === true ? theme + THEME_DARKNESS_SUFFIX : theme; + + const classList = this.overlayContainer.getContainerElement().classList; + if (classList.contains(this.activeThemeCssClass)) + classList.replace(this.activeThemeCssClass, cssClass); + else + classList.add(cssClass); + + this.activeThemeCssClass = cssClass + } } diff --git a/wg_dashboard_frontend/src/app/app.module.ts b/wg_dashboard_frontend/src/app/app.module.ts index cd7eadd..aef8a7d 100644 --- a/wg_dashboard_frontend/src/app/app.module.ts +++ b/wg_dashboard_frontend/src/app/app.module.ts @@ -6,7 +6,6 @@ import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { VarDirective } from './directives/var.directive'; import { QRCodeModule } from 'angularx-qrcode'; -import {NgbModule} from "@ng-bootstrap/ng-bootstrap"; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { MatGridListModule } from '@angular/material/grid-list'; import { MatCardModule } from '@angular/material/card'; @@ -17,7 +16,8 @@ import { MatButtonModule } from '@angular/material/button'; import { MatToolbarModule } from '@angular/material/toolbar'; import { MatSidenavModule } from '@angular/material/sidenav'; import { MatListModule } from '@angular/material/list'; -import {FlexLayoutModule} from "@angular/flex-layout"; +import { FlexLayoutModule } from '@angular/flex-layout'; +import {CookieService} from "ngx-cookie-service"; @NgModule({ declarations: [ @@ -28,7 +28,6 @@ import {FlexLayoutModule} from "@angular/flex-layout"; BrowserModule, AppRoutingModule, HttpClientModule, - NgbModule, QRCodeModule, BrowserAnimationsModule, MatGridListModule, @@ -40,18 +39,20 @@ import {FlexLayoutModule} from "@angular/flex-layout"; MatSidenavModule, MatListModule, FlexLayoutModule, + ], providers: [ + CookieService, AuthService, { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true, - } + }, ], bootstrap: [AppComponent], exports: [ - VarDirective - ] + VarDirective, + ], }) export class AppModule {} diff --git a/wg_dashboard_frontend/src/app/components/blank-layout-card/blank-layout-card.component.scss b/wg_dashboard_frontend/src/app/components/blank-layout-card/blank-layout-card.component.scss deleted file mode 100644 index 537f004..0000000 --- a/wg_dashboard_frontend/src/app/components/blank-layout-card/blank-layout-card.component.scss +++ /dev/null @@ -1,80 +0,0 @@ -@import '~theme/helpers'; - -.blank-layout-card { - margin: auto; - - .mdl-button { - font-weight: 500; - } - - font-family: Roboto, Helvetica, sans-serif; - font-size: 1rem; - - .mdl-card__blank-layout-card.mdl-card { - max-width: 450px; - margin: auto; - - .mdl-card__supporting-text { - min-height: inherit; - width: 100%; - padding: 32px 24px; - box-sizing: border-box; - - .mdl-card__title-text { - font-size: 17px; - font-weight: bold; - } - - .blank-layout-card-name { - font-size: 24px; - display: block; - padding: 0 0 8px 0; - } - - .blank-layout-card-link { - padding: 12px 0; - } - - .blank-layout-card-link, - .blank-layout-card-link * { - display: inline-block; - font-size: 1rem; - font-weight: inherit; - color: $color-alto; - } - - .underlined { - display: inline-block; - border-bottom: 1px solid $color-light-blue; - } - - .checkbox--inline { - display: inline; - padding-top: 4px; - padding-left: 35px; - } - - .submit-cell { - display: flex; - } - - .text--huge { - font-size: 120px; - font-weight: bold; - display: inline-block; - padding: 100px 0 40px 0; - } - - .text--sorry { - font-size: 28px; - font-weight: 300; - } - - .alignment--bottom-right { - position: absolute; - bottom: 39px; - right: 46px; - } - } - } -} diff --git a/wg_dashboard_frontend/src/app/components/blank-layout-card/blank-layout-card.component.ts b/wg_dashboard_frontend/src/app/components/blank-layout-card/blank-layout-card.component.ts deleted file mode 100644 index 21be3b4..0000000 --- a/wg_dashboard_frontend/src/app/components/blank-layout-card/blank-layout-card.component.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Component, HostBinding } from '@angular/core'; - -import { UpgradableComponent } from 'theme/components/upgradable'; - -@Component({ - template: '', -}) -export class BlankLayoutCardComponent extends UpgradableComponent { - @HostBinding('class.blank-layout-card') protected readonly blankLayoutCard = true; -} diff --git a/wg_dashboard_frontend/src/app/components/blank-layout-card/index.ts b/wg_dashboard_frontend/src/app/components/blank-layout-card/index.ts deleted file mode 100644 index 9681003..0000000 --- a/wg_dashboard_frontend/src/app/components/blank-layout-card/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { BlankLayoutCardComponent } from './blank-layout-card.component'; diff --git a/wg_dashboard_frontend/src/app/components/message-menu/index.ts b/wg_dashboard_frontend/src/app/components/message-menu/index.ts deleted file mode 100644 index c26d3cf..0000000 --- a/wg_dashboard_frontend/src/app/components/message-menu/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { MessageMenuComponent } from './message-menu.component'; -export { MessageMenuService } from './message-menu.service'; diff --git a/wg_dashboard_frontend/src/app/components/message-menu/message-menu.component.html b/wg_dashboard_frontend/src/app/components/message-menu/message-menu.component.html deleted file mode 100644 index fdaaf3e..0000000 --- a/wg_dashboard_frontend/src/app/components/message-menu/message-menu.component.html +++ /dev/null @@ -1,27 +0,0 @@ -
- mail_outline -
- diff --git a/wg_dashboard_frontend/src/app/components/message-menu/message-menu.component.scss b/wg_dashboard_frontend/src/app/components/message-menu/message-menu.component.scss deleted file mode 100644 index 7c41ed2..0000000 --- a/wg_dashboard_frontend/src/app/components/message-menu/message-menu.component.scss +++ /dev/null @@ -1,54 +0,0 @@ -@import '~theme/helpers'; - -.message-menu { - position: relative; -} - -.messages-dropdown { - &.mdl-menu { - width: 310px; - } - - .label { - color: $messages-dropdown-label-text-color; - } - - .mdl-list__item-primary-content { - font-weight: 400; - line-height: 18px; - - .mdl-list__item-avatar { - padding: ($list-avatar-size - $list-icon-size); - text-align: center; - - .material-icons { - vertical-align: top; - } - - .text { - font-size: 19px; - vertical-align: middle; - } - } - - .mdl-list__item-sub-title { - font-weight: 100; - font-size: 12px; - } - } - - &.mdl-list { - .mdl-list__item { - @include typo-dropdown-menu-li; - - &:first-child { - color: $dropdown-menu-header-font-color; - } - - &:last-child { - padding-top: $list-min-padding/2; - padding-bottom: 0; - } - } - } -} diff --git a/wg_dashboard_frontend/src/app/components/message-menu/message-menu.component.ts b/wg_dashboard_frontend/src/app/components/message-menu/message-menu.component.ts deleted file mode 100644 index b6b0871..0000000 --- a/wg_dashboard_frontend/src/app/components/message-menu/message-menu.component.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Component, HostBinding } from '@angular/core'; - -import { MessageMenuService } from './message-menu.service'; - -@Component({ - selector: 'app-message-menu', - styleUrls: ['./message-menu.component.scss'], - templateUrl: './message-menu.component.html', - providers: [MessageMenuService], -}) -export class MessageMenuComponent { - @HostBinding('class.message-menu') private readonly messageMenu = true; - - public messages: object[]; - - constructor(messageMenuService: MessageMenuService) { - this.messages = messageMenuService.getMessages(); - } -} diff --git a/wg_dashboard_frontend/src/app/components/message-menu/message-menu.service.ts b/wg_dashboard_frontend/src/app/components/message-menu/message-menu.service.ts deleted file mode 100644 index 6c3b3c9..0000000 --- a/wg_dashboard_frontend/src/app/components/message-menu/message-menu.service.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { Injectable } from '@angular/core'; - -@Injectable() -export class MessageMenuService { - public getMessages(): object[] { - return [ - { - name: 'Alice', - type: 'Birthday Party', - time: 'just now', - icon: 'A', - color: 'primary', - }, - { - name: 'Vladimir', - type: 'Deployment', - time: 'just now', - icon: 'V', - color: 'primary', - }, - { - name: 'Mike', - type: 'No theme', - time: '5 min', - icon: 'M', - color: 'baby-blue', - }, - { - name: 'Darth', - type: 'Suggestion', - time: '23 hours', - icon: 'D', - color: 'cerulean', - }, - { - name: 'Don McDuket', - type: 'NEWS', - time: '30 Nov', - icon: 'D', - color: 'mint', - }, - ]; - } -} diff --git a/wg_dashboard_frontend/src/app/components/notification-menu/index.ts b/wg_dashboard_frontend/src/app/components/notification-menu/index.ts deleted file mode 100644 index a7fbfe6..0000000 --- a/wg_dashboard_frontend/src/app/components/notification-menu/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { NotificationMenuComponent } from './notification-menu.component'; -export { NotificationMenuService } from './notification-menu.service'; diff --git a/wg_dashboard_frontend/src/app/components/notification-menu/notification-menu.component.html b/wg_dashboard_frontend/src/app/components/notification-menu/notification-menu.component.html deleted file mode 100644 index 489810c..0000000 --- a/wg_dashboard_frontend/src/app/components/notification-menu/notification-menu.component.html +++ /dev/null @@ -1,27 +0,0 @@ -
- notifications_none -
- diff --git a/wg_dashboard_frontend/src/app/components/notification-menu/notification-menu.component.scss b/wg_dashboard_frontend/src/app/components/notification-menu/notification-menu.component.scss deleted file mode 100644 index 7b729a7..0000000 --- a/wg_dashboard_frontend/src/app/components/notification-menu/notification-menu.component.scss +++ /dev/null @@ -1,31 +0,0 @@ -@import '~theme/helpers'; - -.notification-menu { - position: relative; -} - -.notifications-dropdown.mdl-list { - width: 310px; - - .mdl-list__item { - @include typo-dropdown-menu-li; - - &:first-child { - color: $dropdown-menu-header-font-color; - } - - .mdl-list__item-avatar { - padding: ($list-avatar-size - $list-icon-size); - text-align: center; - - .material-icons { - vertical-align: top; - } - } - - &:last-child { - padding-top: $list-min-padding/2; - padding-bottom: 0; - } - } -} diff --git a/wg_dashboard_frontend/src/app/components/notification-menu/notification-menu.component.ts b/wg_dashboard_frontend/src/app/components/notification-menu/notification-menu.component.ts deleted file mode 100644 index 40a4357..0000000 --- a/wg_dashboard_frontend/src/app/components/notification-menu/notification-menu.component.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Component, HostBinding } from '@angular/core'; - -import { NotificationMenuService } from './notification-menu.service'; - -@Component({ - selector: 'app-notification-menu', - styleUrls: ['./notification-menu.component.scss'], - templateUrl: './notification-menu.component.html', - providers: [NotificationMenuService], -}) -export class NotificationMenuComponent { - @HostBinding('class.notification-menu') private readonly notificationMenu = true; - - public notifications: object[]; - - constructor(notificationMenuService: NotificationMenuService) { - this.notifications = notificationMenuService.getNotifications(); - } -} diff --git a/wg_dashboard_frontend/src/app/components/notification-menu/notification-menu.service.ts b/wg_dashboard_frontend/src/app/components/notification-menu/notification-menu.service.ts deleted file mode 100644 index cb7e0bf..0000000 --- a/wg_dashboard_frontend/src/app/components/notification-menu/notification-menu.service.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Injectable } from '@angular/core'; - -@Injectable() -export class NotificationMenuService { - public getNotifications(): object[] { - return [ - { - text: 'You have 3 new orders.', - time: 'just now', - icon: 'plus_one', - color: 'primary', - }, { - text: 'Database error', - time: '1 min', - icon: 'error_outline', - color: 'secondary', - }, { - text: 'The Death Star is built!', - time: '2 hours', - icon: 'new_releases', - color: 'primary', - }, { - text: 'You have 4 new mails.', - time: '5 days', - icon: 'mail_outline', - color: 'primary', - }, - ]; - } -} diff --git a/wg_dashboard_frontend/src/app/components/sidebar/index.ts b/wg_dashboard_frontend/src/app/components/sidebar/index.ts deleted file mode 100644 index f887d29..0000000 --- a/wg_dashboard_frontend/src/app/components/sidebar/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { SidebarComponent } from './sidebar.component'; diff --git a/wg_dashboard_frontend/src/app/components/sidebar/sidebar.component.scss b/wg_dashboard_frontend/src/app/components/sidebar/sidebar.component.scss deleted file mode 100644 index dfb7984..0000000 --- a/wg_dashboard_frontend/src/app/components/sidebar/sidebar.component.scss +++ /dev/null @@ -1,3 +0,0 @@ -.mdl-navigation base-menu-item:nth-child(2) i.material-icons { - transform: rotate(180deg); -} diff --git a/wg_dashboard_frontend/src/app/components/sidebar/sidebar.component.ts b/wg_dashboard_frontend/src/app/components/sidebar/sidebar.component.ts deleted file mode 100644 index 4f4f7c8..0000000 --- a/wg_dashboard_frontend/src/app/components/sidebar/sidebar.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component, Input } from '@angular/core'; - -import { SidebarComponent as BaseSidebarComponent } from 'theme/components/sidebar'; - -@Component({ - selector: 'app-sidebar', - styleUrls: ['../../../theme/components/sidebar/sidebar.component.scss', './sidebar.component.scss'], - templateUrl: '../../../theme/components/sidebar/sidebar.component.html', -}) -export class SidebarComponent extends BaseSidebarComponent { - public title = 'Wireguard'; - public menu = [ - { name: 'Dashboard', link: '/app/dashboard', icon: 'dashboard' }, - ]; -} diff --git a/wg_dashboard_frontend/src/app/directives/var.directive.ts b/wg_dashboard_frontend/src/app/directives/var.directive.ts index 2179a77..c89475f 100644 --- a/wg_dashboard_frontend/src/app/directives/var.directive.ts +++ b/wg_dashboard_frontend/src/app/directives/var.directive.ts @@ -1,4 +1,4 @@ -import {Directive, Input, TemplateRef, ViewContainerRef} from "@angular/core"; +import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core'; @Directive({ selector: '[ngVar]', @@ -6,7 +6,7 @@ import {Directive, Input, TemplateRef, ViewContainerRef} from "@angular/core"; export class VarDirective { @Input() set ngVar(context: any) { - console.log(context) + console.log(context); this.context.$implicit = this.context.ngVar = context; this.updateView(); } diff --git a/wg_dashboard_frontend/src/app/interfaces/peer.ts b/wg_dashboard_frontend/src/app/interfaces/peer.ts index 3f78db4..99d61c0 100644 --- a/wg_dashboard_frontend/src/app/interfaces/peer.ts +++ b/wg_dashboard_frontend/src/app/interfaces/peer.ts @@ -6,12 +6,13 @@ export interface Peer { dns: string; allowed_ips: string; name: string; + configuration: string; stats: { sent: string, received: string, - handshake: string - } + handshake: string, + }; _expand?: boolean; - _edit?: boolean + _edit?: boolean; } diff --git a/wg_dashboard_frontend/src/app/interfaces/server.ts b/wg_dashboard_frontend/src/app/interfaces/server.ts index 07c5e66..fb0d536 100644 --- a/wg_dashboard_frontend/src/app/interfaces/server.ts +++ b/wg_dashboard_frontend/src/app/interfaces/server.ts @@ -1,4 +1,4 @@ -import {Peer} from "./peer"; +import { Peer } from './peer'; export interface Server { address: string; @@ -11,5 +11,6 @@ export interface Server { is_running: boolean; post_up: string; post_down: string; - peers: Array + configuration: string; + peers: Peer[]; } diff --git a/wg_dashboard_frontend/src/app/interfaces/user.ts b/wg_dashboard_frontend/src/app/interfaces/user.ts index 47b6c30..2a9a999 100644 --- a/wg_dashboard_frontend/src/app/interfaces/user.ts +++ b/wg_dashboard_frontend/src/app/interfaces/user.ts @@ -1,11 +1,11 @@ -import {Peer} from "./peer"; +import { Peer } from './peer'; export interface User { full_name: string; email: string; role: string; username: string; - access_token: string, - token_type: string, + access_token: string; + token_type: string; } diff --git a/wg_dashboard_frontend/src/app/layout/layout.module.ts b/wg_dashboard_frontend/src/app/layout/layout.module.ts index bebe2d8..11319b9 100644 --- a/wg_dashboard_frontend/src/app/layout/layout.module.ts +++ b/wg_dashboard_frontend/src/app/layout/layout.module.ts @@ -2,30 +2,32 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { LayoutComponent } from './layout/layout.component'; -import {MatSidenavModule} from "@angular/material/sidenav"; -import {MatToolbarModule} from "@angular/material/toolbar"; -import {MatListModule} from "@angular/material/list"; -import {MatIconModule} from "@angular/material/icon"; -import {MatButtonModule} from "@angular/material/button"; -import {FlexLayoutModule} from "@angular/flex-layout"; -import {RouterModule} from "@angular/router"; - - +import { MatSidenavModule } from '@angular/material/sidenav'; +import { MatToolbarModule } from '@angular/material/toolbar'; +import { MatListModule } from '@angular/material/list'; +import { MatIconModule } from '@angular/material/icon'; +import { MatButtonModule } from '@angular/material/button'; +import { FlexLayoutModule } from '@angular/flex-layout'; +import { RouterModule } from '@angular/router'; +import { MatMenuModule } from '@angular/material/menu'; +import {MatSlideToggleModule} from "@angular/material/slide-toggle"; @NgModule({ declarations: [LayoutComponent], - imports: [ - CommonModule, - MatSidenavModule, - MatToolbarModule, - MatListModule, - MatIconModule, - MatButtonModule, - FlexLayoutModule, - RouterModule - ], + imports: [ + CommonModule, + MatSidenavModule, + MatToolbarModule, + MatListModule, + MatIconModule, + MatButtonModule, + FlexLayoutModule, + RouterModule, + MatMenuModule, + MatSlideToggleModule, + ], exports: [ - ] + ], }) export class LayoutModule { } diff --git a/wg_dashboard_frontend/src/app/layout/layout/layout.component.html b/wg_dashboard_frontend/src/app/layout/layout/layout.component.html index 88e2913..d6b567c 100644 --- a/wg_dashboard_frontend/src/app/layout/layout/layout.component.html +++ b/wg_dashboard_frontend/src/app/layout/layout/layout.component.html @@ -1,4 +1,4 @@ -
+
@@ -7,17 +7,46 @@ menu {{config.applicationName}} -
- - {{item.icon}} {{item.text}}
+ + + + + + + + + + + + + + + + Dark + + + + + +
diff --git a/wg_dashboard_frontend/src/app/layout/layout/layout.component.scss b/wg_dashboard_frontend/src/app/layout/layout/layout.component.scss index d078885..616e7ab 100644 --- a/wg_dashboard_frontend/src/app/layout/layout/layout.component.scss +++ b/wg_dashboard_frontend/src/app/layout/layout/layout.component.scss @@ -16,4 +16,6 @@ z-index: 1; } - +.menu-spacer { + flex: 1 1 auto; +} diff --git a/wg_dashboard_frontend/src/app/layout/layout/layout.component.ts b/wg_dashboard_frontend/src/app/layout/layout/layout.component.ts index 9d8daca..07d0761 100644 --- a/wg_dashboard_frontend/src/app/layout/layout/layout.component.ts +++ b/wg_dashboard_frontend/src/app/layout/layout/layout.component.ts @@ -1,29 +1,78 @@ import { Component, OnInit } from '@angular/core'; -import {Observable} from "rxjs"; -import {BreakpointObserver, Breakpoints} from "@angular/cdk/layout"; -import {map, shareReplay} from "rxjs/operators"; -import {ConfigService} from "../../services/config.service"; +import { Observable } from 'rxjs'; +import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout'; +import { map, shareReplay } from 'rxjs/operators'; +import { ConfigService } from '../../services/config.service'; +import { AuthService } from '@services/*'; +import {OverlayContainer} from "@angular/cdk/overlay"; +import {DataService} from "../../services/data.service"; +import {CookieService} from "ngx-cookie-service"; @Component({ selector: 'app-layout', templateUrl: './layout.component.html', - styleUrls: ['./layout.component.scss'] + styleUrls: ['./layout.component.scss'], }) export class LayoutComponent implements OnInit { isHandset$: Observable = this.breakpointObserver.observe(Breakpoints.Handset) .pipe( map(result => result.matches), - shareReplay() + shareReplay(), ); - menu: Array<{link: Array, icon: string, text: string}> = [ - { link: ["/page/dashboard"], icon: "home", text: "Dashboard"} + menu: {link: string[], icon: string, text: string}[] = [ + { link: ['/page/dashboard'], icon: 'home', text: 'Dashboard' }, ]; - constructor(private breakpointObserver: BreakpointObserver, public config: ConfigService) {} + themes = [ + {theme: "indigo-pink", name: "Blue"}, + {theme: "deeppurple-amber", name: "Purple"}, + {theme: "pink-bluegrey", name: "Pink"}, + {theme: "purple-green", name: "Purple-Green"}, + ]; + currentTheme = null; + darkMode = false; + + constructor( + private breakpointObserver: BreakpointObserver, + public config: ConfigService, + public auth: AuthService, + private comm: DataService, + private cookieService: CookieService + ) {} ngOnInit(): void { - console.log("Layout") + console.log('Layout'); + + if(this.cookieService.check("currentTheme")){ + this.currentTheme = JSON.parse(this.cookieService.get("currentTheme")); + this.darkMode = (this.cookieService.get("darkMode") === 'true'); + }else { + this.currentTheme = { ... this.themes[0]} + } + + } + + toggleDarkMode($event){ + $event.stopPropagation(); + this.darkMode = !this.darkMode; + this.cookieService.set("darkMode", String(this.darkMode)); + this.sendData(); + } + + setCurrentTheme(theme){ + this.cookieService.set("currentTheme", JSON.stringify(theme)); + this.currentTheme = theme; + this.sendData(); + } + + sendData(){ + const send = { + theme: this.currentTheme, + darkMode: this.darkMode + }; + + this.comm.emit('changeTheme', send); } } diff --git a/wg_dashboard_frontend/src/app/page/components/components.component.ts b/wg_dashboard_frontend/src/app/page/components/components.component.ts index 8fab81e..39ee2b4 100644 --- a/wg_dashboard_frontend/src/app/page/components/components.component.ts +++ b/wg_dashboard_frontend/src/app/page/components/components.component.ts @@ -1,30 +1,10 @@ -import { Component, HostBinding } from '@angular/core'; - +import { Component } from '@angular/core'; @Component({ selector: 'app-components', - templateUrl: './components.component.html', - styleUrls: ['./components.component.scss'], + template: '', + styles: [''], }) export class ComponentsComponent { - @HostBinding('class.mdl-grid') private readonly mdlGrid = true; - @HostBinding('class.ui-components') private readonly uiComponents = true; - public data = [ - { - name: 'Nathan Fillion', - description: 'Malcolm “Mal” Reynolds', - image: 'nathan-fillion.png', - }, - { - name: 'Gina Torres', - description: 'Zoe Alleyne Washburne', - image: 'gina-torres.png', - }, - { - name: 'Alan Tudyk', - description: 'Hoban “Wash” Washburne', - image: 'tudyk.png', - }, - ]; } diff --git a/wg_dashboard_frontend/src/app/page/components/components.module.ts b/wg_dashboard_frontend/src/app/page/components/components.module.ts index 7a6ba84..c5a9040 100644 --- a/wg_dashboard_frontend/src/app/page/components/components.module.ts +++ b/wg_dashboard_frontend/src/app/page/components/components.module.ts @@ -5,27 +5,35 @@ import { FormsModule } from '@angular/forms'; import { ThemeModule } from 'theme'; import { ComponentsComponent } from './components.component'; -import {NgbActiveModal} from "@ng-bootstrap/ng-bootstrap"; -import {ModalConfirmComponent} from "./modal-confirm"; -import {QRCodeModule} from "angularx-qrcode"; +import { ModalConfirmComponent } from './modal-confirm'; +import { QRCodeModule } from 'angularx-qrcode'; +import {MatButtonModule} from "@angular/material/button"; +import {MatTooltipModule} from "@angular/material/tooltip"; +import {MatCardModule} from "@angular/material/card"; +import {MatIconModule} from "@angular/material/icon"; +import {FlexModule} from "@angular/flex-layout"; @NgModule({ - imports: [ - CommonModule, - ThemeModule, - FormsModule, - QRCodeModule - ], + imports: [ + CommonModule, + ThemeModule, + FormsModule, + QRCodeModule, + MatButtonModule, + MatTooltipModule, + MatCardModule, + MatIconModule, + FlexModule, + ], providers: [ - NgbActiveModal ], exports: [ ComponentsComponent, - ModalConfirmComponent + ModalConfirmComponent, ], declarations: [ ComponentsComponent, - ModalConfirmComponent + ModalConfirmComponent, ], }) export class ComponentsModule { } diff --git a/wg_dashboard_frontend/src/app/page/components/modal-confirm/modal-confirm.component.html b/wg_dashboard_frontend/src/app/page/components/modal-confirm/modal-confirm.component.html index 07d7f39..7eed172 100644 --- a/wg_dashboard_frontend/src/app/page/components/modal-confirm/modal-confirm.component.html +++ b/wg_dashboard_frontend/src/app/page/components/modal-confirm/modal-confirm.component.html @@ -1,36 +1,51 @@ - - diff --git a/wg_dashboard_frontend/src/app/page/components/modal-confirm/modal-confirm.component.scss b/wg_dashboard_frontend/src/app/page/components/modal-confirm/modal-confirm.component.scss index 1427e90..f51f379 100644 --- a/wg_dashboard_frontend/src/app/page/components/modal-confirm/modal-confirm.component.scss +++ b/wg_dashboard_frontend/src/app/page/components/modal-confirm/modal-confirm.component.scss @@ -6,6 +6,7 @@ .dark-modal .close { color: white; } + .light-blue-backdrop { background-color: #5cb3fd; } diff --git a/wg_dashboard_frontend/src/app/page/components/modal-confirm/modal-confirm.component.ts b/wg_dashboard_frontend/src/app/page/components/modal-confirm/modal-confirm.component.ts index eb559a5..b6fa531 100644 --- a/wg_dashboard_frontend/src/app/page/components/modal-confirm/modal-confirm.component.ts +++ b/wg_dashboard_frontend/src/app/page/components/modal-confirm/modal-confirm.component.ts @@ -1,15 +1,24 @@ -import {Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation} from '@angular/core'; -import {NgbModal} from "@ng-bootstrap/ng-bootstrap"; +import { + Component, + ContentChild, + EventEmitter, + Input, + OnInit, + Output, + TemplateRef, ViewChild, ViewContainerRef, + ViewEncapsulation +} from '@angular/core'; +import {NgForOfContext} from "@angular/common"; @Component({ selector: 'app-modal-confirm', templateUrl: './modal-confirm.component.html', - encapsulation: ViewEncapsulation.None, - styleUrls: ['./modal-confirm.component.scss'] + encapsulation: ViewEncapsulation.Emulated, + styleUrls: ['./modal-confirm.component.scss'], }) -export class ModalConfirmComponent implements OnInit{ - @Input() noConfirm: boolean = false; - @Input() qrCode: boolean = false; +export class ModalConfirmComponent implements OnInit { + @Input() noConfirm = false; + @Input() qrCode = false; @Input() icon: string; @Input() hover: string; @Input() title: string; @@ -17,40 +26,42 @@ export class ModalConfirmComponent implements OnInit{ @Input() area: boolean; @Output() onCancel: EventEmitter = new EventEmitter(); @Output() onConfirm: EventEmitter = new EventEmitter(); - constructor(public modal: NgbModal) { + + @ViewChild('modal', { read: TemplateRef }) _template: TemplateRef; + @ViewChild('vc', {read: ViewContainerRef}) vc: ViewContainerRef; + shown = false; + + constructor() { + } - open($event, content) { - $event.stopPropagation(); - if(this.noConfirm) { + open($event){ + if (this.noConfirm) { this.onConfirm.emit(); return true; } - this.modal.open(content, { - ariaLabelledBy: 'modal-basic-title', - backdropClass: "light-blue-backdrop", - windowClass: "dark-modal" - }).result.then((result) => { - if(result === "cancel"){ - this.onCancel.emit() - }else if(result === "confirm"){ - this.onConfirm.emit(); - } + this.shown = true; + //this.vc.createEmbeddedView(this._template, {fromContext: 'John'}); - }, (reason) => { + } + confirm($event){ + $event.stopPropagation(); + this.onConfirm.emit(); + this.shown= false; - }); + } + + cancel($event){ + this.onCancel.emit(); + this.shown = false } ngOnInit(): void { this.area = this.area || false; - this.area = !!this.area + this.area = !!this.area; } - - - } diff --git a/wg_dashboard_frontend/src/app/page/dashboard2/add-server/add-server.component.html b/wg_dashboard_frontend/src/app/page/dashboard/add-server/add-server.component.html similarity index 79% rename from wg_dashboard_frontend/src/app/page/dashboard2/add-server/add-server.component.html rename to wg_dashboard_frontend/src/app/page/dashboard/add-server/add-server.component.html index b75f10a..9cbab1d 100644 --- a/wg_dashboard_frontend/src/app/page/dashboard2/add-server/add-server.component.html +++ b/wg_dashboard_frontend/src/app/page/dashboard/add-server/add-server.component.html @@ -1,9 +1,9 @@ -
+ -

Essentials

+

Essentials

@@ -34,7 +34,7 @@
-

Keys

+

Keys

Private-Key @@ -56,18 +56,18 @@

-
- -
-

Scripts

+

Scripts

Post-Up @@ -82,9 +82,14 @@

+
-
- @@ -94,6 +99,7 @@
+ diff --git a/wg_dashboard_frontend/src/app/page/dashboard2/add-server/add-server.component.scss b/wg_dashboard_frontend/src/app/page/dashboard/add-server/add-server.component.scss similarity index 76% rename from wg_dashboard_frontend/src/app/page/dashboard2/add-server/add-server.component.scss rename to wg_dashboard_frontend/src/app/page/dashboard/add-server/add-server.component.scss index bfd7057..05b831f 100644 --- a/wg_dashboard_frontend/src/app/page/dashboard2/add-server/add-server.component.scss +++ b/wg_dashboard_frontend/src/app/page/dashboard/add-server/add-server.component.scss @@ -12,7 +12,8 @@ td { padding-right: 8px; } -.add-server-button-group{ - margin-right: 8px; -} + +:host { + width: 100%; +} diff --git a/wg_dashboard_frontend/src/app/page/dashboard2/add-server/add-server.component.ts b/wg_dashboard_frontend/src/app/page/dashboard/add-server/add-server.component.ts similarity index 58% rename from wg_dashboard_frontend/src/app/page/dashboard2/add-server/add-server.component.ts rename to wg_dashboard_frontend/src/app/page/dashboard/add-server/add-server.component.ts index ac88be6..46721fc 100644 --- a/wg_dashboard_frontend/src/app/page/dashboard2/add-server/add-server.component.ts +++ b/wg_dashboard_frontend/src/app/page/dashboard/add-server/add-server.component.ts @@ -1,54 +1,55 @@ -import {Component, Input, OnInit, ViewEncapsulation} from '@angular/core'; -import {FormControl, FormGroup, Validators} from "@angular/forms"; -import {IPValidator} from "../../../validators/ip-address.validator"; -import {NumberValidator} from "../../../validators/number.validator"; -import {Server} from "../../../interfaces/server"; -import {ServerService} from "../../../services/server.service"; -import {DataService} from "../../../services/data.service"; +import { Component, Input, OnInit, ViewEncapsulation } from '@angular/core'; +import { FormControl, FormGroup, Validators } from '@angular/forms'; +import { IPValidator } from '../../../validators/ip-address.validator'; +import { NumberValidator } from '../../../validators/number.validator'; +import { Server } from '../../../interfaces/server'; +import { ServerService } from '../../../services/server.service'; +import { DataService } from '../../../services/data.service'; @Component({ selector: 'app-add-server', templateUrl: './add-server.component.html', - encapsulation: ViewEncapsulation.None, - styleUrls: ['./add-server.component.scss', '../dashboard2.component.css'] + styleUrls: ['./add-server.component.scss', '../dashboard.component.css'], }) export class AddServerComponent implements OnInit { - @Input() servers: Array; + @Input() servers: Server[]; serverForm = new FormGroup({ address: new FormControl('', [IPValidator.isIPAddress]), interface: new FormControl('', [Validators.required, Validators.minLength(3)]), listen_port: new FormControl('', [Validators.required, NumberValidator.stringIsNumber]), endpoint: new FormControl('', Validators.required), - private_key: new FormControl('', [Validators.minLength(44), Validators.maxLength(44)]), - public_key: new FormControl('', [Validators.minLength(44), Validators.maxLength(44)]), - shared_key: new FormControl('', [Validators.minLength(44), Validators.maxLength(44)]), + private_key: new FormControl('' ), + public_key: new FormControl('' ), + shared_key: new FormControl('' ), post_up: new FormControl(''), post_down: new FormControl(''), // Unused on backend + configuration: new FormControl(''), is_running: new FormControl(false), peers: new FormControl([]), }); - isEdit: boolean = false; + isEdit = false; editServer: Server = null; constructor(private serverAPI: ServerService, private comm: DataService) { } ngOnInit(): void { - this.comm.on("server-edit").subscribe( (data: Server) => { + this.comm.on('server-edit').subscribe((data: Server) => { this.isEdit = true; - this.serverForm.setValue(data); + this.serverForm.patchValue(data); + this.editServer = data; - }) + }); } add(form: Server) { - if(this.isEdit){ + if (this.isEdit) { const idx = this.servers.indexOf(this.editServer); this.serverAPI.editServer(this.editServer, form).subscribe((server: Server) => { this.servers[idx] = server; @@ -62,24 +63,25 @@ export class AddServerComponent implements OnInit { } this.isEdit = false; - this.serverForm.reset(); this.editServer = null; + this.serverForm.reset(); + this.serverForm.clearValidators(); } getKeyPair() { this.serverAPI.getKeyPair().subscribe((kp: any) => { this.serverForm.patchValue({ private_key: kp.private_key, - public_key: kp.public_key - }) + public_key: kp.public_key, + }); }); } getPSK() { this.serverAPI.getPSK().subscribe((psk: any) => { this.serverForm.patchValue({ - shared_key: psk.psk - }) + shared_key: psk.psk, + }); }); } } diff --git a/wg_dashboard_frontend/src/app/page/dashboard/dashboard.component.css b/wg_dashboard_frontend/src/app/page/dashboard/dashboard.component.css new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/wg_dashboard_frontend/src/app/page/dashboard/dashboard.component.css @@ -0,0 +1 @@ + diff --git a/wg_dashboard_frontend/src/app/page/dashboard2/dashboard2.component.html b/wg_dashboard_frontend/src/app/page/dashboard/dashboard.component.html similarity index 64% rename from wg_dashboard_frontend/src/app/page/dashboard2/dashboard2.component.html rename to wg_dashboard_frontend/src/app/page/dashboard/dashboard.component.html index 2bbd2d8..45e6ad7 100644 --- a/wg_dashboard_frontend/src/app/page/dashboard2/dashboard2.component.html +++ b/wg_dashboard_frontend/src/app/page/dashboard/dashboard.component.html @@ -1,9 +1,15 @@ -
+
+
-
+
diff --git a/wg_dashboard_frontend/src/app/page/dashboard/dashboard.component.ts b/wg_dashboard_frontend/src/app/page/dashboard/dashboard.component.ts new file mode 100644 index 0000000..2a1438a --- /dev/null +++ b/wg_dashboard_frontend/src/app/page/dashboard/dashboard.component.ts @@ -0,0 +1,38 @@ +import { Component, OnInit } from '@angular/core'; +import { BreakpointObserver } from '@angular/cdk/layout'; +import { Server } from '../../interfaces/server'; +import { ServerService } from '../../services/server.service'; +import { Peer } from '../../interfaces/peer'; + +@Component({ + selector: 'dashboard', + templateUrl: './dashboard.component.html', + styleUrls: ['./dashboard.component.css'], +}) +export class DashboardComponent implements OnInit { + servers: Server[] = []; + + constructor(private breakpointObserver: BreakpointObserver, private serverAPI: ServerService) { + + } + + ngOnInit(): void { + this.serverAPI.getServers() + .subscribe((servers: Server[]) => { + this.servers.push(...servers); + servers.forEach((server) => { + + this.serverAPI.serverStats(server).subscribe((stats: Peer[]) => { + stats.forEach(item => { + const peer = server.peers.find(x => x.public_key == item.public_key); + peer._stats = item; + }); + + }); + + }); + + }); + } + +} diff --git a/wg_dashboard_frontend/src/app/page/dashboard/dashboard.module.ts b/wg_dashboard_frontend/src/app/page/dashboard/dashboard.module.ts new file mode 100644 index 0000000..7560191 --- /dev/null +++ b/wg_dashboard_frontend/src/app/page/dashboard/dashboard.module.ts @@ -0,0 +1,49 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { DashboardComponent } from './dashboard.component'; +import { MatGridListModule } from '@angular/material/grid-list'; +import { MatCardModule } from '@angular/material/card'; +import { MatMenuModule } from '@angular/material/menu'; +import { MatIconModule } from '@angular/material/icon'; +import { MatButtonModule } from '@angular/material/button'; +import { ServerComponent } from './server/server.component'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { AddServerComponent } from './add-server/add-server.component'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { ComponentsModule } from '../components'; +import { FlexModule } from '@angular/flex-layout'; +import { MatTableModule } from '@angular/material/table'; +import { PeerComponent } from './peer/peer.component'; +import { QRCodeModule } from 'angularx-qrcode'; +import {MatTooltipModule} from "@angular/material/tooltip"; + +@NgModule({ + declarations: [ + DashboardComponent, + ServerComponent, + AddServerComponent, + PeerComponent, + ], + imports: [ + CommonModule, + MatGridListModule, + MatCardModule, + MatMenuModule, + MatIconModule, + MatButtonModule, + MatExpansionModule, + MatFormFieldModule, + MatInputModule, + ReactiveFormsModule, + ComponentsModule, + FlexModule, + MatTableModule, + FormsModule, + QRCodeModule, + MatTooltipModule, + + ], +}) +export class DashboardModule { } diff --git a/wg_dashboard_frontend/src/app/page/dashboard2/peer/peer.component.html b/wg_dashboard_frontend/src/app/page/dashboard/peer/peer.component.html similarity index 80% rename from wg_dashboard_frontend/src/app/page/dashboard2/peer/peer.component.html rename to wg_dashboard_frontend/src/app/page/dashboard/peer/peer.component.html index 844ec17..564fd95 100644 --- a/wg_dashboard_frontend/src/app/page/dashboard2/peer/peer.component.html +++ b/wg_dashboard_frontend/src/app/page/dashboard/peer/peer.component.html @@ -1,5 +1,10 @@ -
-
+
+
@@ -61,16 +66,20 @@
- -
-
- +
+
-
- +
+
diff --git a/wg_dashboard_frontend/src/app/page/dashboard2/peer/peer.component.scss b/wg_dashboard_frontend/src/app/page/dashboard/peer/peer.component.scss similarity index 85% rename from wg_dashboard_frontend/src/app/page/dashboard2/peer/peer.component.scss rename to wg_dashboard_frontend/src/app/page/dashboard/peer/peer.component.scss index 125b8c7..6473b13 100644 --- a/wg_dashboard_frontend/src/app/page/dashboard2/peer/peer.component.scss +++ b/wg_dashboard_frontend/src/app/page/dashboard/peer/peer.component.scss @@ -5,11 +5,6 @@ text-align: left; } -.full-width { - width: 100%; -} - - td { padding-left: 0 !important; padding-right: 8px; diff --git a/wg_dashboard_frontend/src/app/page/dashboard/peer/peer.component.ts b/wg_dashboard_frontend/src/app/page/dashboard/peer/peer.component.ts new file mode 100644 index 0000000..81229d6 --- /dev/null +++ b/wg_dashboard_frontend/src/app/page/dashboard/peer/peer.component.ts @@ -0,0 +1,70 @@ +import { Component, EventEmitter, Input, OnInit, ViewEncapsulation } from '@angular/core'; +import { ServerService } from '../../../services/server.service'; +import { Peer } from '../../../interfaces/peer'; +import { Server } from '../../../interfaces/server'; +import { FormControl, FormGroup } from '@angular/forms'; + +@Component({ + selector: 'app-peer', + templateUrl: './peer.component.html', + encapsulation: ViewEncapsulation.None, + styleUrls: ['./peer.component.scss'], +}) +export class PeerComponent implements OnInit { + + @Input('peer') peer: Peer; + @Input('server') server: Server; + @Input('selectedPeer') selectedPeer: Peer; + @Input('onEvent') editPeerEmitter: EventEmitter = new EventEmitter(); + + constructor(public serverAPI: ServerService) { } + + ngOnInit(): void { + + this.editPeerEmitter.subscribe((msg) => { + if (msg.peer !== this.peer) { + return; + } + if (msg.type === 'edit') { + this.edit(); + + } else if (msg.type == 'delete') { + this.delete(); + } + }); + + } + + edit() { + if (this.peer._edit) { + + // Submit the edit (True -> False) + const idx = this.server.peers.indexOf(this.peer); + this.serverAPI.editPeer(this.peer).subscribe((newPeer) => { + Object.keys(newPeer).forEach(k => { + this.server.peers[idx][k] = newPeer[k]; + }); + }); + + } else if (!this.peer._edit) { + this.peer._expand = true; + + // Open for edit. aka do nothing (False -> True + + } + + this.peer._edit = !this.peer._edit; + + } + + delete() { + const idx = this.server.peers.indexOf(this.peer); + this.serverAPI.deletePeer(this.peer).subscribe((apiServer) => { + this.server.peers.splice(idx, 1); + }); + } + + + + +} diff --git a/wg_dashboard_frontend/src/app/page/dashboard/server/server.component.html b/wg_dashboard_frontend/src/app/page/dashboard/server/server.component.html new file mode 100644 index 0000000..223c4f1 --- /dev/null +++ b/wg_dashboard_frontend/src/app/page/dashboard/server/server.component.html @@ -0,0 +1,148 @@ + + + + + + + check_circle + {{server.interface}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + Endpoint: {{server.endpoint}}:{{server.listen_port}} - Address Space: {{server.address}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameAddressPublic-KeyTotal tx/rxHandshakeManage
+ check_circle + {{peer.name}}{{peer.address}}{{peer.public_key}}{{peer._stats?.tx || '0'}}/{{peer._stats?.rx || '0'}} {{peer._stats?.handshake || 'N/A'}} + + + + + + + + + + +
+ +
+ + + + +
+ + +
diff --git a/wg_dashboard_frontend/src/app/page/dashboard/server/server.component.scss b/wg_dashboard_frontend/src/app/page/dashboard/server/server.component.scss new file mode 100644 index 0000000..9aa55a2 --- /dev/null +++ b/wg_dashboard_frontend/src/app/page/dashboard/server/server.component.scss @@ -0,0 +1,13 @@ + +table { + width: 100%; +} + +:host { + width: 100%; +} + +.table-icon{ + font-size: 20px; +} + diff --git a/wg_dashboard_frontend/src/app/page/dashboard/server/server.component.ts b/wg_dashboard_frontend/src/app/page/dashboard/server/server.component.ts new file mode 100644 index 0000000..644d7c6 --- /dev/null +++ b/wg_dashboard_frontend/src/app/page/dashboard/server/server.component.ts @@ -0,0 +1,75 @@ +import { Component, EventEmitter, Input, OnInit, ViewEncapsulation } from '@angular/core'; +import { Server } from '../../../interfaces/server'; +import { ServerService } from '../../../services/server.service'; +import { DataService } from '../../../services/data.service'; +import { Peer } from '../../../interfaces/peer'; + +@Component({ + selector: 'app-server', + templateUrl: './server.component.html', + + styleUrls: ['./server.component.scss', '../dashboard.component.css'], +}) +export class ServerComponent implements OnInit { + @Input() server: Server; + @Input() servers: Server[]; + public editPeerEmitter: EventEmitter = new EventEmitter(); + + selectedPeer: Peer | null; + + constructor(private serverAPI: ServerService, private comm: DataService) { } + + ngOnInit(): void { + console.log('Server'); + } + + edit() { + + this.comm.emit('server-edit', this.server); + } + + stop() { + this.serverAPI.stopServer(this.server).subscribe((apiServer) => { + this.server.is_running = apiServer.is_running; + }); + } + + start() { + this.serverAPI.startServer(this.server).subscribe((apiServer) => { + this.server.is_running = apiServer.is_running; + }); + } + + addPeer() { + this.serverAPI.addPeer({ + server_interface: this.server.interface + }).subscribe((peer) => { + this.server.peers.push(peer); + }); + } + + restart() { + this.serverAPI.restartServer(this.server).subscribe((apiServer) => { + this.server.is_running = apiServer.is_running; + }); + } + + delete() { + const index = this.servers.indexOf(this.server); + this.serverAPI.deleteServer(this.server).subscribe((apiServer) => { + this.servers.splice(index, 1); + }); + } + + openPeer(peer: Peer) { + if (this.selectedPeer == peer) { + this.selectedPeer = null; + return; + } + this.selectedPeer = peer; + this.editPeerEmitter.emit({ type: 'open', peer }); + } + pInt(string: string) { + return parseInt(string); + } +} diff --git a/wg_dashboard_frontend/src/app/page/dashboard2/dashboard2.component.css b/wg_dashboard_frontend/src/app/page/dashboard2/dashboard2.component.css deleted file mode 100644 index 2256f10..0000000 --- a/wg_dashboard_frontend/src/app/page/dashboard2/dashboard2.component.css +++ /dev/null @@ -1,18 +0,0 @@ -.grid-container { - margin: 20px; -} - -.dashboard-card { - position: absolute; - top: 15px; - left: 15px; - right: 15px; - bottom: 15px; -} - -.more-button { - position: absolute; - top: 5px; - right: 10px; -} - diff --git a/wg_dashboard_frontend/src/app/page/dashboard2/dashboard2.component.spec.ts b/wg_dashboard_frontend/src/app/page/dashboard2/dashboard2.component.spec.ts deleted file mode 100644 index d61715d..0000000 --- a/wg_dashboard_frontend/src/app/page/dashboard2/dashboard2.component.spec.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { LayoutModule } from '@angular/cdk/layout'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { MatButtonModule } from '@angular/material/button'; -import { MatCardModule } from '@angular/material/card'; -import { MatGridListModule } from '@angular/material/grid-list'; -import { MatIconModule } from '@angular/material/icon'; -import { MatMenuModule } from '@angular/material/menu'; - -import { Dashboard2Component } from './dashboard2.component'; - -describe('Dashboard2Component', () => { - let component: Dashboard2Component; - let fixture: ComponentFixture; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [Dashboard2Component], - imports: [ - NoopAnimationsModule, - LayoutModule, - MatButtonModule, - MatCardModule, - MatGridListModule, - MatIconModule, - MatMenuModule, - ] - }).compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(Dashboard2Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should compile', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/wg_dashboard_frontend/src/app/page/dashboard2/dashboard2.component.ts b/wg_dashboard_frontend/src/app/page/dashboard2/dashboard2.component.ts deleted file mode 100644 index 9504b79..0000000 --- a/wg_dashboard_frontend/src/app/page/dashboard2/dashboard2.component.ts +++ /dev/null @@ -1,44 +0,0 @@ -import {Component, OnInit} from '@angular/core'; -import { map } from 'rxjs/operators'; -import { Breakpoints, BreakpointObserver } from '@angular/cdk/layout'; -import {Server} from "../../interfaces/server"; -import {ServerService} from "../../services/server.service"; -import {Peer} from "../../interfaces/peer"; - -@Component({ - selector: 'dashboard2', - templateUrl: './dashboard2.component.html', - styleUrls: ['./dashboard2.component.css'] -}) -export class Dashboard2Component implements OnInit -{ - servers: Array = []; - - constructor(private breakpointObserver: BreakpointObserver, private serverAPI: ServerService) { - - } - - - ngOnInit(): void { - this.serverAPI.getServers() - .subscribe( (servers: Array) => { - this.servers.push(...servers); - servers.forEach((server) => { - - this.serverAPI.serverStats(server).subscribe((stats: Peer[]) => { - stats.forEach( item => { - const peer = server.peers.find(x => x.public_key == item.public_key); - peer._stats = item - }); - - - }); - - - }); - - - }) - } - -} diff --git a/wg_dashboard_frontend/src/app/page/dashboard2/dashboard2.module.ts b/wg_dashboard_frontend/src/app/page/dashboard2/dashboard2.module.ts deleted file mode 100644 index 37bd4f9..0000000 --- a/wg_dashboard_frontend/src/app/page/dashboard2/dashboard2.module.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import {Dashboard2Component} from "./dashboard2.component"; -import {MatGridListModule} from "@angular/material/grid-list"; -import {MatCardModule} from "@angular/material/card"; -import {MatMenuModule} from "@angular/material/menu"; -import {MatIconModule} from "@angular/material/icon"; -import {MatButtonModule} from "@angular/material/button"; -import {ServerComponent} from "./server/server.component"; -import {MatExpansionModule} from "@angular/material/expansion"; -import {AddServerComponent} from "./add-server/add-server.component"; -import {MatFormFieldModule} from "@angular/material/form-field"; -import {MatInputModule} from "@angular/material/input"; -import {FormsModule, ReactiveFormsModule} from "@angular/forms"; -import {ComponentsModule} from "../components"; -import {FlexModule} from "@angular/flex-layout"; -import {MatTableModule} from "@angular/material/table"; -import {PeerComponent} from "./peer/peer.component"; -import {QRCodeModule} from "angularx-qrcode"; - - - -@NgModule({ - declarations: [ - Dashboard2Component, - ServerComponent, - AddServerComponent, - PeerComponent - ], - imports: [ - CommonModule, - MatGridListModule, - MatCardModule, - MatMenuModule, - MatIconModule, - MatButtonModule, - MatExpansionModule, - MatFormFieldModule, - MatInputModule, - ReactiveFormsModule, - ComponentsModule, - FlexModule, - MatTableModule, - FormsModule, - QRCodeModule, - - ] -}) -export class Dashboard2Module { } diff --git a/wg_dashboard_frontend/src/app/page/dashboard2/peer/peer.component.ts b/wg_dashboard_frontend/src/app/page/dashboard2/peer/peer.component.ts deleted file mode 100644 index 91f709f..0000000 --- a/wg_dashboard_frontend/src/app/page/dashboard2/peer/peer.component.ts +++ /dev/null @@ -1,84 +0,0 @@ -import {Component, EventEmitter, Input, OnInit, ViewEncapsulation} from '@angular/core'; -import {ServerService} from "../../../services/server.service"; -import {Peer} from "../../../interfaces/peer"; -import {Server} from "../../../interfaces/server"; -import {FormControl, FormGroup} from "@angular/forms"; - -@Component({ - selector: 'app-peer', - templateUrl: './peer.component.html', - encapsulation: ViewEncapsulation.None, - styleUrls: ['./peer.component.scss'], -}) -export class PeerComponent implements OnInit { - - @Input("peer") peer: Peer; - @Input("server") server: Server; - @Input("selectedPeer") selectedPeer: Peer; - @Input("onEvent") editPeerEmitter: EventEmitter = new EventEmitter(); - - - - config: string = "Loading..."; - - - constructor(public serverAPI: ServerService) { } - - ngOnInit(): void { - - this.editPeerEmitter.subscribe( (msg) => { - if(msg.peer !== this.peer){ - return; - } - if(msg.type === "edit"){ - this.edit(); - - }else if(msg.type == "delete"){ - this.delete(); - }else if(msg.type == "open"){ - this.fetchConfig(); - } - }) - - } - - edit(){ - if(this.peer._edit) { - - // Submit the edit (True -> False) - const idx = this.server.peers.indexOf(this.peer); - this.serverAPI.editPeer(this.peer).subscribe((newPeer) => { - Object.keys(newPeer).forEach(k => { - this.server.peers[idx][k] = newPeer[k]; - }); - }); - - } else if(!this.peer._edit) { - this.peer._expand = true; - - // Open for edit. aka do nothing (False -> True - - } - - this.peer._edit = !this.peer._edit; - - - } - - delete(){ - const idx = this.server.peers.indexOf(this.peer); - this.serverAPI.deletePeer(this.peer).subscribe((apiServer) => { - this.server.peers.splice(idx, 1); - }) - } - - fetchConfig() { - this.serverAPI.peerConfig(this.peer).subscribe((config: any) => { - this.config = config.config - }) - } - - pInt(string: string) { - return parseInt(string) - } -} diff --git a/wg_dashboard_frontend/src/app/page/dashboard2/server/server.component.html b/wg_dashboard_frontend/src/app/page/dashboard2/server/server.component.html deleted file mode 100644 index 20a4ddd..0000000 --- a/wg_dashboard_frontend/src/app/page/dashboard2/server/server.component.html +++ /dev/null @@ -1,248 +0,0 @@ - - - - - {{server.interface}} - - - - - check_circle - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {{server.address}} @ {{server.endpoint}} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameAddressPublic-KeyTotal tx/rxHandshakeManage
{{peer.name}}{{peer.address}}{{peer.public_key}}{{peer._stats?.tx || '0'}}/{{peer._stats?.rx || '0'}}{{peer._stats?.handshake || 'N/A'}} - - - - - - - - - - -
- -
- - - - -
- - -
- - - - - - diff --git a/wg_dashboard_frontend/src/app/page/dashboard2/server/server.component.scss b/wg_dashboard_frontend/src/app/page/dashboard2/server/server.component.scss deleted file mode 100644 index 355625a..0000000 --- a/wg_dashboard_frontend/src/app/page/dashboard2/server/server.component.scss +++ /dev/null @@ -1,28 +0,0 @@ - -table { - width: 100%; -} - -tr.example-detail-row { - height: 0 !important; -} - -tr.example-element-row:not(.example-expanded-row):hover { - background: whitesmoke; -} - -tr.example-element-row:not(.example-expanded-row):active { - background: #efefef; -} - -.example-element-row td { - border-bottom-width: 0; -} - -.example-element-detail { - overflow: hidden; - display: flex; -} - - - diff --git a/wg_dashboard_frontend/src/app/page/dashboard2/server/server.component.ts b/wg_dashboard_frontend/src/app/page/dashboard2/server/server.component.ts deleted file mode 100644 index b67a944..0000000 --- a/wg_dashboard_frontend/src/app/page/dashboard2/server/server.component.ts +++ /dev/null @@ -1,77 +0,0 @@ -import {Component, EventEmitter, Input, OnInit, ViewEncapsulation} from '@angular/core'; -import {Server} from "../../../interfaces/server"; -import {ServerService} from "../../../services/server.service"; -import {DataService} from "../../../services/data.service"; -import {Peer} from "../../../interfaces/peer"; - - -@Component({ - selector: 'app-server', - templateUrl: './server.component.html', - encapsulation: ViewEncapsulation.None, - styleUrls: ['./server.component.scss', '../dashboard2.component.css'], -}) -export class ServerComponent implements OnInit { - @Input() server: Server; - @Input() servers: Array; - public editPeerEmitter: EventEmitter = new EventEmitter(); - - serverConfig: string; - - selectedPeer: Peer | null; - - constructor(private serverAPI: ServerService, private comm: DataService) { } - - ngOnInit(): void { - console.log("Server"); - - this.serverAPI.serverConfig(this.server).subscribe((x: any) => this.serverConfig = x.config) - - } - - edit(){ - - this.comm.emit('server-edit', this.server); - } - - stop() { - this.serverAPI.stopServer(this.server).subscribe((apiServer) => { - this.server.is_running = apiServer.is_running - }) - } - - start() { - this.serverAPI.startServer(this.server).subscribe((apiServer) => { - this.server.is_running = apiServer.is_running - }) - } - - addPeer() { - this.serverAPI.addPeer(this.server).subscribe((peer) => { - this.server.peers.push(peer) - }) - } - - restart() { - this.serverAPI.restartServer(this.server).subscribe((apiServer) => { - this.server.is_running = apiServer.is_running - }) - } - - - delete() { - const index = this.servers.indexOf(this.server); - this.serverAPI.deleteServer(this.server).subscribe((apiServer) => { - this.servers.splice(index, 1); - }) - } - - openPeer(peer: Peer) { - if(this.selectedPeer == peer){ - this.selectedPeer = null; - return - } - this.selectedPeer = peer; - this.editPeerEmitter.emit({type: 'open', peer: peer}); - } -} diff --git a/wg_dashboard_frontend/src/app/page/page-routing.module.ts b/wg_dashboard_frontend/src/app/page/page-routing.module.ts index d56f4a4..6e4bb68 100644 --- a/wg_dashboard_frontend/src/app/page/page-routing.module.ts +++ b/wg_dashboard_frontend/src/app/page/page-routing.module.ts @@ -1,32 +1,29 @@ import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; -import {Dashboard2Component} from "./dashboard2/dashboard2.component"; -import {LayoutComponent} from "../layout/layout/layout.component"; -import {ErrorComponent} from "./error"; -import {LoginComponent} from "./user/login/login.component"; -import {AuthGuard} from "@services/*"; - - - +import { DashboardComponent } from './dashboard/dashboard.component'; +import { LayoutComponent } from '../layout/layout/layout.component'; +import { ErrorComponent } from './error'; +import { LoginComponent } from './user/login/login.component'; +import { AuthGuard } from '@services/*'; +import { EditComponent } from './user/edit/edit.component'; const routes: Routes = [ { path: '', component: LayoutComponent, children: - [ - //{ path: 'dashboard', component: DashboardComponent, pathMatch: 'full', canActivate: [AuthGuard]}, - { path: 'dashboard', component: Dashboard2Component, pathMatch: 'full', canActivate: [AuthGuard]}, + [ + { path: 'dashboard', component: DashboardComponent, pathMatch: 'full', canActivate: [AuthGuard] }, { path: '404', component: ErrorComponent, pathMatch: 'full' }, - ] + ], }, { path: 'user', component: LayoutComponent, children: - [ - //{ path: 'dashboard', component: DashboardComponent, pathMatch: 'full', canActivate: [AuthGuard]}, - { path: 'login', component: LoginComponent, pathMatch: 'full'}, - ] + [ + { path: 'edit', component: EditComponent, pathMatch: 'full' }, + { path: 'login', component: LoginComponent, pathMatch: 'full' }, + ], }, ]; @NgModule({ imports: [RouterModule.forChild(routes)], - exports: [RouterModule] + exports: [RouterModule], }) export class PageRoutingModule { } diff --git a/wg_dashboard_frontend/src/app/page/page.module.ts b/wg_dashboard_frontend/src/app/page/page.module.ts index 06a19cf..f48a155 100644 --- a/wg_dashboard_frontend/src/app/page/page.module.ts +++ b/wg_dashboard_frontend/src/app/page/page.module.ts @@ -1,23 +1,27 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; -import {PageRoutingModule} from "./page-routing.module"; -import {Dashboard2Module} from "./dashboard2/dashboard2.module"; -import {LoginComponent} from "./user/login/login.component"; -import {MatCardModule} from "@angular/material/card"; -import {FormsModule, ReactiveFormsModule} from "@angular/forms"; -import {MatInputModule} from "@angular/material/input"; - +import { PageRoutingModule } from './page-routing.module'; +import { DashboardModule } from './dashboard/dashboard.module'; +import { LoginComponent } from './user/login/login.component'; +import { MatCardModule } from '@angular/material/card'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatInputModule } from '@angular/material/input'; +import { FlexModule } from '@angular/flex-layout'; +import { EditComponent } from './user/edit/edit.component'; +import { MatButtonModule } from '@angular/material/button'; @NgModule({ - declarations: [LoginComponent], + declarations: [LoginComponent, EditComponent], imports: [ CommonModule, PageRoutingModule, FormsModule, - Dashboard2Module, + DashboardModule, MatCardModule, ReactiveFormsModule, MatInputModule, + FlexModule, + MatButtonModule, ], }) diff --git a/wg_dashboard_frontend/src/app/page/user/edit/edit.component.html b/wg_dashboard_frontend/src/app/page/user/edit/edit.component.html index 6e2720c..dc50960 100644 --- a/wg_dashboard_frontend/src/app/page/user/edit/edit.component.html +++ b/wg_dashboard_frontend/src/app/page/user/edit/edit.component.html @@ -1,48 +1,55 @@ -
+
+
- - -

Edit User

-
- - -
+ + + Edit User + -
-
- - -
+ + +

+ + Full Name + + +

-
- - -
+

+ + Username + + +

-
- - -
+

+ + E-Mail + + +

-
- - -
+

+ + Password + + +

-
+ - + + +
+
- +
- - -
diff --git a/wg_dashboard_frontend/src/app/page/user/edit/edit.component.ts b/wg_dashboard_frontend/src/app/page/user/edit/edit.component.ts index 5cd430a..aef49ba 100644 --- a/wg_dashboard_frontend/src/app/page/user/edit/edit.component.ts +++ b/wg_dashboard_frontend/src/app/page/user/edit/edit.component.ts @@ -1,12 +1,12 @@ import { Component, OnInit } from '@angular/core'; -import {FormControl, FormGroup, Validators} from "@angular/forms"; -import {AuthService} from "@services/*"; -import {Router} from "@angular/router"; +import { FormControl, FormGroup, Validators } from '@angular/forms'; +import { AuthService } from '@services/*'; +import { Router } from '@angular/router'; @Component({ selector: 'app-edit', templateUrl: './edit.component.html', - styleUrls: ['./edit.component.scss'] + styleUrls: ['./edit.component.scss'], }) export class EditComponent implements OnInit { @@ -31,20 +31,19 @@ export class EditComponent implements OnInit { public ngOnInit() { this.user = this.authService.user; - this.editForm.setValue({ full_name: this.user.full_name, - password: "", + password: '', email: this.user.email, - username: this.user.username - }) + username: this.user.username, + }); } public edit() { if (this.editForm.valid) { this.authService.edit(this.editForm.getRawValue()) .subscribe(res => this.router.navigate(['/app/dashboard']), - error => this.error = error.message); + error => this.error = error.message); } } diff --git a/wg_dashboard_frontend/src/app/page/user/login/login.component.html b/wg_dashboard_frontend/src/app/page/user/login/login.component.html index f3861fa..fa5173b 100644 --- a/wg_dashboard_frontend/src/app/page/user/login/login.component.html +++ b/wg_dashboard_frontend/src/app/page/user/login/login.component.html @@ -1,40 +1,42 @@ +
+
+ + + Authenticate to Wireguard Management + - - - Authenticate to Wireguard Management - + +
- - +

+ + Username + + +

-

- - Username - - -

+

+ + Password + + +

-

- - Password - - -

+ - + +
+
+
+
- - - - - diff --git a/wg_dashboard_frontend/src/app/page/user/login/login.component.ts b/wg_dashboard_frontend/src/app/page/user/login/login.component.ts index b2ff96a..9b518ef 100644 --- a/wg_dashboard_frontend/src/app/page/user/login/login.component.ts +++ b/wg_dashboard_frontend/src/app/page/user/login/login.component.ts @@ -1,12 +1,13 @@ -import { Component, OnInit } from '@angular/core'; -import {FormBuilder, FormControl, FormGroup, Validators} from "@angular/forms"; -import {AuthService} from "@services/*"; -import {Router} from "@angular/router"; +import { Component, OnInit, ViewEncapsulation } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; +import { AuthService } from '@services/*'; +import { Router } from '@angular/router'; @Component({ selector: 'app-login', templateUrl: './login.component.html', - styleUrls: ['./login.component.scss'] + encapsulation: ViewEncapsulation.None, + styleUrls: ['./login.component.scss'], }) export class LoginComponent implements OnInit { @@ -19,7 +20,6 @@ export class LoginComponent implements OnInit { private fb: FormBuilder, private router: Router) { - this.loginForm = this.fb.group({ password: new FormControl('', Validators.required), username: new FormControl('', [ @@ -31,7 +31,7 @@ export class LoginComponent implements OnInit { } public ngOnInit() { - this.authService.logout(); + this.loginForm.valueChanges.subscribe(() => { this.error = null; }); @@ -42,7 +42,7 @@ export class LoginComponent implements OnInit { if (this.loginForm.valid) { this.authService.login(this.loginForm.getRawValue()) .subscribe(res => this.router.navigate(['/page/dashboard']), - error => this.error = error.message); + error => this.error = error.message); } } diff --git a/wg_dashboard_frontend/src/app/services/auth/auth.interceptor.ts b/wg_dashboard_frontend/src/app/services/auth/auth.interceptor.ts index 4937c4c..f19904f 100644 --- a/wg_dashboard_frontend/src/app/services/auth/auth.interceptor.ts +++ b/wg_dashboard_frontend/src/app/services/auth/auth.interceptor.ts @@ -10,8 +10,8 @@ import { } from '@angular/common/http'; import { AuthService } from './auth.service'; -import {tap} from "rxjs/operators"; -import {Router} from "@angular/router"; +import { tap } from 'rxjs/operators'; +import { Router } from '@angular/router'; @Injectable() export class AuthInterceptor implements HttpInterceptor { @@ -21,13 +21,13 @@ export class AuthInterceptor implements HttpInterceptor { // add authorization token for full api requests if (request.url.includes('api') && this.auth.isLoggedIn) { request = request.clone({ - setHeaders: { Authorization: `Bearer ${this.auth.user.access_token}`}, + setHeaders: { Authorization: `Bearer ${this.auth.user.access_token}` }, }); } - return next.handle(request).pipe( tap(() => {}, - (err: any) => { - if (err instanceof HttpErrorResponse) { + return next.handle(request).pipe(tap(() => {}, + (err: any) => { + if (err instanceof HttpErrorResponse) { if (err.status !== 401 && err.status !== 403) { return; } @@ -35,6 +35,6 @@ export class AuthInterceptor implements HttpInterceptor { this.auth.clearData(); this.router.navigate(['/page/user/login']); } - })); + })); } } diff --git a/wg_dashboard_frontend/src/app/services/auth/auth.service.ts b/wg_dashboard_frontend/src/app/services/auth/auth.service.ts index c966c0f..a141c00 100644 --- a/wg_dashboard_frontend/src/app/services/auth/auth.service.ts +++ b/wg_dashboard_frontend/src/app/services/auth/auth.service.ts @@ -4,7 +4,8 @@ import { BehaviorSubject, Observable, of } from 'rxjs'; import { map } from 'rxjs/operators'; import { environment } from '../../../environments/environment'; -import {User} from "../../interfaces/user"; +import { User } from '../../interfaces/user'; +import { Router } from '@angular/router'; const tokenName = 'token'; @@ -14,21 +15,20 @@ const tokenName = 'token'; export class AuthService { public user: User = null; - private url = `${environment.apiBaseUrl}/api`; + private url = `${environment.apiBaseUrl}/api/v1`; - constructor(private http: HttpClient) {} + constructor(private http: HttpClient, private router: Router) {} public get isLoggedIn(): boolean { - return !!this.user?.access_token + return !!this.user?.access_token; } public login(data): Observable { // Create form - let formData: FormData = new FormData(); + const formData: FormData = new FormData(); formData.append('username', data.username); formData.append('password', data.password); - return this.http.post(`${this.url}/login`, formData) .pipe( map((res: any) => { @@ -36,18 +36,18 @@ export class AuthService { })); } - public edit(formData: any){ + public edit(formData: any) { return this.http.post(`${this.url}/user/edit`, formData) .pipe(map((res: any) => { this._handleUser(res); })); } - _handleUser(res: any){ + _handleUser(res: any) { const user: any = res.user; user.access_token = res.access_token; user.token_type = res.token_type; - localStorage.setItem("session", JSON.stringify(user)); + localStorage.setItem('session', JSON.stringify(user)); this.init(); } @@ -55,12 +55,12 @@ export class AuthService { return this.http.get(`${this.url}/logout`) .pipe(map((data) => { this.clearData(); + this.router.navigate(['/page/user/login']); return of(false); })); } - - public clearData(){ + public clearData() { this.user = null; localStorage.clear(); @@ -70,7 +70,6 @@ export class AuthService { return localStorage.getItem(tokenName); } - public init() { this.user = JSON.parse(localStorage.getItem('session')); } diff --git a/wg_dashboard_frontend/src/app/services/config.service.ts b/wg_dashboard_frontend/src/app/services/config.service.ts index 1e42620..a3fbab9 100644 --- a/wg_dashboard_frontend/src/app/services/config.service.ts +++ b/wg_dashboard_frontend/src/app/services/config.service.ts @@ -1,13 +1,13 @@ import { Injectable } from '@angular/core'; -import {HttpErrorResponse} from "@angular/common/http"; -import {throwError} from "rxjs"; +import { HttpErrorResponse } from '@angular/common/http'; +import { throwError } from 'rxjs'; @Injectable({ - providedIn: 'root' + providedIn: 'root', }) export class ConfigService { - public applicationName = "Wireguard Manager"; + public applicationName = 'Wireguard Manager'; constructor() { } @@ -25,5 +25,5 @@ export class ConfigService { // return an observable with a user-facing error message return throwError( 'Something bad happened; please try again later.'); - }; + } } diff --git a/wg_dashboard_frontend/src/app/services/data.service.ts b/wg_dashboard_frontend/src/app/services/data.service.ts index 99fc10d..ccd8dfb 100644 --- a/wg_dashboard_frontend/src/app/services/data.service.ts +++ b/wg_dashboard_frontend/src/app/services/data.service.ts @@ -1,28 +1,26 @@ -import {EventEmitter, Injectable} from '@angular/core'; -import {Observable} from "rxjs"; - +import { EventEmitter, Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; @Injectable({ - providedIn: 'root' + providedIn: 'root', }) export class DataService { _observables: any = {}; constructor() {} - - emit(event: string, value: any): void{ - if(this._observables.hasOwnProperty(event)) { - this._observables[event].emit(value) + emit(event: string, value: any): void { + if (this._observables.hasOwnProperty(event)) { + this._observables[event].emit(value); } } on(event: string): Observable { - if(!this._observables.hasOwnProperty(event)) { - this._observables[event] = new EventEmitter() + if (!this._observables.hasOwnProperty(event)) { + this._observables[event] = new EventEmitter(); } - return this._observables[event].asObservable() + return this._observables[event].asObservable(); } } diff --git a/wg_dashboard_frontend/src/app/services/server.service.ts b/wg_dashboard_frontend/src/app/services/server.service.ts index 5b48eed..b4bb038 100644 --- a/wg_dashboard_frontend/src/app/services/server.service.ts +++ b/wg_dashboard_frontend/src/app/services/server.service.ts @@ -1,93 +1,93 @@ import { Injectable } from '@angular/core'; -import {ConfigService} from "./config.service"; -import {HttpClient} from "@angular/common/http"; +import { ConfigService } from './config.service'; +import { HttpClient } from '@angular/common/http'; -import {catchError} from "rxjs/operators"; -import {Server} from "../interfaces/server"; -import {Peer} from "../interfaces/peer"; -import {Observable, Subscribable} from "rxjs"; +import { catchError } from 'rxjs/operators'; +import { Server } from '../interfaces/server'; +import { Peer } from '../interfaces/peer'; +import { Observable, Subscribable } from 'rxjs'; @Injectable({ - providedIn: 'root' + providedIn: 'root', }) export class ServerService { - public_url_wg: string = "/api/wg"; - public url: string = this.public_url_wg + "/server"; - constructor(private config: ConfigService, private http: HttpClient) { + public base = '/api/v1/'; + public serverURL = this.base + "server"; + public peerURL = this.base + "peer"; + public wgURL = this.base + "wg"; + constructor(private config: ConfigService, private http: HttpClient) { } - public deletePeer(peer: Peer): Subscribable{ - return this.http.post(this.url + "/peer/delete", peer) + public deletePeer(peer: Peer): Subscribable { + return this.http.post(this.peerURL + '/delete', peer); } - public serverPerformAction(action: string, item: any): Subscribable { - return this.http.post(this.url + "/" + action, item) - .pipe(catchError(this.config.handleError.bind(this))) + return this.http.post(this.serverURL + '/' + action, item) + .pipe(catchError(this.config.handleError.bind(this))); } - public addPeer(server: Server): Subscribable{ - return this.http.post(this.url + "/peer/add", server) + public addPeer(server_interface: any): Subscribable { + return this.http.post(this.peerURL + '/add', server_interface); } - public editPeer(peer: Peer): Subscribable{ - return this.http.post(this.url + "/peer/edit", peer) + public editPeer(peer: Peer): Subscribable { + return this.http.post(this.peerURL + '/edit', peer); } - public getServers(): Observable>{ - return this.http.get>(this.url + "/all") - .pipe(catchError(this.config.handleError.bind(this))) + public getServers(): Observable { + return this.http.get(this.serverURL + '/all') + .pipe(catchError(this.config.handleError.bind(this))); } - public addServer(item: Server): Subscribable { - return this.http.post(this.url + "/add", item) - .pipe(catchError(this.config.handleError.bind(this))) + return this.http.post(this.serverURL + '/add', item) + .pipe(catchError(this.config.handleError.bind(this))); } public startServer(item: Server): Subscribable { - return this.serverPerformAction("start", item) + return this.serverPerformAction('start', item); } public stopServer(item: Server): Subscribable { - return this.serverPerformAction("stop", item) + return this.serverPerformAction('stop', item); } public restartServer(item: Server): Subscribable { - return this.serverPerformAction("restart", item) + return this.serverPerformAction('restart', item); } public deleteServer(item: Server): Subscribable { - return this.serverPerformAction("delete", item) + return this.serverPerformAction('delete', item); } public editServer(oldServer: Server, newServer: Server): Subscribable { - return this.serverPerformAction("edit", { - "interface": oldServer.interface, - "server": newServer - }) + return this.serverPerformAction('edit', { + interface: oldServer.interface, + server: newServer, + }); } public getKeyPair() { - return this.http.get(this.public_url_wg + "/generate_keypair") + return this.http.get(this.wgURL + '/generate_keypair'); } public getPSK() { - return this.http.get(this.public_url_wg + "/generate_psk") + return this.http.get(this.wgURL + '/generate_psk'); } public peerConfig(peer: Peer) { - return this.http.post(this.public_url_wg + "/server/peer/config", peer) + return this.http.post(this.peerURL + '/config', peer); } public serverConfig(server: Server) { - return this.http.post(this.url + "/config", server) + return this.http.post(this.serverURL + '/config', server); } public serverStats(server: Server) { - return this.http.post(this.url + "/stats", server) + return this.http.post(this.serverURL + '/stats', server); } } diff --git a/wg_dashboard_frontend/src/app/validators/ip-address.validator.ts b/wg_dashboard_frontend/src/app/validators/ip-address.validator.ts index 29c8131..00bd47c 100644 --- a/wg_dashboard_frontend/src/app/validators/ip-address.validator.ts +++ b/wg_dashboard_frontend/src/app/validators/ip-address.validator.ts @@ -1,11 +1,11 @@ import { AbstractControl, ValidationErrors } from '@angular/forms'; -import * as IPCIDR from "ip-cidr"; +import * as IPCIDR from 'ip-cidr'; export class IPValidator { - static isIPAddress(control: AbstractControl) : ValidationErrors | null { - if(!control.value || !(new IPCIDR(control.value).isValid()) || !control.value.includes("/")){ - return {validIP: true} + static isIPAddress(control: AbstractControl): ValidationErrors | null { + if (!control.value || !(new IPCIDR(control.value).isValid()) || !control.value.includes('/')) { + return { validIP: true }; } return null; } diff --git a/wg_dashboard_frontend/src/app/validators/number.validator.ts b/wg_dashboard_frontend/src/app/validators/number.validator.ts index 8e6f28b..98bc65f 100644 --- a/wg_dashboard_frontend/src/app/validators/number.validator.ts +++ b/wg_dashboard_frontend/src/app/validators/number.validator.ts @@ -1,11 +1,11 @@ import { AbstractControl, ValidationErrors } from '@angular/forms'; -import * as IPCIDR from "ip-cidr"; +import * as IPCIDR from 'ip-cidr'; export class NumberValidator { - static stringIsNumber(control: AbstractControl) : ValidationErrors | null { - if(isNaN(control.value)){ - return {validNumber: true} + static stringIsNumber(control: AbstractControl): ValidationErrors | null { + if (isNaN(control.value)) { + return { validNumber: true }; } return null; } diff --git a/wg_dashboard_frontend/src/main.ts b/wg_dashboard_frontend/src/main.ts index 2081283..0951b35 100644 --- a/wg_dashboard_frontend/src/main.ts +++ b/wg_dashboard_frontend/src/main.ts @@ -1,10 +1,23 @@ import { enableProdMode, ViewEncapsulation } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; -import { AppModule } from './app/app.module'; +import { AppModule } from './app'; import { environment } from './environments/environment'; import 'hammerjs'; +(function () { + if (typeof EventTarget !== 'undefined') { + const func = EventTarget.prototype.addEventListener; + EventTarget.prototype.addEventListener = function (type, fn, capture) { + this.func = func; + if (typeof capture !== 'boolean') { + capture = capture || {}; + capture.passive = false; + } + this.func(type, fn, capture); + }; + } +}()); if (environment.production) { enableProdMode(); } diff --git a/wg_dashboard_frontend/src/polyfills.ts b/wg_dashboard_frontend/src/polyfills.ts index 4a19eaf..1296de3 100644 --- a/wg_dashboard_frontend/src/polyfills.ts +++ b/wg_dashboard_frontend/src/polyfills.ts @@ -22,18 +22,17 @@ import '@angular/localize/init'; * BROWSER POLYFILLS */ - /** IE10 and IE11 requires the following for NgClass support on SVG elements */ import 'classlist.js'; // Run `npm install --save classlist.js`. /** IE10 and IE11 requires the following for the Reflect API. */ -//import 'core-js/es6/reflect'; +// import 'core-js/es6/reflect'; /** * Evergreen browsers require these. */ // Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove. -//import 'core-js/es7/reflect'; +// import 'core-js/es7/reflect'; /** * Required to support Web Animations `@angular/platform-browser/animations`. diff --git a/wg_dashboard_frontend/src/theme/styles.scss b/wg_dashboard_frontend/src/theme/styles.scss index dc13c69..2a32a31 100644 --- a/wg_dashboard_frontend/src/theme/styles.scss +++ b/wg_dashboard_frontend/src/theme/styles.scss @@ -1,13 +1,80 @@ @import "./fonts/font-roboto.css"; $material-icons-font-path: '~material-icons/iconfont/'; @import '~material-icons/iconfont/material-icons.scss'; -@import "~material-design-lite/material.css"; +@import '~@angular/material/theming'; + +@include mat-core(); + +// Add your desired themes to this map. +$themes-map: ( + indigo-pink: ( + primary-base: $mat-indigo, + accent-base: $mat-pink, + ), + + deeppurple-amber: ( + primary-base: $mat-deep-purple, + accent-base: $mat-amber, + ), + + pink-bluegrey: ( + primary-base: $mat-pink, + accent-base: $mat-blue-gray, + ), + + purple-green: ( + primary-base: $mat-purple, + accent-base: $mat-green, + ), +); + + +// Import the module and do the job: +@import '~angular-material-dynamic-themes/themes-core'; +@include make-stylesheets($themes-map); + //html, body { height: 100%; } //body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; } -html, body { +html, +body { box-sizing: border-box; height: 100%; margin: 0; } + +.full-width { + width: 100%; +} + +.app-material-icon-valign { + display: inline-flex; + vertical-align: middle; +} + +.mat-card-header-text{ + width: 100% !important; +} + +.button-row button, +.button-row a{ + margin-right: 8px; +} + +.card-container-right{ + display: inline; + float: right; +} + +.card-container-left{ + display: inline !important; +} + +.green{ + color:green;; + +} +.red{ + color:red; +} diff --git a/wg_dashboard_frontend/src/theme/theme.module.ts b/wg_dashboard_frontend/src/theme/theme.module.ts index c7f5ad0..c3e3999 100644 --- a/wg_dashboard_frontend/src/theme/theme.module.ts +++ b/wg_dashboard_frontend/src/theme/theme.module.ts @@ -2,7 +2,6 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; - const BASE_COMPONENTS = [ ]; diff --git a/wg_dashboard_frontend/src/tsconfig.app.json b/wg_dashboard_frontend/src/tsconfig.app.json index 173c40f..2e7a5b2 100644 --- a/wg_dashboard_frontend/src/tsconfig.app.json +++ b/wg_dashboard_frontend/src/tsconfig.app.json @@ -3,7 +3,7 @@ "compilerOptions": { "outDir": "../out-tsc/app", "baseUrl": "./", - "types": ["d3", "nvd3", "material-design-lite"] + "types": [] }, "files": [ "main.ts", diff --git a/wg_dashboard_frontend/src/typings.d.ts b/wg_dashboard_frontend/src/typings.d.ts index 365a498..ef5c7bd 100644 --- a/wg_dashboard_frontend/src/typings.d.ts +++ b/wg_dashboard_frontend/src/typings.d.ts @@ -3,7 +3,3 @@ declare var module: NodeModule; interface NodeModule { id: string; } - -declare var getmdlSelect: { - init: any; -};