mirror of
https://github.com/danog/sass-site.git
synced 2024-11-27 04:24:50 +01:00
Learn sass page and first pass at code example helper
This commit is contained in:
parent
ab5560c47f
commit
28d14ddc2c
@ -6,6 +6,7 @@ const yaml = require('js-yaml');
|
||||
const markdown = require('markdown-it');
|
||||
const markdownDefList = require('markdown-it-deflist');
|
||||
const typogrify = require('typogr');
|
||||
const sass = require('sass');
|
||||
|
||||
/** @param {import('@11ty/eleventy').UserConfig} eleventyConfig */
|
||||
module.exports = (eleventyConfig) => {
|
||||
@ -63,6 +64,43 @@ module.exports = (eleventyConfig) => {
|
||||
page.url.startsWith('/documentation/js-api/'),
|
||||
);
|
||||
|
||||
eleventyConfig.addLiquidFilter(
|
||||
'codeExample',
|
||||
(contents, autogenCSS=true, syntax=null) => {
|
||||
//TODO when are values for syntax passed in?
|
||||
//TODO add tests
|
||||
const splitContents = contents.split('===');
|
||||
|
||||
const scssContents = splitContents[0];
|
||||
const sassContents = splitContents[1];
|
||||
const cssContents = splitContents[2];
|
||||
|
||||
const scssExamples = scssContents.split('---')
|
||||
const sassExamples = sassContents.split('---')
|
||||
|
||||
let cssExample;
|
||||
if(cssContents){
|
||||
cssExample = cssContents
|
||||
}
|
||||
else if(!cssContents && autogenCSS) {
|
||||
// TODO check first if you even have scss or sass to generate css from
|
||||
// TODO what if no scss but sass?
|
||||
cssExample = '';
|
||||
scssExamples.forEach((scssSnippet) => {
|
||||
const generatedCSS = sass.compileString(scssSnippet);
|
||||
cssExample += generatedCSS.css;
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
scss: scssExamples,
|
||||
css: cssExample,
|
||||
sass: sassExamples,
|
||||
splitLocation: '50.0%' //TODO dynamically determine
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
eleventyConfig.addPlugin(EleventyRenderPlugin);
|
||||
|
||||
// settings
|
||||
|
@ -69,7 +69,7 @@
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^2.8.3",
|
||||
"rollup": "^3.12.0",
|
||||
"sass": "^1.57.1",
|
||||
"sass": "^1.58.0",
|
||||
"semver-parser": "^4.0.1",
|
||||
"stylelint": "^14.16.1",
|
||||
"stylelint-config-prettier": "^9.0.4",
|
||||
|
45
source/_includes/code_example.liquid
Normal file
45
source/_includes/code_example.liquid
Normal file
@ -0,0 +1,45 @@
|
||||
{% assign first_tab_id = ui_id %}
|
||||
{% assign second_tab_id = first_tab_id | plus: 1 %}
|
||||
{% assign third_tab_id = second_tab_id | plus: 1 %}
|
||||
|
||||
<div class="code-example ui-tabs" style="--split-location: {{ code.splitLocation }}">
|
||||
<ul class="ui-tabs-nav ui-helper-reset ui-helper-clearfix" role="tablist">
|
||||
<li class="ui-tabs-tab ui-tab ui-tabs-active" aria-controls="example-{{ example_id | strip }}-scss" role="tab" aria-expanded="true" aria-selected="true">
|
||||
<a href="#example-{{ example_id | strip }}-scss" class="ui-tabs-anchor" role="presentation" tabindex="-1" id="ui-id-{{ first_tab_id | strip }}">SCSS</a>
|
||||
</li>
|
||||
<li class="ui-tabs-tab ui-tab" role="tab"
|
||||
aria-controls="example-{{ example_id | strip }}-sass"
|
||||
aria-selected="false" aria-expanded="false"
|
||||
tabindex="-1">
|
||||
<a href="#example-{{ example_id | strip }}-sass" class="ui-tabs-anchor" role="presentation" tabindex="-1" id="ui-id-{{ second_tab_id | strip }}">Sass</a>
|
||||
</li>
|
||||
<li class="ui-tabs-tab css-tab ui-tab" role="tab" tabindex="-1" aria-controls="example-{{ example_id | strip }}-css" aria-labelledby="ui-id-{{ third_tab_id | strip }}" aria-selected="false" aria-expanded="false">
|
||||
<a href="#example-{{ example_id | strip }}-css" class="ui-tabs-anchor" role="presentation" tabindex="-1" id="ui-id-{{ third_tab_id | strip }}">CSS</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div id="example-{{ example_id | strip }}-scss" class="ui-tabs-panel scss" aria-labelledby="ui-id-{{ first_tab_id | strip }}" role="tabpanel" aria-hidden="false" style="">
|
||||
{% for scss in code.scss %}
|
||||
<pre class="highlight scss">
|
||||
<code>
|
||||
{{ scss | strip }}
|
||||
</code>
|
||||
</pre>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div id="example-{{ example_id | strip }}-sass" class="ui-tabs-panel sass ui-tabs-panel-inactive ui-tabs-panel-previously-active" aria-labelledby="ui-id-{{ second_tab_id | strip }}" role="tabpanel" aria-hidden="true" style="">
|
||||
{% for sass in code.sass %}
|
||||
<pre class="highlight sass">
|
||||
<code>
|
||||
{{ sass | strip }}
|
||||
</code>
|
||||
</pre>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div id="example-{{ example_id | strip }}-css" class="ui-tabs-panel css ui-tabs-panel-inactive" aria-labelledby="ui-id-{{ third_tab_id | strip }}" role="tabpanel" aria-hidden="true" style="">
|
||||
<pre class="highlight css">
|
||||
<code>
|
||||
{{ code.css | strip }}
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
@ -43,6 +43,7 @@
|
||||
|
||||
gtag('config', 'UA-535380-14');
|
||||
</script>
|
||||
<script src="/assets/dist/js/sass.js"></script>
|
||||
</head>
|
||||
|
||||
<body data-layout="body">
|
||||
@ -130,7 +131,6 @@
|
||||
}
|
||||
}(document, 'script', 'twitter-wjs');
|
||||
</script>
|
||||
<script src="/assets/dist/js/sass.js"></script>
|
||||
<!-- Current page: {{ page.url }} -->
|
||||
</body>
|
||||
</html>
|
||||
|
4
source/assets/js/vendor/index.ts
vendored
4
source/assets/js/vendor/index.ts
vendored
@ -1,5 +1,7 @@
|
||||
import 'jquery';
|
||||
import 'jquery-ui';
|
||||
|
||||
import 'jquery-ui/ui/unique-id';
|
||||
import 'jquery-ui/ui/widgets/tabs';
|
||||
import './jquery-smooth-scroll.min';
|
||||
import './modernizr.custom.min';
|
||||
import './html5-boilerplate/plugins';
|
||||
|
3
source/code-snippets/_homepage-sass-watch.md
Normal file
3
source/code-snippets/_homepage-sass-watch.md
Normal file
@ -0,0 +1,3 @@
|
||||
```
|
||||
sass --watch app/sass:public/stylesheets
|
||||
```
|
447
source/guide.md
Normal file
447
source/guide.md
Normal file
@ -0,0 +1,447 @@
|
||||
---
|
||||
layout: has_no_sidebars
|
||||
title: Sass Basics
|
||||
introduction: >
|
||||
Before you can use Sass, you need to set it up on your project. If you want to
|
||||
just browse here, go ahead, but we recommend you go install Sass first. [Go
|
||||
here](/install) if you want to learn how to get everything set up.
|
||||
---
|
||||
|
||||
<!-- TODO anchor links <nav class="sl-c-list-navigation-wrapper">
|
||||
|
||||
[Preprocessing](#topic-1)
|
||||
[Variables](#topic-2)
|
||||
[Nesting](#topic-3)
|
||||
[Partials](#topic-4)
|
||||
[Modules](#topic-5)
|
||||
[Mixins](#topic-6)
|
||||
[Inheritance](#topic-7)
|
||||
[Operators](#topic-8)
|
||||
[Lists](#topic-9)
|
||||
|
||||
</nav> -->
|
||||
|
||||
## Preprocessing
|
||||
|
||||
CSS on its own can be fun, but stylesheets are getting larger, more
|
||||
complex, and harder to maintain. This is where a preprocessor can help.
|
||||
Sass has features that don't exist in CSS yet like nesting, mixins,
|
||||
inheritance, and other nifty goodies that help you write robust,
|
||||
maintainable CSS.
|
||||
|
||||
Once you start tinkering with Sass, it will take your preprocessed Sass
|
||||
file and save it as a normal CSS file that you can use in your website.
|
||||
|
||||
The most direct way to make this happen is in your terminal. Once Sass is
|
||||
installed, you can compile your Sass to CSS using the `sass` command.
|
||||
You'll need to tell Sass which file to build from, and where to output CSS
|
||||
to. For example, running `sass input.scss output.css` from your terminal
|
||||
would take a single Sass file, `input.scss`, and compile that file to
|
||||
`output.css`.
|
||||
|
||||
You can also watch individual files or directories with the `--watch`
|
||||
flag. The watch flag tells Sass to watch your source files for changes,
|
||||
and re-compile CSS each time you save your Sass. If you wanted to watch
|
||||
(instead of manually build) your `input.scss` file, you'd just add the
|
||||
watch flag to your command, like so:
|
||||
|
||||
```
|
||||
sass --watch input.scss output.css
|
||||
```
|
||||
|
||||
You can watch and output to directories by using folder paths as your
|
||||
input and output, and separating them with a colon. In this example:
|
||||
|
||||
{% renderFile 'source/code-snippets/_homepage-sass-watch.md' %}
|
||||
|
||||
Sass would watch all files in the `app/sass` folder for changes, and
|
||||
compile CSS to the `public/stylesheets` folder.
|
||||
|
||||
<div class="sl-c-callout sl-c-callout--fun-fact">
|
||||
|
||||
### 💡 Fun fact:
|
||||
|
||||
Sass has two syntaxes! The SCSS syntax (`.scss`) is used most commonly. It's
|
||||
a superset of CSS, which means all valid CSS is also valid SCSS. The
|
||||
indented syntax (`.sass`) is more unusual: it uses indentation rather than
|
||||
curly braces to nest statements, and newlines instead of semicolons to
|
||||
separate them. All our examples are available in both syntaxes.
|
||||
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
## Variables
|
||||
|
||||
Think of variables as a way to store information that you want to reuse
|
||||
throughout your stylesheet. You can store things like colors, font stacks,
|
||||
or any CSS value you think you'll want to reuse. Sass uses the `$` symbol
|
||||
to make something a variable. Here's an example:
|
||||
|
||||
{% assign code = "$font-stack: Helvetica, sans-serif;
|
||||
$primary-color: #333;
|
||||
|
||||
body {
|
||||
font: 100% $font-stack;
|
||||
color: $primary-color;
|
||||
}
|
||||
|
||||
===
|
||||
|
||||
$font-stack: Helvetica, sans-serif
|
||||
$primary-color: #333
|
||||
|
||||
body
|
||||
font: 100% $font-stack
|
||||
color: $primary-color" | codeExample: true, 'scss' -%}
|
||||
|
||||
{% assign example_id = 1 %}
|
||||
{% assign ui_id = 1 %}
|
||||
{% render 'code_example',
|
||||
code: code,
|
||||
example_id: example_id,
|
||||
ui_id: ui_id %}
|
||||
|
||||
When the Sass is processed, it takes the variables we define for the
|
||||
`$font-stack` and `$primary-color` and outputs normal CSS with our
|
||||
variable values placed in the CSS. This can be extremely powerful when
|
||||
working with brand colors and keeping them consistent throughout the site.
|
||||
|
||||
---
|
||||
|
||||
## Nesting
|
||||
|
||||
When writing HTML you've probably noticed that it has a clear nested and visual hierarchy. CSS, on the other hand, doesn't.
|
||||
|
||||
Sass will let you nest your CSS selectors in a way that follows the same
|
||||
visual hierarchy of your HTML. Be aware that overly nested rules will
|
||||
result in over-qualified CSS that could prove hard to maintain and is
|
||||
generally considered bad practice.
|
||||
|
||||
With that in mind, here's an example of some typical styles for a site's
|
||||
navigation:
|
||||
|
||||
{% capture example_id %}
|
||||
{{ example_id | plus: 1 }}
|
||||
{% endcapture %}
|
||||
{% capture ui_id %}
|
||||
{{ ui_id | plus: 3 }}
|
||||
{% endcapture %}
|
||||
|
||||
{% assign code =
|
||||
"nav {
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
li { display: inline-block; }
|
||||
|
||||
a {
|
||||
display: block;
|
||||
padding: 6px 12px;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
===
|
||||
nav
|
||||
ul
|
||||
margin: 0
|
||||
padding: 0
|
||||
list-style: none
|
||||
|
||||
li
|
||||
display: inline-block
|
||||
|
||||
a
|
||||
display: block
|
||||
padding: 6px 12px
|
||||
text-decoration: none" | codeExample: true, 'scss' %}
|
||||
|
||||
|
||||
{% render 'code_example',
|
||||
code: code,
|
||||
example_id: example_id,
|
||||
ui_id: ui_id %}
|
||||
|
||||
---
|
||||
|
||||
## Partials
|
||||
|
||||
You can create partial Sass files that contain little snippets of CSS that you can include in other Sass files.
|
||||
This is a great way to modularize your CSS and help keep things easier to maintain. A partial is a
|
||||
Sass file named with a leading underscore. You might name it something
|
||||
like `_partial.scss`. The underscore lets Sass know that the file is only
|
||||
a partial file and that it should not be generated into a CSS file. Sass
|
||||
partials are used with the `@use` rule.
|
||||
|
||||
---
|
||||
|
||||
## Modules
|
||||
|
||||
<!-- TODO compatibility snippet -->
|
||||
You don't have to write all your Sass in a single file. You can split it up however you want with the `@use` rule. This rule loads another Sass file as
|
||||
a *module*, which means you can refer to its variables, [mixins][], and [functions][] in your Sass file with a namespace based on the filename. Using a file will also include the CSS it generates in your compiled output!
|
||||
|
||||
[mixins]: #topic-6
|
||||
[functions]: documentation/at-rules/function
|
||||
|
||||
{% capture example_id %}
|
||||
{{ example_id | plus: 1 }}
|
||||
{% endcapture %}
|
||||
{% capture ui_id %}
|
||||
{{ ui_id | plus: 3 }}
|
||||
{% endcapture %}
|
||||
|
||||
{% assign code =
|
||||
"// _base.scss
|
||||
$font-stack: Helvetica, sans-serif;
|
||||
$primary-color: #333;
|
||||
|
||||
body {
|
||||
font: 100% $font-stack;
|
||||
color: $primary-color;
|
||||
}
|
||||
---
|
||||
// styles.scss
|
||||
@use 'base';
|
||||
|
||||
.inverse {
|
||||
background-color: base.$primary-color;
|
||||
color: white;
|
||||
}
|
||||
===
|
||||
// _base.sass
|
||||
$font-stack: Helvetica, sans-serif
|
||||
$primary-color: #333
|
||||
|
||||
body
|
||||
font: 100% $font-stack
|
||||
color: $primary-color
|
||||
---
|
||||
// styles.sass
|
||||
@use 'base'
|
||||
|
||||
.inverse
|
||||
background-color: base.$primary-color
|
||||
color: white
|
||||
===
|
||||
body {
|
||||
font: 100% Helvetica, sans-serif;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.inverse {
|
||||
background-color: #333;
|
||||
color: white;
|
||||
}"
|
||||
| codeExample: true, 'scss' %}
|
||||
|
||||
|
||||
{% render 'code_example',
|
||||
code: code,
|
||||
example_id: example_id,
|
||||
ui_id: ui_id %}
|
||||
|
||||
---
|
||||
|
||||
## Mixins
|
||||
|
||||
Some things in CSS are a bit tedious to write, especially with CSS3 and the many vendor prefixes that exist. A mixin lets you make groups of CSS declarations that you want to reuse throughout your site. It helps keep your
|
||||
Sass very DRY. You can even pass in values to make your mixin more flexible. Here's an example for `theme`.
|
||||
|
||||
{% capture example_id %}
|
||||
{{ example_id | plus: 1 }}
|
||||
{% endcapture %}
|
||||
{% capture ui_id %}
|
||||
{{ ui_id | plus: 3 }}
|
||||
{% endcapture %}
|
||||
|
||||
{% assign code =
|
||||
"@mixin theme($theme: DarkGray) {
|
||||
background: $theme;
|
||||
box-shadow: 0 0 1px rgba($theme, .25);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.info {
|
||||
@include theme;
|
||||
}
|
||||
.alert {
|
||||
@include theme($theme: DarkRed);
|
||||
}
|
||||
.success {
|
||||
@include theme($theme: DarkGreen);
|
||||
}
|
||||
===
|
||||
@mixin theme($theme: DarkGray)
|
||||
background: $theme
|
||||
box-shadow: 0 0 1px rgba($theme, .25)
|
||||
color: #fff
|
||||
|
||||
|
||||
.info
|
||||
@include theme
|
||||
|
||||
.alert
|
||||
@include theme($theme: DarkRed)
|
||||
|
||||
.success
|
||||
@include theme($theme: DarkGreen)"
|
||||
| codeExample: true, 'scss' %}
|
||||
|
||||
{% render 'code_example',
|
||||
code: code,
|
||||
example_id: example_id,
|
||||
ui_id: ui_id %}
|
||||
|
||||
To create a mixin you use the `@mixin` directive and give it a name. We've named our mixin `theme`. We're also using the variable `$theme` inside the parentheses so we can pass in a `theme` of whatever we want.
|
||||
After you create your mixin, you can then use it as a CSS declaration starting with `@include` followed by the name of the mixin.
|
||||
|
||||
---
|
||||
|
||||
## Extend/Inheritance
|
||||
|
||||
Using `@extend` lets you share a set of CSS properties from one selector to another. In our example we're going to create a simple series of messaging for errors, warnings and successes using another feature which goes hand in hand with extend, placeholder classes. A placeholder class is a special type of class that only prints when it is extended, and can help keep your compiled CSS neat and clean.
|
||||
|
||||
{% capture example_id %}
|
||||
{{ example_id | plus: 1 }}
|
||||
{% endcapture %}
|
||||
{% capture ui_id %}
|
||||
{{ ui_id | plus: 3 }}
|
||||
{% endcapture %}
|
||||
|
||||
{% assign code =
|
||||
"// This CSS will print because %message-shared is extended.
|
||||
%message-shared {
|
||||
border: 1px solid #ccc;
|
||||
padding: 10px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
// This CSS won't print because %equal-heights is never extended.
|
||||
%equal-heights {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.message {
|
||||
@extend %message-shared;
|
||||
}
|
||||
|
||||
.success {
|
||||
@extend %message-shared;
|
||||
border-color: green;
|
||||
}
|
||||
|
||||
.error {
|
||||
@extend %message-shared;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
.warning {
|
||||
@extend %message-shared;
|
||||
border-color: yellow;
|
||||
}
|
||||
===
|
||||
// This CSS will print because %message-shared is extended.
|
||||
%message-shared
|
||||
border: 1px solid #ccc
|
||||
padding: 10px
|
||||
color: #333
|
||||
|
||||
|
||||
// This CSS won't print because %equal-heights is never extended.
|
||||
%equal-heights
|
||||
display: flex
|
||||
flex-wrap: wrap
|
||||
|
||||
|
||||
.message
|
||||
@extend %message-shared
|
||||
|
||||
|
||||
.success
|
||||
@extend %message-shared
|
||||
border-color: green
|
||||
|
||||
|
||||
.error
|
||||
@extend %message-shared
|
||||
border-color: red
|
||||
|
||||
|
||||
.warning
|
||||
@extend %message-shared
|
||||
border-color: yellow"| codeExample: true, 'scss' %}
|
||||
|
||||
{% render 'code_example',
|
||||
code: code,
|
||||
example_id: example_id,
|
||||
ui_id: ui_id %}
|
||||
|
||||
What the above code does is tells `.message`, `.success`, `.error`, and `.warning` to behave just like `%message-shared`. That means anywhere that `%message-shared` shows up, `.message`, `.success`, `.error`, & `.warning` will too. The magic happens in the generated CSS, where each of these classes will get the same CSS properties as `%message-shared`. This helps you avoid having to write multiple class names on HTML elements.
|
||||
|
||||
You can extend most simple CSS selectors in addition to placeholder classes in Sass, but using placeholders is the easiest way to make sure you aren't extending a class that's nested elsewhere in your styles, which can result in unintended selectors in your CSS.
|
||||
|
||||
Note that the CSS in `%equal-heights` isn't generated, because `%equal-heights` is never extended.
|
||||
|
||||
---
|
||||
|
||||
## Operators
|
||||
|
||||
Doing math in your CSS is very helpful. Sass has a handful of standard math operators like `+`, `-`, `*`, `math.div()`, and `%`. In our example we're going to do some simple math to calculate widths for an `article` and `aside`.
|
||||
|
||||
{% capture example_id %}
|
||||
{{ example_id | plus: 1 }}
|
||||
{% endcapture %}
|
||||
{% capture ui_id %}
|
||||
{{ ui_id | plus: 3 }}
|
||||
{% endcapture %}
|
||||
|
||||
{% assign code =
|
||||
'@use "sass:math";
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
article[role="main"] {
|
||||
width: math.div(600px, 960px) * 100%;
|
||||
}
|
||||
|
||||
aside[role="complementary"] {
|
||||
width: math.div(300px, 960px) * 100%;
|
||||
margin-left: auto;
|
||||
}
|
||||
===
|
||||
@use "sass:math"
|
||||
|
||||
.container
|
||||
display: flex
|
||||
|
||||
article[role="main"]
|
||||
width: math.div(600px, 960px) * 100%
|
||||
|
||||
aside[role="complementary"]
|
||||
width: math.div(300px, 960px) * 100%
|
||||
margin-left: auto
|
||||
===
|
||||
.container {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
article[role="main"] {
|
||||
width: 62.5%;
|
||||
}
|
||||
|
||||
aside[role="complementary"] {
|
||||
width: 31.25%;
|
||||
margin-left: auto;
|
||||
}'| codeExample: true, 'scss' %}
|
||||
|
||||
{% render 'code_example',
|
||||
code: code,
|
||||
example_id: example_id,
|
||||
ui_id: ui_id %}
|
10
yarn.lock
10
yarn.lock
@ -6277,7 +6277,7 @@ __metadata:
|
||||
npm-run-all: ^4.1.5
|
||||
prettier: ^2.8.3
|
||||
rollup: ^3.12.0
|
||||
sass: ^1.57.1
|
||||
sass: ^1.58.0
|
||||
semver-parser: ^4.0.1
|
||||
stylelint: ^14.16.1
|
||||
stylelint-config-prettier: ^9.0.4
|
||||
@ -6288,16 +6288,16 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"sass@npm:^1.57.1":
|
||||
version: 1.57.1
|
||||
resolution: "sass@npm:1.57.1"
|
||||
"sass@npm:^1.58.0":
|
||||
version: 1.58.0
|
||||
resolution: "sass@npm:1.58.0"
|
||||
dependencies:
|
||||
chokidar: ">=3.0.0 <4.0.0"
|
||||
immutable: ^4.0.0
|
||||
source-map-js: ">=0.6.2 <2.0.0"
|
||||
bin:
|
||||
sass: sass.js
|
||||
checksum: 734a08781bcbe0e8defb2d54864e7012014ed3e68ba5fcb766189b002929019fc37b2f83a18d4be0b5f69ad77317c92396ce6112447ab47a194ed600ae1afb27
|
||||
checksum: a7219634881d2de6441fb619787fb1a02e3fa0333fb715be26aa335ba49d6bdb4f1105d9df70a80a67200893022b08346745783dc49046095d94fc6e044492d6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user