From c3c3b770b037cb80a37b3508ac890699d7391083 Mon Sep 17 00:00:00 2001 From: Maks Jopek Date: Sun, 18 Apr 2021 00:03:32 +0200 Subject: Everything till generating empty game board --- .gitignore | 2 + TODO | 2 - backend/ts/api/getCurrentGameState.ts | 16 ++++ backend/ts/api/login.ts | 48 +++++++---- backend/ts/api/readyStateToggle.ts | 18 ++-- backend/ts/api/startPoint.ts | 8 +- backend/ts/index.ts | 2 + backend/ts/startGame.ts | 41 +++++++++ frontend/ts/login.ts | 53 ++++++------ frontend/ts/startGame.ts | 157 ++++++++++++++++++++++++---------- helpers/helpers.ts | 143 +++++++++++++------------------ helpers/helpersBack.ts | 86 +++++++++++++++++++ public/map.html | 10 +-- tsconfig.json | 3 +- 14 files changed, 403 insertions(+), 186 deletions(-) delete mode 100644 TODO create mode 100644 backend/ts/api/getCurrentGameState.ts create mode 100644 backend/ts/startGame.ts create mode 100644 helpers/helpersBack.ts diff --git a/.gitignore b/.gitignore index f9c0eb5..c8b8e9b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ ## MINE bootstrap.min.css +bootstrap.min.css.map *.js + ## Github # Logs logs diff --git a/TODO b/TODO deleted file mode 100644 index 2388448..0000000 --- a/TODO +++ /dev/null @@ -1,2 +0,0 @@ -Classes -Starting game diff --git a/backend/ts/api/getCurrentGameState.ts b/backend/ts/api/getCurrentGameState.ts new file mode 100644 index 0000000..7efa009 --- /dev/null +++ b/backend/ts/api/getCurrentGameState.ts @@ -0,0 +1,16 @@ +import { Request, Response } from "express"; +import { Data, makeQuery } from "../../../helpers/helpersBack"; + +export default async function getCurrentGameState(req: Request, res: Response) { + if (req.session === undefined /* || req.body.state === undefined */) { + res.status(500); + res.send(""); + return; + } + + let dbRes: {gameBoard: Data, currentPlayer: number} + = (await makeQuery("SELECT `gameBoard`, `currentPlayer` FROM `fia` WHERE `id` = ?", [req.session.gid]))[0], + currentPlayer = dbRes.currentPlayer === req.session.index; + + res.send(JSON.stringify({gameBoard: dbRes.gameBoard, currentPlayer})); +} \ No newline at end of file diff --git a/backend/ts/api/login.ts b/backend/ts/api/login.ts index d5393ef..0c6ef75 100644 --- a/backend/ts/api/login.ts +++ b/backend/ts/api/login.ts @@ -1,10 +1,11 @@ import { Request, Response } from "express"; -import { makeQuery, fiaTable, dbRes, dbResToFiaTable, Color, Colors } from "../../../helpers/helpers"; +import { fiaTable, dbRes, Color, Colors, Helpers, makeQuery, Chequer, tColors } from "../../../helpers/helpersBack"; +import startGame from "../startGame"; -// export default async function apiLogin(req: Request, res: Response) { -export default async function (req: Request, res: Response) { +export default async function apiLogin(req: Request, res: Response) { if (req.session === undefined) { - res.send(/* html */ ``); + res.status(500); + res.send(""); return; } req.session.uid = req.session.id; @@ -13,30 +14,47 @@ export default async function (req: Request, res: Response) { let dbRes = (await makeQuery("SELECT * FROM `fia` WHERE `started`= 0 LIMIT 1", [])) as Array, row: fiaTable; if (dbRes.length === 0) { + let color = Helpers.getRandomInt(0, 5); row = {} as fiaTable; - row.data = [{ id: req.session.uid, color: Color.blue, name: req.body.name }]; + + row.data = [{ + id: req.session.uid, + index: 0, + color: Color[color as keyof Colors], + name: req.body.name, + }]; req.session.color = Color.blue; await makeQuery('INSERT INTO `fia`(`data`, `started`) VALUES (?, ?)', [JSON.stringify(row.data), 0]); - req.session.gid = (await makeQuery('SELECT `id` FROM `fia` WHERE `data`=?', [JSON.stringify(row.data)]) as any)[0].id; + req.session.gid = (await makeQuery('SELECT `id` FROM `fia` WHERE `data`= ?', [JSON.stringify(row.data)]) as any)[0].id; } else { - row = dbResToFiaTable(dbRes[0]); - let color = Color[row.data.length as keyof Colors]; + row = Helpers.dbResToFiaTable(dbRes[0]); + let playersColors: Array = [], + colors = [...Array(4).keys()]; + + for (let playerData of row.data) + playersColors.push(playerData.color); + + colors = colors.filter(el => !playersColors.includes(el)); + let color = colors[Helpers.getRandomInt(0, colors.length)], + index = row.data.length; + row.data.push({ id: req.session.uid, - color: Color.blue, - name: req.body.name + index: index, + color: color, + name: req.body.name, }); req.session.gid = row.id; - req.session.color = color; - makeQuery('UPDATE `fia` SET `data`=? WHERE `id`=?', [JSON.stringify(row.data), row.id]); + req.session.index = index; + + makeQuery('UPDATE `fia` SET `data`= ? WHERE `id`= ?', [JSON.stringify(row.data), row.id]); if (row.data.length === 4) { - makeQuery("UPDATE `fia` SET `started` = 1 WHERE `id`=?", [row.id]); - // TODO: Start game from backend + startGame(req, res); } } - makeQuery("UPDATE `fia` SET `playersCount`=`playersCount`+1 WHERE `id`=?", [req.session.gid]); + makeQuery("UPDATE `fia` SET `playersCount`=`playersCount`+1 WHERE `id`= ?", [req.session.gid]); res.send(JSON.stringify(row.data)); } diff --git a/backend/ts/api/readyStateToggle.ts b/backend/ts/api/readyStateToggle.ts index f6269bc..6bca5b2 100644 --- a/backend/ts/api/readyStateToggle.ts +++ b/backend/ts/api/readyStateToggle.ts @@ -1,11 +1,19 @@ import { Request, Response } from "express"; -import { makeQuery, checkApiRes } from "../../../helpers/helpers"; +import { makeQuery } from "../../../helpers/helpersBack"; +import startGame from "../startGame"; export default async function (req: Request, res: Response) { - if (req.session === undefined || req.body.state == undefined) { - res.send(/* html */ ``); + if (req.session === undefined || req.body.state === undefined) { + res.status(500); + res.send(""); return; } - makeQuery("UPDATE `fia` SET `playersAreReady`=`playersAreReady`+" + (req.body.state ? 1 : 0) - + " WHERE `id`=" + req.session.gid, []).then(dbRes => checkApiRes(dbRes, res)); + await makeQuery("UPDATE `fia` SET `playersAreReady`=`playersAreReady`+" + (req.body.state ? 1 : -1) + + " WHERE `id`=" + req.session.gid, []); + let start = ( + await makeQuery('SELECT playersAreReady=playersCount and playersCount > 1 "start" FROM `fia` WHERE `id`= ?', + [req.session.gid]) + )[0].start; + if(start === 1) + startGame(req, res); } diff --git a/backend/ts/api/startPoint.ts b/backend/ts/api/startPoint.ts index 0fa79e5..d635622 100644 --- a/backend/ts/api/startPoint.ts +++ b/backend/ts/api/startPoint.ts @@ -1,20 +1,20 @@ import { Request, Response } from "express"; -import { makeQuery } from "../../../helpers/helpers"; +import { makeQuery } from "../../../helpers/helpersBack"; export default async function (req: Request, res: Response) { if (req.session === undefined) { res.send(/* html */ ``); return; } - console.log("uid:", req.session.uid, "gid:", req.session.gid); + // console.log("uid:", req.session.uid, "gid:", req.session.gid); if (req.session.uid !== undefined) { let data = await makeQuery('SELECT `data` FROM `fia` WHERE `id`=?', [req.session.gid]); - console.log("data: ", data); res.send(JSON.stringify({ status: true, data: data })) } - else + else { res.send(JSON.stringify({ status: false })); + } } \ No newline at end of file diff --git a/backend/ts/index.ts b/backend/ts/index.ts index 6b12571..d0899dd 100644 --- a/backend/ts/index.ts +++ b/backend/ts/index.ts @@ -5,6 +5,7 @@ import * as dotenv from "dotenv"; import login from "./api/login"; import startPoint from "./api/startPoint"; import readyStateToggle from "./api/readyStateToggle"; +import getCurrentGameState from "./api/getCurrentGameState"; dotenv.config(); const app = express(); @@ -23,6 +24,7 @@ app.get("/startPoint", startPoint) app.post("/login", login); app.post("/readyStateToggle", readyStateToggle); +app.post("/getCurrentGameState", getCurrentGameState); app.listen(PORT, () => { diff --git a/backend/ts/startGame.ts b/backend/ts/startGame.ts new file mode 100644 index 0000000..4188d29 --- /dev/null +++ b/backend/ts/startGame.ts @@ -0,0 +1,41 @@ +import { } from "../../helpers/helpers"; +import { makeQuery, Color, GameBoard, Chequer, Coordinates, Data } from "../../helpers/helpersBack"; +import { Request, Response } from "express"; + +export default async function startGame(req: Request, res: Response) { + if (req.session === undefined) { + res.status(500); + res.send(""); + return; + } + + makeQuery("UPDATE `fia` SET `started` = 1 WHERE `id`= ?", [req.session.gid]); + let dbRes: {gameBoard: GameBoard, data: Data} + = (await makeQuery("SELECT `gameBoard`, `playersCount` FROM `fia` WHERE `id` = ?", [req.session.gid]))[0]; + + for (let player of dbRes.data) { + let chequer: Chequer = { color: player.color, x: 1, y: 1 }, + start: Coordinates; + + switch (player.color) { + case Color.red: start = { x: 1, y: 1 }; break; + case Color.blue: start = { x: 8, y: 1 }; break; + case Color.yellow: start = { x: 1, y: 8 }; break; + default /* Color.green */: start = { x: 8, y: 8 }; break; + // case Color.green: start = { x: 8, y: 8 }; break; + } + + for (let i = 0; i < 2; i++) { + for (let j = 0; j < 2; j++) { + //@ts-ignore - 8 + 1 <= 11 which is max of Coordinates + [chequer.x, chequer.y] = [start.x + i, start.y + j]; + } + } + + dbRes.gameBoard.push(chequer); + } + + await makeQuery("UPDATE `fia` SET `gameBoard` = ? WHERE `id`= ?", [dbRes.gameBoard, req.session.gid]); + + res.send(""); +} \ No newline at end of file diff --git a/frontend/ts/login.ts b/frontend/ts/login.ts index 5b09e89..ec4defa 100644 --- a/frontend/ts/login.ts +++ b/frontend/ts/login.ts @@ -1,35 +1,34 @@ -import { json } from "express"; -import startGame from "./startGame.js"; -// import { Data, Color } from "../../helpers/helpers.js"; +import StartGame from "./startGame.js"; +import Helpers from "../../helpers/helpers.js"; -let html = /* html */ ` +class Login { + static html = /* html */ `
- - + +
`; -async function login(username = "") { - if (username === "") - username = document.getElementsByTagName("input")[0].value; - let res = await fetch("/login", { - method: "POST", - headers: { - Accept: "application/json", - "Content-Type": "application/json" - }, - body: JSON.stringify({ name: username }) - }); - startGame(await res.json()); -} + static async start() { + let res = await (await fetch("/startPoint")).json(); + if (res.status === true) { + new StartGame(JSON.parse(res.data[0].data)); + } else { + document.body.innerHTML = Login.html; + document.getElementsByTagName("button")[0].onclick = () => Login.login(); + + // !! + document.getElementsByTagName("button")[0].click(); + } + } -(async () => { - let res = await (await fetch("/startPoint")).json(); - if (res.status === true) { - startGame(JSON.parse(res.data[0].data)); - } else { - document.body.innerHTML = html; - document.getElementsByTagName("button")[0].onclick = () => login(); + static async login(username = "") { + if (username === "") + username = document.getElementsByTagName("input")[0].value; + + let res = await Helpers.mFetch("/login", { name: username }); + new StartGame(await res.json()); } -})() \ No newline at end of file +} +Login.start(); \ No newline at end of file diff --git a/frontend/ts/startGame.ts b/frontend/ts/startGame.ts index a14742f..dbeeac1 100644 --- a/frontend/ts/startGame.ts +++ b/frontend/ts/startGame.ts @@ -1,49 +1,118 @@ -import { Data, checkApiRes, mFetch } from "../../helpers/helpers"; - -function getCanvasAndCtx(): [HTMLCanvasElement, CanvasRenderingContext2D] { - let canvas = document.getElementsByTagName("canvas")[0], - ctx = canvas.getContext("2d"); - if (ctx === null) { - document.write("ur muther is fat, stop using IE"); - throw new Error("Player is using browser older that his mom"); - } else return [canvas, ctx]; -} - -function setOpponents(data: Data) { - // Start game - console.log("startGame.ts: data: ", data) - let tds = document.getElementsByClassName("player-name"), - colors = ["primary", "danger", "success", "warning"], - replacement = { name: "", color: "" }; - for (let i = 0; i < 4; i++) { - if (data[i] !== undefined) { - replacement.name = data[i].name; - replacement.color = colors[i]; - } else { - replacement.name = "?"; - replacement.color = "secondary"; +import { Data } from "../../helpers/helpersBack"; +import Helpers from "../../helpers/helpers.js"; +import { Chequer, GameBoard } from "../../helpers/helpersBack.js"; + +export default class StartGame { + colors = ["primary", "danger", "success", "warning"]; + radius = 20; + + ctx!: CanvasRenderingContext2D; + canvas!: HTMLCanvasElement; + interval!: any; + img!: HTMLImageElement; + + chequers: Array = []; + gameBoard: GameBoard = []; + + constructor(data: Data) { + this.init(data); + } + + async init(data: Data) { + document.body.innerHTML = await (await fetch("/map.html")).text(); + document.getElementsByTagName("input")[0].onclick = this.readyStateToggle; + [this.canvas, this.ctx] = this.getCanvasAndCtx(); + + this.setOpponents(data); + + [this.canvas, this.ctx] = this.getCanvasAndCtx(); + this.canvas.onclick = this.canvasClickHandler; + + this.img = await this.loadImage("https://jopek.eu/maks/szkola/apkKli/fiaFiles/fia.png"); + + await this.getData(); + // this.ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, this.canvas.width, this.canvas.height); + // this.drawChequer({ x: 4, y: 1, color: 1 }); + + this.interval = setInterval(this.getData, 2000); + } + + getCanvasAndCtx(): [HTMLCanvasElement, CanvasRenderingContext2D] { + let canvas = document.getElementsByTagName("canvas")[0], + ctx = canvas.getContext("2d"); + if (ctx === null) { + document.write("stop using IE ..."); + throw new Error("Player is using browser older than ..."); + } else return [canvas, ctx]; + } + + async setOpponents(data: Data): Promise { + let tds = (document.getElementsByClassName("player-name") as HTMLCollectionOf), + i = 0; + + for(let player of data) { + tds[i].classList.add("bg-" + this.colors[player.color]); + tds[i].innerText = player.name; + console.log("player, i", player, i); + i++; + } + for(; i < 4; i++) { + console.log("i", i); + tds[i].classList.add("bg-secondary"); + tds[i].innerText = "?"; } - tds[i].innerHTML = replacement.name; - tds[i].classList.add("bg-" + replacement.color); } -} -function readyStateToggle(e: MouseEvent) { - mFetch("/readyStateToggle", { state: (e.target as any).checked }); -} + isIntersect(point: { x: number, y: number }, circle: Chequer) { + return Math.sqrt((point.x - circle.x) ** 2 + (point.y - circle.y) ** 2) < this.radius; + } -export default async function (data: Data) { - console.log(data); - let body = await (await fetch("/map.html")).text(); - document.body.innerHTML = body; + canvasClickHandler(e: MouseEvent) { + const mousePos = { + x: e.clientX - this.canvas.offsetLeft, + y: e.clientY - this.canvas.offsetTop + }; + this.chequers.forEach(chequer => { + if (this.isIntersect(mousePos, chequer)) { + alert('click on circle: ' + chequer); + } + }); + } - setOpponents(data); - document.getElementsByTagName("input")[0].onclick = readyStateToggle; - - let [canvas, ctx] = getCanvasAndCtx(); - let img = new Image(600, 600); - img.width = 600; - img.height = 600; - img.src = "https://www.egierki.pl/app/uploads/2020/05/Ludo-Play.jpg"; - img.onload = () => ctx.drawImage(img, 0, 0); -} + readyStateToggle(e: MouseEvent): void { + Helpers.mFetch("/readyStateToggle", { + state: (e.target as HTMLInputElement).checked + }); + } + + async loadImage(src: string): Promise { + return new Promise(resolve => { + let img = new Image() + img.src = src + img.onload = () => resolve(img) + }) + } + + drawChequer(chequer: Chequer): void { + let x = chequer.x * 60 + 30, + y = chequer.y * 60 + 28; + + this.ctx.beginPath(); + this.ctx.arc(x, y, this.radius, 0, 2 * Math.PI); + this.ctx.fillStyle = this.colors[chequer.color]; + this.ctx.fill(); + this.ctx.lineWidth = 5; + this.ctx.strokeStyle = 'grey'; + this.ctx.closePath(); + this.ctx.stroke(); + + this.chequers.push(chequer); + } + + async getData() { + let data = await Helpers.mFetch("/getCurrentGameState", {}); + // TODO: assign data to this.gameBoard and draw it + // TODO: add D6 dice + // TODO: if currentPLayer === true, call to logic or calc logic here + } +} \ No newline at end of file diff --git a/helpers/helpers.ts b/helpers/helpers.ts index de6744f..03bc7d7 100644 --- a/helpers/helpers.ts +++ b/helpers/helpers.ts @@ -1,92 +1,69 @@ -import fetch from "node-fetch"; -import { Response } from "express"; +import { Colors, Color, tColors, Data, fiaTable, dbRes } from "./helpersBack"; +import { Request, Response } from "express"; -export async function makeQuery(query: string, params: Array): Promise { - let t = await ( - await fetch("https://jopek.eu/maks/szkola/apkKli/fiaFiles/fia.php", { - method: "POST", - headers: { - Accept: "application/json", - "Content-Type": "application/json" - }, - body: JSON.stringify({ - apiKey: process.env.API_KEY, - query: query, - params: params +export default class Helpers { + static async makeQuery(query: string, params: Array): Promise { + let t = await ( + //@ts-ignore - this doesn't exist for backend, but its never used there + await fetch("https://jopek.eu/maks/szkola/apkKli/fiaFiles/fia.php", { + method: "POST", + headers: { + Accept: "application/json", + "Content-Type": "application/json" + }, + body: JSON.stringify({ + apiKey: process.env.API_KEY, + query: query, + params: params + }) }) - }) - ).text(); - // console.log(t); - return JSON.parse(t); -} + ).text(); + // console.log(t); + return JSON.parse(t); + } -export function dbResToFiaTable(dbRes: dbRes): fiaTable { - if (typeof dbRes.data === "string") - dbRes.data = JSON.parse(dbRes.data); - else - throw new Error("dbResToFiaTable : wrong $1 type; "); + static dbResToFiaTable(dbRes: dbRes): fiaTable { + if (typeof dbRes.data === "string") + dbRes.data = JSON.parse(dbRes.data); + else + throw new Error("dbResToFiaTable : wrong $1 type; "); - // @ts-ignore - return dbRes; -} + // @ts-ignore + return dbRes; + } -export function checkApiRes(res: any, nRes = {} as Response): void { - if (res.api === false) { - if (Object.keys(nRes).length === 0) { - alert("API Error!"); - throw new Error("API Error!"); - } else { - nRes.status(500); - res.send(""); + static checkApiRes(res: any, nRes = {} as Response): any { + if (res.api === false) { + if (Object.keys(nRes).length === 0) { + // @ts-ignore - here error is because backend tsc is checking this file, where lib: DOM is not present + alert("API Error!"); + throw new Error("API Error!"); + } else { + nRes.status(500); + nRes.send(""); + return false; + } } + if (Object.keys(nRes).length !== 0) + nRes.status(200); + return res; } - if (Object.keys(nRes).length !== 0) - nRes.status(200); - return res; -} - -export async function mFetch(url: string, body: object) /* : Promise */ { - return fetch(url, { - method: "POST", - headers: { - Accept: "application/json", - "Content-Type": "application/json" - }, - body: JSON.stringify(body) - }).then(checkApiRes); -} -export interface Colors { - blue: number; - red: number; - green: number; - yellow: number; - 0: number; - 1: number; - 2: number; - 3: number; -} - -export const Color: Colors = { - blue: 0, - red: 1, - green: 2, - yellow: 3, - 0: 0, - 1: 1, - 2: 2, - 3: 3 -}; + static async mFetch(url: string, body: object): Promise { + //@ts-ignore - this doesn't exist for backend, but its never used there + return fetch(url, { + method: "POST", + headers: { + Accept: "application/json", + "Content-Type": "application/json" + }, + body: JSON.stringify(body) + }).then(Helpers.checkApiRes); + } -export type tColors = typeof Color[keyof typeof Color]; -export type Data = Array<{ id: any; color: tColors; name: string }>; -export interface fiaTable { - id: number; - data: Data; - started: boolean; -} -export interface dbRes { - id: number; - data: string | Data; - started: boolean; -} + static getRandomInt(min: number, max: number) { + min = Math.ceil(min); + max = Math.floor(max); + return Math.floor(Math.random() * (max - min) + min); //The maximum is exclusive and the minimum is inclusive + } +} \ No newline at end of file diff --git a/helpers/helpersBack.ts b/helpers/helpersBack.ts new file mode 100644 index 0000000..d594c03 --- /dev/null +++ b/helpers/helpersBack.ts @@ -0,0 +1,86 @@ +import fetch from "node-fetch"; +import { Response } from "express"; +import Helpers from "./helpers"; + +export { Helpers }; +export async function makeQuery(query: string, params: Array): Promise { + let t = await ( + await fetch("https://jopek.eu/maks/szkola/apkKli/fiaFiles/fia.php", { + method: "POST", + headers: { + Accept: "application/json", + "Content-Type": "application/json" + }, + body: JSON.stringify({ + apiKey: process.env.API_KEY, + query: query, + params: params + }) + }) + ).text(); + // console.log(t); + return JSON.parse(t); +} + +export async function mFetch(url: string, body: object, res: Response): Promise { + return fetch(url, { + method: "POST", + headers: { + Accept: "application/json", + "Content-Type": "application/json" + }, + body: JSON.stringify(body) + }).then(fRes => Helpers.checkApiRes(fRes, res)) as Promise; +} + +export interface Colors { + blue: number; + red: number; + green: number; + yellow: number; + 0: number; + 1: number; + 2: number; + 3: number; +} + +export const Color: Colors = { + blue: 0, + red: 1, + green: 2, + yellow: 3, + 0: 0, + 1: 1, + 2: 2, + 3: 3 +}; + +export type tColors = typeof Color[keyof typeof Color]; +export type Data = Array; +export interface DataObject { + id: any; + index: number; + color: tColors; + name: string; +} +export interface Chequer extends Coordinates { + color: tColors; +}; + +export interface Coordinates { + x: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11; + y: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11; +} +export type GameBoard = Array; +export interface fiaTable { + id: number; + data: Data; + gameBoard: GameBoard; + playersAreReady: 1 | 2 | 3 | 4; + playersCount: 1 | 2 | 3 | 4; + currentPlayer: 1 | 2 | 3 | 4; + started: boolean; +} +export interface dbRes extends Omit { + data: string | Data; +} diff --git a/public/map.html b/public/map.html index c23ccfd..23ef7de 100644 --- a/public/map.html +++ b/public/map.html @@ -2,13 +2,13 @@ - + - + - + - +
@@ -18,7 +18,7 @@
- + Din webbläsare stöder inte canvas, vilket betyder att du inte kan spela fia diff --git a/tsconfig.json b/tsconfig.json index 4478def..09abbe6 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,9 +18,10 @@ "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */, "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, - "downlevelIteration": true + "downlevelIteration": true, /* END MINE */ }, + // "include": [ // "src/ts/**/*" // ], -- cgit v1.3.1