hdoc-tools 0.8.23 → 0.8.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/hdoc-build-pdf.js +169 -0
  2. package/hdoc-build.js +34 -8
  3. package/hdoc-init.js +0 -1
  4. package/hdoc-validate.js +0 -2
  5. package/hdoc.js +1 -1
  6. package/package.json +4 -2
  7. package/templates/pdf/css/custom-block.css +90 -0
  8. package/templates/pdf/css/fonts.css +221 -0
  9. package/templates/pdf/css/hdocs-pdf.css +242 -0
  10. package/templates/pdf/css/vars.css +393 -0
  11. package/templates/pdf/fonts/inter-cyrillic copy.woff2 +0 -0
  12. package/templates/pdf/fonts/inter-cyrillic-ext.woff2 +0 -0
  13. package/templates/pdf/fonts/inter-cyrillic.woff2 +0 -0
  14. package/templates/pdf/fonts/inter-greek-ext.woff2 +0 -0
  15. package/templates/pdf/fonts/inter-greek.woff2 +0 -0
  16. package/templates/pdf/fonts/inter-italic-cyrillic-ext.woff2 +0 -0
  17. package/templates/pdf/fonts/inter-italic-cyrillic.woff2 +0 -0
  18. package/templates/pdf/fonts/inter-italic-greek-ext.woff2 +0 -0
  19. package/templates/pdf/fonts/inter-italic-greek.woff2 +0 -0
  20. package/templates/pdf/fonts/inter-italic-latin-ext.woff2 +0 -0
  21. package/templates/pdf/fonts/inter-italic-latin.woff2 +0 -0
  22. package/templates/pdf/fonts/inter-italic-vietnamese.woff2 +0 -0
  23. package/templates/pdf/fonts/inter-latin-ext.woff2 +0 -0
  24. package/templates/pdf/fonts/inter-latin.woff2 +0 -0
  25. package/templates/pdf/fonts/inter-roman-cyrillic-ext.woff2 +0 -0
  26. package/templates/pdf/fonts/inter-roman-cyrillic.woff2 +0 -0
  27. package/templates/pdf/fonts/inter-roman-greek-ext.woff2 +0 -0
  28. package/templates/pdf/fonts/inter-roman-greek.woff2 +0 -0
  29. package/templates/pdf/fonts/inter-roman-latin-ext.woff2 +0 -0
  30. package/templates/pdf/fonts/inter-roman-latin.woff2 +0 -0
  31. package/templates/pdf/fonts/inter-roman-vietnamese.woff2 +0 -0
  32. package/templates/pdf/fonts/inter-vietnamese.woff2 +0 -0
  33. package/templates/pdf/images/hornbill-logo-full.svg +92 -0
  34. package/templates/pdf/template-footer.html +19 -0
  35. package/templates/pdf/template.html +13 -0
  36. package/templates/pdf-header-non-git.html +13 -0
  37. package/templates/pdf-header.html +17 -0
