mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-07-08 00:05:00 +00:00
Clean up web code errors and make CI enforce them
This commit is contained in:
parent
14de67c5a7
commit
1ee5ffbbe8
18 changed files with 44 additions and 129 deletions
|
@ -40,7 +40,7 @@ module.exports = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
extends: ["plugin:@typescript-eslint/disable-type-checked"],
|
extends: ["plugin:@typescript-eslint/disable-type-checked"],
|
||||||
files: [".eslintrc.cjs"],
|
files: ["./*.js", "./*.cjs"],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
rules: {
|
rules: {
|
||||||
|
|
|
@ -30,7 +30,7 @@ if (isInstallNeeded()) {
|
||||||
|
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log("Finished installing npm packages.");
|
console.log("Finished installing npm packages.");
|
||||||
} catch (error) {
|
} catch (_) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.error("Failed to install npm packages. Please run `npm install` from the `/frontend` directory.");
|
console.error("Failed to install npm packages. Please run `npm install` from the `/frontend` directory.");
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
"build-profiling": "npm run wasm:build-profiling && vite build",
|
"build-profiling": "npm run wasm:build-profiling && vite build",
|
||||||
"build": "npm run wasm:build-production && vite build",
|
"build": "npm run wasm:build-production && vite build",
|
||||||
"---------- UTILITIES ----------": "",
|
"---------- UTILITIES ----------": "",
|
||||||
"lint": "eslint .",
|
"lint": "eslint . && tsc --noEmit",
|
||||||
"lint-fix": "eslint . --fix",
|
"lint-fix": "eslint . --fix && tsc --noEmit",
|
||||||
"---------- INTERNAL ----------": "",
|
"---------- INTERNAL ----------": "",
|
||||||
"setup": "node package-installer.js",
|
"setup": "node package-installer.js",
|
||||||
"wasm:build-dev": "wasm-pack build ./wasm --dev --target=web",
|
"wasm:build-dev": "wasm-pack build ./wasm --dev --target=web",
|
||||||
|
@ -30,7 +30,6 @@
|
||||||
"@tauri-apps/api": "^1.6.0",
|
"@tauri-apps/api": "^1.6.0",
|
||||||
"class-transformer": "^0.5.1",
|
"class-transformer": "^0.5.1",
|
||||||
"idb-keyval": "^6.2.1",
|
"idb-keyval": "^6.2.1",
|
||||||
"paper": "^0.12.18",
|
|
||||||
"reflect-metadata": "^0.2.2"
|
"reflect-metadata": "^0.2.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
@ -203,7 +203,7 @@
|
||||||
|
|
||||||
function setColorRGB(channel: keyof RGB, strength: number | undefined) {
|
function setColorRGB(channel: keyof RGB, strength: number | undefined) {
|
||||||
// Do nothing if the given value is undefined
|
// Do nothing if the given value is undefined
|
||||||
if (strength === undefined) undefined;
|
if (strength === undefined) return undefined;
|
||||||
// Set the specified channel to the given value
|
// Set the specified channel to the given value
|
||||||
else if (channel === "r") setColor(new Color(strength / 255, newColor.green, newColor.blue, newColor.alpha));
|
else if (channel === "r") setColor(new Color(strength / 255, newColor.green, newColor.blue, newColor.alpha));
|
||||||
else if (channel === "g") setColor(new Color(newColor.red, strength / 255, newColor.blue, newColor.alpha));
|
else if (channel === "g") setColor(new Color(newColor.red, strength / 255, newColor.blue, newColor.alpha));
|
||||||
|
@ -212,7 +212,7 @@
|
||||||
|
|
||||||
function setColorHSV(channel: keyof HSV, strength: number | undefined) {
|
function setColorHSV(channel: keyof HSV, strength: number | undefined) {
|
||||||
// Do nothing if the given value is undefined
|
// Do nothing if the given value is undefined
|
||||||
if (strength === undefined) undefined;
|
if (strength === undefined) return undefined;
|
||||||
// Set the specified channel to the given value
|
// Set the specified channel to the given value
|
||||||
else if (channel === "h") hue = strength / 360;
|
else if (channel === "h") hue = strength / 360;
|
||||||
else if (channel === "s") saturation = strength / 100;
|
else if (channel === "s") saturation = strength / 100;
|
||||||
|
|
|
@ -219,7 +219,7 @@
|
||||||
|
|
||||||
childReference.open = true;
|
childReference.open = true;
|
||||||
// The reason we bother taking `highlightdEntry` as an argument is because, when this function is called, it can ensure `highlightedEntry` is not undefined.
|
// The reason we bother taking `highlightdEntry` as an argument is because, when this function is called, it can ensure `highlightedEntry` is not undefined.
|
||||||
// But here we still have to set `highlighted` to itself so Svelte knows to reactively update it after we set its `.ref.open` property.
|
// But here we still have to set `highlighted` to itself so Svelte knows to reactively update it after we set its `childReference.open` property.
|
||||||
highlighted = highlighted;
|
highlighted = highlighted;
|
||||||
|
|
||||||
// Highlight first item
|
// Highlight first item
|
||||||
|
@ -452,11 +452,11 @@
|
||||||
|
|
||||||
{#if entry.children}
|
{#if entry.children}
|
||||||
<MenuList
|
<MenuList
|
||||||
on:naturalWidth={() => {
|
on:naturalWidth={({ detail }) => {
|
||||||
// We do a manual dispatch here instead of just `on:naturalWidth` as a workaround for the <script> tag
|
// We do a manual dispatch here instead of just `on:naturalWidth` as a workaround for the <script> tag
|
||||||
// at the top of this file displaying a "'render' implicitly has return type 'any' because..." error.
|
// at the top of this file displaying a "'render' implicitly has return type 'any' because..." error.
|
||||||
// See explanation at <https://github.com/sveltejs/language-tools/issues/452#issuecomment-723148184>.
|
// See explanation at <https://github.com/sveltejs/language-tools/issues/452#issuecomment-723148184>.
|
||||||
dispatch("naturalWidth");
|
dispatch("naturalWidth", detail);
|
||||||
}}
|
}}
|
||||||
open={getChildReference(entry)?.open || false}
|
open={getChildReference(entry)?.open || false}
|
||||||
direction="TopRight"
|
direction="TopRight"
|
||||||
|
|
|
@ -178,10 +178,10 @@
|
||||||
const { nodeOutput, nodeInput } = resolveWire(wire);
|
const { nodeOutput, nodeInput } = resolveWire(wire);
|
||||||
if (!nodeOutput || !nodeInput) return [];
|
if (!nodeOutput || !nodeInput) return [];
|
||||||
|
|
||||||
const wireStartNode = $nodeGraph.nodes.get((wire.wireStart as Node).nodeId);
|
const wireStartNode = wire.wireStart.nodeId !== undefined ? $nodeGraph.nodes.get(wire.wireStart.nodeId) : undefined;
|
||||||
const wireStart = wireStartNode?.isLayer || false;
|
const wireStart = wireStartNode?.isLayer || false;
|
||||||
|
|
||||||
const wireEndNode = $nodeGraph.nodes.get((wire.wireEnd as Node).nodeId);
|
const wireEndNode = wire.wireEnd.nodeId !== undefined ? $nodeGraph.nodes.get(wire.wireEnd.nodeId) : undefined;
|
||||||
const wireEnd = (wireEndNode?.isLayer && Number(wire.wireEnd.index) === 0) || false;
|
const wireEnd = (wireEndNode?.isLayer && Number(wire.wireEnd.index) === 0) || false;
|
||||||
|
|
||||||
return [createWirePath(nodeOutput, nodeInput, wireStart, wireEnd, wire.dashed)];
|
return [createWirePath(nodeOutput, nodeInput, wireStart, wireEnd, wire.dashed)];
|
||||||
|
|
|
@ -42,11 +42,8 @@
|
||||||
(e.target as HTMLElement | undefined)?.focus();
|
(e.target as HTMLElement | undefined)?.focus();
|
||||||
|
|
||||||
// Open the menu list floating menu
|
// Open the menu list floating menu
|
||||||
if (self) {
|
if (self) self.open = true;
|
||||||
self.open = true;
|
else throw new Error("The menu bar floating menu has no reference to `self`");
|
||||||
} else {
|
|
||||||
throw new Error("The menu bar floating menu has no associated ref");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
activeEntrySkipWatcher = false;
|
activeEntrySkipWatcher = false;
|
||||||
} else if (activeEntry !== DASH_ENTRY) {
|
} else if (activeEntry !== DASH_ENTRY) {
|
||||||
// We need to set to the initial value first to track a right history step, as if we hover in initial selection.
|
// We need to set to the initial value first to track a right history step, as if we hover in initial selection.
|
||||||
dispatch("hoverInEntry", initialSelectedIndex);
|
if (initialSelectedIndex !== undefined) dispatch("hoverInEntry", initialSelectedIndex);
|
||||||
dispatch("selectedIndex", entries.flat().indexOf(activeEntry));
|
dispatch("selectedIndex", entries.flat().indexOf(activeEntry));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function dispatchHoverOutEntry() {
|
function dispatchHoverOutEntry() {
|
||||||
dispatch("hoverOutEntry", initialSelectedIndex);
|
if (initialSelectedIndex !== undefined) dispatch("hoverOutEntry", initialSelectedIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeActiveEntry(): MenuListEntry {
|
function makeActiveEntry(): MenuListEntry {
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
const pointerPosition = (direction: ScrollbarDirection, e: PointerEvent): number => (direction === "Vertical" ? e.clientY : e.clientX);
|
const pointerPosition = (direction: ScrollbarDirection, e: PointerEvent): number => (direction === "Vertical" ? e.clientY : e.clientX);
|
||||||
|
|
||||||
const dispatch = createEventDispatcher<{ handlePosition: number; pressTrack: number; pointerup }>();
|
const dispatch = createEventDispatcher<{ handlePosition: number; pressTrack: number; pointerup: undefined }>();
|
||||||
|
|
||||||
export let direction: ScrollbarDirection = "Vertical";
|
export let direction: ScrollbarDirection = "Vertical";
|
||||||
export let handlePosition = 0.5;
|
export let handlePosition = 0.5;
|
||||||
|
|
|
@ -59,10 +59,9 @@
|
||||||
|
|
||||||
// New fields in `MenuListEntry`
|
// New fields in `MenuListEntry`
|
||||||
shortcutRequiresLock: entry.shortcut ? shortcutRequiresLock(entry.shortcut.keys) : undefined,
|
shortcutRequiresLock: entry.shortcut ? shortcutRequiresLock(entry.shortcut.keys) : undefined,
|
||||||
value: undefined,
|
value: "",
|
||||||
disabled: entry.disabled ?? undefined,
|
disabled: entry.disabled ?? undefined,
|
||||||
font: undefined,
|
font: undefined,
|
||||||
ref: undefined,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
entries = updateMenuBarLayout.layout.map(menuBarEntryToMenuListEntry);
|
entries = updateMenuBarLayout.layout.map(menuBarEntryToMenuListEntry);
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
import paper from "paper/dist/paper-core";
|
|
||||||
|
|
||||||
// Required setup to be used headlessly
|
|
||||||
paper.setup(new paper.Size(1, 1));
|
|
||||||
paper.view.autoUpdate = false;
|
|
||||||
|
|
||||||
export function booleanUnion(path1: string, path2: string): string {
|
|
||||||
return booleanOperation(path1, path2, "unite");
|
|
||||||
}
|
|
||||||
|
|
||||||
export function booleanSubtract(path1: string, path2: string): string {
|
|
||||||
return booleanOperation(path1, path2, "subtract");
|
|
||||||
}
|
|
||||||
|
|
||||||
export function booleanIntersect(path1: string, path2: string): string {
|
|
||||||
return booleanOperation(path1, path2, "intersect");
|
|
||||||
}
|
|
||||||
|
|
||||||
function booleanOperation(path1: string, path2: string, operation: "unite" | "subtract" | "intersect"): string {
|
|
||||||
const paperPath1 = new paper.CompoundPath(path1);
|
|
||||||
const paperPath2 = new paper.CompoundPath(path2);
|
|
||||||
const result = paperPath1[operation](paperPath2);
|
|
||||||
paperPath1.remove();
|
|
||||||
paperPath2.remove();
|
|
||||||
return result.pathData;
|
|
||||||
}
|
|
|
@ -12,31 +12,12 @@ export class JsMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
const TupleToVec2 = Transform(({ value }: { value: [number, number] | undefined }) => (value === undefined ? undefined : { x: value[0], y: value[1] }));
|
const TupleToVec2 = Transform(({ value }: { value: [number, number] | undefined }) => (value === undefined ? undefined : { x: value[0], y: value[1] }));
|
||||||
const ImportsToVec2Array = Transform(({ obj }) => {
|
const ImportsToVec2Array = Transform(({ obj: { imports } }: { obj: { imports: [FrontendGraphOutput, number, number][] } }) =>
|
||||||
const imports: { outputMetadata: FrontendGraphOutput; position: XY }[] = [];
|
imports.map(([outputMetadata, x, y]) => ({ outputMetadata, position: { x, y } })),
|
||||||
obj.imports.forEach(([outputMetadata, x, y]: [FrontendGraphOutput, number, number]) => {
|
);
|
||||||
outputMetadata.connectedTo = outputMetadata.connectedTo.map((connector: any) => {
|
const ExportsToVec2Array = Transform(({ obj: { exports } }: { obj: { exports: [FrontendGraphInput, number, number][] } }) =>
|
||||||
if (connector.export !== undefined) return { index: connector.export.index };
|
exports.map(([inputMetadata, x, y]) => ({ inputMetadata, position: { x, y } })),
|
||||||
return { nodeId: connector.node.nodeId, index: connector.node.inputIndex };
|
);
|
||||||
});
|
|
||||||
imports.push({ outputMetadata, position: { x, y } });
|
|
||||||
});
|
|
||||||
return imports;
|
|
||||||
});
|
|
||||||
const ExportsToVec2Array = Transform(({ obj }) => {
|
|
||||||
const exports: { inputMetadata: FrontendGraphInput; position: XY }[] = [];
|
|
||||||
obj.exports.forEach(([inputMetadata, x, y]: [FrontendGraphInput, number, number]) => {
|
|
||||||
if (inputMetadata.connectedTo !== undefined) {
|
|
||||||
if (inputMetadata.connectedTo?.import !== undefined) {
|
|
||||||
inputMetadata.connectedTo = { index: inputMetadata.connectedTo?.import.index };
|
|
||||||
} else {
|
|
||||||
inputMetadata.connectedTo = { nodeId: inputMetadata.connectedTo?.node.nodeId, index: inputMetadata.connectedTo?.node.outputIndex };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.push({ inputMetadata, position: { x, y } });
|
|
||||||
});
|
|
||||||
return exports;
|
|
||||||
});
|
|
||||||
|
|
||||||
// const BigIntTupleToVec2 = Transform(({ value }: { value: [bigint, bigint] | undefined }) => (value === undefined ? undefined : { x: Number(value[0]), y: Number(value[1]) }));
|
// const BigIntTupleToVec2 = Transform(({ value }: { value: [bigint, bigint] | undefined }) => (value === undefined ? undefined : { x: Number(value[0]), y: Number(value[1]) }));
|
||||||
|
|
||||||
|
@ -187,22 +168,11 @@ export type ContextMenuInformation = {
|
||||||
export type FrontendGraphDataType = "General" | "Raster" | "VectorData" | "Number" | "Graphic" | "Artboard";
|
export type FrontendGraphDataType = "General" | "Raster" | "VectorData" | "Number" | "Graphic" | "Artboard";
|
||||||
|
|
||||||
export class Node {
|
export class Node {
|
||||||
readonly nodeId!: bigint;
|
|
||||||
readonly index!: bigint;
|
readonly index!: bigint;
|
||||||
|
// Omitted if this Node is an Import or Export to/from the node network
|
||||||
|
readonly nodeId?: bigint;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Export {
|
|
||||||
readonly index!: bigint;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Import {
|
|
||||||
readonly index!: bigint;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type OutputConnector = Node | Import;
|
|
||||||
|
|
||||||
export type InputConnector = Node | Export;
|
|
||||||
|
|
||||||
const CreateOutputConnectorOptional = Transform(({ obj }) => {
|
const CreateOutputConnectorOptional = Transform(({ obj }) => {
|
||||||
if (obj.connectedTo == undefined) {
|
if (obj.connectedTo == undefined) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -228,11 +198,11 @@ export class FrontendGraphInput {
|
||||||
readonly resolvedType!: string | undefined;
|
readonly resolvedType!: string | undefined;
|
||||||
|
|
||||||
@CreateOutputConnectorOptional
|
@CreateOutputConnectorOptional
|
||||||
connectedTo!: OutputConnector | undefined;
|
connectedTo!: Node | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CreateInputConnectorArray = Transform(({ obj }) => {
|
const CreateInputConnectorArray = Transform(({ obj }) => {
|
||||||
const newInputConnectors: InputConnector[] = [];
|
const newInputConnectors: Node[] = [];
|
||||||
obj.connectedTo.forEach((connector: any) => {
|
obj.connectedTo.forEach((connector: any) => {
|
||||||
if (connector.export !== undefined) {
|
if (connector.export !== undefined) {
|
||||||
newInputConnectors.push({ index: connector.export });
|
newInputConnectors.push({ index: connector.export });
|
||||||
|
@ -257,7 +227,7 @@ export class FrontendGraphOutput {
|
||||||
readonly resolvedType!: string | undefined;
|
readonly resolvedType!: string | undefined;
|
||||||
|
|
||||||
@CreateInputConnectorArray
|
@CreateInputConnectorArray
|
||||||
readonly connectedTo!: InputConnector[];
|
connectedTo!: Node[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export class FrontendNode {
|
export class FrontendNode {
|
||||||
|
@ -329,10 +299,10 @@ const CreateInputConnector = Transform(({ obj }) => {
|
||||||
|
|
||||||
export class FrontendNodeWire {
|
export class FrontendNodeWire {
|
||||||
@CreateOutputConnector
|
@CreateOutputConnector
|
||||||
readonly wireStart!: OutputConnector;
|
readonly wireStart!: Node;
|
||||||
|
|
||||||
@CreateInputConnector
|
@CreateInputConnector
|
||||||
readonly wireEnd!: InputConnector;
|
readonly wireEnd!: Node;
|
||||||
|
|
||||||
readonly dashed!: boolean;
|
readonly dashed!: boolean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
// #![cfg(target_arch = "wasm32")]
|
|
||||||
|
|
||||||
// use wasm_bindgen_test::*;
|
|
||||||
|
|
||||||
// wasm_bindgen_test_configure!(run_in_browser);
|
|
||||||
|
|
||||||
// #[wasm_bindgen_test]
|
|
||||||
// fn pass() {
|
|
||||||
// assert_eq!(1 + 1, 2);
|
|
||||||
// }
|
|
|
@ -12,12 +12,6 @@ module.exports = {
|
||||||
ecmaVersion: "latest",
|
ecmaVersion: "latest",
|
||||||
project: "./tsconfig.json",
|
project: "./tsconfig.json",
|
||||||
},
|
},
|
||||||
overrides: [
|
|
||||||
{
|
|
||||||
extends: ["plugin:@typescript-eslint/disable-type-checked"],
|
|
||||||
files: [".eslintrc.cjs"],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
ignorePatterns: [
|
ignorePatterns: [
|
||||||
// Ignore generated directories
|
// Ignore generated directories
|
||||||
"node_modules/",
|
"node_modules/",
|
||||||
|
@ -28,6 +22,12 @@ module.exports = {
|
||||||
"!.*.js",
|
"!.*.js",
|
||||||
"!.*.ts",
|
"!.*.ts",
|
||||||
],
|
],
|
||||||
|
overrides: [
|
||||||
|
{
|
||||||
|
extends: ["plugin:@typescript-eslint/disable-type-checked"],
|
||||||
|
files: ["./*.js", "./*.cjs"],
|
||||||
|
},
|
||||||
|
],
|
||||||
rules: {
|
rules: {
|
||||||
// Standard ESLint config (for ordinary JS syntax linting)
|
// Standard ESLint config (for ordinary JS syntax linting)
|
||||||
indent: "off",
|
indent: "off",
|
||||||
|
|
|
@ -30,7 +30,7 @@ if (isInstallNeeded()) {
|
||||||
|
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log("Finished installing npm packages.");
|
console.log("Finished installing npm packages.");
|
||||||
} catch (error) {
|
} catch (_) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.error("Failed to install npm packages. Please run `npm install` from the `/frontend` directory.");
|
console.error("Failed to install npm packages. Please run `npm install` from the `/frontend` directory.");
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
"build-profiling": "npm run wasm:build-profiling && vite build",
|
"build-profiling": "npm run wasm:build-profiling && vite build",
|
||||||
"build": "npm run wasm:build-production && vite build",
|
"build": "npm run wasm:build-production && vite build",
|
||||||
"---------- UTILITIES ----------": "",
|
"---------- UTILITIES ----------": "",
|
||||||
"lint": "eslint .",
|
"lint": "eslint . && tsc --noEmit",
|
||||||
"lint-fix": "eslint . --fix",
|
"lint-fix": "eslint . --fix && tsc --noEmit",
|
||||||
"---------- INTERNAL ----------": "",
|
"---------- INTERNAL ----------": "",
|
||||||
"setup": "node package-installer.js",
|
"setup": "node package-installer.js",
|
||||||
"wasm:build-dev": "wasm-pack build ./wasm --dev --target=web",
|
"wasm:build-dev": "wasm-pack build ./wasm --dev --target=web",
|
||||||
|
|
|
@ -12,27 +12,12 @@
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": [
|
"@/*": ["src/*"]
|
||||||
"src/*"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"lib": [
|
"lib": ["esnext", "dom", "dom.iterable", "scripthost"]
|
||||||
"esnext",
|
|
||||||
"dom",
|
|
||||||
"dom.iterable",
|
|
||||||
"scripthost"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"include": [
|
"include": ["src/**/*.ts", "src/**/*.d.ts", "*.ts", "*.js", "*.cjs"],
|
||||||
"src/**/*.ts",
|
"exclude": ["node_modules"],
|
||||||
"src/**/*.d.ts",
|
|
||||||
"*.ts",
|
|
||||||
"*.js",
|
|
||||||
"*.cjs"
|
|
||||||
],
|
|
||||||
"exclude": [
|
|
||||||
"node_modules"
|
|
||||||
],
|
|
||||||
"ts-node": {
|
"ts-node": {
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
|
|
|
@ -101,6 +101,7 @@
|
||||||
<footer>
|
<footer>
|
||||||
<hr />
|
<hr />
|
||||||
<nav class="balance-text require-polyfill">
|
<nav class="balance-text require-polyfill">
|
||||||
|
<a href="https://github.com/GraphiteEditor/Graphite" class="link not-uppercase">GitHub</a>
|
||||||
<a href="/license" class="link not-uppercase">License</a>
|
<a href="/license" class="link not-uppercase">License</a>
|
||||||
<a href="/logo" class="link not-uppercase">Logo</a>
|
<a href="/logo" class="link not-uppercase">Logo</a>
|
||||||
<a href="/press" class="link not-uppercase">Press</a>
|
<a href="/press" class="link not-uppercase">Press</a>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue