update --css
This commit is contained in:
parent
74e84b1ab4
commit
77e4ecb2fb
122
cli.js
122
cli.js
|
@ -1,24 +1,24 @@
|
||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
import { readFileSync } from "fs";
|
import { readFileSync, existsSync } from "fs";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import fs from "vinyl-fs";
|
import fs from "vinyl-fs";
|
||||||
import map from "map-stream";
|
import map from "map-stream";
|
||||||
import yargs from "yargs";
|
import yargs from "yargs";
|
||||||
import CleanCSS from "clean-css";
|
import * as CSS from "./css.js";
|
||||||
import toHTML, { BASE_CSS, html } from "./html.js";
|
import toHTML, { html } from "./html.js";
|
||||||
|
|
||||||
const cli = yargs(process.argv.slice(2))
|
const cli = yargs(process.argv.slice(2))
|
||||||
.config("config", function (path) {
|
.config("config", function (path) {
|
||||||
return JSON.parse(readFileSync(path));
|
return JSON.parse(readFileSync(path), "utf-8");
|
||||||
})
|
})
|
||||||
.scriptName("gmi-web")
|
.scriptName("gmi-web")
|
||||||
.command("$0 [files..]", "Convert text/gemini to text/html.", (yargs) =>
|
.command("$0 [files..]", "Convert text/gemini to text/html.", (yargs) =>
|
||||||
yargs
|
yargs
|
||||||
|
.example("$0 --body < ~/my-capsule/index.gmi")
|
||||||
.example("$0 --html en $(find ~/my-capsule -name '*.gmi')")
|
.example("$0 --html en $(find ~/my-capsule -name '*.gmi')")
|
||||||
.example(
|
.example(
|
||||||
"$0 --foreground '#000000' --background '#EEEEEE' --html en < doc.gmi"
|
"$0 --foreground '#000000' --background '#EEEEEE' --html en < doc.gmi"
|
||||||
)
|
)
|
||||||
.example("$0 --body < ~/my-capsule/index.gmi")
|
|
||||||
.example("$0 --image jpg --audio mp3 --image png --body < doc.gmi")
|
.example("$0 --image jpg --audio mp3 --image png --body < doc.gmi")
|
||||||
.epilog("See the gmi-web(1) man page for more information")
|
.epilog("See the gmi-web(1) man page for more information")
|
||||||
)
|
)
|
||||||
|
@ -44,8 +44,7 @@ const cli = yargs(process.argv.slice(2))
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
},
|
},
|
||||||
css: {
|
css: {
|
||||||
choices: ["gmi.css", "base", "none"],
|
default: "full",
|
||||||
default: "gmi.css",
|
|
||||||
requiresArg: true,
|
requiresArg: true,
|
||||||
},
|
},
|
||||||
charset: {
|
charset: {
|
||||||
|
@ -54,99 +53,70 @@ const cli = yargs(process.argv.slice(2))
|
||||||
default: "utf-8",
|
default: "utf-8",
|
||||||
requiresArg: true,
|
requiresArg: true,
|
||||||
},
|
},
|
||||||
|
image: {
|
||||||
|
type: "array",
|
||||||
|
requiresArg: true,
|
||||||
|
},
|
||||||
|
audio: {
|
||||||
|
type: "array",
|
||||||
|
requiresArg: true,
|
||||||
|
},
|
||||||
|
video: {
|
||||||
|
type: "array",
|
||||||
|
requiresArg: true,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
cli.options({
|
const CSS_VARS = CSS.rootVariables(CSS.FULL);
|
||||||
image: {
|
Object.keys(CSS_VARS).map((key) => {
|
||||||
type: "array",
|
cli.option(key, { default: CSS_VARS[key] });
|
||||||
requiresArg: true,
|
|
||||||
},
|
|
||||||
audio: {
|
|
||||||
type: "array",
|
|
||||||
requiresArg: true,
|
|
||||||
},
|
|
||||||
video: {
|
|
||||||
type: "array",
|
|
||||||
requiresArg: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO: automatically pull these in from gmi.css (also for gmi.css(5))
|
|
||||||
const GMI_CSS_VARS = [
|
|
||||||
"body-width",
|
|
||||||
"foreground",
|
|
||||||
"background",
|
|
||||||
"p-size",
|
|
||||||
"p-indent",
|
|
||||||
"p-line-height",
|
|
||||||
"a-size",
|
|
||||||
"pre-size",
|
|
||||||
"pre-line-height",
|
|
||||||
"h1-size",
|
|
||||||
"h2-size",
|
|
||||||
"h3-size",
|
|
||||||
"heading-line-height",
|
|
||||||
"ul-size",
|
|
||||||
"ul-line-height",
|
|
||||||
"blockquote-size",
|
|
||||||
"blockquote-line-height",
|
|
||||||
"mono",
|
|
||||||
"serif",
|
|
||||||
"sans-serif",
|
|
||||||
].map((key) => {
|
|
||||||
cli.option(key);
|
|
||||||
cli.conflicts(key, "body");
|
cli.conflicts(key, "body");
|
||||||
return key;
|
return key;
|
||||||
});
|
});
|
||||||
|
|
||||||
const argv = cli
|
const argv = cli
|
||||||
.conflicts("author", "body")
|
.conflicts("author", "body")
|
||||||
.conflicts("description", "body")
|
.conflicts("descriptions", "body")
|
||||||
.conflicts("html", "body")
|
.conflicts("html", "body")
|
||||||
.group(["html", "body"], "Core:")
|
.group(["html", "body"], "Core:")
|
||||||
.group(["author", "description", "css", "dir"], "HTML:")
|
.group(["author", "descriptions", "css", "dir"], "HTML:")
|
||||||
.group(["image", "audio", "video"], "Inline Media:")
|
.group(["image", "audio", "video"], "Inline Media:")
|
||||||
.group(GMI_CSS_VARS, "gmi.css:")
|
.group(Object.keys(CSS_VARS), "CSS:")
|
||||||
.alias("html", "language")
|
.alias("html", "language")
|
||||||
.alias("html", "lang")
|
.alias("html", "lang")
|
||||||
|
.coerce("css", (arg) => {
|
||||||
|
if (arg === "full") {
|
||||||
|
return CSS.stringify(CSS.FULL, { compress: true });
|
||||||
|
} else if (arg === "core") {
|
||||||
|
return CSS.stringify(CSS.CORE, { compress: true });
|
||||||
|
} else if (arg !== "none" && arg !== "") {
|
||||||
|
if (existsSync(path.resolve(arg))) {
|
||||||
|
return CSS.resolve(arg, { compress: true });
|
||||||
|
} else {
|
||||||
|
return CSS.parse(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
.showHelpOnFail(true)
|
.showHelpOnFail(true)
|
||||||
.help().argv;
|
.help().argv;
|
||||||
|
|
||||||
let styles = "";
|
if (!argv.html && !argv.body) {
|
||||||
if (argv.css === "gmi.css") {
|
|
||||||
styles = GMI_CSS_VARS.reduce((style, key) => {
|
|
||||||
if (argv[key]) {
|
|
||||||
style += `--${key}: ${argv[key]};`;
|
|
||||||
}
|
|
||||||
return style;
|
|
||||||
}, styles);
|
|
||||||
|
|
||||||
argv.css = new CleanCSS().minify(
|
|
||||||
readFileSync(
|
|
||||||
// TODO import.meta.resolve is supposed to accomplish this without "path"
|
|
||||||
path.resolve(
|
|
||||||
path.dirname(new URL(import.meta.url).pathname),
|
|
||||||
"./gmi.css"
|
|
||||||
),
|
|
||||||
"utf-8"
|
|
||||||
)
|
|
||||||
).styles;
|
|
||||||
} else if (argv.css === "base") {
|
|
||||||
argv.css = BASE_CSS;
|
|
||||||
} else {
|
|
||||||
argv.css = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!argv.lang && !argv.body) {
|
|
||||||
cli.showHelp();
|
cli.showHelp();
|
||||||
console.error(`\nMissing required argument: --html or --body`);
|
console.error(`\nMissing required argument: --html or --body`);
|
||||||
cli.exit(1);
|
cli.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let styles = Object.keys(CSS_VARS).reduce((style, key) => {
|
||||||
|
if (argv[key]) {
|
||||||
|
style += `--${key}: ${argv[key]};`;
|
||||||
|
}
|
||||||
|
return style;
|
||||||
|
}, "");
|
||||||
|
|
||||||
if (!argv.files) {
|
if (!argv.files) {
|
||||||
let gemtext;
|
let gemtext;
|
||||||
try {
|
try {
|
||||||
gemtext = readFileSync(process.stdin.fd);
|
gemtext = readFileSync(process.stdin.fd, "utf-8");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
cli.showHelp();
|
cli.showHelp();
|
||||||
console.error("\nMissing files: pipe from stdin or provide [files..]");
|
console.error("\nMissing files: pipe from stdin or provide [files..]");
|
||||||
|
|
48
css.js
Normal file
48
css.js
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
import { readFileSync } from "fs";
|
||||||
|
import path from "path";
|
||||||
|
import { stringify, parse } from "css";
|
||||||
|
export { stringify, parse };
|
||||||
|
|
||||||
|
// TODO import.meta.resolve is supposed to accomplish this without "path"
|
||||||
|
const GMI_CSS = path.resolve(
|
||||||
|
path.dirname(new URL(import.meta.url).pathname),
|
||||||
|
"./gmi.css"
|
||||||
|
);
|
||||||
|
|
||||||
|
export const CORE = parse(`p,
|
||||||
|
a,
|
||||||
|
pre,
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
ul,
|
||||||
|
blockquote,
|
||||||
|
img,
|
||||||
|
audio,
|
||||||
|
video {
|
||||||
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
max-width: 100%;
|
||||||
|
}`);
|
||||||
|
|
||||||
|
export const FULL = parse(readFileSync(GMI_CSS, "utf-8"));
|
||||||
|
|
||||||
|
export function rootVariables({ stylesheet }) {
|
||||||
|
return stylesheet.rules
|
||||||
|
.find(
|
||||||
|
({ type, selectors }) => type === "rule" && selectors.includes(":root")
|
||||||
|
)
|
||||||
|
.declarations.reduce(
|
||||||
|
(obj, { property, value }) =>
|
||||||
|
!/^\-\-/.test(property)
|
||||||
|
? obj
|
||||||
|
: Object.assign(obj, { [property.replace("--", "")]: value }),
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resolve(arg, options) {
|
||||||
|
return stringify(parse(readFileSync(path.resolve(arg), "utf-8")), options);
|
||||||
|
}
|
28
gmi-web.1
28
gmi-web.1
|
@ -48,16 +48,10 @@ be used.
|
||||||
Use \fB--author\fR \fINAME\fR to set the author <meta> tag on every file.
|
Use \fB--author\fR \fINAME\fR to set the author <meta> tag on every file.
|
||||||
.P
|
.P
|
||||||
.RE
|
.RE
|
||||||
\fB--css\fR \fIMODE\fR
|
\fB--css\fR [\fIMODE\fR|\fIFILE\fR|\fICSS\fR]
|
||||||
.RS 4
|
.RS 4
|
||||||
By default this will be set to \fBgmi.css\fR. Choosing \fBbase\fR will use just what
|
By default this will be set to \fBfull\fR enabling a handful of customizable
|
||||||
is needed to fix issues with CSS 2.1's Normal Flow. Choosing \fBnone\fR will not
|
variables to be set. See --help for the complete list.
|
||||||
include any style information and inline elements will be wrapped in <p>.
|
|
||||||
.P
|
|
||||||
.RE
|
|
||||||
\fBgmi.css\fR
|
|
||||||
.RS 4
|
|
||||||
See --help or gmi.css(5) for the complete list of customizable styles.
|
|
||||||
.P
|
.P
|
||||||
.RE
|
.RE
|
||||||
.nf
|
.nf
|
||||||
|
@ -68,7 +62,17 @@ gmi-web --html en \\
|
||||||
.fi
|
.fi
|
||||||
.RE
|
.RE
|
||||||
.P
|
.P
|
||||||
\fB[--image|--audio|--video]\fR \fIEXENSIONS\fR
|
.RS 4
|
||||||
|
Choosing \fBcore\fR will use just what is needed to fix vertical layout issues
|
||||||
|
with CSS 2.1's Normal Flow and inline elements.
|
||||||
|
.P
|
||||||
|
Pointing to a .css \fIFILE\fR or providing a valid \fICSS\fR string will use those
|
||||||
|
styles.
|
||||||
|
.P
|
||||||
|
Choosing \fBnone\fR will not include any style information.
|
||||||
|
.P
|
||||||
|
.RE
|
||||||
|
\fB[--image|--audio|--video]\fR \fIEXTENSIONS\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Include media extensions inline. You can provide multiple extensions per flag
|
Include media extensions inline. You can provide multiple extensions per flag
|
||||||
or multiple flags per extension.
|
or multiple flags per extension.
|
||||||
|
@ -89,10 +93,6 @@ All the options documented here and by \fB--help\fR may be captured in a .json
|
||||||
file and passed to \fB--config\fR instead of as flags on the command-line.
|
file and passed to \fB--config\fR instead of as flags on the command-line.
|
||||||
.P
|
.P
|
||||||
.RE
|
.RE
|
||||||
.SH SEE ALSO
|
|
||||||
.P
|
|
||||||
\fBgmi.css\fR(5)
|
|
||||||
.P
|
|
||||||
.SH AUTHORS
|
.SH AUTHORS
|
||||||
.P
|
.P
|
||||||
Maintained by Talon Poole <code@talon.computer>. Up-to-date sources can be
|
Maintained by Talon Poole <code@talon.computer>. Up-to-date sources can be
|
||||||
|
|
|
@ -20,10 +20,6 @@ mobile-friendly fashion!
|
||||||
*--body*
|
*--body*
|
||||||
Generate only the HTML for the lines of the Gemini document.
|
Generate only the HTML for the lines of the Gemini document.
|
||||||
|
|
||||||
```
|
|
||||||
gmi-web --body < doc.gmi
|
|
||||||
```
|
|
||||||
|
|
||||||
*--html* _LANG_
|
*--html* _LANG_
|
||||||
Generate a full HTML5 document with the provided _LANG_. *--dir* can be used
|
Generate a full HTML5 document with the provided _LANG_. *--dir* can be used
|
||||||
to adjust the document text direction from "ltr" to "rtl".
|
to adjust the document text direction from "ltr" to "rtl".
|
||||||
|
@ -35,13 +31,9 @@ gmi-web --body < doc.gmi
|
||||||
|
|
||||||
Use *--author* _NAME_ to set the author <meta> tag on every file.
|
Use *--author* _NAME_ to set the author <meta> tag on every file.
|
||||||
|
|
||||||
*--css* _MODE_
|
*--css* [_MODE_|_FILE_|_CSS_]
|
||||||
By default this will be set to *gmi.css*. Choosing *base* will use just what
|
By default this will be set to *full* enabling a handful of customizable
|
||||||
is needed to fix issues with CSS 2.1's Normal Flow. Choosing *none* will not
|
variables to be set. See --help for the complete list.
|
||||||
include any style information and inline elements will be wrapped in <p>.
|
|
||||||
|
|
||||||
*gmi.css*
|
|
||||||
See --help or gmi.css(5) for the complete list of customizable styles.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
gmi-web --html en \\
|
gmi-web --html en \\
|
||||||
|
@ -49,7 +41,15 @@ gmi-web --html en \\
|
||||||
--background "#9EEBCF" < doc.gmi
|
--background "#9EEBCF" < doc.gmi
|
||||||
```
|
```
|
||||||
|
|
||||||
*[--image|--audio|--video]* _EXENSIONS_
|
Choosing *core* will use just what is needed to fix vertical layout issues
|
||||||
|
with CSS 2.1's Normal Flow and inline elements.
|
||||||
|
|
||||||
|
Pointing to a .css _FILE_ or providing a valid _CSS_ string will use those
|
||||||
|
styles.
|
||||||
|
|
||||||
|
Choosing *none* will not include any style information.
|
||||||
|
|
||||||
|
*[--image|--audio|--video]* _EXTENSIONS_
|
||||||
Include media extensions inline. You can provide multiple extensions per flag
|
Include media extensions inline. You can provide multiple extensions per flag
|
||||||
or multiple flags per extension.
|
or multiple flags per extension.
|
||||||
|
|
||||||
|
@ -64,10 +64,6 @@ gmi-web --html en \\
|
||||||
All the options documented here and by *--help* may be captured in a .json
|
All the options documented here and by *--help* may be captured in a .json
|
||||||
file and passed to *--config* instead of as flags on the command-line.
|
file and passed to *--config* instead of as flags on the command-line.
|
||||||
|
|
||||||
# SEE ALSO
|
|
||||||
|
|
||||||
*gmi.css*(5)
|
|
||||||
|
|
||||||
# AUTHORS
|
# AUTHORS
|
||||||
|
|
||||||
Maintained by Talon Poole <code@talon.computer>. Up-to-date sources can be
|
Maintained by Talon Poole <code@talon.computer>. Up-to-date sources can be
|
||||||
|
|
17
html.js
17
html.js
|
@ -33,15 +33,14 @@ ${body(tokens, options)}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BASE_CSS =
|
|
||||||
"p,a,pre,h1,h2,h3,ul,blockquote,img,audio,video{display:block;max-width:100%;margin:0;padding:0;overflow-wrap:anywhere;}";
|
|
||||||
|
|
||||||
export function head(options) {
|
export function head(options) {
|
||||||
return `
|
return `
|
||||||
<meta charset="${options.charset}">
|
<meta charset="${options.charset}">
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
<meta name="viewport" content="width=device-width,initial-scale=1">${
|
||||||
${options.css !== "" ? `<meta name="color-scheme" content="dark light">` : ""}
|
options.css && options.css !== ""
|
||||||
${options.css !== "" ? `<style>${options.css}</style>` : ""}
|
? `<meta name="color-scheme" content="dark light">`
|
||||||
|
: ""
|
||||||
|
}${options.css && options.css !== "" ? `<style>${options.css}</style>` : ""}
|
||||||
<title>${options.title}</title>${
|
<title>${options.title}</title>${
|
||||||
!options.author ? "" : `<meta name="author" content="${options.author}">`
|
!options.author ? "" : `<meta name="author" content="${options.author}">`
|
||||||
}${
|
}${
|
||||||
|
@ -70,17 +69,11 @@ function line(
|
||||||
return `<img src="${href}"${titleProp}/>`;
|
return `<img src="${href}"${titleProp}/>`;
|
||||||
}
|
}
|
||||||
if (audio && matchesExt(href, audio)) {
|
if (audio && matchesExt(href, audio)) {
|
||||||
if (css === "") {
|
|
||||||
return `<p><audio controls src="${href}"${titleProp}></audio><p>`;
|
|
||||||
}
|
|
||||||
return `<audio controls src="${href}"${titleProp}></audio>`;
|
return `<audio controls src="${href}"${titleProp}></audio>`;
|
||||||
}
|
}
|
||||||
if (video && matchesExt(href, video))
|
if (video && matchesExt(href, video))
|
||||||
return `<video controls src="${href}"${titleProp}/></video>`;
|
return `<video controls src="${href}"${titleProp}/></video>`;
|
||||||
|
|
||||||
if (css === "") {
|
|
||||||
return `<p><a href="${href}">${title ? escape(title) : href}</a></p>`;
|
|
||||||
}
|
|
||||||
return `<a href="${href}">${title ? escape(title) : href}</a>`;
|
return `<a href="${href}">${title ? escape(title) : href}</a>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
29
package-lock.json
generated
29
package-lock.json
generated
|
@ -25,6 +25,11 @@
|
||||||
"buffer-equal": "^1.0.0"
|
"buffer-equal": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"atob": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
|
||||||
|
},
|
||||||
"balanced-match": {
|
"balanced-match": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||||
|
@ -127,6 +132,21 @@
|
||||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||||
},
|
},
|
||||||
|
"css": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==",
|
||||||
|
"requires": {
|
||||||
|
"inherits": "^2.0.4",
|
||||||
|
"source-map": "^0.6.1",
|
||||||
|
"source-map-resolve": "^0.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"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="
|
||||||
|
},
|
||||||
"define-properties": {
|
"define-properties": {
|
||||||
"version": "1.1.3",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
|
||||||
|
@ -549,6 +569,15 @@
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
|
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
|
||||||
},
|
},
|
||||||
|
"source-map-resolve": {
|
||||||
|
"version": "0.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz",
|
||||||
|
"integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==",
|
||||||
|
"requires": {
|
||||||
|
"atob": "^2.1.2",
|
||||||
|
"decode-uri-component": "^0.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"stream-shift": {
|
"stream-shift": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz",
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"clean-css": "^5.0.1",
|
"clean-css": "^5.0.1",
|
||||||
|
"css": "^3.0.0",
|
||||||
"escape-html": "^1.0.3",
|
"escape-html": "^1.0.3",
|
||||||
"map-stream": "0.0.7",
|
"map-stream": "0.0.7",
|
||||||
"vinyl-fs": "^3.0.3",
|
"vinyl-fs": "^3.0.3",
|
||||||
|
|
Loading…
Reference in a new issue