From 506b11bf21b59c6c890658d39c819f15268a76b7 Mon Sep 17 00:00:00 2001 From: bokuweb Date: Tue, 12 Nov 2019 13:33:45 +0900 Subject: [PATCH] spec: Add VRT foundation --- .gitignore | 7 +- docx-core/src/documents/document.rs | 2 +- docx-core/src/documents/elements/paragraph.rs | 4 +- docx-core/src/documents/elements/style.rs | 2 +- docx-core/src/documents/styles.rs | 4 +- docx-core/src/types/border_type.rs | 199 ++++++++++++++++++ docx-core/src/types/mod.rs | 2 + docx-core/src/types/width_type.rs | 16 ++ docx-core/src/xml_builder/elements.rs | 23 ++ docx-core/src/xml_builder/macros.rs | 30 +++ docx-core/tests/lib.rs | 60 ++++++ docx-core/tests/output/.keep | 0 makefile | 8 + vrt/index.js | 13 ++ vrt/package.json | 14 ++ vrt/pdf.js | 25 +++ vrt/screenshot/expected/alignment.png | Bin 0 -> 7555 bytes vrt/screenshot/expected/indent.png | Bin 0 -> 25021 bytes vrt/screenshot/expected/size.png | Bin 0 -> 9906 bytes vrt/yarn.lock | 109 ++++++++++ 20 files changed, 511 insertions(+), 7 deletions(-) create mode 100644 docx-core/src/types/border_type.rs create mode 100644 docx-core/src/types/width_type.rs create mode 100644 docx-core/tests/lib.rs create mode 100644 docx-core/tests/output/.keep create mode 100644 makefile create mode 100644 vrt/index.js create mode 100644 vrt/package.json create mode 100644 vrt/pdf.js create mode 100644 vrt/screenshot/expected/alignment.png create mode 100644 vrt/screenshot/expected/indent.png create mode 100644 vrt/screenshot/expected/size.png create mode 100644 vrt/yarn.lock diff --git a/.gitignore b/.gitignore index a4de448..1c7e3e2 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,9 @@ node_modules pkg *.docx# test.docx -output/*.docx \ No newline at end of file +output/*.docx +vrt/screenshot/actual +vrt/screenshot/diff +vrt/report.html +reg.json +docx-core/tests/output/*.docx \ No newline at end of file diff --git a/docx-core/src/documents/document.rs b/docx-core/src/documents/document.rs index a1a11af..3695b98 100644 --- a/docx-core/src/documents/document.rs +++ b/docx-core/src/documents/document.rs @@ -57,7 +57,7 @@ mod tests { str::from_utf8(&b).unwrap(), r#" - Hello + Hello "# ); } diff --git a/docx-core/src/documents/elements/paragraph.rs b/docx-core/src/documents/elements/paragraph.rs index 8e43fc6..5fc7d91 100644 --- a/docx-core/src/documents/elements/paragraph.rs +++ b/docx-core/src/documents/elements/paragraph.rs @@ -73,7 +73,7 @@ mod tests { let b = Paragraph::new().add_run(Run::new("Hello")).build(); assert_eq!( str::from_utf8(&b).unwrap(), - r#"Hello"# + r#"Hello"# ); } @@ -82,7 +82,7 @@ mod tests { let b = Paragraph::new().add_run(Run::new("Hello")).size(60).build(); assert_eq!( str::from_utf8(&b).unwrap(), - r#"Hello"# + r#"Hello"# ); } } diff --git a/docx-core/src/documents/elements/style.rs b/docx-core/src/documents/elements/style.rs index 0a91b4c..9ffd107 100644 --- a/docx-core/src/documents/elements/style.rs +++ b/docx-core/src/documents/elements/style.rs @@ -75,7 +75,7 @@ mod tests { let b = c.build(); assert_eq!( str::from_utf8(&b).unwrap(), - r#""# + r#""# ); } } diff --git a/docx-core/src/documents/styles.rs b/docx-core/src/documents/styles.rs index dd79f32..f1e8cfe 100644 --- a/docx-core/src/documents/styles.rs +++ b/docx-core/src/documents/styles.rs @@ -49,12 +49,12 @@ mod tests { use std::str; #[test] - fn test_build() { + fn test_style() { let c = Styles::new().add_style(Style::new("Title", "TitleName", StyleType::Paragraph)); let b = c.build(); assert_eq!( str::from_utf8(&b).unwrap(), - r#""# + r#""# ); } } diff --git a/docx-core/src/types/border_type.rs b/docx-core/src/types/border_type.rs new file mode 100644 index 0000000..40d9265 --- /dev/null +++ b/docx-core/src/types/border_type.rs @@ -0,0 +1,199 @@ +// +// Please see p3813 +// + +/* +"nil" +"none" +"single" +"thick" +"double" +"dotted" +"dashed" +"dotDash" +"dotDotDash" +"triple" +"thinThickSmallGap" +"thickThinSmallGap" +"thinThickThinSmallGap" +"thinThickMediumGap" +"thickThinMediumGap" +"thinThickThinMediumGap" +"thinThickLargeGap" +"thickThinLargeGap" +"thinThickThinLargeGap" +"wave" +"doubleWave" +"dashSmallGap" +"dashDotStroked" +"threeDEmboss" +"threeDEngrave" +"outset" +"inset" +"apples" +"archedScallops" +"babyPacifier" +"babyRattle" +"balloons3Colors" +"balloonsHotAir" +"basicBlackDashes" +"basicBlackDots" +"basicBlackSquares" +"basicThinLines" +"basicWhiteDashes" +"basicWhiteDots" +"basicWhiteSquares" +"basicWideInline" +"basicWideMidline" +"basicWideOutline" +"bats" +"birds" +"birdsFlight" +"cabins" +"cakeSlice" +"candyCorn" +"celticKnotwork" +"certificateBanner" +"chainLink" +"champagneBottle" +"checkedBarBlack" +"checkedBarColor" +"checkered" +"christmasTree" +"circlesLines" +"circlesRectangles" +"classicalWave" +"clocks" +"compass" +"confetti" +"confettiGrays" +"confettiOutline" +"confettiStreamers" +"confettiWhite" +"cornerTriangles" +"couponCutoutDashes" +"couponCutoutDots" +"crazyMaze" +"creaturesButterfly" +"creaturesFish" +"creaturesInsects" +"creaturesLadyBug" +"crossStitch" +"cup" +"decoArch" +"decoArchColor" +"decoBlocks" +"diamondsGray" +"doubleD" +"doubleDiamonds" +"earth1" +"earth2" +"earth3" +"eclipsingSquares1" +"eclipsingSquares2" +"eggsBlack" +"fans" +"film" +"firecrackers" +"flowersBlockPrint" +"flowersDaisies" +"flowersModern1" +"flowersModern2" +"flowersPansy" +"flowersRedRose" +"flowersRoses" +"flowersTeacup" +"flowersTiny" +"gems" +"gingerbreadMan" +"gradient" +"handmade1" +"handmade2" +"heartBalloon" +"heartGray" +"hearts" +"heebieJeebies" +"holly" +"houseFunky" +"hypnotic" +"iceCreamCones" +"lightBulb" +"lightning1" +"lightning2" +"mapPins" +"mapleLeaf" +"mapleMuffins" +"marquee" +"marqueeToothed" +"moons" +"mosaic" +"musicNotes" +"northwest" +"ovals" +"packages" +"palmsBlack" +"palmsColor" +"paperClips" +"papyrus" +"partyFavor" +"partyGlass" +"pencils" +"people" +"peopleWaving" +"peopleHats" +"poinsettias" +"postageStamp" +"pumpkin1" +"pushPinNote2" +"pushPinNote1" +"pyramids" +"pyramidsAbove" +"quadrants" +"rings" +"safari" +"sawtooth" +"sawtoothGray" +"scaredCat" +"seattle" +"shadowedSquares" +"sharksTeeth" +"shorebirdTracks" +"skyrocket" +"snowflakeFancy" +"snowflakes" +"sombrero" +"southwest" +"stars" +"starsTop" +"stars3d" +"starsBlack" +"starsShadowed" +"sun" +"swirligig" +"tornPaper" +"tornPaperBlack" +"trees" +"triangleParty" +"triangles" +"triangle1" +"triangle2" +"triangleCircle1" +"triangleCircle2" +"shapes1" +"shapes2" +"twistedLines1" +"twistedLines2" +"vine" +"waveline" +"weavingAngles" +"weavingBraid" +"weavingRibbon" +"weavingStrips" +"whiteFlowers" +"woodwork" +"xIllusions" +"zanyTriangles" +"zigZag" +"zigZagStitch" +"custom" +*/ diff --git a/docx-core/src/types/mod.rs b/docx-core/src/types/mod.rs index 243f6c6..5798544 100644 --- a/docx-core/src/types/mod.rs +++ b/docx-core/src/types/mod.rs @@ -1,7 +1,9 @@ pub mod alignment_type; pub mod special_indent_type; pub mod style_type; +pub mod width_type; pub use alignment_type::*; pub use special_indent_type::*; pub use style_type::*; +pub use width_type::*; diff --git a/docx-core/src/types/width_type.rs b/docx-core/src/types/width_type.rs new file mode 100644 index 0000000..f51bcfc --- /dev/null +++ b/docx-core/src/types/width_type.rs @@ -0,0 +1,16 @@ +use std::fmt; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +#[derive(Copy, Clone, Debug)] +pub enum WidthType { + DXA, +} + +impl fmt::Display for WidthType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + WidthType::DXA => write!(f, "dxa"), + } + } +} diff --git a/docx-core/src/xml_builder/elements.rs b/docx-core/src/xml_builder/elements.rs index 34bb5e9..db10969 100644 --- a/docx-core/src/xml_builder/elements.rs +++ b/docx-core/src/xml_builder/elements.rs @@ -87,6 +87,29 @@ impl XMLBuilder { }; self.close() } + + // + // Table elements + // + opened_el!(open_table, "w:tbl"); + opened_el!(open_table_property, "w:tblPr"); + opened_el!(open_table_grid, "w:tblGrid"); + opened_el!(open_table_row, "w:tr"); + opened_el!(open_table_row_property, "w:trPr"); + opened_el!(open_table_cell, "w:tc"); + opened_el!(open_table_cell_property, "w:tcPr"); + opened_el!(open_table_borders, "w:tblBorders"); + opened_el!(open_table_cell_margins, "w:tblCellMar"); + + closed_w_with_type_el!(table_width, "w:tblW"); + closed_w_with_type_el!(table_indent, "w:tblInd"); + closed_w_with_type_el!(grid_column, "w:gridCol"); + closed_w_with_type_el!(table_cell_width, "w:tcW"); + + // TODO: + // w:shd + // w:top/left/bottom/right + // w:insideH/insideV } #[cfg(test)] diff --git a/docx-core/src/xml_builder/macros.rs b/docx-core/src/xml_builder/macros.rs index ad3981d..daf211f 100644 --- a/docx-core/src/xml_builder/macros.rs +++ b/docx-core/src/xml_builder/macros.rs @@ -152,3 +152,33 @@ macro_rules! only_usize_val_el { } }; } + +macro_rules! closed_w_with_type_el { + ($name: ident, $el_name: expr) => { + pub(crate) fn $name(mut self, w: usize, t: WidthType) -> Self { + self.writer + .write( + XmlEvent::start_element($el_name) + .attr("w:w", &format!("{}", w)) + .attr("w:type", &t.to_string()), + ) + .expect(EXPECT_MESSAGE); + self.close() + } + }; +} + +macro_rules! closed_border_el { + ($name: ident, $el_name: expr) => { + pub(crate) fn $name(mut self, size: usize, space: usize, color: &str) -> Self { + self.writer + .write( + XmlEvent::start_element($el_name) + .attr("w:w", &format!("{}", w)) + .attr("w:type", &t.to_string()), + ) + .expect(EXPECT_MESSAGE); + self.close() + } + }; +} diff --git a/docx-core/tests/lib.rs b/docx-core/tests/lib.rs new file mode 100644 index 0000000..f705007 --- /dev/null +++ b/docx-core/tests/lib.rs @@ -0,0 +1,60 @@ +extern crate docx_core; + +use docx_core::*; + +pub const DUMMY: &str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."; + +#[test] +pub fn indent() -> Result<(), DocxError> { + let path = std::path::Path::new("./tests/output/indent.docx"); + let file = std::fs::File::create(&path).unwrap(); + Docx::new() + .add_paragraph(Paragraph::new().add_run(Run::new(DUMMY)).indent(840, None)) + .add_paragraph(Paragraph::new()) + .add_paragraph( + Paragraph::new() + .add_run(Run::new(DUMMY)) + .indent(840, Some(SpecialIndentType::FirstLine(720))), + ) + .add_paragraph(Paragraph::new()) + .add_paragraph( + Paragraph::new() + .add_run(Run::new(DUMMY)) + .indent(1560, Some(SpecialIndentType::Hanging(720))), + ) + .build() + .pack(file)?; + Ok(()) +} + +#[test] +pub fn size() -> Result<(), DocxError> { + let path = std::path::Path::new("./tests/output/size.docx"); + let file = std::fs::File::create(&path).unwrap(); + Docx::new() + .add_paragraph(Paragraph::new().add_run(Run::new("Hello")).size(60)) + .add_paragraph( + Paragraph::new() + .add_run(Run::new(" Wor").size(50)) + .add_run(Run::new("ld")), + ) + .build() + .pack(file)?; + Ok(()) +} + +#[test] +pub fn alignment() -> Result<(), DocxError> { + let path = std::path::Path::new("./tests/output/alignment.docx"); + let file = std::fs::File::create(&path).unwrap(); + Docx::new() + .add_paragraph(Paragraph::new().add_run(Run::new("Hello"))) + .add_paragraph( + Paragraph::new() + .add_run(Run::new(" World")) + .align(AlignmentType::Right), + ) + .build() + .pack(file)?; + Ok(()) +} diff --git a/docx-core/tests/output/.keep b/docx-core/tests/output/.keep new file mode 100644 index 0000000..e69de29 diff --git a/makefile b/makefile new file mode 100644 index 0000000..b48caa3 --- /dev/null +++ b/makefile @@ -0,0 +1,8 @@ +test: + cargo test + +vrt: + node vrt/index.js && reg-cli vrt/screenshot/actual vrt/screenshot/expected vrt/screenshot/diff -R vrt/report.html + +vrt-update: + node vrt/index.js && reg-cli vrt/screenshot/actual vrt/screenshot/expected vrt/screenshot/diff -R vrt/report.html -U \ No newline at end of file diff --git a/vrt/index.js b/vrt/index.js new file mode 100644 index 0000000..1d4a562 --- /dev/null +++ b/vrt/index.js @@ -0,0 +1,13 @@ +const glob = require("glob"); +const path = require("path"); +const createPDF = require("./pdf"); + +glob( + path.join(__dirname, "..", "./docx-core/tests/output/**/*.docx"), + {}, + async (err, files) => { + for await (file of files) { + await createPDF(file, path.join(__dirname, "./screenshot/actual")); + } + } +); diff --git a/vrt/package.json b/vrt/package.json new file mode 100644 index 0000000..7120501 --- /dev/null +++ b/vrt/package.json @@ -0,0 +1,14 @@ +{ + "name": "docx-rs", + "version": "1.0.0", + "main": "index.js", + "repository": "https://github.com/bokuweb/docx-rs.git", + "author": "bokuweb ", + "license": "MIT", + "devDependencies": { + "libreoffice-convert": "^1.0.3" + }, + "dependencies": { + "glob": "^7.1.6" + } +} diff --git a/vrt/pdf.js b/vrt/pdf.js new file mode 100644 index 0000000..ba5e597 --- /dev/null +++ b/vrt/pdf.js @@ -0,0 +1,25 @@ +const libre = require("libreoffice-convert"); +const path = require("path"); +const fs = require("fs"); + +const extend = "png"; + +module.exports = (docxPath, outputDir) => + new Promise((resolve, reject) => { + const filename = path.basename(docxPath, ".docx"); + const docxFile = fs.readFileSync(docxPath); + libre.convert(docxFile, extend, undefined, async (err, done) => { + if (err) { + reject(err); + } + try { + fs.mkdirSync(outputDir, { recursive: true }); + } catch (e) { + if (e.code !== "EEXIST") { + reject(e); + } + } + fs.writeFileSync(path.join(outputDir, `${filename}.${extend}`), done); + resolve(); + }); + }); diff --git a/vrt/screenshot/expected/alignment.png b/vrt/screenshot/expected/alignment.png new file mode 100644 index 0000000000000000000000000000000000000000..3022f9ba11e12e1b4fd502ed0d63726ddd90a013 GIT binary patch literal 7555 zcmeI1Yfw{X9>$Nx8Woi~y57P?$0@EiKu~T0&nj-w1)*vc6@;`A&;`P#SO^dj7Z<5Q zh?iQ3A<0&%(INyIE{0oxVxn9^Eh+?oXrhTBKsW>>mqW5IPIqSa!+zUOoqRcS=FB7fiSvz}^2W;Kx;zmf+i^_xImhv-Q-~6}RIk2kIB?K8)hG0+FxU8$N!wLXKk_5;Yp6%LVW3Ltf_KTDdWyWd=t!EF4u@x_kY9ow z8L$;$>YOo93;p7M%HxCpKmL$dLbsX>Jsq_}X)noxWGN%mqv?E-u-gYmW!&5rS;(`Y z8Wk8A*DzkM^P7HlR4USN@wEegEwd?ou@E8EjZo{^1KZGm)RbnE`Z|(aH{`P%MkmN! zJEdK%NS$~#88u2_7eTXm9FR1GGPoJGSr(Lfu7Y2GbSUsvHORVtp&? zHqf$9?ge>HBRbhh%yUjVp-<#l1~sc~*)o4kK?+rcQ{82gPL;d_l_b|fT>J$cqo6?> zB9!6vjpX(fAq9zorZks`y;B2;0!F8YnA&V@$aaJvipTtThskS9>Y2ezUAe9+V%sK< z#)&pmFSgC#=HjxvpD35 zISlq?2O7G(L)B{}4m{v+Txd&Wd-ZzZ%y3o@_6Rpa&0?QtFlkezMAPJ3)pt>(b(^^q zr4rp`oyda&-w&lL97lBXp~~D9o)3rv?xxD0m*W)X7j*%X?AO|*>FDgK%01hl9!>jb>IFfNy$N^l3TGos=lsQ+`Y5Ib|*8#v<0 z2E{CiBf>2ABMfF}IQq<{GN6ruZ;JK$|XOqar?!W~RLRK2I$id7){=x;n)g z+tx@nF$2B!7+5_?lbQ(|4>*NzamW70K{JEig}^9}Oy>ff#dJXN!09LMLR4JflBE28~* zhi3YT%x>&yUgpSs!`{BA8Q#N$ z;!+yP=qoI|c1~B)FY=syNDX7Prdvtt=5{As+>&B#0&#AF(s@`XPk|(?%&T{#t4NH# z%?SLct8Hs{Tei1`lRoUH{AQD+rY{E1bOfn_{M*vQ3kV<^iZu#~ib3u@z)c#7-O0Y8~ed|F(@`<|gIxZ$|BcTws8cj7@2zQ;OZoTN7 zfUA1L@r=lrjJTL<{+3Z;QMB&AjozJ_HCEHtAn62w5*V9s<@@wo<~_(B+t#fg;3S(*_Am1t^bF~6$r`O%yDHZFYmu65)B`CX?@F06co}