@@ -0,0 +1,169 @@
1
+ (function () {
2
+ 'use strict';
3
+
4
+ const cheerio = require('cheerio'),
5
+ dree = require('dree'),
6
+ fs = require('fs-extra'),
7
+ mime = require('mime-types'),
8
+ path = require('path'),
9
+ puppeteer = require('puppeteer'),
10
+ request = require('sync-request'),
11
+ hdoc = require(path.join(__dirname, 'hdoc-module.js'));
12
+
13
+ const dree_options = {
14
+ extensions: ['css'],
15
+ normalize: true,
16
+ };
17
+
18
+ let css_files = [],
19
+ hb_logo = '',
20
+ header = '',
21
+ footer = '';
22
+
23
+ const file_callback = function (element) {
24
+ css_files.push(element.path);
25
+ };
26
+
27
+ const get_footer = function (template_path) {
28
+ let footer_content = null;
29
+ try {
30
+ footer_content = fs.readFileSync(path.join(template_path, 'template-footer.html'), 'utf8');
31
+ } catch (err) {
32
+ console.log(`Error loading template: ${err}`);
33
+ }
34
+ return footer_content;
35
+ };
36
+
37
+ exports.process_images = async function (file_path, html_source, verbose) {
38
+ const book_work_root = file_path.path.replace(file_path.relativePath, '');
39
+ if (verbose) console.log('Parsing img tags from HTML source');
40
+
41
+ // Use cheerio to parse html
42
+ const $ = cheerio.load(html_source);
43
+
44
+ // Get iFrames from HTML, to replace with a tags
45
+ let iframes = [];
46
+ const iframe_html = $('iframe').map(function () {
47
+ const response = {
48
+ html: $.html(this),
49
+ src: $(this).attr('src'),
50
+ title: $(this).attr('title') ? $(this).attr('title') : 'No Link Title Provided'
51
+ };
52
+ return response;
53
+ }).get();
54
+ iframes.push(...iframe_html);
55
+ for (let i = 0; i < iframes.length; i++) {
56
+ const link = `<p><a href="${iframes[i].src}">${iframes[i].title}</a></p>`;
57
+ const regex = new RegExp(`<iframe.*src="${iframes[i].src.replace('/', '\\/')}".*</iframe>`);
58
+ html_source = html_source.replace(regex, link);
59
+ }
60
+
61
+ // Get image links from HTML, to embed into the pdf
62
+ let imgs = [];
63
+ const srcs = $('img').map(function (i) {
64
+ return $(this).attr('src');
65
+ }).get();
66
+ imgs.push(...srcs);
67
+ for (let i = 0; i < imgs.length; i++) {
68
+ if (hdoc.valid_url(imgs[i]).valid) {
69
+ // External Link
70
+ const file_response = request('GET', imgs[i]);
71
+ if (file_response.statusCode === 200) {
72
+ const image_buffer = file_response.getBody();
73
+ const mime_type = mime.lookup(imgs[i]);
74
+ let image_b64 = image_buffer.toString("base64");
75
+ image_b64 = `data:${mime_type};base64,${image_b64}`;
76
+ html_source = html_source.replace(imgs[i], image_b64);
77
+ } else {
78
+ throw `Unexpected Status ${file_response.statusCode}`;
79
+ }
80
+ } else {
81
+ // Internal link
82
+ const image_path = path.join(book_work_root, imgs[i].replace('_books/', ''));
83
+ try {
84
+ const image_buffer = fs.readFileSync(image_path);
85
+ const mime_type = mime.lookup(image_path);
86
+ let image_b64 = image_buffer.toString("base64");
87
+ image_b64 = `data:${mime_type};base64,${image_b64}`;
88
+ html_source = html_source.replace(imgs[i], image_b64);
89
+ } catch (err) {
90
+ console.log('Error reading image from HTML source [', image_path, '] - ', err);
91
+ return null;
92
+ }
93
+ }
94
+ }
95
+
96
+ return html_source;
97
+ };
98
+
99
+ exports.generate_pdf = async function (pdf_template_path, pdf_template_content, book_config, html_source, target_file, verbose = false) {
100
+ if (verbose) console.log(`Generating PDF: ${target_file}`);
101
+
102
+ // Cache footer
103
+ if (footer === '') footer = get_footer(pdf_template_path);
104
+
105
+ // Read svg logo file into buffer, convert to B64 string
106
+ if (hb_logo === '') {
107
+ const hb_logo_path = path.join(pdf_template_path, 'images', 'hornbill-logo-full.svg');
108
+ try {
109
+ const hb_logo_file_buffer = fs.readFileSync(hb_logo_path);
110
+ hb_logo = hb_logo_file_buffer.toString("base64");
111
+ hb_logo = `data:image/svg+xml;base64,${hb_logo}`;
112
+ } catch (err) {
113
+ console.log('Error reading logo from template:', err);
114
+ return;
115
+ }
116
+ }
117
+
118
+ html_source = pdf_template_content.replace('{{book_title}}', book_config.title).replace('{{document_content}}', html_source).replace('{{hb_logo}}', hb_logo);
119
+
120
+ // Create a browser instance
121
+ const browser = await puppeteer.launch();
122
+
123
+ // Create a new page
124
+ const page = await browser.newPage();
125
+
126
+ // Set HTML content from HTML source
127
+ await page.setContent(html_source, {
128
+ waitUntil: 'domcontentloaded'
129
+ });
130
+
131
+ // To reflect CSS used for screens instead of print
132
+ await page.emulateMediaType('screen');
133
+
134
+ if (css_files.length === 0) {
135
+ // Get a list of CSS files
136
+ dree.scan(pdf_template_path, dree_options, file_callback);
137
+ }
138
+
139
+ for (let i = 0; i < css_files.length; i++) {
140
+ await page.addStyleTag({
141
+ path: css_files[i]
142
+ });
143
+ }
144
+
145
+ try {
146
+ await page.pdf({
147
+ path: target_file,
148
+ margin: {
149
+ top: '30px',
150
+ right: '35px',
151
+ bottom: '80px',
152
+ left: '35px'
153
+ },
154
+ printBackground: true,
155
+ format: 'A4',
156
+ displayHeaderFooter: true,
157
+ headerTemplate: '<div />',
158
+ footerTemplate: footer
159
+ });
160
+ if (verbose) console.log('PDF generation success.');
161
+
162
+ } catch (err) {
163
+ console.log(`Error generating PDF ${target_file} - ${err}`);
164
+ }
165
+
166
+ // Close the browser instance
167
+ await browser.close();
168
+ };
169
+ })();
package/hdoc-build.js CHANGED
@@ -10,12 +10,17 @@
10
10
  validate = require(path.join(__dirname, 'hdoc-validate.js')),
