From 7e6194dec043fb74fdb22a7fbde229f6873bf37b Mon Sep 17 00:00:00 2001 From: Adam Obuchowicz Date: Tue, 19 Nov 2019 09:48:04 +0100 Subject: [PATCH 01/19] Displaying first char - untested --- Cargo.toml | 2 + build-utilities/Cargo.toml | 8 +++ build-utilities/src/lib.rs | 28 ++++++++ lib/core/Cargo.toml | 22 +++--- lib/core/fonts-base/Cargo.toml | 17 +++++ lib/core/fonts-base/build.rs | 62 +++++++++++++++++ lib/core/fonts-base/src/lib.rs | 16 +++++ lib/core/msdf-sys/Cargo.toml | 4 +- lib/core/msdf-sys/build.rs | 86 +---------------------- lib/core/msdf-sys/src/lib.rs | 7 +- lib/core/src/font_base.rs | 13 ++++ lib/core/src/lib.rs | 2 + lib/core/src/text/mod.rs | 113 +++++++++++++++++++++++++++++++ lib/core/src/text/msdf_frag.glsl | 19 ++++++ lib/prelude/src/lib.rs | 1 + 15 files changed, 300 insertions(+), 100 deletions(-) create mode 100644 build-utilities/Cargo.toml create mode 100644 build-utilities/src/lib.rs create mode 100644 lib/core/fonts-base/Cargo.toml create mode 100644 lib/core/fonts-base/build.rs create mode 100644 lib/core/fonts-base/src/lib.rs create mode 100644 lib/core/src/font_base.rs create mode 100644 lib/core/src/text/mod.rs create mode 100644 lib/core/src/text/msdf_frag.glsl diff --git a/Cargo.toml b/Cargo.toml index f46a15ddfb..8ce7f8829d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,10 @@ [workspace] members = [ + "build-utilities", "lib/prelude", "lib/core", + "lib/core/fonts-base", "lib/core/msdf-sys", "lib/backend/webgl", "lib/system/web", diff --git a/build-utilities/Cargo.toml b/build-utilities/Cargo.toml new file mode 100644 index 0000000000..419fba0a61 --- /dev/null +++ b/build-utilities/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "basegl-build-utilities" +version = "0.1.0" +authors = ["Adam Obuchowicz "] +edition = "2018" + +[dependencies] +download-lp = "0.2.0" diff --git a/build-utilities/src/lib.rs b/build-utilities/src/lib.rs new file mode 100644 index 0000000000..140b5ac12c --- /dev/null +++ b/build-utilities/src/lib.rs @@ -0,0 +1,28 @@ +use std::{fs, path}; + +/// Download the release package from github +pub fn github_download( + project_url : &str, + version : &str, + filename : &str, + destination_dir : &path::Path +) { + let url = format!( + "{project}/releases/download/{version}/{filename}", + project = project_url, + version = version, + filename = filename + ); + + let destination_file = path::Path::new(destination_dir) + .join(filename); + + if destination_file.exists() { + fs::remove_file(&destination_file).unwrap(); + } + + download_lp::download( + url.as_str(), + destination_dir.to_str().unwrap() + ).unwrap(); +} diff --git a/lib/core/Cargo.toml b/lib/core/Cargo.toml index c76a5186ab..628b638f59 100644 --- a/lib/core/Cargo.toml +++ b/lib/core/Cargo.toml @@ -11,16 +11,18 @@ crate-type = ["rlib", "cdylib"] default = ["console_error_panic_hook"] [dependencies] -basegl-prelude = { version = "0.1.0" , path = "../prelude" } -basegl-system-web = { version = "0.1.0" , path = "../system/web" } -basegl-backend-webgl = { version = "0.1.0" , path = "../backend/webgl" } -wasm-bindgen = { version = "^0.2" , features = ["nightly"] } -js-sys = { version = "0.3.28" } -failure = { version = "0.1.5" } -derive_more = { version = "0.15.0" } -shrinkwraprs = { version = "0.2.1" } -itertools = { version = "0.8" } -nalgebra = { version = "0.18.1" } +basegl-prelude = { version = "0.1.0" , path = "../prelude" } +basegl-system-web = { version = "0.1.0" , path = "../system/web" } +basegl-backend-webgl = { version = "0.1.0" , path = "../backend/webgl" } +basegl-core-msdf-sys = { version = "0.1.0" , path = "msdf-sys" } +basegl-core-fonts-base = { version = "0.1.0" , path = "fonts-base" } +wasm-bindgen = { version = "^0.2" , features = ["nightly"] } +js-sys = { version = "0.3.28" } +failure = { version = "0.1.5" } +derive_more = { version = "0.15.0" } +shrinkwraprs = { version = "0.2.1" } +itertools = { version = "0.8" } +nalgebra = { version = "0.18.1" } # TODO: disable for release console_error_panic_hook = { version = "0.1.1", optional = true } diff --git a/lib/core/fonts-base/Cargo.toml b/lib/core/fonts-base/Cargo.toml new file mode 100644 index 0000000000..d2f0578042 --- /dev/null +++ b/lib/core/fonts-base/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "basegl-core-fonts-base" +version = "0.1.0" +authors = ["Adam Obuchowicz "] +edition = "2018" + +[lib] +crate-type = ["cdylib", "rlib"] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +basegl-prelude = { version = "0.1.0", path="../../prelude"} + +[build-dependencies] +basegl-build-utilities = { version = "0.1.0", path="../../../build-utilities" } +zip = "0.5" \ No newline at end of file diff --git a/lib/core/fonts-base/build.rs b/lib/core/fonts-base/build.rs new file mode 100644 index 0000000000..9ad9a26f50 --- /dev/null +++ b/lib/core/fonts-base/build.rs @@ -0,0 +1,62 @@ +use basegl_build_utilities::github_download; +use std::{path, env, fs}; +use std::io::Write; + +pub const PACKAGE_NAME : &str = "dejavu-fonts-ttf-2.37.zip"; +pub const VERSION : &str = "version_2_37"; +pub const PROJECT_URL : &str = + "https://github.com/dejavu-fonts/dejavu-fonts/"; +pub const PACKAGE_FONTS_PREFIX : &str = "dejavu-fonts-ttf-2.37/ttf"; +pub const FONTS_TO_EXTRACT : &[&str] = &[ + "DejaVuSansMono", + "DejaVuSansMono-Bold" +]; + +fn extract_dejavu_font(package_path : &path::Path, font_name : &str) { + let font_file = format!("{}.ttf", font_name); + let font_package_path = format!("{}/{}", + PACKAGE_FONTS_PREFIX, + font_file + ); + + let mut archive = zip::ZipArchive::new( + std::fs::File::open(package_path).unwrap() + ).unwrap(); + let mut input = archive.by_name( + font_package_path.as_str() + ).unwrap(); + let mut output = std::fs::File::create( + package_path.parent().unwrap().join(font_file) + ).unwrap(); + std::io::copy(&mut input, &mut output).unwrap(); +} + +fn main() { + let out = env::var("OUT_DIR").unwrap(); + let out_dir = path::Path::new(&out); + let package_path = out_dir.join(PACKAGE_NAME); + let fill_map_rs_path = out_dir.join("fill_map.rs"); + + github_download( + PROJECT_URL, + VERSION, + PACKAGE_NAME, + path::Path::new(&out_dir) + ); + + for font_name in FONTS_TO_EXTRACT { + extract_dejavu_font(package_path.as_path(), font_name); + } + + let mut fill_map_rs_file = fs::File::create(fill_map_rs_path).unwrap(); + writeln!(fill_map_rs_file, "{{").unwrap(); + for font_name in FONTS_TO_EXTRACT { + writeln!(fill_map_rs_file, + " fonts_by_name.insert(\"{}\", include_bytes!(\"{}.ttf\"));", + font_name, + font_name + ).unwrap(); + } + writeln!(fill_map_rs_file, "}}").unwrap(); + println!("cargo:rerun-if-changed=build.rs"); +} \ No newline at end of file diff --git a/lib/core/fonts-base/src/lib.rs b/lib/core/fonts-base/src/lib.rs new file mode 100644 index 0000000000..bffb695c57 --- /dev/null +++ b/lib/core/fonts-base/src/lib.rs @@ -0,0 +1,16 @@ +use basegl_prelude::*; + +pub struct FontsBase { + pub fonts_by_name : HashMap<&'static str, &'static [u8]> +} + +impl FontsBase { + pub fn new() -> FontsBase { + let mut fonts_by_name : HashMap<&'static str, &'static [u8]> + = HashMap::new(); + include!(concat!(env!("OUT_DIR"), "/fill_map.rs")); + FontsBase { + fonts_by_name + } + } +} \ No newline at end of file diff --git a/lib/core/msdf-sys/Cargo.toml b/lib/core/msdf-sys/Cargo.toml index dd6f26c5ad..90652b4b3e 100644 --- a/lib/core/msdf-sys/Cargo.toml +++ b/lib/core/msdf-sys/Cargo.toml @@ -14,7 +14,7 @@ vector2d = "2.2.0" [dev-dependencies] wasm-bindgen-test = "0.3.3" +basegl-core-fonts-base = { version = "0.1.0", path="../fonts-base" } [build-dependencies] -download-lp = "0.2.0" -zip = { version = "0.5" } \ No newline at end of file +basegl-build-utilities = { version = "0.1.0", path="../../../build-utilities" } \ No newline at end of file diff --git a/lib/core/msdf-sys/build.rs b/lib/core/msdf-sys/build.rs index 4faabb7064..6d4471af1c 100644 --- a/lib/core/msdf-sys/build.rs +++ b/lib/core/msdf-sys/build.rs @@ -1,33 +1,4 @@ -extern crate download_lp; - -use std::{fs, path}; - -/// Download the release package from github -pub fn github_download( - project_url : &str, - version : &str, - filename : &str, - destination_dir : &path::Path -) { - let url = format!( - "{project}/releases/download/{version}/{filename}", - project = project_url, - version = version, - filename = filename - ); - - let destination_file = path::Path::new(destination_dir) - .join(filename); - - if destination_file.exists() { - fs::remove_file(&destination_file).unwrap(); - } - - download_lp::download( - url.as_str(), - destination_dir.to_str().unwrap() - ).unwrap(); -} +use basegl_build_utilities::github_download; mod msdfgen_wasm { use crate::github_download; @@ -59,62 +30,7 @@ mod msdfgen_wasm { */ } -mod fonts { - use crate::github_download; - use std::{path, env}; - - pub const PACKAGE_NAME : &str = "dejavu-fonts-ttf-2.37.zip"; - pub const VERSION : &str = "version_2_37"; - pub const PROJECT_URL : &str = - "https://github.com/dejavu-fonts/dejavu-fonts/"; - pub const PACKAGE_FONTS_PREFIX : &str = "dejavu-fonts-ttf-2.37/ttf"; - pub const FONTS_TO_EXTRACT : &[&str] = &["DejaVuSansMono-Bold"]; - - /// Extract font file from official DejaVu zip package - /// - /// The font file extracted to package's directory - fn extract_dejavu_font( - package : &std::path::Path, - font_name : &str, - ) { - let font_file = format!("{}.ttf", font_name); - let font_package_path = format!("{}/{}", - PACKAGE_FONTS_PREFIX, - font_file - ); - - let mut archive = zip::ZipArchive::new( - std::fs::File::open(package).unwrap() - ).unwrap(); - let mut input = archive.by_name( - font_package_path.as_str() - ).unwrap(); - let mut output = std::fs::File::create( - package.parent().unwrap().join(font_file) - ).unwrap(); - std::io::copy(&mut input, &mut output).unwrap(); - } - - pub fn download_and_unzip() { - let out_dir = env::var("OUT_DIR").unwrap(); - let destination_dir = path::Path::new(&out_dir); - let package_path = destination_dir.join(PACKAGE_NAME); - - github_download( - PROJECT_URL, - VERSION, - PACKAGE_NAME, - destination_dir - ); - - for font in FONTS_TO_EXTRACT { - extract_dejavu_font(package_path.as_path(), &font); - } - } -} - fn main() { msdfgen_wasm::download(); - fonts::download_and_unzip(); println!("cargo:rerun-if-changed=build.rs"); } diff --git a/lib/core/msdf-sys/src/lib.rs b/lib/core/msdf-sys/src/lib.rs index 6b9a024c15..4606955fae 100644 --- a/lib/core/msdf-sys/src/lib.rs +++ b/lib/core/msdf-sys/src/lib.rs @@ -137,14 +137,15 @@ mod tests { use wasm_bindgen_test::wasm_bindgen_test; use internal::msdfgen_max_msdf_size; use crate::*; + use basegl_core_fonts_base::FontsBase; #[wasm_bindgen_test] fn generate_msdf_for_capital_a() { // given - let test_font : &[u8] = include_bytes!( - concat!(env!("OUT_DIR"), "/DejaVuSansMono-Bold.ttf") + let font_base = FontsBase::new(); + let font = Font::load_from_memory( + font_base.fonts_by_name.get("DejaVuSansMono-Bold").unwrap() ); - let font = Font::load_from_memory(test_font); let params = MSDFParameters { width: 32, height: 32, diff --git a/lib/core/src/font_base.rs b/lib/core/src/font_base.rs new file mode 100644 index 0000000000..b235839fa8 --- /dev/null +++ b/lib/core/src/font_base.rs @@ -0,0 +1,13 @@ +use crate::prelude::*; +use basegl_core_msdf_sys as msdf_sys; +use basegl_core_fonts_base as font_base; + +pub struct Font { + msdf_sys_handle : msdf_sys::Font, + pub name : String, + chars : HashMap +} + +pub struct CharInfo { + msdf : msdf_sys::MutlichannelSignedDistanceField, +} diff --git a/lib/core/src/lib.rs b/lib/core/src/lib.rs index a4d34f8972..437049f808 100644 --- a/lib/core/src/lib.rs +++ b/lib/core/src/lib.rs @@ -14,6 +14,8 @@ pub mod data; pub mod math; pub mod dirty; pub mod display; +pub mod font_base; +pub mod text; pub use basegl_prelude as prelude; pub mod backend { pub use basegl_backend_webgl as webgl; diff --git a/lib/core/src/text/mod.rs b/lib/core/src/text/mod.rs new file mode 100644 index 0000000000..6c0b4fb5fb --- /dev/null +++ b/lib/core/src/text/mod.rs @@ -0,0 +1,113 @@ + +use basegl_backend_webgl::{Context, compile_shader, link_program}; +use basegl_core_msdf_sys as msdf_sys; +use basegl_core_fonts_base::FontsBase; + +use wasm_bindgen::prelude::*; +use web_sys::WebGlRenderingContext; + +pub fn print_line(context : &Context, text : &str) +{ + let vert_shader = compile_shader( + &context, + WebGlRenderingContext::VERTEX_SHADER, + r#" + attribute vec4 position; + void main() { + gl_Position = position; + } + "#, + ).unwrap(); + let frag_shader = compile_shader( + &context, + WebGlRenderingContext::FRAGMENT_SHADER, + include_str!("msdf_frag.glsl") + ).unwrap(); + let program = link_program(&context, &vert_shader, &frag_shader).unwrap(); + context.use_program(Some(&program)); + + let msdf_location = context.get_uniform(program, "msdf"); + let bg_color_location = context.get_uniform(program, "bgColor"); + let fg_color_location = context.get_uniform(program, "fgColor"); + let px_range_location = context.get_uniform(program, "pxRange"); + + let vertices= [ + -0.5, -0.5, 0.0, + -0.5, 0.5, 0.0, + 0.5, 0.5, 0.0, + 0.5, -0.5, 0.0 + ]; + + let buffer = context.create_buffer().unwrap(); + context.bind_buffer(WebGlRenderingContext::ARRAY_BUFFER, Some(&buffer)); + + let font_base = FontsBase::new(); + let font = msdf_sys::Font::load_from_memory( + font_base.fonts_by_name.get("DejaVuSansMono-Bold").unwrap() + ); + let params = msdf_sys::MSDFParameters { + width: 16, + height: 16, + edge_coloring_angle_threshold: 3.0, + range: 2.0, + edge_threshold: 1.001, + overlap_support: true + }; + // when + let msdf = msdf_sys::MutlichannelSignedDistanceField::generate( + &font, + text[0], + ¶ms, + Vector2D { x: 1.0, y: 1.0 }, + Vector2D { x: 0.0, y: 0.0 } + ); + + let msdf_texture = context.create_texture(); + context.bind_texture(context.TEXTURE_2D, msdf_texture.as_ref()); + context.tex_image_2d_with_i32_and_i32_and_i32_and_format_and_type_and_opt_array_buffer_view( + Context::TEXTURE_2D, + 0, + Context::RGB32F, + 16, + 16, + 0, + Context::RGB32F, + gl.FLOAT, + js_sys::Float32Array::view(&vertices[0..16*16*3]) + ); + + context.uniform1i(msdf_location, 0); + context.uniform4f(bg_color_location, 0.0, 0.0, 0.0, 0.0); + context.uniform4f(fg_color_location, 255.0, 255.0, 255.0, 0.0); + context.uniform1f(px_range_location, 1.0); + + // Note that `Float32Array::view` is somewhat dangerous (hence the + // `unsafe`!). This is creating a raw view into our module's + // `WebAssembly.Memory` buffer, but if we allocate more pages for ourself + // (aka do a memory allocation in Rust) it'll cause the buffer to change, + // causing the `Float32Array` to be invalid. + // + // As a result, after `Float32Array::view` we have to be very careful not to + // do any memory allocations before it's dropped. + unsafe { + let vert_array = js_sys::Float32Array::view(&vertices); + + context.buffer_data_with_array_buffer_view( + WebGlRenderingContext::ARRAY_BUFFER, + &vert_array, + WebGlRenderingContext::STATIC_DRAW, + ); + } + + context.vertex_attrib_pointer_with_i32(0, 3, WebGlRenderingContext::FLOAT, false, 0, 0); + context.enable_vertex_attrib_array(0); + + context.clear_color(0.0, 0.0, 0.0, 1.0); + context.clear(WebGlRenderingContext::COLOR_BUFFER_BIT); + + context.draw_arrays( + WebGlRenderingContext::TRIANGLES, + 0, + (vertices.len() / 3) as i32, + ); +} \ No newline at end of file diff --git a/lib/core/src/text/msdf_frag.glsl b/lib/core/src/text/msdf_frag.glsl new file mode 100644 index 0000000000..23fcad186b --- /dev/null +++ b/lib/core/src/text/msdf_frag.glsl @@ -0,0 +1,19 @@ +in vec2 pos; +out vec4 color; +uniform sampler2D msdf; +uniform float pxRange; +uniform vec4 bgColor; +uniform vec4 fgColor; + +float median(float r, float g, float b) { + return max(min(r, g), min(max(r, g), b)); +} + +void main() { + vec2 msdfUnit = pxRange/vec2(textureSize(msdf, 0)); + vec3 sample = texture(msdf, pos).rgb; + float sigDist = median(sample.r, sample.g, sample.b) - 0.5; + sigDist *= dot(msdfUnit, 0.5/fwidth(pos)); + float opacity = clamp(sigDist + 0.5, 0.0, 1.0); + color = mix(bgColor, fgColor, opacity); +} \ No newline at end of file diff --git a/lib/prelude/src/lib.rs b/lib/prelude/src/lib.rs index 8b6079c863..443a4a2d62 100644 --- a/lib/prelude/src/lib.rs +++ b/lib/prelude/src/lib.rs @@ -144,3 +144,4 @@ impl WithPhantom { Self { without_phantom, phantom } } } + From 7ed0490bc6be40e218b56f9e1dedbc70db3e55c6 Mon Sep 17 00:00:00 2001 From: Adam Obuchowicz Date: Tue, 19 Nov 2019 16:17:03 +0100 Subject: [PATCH 02/19] Displaying a letter --- examples/03-text/.gitignore | 2 + examples/03-text/bootstrap.js | 5 + examples/03-text/index.html | 19 + examples/03-text/index.js | 6 + examples/03-text/package-lock.json | 6058 +++++++++++++++++++++++++ examples/03-text/package.json | 38 + examples/03-text/webpack.config.js | 19 + lib/core/Cargo.toml | 4 +- lib/core/msdf-sys/Cargo.toml | 2 +- lib/core/msdf-sys/src/lib.rs | 4 +- lib/core/src/display/workspace.rs | 135 +- lib/core/src/font_base.rs | 26 +- lib/core/src/lib.rs | 2 + lib/core/src/text/mod.rs | 94 +- lib/core/src/text/msdf_frag.glsl | 30 +- lib/core/src/text/msdf_vert.glsl | 7 + lib/system/web/src/resize_observer.rs | 4 +- 17 files changed, 6314 insertions(+), 141 deletions(-) create mode 100644 examples/03-text/.gitignore create mode 100644 examples/03-text/bootstrap.js create mode 100644 examples/03-text/index.html create mode 100644 examples/03-text/index.js create mode 100644 examples/03-text/package-lock.json create mode 100644 examples/03-text/package.json create mode 100644 examples/03-text/webpack.config.js create mode 100644 lib/core/src/text/msdf_vert.glsl diff --git a/examples/03-text/.gitignore b/examples/03-text/.gitignore new file mode 100644 index 0000000000..f06235c460 --- /dev/null +++ b/examples/03-text/.gitignore @@ -0,0 +1,2 @@ +node_modules +dist diff --git a/examples/03-text/bootstrap.js b/examples/03-text/bootstrap.js new file mode 100644 index 0000000000..7934d627e8 --- /dev/null +++ b/examples/03-text/bootstrap.js @@ -0,0 +1,5 @@ +// A dependency graph that contains any wasm must all be imported +// asynchronously. This `bootstrap.js` file does the single async import, so +// that no one else needs to worry about it again. +import("./index.js") + .catch(e => console.error("Error importing `index.js`:", e)); diff --git a/examples/03-text/index.html b/examples/03-text/index.html new file mode 100644 index 0000000000..2d9b254378 --- /dev/null +++ b/examples/03-text/index.html @@ -0,0 +1,19 @@ + + + + + + BaseGL Example + + + + +
+ +
+ + + diff --git a/examples/03-text/index.js b/examples/03-text/index.js new file mode 100644 index 0000000000..73b4bc3aa6 --- /dev/null +++ b/examples/03-text/index.js @@ -0,0 +1,6 @@ + var Module = { + onRuntimeInitialized: function() { + console.log("Wojtas"); + } + }; +import * as wasm from "basegl"; diff --git a/examples/03-text/package-lock.json b/examples/03-text/package-lock.json new file mode 100644 index 0000000000..eaf214c099 --- /dev/null +++ b/examples/03-text/package-lock.json @@ -0,0 +1,6058 @@ +{ + "name": "example-scene", + "version": "0.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@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/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "dev": true, + "requires": { + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, + "@types/node": { + "version": "12.7.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.9.tgz", + "integrity": "sha512-P57oKTJ/vYivL2BCfxCC5tQjlS8qW31pbOL6qt99Yrjm95YdHgNZwjrTTjMBh+C2/y6PXIX4oz253+jUzxKKfQ==", + "dev": true + }, + "@webassemblyjs/ast": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", + "integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==", + "dev": true, + "requires": { + "@webassemblyjs/helper-module-context": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/wast-parser": "1.8.5" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz", + "integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz", + "integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz", + "integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==", + "dev": true + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz", + "integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==", + "dev": true, + "requires": { + "@webassemblyjs/wast-printer": "1.8.5" + } + }, + "@webassemblyjs/helper-fsm": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz", + "integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==", + "dev": true + }, + "@webassemblyjs/helper-module-context": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz", + "integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.5", + "mamacro": "^0.0.3" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz", + "integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz", + "integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz", + "integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz", + "integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz", + "integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz", + "integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/helper-wasm-section": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5", + "@webassemblyjs/wasm-opt": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5", + "@webassemblyjs/wast-printer": "1.8.5" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz", + "integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/ieee754": "1.8.5", + "@webassemblyjs/leb128": "1.8.5", + "@webassemblyjs/utf8": "1.8.5" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz", + "integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz", + "integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-api-error": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/ieee754": "1.8.5", + "@webassemblyjs/leb128": "1.8.5", + "@webassemblyjs/utf8": "1.8.5" + } + }, + "@webassemblyjs/wast-parser": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz", + "integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/floating-point-hex-parser": "1.8.5", + "@webassemblyjs/helper-api-error": "1.8.5", + "@webassemblyjs/helper-code-frame": "1.8.5", + "@webassemblyjs/helper-fsm": "1.8.5", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz", + "integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/wast-parser": "1.8.5", + "@xtuc/long": "4.2.2" + } + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dev": true, + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "acorn": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz", + "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==", + "dev": true + }, + "ajv": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "dev": true + }, + "ajv-keywords": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", + "dev": true + }, + "ansi-colors": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", + "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", + "dev": true + }, + "ansi-html": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", + "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", + "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 + }, + "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" + } + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", + "dev": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "dev": true, + "requires": { + "object-assign": "^4.1.1", + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true + }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "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==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "dev": true + }, + "basegl": { + "version": "file:../../target/web", + "dev": true + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", + "dev": true + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true + }, + "bluebird": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.0.tgz", + "integrity": "sha512-aBQ1FxIa7kSWCcmKHlcHFlT2jt6J/l4FzC7KcPELkOJOsPOb/bccdhmIrKDfXhwFrmc7vDoDrrepFvGqjyXGJg==", + "dev": true + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "dev": true + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "dependencies": { + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + } + } + }, + "bonjour": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", + "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", + "dev": true, + "requires": { + "array-flatten": "^2.1.0", + "deep-equal": "^1.0.1", + "dns-equal": "^1.0.0", + "dns-txt": "^2.0.2", + "multicast-dns": "^6.0.1", + "multicast-dns-service-types": "^1.1.0" + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "dev": true, + "requires": { + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "~1.0.5" + } + }, + "buffer": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "buffer-indexof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", + "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true + }, + "cacache": { + "version": "11.3.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.3.tgz", + "integrity": "sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "dev": true, + "requires": { + "no-case": "^2.2.0", + "upper-case": "^1.1.1" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "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==", + "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" + } + } + } + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "chownr": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", + "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==", + "dev": true + }, + "chrome-trace-event": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", + "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "clean-css": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", + "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==", + "dev": true, + "requires": { + "source-map": "~0.6.0" + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.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 + }, + "commander": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "compressible": { + "version": "2.0.17", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.17.tgz", + "integrity": "sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==", + "dev": true, + "requires": { + "mime-db": ">= 1.40.0 < 2" + } + }, + "compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dev": true, + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "dev": true + }, + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "dev": true, + "requires": { + "date-now": "^0.1.4" + } + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "copy-webpack-plugin": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.0.4.tgz", + "integrity": "sha512-YBuYGpSzoCHSSDGyHy6VJ7SHojKp6WHT4D7ItcQFNAYx2hrwkMe56e97xfVR0/ovDuMTrMffXUiltvQljtAGeg==", + "dev": true, + "requires": { + "cacache": "^11.3.3", + "find-cache-dir": "^2.1.0", + "glob-parent": "^3.1.0", + "globby": "^7.1.1", + "is-glob": "^4.0.1", + "loader-utils": "^1.2.3", + "minimatch": "^3.0.4", + "normalize-path": "^3.0.0", + "p-limit": "^2.2.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^1.7.0", + "webpack-log": "^2.0.0" + } + }, + "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=", + "dev": true + }, + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "dev": true, + "requires": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", + "dev": true + }, + "cyclist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", + "dev": true + }, + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "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=", + "dev": true + }, + "deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.0.tgz", + "integrity": "sha512-ZbfWJq/wN1Z273o7mUSjILYqehAktR2NVoSrOukDkU9kg2v/Uv89yU4Cvz8seJeAmtN5oqiefKq8FPuXOboqLw==", + "dev": true, + "requires": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + } + }, + "default-gateway": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", + "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "ip-regex": "^2.1.0" + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "del": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", + "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "globby": "^6.1.0", + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "pify": "^4.0.1", + "rimraf": "^2.6.3" + }, + "dependencies": { + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + } + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "des.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true + }, + "detect-node": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", + "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "dir-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", + "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", + "dev": true, + "requires": { + "path-type": "^3.0.0" + } + }, + "dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", + "dev": true + }, + "dns-packet": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", + "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", + "dev": true, + "requires": { + "ip": "^1.1.0", + "safe-buffer": "^5.0.1" + } + }, + "dns-txt": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", + "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", + "dev": true, + "requires": { + "buffer-indexof": "^1.0.0" + } + }, + "dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "dev": true, + "requires": { + "utila": "~0.4" + } + }, + "dom-serializer": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", + "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + }, + "dependencies": { + "domelementtype": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", + "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==", + "dev": true + } + } + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dev": true, + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "elliptic": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.1.tgz", + "integrity": "sha512-xvJINNLbTeWQjrl6X+7eQCrIy/YPv5XCpKW6kB5mKvtnGILoLDcySuwomfdzt0BMdLNVnuRNTuzKNHj0bva1Cg==", + "dev": true, + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "enhanced-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", + "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.4.0", + "tapable": "^1.0.0" + } + }, + "entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", + "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==", + "dev": true + }, + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "es-abstract": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.15.0.tgz", + "integrity": "sha512-bhkEqWJ2t2lMeaJDuk7okMkJWI/yqgH/EoGwpcvv0XW9RWQsRspI4wt6xuyuvMvvQE3gg/D9HXppgk21w78GyQ==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.0", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-inspect": "^1.6.0", + "object-keys": "^1.1.1", + "string.prototype.trimleft": "^2.1.0", + "string.prototype.trimright": "^2.1.0" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, + "eventemitter3": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz", + "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==", + "dev": true + }, + "events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", + "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", + "dev": true + }, + "eventsource": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", + "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", + "dev": true, + "requires": { + "original": "^1.0.0" + } + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "dev": true, + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + } + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "figgy-pudding": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", + "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==", + "dev": true + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.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" + } + }, + "findup-sync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, + "flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "follow-redirects": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.9.0.tgz", + "integrity": "sha512-CRcPzsSIbXyVDl0QI01muNDu69S8trU4jArW9LpOt2WtC6LyUJetcIrmfHsRBx7/Jb6GHJUiuqyYxPooFfNt6A==", + "dev": true, + "requires": { + "debug": "^3.0.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "dev": true + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "dev": true, + "optional": 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" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.3.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.12.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "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 + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "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" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "requires": { + "global-prefix": "^3.0.0" + }, + "dependencies": { + "global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + } + } + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "globby": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz", + "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "dir-glob": "^2.0.0", + "glob": "^7.1.2", + "ignore": "^3.3.5", + "pify": "^3.0.0", + "slash": "^1.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "graceful-fs": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "dev": true + }, + "handle-thing": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.0.tgz", + "integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "hello-wasm-pack": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/hello-wasm-pack/-/hello-wasm-pack-0.1.0.tgz", + "integrity": "sha512-3hx0GDkDLf/a9ThCMV2qG4mwza8N/MCtm8aeFFc/cdBCL2zMJ1kW1wjNl7xPqD1lz8Yl5+uhnc/cpui4dLwz/w==", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "html-entities": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", + "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=", + "dev": true + }, + "html-minifier": { + "version": "3.5.21", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz", + "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==", + "dev": true, + "requires": { + "camel-case": "3.0.x", + "clean-css": "4.2.x", + "commander": "2.17.x", + "he": "1.2.x", + "param-case": "2.1.x", + "relateurl": "0.2.x", + "uglify-js": "3.4.x" + } + }, + "html-webpack-plugin": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz", + "integrity": "sha1-sBq71yOsqqeze2r0SS69oD2d03s=", + "dev": true, + "requires": { + "html-minifier": "^3.2.3", + "loader-utils": "^0.2.16", + "lodash": "^4.17.3", + "pretty-error": "^2.0.2", + "tapable": "^1.0.0", + "toposort": "^1.0.0", + "util.promisify": "1.0.0" + }, + "dependencies": { + "big.js": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", + "dev": true + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, + "loader-utils": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", + "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", + "dev": true, + "requires": { + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0", + "object-assign": "^4.0.1" + } + } + } + }, + "htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "dev": true, + "requires": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, + "readable-stream": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", + "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", + "dev": true + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + } + } + }, + "http-parser-js": { + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", + "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=", + "dev": true + }, + "http-proxy": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.0.tgz", + "integrity": "sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==", + "dev": true, + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-proxy-middleware": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", + "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", + "dev": true, + "requires": { + "http-proxy": "^1.17.0", + "is-glob": "^4.0.0", + "lodash": "^4.17.11", + "micromatch": "^3.1.10" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "iconv-lite": { + "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" + } + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "dev": true + }, + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "dev": true + }, + "ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + }, + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "requires": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "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=", + "dev": true, + "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==", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "internal-ip": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", + "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", + "dev": true, + "requires": { + "default-gateway": "^4.2.0", + "ipaddr.js": "^1.9.0" + } + }, + "interpret": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", + "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", + "dev": true + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "dev": true + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true + }, + "ipaddr.js": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", + "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==", + "dev": true + }, + "is-absolute-url": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arguments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", + "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "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 + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true + }, + "is-path-in-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", + "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", + "dev": true, + "requires": { + "is-path-inside": "^2.1.0" + } + }, + "is-path-inside": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", + "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", + "dev": true, + "requires": { + "path-is-inside": "^1.0.2" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "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==", + "dev": true + }, + "json3": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", + "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "killable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", + "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "dev": true + }, + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + } + }, + "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" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "loglevel": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.4.tgz", + "integrity": "sha512-p0b6mOGKcGa+7nnmKbpzR6qloPbrgLcnio++E+14Vo/XffOGwZtRpUhr8dTH/x2oCMmEoIU0Zwm3ZauhvYD17g==", + "dev": true + }, + "lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", + "dev": true + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "mamacro": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz", + "integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==", + "dev": true + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", + "dev": true + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "dev": true, + "requires": { + "mime-db": "1.40.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dev": true, + "requires": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + } + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "multicast-dns": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", + "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", + "dev": true, + "requires": { + "dns-packet": "^1.3.1", + "thunky": "^1.0.2" + } + }, + "multicast-dns-service-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", + "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", + "dev": true + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "dev": true, + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true + }, + "neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "dev": true, + "requires": { + "lower-case": "^1.1.1" + } + }, + "node-forge": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz", + "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==", + "dev": true + }, + "node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dev": true, + "requires": { + "boolbase": "~1.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-inspect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", + "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", + "dev": true + }, + "object-is": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.1.tgz", + "integrity": "sha1-CqYOyZiaCz7Xlc9NBvYs8a1lObY=", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.getownpropertydescriptors": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", + "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "opn": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", + "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", + "dev": true, + "requires": { + "is-wsl": "^1.1.0" + } + }, + "original": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", + "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", + "dev": true, + "requires": { + "url-parse": "^1.4.3" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", + "dev": true + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "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-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true + }, + "p-retry": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", + "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", + "dev": true, + "requires": { + "retry": "^0.12.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 + }, + "pako": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", + "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==", + "dev": true + }, + "parallel-transform": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", + "dev": true, + "requires": { + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "param-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", + "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", + "dev": true, + "requires": { + "no-case": "^2.2.0" + } + }, + "parse-asn1": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", + "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", + "dev": true, + "requires": { + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "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 + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "portfinder": { + "version": "1.0.24", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.24.tgz", + "integrity": "sha512-ekRl7zD2qxYndYflwiryJwMioBI7LI7rVXg3EnLK3sjkouT5eOuhS3gS255XxBksa30VG8UPZYZCdgfGOfkSUg==", + "dev": true, + "requires": { + "async": "^1.5.2", + "debug": "^2.2.0", + "mkdirp": "0.5.x" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "pretty-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", + "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", + "dev": true, + "requires": { + "renderkid": "^2.0.1", + "utila": "~0.4" + } + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "proxy-addr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", + "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", + "dev": true, + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.0" + } + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "querystringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", + "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexp.prototype.flags": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.2.0.tgz", + "integrity": "sha512-ztaw4M1VqgMwl9HlPpOuiYgItcHlunW0He2fE6eNfT6E/CF2FtYi9ofOYe4mKntstYk0Fyh/rDRBdS3AnxjlrA==", + "dev": true, + "requires": { + "define-properties": "^1.1.2" + } + }, + "relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", + "dev": true + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "renderkid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.3.tgz", + "integrity": "sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA==", + "dev": true, + "requires": { + "css-select": "^1.1.0", + "dom-converter": "^0.2", + "htmlparser2": "^3.3.0", + "strip-ansi": "^3.0.0", + "utila": "^0.4.0" + } + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "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 + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "dependencies": { + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + } + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "dev": true, + "requires": { + "aproba": "^1.1.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", + "dev": true + }, + "selfsigned": { + "version": "1.10.7", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.7.tgz", + "integrity": "sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA==", + "dev": true, + "requires": { + "node-forge": "0.9.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "serialize-javascript": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz", + "integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A==", + "dev": true + }, + "serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "dependencies": { + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "sockjs": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz", + "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==", + "dev": true, + "requires": { + "faye-websocket": "^0.10.0", + "uuid": "^3.0.1" + } + }, + "sockjs-client": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz", + "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==", + "dev": true, + "requires": { + "debug": "^3.2.5", + "eventsource": "^1.0.7", + "faye-websocket": "~0.11.1", + "inherits": "^2.0.3", + "json3": "^3.3.2", + "url-parse": "^1.4.3" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "faye-websocket": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", + "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "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 + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dev": true, + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "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=", + "dev": true + }, + "spdy": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.1.tgz", + "integrity": "sha512-HeZS3PBdMA+sZSu0qwpCxl3DeALD5ASx8pAX0jZdKXSpPWbQ6SYGnlg3BBmYLx5LtiZrmkAZfErCm2oECBcioA==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "readable-stream": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", + "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-shift": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "string.prototype.trimleft": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", + "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string.prototype.trimright": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", + "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.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" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true + }, + "terser": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.3.4.tgz", + "integrity": "sha512-Kcrn3RiW8NtHBP0ssOAzwa2MsIRQ8lJWiBG/K7JgqPlomA3mtb2DEmp4/hrUA+Jujx+WZ02zqd7GYD+QRBB/2Q==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "dependencies": { + "commander": { + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.1.tgz", + "integrity": "sha512-cCuLsMhJeWQ/ZpsFTbE765kvVfoeSddc4nU3up4fV+fDBcfUXnbITJ+JzhkdjzOqhURjZgujxaioam4RM9yGUg==", + "dev": true + } + } + }, + "terser-webpack-plugin": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.1.tgz", + "integrity": "sha512-ZXmmfiwtCLfz8WKZyYUuuHf3dMYEjg8NrjHMb0JqHVHVOSkzp3cW2/XG1fP3tRhqEqSzMwzzRQGtAPbs4Cncxg==", + "dev": true, + "requires": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^1.7.0", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + }, + "dependencies": { + "cacache": { + "version": "12.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz", + "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + } + } + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "thunky": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.3.tgz", + "integrity": "sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow==", + "dev": true + }, + "timers-browserify": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", + "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", + "dev": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true + }, + "toposort": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz", + "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=", + "dev": true + }, + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "dev": true + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "uglify-js": { + "version": "3.4.10", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz", + "integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==", + "dev": true, + "requires": { + "commander": "~2.19.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "dev": true + } + } + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true + }, + "upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", + "dev": true + }, + "uri-js": { + "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" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "url-parse": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", + "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", + "dev": true, + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "requires": { + "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "util.promisify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", + "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "object.getownpropertydescriptors": "^2.0.3" + } + }, + "utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", + "dev": true + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, + "uuid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", + "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==", + "dev": true + }, + "v8-compile-cache": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz", + "integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==", + "dev": true + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true + }, + "vm-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", + "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==", + "dev": true + }, + "watchpack": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", + "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", + "dev": true, + "requires": { + "chokidar": "^2.0.2", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" + } + }, + "wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "requires": { + "minimalistic-assert": "^1.0.0" + } + }, + "webpack": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.41.0.tgz", + "integrity": "sha512-yNV98U4r7wX1VJAj5kyMsu36T8RPPQntcb5fJLOsMz/pt/WrKC0Vp1bAlqPLkA1LegSwQwf6P+kAbyhRKVQ72g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-module-context": "1.8.5", + "@webassemblyjs/wasm-edit": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5", + "acorn": "^6.2.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^4.1.0", + "eslint-scope": "^4.0.3", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.1", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", + "schema-utils": "^1.0.0", + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.1", + "watchpack": "^1.6.0", + "webpack-sources": "^1.4.1" + } + }, + "webpack-cli": { + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.9.tgz", + "integrity": "sha512-xwnSxWl8nZtBl/AFJCOn9pG7s5CYUYdZxmmukv+fAHLcBIHM36dImfpQg3WfShZXeArkWlf6QRw24Klcsv8a5A==", + "dev": true, + "requires": { + "chalk": "2.4.2", + "cross-spawn": "6.0.5", + "enhanced-resolve": "4.1.0", + "findup-sync": "3.0.0", + "global-modules": "2.0.0", + "import-local": "2.0.0", + "interpret": "1.2.0", + "loader-utils": "1.2.3", + "supports-color": "6.1.0", + "v8-compile-cache": "2.0.3", + "yargs": "13.2.4" + } + }, + "webpack-dev-middleware": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz", + "integrity": "sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==", + "dev": true, + "requires": { + "memory-fs": "^0.4.1", + "mime": "^2.4.4", + "mkdirp": "^0.5.1", + "range-parser": "^1.2.1", + "webpack-log": "^2.0.0" + }, + "dependencies": { + "mime": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", + "dev": true + } + } + }, + "webpack-dev-server": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.8.2.tgz", + "integrity": "sha512-0xxogS7n5jHDQWy0WST0q6Ykp7UGj4YvWh+HVN71JoE7BwPxMZrwgraBvmdEMbDVMBzF0u+mEzn8TQzBm5NYJQ==", + "dev": true, + "requires": { + "ansi-html": "0.0.7", + "bonjour": "^3.5.0", + "chokidar": "^2.1.8", + "compression": "^1.7.4", + "connect-history-api-fallback": "^1.6.0", + "debug": "^4.1.1", + "del": "^4.1.1", + "express": "^4.17.1", + "html-entities": "^1.2.1", + "http-proxy-middleware": "0.19.1", + "import-local": "^2.0.0", + "internal-ip": "^4.3.0", + "ip": "^1.1.5", + "is-absolute-url": "^3.0.3", + "killable": "^1.0.1", + "loglevel": "^1.6.4", + "opn": "^5.5.0", + "p-retry": "^3.0.1", + "portfinder": "^1.0.24", + "schema-utils": "^1.0.0", + "selfsigned": "^1.10.7", + "semver": "^6.3.0", + "serve-index": "^1.9.1", + "sockjs": "0.3.19", + "sockjs-client": "1.4.0", + "spdy": "^4.0.1", + "strip-ansi": "^3.0.1", + "supports-color": "^6.1.0", + "url": "^0.11.0", + "webpack-dev-middleware": "^3.7.2", + "webpack-log": "^2.0.0", + "ws": "^6.2.1", + "yargs": "12.0.5" + }, + "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 + }, + "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": { + "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" + } + } + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "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 + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "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 + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "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": { + "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" + } + } + } + }, + "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" + } + } + } + }, + "webpack-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", + "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", + "dev": true, + "requires": { + "ansi-colors": "^3.0.0", + "uuid": "^3.3.2" + } + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + }, + "websocket-driver": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", + "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", + "dev": true, + "requires": { + "http-parser-js": ">=0.4.0 <0.4.11", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", + "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "dev": true, + "requires": { + "errno": "~0.1.7" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "yargs": { + "version": "13.2.4", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", + "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.0" + } + }, + "yargs-parser": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} diff --git a/examples/03-text/package.json b/examples/03-text/package.json new file mode 100644 index 0000000000..ca462cc11a --- /dev/null +++ b/examples/03-text/package.json @@ -0,0 +1,38 @@ +{ + "name": "example-scene", + "version": "0.1.0", + "description": "Example Scene", + "main": "index.js", + "bin": { + "create-wasm-app": ".bin/create-wasm-app.js" + }, + "scripts": { + "build": "webpack --config webpack.config.js", + "start": "webpack-dev-server" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/rustwasm/create-wasm-app.git" + }, + "keywords": [ + "webassembly", + "wasm", + "rust", + "webpack" + ], + "author": "Ashley Williams ", + "license": "(MIT OR Apache-2.0)", + "bugs": { + "url": "https://github.com/rustwasm/create-wasm-app/issues" + }, + "homepage": "https://github.com/rustwasm/create-wasm-app#readme", + "devDependencies": { + "basegl": "file:../../target/web", + "hello-wasm-pack": "^0.1.0", + "webpack": "^4.29.3", + "webpack-cli": "^3.1.0", + "webpack-dev-server": "^3.1.5", + "copy-webpack-plugin": "^5.0.0", + "html-webpack-plugin": "^3.2.0" + } +} diff --git a/examples/03-text/webpack.config.js b/examples/03-text/webpack.config.js new file mode 100644 index 0000000000..0fa312baab --- /dev/null +++ b/examples/03-text/webpack.config.js @@ -0,0 +1,19 @@ +const CopyWebpackPlugin = require("copy-webpack-plugin"); +const HtmlWebpackPlugin = require('html-webpack-plugin') +const path = require('path'); + +module.exports = { + entry: "./bootstrap.js", + output: { + path: path.resolve(__dirname, "dist"), + filename: "bootstrap.js", + }, + mode: "development", + node: { + fs: 'empty' + }, + plugins: [ + new CopyWebpackPlugin(['index.html']), +// new HtmlWebpackPlugin({template: 'index.html'}), + ], +}; diff --git a/lib/core/Cargo.toml b/lib/core/Cargo.toml index 628b638f59..b85816b638 100644 --- a/lib/core/Cargo.toml +++ b/lib/core/Cargo.toml @@ -14,8 +14,8 @@ default = ["console_error_panic_hook"] basegl-prelude = { version = "0.1.0" , path = "../prelude" } basegl-system-web = { version = "0.1.0" , path = "../system/web" } basegl-backend-webgl = { version = "0.1.0" , path = "../backend/webgl" } -basegl-core-msdf-sys = { version = "0.1.0" , path = "msdf-sys" } basegl-core-fonts-base = { version = "0.1.0" , path = "fonts-base" } +basegl-core-msdf-sys = { version = "0.1.0" , path = "msdf-sys" } wasm-bindgen = { version = "^0.2" , features = ["nightly"] } js-sys = { version = "0.3.28" } failure = { version = "0.1.5" } @@ -41,6 +41,8 @@ features = [ 'WebGlRenderingContext', 'WebGlProgram', 'WebGlShader', + 'WebGlUniformLocation', + 'WebGlTexture', 'Window', 'console' ] diff --git a/lib/core/msdf-sys/Cargo.toml b/lib/core/msdf-sys/Cargo.toml index 90652b4b3e..22bd85c46e 100644 --- a/lib/core/msdf-sys/Cargo.toml +++ b/lib/core/msdf-sys/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Adam Obuchowicz "] edition = "2018" [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "rlib"] [dependencies] wasm-bindgen = "0.2.53" diff --git a/lib/core/msdf-sys/src/lib.rs b/lib/core/msdf-sys/src/lib.rs index 4606955fae..53fc39c52a 100644 --- a/lib/core/msdf-sys/src/lib.rs +++ b/lib/core/msdf-sys/src/lib.rs @@ -8,9 +8,11 @@ use internal::{ }; use js_sys::Uint8Array; use wasm_bindgen::JsValue; -use vector2d::Vector2D; +pub use vector2d::Vector2D; use crate::internal::copy_f32_data_from_msdfgen_memory; +pub use internal::msdfgen_max_msdf_size; + // ============ // === Font === // ============ diff --git a/lib/core/src/display/workspace.rs b/lib/core/src/display/workspace.rs index 0b364883d2..c7c6ff4a25 100644 --- a/lib/core/src/display/workspace.rs +++ b/lib/core/src/display/workspace.rs @@ -59,73 +59,74 @@ impl Workspace { } pub fn refresh(&self) { - if self.dirty.is_set() { - self.logger.group("Refresh.", || { - self.dirty.unset(); - let vert_shader = webgl::compile_shader( - &self.context, - webgl::Context::VERTEX_SHADER, - r#" - attribute vec4 position; - void main() { - gl_Position = position; - } - "#, - ) - .unwrap(); - let frag_shader = webgl::compile_shader( - &self.context, - webgl::Context::FRAGMENT_SHADER, - r#" - void main() { - gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); - } - "#, - ) - .unwrap(); - let program = - webgl::link_program(&self.context, &vert_shader, &frag_shader).unwrap(); - self.context.use_program(Some(&program)); - - let vertices: [f32; 9] = [-1.0, -1.0, 0.0, 1.0, -1.0, 0.0, 0.0, 1.0, 0.0]; - - let buffer = self.context.create_buffer().ok_or("failed to create buffer").unwrap(); - self.context.bind_buffer(webgl::Context::ARRAY_BUFFER, Some(&buffer)); - - // Note that `Float32Array::view` is somewhat dangerous (hence the - // `unsafe`!). This is creating a raw view into our module's - // `WebAssembly.Memory` buffer, but if we allocate more pages for ourself - // (aka do a memory allocation in Rust) it'll cause the buffer to change, - // causing the `Float32Array` to be invalid. - // - // As a result, after `Float32Array::view` we have to be very careful not to - // do any memory allocations before it's dropped. - unsafe { - let vert_array = js_sys::Float32Array::view(&vertices); - - self.context.buffer_data_with_array_buffer_view( - webgl::Context::ARRAY_BUFFER, - &vert_array, - webgl::Context::STATIC_DRAW, - ); - } - - self.context.vertex_attrib_pointer_with_i32( - 0, - 3, - webgl::Context::FLOAT, - false, - 0, - 0, - ); - self.context.enable_vertex_attrib_array(0); - - self.context.clear_color(0.0, 0.0, 0.0, 1.0); - self.context.clear(webgl::Context::COLOR_BUFFER_BIT); - - self.context.draw_arrays(webgl::Context::TRIANGLES, 0, (vertices.len() / 3) as i32); - }); - } + crate::text::print_line(&self.context, "G", &self.logger); +// if self.dirty.is_set() { +// self.logger.group("Refresh.", || { +// self.dirty.unset(); +// let vert_shader = webgl::compile_shader( +// &self.context, +// webgl::Context::VERTEX_SHADER, +// r#" +// attribute vec4 position; +// void main() { +// gl_Position = position; +// } +// "#, +// ) +// .unwrap(); +// let frag_shader = webgl::compile_shader( +// &self.context, +// webgl::Context::FRAGMENT_SHADER, +// r#" +// void main() { +// gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); +// } +// "#, +// ) +// .unwrap(); +// let program = +// webgl::link_program(&self.context, &vert_shader, &frag_shader).unwrap(); +// self.context.use_program(Some(&program)); +// +// let vertices: [f32; 9] = [-1.0, -1.0, 0.0, 1.0, -1.0, 0.0, 0.0, 1.0, 0.0]; +// +// let buffer = self.context.create_buffer().ok_or("failed to create buffer").unwrap(); +// self.context.bind_buffer(webgl::Context::ARRAY_BUFFER, Some(&buffer)); +// +// // Note that `Float32Array::view` is somewhat dangerous (hence the +// // `unsafe`!). This is creating a raw view into our module's +// // `WebAssembly.Memory` buffer, but if we allocate more pages for ourself +// // (aka do a memory allocation in Rust) it'll cause the buffer to change, +// // causing the `Float32Array` to be invalid. +// // +// // As a result, after `Float32Array::view` we have to be very careful not to +// // do any memory allocations before it's dropped. +// unsafe { +// let vert_array = js_sys::Float32Array::view(&vertices); +// +// self.context.buffer_data_with_array_buffer_view( +// webgl::Context::ARRAY_BUFFER, +// &vert_array, +// webgl::Context::STATIC_DRAW, +// ); +// } +// +// self.context.vertex_attrib_pointer_with_i32( +// 0, +// 3, +// webgl::Context::FLOAT, +// false, +// 0, +// 0, +// ); +// self.context.enable_vertex_attrib_array(0); +// +// self.context.clear_color(0.0, 0.0, 0.0, 1.0); +// self.context.clear(webgl::Context::COLOR_BUFFER_BIT); +// +// self.context.draw_arrays(webgl::Context::TRIANGLES, 0, (vertices.len() / 3) as i32); +// }); +// } } } diff --git a/lib/core/src/font_base.rs b/lib/core/src/font_base.rs index b235839fa8..3139abf661 100644 --- a/lib/core/src/font_base.rs +++ b/lib/core/src/font_base.rs @@ -1,13 +1,13 @@ -use crate::prelude::*; -use basegl_core_msdf_sys as msdf_sys; -use basegl_core_fonts_base as font_base; - -pub struct Font { - msdf_sys_handle : msdf_sys::Font, - pub name : String, - chars : HashMap -} - -pub struct CharInfo { - msdf : msdf_sys::MutlichannelSignedDistanceField, -} +//use crate::prelude::*; +//use basegl_core_msdf_sys as msdf_sys; +//use basegl_core_fonts_base as font_base; +// +//pub struct Font { +// msdf_sys_handle : msdf_sys::Font, +// pub name : String, +// chars : HashMap +//} +// +//pub struct CharInfo { +// msdf : msdf_sys::MutlichannelSignedDistanceField, +//} diff --git a/lib/core/src/lib.rs b/lib/core/src/lib.rs index 437049f808..5f4ed3c68f 100644 --- a/lib/core/src/lib.rs +++ b/lib/core/src/lib.rs @@ -23,6 +23,7 @@ pub mod backend { pub mod system { pub use basegl_system_web as web; } +pub mod utils; // ============ // === Main === @@ -33,6 +34,7 @@ use wasm_bindgen::prelude::*; #[wasm_bindgen(start)] pub fn start() { + utils::set_panic_hook(); let world = World::new(); world.add_workspace("canvas"); world.start(); diff --git a/lib/core/src/text/mod.rs b/lib/core/src/text/mod.rs index 6c0b4fb5fb..c7bf3ee045 100644 --- a/lib/core/src/text/mod.rs +++ b/lib/core/src/text/mod.rs @@ -1,53 +1,40 @@ - use basegl_backend_webgl::{Context, compile_shader, link_program}; use basegl_core_msdf_sys as msdf_sys; use basegl_core_fonts_base::FontsBase; -use wasm_bindgen::prelude::*; use web_sys::WebGlRenderingContext; +use basegl_system_web::Logger; -pub fn print_line(context : &Context, text : &str) +pub fn print_line(context : &Context, text : &str, logger : &Logger) { let vert_shader = compile_shader( &context, WebGlRenderingContext::VERTEX_SHADER, - r#" - attribute vec4 position; - void main() { - gl_Position = position; - } - "#, + include_str!("msdf_vert.glsl") ).unwrap(); +// logger.trace(|| format!("{:?}", vert_shader.as_ref().expect_err("No error?"))); + context.get_extension("OES_standard_derivatives").unwrap(); let frag_shader = compile_shader( &context, WebGlRenderingContext::FRAGMENT_SHADER, include_str!("msdf_frag.glsl") ).unwrap(); +// logger.trace(|| format!("{:?}", frag_shader.as_ref().expect_err("No error?"))); let program = link_program(&context, &vert_shader, &frag_shader).unwrap(); context.use_program(Some(&program)); - let msdf_location = context.get_uniform(program, "msdf"); - let bg_color_location = context.get_uniform(program, "bgColor"); - let fg_color_location = context.get_uniform(program, "fgColor"); - let px_range_location = context.get_uniform(program, "pxRange"); - - let vertices= [ - -0.5, -0.5, 0.0, - -0.5, 0.5, 0.0, - 0.5, 0.5, 0.0, - 0.5, -0.5, 0.0 - ]; - - let buffer = context.create_buffer().unwrap(); - context.bind_buffer(WebGlRenderingContext::ARRAY_BUFFER, Some(&buffer)); + let msdf_location = context.get_uniform_location(&program, "msdf"); + let msdf_size_location = context.get_uniform_location(&program, "msdf_size"); + let bg_color_location = context.get_uniform_location(&program, "bgColor"); + let fg_color_location = context.get_uniform_location(&program, "fgColor"); + let px_range_location = context.get_uniform_location(&program, "pxRange"); let font_base = FontsBase::new(); - let font = msdf_sys::Font::load_from_memory( - font_base.fonts_by_name.get("DejaVuSansMono-Bold").unwrap() - ); + let mfont = font_base.fonts_by_name.get("DejaVuSansMono-Bold").unwrap(); + let font = msdf_sys::Font::load_from_memory(mfont); let params = msdf_sys::MSDFParameters { - width: 16, - height: 16, + width: 32, + height: 32, edge_coloring_angle_threshold: 3.0, range: 2.0, edge_threshold: 1.001, @@ -56,30 +43,51 @@ pub fn print_line(context : &Context, text : &str) // when let msdf = msdf_sys::MutlichannelSignedDistanceField::generate( &font, - text[0], + text.chars().next().unwrap() as u32, ¶ms, - Vector2D { x: 1.0, y: 1.0 }, - Vector2D { x: 0.0, y: 0.0 } + msdf_sys::Vector2D { x: 1.0, y: 1.0 }, + msdf_sys::Vector2D { x: 4.0, y: 4.0 } ); + let u8msdf = msdf.data[0..32*32*3].iter().map(|f| nalgebra::clamp(f*255.0, 0.0, 255.0) as u8).collect::>(); +// logger.trace(|| format!("{:?}", (msdf.data[0..16*16*3].to_vec()))); +// logger.trace(|| format!("{:?}", u8msdf)); + let msdf_texture = context.create_texture(); - context.bind_texture(context.TEXTURE_2D, msdf_texture.as_ref()); - context.tex_image_2d_with_i32_and_i32_and_i32_and_format_and_type_and_opt_array_buffer_view( +// context.active_texture(Context::TEXTURE0); + context.bind_texture(Context::TEXTURE_2D, msdf_texture.as_ref()); + let res = context.tex_image_2d_with_i32_and_i32_and_i32_and_format_and_type_and_opt_u8_array( Context::TEXTURE_2D, 0, - Context::RGB32F, - 16, - 16, + Context::RGB as i32, + 32, + 32, 0, - Context::RGB32F, - gl.FLOAT, - js_sys::Float32Array::view(&vertices[0..16*16*3]) + Context::RGB, + Context::UNSIGNED_BYTE, + Some(&u8msdf) ); + context.tex_parameteri(Context::TEXTURE_2D, Context::TEXTURE_WRAP_S, Context::CLAMP_TO_EDGE as i32); + context.tex_parameteri(Context::TEXTURE_2D, Context::TEXTURE_WRAP_T, Context::CLAMP_TO_EDGE as i32); + context.tex_parameteri(Context::TEXTURE_2D, Context::TEXTURE_MIN_FILTER, Context::LINEAR as i32); +// logger.trace(|| format!("{:?}", res.as_ref().expect_err("No error?"))); + context.uniform1i(msdf_location.as_ref(), 0); + context.uniform1i(msdf_size_location.as_ref(), 16); + context.uniform4f(bg_color_location.as_ref(), 0.0, 0.0, 0.0, 1.0); + context.uniform4f(fg_color_location.as_ref(), 255.0, 255.0, 255.0, 1.0); + context.uniform1f(px_range_location.as_ref(), 1.0); - context.uniform1i(msdf_location, 0); - context.uniform4f(bg_color_location, 0.0, 0.0, 0.0, 0.0); - context.uniform4f(fg_color_location, 255.0, 255.0, 255.0, 0.0); - context.uniform1f(px_range_location, 1.0); + let vertices= [ + -1.0, -1.0, 0.0, + -1.0, 1.0, 0.0, + 1.0, 1.0, 0.0, + 1.0, 1.0, 0.0, + 1.0, -1.0, 0.0, + -1.0, -1.0, 0.0 + ]; + + let buffer = context.create_buffer().unwrap(); + context.bind_buffer(WebGlRenderingContext::ARRAY_BUFFER, Some(&buffer)); // Note that `Float32Array::view` is somewhat dangerous (hence the // `unsafe`!). This is creating a raw view into our module's diff --git a/lib/core/src/text/msdf_frag.glsl b/lib/core/src/text/msdf_frag.glsl index 23fcad186b..b1af3bc00a 100644 --- a/lib/core/src/text/msdf_frag.glsl +++ b/lib/core/src/text/msdf_frag.glsl @@ -1,19 +1,23 @@ -in vec2 pos; -out vec4 color; +#extension GL_OES_standard_derivatives : enable + +varying highp vec2 vTextureCoord; + uniform sampler2D msdf; -uniform float pxRange; -uniform vec4 bgColor; -uniform vec4 fgColor; +uniform int msdf_size; +uniform lowp float pxRange; +uniform lowp vec4 bgColor; +uniform lowp vec4 fgColor; -float median(float r, float g, float b) { +highp float median(highp float r, highp float g, highp float b) { return max(min(r, g), min(max(r, g), b)); } void main() { - vec2 msdfUnit = pxRange/vec2(textureSize(msdf, 0)); - vec3 sample = texture(msdf, pos).rgb; - float sigDist = median(sample.r, sample.g, sample.b) - 0.5; - sigDist *= dot(msdfUnit, 0.5/fwidth(pos)); - float opacity = clamp(sigDist + 0.5, 0.0, 1.0); - color = mix(bgColor, fgColor, opacity); -} \ No newline at end of file + highp vec2 msdfUnit = pxRange/vec2(msdf_size, 0); + highp vec3 smple = texture2D(msdf, vTextureCoord).rgb; + highp float sigDist = median(smple.r, smple.g, smple.b) - 0.5; + sigDist *= dot(msdfUnit, 0.5/fwidth(vTextureCoord)); + highp float opacity = clamp(sigDist + 0.5, 0.0, 1.0); + gl_FragColor = mix(bgColor, fgColor, opacity); +// gl_FragColor = vec4(sigDist, 0.0, 0.0, 1.0); +} diff --git a/lib/core/src/text/msdf_vert.glsl b/lib/core/src/text/msdf_vert.glsl new file mode 100644 index 0000000000..6bcb77a40b --- /dev/null +++ b/lib/core/src/text/msdf_vert.glsl @@ -0,0 +1,7 @@ +attribute vec4 position; +varying highp vec2 vTextureCoord; + +void main() { + gl_Position = position; + vTextureCoord = position.xy/2.0 + vec2(0.5, 0.5); +} \ No newline at end of file diff --git a/lib/system/web/src/resize_observer.rs b/lib/system/web/src/resize_observer.rs index d09b2805ac..4a56e55694 100644 --- a/lib/system/web/src/resize_observer.rs +++ b/lib/system/web/src/resize_observer.rs @@ -39,8 +39,8 @@ pub struct ResizeObserver { impl ResizeObserver { pub fn new(target: &JsValue, listener: Listener) -> Self { let target = target.clone(); - let observer_id = resize_observe(&target, &listener); - Self { target, listener, observer_id } +// let observer_id = resize_observe(&target, &listener); + Self { target, listener, observer_id: 0 } } } From 1b86cfe6c78388843de71588dde53499ae32a2ec Mon Sep 17 00:00:00 2001 From: Adam Obuchowicz Date: Thu, 21 Nov 2019 10:38:06 +0100 Subject: [PATCH 03/19] Text component in workspace --- examples/03-text/index.html | 2 +- lib/core/msdf-sys/Cargo.toml | 1 + lib/core/msdf-sys/src/internal.rs | 75 ++++- lib/core/msdf-sys/src/lib.rs | 250 ++++++++-------- lib/core/src/display/workspace.rs | 144 ++++----- lib/core/src/display/world.rs | 1 + lib/core/src/font_base.rs | 13 - lib/core/src/lib.rs | 40 ++- lib/core/src/text/font.rs | 92 ++++++ lib/core/src/text/mod.rs | 465 ++++++++++++++++++++++-------- lib/core/src/text/msdf_frag.glsl | 22 +- lib/core/src/text/msdf_vert.glsl | 10 +- 12 files changed, 773 insertions(+), 342 deletions(-) delete mode 100644 lib/core/src/font_base.rs create mode 100644 lib/core/src/text/font.rs diff --git a/examples/03-text/index.html b/examples/03-text/index.html index 2d9b254378..c7a16dc730 100644 --- a/examples/03-text/index.html +++ b/examples/03-text/index.html @@ -12,7 +12,7 @@
- +
diff --git a/lib/core/msdf-sys/Cargo.toml b/lib/core/msdf-sys/Cargo.toml index 22bd85c46e..180964ca90 100644 --- a/lib/core/msdf-sys/Cargo.toml +++ b/lib/core/msdf-sys/Cargo.toml @@ -14,6 +14,7 @@ vector2d = "2.2.0" [dev-dependencies] wasm-bindgen-test = "0.3.3" +futures = "" basegl-core-fonts-base = { version = "0.1.0", path="../fonts-base" } [build-dependencies] diff --git a/lib/core/msdf-sys/src/internal.rs b/lib/core/msdf-sys/src/internal.rs index 91ee08c7a2..87b97e4a8a 100644 --- a/lib/core/msdf-sys/src/internal.rs +++ b/lib/core/msdf-sys/src/internal.rs @@ -3,6 +3,13 @@ use wasm_bindgen::JsValue; #[wasm_bindgen(module = "/msdfgen_wasm.js")] extern { + #[wasm_bindgen(js_name="addInitializationCb")] + pub fn on_emscripten_runtime_initialized(callback : JsValue) + -> js_sys::Promise; + + #[wasm_bindgen(js_name="isInitialized")] + pub fn is_emscripten_runtime_initialized() -> bool; + #[wasm_bindgen(js_name="ccall")] pub fn emscripten_call_function( name : &str, @@ -48,18 +55,60 @@ pub mod emscripten_data_types { pub const FLOAT : &str = "float"; } -pub fn copy_f32_data_from_msdfgen_memory( - address : usize, - output : &mut[f32], - elements_count : usize -) { - for (i, element) in - output.iter_mut().enumerate().take(elements_count) { - - let offset = i * emscripten_data_types::FLOAT_SIZE_IN_BYTES; - *element = emscripten_get_value_from_memory( - address + offset, - emscripten_data_types::FLOAT - ).as_f64().unwrap() as f32; +// ========================== +// === F32ArrayMemoryView === +// ========================== + +pub struct F32ArrayMemoryView { + begin_address : usize, + end_address : usize +} + +pub struct F32ArrayMemoryViewIterator { + next_read_address : usize, + end_address : usize +} + +impl F32ArrayMemoryView { + pub fn new(address : usize, size : usize) -> F32ArrayMemoryView { + let size_in_bytes = + size * emscripten_data_types::FLOAT_SIZE_IN_BYTES; + F32ArrayMemoryView { + begin_address : address, + end_address : address + size_in_bytes + } + } + + pub fn iter(&self) -> F32ArrayMemoryViewIterator { + F32ArrayMemoryViewIterator { + next_read_address : self.begin_address, + end_address : self.end_address + } + } +} + +impl IntoIterator for F32ArrayMemoryView { + type Item = f32; + type IntoIter = F32ArrayMemoryViewIterator; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +impl Iterator for F32ArrayMemoryViewIterator { + type Item = f32; + + fn next(&mut self) -> Option { + if self.next_read_address < self.end_address { + let ret_val = emscripten_get_value_from_memory( + self.next_read_address, + emscripten_data_types::FLOAT + ); + self.next_read_address += emscripten_data_types::FLOAT_SIZE_IN_BYTES; + Some(ret_val.as_f64().unwrap() as f32) + } else { + None + } } } \ No newline at end of file diff --git a/lib/core/msdf-sys/src/lib.rs b/lib/core/msdf-sys/src/lib.rs index 53fc39c52a..efe416eb2a 100644 --- a/lib/core/msdf-sys/src/lib.rs +++ b/lib/core/msdf-sys/src/lib.rs @@ -1,24 +1,39 @@ mod internal; use internal::{ + on_emscripten_runtime_initialized, + is_emscripten_runtime_initialized, emscripten_call_function, msdfgen_generate_msdf, msdfgen_free_font, - emscripten_data_types + emscripten_data_types, + F32ArrayMemoryView, }; use js_sys::Uint8Array; use wasm_bindgen::JsValue; +use wasm_bindgen::prelude::Closure; pub use vector2d::Vector2D; -use crate::internal::copy_f32_data_from_msdfgen_memory; -pub use internal::msdfgen_max_msdf_size; +// ====================== +// === Initialization === +// ====================== + +pub fn set_library_initialized_callback(callback : F) +where F : 'static + FnOnce() { + if is_emscripten_runtime_initialized() { + callback() + } else { + let js_callback = Closure::once_into_js(callback); + on_emscripten_runtime_initialized(js_callback); + } +} // ============ // === Font === // ============ pub struct Font { - handle: JsValue + pub handle: JsValue } impl Font { @@ -31,47 +46,28 @@ impl Font { &JsValue::from_str(emscripten_data_types::ARRAY), &JsValue::from_str(emscripten_data_types::NUMBER) ); - unsafe { // Note [Usage of Uint8Array::view] - let params = js_sys::Array::of2( - &JsValue::from(Uint8Array::view(data)), - &JsValue::from_f64(data.len() as f64) - ); - let handle = emscripten_call_function( - "msdfgen_loadFontMemory", - emscripten_data_types::NUMBER, - param_types, - params); - Font { handle } - } + let params = js_sys::Array::of2( + &JsValue::from(Uint8Array::from(data)), + &JsValue::from_f64(data.len() as f64) + ); + let handle = emscripten_call_function( + "msdfgen_loadFontMemory", + emscripten_data_types::NUMBER, + param_types, + params); + Font { handle } } } -/* - * Note [Usage of Uint8Array::view] - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * We use view in this place to avoid copying font data. This is the only way - * to do it with js_sys structures. The Uint8Array does not leave function - * scope, so does not excess lifetime of data - */ - impl Drop for Font { fn drop(&mut self) { msdfgen_free_font(self.handle.clone()) } } -// ======================================= -// === MutlichannelSignedDistanceField === -// ======================================= - -/// Mutlichannel Signed Distance Field for one glyph -/// -/// For more information about MSDF see [https://github.com/Chlumsky/msdfgen]. -pub struct MutlichannelSignedDistanceField { - pub width : usize, - pub height : usize, - pub data : [f32; Self::MAX_DATA_SIZE] -} +// ===================================================== +// === Mutlichannel signed distance field generation === +// ===================================================== /// Parameters of MSDF generation /// @@ -86,53 +82,46 @@ pub struct MSDFParameters { pub overlap_support : bool } -impl MutlichannelSignedDistanceField { - pub const MAX_SIZE : usize = 32; - pub const CHANNELS_COUNT : usize = 3; - pub const MAX_DATA_SIZE : usize = Self::MAX_SIZE * Self::MAX_SIZE * - Self::CHANNELS_COUNT; - - pub fn generate( - font : &Font, - unicode : u32, - params : &MSDFParameters, - scale : Vector2D, - translate : Vector2D, - ) -> MutlichannelSignedDistanceField { - assert!(params.width <= Self::MAX_SIZE); - assert!(params.height <= Self::MAX_SIZE); - - let output_address = msdfgen_generate_msdf( - params.width, - params.height, - font.handle.clone(), - unicode, - params.edge_coloring_angle_threshold, - params.range, - scale.x, - scale.y, - translate.x, - translate.y, - params.edge_threshold, - params.overlap_support - ); - let mut data : [f32; Self::MAX_DATA_SIZE] = [0.0; Self::MAX_DATA_SIZE]; - let data_size = params.width * params.height * - Self::CHANNELS_COUNT; - copy_f32_data_from_msdfgen_memory( - output_address, - &mut data, - data_size - ); - MutlichannelSignedDistanceField { - width: params.width, - height: params.height, - data - } - } +pub const MAX_MSDF_SIZE: usize = 64; +pub const MSDF_CHANNELS_COUNT: usize = 3; + +///// Generate Mutlichannel Signed Distance Field (MSDF) for one glyph +///// +///// For more information about MSDF see [https://github.com/Chlumsky/msdfgen]. +pub fn generate_msdf>( + output : &mut Output, + font : &Font, + unicode : u32, + params : &MSDFParameters, + scale : Vector2D, + translate : Vector2D, +) { + assert!(params.width <= MAX_MSDF_SIZE); + assert!(params.height <= MAX_MSDF_SIZE); + + let output_size = params.width * params.height * MSDF_CHANNELS_COUNT; + let output_address = msdfgen_generate_msdf( + params.width, + params.height, + font.handle.clone(), + unicode, + params.edge_coloring_angle_threshold, + params.range, + scale.x, + scale.y, + translate.x, + translate.y, + params.edge_threshold, + params.overlap_support + ); + let view = F32ArrayMemoryView::new(output_address, output_size); + + output.extend(view); // Note [Output variable] } - +// ============= +// === Tests === +// ============= #[cfg(test)] mod tests { @@ -141,35 +130,63 @@ mod tests { use crate::*; use basegl_core_fonts_base::FontsBase; - #[wasm_bindgen_test] - fn generate_msdf_for_capital_a() { - // given - let font_base = FontsBase::new(); - let font = Font::load_from_memory( - font_base.fonts_by_name.get("DejaVuSansMono-Bold").unwrap() - ); - let params = MSDFParameters { - width: 32, - height: 32, - edge_coloring_angle_threshold: 3.0, - range: 2.0, - edge_threshold: 1.001, - overlap_support: true - }; - // when - let msdf = MutlichannelSignedDistanceField::generate( - &font, - 'A' as u32, - ¶ms, - Vector2D { x: 1.0, y: 1.0 }, - Vector2D { x: 0.0, y: 0.0 } - ); - // then - // Note [asserts] - assert_eq!(0.42730755, msdf.data[0]); - assert_eq!(0.75, msdf.data[10]); - assert_eq!(-9.759168, msdf.data[params.width * params.height * - MutlichannelSignedDistanceField::CHANNELS_COUNT - 1]); + use std::future::Future; + use std::pin::Pin; + use std::task::{Context, Poll}; + + struct InitializationFuture { + initialized : F + } + + impl Future for InitializationFuture { + type Output = (); + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + if is_emscripten_runtime_initialized() { + (self.initialized)(); + Poll::Ready(()) + } else { + let waker = cx.waker().clone(); + set_library_initialized_callback(move || waker.wake()); + Poll::Pending + } + } + } + + #[wasm_bindgen_test(async)] + fn generate_msdf_for_capital_a() -> impl Future{ + InitializationFuture { + initialized : || { + // given + let font_base = FontsBase::new(); + let font = Font::load_from_memory( + font_base.fonts_by_name.get("DejaVuSansMono-Bold").unwrap() + ); + let params = MSDFParameters { + width: 32, + height: 32, + edge_coloring_angle_threshold: 3.0, + range: 2.0, + edge_threshold: 1.001, + overlap_support: true + }; + // when + let mut msdf = Vec::::new(); + generate_msdf( + &mut msdf, + &font, + 'A' as u32, + ¶ms, + Vector2D { x: 1.0, y: 1.0 }, + Vector2D { x: 0.0, y: 0.0 } + ); + // then + // Note [asserts] + assert_eq!(0.42730755, msdf[0]); + assert_eq!(0.75, msdf[10]); + assert_eq!(-9.759168, msdf[msdf.len()-1]); + } + } } /* Note [asserts] @@ -178,9 +195,16 @@ mod tests { * all values */ + #[wasm_bindgen_test(async)] + fn msdf_data_limits() -> impl Future { + InitializationFuture { + initialized: || { + assert!(MAX_MSDF_SIZE <= msdfgen_max_msdf_size()); + } + } + } #[wasm_bindgen_test] - fn msdf_data_limits() { - assert!(MutlichannelSignedDistanceField::MAX_SIZE - < msdfgen_max_msdf_size()); + fn test() { + assert!(true) } } diff --git a/lib/core/src/display/workspace.rs b/lib/core/src/display/workspace.rs index c7c6ff4a25..9d837d6126 100644 --- a/lib/core/src/display/workspace.rs +++ b/lib/core/src/display/workspace.rs @@ -8,6 +8,7 @@ use crate::system::web::resize_observer::ResizeObserver; use crate::system::web::Logger; use wasm_bindgen::prelude::Closure; use web_sys::WebGlRenderingContext; +use crate::text; // ============= // === Error === @@ -33,6 +34,7 @@ pub type ID = usize; pub struct Workspace { #[shrinkwrap(main_field)] pub data: Rc, + pub text_components : Vec, pub listeners: Listeners, } @@ -46,7 +48,7 @@ impl Workspace { let data = Rc::new(WorkspaceData::new(id, dom, sup_logger, sup_dirty)?); let listeners = Self::new_listeners(&data); data.logger.trace("Initialized."); - Ok(Self { data, listeners }) + Ok(Self { data, text_components: Vec::new(), listeners }) } pub fn new_listeners(data: &Rc) -> Listeners { @@ -59,74 +61,78 @@ impl Workspace { } pub fn refresh(&self) { - crate::text::print_line(&self.context, "G", &self.logger); -// if self.dirty.is_set() { -// self.logger.group("Refresh.", || { -// self.dirty.unset(); -// let vert_shader = webgl::compile_shader( -// &self.context, -// webgl::Context::VERTEX_SHADER, -// r#" -// attribute vec4 position; -// void main() { -// gl_Position = position; -// } -// "#, -// ) -// .unwrap(); -// let frag_shader = webgl::compile_shader( -// &self.context, -// webgl::Context::FRAGMENT_SHADER, -// r#" -// void main() { -// gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); -// } -// "#, -// ) -// .unwrap(); -// let program = -// webgl::link_program(&self.context, &vert_shader, &frag_shader).unwrap(); -// self.context.use_program(Some(&program)); -// -// let vertices: [f32; 9] = [-1.0, -1.0, 0.0, 1.0, -1.0, 0.0, 0.0, 1.0, 0.0]; -// -// let buffer = self.context.create_buffer().ok_or("failed to create buffer").unwrap(); -// self.context.bind_buffer(webgl::Context::ARRAY_BUFFER, Some(&buffer)); -// -// // Note that `Float32Array::view` is somewhat dangerous (hence the -// // `unsafe`!). This is creating a raw view into our module's -// // `WebAssembly.Memory` buffer, but if we allocate more pages for ourself -// // (aka do a memory allocation in Rust) it'll cause the buffer to change, -// // causing the `Float32Array` to be invalid. -// // -// // As a result, after `Float32Array::view` we have to be very careful not to -// // do any memory allocations before it's dropped. -// unsafe { -// let vert_array = js_sys::Float32Array::view(&vertices); -// -// self.context.buffer_data_with_array_buffer_view( -// webgl::Context::ARRAY_BUFFER, -// &vert_array, -// webgl::Context::STATIC_DRAW, -// ); -// } -// -// self.context.vertex_attrib_pointer_with_i32( -// 0, -// 3, -// webgl::Context::FLOAT, -// false, -// 0, -// 0, -// ); -// self.context.enable_vertex_attrib_array(0); -// -// self.context.clear_color(0.0, 0.0, 0.0, 1.0); -// self.context.clear(webgl::Context::COLOR_BUFFER_BIT); -// -// self.context.draw_arrays(webgl::Context::TRIANGLES, 0, (vertices.len() / 3) as i32); -// }); -// } + if self.dirty.is_set() { + self.logger.group("Refresh.", || { + self.dirty.unset(); + self.context.clear_color(0.0, 0.0, 0.0, 1.0); + self.context.clear(WebGlRenderingContext::COLOR_BUFFER_BIT); + + for text_component in &self.text_components { + text_component.display(); + } + if self.text_components.is_empty() { + let vert_shader = webgl::compile_shader( + &self.context, + webgl::Context::VERTEX_SHADER, + r#" + attribute vec4 position; + void main() { + gl_Position = position; + } + "#, + ) + .unwrap(); + let frag_shader = webgl::compile_shader( + &self.context, + webgl::Context::FRAGMENT_SHADER, + r#" + void main() { + gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); + } + "#, + ) + .unwrap(); + let program = + webgl::link_program(&self.context, &vert_shader, &frag_shader).unwrap(); + self.context.use_program(Some(&program)); + + let vertices: [f32; 9] = [-1.0, -1.0, 0.0, 1.0, -1.0, 0.0, 0.0, 1.0, 0.0]; + + let buffer = self.context.create_buffer().ok_or("failed to create buffer").unwrap(); + self.context.bind_buffer(webgl::Context::ARRAY_BUFFER, Some(&buffer)); + + // Note that `Float32Array::view` is somewhat dangerous (hence the + // `unsafe`!). This is creating a raw view into our module's + // `WebAssembly.Memory` buffer, but if we allocate more pages for ourself + // (aka do a memory allocation in Rust) it'll cause the buffer to change, + // causing the `Float32Array` to be invalid. + // + // As a result, after `Float32Array::view` we have to be very careful not to + // do any memory allocations before it's dropped. + unsafe { + let vert_array = js_sys::Float32Array::view(&vertices); + + self.context.buffer_data_with_array_buffer_view( + webgl::Context::ARRAY_BUFFER, + &vert_array, + webgl::Context::STATIC_DRAW, + ); + } + + self.context.vertex_attrib_pointer_with_i32( + 0, + 3, + webgl::Context::FLOAT, + false, + 0, + 0, + ); + self.context.enable_vertex_attrib_array(0); + + self.context.draw_arrays(webgl::Context::TRIANGLES, 0, (vertices.len() / 3) as i32); + } + }) + } } } diff --git a/lib/core/src/display/world.rs b/lib/core/src/display/world.rs index 715800fab4..54c674429f 100644 --- a/lib/core/src/display/world.rs +++ b/lib/core/src/display/world.rs @@ -58,6 +58,7 @@ impl World { self.data.borrow_mut().started = true; Self::request_callback(&self.on_every_frame); } + self.data.borrow().logger.info("STARTED!"); } pub fn stop(&self) { diff --git a/lib/core/src/font_base.rs b/lib/core/src/font_base.rs deleted file mode 100644 index 3139abf661..0000000000 --- a/lib/core/src/font_base.rs +++ /dev/null @@ -1,13 +0,0 @@ -//use crate::prelude::*; -//use basegl_core_msdf_sys as msdf_sys; -//use basegl_core_fonts_base as font_base; -// -//pub struct Font { -// msdf_sys_handle : msdf_sys::Font, -// pub name : String, -// chars : HashMap -//} -// -//pub struct CharInfo { -// msdf : msdf_sys::MutlichannelSignedDistanceField, -//} diff --git a/lib/core/src/lib.rs b/lib/core/src/lib.rs index 5f4ed3c68f..17620ddebe 100644 --- a/lib/core/src/lib.rs +++ b/lib/core/src/lib.rs @@ -14,7 +14,6 @@ pub mod data; pub mod math; pub mod dirty; pub mod display; -pub mod font_base; pub mod text; pub use basegl_prelude as prelude; pub mod backend { @@ -31,11 +30,44 @@ pub mod utils; use display::world::World; use wasm_bindgen::prelude::*; +use basegl_core_fonts_base::FontsBase; +use crate::text::font::FontRenderInfo; +use itertools::iproduct; #[wasm_bindgen(start)] pub fn start() { utils::set_panic_hook(); - let world = World::new(); - world.add_workspace("canvas"); - world.start(); + basegl_core_msdf_sys::set_library_initialized_callback(|| { + let world = World::new(); + let workspace_id = world.add_workspace("canvas"); + + { + let mut world_data = world.data.borrow_mut(); + let workspace = world_data.workspaces.items[workspace_id].as_mut().unwrap(); + + let font_base = FontsBase::new(); + let mut fonts = [ + FontRenderInfo::from_embedded(&font_base, "DejaVuSansMono".to_string()), + FontRenderInfo::from_embedded(&font_base, "DejaVuSansMono-Bold".to_string()), + ]; + let sizes = [0.02, 0.025, 0.03, 0.04, 0.05, 0.06, 0.08, 0.1]; + + for (i, (font, size)) in iproduct!(0..fonts.len(), sizes.iter()).enumerate() { + let text_compnent = crate::text::TextComponent::new( + workspace.data.clone(), + "abcdefghijklmnopqrstuvwxyz1234567890!ABCDEFGHIJKLMNOPQRSTUVWXYZ@#$%^&*()-=_+,./<>?;\':[]{}żźć„”ńµąśðæŋ’ə…łπœę©ß←↓→óþ²³¢€½§·«»–ş".to_string(), + -0.95, + 0.9 - 0.1*(i as f32), + *size, + &mut fonts[font], + text::Color {r: 1.0, g: 1.0, b: 1.0, a: 1.0}, + text::Color {r: 0.0, g: 0.0, b: 0.0, a: 1.0} + ); + workspace.text_components.push(text_compnent); + } + workspace.dirty.set(); + } + + world.start(); + }); } diff --git a/lib/core/src/text/font.rs b/lib/core/src/text/font.rs new file mode 100644 index 0000000000..df76f28474 --- /dev/null +++ b/lib/core/src/text/font.rs @@ -0,0 +1,92 @@ +use crate::prelude::*; +use basegl_core_msdf_sys as msdf_sys; +use basegl_core_fonts_base::FontsBase; + +pub struct MsdfTexture { + pub data : Vec +} + +impl MsdfTexture { + pub const WIDTH : usize = 32; + + pub fn rows(&self) -> usize { + self.data.len()/(3*Self::WIDTH) + } +} + +impl Extend for MsdfTexture { + fn extend>(&mut self, iter: T) { + self.data.extend( + iter.into_iter().map(|float| nalgebra::clamp(float*255.0, 0.0, 255.0) as u8) + ); + } +} + +pub struct FontRenderInfo { + pub name : String, + pub msdf_sys_handle : msdf_sys::Font, + pub msdf_texture : MsdfTexture, + chars : HashMap +} + +pub struct CharInfo { + pub msdf_texture_rows : std::ops::Range, +} + +impl FontRenderInfo { + pub const MSDF_PARAMS : msdf_sys::MSDFParameters = msdf_sys::MSDFParameters { + width: MsdfTexture::WIDTH, + height: MsdfTexture::WIDTH, + edge_coloring_angle_threshold: 3.0, + range: 8.0, + edge_threshold: 1.001, + overlap_support: true + }; + + pub fn new( + name : String, + font_data : &[u8], + ) -> FontRenderInfo { + FontRenderInfo { + name, + msdf_sys_handle : msdf_sys::Font::load_from_memory(font_data), + msdf_texture : MsdfTexture { data : Vec::new() }, + chars : HashMap::new() + } + } + + pub fn from_embedded( + base : &FontsBase, + name : String + ) -> FontRenderInfo { + let mfont = base.fonts_by_name.get(name.as_str()).unwrap(); + crate::text::font::FontRenderInfo::new( + name, mfont + ) + } + + pub fn get_char_info(&mut self, ch : char) -> &CharInfo { + if !self.chars.contains_key(&ch) { + self.chars.insert(ch, CharInfo::new(ch, &mut self.msdf_texture, &self.msdf_sys_handle)); + } + self.chars.get(&ch).unwrap() + } +} + +impl CharInfo { + fn new(ch : char, msdf_texture : &mut MsdfTexture, font_handle : &msdf_sys::Font) -> CharInfo { + let msdf_texture_rows_begin = msdf_texture.rows(); + msdf_sys::generate_msdf( + msdf_texture, + &font_handle, + ch as u32, + &FontRenderInfo::MSDF_PARAMS, + msdf_sys::Vector2D{ x : 1.0, y : 1.0 }, + msdf_sys::Vector2D{ x : 2.4, y : 2.4 } + ); + let msdf_texture_rows_end = msdf_texture.rows(); + CharInfo { + msdf_texture_rows : msdf_texture_rows_begin..msdf_texture_rows_end + } + } +} \ No newline at end of file diff --git a/lib/core/src/text/mod.rs b/lib/core/src/text/mod.rs index c7bf3ee045..9588d07d7d 100644 --- a/lib/core/src/text/mod.rs +++ b/lib/core/src/text/mod.rs @@ -1,121 +1,356 @@ -use basegl_backend_webgl::{Context, compile_shader, link_program}; -use basegl_core_msdf_sys as msdf_sys; -use basegl_core_fonts_base::FontsBase; - -use web_sys::WebGlRenderingContext; -use basegl_system_web::Logger; - -pub fn print_line(context : &Context, text : &str, logger : &Logger) -{ - let vert_shader = compile_shader( - &context, - WebGlRenderingContext::VERTEX_SHADER, - include_str!("msdf_vert.glsl") - ).unwrap(); -// logger.trace(|| format!("{:?}", vert_shader.as_ref().expect_err("No error?"))); - context.get_extension("OES_standard_derivatives").unwrap(); - let frag_shader = compile_shader( - &context, - WebGlRenderingContext::FRAGMENT_SHADER, - include_str!("msdf_frag.glsl") - ).unwrap(); -// logger.trace(|| format!("{:?}", frag_shader.as_ref().expect_err("No error?"))); - let program = link_program(&context, &vert_shader, &frag_shader).unwrap(); - context.use_program(Some(&program)); - - let msdf_location = context.get_uniform_location(&program, "msdf"); - let msdf_size_location = context.get_uniform_location(&program, "msdf_size"); - let bg_color_location = context.get_uniform_location(&program, "bgColor"); - let fg_color_location = context.get_uniform_location(&program, "fgColor"); - let px_range_location = context.get_uniform_location(&program, "pxRange"); - - let font_base = FontsBase::new(); - let mfont = font_base.fonts_by_name.get("DejaVuSansMono-Bold").unwrap(); - let font = msdf_sys::Font::load_from_memory(mfont); - let params = msdf_sys::MSDFParameters { - width: 32, - height: 32, - edge_coloring_angle_threshold: 3.0, - range: 2.0, - edge_threshold: 1.001, - overlap_support: true - }; - // when - let msdf = msdf_sys::MutlichannelSignedDistanceField::generate( - &font, - text.chars().next().unwrap() as u32, - ¶ms, - msdf_sys::Vector2D { x: 1.0, y: 1.0 }, - msdf_sys::Vector2D { x: 4.0, y: 4.0 } - ); - - let u8msdf = msdf.data[0..32*32*3].iter().map(|f| nalgebra::clamp(f*255.0, 0.0, 255.0) as u8).collect::>(); -// logger.trace(|| format!("{:?}", (msdf.data[0..16*16*3].to_vec()))); -// logger.trace(|| format!("{:?}", u8msdf)); - - let msdf_texture = context.create_texture(); -// context.active_texture(Context::TEXTURE0); - context.bind_texture(Context::TEXTURE_2D, msdf_texture.as_ref()); - let res = context.tex_image_2d_with_i32_and_i32_and_i32_and_format_and_type_and_opt_u8_array( - Context::TEXTURE_2D, - 0, - Context::RGB as i32, - 32, - 32, - 0, - Context::RGB, - Context::UNSIGNED_BYTE, - Some(&u8msdf) - ); - context.tex_parameteri(Context::TEXTURE_2D, Context::TEXTURE_WRAP_S, Context::CLAMP_TO_EDGE as i32); - context.tex_parameteri(Context::TEXTURE_2D, Context::TEXTURE_WRAP_T, Context::CLAMP_TO_EDGE as i32); - context.tex_parameteri(Context::TEXTURE_2D, Context::TEXTURE_MIN_FILTER, Context::LINEAR as i32); -// logger.trace(|| format!("{:?}", res.as_ref().expect_err("No error?"))); - context.uniform1i(msdf_location.as_ref(), 0); - context.uniform1i(msdf_size_location.as_ref(), 16); - context.uniform4f(bg_color_location.as_ref(), 0.0, 0.0, 0.0, 1.0); - context.uniform4f(fg_color_location.as_ref(), 255.0, 255.0, 255.0, 1.0); - context.uniform1f(px_range_location.as_ref(), 1.0); - - let vertices= [ - -1.0, -1.0, 0.0, - -1.0, 1.0, 0.0, - 1.0, 1.0, 0.0, - 1.0, 1.0, 0.0, - 1.0, -1.0, 0.0, - -1.0, -1.0, 0.0 - ]; - - let buffer = context.create_buffer().unwrap(); - context.bind_buffer(WebGlRenderingContext::ARRAY_BUFFER, Some(&buffer)); - - // Note that `Float32Array::view` is somewhat dangerous (hence the - // `unsafe`!). This is creating a raw view into our module's - // `WebAssembly.Memory` buffer, but if we allocate more pages for ourself - // (aka do a memory allocation in Rust) it'll cause the buffer to change, - // causing the `Float32Array` to be invalid. - // - // As a result, after `Float32Array::view` we have to be very careful not to - // do any memory allocations before it's dropped. - unsafe { - let vert_array = js_sys::Float32Array::view(&vertices); - - context.buffer_data_with_array_buffer_view( +use basegl_backend_webgl::{Context, compile_shader, link_program, Program, Shader}; + +use web_sys::{WebGlRenderingContext, WebGlBuffer, WebGlTexture}; +use crate::prelude::*; + +pub mod font; + +use font::FontRenderInfo; +use crate::text::font::MsdfTexture; +use js_sys::Float32Array; +use crate::display::workspace::WorkspaceData; + +#[derive(Debug)] +pub struct Color { + pub r : f32, + pub g : f32, + pub b : f32, + pub a : f32 +} + +#[derive(Debug)] +struct TextShaders { + vert_shader : Shader, + frag_shader : Shader, + program : Program +} + +#[derive(Debug)] +pub struct TextComponent { + pub text : String, + pub x : f32, + pub y : f32, + pub size : f32, + pub color : Color, + pub background_color : Color, + + workspace : Rc, + gl_shaders : TextShaders, + gl_vertex_buf : WebGlBuffer, + gl_tex_coord_buf : WebGlBuffer, + gl_msdf_texture : WebGlTexture +} + +impl TextComponent { + pub fn new( + workspace : Rc, + text : String, + x : f32, + y : f32, + size : f32, + font : &mut FontRenderInfo, + color : Color, + background_color : Color, + ) -> TextComponent { + let gl_shaders = Self::create_shaders(&workspace.context); + let gl_vertex_buf = Self::create_vertex_buf( + &workspace.context, + text.as_str(), + x, + y, + size, + ); + let gl_tex_coord_buf = Self::create_tex_coord_buf( + &workspace.context, + text.as_str(), + font, + ); + let gl_msdf_texture = Self::create_msdf_texture( + &workspace.context, + &gl_shaders.program, + font + ); + + let component = TextComponent { + text, x, y, size, workspace, color, background_color, + gl_shaders, gl_vertex_buf, gl_tex_coord_buf, gl_msdf_texture + }; + component.setup_uniforms(); + component + } + + fn create_shaders(gl_context : &Context) -> TextShaders { + gl_context.get_extension("OES_standard_derivatives") + .unwrap().unwrap(); + let vert_shader = compile_shader( + &gl_context, + WebGlRenderingContext::VERTEX_SHADER, + include_str!("msdf_vert.glsl") + ).unwrap(); + let frag_shader = compile_shader( + &gl_context, + WebGlRenderingContext::FRAGMENT_SHADER, + include_str!("msdf_frag.glsl") + ).unwrap(); + + let program = link_program(&gl_context, &vert_shader, &frag_shader) + .unwrap(); + + TextShaders { vert_shader, frag_shader, program} + } + + fn create_vertex_buf( + gl_context : &Context, + text : &str, + x : f32, + y : f32, + size : f32 + ) -> WebGlBuffer { + let y_max = y + size; + let x_step = size; + let vertices = (0..text.len()).map(|i| { + let ix = x + (i as f32) * x_step; + let ix_max = ix + x_step; + vec![ix, y, ix, y_max, ix_max, y, ix_max, + y, ix, y_max, ix_max, y_max] + }).flatten().collect::>(); + + let buffer = gl_context.create_buffer().unwrap(); + gl_context.bind_buffer( WebGlRenderingContext::ARRAY_BUFFER, - &vert_array, - WebGlRenderingContext::STATIC_DRAW, + Some(&buffer) ); + unsafe { + let float_32_array = Float32Array::view(&vertices); + gl_context.buffer_data_with_array_buffer_view( + WebGlRenderingContext::ARRAY_BUFFER, + &float_32_array, + WebGlRenderingContext::STATIC_DRAW, + ); + } + buffer } - context.vertex_attrib_pointer_with_i32(0, 3, WebGlRenderingContext::FLOAT, false, 0, 0); - context.enable_vertex_attrib_array(0); + fn create_tex_coord_buf( + gl_context : &Context, + text : &str, + font : &mut FontRenderInfo, + ) -> WebGlBuffer { + for ch in text.chars() { + font.get_char_info(ch); + } + let vertices = text.chars().map(|c| { + let msdf_rows = font.msdf_texture.rows() as f32; + let info = font.get_char_info(c); + let y_min = info.msdf_texture_rows.start as f32 / msdf_rows; + let y_max = info.msdf_texture_rows.end as f32 / msdf_rows; + vec![0.0, y_min, 0.0, y_max, 1.0, y_min, + 1.0, y_min, 0.0, y_max, 1.0, y_max] + }).flatten().collect::>(); + + let buffer = gl_context.create_buffer().unwrap(); + gl_context.bind_buffer(WebGlRenderingContext::ARRAY_BUFFER, Some(&buffer)); + unsafe { + let float_32_array = Float32Array::view(&vertices); + gl_context.buffer_data_with_array_buffer_view( + WebGlRenderingContext::ARRAY_BUFFER, + &float_32_array, + WebGlRenderingContext::STATIC_DRAW, + ); + } + buffer + } + + fn create_msdf_texture( + gl_context : &Context, + gl_program : &Program, + font : &FontRenderInfo + ) -> WebGlTexture { + let msdf_texture = gl_context.create_texture().unwrap(); + gl_context.bind_texture(Context::TEXTURE_2D, Some(&msdf_texture)); + + gl_context.tex_parameteri( + Context::TEXTURE_2D, + Context::TEXTURE_WRAP_S, + Context::CLAMP_TO_EDGE as i32 + ); + gl_context.tex_parameteri( + Context::TEXTURE_2D, + Context::TEXTURE_WRAP_T, + Context::CLAMP_TO_EDGE as i32 + ); + gl_context.tex_parameteri( + Context::TEXTURE_2D, + Context::TEXTURE_MIN_FILTER, + Context::LINEAR as i32 + ); - context.clear_color(0.0, 0.0, 0.0, 1.0); - context.clear(WebGlRenderingContext::COLOR_BUFFER_BIT); + gl_context.tex_image_2d_with_i32_and_i32_and_i32_and_format_and_type_and_opt_u8_array( + Context::TEXTURE_2D, + 0, + Context::RGB as i32, + MsdfTexture::WIDTH as i32, + font.msdf_texture.rows() as i32, + 0, + Context::RGB, + Context::UNSIGNED_BYTE, + Some(font.msdf_texture.data.as_slice()) + ).unwrap(); - context.draw_arrays( - WebGlRenderingContext::TRIANGLES, - 0, - (vertices.len() / 3) as i32, - ); -} \ No newline at end of file + let msdf_loc = gl_context.get_uniform_location(gl_program, "msdf"); + let msdf_size_loc = + gl_context.get_uniform_location(gl_program, "msdfSize"); + + gl_context.use_program(Some(gl_program)); + gl_context.uniform1i(msdf_loc.as_ref(), 0); + gl_context.uniform2f( + msdf_size_loc.as_ref(), + MsdfTexture::WIDTH as f32, + font.msdf_texture.rows() as f32 + ); + + msdf_texture + } + + fn setup_uniforms(&self) { + let gl = &self.workspace.context; + let program = &self.gl_shaders.program; + let bg_color_location = gl.get_uniform_location(program, "bgColor"); + let fg_color_location = gl.get_uniform_location(program, "fgColor"); + let px_range_location = gl.get_uniform_location(program, "pxRange"); + + gl.use_program(Some(program)); + gl.uniform4f( + bg_color_location.as_ref(), + self.background_color.r, + self.background_color.g, + self.background_color.b, + self.background_color.a + ); + gl.uniform4f( + fg_color_location.as_ref(), + self.color.r, + self.color.g, + self.color.b, + self.color.a, + ); + gl.uniform1f( + px_range_location.as_ref(), + FontRenderInfo::MSDF_PARAMS.range as f32 + ); + } + + pub fn display(&self) { + let gl = &self.workspace.context; + let program = &self.gl_shaders.program; + + gl.use_program(Some(&self.gl_shaders.program)); + + let position_location = gl.get_attrib_location(program, "position"); + gl.enable_vertex_attrib_array(position_location as u32); + gl.bind_buffer( + WebGlRenderingContext::ARRAY_BUFFER, + Some(&self.gl_vertex_buf) + ); + gl.vertex_attrib_pointer_with_i32( + position_location as u32, + 2, + WebGlRenderingContext::FLOAT, + false, + 0, + 0 + ); + + gl.bind_texture(Context::TEXTURE_2D, Some(&self.gl_msdf_texture)); + + let tex_coord_location = gl.get_attrib_location(program, "texCoord"); + assert!(tex_coord_location >= 0); + gl.enable_vertex_attrib_array(tex_coord_location as u32); + gl.bind_buffer( + WebGlRenderingContext::ARRAY_BUFFER, + Some(&self.gl_tex_coord_buf) + ); + gl.vertex_attrib_pointer_with_i32( + tex_coord_location as u32, + 2, + WebGlRenderingContext::FLOAT, + false, + 0, + 0 + ); + +// gl.clear_color(0.0, 0.0, 0.0, 1.0); +// gl.clear(WebGlRenderingContext::COLOR_BUFFER_BIT); + + gl.draw_arrays( + WebGlRenderingContext::TRIANGLES, + 0, + (self.text.chars().count()*6) as i32, + ); + } +} +// +//pub fn print_line( +// context : &Context, +// text : &str, +// +// logger : &Logger +//) +//{ +// +// context.use_program(Some(&program)); +// +// // when +// +// context.bind_texture(Context::TEXTURE_2D, msdf_texture.as_ref()); +// context.tex_parameteri(Context::TEXTURE_2D, Context::TEXTURE_WRAP_S, Context::CLAMP_TO_EDGE as i32); +// context.tex_parameteri(Context::TEXTURE_2D, Context::TEXTURE_WRAP_T, Context::CLAMP_TO_EDGE as i32); +// context.tex_parameteri(Context::TEXTURE_2D, Context::TEXTURE_MIN_FILTER, Context::LINEAR as i32); +//// logger.trace(|| format!("{:?}", res.as_ref().expect_err("No error?"))); +// context.uniform1i(msdf_location.as_ref(), 0); +// context.uniform1i(msdf_size_location.as_ref(), 16); +// +// +// let y_max = y + size; +// let vertices= (0..text.len()).map[ +// -1.0, -1.0, 0.0, +// -1.0, 1.0, 0.0, +// 1.0, 1.0, 0.0, +// 1.0, 1.0, 0.0, +// 1.0, -1.0, 0.0, +// -1.0, -1.0, 0.0 +// ]; +// +// let buffer = context.create_buffer().unwrap(); +// context.bind_buffer(WebGlRenderingContext::ARRAY_BUFFER, Some(&buffer)); +// +// // Note that `Float32Array::view` is somewhat dangerous (hence the +// // `unsafe`!). This is creating a raw view into our module's +// // `WebAssembly.Memory` buffer, but if we allocate more pages for ourself +// // (aka do a memory allocation in Rust) it'll cause the buffer to change, +// // causing the `Float32Array` to be invalid. +// // +// // As a result, after `Float32Array::view` we have to be very careful not to +// // do any memory allocations before it's dropped. +// unsafe { +// let vert_array = js_sys::Float32Array::view(&vertices); +// +// context.buffer_data_with_array_buffer_view( +// WebGlRenderingContext::ARRAY_BUFFER, +// &vert_array, +// WebGlRenderingContext::STATIC_DRAW, +// ); +// } +// +// context.vertex_attrib_pointer_with_i32(0, 3, WebGlRenderingContext::FLOAT, false, 0, 0); +// context.enable_vertex_attrib_array(0); +// +// context.clear_color(0.0, 0.0, 0.0, 1.0); +// context.clear(WebGlRenderingContext::COLOR_BUFFER_BIT); +// +// context.draw_arrays( +// WebGlRenderingContext::TRIANGLES, +// 0, +// (vertices.len() / 3) as i32, +// ); +//} \ No newline at end of file diff --git a/lib/core/src/text/msdf_frag.glsl b/lib/core/src/text/msdf_frag.glsl index b1af3bc00a..f174e353e7 100644 --- a/lib/core/src/text/msdf_frag.glsl +++ b/lib/core/src/text/msdf_frag.glsl @@ -1,23 +1,25 @@ #extension GL_OES_standard_derivatives : enable -varying highp vec2 vTextureCoord; +varying highp vec2 vTexCoord; +varying highp vec2 msdfCoord; uniform sampler2D msdf; -uniform int msdf_size; -uniform lowp float pxRange; -uniform lowp vec4 bgColor; -uniform lowp vec4 fgColor; +uniform highp vec2 msdfSize; +uniform highp float pxRange; +uniform highp vec4 bgColor; +uniform highp vec4 fgColor; highp float median(highp float r, highp float g, highp float b) { return max(min(r, g), min(max(r, g), b)); } void main() { - highp vec2 msdfUnit = pxRange/vec2(msdf_size, 0); - highp vec3 smple = texture2D(msdf, vTextureCoord).rgb; + highp vec2 msdfUnitTex = pxRange/msdfSize; + highp vec2 msdfUnitPx = msdfUnitTex/fwidth(vTexCoord); + highp vec3 smple = texture2D(msdf, vTexCoord).rgb; highp float sigDist = median(smple.r, smple.g, smple.b) - 0.5; - sigDist *= dot(msdfUnit, 0.5/fwidth(vTextureCoord)); - highp float opacity = clamp(sigDist + 0.5, 0.0, 1.0); + highp float sigDistPx = sigDist*((msdfUnitPx.x + msdfUnitPx.y)/2.0); + highp float opacity = clamp(sigDistPx + 0.5, 0.0, 1.0); gl_FragColor = mix(bgColor, fgColor, opacity); -// gl_FragColor = vec4(sigDist, 0.0, 0.0, 1.0); +// gl_FragColor = vec4(sigDist+0.5, 0.0, 0.0, 1.0); } diff --git a/lib/core/src/text/msdf_vert.glsl b/lib/core/src/text/msdf_vert.glsl index 6bcb77a40b..913a2f7452 100644 --- a/lib/core/src/text/msdf_vert.glsl +++ b/lib/core/src/text/msdf_vert.glsl @@ -1,7 +1,9 @@ -attribute vec4 position; -varying highp vec2 vTextureCoord; +attribute vec2 position; +attribute vec2 texCoord; + +varying vec2 vTexCoord; void main() { - gl_Position = position; - vTextureCoord = position.xy/2.0 + vec2(0.5, 0.5); + vTexCoord = texCoord; + gl_Position = vec4(position, 0.0, 1.0); } \ No newline at end of file From 2a4e286d57a4616c0e05e7da9923a901defb3316 Mon Sep 17 00:00:00 2001 From: Adam Obuchowicz Date: Mon, 25 Nov 2019 11:57:07 +0100 Subject: [PATCH 04/19] Much refactoring --- Cargo.toml | 2 +- build-utilities/Cargo.toml | 2 +- build-utilities/src/lib.rs | 2 + lib/core/Cargo.toml | 24 ++-- .../{fonts-base => embedded-fonts}/Cargo.toml | 6 +- lib/core/embedded-fonts/build.rs | 128 ++++++++++++++++++ lib/core/embedded-fonts/src/lib.rs | 26 ++++ lib/core/fonts-base/build.rs | 62 --------- lib/core/fonts-base/src/lib.rs | 16 --- lib/core/msdf-sys/Cargo.toml | 2 +- lib/core/msdf-sys/build.rs | 4 +- lib/core/msdf-sys/src/lib.rs | 4 +- lib/core/src/lib.rs | 15 +- lib/core/src/text/font.rs | 8 +- lib/core/src/text/msdf_frag.glsl | 7 +- 15 files changed, 197 insertions(+), 111 deletions(-) rename lib/core/{fonts-base => embedded-fonts}/Cargo.toml (76%) create mode 100644 lib/core/embedded-fonts/build.rs create mode 100644 lib/core/embedded-fonts/src/lib.rs delete mode 100644 lib/core/fonts-base/build.rs delete mode 100644 lib/core/fonts-base/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 8ce7f8829d..de7d3a3ea9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ members = [ "build-utilities", "lib/prelude", "lib/core", - "lib/core/fonts-base", + "lib/core/embedded-fonts", "lib/core/msdf-sys", "lib/backend/webgl", "lib/system/web", diff --git a/build-utilities/Cargo.toml b/build-utilities/Cargo.toml index 419fba0a61..fc03ea2c90 100644 --- a/build-utilities/Cargo.toml +++ b/build-utilities/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "basegl-build-utilities" version = "0.1.0" -authors = ["Adam Obuchowicz "] +authors = ["Enso Team "] edition = "2018" [dependencies] diff --git a/build-utilities/src/lib.rs b/build-utilities/src/lib.rs index 140b5ac12c..05322ec841 100644 --- a/build-utilities/src/lib.rs +++ b/build-utilities/src/lib.rs @@ -1,6 +1,8 @@ use std::{fs, path}; /// Download the release package from github +/// +/// The project_url should be a project's main page on github. pub fn github_download( project_url : &str, version : &str, diff --git a/lib/core/Cargo.toml b/lib/core/Cargo.toml index b85816b638..4cd3bfa63f 100644 --- a/lib/core/Cargo.toml +++ b/lib/core/Cargo.toml @@ -11,18 +11,18 @@ crate-type = ["rlib", "cdylib"] default = ["console_error_panic_hook"] [dependencies] -basegl-prelude = { version = "0.1.0" , path = "../prelude" } -basegl-system-web = { version = "0.1.0" , path = "../system/web" } -basegl-backend-webgl = { version = "0.1.0" , path = "../backend/webgl" } -basegl-core-fonts-base = { version = "0.1.0" , path = "fonts-base" } -basegl-core-msdf-sys = { version = "0.1.0" , path = "msdf-sys" } -wasm-bindgen = { version = "^0.2" , features = ["nightly"] } -js-sys = { version = "0.3.28" } -failure = { version = "0.1.5" } -derive_more = { version = "0.15.0" } -shrinkwraprs = { version = "0.2.1" } -itertools = { version = "0.8" } -nalgebra = { version = "0.18.1" } +basegl-prelude = { version = "0.1.0" , path = "../prelude" } +basegl-system-web = { version = "0.1.0" , path = "../system/web" } +basegl-backend-webgl = { version = "0.1.0" , path = "../backend/webgl" } +basegl-core-embedded-fonts = { version = "0.1.0" , path = "embedded-fonts" } +basegl-core-msdf-sys = { version = "0.1.0" , path = "msdf-sys" } +wasm-bindgen = { version = "^0.2" , features = ["nightly"] } +js-sys = { version = "0.3.28" } +failure = { version = "0.1.5" } +derive_more = { version = "0.15.0" } +shrinkwraprs = { version = "0.2.1" } +itertools = { version = "0.8" } +nalgebra = { version = "0.18.1" } # TODO: disable for release console_error_panic_hook = { version = "0.1.1", optional = true } diff --git a/lib/core/fonts-base/Cargo.toml b/lib/core/embedded-fonts/Cargo.toml similarity index 76% rename from lib/core/fonts-base/Cargo.toml rename to lib/core/embedded-fonts/Cargo.toml index d2f0578042..4caae4f756 100644 --- a/lib/core/fonts-base/Cargo.toml +++ b/lib/core/embedded-fonts/Cargo.toml @@ -1,7 +1,7 @@ [package] -name = "basegl-core-fonts-base" +name = "basegl-core-embedded-fonts" version = "0.1.0" -authors = ["Adam Obuchowicz "] +authors = ["Enso Team "] edition = "2018" [lib] @@ -14,4 +14,4 @@ basegl-prelude = { version = "0.1.0", path="../../prelude"} [build-dependencies] basegl-build-utilities = { version = "0.1.0", path="../../../build-utilities" } -zip = "0.5" \ No newline at end of file +zip = "0.5" diff --git a/lib/core/embedded-fonts/build.rs b/lib/core/embedded-fonts/build.rs new file mode 100644 index 0000000000..16f0f99676 --- /dev/null +++ b/lib/core/embedded-fonts/build.rs @@ -0,0 +1,128 @@ +use std::{path, env, fs, io}; +use std::io::Write; + +// ===================== +// === FillMapRsFile === +// ===================== + +/// Generated file with code filling embedded fonts map +pub struct FillMapRsFile { + file : fs::File +} + +impl FillMapRsFile { + fn create>(path : P) -> io::Result { + let mut file = fs::File::create(path)?; + writeln!(file, "{{")?; + Ok(FillMapRsFile{ file }) + } + + fn add_font_inserting_line(&mut self, font_name : &str, font_file : &str) + -> io::Result<()> { + writeln!( + self.file, + " fonts_by_name.insert(\"{}\", include_bytes!(\"{}\"));", + font_name, + font_file + ) + } + + fn close_block(&mut self) -> io::Result<()> { + writeln!(self.file, "}}") + } +} + +// ==================== +// === DejaVu fonts === +// ==================== + +mod deja_vu { + use std::path; + use basegl_build_utilities::github_download; + use crate::FillMapRsFile; + + pub const PACKAGE_NAME : &str = "dejavu-fonts-ttf-2.37.zip"; + pub const PACKAGE_VERSION : &str = "version_2_37"; + pub const PROJECT_URL : &str = + "https://github.com/dejavu-fonts/dejavu-fonts/"; + + pub const PACKAGE_FONTS_PREFIX: &str = "dejavu-fonts-ttf-2.37/ttf"; + + pub fn font_file_from_font_name(font_name : &str) -> String { + return format!("{}.ttf", font_name); + } + + pub fn extract_font(package_path : &path::Path, font_name : &str) { + let font_file = font_file_from_font_name(font_name); + let font_package_path = format!("{}/{}", + PACKAGE_FONTS_PREFIX, + font_file + ); + + let mut archive = zip::ZipArchive::new( + std::fs::File::open(package_path).unwrap() + ).unwrap(); + let mut input = archive.by_name( + font_package_path.as_str() + ).unwrap(); + let mut output = std::fs::File::create( + package_path.parent().unwrap().join(font_file) + ).unwrap(); + std::io::copy(&mut input, &mut output).unwrap(); + } + + pub const FONTS_TO_EXTRACT : &[&str] = &[ + "DejaVuSans", + "DejaVuSans-ExtraLight", + "DejaVuSansMono", + "DejaVuSansMono-Bold", + "DejaVuSansMono-Oblique", + "DejaVuSansCondensed", + "DejaVuSerif", + "DejaVuSerifCondensed", + ]; + + pub fn extract_all_fonts(package_path : &path::Path) { + for font_name in FONTS_TO_EXTRACT { + extract_font(package_path, font_name); + } + } + + pub fn download_and_extract_all_fonts(out_dir : &path::Path) { + github_download( + PROJECT_URL, + PACKAGE_VERSION, + PACKAGE_NAME, + &out_dir + ); + + let package_path = out_dir.join(PACKAGE_NAME); + extract_all_fonts(package_path.as_path()); + } + + pub fn add_entries_to_fill_map_rs(file : &mut FillMapRsFile) { + for font_name in FONTS_TO_EXTRACT { + let font_file = font_file_from_font_name(font_name); + file.add_font_inserting_line( + font_name, + font_file.as_str() + ).unwrap(); + } + } +} + +fn main() { + let out = env::var("OUT_DIR").unwrap(); + let out_dir = path::Path::new(&out); + let fill_map_rs_path = out_dir.join("fill_map.rs"); + + let mut fill_map_rs_file = + FillMapRsFile::create(fill_map_rs_path).unwrap(); + + deja_vu::download_and_extract_all_fonts(out_dir); + deja_vu::add_entries_to_fill_map_rs(&mut fill_map_rs_file); + + fill_map_rs_file.close_block().unwrap(); + + println!("cargo:rerun-if-changed=build.rs"); +} \ No newline at end of file diff --git a/lib/core/embedded-fonts/src/lib.rs b/lib/core/embedded-fonts/src/lib.rs new file mode 100644 index 0000000000..624f1017a5 --- /dev/null +++ b/lib/core/embedded-fonts/src/lib.rs @@ -0,0 +1,26 @@ +use basegl_prelude::*; + +/// A base of built-in fonts in application +/// +/// The structure keeps only a binary data in ttf format. The data should be +/// then interpreted by user (e.g. by using msdf-sys crate) +/// +/// For list of embedded fonts, see FONTS_TO_EXTRACT constant in `build.rs` +pub struct EmbeddedFonts { + pub font_data_by_name: HashMap<&'static str, &'static [u8]> +} + +impl EmbeddedFonts { + /// Creates an embedded fonts base filled with data + /// + /// For list of embedded fonts, see `FONTS_TO_EXTRACT` constant in + /// `build.rs` + pub fn create_and_fill() -> EmbeddedFonts { + let mut fonts_by_name : HashMap<&'static str, &'static [u8]> + = HashMap::new(); + include!(concat!(env!("OUT_DIR"), "/fill_map.rs")); + EmbeddedFonts { + font_data_by_name: fonts_by_name + } + } +} \ No newline at end of file diff --git a/lib/core/fonts-base/build.rs b/lib/core/fonts-base/build.rs deleted file mode 100644 index 9ad9a26f50..0000000000 --- a/lib/core/fonts-base/build.rs +++ /dev/null @@ -1,62 +0,0 @@ -use basegl_build_utilities::github_download; -use std::{path, env, fs}; -use std::io::Write; - -pub const PACKAGE_NAME : &str = "dejavu-fonts-ttf-2.37.zip"; -pub const VERSION : &str = "version_2_37"; -pub const PROJECT_URL : &str = - "https://github.com/dejavu-fonts/dejavu-fonts/"; -pub const PACKAGE_FONTS_PREFIX : &str = "dejavu-fonts-ttf-2.37/ttf"; -pub const FONTS_TO_EXTRACT : &[&str] = &[ - "DejaVuSansMono", - "DejaVuSansMono-Bold" -]; - -fn extract_dejavu_font(package_path : &path::Path, font_name : &str) { - let font_file = format!("{}.ttf", font_name); - let font_package_path = format!("{}/{}", - PACKAGE_FONTS_PREFIX, - font_file - ); - - let mut archive = zip::ZipArchive::new( - std::fs::File::open(package_path).unwrap() - ).unwrap(); - let mut input = archive.by_name( - font_package_path.as_str() - ).unwrap(); - let mut output = std::fs::File::create( - package_path.parent().unwrap().join(font_file) - ).unwrap(); - std::io::copy(&mut input, &mut output).unwrap(); -} - -fn main() { - let out = env::var("OUT_DIR").unwrap(); - let out_dir = path::Path::new(&out); - let package_path = out_dir.join(PACKAGE_NAME); - let fill_map_rs_path = out_dir.join("fill_map.rs"); - - github_download( - PROJECT_URL, - VERSION, - PACKAGE_NAME, - path::Path::new(&out_dir) - ); - - for font_name in FONTS_TO_EXTRACT { - extract_dejavu_font(package_path.as_path(), font_name); - } - - let mut fill_map_rs_file = fs::File::create(fill_map_rs_path).unwrap(); - writeln!(fill_map_rs_file, "{{").unwrap(); - for font_name in FONTS_TO_EXTRACT { - writeln!(fill_map_rs_file, - " fonts_by_name.insert(\"{}\", include_bytes!(\"{}.ttf\"));", - font_name, - font_name - ).unwrap(); - } - writeln!(fill_map_rs_file, "}}").unwrap(); - println!("cargo:rerun-if-changed=build.rs"); -} \ No newline at end of file diff --git a/lib/core/fonts-base/src/lib.rs b/lib/core/fonts-base/src/lib.rs deleted file mode 100644 index bffb695c57..0000000000 --- a/lib/core/fonts-base/src/lib.rs +++ /dev/null @@ -1,16 +0,0 @@ -use basegl_prelude::*; - -pub struct FontsBase { - pub fonts_by_name : HashMap<&'static str, &'static [u8]> -} - -impl FontsBase { - pub fn new() -> FontsBase { - let mut fonts_by_name : HashMap<&'static str, &'static [u8]> - = HashMap::new(); - include!(concat!(env!("OUT_DIR"), "/fill_map.rs")); - FontsBase { - fonts_by_name - } - } -} \ No newline at end of file diff --git a/lib/core/msdf-sys/Cargo.toml b/lib/core/msdf-sys/Cargo.toml index 180964ca90..6d217eee4a 100644 --- a/lib/core/msdf-sys/Cargo.toml +++ b/lib/core/msdf-sys/Cargo.toml @@ -15,7 +15,7 @@ vector2d = "2.2.0" [dev-dependencies] wasm-bindgen-test = "0.3.3" futures = "" -basegl-core-fonts-base = { version = "0.1.0", path="../fonts-base" } +basegl-core-embedded-fonts = { version = "0.1.0", path="../embedded-fonts" } [build-dependencies] basegl-build-utilities = { version = "0.1.0", path="../../../build-utilities" } \ No newline at end of file diff --git a/lib/core/msdf-sys/build.rs b/lib/core/msdf-sys/build.rs index 6d4471af1c..7d76e11e44 100644 --- a/lib/core/msdf-sys/build.rs +++ b/lib/core/msdf-sys/build.rs @@ -4,7 +4,7 @@ mod msdfgen_wasm { use crate::github_download; use std::path; - pub const VERSION : &str = "v1.0"; + pub const VERSION : &str = "v1.0.1"; pub const FILENAME : &str = "msdfgen_wasm.js"; pub const PROJECT_URL : &str = "https://github.com/luna/msdfgen-wasm"; @@ -14,7 +14,7 @@ mod msdfgen_wasm { VERSION, FILENAME, path::Path::new(".") // Note [Downloading to src dir] - ); + ) } /* Note [Downloading to src dir] diff --git a/lib/core/msdf-sys/src/lib.rs b/lib/core/msdf-sys/src/lib.rs index efe416eb2a..9c4749bbb9 100644 --- a/lib/core/msdf-sys/src/lib.rs +++ b/lib/core/msdf-sys/src/lib.rs @@ -82,8 +82,8 @@ pub struct MSDFParameters { pub overlap_support : bool } -pub const MAX_MSDF_SIZE: usize = 64; -pub const MSDF_CHANNELS_COUNT: usize = 3; +pub const MAX_MSDF_SIZE : usize = 64; +pub const MSDF_CHANNELS_COUNT : usize = 3; ///// Generate Mutlichannel Signed Distance Field (MSDF) for one glyph ///// diff --git a/lib/core/src/lib.rs b/lib/core/src/lib.rs index 17620ddebe..bbebbe47e1 100644 --- a/lib/core/src/lib.rs +++ b/lib/core/src/lib.rs @@ -30,7 +30,7 @@ pub mod utils; use display::world::World; use wasm_bindgen::prelude::*; -use basegl_core_fonts_base::FontsBase; +use basegl_core_embedded_fonts::EmbeddedFonts; use crate::text::font::FontRenderInfo; use itertools::iproduct; @@ -45,19 +45,24 @@ pub fn start() { let mut world_data = world.data.borrow_mut(); let workspace = world_data.workspaces.items[workspace_id].as_mut().unwrap(); - let font_base = FontsBase::new(); + let font_base = EmbeddedFonts::create_and_fill(); let mut fonts = [ + FontRenderInfo::from_embedded(&font_base, "DejaVuSans".to_string()), FontRenderInfo::from_embedded(&font_base, "DejaVuSansMono".to_string()), FontRenderInfo::from_embedded(&font_base, "DejaVuSansMono-Bold".to_string()), + FontRenderInfo::from_embedded(&font_base, "DejaVuSansMono-Oblique".to_string()), + FontRenderInfo::from_embedded(&font_base, "DejaVuSansCondensed".to_string()), + FontRenderInfo::from_embedded(&font_base, "DejaVuSerif".to_string()), + FontRenderInfo::from_embedded(&font_base, "DejaVuSerifCondensed".to_string()), ]; - let sizes = [0.02, 0.025, 0.03, 0.04, 0.05, 0.06, 0.08, 0.1]; + let sizes = [0.024, 0.032, 0.048, 0.064]; for (i, (font, size)) in iproduct!(0..fonts.len(), sizes.iter()).enumerate() { let text_compnent = crate::text::TextComponent::new( workspace.data.clone(), - "abcdefghijklmnopqrstuvwxyz1234567890!ABCDEFGHIJKLMNOPQRSTUVWXYZ@#$%^&*()-=_+,./<>?;\':[]{}żźć„”ńµąśðæŋ’ə…łπœę©ß←↓→óþ²³¢€½§·«»–ş".to_string(), + "To be, or not to be, that is the question: Whether 'tis nobler in the mind to suffer The slings and arrows of outrageous fortune, Or to take arms against a sea of troubles And by opposing end them.".to_string(), -0.95, - 0.9 - 0.1*(i as f32), + 0.9 - 0.064*(i as f32), *size, &mut fonts[font], text::Color {r: 1.0, g: 1.0, b: 1.0, a: 1.0}, diff --git a/lib/core/src/text/font.rs b/lib/core/src/text/font.rs index df76f28474..53cdc79ea0 100644 --- a/lib/core/src/text/font.rs +++ b/lib/core/src/text/font.rs @@ -1,6 +1,6 @@ use crate::prelude::*; use basegl_core_msdf_sys as msdf_sys; -use basegl_core_fonts_base::FontsBase; +use basegl_core_embedded_fonts::EmbeddedFonts; pub struct MsdfTexture { pub data : Vec @@ -56,10 +56,10 @@ impl FontRenderInfo { } pub fn from_embedded( - base : &FontsBase, + base : &EmbeddedFonts, name : String ) -> FontRenderInfo { - let mfont = base.fonts_by_name.get(name.as_str()).unwrap(); + let mfont = base.font_data_by_name.get(name.as_str()).unwrap(); crate::text::font::FontRenderInfo::new( name, mfont ) @@ -82,7 +82,7 @@ impl CharInfo { ch as u32, &FontRenderInfo::MSDF_PARAMS, msdf_sys::Vector2D{ x : 1.0, y : 1.0 }, - msdf_sys::Vector2D{ x : 2.4, y : 2.4 } + msdf_sys::Vector2D{ x : 2.0, y : 2.25 } ); let msdf_texture_rows_end = msdf_texture.rows(); CharInfo { diff --git a/lib/core/src/text/msdf_frag.glsl b/lib/core/src/text/msdf_frag.glsl index f174e353e7..6b8c3e1259 100644 --- a/lib/core/src/text/msdf_frag.glsl +++ b/lib/core/src/text/msdf_frag.glsl @@ -18,8 +18,11 @@ void main() { highp vec2 msdfUnitPx = msdfUnitTex/fwidth(vTexCoord); highp vec3 smple = texture2D(msdf, vTexCoord).rgb; highp float sigDist = median(smple.r, smple.g, smple.b) - 0.5; + + highp float dpiDilate = (msdfUnitPx.x + msdfUnitPx.y) < pxRange*0.9 ? 1.0 : 0.0; + highp float sigDistPx = sigDist*((msdfUnitPx.x + msdfUnitPx.y)/2.0); - highp float opacity = clamp(sigDistPx + 0.5, 0.0, 1.0); + highp float opacity = clamp(sigDistPx + 0.5 + dpiDilate*0.1, 0.0, 1.0); gl_FragColor = mix(bgColor, fgColor, opacity); -// gl_FragColor = vec4(sigDist+0.5, 0.0, 0.0, 1.0); +// gl_FragColor = vec4(sigDist+0.5, dpiDilate, 0.0, 1.0); } From 60dfe379604265e9b6e324810f6d65b67d908299 Mon Sep 17 00:00:00 2001 From: Adam Obuchowicz Date: Mon, 25 Nov 2019 16:32:55 +0100 Subject: [PATCH 05/19] Tests WIP --- lib/core/embedded-fonts/src/lib.rs | 14 +++ lib/core/msdf-sys/src/lib.rs | 105 ++++++++-------- lib/core/src/lib.rs | 16 +-- lib/core/src/text/font.rs | 184 +++++++++++++++++++++++------ lib/core/src/text/mod.rs | 158 +++++++------------------ script/rust/src/bin/test-all.rs | 8 +- script/test.sh | 3 +- 7 files changed, 282 insertions(+), 206 deletions(-) diff --git a/lib/core/embedded-fonts/src/lib.rs b/lib/core/embedded-fonts/src/lib.rs index 624f1017a5..361fa8f076 100644 --- a/lib/core/embedded-fonts/src/lib.rs +++ b/lib/core/embedded-fonts/src/lib.rs @@ -23,4 +23,18 @@ impl EmbeddedFonts { font_data_by_name: fonts_by_name } } +} + +#[cfg(test)] +mod test { + use crate::EmbeddedFonts; + + #[test] + fn loading_embedded_fonts() { + let fonts = EmbeddedFonts::create_and_fill(); + let example_font = fonts.font_data_by_name.get("DejaVuSans").unwrap(); + assert_eq!(0x00, example_font[0]); + assert_eq!(0x01, example_font[1]); + assert_eq!(0x1d, example_font[example_font.len()-1]); + } } \ No newline at end of file diff --git a/lib/core/msdf-sys/src/lib.rs b/lib/core/msdf-sys/src/lib.rs index 9c4749bbb9..37936d6b9c 100644 --- a/lib/core/msdf-sys/src/lib.rs +++ b/lib/core/msdf-sys/src/lib.rs @@ -18,7 +18,11 @@ pub use vector2d::Vector2D; // === Initialization === // ====================== -pub fn set_library_initialized_callback(callback : F) +/// Add initialization callback +/// +/// The callback passed as argument will be called once the msdfgen libirary +/// will be initialized. +pub fn run_once_initialized(callback : F) where F : 'static + FnOnce() { if is_emscripten_runtime_initialized() { callback() @@ -128,65 +132,74 @@ mod tests { use wasm_bindgen_test::wasm_bindgen_test; use internal::msdfgen_max_msdf_size; use crate::*; - use basegl_core_fonts_base::FontsBase; + use basegl_core_embedded_fonts::EmbeddedFonts; use std::future::Future; use std::pin::Pin; use std::task::{Context, Poll}; - struct InitializationFuture { - initialized : F + /// The future for running test after initialization + struct TestAfterInit { + test : F + } + + impl TestAfterInit { + fn schedule(test : F) -> TestAfterInit { + TestAfterInit { test } + } } - impl Future for InitializationFuture { + impl Future for TestAfterInit { + type Output = (); - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) + -> Poll { + if is_emscripten_runtime_initialized() { - (self.initialized)(); + (self.test)(); Poll::Ready(()) } else { let waker = cx.waker().clone(); - set_library_initialized_callback(move || waker.wake()); + run_once_initialized(move || waker.wake()); Poll::Pending } } } + #[wasm_bindgen_test(async)] fn generate_msdf_for_capital_a() -> impl Future{ - InitializationFuture { - initialized : || { - // given - let font_base = FontsBase::new(); - let font = Font::load_from_memory( - font_base.fonts_by_name.get("DejaVuSansMono-Bold").unwrap() - ); - let params = MSDFParameters { - width: 32, - height: 32, - edge_coloring_angle_threshold: 3.0, - range: 2.0, - edge_threshold: 1.001, - overlap_support: true - }; - // when - let mut msdf = Vec::::new(); - generate_msdf( - &mut msdf, - &font, - 'A' as u32, - ¶ms, - Vector2D { x: 1.0, y: 1.0 }, - Vector2D { x: 0.0, y: 0.0 } - ); - // then - // Note [asserts] - assert_eq!(0.42730755, msdf[0]); - assert_eq!(0.75, msdf[10]); - assert_eq!(-9.759168, msdf[msdf.len()-1]); - } - } + TestAfterInit::schedule(|| { + // given + let font_base = EmbeddedFonts::create_and_fill(); + let font = Font::load_from_memory( + font_base.font_data_by_name.get("DejaVuSansMono-Bold").unwrap() + ); + let params = MSDFParameters { + width: 32, + height: 32, + edge_coloring_angle_threshold: 3.0, + range: 2.0, + edge_threshold: 1.001, + overlap_support: true + }; + // when + let mut msdf = Vec::::new(); + generate_msdf( + &mut msdf, + &font, + 'A' as u32, + ¶ms, + Vector2D { x: 1.0, y: 1.0 }, + Vector2D { x: 0.0, y: 0.0 } + ); + // then + // Note [asserts] + assert_eq!(0.42730755, msdf[0]); + assert_eq!(0.75, msdf[10]); + assert_eq!(-9.759168, msdf[msdf.len()-1]); + }) } /* Note [asserts] @@ -197,14 +210,8 @@ mod tests { #[wasm_bindgen_test(async)] fn msdf_data_limits() -> impl Future { - InitializationFuture { - initialized: || { - assert!(MAX_MSDF_SIZE <= msdfgen_max_msdf_size()); - } - } - } - #[wasm_bindgen_test] - fn test() { - assert!(true) + TestAfterInit::schedule(|| { + assert!(MAX_MSDF_SIZE <= msdfgen_max_msdf_size()); + }) } } diff --git a/lib/core/src/lib.rs b/lib/core/src/lib.rs index bbebbe47e1..0074a9f2ee 100644 --- a/lib/core/src/lib.rs +++ b/lib/core/src/lib.rs @@ -37,7 +37,7 @@ use itertools::iproduct; #[wasm_bindgen(start)] pub fn start() { utils::set_panic_hook(); - basegl_core_msdf_sys::set_library_initialized_callback(|| { + basegl_core_msdf_sys::run_once_initialized(|| { let world = World::new(); let workspace_id = world.add_workspace("canvas"); @@ -47,13 +47,13 @@ pub fn start() { let font_base = EmbeddedFonts::create_and_fill(); let mut fonts = [ - FontRenderInfo::from_embedded(&font_base, "DejaVuSans".to_string()), - FontRenderInfo::from_embedded(&font_base, "DejaVuSansMono".to_string()), - FontRenderInfo::from_embedded(&font_base, "DejaVuSansMono-Bold".to_string()), - FontRenderInfo::from_embedded(&font_base, "DejaVuSansMono-Oblique".to_string()), - FontRenderInfo::from_embedded(&font_base, "DejaVuSansCondensed".to_string()), - FontRenderInfo::from_embedded(&font_base, "DejaVuSerif".to_string()), - FontRenderInfo::from_embedded(&font_base, "DejaVuSerifCondensed".to_string()), + FontRenderInfo::from_embedded(&font_base, "DejaVuSans"), + FontRenderInfo::from_embedded(&font_base, "DejaVuSansMono"), + FontRenderInfo::from_embedded(&font_base, "DejaVuSansMono-Bold"), + FontRenderInfo::from_embedded(&font_base, "DejaVuSansMono-Oblique"), + FontRenderInfo::from_embedded(&font_base, "DejaVuSansCondensed"), + FontRenderInfo::from_embedded(&font_base, "DejaVuSerif"), + FontRenderInfo::from_embedded(&font_base, "DejaVuSerifCondensed"), ]; let sizes = [0.024, 0.032, 0.048, 0.064]; diff --git a/lib/core/src/text/font.rs b/lib/core/src/text/font.rs index 53cdc79ea0..8ced1b91e4 100644 --- a/lib/core/src/text/font.rs +++ b/lib/core/src/text/font.rs @@ -2,6 +2,18 @@ use crate::prelude::*; use basegl_core_msdf_sys as msdf_sys; use basegl_core_embedded_fonts::EmbeddedFonts; +// ==================== +// === MSDF Texture === +// ==================== + +/// Texture with msdf for all loaded glyphs of font +/// +/// This structure keeps texture data in 8-bit-per-channel RGB format, which +/// is ready to be passed to webgl texImage2D. The texture contains MSDFs for +/// all loaded glyphs, organized in vertical column. +/// +/// It implements Extend trait making possible to pass this structure +/// as an output argument for `basegl_core_msdf_sys::generate_msdf` function pub struct MsdfTexture { pub data : Vec } @@ -9,40 +21,59 @@ pub struct MsdfTexture { impl MsdfTexture { pub const WIDTH : usize = 32; + /// Number of rows in texture pub fn rows(&self) -> usize { - self.data.len()/(3*Self::WIDTH) + self.data.len()/(msdf_sys::MSDF_CHANNELS_COUNT*Self::WIDTH) + } + + fn convert_cell_from_f32(value : f32) -> u8 { + nalgebra::clamp(value*255.0, 0.0, 255.0) as u8 } } impl Extend for MsdfTexture { + /// Extends texture with new MSDF data in f32 format fn extend>(&mut self, iter: T) { self.data.extend( - iter.into_iter().map(|float| nalgebra::clamp(float*255.0, 0.0, 255.0) as u8) + iter.into_iter().map(Self::convert_cell_from_f32) ); } } -pub struct FontRenderInfo { - pub name : String, - pub msdf_sys_handle : msdf_sys::Font, - pub msdf_texture : MsdfTexture, - chars : HashMap -} +// ================= +// === Char info === +// ================= -pub struct CharInfo { +/// A single character data used for rendering +/// +/// For now it has only information which fragment of `MsdfTexture` keeps MSDF +/// of this character +pub struct CharRenderInfo { pub msdf_texture_rows : std::ops::Range, } +/// A single font data used for rendering +/// +/// The data for individual characters are load on demand +pub struct FontRenderInfo { + pub name : String, + pub msdf_sys_handle : msdf_sys::Font, + pub msdf_texture : MsdfTexture, + chars : HashMap +} + impl FontRenderInfo { - pub const MSDF_PARAMS : msdf_sys::MSDFParameters = msdf_sys::MSDFParameters { - width: MsdfTexture::WIDTH, - height: MsdfTexture::WIDTH, - edge_coloring_angle_threshold: 3.0, - range: 8.0, - edge_threshold: 1.001, - overlap_support: true + pub const MSDF_PARAMS : msdf_sys::MSDFParameters = + msdf_sys::MSDFParameters { + width : MsdfTexture::WIDTH, + height : MsdfTexture::WIDTH, + edge_coloring_angle_threshold : 3.0, + range : 8.0, + edge_threshold : 1.001, + overlap_support : true }; + /// Create render info for font data in memory pub fn new( name : String, font_data : &[u8], @@ -55,38 +86,123 @@ impl FontRenderInfo { } } + /// Create render info for one of embedded fonts pub fn from_embedded( base : &EmbeddedFonts, - name : String + name : &'static str ) -> FontRenderInfo { - let mfont = base.font_data_by_name.get(name.as_str()).unwrap(); + let font_data = base.font_data_by_name.get(name).unwrap(); crate::text::font::FontRenderInfo::new( - name, mfont + name.to_string(), font_data ) } - pub fn get_char_info(&mut self, ch : char) -> &CharInfo { - if !self.chars.contains_key(&ch) { - self.chars.insert(ch, CharInfo::new(ch, &mut self.msdf_texture, &self.msdf_sys_handle)); - } - self.chars.get(&ch).unwrap() - } -} - -impl CharInfo { - fn new(ch : char, msdf_texture : &mut MsdfTexture, font_handle : &msdf_sys::Font) -> CharInfo { - let msdf_texture_rows_begin = msdf_texture.rows(); + /// Load char render info + pub fn load_char(&mut self, ch : char) { + let msdf_texture_rows_begin = self.msdf_texture.rows(); msdf_sys::generate_msdf( - msdf_texture, - &font_handle, + &mut self.msdf_texture, + &self.msdf_sys_handle, ch as u32, &FontRenderInfo::MSDF_PARAMS, + // TODO [AO] should be soon loaded from font info msdf_sys::Vector2D{ x : 1.0, y : 1.0 }, + // TODO [AO] should be soon loaded from font info msdf_sys::Vector2D{ x : 2.0, y : 2.25 } ); - let msdf_texture_rows_end = msdf_texture.rows(); - CharInfo { + let msdf_texture_rows_end = self.msdf_texture.rows(); + let char_info = CharRenderInfo { msdf_texture_rows : msdf_texture_rows_begin..msdf_texture_rows_end + }; + self.chars.insert(ch, char_info); + } + + /// Get or create render info for one character + pub fn get_or_create_char_info(&mut self, ch : char) -> &CharRenderInfo { + if !self.chars.contains_key(&ch) { + self.load_char(ch); + } + self.chars.get(&ch).unwrap() + } +} + + +#[cfg(test)] +mod test { + use crate::text::font::{MsdfTexture, FontRenderInfo}; + use basegl_core_msdf_sys as msdf_sys; + use basegl_core_embedded_fonts::EmbeddedFonts; + use wasm_bindgen_test::wasm_bindgen_test; + + const TEST_FONT_NAME : &str = "DejaVuSansMono-Bold"; + + fn create_test_font_render_info() -> FontRenderInfo { + let mut embedded_fonts = EmbeddedFonts::create_and_fill(); + FontRenderInfo::from_embedded( + &mut embedded_fonts, + TEST_FONT_NAME + ) + } + + #[test] + fn extending_msdf_texture() { + let mut texture = MsdfTexture { + data : Vec::new() + }; + let msdf_values: &[f32] = &[-0.5, 0.0, 0.25, 0.5, 0.75, 1.0, 1.25]; + texture.extend(msdf_values[..4].iter().cloned()); + texture.extend(msdf_values[4..].iter().cloned()); + + assert_eq!([0, 0, 63, 127, 191, 255, 255], texture.data.as_slice()); + } + + #[wasm_bindgen_test] + fn empty_font_render_info() { + let font_render_info = create_test_font_render_info(); + + assert_eq!(TEST_FONT_NAME, font_render_info.name); + assert_eq!(0, font_render_info.msdf_texture.data.len()); + assert_eq!(0, font_render_info.chars.len()); + } + + + #[wasm_bindgen_test] + fn loading_chars() { + let mut font_render_info = create_test_font_render_info(); + + font_render_info.load_char('A'); + font_render_info.load_char('B'); + + let expected_texture_size = MsdfTexture::WIDTH * MsdfTexture::WIDTH * + msdf_sys::MAX_MSDF_SIZE * msdf_sys::MSDF_CHANNELS_COUNT * 2; + + assert_eq!(MsdfTexture::WIDTH*2, font_render_info.msdf_texture.rows()); + assert_eq!(expected_texture_size, + font_render_info.msdf_texture.data.len()); + assert_eq!(2, font_render_info.chars.len()); + + let first_char = font_render_info.chars.get(&'A').unwrap(); + let second_char = font_render_info.chars.get(&'B').unwrap(); + + assert_eq!(0..MsdfTexture::WIDTH, first_char.msdf_texture_rows); + assert_eq!(MsdfTexture::WIDTH..2*MsdfTexture::WIDTH, + second_char.msdf_texture_rows); + } + + #[wasm_bindgen_test] + fn getting_or_creating_char() { + let mut font_render_info = create_test_font_render_info(); + + { + let char_info = font_render_info.get_or_create_char_info('A'); + assert_eq!(0..MsdfTexture::WIDTH, char_info.msdf_texture_rows); + } + assert_eq!(1, font_render_info.chars.len()); + + { + let char_info = font_render_info.get_or_create_char_info('A'); + assert_eq!(0..MsdfTexture::WIDTH, char_info.msdf_texture_rows); } + assert_eq!(1, font_render_info.chars.len()); } } \ No newline at end of file diff --git a/lib/core/src/text/mod.rs b/lib/core/src/text/mod.rs index 9588d07d7d..6c985e4683 100644 --- a/lib/core/src/text/mod.rs +++ b/lib/core/src/text/mod.rs @@ -1,4 +1,4 @@ -use basegl_backend_webgl::{Context, compile_shader, link_program, Program, Shader}; +use basegl_backend_webgl::{Context, compile_shader, link_program, Program, }; use web_sys::{WebGlRenderingContext, WebGlBuffer, WebGlTexture}; use crate::prelude::*; @@ -18,13 +18,6 @@ pub struct Color { pub a : f32 } -#[derive(Debug)] -struct TextShaders { - vert_shader : Shader, - frag_shader : Shader, - program : Program -} - #[derive(Debug)] pub struct TextComponent { pub text : String, @@ -35,7 +28,7 @@ pub struct TextComponent { pub background_color : Color, workspace : Rc, - gl_shaders : TextShaders, + gl_program : Program, gl_vertex_buf : WebGlBuffer, gl_tex_coord_buf : WebGlBuffer, gl_msdf_texture : WebGlTexture @@ -52,7 +45,7 @@ impl TextComponent { color : Color, background_color : Color, ) -> TextComponent { - let gl_shaders = Self::create_shaders(&workspace.context); + let gl_program = Self::create_program(&workspace.context); let gl_vertex_buf = Self::create_vertex_buf( &workspace.context, text.as_str(), @@ -67,38 +60,67 @@ impl TextComponent { ); let gl_msdf_texture = Self::create_msdf_texture( &workspace.context, - &gl_shaders.program, + &gl_program, font ); let component = TextComponent { text, x, y, size, workspace, color, background_color, - gl_shaders, gl_vertex_buf, gl_tex_coord_buf, gl_msdf_texture + gl_program, gl_vertex_buf, gl_tex_coord_buf, gl_msdf_texture }; component.setup_uniforms(); component } - fn create_shaders(gl_context : &Context) -> TextShaders { + fn create_program(gl_context : &Context) -> Program { gl_context.get_extension("OES_standard_derivatives") .unwrap().unwrap(); + let vert_shader = compile_shader( &gl_context, WebGlRenderingContext::VERTEX_SHADER, include_str!("msdf_vert.glsl") ).unwrap(); + let frag_shader = compile_shader( &gl_context, WebGlRenderingContext::FRAGMENT_SHADER, include_str!("msdf_frag.glsl") ).unwrap(); - let program = link_program(&gl_context, &vert_shader, &frag_shader) - .unwrap(); + link_program(&gl_context, &vert_shader, &frag_shader).unwrap() + } - TextShaders { vert_shader, frag_shader, program} + fn create_buffer( + gl_context : &Context, + vertices : &[f32] + ) -> WebGlBuffer { + let buffer = gl_context.create_buffer().unwrap(); + gl_context.bind_buffer( + WebGlRenderingContext::ARRAY_BUFFER, + Some(&buffer) + ); + + unsafe { // Note [unsafe buffer_data] + let float_32_array = Float32Array::view(&vertices); + gl_context.buffer_data_with_array_buffer_view( + WebGlRenderingContext::ARRAY_BUFFER, + &float_32_array, + WebGlRenderingContext::STATIC_DRAW, + ); + } + + buffer } + /* Note [unsafe buffer_data] + * + * The Float32Array::view is safe as long there are no allocations done + * until it is destroyed. This way of creating buffers were taken from + * wasm-bindgen examples + * (https://rustwasm.github.io/wasm-bindgen/examples/webgl.html) + */ + fn create_vertex_buf( gl_context : &Context, text : &str, @@ -115,20 +137,7 @@ impl TextComponent { y, ix, y_max, ix_max, y_max] }).flatten().collect::>(); - let buffer = gl_context.create_buffer().unwrap(); - gl_context.bind_buffer( - WebGlRenderingContext::ARRAY_BUFFER, - Some(&buffer) - ); - unsafe { - let float_32_array = Float32Array::view(&vertices); - gl_context.buffer_data_with_array_buffer_view( - WebGlRenderingContext::ARRAY_BUFFER, - &float_32_array, - WebGlRenderingContext::STATIC_DRAW, - ); - } - buffer + Self::create_buffer(gl_context, vertices.as_ref()) } fn create_tex_coord_buf( @@ -137,28 +146,18 @@ impl TextComponent { font : &mut FontRenderInfo, ) -> WebGlBuffer { for ch in text.chars() { - font.get_char_info(ch); + font.get_or_create_char_info(ch); } let vertices = text.chars().map(|c| { let msdf_rows = font.msdf_texture.rows() as f32; - let info = font.get_char_info(c); + let info = font.get_or_create_char_info(c); let y_min = info.msdf_texture_rows.start as f32 / msdf_rows; let y_max = info.msdf_texture_rows.end as f32 / msdf_rows; vec![0.0, y_min, 0.0, y_max, 1.0, y_min, 1.0, y_min, 0.0, y_max, 1.0, y_max] }).flatten().collect::>(); - let buffer = gl_context.create_buffer().unwrap(); - gl_context.bind_buffer(WebGlRenderingContext::ARRAY_BUFFER, Some(&buffer)); - unsafe { - let float_32_array = Float32Array::view(&vertices); - gl_context.buffer_data_with_array_buffer_view( - WebGlRenderingContext::ARRAY_BUFFER, - &float_32_array, - WebGlRenderingContext::STATIC_DRAW, - ); - } - buffer + Self::create_buffer(gl_context, vertices.as_ref()) } fn create_msdf_texture( @@ -214,7 +213,7 @@ impl TextComponent { fn setup_uniforms(&self) { let gl = &self.workspace.context; - let program = &self.gl_shaders.program; + let program = &self.gl_program; let bg_color_location = gl.get_uniform_location(program, "bgColor"); let fg_color_location = gl.get_uniform_location(program, "fgColor"); let px_range_location = gl.get_uniform_location(program, "pxRange"); @@ -242,9 +241,9 @@ impl TextComponent { pub fn display(&self) { let gl = &self.workspace.context; - let program = &self.gl_shaders.program; + let program = &self.gl_program; - gl.use_program(Some(&self.gl_shaders.program)); + gl.use_program(Some(&self.gl_program)); let position_location = gl.get_attrib_location(program, "position"); gl.enable_vertex_attrib_array(position_location as u32); @@ -279,8 +278,6 @@ impl TextComponent { 0 ); -// gl.clear_color(0.0, 0.0, 0.0, 1.0); -// gl.clear(WebGlRenderingContext::COLOR_BUFFER_BIT); gl.draw_arrays( WebGlRenderingContext::TRIANGLES, @@ -289,68 +286,3 @@ impl TextComponent { ); } } -// -//pub fn print_line( -// context : &Context, -// text : &str, -// -// logger : &Logger -//) -//{ -// -// context.use_program(Some(&program)); -// -// // when -// -// context.bind_texture(Context::TEXTURE_2D, msdf_texture.as_ref()); -// context.tex_parameteri(Context::TEXTURE_2D, Context::TEXTURE_WRAP_S, Context::CLAMP_TO_EDGE as i32); -// context.tex_parameteri(Context::TEXTURE_2D, Context::TEXTURE_WRAP_T, Context::CLAMP_TO_EDGE as i32); -// context.tex_parameteri(Context::TEXTURE_2D, Context::TEXTURE_MIN_FILTER, Context::LINEAR as i32); -//// logger.trace(|| format!("{:?}", res.as_ref().expect_err("No error?"))); -// context.uniform1i(msdf_location.as_ref(), 0); -// context.uniform1i(msdf_size_location.as_ref(), 16); -// -// -// let y_max = y + size; -// let vertices= (0..text.len()).map[ -// -1.0, -1.0, 0.0, -// -1.0, 1.0, 0.0, -// 1.0, 1.0, 0.0, -// 1.0, 1.0, 0.0, -// 1.0, -1.0, 0.0, -// -1.0, -1.0, 0.0 -// ]; -// -// let buffer = context.create_buffer().unwrap(); -// context.bind_buffer(WebGlRenderingContext::ARRAY_BUFFER, Some(&buffer)); -// -// // Note that `Float32Array::view` is somewhat dangerous (hence the -// // `unsafe`!). This is creating a raw view into our module's -// // `WebAssembly.Memory` buffer, but if we allocate more pages for ourself -// // (aka do a memory allocation in Rust) it'll cause the buffer to change, -// // causing the `Float32Array` to be invalid. -// // -// // As a result, after `Float32Array::view` we have to be very careful not to -// // do any memory allocations before it's dropped. -// unsafe { -// let vert_array = js_sys::Float32Array::view(&vertices); -// -// context.buffer_data_with_array_buffer_view( -// WebGlRenderingContext::ARRAY_BUFFER, -// &vert_array, -// WebGlRenderingContext::STATIC_DRAW, -// ); -// } -// -// context.vertex_attrib_pointer_with_i32(0, 3, WebGlRenderingContext::FLOAT, false, 0, 0); -// context.enable_vertex_attrib_array(0); -// -// context.clear_color(0.0, 0.0, 0.0, 1.0); -// context.clear(WebGlRenderingContext::COLOR_BUFFER_BIT); -// -// context.draw_arrays( -// WebGlRenderingContext::TRIANGLES, -// 0, -// (vertices.len() / 3) as i32, -// ); -//} \ No newline at end of file diff --git a/script/rust/src/bin/test-all.rs b/script/rust/src/bin/test-all.rs index d7c95a46a2..833bbcb749 100644 --- a/script/rust/src/bin/test-all.rs +++ b/script/rust/src/bin/test-all.rs @@ -11,6 +11,8 @@ fn get_workspace_members(cargo_toml_root : toml::Value) -> Vec { } } +const BUILD_UTILITIES_DIR : &str = "build-utilities"; + /// Call wasm-pack test for each workspace member /// /// This function reads workspace members list from `Cargo.toml` in current @@ -21,7 +23,11 @@ fn main() { let cargo_toml_root = std::fs::read_to_string("Cargo.toml").unwrap() .parse::().unwrap(); - for member in get_workspace_members(cargo_toml_root) { + let all_members = get_workspace_members(cargo_toml_root); + let tested_members = all_members.iter() + .filter(|path| !path.starts_with(BUILD_UTILITIES_DIR)); + + for member in tested_members { println!("Running tests for {}:", member); let status = std::process::Command::new("wasm-pack") .arg("test") diff --git a/script/test.sh b/script/test.sh index 0cbee3f698..3b4a014afa 100755 --- a/script/test.sh +++ b/script/test.sh @@ -1,3 +1,4 @@ #!/bin/sh +cargo test && cargo run --manifest-path=script/rust/Cargo.toml --bin test-all -- \ - --node --firefox --chrome --headless + --node --firefox --chrome --headless From b05152ce0427e5f48fc183a71f998969d2949cb1 Mon Sep 17 00:00:00 2001 From: Adam Obuchowicz Date: Tue, 26 Nov 2019 09:41:37 +0100 Subject: [PATCH 06/19] WIP --- lib/core/Cargo.toml | 2 +- lib/core/msdf-sys/build.rs | 10 +++- lib/core/msdf-sys/src/lib.rs | 39 ++----------- lib/core/msdf-sys/src/test_utils.rs | 33 +++++++++++ lib/core/src/text/font.rs | 90 ++++++++++++++++------------- 5 files changed, 98 insertions(+), 76 deletions(-) create mode 100644 lib/core/msdf-sys/src/test_utils.rs diff --git a/lib/core/Cargo.toml b/lib/core/Cargo.toml index 4cd3bfa63f..fe186c9dbc 100644 --- a/lib/core/Cargo.toml +++ b/lib/core/Cargo.toml @@ -48,4 +48,4 @@ features = [ ] [dev-dependencies] -wasm-bindgen-test = "0.2" +wasm-bindgen-test = "0.3.3" diff --git a/lib/core/msdf-sys/build.rs b/lib/core/msdf-sys/build.rs index 7d76e11e44..84c2046a46 100644 --- a/lib/core/msdf-sys/build.rs +++ b/lib/core/msdf-sys/build.rs @@ -2,7 +2,8 @@ use basegl_build_utilities::github_download; mod msdfgen_wasm { use crate::github_download; - use std::path; + use std::{path, fs}; + use std::io::Write; pub const VERSION : &str = "v1.0.1"; pub const FILENAME : &str = "msdfgen_wasm.js"; @@ -28,9 +29,16 @@ mod msdfgen_wasm { * If you find and implement a better way to downloading js snippets, please * remember to remove msdfgen_wasm.js entry from .gitignore */ + + pub fn patch_for_wasm_bindgen_test() { + let path = path::Path::new(FILENAME); + let mut file = fs::OpenOptions::new().append(true).open(path).unwrap(); + file.write("; export { ccall, getValue, _msdfgen_maxMSDFSize, _msdfgen_generateMSDF, _msdfgen_freeFont, addInitializationCb, isInitialized }".as_bytes()).unwrap(); + } } fn main() { msdfgen_wasm::download(); + msdfgen_wasm::patch_for_wasm_bindgen_test(); println!("cargo:rerun-if-changed=build.rs"); } diff --git a/lib/core/msdf-sys/src/lib.rs b/lib/core/msdf-sys/src/lib.rs index 37936d6b9c..37fe247fde 100644 --- a/lib/core/msdf-sys/src/lib.rs +++ b/lib/core/msdf-sys/src/lib.rs @@ -1,4 +1,5 @@ mod internal; +pub mod test_utils; use internal::{ on_emscripten_runtime_initialized, @@ -129,47 +130,17 @@ pub fn generate_msdf>( #[cfg(test)] mod tests { - use wasm_bindgen_test::wasm_bindgen_test; + use wasm_bindgen_test::{wasm_bindgen_test, wasm_bindgen_test_configure}; use internal::msdfgen_max_msdf_size; use crate::*; use basegl_core_embedded_fonts::EmbeddedFonts; - use std::future::Future; - use std::pin::Pin; - use std::task::{Context, Poll}; - - /// The future for running test after initialization - struct TestAfterInit { - test : F - } - - impl TestAfterInit { - fn schedule(test : F) -> TestAfterInit { - TestAfterInit { test } - } - } - - impl Future for TestAfterInit { - - type Output = (); - - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) - -> Poll { - - if is_emscripten_runtime_initialized() { - (self.test)(); - Poll::Ready(()) - } else { - let waker = cx.waker().clone(); - run_once_initialized(move || waker.wake()); - Poll::Pending - } - } - } + use test_utils::TestAfterInit; + wasm_bindgen_test_configure!(run_in_browser); #[wasm_bindgen_test(async)] - fn generate_msdf_for_capital_a() -> impl Future{ + fn generate_msdf_for_capital_a() -> impl Future { TestAfterInit::schedule(|| { // given let font_base = EmbeddedFonts::create_and_fill(); diff --git a/lib/core/msdf-sys/src/test_utils.rs b/lib/core/msdf-sys/src/test_utils.rs new file mode 100644 index 0000000000..8419d669ee --- /dev/null +++ b/lib/core/msdf-sys/src/test_utils.rs @@ -0,0 +1,33 @@ +use std::pin::Pin; +use std::task::{Context, Poll}; +use std::future::Future; +use crate::{ is_emscripten_runtime_initialized, run_once_initialized }; + +/// The future for running test after initialization +pub struct TestAfterInit { + test : F +} + +impl TestAfterInit { + pub fn schedule(test : F) -> TestAfterInit { + TestAfterInit { test } + } +} + +impl Future for TestAfterInit { + + type Output = (); + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) + -> Poll { + + if is_emscripten_runtime_initialized() { + (self.test)(); + Poll::Ready(()) + } else { + let waker = cx.waker().clone(); + run_once_initialized(move || waker.wake()); + Poll::Pending + } + } +} \ No newline at end of file diff --git a/lib/core/src/text/font.rs b/lib/core/src/text/font.rs index 8ced1b91e4..f240db8366 100644 --- a/lib/core/src/text/font.rs +++ b/lib/core/src/text/font.rs @@ -128,11 +128,13 @@ impl FontRenderInfo { #[cfg(test)] -mod test { +mod tests { use crate::text::font::{MsdfTexture, FontRenderInfo}; use basegl_core_msdf_sys as msdf_sys; use basegl_core_embedded_fonts::EmbeddedFonts; - use wasm_bindgen_test::wasm_bindgen_test; + use wasm_bindgen_test::{wasm_bindgen_test, wasm_bindgen_test_configure}; + use msdf_sys::test_utils::TestAfterInit; + use std::future::Future; const TEST_FONT_NAME : &str = "DejaVuSansMono-Bold"; @@ -156,53 +158,61 @@ mod test { assert_eq!([0, 0, 63, 127, 191, 255, 255], texture.data.as_slice()); } - #[wasm_bindgen_test] - fn empty_font_render_info() { - let font_render_info = create_test_font_render_info(); + wasm_bindgen_test_configure!(run_in_browser); - assert_eq!(TEST_FONT_NAME, font_render_info.name); - assert_eq!(0, font_render_info.msdf_texture.data.len()); - assert_eq!(0, font_render_info.chars.len()); - } + #[wasm_bindgen_test(async)] + fn empty_font_render_info() -> impl Future { + TestAfterInit::schedule(||{ + let font_render_info = create_test_font_render_info(); + assert_eq!(TEST_FONT_NAME, font_render_info.name); + assert_eq!(0, font_render_info.msdf_texture.data.len()); + assert_eq!(0, font_render_info.chars.len()); + }) + } - #[wasm_bindgen_test] - fn loading_chars() { - let mut font_render_info = create_test_font_render_info(); + #[wasm_bindgen_test(async)] + fn loading_chars() -> impl Future { + TestAfterInit::schedule(|| { + let mut font_render_info = create_test_font_render_info(); - font_render_info.load_char('A'); - font_render_info.load_char('B'); + font_render_info.load_char('A'); + font_render_info.load_char('B'); - let expected_texture_size = MsdfTexture::WIDTH * MsdfTexture::WIDTH * - msdf_sys::MAX_MSDF_SIZE * msdf_sys::MSDF_CHANNELS_COUNT * 2; + let expected_texture_size = MsdfTexture::WIDTH * MsdfTexture::WIDTH + * msdf_sys::MSDF_CHANNELS_COUNT * 2; - assert_eq!(MsdfTexture::WIDTH*2, font_render_info.msdf_texture.rows()); - assert_eq!(expected_texture_size, - font_render_info.msdf_texture.data.len()); - assert_eq!(2, font_render_info.chars.len()); + assert_eq!(MsdfTexture::WIDTH * 2, + font_render_info.msdf_texture.rows()); + assert_eq!(expected_texture_size, + font_render_info.msdf_texture.data.len()); + assert_eq!(2, font_render_info.chars.len()); - let first_char = font_render_info.chars.get(&'A').unwrap(); - let second_char = font_render_info.chars.get(&'B').unwrap(); + let first_char = font_render_info.chars.get(&'A').unwrap(); + let second_char = font_render_info.chars.get(&'B').unwrap(); - assert_eq!(0..MsdfTexture::WIDTH, first_char.msdf_texture_rows); - assert_eq!(MsdfTexture::WIDTH..2*MsdfTexture::WIDTH, - second_char.msdf_texture_rows); + assert_eq!(0..MsdfTexture::WIDTH, first_char.msdf_texture_rows); + assert_eq!(MsdfTexture::WIDTH..2 * MsdfTexture::WIDTH, + second_char.msdf_texture_rows); + }) } - #[wasm_bindgen_test] - fn getting_or_creating_char() { - let mut font_render_info = create_test_font_render_info(); - - { - let char_info = font_render_info.get_or_create_char_info('A'); - assert_eq!(0..MsdfTexture::WIDTH, char_info.msdf_texture_rows); - } - assert_eq!(1, font_render_info.chars.len()); - - { - let char_info = font_render_info.get_or_create_char_info('A'); - assert_eq!(0..MsdfTexture::WIDTH, char_info.msdf_texture_rows); - } - assert_eq!(1, font_render_info.chars.len()); + #[wasm_bindgen_test(async)] + fn getting_or_creating_char() -> impl Future { + TestAfterInit::schedule(|| { + let mut font_render_info = create_test_font_render_info(); + + { + let char_info = font_render_info.get_or_create_char_info('A'); + assert_eq!(0..MsdfTexture::WIDTH, char_info.msdf_texture_rows); + } + assert_eq!(1, font_render_info.chars.len()); + + { + let char_info = font_render_info.get_or_create_char_info('A'); + assert_eq!(0..MsdfTexture::WIDTH, char_info.msdf_texture_rows); + } + assert_eq!(1, font_render_info.chars.len()); + }) } } \ No newline at end of file From 007b74fbc15e54e5777bb476b5f82a023575f4de Mon Sep 17 00:00:00 2001 From: Adam Obuchowicz Date: Tue, 26 Nov 2019 16:20:06 +0100 Subject: [PATCH 07/19] Final touches --- examples/01-scene/index.js | 1 + examples/01-scene/webpack.config.js | 3 +++ examples/03-text/index.js | 6 +----- lib/core/msdf-sys/build.rs | 10 +++++++++- lib/core/src/display/workspace.rs | 3 +++ lib/core/src/display/world.rs | 1 - lib/core/src/lib.rs | 12 ++++++++++-- 7 files changed, 27 insertions(+), 9 deletions(-) diff --git a/examples/01-scene/index.js b/examples/01-scene/index.js index 861c1887b9..312df98d3f 100644 --- a/examples/01-scene/index.js +++ b/examples/01-scene/index.js @@ -1 +1,2 @@ import * as wasm from "basegl"; +wasm.run_01_example() \ No newline at end of file diff --git a/examples/01-scene/webpack.config.js b/examples/01-scene/webpack.config.js index e22cccdaa5..205fc67a83 100644 --- a/examples/01-scene/webpack.config.js +++ b/examples/01-scene/webpack.config.js @@ -9,6 +9,9 @@ module.exports = { filename: "bootstrap.js", }, mode: "development", + node: { + fs: 'empty' + }, plugins: [ new CopyWebpackPlugin(['index.html']), // new HtmlWebpackPlugin({template: 'index.html'}), diff --git a/examples/03-text/index.js b/examples/03-text/index.js index 73b4bc3aa6..7cf2850c78 100644 --- a/examples/03-text/index.js +++ b/examples/03-text/index.js @@ -1,6 +1,2 @@ - var Module = { - onRuntimeInitialized: function() { - console.log("Wojtas"); - } - }; import * as wasm from "basegl"; +wasm.run_03_text() diff --git a/lib/core/msdf-sys/build.rs b/lib/core/msdf-sys/build.rs index 84c2046a46..0c1e2b9fd0 100644 --- a/lib/core/msdf-sys/build.rs +++ b/lib/core/msdf-sys/build.rs @@ -30,10 +30,18 @@ mod msdfgen_wasm { * remember to remove msdfgen_wasm.js entry from .gitignore */ + const PATCH_LINE : &str = "; export { ccall, getValue, \ + _msdfgen_maxMSDFSize, _msdfgen_generateMSDF, _msdfgen_freeFont, \ + addInitializationCb, isInitialized }"; + + /// Patches downloaded msdfgen_wasm.js file + /// + /// For some reason, for wasm-bindgen test on browsers the function must + /// be explicitly exported. Examples works without this line perfectly. pub fn patch_for_wasm_bindgen_test() { let path = path::Path::new(FILENAME); let mut file = fs::OpenOptions::new().append(true).open(path).unwrap(); - file.write("; export { ccall, getValue, _msdfgen_maxMSDFSize, _msdfgen_generateMSDF, _msdfgen_freeFont, addInitializationCb, isInitialized }".as_bytes()).unwrap(); + file.write(PATCH_LINE.as_bytes()).unwrap(); } } diff --git a/lib/core/src/display/workspace.rs b/lib/core/src/display/workspace.rs index 9d837d6126..19ed3637b9 100644 --- a/lib/core/src/display/workspace.rs +++ b/lib/core/src/display/workspace.rs @@ -129,6 +129,9 @@ impl Workspace { ); self.context.enable_vertex_attrib_array(0); + self.context.clear_color(0.0, 0.0, 0.0, 1.0); + self.context.clear(WebGlRenderingContext::COLOR_BUFFER_BIT); + self.context.draw_arrays(webgl::Context::TRIANGLES, 0, (vertices.len() / 3) as i32); } }) diff --git a/lib/core/src/display/world.rs b/lib/core/src/display/world.rs index 54c674429f..715800fab4 100644 --- a/lib/core/src/display/world.rs +++ b/lib/core/src/display/world.rs @@ -58,7 +58,6 @@ impl World { self.data.borrow_mut().started = true; Self::request_callback(&self.on_every_frame); } - self.data.borrow().logger.info("STARTED!"); } pub fn stop(&self) { diff --git a/lib/core/src/lib.rs b/lib/core/src/lib.rs index 0074a9f2ee..3f81895055 100644 --- a/lib/core/src/lib.rs +++ b/lib/core/src/lib.rs @@ -34,8 +34,16 @@ use basegl_core_embedded_fonts::EmbeddedFonts; use crate::text::font::FontRenderInfo; use itertools::iproduct; -#[wasm_bindgen(start)] -pub fn start() { +#[wasm_bindgen] +pub fn run_01_example() { + utils::set_panic_hook(); + let world = World::new(); + world.add_workspace("canvas"); + world.start(); +} + +#[wasm_bindgen] +pub fn run_03_text() { utils::set_panic_hook(); basegl_core_msdf_sys::run_once_initialized(|| { let world = World::new(); From 7d3256b0dbe920034f110c5c29f6debad9d45d1f Mon Sep 17 00:00:00 2001 From: Adam Obuchowicz Date: Fri, 29 Nov 2019 12:45:49 +0100 Subject: [PATCH 08/19] Review and linter fixes The linter forced me to somehow refactor a TestComponent code --- build-utilities/src/lib.rs | 10 +- lib/core/src/lib.rs | 209 +++++++++++++++----------- lib/core/src/text/mod.rs | 167 +++++++++----------- lib/system/web/src/resize_observer.rs | 4 +- 4 files changed, 200 insertions(+), 190 deletions(-) diff --git a/build-utilities/src/lib.rs b/build-utilities/src/lib.rs index 05322ec841..acf766cd3d 100644 --- a/build-utilities/src/lib.rs +++ b/build-utilities/src/lib.rs @@ -1,4 +1,7 @@ +#![feature(option_unwrap_none)] + use std::{fs, path}; +use std::io::ErrorKind; /// Download the release package from github /// @@ -19,9 +22,10 @@ pub fn github_download( let destination_file = path::Path::new(destination_dir) .join(filename); - if destination_file.exists() { - fs::remove_file(&destination_file).unwrap(); - } + let rm_error = fs::remove_file(&destination_file).err(); + let fatal_rm_error = + rm_error.filter(|err| err.kind() != ErrorKind::NotFound); + fatal_rm_error.unwrap_none(); download_lp::download( url.as_str(), diff --git a/lib/core/src/lib.rs b/lib/core/src/lib.rs index 72c5c8298d..053622eecd 100644 --- a/lib/core/src/lib.rs +++ b/lib/core/src/lib.rs @@ -34,116 +34,145 @@ pub mod system { } pub mod tp; pub mod utils; -use dirty::traits::SharedSetter1; - -// ============ -// === Main === -// ============ - -use console_error_panic_hook; -use display::world::*; -use nalgebra; -use nalgebra::Vector2; -use nalgebra::Vector3; -use wasm_bindgen::prelude::*; -use basegl_core_embedded_fonts::EmbeddedFonts; -use crate::text::font::FontRenderInfo; -use itertools::iproduct; // ================== // === Example 01 === // ================== -#[wasm_bindgen] -pub fn run_01_example() { - console_error_panic_hook::set_once(); - set_stdout(); - init(&mut World::new().borrow_mut()); -} +mod example_01 { + use crate::set_stdout; + use crate::display::world::*; + use crate::prelude::*; + use nalgebra::{Vector2, Vector3}; + use wasm_bindgen::prelude::*; + + #[wasm_bindgen] + #[allow(dead_code)] + pub fn run_01_example() { + console_error_panic_hook::set_once(); + set_stdout(); + init(&mut World::new().borrow_mut()); + } -type Position = SharedBuffer>; -type Color = SharedBuffer>; + type Position = SharedBuffer>; + type Color = SharedBuffer>; -#[derive(Debug)] -pub struct Rect { - position : Var>, - color : Var>, -} + #[derive(Debug)] + pub struct Rect { + position : Var>, + color : Var>, + } -fn init(world: &mut World) { - let wspace_id : WorkspaceID = world.add(Workspace::build("canvas")); - let workspace : &mut Workspace = &mut world[wspace_id]; - let mesh_id : MeshID = workspace.new_mesh(); - let mesh : &mut Mesh = &mut workspace[mesh_id]; - let geo : &mut Geometry = &mut mesh.geometry; - let scopes : &mut Scopes = &mut geo.scopes; - let pt_scope : &mut VarScope = &mut scopes.point; - let pos : Position = pt_scope.add_buffer("position"); - let color : Color = pt_scope.add_buffer("color"); - - let inst_ix = pt_scope.add_instance(); - - let rect = Rect { - position : pos.get(inst_ix), - color : color.get(inst_ix) - }; - - world.on_frame(move |_| on_frame(&rect)).forget(); -} + fn init(world: &mut World) { + let wspace_id : WorkspaceID = world.add(Workspace::build("canvas")); + let workspace : &mut Workspace = &mut world[wspace_id]; + let mesh_id : MeshID = workspace.new_mesh(); + let mesh : &mut Mesh = &mut workspace[mesh_id]; + let geo : &mut Geometry = &mut mesh.geometry; + let scopes : &mut Scopes = &mut geo.scopes; + let pt_scope : &mut VarScope = &mut scopes.point; + let pos : Position = pt_scope.add_buffer("position"); + let color : Color = pt_scope.add_buffer("color"); + + let inst_ix = pt_scope.add_instance(); + + let rect = Rect { + position : pos.get(inst_ix), + color : color.get(inst_ix) + }; + + world.on_frame(move |_| on_frame(&rect)).forget(); + } -pub fn on_frame(rect: &Rect) { - rect.position.modify(|p| p.x += 1.0) + pub fn on_frame(rect: &Rect) { + rect.position.modify(|p| p.x += 1.0) + } } // ================== // === Example 03 === // ================== -#[wasm_bindgen] -pub fn run_03_text() { - utils::set_panic_hook(); - basegl_core_msdf_sys::run_once_initialized(|| { - let mut world_ref = World::new(); - let workspace_id : WorkspaceID = world_ref.add(Workspace::build("canvas")); - - let world = &mut world_ref.borrow_mut(); - let workspace = &mut world[workspace_id]; - - let font_base = EmbeddedFonts::create_and_fill(); - let font_names = [ - "DejaVuSans", - "DejaVuSansMono", - "DejaVuSansMono-Bold", - "DejaVuSansMono-Oblique", - "DejaVuSansCondensed", - "DejaVuSerif", - "DejaVuSerifCondensed", - ]; - let mut fonts : Box<[FontRenderInfo]> = font_names.iter().map( - |name| FontRenderInfo::from_embedded(&font_base, name) - ).collect(); - let sizes = [0.024, 0.032, 0.048, 0.064]; - - for (i, (font, size)) in iproduct!(0..fonts.len(), sizes.iter()).enumerate() { - let text_compnent = crate::text::TextComponent::new( - workspace, - "To be, or not to be, that is the question: Whether 'tis nobler in the mind to suffer The slings and arrows of outrageous fortune, Or to take arms against a sea of troubles And by opposing end them.".to_string(), - -0.95, - 0.9 - 0.064*(i as f32), - *size, - &mut fonts[font], - text::Color {r: 1.0, g: 1.0, b: 1.0, a: 1.0}, - text::Color {r: 0.0, g: 0.0, b: 0.0, a: 1.0} - ); - workspace.text_components.push(text_compnent); - } - world.workspace_dirty.set(workspace_id); - }); +mod example_03 { + use crate::utils; + use crate::display::world::{World, WorkspaceID, Workspace, Add}; + use crate::text::font::FontRenderInfo; + use crate::Color; + use crate::dirty::traits::SharedSetter1; + use basegl_core_embedded_fonts::EmbeddedFonts; + use itertools::iproduct; + use wasm_bindgen::prelude::*; + + #[wasm_bindgen] + #[allow(dead_code)] + pub fn run_03_text() { + utils::set_panic_hook(); + basegl_core_msdf_sys::run_once_initialized(|| { + let mut world_ref = World::new(); + let workspace_id : WorkspaceID = world_ref.add(Workspace::build("canvas")); + + let world = &mut world_ref.borrow_mut(); + let workspace = &mut world[workspace_id]; + + let font_base = EmbeddedFonts::create_and_fill(); + let font_names = [ + "DejaVuSans", + "DejaVuSansMono", + "DejaVuSansMono-Bold", + "DejaVuSansMono-Oblique", + "DejaVuSansCondensed", + "DejaVuSerif", + "DejaVuSerifCondensed", + ]; + let mut fonts : Box<[FontRenderInfo]> = font_names.iter().map( + |name| FontRenderInfo::from_embedded(&font_base, name) + ).collect(); + let sizes = [0.024, 0.032, 0.048, 0.064]; + + for (i, (font, size)) in + iproduct!(0..fonts.len(), sizes.iter()).enumerate() { + + let text_compnent = crate::text::TextComponentBuilder { + text : "To be, or not to be, that is the question: \ + Whether 'tis nobler in the mind to suffer \ + The slings and arrows of outrageous fortune, \ + Or to take arms against a sea of troubles \ + And by opposing end them." + .to_string(), + font : &mut fonts[font], + x : -0.95, + y : 0.9 - 0.064*(i as f32), + size : *size, + color : Color {r: 1.0, g: 1.0, b: 1.0, a: 1.0}, + background_color : Color {r: 0.0, g: 0.0, b: 0.0, a: 1.0} + }.build(workspace); + workspace.text_components.push(text_compnent); + } + world.workspace_dirty.set(workspace_id); + }); + } } //////////////////////////////////////////////// //////////////////////////////////////////////// +// ================= +// === Utilities === +// ================= + +#[derive(Debug)] +pub struct Color { + pub r : T, + pub g : T, + pub b : T, + pub a : T +} + + +// =============== +// === Printer === +// =============== + type PrintFn = fn(&str) -> std::io::Result<()>; struct Printer { diff --git a/lib/core/src/text/mod.rs b/lib/core/src/text/mod.rs index 1f22aa275e..04cbb68cf8 100644 --- a/lib/core/src/text/mod.rs +++ b/lib/core/src/text/mod.rs @@ -2,6 +2,7 @@ use basegl_backend_webgl::{Context, compile_shader, link_program, Program, }; use web_sys::{WebGlRenderingContext, WebGlBuffer, WebGlTexture}; use crate::prelude::*; +use crate::Color; pub mod font; @@ -10,71 +11,48 @@ use crate::text::font::MsdfTexture; use js_sys::Float32Array; use crate::display::world::Workspace; -#[derive(Debug)] -pub struct Color { - pub r : f32, - pub g : f32, - pub b : f32, - pub a : f32 -} - -#[derive(Debug)] -pub struct TextComponent { +pub struct TextComponentBuilder<'a> { pub text : String, + pub font : &'a mut FontRenderInfo, pub x : f32, pub y : f32, pub size : f32, - pub color : Color, - pub background_color : Color, + pub color : Color, + pub background_color : Color, +} - // TODO Split structure to component data and rendering separately +#[derive(Debug)] +pub struct TextComponent { gl_context : WebGlRenderingContext, gl_program : Program, gl_vertex_buf : WebGlBuffer, gl_tex_coord_buf : WebGlBuffer, - gl_msdf_texture : WebGlTexture + gl_msdf_texture : WebGlTexture, + buffers_size : usize, } -impl TextComponent { - pub fn new( - workspace : &Workspace, - text : String, - x : f32, - y : f32, - size : f32, - font : &mut FontRenderInfo, - color : Color, - background_color : Color, - ) -> TextComponent { - let gl_context = workspace.context.clone(); - let gl_program = Self::create_program(&gl_context); - let gl_vertex_buf = Self::create_vertex_buf( - &gl_context, - text.as_str(), - x, - y, - size, - ); - let gl_tex_coord_buf = Self::create_tex_coord_buf( - &gl_context, - text.as_str(), - font, - ); - let gl_msdf_texture = Self::create_msdf_texture( - &gl_context, - &gl_program, - font - ); - - let component = TextComponent { - text, x, y, size, color, background_color, gl_context, - gl_program, gl_vertex_buf, gl_tex_coord_buf, gl_msdf_texture - }; - component.setup_uniforms(); - component +impl<'a> TextComponentBuilder<'a> { + pub fn build(mut self, workspace : &Workspace) -> TextComponent { + let gl_context = workspace.context.clone(); + let gl_program = self.create_program(&gl_context); + let gl_vertex_buf = self.create_vertex_buf(&gl_context); + let gl_tex_coord_buf = self.create_tex_coord_buf(&gl_context); + let gl_msdf_texture = + self.create_msdf_texture(&gl_context, &gl_program); + + self.setup_uniforms(&gl_context, &gl_program); + + TextComponent { + gl_context, + gl_program, + gl_vertex_buf, + gl_tex_coord_buf, + gl_msdf_texture, + buffers_size: self.text.len() + } } - fn create_program(gl_context : &Context) -> Program { + fn create_program(&self, gl_context : &Context) -> Program { gl_context.get_extension("OES_standard_derivatives") .unwrap().unwrap(); @@ -123,50 +101,45 @@ impl TextComponent { * (https://rustwasm.github.io/wasm-bindgen/examples/webgl.html) */ - fn create_vertex_buf( - gl_context : &Context, - text : &str, - x : f32, - y : f32, - size : f32 - ) -> WebGlBuffer { - let y_max = y + size; - let x_step = size; - let vertices = (0..text.len()).map(|i| { - let ix = x + (i as f32) * x_step; + fn create_vertex_buf(&self, gl_context : &Context) -> WebGlBuffer { + let y_max = self.y + self.size; + let x_step = self.size; + let vertices = (0..self.text.len()).map(|i| { + let ix = self.x + (i as f32) * x_step; let ix_max = ix + x_step; - vec![ix, y, ix, y_max, ix_max, y, ix_max, - y, ix, y_max, ix_max, y_max] + vec![ix, self.y, ix, y_max, ix_max, self.y, ix_max, + self.y, ix, y_max, ix_max, y_max] // Note [The ugly code] }).flatten().collect::>(); Self::create_buffer(gl_context, vertices.as_ref()) } - fn create_tex_coord_buf( - gl_context : &Context, - text : &str, - font : &mut FontRenderInfo, - ) -> WebGlBuffer { - for ch in text.chars() { + /* Note [The ugly code] + * + * I have already refactored this function on branch + * wip/ao/letter-alignment. Please be patient + */ + + fn create_tex_coord_buf(&mut self, gl_context : &Context) -> WebGlBuffer { + let font = &mut self.font; + for ch in self.text.chars() { font.get_or_create_char_info(ch); } - let vertices = text.chars().map(|c| { + let vertices = self.text.chars().map(|c| { let msdf_rows = font.msdf_texture.rows() as f32; let info = font.get_or_create_char_info(c); let y_min = info.msdf_texture_rows.start as f32 / msdf_rows; let y_max = info.msdf_texture_rows.end as f32 / msdf_rows; vec![0.0, y_min, 0.0, y_max, 1.0, y_min, - 1.0, y_min, 0.0, y_max, 1.0, y_max] + 1.0, y_min, 0.0, y_max, 1.0, y_max] }).flatten().collect::>(); Self::create_buffer(gl_context, vertices.as_ref()) } - fn create_msdf_texture( - gl_context : &Context, - gl_program : &Program, - font : &FontRenderInfo - ) -> WebGlTexture { + fn create_msdf_texture(&self, gl_context : &Context, gl_program : &Program) + -> WebGlTexture { + let msdf_texture = gl_context.create_texture().unwrap(); gl_context.bind_texture(Context::TEXTURE_2D, Some(&msdf_texture)); @@ -191,11 +164,11 @@ impl TextComponent { 0, Context::RGB as i32, MsdfTexture::WIDTH as i32, - font.msdf_texture.rows() as i32, + self.font.msdf_texture.rows() as i32, 0, Context::RGB, Context::UNSIGNED_BYTE, - Some(font.msdf_texture.data.as_slice()) + Some(self.font.msdf_texture.data.as_slice()) ).unwrap(); let msdf_loc = gl_context.get_uniform_location(gl_program, "msdf"); @@ -207,39 +180,43 @@ impl TextComponent { gl_context.uniform2f( msdf_size_loc.as_ref(), MsdfTexture::WIDTH as f32, - font.msdf_texture.rows() as f32 + self.font.msdf_texture.rows() as f32 ); msdf_texture } - fn setup_uniforms(&self) { - let gl = &self.gl_context; - let program = &self.gl_program; - let bg_color_location = gl.get_uniform_location(program, "bgColor"); - let fg_color_location = gl.get_uniform_location(program, "fgColor"); - let px_range_location = gl.get_uniform_location(program, "pxRange"); + fn setup_uniforms(&self, gl_context : &Context, gl_program : &Program) { + let bg_color_loc = + gl_context.get_uniform_location(gl_program, "bgColor"); + let fg_color_loc = + gl_context.get_uniform_location(gl_program, "fgColor"); + let px_range_loc = + gl_context.get_uniform_location(gl_program, "pxRange"); - gl.use_program(Some(program)); - gl.uniform4f( - bg_color_location.as_ref(), + gl_context.use_program(Some(gl_program)); + gl_context.uniform4f( + bg_color_loc.as_ref(), self.background_color.r, self.background_color.g, self.background_color.b, self.background_color.a ); - gl.uniform4f( - fg_color_location.as_ref(), + gl_context.uniform4f( + fg_color_loc.as_ref(), self.color.r, self.color.g, self.color.b, self.color.a, ); - gl.uniform1f( - px_range_location.as_ref(), + gl_context.uniform1f( + px_range_loc.as_ref(), FontRenderInfo::MSDF_PARAMS.range as f32 ); } +} + +impl TextComponent { pub fn display(&self) { let gl = &self.gl_context; @@ -284,7 +261,7 @@ impl TextComponent { gl.draw_arrays( WebGlRenderingContext::TRIANGLES, 0, - (self.text.chars().count()*6) as i32, + (self.buffers_size*6) as i32, ); } } diff --git a/lib/system/web/src/resize_observer.rs b/lib/system/web/src/resize_observer.rs index 4a56e55694..d09b2805ac 100644 --- a/lib/system/web/src/resize_observer.rs +++ b/lib/system/web/src/resize_observer.rs @@ -39,8 +39,8 @@ pub struct ResizeObserver { impl ResizeObserver { pub fn new(target: &JsValue, listener: Listener) -> Self { let target = target.clone(); -// let observer_id = resize_observe(&target, &listener); - Self { target, listener, observer_id: 0 } + let observer_id = resize_observe(&target, &listener); + Self { target, listener, observer_id } } } From d48cb9d543fae803e613310ddc78f94f07e8e5f1 Mon Sep 17 00:00:00 2001 From: Adam Obuchowicz Date: Fri, 29 Nov 2019 14:11:57 +0100 Subject: [PATCH 09/19] Review --- lib/core/msdf-sys/Cargo.toml | 13 +-- lib/core/msdf-sys/src/internal.rs | 11 ++- lib/core/msdf-sys/src/lib.rs | 1 + lib/core/src/display/workspace.rs | 144 ++++++++++++++++-------------- 4 files changed, 88 insertions(+), 81 deletions(-) diff --git a/lib/core/msdf-sys/Cargo.toml b/lib/core/msdf-sys/Cargo.toml index aa4ea32635..cae4f95639 100644 --- a/lib/core/msdf-sys/Cargo.toml +++ b/lib/core/msdf-sys/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "basegl-core-msdf-sys" +name = "basegl-core-msdf-sys" version = "0.1.0" authors = ["Enso Team "] edition = "2018" @@ -8,13 +8,14 @@ edition = "2018" crate-type = ["cdylib", "rlib"] [dependencies] -wasm-bindgen = "0.2.53" -js-sys = "0.3.30" -vector2d = "2.2.0" +wasm-bindgen = "0.2.53" +js-sys = "0.3.30" +vector2d = "2.2.0" +basegl-prelude = { version = "0.1.0", path="../../prelude" } [dev-dependencies] -wasm-bindgen-test = "0.3.3" -futures = "" +wasm-bindgen-test = "0.3.3" +futures = "" basegl-core-embedded-fonts = { version = "0.1.0", path="../embedded-fonts" } [build-dependencies] diff --git a/lib/core/msdf-sys/src/internal.rs b/lib/core/msdf-sys/src/internal.rs index 87b97e4a8a..c6727ecfd7 100644 --- a/lib/core/msdf-sys/src/internal.rs +++ b/lib/core/msdf-sys/src/internal.rs @@ -1,5 +1,6 @@ use wasm_bindgen::prelude::wasm_bindgen; use wasm_bindgen::JsValue; +use crate::prelude::*; #[wasm_bindgen(module = "/msdfgen_wasm.js")] extern { @@ -100,15 +101,13 @@ impl Iterator for F32ArrayMemoryViewIterator { type Item = f32; fn next(&mut self) -> Option { - if self.next_read_address < self.end_address { + let has_element = self.next_read_address < self.end_address; + has_element.and_option_from(|| { let ret_val = emscripten_get_value_from_memory( self.next_read_address, - emscripten_data_types::FLOAT - ); + emscripten_data_types::FLOAT); self.next_read_address += emscripten_data_types::FLOAT_SIZE_IN_BYTES; Some(ret_val.as_f64().unwrap() as f32) - } else { - None - } + }) } } \ No newline at end of file diff --git a/lib/core/msdf-sys/src/lib.rs b/lib/core/msdf-sys/src/lib.rs index 37fe247fde..e619844047 100644 --- a/lib/core/msdf-sys/src/lib.rs +++ b/lib/core/msdf-sys/src/lib.rs @@ -1,5 +1,6 @@ mod internal; pub mod test_utils; +pub use basegl_prelude as prelude; use internal::{ on_emscripten_runtime_initialized, diff --git a/lib/core/src/display/workspace.rs b/lib/core/src/display/workspace.rs index 8aa98c34d2..f09df47942 100644 --- a/lib/core/src/display/workspace.rs +++ b/lib/core/src/display/workspace.rs @@ -175,89 +175,95 @@ impl Workspace { } if self.text_components.is_empty() { - let vert_shader = webgl::compile_shader( + // Note [broken indentation] + let vert_shader = webgl::compile_shader( + &self.context, + webgl::Context::VERTEX_SHADER, + r#" +attribute vec4 position; +void main() { + gl_Position = position; +} +"#, + ) + .unwrap(); + let frag_shader = webgl::compile_shader( &self.context, - webgl::Context::VERTEX_SHADER, + webgl::Context::FRAGMENT_SHADER, r#" - attribute vec4 position; void main() { - gl_Position = position; + gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); } "#, - ) - .unwrap(); - let frag_shader = webgl::compile_shader( - &self.context, - webgl::Context::FRAGMENT_SHADER, - r#" - void main() { - gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); - } - "#, - ) - .unwrap(); - let program = - webgl::link_program(&self.context, &vert_shader, &frag_shader).unwrap(); - - let pos_loc = self.context.get_attrib_location(&program, "position"); - let pos_loc = pos_loc as u32; - - println!("pos_loc: {}", pos_loc); - - let vertices: [f32; 9] = - [ -1.0, -1.0, 0.0 - , 1.0, -1.0, 0.0 - , 0.0, 1.0, 0.0 - ]; - - let buffer = self.context.create_buffer().ok_or("failed to create buffer").unwrap(); - self.context.bind_buffer(webgl::Context::ARRAY_BUFFER, Some(&buffer)); - - // Note that `Float32Array::view` is somewhat dangerous (hence the - // `unsafe`!). This is creating a raw view into our module's - // `WebAssembly.Memory` buffer, but if we allocate more pages for ourself - // (aka do a memory allocation in Rust) it'll cause the buffer to change, - // causing the `Float32Array` to be invalid. - // - // As a result, after `Float32Array::view` we have to be very careful not to - // do any memory allocations before it's dropped. - unsafe { - let vert_array = js_sys::Float32Array::view(&vertices); - - self.context.buffer_data_with_array_buffer_view( - webgl::Context::ARRAY_BUFFER, - &vert_array, - webgl::Context::STATIC_DRAW, - ); - } - - // ================= - // === Rendering === - // ================= - - self.context.use_program(Some(&program)); - - self.context.enable_vertex_attrib_array(pos_loc); - self.context.bind_buffer(webgl::Context::ARRAY_BUFFER, Some(&buffer)); - - // hidden part: binds ARRAY_BUFFER to the attribute - self.context.vertex_attrib_pointer_with_i32( - pos_loc, - 3, // size - 3 components per iteration - webgl::Context::FLOAT, // type - false, // normalize - 0, // stride - 0, // offset + ) + .unwrap(); + let program = + webgl::link_program(&self.context, &vert_shader, &frag_shader).unwrap(); + + let pos_loc = self.context.get_attrib_location(&program, "position"); + let pos_loc = pos_loc as u32; + + println!("pos_loc: {}", pos_loc); + + let vertices: [f32; 9] = + [ -1.0, -1.0, 0.0 + , 1.0, -1.0, 0.0 + , 0.0, 1.0, 0.0 + ]; + + let buffer = self.context.create_buffer().ok_or("failed to create buffer").unwrap(); + self.context.bind_buffer(webgl::Context::ARRAY_BUFFER, Some(&buffer)); + + // Note that `Float32Array::view` is somewhat dangerous (hence the + // `unsafe`!). This is creating a raw view into our module's + // `WebAssembly.Memory` buffer, but if we allocate more pages for ourself + // (aka do a memory allocation in Rust) it'll cause the buffer to change, + // causing the `Float32Array` to be invalid. + // + // As a result, after `Float32Array::view` we have to be very careful not to + // do any memory allocations before it's dropped. + unsafe { + let vert_array = js_sys::Float32Array::view(&vertices); + + self.context.buffer_data_with_array_buffer_view( + webgl::Context::ARRAY_BUFFER, + &vert_array, + webgl::Context::STATIC_DRAW, ); + } + + // ================= + // === Rendering === + // ================= + + self.context.use_program(Some(&program)); + + self.context.enable_vertex_attrib_array(pos_loc); + self.context.bind_buffer(webgl::Context::ARRAY_BUFFER, Some(&buffer)); + + // hidden part: binds ARRAY_BUFFER to the attribute + self.context.vertex_attrib_pointer_with_i32( + pos_loc, + 3, // size - 3 components per iteration + webgl::Context::FLOAT, // type + false, // normalize + 0, // stride + 0, // offset + ); - self.context.draw_arrays(webgl::Context::TRIANGLES, 0, (vertices.len() / 3) as i32); + self.context.draw_arrays(webgl::Context::TRIANGLES, 0, (vertices.len() / 3) as i32); } }) } } +/* Note [broken indentation] + * + * This code is refactored on another branch, so is left as it is to avoid + * heavy merge/rebase conflicts + */ impl Index for Workspace { type Output = Mesh; From b5c84459214e859938f97ba3316a4899823e0066 Mon Sep 17 00:00:00 2001 From: Adam Obuchowicz Date: Wed, 27 Nov 2019 16:53:50 +0100 Subject: [PATCH 10/19] Characters MSDF scaling and alignment The code is to refactor yet, and works only with special version of MDSF --- lib/core/Cargo.toml | 2 +- lib/core/msdf-sys/Cargo.toml | 2 +- lib/core/msdf-sys/src/internal.rs | 6 +-- lib/core/msdf-sys/src/lib.rs | 25 +++++------ lib/core/src/lib.rs | 3 +- lib/core/src/text/font.rs | 17 +++---- lib/core/src/text/mod.rs | 74 +++++++++++++++++-------------- lib/core/src/text/msdf_frag.glsl | 6 +-- 8 files changed, 66 insertions(+), 69 deletions(-) diff --git a/lib/core/Cargo.toml b/lib/core/Cargo.toml index 35364b554e..c2b9a58e5a 100644 --- a/lib/core/Cargo.toml +++ b/lib/core/Cargo.toml @@ -26,7 +26,7 @@ failure = { version = "0.1.5" } derive_more = { version = "0.15.0" } shrinkwraprs = { version = "0.2.1" } itertools = { version = "0.8" } -nalgebra = { version = "0.18.1" } +nalgebra = { version = "0.19.0" } bit_field = { version = "0.10.0" } paste = { version = "0.1.6" } enum_dispatch = { version = "= 0.1.3" } # https://gitlab.com/antonok/enum_dispatch/issues/10 diff --git a/lib/core/msdf-sys/Cargo.toml b/lib/core/msdf-sys/Cargo.toml index cae4f95639..59f13131f3 100644 --- a/lib/core/msdf-sys/Cargo.toml +++ b/lib/core/msdf-sys/Cargo.toml @@ -10,7 +10,7 @@ crate-type = ["cdylib", "rlib"] [dependencies] wasm-bindgen = "0.2.53" js-sys = "0.3.30" -vector2d = "2.2.0" +nalgebra = "0.19.0" basegl-prelude = { version = "0.1.0", path="../../prelude" } [dev-dependencies] diff --git a/lib/core/msdf-sys/src/internal.rs b/lib/core/msdf-sys/src/internal.rs index c6727ecfd7..20649bab93 100644 --- a/lib/core/msdf-sys/src/internal.rs +++ b/lib/core/msdf-sys/src/internal.rs @@ -28,7 +28,7 @@ extern { #[wasm_bindgen(js_name="_msdfgen_maxMSDFSize")] pub fn msdfgen_max_msdf_size() -> usize; - #[wasm_bindgen(js_name="_msdfgen_generateMSDF")] + #[wasm_bindgen(js_name="_msdfgen_generateAutoscaledMSDF")] pub fn msdfgen_generate_msdf( width : usize, height : usize, @@ -36,10 +36,6 @@ extern { unicode : u32, edge_coloring_angle_threshold : f64, range : f64, - scale_x : f64, - scale_y : f64, - translate_x : f64, - translate_y : f64, edge_threshold : f64, overlap_support : bool ) -> usize; diff --git a/lib/core/msdf-sys/src/lib.rs b/lib/core/msdf-sys/src/lib.rs index e619844047..cf7cafce7d 100644 --- a/lib/core/msdf-sys/src/lib.rs +++ b/lib/core/msdf-sys/src/lib.rs @@ -14,7 +14,6 @@ use internal::{ use js_sys::Uint8Array; use wasm_bindgen::JsValue; use wasm_bindgen::prelude::Closure; -pub use vector2d::Vector2D; // ====================== // === Initialization === @@ -99,13 +98,11 @@ pub fn generate_msdf>( font : &Font, unicode : u32, params : &MSDFParameters, - scale : Vector2D, - translate : Vector2D, -) { +) -> (nalgebra::Projective2, f32) { assert!(params.width <= MAX_MSDF_SIZE); assert!(params.height <= MAX_MSDF_SIZE); - let output_size = params.width * params.height * MSDF_CHANNELS_COUNT; + let output_size = params.width * params.height * MSDF_CHANNELS_COUNT + 4; let output_address = msdfgen_generate_msdf( params.width, params.height, @@ -113,16 +110,20 @@ pub fn generate_msdf>( unicode, params.edge_coloring_angle_threshold, params.range, - scale.x, - scale.y, - translate.x, - translate.y, params.edge_threshold, params.overlap_support ); - let view = F32ArrayMemoryView::new(output_address, output_size); + let mut output_iter = F32ArrayMemoryView::new(output_address, output_size) + .iter(); + let translation = nalgebra::Vector2::new( + output_iter.next().unwrap()/params.width as f32, + output_iter.next().unwrap()/params.height as f32 + ); + let scale = output_iter.next().unwrap(); + let advance = output_iter.next().unwrap(); + output.extend(output_iter); // Note [Output variable] - output.extend(view); // Note [Output variable] + (nalgebra::convert(nalgebra::Similarity2::new(translation, 0.0, scale)), advance) } // ============= @@ -163,8 +164,6 @@ mod tests { &font, 'A' as u32, ¶ms, - Vector2D { x: 1.0, y: 1.0 }, - Vector2D { x: 0.0, y: 0.0 } ); // then // Note [asserts] diff --git a/lib/core/src/lib.rs b/lib/core/src/lib.rs index 053622eecd..60011ca905 100644 --- a/lib/core/src/lib.rs +++ b/lib/core/src/lib.rs @@ -127,7 +127,7 @@ mod example_03 { let mut fonts : Box<[FontRenderInfo]> = font_names.iter().map( |name| FontRenderInfo::from_embedded(&font_base, name) ).collect(); - let sizes = [0.024, 0.032, 0.048, 0.064]; + let sizes = [0.016, 0.024, 0.032, 0.048, 0.064]; for (i, (font, size)) in iproduct!(0..fonts.len(), sizes.iter()).enumerate() { @@ -144,7 +144,6 @@ mod example_03 { y : 0.9 - 0.064*(i as f32), size : *size, color : Color {r: 1.0, g: 1.0, b: 1.0, a: 1.0}, - background_color : Color {r: 0.0, g: 0.0, b: 0.0, a: 1.0} }.build(workspace); workspace.text_components.push(text_compnent); } diff --git a/lib/core/src/text/font.rs b/lib/core/src/text/font.rs index f240db8366..08a35526ae 100644 --- a/lib/core/src/text/font.rs +++ b/lib/core/src/text/font.rs @@ -45,11 +45,10 @@ impl Extend for MsdfTexture { // ================= /// A single character data used for rendering -/// -/// For now it has only information which fragment of `MsdfTexture` keeps MSDF -/// of this character pub struct CharRenderInfo { - pub msdf_texture_rows : std::ops::Range, + pub msdf_texture_rows : std::ops::Range, + pub points_transformation : nalgebra::Projective2, + pub advance : f32 } /// A single font data used for rendering @@ -100,19 +99,17 @@ impl FontRenderInfo { /// Load char render info pub fn load_char(&mut self, ch : char) { let msdf_texture_rows_begin = self.msdf_texture.rows(); - msdf_sys::generate_msdf( + let (transformation, advance) = msdf_sys::generate_msdf( &mut self.msdf_texture, &self.msdf_sys_handle, ch as u32, &FontRenderInfo::MSDF_PARAMS, - // TODO [AO] should be soon loaded from font info - msdf_sys::Vector2D{ x : 1.0, y : 1.0 }, - // TODO [AO] should be soon loaded from font info - msdf_sys::Vector2D{ x : 2.0, y : 2.25 } ); let msdf_texture_rows_end = self.msdf_texture.rows(); let char_info = CharRenderInfo { - msdf_texture_rows : msdf_texture_rows_begin..msdf_texture_rows_end + msdf_texture_rows : msdf_texture_rows_begin..msdf_texture_rows_end, + points_transformation: transformation.inverse(), + advance: advance/MsdfTexture::WIDTH as f32 }; self.chars.insert(ch, char_info); } diff --git a/lib/core/src/text/mod.rs b/lib/core/src/text/mod.rs index 04cbb68cf8..f4136b9235 100644 --- a/lib/core/src/text/mod.rs +++ b/lib/core/src/text/mod.rs @@ -1,15 +1,16 @@ -use basegl_backend_webgl::{Context, compile_shader, link_program, Program, }; +pub mod font; -use web_sys::{WebGlRenderingContext, WebGlBuffer, WebGlTexture}; use crate::prelude::*; -use crate::Color; - -pub mod font; -use font::FontRenderInfo; +use crate::Color; use crate::text::font::MsdfTexture; -use js_sys::Float32Array; use crate::display::world::Workspace; +use basegl_backend_webgl::{Context, compile_shader, link_program, Program, }; +use web_sys::{WebGlRenderingContext, WebGlBuffer, WebGlTexture}; +use font::FontRenderInfo; +use js_sys::Float32Array; +use nalgebra::{Vector2, Point2}; + pub struct TextComponentBuilder<'a> { pub text : String, @@ -18,7 +19,6 @@ pub struct TextComponentBuilder<'a> { pub y : f32, pub size : f32, pub color : Color, - pub background_color : Color, } #[derive(Debug)] @@ -101,30 +101,40 @@ impl<'a> TextComponentBuilder<'a> { * (https://rustwasm.github.io/wasm-bindgen/examples/webgl.html) */ - fn create_vertex_buf(&self, gl_context : &Context) -> WebGlBuffer { - let y_max = self.y + self.size; - let x_step = self.size; - let vertices = (0..self.text.len()).map(|i| { - let ix = self.x + (i as f32) * x_step; - let ix_max = ix + x_step; - vec![ix, self.y, ix, y_max, ix_max, self.y, ix_max, - self.y, ix, y_max, ix_max, y_max] // Note [The ugly code] + const BASE_GLYPH_VERTICES_LAYOUT : &'static[(f32, f32)] = &[ + (0.0, 0.0), + (0.0, 1.0), + (1.0, 0.0), + (1.0, 0.0), + (0.0, 1.0), + (1.0, 1.0), + ]; + + fn create_vertex_buf(&mut self, gl_context : &Context) -> WebGlBuffer { + let to_window = nalgebra::Similarity2::new( + Vector2::new(self.x, self.y), + 0.0, + self.size + ); + let mut position = nalgebra::Translation2::new(0.0, 0.0); + let font = &mut self.font; + let vertices = self.text.chars().map(|ch| { + let ch_info = font.get_or_create_char_info(ch); + let transformation = to_window*position*ch_info.points_transformation; + position = nalgebra::Translation2::new(ch_info.advance, 0.0)*position; + Self::BASE_GLYPH_VERTICES_LAYOUT.iter() + .map(|(x, y)| Point2::new(*x, *y)) + .map(|p| transformation.transform_point(&p)) + .map(|p| p.iter().cloned().collect::>()) + .flatten().collect::>() }).flatten().collect::>(); Self::create_buffer(gl_context, vertices.as_ref()) } - /* Note [The ugly code] - * - * I have already refactored this function on branch - * wip/ao/letter-alignment. Please be patient - */ fn create_tex_coord_buf(&mut self, gl_context : &Context) -> WebGlBuffer { let font = &mut self.font; - for ch in self.text.chars() { - font.get_or_create_char_info(ch); - } let vertices = self.text.chars().map(|c| { let msdf_rows = font.msdf_texture.rows() as f32; let info = font.get_or_create_char_info(c); @@ -187,21 +197,12 @@ impl<'a> TextComponentBuilder<'a> { } fn setup_uniforms(&self, gl_context : &Context, gl_program : &Program) { - let bg_color_loc = - gl_context.get_uniform_location(gl_program, "bgColor"); let fg_color_loc = gl_context.get_uniform_location(gl_program, "fgColor"); let px_range_loc = gl_context.get_uniform_location(gl_program, "pxRange"); gl_context.use_program(Some(gl_program)); - gl_context.uniform4f( - bg_color_loc.as_ref(), - self.background_color.r, - self.background_color.g, - self.background_color.b, - self.background_color.a - ); gl_context.uniform4f( fg_color_loc.as_ref(), self.color.r, @@ -257,6 +258,13 @@ impl TextComponent { 0 ); + gl.enable(Context::BLEND); + gl.blend_func_separate( + Context::SRC_ALPHA, + Context::ONE_MINUS_SRC_ALPHA, + Context::ZERO, + Context::ONE + ); gl.draw_arrays( WebGlRenderingContext::TRIANGLES, diff --git a/lib/core/src/text/msdf_frag.glsl b/lib/core/src/text/msdf_frag.glsl index 6b8c3e1259..3cdf858603 100644 --- a/lib/core/src/text/msdf_frag.glsl +++ b/lib/core/src/text/msdf_frag.glsl @@ -6,8 +6,7 @@ varying highp vec2 msdfCoord; uniform sampler2D msdf; uniform highp vec2 msdfSize; uniform highp float pxRange; -uniform highp vec4 bgColor; -uniform highp vec4 fgColor; +uniform highp vec4 color; highp float median(highp float r, highp float g, highp float b) { return max(min(r, g), min(max(r, g), b)); @@ -23,6 +22,5 @@ void main() { highp float sigDistPx = sigDist*((msdfUnitPx.x + msdfUnitPx.y)/2.0); highp float opacity = clamp(sigDistPx + 0.5 + dpiDilate*0.1, 0.0, 1.0); - gl_FragColor = mix(bgColor, fgColor, opacity); -// gl_FragColor = vec4(sigDist+0.5, dpiDilate, 0.0, 1.0); + gl_FragColor = vec4(color.xyz, color.w*opacity); } From cddd55431e8f7f7b805c9ae7ee27e572f3e54b91 Mon Sep 17 00:00:00 2001 From: Adam Obuchowicz Date: Thu, 28 Nov 2019 15:55:19 +0100 Subject: [PATCH 11/19] Kerning Code still needs special version of MSDF. Some refactoring wouldn't hurt either. --- lib/core/msdf-sys/src/emscripten_data.rs | 92 ++++++++++++++++ lib/core/msdf-sys/src/internal.rs | 85 ++++----------- lib/core/msdf-sys/src/lib.rs | 132 +++++++++++++++-------- lib/core/src/text/font.rs | 53 ++++++--- lib/core/src/text/mod.rs | 46 +++++++- 5 files changed, 283 insertions(+), 125 deletions(-) create mode 100644 lib/core/msdf-sys/src/emscripten_data.rs diff --git a/lib/core/msdf-sys/src/emscripten_data.rs b/lib/core/msdf-sys/src/emscripten_data.rs new file mode 100644 index 0000000000..6c6694da82 --- /dev/null +++ b/lib/core/msdf-sys/src/emscripten_data.rs @@ -0,0 +1,92 @@ +use wasm_bindgen::JsValue; +use crate::internal::emscripten_get_value_from_memory; +use crate::prelude::*; + +// ================================ +// === EmscriptenRepresentation === +// ================================ + +pub trait EmscriptenRepresentation : Sized { + const EMSCRIPTEN_SIZE_IN_BYTES : usize; + const EMSCRIPTEN_TYPE_NAME : &'static str; + + fn from_js_value(js_value : JsValue) -> Option; + + fn read_from_emscripten_memory(address : usize) -> Option { + let js_value = emscripten_get_value_from_memory( + address, + Self::EMSCRIPTEN_TYPE_NAME + ); + Self::from_js_value(js_value) + } +} + +impl EmscriptenRepresentation for f32 { + const EMSCRIPTEN_SIZE_IN_BYTES : usize = 4; + const EMSCRIPTEN_TYPE_NAME : &'static str = "float"; + + fn from_js_value(js_value: JsValue) -> Option { + js_value.as_f64().map(|f| f as f32) + } +} + +impl EmscriptenRepresentation for f64 { + const EMSCRIPTEN_SIZE_IN_BYTES : usize = 8; + const EMSCRIPTEN_TYPE_NAME : &'static str = "double"; + + fn from_js_value(js_value: JsValue) -> Option { + js_value.as_f64() + } +} + +// ======================= +// === ArrayMemoryView === +// ======================= + +pub struct ArrayMemoryView { + begin_address : usize, + end_address : usize, + type_marker : std::marker::PhantomData +} + +pub struct ArrayMemoryViewIterator<'a, F : EmscriptenRepresentation> { + next_read_address : usize, + end_address : usize, + view_lifetime : std::marker::PhantomData<&'a ArrayMemoryView> +} + +impl +ArrayMemoryView { + pub fn new(address : usize, size : usize) -> ArrayMemoryView { + let size_in_bytes = + size * F::EMSCRIPTEN_SIZE_IN_BYTES; + ArrayMemoryView { + begin_address : address, + end_address : address + size_in_bytes, + type_marker : std::marker::PhantomData + } + } + + pub fn iter(&self) -> ArrayMemoryViewIterator { + ArrayMemoryViewIterator { + next_read_address : self.begin_address, + end_address : self.end_address, + view_lifetime : std::marker::PhantomData + } + } +} + +impl<'a, F : EmscriptenRepresentation> +Iterator for ArrayMemoryViewIterator<'a, F> { + type Item = F; + + fn next(&mut self) -> Option { + let has_element = self.next_read_address < self.end_address; + has_element.and_option_from(|| { + let ret_val = + F::read_from_emscripten_memory(self.next_read_address).unwrap(); + self.next_read_address += F::EMSCRIPTEN_SIZE_IN_BYTES; + Some(ret_val) + }) + } +} diff --git a/lib/core/msdf-sys/src/internal.rs b/lib/core/msdf-sys/src/internal.rs index 20649bab93..4f67ddf2dc 100644 --- a/lib/core/msdf-sys/src/internal.rs +++ b/lib/core/msdf-sys/src/internal.rs @@ -1,6 +1,5 @@ use wasm_bindgen::prelude::wasm_bindgen; use wasm_bindgen::JsValue; -use crate::prelude::*; #[wasm_bindgen(module = "/msdfgen_wasm.js")] extern { @@ -25,8 +24,12 @@ extern { a_type: &str ) -> JsValue; - #[wasm_bindgen(js_name="_msdfgen_maxMSDFSize")] - pub fn msdfgen_max_msdf_size() -> usize; + #[wasm_bindgen(js_name="_msdfgen_getKerning")] + pub fn msdfgen_get_kerning( + font_handle : JsValue, + left_unicode : u32, + right_unicode : u32 + ) -> f64; #[wasm_bindgen(js_name="_msdfgen_generateAutoscaledMSDF")] pub fn msdfgen_generate_msdf( @@ -38,72 +41,28 @@ extern { range : f64, edge_threshold : f64, overlap_support : bool - ) -> usize; - - #[wasm_bindgen(js_name="_msdfgen_freeFont")] - pub fn msdfgen_free_font(font_handle: JsValue); -} - -pub mod emscripten_data_types { - pub const FLOAT_SIZE_IN_BYTES : usize = 4; + ) -> JsValue; - pub const ARRAY : &str = "array"; - pub const NUMBER : &str = "number"; - pub const FLOAT : &str = "float"; -} + #[wasm_bindgen(js_name="_msdfgen_result_getMSDFData")] + pub fn msdfgen_result_get_msdf_data(result_handle : JsValue) -> usize; -// ========================== -// === F32ArrayMemoryView === -// ========================== + #[wasm_bindgen(js_name="_msdfgen_result_getAdvance")] + pub fn msdfgen_result_get_advance(result_handle : JsValue) -> f64; -pub struct F32ArrayMemoryView { - begin_address : usize, - end_address : usize -} + #[wasm_bindgen(js_name="_msdfgen_result_getTranslation")] + pub fn msdfgen_result_get_translation(result_handle : JsValue) -> usize; -pub struct F32ArrayMemoryViewIterator { - next_read_address : usize, - end_address : usize -} + #[wasm_bindgen(js_name="_msdfgen_result_getScale")] + pub fn msdfgen_result_get_scale(result_handle : JsValue) -> usize; -impl F32ArrayMemoryView { - pub fn new(address : usize, size : usize) -> F32ArrayMemoryView { - let size_in_bytes = - size * emscripten_data_types::FLOAT_SIZE_IN_BYTES; - F32ArrayMemoryView { - begin_address : address, - end_address : address + size_in_bytes - } - } + #[wasm_bindgen(js_name="_msdfgen_freeResult")] + pub fn msdfgen_free_result(result_handle : JsValue); - pub fn iter(&self) -> F32ArrayMemoryViewIterator { - F32ArrayMemoryViewIterator { - next_read_address : self.begin_address, - end_address : self.end_address - } - } + #[wasm_bindgen(js_name="_msdfgen_freeFont")] + pub fn msdfgen_free_font(font_handle: JsValue); } -impl IntoIterator for F32ArrayMemoryView { - type Item = f32; - type IntoIter = F32ArrayMemoryViewIterator; - - fn into_iter(self) -> Self::IntoIter { - self.iter() - } +pub mod ccall_types { + pub const ARRAY : &str = "array"; + pub const NUMBER : &str = "number"; } - -impl Iterator for F32ArrayMemoryViewIterator { - type Item = f32; - - fn next(&mut self) -> Option { - let has_element = self.next_read_address < self.end_address; - has_element.and_option_from(|| { - let ret_val = emscripten_get_value_from_memory( - self.next_read_address, - emscripten_data_types::FLOAT); - self.next_read_address += emscripten_data_types::FLOAT_SIZE_IN_BYTES; - Some(ret_val.as_f64().unwrap() as f32) - }) - } -} \ No newline at end of file diff --git a/lib/core/msdf-sys/src/lib.rs b/lib/core/msdf-sys/src/lib.rs index cf7cafce7d..da9b892bc4 100644 --- a/lib/core/msdf-sys/src/lib.rs +++ b/lib/core/msdf-sys/src/lib.rs @@ -1,4 +1,5 @@ mod internal; +pub mod emscripten_data; pub mod test_utils; pub use basegl_prelude as prelude; @@ -8,12 +9,18 @@ use internal::{ emscripten_call_function, msdfgen_generate_msdf, msdfgen_free_font, - emscripten_data_types, - F32ArrayMemoryView, + msdfgen_result_get_msdf_data, + msdfgen_result_get_translation, + msdfgen_result_get_advance, + msdfgen_result_get_scale, + msdfgen_free_result, + ccall_types }; +use emscripten_data::ArrayMemoryView; use js_sys::Uint8Array; use wasm_bindgen::JsValue; use wasm_bindgen::prelude::Closure; +use crate::internal::msdfgen_get_kerning; // ====================== // === Initialization === @@ -48,8 +55,8 @@ impl Font { /// See [https://www.freetype.org/freetype2/docs/index.html] for reference. pub fn load_from_memory(data: &[u8]) -> Self { let param_types = js_sys::Array::of2( - &JsValue::from_str(emscripten_data_types::ARRAY), - &JsValue::from_str(emscripten_data_types::NUMBER) + &JsValue::from_str(ccall_types::ARRAY), + &JsValue::from_str(ccall_types::NUMBER) ); let params = js_sys::Array::of2( &JsValue::from(Uint8Array::from(data)), @@ -57,11 +64,15 @@ impl Font { ); let handle = emscripten_call_function( "msdfgen_loadFontMemory", - emscripten_data_types::NUMBER, + ccall_types::NUMBER, param_types, params); Font { handle } } + + pub fn retrieve_kerning(&self, left : char, right : char) -> f64 { + msdfgen_get_kerning(self.handle.clone(), left as u32, right as u32) + } } impl Drop for Font { @@ -78,7 +89,7 @@ impl Drop for Font { /// /// The structure gathering MSDF generation parameters meant to be same for all /// rendered glyphs -pub struct MSDFParameters { +pub struct MsdfParameters { pub width : usize, pub height : usize, pub edge_coloring_angle_threshold : f64, @@ -87,43 +98,76 @@ pub struct MSDFParameters { pub overlap_support : bool } -pub const MAX_MSDF_SIZE : usize = 64; -pub const MSDF_CHANNELS_COUNT : usize = 3; - -///// Generate Mutlichannel Signed Distance Field (MSDF) for one glyph -///// -///// For more information about MSDF see [https://github.com/Chlumsky/msdfgen]. -pub fn generate_msdf>( - output : &mut Output, - font : &Font, - unicode : u32, - params : &MSDFParameters, -) -> (nalgebra::Projective2, f32) { - assert!(params.width <= MAX_MSDF_SIZE); - assert!(params.height <= MAX_MSDF_SIZE); - - let output_size = params.width * params.height * MSDF_CHANNELS_COUNT + 4; - let output_address = msdfgen_generate_msdf( - params.width, - params.height, - font.handle.clone(), - unicode, - params.edge_coloring_angle_threshold, - params.range, - params.edge_threshold, - params.overlap_support - ); - let mut output_iter = F32ArrayMemoryView::new(output_address, output_size) - .iter(); - let translation = nalgebra::Vector2::new( - output_iter.next().unwrap()/params.width as f32, - output_iter.next().unwrap()/params.height as f32 - ); - let scale = output_iter.next().unwrap(); - let advance = output_iter.next().unwrap(); - output.extend(output_iter); // Note [Output variable] - - (nalgebra::convert(nalgebra::Similarity2::new(translation, 0.0, scale)), advance) +pub struct MultichannelSignedDistanceField { + handle : JsValue, + pub advance : f64, + pub translation : nalgebra::Vector2, + pub scale : nalgebra::Vector2, + pub data : ArrayMemoryView +} + +impl MultichannelSignedDistanceField { + pub const CHANNELS_COUNT : usize = 3; + + ///// Generate Mutlichannel Signed Distance Field (MSDF) for one glyph + ///// + ///// For more information about MSDF see [https://github.com/Chlumsky/msdfgen]. + pub fn generate( + font : &Font, + unicode : u32, + params : &MsdfParameters, + ) -> MultichannelSignedDistanceField { + let handle = msdfgen_generate_msdf( + params.width, + params.height, + font.handle.clone(), + unicode, + params.edge_coloring_angle_threshold, + params.range, + params.edge_threshold, + params.overlap_support + ); + let advance = msdfgen_result_get_advance(handle.clone()); + let translation = Self::translation(&handle); + let scale = Self::scale(&handle); + + let data_adress = msdfgen_result_get_msdf_data(handle.clone()); + let data_size = params.width * params.height * Self::CHANNELS_COUNT; + let data = ArrayMemoryView::::new(data_adress, data_size); + + MultichannelSignedDistanceField { + handle, advance, translation, scale, data + } + } + + const TRANSLATION_DIMS : usize = 2; + const SCALE_DIMS : usize = 2; + + fn translation(handle : &JsValue) -> nalgebra::Vector2 { + let address = msdfgen_result_get_translation(handle.clone()); + let view = ArrayMemoryView::::new( + address, + Self::TRANSLATION_DIMS + ); + let mut iter = view.iter(); + nalgebra::Vector2::new(iter.next().unwrap(), iter.next().unwrap()) + } + + fn scale(handle : &JsValue) -> nalgebra::Vector2 { + let address = msdfgen_result_get_scale(handle.clone()); + let view = ArrayMemoryView::::new( + address, + Self::SCALE_DIMS + ); + let mut iter = view.iter(); + nalgebra::Vector2::new(iter.next().unwrap(), iter.next().unwrap()) + } +} + +impl Drop for MultichannelSignedDistanceField { + fn drop(&mut self) { + msdfgen_free_result(self.handle.clone()); + } } // ============= @@ -149,7 +193,7 @@ mod tests { let font = Font::load_from_memory( font_base.font_data_by_name.get("DejaVuSansMono-Bold").unwrap() ); - let params = MSDFParameters { + let params = MsdfParameters { width: 32, height: 32, edge_coloring_angle_threshold: 3.0, diff --git a/lib/core/src/text/font.rs b/lib/core/src/text/font.rs index 08a35526ae..d40ea7b7e6 100644 --- a/lib/core/src/text/font.rs +++ b/lib/core/src/text/font.rs @@ -23,7 +23,7 @@ impl MsdfTexture { /// Number of rows in texture pub fn rows(&self) -> usize { - self.data.len()/(msdf_sys::MSDF_CHANNELS_COUNT*Self::WIDTH) + self.data.len()/(msdf_sys::MultichannelSignedDistanceField::CHANNELS_COUNT*Self::WIDTH) } fn convert_cell_from_f32(value : f32) -> u8 { @@ -55,15 +55,16 @@ pub struct CharRenderInfo { /// /// The data for individual characters are load on demand pub struct FontRenderInfo { - pub name : String, - pub msdf_sys_handle : msdf_sys::Font, - pub msdf_texture : MsdfTexture, - chars : HashMap + pub name : String, + pub msdf_sys_font : msdf_sys::Font, + pub msdf_texture : MsdfTexture, + chars : HashMap, + kerning : HashMap<(char, char), f32> } impl FontRenderInfo { - pub const MSDF_PARAMS : msdf_sys::MSDFParameters = - msdf_sys::MSDFParameters { + pub const MSDF_PARAMS : msdf_sys::MsdfParameters = + msdf_sys::MsdfParameters { width : MsdfTexture::WIDTH, height : MsdfTexture::WIDTH, edge_coloring_angle_threshold : 3.0, @@ -79,9 +80,10 @@ impl FontRenderInfo { ) -> FontRenderInfo { FontRenderInfo { name, - msdf_sys_handle : msdf_sys::Font::load_from_memory(font_data), + msdf_sys_font: msdf_sys::Font::load_from_memory(font_data), msdf_texture : MsdfTexture { data : Vec::new() }, - chars : HashMap::new() + chars : HashMap::new(), + kerning : HashMap::new() } } @@ -98,18 +100,27 @@ impl FontRenderInfo { /// Load char render info pub fn load_char(&mut self, ch : char) { - let msdf_texture_rows_begin = self.msdf_texture.rows(); - let (transformation, advance) = msdf_sys::generate_msdf( - &mut self.msdf_texture, - &self.msdf_sys_handle, + let msdf = msdf_sys::MultichannelSignedDistanceField::generate( + &self.msdf_sys_font, ch as u32, &FontRenderInfo::MSDF_PARAMS, ); + + let msdf_texture_rows_begin = self.msdf_texture.rows(); + self.msdf_texture.extend(msdf.data.iter()); let msdf_texture_rows_end = self.msdf_texture.rows(); + + let msdf_tranformation_matrix = nalgebra::Matrix3::new( + msdf.scale[0] as f32, 0.0, msdf.translation[0] as f32/MsdfTexture::WIDTH as f32*msdf.scale[0] as f32, + 0.0, msdf.scale[1] as f32, msdf.translation[1] as f32/MsdfTexture::WIDTH as f32*msdf.scale[0] as f32, + 0.0, 0.0, 1.0 + ); + let msdf_transformation : nalgebra::Projective2 = nalgebra::Projective2::from_matrix_unchecked(msdf_tranformation_matrix); + let char_info = CharRenderInfo { msdf_texture_rows : msdf_texture_rows_begin..msdf_texture_rows_end, - points_transformation: transformation.inverse(), - advance: advance/MsdfTexture::WIDTH as f32 + points_transformation: msdf_transformation.inverse(), + advance: msdf.advance as f32 / MsdfTexture::WIDTH as f32 }; self.chars.insert(ch, char_info); } @@ -121,6 +132,18 @@ impl FontRenderInfo { } self.chars.get(&ch).unwrap() } + + pub fn get_or_retrieve_kerning(&mut self, left : char, right : char) + -> f32 { + if !self.kerning.contains_key(&(left, right)) { + let kerning = + self.msdf_sys_font.retrieve_kerning(left, right) as f32 / MsdfTexture::WIDTH as f32; + self.kerning.insert((left, right), kerning); + kerning + } else { + *self.kerning.get(&(left, right)).unwrap() + } + } } diff --git a/lib/core/src/text/mod.rs b/lib/core/src/text/mod.rs index f4136b9235..2beb877144 100644 --- a/lib/core/src/text/mod.rs +++ b/lib/core/src/text/mod.rs @@ -11,6 +11,39 @@ use font::FontRenderInfo; use js_sys::Float32Array; use nalgebra::{Vector2, Point2}; +struct CachingIterator> { + last : Option, + iter : It +} + +impl> Iterator for CachingIterator { + type Item = (Option, T); + + fn next(&mut self) -> Option { + self.iter.next().map(|value| { + let new_last = Some(value.clone()); + let old_last = std::mem::replace(&mut self.last, new_last); + (old_last, value) + }) + } +} + +trait IntoCachingIterator { + type Item : Clone; + type Iter : Iterator; + fn cache_last_value(self) -> CachingIterator; +} + +impl> IntoCachingIterator for It { + type Item = T; + type Iter = Self; + + fn cache_last_value(self) -> CachingIterator { + CachingIterator { last : None, iter : self } + } +} + + pub struct TextComponentBuilder<'a> { pub text : String, @@ -35,6 +68,11 @@ impl<'a> TextComponentBuilder<'a> { pub fn build(mut self, workspace : &Workspace) -> TextComponent { let gl_context = workspace.context.clone(); let gl_program = self.create_program(&gl_context); + + for ch in self.text.chars() { + self.font.get_or_create_char_info(ch); + } + let gl_vertex_buf = self.create_vertex_buf(&gl_context); let gl_tex_coord_buf = self.create_tex_coord_buf(&gl_context); let gl_msdf_texture = @@ -118,10 +156,12 @@ impl<'a> TextComponentBuilder<'a> { ); let mut position = nalgebra::Translation2::new(0.0, 0.0); let font = &mut self.font; - let vertices = self.text.chars().map(|ch| { + let vertices = self.text.chars().cache_last_value().map(|(last_ch, ch)| { + let kerning = last_ch.map(|lc| font.get_or_retrieve_kerning(lc, ch) ).unwrap_or(0.0); let ch_info = font.get_or_create_char_info(ch); - let transformation = to_window*position*ch_info.points_transformation; - position = nalgebra::Translation2::new(ch_info.advance, 0.0)*position; + let kerning_trans = nalgebra::Translation2::new(kerning, 0.0); + let transformation = to_window*position*ch_info.points_transformation*kerning_trans; + position = nalgebra::Translation2::new(ch_info.advance+kerning, 0.0)*position; Self::BASE_GLYPH_VERTICES_LAYOUT.iter() .map(|(x, y)| Point2::new(*x, *y)) .map(|p| transformation.transform_point(&p)) From 94d10517a3b27eea429f1e23d3c4c1fb00652c07 Mon Sep 17 00:00:00 2001 From: Adam Obuchowicz Date: Fri, 29 Nov 2019 13:54:03 +0100 Subject: [PATCH 12/19] WIP --- lib/core/src/data/container.rs | 50 ++++++++++++++++++++++++++++++++++ lib/core/src/text/mod.rs | 40 ++------------------------- 2 files changed, 53 insertions(+), 37 deletions(-) diff --git a/lib/core/src/data/container.rs b/lib/core/src/data/container.rs index fea9d21128..4a77640644 100644 --- a/lib/core/src/data/container.rs +++ b/lib/core/src/data/container.rs @@ -11,3 +11,53 @@ pub trait Add { } pub type AddResult = >::Result; + +// ======================= +// === CachingIterator === +// ======================= + +/// Iterator wrapper caching the last retrieved value +/// +/// The item type is `(Option, T)` where the second tuple element is +/// a current value and first element is a previous one `None` on the first +/// iteration. +pub struct CachingIterator> { + last : Option, + iter : It +} + +impl> Iterator for CachingIterator { + type Item = (Option, T); + + fn next(&mut self) -> Option { + self.iter.next().map(|value| { + let new_last = Some(value.clone()); + let old_last = std::mem::replace(&mut self.last, new_last); + (old_last, value) + }) + } +} + +/// A trait for wrapping in caching iterator +/// +/// It is implemented for each iterator over cloneable items. +pub trait IntoCachingIterator { + type Item : Clone; + type Iter : Iterator; + + fn cache_last_value(self) -> CachingIterator; +} + +impl> IntoCachingIterator for It { + type Item = T; + type Iter = Self; + + fn cache_last_value(self) -> CachingIterator { + CachingIterator { last : None, iter : self } + } +} + +#[cfg(test)] +mod tests { + +} \ No newline at end of file diff --git a/lib/core/src/text/mod.rs b/lib/core/src/text/mod.rs index 2beb877144..5502383bd9 100644 --- a/lib/core/src/text/mod.rs +++ b/lib/core/src/text/mod.rs @@ -5,46 +5,13 @@ use crate::prelude::*; use crate::Color; use crate::text::font::MsdfTexture; use crate::display::world::Workspace; +use crate::data::container::IntoCachingIterator; use basegl_backend_webgl::{Context, compile_shader, link_program, Program, }; use web_sys::{WebGlRenderingContext, WebGlBuffer, WebGlTexture}; use font::FontRenderInfo; use js_sys::Float32Array; use nalgebra::{Vector2, Point2}; -struct CachingIterator> { - last : Option, - iter : It -} - -impl> Iterator for CachingIterator { - type Item = (Option, T); - - fn next(&mut self) -> Option { - self.iter.next().map(|value| { - let new_last = Some(value.clone()); - let old_last = std::mem::replace(&mut self.last, new_last); - (old_last, value) - }) - } -} - -trait IntoCachingIterator { - type Item : Clone; - type Iter : Iterator; - fn cache_last_value(self) -> CachingIterator; -} - -impl> IntoCachingIterator for It { - type Item = T; - type Iter = Self; - - fn cache_last_value(self) -> CachingIterator { - CachingIterator { last : None, iter : self } - } -} - - - pub struct TextComponentBuilder<'a> { pub text : String, pub font : &'a mut FontRenderInfo, @@ -237,14 +204,13 @@ impl<'a> TextComponentBuilder<'a> { } fn setup_uniforms(&self, gl_context : &Context, gl_program : &Program) { - let fg_color_loc = - gl_context.get_uniform_location(gl_program, "fgColor"); + let color_loc = gl_context.get_uniform_location(gl_program, "color"); let px_range_loc = gl_context.get_uniform_location(gl_program, "pxRange"); gl_context.use_program(Some(gl_program)); gl_context.uniform4f( - fg_color_loc.as_ref(), + color_loc.as_ref(), self.color.r, self.color.g, self.color.b, From 3d0225355a49f144dfcb78f63bdd25769793a60a Mon Sep 17 00:00:00 2001 From: Adam Obuchowicz Date: Fri, 29 Nov 2019 14:57:15 +0100 Subject: [PATCH 13/19] Moved CachingIterator and fix tests --- lib/core/msdf-sys/build.rs | 6 ++++-- lib/core/msdf-sys/src/lib.rs | 37 +++++++++++++++------------------- lib/core/src/data/container.rs | 19 ++++++++++++++++- lib/core/src/text/font.rs | 2 +- 4 files changed, 39 insertions(+), 25 deletions(-) diff --git a/lib/core/msdf-sys/build.rs b/lib/core/msdf-sys/build.rs index 0c1e2b9fd0..23db79cbc8 100644 --- a/lib/core/msdf-sys/build.rs +++ b/lib/core/msdf-sys/build.rs @@ -30,8 +30,10 @@ mod msdfgen_wasm { * remember to remove msdfgen_wasm.js entry from .gitignore */ - const PATCH_LINE : &str = "; export { ccall, getValue, \ - _msdfgen_maxMSDFSize, _msdfgen_generateMSDF, _msdfgen_freeFont, \ + const PATCH_LINE : &str = "; export { ccall, getValue, _msdfgen_getKerning,\ + _msdfgen_generateAutoscaledMSDF, _msdfgen_result_getMSDFData,\ + _msdfgen_result_getAdvance, _msdfgen_result_getTranslation,\ + _msdfgen_result_getScale, _msdfgen_freeResult, _msdfgen_freeFont,\ addInitializationCb, isInitialized }"; /// Patches downloaded msdfgen_wasm.js file diff --git a/lib/core/msdf-sys/src/lib.rs b/lib/core/msdf-sys/src/lib.rs index da9b892bc4..b9c3462176 100644 --- a/lib/core/msdf-sys/src/lib.rs +++ b/lib/core/msdf-sys/src/lib.rs @@ -176,12 +176,12 @@ impl Drop for MultichannelSignedDistanceField { #[cfg(test)] mod tests { - use wasm_bindgen_test::{wasm_bindgen_test, wasm_bindgen_test_configure}; - use internal::msdfgen_max_msdf_size; use crate::*; + use wasm_bindgen_test::{wasm_bindgen_test, wasm_bindgen_test_configure}; use basegl_core_embedded_fonts::EmbeddedFonts; use std::future::Future; use test_utils::TestAfterInit; + use nalgebra::Vector2; wasm_bindgen_test_configure!(run_in_browser); @@ -194,26 +194,28 @@ mod tests { font_base.font_data_by_name.get("DejaVuSansMono-Bold").unwrap() ); let params = MsdfParameters { - width: 32, - height: 32, - edge_coloring_angle_threshold: 3.0, - range: 2.0, - edge_threshold: 1.001, - overlap_support: true + width : 32, + height : 32, + edge_coloring_angle_threshold : 3.0, + range : 2.0, + edge_threshold : 1.001, + overlap_support : true }; // when - let mut msdf = Vec::::new(); - generate_msdf( - &mut msdf, + let msdf = MultichannelSignedDistanceField::generate( &font, 'A' as u32, ¶ms, ); // then + let data : Vec = msdf.data.iter().collect(); // Note [asserts] - assert_eq!(0.42730755, msdf[0]); - assert_eq!(0.75, msdf[10]); - assert_eq!(-9.759168, msdf[msdf.len()-1]); + assert_eq!(-0.9408906, data[0]); + assert_eq!(0.2, data[10]); + assert_eq!(-4.3035655, data[data.len()-1]); + assert_eq!(Vector2::new(3.03125, 1.0), msdf.translation); + assert_eq!(Vector2::new(1.25, 1.25), msdf.scale); + assert_eq!(19.265625, msdf.advance); }) } @@ -222,11 +224,4 @@ mod tests { * we're checking rust - js interface only, so there is no need to check * all values */ - - #[wasm_bindgen_test(async)] - fn msdf_data_limits() -> impl Future { - TestAfterInit::schedule(|| { - assert!(MAX_MSDF_SIZE <= msdfgen_max_msdf_size()); - }) - } } diff --git a/lib/core/src/data/container.rs b/lib/core/src/data/container.rs index 4a77640644..8835d52cd5 100644 --- a/lib/core/src/data/container.rs +++ b/lib/core/src/data/container.rs @@ -59,5 +59,22 @@ impl> IntoCachingIterator for It { #[cfg(test)] mod tests { - + use crate::data::container::IntoCachingIterator; + + #[test] + fn caching_iterator_on_empty() { + let data = Vec::::new(); + let result = data.iter().cache_last_value().next(); + assert_eq!(None, result); + } + + #[test] + fn caching_iterator() { + let data = vec![2, 3, 5]; + let mut caching_iterator = data.iter().cloned().cache_last_value(); + assert_eq!(Some((None , 2)), caching_iterator.next()); + assert_eq!(Some((Some(2), 3)), caching_iterator.next()); + assert_eq!(Some((Some(3), 5)), caching_iterator.next()); + assert_eq!(None, caching_iterator.next()); + } } \ No newline at end of file diff --git a/lib/core/src/text/font.rs b/lib/core/src/text/font.rs index d40ea7b7e6..a63edae66f 100644 --- a/lib/core/src/text/font.rs +++ b/lib/core/src/text/font.rs @@ -200,7 +200,7 @@ mod tests { font_render_info.load_char('B'); let expected_texture_size = MsdfTexture::WIDTH * MsdfTexture::WIDTH - * msdf_sys::MSDF_CHANNELS_COUNT * 2; + * msdf_sys::MultichannelSignedDistanceField::CHANNELS_COUNT * 2; assert_eq!(MsdfTexture::WIDTH * 2, font_render_info.msdf_texture.rows()); From 2cd9e5ad5e85def09efa3b753f5e8e6f03cc07c2 Mon Sep 17 00:00:00 2001 From: Adam Obuchowicz Date: Tue, 3 Dec 2019 15:29:18 +0100 Subject: [PATCH 14/19] Massive refactoring --- build-utilities/src/lib.rs | 61 ++--- lib/core/Cargo.toml | 1 - lib/core/embedded-fonts/build.rs | 91 +++---- lib/core/embedded-fonts/src/lib.rs | 14 +- lib/core/msdf-sys/build.rs | 31 +-- lib/core/msdf-sys/src/emscripten_data.rs | 22 +- lib/core/msdf-sys/src/internal.rs | 59 ++--- lib/core/msdf-sys/src/lib.rs | 152 ++++++------ lib/core/msdf-sys/src/test_utils.rs | 10 +- lib/core/src/data/container.rs | 19 +- lib/core/src/data/opt_vec.rs | 1 - lib/core/src/lib.rs | 62 ++--- lib/core/src/text.rs | 229 ++++++++++++++++++ lib/core/src/text/font.rs | 276 ++++++++++----------- lib/core/src/text/glyph_render.rs | 290 +++++++++++++++++++++++ lib/core/src/text/mod.rs | 281 ---------------------- lib/core/src/text/msdf.rs | 148 ++++++++++++ lib/core/src/text/msdf_frag.glsl | 41 ++-- lib/core/src/text/msdf_vert.glsl | 2 +- lib/prelude/Cargo.toml | 3 +- lib/prelude/src/lib.rs | 1 + lib/system/web/js/resize_observer.js | 1 + 22 files changed, 1095 insertions(+), 700 deletions(-) create mode 100644 lib/core/src/text.rs create mode 100644 lib/core/src/text/glyph_render.rs delete mode 100644 lib/core/src/text/mod.rs create mode 100644 lib/core/src/text/msdf.rs diff --git a/build-utilities/src/lib.rs b/build-utilities/src/lib.rs index acf766cd3d..9ec9ef9c24 100644 --- a/build-utilities/src/lib.rs +++ b/build-utilities/src/lib.rs @@ -3,32 +3,37 @@ use std::{fs, path}; use std::io::ErrorKind; -/// Download the release package from github -/// -/// The project_url should be a project's main page on github. -pub fn github_download( - project_url : &str, - version : &str, - filename : &str, - destination_dir : &path::Path -) { - let url = format!( - "{project}/releases/download/{version}/{filename}", - project = project_url, - version = version, - filename = filename - ); - - let destination_file = path::Path::new(destination_dir) - .join(filename); - - let rm_error = fs::remove_file(&destination_file).err(); - let fatal_rm_error = - rm_error.filter(|err| err.kind() != ErrorKind::NotFound); - fatal_rm_error.unwrap_none(); - - download_lp::download( - url.as_str(), - destination_dir.to_str().unwrap() - ).unwrap(); + +/// A structure describing a concrete release package on github +pub struct GithubRelease<'a,'b,'c> { + pub project_url : &'a str, + pub version : &'b str, + pub filename : &'c str, +} + +impl GithubRelease<'_, '_, '_> { + /// Download the release package from github + /// + /// The project_url should be a project's main page on github. + pub fn download(&self, destination_dir:&path::Path) { + let url = format!( + "{project}/releases/download/{version}/{filename}", + project = self.project_url, + version = self.version, + filename = self.filename); + + let destination_dir_str = destination_dir.to_str().unwrap(); + let destination_file = destination_dir.join(self.filename); + + Self::remove_old_file(&destination_file); + + download_lp::download(url.as_str(),destination_dir_str).unwrap(); + } + + fn remove_old_file(file:&path::Path) { + let result = fs::remove_file(&file); + let error = result.err(); + let fatal_error = error.filter(|err| err.kind() != ErrorKind::NotFound); + fatal_error.unwrap_none(); + } } diff --git a/lib/core/Cargo.toml b/lib/core/Cargo.toml index c2b9a58e5a..2f3f67ce0f 100644 --- a/lib/core/Cargo.toml +++ b/lib/core/Cargo.toml @@ -34,7 +34,6 @@ typenum = { version = "1.11.2" } rustc-hash = { version = "1.0.1" } console_error_panic_hook = { version = "0.1.6" } num_enum = { version = "0.4.2" } -smallvec = { version = "1.0.0" } [dependencies.web-sys] version = "0.3.4" diff --git a/lib/core/embedded-fonts/build.rs b/lib/core/embedded-fonts/build.rs index 16f0f99676..fd5ccbd1e1 100644 --- a/lib/core/embedded-fonts/build.rs +++ b/lib/core/embedded-fonts/build.rs @@ -11,19 +11,17 @@ pub struct FillMapRsFile { } impl FillMapRsFile { - fn create>(path : P) -> io::Result { + fn create>(path:P) -> io::Result { let mut file = fs::File::create(path)?; writeln!(file, "{{")?; Ok(FillMapRsFile{ file }) } - fn add_font_inserting_line(&mut self, font_name : &str, font_file : &str) - -> io::Result<()> { - writeln!( - self.file, - " fonts_by_name.insert(\"{}\", include_bytes!(\"{}\"));", - font_name, - font_file + fn add_font_inserting_line(&mut self, font_name:&str, font_file:&str) -> io::Result<()> { + writeln!(self.file, + " font_data_by_name.insert(\"{font_name}\", include_bytes!(\"{font_file}\"));", + font_name = font_name, + font_file = font_file ) } @@ -37,38 +35,34 @@ impl FillMapRsFile { // ==================== mod deja_vu { - use std::path; - use basegl_build_utilities::github_download; use crate::FillMapRsFile; - pub const PACKAGE_NAME : &str = "dejavu-fonts-ttf-2.37.zip"; - pub const PACKAGE_VERSION : &str = "version_2_37"; - pub const PROJECT_URL : &str = - "https://github.com/dejavu-fonts/dejavu-fonts/"; + use std::path; + use basegl_build_utilities::GithubRelease; + + pub const PACKAGE : GithubRelease = GithubRelease { + project_url : "https://github.com/dejavu-fonts/dejavu-fonts/", + version : "version_2_37", + filename : "dejavu-fonts-ttf-2.37.zip" + }; - pub const PACKAGE_FONTS_PREFIX: &str = "dejavu-fonts-ttf-2.37/ttf"; + pub const PACKAGE_FONTS_PREFIX : &str = "dejavu-fonts-ttf-2.37/ttf"; - pub fn font_file_from_font_name(font_name : &str) -> String { + pub fn font_file_from_font_name(font_name:&str) -> String { return format!("{}.ttf", font_name); } - pub fn extract_font(package_path : &path::Path, font_name : &str) { - let font_file = font_file_from_font_name(font_name); - let font_package_path = format!("{}/{}", - PACKAGE_FONTS_PREFIX, - font_file - ); - - let mut archive = zip::ZipArchive::new( - std::fs::File::open(package_path).unwrap() - ).unwrap(); - let mut input = archive.by_name( - font_package_path.as_str() - ).unwrap(); - let mut output = std::fs::File::create( - package_path.parent().unwrap().join(font_file) - ).unwrap(); - std::io::copy(&mut input, &mut output).unwrap(); + pub fn extract_font(package_path:&path::Path, font_name:&str) { + let font_file = font_file_from_font_name(font_name); + let font_in_package_path = format!("{}/{}",PACKAGE_FONTS_PREFIX,font_file); + let package_dir = package_path.parent().unwrap(); + let output_path = package_dir.join(font_file); + + let archive_file = std::fs::File::open(package_path).unwrap(); + let mut archive = zip::ZipArchive::new(archive_file).unwrap(); + let mut input_stream = archive.by_name(font_in_package_path.as_str()).unwrap(); + let mut output_stream = std::fs::File::create(output_path).unwrap(); + std::io::copy(&mut input_stream, &mut output_stream).unwrap(); } pub const FONTS_TO_EXTRACT : &[&str] = &[ @@ -79,8 +73,7 @@ mod deja_vu { "DejaVuSansMono-Oblique", "DejaVuSansCondensed", "DejaVuSerif", - "DejaVuSerifCondensed", - ]; + "DejaVuSerifCondensed" ]; pub fn extract_all_fonts(package_path : &path::Path) { for font_name in FONTS_TO_EXTRACT { @@ -89,35 +82,27 @@ mod deja_vu { } pub fn download_and_extract_all_fonts(out_dir : &path::Path) { - github_download( - PROJECT_URL, - PACKAGE_VERSION, - PACKAGE_NAME, - &out_dir - ); - - let package_path = out_dir.join(PACKAGE_NAME); + let package_path = out_dir.join(PACKAGE.filename); + + PACKAGE.download(&out_dir); extract_all_fonts(package_path.as_path()); } - pub fn add_entries_to_fill_map_rs(file : &mut FillMapRsFile) { + pub fn add_entries_to_fill_map_rs(file:&mut FillMapRsFile) { for font_name in FONTS_TO_EXTRACT { let font_file = font_file_from_font_name(font_name); - file.add_font_inserting_line( - font_name, - font_file.as_str() - ).unwrap(); + + file.add_font_inserting_line(font_name,font_file.as_str()).unwrap(); } } } fn main() { - let out = env::var("OUT_DIR").unwrap(); - let out_dir = path::Path::new(&out); - let fill_map_rs_path = out_dir.join("fill_map.rs"); + let out = env::var("OUT_DIR").unwrap(); + let out_dir = path::Path::new(&out); + let fill_map_rs_path = out_dir.join("fill_map.rs"); - let mut fill_map_rs_file = - FillMapRsFile::create(fill_map_rs_path).unwrap(); + let mut fill_map_rs_file = FillMapRsFile::create(fill_map_rs_path).unwrap(); deja_vu::download_and_extract_all_fonts(out_dir); deja_vu::add_entries_to_fill_map_rs(&mut fill_map_rs_file); diff --git a/lib/core/embedded-fonts/src/lib.rs b/lib/core/embedded-fonts/src/lib.rs index 361fa8f076..dcd8529485 100644 --- a/lib/core/embedded-fonts/src/lib.rs +++ b/lib/core/embedded-fonts/src/lib.rs @@ -7,7 +7,7 @@ use basegl_prelude::*; /// /// For list of embedded fonts, see FONTS_TO_EXTRACT constant in `build.rs` pub struct EmbeddedFonts { - pub font_data_by_name: HashMap<&'static str, &'static [u8]> + pub font_data_by_name: HashMap<&'static str,&'static [u8]> } impl EmbeddedFonts { @@ -16,23 +16,21 @@ impl EmbeddedFonts { /// For list of embedded fonts, see `FONTS_TO_EXTRACT` constant in /// `build.rs` pub fn create_and_fill() -> EmbeddedFonts { - let mut fonts_by_name : HashMap<&'static str, &'static [u8]> - = HashMap::new(); + let mut font_data_by_name = HashMap::<&'static str,&'static [u8]>::new(); include!(concat!(env!("OUT_DIR"), "/fill_map.rs")); - EmbeddedFonts { - font_data_by_name: fonts_by_name - } + EmbeddedFonts{font_data_by_name} } } #[cfg(test)] mod test { - use crate::EmbeddedFonts; + use crate::*; #[test] fn loading_embedded_fonts() { - let fonts = EmbeddedFonts::create_and_fill(); + let fonts = EmbeddedFonts::create_and_fill(); let example_font = fonts.font_data_by_name.get("DejaVuSans").unwrap(); + assert_eq!(0x00, example_font[0]); assert_eq!(0x01, example_font[1]); assert_eq!(0x1d, example_font[example_font.len()-1]); diff --git a/lib/core/msdf-sys/build.rs b/lib/core/msdf-sys/build.rs index 23db79cbc8..526f92eb2a 100644 --- a/lib/core/msdf-sys/build.rs +++ b/lib/core/msdf-sys/build.rs @@ -1,21 +1,20 @@ -use basegl_build_utilities::github_download; mod msdfgen_wasm { - use crate::github_download; - use std::{path, fs}; + use basegl_build_utilities::GithubRelease; + + use std::{path,fs}; use std::io::Write; - pub const VERSION : &str = "v1.0.1"; - pub const FILENAME : &str = "msdfgen_wasm.js"; - pub const PROJECT_URL : &str = "https://github.com/luna/msdfgen-wasm"; + pub const PACKAGE : GithubRelease = GithubRelease { + project_url : "https://github.com/luna/msdfgen-wasm", + version : "v1.1", + filename : "msdfgen_wasm.js" + }; + + pub const FILENAME : &str = PACKAGE.filename; pub fn download() { - github_download( - PROJECT_URL, - VERSION, - FILENAME, - path::Path::new(".") // Note [Downloading to src dir] - ) + PACKAGE.download(path::Path::new(".")) // Note [Downloading to src dir] } /* Note [Downloading to src dir] @@ -31,7 +30,7 @@ mod msdfgen_wasm { */ const PATCH_LINE : &str = "; export { ccall, getValue, _msdfgen_getKerning,\ - _msdfgen_generateAutoscaledMSDF, _msdfgen_result_getMSDFData,\ + _msdfgen_generateAutoframedMSDF, _msdfgen_result_getMSDFData,\ _msdfgen_result_getAdvance, _msdfgen_result_getTranslation,\ _msdfgen_result_getScale, _msdfgen_freeResult, _msdfgen_freeFont,\ addInitializationCb, isInitialized }"; @@ -42,7 +41,11 @@ mod msdfgen_wasm { /// be explicitly exported. Examples works without this line perfectly. pub fn patch_for_wasm_bindgen_test() { let path = path::Path::new(FILENAME); - let mut file = fs::OpenOptions::new().append(true).open(path).unwrap(); + + let mut open_options = fs::OpenOptions::new(); + open_options.append(true); + + let mut file = open_options.open(path).unwrap(); file.write(PATCH_LINE.as_bytes()).unwrap(); } } diff --git a/lib/core/msdf-sys/src/emscripten_data.rs b/lib/core/msdf-sys/src/emscripten_data.rs index 6c6694da82..982a70e6e0 100644 --- a/lib/core/msdf-sys/src/emscripten_data.rs +++ b/lib/core/msdf-sys/src/emscripten_data.rs @@ -13,10 +13,7 @@ pub trait EmscriptenRepresentation : Sized { fn from_js_value(js_value : JsValue) -> Option; fn read_from_emscripten_memory(address : usize) -> Option { - let js_value = emscripten_get_value_from_memory( - address, - Self::EMSCRIPTEN_TYPE_NAME - ); + let js_value = emscripten_get_value_from_memory(address,Self::EMSCRIPTEN_TYPE_NAME); Self::from_js_value(js_value) } } @@ -58,8 +55,7 @@ pub struct ArrayMemoryViewIterator<'a, F : EmscriptenRepresentation> { impl ArrayMemoryView { pub fn new(address : usize, size : usize) -> ArrayMemoryView { - let size_in_bytes = - size * F::EMSCRIPTEN_SIZE_IN_BYTES; + let size_in_bytes = size * F::EMSCRIPTEN_SIZE_IN_BYTES; ArrayMemoryView { begin_address : address, end_address : address + size_in_bytes, @@ -67,6 +63,14 @@ ArrayMemoryView { } } + pub fn empty() -> ArrayMemoryView { + ArrayMemoryView { + begin_address : 0, + end_address : 0, + type_marker : std::marker::PhantomData + } + } + pub fn iter(&self) -> ArrayMemoryViewIterator { ArrayMemoryViewIterator { next_read_address : self.begin_address, @@ -83,10 +87,10 @@ Iterator for ArrayMemoryViewIterator<'a, F> { fn next(&mut self) -> Option { let has_element = self.next_read_address < self.end_address; has_element.and_option_from(|| { - let ret_val = - F::read_from_emscripten_memory(self.next_read_address).unwrap(); + let current_value = F::read_from_emscripten_memory(self.next_read_address).unwrap(); + self.next_read_address += F::EMSCRIPTEN_SIZE_IN_BYTES; - Some(ret_val) + Some(current_value) }) } } diff --git a/lib/core/msdf-sys/src/internal.rs b/lib/core/msdf-sys/src/internal.rs index 4f67ddf2dc..42897cc3a7 100644 --- a/lib/core/msdf-sys/src/internal.rs +++ b/lib/core/msdf-sys/src/internal.rs @@ -4,62 +4,55 @@ use wasm_bindgen::JsValue; #[wasm_bindgen(module = "/msdfgen_wasm.js")] extern { #[wasm_bindgen(js_name="addInitializationCb")] - pub fn on_emscripten_runtime_initialized(callback : JsValue) - -> js_sys::Promise; + pub fn on_emscripten_runtime_initialized(callback:JsValue) -> js_sys::Promise; #[wasm_bindgen(js_name="isInitialized")] pub fn is_emscripten_runtime_initialized() -> bool; #[wasm_bindgen(js_name="ccall")] - pub fn emscripten_call_function( - name : &str, - return_type : &str, - types : js_sys::Array, - values : js_sys::Array + pub fn emscripten_call_function + ( name : &str + , return_type : &str + , types : js_sys::Array + , values : js_sys::Array ) -> JsValue; #[wasm_bindgen(js_name="getValue")] - pub fn emscripten_get_value_from_memory( - address: usize, - a_type: &str - ) -> JsValue; + pub fn emscripten_get_value_from_memory(address:usize, a_type:&str) -> JsValue; #[wasm_bindgen(js_name="_msdfgen_getKerning")] - pub fn msdfgen_get_kerning( - font_handle : JsValue, - left_unicode : u32, - right_unicode : u32 - ) -> f64; - - #[wasm_bindgen(js_name="_msdfgen_generateAutoscaledMSDF")] - pub fn msdfgen_generate_msdf( - width : usize, - height : usize, - font_handle : JsValue, - unicode : u32, - edge_coloring_angle_threshold : f64, - range : f64, - edge_threshold : f64, - overlap_support : bool + pub fn msdfgen_get_kerning(font_handle:JsValue, left_unicode:u32, right_unicode:u32) -> f64; + + #[wasm_bindgen(js_name="_msdfgen_generateAutoframedMSDF")] + pub fn msdfgen_generate_msdf + ( width : usize + , height : usize + , font_handle : JsValue + , unicode : u32 + , edge_coloring_angle_threshold : f64 + , range : f64 + , max_scale : f64 + , edge_threshold : f64 + , overlap_support : bool ) -> JsValue; #[wasm_bindgen(js_name="_msdfgen_result_getMSDFData")] - pub fn msdfgen_result_get_msdf_data(result_handle : JsValue) -> usize; + pub fn msdfgen_result_get_msdf_data(result_handle:JsValue) -> usize; #[wasm_bindgen(js_name="_msdfgen_result_getAdvance")] - pub fn msdfgen_result_get_advance(result_handle : JsValue) -> f64; + pub fn msdfgen_result_get_advance(result_handle:JsValue) -> f64; #[wasm_bindgen(js_name="_msdfgen_result_getTranslation")] - pub fn msdfgen_result_get_translation(result_handle : JsValue) -> usize; + pub fn msdfgen_result_get_translation(result_handle:JsValue) -> usize; #[wasm_bindgen(js_name="_msdfgen_result_getScale")] - pub fn msdfgen_result_get_scale(result_handle : JsValue) -> usize; + pub fn msdfgen_result_get_scale(result_handle:JsValue) -> usize; #[wasm_bindgen(js_name="_msdfgen_freeResult")] - pub fn msdfgen_free_result(result_handle : JsValue); + pub fn msdfgen_free_result(result_handle:JsValue); #[wasm_bindgen(js_name="_msdfgen_freeFont")] - pub fn msdfgen_free_font(font_handle: JsValue); + pub fn msdfgen_free_font(font_handle:JsValue); } pub mod ccall_types { diff --git a/lib/core/msdf-sys/src/lib.rs b/lib/core/msdf-sys/src/lib.rs index b9c3462176..8b7b83f673 100644 --- a/lib/core/msdf-sys/src/lib.rs +++ b/lib/core/msdf-sys/src/lib.rs @@ -3,24 +3,12 @@ pub mod emscripten_data; pub mod test_utils; pub use basegl_prelude as prelude; -use internal::{ - on_emscripten_runtime_initialized, - is_emscripten_runtime_initialized, - emscripten_call_function, - msdfgen_generate_msdf, - msdfgen_free_font, - msdfgen_result_get_msdf_data, - msdfgen_result_get_translation, - msdfgen_result_get_advance, - msdfgen_result_get_scale, - msdfgen_free_result, - ccall_types -}; +use internal::*; + use emscripten_data::ArrayMemoryView; use js_sys::Uint8Array; use wasm_bindgen::JsValue; use wasm_bindgen::prelude::Closure; -use crate::internal::msdfgen_get_kerning; // ====================== // === Initialization === @@ -30,7 +18,7 @@ use crate::internal::msdfgen_get_kerning; /// /// The callback passed as argument will be called once the msdfgen libirary /// will be initialized. -pub fn run_once_initialized(callback : F) +pub fn run_once_initialized(callback:F) where F : 'static + FnOnce() { if is_emscripten_runtime_initialized() { callback() @@ -45,7 +33,7 @@ where F : 'static + FnOnce() { // ============ pub struct Font { - pub handle: JsValue + handle: JsValue } impl Font { @@ -53,25 +41,32 @@ impl Font { /// /// Loads font from a any format which freetype library can handle. /// See [https://www.freetype.org/freetype2/docs/index.html] for reference. - pub fn load_from_memory(data: &[u8]) -> Self { - let param_types = js_sys::Array::of2( - &JsValue::from_str(ccall_types::ARRAY), - &JsValue::from_str(ccall_types::NUMBER) - ); - let params = js_sys::Array::of2( - &JsValue::from(Uint8Array::from(data)), - &JsValue::from_f64(data.len() as f64) - ); - let handle = emscripten_call_function( - "msdfgen_loadFontMemory", - ccall_types::NUMBER, - param_types, - params); + pub fn load_from_memory(data:&[u8]) -> Self { + let array_type_js = JsValue::from_str(ccall_types::ARRAY); + let number_type_js = JsValue::from_str(ccall_types::NUMBER); + let data_js_array = Uint8Array::from(data); + let data_js = JsValue::from(data_js_array); + let data_size_js = JsValue::from_f64(data.len() as f64); + + let function_name = "msdfgen_loadFontMemory"; + let return_type = ccall_types::NUMBER; + let param_types = js_sys::Array::of2(&array_type_js,&number_type_js); + let params = js_sys::Array::of2(&data_js,&data_size_js); + + let handle = emscripten_call_function(function_name,return_type,param_types,params); Font { handle } } - pub fn retrieve_kerning(&self, left : char, right : char) -> f64 { - msdfgen_get_kerning(self.handle.clone(), left as u32, right as u32) + pub fn retrieve_kerning(&self, left:char, right:char) -> f64 { + let left_unicode = left as u32; + let right_unicode = right as u32; + msdfgen_get_kerning(self.handle.clone(),left_unicode,right_unicode) + } + + pub fn mock_font() -> Font { + Font { + handle : JsValue::from_f64(0.0) + } } } @@ -94,12 +89,13 @@ pub struct MsdfParameters { pub height : usize, pub edge_coloring_angle_threshold : f64, pub range : f64, + pub max_scale : f64, pub edge_threshold : f64, pub overlap_support : bool } pub struct MultichannelSignedDistanceField { - handle : JsValue, + handle : JsValue, pub advance : f64, pub translation : nalgebra::Vector2, pub scale : nalgebra::Vector2, @@ -109,58 +105,56 @@ pub struct MultichannelSignedDistanceField { impl MultichannelSignedDistanceField { pub const CHANNELS_COUNT : usize = 3; - ///// Generate Mutlichannel Signed Distance Field (MSDF) for one glyph - ///// - ///// For more information about MSDF see [https://github.com/Chlumsky/msdfgen]. - pub fn generate( - font : &Font, - unicode : u32, - params : &MsdfParameters, - ) -> MultichannelSignedDistanceField { - let handle = msdfgen_generate_msdf( - params.width, - params.height, - font.handle.clone(), - unicode, - params.edge_coloring_angle_threshold, - params.range, - params.edge_threshold, - params.overlap_support - ); - let advance = msdfgen_result_get_advance(handle.clone()); + /// Generate Mutlichannel Signed Distance Field (MSDF) for one glyph + /// + /// For more information about MSDF see + /// [https://github.com/Chlumsky/msdfgen]. + pub fn generate(font:&Font, unicode:u32, params:&MsdfParameters) + -> MultichannelSignedDistanceField { + let handle = msdfgen_generate_msdf + (params.width,params.height,font.handle.clone(),unicode, + params.edge_coloring_angle_threshold,params.range,params.max_scale,params.edge_threshold, + params.overlap_support); + + let advance = msdfgen_result_get_advance(handle.clone()); let translation = Self::translation(&handle); - let scale = Self::scale(&handle); + let scale = Self::scale(&handle); let data_adress = msdfgen_result_get_msdf_data(handle.clone()); - let data_size = params.width * params.height * Self::CHANNELS_COUNT; - let data = ArrayMemoryView::::new(data_adress, data_size); + let data_size = params.width * params.height * Self::CHANNELS_COUNT; + let data = ArrayMemoryView::::new(data_adress,data_size); - MultichannelSignedDistanceField { - handle, advance, translation, scale, data - } + MultichannelSignedDistanceField{handle,advance,translation,scale,data} } - const TRANSLATION_DIMS : usize = 2; - const SCALE_DIMS : usize = 2; + const DIMENSIONS: usize = 2; fn translation(handle : &JsValue) -> nalgebra::Vector2 { - let address = msdfgen_result_get_translation(handle.clone()); - let view = ArrayMemoryView::::new( - address, - Self::TRANSLATION_DIMS - ); - let mut iter = view.iter(); - nalgebra::Vector2::new(iter.next().unwrap(), iter.next().unwrap()) + let address = msdfgen_result_get_translation(handle.clone()); + let view = ArrayMemoryView::::new(address,Self::DIMENSIONS); + let mut iter = view.iter(); + let translate_x = iter.next().unwrap(); + let translate_y = iter.next().unwrap(); + nalgebra::Vector2::new(translate_x,translate_y) } fn scale(handle : &JsValue) -> nalgebra::Vector2 { - let address = msdfgen_result_get_scale(handle.clone()); - let view = ArrayMemoryView::::new( - address, - Self::SCALE_DIMS - ); + let address = msdfgen_result_get_scale(handle.clone()); + let view = ArrayMemoryView::::new(address,Self::DIMENSIONS); let mut iter = view.iter(); - nalgebra::Vector2::new(iter.next().unwrap(), iter.next().unwrap()) + let scale_x = iter.next().unwrap(); + let scale_y = iter.next().unwrap(); + nalgebra::Vector2::new(scale_x, scale_y) + } + + pub fn mock_results() -> MultichannelSignedDistanceField { + MultichannelSignedDistanceField { + handle : JsValue::from_f64(0.0), + advance : 0.0, + translation : nalgebra::Vector2::new(0.0, 0.0), + scale : nalgebra::Vector2::new(1.0, 1.0), + data : ArrayMemoryView::empty() + } } } @@ -198,6 +192,7 @@ mod tests { height : 32, edge_coloring_angle_threshold : 3.0, range : 2.0, + max_scale : 2.0, edge_threshold : 1.001, overlap_support : true }; @@ -209,13 +204,12 @@ mod tests { ); // then let data : Vec = msdf.data.iter().collect(); - // Note [asserts] - assert_eq!(-0.9408906, data[0]); - assert_eq!(0.2, data[10]); - assert_eq!(-4.3035655, data[data.len()-1]); + assert_eq!(-0.9408906 , data[0]); // Note [asserts] + assert_eq!(0.2 , data[10]); + assert_eq!(-4.3035655 , data[data.len()-1]); assert_eq!(Vector2::new(3.03125, 1.0), msdf.translation); - assert_eq!(Vector2::new(1.25, 1.25), msdf.scale); - assert_eq!(19.265625, msdf.advance); + assert_eq!(Vector2::new(1.25, 1.25) , msdf.scale); + assert_eq!(19.265625 , msdf.advance); }) } diff --git a/lib/core/msdf-sys/src/test_utils.rs b/lib/core/msdf-sys/src/test_utils.rs index 8419d669ee..72acb768b4 100644 --- a/lib/core/msdf-sys/src/test_utils.rs +++ b/lib/core/msdf-sys/src/test_utils.rs @@ -4,13 +4,13 @@ use std::future::Future; use crate::{ is_emscripten_runtime_initialized, run_once_initialized }; /// The future for running test after initialization -pub struct TestAfterInit { +pub struct TestAfterInit { test : F } impl TestAfterInit { - pub fn schedule(test : F) -> TestAfterInit { - TestAfterInit { test } + pub fn schedule(test:F) -> TestAfterInit { + TestAfterInit{test} } } @@ -18,9 +18,7 @@ impl Future for TestAfterInit { type Output = (); - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) - -> Poll { - + fn poll(self:Pin<&mut Self>, cx:&mut Context<'_>) -> Poll { if is_emscripten_runtime_initialized() { (self.test)(); Poll::Ready(()) diff --git a/lib/core/src/data/container.rs b/lib/core/src/data/container.rs index 8835d52cd5..3dd6d63f67 100644 --- a/lib/core/src/data/container.rs +++ b/lib/core/src/data/container.rs @@ -45,15 +45,18 @@ pub trait IntoCachingIterator { type Item : Clone; type Iter : Iterator; - fn cache_last_value(self) -> CachingIterator; + fn cache_last_value(self) -> CachingIterator; } impl> IntoCachingIterator for It { type Item = T; type Iter = Self; - fn cache_last_value(self) -> CachingIterator { - CachingIterator { last : None, iter : self } + fn cache_last_value(self) -> CachingIterator { + CachingIterator { + last : None, + iter : self + } } } @@ -72,9 +75,9 @@ mod tests { fn caching_iterator() { let data = vec![2, 3, 5]; let mut caching_iterator = data.iter().cloned().cache_last_value(); - assert_eq!(Some((None , 2)), caching_iterator.next()); - assert_eq!(Some((Some(2), 3)), caching_iterator.next()); - assert_eq!(Some((Some(3), 5)), caching_iterator.next()); - assert_eq!(None, caching_iterator.next()); + assert_eq!(Some((None ,2)), caching_iterator.next()); + assert_eq!(Some((Some(2),3)), caching_iterator.next()); + assert_eq!(Some((Some(3),5)), caching_iterator.next()); + assert_eq!(None , caching_iterator.next()); } -} \ No newline at end of file +} diff --git a/lib/core/src/data/opt_vec.rs b/lib/core/src/data/opt_vec.rs index 72745063a8..dfbd445238 100644 --- a/lib/core/src/data/opt_vec.rs +++ b/lib/core/src/data/opt_vec.rs @@ -1,5 +1,4 @@ use crate::prelude::*; -use smallvec::SmallVec; use std::iter::FilterMap; use std::slice; diff --git a/lib/core/src/lib.rs b/lib/core/src/lib.rs index 60011ca905..827665a4db 100644 --- a/lib/core/src/lib.rs +++ b/lib/core/src/lib.rs @@ -94,14 +94,28 @@ mod example_01 { // ================== mod example_03 { + use wasm_bindgen::prelude::*; + use crate::utils; - use crate::display::world::{World, WorkspaceID, Workspace, Add}; + use crate::display::world::{World,Workspace,Add}; use crate::text::font::FontRenderInfo; use crate::Color; + use crate::dirty::traits::SharedSetter1; use basegl_core_embedded_fonts::EmbeddedFonts; use itertools::iproduct; - use wasm_bindgen::prelude::*; + + const FONT_NAMES : &[&str] = & + [ "DejaVuSans" + , "DejaVuSansMono" + , "DejaVuSansMono-Bold" + , "DejaVuSansMono-Oblique" + , "DejaVuSansCondensed" + , "DejaVuSerif" + , "DejaVuSerifCondensed" + ]; + + const SIZES : &[f64] = &[0.016, 0.024, 0.032, 0.048, 0.064]; #[wasm_bindgen] #[allow(dead_code)] @@ -109,29 +123,19 @@ mod example_03 { utils::set_panic_hook(); basegl_core_msdf_sys::run_once_initialized(|| { let mut world_ref = World::new(); - let workspace_id : WorkspaceID = world_ref.add(Workspace::build("canvas")); - - let world = &mut world_ref.borrow_mut(); - let workspace = &mut world[workspace_id]; - - let font_base = EmbeddedFonts::create_and_fill(); - let font_names = [ - "DejaVuSans", - "DejaVuSansMono", - "DejaVuSansMono-Bold", - "DejaVuSansMono-Oblique", - "DejaVuSansCondensed", - "DejaVuSerif", - "DejaVuSerifCondensed", - ]; - let mut fonts : Box<[FontRenderInfo]> = font_names.iter().map( - |name| FontRenderInfo::from_embedded(&font_base, name) - ).collect(); - let sizes = [0.016, 0.024, 0.032, 0.048, 0.064]; - - for (i, (font, size)) in - iproduct!(0..fonts.len(), sizes.iter()).enumerate() { + let workspace_id = world_ref.add(Workspace::build("canvas")); + let world = &mut world_ref.borrow_mut(); + let workspace = &mut world[workspace_id]; + let font_base = EmbeddedFonts::create_and_fill(); + let font_creator = |name:&&'static str| FontRenderInfo::from_embedded(&font_base,name); + let fonts_iter = FONT_NAMES.iter().map(font_creator); + let mut fonts = fonts_iter.collect::>(); + + let all_cases = iproduct!(0..fonts.len(), SIZES.iter()); + for (i, (font, size)) in all_cases.enumerate() { + + let line_position = nalgebra::Vector2::new(-0.95, 0.9 - 0.064*(i as f64)); let text_compnent = crate::text::TextComponentBuilder { text : "To be, or not to be, that is the question: \ Whether 'tis nobler in the mind to suffer \ @@ -139,17 +143,17 @@ mod example_03 { Or to take arms against a sea of troubles \ And by opposing end them." .to_string(), - font : &mut fonts[font], - x : -0.95, - y : 0.9 - 0.064*(i as f32), - size : *size, - color : Color {r: 1.0, g: 1.0, b: 1.0, a: 1.0}, + font : &mut fonts[font], + position : line_position, + size : *size, + color : Color {r: 1.0, g: 1.0, b: 1.0, a: 1.0}, }.build(workspace); workspace.text_components.push(text_compnent); } world.workspace_dirty.set(workspace_id); }); } + } //////////////////////////////////////////////// diff --git a/lib/core/src/text.rs b/lib/core/src/text.rs new file mode 100644 index 0000000000..edfea9cb89 --- /dev/null +++ b/lib/core/src/text.rs @@ -0,0 +1,229 @@ +pub mod font; +pub mod glyph_render; +pub mod msdf; + +use crate::prelude::*; + +use crate::Color; +use crate::display::world::Workspace; +use crate::text::glyph_render::{GylphSquareVerticesBuilder, GlyphSquareTextureCoordinatesBuilder}; +use crate::text::msdf::MsdfTexture; + +use font::FontRenderInfo; +use basegl_backend_webgl::{Context,compile_shader,link_program,Program,Shader}; +use js_sys::Float32Array; +use nalgebra::{Vector2,Similarity2,Transform2}; +use web_sys::{WebGlRenderingContext,WebGlBuffer,WebGlTexture}; + +pub struct TextComponentBuilder<'a> { + pub text : String, + pub font : &'a mut FontRenderInfo, + pub position : Vector2, + pub size : f64, + pub color : Color, +} + +#[derive(Debug)] +pub struct TextComponent { + gl_context : WebGlRenderingContext, + gl_program : Program, + gl_vertex_buf : WebGlBuffer, + gl_tex_coord_buf : WebGlBuffer, + gl_msdf_texture : WebGlTexture, + buffers_size : usize, +} + +impl<'a> TextComponentBuilder<'a> { + pub fn build(mut self, workspace : &Workspace) -> TextComponent { + self.load_all_chars(); + let gl_context = workspace.context.clone(); + let gl_program = self.create_program(&gl_context); + let gl_vertex_buf = self.create_vertex_buf(&gl_context); + let gl_tex_coord_buf = self.create_tex_coord_buf(&gl_context); + let gl_msdf_texture = self.create_msdf_texture(&gl_context); + let glyph_vertices_count = glyph_render::GLYPH_SQUARE_VERTICES_BASE_LAYOUT.len(); + let buffers_size = self.text.len() * glyph_vertices_count; + + self.setup_uniforms(&gl_context, &gl_program); + + TextComponent + {gl_context,gl_program,gl_vertex_buf,gl_tex_coord_buf,gl_msdf_texture,buffers_size} + } + + fn load_all_chars(&mut self) { + for ch in self.text.chars() { + self.font.get_glyph_info(ch); + } + } + + fn create_program(&self, gl_context:&Context) -> Program { + gl_context.get_extension("OES_standard_derivatives").unwrap().unwrap(); + + let vert_shader = self.create_vertex_shader(gl_context); + let frag_shader = self.create_fragment_shader(gl_context); + + link_program(&gl_context, &vert_shader, &frag_shader).unwrap() + } + + fn create_vertex_shader(&self, gl_context:&Context) -> Shader { + let body = include_str!("text/msdf_vert.glsl"); + let shader_type = WebGlRenderingContext::VERTEX_SHADER; + + compile_shader(gl_context,shader_type,body).unwrap() + } + + fn create_fragment_shader(&self, gl_context:&Context) -> Shader { + let body = include_str!("text/msdf_frag.glsl"); + let shader_type = WebGlRenderingContext::FRAGMENT_SHADER; + + compile_shader(gl_context,shader_type,body).unwrap() + } + + fn create_buffer(gl_context:&Context, vertices:&[f32]) -> WebGlBuffer { + let buffer = gl_context.create_buffer().unwrap(); + let target = WebGlRenderingContext::ARRAY_BUFFER; + let usage = WebGlRenderingContext::STATIC_DRAW; + gl_context.bind_buffer(target,Some(&buffer)); + + unsafe { // Note [unsafe buffer_data] + let float_32_array = Float32Array::view(&vertices); + gl_context.buffer_data_with_array_buffer_view(target,&float_32_array,usage); + } + + buffer + } + + /* Note [unsafe buffer_data] + * + * The Float32Array::view is safe as long there are no allocations done + * until it is destroyed. This way of creating buffers were taken from + * wasm-bindgen examples + * (https://rustwasm.github.io/wasm-bindgen/examples/webgl.html) + */ + + fn create_vertex_buf(&mut self, gl_context:&Context) -> WebGlBuffer { + let to_window = self.to_window_transform(); + let font = &mut self.font; + let mut vertices_builder = GylphSquareVerticesBuilder::new(font,to_window); + let char_to_vertices = |ch| vertices_builder.build_for_next_glyph(ch); + + let grouped_vertices = self.text.chars().map(char_to_vertices); + let vertices = grouped_vertices.flatten(); + let buffer_data = vertices.map(|f| f as f32).collect::>(); + + Self::create_buffer(gl_context,buffer_data.as_ref()) + } + + fn to_window_transform(&self) -> Transform2 { + const ROTATION : f64 = 0.0; + let similarity = Similarity2::new(self.position,ROTATION,self.size); + nalgebra::convert(similarity) + } + + fn create_tex_coord_buf(&mut self, gl_context:&Context) -> WebGlBuffer { + let font = &mut self.font; + let mut texture_coordinates_builder = GlyphSquareTextureCoordinatesBuilder::new(font); + let char_to_texture_coordinates = |ch| texture_coordinates_builder.build_for_next_glyph(ch); + + let grouped_texture_coordinates = self.text.chars().map(char_to_texture_coordinates); + let texture_coordinates = grouped_texture_coordinates.flatten(); + let converted_data = texture_coordinates.map(|f| f as f32); + let buffer_data = converted_data.collect::>(); + + Self::create_buffer(gl_context,buffer_data.as_ref()) + } + + fn create_msdf_texture(&self, gl_ctx:&Context) + -> WebGlTexture { + let msdf_texture = gl_ctx.create_texture().unwrap(); + let target = Context::TEXTURE_2D; + let wrap = Context::CLAMP_TO_EDGE as i32; + let min_filter = Context::LINEAR as i32; + let width = MsdfTexture::WIDTH as i32; + let height = self.font.msdf_texture.rows() as i32; + let border = 0; + let tex_level = 0; + let format = Context::RGB; + let internal_fmt = Context::RGB as i32; + let tex_type = Context::UNSIGNED_BYTE; + let data = Some(self.font.msdf_texture.data.as_slice()); + + gl_ctx.bind_texture(target,Some(&msdf_texture)); + + gl_ctx.tex_parameteri(target,Context::TEXTURE_WRAP_S,wrap); + gl_ctx.tex_parameteri(target,Context::TEXTURE_WRAP_T,wrap); + gl_ctx.tex_parameteri(target,Context::TEXTURE_MIN_FILTER,min_filter); + + let tex_image_result = + gl_ctx.tex_image_2d_with_i32_and_i32_and_i32_and_format_and_type_and_opt_u8_array + (target,tex_level,internal_fmt,width,height,border,format,tex_type,data); + + tex_image_result.unwrap(); + + msdf_texture + } + + fn setup_uniforms(&self, gl_context:&Context, gl_program:&Program) { + let color_loc = gl_context.get_uniform_location(gl_program,"color"); + let range_loc = gl_context.get_uniform_location(gl_program,"range"); + let msdf_loc = gl_context.get_uniform_location(gl_program,"msdf"); + let msdf_size_loc = gl_context.get_uniform_location(gl_program,"msdfSize"); + + let color = &self.color; + let range = FontRenderInfo::MSDF_PARAMS.range as f32; + let msdf_width = MsdfTexture::WIDTH as f32; + let msdf_height = self.font.msdf_texture.rows() as f32; + + gl_context.use_program(Some(gl_program)); + gl_context.uniform4f(color_loc.as_ref(),color.r,color.g,color.b,color.a); + gl_context.uniform1f(range_loc.as_ref(),range); + gl_context.uniform1i(msdf_loc.as_ref(),0); + gl_context.uniform2f(msdf_size_loc.as_ref(),msdf_width,msdf_height); + } +} + +impl TextComponent { + + pub fn display(&self) { + let gl_context = &self.gl_context; + + gl_context.use_program(Some(&self.gl_program)); + + self.bind_buffer_to_attribute("position",&self.gl_vertex_buf); + self.bind_buffer_to_attribute("texCoord",&self.gl_tex_coord_buf); + self.setup_blending(); + + gl_context.bind_texture(Context::TEXTURE_2D, Some(&self.gl_msdf_texture)); + + gl_context.draw_arrays(WebGlRenderingContext::TRIANGLES,0,self.buffers_size as i32); + } + + fn bind_buffer_to_attribute(&self, attribute_name:&str, buffer:&WebGlBuffer) { + let gl_context = &self.gl_context; + let gl_program = &self.gl_program; + let location = gl_context.get_attrib_location(gl_program,attribute_name) as u32; + let target = WebGlRenderingContext::ARRAY_BUFFER; + let item_size = 2; + let item_type = WebGlRenderingContext::FLOAT; + let normalized = false; + let stride = 0; + let offset = 0; + + gl_context.enable_vertex_attrib_array(location); + gl_context.bind_buffer(target,Some(buffer)); + + gl_context.vertex_attrib_pointer_with_i32 + (location,item_size,item_type,normalized,stride,offset); + } + + fn setup_blending(&self) { + let gl_context = &self.gl_context; + let rgb_source = Context::SRC_ALPHA; + let alpha_source = Context::ZERO; + let rgb_destination = Context::ONE_MINUS_SRC_ALPHA; + let alhpa_destination = Context::ONE; + + gl_context.enable(Context::BLEND); + gl_context.blend_func_separate(rgb_source,rgb_destination,alpha_source,alhpa_destination); + } +} diff --git a/lib/core/src/text/font.rs b/lib/core/src/text/font.rs index a63edae66f..0c196e06ec 100644 --- a/lib/core/src/text/font.rs +++ b/lib/core/src/text/font.rs @@ -1,155 +1,174 @@ use crate::prelude::*; +use crate::text::msdf:: +{MsdfTexture,convert_msdf_transformation,x_distance_from_msdf_value}; + use basegl_core_msdf_sys as msdf_sys; use basegl_core_embedded_fonts::EmbeddedFonts; +use msdf_sys::{MsdfParameters,MultichannelSignedDistanceField}; -// ==================== -// === MSDF Texture === -// ==================== +// ======================== +// === Font render info === +// ======================== -/// Texture with msdf for all loaded glyphs of font +/// Data used for rendering a single glyph /// -/// This structure keeps texture data in 8-bit-per-channel RGB format, which -/// is ready to be passed to webgl texImage2D. The texture contains MSDFs for -/// all loaded glyphs, organized in vertical column. +/// Each distance and transformation values are expressed in normalized coordinates, where +/// (0.0, 0.0) is initial pen position for an character, and `y` = 1.0 is _ascender_. /// -/// It implements Extend trait making possible to pass this structure -/// as an output argument for `basegl_core_msdf_sys::generate_msdf` function -pub struct MsdfTexture { - pub data : Vec -} - -impl MsdfTexture { - pub const WIDTH : usize = 32; - - /// Number of rows in texture - pub fn rows(&self) -> usize { - self.data.len()/(msdf_sys::MultichannelSignedDistanceField::CHANNELS_COUNT*Self::WIDTH) - } - - fn convert_cell_from_f32(value : f32) -> u8 { - nalgebra::clamp(value*255.0, 0.0, 255.0) as u8 - } -} - -impl Extend for MsdfTexture { - /// Extends texture with new MSDF data in f32 format - fn extend>(&mut self, iter: T) { - self.data.extend( - iter.into_iter().map(Self::convert_cell_from_f32) - ); - } -} - -// ================= -// === Char info === -// ================= - -/// A single character data used for rendering -pub struct CharRenderInfo { - pub msdf_texture_rows : std::ops::Range, - pub points_transformation : nalgebra::Projective2, - pub advance : f32 +/// `from_base_layout` transforms the _base square_ for a character, such the glyph will be rendered +/// correctly with assigned MSDF texture. The _base square_ corners are (0.0, 0.0), (1.0, 1.0). +/// See also `glyph_render::GLYPH_SQUARE_VERTICES_BASE_LAYOUT`. +/// +/// For explanation of various font-rendering terms, see +/// [freetype documentation](https://www.freetype.org/freetype2/docs/glyphs/glyphs-3.html#section-1) +pub struct GlyphRenderInfo { + pub msdf_texture_rows : std::ops::Range, + pub from_base_layout : nalgebra::Projective2, + pub advance : f64 } /// A single font data used for rendering /// -/// The data for individual characters are load on demand +/// The data for individual characters and kerning are load on demand. +/// +/// Each distance and transformation values are expressed in normalized coordinates, where `y` = 0.0 +/// is _baseline_ and `y` = 1.0 is _ascender_. For explanation of various font-rendering terms, see +/// [freetype documentation](https://www.freetype.org/freetype2/docs/glyphs/glyphs-3.html#section-1) pub struct FontRenderInfo { pub name : String, pub msdf_sys_font : msdf_sys::Font, pub msdf_texture : MsdfTexture, - chars : HashMap, - kerning : HashMap<(char, char), f32> + glyphs : HashMap, + kerning : HashMap<(char,char),f64> } impl FontRenderInfo { - pub const MSDF_PARAMS : msdf_sys::MsdfParameters = - msdf_sys::MsdfParameters { + pub const MAX_MSDF_SHRINK_FACTOR : f64 = 4.; // Note [Picked MSDF parameters] + pub const MAX_MSDF_GLYPH_SCALE : f64 = 2.; // Note [Picked MSDF parameters] + + pub const MSDF_PARAMS : MsdfParameters = MsdfParameters { width : MsdfTexture::WIDTH, - height : MsdfTexture::WIDTH, - edge_coloring_angle_threshold : 3.0, - range : 8.0, - edge_threshold : 1.001, - overlap_support : true + height : MsdfTexture::ONE_GLYPH_HEIGHT, + edge_coloring_angle_threshold : 3.0, // Note [Picked MSDF parameters] + range : Self::MAX_MSDF_SHRINK_FACTOR * Self::MAX_MSDF_GLYPH_SCALE, + max_scale : Self::MAX_MSDF_GLYPH_SCALE, + edge_threshold : 1.001, // Note [Picked MSDF parameters] + overlap_support : true // Note [Picked MSDF parameters] }; - /// Create render info for font data in memory - pub fn new( - name : String, - font_data : &[u8], - ) -> FontRenderInfo { + /* Note [Picked MSDF parameters] + * + * The range was picked such way, that we avoid fitting range in one rendered pixel. + * Otherwise the antialiasing won't work. I assumed some maximum `shrink factor` (how many + * times rendered square will be smaller than MSDF size), and pick an arbitrary maximum glyph + * scale up. + * + * The rest of parameters are the defaults taken from msdfgen library + */ + + /// Create render info based on font data in memory + pub fn new(name:String, font_data:&[u8]) -> FontRenderInfo { FontRenderInfo { name, - msdf_sys_font: msdf_sys::Font::load_from_memory(font_data), - msdf_texture : MsdfTexture { data : Vec::new() }, - chars : HashMap::new(), - kerning : HashMap::new() + msdf_sys_font : msdf_sys::Font::load_from_memory(font_data), + msdf_texture : MsdfTexture { data : Vec::new() }, + glyphs : HashMap::new(), + kerning : HashMap::new() } } /// Create render info for one of embedded fonts - pub fn from_embedded( - base : &EmbeddedFonts, - name : &'static str - ) -> FontRenderInfo { + pub fn from_embedded(base:&EmbeddedFonts, name:&'static str) + -> FontRenderInfo { let font_data = base.font_data_by_name.get(name).unwrap(); - crate::text::font::FontRenderInfo::new( - name.to_string(), font_data - ) + FontRenderInfo::new(name.to_string(),font_data) } /// Load char render info - pub fn load_char(&mut self, ch : char) { - let msdf = msdf_sys::MultichannelSignedDistanceField::generate( - &self.msdf_sys_font, - ch as u32, - &FontRenderInfo::MSDF_PARAMS, - ); + pub fn load_char(&mut self, ch:char) { + let handle = &self.msdf_sys_font; + let unicode = ch as u32; + let params = Self::MSDF_PARAMS; + let msdf_height = MsdfTexture::ONE_GLYPH_HEIGHT; + + let msdf = MultichannelSignedDistanceField::generate(handle,unicode,¶ms); + let msdf_tex_rows_begin = self.msdf_texture.rows(); + let msdf_tex_rows_end = msdf_tex_rows_begin + msdf_height; + let msdf_transformation = convert_msdf_transformation(&msdf); + + let advance = x_distance_from_msdf_value(msdf.advance); + + let glyph_info = GlyphRenderInfo { + msdf_texture_rows : msdf_tex_rows_begin..msdf_tex_rows_end, + from_base_layout : msdf_transformation.inverse(), + advance + }; - let msdf_texture_rows_begin = self.msdf_texture.rows(); self.msdf_texture.extend(msdf.data.iter()); - let msdf_texture_rows_end = self.msdf_texture.rows(); - - let msdf_tranformation_matrix = nalgebra::Matrix3::new( - msdf.scale[0] as f32, 0.0, msdf.translation[0] as f32/MsdfTexture::WIDTH as f32*msdf.scale[0] as f32, - 0.0, msdf.scale[1] as f32, msdf.translation[1] as f32/MsdfTexture::WIDTH as f32*msdf.scale[0] as f32, - 0.0, 0.0, 1.0 - ); - let msdf_transformation : nalgebra::Projective2 = nalgebra::Projective2::from_matrix_unchecked(msdf_tranformation_matrix); - - let char_info = CharRenderInfo { - msdf_texture_rows : msdf_texture_rows_begin..msdf_texture_rows_end, - points_transformation: msdf_transformation.inverse(), - advance: msdf.advance as f32 / MsdfTexture::WIDTH as f32 - }; - self.chars.insert(ch, char_info); + self.glyphs.insert(ch, glyph_info); } - /// Get or create render info for one character - pub fn get_or_create_char_info(&mut self, ch : char) -> &CharRenderInfo { - if !self.chars.contains_key(&ch) { + /// Get render info for one character, generating one if not found + pub fn get_glyph_info(&mut self, ch:char) -> &GlyphRenderInfo { + if !self.glyphs.contains_key(&ch) { self.load_char(ch); } - self.chars.get(&ch).unwrap() + self.glyphs.get(&ch).unwrap() } - pub fn get_or_retrieve_kerning(&mut self, left : char, right : char) - -> f32 { + /// Get kerning between two characters + pub fn get_kerning(&mut self, left : char, right : char) -> f64 { if !self.kerning.contains_key(&(left, right)) { - let kerning = - self.msdf_sys_font.retrieve_kerning(left, right) as f32 / MsdfTexture::WIDTH as f32; - self.kerning.insert((left, right), kerning); - kerning + let msdf_val = self.msdf_sys_font.retrieve_kerning(left, right); + let normalized = x_distance_from_msdf_value(msdf_val); + self.kerning.insert((left, right), normalized); + normalized } else { *self.kerning.get(&(left, right)).unwrap() } } + + #[cfg(test)] + pub fn mock_font(name : String) -> FontRenderInfo { + FontRenderInfo { + name, + msdf_sys_font : msdf_sys::Font::mock_font(), + msdf_texture : MsdfTexture { data : Vec::new() }, + glyphs : HashMap::new(), + kerning : HashMap::new() + } + } + + #[cfg(test)] + pub fn mock_char_info(&mut self, ch : char) -> &mut GlyphRenderInfo { + let msdf_height = MsdfTexture::ONE_GLYPH_HEIGHT; + let msdf_texture_rows_begin = self.msdf_texture.rows(); + let msdf_texture_rows_end = msdf_texture_rows_begin + msdf_height; + let data_size = MsdfTexture::ONE_GLYPH_SIZE; + let msdf_data = (0..data_size).map(|_| 0.12345); + + let char_info = GlyphRenderInfo { + msdf_texture_rows : (msdf_texture_rows_begin..msdf_texture_rows_end), + from_base_layout : nalgebra::Transform::identity(), + advance : 0.0 + }; + + self.msdf_texture.extend(msdf_data); + self.glyphs.insert(ch, char_info); + self.glyphs.get_mut(&ch).unwrap() + } + + #[cfg(test)] + pub fn mock_kerning_info(&mut self, l : char, r : char, value : f64) { + self.kerning.insert((l, r),value); + } } #[cfg(test)] mod tests { - use crate::text::font::{MsdfTexture, FontRenderInfo}; + use super::*; + use crate::text::msdf::MsdfTexture; use basegl_core_msdf_sys as msdf_sys; use basegl_core_embedded_fonts::EmbeddedFonts; use wasm_bindgen_test::{wasm_bindgen_test, wasm_bindgen_test_configure}; @@ -166,18 +185,6 @@ mod tests { ) } - #[test] - fn extending_msdf_texture() { - let mut texture = MsdfTexture { - data : Vec::new() - }; - let msdf_values: &[f32] = &[-0.5, 0.0, 0.25, 0.5, 0.75, 1.0, 1.25]; - texture.extend(msdf_values[..4].iter().cloned()); - texture.extend(msdf_values[4..].iter().cloned()); - - assert_eq!([0, 0, 63, 127, 191, 255, 255], texture.data.as_slice()); - } - wasm_bindgen_test_configure!(run_in_browser); #[wasm_bindgen_test(async)] @@ -187,7 +194,7 @@ mod tests { assert_eq!(TEST_FONT_NAME, font_render_info.name); assert_eq!(0, font_render_info.msdf_texture.data.len()); - assert_eq!(0, font_render_info.chars.len()); + assert_eq!(0, font_render_info.glyphs.len()); }) } @@ -199,21 +206,24 @@ mod tests { font_render_info.load_char('A'); font_render_info.load_char('B'); - let expected_texture_size = MsdfTexture::WIDTH * MsdfTexture::WIDTH - * msdf_sys::MultichannelSignedDistanceField::CHANNELS_COUNT * 2; + let chars = 2; + let tex_width = MsdfTexture::WIDTH; + let tex_height = MsdfTexture::ONE_GLYPH_HEIGHT * chars; + let channels = MultichannelSignedDistanceField::CHANNELS_COUNT; + let tex_size = tex_width * tex_height * channels; - assert_eq!(MsdfTexture::WIDTH * 2, - font_render_info.msdf_texture.rows()); - assert_eq!(expected_texture_size, - font_render_info.msdf_texture.data.len()); - assert_eq!(2, font_render_info.chars.len()); + assert_eq!(tex_height , font_render_info.msdf_texture.rows()); + assert_eq!(tex_size , font_render_info.msdf_texture.data.len()); + assert_eq!(chars , font_render_info.glyphs.len()); - let first_char = font_render_info.chars.get(&'A').unwrap(); - let second_char = font_render_info.chars.get(&'B').unwrap(); + let first_char = font_render_info.glyphs.get(&'A').unwrap(); + let second_char = font_render_info.glyphs.get(&'B').unwrap(); - assert_eq!(0..MsdfTexture::WIDTH, first_char.msdf_texture_rows); - assert_eq!(MsdfTexture::WIDTH..2 * MsdfTexture::WIDTH, - second_char.msdf_texture_rows); + let first_range = 0..MsdfTexture::ONE_GLYPH_HEIGHT; + let second_range = MsdfTexture::ONE_GLYPH_HEIGHT..tex_height; + + assert_eq!(first_range , first_char.msdf_texture_rows); + assert_eq!(second_range , second_char.msdf_texture_rows); }) } @@ -223,16 +233,16 @@ mod tests { let mut font_render_info = create_test_font_render_info(); { - let char_info = font_render_info.get_or_create_char_info('A'); + let char_info = font_render_info.get_glyph_info('A'); assert_eq!(0..MsdfTexture::WIDTH, char_info.msdf_texture_rows); } - assert_eq!(1, font_render_info.chars.len()); + assert_eq!(1, font_render_info.glyphs.len()); { - let char_info = font_render_info.get_or_create_char_info('A'); + let char_info = font_render_info.get_glyph_info('A'); assert_eq!(0..MsdfTexture::WIDTH, char_info.msdf_texture_rows); } - assert_eq!(1, font_render_info.chars.len()); + assert_eq!(1, font_render_info.glyphs.len()); }) } -} \ No newline at end of file +} diff --git a/lib/core/src/text/glyph_render.rs b/lib/core/src/text/glyph_render.rs new file mode 100644 index 0000000000..3a05a91d05 --- /dev/null +++ b/lib/core/src/text/glyph_render.rs @@ -0,0 +1,290 @@ +use crate::prelude::*; + +use crate::text::font::FontRenderInfo; +use crate::text::msdf::MsdfTexture; + +use nalgebra::{Point2,Transform2,Translation2,Affine2,Matrix3,Scalar}; + +// ============================ +// === Base vertices layout === +// ============================ + +pub const GLYPH_SQUARE_VERTICES_BASE_LAYOUT: &'static[(f64, f64)] = & + [ (0.0, 0.0) + , (0.0, 1.0) + , (1.0, 0.0) + , (1.0, 0.0) + , (0.0, 1.0) + , (1.0, 1.0) + ]; + +fn point_to_iterable(p:Point2) -> SmallVec<[T;2]> { + p.iter().cloned().collect() +} + +// ================================== +// === GylphSquareVerticesBuilder === +// ================================== + +const GLYPH_SQUARE_VERTICES_SIZE : usize = GLYPH_SQUARE_VERTICES_BASE_LAYOUT.len() * 2; + +pub type GlyphSquareVertices = SmallVec<[f64;GLYPH_SQUARE_VERTICES_SIZE]>; + +/// Builder for glyph vertices +/// +/// Once created, each `build_for_next_glyph` gives vertices of the next glyph's square +pub struct GylphSquareVerticesBuilder<'a> { + pub previous_char : Option, + pub font : &'a mut FontRenderInfo, + pub pen_position : Point2, + pub to_window : Transform2, +} + +impl<'a> GylphSquareVerticesBuilder<'a> { + + /// New GylphSquareVerticesBuilder + /// + /// The newly created builder start to place glyphs with pen located at `to_window` * (0.0, 0.0) + pub fn new(font:&'a mut FontRenderInfo, to_window:Transform2) + -> GylphSquareVerticesBuilder<'a> { + GylphSquareVerticesBuilder { + previous_char : None, + font, + pen_position : Point2::new(0.0, 0.0), + to_window + } + } + + /// Compute vertices for one glyph and move pen for next position + pub fn build_for_next_glyph(&mut self, ch:char) -> GlyphSquareVertices { + let apply_kerning = self.translation_by_kerning_value(ch); + let to_pen_position = self.translation_by_pen_position(); + + let glyph_info = self.font.get_glyph_info(ch); + let glyph_specific_transform = &glyph_info.from_base_layout; + let to_window = &self.to_window; + + let advance_pen = Translation2::new(glyph_info.advance, 0.0); + let pen_transformation = apply_kerning * advance_pen; + + let plain_base = GLYPH_SQUARE_VERTICES_BASE_LAYOUT.iter(); + let base = plain_base .map(|(x, y)| Point2::new(*x, *y)); + let glyph_fixed = base .map(|p| glyph_specific_transform * p); + let moved_to_pen_position = glyph_fixed .map(|p| to_pen_position * p); + let kerning_applied = moved_to_pen_position.map(|p| apply_kerning * p); + let mapped_to_window = kerning_applied .map(|p| to_window * p); + + self.pen_position = pen_transformation * self.pen_position; + self.previous_char = Some(ch); + mapped_to_window.map(point_to_iterable).flatten().collect() + } + + fn translation_by_kerning_value(&mut self, ch:char) -> Translation2 { + let prev_char = self.previous_char; + let opt_value = prev_char.map(|lc| self.font.get_kerning(lc, ch)); + let value = opt_value.unwrap_or(0.0); + Translation2::new(value, 0.0) + } + + fn translation_by_pen_position(&self) -> Translation2{ + Translation2::new(self.pen_position.x, self.pen_position.y) + } +} + +// ================================= +// === TextureCoordinatesBuilder === +// ================================= + +const GLYPH_SQUARE_TEXTURE_COORDINATES_SIZE : usize = GLYPH_SQUARE_VERTICES_BASE_LAYOUT.len() * 2; + +pub type GlyphTextureCoordinates = SmallVec<[f64;GLYPH_SQUARE_TEXTURE_COORDINATES_SIZE]>; + +/// Builder for glyph MSDF texture coordinates +pub struct GlyphSquareTextureCoordinatesBuilder<'a> { + pub font : &'a mut FontRenderInfo +} + +impl<'a> GlyphSquareTextureCoordinatesBuilder<'a> { + /// Create new builder using given font + pub fn new(font:&'a mut FontRenderInfo) -> GlyphSquareTextureCoordinatesBuilder<'a> { + GlyphSquareTextureCoordinatesBuilder {font} + } + + /// Compute texture coordinates for `ch` + pub fn build_for_next_glyph(&mut self, ch:char) -> GlyphTextureCoordinates { + let border_align = self.align_borders_to_msdf_cell_center_transform(); + let to_proper_fragment = self.glyph_texture_fragment_transform(ch); + + let plain_base = GLYPH_SQUARE_VERTICES_BASE_LAYOUT.iter(); + let base = plain_base .map(|(x,y)| Point2::new(*x, *y)); + let aligned_to_border = base .map(|p| border_align * p); + let transformed = aligned_to_border.map(|p| to_proper_fragment * p); + + transformed.map(point_to_iterable).flatten().collect() + } + + /// Transformation aligning borders to MSDF cell center + /// + /// Each cell in MSFD contains a distance measured from its center, therefore the borders of + /// glyph's square should be matched with center of MSDF cells to read distance properly + /// + /// The transformation's input should be a point in _single MSDF space_, where (0.0, 0.0) is + /// the bottom-left corner of MSDF, and (1.0, 1.0) is the top-right corner. + pub fn align_borders_to_msdf_cell_center_transform(&self) -> Affine2 { + let columns = MsdfTexture::WIDTH as f64; + let rows = MsdfTexture::ONE_GLYPH_HEIGHT as f64; + let column_size = 1.0 / columns; + let row_size = 1.0 / rows; + + let translation_x = column_size / 2.0; + let translation_y = row_size / 2.0; + + let scale_x = 1.0 - column_size; + let scale_y = 1.0 - row_size; + + let matrix = Matrix3::new + ( scale_x, 0.0 , translation_x + , 0.0 , scale_y, translation_y + , 0.0 , 0.0 , 1.0 + ); + + Affine2::from_matrix_unchecked(matrix) + } + + /// Transformation MSDF texture fragment associated with given glyph + /// + /// The MSDF texture contains MSDFs for many glyphs. The returned transform maps the point in + /// a _single MSDF space_ to actual texture space. In other words, a (0.0, 0.0) point will be + /// mapped to bottom-left corner of `ch` texture fragment, and a (1.0, 1.0) will be mapped to + /// upper-right corner. + pub fn glyph_texture_fragment_transform(&mut self, ch:char) -> Affine2 { + let one_glyph_rows = MsdfTexture::ONE_GLYPH_HEIGHT as f64; + let all_rows = self.font.msdf_texture.rows() as f64; + let fraction = one_glyph_rows / all_rows; + let glyph_info = self.font.get_glyph_info(ch); + let offset = glyph_info.msdf_texture_rows.start as f64 / all_rows; + let matrix = nalgebra::Matrix3::new + ( 1.0, 0.0 , 0.0 + , 0.0, fraction, offset + , 0.0, 0.0 , 1.0 + ); + Affine2::from_matrix_unchecked(matrix) + } +} + + +#[cfg(test)] +mod tests { + use super::*; + + use crate::text::font::GlyphRenderInfo; + + use basegl_core_msdf_sys::test_utils::TestAfterInit; + use std::future::Future; + use wasm_bindgen_test::wasm_bindgen_test; + + #[wasm_bindgen_test(async)] + fn build_vertices_for_glyph_square() -> impl Future { + TestAfterInit::schedule(|| { + let mut font = FontRenderInfo::mock_font("Test font".to_string()); + mock_a_glyph_info(&mut font); + mock_w_glyph_info(&mut font); + font.mock_kerning_info('A', 'W', -0.16); + let to_window_transformation = { + let to_window_mtx = nalgebra::Matrix3::new + ( 0.1, 0.0, -1.0 + , 0.0, 0.1, -0.5 + , 0.0, 0.0, 1.0 + ); + nalgebra::Transform2::from_matrix_unchecked(to_window_mtx) + }; + + let mut builder = GylphSquareVerticesBuilder::new(&mut font,to_window_transformation); + let a_vertices = builder.build_for_next_glyph('A'); + assert_eq!(Some('A'), builder.previous_char); + assert_eq!(0.56 , builder.pen_position.x); + assert_eq!(0.0 , builder.pen_position.y); + let w_vertices = builder.build_for_next_glyph('W'); + assert_eq!(Some('W'), builder.previous_char); + assert_eq!(1.1 , builder.pen_position.x); + assert_eq!(0.0 , builder.pen_position.y); + + let expected_a_vertices = & + [ -0.99 , -0.48 + , -0.99 , -0.4 + , -0.94 , -0.48 + , -0.94 , -0.48 + , -0.99 , -0.4 + , -0.94 , -0.4 + ]; + let expected_w_vertices = & + [ -0.95 , -0.48 + , -0.95 , -0.39 + , -0.89 , -0.48 + , -0.89 , -0.48 + , -0.95 , -0.39 + , -0.89 , -0.39 + ]; + + assert_eq!(expected_a_vertices, a_vertices.as_ref()); + assert_eq!(expected_w_vertices, w_vertices.as_ref()); + }) + } + + #[wasm_bindgen_test(async)] + fn build_texture_coordinates_for_glyph_square() -> impl Future { + TestAfterInit::schedule(|| { + let mut font = FontRenderInfo::mock_font("Test font".to_string()); + font.mock_char_info('A'); + font.mock_char_info('W'); + + let mut builder = GlyphSquareTextureCoordinatesBuilder::new(&mut font); + let a_texture_coordinates = builder.build_for_next_glyph('A'); + let w_texture_coordinates = builder.build_for_next_glyph('W'); + + let expected_a_coordinates = & + [ 1./64. , 1./128. + , 1./64. , 63./128. + , 63./64. , 1./128. + , 63./64. , 1./128. + , 1./64. , 63./128. + , 63./64. , 63./128. + ]; + let expected_w_coordinates = & + [ 1./64. , 65./128. + , 1./64. , 127./128. + , 63./64. , 65./128. + , 63./64. , 65./128. + , 1./64. , 127./128. + , 63./64. , 127./128. + ]; + + assert_eq!(expected_a_coordinates, a_texture_coordinates.as_ref()); + assert_eq!(expected_w_coordinates, w_texture_coordinates.as_ref()); + }) + } + + fn mock_a_glyph_info(font:&mut FontRenderInfo) -> &mut GlyphRenderInfo { + let a_info = font.mock_char_info('A'); + a_info.advance = 0.56; + let trans_mtx = nalgebra::Matrix3::new + ( 0.5, 0.0, 0.1 + , 0.0, 0.8, 0.2 + , 0.0, 0.0, 1.0 + ); + a_info.from_base_layout = nalgebra::Projective2::from_matrix_unchecked(trans_mtx); + a_info + } + + fn mock_w_glyph_info(font:&mut FontRenderInfo) -> &mut GlyphRenderInfo { + let a_info = font.mock_char_info('W'); + a_info.advance = 0.7; + let trans_mtx = nalgebra::Matrix3::new + ( 0.6, 0.0, 0.1 + , 0.0, 0.9, 0.2 + , 0.0, 0.0, 1.0 + ); + a_info.from_base_layout = nalgebra::Projective2::from_matrix_unchecked(trans_mtx); + a_info + } +} diff --git a/lib/core/src/text/mod.rs b/lib/core/src/text/mod.rs deleted file mode 100644 index 5502383bd9..0000000000 --- a/lib/core/src/text/mod.rs +++ /dev/null @@ -1,281 +0,0 @@ -pub mod font; - -use crate::prelude::*; - -use crate::Color; -use crate::text::font::MsdfTexture; -use crate::display::world::Workspace; -use crate::data::container::IntoCachingIterator; -use basegl_backend_webgl::{Context, compile_shader, link_program, Program, }; -use web_sys::{WebGlRenderingContext, WebGlBuffer, WebGlTexture}; -use font::FontRenderInfo; -use js_sys::Float32Array; -use nalgebra::{Vector2, Point2}; - -pub struct TextComponentBuilder<'a> { - pub text : String, - pub font : &'a mut FontRenderInfo, - pub x : f32, - pub y : f32, - pub size : f32, - pub color : Color, -} - -#[derive(Debug)] -pub struct TextComponent { - gl_context : WebGlRenderingContext, - gl_program : Program, - gl_vertex_buf : WebGlBuffer, - gl_tex_coord_buf : WebGlBuffer, - gl_msdf_texture : WebGlTexture, - buffers_size : usize, -} - -impl<'a> TextComponentBuilder<'a> { - pub fn build(mut self, workspace : &Workspace) -> TextComponent { - let gl_context = workspace.context.clone(); - let gl_program = self.create_program(&gl_context); - - for ch in self.text.chars() { - self.font.get_or_create_char_info(ch); - } - - let gl_vertex_buf = self.create_vertex_buf(&gl_context); - let gl_tex_coord_buf = self.create_tex_coord_buf(&gl_context); - let gl_msdf_texture = - self.create_msdf_texture(&gl_context, &gl_program); - - self.setup_uniforms(&gl_context, &gl_program); - - TextComponent { - gl_context, - gl_program, - gl_vertex_buf, - gl_tex_coord_buf, - gl_msdf_texture, - buffers_size: self.text.len() - } - } - - fn create_program(&self, gl_context : &Context) -> Program { - gl_context.get_extension("OES_standard_derivatives") - .unwrap().unwrap(); - - let vert_shader = compile_shader( - &gl_context, - WebGlRenderingContext::VERTEX_SHADER, - include_str!("msdf_vert.glsl") - ).unwrap(); - - let frag_shader = compile_shader( - &gl_context, - WebGlRenderingContext::FRAGMENT_SHADER, - include_str!("msdf_frag.glsl") - ).unwrap(); - - link_program(&gl_context, &vert_shader, &frag_shader).unwrap() - } - - fn create_buffer( - gl_context : &Context, - vertices : &[f32] - ) -> WebGlBuffer { - let buffer = gl_context.create_buffer().unwrap(); - gl_context.bind_buffer( - WebGlRenderingContext::ARRAY_BUFFER, - Some(&buffer) - ); - - unsafe { // Note [unsafe buffer_data] - let float_32_array = Float32Array::view(&vertices); - gl_context.buffer_data_with_array_buffer_view( - WebGlRenderingContext::ARRAY_BUFFER, - &float_32_array, - WebGlRenderingContext::STATIC_DRAW, - ); - } - - buffer - } - - /* Note [unsafe buffer_data] - * - * The Float32Array::view is safe as long there are no allocations done - * until it is destroyed. This way of creating buffers were taken from - * wasm-bindgen examples - * (https://rustwasm.github.io/wasm-bindgen/examples/webgl.html) - */ - - const BASE_GLYPH_VERTICES_LAYOUT : &'static[(f32, f32)] = &[ - (0.0, 0.0), - (0.0, 1.0), - (1.0, 0.0), - (1.0, 0.0), - (0.0, 1.0), - (1.0, 1.0), - ]; - - fn create_vertex_buf(&mut self, gl_context : &Context) -> WebGlBuffer { - let to_window = nalgebra::Similarity2::new( - Vector2::new(self.x, self.y), - 0.0, - self.size - ); - let mut position = nalgebra::Translation2::new(0.0, 0.0); - let font = &mut self.font; - let vertices = self.text.chars().cache_last_value().map(|(last_ch, ch)| { - let kerning = last_ch.map(|lc| font.get_or_retrieve_kerning(lc, ch) ).unwrap_or(0.0); - let ch_info = font.get_or_create_char_info(ch); - let kerning_trans = nalgebra::Translation2::new(kerning, 0.0); - let transformation = to_window*position*ch_info.points_transformation*kerning_trans; - position = nalgebra::Translation2::new(ch_info.advance+kerning, 0.0)*position; - Self::BASE_GLYPH_VERTICES_LAYOUT.iter() - .map(|(x, y)| Point2::new(*x, *y)) - .map(|p| transformation.transform_point(&p)) - .map(|p| p.iter().cloned().collect::>()) - .flatten().collect::>() - }).flatten().collect::>(); - - Self::create_buffer(gl_context, vertices.as_ref()) - } - - - fn create_tex_coord_buf(&mut self, gl_context : &Context) -> WebGlBuffer { - let font = &mut self.font; - let vertices = self.text.chars().map(|c| { - let msdf_rows = font.msdf_texture.rows() as f32; - let info = font.get_or_create_char_info(c); - let y_min = info.msdf_texture_rows.start as f32 / msdf_rows; - let y_max = info.msdf_texture_rows.end as f32 / msdf_rows; - vec![0.0, y_min, 0.0, y_max, 1.0, y_min, - 1.0, y_min, 0.0, y_max, 1.0, y_max] - }).flatten().collect::>(); - - Self::create_buffer(gl_context, vertices.as_ref()) - } - - fn create_msdf_texture(&self, gl_context : &Context, gl_program : &Program) - -> WebGlTexture { - - let msdf_texture = gl_context.create_texture().unwrap(); - gl_context.bind_texture(Context::TEXTURE_2D, Some(&msdf_texture)); - - gl_context.tex_parameteri( - Context::TEXTURE_2D, - Context::TEXTURE_WRAP_S, - Context::CLAMP_TO_EDGE as i32 - ); - gl_context.tex_parameteri( - Context::TEXTURE_2D, - Context::TEXTURE_WRAP_T, - Context::CLAMP_TO_EDGE as i32 - ); - gl_context.tex_parameteri( - Context::TEXTURE_2D, - Context::TEXTURE_MIN_FILTER, - Context::LINEAR as i32 - ); - - gl_context.tex_image_2d_with_i32_and_i32_and_i32_and_format_and_type_and_opt_u8_array( - Context::TEXTURE_2D, - 0, - Context::RGB as i32, - MsdfTexture::WIDTH as i32, - self.font.msdf_texture.rows() as i32, - 0, - Context::RGB, - Context::UNSIGNED_BYTE, - Some(self.font.msdf_texture.data.as_slice()) - ).unwrap(); - - let msdf_loc = gl_context.get_uniform_location(gl_program, "msdf"); - let msdf_size_loc = - gl_context.get_uniform_location(gl_program, "msdfSize"); - - gl_context.use_program(Some(gl_program)); - gl_context.uniform1i(msdf_loc.as_ref(), 0); - gl_context.uniform2f( - msdf_size_loc.as_ref(), - MsdfTexture::WIDTH as f32, - self.font.msdf_texture.rows() as f32 - ); - - msdf_texture - } - - fn setup_uniforms(&self, gl_context : &Context, gl_program : &Program) { - let color_loc = gl_context.get_uniform_location(gl_program, "color"); - let px_range_loc = - gl_context.get_uniform_location(gl_program, "pxRange"); - - gl_context.use_program(Some(gl_program)); - gl_context.uniform4f( - color_loc.as_ref(), - self.color.r, - self.color.g, - self.color.b, - self.color.a, - ); - gl_context.uniform1f( - px_range_loc.as_ref(), - FontRenderInfo::MSDF_PARAMS.range as f32 - ); - } -} - -impl TextComponent { - - pub fn display(&self) { - let gl = &self.gl_context; - let program = &self.gl_program; - - gl.use_program(Some(&self.gl_program)); - - let position_location = gl.get_attrib_location(program, "position"); - gl.enable_vertex_attrib_array(position_location as u32); - gl.bind_buffer( - WebGlRenderingContext::ARRAY_BUFFER, - Some(&self.gl_vertex_buf) - ); - gl.vertex_attrib_pointer_with_i32( - position_location as u32, - 2, - WebGlRenderingContext::FLOAT, - false, - 0, - 0 - ); - - gl.bind_texture(Context::TEXTURE_2D, Some(&self.gl_msdf_texture)); - - let tex_coord_location = gl.get_attrib_location(program, "texCoord"); - assert!(tex_coord_location >= 0); - gl.enable_vertex_attrib_array(tex_coord_location as u32); - gl.bind_buffer( - WebGlRenderingContext::ARRAY_BUFFER, - Some(&self.gl_tex_coord_buf) - ); - gl.vertex_attrib_pointer_with_i32( - tex_coord_location as u32, - 2, - WebGlRenderingContext::FLOAT, - false, - 0, - 0 - ); - - gl.enable(Context::BLEND); - gl.blend_func_separate( - Context::SRC_ALPHA, - Context::ONE_MINUS_SRC_ALPHA, - Context::ZERO, - Context::ONE - ); - - gl.draw_arrays( - WebGlRenderingContext::TRIANGLES, - 0, - (self.buffers_size*6) as i32, - ); - } -} diff --git a/lib/core/src/text/msdf.rs b/lib/core/src/text/msdf.rs new file mode 100644 index 0000000000..6d5d1c0792 --- /dev/null +++ b/lib/core/src/text/msdf.rs @@ -0,0 +1,148 @@ +use basegl_core_msdf_sys as msdf_sys; +use msdf_sys::MultichannelSignedDistanceField; +use nalgebra::clamp; + +// ==================== +// === MSDF Texture === +// ==================== + +/// Texture with msdf for all loaded glyphs of font +/// +/// This structure keeps texture data in 8-bit-per-channel RGB format, which +/// is ready to be passed to webgl texImage2D. The texture contains MSDFs for +/// all loaded glyphs, organized in vertical column. +pub struct MsdfTexture { + pub data : Vec +} + +impl MsdfTexture { + pub const CHANNELS_COUNT : usize = MultichannelSignedDistanceField::CHANNELS_COUNT; + + pub const WIDTH : usize = 32; + pub const ROW_SIZE : usize = Self::CHANNELS_COUNT * Self::WIDTH; + + pub const ONE_GLYPH_HEIGHT : usize = 32; + pub const ONE_GLYPH_SIZE : usize = Self::ROW_SIZE * Self::ONE_GLYPH_HEIGHT; + + /// Number of rows in texture + pub fn rows(&self) -> usize { + self.data.len() / Self::ROW_SIZE + } + + fn convert_cell_from_f32(value : f32) -> u8 { + const UNSIGNED_BYTE_MIN : f32 = 0.0; + const UNSIGNED_BYTE_MAX : f32 = 255.0; + + let scaled_to_byte = value * 255.0; + let clamped_to_byte = clamp(scaled_to_byte,UNSIGNED_BYTE_MIN,UNSIGNED_BYTE_MAX); + + clamped_to_byte as u8 + } +} + +impl Extend for MsdfTexture { + /// Extends texture with new MSDF data in f32 format + fn extend>(&mut self, iter:T) { + let f32_iterator = iter.into_iter(); + let converted_iterator = f32_iterator.map(Self::convert_cell_from_f32); + self.data.extend(converted_iterator); + } +} + +// ================================== +// === msdf-sys values converting === +// ================================== + +/// Converts x dimension distance obtained from msdf-sys to vertex-space values +/// +/// The values obtained from `msdf-sys` are expressed in MSDF cells. This +/// function convert them to normalized coordinates, where +/// (0.0, 0.0) is initial pen position for an character, and `y` = 1.0 is +/// _ascender_. +pub fn x_distance_from_msdf_value(msdf_value:f64) -> f64 { + msdf_value / MsdfTexture::WIDTH as f64 +} + +/// Converts y dimension distance obtained from msdf-sys to vertex-space values +/// +/// The values obtained from `msdf-sys` are expressed in MSDF cells. This +/// function convert them to normalized coordinates, where +/// (0.0, 0.0) is initial pen position for an character, and `y` = 1.0 is +/// _ascender_. +pub fn y_distance_from_msdf_value(msdf_value:f64) -> f64 { + msdf_value / MsdfTexture::ONE_GLYPH_HEIGHT as f64 +} + +/// Converts transformation obtained from msdf-sys to vertex-space values +/// +/// This function get the transformation obtained from `msdf_sys` which is +/// expressed in MSDF units, and convert it to normalized coordinates, where +/// (0.0, 0.0) is initial pen position for an character, and `y` = 1.0 is +/// _ascender_. +pub fn convert_msdf_transformation(msdf:&MultichannelSignedDistanceField) +-> nalgebra::Projective2 { + let translate_converted_x = x_distance_from_msdf_value(msdf.translation.x); + let translate_converted_y = y_distance_from_msdf_value(msdf.translation.y); + + let translate_scaled_x = translate_converted_x * msdf.scale.x; + let translate_scaled_y = translate_converted_y * msdf.scale.y; + + let msdf_transformation_matrix = nalgebra::Matrix3::new( + msdf.scale.x, 0.0, translate_scaled_x, + 0.0, msdf.scale.y, translate_scaled_y, + 0.0, 0.0, 1.0 + ); + + nalgebra::Projective2::from_matrix_unchecked(msdf_transformation_matrix) +} + +#[cfg(test)] +mod test { + use super::*; + + use basegl_core_msdf_sys::test_utils::TestAfterInit; + use nalgebra::Vector2; + use std::future::Future; + use wasm_bindgen_test::wasm_bindgen_test; + + #[test] + fn extending_msdf_texture() { + let mut texture = MsdfTexture{data : Vec::new()}; + let msdf_values: &[f32] = &[-0.5, 0.0, 0.25, 0.5, 0.75, 1.0, 1.25]; + texture.extend(msdf_values[..4].iter().cloned()); + texture.extend(msdf_values[4..].iter().cloned()); + + assert_eq!([0, 0, 63, 127, 191, 255, 255], texture.data.as_slice()); + } + + #[test] + fn x_dimension_converting() { + assert_eq!(1.0/8.0, x_distance_from_msdf_value(4.0)); + assert_eq!(1.0/2.0, x_distance_from_msdf_value(16.0)); + } + + #[test] + fn y_dimension_converting() { + assert_eq!(1.0/8.0, y_distance_from_msdf_value(4.0)); + assert_eq!(1.0/2.0, y_distance_from_msdf_value(16.0)); + } + + #[wasm_bindgen_test(async)] + fn msdf_transformation_converting() -> impl Future { + TestAfterInit::schedule(|| { + let mut msdf = MultichannelSignedDistanceField::mock_results(); + msdf.scale = Vector2::new(2.0, 3.0); + msdf.translation = Vector2::new(16.0, 4.0); + + let converted = convert_msdf_transformation(&msdf); + + let expected_mtx = nalgebra::Matrix3::new( + 2.0, 0.0, 1.0, + 0.0, 3.0, 3.0/8.0, + 0.0, 0.0, 1.0 + ); + + assert_eq!(expected_mtx, *converted.matrix()); + }) + } +} diff --git a/lib/core/src/text/msdf_frag.glsl b/lib/core/src/text/msdf_frag.glsl index 3cdf858603..90f2d53ef9 100644 --- a/lib/core/src/text/msdf_frag.glsl +++ b/lib/core/src/text/msdf_frag.glsl @@ -1,26 +1,37 @@ #extension GL_OES_standard_derivatives : enable varying highp vec2 vTexCoord; -varying highp vec2 msdfCoord; -uniform sampler2D msdf; -uniform highp vec2 msdfSize; -uniform highp float pxRange; -uniform highp vec4 color; +uniform sampler2D msdf; +// Number of MSDF cells in row and column +uniform highp vec2 msdfSize; +// Range parameter of msdf generation - the distance between 0.0 and 1.0 values +// expressed in MSDF cells +uniform highp float range; +uniform highp vec4 color; -highp float median(highp float r, highp float g, highp float b) { - return max(min(r, g), min(max(r, g), b)); +highp float median(highp vec3 v) { + return max(min(v.x, v.y), min(max(v.x, v.y), v.z)); } void main() { - highp vec2 msdfUnitTex = pxRange/msdfSize; - highp vec2 msdfUnitPx = msdfUnitTex/fwidth(vTexCoord); - highp vec3 smple = texture2D(msdf, vTexCoord).rgb; - highp float sigDist = median(smple.r, smple.g, smple.b) - 0.5; + highp vec2 msdfUnitTex = range/msdfSize; + highp vec2 msdfUnitPx = msdfUnitTex/fwidth(vTexCoord); + highp float avgMsdfUnitPx = (msdfUnitPx.x + msdfUnitPx.y) / 2.0; + // Note [dpiDilate] + highp float dpiDilate = avgMsdfUnitPx < range*0.49 ? 1.0 : 0.0; - highp float dpiDilate = (msdfUnitPx.x + msdfUnitPx.y) < pxRange*0.9 ? 1.0 : 0.0; + highp vec3 msdfSample = texture2D(msdf, vTexCoord).rgb; + highp float sigDist = median(msdfSample) - 0.5; - highp float sigDistPx = sigDist*((msdfUnitPx.x + msdfUnitPx.y)/2.0); - highp float opacity = clamp(sigDistPx + 0.5 + dpiDilate*0.1, 0.0, 1.0); - gl_FragColor = vec4(color.xyz, color.w*opacity); + highp float sigDistPx = sigDist * avgMsdfUnitPx; + highp float opacity = 0.5 + sigDistPx + dpiDilate*0.1; + gl_FragColor = vec4(color.xyz, color.w * clamp(opacity, 0.0, 1.0)); } + +/* Note [dpiDilate] + * + * This is 1.0 on low dpi and 0.0 otherwise. We use this parameter to fatten + * somewhat font on low resolutions. The thershold and exact value of this + * fattening was picked by trial an error, searching for best rendering effect. + */ diff --git a/lib/core/src/text/msdf_vert.glsl b/lib/core/src/text/msdf_vert.glsl index 913a2f7452..17a178d096 100644 --- a/lib/core/src/text/msdf_vert.glsl +++ b/lib/core/src/text/msdf_vert.glsl @@ -6,4 +6,4 @@ varying vec2 vTexCoord; void main() { vTexCoord = texCoord; gl_Position = vec4(position, 0.0, 1.0); -} \ No newline at end of file +} diff --git a/lib/prelude/Cargo.toml b/lib/prelude/Cargo.toml index 90713eacca..24d8f304e3 100644 --- a/lib/prelude/Cargo.toml +++ b/lib/prelude/Cargo.toml @@ -14,4 +14,5 @@ itertools = "0.8" derivative = "1.0.3" num = "0.2.0" boolinator = "2.4.0" -paste = "0.1" \ No newline at end of file +paste = "0.1" +smallvec = "1.0.0" diff --git a/lib/prelude/src/lib.rs b/lib/prelude/src/lib.rs index 06cd2caa27..33dd243e5e 100644 --- a/lib/prelude/src/lib.rs +++ b/lib/prelude/src/lib.rs @@ -15,6 +15,7 @@ pub use itertools::Itertools; pub use num::Num; pub use paste; pub use shrinkwraprs::Shrinkwrap; +pub use smallvec::SmallVec; pub use std::cell::Ref; pub use std::cell::RefMut; pub use std::cell::RefCell; diff --git a/lib/system/web/js/resize_observer.js b/lib/system/web/js/resize_observer.js index 568820393c..b739200952 100644 --- a/lib/system/web/js/resize_observer.js +++ b/lib/system/web/js/resize_observer.js @@ -57,6 +57,7 @@ let resizeObserverPool = new Pool((...args) => new ResizeObserver(...args)) export function resize_observe(target, f) { let id = resizeObserverPool.reserve(resize_observer_update(f)) resizeObserverPool[id].observe(target) + return id } export function resize_unobserve(id) { From cc7ab1d6a4f4109aa30dd3631208bad6db1fafaf Mon Sep 17 00:00:00 2001 From: Adam Obuchowicz Date: Tue, 3 Dec 2019 23:07:52 +0100 Subject: [PATCH 15/19] Lint suggestions --- lib/core/src/text/font.rs | 15 ++++++++------- lib/core/src/text/glyph_render.rs | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/core/src/text/font.rs b/lib/core/src/text/font.rs index 0c196e06ec..ed37ee2f41 100644 --- a/lib/core/src/text/font.rs +++ b/lib/core/src/text/font.rs @@ -5,6 +5,7 @@ use crate::text::msdf:: use basegl_core_msdf_sys as msdf_sys; use basegl_core_embedded_fonts::EmbeddedFonts; use msdf_sys::{MsdfParameters,MultichannelSignedDistanceField}; +use std::collections::hash_map::Entry::{Occupied,Vacant}; // ======================== // === Font render info === @@ -118,13 +119,13 @@ impl FontRenderInfo { /// Get kerning between two characters pub fn get_kerning(&mut self, left : char, right : char) -> f64 { - if !self.kerning.contains_key(&(left, right)) { - let msdf_val = self.msdf_sys_font.retrieve_kerning(left, right); - let normalized = x_distance_from_msdf_value(msdf_val); - self.kerning.insert((left, right), normalized); - normalized - } else { - *self.kerning.get(&(left, right)).unwrap() + match self.kerning.entry((left,right)) { + Occupied(entry) => *entry.get(), + Vacant(entry) => { + let msdf_val = self.msdf_sys_font.retrieve_kerning(left, right); + let normalized = x_distance_from_msdf_value(msdf_val); + *entry.insert(normalized) + } } } diff --git a/lib/core/src/text/glyph_render.rs b/lib/core/src/text/glyph_render.rs index 3a05a91d05..752bd48ee7 100644 --- a/lib/core/src/text/glyph_render.rs +++ b/lib/core/src/text/glyph_render.rs @@ -9,7 +9,7 @@ use nalgebra::{Point2,Transform2,Translation2,Affine2,Matrix3,Scalar}; // === Base vertices layout === // ============================ -pub const GLYPH_SQUARE_VERTICES_BASE_LAYOUT: &'static[(f64, f64)] = & +pub const GLYPH_SQUARE_VERTICES_BASE_LAYOUT: &[(f64, f64)] = & [ (0.0, 0.0) , (0.0, 1.0) , (1.0, 0.0) From 4d4ae4be309d7651173c75dca5db37a9d3947c94 Mon Sep 17 00:00:00 2001 From: Adam Obuchowicz Date: Wed, 4 Dec 2019 12:26:47 +0100 Subject: [PATCH 16/19] Review fixes --- build-utilities/src/lib.rs | 22 +++--- lib/core/embedded-fonts/build.rs | 4 +- lib/core/msdf-sys/build.rs | 2 +- lib/core/msdf-sys/src/emscripten_data.rs | 20 ++++- lib/core/msdf-sys/src/lib.rs | 21 +++--- lib/core/msdf-sys/src/test_utils.rs | 4 +- lib/core/src/text.rs | 95 +++++++++++++----------- lib/core/src/text/font.rs | 8 +- lib/core/src/text/glyph_render.rs | 12 +-- lib/core/src/text/msdf.rs | 8 +- 10 files changed, 102 insertions(+), 94 deletions(-) diff --git a/build-utilities/src/lib.rs b/build-utilities/src/lib.rs index 9ec9ef9c24..c898fc4876 100644 --- a/build-utilities/src/lib.rs +++ b/build-utilities/src/lib.rs @@ -4,29 +4,27 @@ use std::{fs, path}; use std::io::ErrorKind; -/// A structure describing a concrete release package on github -pub struct GithubRelease<'a,'b,'c> { - pub project_url : &'a str, - pub version : &'b str, - pub filename : &'c str, +/// A structure describing a concrete release package on github. +pub struct GithubRelease> { + pub project_url : Str, + pub version : Str, + pub filename : Str, } -impl GithubRelease<'_, '_, '_> { +impl> GithubRelease { /// Download the release package from github /// /// The project_url should be a project's main page on github. pub fn download(&self, destination_dir:&path::Path) { let url = format!( "{project}/releases/download/{version}/{filename}", - project = self.project_url, - version = self.version, - filename = self.filename); - + project = self.project_url.as_ref(), + version = self.version.as_ref(), + filename = self.filename.as_ref()); let destination_dir_str = destination_dir.to_str().unwrap(); - let destination_file = destination_dir.join(self.filename); + let destination_file = destination_dir.join(self.filename.as_ref()); Self::remove_old_file(&destination_file); - download_lp::download(url.as_str(),destination_dir_str).unwrap(); } diff --git a/lib/core/embedded-fonts/build.rs b/lib/core/embedded-fonts/build.rs index fd5ccbd1e1..329949f320 100644 --- a/lib/core/embedded-fonts/build.rs +++ b/lib/core/embedded-fonts/build.rs @@ -40,7 +40,7 @@ mod deja_vu { use std::path; use basegl_build_utilities::GithubRelease; - pub const PACKAGE : GithubRelease = GithubRelease { + pub const PACKAGE : GithubRelease<&str> = GithubRelease { project_url : "https://github.com/dejavu-fonts/dejavu-fonts/", version : "version_2_37", filename : "dejavu-fonts-ttf-2.37.zip" @@ -58,7 +58,7 @@ mod deja_vu { let package_dir = package_path.parent().unwrap(); let output_path = package_dir.join(font_file); - let archive_file = std::fs::File::open(package_path).unwrap(); + let archive_file = std::fs::File::open(package_path).unwrap(); let mut archive = zip::ZipArchive::new(archive_file).unwrap(); let mut input_stream = archive.by_name(font_in_package_path.as_str()).unwrap(); let mut output_stream = std::fs::File::create(output_path).unwrap(); diff --git a/lib/core/msdf-sys/build.rs b/lib/core/msdf-sys/build.rs index 526f92eb2a..674a0be888 100644 --- a/lib/core/msdf-sys/build.rs +++ b/lib/core/msdf-sys/build.rs @@ -5,7 +5,7 @@ mod msdfgen_wasm { use std::{path,fs}; use std::io::Write; - pub const PACKAGE : GithubRelease = GithubRelease { + pub const PACKAGE : GithubRelease<&str> = GithubRelease { project_url : "https://github.com/luna/msdfgen-wasm", version : "v1.1", filename : "msdfgen_wasm.js" diff --git a/lib/core/msdf-sys/src/emscripten_data.rs b/lib/core/msdf-sys/src/emscripten_data.rs index 982a70e6e0..99f14c460e 100644 --- a/lib/core/msdf-sys/src/emscripten_data.rs +++ b/lib/core/msdf-sys/src/emscripten_data.rs @@ -6,12 +6,19 @@ use crate::prelude::*; // === EmscriptenRepresentation === // ================================ +/// Trait of type having its representation in emscripten API +/// +/// The _emscirpten API_ is a set of functions that are put to library by emscripten SDK, the +/// especially useful is a function reading value from given address in `msdfgen` library memory +/// (we cannot do it directly, because each wasm module have separate address space) pub trait EmscriptenRepresentation : Sized { const EMSCRIPTEN_SIZE_IN_BYTES : usize; const EMSCRIPTEN_TYPE_NAME : &'static str; + /// Convert from JsValue returned from emscripten API fn from_js_value(js_value : JsValue) -> Option; + /// Read value from address in `msdfgen` library memory fn read_from_emscripten_memory(address : usize) -> Option { let js_value = emscripten_get_value_from_memory(address,Self::EMSCRIPTEN_TYPE_NAME); Self::from_js_value(js_value) @@ -40,20 +47,26 @@ impl EmscriptenRepresentation for f64 { // === ArrayMemoryView === // ======================= +/// View of array in `msdfgen` library memory pub struct ArrayMemoryView { begin_address : usize, end_address : usize, type_marker : std::marker::PhantomData } +/// Iterator over values in `msdfgen` library memory +/// +/// It cannot outlives view from which was created, because one might expect, that data may be freed +/// by library once view is destroyed pub struct ArrayMemoryViewIterator<'a, F : EmscriptenRepresentation> { next_read_address : usize, end_address : usize, view_lifetime : std::marker::PhantomData<&'a ArrayMemoryView> } -impl -ArrayMemoryView { +impl ArrayMemoryView { + + /// Create view from first element's address and array size pub fn new(address : usize, size : usize) -> ArrayMemoryView { let size_in_bytes = size * F::EMSCRIPTEN_SIZE_IN_BYTES; ArrayMemoryView { @@ -63,6 +76,7 @@ ArrayMemoryView { } } + /// Create an empty view pub fn empty() -> ArrayMemoryView { ArrayMemoryView { begin_address : 0, @@ -71,6 +85,7 @@ ArrayMemoryView { } } + /// Iterator over elements pub fn iter(&self) -> ArrayMemoryViewIterator { ArrayMemoryViewIterator { next_read_address : self.begin_address, @@ -88,7 +103,6 @@ Iterator for ArrayMemoryViewIterator<'a, F> { let has_element = self.next_read_address < self.end_address; has_element.and_option_from(|| { let current_value = F::read_from_emscripten_memory(self.next_read_address).unwrap(); - self.next_read_address += F::EMSCRIPTEN_SIZE_IN_BYTES; Some(current_value) }) diff --git a/lib/core/msdf-sys/src/lib.rs b/lib/core/msdf-sys/src/lib.rs index 8b7b83f673..1556fb48b2 100644 --- a/lib/core/msdf-sys/src/lib.rs +++ b/lib/core/msdf-sys/src/lib.rs @@ -112,18 +112,21 @@ impl MultichannelSignedDistanceField { pub fn generate(font:&Font, unicode:u32, params:&MsdfParameters) -> MultichannelSignedDistanceField { let handle = msdfgen_generate_msdf - (params.width,params.height,font.handle.clone(),unicode, - params.edge_coloring_angle_threshold,params.range,params.max_scale,params.edge_threshold, - params.overlap_support); - + ( params.width + , params.height + , font.handle.clone() + , unicode + , params.edge_coloring_angle_threshold + , params.range,params.max_scale + , params.edge_threshold + , params.overlap_support + ); let advance = msdfgen_result_get_advance(handle.clone()); let translation = Self::translation(&handle); let scale = Self::scale(&handle); - let data_adress = msdfgen_result_get_msdf_data(handle.clone()); let data_size = params.width * params.height * Self::CHANNELS_COUNT; - let data = ArrayMemoryView::::new(data_adress,data_size); - + let data = ArrayMemoryView::new(data_adress,data_size); MultichannelSignedDistanceField{handle,advance,translation,scale,data} } @@ -131,7 +134,7 @@ impl MultichannelSignedDistanceField { fn translation(handle : &JsValue) -> nalgebra::Vector2 { let address = msdfgen_result_get_translation(handle.clone()); - let view = ArrayMemoryView::::new(address,Self::DIMENSIONS); + let view = ArrayMemoryView::new(address,Self::DIMENSIONS); let mut iter = view.iter(); let translate_x = iter.next().unwrap(); let translate_y = iter.next().unwrap(); @@ -140,7 +143,7 @@ impl MultichannelSignedDistanceField { fn scale(handle : &JsValue) -> nalgebra::Vector2 { let address = msdfgen_result_get_scale(handle.clone()); - let view = ArrayMemoryView::::new(address,Self::DIMENSIONS); + let view = ArrayMemoryView::new(address,Self::DIMENSIONS); let mut iter = view.iter(); let scale_x = iter.next().unwrap(); let scale_y = iter.next().unwrap(); diff --git a/lib/core/msdf-sys/src/test_utils.rs b/lib/core/msdf-sys/src/test_utils.rs index 72acb768b4..4da7e3c4db 100644 --- a/lib/core/msdf-sys/src/test_utils.rs +++ b/lib/core/msdf-sys/src/test_utils.rs @@ -8,13 +8,13 @@ pub struct TestAfterInit { test : F } -impl TestAfterInit { +impl TestAfterInit { pub fn schedule(test:F) -> TestAfterInit { TestAfterInit{test} } } -impl Future for TestAfterInit { +impl Future for TestAfterInit { type Output = (); diff --git a/lib/core/src/text.rs b/lib/core/src/text.rs index edfea9cb89..11b0d04fbf 100644 --- a/lib/core/src/text.rs +++ b/lib/core/src/text.rs @@ -25,12 +25,12 @@ pub struct TextComponentBuilder<'a> { #[derive(Debug)] pub struct TextComponent { - gl_context : WebGlRenderingContext, - gl_program : Program, - gl_vertex_buf : WebGlBuffer, - gl_tex_coord_buf : WebGlBuffer, - gl_msdf_texture : WebGlTexture, - buffers_size : usize, + gl_context : WebGlRenderingContext, + gl_program : Program, + gl_vertex_buffer : WebGlBuffer, + gl_texture_coordinates_buffer : WebGlBuffer, + gl_msdf_texture : WebGlTexture, + buffers_size : usize, } impl<'a> TextComponentBuilder<'a> { @@ -38,16 +38,20 @@ impl<'a> TextComponentBuilder<'a> { self.load_all_chars(); let gl_context = workspace.context.clone(); let gl_program = self.create_program(&gl_context); - let gl_vertex_buf = self.create_vertex_buf(&gl_context); - let gl_tex_coord_buf = self.create_tex_coord_buf(&gl_context); + let gl_vertex_buffer = self.create_vertex_bufffer(&gl_context); + let gl_tex_coord_buffer = self.create_texture_coordinates_buffer(&gl_context); let gl_msdf_texture = self.create_msdf_texture(&gl_context); let glyph_vertices_count = glyph_render::GLYPH_SQUARE_VERTICES_BASE_LAYOUT.len(); let buffers_size = self.text.len() * glyph_vertices_count; - self.setup_uniforms(&gl_context, &gl_program); - - TextComponent - {gl_context,gl_program,gl_vertex_buf,gl_tex_coord_buf,gl_msdf_texture,buffers_size} + TextComponent { + gl_context, + gl_program, + gl_vertex_buffer, + gl_texture_coordinates_buffer : gl_tex_coord_buffer, + gl_msdf_texture, + buffers_size + } } fn load_all_chars(&mut self) { @@ -58,10 +62,8 @@ impl<'a> TextComponentBuilder<'a> { fn create_program(&self, gl_context:&Context) -> Program { gl_context.get_extension("OES_standard_derivatives").unwrap().unwrap(); - let vert_shader = self.create_vertex_shader(gl_context); let frag_shader = self.create_fragment_shader(gl_context); - link_program(&gl_context, &vert_shader, &frag_shader).unwrap() } @@ -80,17 +82,20 @@ impl<'a> TextComponentBuilder<'a> { } fn create_buffer(gl_context:&Context, vertices:&[f32]) -> WebGlBuffer { - let buffer = gl_context.create_buffer().unwrap(); let target = WebGlRenderingContext::ARRAY_BUFFER; - let usage = WebGlRenderingContext::STATIC_DRAW; + + let buffer = gl_context.create_buffer().unwrap(); gl_context.bind_buffer(target,Some(&buffer)); + Self::set_binded_buffer_data(gl_context,target,vertices); + buffer + } + fn set_binded_buffer_data(gl_context:&Context, target:u32, data:&[f32]) { + let usage = WebGlRenderingContext::STATIC_DRAW; unsafe { // Note [unsafe buffer_data] - let float_32_array = Float32Array::view(&vertices); + let float_32_array = Float32Array::view(&data); gl_context.buffer_data_with_array_buffer_view(target,&float_32_array,usage); } - - buffer } /* Note [unsafe buffer_data] @@ -101,16 +106,15 @@ impl<'a> TextComponentBuilder<'a> { * (https://rustwasm.github.io/wasm-bindgen/examples/webgl.html) */ - fn create_vertex_buf(&mut self, gl_context:&Context) -> WebGlBuffer { + fn create_vertex_bufffer(&mut self, gl_context:&Context) -> WebGlBuffer { let to_window = self.to_window_transform(); let font = &mut self.font; + let mut vertices_builder = GylphSquareVerticesBuilder::new(font,to_window); let char_to_vertices = |ch| vertices_builder.build_for_next_glyph(ch); - let grouped_vertices = self.text.chars().map(char_to_vertices); let vertices = grouped_vertices.flatten(); let buffer_data = vertices.map(|f| f as f32).collect::>(); - Self::create_buffer(gl_context,buffer_data.as_ref()) } @@ -120,16 +124,15 @@ impl<'a> TextComponentBuilder<'a> { nalgebra::convert(similarity) } - fn create_tex_coord_buf(&mut self, gl_context:&Context) -> WebGlBuffer { + fn create_texture_coordinates_buffer(&mut self, gl_context:&Context) -> WebGlBuffer { let font = &mut self.font; + let mut texture_coordinates_builder = GlyphSquareTextureCoordinatesBuilder::new(font); let char_to_texture_coordinates = |ch| texture_coordinates_builder.build_for_next_glyph(ch); - let grouped_texture_coordinates = self.text.chars().map(char_to_texture_coordinates); let texture_coordinates = grouped_texture_coordinates.flatten(); let converted_data = texture_coordinates.map(|f| f as f32); let buffer_data = converted_data.collect::>(); - Self::create_buffer(gl_context,buffer_data.as_ref()) } @@ -149,31 +152,35 @@ impl<'a> TextComponentBuilder<'a> { let data = Some(self.font.msdf_texture.data.as_slice()); gl_ctx.bind_texture(target,Some(&msdf_texture)); - gl_ctx.tex_parameteri(target,Context::TEXTURE_WRAP_S,wrap); gl_ctx.tex_parameteri(target,Context::TEXTURE_WRAP_T,wrap); gl_ctx.tex_parameteri(target,Context::TEXTURE_MIN_FILTER,min_filter); - let tex_image_result = - gl_ctx.tex_image_2d_with_i32_and_i32_and_i32_and_format_and_type_and_opt_u8_array - (target,tex_level,internal_fmt,width,height,border,format,tex_type,data); - + gl_ctx.tex_image_2d_with_i32_and_i32_and_i32_and_format_and_type_and_opt_u8_array + ( target + , tex_level + , internal_fmt + , width + , height + , border + , format + , tex_type + , data + ); tex_image_result.unwrap(); - msdf_texture } fn setup_uniforms(&self, gl_context:&Context, gl_program:&Program) { + let color = &self.color; + let range = FontRenderInfo::MSDF_PARAMS.range as f32; + let msdf_width = MsdfTexture::WIDTH as f32; + let msdf_height = self.font.msdf_texture.rows() as f32; let color_loc = gl_context.get_uniform_location(gl_program,"color"); let range_loc = gl_context.get_uniform_location(gl_program,"range"); let msdf_loc = gl_context.get_uniform_location(gl_program,"msdf"); let msdf_size_loc = gl_context.get_uniform_location(gl_program,"msdfSize"); - let color = &self.color; - let range = FontRenderInfo::MSDF_PARAMS.range as f32; - let msdf_width = MsdfTexture::WIDTH as f32; - let msdf_height = self.font.msdf_texture.rows() as f32; - gl_context.use_program(Some(gl_program)); gl_context.uniform4f(color_loc.as_ref(),color.r,color.g,color.b,color.a); gl_context.uniform1f(range_loc.as_ref(),range); @@ -188,13 +195,10 @@ impl TextComponent { let gl_context = &self.gl_context; gl_context.use_program(Some(&self.gl_program)); - - self.bind_buffer_to_attribute("position",&self.gl_vertex_buf); - self.bind_buffer_to_attribute("texCoord",&self.gl_tex_coord_buf); + self.bind_buffer_to_attribute("position",&self.gl_vertex_buffer); + self.bind_buffer_to_attribute("texCoord",&self.gl_texture_coordinates_buffer); self.setup_blending(); - gl_context.bind_texture(Context::TEXTURE_2D, Some(&self.gl_msdf_texture)); - gl_context.draw_arrays(WebGlRenderingContext::TRIANGLES,0,self.buffers_size as i32); } @@ -211,9 +215,14 @@ impl TextComponent { gl_context.enable_vertex_attrib_array(location); gl_context.bind_buffer(target,Some(buffer)); - gl_context.vertex_attrib_pointer_with_i32 - (location,item_size,item_type,normalized,stride,offset); + ( location + , item_size + , item_type + , normalized + , stride + , offset + ); } fn setup_blending(&self) { diff --git a/lib/core/src/text/font.rs b/lib/core/src/text/font.rs index ed37ee2f41..dbe3917b3c 100644 --- a/lib/core/src/text/font.rs +++ b/lib/core/src/text/font.rs @@ -91,20 +91,17 @@ impl FontRenderInfo { let unicode = ch as u32; let params = Self::MSDF_PARAMS; let msdf_height = MsdfTexture::ONE_GLYPH_HEIGHT; - - let msdf = MultichannelSignedDistanceField::generate(handle,unicode,¶ms); let msdf_tex_rows_begin = self.msdf_texture.rows(); let msdf_tex_rows_end = msdf_tex_rows_begin + msdf_height; - let msdf_transformation = convert_msdf_transformation(&msdf); + let msdf = MultichannelSignedDistanceField::generate(handle,unicode,¶ms); + let msdf_transformation = convert_msdf_transformation(&msdf); let advance = x_distance_from_msdf_value(msdf.advance); - let glyph_info = GlyphRenderInfo { msdf_texture_rows : msdf_tex_rows_begin..msdf_tex_rows_end, from_base_layout : msdf_transformation.inverse(), advance }; - self.msdf_texture.extend(msdf.data.iter()); self.glyphs.insert(ch, glyph_info); } @@ -153,7 +150,6 @@ impl FontRenderInfo { from_base_layout : nalgebra::Transform::identity(), advance : 0.0 }; - self.msdf_texture.extend(msdf_data); self.glyphs.insert(ch, char_info); self.glyphs.get_mut(&ch).unwrap() diff --git a/lib/core/src/text/glyph_render.rs b/lib/core/src/text/glyph_render.rs index 752bd48ee7..658423c93a 100644 --- a/lib/core/src/text/glyph_render.rs +++ b/lib/core/src/text/glyph_render.rs @@ -59,23 +59,20 @@ impl<'a> GylphSquareVerticesBuilder<'a> { pub fn build_for_next_glyph(&mut self, ch:char) -> GlyphSquareVertices { let apply_kerning = self.translation_by_kerning_value(ch); let to_pen_position = self.translation_by_pen_position(); - let glyph_info = self.font.get_glyph_info(ch); let glyph_specific_transform = &glyph_info.from_base_layout; let to_window = &self.to_window; - let advance_pen = Translation2::new(glyph_info.advance, 0.0); let pen_transformation = apply_kerning * advance_pen; + self.pen_position = pen_transformation * self.pen_position; + self.previous_char = Some(ch); let plain_base = GLYPH_SQUARE_VERTICES_BASE_LAYOUT.iter(); let base = plain_base .map(|(x, y)| Point2::new(*x, *y)); let glyph_fixed = base .map(|p| glyph_specific_transform * p); let moved_to_pen_position = glyph_fixed .map(|p| to_pen_position * p); let kerning_applied = moved_to_pen_position.map(|p| apply_kerning * p); let mapped_to_window = kerning_applied .map(|p| to_window * p); - - self.pen_position = pen_transformation * self.pen_position; - self.previous_char = Some(ch); mapped_to_window.map(point_to_iterable).flatten().collect() } @@ -119,7 +116,6 @@ impl<'a> GlyphSquareTextureCoordinatesBuilder<'a> { let base = plain_base .map(|(x,y)| Point2::new(*x, *y)); let aligned_to_border = base .map(|p| border_align * p); let transformed = aligned_to_border.map(|p| to_proper_fragment * p); - transformed.map(point_to_iterable).flatten().collect() } @@ -138,16 +134,13 @@ impl<'a> GlyphSquareTextureCoordinatesBuilder<'a> { let translation_x = column_size / 2.0; let translation_y = row_size / 2.0; - let scale_x = 1.0 - column_size; let scale_y = 1.0 - row_size; - let matrix = Matrix3::new ( scale_x, 0.0 , translation_x , 0.0 , scale_y, translation_y , 0.0 , 0.0 , 1.0 ); - Affine2::from_matrix_unchecked(matrix) } @@ -160,6 +153,7 @@ impl<'a> GlyphSquareTextureCoordinatesBuilder<'a> { pub fn glyph_texture_fragment_transform(&mut self, ch:char) -> Affine2 { let one_glyph_rows = MsdfTexture::ONE_GLYPH_HEIGHT as f64; let all_rows = self.font.msdf_texture.rows() as f64; + let fraction = one_glyph_rows / all_rows; let glyph_info = self.font.get_glyph_info(ch); let offset = glyph_info.msdf_texture_rows.start as f64 / all_rows; diff --git a/lib/core/src/text/msdf.rs b/lib/core/src/text/msdf.rs index 6d5d1c0792..b4cacb0f80 100644 --- a/lib/core/src/text/msdf.rs +++ b/lib/core/src/text/msdf.rs @@ -17,10 +17,8 @@ pub struct MsdfTexture { impl MsdfTexture { pub const CHANNELS_COUNT : usize = MultichannelSignedDistanceField::CHANNELS_COUNT; - pub const WIDTH : usize = 32; pub const ROW_SIZE : usize = Self::CHANNELS_COUNT * Self::WIDTH; - pub const ONE_GLYPH_HEIGHT : usize = 32; pub const ONE_GLYPH_SIZE : usize = Self::ROW_SIZE * Self::ONE_GLYPH_HEIGHT; @@ -33,9 +31,8 @@ impl MsdfTexture { const UNSIGNED_BYTE_MIN : f32 = 0.0; const UNSIGNED_BYTE_MAX : f32 = 255.0; - let scaled_to_byte = value * 255.0; + let scaled_to_byte = value * UNSIGNED_BYTE_MAX; let clamped_to_byte = clamp(scaled_to_byte,UNSIGNED_BYTE_MIN,UNSIGNED_BYTE_MAX); - clamped_to_byte as u8 } } @@ -83,16 +80,13 @@ pub fn convert_msdf_transformation(msdf:&MultichannelSignedDistanceField) -> nalgebra::Projective2 { let translate_converted_x = x_distance_from_msdf_value(msdf.translation.x); let translate_converted_y = y_distance_from_msdf_value(msdf.translation.y); - let translate_scaled_x = translate_converted_x * msdf.scale.x; let translate_scaled_y = translate_converted_y * msdf.scale.y; - let msdf_transformation_matrix = nalgebra::Matrix3::new( msdf.scale.x, 0.0, translate_scaled_x, 0.0, msdf.scale.y, translate_scaled_y, 0.0, 0.0, 1.0 ); - nalgebra::Projective2::from_matrix_unchecked(msdf_transformation_matrix) } From cd16f4f5afe98eee917b1cf433f9f1724d12bc12 Mon Sep 17 00:00:00 2001 From: Adam Obuchowicz Date: Wed, 4 Dec 2019 13:23:28 +0100 Subject: [PATCH 17/19] Naming fix --- lib/core/src/text.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/src/text.rs b/lib/core/src/text.rs index 11b0d04fbf..afba109e5e 100644 --- a/lib/core/src/text.rs +++ b/lib/core/src/text.rs @@ -90,7 +90,7 @@ impl<'a> TextComponentBuilder<'a> { buffer } - fn set_binded_buffer_data(gl_context:&Context, target:u32, data:&[f32]) { + fn set_bound_buffer_data(gl_context:&Context, target:u32, data:&[f32]) { let usage = WebGlRenderingContext::STATIC_DRAW; unsafe { // Note [unsafe buffer_data] let float_32_array = Float32Array::view(&data); From e11ace2dd78577668e33e33dbad3652ea7eff52f Mon Sep 17 00:00:00 2001 From: Adam Obuchowicz Date: Wed, 4 Dec 2019 15:12:36 +0100 Subject: [PATCH 18/19] Remove the big file and fix tests --- examples/03-text/.gitignore | 1 + examples/03-text/package-lock.json | 6058 ---------------------------- lib/core/src/text.rs | 2 +- 3 files changed, 2 insertions(+), 6059 deletions(-) delete mode 100644 examples/03-text/package-lock.json diff --git a/examples/03-text/.gitignore b/examples/03-text/.gitignore index f06235c460..16acd49d7f 100644 --- a/examples/03-text/.gitignore +++ b/examples/03-text/.gitignore @@ -1,2 +1,3 @@ node_modules dist +package-lock.json diff --git a/examples/03-text/package-lock.json b/examples/03-text/package-lock.json deleted file mode 100644 index eaf214c099..0000000000 --- a/examples/03-text/package-lock.json +++ /dev/null @@ -1,6058 +0,0 @@ -{ - "name": "example-scene", - "version": "0.1.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@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/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/node": { - "version": "12.7.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.9.tgz", - "integrity": "sha512-P57oKTJ/vYivL2BCfxCC5tQjlS8qW31pbOL6qt99Yrjm95YdHgNZwjrTTjMBh+C2/y6PXIX4oz253+jUzxKKfQ==", - "dev": true - }, - "@webassemblyjs/ast": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", - "integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/wast-parser": "1.8.5" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz", - "integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz", - "integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz", - "integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz", - "integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.8.5" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz", - "integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz", - "integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "mamacro": "^0.0.3" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz", - "integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz", - "integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz", - "integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz", - "integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz", - "integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz", - "integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/helper-wasm-section": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5", - "@webassemblyjs/wasm-opt": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5", - "@webassemblyjs/wast-printer": "1.8.5" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz", - "integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/ieee754": "1.8.5", - "@webassemblyjs/leb128": "1.8.5", - "@webassemblyjs/utf8": "1.8.5" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz", - "integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz", - "integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-api-error": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/ieee754": "1.8.5", - "@webassemblyjs/leb128": "1.8.5", - "@webassemblyjs/utf8": "1.8.5" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz", - "integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/floating-point-hex-parser": "1.8.5", - "@webassemblyjs/helper-api-error": "1.8.5", - "@webassemblyjs/helper-code-frame": "1.8.5", - "@webassemblyjs/helper-fsm": "1.8.5", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz", - "integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/wast-parser": "1.8.5", - "@xtuc/long": "4.2.2" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "dev": true, - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "acorn": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz", - "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==", - "dev": true - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "dev": true, - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", - "dev": true - }, - "ansi-html": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", - "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", - "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 - }, - "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" - } - }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", - "dev": true - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "assert": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", - "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", - "dev": true, - "requires": { - "object-assign": "^4.1.1", - "util": "0.10.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - } - } - } - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "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==", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "basegl": { - "version": "file:../../target/web", - "dev": true - }, - "batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", - "dev": true - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bluebird": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.0.tgz", - "integrity": "sha512-aBQ1FxIa7kSWCcmKHlcHFlT2jt6J/l4FzC7KcPELkOJOsPOb/bccdhmIrKDfXhwFrmc7vDoDrrepFvGqjyXGJg==", - "dev": true - }, - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - }, - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "dev": true, - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "dependencies": { - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true - } - } - }, - "bonjour": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", - "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", - "dev": true, - "requires": { - "array-flatten": "^2.1.0", - "deep-equal": "^1.0.1", - "dns-equal": "^1.0.0", - "dns-txt": "^2.0.2", - "multicast-dns": "^6.0.1", - "multicast-dns-service-types": "^1.1.0" - } - }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - } - }, - "browserify-sign": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", - "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", - "dev": true, - "requires": { - "bn.js": "^4.1.1", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.2", - "elliptic": "^6.0.0", - "inherits": "^2.0.1", - "parse-asn1": "^5.0.0" - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", - "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-indexof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", - "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true - }, - "cacache": { - "version": "11.3.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.3.tgz", - "integrity": "sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "camel-case": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", - "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", - "dev": true, - "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.1.1" - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "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==", - "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" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "chownr": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", - "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "clean-css": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", - "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==", - "dev": true, - "requires": { - "source-map": "~0.6.0" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.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 - }, - "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compressible": { - "version": "2.0.17", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.17.tgz", - "integrity": "sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==", - "dev": true, - "requires": { - "mime-db": ">= 1.40.0 < 2" - } - }, - "compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dev": true, - "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "connect-history-api-fallback": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", - "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", - "dev": true - }, - "console-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", - "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", - "dev": true, - "requires": { - "date-now": "^0.1.4" - } - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", - "dev": true, - "requires": { - "safe-buffer": "5.1.2" - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true - }, - "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", - "dev": true - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", - "dev": true - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "copy-webpack-plugin": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.0.4.tgz", - "integrity": "sha512-YBuYGpSzoCHSSDGyHy6VJ7SHojKp6WHT4D7ItcQFNAYx2hrwkMe56e97xfVR0/ovDuMTrMffXUiltvQljtAGeg==", - "dev": true, - "requires": { - "cacache": "^11.3.3", - "find-cache-dir": "^2.1.0", - "glob-parent": "^3.1.0", - "globby": "^7.1.1", - "is-glob": "^4.0.1", - "loader-utils": "^1.2.3", - "minimatch": "^3.0.4", - "normalize-path": "^3.0.0", - "p-limit": "^2.2.0", - "schema-utils": "^1.0.0", - "serialize-javascript": "^1.7.0", - "webpack-log": "^2.0.0" - } - }, - "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=", - "dev": true - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "css-select": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", - "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", - "dev": true, - "requires": { - "boolbase": "~1.0.0", - "css-what": "2.1", - "domutils": "1.5.1", - "nth-check": "~1.0.1" - } - }, - "css-what": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", - "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", - "dev": true - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "date-now": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", - "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", - "dev": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "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=", - "dev": true - }, - "deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.0.tgz", - "integrity": "sha512-ZbfWJq/wN1Z273o7mUSjILYqehAktR2NVoSrOukDkU9kg2v/Uv89yU4Cvz8seJeAmtN5oqiefKq8FPuXOboqLw==", - "dev": true, - "requires": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - } - }, - "default-gateway": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", - "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "ip-regex": "^2.1.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true - }, - "des.js": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", - "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true - }, - "detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", - "dev": true - }, - "detect-node": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", - "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "dir-glob": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", - "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", - "dev": true, - "requires": { - "path-type": "^3.0.0" - } - }, - "dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", - "dev": true - }, - "dns-packet": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", - "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", - "dev": true, - "requires": { - "ip": "^1.1.0", - "safe-buffer": "^5.0.1" - } - }, - "dns-txt": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", - "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", - "dev": true, - "requires": { - "buffer-indexof": "^1.0.0" - } - }, - "dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "dev": true, - "requires": { - "utila": "~0.4" - } - }, - "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", - "dev": true, - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==", - "dev": true - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", - "dev": true - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "dev": true, - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", - "dev": true, - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "elliptic": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.1.tgz", - "integrity": "sha512-xvJINNLbTeWQjrl6X+7eQCrIy/YPv5XCpKW6kB5mKvtnGILoLDcySuwomfdzt0BMdLNVnuRNTuzKNHj0bva1Cg==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", - "dev": true - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", - "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.4.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==", - "dev": true - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.15.0.tgz", - "integrity": "sha512-bhkEqWJ2t2lMeaJDuk7okMkJWI/yqgH/EoGwpcvv0XW9RWQsRspI4wt6xuyuvMvvQE3gg/D9HXppgk21w78GyQ==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.0", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.0", - "is-callable": "^1.1.4", - "is-regex": "^1.0.4", - "object-inspect": "^1.6.0", - "object-keys": "^1.1.1", - "string.prototype.trimleft": "^2.1.0", - "string.prototype.trimright": "^2.1.0" - } - }, - "es-to-primitive": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", - "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true - }, - "eventemitter3": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz", - "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==", - "dev": true - }, - "events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", - "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", - "dev": true - }, - "eventsource": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", - "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", - "dev": true, - "requires": { - "original": "^1.0.0" - } - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", - "dev": true, - "requires": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", - "dev": true - } - } - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true - }, - "faye-websocket": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", - "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "figgy-pudding": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", - "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==", - "dev": true - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.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" - } - }, - "findup-sync": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", - "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", - "dev": true, - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - } - }, - "follow-redirects": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.9.0.tgz", - "integrity": "sha512-CRcPzsSIbXyVDl0QI01muNDu69S8trU4jArW9LpOt2WtC6LyUJetcIrmfHsRBx7/Jb6GHJUiuqyYxPooFfNt6A==", - "dev": true, - "requires": { - "debug": "^3.0.0" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", - "dev": true - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", - "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", - "dev": true, - "optional": true, - "requires": { - "nan": "^2.12.1", - "node-pre-gyp": "^0.12.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.3", - "bundled": true, - "dev": true, - "optional": 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" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.3.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.2.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.3.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^4.1.0", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.12.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.6.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.7.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "yallist": { - "version": "3.0.3", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "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 - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", - "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" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "dev": true, - "requires": { - "global-prefix": "^3.0.0" - }, - "dependencies": { - "global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "dev": true, - "requires": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - } - } - } - }, - "global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - } - }, - "globby": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz", - "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "dir-glob": "^2.0.0", - "glob": "^7.1.2", - "ignore": "^3.3.5", - "pify": "^3.0.0", - "slash": "^1.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", - "dev": true - }, - "handle-thing": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.0.tgz", - "integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==", - "dev": true - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "hello-wasm-pack": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/hello-wasm-pack/-/hello-wasm-pack-0.1.0.tgz", - "integrity": "sha512-3hx0GDkDLf/a9ThCMV2qG4mwza8N/MCtm8aeFFc/cdBCL2zMJ1kW1wjNl7xPqD1lz8Yl5+uhnc/cpui4dLwz/w==", - "dev": true - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "dev": true, - "requires": { - "parse-passwd": "^1.0.0" - } - }, - "hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - } - }, - "html-entities": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", - "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=", - "dev": true - }, - "html-minifier": { - "version": "3.5.21", - "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz", - "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==", - "dev": true, - "requires": { - "camel-case": "3.0.x", - "clean-css": "4.2.x", - "commander": "2.17.x", - "he": "1.2.x", - "param-case": "2.1.x", - "relateurl": "0.2.x", - "uglify-js": "3.4.x" - } - }, - "html-webpack-plugin": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz", - "integrity": "sha1-sBq71yOsqqeze2r0SS69oD2d03s=", - "dev": true, - "requires": { - "html-minifier": "^3.2.3", - "loader-utils": "^0.2.16", - "lodash": "^4.17.3", - "pretty-error": "^2.0.2", - "tapable": "^1.0.0", - "toposort": "^1.0.0", - "util.promisify": "1.0.0" - }, - "dependencies": { - "big.js": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", - "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", - "dev": true - }, - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true - }, - "loader-utils": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", - "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", - "dev": true, - "requires": { - "big.js": "^3.1.3", - "emojis-list": "^2.0.0", - "json5": "^0.5.0", - "object-assign": "^4.0.1" - } - } - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "dev": true, - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - }, - "dependencies": { - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", - "dev": true - }, - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - }, - "http-parser-js": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", - "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=", - "dev": true - }, - "http-proxy": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.0.tgz", - "integrity": "sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==", - "dev": true, - "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "http-proxy-middleware": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", - "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", - "dev": true, - "requires": { - "http-proxy": "^1.17.0", - "is-glob": "^4.0.0", - "lodash": "^4.17.11", - "micromatch": "^3.1.10" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "iconv-lite": { - "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" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", - "dev": true - }, - "import-local": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", - "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", - "dev": true, - "requires": { - "pkg-dir": "^3.0.0", - "resolve-cwd": "^2.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "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=", - "dev": true, - "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==", - "dev": true - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true - }, - "internal-ip": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", - "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", - "dev": true, - "requires": { - "default-gateway": "^4.2.0", - "ipaddr.js": "^1.9.0" - } - }, - "interpret": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", - "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", - "dev": true - }, - "invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", - "dev": true - }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true - }, - "ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", - "dev": true - }, - "ipaddr.js": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", - "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==", - "dev": true - }, - "is-absolute-url": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", - "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", - "dev": true - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-arguments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", - "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", - "dev": true - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "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 - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "dev": true, - "requires": { - "has": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-symbol": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", - "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.0" - } - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "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==", - "dev": true - }, - "json3": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", - "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==", - "dev": true - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "killable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", - "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "dev": true, - "requires": { - "invert-kv": "^2.0.0" - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", - "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^2.0.0", - "json5": "^1.0.1" - } - }, - "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" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - }, - "loglevel": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.4.tgz", - "integrity": "sha512-p0b6mOGKcGa+7nnmKbpzR6qloPbrgLcnio++E+14Vo/XffOGwZtRpUhr8dTH/x2oCMmEoIU0Zwm3ZauhvYD17g==", - "dev": true - }, - "lower-case": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", - "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", - "dev": true - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - } - }, - "mamacro": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz", - "integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==", - "dev": true - }, - "map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", - "dev": true, - "requires": { - "p-defer": "^1.0.0" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true - }, - "mem": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", - "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.0" - } - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", - "dev": true - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", - "dev": true - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "dev": true, - "requires": { - "mime-db": "1.40.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "multicast-dns": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", - "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", - "dev": true, - "requires": { - "dns-packet": "^1.3.1", - "thunky": "^1.0.2" - } - }, - "multicast-dns-service-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", - "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", - "dev": true - }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "no-case": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", - "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", - "dev": true, - "requires": { - "lower-case": "^1.1.1" - } - }, - "node-forge": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz", - "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==", - "dev": true - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", - "dev": true, - "requires": { - "boolbase": "~1.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "object-inspect": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", - "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", - "dev": true - }, - "object-is": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.1.tgz", - "integrity": "sha1-CqYOyZiaCz7Xlc9NBvYs8a1lObY=", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, - "object.getownpropertydescriptors": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", - "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": true - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opn": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", - "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", - "dev": true, - "requires": { - "is-wsl": "^1.1.0" - } - }, - "original": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", - "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", - "dev": true, - "requires": { - "url-parse": "^1.4.3" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - } - }, - "p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, - "p-is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", - "dev": true - }, - "p-limit": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", - "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", - "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-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-retry": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", - "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", - "dev": true, - "requires": { - "retry": "^0.12.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 - }, - "pako": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", - "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - } - }, - "param-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", - "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", - "dev": true, - "requires": { - "no-case": "^2.2.0" - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.0", - "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", - "dev": true - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "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 - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", - "dev": true - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "portfinder": { - "version": "1.0.24", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.24.tgz", - "integrity": "sha512-ekRl7zD2qxYndYflwiryJwMioBI7LI7rVXg3EnLK3sjkouT5eOuhS3gS255XxBksa30VG8UPZYZCdgfGOfkSUg==", - "dev": true, - "requires": { - "async": "^1.5.2", - "debug": "^2.2.0", - "mkdirp": "0.5.x" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "pretty-error": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", - "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", - "dev": true, - "requires": { - "renderkid": "^2.0.1", - "utila": "~0.4" - } - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "proxy-addr": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", - "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", - "dev": true, - "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.0" - } - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "dev": true - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true - }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "dev": true, - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "dependencies": { - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "regexp.prototype.flags": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.2.0.tgz", - "integrity": "sha512-ztaw4M1VqgMwl9HlPpOuiYgItcHlunW0He2fE6eNfT6E/CF2FtYi9ofOYe4mKntstYk0Fyh/rDRBdS3AnxjlrA==", - "dev": true, - "requires": { - "define-properties": "^1.1.2" - } - }, - "relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", - "dev": true - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "renderkid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.3.tgz", - "integrity": "sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA==", - "dev": true, - "requires": { - "css-select": "^1.1.0", - "dom-converter": "^0.2", - "htmlparser2": "^3.3.0", - "strip-ansi": "^3.0.0", - "utila": "^0.4.0" - } - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "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 - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", - "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", - "dev": true, - "requires": { - "resolve-from": "^3.0.0" - } - }, - "resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", - "dev": true, - "requires": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - }, - "dependencies": { - "global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "dev": true, - "requires": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - } - } - } - }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", - "dev": true - }, - "selfsigned": { - "version": "1.10.7", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.7.tgz", - "integrity": "sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA==", - "dev": true, - "requires": { - "node-forge": "0.9.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "dev": true, - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "dependencies": { - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - } - } - }, - "serialize-javascript": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz", - "integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A==", - "dev": true - }, - "serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", - "dev": true, - "requires": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "dependencies": { - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - } - } - }, - "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "dev": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "sockjs": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz", - "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==", - "dev": true, - "requires": { - "faye-websocket": "^0.10.0", - "uuid": "^3.0.1" - } - }, - "sockjs-client": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz", - "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==", - "dev": true, - "requires": { - "debug": "^3.2.5", - "eventsource": "^1.0.7", - "faye-websocket": "~0.11.1", - "inherits": "^2.0.3", - "json3": "^3.3.2", - "url-parse": "^1.4.3" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "faye-websocket": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", - "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "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 - }, - "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", - "dev": true, - "requires": { - "atob": "^2.1.1", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "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=", - "dev": true - }, - "spdy": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.1.tgz", - "integrity": "sha512-HeZS3PBdMA+sZSu0qwpCxl3DeALD5ASx8pAX0jZdKXSpPWbQ6SYGnlg3BBmYLx5LtiZrmkAZfErCm2oECBcioA==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - } - }, - "stream-shift": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", - "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "string.prototype.trimleft": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", - "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" - } - }, - "string.prototype.trimright": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", - "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.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" - } - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "terser": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.3.4.tgz", - "integrity": "sha512-Kcrn3RiW8NtHBP0ssOAzwa2MsIRQ8lJWiBG/K7JgqPlomA3mtb2DEmp4/hrUA+Jujx+WZ02zqd7GYD+QRBB/2Q==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.1.tgz", - "integrity": "sha512-cCuLsMhJeWQ/ZpsFTbE765kvVfoeSddc4nU3up4fV+fDBcfUXnbITJ+JzhkdjzOqhURjZgujxaioam4RM9yGUg==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.1.tgz", - "integrity": "sha512-ZXmmfiwtCLfz8WKZyYUuuHf3dMYEjg8NrjHMb0JqHVHVOSkzp3cW2/XG1fP3tRhqEqSzMwzzRQGtAPbs4Cncxg==", - "dev": true, - "requires": { - "cacache": "^12.0.2", - "find-cache-dir": "^2.1.0", - "is-wsl": "^1.1.0", - "schema-utils": "^1.0.0", - "serialize-javascript": "^1.7.0", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - }, - "dependencies": { - "cacache": { - "version": "12.0.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz", - "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - } - } - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "thunky": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.3.tgz", - "integrity": "sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow==", - "dev": true - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", - "dev": true - }, - "toposort": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz", - "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=", - "dev": true - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "uglify-js": { - "version": "3.4.10", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz", - "integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==", - "dev": true, - "requires": { - "commander": "~2.19.0", - "source-map": "~0.6.1" - }, - "dependencies": { - "commander": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", - "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", - "dev": true - } - } - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "upper-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", - "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", - "dev": true - }, - "uri-js": { - "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" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "util.promisify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", - "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "object.getownpropertydescriptors": "^2.0.3" - } - }, - "utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", - "dev": true - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true - }, - "uuid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", - "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==", - "dev": true - }, - "v8-compile-cache": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz", - "integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==", - "dev": true - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true - }, - "vm-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", - "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==", - "dev": true - }, - "watchpack": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", - "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", - "dev": true, - "requires": { - "chokidar": "^2.0.2", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - } - }, - "wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "dev": true, - "requires": { - "minimalistic-assert": "^1.0.0" - } - }, - "webpack": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.41.0.tgz", - "integrity": "sha512-yNV98U4r7wX1VJAj5kyMsu36T8RPPQntcb5fJLOsMz/pt/WrKC0Vp1bAlqPLkA1LegSwQwf6P+kAbyhRKVQ72g==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-module-context": "1.8.5", - "@webassemblyjs/wasm-edit": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5", - "acorn": "^6.2.1", - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.3", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.4.0", - "loader-utils": "^1.2.3", - "memory-fs": "^0.4.1", - "micromatch": "^3.1.10", - "mkdirp": "^0.5.1", - "neo-async": "^2.6.1", - "node-libs-browser": "^2.2.1", - "schema-utils": "^1.0.0", - "tapable": "^1.1.3", - "terser-webpack-plugin": "^1.4.1", - "watchpack": "^1.6.0", - "webpack-sources": "^1.4.1" - } - }, - "webpack-cli": { - "version": "3.3.9", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.9.tgz", - "integrity": "sha512-xwnSxWl8nZtBl/AFJCOn9pG7s5CYUYdZxmmukv+fAHLcBIHM36dImfpQg3WfShZXeArkWlf6QRw24Klcsv8a5A==", - "dev": true, - "requires": { - "chalk": "2.4.2", - "cross-spawn": "6.0.5", - "enhanced-resolve": "4.1.0", - "findup-sync": "3.0.0", - "global-modules": "2.0.0", - "import-local": "2.0.0", - "interpret": "1.2.0", - "loader-utils": "1.2.3", - "supports-color": "6.1.0", - "v8-compile-cache": "2.0.3", - "yargs": "13.2.4" - } - }, - "webpack-dev-middleware": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz", - "integrity": "sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==", - "dev": true, - "requires": { - "memory-fs": "^0.4.1", - "mime": "^2.4.4", - "mkdirp": "^0.5.1", - "range-parser": "^1.2.1", - "webpack-log": "^2.0.0" - }, - "dependencies": { - "mime": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", - "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", - "dev": true - } - } - }, - "webpack-dev-server": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.8.2.tgz", - "integrity": "sha512-0xxogS7n5jHDQWy0WST0q6Ykp7UGj4YvWh+HVN71JoE7BwPxMZrwgraBvmdEMbDVMBzF0u+mEzn8TQzBm5NYJQ==", - "dev": true, - "requires": { - "ansi-html": "0.0.7", - "bonjour": "^3.5.0", - "chokidar": "^2.1.8", - "compression": "^1.7.4", - "connect-history-api-fallback": "^1.6.0", - "debug": "^4.1.1", - "del": "^4.1.1", - "express": "^4.17.1", - "html-entities": "^1.2.1", - "http-proxy-middleware": "0.19.1", - "import-local": "^2.0.0", - "internal-ip": "^4.3.0", - "ip": "^1.1.5", - "is-absolute-url": "^3.0.3", - "killable": "^1.0.1", - "loglevel": "^1.6.4", - "opn": "^5.5.0", - "p-retry": "^3.0.1", - "portfinder": "^1.0.24", - "schema-utils": "^1.0.0", - "selfsigned": "^1.10.7", - "semver": "^6.3.0", - "serve-index": "^1.9.1", - "sockjs": "0.3.19", - "sockjs-client": "1.4.0", - "spdy": "^4.0.1", - "strip-ansi": "^3.0.1", - "supports-color": "^6.1.0", - "url": "^0.11.0", - "webpack-dev-middleware": "^3.7.2", - "webpack-log": "^2.0.0", - "ws": "^6.2.1", - "yargs": "12.0.5" - }, - "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 - }, - "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": { - "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" - } - } - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "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 - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "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 - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "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": { - "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" - } - } - } - }, - "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" - } - } - } - }, - "webpack-log": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", - "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", - "dev": true, - "requires": { - "ansi-colors": "^3.0.0", - "uuid": "^3.3.2" - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "websocket-driver": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", - "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", - "dev": true, - "requires": { - "http-parser-js": ">=0.4.0 <0.4.11", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - } - }, - "websocket-extensions": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", - "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yargs": { - "version": "13.2.4", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", - "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "os-locale": "^3.1.0", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.0" - } - }, - "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } -} diff --git a/lib/core/src/text.rs b/lib/core/src/text.rs index afba109e5e..64d881ce74 100644 --- a/lib/core/src/text.rs +++ b/lib/core/src/text.rs @@ -86,7 +86,7 @@ impl<'a> TextComponentBuilder<'a> { let buffer = gl_context.create_buffer().unwrap(); gl_context.bind_buffer(target,Some(&buffer)); - Self::set_binded_buffer_data(gl_context,target,vertices); + Self::set_bound_buffer_data(gl_context,target,vertices); buffer } From d327200eca7060a800b37a8de8eccd3deea490c2 Mon Sep 17 00:00:00 2001 From: Adam Obuchowicz Date: Wed, 4 Dec 2019 15:59:23 +0100 Subject: [PATCH 19/19] Fix compilation after merge --- lib/core/msdf-sys/src/internal.rs | 1 - lib/core/src/text/mod.rs | 267 ------------------------------ 2 files changed, 268 deletions(-) delete mode 100644 lib/core/src/text/mod.rs diff --git a/lib/core/msdf-sys/src/internal.rs b/lib/core/msdf-sys/src/internal.rs index 70633f2720..42897cc3a7 100644 --- a/lib/core/msdf-sys/src/internal.rs +++ b/lib/core/msdf-sys/src/internal.rs @@ -1,6 +1,5 @@ use wasm_bindgen::prelude::wasm_bindgen; use wasm_bindgen::JsValue; -use crate::prelude::*; #[wasm_bindgen(module = "/msdfgen_wasm.js")] extern { diff --git a/lib/core/src/text/mod.rs b/lib/core/src/text/mod.rs deleted file mode 100644 index 04cbb68cf8..0000000000 --- a/lib/core/src/text/mod.rs +++ /dev/null @@ -1,267 +0,0 @@ -use basegl_backend_webgl::{Context, compile_shader, link_program, Program, }; - -use web_sys::{WebGlRenderingContext, WebGlBuffer, WebGlTexture}; -use crate::prelude::*; -use crate::Color; - -pub mod font; - -use font::FontRenderInfo; -use crate::text::font::MsdfTexture; -use js_sys::Float32Array; -use crate::display::world::Workspace; - -pub struct TextComponentBuilder<'a> { - pub text : String, - pub font : &'a mut FontRenderInfo, - pub x : f32, - pub y : f32, - pub size : f32, - pub color : Color, - pub background_color : Color, -} - -#[derive(Debug)] -pub struct TextComponent { - gl_context : WebGlRenderingContext, - gl_program : Program, - gl_vertex_buf : WebGlBuffer, - gl_tex_coord_buf : WebGlBuffer, - gl_msdf_texture : WebGlTexture, - buffers_size : usize, -} - -impl<'a> TextComponentBuilder<'a> { - pub fn build(mut self, workspace : &Workspace) -> TextComponent { - let gl_context = workspace.context.clone(); - let gl_program = self.create_program(&gl_context); - let gl_vertex_buf = self.create_vertex_buf(&gl_context); - let gl_tex_coord_buf = self.create_tex_coord_buf(&gl_context); - let gl_msdf_texture = - self.create_msdf_texture(&gl_context, &gl_program); - - self.setup_uniforms(&gl_context, &gl_program); - - TextComponent { - gl_context, - gl_program, - gl_vertex_buf, - gl_tex_coord_buf, - gl_msdf_texture, - buffers_size: self.text.len() - } - } - - fn create_program(&self, gl_context : &Context) -> Program { - gl_context.get_extension("OES_standard_derivatives") - .unwrap().unwrap(); - - let vert_shader = compile_shader( - &gl_context, - WebGlRenderingContext::VERTEX_SHADER, - include_str!("msdf_vert.glsl") - ).unwrap(); - - let frag_shader = compile_shader( - &gl_context, - WebGlRenderingContext::FRAGMENT_SHADER, - include_str!("msdf_frag.glsl") - ).unwrap(); - - link_program(&gl_context, &vert_shader, &frag_shader).unwrap() - } - - fn create_buffer( - gl_context : &Context, - vertices : &[f32] - ) -> WebGlBuffer { - let buffer = gl_context.create_buffer().unwrap(); - gl_context.bind_buffer( - WebGlRenderingContext::ARRAY_BUFFER, - Some(&buffer) - ); - - unsafe { // Note [unsafe buffer_data] - let float_32_array = Float32Array::view(&vertices); - gl_context.buffer_data_with_array_buffer_view( - WebGlRenderingContext::ARRAY_BUFFER, - &float_32_array, - WebGlRenderingContext::STATIC_DRAW, - ); - } - - buffer - } - - /* Note [unsafe buffer_data] - * - * The Float32Array::view is safe as long there are no allocations done - * until it is destroyed. This way of creating buffers were taken from - * wasm-bindgen examples - * (https://rustwasm.github.io/wasm-bindgen/examples/webgl.html) - */ - - fn create_vertex_buf(&self, gl_context : &Context) -> WebGlBuffer { - let y_max = self.y + self.size; - let x_step = self.size; - let vertices = (0..self.text.len()).map(|i| { - let ix = self.x + (i as f32) * x_step; - let ix_max = ix + x_step; - vec![ix, self.y, ix, y_max, ix_max, self.y, ix_max, - self.y, ix, y_max, ix_max, y_max] // Note [The ugly code] - }).flatten().collect::>(); - - Self::create_buffer(gl_context, vertices.as_ref()) - } - - /* Note [The ugly code] - * - * I have already refactored this function on branch - * wip/ao/letter-alignment. Please be patient - */ - - fn create_tex_coord_buf(&mut self, gl_context : &Context) -> WebGlBuffer { - let font = &mut self.font; - for ch in self.text.chars() { - font.get_or_create_char_info(ch); - } - let vertices = self.text.chars().map(|c| { - let msdf_rows = font.msdf_texture.rows() as f32; - let info = font.get_or_create_char_info(c); - let y_min = info.msdf_texture_rows.start as f32 / msdf_rows; - let y_max = info.msdf_texture_rows.end as f32 / msdf_rows; - vec![0.0, y_min, 0.0, y_max, 1.0, y_min, - 1.0, y_min, 0.0, y_max, 1.0, y_max] - }).flatten().collect::>(); - - Self::create_buffer(gl_context, vertices.as_ref()) - } - - fn create_msdf_texture(&self, gl_context : &Context, gl_program : &Program) - -> WebGlTexture { - - let msdf_texture = gl_context.create_texture().unwrap(); - gl_context.bind_texture(Context::TEXTURE_2D, Some(&msdf_texture)); - - gl_context.tex_parameteri( - Context::TEXTURE_2D, - Context::TEXTURE_WRAP_S, - Context::CLAMP_TO_EDGE as i32 - ); - gl_context.tex_parameteri( - Context::TEXTURE_2D, - Context::TEXTURE_WRAP_T, - Context::CLAMP_TO_EDGE as i32 - ); - gl_context.tex_parameteri( - Context::TEXTURE_2D, - Context::TEXTURE_MIN_FILTER, - Context::LINEAR as i32 - ); - - gl_context.tex_image_2d_with_i32_and_i32_and_i32_and_format_and_type_and_opt_u8_array( - Context::TEXTURE_2D, - 0, - Context::RGB as i32, - MsdfTexture::WIDTH as i32, - self.font.msdf_texture.rows() as i32, - 0, - Context::RGB, - Context::UNSIGNED_BYTE, - Some(self.font.msdf_texture.data.as_slice()) - ).unwrap(); - - let msdf_loc = gl_context.get_uniform_location(gl_program, "msdf"); - let msdf_size_loc = - gl_context.get_uniform_location(gl_program, "msdfSize"); - - gl_context.use_program(Some(gl_program)); - gl_context.uniform1i(msdf_loc.as_ref(), 0); - gl_context.uniform2f( - msdf_size_loc.as_ref(), - MsdfTexture::WIDTH as f32, - self.font.msdf_texture.rows() as f32 - ); - - msdf_texture - } - - fn setup_uniforms(&self, gl_context : &Context, gl_program : &Program) { - let bg_color_loc = - gl_context.get_uniform_location(gl_program, "bgColor"); - let fg_color_loc = - gl_context.get_uniform_location(gl_program, "fgColor"); - let px_range_loc = - gl_context.get_uniform_location(gl_program, "pxRange"); - - gl_context.use_program(Some(gl_program)); - gl_context.uniform4f( - bg_color_loc.as_ref(), - self.background_color.r, - self.background_color.g, - self.background_color.b, - self.background_color.a - ); - gl_context.uniform4f( - fg_color_loc.as_ref(), - self.color.r, - self.color.g, - self.color.b, - self.color.a, - ); - gl_context.uniform1f( - px_range_loc.as_ref(), - FontRenderInfo::MSDF_PARAMS.range as f32 - ); - } -} - -impl TextComponent { - - pub fn display(&self) { - let gl = &self.gl_context; - let program = &self.gl_program; - - gl.use_program(Some(&self.gl_program)); - - let position_location = gl.get_attrib_location(program, "position"); - gl.enable_vertex_attrib_array(position_location as u32); - gl.bind_buffer( - WebGlRenderingContext::ARRAY_BUFFER, - Some(&self.gl_vertex_buf) - ); - gl.vertex_attrib_pointer_with_i32( - position_location as u32, - 2, - WebGlRenderingContext::FLOAT, - false, - 0, - 0 - ); - - gl.bind_texture(Context::TEXTURE_2D, Some(&self.gl_msdf_texture)); - - let tex_coord_location = gl.get_attrib_location(program, "texCoord"); - assert!(tex_coord_location >= 0); - gl.enable_vertex_attrib_array(tex_coord_location as u32); - gl.bind_buffer( - WebGlRenderingContext::ARRAY_BUFFER, - Some(&self.gl_tex_coord_buf) - ); - gl.vertex_attrib_pointer_with_i32( - tex_coord_location as u32, - 2, - WebGlRenderingContext::FLOAT, - false, - 0, - 0 - ); - - - gl.draw_arrays( - WebGlRenderingContext::TRIANGLES, - 0, - (self.buffers_size*6) as i32, - ); - } -}