|_-cZy`H zTubcTV{EOPEs7+HE1@Va=j(Zr-qoGG$2)OKqN}AJT`2@@+N>64uw&5qL7*_h`>x-VkUTS#?#eSi<4bNt>=B*$DBg>~HxO2*xkdeL z>S+j5ClJ$yy)rVnvcI!xiQp<FXf- zzHBmV=20in6TG<`K}a;qOGQPxb)-xX<7IvANcV$>&kbBI=$^B={k&u+U?*TFU?*TF zU?*TFU?*TFU?*TFU?*TFU?*TFU?*TFU?=eZCm<0+316mUhhMAbf}fbs!9R!Zuh>V( F`4>QpWS#&3 literal 0 HcmV?d00001 diff --git a/vrt/screenshot/expected/indent.png b/vrt/screenshot/expected/indent.png new file mode 100644 index 0000000000000000000000000000000000000000..ca69f6b22737b302e141fdb368cb1f42021747b1 GIT binary patch literal 25021 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 literal 0 HcmV?d00001 diff --git a/vrt/yarn.lock b/vrt/yarn.lock new file mode 100644 index 0000000..25d6e64 --- /dev/null +++ b/vrt/yarn.lock @@ -0,0 +1,109 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +async@^2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +glob@^7.1.3, glob@^7.1.6: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + 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" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +libreoffice-convert@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/libreoffice-convert/-/libreoffice-convert-1.0.3.tgz#ddcee6da4f271b6d161d9dfd8bf17db534e099a2" + integrity sha512-dr2cM5+pV0OGLxWYVEUKFdEBMe9cyaIiQ/OfnsI1aVYVSDDyaHA6dURRGzCSu0pAtIG3jUfvxqMSv8wWx6ttqQ== + dependencies: + async "^2.6.2" + temp "^0.9.0" + +lodash@^4.17.14: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" + integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +rimraf@~2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + +temp@^0.9.0: + version "0.9.1" + resolved "https://registry.yarnpkg.com/temp/-/temp-0.9.1.tgz#2d666114fafa26966cd4065996d7ceedd4dd4697" + integrity sha512-WMuOgiua1xb5R56lE0eH6ivpVmg/lq2OHm4+LtT/xtEtPQ+sz6N3bBM6WZ5FvO1lO4IKIOb43qnhoc4qxP5OeA== + dependencies: + rimraf "~2.6.2" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=