11
11
  hdoc = require(path.join(__dirname, 'hdoc-module.js')),
12
12
  hdoc_build_db = require(path.join(__dirname, 'hdoc-build-db.js')),
13
+ hdoc_build_pdf = require(path.join(__dirname, 'hdoc-build-pdf.js')),
13
14
  hdoc_index = require(path.join(__dirname, 'hdoc-db.js')),
14
15
  zipper = require('zip-local');
15
16
 
16
17
  const h_tags_to_search = ['h1', 'h2', 'h3'],
17
18
  doc_header_template_path = path.join(__dirname, 'templates', 'doc-header.html'),
18
- non_git_doc_header_template_path = path.join(__dirname, 'templates', 'doc-header-non-git.html');
19
+ non_git_doc_header_template_path = path.join(__dirname, 'templates', 'doc-header-non-git.html'),
20
+ pdf_header_template_path = path.join(__dirname, 'templates', 'pdf-header.html'),
21
+ non_git_pdf_header_template_path = path.join(__dirname, 'templates', 'pdf-header-non-git.html'),
22
+ pdf_template_path = path.join(__dirname, 'templates', 'pdf'),
23
+ pdf_template_file_path = path.join(pdf_template_path, 'template.html');
19
24
 
20
25
  let bc = {}, // Breadcrumbs map
21
26
  book_read_time = 0,
@@ -25,6 +30,9 @@
25
30
  conversion_failed = 0,
26
31
  doc_header_template = '',
27
32
  doc_header_template_non_git = '',
33
+ pdf_header_template = '',
34
+ pdf_header_template_non_git = '',
35
+ pdf_template = '',
28
36
  doc_id = '',
29
37
  git_token = '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', // Github fine-grained personal access token that has minimum read-only access to Hornbill Docs org repo content
30
38
  hdocbook_config = {},
@@ -211,7 +219,7 @@
211
219
  }
212
220
  };
213
221
 
214
- const transform_markdown_and_save_html = async function (file_path) {
222
+ const transform_markdown_and_save_html = async function (file_path, verbose) {
215
223
  conversion_attempted++;
216
224
  if (fs.existsSync(file_path.path)) {
217
225
  // Load markdown file
@@ -372,17 +380,24 @@
372
380
  fm_header += ']]-->';
373
381
 
374
382
  let doc_header = '';
383
+ let pdf_header = '';
375
384
  if (hdocbook_config.publicSource.includes('github.com/Hornbill-Docs')) {
376
385
  // Build doc header from template and frontmatter tags
377
386
  doc_header = process_doc_header(fm_headers, file_path.relativePath, doc_header_template);
387
+ pdf_header = process_doc_header(fm_headers, file_path.relativePath, pdf_header_template);
378
388
  } else {
379
389
  // Build doc header from template and frontmatter tags
380
390
  doc_header = process_doc_header(fm_headers, file_path.relativePath, doc_header_template_non_git);
391
+ pdf_header = process_doc_header(fm_headers, file_path.relativePath, pdf_header_template_non_git);
381
392
  }
382
- /*
383
- const pdf_html = `${fm_header}\n${doc_header}\n${html_txt}`;
384
- const pdf_file = file_path.path.replace(path.extname(file_path.path), '.pdf');
385
- */
393
+
394
+ let pdf_txt = await hdoc_build_pdf.process_images(file_path, html_txt);
395
+ pdf_txt = `${pdf_header}\n${pdf_txt}`;
396
+
397
+ // Generate PDF file from HTML
398
+ const pdf_file_path = file_path.path.replace(path.extname(file_path.path), '.pdf');
399
+ await hdoc_build_pdf.generate_pdf(pdf_template_path, pdf_template, hdocbook_config, pdf_txt, pdf_file_path, verbose);
400
+
386
401
  html_txt = `${fm_header}\n${doc_header}\n${html_txt}`;
387
402
 
388
403
  // Save HTML into HTML file
@@ -658,21 +673,32 @@
658
673
  try {
659
674
  doc_header_template = fs.readFileSync(doc_header_template_path, 'utf8');
660
675
  doc_header_template_non_git = fs.readFileSync(non_git_doc_header_template_path, 'utf8');
676
+ pdf_header_template = fs.readFileSync(pdf_header_template_path, 'utf8');
677
+ pdf_header_template_non_git = fs.readFileSync(non_git_pdf_header_template_path, 'utf8');
661
678
  } catch (err) {
662
679
  console.log(`Error reading document header template: ${err}`);
663
680
  process.exit(1);
664
681
  }
665
682
 
683
+ // Load PDF templates
684
+ try {
685
+ pdf_template = fs.readFileSync(pdf_template_file_path, 'utf8');
686
+ } catch (err) {
687
+ console.log(`Error reading PDF template: ${err}`);
688
+ process.exit(1);
689
+ }
690
+
666
691
  build_breadcrumbs(hdocbook_config.navigation.items);
667
692
 
693
+ console.log('Processing content...');
668
694
  // Get a list of MD files in work_path
669
695
  dree.scan(work_path, dreeOptions, build_file_callback);
670
696
 
671
697
  // Work through MD files and convert to HTML
672
698
  for (let i = 0; i < md_files.length; i++) {
673
- await transform_markdown_and_save_html(md_files[i]);
699
+ await transform_markdown_and_save_html(md_files[i], verbose);
674
700
  }
675
-
701
+
676
702
  // Work through Static HTML files and add Frontmatter tags
677
703
  for (let i = 0; i < static_html_files.length; i++) {
678
704
  await transform_static_html(static_html_files[i]);
package/hdoc-init.js CHANGED
@@ -3,7 +3,6 @@
3
3
 
4
4
  // Required modules
5
5
  const prompt = require('prompt');
6
- //const fs = require('fs');
7
6
  const fs = require('fs-extra');
8
7
  const path = require('path');
9
8
 
package/hdoc-validate.js CHANGED
@@ -1,5 +1,3 @@
1
- const parseLinkDestination = require('markdown-it/lib/helpers/parse_link_destination');
2
-
3
1
  (function () {
4
2
  'use strict';
5
3
 
package/hdoc.js CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
 
3
3
  (async function () {
4
4
  'use strict';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hdoc-tools",
3
- "version": "0.8.23",
3
+ "version": "0.8.25",
4
4
  "description": "Hornbill HDocBook Development Support Tool",
5
5
  "main": "hdoc.js",
6
6
  "bin": {
@@ -11,6 +11,7 @@
11
11
  "hdoc-db.js",
12
12
  "hdoc-build.js",
13
13
  "hdoc-build-db.js",
14
+ "hdoc-build-pdf.js",
14
15
  "hdoc-help.js",
15
16
  "hdoc-init.js",
16
17
  "hdoc-module.js",
@@ -43,9 +44,10 @@
43
44
  "markdown-it": "^13.0.1",
44
45
  "markdown-it-container": "^3.0.0",
45
46
  "markdown-it-front-matter": "^0.2.3",
47
+ "mime-types": "^2.1.35",
46
48
  "multer": "^1.4.5-lts.1",
47
- "pdf-creator-node": "^2.3.5",
48
49
  "prompt": "^1.3.0",
50
+ "puppeteer": "^19.6.0",
49
51
  "stream": "0.0.2",
50
52
  "sync-request": "^6.1.0",
51
53
  "words-count": "^2.0.2",
@@ -0,0 +1,90 @@
1
+ .custom-block {
2
+ border: 1px solid transparent;
3
+ border-radius: 8px;
4
+ padding: 16px 16px 8px;
5
+ line-height: 24px;
6
+ font-size: var(--htl-default-font-size);
7
+ color: var(--htl-c-text-2);
8
+ }
9
+
10
+ .custom-block.info {
11
+ border-color: var(--htl-custom-block-info-border);
12
+ color: var(--htl-custom-block-info-text);
13
+ background-color: var(--htl-custom-block-info-bg);
14
+ }
15
+
16
+ .custom-block.info code {
17
+ background-color: var(--htl-custom-block-info-code-bg);
18
+ }
19
+
20
+ .custom-block.tip {
21
+ border-color: var(--htl-custom-block-tip-border);
22
+ color: var(--htl-custom-block-tip-text);
23
+ background-color: var(--htl-custom-block-tip-bg);
24
+ }
25
+
26
+ .custom-block.tip code {
27
+ background-color: var(--htl-custom-block-tip-code-bg);
28
+ }
29
+
30
+ .custom-block.warning {
31
+ border-color: var(--htl-custom-block-warning-border);
32
+ color: var(--htl-custom-block-warning-text);
33
+ background-color: var(--htl-custom-block-warning-bg);
34
+ }
35
+
36
+ .custom-block.warning code {
37
+ background-color: var(--htl-custom-block-warning-code-bg);
38
+ }
39
+
40
+ .custom-block.danger {
41
+ border-color: var(--htl-custom-block-danger-border);
42
+ color: var(--htl-custom-block-danger-text);
43
+ background-color: var(--htl-custom-block-danger-bg);
44
+ }
45
+
46
+ .custom-block.danger code {
47
+ background-color: var(--htl-custom-block-danger-code-bg);
48
+ }
49
+
50
+ .custom-block.details {
51
+ border-color: var(--htl-custom-block-details-border);
52
+ color: var(--htl-custom-block-details-text);
53
+ background-color: var(--htl-custom-block-details-bg);
54
+ }
55
+
56
+ .custom-block.details code {
57
+ background-color: var(--htl-custom-block-details-code-bg);
58
+ }
59
+
60
+ .custom-block-title {
61
+ font-weight: 700;
62
+ }
63
+
64
+ .custom-block p + p {
65
+ margin: 8px 0;
66
+ }
67
+
68
+ .custom-block.details summary {
69
+ margin: 0 0 8px;
70
+ font-weight: 700;
71
+ }
72
+
73
+ .custom-block.details summary + p {
74
+ margin: 8px 0;
75
+ }
76
+
77
+ .custom-block a {
78
+ color: inherit;
79
+ font-weight: 600;
80
+ text-decoration: underline;
81
+ transition: opacity 0.25s;
82
+ }
83
+
84
+ .custom-block a:hover {
85
+ opacity: 0.6;
86
+ }
87
+
88
+ .custom-block code {
89
+ font-size: var(--htl-custom-block-code-font-size);
90
+ }
@@ -0,0 +1,221 @@
1
+ /* webfont-marker-begin */
2
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap');
3
+ /* webfont-marker-end */
4
+
5
+ @font-face {
6
+ font-family: 'Inter var';
7
+ font-weight: 100 900;
8
+ font-display: swap;
9
+ font-style: normal;
10
+ font-named-instance: 'Regular';
11
+ src: url('../fonts/inter-roman-cyrillic.woff2') format('woff2');
12
+ unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
13
+ }
14
+
15
+ @font-face {
16
+ font-family: 'Inter var';
17
+ font-weight: 100 900;
18
+ font-display: swap;
19
+ font-style: normal;
20
+ font-named-instance: 'Regular';
21
+ src: url('../fonts/inter-roman-cyrillic-ext.woff2') format('woff2');
22
+ unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
23
+ U+FE2E-FE2F;
24
+ }
25
+
26
+ @font-face {
27
+ font-family: 'Inter var';
28
+ font-weight: 100 900;
29
+ font-display: swap;
30
+ font-style: normal;
31
+ font-named-instance: 'Regular';
32
+ src: url('../fonts/inter-roman-greek.woff2') format('woff2');
33
+ unicode-range: U+0370-03FF;
34
+ }
35
+
36
+ @font-face {
37
+ font-family: 'Inter var';
38
+ font-weight: 100 900;
39
+ font-display: swap;
40
+ font-style: normal;
41
+ font-named-instance: 'Regular';
42
+ src: url('../fonts/inter-roman-greek-ext.woff2') format('woff2');
43
+ unicode-range: U+1F00-1FFF;
44
+ }
45
+
46
+ @font-face {
47
+ font-family: 'Inter var';
48
+ font-weight: 100 900;
49
+ font-display: swap;
50
+ font-style: normal;
51
+ font-named-instance: 'Regular';
52
+ src: url('../fonts/inter-roman-latin.woff2') format('woff2');
53
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
54
+ U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
55
+ U+FEFF, U+FFFD;
56
+ }
57
+
58
+ @font-face {
59
+ font-family: 'Inter var';
60
+ font-weight: 100 900;
61
+ font-display: swap;
62
+ font-style: normal;
63
+ font-named-instance: 'Regular';
64
+ src: url('../fonts/inter-roman-latin-ext.woff2') format('woff2');
65
+ unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
66
+ U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
67
+ }
68
+
69
+ @font-face {
70
+ font-family: 'Inter var';
71
+ font-weight: 100 900;
72
+ font-display: swap;
73
+ font-style: normal;
74
+ font-named-instance: 'Regular';
75
+ src: url('../fonts/inter-roman-vietnamese.woff2') format('woff2');
76
+ unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
77
+ U+01AF-01B0, U+1EA0-1EF9, U+20AB;
78
+ }
79
+
80
+ @font-face {
81
+ font-family: 'Inter var';
82
+ font-weight: 100 900;
83
+ font-display: swap;
84
+ font-style: italic;
85
+ font-named-instance: 'Italic';
86
+ src: url('../fonts/inter-italic-cyrillic.woff2') format('woff2');
87
+ unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
88
+ }
89
+
90
+ @font-face {
91
+ font-family: 'Inter var';
92
+ font-weight: 100 900;
93
+ font-display: swap;
94
+ font-style: italic;
95
+ font-named-instance: 'Italic';
96
+ src: url('../fonts/inter-italic-cyrillic-ext.woff2') format('woff2');
97
+ unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
98
+ U+FE2E-FE2F;
99
+ }
100
+
101
+ @font-face {
102
+ font-family: 'Inter var';
103
+ font-weight: 100 900;
104
+ font-display: swap;
105
+ font-style: italic;
106
+ font-named-instance: 'Italic';
107
+ src: url('../fonts/inter-italic-greek.woff2') format('woff2');
108
+ unicode-range: U+0370-03FF;
109
+ }
110
+
111
+ @font-face {
112
+ font-family: 'Inter var';
113
+ font-weight: 100 900;
114
+ font-display: swap;
115
+ font-style: italic;
116
+ font-named-instance: 'Italic';
117
+ src: url('../fonts/inter-italic-greek-ext.woff2') format('woff2');
118
+ unicode-range: U+1F00-1FFF;
119
+ }
120
+
121
+ @font-face {
122
+ font-family: 'Inter var';
123
+ font-weight: 100 900;
124
+ font-display: swap;
125
+ font-style: italic;
126
+ font-named-instance: 'Italic';
127
+ src: url('../fonts/inter-italic-latin.woff2') format('woff2');
128
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
129
+ U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
130
+ U+FEFF, U+FFFD;
131
+ }
132
+
133
+ @font-face {
134
+ font-family: 'Inter var';
135
+ font-weight: 100 900;
136
+ font-display: swap;
137
+ font-style: italic;
138
+ font-named-instance: 'Italic';
139
+ src: url('../fonts/inter-italic-latin-ext.woff2') format('woff2');
140
+ unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
141
+ U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
142
+ }
143
+
144
+ @font-face {
145
+ font-family: 'Inter var';
146
+ font-weight: 100 900;
147
+ font-display: swap;
148
+ font-style: italic;
149
+ font-named-instance: 'Italic';
150
+ src: url('../fonts/inter-italic-vietnamese.woff2') format('woff2');
151
+ unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
152
+ U+01AF-01B0, U+1EA0-1EF9, U+20AB;
153
+ }
154
+
155
+ @font-face {
156
+ font-family: 'Inter var experimental';
157
+ font-weight: 100 900;
158
+ font-display: swap;
159
+ font-style: oblique 0deg 10deg;
160
+ src: url('../fonts/inter-cyrillic.woff2') format('woff2');
161
+ unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
162
+ }
163
+
164
+ @font-face {
165
+ font-family: 'Inter var experimental';
166
+ font-weight: 100 900;
167
+ font-display: swap;
168
+ font-style: oblique 0deg 10deg;
169
+ src: url('../fonts/inter-cyrillic-ext.woff2') format('woff2');
170
+ unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
171
+ U+FE2E-FE2F;
172
+ }
173
+
174
+ @font-face {
175
+ font-family: 'Inter var experimental';
176
+ font-weight: 100 900;
177
+ font-display: swap;
178
+ font-style: oblique 0deg 10deg;
179
+ src: url('../fonts/inter-greek.woff2') format('woff2');
180
+ unicode-range: U+0370-03FF;
181
+ }
182
+
183
+ @font-face {
184
+ font-family: 'Inter var experimental';
185
+ font-weight: 100 900;
186
+ font-display: swap;
187
+ font-style: oblique 0deg 10deg;
188
+ src: url('../fonts/inter-greek-ext.woff2') format('woff2');
189
+ unicode-range: U+1F00-1FFF;
190
+ }
191
+
192
+ @font-face {
193
+ font-family: 'Inter var experimental';
194
+ font-weight: 100 900;
195
+ font-display: swap;
196
+ font-style: oblique 0deg 10deg;
197
+ src: url('../fonts/inter-latin.woff2') format('woff2');
198
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
199
+ U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
200
+ U+FEFF, U+FFFD;
201
+ }
202
+
203
+ @font-face {
204
+ font-family: 'Inter var experimental';
205
+ font-weight: 100 900;
206
+ font-display: swap;
207
+ font-style: oblique 0deg 10deg;
208
+ src: url('../fonts/inter-latin-ext.woff2') format('woff2');
209
+ unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
210
+ U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
211
+ }
212
+
213
+ @font-face {
214
+ font-family: 'Inter var experimental';
215
+ font-weight: 100 900;
216
+ font-display: swap;
217
+ font-style: oblique 0deg 10deg;
218
+ src: url('../fonts/inter-vietnamese.woff2') format('woff2');
219
+ unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
220
+ U+01AF-01B0, U+1EA0-1EF9, U+20AB;
221
+ }