feat(dev): Generate OG images at build time
This commit is contained in:
parent
6030252518
commit
55e376647e
11 changed files with 401 additions and 59 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -111,6 +111,7 @@ sites/*/out
|
||||||
sites/*/public/mdx
|
sites/*/public/mdx
|
||||||
sites/*/prebuild
|
sites/*/prebuild
|
||||||
!sites/shared/prebuild
|
!sites/shared/prebuild
|
||||||
|
sites/dev/public/og
|
||||||
|
|
||||||
# misc
|
# misc
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
*.md
|
*.md
|
||||||
*.mustache
|
*.mustache
|
||||||
*.png
|
*.png
|
||||||
|
*.svg
|
||||||
yarn.lock
|
yarn.lock
|
||||||
.husky/pre-commit
|
.husky/pre-commit
|
||||||
.prettierignore
|
.prettierignore
|
||||||
|
|
|
@ -7,10 +7,22 @@
|
||||||
<stop stop-color="#262626" offset="0"/>
|
<stop stop-color="#262626" offset="0"/>
|
||||||
<stop stop-color="#262626" stop-opacity="0" offset="1"/>
|
<stop stop-color="#262626" stop-opacity="0" offset="1"/>
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
|
<linearGradient id="d" x1="0%" x2="160%" y1="0%" y2="75%" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#f87171" offset="0%"/>
|
||||||
|
<stop stop-color="#fb923c" offset="11%"/>
|
||||||
|
<stop stop-color="#facc15" offset="22%"/>
|
||||||
|
<stop stop-color="#a3e635" offset="33%"/>
|
||||||
|
<stop stop-color="#4ade80" offset="44%"/>
|
||||||
|
<stop stop-color="#22d3ee" offset="55%"/>
|
||||||
|
<stop stop-color="#60a5fa" offset="66%"/>
|
||||||
|
<stop stop-color="#818cf8" offset="77%"/>
|
||||||
|
<stop stop-color="#a78bfa" offset="88%"/>
|
||||||
|
<stop stop-color="#c084fc" offset="100%"/>
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
</defs>
|
</defs>
|
||||||
<style>
|
<style>
|
||||||
.mono { font-family: 'Ubuntu Mono'; }
|
text, tspan { font-family: 'Ubuntu Mono' }
|
||||||
.pacifico { font-family: Pacifico; font-size: 16px; }}
|
|
||||||
.tiny { font-size: 8px; }
|
.tiny { font-size: 8px; }
|
||||||
.mini { font-size: 9px; }
|
.mini { font-size: 9px; }
|
||||||
.small { font-size: 11px; }
|
.small { font-size: 11px; }
|
||||||
|
@ -30,11 +42,11 @@
|
||||||
<rect x="-5" y="-5" width="330" height="180" class="gray-800"/>
|
<rect x="-5" y="-5" width="330" height="180" class="gray-800"/>
|
||||||
</g>
|
</g>
|
||||||
<g transform="translate(0,-149.83637)">
|
<g transform="translate(0,-149.83637)">
|
||||||
<text class="mono gray-300 small italic">
|
<text class="gray-300 small italic">
|
||||||
<tspan x="15" y="273">intro_1</tspan>
|
<tspan x="15" y="273">intro_1</tspan>
|
||||||
<tspan x="15" y="285">intro_2</tspan>
|
<tspan x="15" y="285">intro_2</tspan>
|
||||||
</text>
|
</text>
|
||||||
<text class="mono gray-200 big bold">
|
<text class="gray-200 big bold">
|
||||||
<tspan x="15" y="230">1title_1</tspan>
|
<tspan x="15" y="230">1title_1</tspan>
|
||||||
<tspan x="15" y="215">2title_1</tspan>
|
<tspan x="15" y="215">2title_1</tspan>
|
||||||
<tspan x="15" y="239">2title_2</tspan>
|
<tspan x="15" y="239">2title_2</tspan>
|
||||||
|
@ -42,13 +54,22 @@
|
||||||
<tspan x="15" y="227">3title_2</tspan>
|
<tspan x="15" y="227">3title_2</tspan>
|
||||||
<tspan x="15" y="251">3title_3</tspan>
|
<tspan x="15" y="251">3title_3</tspan>
|
||||||
</text>
|
</text>
|
||||||
<text>
|
<text class="bold" x="15" y="173">
|
||||||
<tspan x="15" y="173" class="pacifico gray-500">FreeSewing</tspan>
|
<tspan dx="0" fill="#f87171">F</tspan>
|
||||||
|
<tspan dx="-7" fill="#fb923c">r</tspan>
|
||||||
|
<tspan dx="-7" fill="#facc15">e</tspan>
|
||||||
|
<tspan dx="-7" fill="#a3e635">e</tspan>
|
||||||
|
<tspan dx="-7" fill="#4ade80">S</tspan>
|
||||||
|
<tspan dx="-7" fill="#22d3ee">e</tspan>
|
||||||
|
<tspan dx="-7" fill="#60a5fa">w</tspan>
|
||||||
|
<tspan dx="-7" fill="#818cf8">i</tspan>
|
||||||
|
<tspan dx="-7" fill="#a78bfa">n</tspan>
|
||||||
|
<tspan dx="-7" fill="#c084fc">g</tspan>
|
||||||
</text>
|
</text>
|
||||||
<text class="gray1 mono mini gray-400">
|
<text class="gray1 mini gray-400">
|
||||||
<tspan x="15" y="305">sub_1sub_2</tspan>
|
<tspan x="15" y="305">sub_1sub_2</tspan>
|
||||||
</text>
|
</text>
|
||||||
<text class="gray1 mono tiny gray-400 bold">
|
<text class="gray1 gray-400 small">
|
||||||
<tspan x="113" y="173">lead_1</tspan>
|
<tspan x="113" y="173">lead_1</tspan>
|
||||||
</text>
|
</text>
|
||||||
</g>
|
</g>
|
||||||
|
@ -58,12 +79,7 @@
|
||||||
<path class="gray-300" d="m 275.12441,297.89232 c -1.76172,0.0243 -3.38909,0.72065 -4.59761,1.98566 -0.84215,0.88156 -1.39167,1.86474 -1.71411,3.06577 -0.1427,0.53073 -0.16298,0.72762 -0.16159,1.58141 0.002,0.85181 0.0227,1.05405 0.16829,1.60363 0.6355,2.39683 2.50583,4.23663 4.91669,4.83665 0.20753,0.0516 0.46213,0.1059 0.56588,0.12029 0.45929,0.0636 1.57081,0.0368 2.06569,-0.0495 2.03747,-0.35518 3.84722,-1.66952 4.77625,-3.46847 1.08425,-2.09884 0.94104,-4.76458 -0.36141,-6.72319 -1.10619,-1.66368 -2.89699,-2.73214 -4.8955,-2.92121 -0.25636,-0.0242 -0.51089,-0.0344 -0.76258,-0.031 z m 15.29524,0.0129 c -1.83068,0 -3.38051,0.63901 -4.64871,1.91648 -1.3014,1.32146 -1.9516,2.88517 -1.9516,4.69107 0,1.80588 0.6502,3.35892 1.9516,4.65852 1.30137,1.29933 2.85122,1.94954 4.64871,1.94954 1.81963,0 3.39678,-0.65512 4.73081,-1.96606 1.25714,-1.24429 1.88604,-2.79159 1.88604,-4.642 0,-1.85042 -0.63931,-3.41359 -1.91805,-4.69107 -1.27982,-1.27747 -2.84597,-1.91648 -4.6988,-1.91648 z m 15.34067,0.43936 a 6.6085787,6.6085787 0 0 0 -2.53243,12.77625 l 1.5458,-4.02763 a 2.2946513,2.2946513 0 1 1 1.6444,0 l 1.5458,4.02763 a 6.6085787,6.6085787 0 0 0 -2.20357,-12.77625 z m -15.32415,0.74966 c 1.49996,0 2.77357,0.52869 3.82111,1.58607 1.05858,1.04604 1.58811,2.32353 1.58811,3.83246 0,1.51969 -0.51861,2.78132 -1.55508,3.7834 -1.09231,1.0795 -2.37631,1.6191 -3.85414,1.6191 -1.47836,0 -2.75252,-0.53414 -3.82161,-1.60257 -1.07022,-1.06845 -1.60361,-2.33526 -1.60361,-3.79993 0,-1.46496 0.53942,-2.74219 1.62013,-3.83246 1.03646,-1.05739 2.30516,-1.58607 3.80509,-1.58607 z m -15.22194,0.008 c 0.87575,-0.002 1.36156,0.087 2.1256,0.3929 1.53377,0.61428 2.73611,2.00492 3.17832,3.67654 0.18496,0.69932 0.18206,2.04756 -0.006,2.74514 h -5.3e-4 c -0.53236,1.97276 -2.15218,3.47823 -4.19645,3.90008 -3.18718,0.65792 -6.29289,-1.75346 -6.49086,-5.04006 -0.12807,-2.12276 1.15704,-4.25275 3.13029,-5.18772 0.74718,-0.35407 1.34887,-0.48378 2.2593,-0.48688 z m 15.18115,1.14359 c -0.49811,0.0175 -0.89249,0.42633 -0.89216,0.92469 -3e-5,0.5107 0.41394,0.92466 0.92471,0.92469 0.51073,-3e-5 0.92471,-0.41399 0.92466,-0.92469 5e-5,-0.51068 -0.41393,-0.92467 -0.92466,-0.92469 -0.0108,-1.8e-4 -0.0217,-1.8e-4 -0.0325,0 z m -1.31965,2.20458 c -0.23506,0 -0.42644,0.1906 -0.42644,0.42647 v 2.70331 h 0.7548 v 3.20052 h 2.04816 v -3.20052 h 0.75378 v -2.70331 c 0,-0.23586 -0.1914,-0.42647 -0.42644,-0.42647 z m -11.75913,0.0263 c -0.31972,-0.007 -0.63903,0.0434 -0.87563,0.15075 -0.81562,0.37031 -1.23263,1.24043 -1.09094,2.27583 0.0977,0.71469 0.55214,1.32252 1.14669,1.53339 0.14243,0.0505 0.48819,0.0941 0.76823,0.0971 0.44804,0.005 0.55539,-0.0181 0.89632,-0.18844 0.33309,-0.16637 0.82814,-0.62807 0.82814,-0.77186 0,-0.022 -0.17236,-0.12712 -0.38311,-0.23336 l -0.38361,-0.19362 -0.19878,0.2282 c -0.44232,0.50754 -1.22169,0.35725 -1.43528,-0.27673 -0.10488,-0.31193 -0.0899,-0.99607 0.0279,-1.27525 0.13167,-0.31204 0.3756,-0.46105 0.75482,-0.46105 0.27548,0 0.32914,0.0242 0.53026,0.24369 l 0.22355,0.24421 0.43212,-0.2091 c 0.23778,-0.11492 0.43216,-0.22666 0.43216,-0.24834 0,-0.12757 -0.49613,-0.58333 -0.79304,-0.72849 -0.23984,-0.11743 -0.56004,-0.18031 -0.87976,-0.1869 z m -3.86757,0.003 c -0.31465,-0.002 -0.62483,0.0471 -0.84519,0.14714 -0.81324,0.36944 -1.21243,1.1924 -1.09145,2.2526 0.0813,0.71532 0.5437,1.3433 1.1467,1.55715 h 5.3e-4 c 0.14232,0.0503 0.48755,0.0935 0.76823,0.0966 0.44805,0.005 0.55549,-0.0181 0.8963,-0.18846 0.40105,-0.20034 0.89968,-0.70905 0.79096,-0.80696 -0.0314,-0.0283 -0.20233,-0.1311 -0.37947,-0.22871 l -0.32218,-0.17762 -0.24989,0.26332 c -0.24793,0.2608 -0.35374,0.29661 -0.77288,0.26434 -0.19934,-0.0153 -0.4106,-0.14975 -0.53643,-0.34179 -0.24256,-0.37018 -0.22501,-1.31046 0.0309,-1.67022 0.15482,-0.21742 0.49684,-0.34514 0.78269,-0.29119 0.11531,0.0215 0.30508,0.13677 0.42906,0.26073 l 0.222,0.22253 0.41666,-0.20549 c 0.22873,-0.11282 0.41613,-0.22336 0.41613,-0.24576 0,-0.13611 -0.54252,-0.62585 -0.83123,-0.75068 -0.23779,-0.10279 -0.55687,-0.15564 -0.87152,-0.15748 z" />
|
<path class="gray-300" d="m 275.12441,297.89232 c -1.76172,0.0243 -3.38909,0.72065 -4.59761,1.98566 -0.84215,0.88156 -1.39167,1.86474 -1.71411,3.06577 -0.1427,0.53073 -0.16298,0.72762 -0.16159,1.58141 0.002,0.85181 0.0227,1.05405 0.16829,1.60363 0.6355,2.39683 2.50583,4.23663 4.91669,4.83665 0.20753,0.0516 0.46213,0.1059 0.56588,0.12029 0.45929,0.0636 1.57081,0.0368 2.06569,-0.0495 2.03747,-0.35518 3.84722,-1.66952 4.77625,-3.46847 1.08425,-2.09884 0.94104,-4.76458 -0.36141,-6.72319 -1.10619,-1.66368 -2.89699,-2.73214 -4.8955,-2.92121 -0.25636,-0.0242 -0.51089,-0.0344 -0.76258,-0.031 z m 15.29524,0.0129 c -1.83068,0 -3.38051,0.63901 -4.64871,1.91648 -1.3014,1.32146 -1.9516,2.88517 -1.9516,4.69107 0,1.80588 0.6502,3.35892 1.9516,4.65852 1.30137,1.29933 2.85122,1.94954 4.64871,1.94954 1.81963,0 3.39678,-0.65512 4.73081,-1.96606 1.25714,-1.24429 1.88604,-2.79159 1.88604,-4.642 0,-1.85042 -0.63931,-3.41359 -1.91805,-4.69107 -1.27982,-1.27747 -2.84597,-1.91648 -4.6988,-1.91648 z m 15.34067,0.43936 a 6.6085787,6.6085787 0 0 0 -2.53243,12.77625 l 1.5458,-4.02763 a 2.2946513,2.2946513 0 1 1 1.6444,0 l 1.5458,4.02763 a 6.6085787,6.6085787 0 0 0 -2.20357,-12.77625 z m -15.32415,0.74966 c 1.49996,0 2.77357,0.52869 3.82111,1.58607 1.05858,1.04604 1.58811,2.32353 1.58811,3.83246 0,1.51969 -0.51861,2.78132 -1.55508,3.7834 -1.09231,1.0795 -2.37631,1.6191 -3.85414,1.6191 -1.47836,0 -2.75252,-0.53414 -3.82161,-1.60257 -1.07022,-1.06845 -1.60361,-2.33526 -1.60361,-3.79993 0,-1.46496 0.53942,-2.74219 1.62013,-3.83246 1.03646,-1.05739 2.30516,-1.58607 3.80509,-1.58607 z m -15.22194,0.008 c 0.87575,-0.002 1.36156,0.087 2.1256,0.3929 1.53377,0.61428 2.73611,2.00492 3.17832,3.67654 0.18496,0.69932 0.18206,2.04756 -0.006,2.74514 h -5.3e-4 c -0.53236,1.97276 -2.15218,3.47823 -4.19645,3.90008 -3.18718,0.65792 -6.29289,-1.75346 -6.49086,-5.04006 -0.12807,-2.12276 1.15704,-4.25275 3.13029,-5.18772 0.74718,-0.35407 1.34887,-0.48378 2.2593,-0.48688 z m 15.18115,1.14359 c -0.49811,0.0175 -0.89249,0.42633 -0.89216,0.92469 -3e-5,0.5107 0.41394,0.92466 0.92471,0.92469 0.51073,-3e-5 0.92471,-0.41399 0.92466,-0.92469 5e-5,-0.51068 -0.41393,-0.92467 -0.92466,-0.92469 -0.0108,-1.8e-4 -0.0217,-1.8e-4 -0.0325,0 z m -1.31965,2.20458 c -0.23506,0 -0.42644,0.1906 -0.42644,0.42647 v 2.70331 h 0.7548 v 3.20052 h 2.04816 v -3.20052 h 0.75378 v -2.70331 c 0,-0.23586 -0.1914,-0.42647 -0.42644,-0.42647 z m -11.75913,0.0263 c -0.31972,-0.007 -0.63903,0.0434 -0.87563,0.15075 -0.81562,0.37031 -1.23263,1.24043 -1.09094,2.27583 0.0977,0.71469 0.55214,1.32252 1.14669,1.53339 0.14243,0.0505 0.48819,0.0941 0.76823,0.0971 0.44804,0.005 0.55539,-0.0181 0.89632,-0.18844 0.33309,-0.16637 0.82814,-0.62807 0.82814,-0.77186 0,-0.022 -0.17236,-0.12712 -0.38311,-0.23336 l -0.38361,-0.19362 -0.19878,0.2282 c -0.44232,0.50754 -1.22169,0.35725 -1.43528,-0.27673 -0.10488,-0.31193 -0.0899,-0.99607 0.0279,-1.27525 0.13167,-0.31204 0.3756,-0.46105 0.75482,-0.46105 0.27548,0 0.32914,0.0242 0.53026,0.24369 l 0.22355,0.24421 0.43212,-0.2091 c 0.23778,-0.11492 0.43216,-0.22666 0.43216,-0.24834 0,-0.12757 -0.49613,-0.58333 -0.79304,-0.72849 -0.23984,-0.11743 -0.56004,-0.18031 -0.87976,-0.1869 z m -3.86757,0.003 c -0.31465,-0.002 -0.62483,0.0471 -0.84519,0.14714 -0.81324,0.36944 -1.21243,1.1924 -1.09145,2.2526 0.0813,0.71532 0.5437,1.3433 1.1467,1.55715 h 5.3e-4 c 0.14232,0.0503 0.48755,0.0935 0.76823,0.0966 0.44805,0.005 0.55549,-0.0181 0.8963,-0.18846 0.40105,-0.20034 0.89968,-0.70905 0.79096,-0.80696 -0.0314,-0.0283 -0.20233,-0.1311 -0.37947,-0.22871 l -0.32218,-0.17762 -0.24989,0.26332 c -0.24793,0.2608 -0.35374,0.29661 -0.77288,0.26434 -0.19934,-0.0153 -0.4106,-0.14975 -0.53643,-0.34179 -0.24256,-0.37018 -0.22501,-1.31046 0.0309,-1.67022 0.15482,-0.21742 0.49684,-0.34514 0.78269,-0.29119 0.11531,0.0215 0.30508,0.13677 0.42906,0.26073 l 0.222,0.22253 0.41666,-0.20549 c 0.22873,-0.11282 0.41613,-0.22336 0.41613,-0.24576 0,-0.13611 -0.54252,-0.62585 -0.83123,-0.75068 -0.23779,-0.10279 -0.55687,-0.15564 -0.87152,-0.15748 z" />
|
||||||
<rect transform="rotate(-15)" x="151.66" y="229.61" width="21.734" height="145.14" fill="url(#a)"/>
|
<rect transform="rotate(-15)" x="151.66" y="229.61" width="21.734" height="145.14" fill="url(#a)"/>
|
||||||
<g transform="matrix(.075655 .28235 -.12714 .034066 214.18 150.21)">
|
<g transform="matrix(.075655 .28235 -.12714 .034066 214.18 150.21)">
|
||||||
<rect x="2.8422e-14" y="-54.459" width="100" height="20" fill="#ef4444"/>
|
<rect x="0" y="-54.459" width="600" height="20" fill="url(#d)"/>
|
||||||
<rect x="100" y="-54.459" width="100" height="20" fill="#f97316"/>
|
|
||||||
<rect x="200" y="-54.459" width="100" height="20" fill="#facc15"/>
|
|
||||||
<rect x="300" y="-54.459" width="100" height="20" fill="#22c55e"/>
|
|
||||||
<rect x="400" y="-54.459" width="100" height="20" fill="#3b82f6"/>
|
|
||||||
<rect x="500" y="-54.459" width="100" height="20" fill="#8b5cf6"/>
|
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 18 KiB |
|
@ -29,11 +29,7 @@ const MdxPage = (props) => {
|
||||||
<meta property="og:type" content="article" key="type" />
|
<meta property="og:type" content="article" key="type" />
|
||||||
<meta property="og:description" content={props.intro} key="type" />
|
<meta property="og:description" content={props.intro} key="type" />
|
||||||
<meta property="og:article:author" content="Joost De Cock" key="author" />
|
<meta property="og:article:author" content="Joost De Cock" key="author" />
|
||||||
<meta
|
<meta property="og:image" content={`/og/${props.page.slug}/og.png`} key="image" />
|
||||||
property="og:image"
|
|
||||||
content={`https://canary.backend.freesewing.org/og-img/en/dev/${props.page.slug}`}
|
|
||||||
key="image"
|
|
||||||
/>
|
|
||||||
<meta property="og:image:type" content="image/png" />
|
<meta property="og:image:type" content="image/png" />
|
||||||
<meta property="og:image:width" content="1200" />
|
<meta property="og:image:width" content="1200" />
|
||||||
<meta property="og:image:height" content="630" />
|
<meta property="og:image:height" content="630" />
|
||||||
|
|
|
@ -14,7 +14,9 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@headlessui/react": "^1.6.6",
|
"@headlessui/react": "^1.6.6",
|
||||||
|
"@resvg/resvg-js": "^2.1.0",
|
||||||
"@tailwindcss/typography": "^0.5.0",
|
"@tailwindcss/typography": "^0.5.0",
|
||||||
|
"Buffer": "^0.0.0",
|
||||||
"d3-dispatch": "^3.0.1",
|
"d3-dispatch": "^3.0.1",
|
||||||
"d3-drag": "^3.0.0",
|
"d3-drag": "^3.0.0",
|
||||||
"d3-selection": "^3.0.0",
|
"d3-selection": "^3.0.0",
|
||||||
|
@ -38,6 +40,7 @@
|
||||||
"remark-extract-frontmatter": "^3.2.0",
|
"remark-extract-frontmatter": "^3.2.0",
|
||||||
"remark-frontmatter": "^4.0.1",
|
"remark-frontmatter": "^4.0.1",
|
||||||
"remark-smartypants": "^2.0.0",
|
"remark-smartypants": "^2.0.0",
|
||||||
|
"sharp": "^0.31.1",
|
||||||
"svg-to-pdfkit": "^0.1.8",
|
"svg-to-pdfkit": "^0.1.8",
|
||||||
"to-vfile": "^7.2.2",
|
"to-vfile": "^7.2.2",
|
||||||
"unist-util-visit": "^4.1.0",
|
"unist-util-visit": "^4.1.0",
|
||||||
|
|
|
@ -3,27 +3,20 @@ import { denyList } from '../../../packages/i18n/scripts/prebuilder.mjs'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
|
|
||||||
const writeJson = async (site, locale, namespace, content) => fs.writeFileSync(
|
const writeJson = async (site, locale, namespace, content) =>
|
||||||
path.resolve(
|
fs.writeFileSync(
|
||||||
'..',
|
path.resolve('..', site, 'public', 'locales', locale, `${namespace}.json`),
|
||||||
site,
|
JSON.stringify(content)
|
||||||
'public',
|
)
|
||||||
'locales',
|
|
||||||
locale,
|
|
||||||
`${namespace}.json`
|
|
||||||
),
|
|
||||||
JSON.stringify(content)
|
|
||||||
)
|
|
||||||
|
|
||||||
export const prebuildI18n = async (site, only=false) => {
|
export const prebuildI18n = async (site, only = false) => {
|
||||||
|
const filter = site === 'dev' ? (loc) => loc === 'en' : (loc) => denyList.indexOf(loc) === -1
|
||||||
const filter = site === 'dev' ? (loc => loc === 'en') : (loc => denyList.indexOf(loc) === -1)
|
|
||||||
const locales = await build(filter, only)
|
const locales = await build(filter, only)
|
||||||
|
|
||||||
console.log (`copying them to ${site}`, Object.keys(locales))
|
console.log(`copying them to ${site}`, Object.keys(locales))
|
||||||
|
|
||||||
const languages = {}
|
const languages = {}
|
||||||
Object.keys(locales).forEach(l => languages[l] = locales[l].i18n[l])
|
Object.keys(locales).forEach((l) => (languages[l] = locales[l].i18n[l]))
|
||||||
for (const locale in locales) {
|
for (const locale in locales) {
|
||||||
// Only English for dev site
|
// Only English for dev site
|
||||||
const loc = locales[locale]
|
const loc = locales[locale]
|
||||||
|
|
|
@ -5,16 +5,25 @@ import { prebuildContributors } from './contributors.mjs'
|
||||||
import { prebuildPatrons } from './patrons.mjs'
|
import { prebuildPatrons } from './patrons.mjs'
|
||||||
import { prebuildI18n } from './i18n.mjs'
|
import { prebuildI18n } from './i18n.mjs'
|
||||||
import { prebuildLab } from './lab.mjs'
|
import { prebuildLab } from './lab.mjs'
|
||||||
|
import { generateOgImage } from './og/index.mjs'
|
||||||
const SITE = process.env.SITE || 'lab'
|
|
||||||
|
|
||||||
const run = async () => {
|
const run = async () => {
|
||||||
|
const SITE = process.env.SITE || 'lab'
|
||||||
if (SITE === 'org') {
|
if (SITE === 'org') {
|
||||||
const mdxPages = await prebuildMdx(SITE)
|
const mdxPages = await prebuildMdx(SITE)
|
||||||
const [posts] = await prebuildStrapi(SITE)
|
const [posts] = await prebuildStrapi(SITE)
|
||||||
prebuildNavigation(mdxPages, posts, SITE)
|
prebuildNavigation(mdxPages, posts, SITE)
|
||||||
} else if (SITE === 'dev') {
|
} else if (SITE === 'dev') {
|
||||||
const mdxPages = await prebuildMdx(SITE)
|
const mdxPages = await prebuildMdx(SITE)
|
||||||
|
if (process.env.GENERATE_OG_IMAGES) {
|
||||||
|
// Create og image for home page
|
||||||
|
const img = await generateOgImage({
|
||||||
|
lang: 'en',
|
||||||
|
site: SITE,
|
||||||
|
slug: '',
|
||||||
|
title: 'FreeSewing.dev',
|
||||||
|
})
|
||||||
|
}
|
||||||
prebuildNavigation(mdxPages, false, SITE)
|
prebuildNavigation(mdxPages, false, SITE)
|
||||||
} else await prebuildLab()
|
} else await prebuildLab()
|
||||||
|
|
||||||
|
|
79
sites/shared/prebuild/md-intro.mjs
Normal file
79
sites/shared/prebuild/md-intro.mjs
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
// We need fs and path to read from disk
|
||||||
|
import fs from 'fs'
|
||||||
|
import path from 'path'
|
||||||
|
|
||||||
|
// Remark
|
||||||
|
import { remark } from 'remark'
|
||||||
|
import { visit } from 'unist-util-visit'
|
||||||
|
// Remark plugins we want to use
|
||||||
|
import remarkParse from 'remark-parse'
|
||||||
|
import remarkFrontmatter from 'remark-frontmatter'
|
||||||
|
|
||||||
|
const asText = ['text', 'strong', 'emphasis', 'inlineCode']
|
||||||
|
|
||||||
|
// Pulls the intro from a markdown document
|
||||||
|
const remarkIntroPlugin = (opts = {}) => {
|
||||||
|
// Pulls text out of a paragraph
|
||||||
|
const extractIntro = (node) => {
|
||||||
|
const text = []
|
||||||
|
for (const child of node.children) {
|
||||||
|
if (asText.indexOf(child.type) !== -1) text.push(child.value)
|
||||||
|
else if (child.type === 'link') text.push(child.children[0].value)
|
||||||
|
}
|
||||||
|
|
||||||
|
return text.map((item) => (item ? item.trim() : '')).join(' ')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pulls the first paragraph out of a root node
|
||||||
|
const extractFirstParagraph = (node) => {
|
||||||
|
for (const child of node.children) {
|
||||||
|
if (child.type === 'paragraph') return extractIntro(child)
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'FIXME_no_intro'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tree visitor
|
||||||
|
const visitor = (node, i, parent) => {
|
||||||
|
if (node.type === 'root') {
|
||||||
|
node.children = [
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
value: extractFirstParagraph(node).split('\n').join(' ').trim(),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transformer method using the visitor pattern
|
||||||
|
const transform = (tree) => {
|
||||||
|
visit(tree, 'root', visitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
return transform
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Summary: Loads markdown from disk and return the intro as plain text
|
||||||
|
*
|
||||||
|
* @param (string) language - language to load (eg: 'en')
|
||||||
|
* @param (string) site - site to load (either 'dev' or 'org')
|
||||||
|
* @param (string) slug - slug of the page (eg: 'guides/patterns')
|
||||||
|
*
|
||||||
|
* @return (string) intro - the document's intro
|
||||||
|
*/
|
||||||
|
export const mdIntro = async (language, site, slug) => {
|
||||||
|
// TODO: Will this work on Windows?
|
||||||
|
const md = await fs.promises.readFile(
|
||||||
|
path.resolve(`../../markdown/${site}/${slug}/${language}.md`),
|
||||||
|
'utf-8'
|
||||||
|
)
|
||||||
|
const intro = []
|
||||||
|
const result = await remark()
|
||||||
|
.use(remarkFrontmatter)
|
||||||
|
.use(remarkParse)
|
||||||
|
.use([remarkIntroPlugin, { intro }])
|
||||||
|
.process(md)
|
||||||
|
|
||||||
|
return result.toString()
|
||||||
|
}
|
|
@ -8,6 +8,8 @@ import remarkFrontmatter from 'remark-frontmatter'
|
||||||
import remarkFrontmatterExtractor from 'remark-extract-frontmatter'
|
import remarkFrontmatterExtractor from 'remark-extract-frontmatter'
|
||||||
import { readSync } from 'to-vfile'
|
import { readSync } from 'to-vfile'
|
||||||
import yaml from 'js-yaml'
|
import yaml from 'js-yaml'
|
||||||
|
import { mdIntro } from './md-intro.mjs'
|
||||||
|
import { generateOgImage } from './og/index.mjs'
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There's an issue in crowdin where it changes the frontmatter marker:
|
* There's an issue in crowdin where it changes the frontmatter marker:
|
||||||
|
@ -17,8 +19,8 @@ import yaml from 'js-yaml'
|
||||||
* which breaks stuff. So this method takes the input and replaces all
|
* which breaks stuff. So this method takes the input and replaces all
|
||||||
* - - - with ---
|
* - - - with ---
|
||||||
*/
|
*/
|
||||||
export const fixCrowdinBugs = md => {
|
export const fixCrowdinBugs = (md) => {
|
||||||
md.value = md.value.split("- - -\n").join("---\n")
|
md.value = md.value.split('- - -\n').join('---\n')
|
||||||
return md
|
return md
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,8 +39,7 @@ export const getMdxFileList = async (folder, lang) => {
|
||||||
let allFiles
|
let allFiles
|
||||||
try {
|
try {
|
||||||
allFiles = await rdir(folder)
|
allFiles = await rdir(folder)
|
||||||
}
|
} catch (err) {
|
||||||
catch (err) {
|
|
||||||
console.log(err)
|
console.log(err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -51,7 +52,8 @@ export const getMdxFileList = async (folder, lang) => {
|
||||||
file.slice(-5) === `${lang}.md` &&
|
file.slice(-5) === `${lang}.md` &&
|
||||||
file.indexOf('/ui/') === -1 &&
|
file.indexOf('/ui/') === -1 &&
|
||||||
file.indexOf('/uimd/') === -1
|
file.indexOf('/uimd/') === -1
|
||||||
) files.push(file)
|
)
|
||||||
|
files.push(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
return files.sort()
|
return files.sort()
|
||||||
|
@ -60,9 +62,8 @@ export const getMdxFileList = async (folder, lang) => {
|
||||||
/*
|
/*
|
||||||
* Helper method to get the website slug (path) from the file path
|
* Helper method to get the website slug (path) from the file path
|
||||||
*/
|
*/
|
||||||
export const fileToSlug = (file, site, lang) => (file.slice(-6) === `/${lang}.md`)
|
export const fileToSlug = (file, site, lang) =>
|
||||||
? file.split(`/markdown/${site}/`).pop().slice(0, -6)
|
file.slice(-6) === `/${lang}.md` ? file.split(`/markdown/${site}/`).pop().slice(0, -6) : false
|
||||||
: false
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper method to get the title and meta data from an MDX file
|
* Helper method to get the title and meta data from an MDX file
|
||||||
|
@ -71,7 +72,7 @@ export const fileToSlug = (file, site, lang) => (file.slice(-6) === `/${lang}.md
|
||||||
*
|
*
|
||||||
* - file: the full path to the file
|
* - file: the full path to the file
|
||||||
*/
|
*/
|
||||||
const mdxMetaInfo = async file => {
|
const mdxMetaInfo = async (file) => {
|
||||||
let result
|
let result
|
||||||
try {
|
try {
|
||||||
result = await unified()
|
result = await unified()
|
||||||
|
@ -80,8 +81,7 @@ const mdxMetaInfo = async file => {
|
||||||
.use(remarkFrontmatter)
|
.use(remarkFrontmatter)
|
||||||
.use(remarkFrontmatterExtractor, { yaml: yaml.load })
|
.use(remarkFrontmatterExtractor, { yaml: yaml.load })
|
||||||
.process(fixCrowdinBugs(readSync(file, { encoding: 'utf-8' })))
|
.process(fixCrowdinBugs(readSync(file, { encoding: 'utf-8' })))
|
||||||
}
|
} catch (err) {
|
||||||
catch (err) {
|
|
||||||
console.log(err)
|
console.log(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,8 +91,7 @@ const mdxMetaInfo = async file => {
|
||||||
/*
|
/*
|
||||||
* Main method that does what needs doing
|
* Main method that does what needs doing
|
||||||
*/
|
*/
|
||||||
export const prebuildMdx = async(site) => {
|
export const prebuildMdx = async (site) => {
|
||||||
|
|
||||||
// Say hi
|
// Say hi
|
||||||
console.log()
|
console.log()
|
||||||
console.log(`Prebuilding MDX for freesewing.${site}`)
|
console.log(`Prebuilding MDX for freesewing.${site}`)
|
||||||
|
@ -100,10 +99,17 @@ export const prebuildMdx = async(site) => {
|
||||||
// Setup MDX root path
|
// Setup MDX root path
|
||||||
const mdxRoot = path.resolve('..', '..', 'markdown', site)
|
const mdxRoot = path.resolve('..', '..', 'markdown', site)
|
||||||
|
|
||||||
|
// Inform if we're also generating OG images
|
||||||
|
if (process.env.GENERATE_OG_IMAGES) {
|
||||||
|
console.log('⚙ Also generating Open Graph images (this takes a while)')
|
||||||
|
console.log(' Unset the GENERATE_OG_IMAGES env var to skip this step)')
|
||||||
|
} else {
|
||||||
|
console.log('⏩ Not generating Open Graph images as it takes a while')
|
||||||
|
console.log(' Set GENERATE_OG_IMAGES env var to include this step')
|
||||||
|
}
|
||||||
// Loop over locales
|
// Loop over locales
|
||||||
const pages = {}
|
const pages = {}
|
||||||
for (const lang of (site === 'dev' ? ['en'] : ['en', 'fr', 'es', 'nl', 'de'])) {
|
for (const lang of site === 'dev' ? ['en'] : ['en', 'fr', 'es', 'nl', 'de']) {
|
||||||
|
|
||||||
console.log(` - Language: ${lang}`)
|
console.log(` - Language: ${lang}`)
|
||||||
|
|
||||||
// Get list of filenames
|
// Get list of filenames
|
||||||
|
@ -119,9 +125,7 @@ export const prebuildMdx = async(site) => {
|
||||||
pages[lang][slug] = {
|
pages[lang][slug] = {
|
||||||
title: meta.data.title,
|
title: meta.data.title,
|
||||||
slug,
|
slug,
|
||||||
order: meta.data.order
|
order: meta.data.order ? `${meta.data.order}${meta.data.title}` : meta.data.title,
|
||||||
? `${meta.data.order}${meta.data.title}`
|
|
||||||
: meta.data.title
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (pages.en[slug]) {
|
if (pages.en[slug]) {
|
||||||
|
@ -132,21 +136,25 @@ export const prebuildMdx = async(site) => {
|
||||||
if (meta.messages.length > 0) console.log(meta.messages)
|
if (meta.messages.length > 0) console.log(meta.messages)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (process.env.GENERATE_OG_IMAGES) {
|
||||||
|
// Create og image
|
||||||
|
const intro = await mdIntro(lang, site, slug)
|
||||||
|
const img = await generateOgImage({ lang, site, slug, title: meta.data.title, intro })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.writeFileSync(
|
fs.writeFileSync(
|
||||||
path.resolve('..', site, 'prebuild', `mdx.${lang}.js`),
|
path.resolve('..', site, 'prebuild', `mdx.${lang}.js`),
|
||||||
`export default ${JSON.stringify(pages[lang], null ,2)}`
|
`export default ${JSON.stringify(pages[lang], null, 2)}`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write list of all MDX paths (in one language)
|
// Write list of all MDX paths (in one language)
|
||||||
fs.writeFileSync(
|
fs.writeFileSync(
|
||||||
path.resolve('..', site, 'prebuild', `mdx.paths.js`),
|
path.resolve('..', site, 'prebuild', `mdx.paths.js`),
|
||||||
`export default ${JSON.stringify(Object.keys(pages.en), null ,2)}`
|
`export default ${JSON.stringify(Object.keys(pages.en), null, 2)}`
|
||||||
)
|
)
|
||||||
|
|
||||||
return pages
|
return pages
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
153
sites/shared/prebuild/og/index.mjs
Normal file
153
sites/shared/prebuild/og/index.mjs
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
import fs_ from 'fs'
|
||||||
|
import path from 'path'
|
||||||
|
import { Buffer } from 'buffer'
|
||||||
|
import sharp from 'sharp'
|
||||||
|
import { capitalize } from '../../utils.mjs'
|
||||||
|
|
||||||
|
const fs = fs_.promises
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
template: ['..', '..', 'artwork', 'og', 'template.svg'],
|
||||||
|
chars: {
|
||||||
|
title_1: 18,
|
||||||
|
title_2: 19,
|
||||||
|
title_3: 20,
|
||||||
|
intro: 34,
|
||||||
|
sub: 42,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load template once at startup
|
||||||
|
const template = fs_.readFileSync(path.resolve(...config.template), 'utf-8')
|
||||||
|
|
||||||
|
/* Find longest possible place to split a string */
|
||||||
|
const splitLine = (line, chars) => {
|
||||||
|
const words = line.split(' ')
|
||||||
|
if (words[0].length > chars) {
|
||||||
|
// Force a word break
|
||||||
|
return [line.slice(0, chars - 1) + '-', line.slice(chars - 1)]
|
||||||
|
}
|
||||||
|
// Glue chunks together until it's too long
|
||||||
|
let firstLine = ''
|
||||||
|
let max = false
|
||||||
|
for (const word of words) {
|
||||||
|
if (!max && `${firstLine}${word}`.length <= chars) firstLine += `${word} `
|
||||||
|
else max = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return [firstLine, words.join(' ').slice(firstLine.length)]
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Divide title into lines to fit on image */
|
||||||
|
const titleAsLines = (title) => {
|
||||||
|
// Does it fit on one line?
|
||||||
|
if (title.length <= config.chars.title_1) return [title]
|
||||||
|
// Does it fit on two lines?
|
||||||
|
let lines = splitLine(title, config.chars.title_1)
|
||||||
|
if (lines[1].length <= config.chars.title_2) return lines
|
||||||
|
// Three lines it is
|
||||||
|
return [lines[0], ...splitLine(lines[1], config.chars.title_2)]
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Divive intro into lines to fit on image */
|
||||||
|
const introAsLines = (intro) => {
|
||||||
|
// Does it fit on one line?
|
||||||
|
if (intro.length <= config.chars.intro) return [intro]
|
||||||
|
// Two lines it is
|
||||||
|
return splitLine(intro, config.chars.intro)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get title and intro
|
||||||
|
const getMetaData = async ({ slug, title, intro, site }) => {
|
||||||
|
const chunks = slug.split('/')
|
||||||
|
if (site === 'dev') {
|
||||||
|
// Home page
|
||||||
|
if (chunks.length === 1 && chunks[0] === '') {
|
||||||
|
return {
|
||||||
|
title: ['FreeSewing.dev'],
|
||||||
|
intro: introAsLines('FreeSewing documentation for developers and contributors'),
|
||||||
|
sub: ['With guides, tutorials,', "How-to's and more"],
|
||||||
|
lead: '.dev',
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// MDX page
|
||||||
|
return {
|
||||||
|
title: titleAsLines(title),
|
||||||
|
intro: introAsLines(intro),
|
||||||
|
sub: ['https://freesewing.dev/', slug],
|
||||||
|
lead: capitalize(chunks[0]),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log('Unsupported data for OG', data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide unused placeholders */
|
||||||
|
const hidePlaceholders = (list) => {
|
||||||
|
let svg = template
|
||||||
|
for (const i of list) {
|
||||||
|
svg = svg.replace(`${i}title_1`, '').replace(`${i}title_2`, '').replace(`${i}title_3`, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
return svg
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Place text in SVG template */
|
||||||
|
const decorateSvg = (data) => {
|
||||||
|
let svg
|
||||||
|
// Single title line
|
||||||
|
if (data.title.length === 1) {
|
||||||
|
svg = hidePlaceholders([2, 3]).replace(`1title_1`, data.title[0])
|
||||||
|
}
|
||||||
|
// Double title line
|
||||||
|
else if (data.title.length === 2) {
|
||||||
|
svg = hidePlaceholders([1, 3])
|
||||||
|
.replace(`2title_1`, data.title[0])
|
||||||
|
.replace(`2title_2`, data.title[1])
|
||||||
|
}
|
||||||
|
// Triple title line
|
||||||
|
else if (data.title.length === 3) {
|
||||||
|
svg = hidePlaceholders([1, 2])
|
||||||
|
.replace(`3title_1`, data.title[0])
|
||||||
|
.replace(`3title_2`, data.title[1])
|
||||||
|
.replace(`3title_3`, data.title[2])
|
||||||
|
}
|
||||||
|
|
||||||
|
return svg
|
||||||
|
.replace('sub_1', data.sub[0] || '')
|
||||||
|
.replace('sub_2', data.sub[1] || '')
|
||||||
|
.replace(`intro_1`, data.intro[0] || '')
|
||||||
|
.replace(`intro_2`, data.intro[1] || '')
|
||||||
|
.replace('lead_1', data.lead || '')
|
||||||
|
}
|
||||||
|
|
||||||
|
const writeAsPng = async (svg, site, slug) => {
|
||||||
|
const dir = path.resolve(path.join('..', '..', 'sites', site, 'public', 'og', ...slug.split('/')))
|
||||||
|
await fs.mkdir(dir, { recursive: true })
|
||||||
|
// Turn into PNG
|
||||||
|
sharp(Buffer.from(svg, 'utf-8'))
|
||||||
|
.resize({ width: 1200 })
|
||||||
|
.toBuffer(async (err, data, info) => {
|
||||||
|
if (err) console.log(err)
|
||||||
|
return await fs.writeFile(path.join(dir, 'og.png'), data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This generates open graph images
|
||||||
|
*
|
||||||
|
* data holds {
|
||||||
|
* lang,
|
||||||
|
* site,
|
||||||
|
* title,
|
||||||
|
* intro,
|
||||||
|
* slug
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const generateOgImage = async (data) => {
|
||||||
|
// Inject into SVG
|
||||||
|
const meta = await getMetaData(data)
|
||||||
|
const svg = decorateSvg(meta)
|
||||||
|
await writeAsPng(svg, data.site, data.slug)
|
||||||
|
}
|
85
yarn.lock
85
yarn.lock
|
@ -3083,6 +3083,84 @@
|
||||||
resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1"
|
resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1"
|
||||||
integrity sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==
|
integrity sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==
|
||||||
|
|
||||||
|
"@resvg/resvg-js-android-arm-eabi@2.1.0":
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@resvg/resvg-js-android-arm-eabi/-/resvg-js-android-arm-eabi-2.1.0.tgz#db9a73969a3d507c4a512953e003088129d17b3a"
|
||||||
|
integrity sha512-JtvWWtC6bYRhyth1qgUgcPQSP+jkwkmUzok/5b/IqKFb6cattMBFFdHnwM8AS+sgzXJKa8LhW48f3FmFQhfdrA==
|
||||||
|
|
||||||
|
"@resvg/resvg-js-android-arm64@2.1.0":
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@resvg/resvg-js-android-arm64/-/resvg-js-android-arm64-2.1.0.tgz#862a423b0396ef057cc5f58e2586fe532503360f"
|
||||||
|
integrity sha512-QXFEoTpoZJZjkFh4+aSD3l+Ivrij3nzgrr4FTayey0hsQypJXmbzB6nuqB1qZwMrXPYqYZ33BoRiwCFoJUw2Ww==
|
||||||
|
|
||||||
|
"@resvg/resvg-js-darwin-arm64@2.1.0":
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@resvg/resvg-js-darwin-arm64/-/resvg-js-darwin-arm64-2.1.0.tgz#b767cd8385f55f62ea35b48b805b3eb81e7a1642"
|
||||||
|
integrity sha512-OrYqlmn2g4Pu/dWr+M5t5W8GDKIX3zk0JxDySU1oNWwhqlmZXBuCrx3TP9dVrTpTYx86E5RQcTZWe64wz8dlIQ==
|
||||||
|
|
||||||
|
"@resvg/resvg-js-darwin-x64@2.1.0":
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@resvg/resvg-js-darwin-x64/-/resvg-js-darwin-x64-2.1.0.tgz#9162cd1ccb2af608ba5a9cb2cb75e0343c48163b"
|
||||||
|
integrity sha512-95F9BoBS1th79n6Zy1tRMKhPlJuhznnQwAPxRhtw0v4DteRKMzaPFfVH6B9BBaoDCa5VMIxH/wYNKtOxCpYPuw==
|
||||||
|
|
||||||
|
"@resvg/resvg-js-linux-arm-gnueabihf@2.1.0":
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@resvg/resvg-js-linux-arm-gnueabihf/-/resvg-js-linux-arm-gnueabihf-2.1.0.tgz#99b52ab1ed0e22ebc43a852b5ffa9839e9b41ba2"
|
||||||
|
integrity sha512-8F0ugeAaYGNNZhSCYt+X4YgyKyKcFiH0tqfJmN69+Gqqmu/lmZcn78JVLyTGD/OGHbYfCCYJbxwV+txIOdVNkQ==
|
||||||
|
|
||||||
|
"@resvg/resvg-js-linux-arm64-gnu@2.1.0":
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@resvg/resvg-js-linux-arm64-gnu/-/resvg-js-linux-arm64-gnu-2.1.0.tgz#81a7f8d19e494b890ec43f4b0fdd6487820cce05"
|
||||||
|
integrity sha512-RveUS3sqvUp5eoBzz1QlPv7yBUNOjHtcWtbFo55gQrzBGT4XtnCaQzuXkN0q0j2o2ufxlmXmFI3g3e/0EWjNMg==
|
||||||
|
|
||||||
|
"@resvg/resvg-js-linux-arm64-musl@2.1.0":
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@resvg/resvg-js-linux-arm64-musl/-/resvg-js-linux-arm64-musl-2.1.0.tgz#0c4deb3bda1572a23d6c3a93a11b0f74db036fa8"
|
||||||
|
integrity sha512-DzuRbZj5oVXYFAlo2PVbiaTSb14z/FDUlvgfzVFHiKEw3w6gT/soveLTIAvfeIlRYYkwYNHCiEPxFztyr7x/rw==
|
||||||
|
|
||||||
|
"@resvg/resvg-js-linux-x64-gnu@2.1.0":
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@resvg/resvg-js-linux-x64-gnu/-/resvg-js-linux-x64-gnu-2.1.0.tgz#93f625815a9b478093f7b0b901167b015d97e0be"
|
||||||
|
integrity sha512-pa4MtKtAEXBj7tl3JXPMQLjgP+KghUYYoXMIX8tlf/xbfJJsOxHpWcwQe/bWPFO4K9hgt/yePkb3G4ydD0uT+g==
|
||||||
|
|
||||||
|
"@resvg/resvg-js-linux-x64-musl@2.1.0":
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@resvg/resvg-js-linux-x64-musl/-/resvg-js-linux-x64-musl-2.1.0.tgz#354f8b1d9248ccf7be2706617befe83893e3bff3"
|
||||||
|
integrity sha512-mkwGe4I9CmQ1GPSnFa22PHwKbE+TZnRk/ViCvO89UOwypW0I+X+KlQVzVbZn9ypvcrbvzotOvl3OkVRq5MgsBA==
|
||||||
|
|
||||||
|
"@resvg/resvg-js-win32-arm64-msvc@2.1.0":
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@resvg/resvg-js-win32-arm64-msvc/-/resvg-js-win32-arm64-msvc-2.1.0.tgz#e3bfe5b4b9db904827398190455fd8175d44d553"
|
||||||
|
integrity sha512-DVloJcQsgd3rMAPemy5KjAA6R+RkRz2/xb7zP9px7lr+Gao+xVbNzRQrY7xwCZFM7O7hu9uHvLvkKCttPoL1aA==
|
||||||
|
|
||||||
|
"@resvg/resvg-js-win32-ia32-msvc@2.1.0":
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@resvg/resvg-js-win32-ia32-msvc/-/resvg-js-win32-ia32-msvc-2.1.0.tgz#1afb29d79c7b61a30965501ad3b4e60559905308"
|
||||||
|
integrity sha512-RtRQ8loZA4zib8kzD1QjoScb6VAaZTbajB3WU/O6raP2/f2zIk9v4FU2E/hiC0vi5DGhJL5GTmSrsWShbLPjZw==
|
||||||
|
|
||||||
|
"@resvg/resvg-js-win32-x64-msvc@2.1.0":
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@resvg/resvg-js-win32-x64-msvc/-/resvg-js-win32-x64-msvc-2.1.0.tgz#d0239707b5f85ae984dcd8ae09da1939bb02109a"
|
||||||
|
integrity sha512-NVYuQn9Aj/ZmRufKON7a+1U1XS+jGKMcWO4J8ZH2xhSP3aNVgO7Nfl45DMgqxdCcn0ZzYhzP+mSQFbA/ENE/mg==
|
||||||
|
|
||||||
|
"@resvg/resvg-js@^2.1.0":
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@resvg/resvg-js/-/resvg-js-2.1.0.tgz#d2e939e39d31e97fb5f61efba25ef5ab64bf27d1"
|
||||||
|
integrity sha512-nR6uVR5ugXLT2jh7U141nhawzgUs4JBl8BpM4XH7/ughSsOA/+WRxVhMUfdtEsz7REpTMKe2Sat+1/eWAuQ04w==
|
||||||
|
optionalDependencies:
|
||||||
|
"@resvg/resvg-js-android-arm-eabi" "2.1.0"
|
||||||
|
"@resvg/resvg-js-android-arm64" "2.1.0"
|
||||||
|
"@resvg/resvg-js-darwin-arm64" "2.1.0"
|
||||||
|
"@resvg/resvg-js-darwin-x64" "2.1.0"
|
||||||
|
"@resvg/resvg-js-linux-arm-gnueabihf" "2.1.0"
|
||||||
|
"@resvg/resvg-js-linux-arm64-gnu" "2.1.0"
|
||||||
|
"@resvg/resvg-js-linux-arm64-musl" "2.1.0"
|
||||||
|
"@resvg/resvg-js-linux-x64-gnu" "2.1.0"
|
||||||
|
"@resvg/resvg-js-linux-x64-musl" "2.1.0"
|
||||||
|
"@resvg/resvg-js-win32-arm64-msvc" "2.1.0"
|
||||||
|
"@resvg/resvg-js-win32-ia32-msvc" "2.1.0"
|
||||||
|
"@resvg/resvg-js-win32-x64-msvc" "2.1.0"
|
||||||
|
|
||||||
"@rushstack/eslint-patch@^1.1.3":
|
"@rushstack/eslint-patch@^1.1.3":
|
||||||
version "1.1.4"
|
version "1.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.1.4.tgz#0c8b74c50f29ee44f423f7416829c0bf8bb5eb27"
|
resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.1.4.tgz#0c8b74c50f29ee44f423f7416829c0bf8bb5eb27"
|
||||||
|
@ -3847,6 +3925,11 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
argparse "^2.0.1"
|
argparse "^2.0.1"
|
||||||
|
|
||||||
|
Buffer@^0.0.0:
|
||||||
|
version "0.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/Buffer/-/Buffer-0.0.0.tgz#82cf8e986a2109ff6d1d6f1c436e47d07127aea4"
|
||||||
|
integrity sha512-+zdncl8lI5TCkARStn9F1BwcuJYofYmD0oEHe5FNfCvGfeDJwf6+dSikCdQN6BMXXmHMhNNUagBN367WST1AIQ==
|
||||||
|
|
||||||
JSONStream@^1.0.4:
|
JSONStream@^1.0.4:
|
||||||
version "1.3.5"
|
version "1.3.5"
|
||||||
resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0"
|
resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0"
|
||||||
|
@ -17404,7 +17487,7 @@ shallowequal@^1.1.0:
|
||||||
resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8"
|
resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8"
|
||||||
integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==
|
integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==
|
||||||
|
|
||||||
sharp@^0.31.0:
|
sharp@^0.31.0, sharp@^0.31.1:
|
||||||
version "0.31.1"
|
version "0.31.1"
|
||||||
resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.31.1.tgz#b2f7076d381a120761aa93700cadefcf90a22458"
|
resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.31.1.tgz#b2f7076d381a120761aa93700cadefcf90a22458"
|
||||||
integrity sha512-GR8M1wBwOiFKLkm9JPun27OQnNRZdHfSf9VwcdZX6UrRmM1/XnOrLFTF0GAil+y/YK4E6qcM/ugxs80QirsHxg==
|
integrity sha512-GR8M1wBwOiFKLkm9JPun27OQnNRZdHfSf9VwcdZX6UrRmM1/XnOrLFTF0GAil+y/YK4E6qcM/ugxs80QirsHxg==
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue