Add Convenience functions
This commit is contained in:
@ -3,6 +3,7 @@
|
|||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import {
|
import {
|
||||||
AlignmentType,
|
AlignmentType,
|
||||||
|
convertInchesToTwip,
|
||||||
Document,
|
Document,
|
||||||
Footer,
|
Footer,
|
||||||
HeadingLevel,
|
HeadingLevel,
|
||||||
@ -110,7 +111,7 @@ const doc = new Document({
|
|||||||
},
|
},
|
||||||
paragraph: {
|
paragraph: {
|
||||||
spacing: { line: 276 },
|
spacing: { line: 276 },
|
||||||
indent: { left: 720 },
|
indent: { left: convertInchesToTwip(0.5) },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Example on how to customise the look at feel using Styles
|
// Example on how to customise the look at feel using Styles
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { AlignmentType, Document, HeadingLevel, Packer, Paragraph, TextRun, UnderlineType } from "../build";
|
import { AlignmentType, convertInchesToTwip, Document, HeadingLevel, Packer, Paragraph, TextRun, UnderlineType } from "../build";
|
||||||
|
|
||||||
const doc = new Document({
|
const doc = new Document({
|
||||||
creator: "Clippy",
|
creator: "Clippy",
|
||||||
@ -56,7 +56,7 @@ const doc = new Document({
|
|||||||
},
|
},
|
||||||
paragraph: {
|
paragraph: {
|
||||||
indent: {
|
indent: {
|
||||||
left: 720,
|
left: convertInchesToTwip(0.5),
|
||||||
},
|
},
|
||||||
spacing: {
|
spacing: {
|
||||||
line: 276,
|
line: 276,
|
||||||
@ -168,8 +168,7 @@ doc.addSection({
|
|||||||
text: "Strong Style",
|
text: "Strong Style",
|
||||||
}),
|
}),
|
||||||
new TextRun({
|
new TextRun({
|
||||||
text:
|
text: " - Very strong.",
|
||||||
" - Very strong.",
|
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Custom styles using JavaScript configuration
|
// Custom styles using JavaScript configuration
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { Document, HeadingLevel, Packer, Paragraph, UnderlineType } from "../build";
|
import { Document, convertInchesToTwip, HeadingLevel, Packer, Paragraph, UnderlineType } from "../build";
|
||||||
|
|
||||||
const doc = new Document({
|
const doc = new Document({
|
||||||
styles: {
|
styles: {
|
||||||
@ -17,7 +17,7 @@ const doc = new Document({
|
|||||||
},
|
},
|
||||||
paragraph: {
|
paragraph: {
|
||||||
indent: {
|
indent: {
|
||||||
left: 720,
|
left: convertInchesToTwip(0.5),
|
||||||
},
|
},
|
||||||
spacing: {
|
spacing: {
|
||||||
line: 276,
|
line: 276,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Numbered lists
|
// Numbered lists
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { AlignmentType, Document, Packer, Paragraph } from "../build";
|
import { AlignmentType, convertInchesToTwip, Document, Packer, Paragraph } from "../build";
|
||||||
|
|
||||||
const doc = new Document({
|
const doc = new Document({
|
||||||
numbering: {
|
numbering: {
|
||||||
@ -15,7 +15,7 @@ const doc = new Document({
|
|||||||
alignment: AlignmentType.START,
|
alignment: AlignmentType.START,
|
||||||
style: {
|
style: {
|
||||||
paragraph: {
|
paragraph: {
|
||||||
indent: { left: 720, hanging: 260 },
|
indent: { left: convertInchesToTwip(0.5), hanging: convertInchesToTwip(0.18) },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -31,7 +31,7 @@ const doc = new Document({
|
|||||||
alignment: AlignmentType.START,
|
alignment: AlignmentType.START,
|
||||||
style: {
|
style: {
|
||||||
paragraph: {
|
paragraph: {
|
||||||
indent: { left: 720, hanging: 260 },
|
indent: { left: convertInchesToTwip(0.5), hanging: convertInchesToTwip(0.18) },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Numbering and bullet points example
|
// Numbering and bullet points example
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { AlignmentType, Document, Packer, Paragraph } from "../build";
|
import { AlignmentType, convertInchesToTwip, Document, Packer, Paragraph } from "../build";
|
||||||
|
|
||||||
const doc = new Document({
|
const doc = new Document({
|
||||||
numbering: {
|
numbering: {
|
||||||
@ -16,7 +16,7 @@ const doc = new Document({
|
|||||||
alignment: AlignmentType.START,
|
alignment: AlignmentType.START,
|
||||||
style: {
|
style: {
|
||||||
paragraph: {
|
paragraph: {
|
||||||
indent: { left: 720, hanging: 260 },
|
indent: { left: convertInchesToTwip(0.5), hanging: convertInchesToTwip(0.18) },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -27,7 +27,7 @@ const doc = new Document({
|
|||||||
alignment: AlignmentType.START,
|
alignment: AlignmentType.START,
|
||||||
style: {
|
style: {
|
||||||
paragraph: {
|
paragraph: {
|
||||||
indent: { left: 1440, hanging: 980 },
|
indent: { left: convertInchesToTwip(1), hanging: convertInchesToTwip(0.68) },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -38,7 +38,7 @@ const doc = new Document({
|
|||||||
alignment: AlignmentType.START,
|
alignment: AlignmentType.START,
|
||||||
style: {
|
style: {
|
||||||
paragraph: {
|
paragraph: {
|
||||||
indent: { left: 2160, hanging: 1700 },
|
indent: { left: convertInchesToTwip(1.5), hanging: convertInchesToTwip(1.18) },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -2,7 +2,20 @@
|
|||||||
// Also includes an example on how to center tables
|
// Also includes an example on how to center tables
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { AlignmentType, BorderStyle, Document, HeadingLevel, Packer, Paragraph, ShadingType, Table, TableCell, TableRow, WidthType } from "../build";
|
import {
|
||||||
|
AlignmentType,
|
||||||
|
BorderStyle,
|
||||||
|
convertInchesToTwip,
|
||||||
|
Document,
|
||||||
|
HeadingLevel,
|
||||||
|
Packer,
|
||||||
|
Paragraph,
|
||||||
|
ShadingType,
|
||||||
|
Table,
|
||||||
|
TableCell,
|
||||||
|
TableRow,
|
||||||
|
WidthType,
|
||||||
|
} from "../build";
|
||||||
|
|
||||||
const doc = new Document();
|
const doc = new Document();
|
||||||
|
|
||||||
@ -37,10 +50,10 @@ const table2 = new Table({
|
|||||||
new TableCell({
|
new TableCell({
|
||||||
children: [new Paragraph("World")],
|
children: [new Paragraph("World")],
|
||||||
margins: {
|
margins: {
|
||||||
top: 1000,
|
top: convertInchesToTwip(0.69),
|
||||||
bottom: 1000,
|
bottom: convertInchesToTwip(0.69),
|
||||||
left: 1000,
|
left: convertInchesToTwip(0.69),
|
||||||
right: 1000,
|
right: convertInchesToTwip(0.69),
|
||||||
},
|
},
|
||||||
columnSpan: 3,
|
columnSpan: 3,
|
||||||
}),
|
}),
|
||||||
@ -64,7 +77,7 @@ const table2 = new Table({
|
|||||||
size: 100,
|
size: 100,
|
||||||
type: WidthType.AUTO,
|
type: WidthType.AUTO,
|
||||||
},
|
},
|
||||||
columnWidths: [1000, 1000, 1000],
|
columnWidths: [convertInchesToTwip(0.69), convertInchesToTwip(0.69), convertInchesToTwip(0.69)],
|
||||||
});
|
});
|
||||||
|
|
||||||
const table3 = new Table({
|
const table3 = new Table({
|
||||||
@ -119,14 +132,14 @@ const table3 = new Table({
|
|||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
width: {
|
width: {
|
||||||
size: 7000,
|
size: convertInchesToTwip(4.86),
|
||||||
type: WidthType.DXA,
|
type: WidthType.DXA,
|
||||||
},
|
},
|
||||||
margins: {
|
margins: {
|
||||||
top: 400,
|
top: convertInchesToTwip(0.27),
|
||||||
bottom: 400,
|
bottom: convertInchesToTwip(0.27),
|
||||||
right: 400,
|
right: convertInchesToTwip(0.27),
|
||||||
left: 400,
|
left: convertInchesToTwip(0.27),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -355,9 +368,7 @@ const table8 = new Table({
|
|||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
new TableRow({
|
new TableRow({
|
||||||
children: [
|
children: [new TableCell({ children: [new Paragraph("4,1")] })],
|
||||||
new TableCell({ children: [new Paragraph("4,1")] }),
|
|
||||||
],
|
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
width: {
|
width: {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Numbered lists - Add parent number in sub number
|
// Numbered lists - Add parent number in sub number
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { AlignmentType, Document, HeadingLevel, Packer, Paragraph } from "../build";
|
import { AlignmentType, convertInchesToTwip, Document, HeadingLevel, Packer, Paragraph } from "../build";
|
||||||
|
|
||||||
const doc = new Document({
|
const doc = new Document({
|
||||||
numbering: {
|
numbering: {
|
||||||
@ -15,7 +15,7 @@ const doc = new Document({
|
|||||||
alignment: AlignmentType.START,
|
alignment: AlignmentType.START,
|
||||||
style: {
|
style: {
|
||||||
paragraph: {
|
paragraph: {
|
||||||
indent: { left: 720, hanging: 260 },
|
indent: { left: convertInchesToTwip(0.5), hanging: 260 },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -26,7 +26,7 @@ const doc = new Document({
|
|||||||
alignment: AlignmentType.START,
|
alignment: AlignmentType.START,
|
||||||
style: {
|
style: {
|
||||||
paragraph: {
|
paragraph: {
|
||||||
indent: { left: 1.25 * 720, hanging: 1.25 * 260 },
|
indent: { left: 1.25 * convertInchesToTwip(0.5), hanging: 1.25 * 260 },
|
||||||
},
|
},
|
||||||
run: {
|
run: {
|
||||||
bold: true,
|
bold: true,
|
||||||
|
@ -28,5 +28,8 @@
|
|||||||
* Exporting
|
* Exporting
|
||||||
|
|
||||||
* [Packers](usage/packers.md)
|
* [Packers](usage/packers.md)
|
||||||
|
* Utility
|
||||||
|
|
||||||
|
* [Convenience functions](usage/convenience-functions.md)
|
||||||
|
|
||||||
* [Contribution Guidelines](contribution-guidelines.md)
|
* [Contribution Guidelines](contribution-guidelines.md)
|
||||||
|
22
docs/usage/convenience-functions.md
Normal file
22
docs/usage/convenience-functions.md
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# Convenience functions
|
||||||
|
|
||||||
|
OOXML and this library mainly uses a unit called twentieths of a point or `twip` for short. a twip is a typographical measurement, defined as 1/20 of a typographical point. One twip is 1/1440 inch, or 17.64 μm. This unit is not intuitive for many users, so some functions were created to help
|
||||||
|
|
||||||
|
More info here: https://en.wikipedia.org/wiki/Twip
|
||||||
|
|
||||||
|
## Convert Inches to Twip
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { convertInchesToTwip } from "docx";
|
||||||
|
|
||||||
|
const twip = convertInchesToTwip(1); // returns 1440
|
||||||
|
const twip = convertInchesToTwip(0.5); // returns 720
|
||||||
|
```
|
||||||
|
|
||||||
|
## Convert Millimeters to Twip
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { convertMillimetersToTwip } from "docx";
|
||||||
|
|
||||||
|
const twip = convertMillimetersToTwip(50); // returns 2834
|
||||||
|
```
|
18
src/convenience-functions.spec.ts
Normal file
18
src/convenience-functions.spec.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { expect } from "chai";
|
||||||
|
import { convertInchesToTwip, convertMillimetersToTwip } from "./convenience-functions";
|
||||||
|
|
||||||
|
describe("Utility", () => {
|
||||||
|
describe("#convertMillimetersToTwip", () => {
|
||||||
|
it("should call the underlying header's addChildElement for Paragraph", () => {
|
||||||
|
expect(convertMillimetersToTwip(1000)).to.equal(56692);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("#convertInchesToTwip", () => {
|
||||||
|
it("should call the underlying header's addChildElement", () => {
|
||||||
|
expect(convertInchesToTwip(1)).to.equal(1440);
|
||||||
|
expect(convertInchesToTwip(0.5)).to.equal(720);
|
||||||
|
expect(convertInchesToTwip(0.25)).to.equal(360);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
8
src/convenience-functions.ts
Normal file
8
src/convenience-functions.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// Twip - twentieths of a point
|
||||||
|
export const convertMillimetersToTwip = (millimeters: number): number => {
|
||||||
|
return Math.floor((millimeters / 25.4) * 72 * 20);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const convertInchesToTwip = (inches: number): number => {
|
||||||
|
return Math.floor(inches * 72 * 20);
|
||||||
|
};
|
@ -1,5 +1,6 @@
|
|||||||
import { expect } from "chai";
|
import { expect } from "chai";
|
||||||
|
|
||||||
|
import { convertInchesToTwip } from "convenience-functions";
|
||||||
import { Formatter } from "export/formatter";
|
import { Formatter } from "export/formatter";
|
||||||
import { FooterWrapper } from "file/footer-wrapper";
|
import { FooterWrapper } from "file/footer-wrapper";
|
||||||
import { HeaderWrapper } from "file/header-wrapper";
|
import { HeaderWrapper } from "file/header-wrapper";
|
||||||
@ -18,10 +19,10 @@ describe("SectionProperties", () => {
|
|||||||
const properties = new SectionProperties({
|
const properties = new SectionProperties({
|
||||||
width: 11906,
|
width: 11906,
|
||||||
height: 16838,
|
height: 16838,
|
||||||
top: 1440,
|
top: convertInchesToTwip(1),
|
||||||
right: 1440,
|
right: convertInchesToTwip(1),
|
||||||
bottom: 1440,
|
bottom: convertInchesToTwip(1),
|
||||||
left: 1440,
|
left: convertInchesToTwip(1),
|
||||||
header: 708,
|
header: 708,
|
||||||
footer: 708,
|
footer: 708,
|
||||||
gutter: 0,
|
gutter: 0,
|
||||||
@ -30,7 +31,7 @@ describe("SectionProperties", () => {
|
|||||||
space: 708,
|
space: 708,
|
||||||
count: 1,
|
count: 1,
|
||||||
},
|
},
|
||||||
linePitch: 360,
|
linePitch: convertInchesToTwip(0.25),
|
||||||
headers: {
|
headers: {
|
||||||
default: new HeaderWrapper(media, 100),
|
default: new HeaderWrapper(media, 100),
|
||||||
},
|
},
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// http://officeopenxml.com/WPsection.php
|
// http://officeopenxml.com/WPsection.php
|
||||||
|
import { convertInchesToTwip } from "convenience-functions";
|
||||||
import { FooterWrapper } from "file/footer-wrapper";
|
import { FooterWrapper } from "file/footer-wrapper";
|
||||||
import { HeaderWrapper } from "file/header-wrapper";
|
import { HeaderWrapper } from "file/header-wrapper";
|
||||||
import { XmlComponent } from "file/xml-components";
|
import { XmlComponent } from "file/xml-components";
|
||||||
@ -64,10 +65,10 @@ export class SectionProperties extends XmlComponent {
|
|||||||
const {
|
const {
|
||||||
width = 11906,
|
width = 11906,
|
||||||
height = 16838,
|
height = 16838,
|
||||||
top = 1440,
|
top = convertInchesToTwip(1),
|
||||||
right = 1440,
|
right = convertInchesToTwip(1),
|
||||||
bottom = 1440,
|
bottom = convertInchesToTwip(1),
|
||||||
left = 1440,
|
left = convertInchesToTwip(1),
|
||||||
header = 708,
|
header = 708,
|
||||||
footer = 708,
|
footer = 708,
|
||||||
gutter = 0,
|
gutter = 0,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// http://officeopenxml.com/WPnumbering.php
|
// http://officeopenxml.com/WPnumbering.php
|
||||||
|
import { convertInchesToTwip } from "convenience-functions";
|
||||||
import { AlignmentType } from "file/paragraph";
|
import { AlignmentType } from "file/paragraph";
|
||||||
import { IXmlableObject, XmlComponent } from "file/xml-components";
|
import { IXmlableObject, XmlComponent } from "file/xml-components";
|
||||||
|
|
||||||
@ -55,7 +56,7 @@ export class Numbering extends XmlComponent {
|
|||||||
alignment: AlignmentType.LEFT,
|
alignment: AlignmentType.LEFT,
|
||||||
style: {
|
style: {
|
||||||
paragraph: {
|
paragraph: {
|
||||||
indent: { left: 720, hanging: 360 },
|
indent: { left: convertInchesToTwip(0.5), hanging: convertInchesToTwip(0.25) },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -66,7 +67,7 @@ export class Numbering extends XmlComponent {
|
|||||||
alignment: AlignmentType.LEFT,
|
alignment: AlignmentType.LEFT,
|
||||||
style: {
|
style: {
|
||||||
paragraph: {
|
paragraph: {
|
||||||
indent: { left: 1440, hanging: 360 },
|
indent: { left: convertInchesToTwip(1), hanging: convertInchesToTwip(0.25) },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -77,7 +78,7 @@ export class Numbering extends XmlComponent {
|
|||||||
alignment: AlignmentType.LEFT,
|
alignment: AlignmentType.LEFT,
|
||||||
style: {
|
style: {
|
||||||
paragraph: {
|
paragraph: {
|
||||||
indent: { left: 2160, hanging: 360 },
|
indent: { left: 2160, hanging: convertInchesToTwip(0.25) },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -88,7 +89,7 @@ export class Numbering extends XmlComponent {
|
|||||||
alignment: AlignmentType.LEFT,
|
alignment: AlignmentType.LEFT,
|
||||||
style: {
|
style: {
|
||||||
paragraph: {
|
paragraph: {
|
||||||
indent: { left: 2880, hanging: 360 },
|
indent: { left: 2880, hanging: convertInchesToTwip(0.25) },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -99,7 +100,7 @@ export class Numbering extends XmlComponent {
|
|||||||
alignment: AlignmentType.LEFT,
|
alignment: AlignmentType.LEFT,
|
||||||
style: {
|
style: {
|
||||||
paragraph: {
|
paragraph: {
|
||||||
indent: { left: 3600, hanging: 360 },
|
indent: { left: 3600, hanging: convertInchesToTwip(0.25) },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -110,7 +111,7 @@ export class Numbering extends XmlComponent {
|
|||||||
alignment: AlignmentType.LEFT,
|
alignment: AlignmentType.LEFT,
|
||||||
style: {
|
style: {
|
||||||
paragraph: {
|
paragraph: {
|
||||||
indent: { left: 4320, hanging: 360 },
|
indent: { left: 4320, hanging: convertInchesToTwip(0.25) },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -121,7 +122,7 @@ export class Numbering extends XmlComponent {
|
|||||||
alignment: AlignmentType.LEFT,
|
alignment: AlignmentType.LEFT,
|
||||||
style: {
|
style: {
|
||||||
paragraph: {
|
paragraph: {
|
||||||
indent: { left: 5040, hanging: 360 },
|
indent: { left: 5040, hanging: convertInchesToTwip(0.25) },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -132,7 +133,7 @@ export class Numbering extends XmlComponent {
|
|||||||
alignment: AlignmentType.LEFT,
|
alignment: AlignmentType.LEFT,
|
||||||
style: {
|
style: {
|
||||||
paragraph: {
|
paragraph: {
|
||||||
indent: { left: 5760, hanging: 360 },
|
indent: { left: 5760, hanging: convertInchesToTwip(0.25) },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -143,7 +144,7 @@ export class Numbering extends XmlComponent {
|
|||||||
alignment: AlignmentType.LEFT,
|
alignment: AlignmentType.LEFT,
|
||||||
style: {
|
style: {
|
||||||
paragraph: {
|
paragraph: {
|
||||||
indent: { left: 6480, hanging: 360 },
|
indent: { left: 6480, hanging: convertInchesToTwip(0.25) },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -4,3 +4,4 @@ export { File as Document } from "./file";
|
|||||||
export * from "./file";
|
export * from "./file";
|
||||||
export * from "./export";
|
export * from "./export";
|
||||||
export * from "./import-dotx";
|
export * from "./import-dotx";
|
||||||
|
export * from "./convenience-functions";
|
||||||
|
Reference in New Issue
Block a user