copy files
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
"dotenv": "^16.3.1",
|
||||
"eventemitter3": "^5.0.1",
|
||||
"express": "^4.18.2",
|
||||
"express-session": "^1.17.3",
|
||||
"ky": "^0.33.3",
|
||||
"lodash-es": "^4.17.21",
|
||||
"pinia": "^2.1.4",
|
||||
@@ -43,6 +44,7 @@
|
||||
"@tsconfig/node18": "^18.2.0",
|
||||
"@types/bootstrap": "^5.2.6",
|
||||
"@types/express": "^4.17.17",
|
||||
"@types/express-session": "^1.17.7",
|
||||
"@types/lodash-es": "^4.17.8",
|
||||
"@types/node": "^18.17.0",
|
||||
"@vitejs/plugin-vue": "^4.2.3",
|
||||
|
||||
Generated
+50
@@ -38,6 +38,9 @@ dependencies:
|
||||
express:
|
||||
specifier: ^4.18.2
|
||||
version: 4.18.2
|
||||
express-session:
|
||||
specifier: ^1.17.3
|
||||
version: 1.17.3
|
||||
ky:
|
||||
specifier: ^0.33.3
|
||||
version: 0.33.3
|
||||
@@ -76,6 +79,9 @@ devDependencies:
|
||||
'@types/express':
|
||||
specifier: ^4.17.17
|
||||
version: 4.17.17
|
||||
'@types/express-session':
|
||||
specifier: ^1.17.7
|
||||
version: 1.17.7
|
||||
'@types/lodash-es':
|
||||
specifier: ^4.17.8
|
||||
version: 4.17.8
|
||||
@@ -550,6 +556,12 @@ packages:
|
||||
'@types/send': 0.17.1
|
||||
dev: true
|
||||
|
||||
/@types/express-session@1.17.7:
|
||||
resolution: {integrity: sha512-L25080PBYoRLu472HY/HNCxaXY8AaGgqGC8/p/8+BYMhG0RDOLQ1wpXOpAzr4Gi5TGozTKyJv5BVODM5UNyVMw==}
|
||||
dependencies:
|
||||
'@types/express': 4.17.17
|
||||
dev: true
|
||||
|
||||
/@types/express@4.17.17:
|
||||
resolution: {integrity: sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==}
|
||||
dependencies:
|
||||
@@ -1311,6 +1323,11 @@ packages:
|
||||
resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==}
|
||||
dev: false
|
||||
|
||||
/cookie@0.4.2:
|
||||
resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==}
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: false
|
||||
|
||||
/cookie@0.5.0:
|
||||
resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==}
|
||||
engines: {node: '>= 0.6'}
|
||||
@@ -1784,6 +1801,22 @@ packages:
|
||||
strip-final-newline: 3.0.0
|
||||
dev: true
|
||||
|
||||
/express-session@1.17.3:
|
||||
resolution: {integrity: sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
dependencies:
|
||||
cookie: 0.4.2
|
||||
cookie-signature: 1.0.6
|
||||
debug: 2.6.9
|
||||
depd: 2.0.0
|
||||
on-headers: 1.0.2
|
||||
parseurl: 1.3.3
|
||||
safe-buffer: 5.2.1
|
||||
uid-safe: 2.1.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/express@4.18.2:
|
||||
resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==}
|
||||
engines: {node: '>= 0.10.0'}
|
||||
@@ -2674,6 +2707,11 @@ packages:
|
||||
ee-first: 1.1.1
|
||||
dev: false
|
||||
|
||||
/on-headers@1.0.2:
|
||||
resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==}
|
||||
engines: {node: '>= 0.8'}
|
||||
dev: false
|
||||
|
||||
/once@1.4.0:
|
||||
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
|
||||
dependencies:
|
||||
@@ -2907,6 +2945,11 @@ packages:
|
||||
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
||||
dev: true
|
||||
|
||||
/random-bytes@1.0.0:
|
||||
resolution: {integrity: sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==}
|
||||
engines: {node: '>= 0.8'}
|
||||
dev: false
|
||||
|
||||
/range-parser@1.2.1:
|
||||
resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
@@ -3520,6 +3563,13 @@ packages:
|
||||
engines: {node: '>=14.17'}
|
||||
hasBin: true
|
||||
|
||||
/uid-safe@2.1.5:
|
||||
resolution: {integrity: sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==}
|
||||
engines: {node: '>= 0.8'}
|
||||
dependencies:
|
||||
random-bytes: 1.0.0
|
||||
dev: false
|
||||
|
||||
/unbox-primitive@1.0.2:
|
||||
resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==}
|
||||
dependencies:
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import "dotenv/config";
|
||||
import { DataSource } from "typeorm";
|
||||
|
||||
export const AppDataSource = new DataSource({
|
||||
type: "mysql",
|
||||
host: process.env.DB_HOST,
|
||||
database: "db/database.sqlite",
|
||||
synchronize: true,
|
||||
logging: false,
|
||||
entities: [],
|
||||
migrations: [],
|
||||
subscribers: [],
|
||||
})
|
||||
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
declare namespace NodeJS {
|
||||
interface ProcessEnv {
|
||||
NODE_ENV: 'development' | 'production';
|
||||
GAME_DB_SERVER: string;
|
||||
GAME_DB_DATABASE: string;
|
||||
GAME_DB_USER: string;
|
||||
GAME_DB_PASSWORD: string;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,1079 @@
|
||||
/* tslint:disable */
|
||||
|
||||
|
||||
/**
|
||||
* AUTO-GENERATED FILE @ 2023-08-05 12:06:36 - DO NOT EDIT!
|
||||
*
|
||||
* This file was automatically generated by schemats v.3.0.3
|
||||
* $ schemats generate -c mysql://username:password@127.0.0.1/hidche_hwe -C -t board -t city -t comment -t diplomacy -t emperior -t event -t general -t general_access_log -t general_record -t general_turn -t hall -t message -t nation -t nation_env -t nation_turn -t ng_auction -t ng_auction_bid -t ng_betting -t ng_diplomacy -t ng_games -t ng_history -t ng_old_generals -t ng_old_nations -t plock -t rank_data -t reserved_open -t select_npc_token -t select_pool -t statistic -t storage -t tournament -t troop -t user_record -t vote -t vote_comment -t world_history -s hidche_hwe
|
||||
*
|
||||
*/
|
||||
|
||||
export type EnumTarget = 'MONTH' | 'OCCUPY_CITY' | 'DESTROY_NATION' | 'PRE_MONTH' | 'UNITED';
|
||||
export type EnumAuctionType = 'buyRice' | 'sellRice' | 'uniqueItem';
|
||||
export type EnumReqResource = 'gold' | 'rice' | 'inheritPoint';
|
||||
export type EnumLogType = 'action' | 'battle_brief' | 'battle' | 'history';
|
||||
export type EnumMsgType = 'private' | 'national' | 'public' | 'diplomacy';
|
||||
export type EnumPermission = 'normal' | 'auditor' | 'ambassador';
|
||||
export type EnumType = 'GAME' | 'ETC' | 'TOURNAMENT';
|
||||
export type EnumState = 'proposed' | 'activated' | 'cancelled' | 'replaced';
|
||||
|
||||
export namespace BoardFields {
|
||||
export type no = number;
|
||||
export type nationNo = number;
|
||||
export type isSecret = boolean;
|
||||
export type date = Date;
|
||||
export type generalNo = number;
|
||||
export type author = string;
|
||||
export type authorIcon = string | null;
|
||||
export type title = string;
|
||||
export type text = string;
|
||||
|
||||
}
|
||||
|
||||
export interface Board {
|
||||
no: BoardFields.no;
|
||||
nationNo: BoardFields.nationNo;
|
||||
isSecret: BoardFields.isSecret;
|
||||
date: BoardFields.date;
|
||||
generalNo: BoardFields.generalNo;
|
||||
author: BoardFields.author;
|
||||
authorIcon: BoardFields.authorIcon;
|
||||
title: BoardFields.title;
|
||||
text: BoardFields.text;
|
||||
|
||||
}
|
||||
|
||||
export namespace CityFields {
|
||||
export type city = number;
|
||||
export type name = string;
|
||||
export type level = number;
|
||||
export type nation = number;
|
||||
export type supply = number;
|
||||
export type front = number;
|
||||
export type pop = number;
|
||||
export type popMax = number;
|
||||
export type agri = number;
|
||||
export type agriMax = number;
|
||||
export type comm = number;
|
||||
export type commMax = number;
|
||||
export type secu = number;
|
||||
export type secuMax = number;
|
||||
export type trust = number;
|
||||
export type trade = number | null;
|
||||
export type dead = number;
|
||||
export type def = number;
|
||||
export type defMax = number;
|
||||
export type wall = number;
|
||||
export type wallMax = number;
|
||||
export type officerSet = number;
|
||||
export type state = number;
|
||||
export type region = number;
|
||||
export type term = number;
|
||||
export type conflict = string;
|
||||
|
||||
}
|
||||
|
||||
export interface City {
|
||||
city: CityFields.city;
|
||||
name: CityFields.name;
|
||||
level: CityFields.level;
|
||||
nation: CityFields.nation;
|
||||
supply: CityFields.supply;
|
||||
front: CityFields.front;
|
||||
pop: CityFields.pop;
|
||||
popMax: CityFields.popMax;
|
||||
agri: CityFields.agri;
|
||||
agriMax: CityFields.agriMax;
|
||||
comm: CityFields.comm;
|
||||
commMax: CityFields.commMax;
|
||||
secu: CityFields.secu;
|
||||
secuMax: CityFields.secuMax;
|
||||
trust: CityFields.trust;
|
||||
trade: CityFields.trade;
|
||||
dead: CityFields.dead;
|
||||
def: CityFields.def;
|
||||
defMax: CityFields.defMax;
|
||||
wall: CityFields.wall;
|
||||
wallMax: CityFields.wallMax;
|
||||
officerSet: CityFields.officerSet;
|
||||
state: CityFields.state;
|
||||
region: CityFields.region;
|
||||
term: CityFields.term;
|
||||
conflict: CityFields.conflict;
|
||||
|
||||
}
|
||||
|
||||
export namespace CommentFields {
|
||||
export type no = number;
|
||||
export type nationNo = number;
|
||||
export type isSecret = boolean;
|
||||
export type date = Date;
|
||||
export type documentNo = number;
|
||||
export type generalNo = number;
|
||||
export type author = string;
|
||||
export type text = string;
|
||||
|
||||
}
|
||||
|
||||
export interface Comment {
|
||||
no: CommentFields.no;
|
||||
nationNo: CommentFields.nationNo;
|
||||
isSecret: CommentFields.isSecret;
|
||||
date: CommentFields.date;
|
||||
documentNo: CommentFields.documentNo;
|
||||
generalNo: CommentFields.generalNo;
|
||||
author: CommentFields.author;
|
||||
text: CommentFields.text;
|
||||
|
||||
}
|
||||
|
||||
export namespace DiplomacyFields {
|
||||
export type no = number;
|
||||
export type me = number;
|
||||
export type you = number;
|
||||
export type state = number | null;
|
||||
export type term = number | null;
|
||||
export type dead = number | null;
|
||||
export type showing = Date | null;
|
||||
|
||||
}
|
||||
|
||||
export interface Diplomacy {
|
||||
no: DiplomacyFields.no;
|
||||
me: DiplomacyFields.me;
|
||||
you: DiplomacyFields.you;
|
||||
state: DiplomacyFields.state;
|
||||
term: DiplomacyFields.term;
|
||||
dead: DiplomacyFields.dead;
|
||||
showing: DiplomacyFields.showing;
|
||||
|
||||
}
|
||||
|
||||
export namespace EmperiorFields {
|
||||
export type no = number;
|
||||
export type serverId = string | null;
|
||||
export type phase = string | null;
|
||||
export type nationCount = string | null;
|
||||
export type nationName = string | null;
|
||||
export type nationHist = string | null;
|
||||
export type genCount = string | null;
|
||||
export type personalHist = string | null;
|
||||
export type specialHist = string | null;
|
||||
export type name = string | null;
|
||||
export type type = string | null;
|
||||
export type color = string | null;
|
||||
export type year = number | null;
|
||||
export type month = number | null;
|
||||
export type power = number | null;
|
||||
export type gennum = number | null;
|
||||
export type citynum = number | null;
|
||||
export type pop = string | null;
|
||||
export type poprate = string | null;
|
||||
export type gold = number | null;
|
||||
export type rice = number | null;
|
||||
export type l12Name = string | null;
|
||||
export type l12Pic = string | null;
|
||||
export type l11Name = string | null;
|
||||
export type l11Pic = string | null;
|
||||
export type l10Name = string | null;
|
||||
export type l10Pic = string | null;
|
||||
export type l9Name = string | null;
|
||||
export type l9Pic = string | null;
|
||||
export type l8Name = string | null;
|
||||
export type l8Pic = string | null;
|
||||
export type l7Name = string | null;
|
||||
export type l7Pic = string | null;
|
||||
export type l6Name = string | null;
|
||||
export type l6Pic = string | null;
|
||||
export type l5Name = string | null;
|
||||
export type l5Pic = string | null;
|
||||
export type tiger = string | null;
|
||||
export type eagle = string | null;
|
||||
export type gen = string | null;
|
||||
export type history = string | null;
|
||||
export type aux = string | null;
|
||||
|
||||
}
|
||||
|
||||
export interface Emperior {
|
||||
no: EmperiorFields.no;
|
||||
serverId: EmperiorFields.serverId;
|
||||
phase: EmperiorFields.phase;
|
||||
nationCount: EmperiorFields.nationCount;
|
||||
nationName: EmperiorFields.nationName;
|
||||
nationHist: EmperiorFields.nationHist;
|
||||
genCount: EmperiorFields.genCount;
|
||||
personalHist: EmperiorFields.personalHist;
|
||||
specialHist: EmperiorFields.specialHist;
|
||||
name: EmperiorFields.name;
|
||||
type: EmperiorFields.type;
|
||||
color: EmperiorFields.color;
|
||||
year: EmperiorFields.year;
|
||||
month: EmperiorFields.month;
|
||||
power: EmperiorFields.power;
|
||||
gennum: EmperiorFields.gennum;
|
||||
citynum: EmperiorFields.citynum;
|
||||
pop: EmperiorFields.pop;
|
||||
poprate: EmperiorFields.poprate;
|
||||
gold: EmperiorFields.gold;
|
||||
rice: EmperiorFields.rice;
|
||||
l12Name: EmperiorFields.l12Name;
|
||||
l12Pic: EmperiorFields.l12Pic;
|
||||
l11Name: EmperiorFields.l11Name;
|
||||
l11Pic: EmperiorFields.l11Pic;
|
||||
l10Name: EmperiorFields.l10Name;
|
||||
l10Pic: EmperiorFields.l10Pic;
|
||||
l9Name: EmperiorFields.l9Name;
|
||||
l9Pic: EmperiorFields.l9Pic;
|
||||
l8Name: EmperiorFields.l8Name;
|
||||
l8Pic: EmperiorFields.l8Pic;
|
||||
l7Name: EmperiorFields.l7Name;
|
||||
l7Pic: EmperiorFields.l7Pic;
|
||||
l6Name: EmperiorFields.l6Name;
|
||||
l6Pic: EmperiorFields.l6Pic;
|
||||
l5Name: EmperiorFields.l5Name;
|
||||
l5Pic: EmperiorFields.l5Pic;
|
||||
tiger: EmperiorFields.tiger;
|
||||
eagle: EmperiorFields.eagle;
|
||||
gen: EmperiorFields.gen;
|
||||
history: EmperiorFields.history;
|
||||
aux: EmperiorFields.aux;
|
||||
|
||||
}
|
||||
|
||||
export namespace EventFields {
|
||||
export type id = number;
|
||||
export type target = EnumTarget;
|
||||
export type priority = number;
|
||||
export type condition = string;
|
||||
export type action = string;
|
||||
|
||||
}
|
||||
|
||||
export interface Event {
|
||||
id: EventFields.id;
|
||||
target: EventFields.target;
|
||||
priority: EventFields.priority;
|
||||
condition: EventFields.condition;
|
||||
action: EventFields.action;
|
||||
|
||||
}
|
||||
|
||||
export namespace GeneralFields {
|
||||
export type no = number;
|
||||
export type owner = number;
|
||||
export type npcmsg = string | null;
|
||||
export type npc = number;
|
||||
export type npcOrg = number | null;
|
||||
export type affinity = number | null;
|
||||
export type bornyear = number | null;
|
||||
export type deadyear = number | null;
|
||||
export type newmsg = number | null;
|
||||
export type picture = string;
|
||||
export type imgsvr = number;
|
||||
export type name = string;
|
||||
export type ownerName = string | null;
|
||||
export type nation = number;
|
||||
export type city = number;
|
||||
export type troop = number;
|
||||
export type leadership = number;
|
||||
export type leadershipExp = number;
|
||||
export type strength = number;
|
||||
export type strengthExp = number;
|
||||
export type intel = number;
|
||||
export type intelExp = number;
|
||||
export type injury = number;
|
||||
export type experience = number;
|
||||
export type dedication = number;
|
||||
export type dex1 = number;
|
||||
export type dex2 = number;
|
||||
export type dex3 = number;
|
||||
export type dex4 = number;
|
||||
export type dex5 = number;
|
||||
export type officerLevel = number;
|
||||
export type officerCity = number;
|
||||
export type permission = EnumPermission | null;
|
||||
export type gold = number;
|
||||
export type rice = number;
|
||||
export type crew = number;
|
||||
export type crewtype = number;
|
||||
export type train = number;
|
||||
export type atmos = number;
|
||||
export type weapon = string;
|
||||
export type book = string;
|
||||
export type horse = string;
|
||||
export type item = string;
|
||||
export type turntime = Date;
|
||||
export type recentWar = Date | null;
|
||||
export type makelimit = number | null;
|
||||
export type killturn = number | null;
|
||||
export type block = number | null;
|
||||
export type dedlevel = number | null;
|
||||
export type explevel = number | null;
|
||||
export type age = number | null;
|
||||
export type startage = number | null;
|
||||
export type belong = number | null;
|
||||
export type betray = number | null;
|
||||
export type personal = string;
|
||||
export type special = string;
|
||||
export type specage = number | null;
|
||||
export type special2 = string;
|
||||
export type specage2 = number | null;
|
||||
export type defenceTrain = number | null;
|
||||
export type tnmt = number | null;
|
||||
export type myset = number | null;
|
||||
export type tournament = number | null;
|
||||
export type newvote = number | null;
|
||||
export type lastTurn = string;
|
||||
export type aux = string;
|
||||
export type penalty = string | null;
|
||||
|
||||
}
|
||||
|
||||
export interface General {
|
||||
no: GeneralFields.no;
|
||||
owner: GeneralFields.owner;
|
||||
npcmsg: GeneralFields.npcmsg;
|
||||
npc: GeneralFields.npc;
|
||||
npcOrg: GeneralFields.npcOrg;
|
||||
affinity: GeneralFields.affinity;
|
||||
bornyear: GeneralFields.bornyear;
|
||||
deadyear: GeneralFields.deadyear;
|
||||
newmsg: GeneralFields.newmsg;
|
||||
picture: GeneralFields.picture;
|
||||
imgsvr: GeneralFields.imgsvr;
|
||||
name: GeneralFields.name;
|
||||
ownerName: GeneralFields.ownerName;
|
||||
nation: GeneralFields.nation;
|
||||
city: GeneralFields.city;
|
||||
troop: GeneralFields.troop;
|
||||
leadership: GeneralFields.leadership;
|
||||
leadershipExp: GeneralFields.leadershipExp;
|
||||
strength: GeneralFields.strength;
|
||||
strengthExp: GeneralFields.strengthExp;
|
||||
intel: GeneralFields.intel;
|
||||
intelExp: GeneralFields.intelExp;
|
||||
injury: GeneralFields.injury;
|
||||
experience: GeneralFields.experience;
|
||||
dedication: GeneralFields.dedication;
|
||||
dex1: GeneralFields.dex1;
|
||||
dex2: GeneralFields.dex2;
|
||||
dex3: GeneralFields.dex3;
|
||||
dex4: GeneralFields.dex4;
|
||||
dex5: GeneralFields.dex5;
|
||||
officerLevel: GeneralFields.officerLevel;
|
||||
officerCity: GeneralFields.officerCity;
|
||||
permission: GeneralFields.permission;
|
||||
gold: GeneralFields.gold;
|
||||
rice: GeneralFields.rice;
|
||||
crew: GeneralFields.crew;
|
||||
crewtype: GeneralFields.crewtype;
|
||||
train: GeneralFields.train;
|
||||
atmos: GeneralFields.atmos;
|
||||
weapon: GeneralFields.weapon;
|
||||
book: GeneralFields.book;
|
||||
horse: GeneralFields.horse;
|
||||
item: GeneralFields.item;
|
||||
turntime: GeneralFields.turntime;
|
||||
recentWar: GeneralFields.recentWar;
|
||||
makelimit: GeneralFields.makelimit;
|
||||
killturn: GeneralFields.killturn;
|
||||
block: GeneralFields.block;
|
||||
dedlevel: GeneralFields.dedlevel;
|
||||
explevel: GeneralFields.explevel;
|
||||
age: GeneralFields.age;
|
||||
startage: GeneralFields.startage;
|
||||
belong: GeneralFields.belong;
|
||||
betray: GeneralFields.betray;
|
||||
personal: GeneralFields.personal;
|
||||
special: GeneralFields.special;
|
||||
specage: GeneralFields.specage;
|
||||
special2: GeneralFields.special2;
|
||||
specage2: GeneralFields.specage2;
|
||||
defenceTrain: GeneralFields.defenceTrain;
|
||||
tnmt: GeneralFields.tnmt;
|
||||
myset: GeneralFields.myset;
|
||||
tournament: GeneralFields.tournament;
|
||||
newvote: GeneralFields.newvote;
|
||||
lastTurn: GeneralFields.lastTurn;
|
||||
aux: GeneralFields.aux;
|
||||
penalty: GeneralFields.penalty;
|
||||
|
||||
}
|
||||
|
||||
export namespace GeneralAccessLogFields {
|
||||
export type id = number;
|
||||
export type generalId = number;
|
||||
export type userId = number | null;
|
||||
export type lastRefresh = Date | null;
|
||||
export type refresh = number;
|
||||
export type refreshTotal = number;
|
||||
export type refreshScore = number;
|
||||
export type refreshScoreTotal = number;
|
||||
|
||||
}
|
||||
|
||||
export interface GeneralAccessLog {
|
||||
id: GeneralAccessLogFields.id;
|
||||
generalId: GeneralAccessLogFields.generalId;
|
||||
userId: GeneralAccessLogFields.userId;
|
||||
lastRefresh: GeneralAccessLogFields.lastRefresh;
|
||||
refresh: GeneralAccessLogFields.refresh;
|
||||
refreshTotal: GeneralAccessLogFields.refreshTotal;
|
||||
refreshScore: GeneralAccessLogFields.refreshScore;
|
||||
refreshScoreTotal: GeneralAccessLogFields.refreshScoreTotal;
|
||||
|
||||
}
|
||||
|
||||
export namespace GeneralRecordFields {
|
||||
export type id = number;
|
||||
export type generalId = number;
|
||||
export type logType = EnumLogType;
|
||||
export type year = number;
|
||||
export type month = number;
|
||||
export type text = string;
|
||||
|
||||
}
|
||||
|
||||
export interface GeneralRecord {
|
||||
id: GeneralRecordFields.id;
|
||||
generalId: GeneralRecordFields.generalId;
|
||||
logType: GeneralRecordFields.logType;
|
||||
year: GeneralRecordFields.year;
|
||||
month: GeneralRecordFields.month;
|
||||
text: GeneralRecordFields.text;
|
||||
|
||||
}
|
||||
|
||||
export namespace GeneralTurnFields {
|
||||
export type id = number;
|
||||
export type generalId = number;
|
||||
export type turnIdx = number;
|
||||
export type action = string;
|
||||
export type arg = string | null;
|
||||
export type brief = string | null;
|
||||
|
||||
}
|
||||
|
||||
export interface GeneralTurn {
|
||||
id: GeneralTurnFields.id;
|
||||
generalId: GeneralTurnFields.generalId;
|
||||
turnIdx: GeneralTurnFields.turnIdx;
|
||||
action: GeneralTurnFields.action;
|
||||
arg: GeneralTurnFields.arg;
|
||||
brief: GeneralTurnFields.brief;
|
||||
|
||||
}
|
||||
|
||||
export namespace HallFields {
|
||||
export type id = number;
|
||||
export type serverId = string;
|
||||
export type season = number;
|
||||
export type scenario = number;
|
||||
export type generalNo = number;
|
||||
export type type = string;
|
||||
export type value = number;
|
||||
export type owner = number | null;
|
||||
export type aux = string;
|
||||
|
||||
}
|
||||
|
||||
export interface Hall {
|
||||
id: HallFields.id;
|
||||
serverId: HallFields.serverId;
|
||||
season: HallFields.season;
|
||||
scenario: HallFields.scenario;
|
||||
generalNo: HallFields.generalNo;
|
||||
type: HallFields.type;
|
||||
value: HallFields.value;
|
||||
owner: HallFields.owner;
|
||||
aux: HallFields.aux;
|
||||
|
||||
}
|
||||
|
||||
export namespace MessageFields {
|
||||
export type id = number;
|
||||
export type mailbox = number;
|
||||
export type type = EnumMsgType;
|
||||
export type src = number;
|
||||
export type dest = number;
|
||||
export type time = Date;
|
||||
export type validUntil = Date;
|
||||
export type message = string;
|
||||
|
||||
}
|
||||
|
||||
export interface Message {
|
||||
id: MessageFields.id;
|
||||
mailbox: MessageFields.mailbox;
|
||||
type: MessageFields.type;
|
||||
src: MessageFields.src;
|
||||
dest: MessageFields.dest;
|
||||
time: MessageFields.time;
|
||||
validUntil: MessageFields.validUntil;
|
||||
message: MessageFields.message;
|
||||
|
||||
}
|
||||
|
||||
export namespace NationFields {
|
||||
export type nation = number;
|
||||
export type name = string;
|
||||
export type color = string;
|
||||
export type capital = number | null;
|
||||
export type capset = number | null;
|
||||
export type gennum = number | null;
|
||||
export type gold = number | null;
|
||||
export type rice = number | null;
|
||||
export type bill = number | null;
|
||||
export type rate = number | null;
|
||||
export type rateTmp = number | null;
|
||||
export type secretlimit = number | null;
|
||||
export type chiefSet = number;
|
||||
export type scout = number | null;
|
||||
export type war = number | null;
|
||||
export type strategicCmdLimit = number | null;
|
||||
export type surlimit = number | null;
|
||||
export type tech = number | null;
|
||||
export type power = number | null;
|
||||
export type spy = string;
|
||||
export type level = number | null;
|
||||
export type type = string;
|
||||
export type aux = string;
|
||||
|
||||
}
|
||||
|
||||
export interface Nation {
|
||||
nation: NationFields.nation;
|
||||
name: NationFields.name;
|
||||
color: NationFields.color;
|
||||
capital: NationFields.capital;
|
||||
capset: NationFields.capset;
|
||||
gennum: NationFields.gennum;
|
||||
gold: NationFields.gold;
|
||||
rice: NationFields.rice;
|
||||
bill: NationFields.bill;
|
||||
rate: NationFields.rate;
|
||||
rateTmp: NationFields.rateTmp;
|
||||
secretlimit: NationFields.secretlimit;
|
||||
chiefSet: NationFields.chiefSet;
|
||||
scout: NationFields.scout;
|
||||
war: NationFields.war;
|
||||
strategicCmdLimit: NationFields.strategicCmdLimit;
|
||||
surlimit: NationFields.surlimit;
|
||||
tech: NationFields.tech;
|
||||
power: NationFields.power;
|
||||
spy: NationFields.spy;
|
||||
level: NationFields.level;
|
||||
type: NationFields.type;
|
||||
aux: NationFields.aux;
|
||||
|
||||
}
|
||||
|
||||
export namespace NationEnvFields {
|
||||
export type id = number;
|
||||
export type namespace = number;
|
||||
export type key = string;
|
||||
export type value = string;
|
||||
|
||||
}
|
||||
|
||||
export interface NationEnv {
|
||||
id: NationEnvFields.id;
|
||||
namespace: NationEnvFields.namespace;
|
||||
key: NationEnvFields.key;
|
||||
value: NationEnvFields.value;
|
||||
|
||||
}
|
||||
|
||||
export namespace NationTurnFields {
|
||||
export type id = number;
|
||||
export type nationId = number;
|
||||
export type officerLevel = number;
|
||||
export type turnIdx = number;
|
||||
export type action = string;
|
||||
export type arg = string | null;
|
||||
export type brief = string | null;
|
||||
|
||||
}
|
||||
|
||||
export interface NationTurn {
|
||||
id: NationTurnFields.id;
|
||||
nationId: NationTurnFields.nationId;
|
||||
officerLevel: NationTurnFields.officerLevel;
|
||||
turnIdx: NationTurnFields.turnIdx;
|
||||
action: NationTurnFields.action;
|
||||
arg: NationTurnFields.arg;
|
||||
brief: NationTurnFields.brief;
|
||||
|
||||
}
|
||||
|
||||
export namespace NgAuctionFields {
|
||||
export type id = number;
|
||||
export type type = EnumAuctionType;
|
||||
export type finished = Buffer;
|
||||
export type target = string | null;
|
||||
export type hostGeneralId = number;
|
||||
export type reqResource = EnumReqResource;
|
||||
export type openDate = Date;
|
||||
export type closeDate = Date;
|
||||
export type detail = string;
|
||||
|
||||
}
|
||||
|
||||
export interface NgAuction {
|
||||
id: NgAuctionFields.id;
|
||||
type: NgAuctionFields.type;
|
||||
finished: NgAuctionFields.finished;
|
||||
target: NgAuctionFields.target;
|
||||
hostGeneralId: NgAuctionFields.hostGeneralId;
|
||||
reqResource: NgAuctionFields.reqResource;
|
||||
openDate: NgAuctionFields.openDate;
|
||||
closeDate: NgAuctionFields.closeDate;
|
||||
detail: NgAuctionFields.detail;
|
||||
|
||||
}
|
||||
|
||||
export namespace NgAuctionBidFields {
|
||||
export type no = number;
|
||||
export type auctionId = number;
|
||||
export type owner = number | null;
|
||||
export type generalId = number;
|
||||
export type amount = number;
|
||||
export type date = Date;
|
||||
export type aux = string;
|
||||
|
||||
}
|
||||
|
||||
export interface NgAuctionBid {
|
||||
no: NgAuctionBidFields.no;
|
||||
auctionId: NgAuctionBidFields.auctionId;
|
||||
owner: NgAuctionBidFields.owner;
|
||||
generalId: NgAuctionBidFields.generalId;
|
||||
amount: NgAuctionBidFields.amount;
|
||||
date: NgAuctionBidFields.date;
|
||||
aux: NgAuctionBidFields.aux;
|
||||
|
||||
}
|
||||
|
||||
export namespace NgBettingFields {
|
||||
export type id = number;
|
||||
export type bettingId = number;
|
||||
export type generalId = number;
|
||||
export type userId = number | null;
|
||||
export type bettingType = string;
|
||||
export type amount = number;
|
||||
|
||||
}
|
||||
|
||||
export interface NgBetting {
|
||||
id: NgBettingFields.id;
|
||||
bettingId: NgBettingFields.bettingId;
|
||||
generalId: NgBettingFields.generalId;
|
||||
userId: NgBettingFields.userId;
|
||||
bettingType: NgBettingFields.bettingType;
|
||||
amount: NgBettingFields.amount;
|
||||
|
||||
}
|
||||
|
||||
export namespace NgDiplomacyFields {
|
||||
export type no = number;
|
||||
export type srcNationId = number;
|
||||
export type destNationId = number;
|
||||
export type prevNo = number | null;
|
||||
export type state = EnumState;
|
||||
export type textBrief = string;
|
||||
export type textDetail = string;
|
||||
export type date = Date;
|
||||
export type srcSigner = number;
|
||||
export type destSigner = number | null;
|
||||
export type aux = string | null;
|
||||
|
||||
}
|
||||
|
||||
export interface NgDiplomacy {
|
||||
no: NgDiplomacyFields.no;
|
||||
srcNationId: NgDiplomacyFields.srcNationId;
|
||||
destNationId: NgDiplomacyFields.destNationId;
|
||||
prevNo: NgDiplomacyFields.prevNo;
|
||||
state: NgDiplomacyFields.state;
|
||||
textBrief: NgDiplomacyFields.textBrief;
|
||||
textDetail: NgDiplomacyFields.textDetail;
|
||||
date: NgDiplomacyFields.date;
|
||||
srcSigner: NgDiplomacyFields.srcSigner;
|
||||
destSigner: NgDiplomacyFields.destSigner;
|
||||
aux: NgDiplomacyFields.aux;
|
||||
|
||||
}
|
||||
|
||||
export namespace NgGamesFields {
|
||||
export type id = number;
|
||||
export type serverId = string;
|
||||
export type date = Date;
|
||||
export type winnerNation = number | null;
|
||||
export type map = string | null;
|
||||
export type season = number;
|
||||
export type scenario = number;
|
||||
export type scenarioName = string;
|
||||
export type env = string;
|
||||
|
||||
}
|
||||
|
||||
export interface NgGames {
|
||||
id: NgGamesFields.id;
|
||||
serverId: NgGamesFields.serverId;
|
||||
date: NgGamesFields.date;
|
||||
winnerNation: NgGamesFields.winnerNation;
|
||||
map: NgGamesFields.map;
|
||||
season: NgGamesFields.season;
|
||||
scenario: NgGamesFields.scenario;
|
||||
scenarioName: NgGamesFields.scenarioName;
|
||||
env: NgGamesFields.env;
|
||||
|
||||
}
|
||||
|
||||
export namespace NgHistoryFields {
|
||||
export type no = number;
|
||||
export type serverId = string;
|
||||
export type year = number | null;
|
||||
export type month = number | null;
|
||||
export type map = string | null;
|
||||
export type globalHistory = string | null;
|
||||
export type globalAction = string | null;
|
||||
export type nations = string | null;
|
||||
|
||||
}
|
||||
|
||||
export interface NgHistory {
|
||||
no: NgHistoryFields.no;
|
||||
serverId: NgHistoryFields.serverId;
|
||||
year: NgHistoryFields.year;
|
||||
month: NgHistoryFields.month;
|
||||
map: NgHistoryFields.map;
|
||||
globalHistory: NgHistoryFields.globalHistory;
|
||||
globalAction: NgHistoryFields.globalAction;
|
||||
nations: NgHistoryFields.nations;
|
||||
|
||||
}
|
||||
|
||||
export namespace NgOldGeneralsFields {
|
||||
export type id = number;
|
||||
export type serverId = string;
|
||||
export type generalNo = number;
|
||||
export type owner = number | null;
|
||||
export type name = string;
|
||||
export type lastYearmonth = number;
|
||||
export type turntime = Date;
|
||||
export type data = string;
|
||||
|
||||
}
|
||||
|
||||
export interface NgOldGenerals {
|
||||
id: NgOldGeneralsFields.id;
|
||||
serverId: NgOldGeneralsFields.serverId;
|
||||
generalNo: NgOldGeneralsFields.generalNo;
|
||||
owner: NgOldGeneralsFields.owner;
|
||||
name: NgOldGeneralsFields.name;
|
||||
lastYearmonth: NgOldGeneralsFields.lastYearmonth;
|
||||
turntime: NgOldGeneralsFields.turntime;
|
||||
data: NgOldGeneralsFields.data;
|
||||
|
||||
}
|
||||
|
||||
export namespace NgOldNationsFields {
|
||||
export type id = number;
|
||||
export type serverId = string;
|
||||
export type nation = number;
|
||||
export type data = string;
|
||||
export type date = Date;
|
||||
|
||||
}
|
||||
|
||||
export interface NgOldNations {
|
||||
id: NgOldNationsFields.id;
|
||||
serverId: NgOldNationsFields.serverId;
|
||||
nation: NgOldNationsFields.nation;
|
||||
data: NgOldNationsFields.data;
|
||||
date: NgOldNationsFields.date;
|
||||
|
||||
}
|
||||
|
||||
export namespace PlockFields {
|
||||
export type no = number;
|
||||
export type type = EnumType;
|
||||
export type plock = number;
|
||||
export type locktime = Date;
|
||||
|
||||
}
|
||||
|
||||
export interface Plock {
|
||||
no: PlockFields.no;
|
||||
type: PlockFields.type;
|
||||
plock: PlockFields.plock;
|
||||
locktime: PlockFields.locktime;
|
||||
|
||||
}
|
||||
|
||||
export namespace RankDataFields {
|
||||
export type id = number;
|
||||
export type nationId = number;
|
||||
export type generalId = number;
|
||||
export type type = string;
|
||||
export type value = number;
|
||||
|
||||
}
|
||||
|
||||
export interface RankData {
|
||||
id: RankDataFields.id;
|
||||
nationId: RankDataFields.nationId;
|
||||
generalId: RankDataFields.generalId;
|
||||
type: RankDataFields.type;
|
||||
value: RankDataFields.value;
|
||||
|
||||
}
|
||||
|
||||
export namespace ReservedOpenFields {
|
||||
export type id = number;
|
||||
export type options = string | null;
|
||||
export type date = Date | null;
|
||||
|
||||
}
|
||||
|
||||
export interface ReservedOpen {
|
||||
id: ReservedOpenFields.id;
|
||||
options: ReservedOpenFields.options;
|
||||
date: ReservedOpenFields.date;
|
||||
|
||||
}
|
||||
|
||||
export namespace SelectNpcTokenFields {
|
||||
export type id = number;
|
||||
export type owner = number;
|
||||
export type validUntil = Date;
|
||||
export type pickMoreFrom = Date;
|
||||
export type pickResult = string;
|
||||
export type nonce = number;
|
||||
|
||||
}
|
||||
|
||||
export interface SelectNpcToken {
|
||||
id: SelectNpcTokenFields.id;
|
||||
owner: SelectNpcTokenFields.owner;
|
||||
validUntil: SelectNpcTokenFields.validUntil;
|
||||
pickMoreFrom: SelectNpcTokenFields.pickMoreFrom;
|
||||
pickResult: SelectNpcTokenFields.pickResult;
|
||||
nonce: SelectNpcTokenFields.nonce;
|
||||
|
||||
}
|
||||
|
||||
export namespace SelectPoolFields {
|
||||
export type id = number;
|
||||
export type uniqueName = string;
|
||||
export type owner = number | null;
|
||||
export type generalId = number | null;
|
||||
export type reservedUntil = Date | null;
|
||||
export type info = string;
|
||||
|
||||
}
|
||||
|
||||
export interface SelectPool {
|
||||
id: SelectPoolFields.id;
|
||||
uniqueName: SelectPoolFields.uniqueName;
|
||||
owner: SelectPoolFields.owner;
|
||||
generalId: SelectPoolFields.generalId;
|
||||
reservedUntil: SelectPoolFields.reservedUntil;
|
||||
info: SelectPoolFields.info;
|
||||
|
||||
}
|
||||
|
||||
export namespace StatisticFields {
|
||||
export type no = number;
|
||||
export type year = number | null;
|
||||
export type month = number | null;
|
||||
export type nationCount = number | null;
|
||||
export type nationName = string | null;
|
||||
export type nationHist = string | null;
|
||||
export type genCount = string | null;
|
||||
export type personalHist = string | null;
|
||||
export type specialHist = string | null;
|
||||
export type powerHist = string | null;
|
||||
export type crewtype = string | null;
|
||||
export type etc = string | null;
|
||||
export type aux = string | null;
|
||||
|
||||
}
|
||||
|
||||
export interface Statistic {
|
||||
no: StatisticFields.no;
|
||||
year: StatisticFields.year;
|
||||
month: StatisticFields.month;
|
||||
nationCount: StatisticFields.nationCount;
|
||||
nationName: StatisticFields.nationName;
|
||||
nationHist: StatisticFields.nationHist;
|
||||
genCount: StatisticFields.genCount;
|
||||
personalHist: StatisticFields.personalHist;
|
||||
specialHist: StatisticFields.specialHist;
|
||||
powerHist: StatisticFields.powerHist;
|
||||
crewtype: StatisticFields.crewtype;
|
||||
etc: StatisticFields.etc;
|
||||
aux: StatisticFields.aux;
|
||||
|
||||
}
|
||||
|
||||
export namespace StorageFields {
|
||||
export type id = number;
|
||||
export type namespace = string;
|
||||
export type key = string;
|
||||
export type value = string;
|
||||
|
||||
}
|
||||
|
||||
export interface Storage {
|
||||
id: StorageFields.id;
|
||||
namespace: StorageFields.namespace;
|
||||
key: StorageFields.key;
|
||||
value: StorageFields.value;
|
||||
|
||||
}
|
||||
|
||||
export namespace TournamentFields {
|
||||
export type seq = number;
|
||||
export type no = number | null;
|
||||
export type npc = number | null;
|
||||
export type name = string | null;
|
||||
export type w = string | null;
|
||||
export type b = string | null;
|
||||
export type h = string | null;
|
||||
export type leadership = number | null;
|
||||
export type strength = number | null;
|
||||
export type intel = number | null;
|
||||
export type lvl = number | null;
|
||||
export type grp = number | null;
|
||||
export type grpNo = number | null;
|
||||
export type win = number | null;
|
||||
export type draw = number | null;
|
||||
export type lose = number | null;
|
||||
export type gl = number | null;
|
||||
export type prmt = number | null;
|
||||
|
||||
}
|
||||
|
||||
export interface Tournament {
|
||||
seq: TournamentFields.seq;
|
||||
no: TournamentFields.no;
|
||||
npc: TournamentFields.npc;
|
||||
name: TournamentFields.name;
|
||||
w: TournamentFields.w;
|
||||
b: TournamentFields.b;
|
||||
h: TournamentFields.h;
|
||||
leadership: TournamentFields.leadership;
|
||||
strength: TournamentFields.strength;
|
||||
intel: TournamentFields.intel;
|
||||
lvl: TournamentFields.lvl;
|
||||
grp: TournamentFields.grp;
|
||||
grpNo: TournamentFields.grpNo;
|
||||
win: TournamentFields.win;
|
||||
draw: TournamentFields.draw;
|
||||
lose: TournamentFields.lose;
|
||||
gl: TournamentFields.gl;
|
||||
prmt: TournamentFields.prmt;
|
||||
|
||||
}
|
||||
|
||||
export namespace TroopFields {
|
||||
export type troopLeader = number;
|
||||
export type nation = number;
|
||||
export type name = string;
|
||||
|
||||
}
|
||||
|
||||
export interface Troop {
|
||||
troopLeader: TroopFields.troopLeader;
|
||||
nation: TroopFields.nation;
|
||||
name: TroopFields.name;
|
||||
|
||||
}
|
||||
|
||||
export namespace UserRecordFields {
|
||||
export type id = number;
|
||||
export type userId = number;
|
||||
export type serverId = string;
|
||||
export type logType = string;
|
||||
export type year = number;
|
||||
export type month = number;
|
||||
export type date = Date | null;
|
||||
export type text = string;
|
||||
|
||||
}
|
||||
|
||||
export interface UserRecord {
|
||||
id: UserRecordFields.id;
|
||||
userId: UserRecordFields.userId;
|
||||
serverId: UserRecordFields.serverId;
|
||||
logType: UserRecordFields.logType;
|
||||
year: UserRecordFields.year;
|
||||
month: UserRecordFields.month;
|
||||
date: UserRecordFields.date;
|
||||
text: UserRecordFields.text;
|
||||
|
||||
}
|
||||
|
||||
export namespace VoteFields {
|
||||
export type id = number;
|
||||
export type voteId = number;
|
||||
export type generalId = number;
|
||||
export type nationId = number;
|
||||
export type selection = string;
|
||||
|
||||
}
|
||||
|
||||
export interface Vote {
|
||||
id: VoteFields.id;
|
||||
voteId: VoteFields.voteId;
|
||||
generalId: VoteFields.generalId;
|
||||
nationId: VoteFields.nationId;
|
||||
selection: VoteFields.selection;
|
||||
|
||||
}
|
||||
|
||||
export namespace VoteCommentFields {
|
||||
export type id = number;
|
||||
export type voteId = number;
|
||||
export type generalId = number;
|
||||
export type nationId = number;
|
||||
export type generalName = string;
|
||||
export type nationName = string;
|
||||
export type text = string;
|
||||
export type date = Date | null;
|
||||
|
||||
}
|
||||
|
||||
export interface VoteComment {
|
||||
id: VoteCommentFields.id;
|
||||
voteId: VoteCommentFields.voteId;
|
||||
generalId: VoteCommentFields.generalId;
|
||||
nationId: VoteCommentFields.nationId;
|
||||
generalName: VoteCommentFields.generalName;
|
||||
nationName: VoteCommentFields.nationName;
|
||||
text: VoteCommentFields.text;
|
||||
date: VoteCommentFields.date;
|
||||
|
||||
}
|
||||
|
||||
export namespace WorldHistoryFields {
|
||||
export type id = number;
|
||||
export type nationId = number;
|
||||
export type year = number;
|
||||
export type month = number;
|
||||
export type text = string;
|
||||
|
||||
}
|
||||
|
||||
export interface WorldHistory {
|
||||
id: WorldHistoryFields.id;
|
||||
nationId: WorldHistoryFields.nationId;
|
||||
year: WorldHistoryFields.year;
|
||||
month: WorldHistoryFields.month;
|
||||
text: WorldHistoryFields.text;
|
||||
|
||||
}
|
||||
+45
-1
@@ -1,8 +1,17 @@
|
||||
import 'reflect-metadata';
|
||||
import { BasicQueryDTO } from './api/index.js';
|
||||
import { validate } from 'class-validator';
|
||||
import express, { Request, Response } from "express"
|
||||
import { AppDataSource } from "./data_source"
|
||||
import dotenv from "dotenv";
|
||||
import session from "express-session";
|
||||
import path from 'node:path';
|
||||
|
||||
export async function test(){
|
||||
dotenv.config({
|
||||
path: `.env.server.${process.env.NODE_ENV}`
|
||||
});
|
||||
|
||||
export async function test() {
|
||||
console.log("Hello World!");
|
||||
|
||||
const dto = new BasicQueryDTO();
|
||||
@@ -17,4 +26,39 @@ export async function test(){
|
||||
|
||||
await test();
|
||||
|
||||
|
||||
AppDataSource.initialize().then(async () => {
|
||||
|
||||
// create express app
|
||||
const app = express()
|
||||
app.use(bodyParser.json())
|
||||
app.use(session({
|
||||
secret: ownConfig.sessionSecret,
|
||||
resave: false,
|
||||
saveUninitialized: false,
|
||||
}))
|
||||
app.set('etag', false);
|
||||
|
||||
initPKIjs();
|
||||
|
||||
app.use('/', rootRouter);
|
||||
|
||||
await fs.mkdir(certDirPath, { recursive: true });
|
||||
if (!existsSync(rootSignKeyPath)) {
|
||||
console.info('generate sign key');
|
||||
generateRootSignKey();
|
||||
}
|
||||
|
||||
if (!existsSync(rootCertPath)) {
|
||||
console.info('generate root certificate');
|
||||
await generateRootCertificateEasy();
|
||||
}
|
||||
|
||||
// start express server
|
||||
app.listen(ownConfig.port)
|
||||
|
||||
console.log(`Express server has started on port ${ownConfig.port}`)
|
||||
|
||||
}).catch(error => console.log(error))
|
||||
|
||||
export default {};
|
||||
Vendored
+26
@@ -0,0 +1,26 @@
|
||||
export function APIPathGen<T, V>(
|
||||
obj: T,
|
||||
callback: (path: string[], tail: V, pathParam?: Record<string, string | number>) => unknown,
|
||||
pathParam?: Record<string, string | number>
|
||||
): T;
|
||||
|
||||
export function StrVar<PathType extends string>(paramKey: string): <NextCall>(next: NextCall) => {
|
||||
[v in PathType]: NextCall
|
||||
};
|
||||
|
||||
export function NumVar<NextCall>(paramKey: string, next: NextCall): {
|
||||
[v: number]: NextCall
|
||||
};
|
||||
|
||||
/*
|
||||
const apiPath = {
|
||||
SomePath: someFunc,
|
||||
User: StrVar<'a'|'b'>('name')({
|
||||
Update: someFunc,
|
||||
Delete: someFunc,
|
||||
}),
|
||||
NationInfo: NumVar('id', {
|
||||
show: someFunc
|
||||
})
|
||||
}
|
||||
*/
|
||||
@@ -0,0 +1,68 @@
|
||||
export function APIPathGen(obj, callback, path, pathParams) {
|
||||
return new Proxy(obj, {
|
||||
get(target, key) {
|
||||
let nextPath;
|
||||
if (path === undefined) {
|
||||
nextPath = [key.toString()];
|
||||
}
|
||||
else {
|
||||
nextPath = [...path, key.toString()];
|
||||
}
|
||||
|
||||
if (pathParams !== undefined) {
|
||||
pathParams = { ...pathParams };
|
||||
}
|
||||
|
||||
const varType = target.__nextVarType;
|
||||
let varKey = target.__nextVarKey;
|
||||
let next;
|
||||
if (varType !== undefined && varKey !== undefined) {
|
||||
if(varType == 'number'){
|
||||
if(key != Number(key)){
|
||||
throw `${key} is not ${varType}`;
|
||||
}
|
||||
key = Number(key);
|
||||
}
|
||||
else if ((typeof key) !== varType) {
|
||||
throw `${key} is not ${varType}, but ${typeof key}`;
|
||||
}
|
||||
if(pathParams === undefined){
|
||||
pathParams = {}
|
||||
}
|
||||
pathParams[varKey] = key;
|
||||
nextPath.pop();
|
||||
next = target.next;
|
||||
}
|
||||
else if (key in target) {
|
||||
next = target[key];
|
||||
}
|
||||
else {
|
||||
throw `${nextPath} is not exists`;
|
||||
}
|
||||
|
||||
if (typeof (next) === 'function') {
|
||||
return callback(nextPath, next, pathParams);
|
||||
}
|
||||
return APIPathGen(next, callback, nextPath, pathParams);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//generic 인자로 '자동'을 주려면 생략해야하므로 2단 호출
|
||||
export function StrVar(key) {
|
||||
return (next) => {
|
||||
return {
|
||||
__nextVarType: 'string',
|
||||
__nextVarKey: key,
|
||||
next
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function NumVar(key, next) {
|
||||
return {
|
||||
__nextVarType: 'number',
|
||||
__nextVarKey: key,
|
||||
next
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export type Bytes = ArrayBuffer | DataView | Uint8Array;
|
||||
export type BytesLike = Bytes | string;
|
||||
@@ -0,0 +1,3 @@
|
||||
export type Entries<T> = {
|
||||
[K in keyof T]: [K, T[K]];
|
||||
}[keyof T][];
|
||||
@@ -0,0 +1,586 @@
|
||||
import { unwrap_err } from "./unwrap_err";
|
||||
|
||||
// https://github.com/coxcore/postposition 의 php 버전을 다시 typescript로 재 작성
|
||||
const KO_START_CODE = 44032;
|
||||
const KO_FINISH_CODE = 55203;
|
||||
const HANJA_START_CODE = 0x4e00;
|
||||
const HANJA_FINISH_CODE = 0xfa0b;
|
||||
const REG_INVALID_CHAR_W_HANJA = /[^a-zA-Z0-9ㄱ-ㅎ가-힣一-廓\s]+/u;
|
||||
const REG_INVALID_CHAR = /[^a-zA-Z0-9ㄱ-ㅎ가-힣\s]+/u;
|
||||
const REG_TARGET_CHAR = /^[\s\S]*?(\S*)\s*$/u;
|
||||
|
||||
const PRE_REG_NORMAL_FIXED = [
|
||||
"check|[hm]ook|limit",
|
||||
];
|
||||
const PRE_REG_SPECIAL_CHAR = [
|
||||
"[ㄱ-ㄷㅁ-ㅎ]",
|
||||
"^[036]",
|
||||
"[^a-zA-Z][036]",
|
||||
"[a-zA-Z]9",
|
||||
"^[mn]",
|
||||
"\\S[mn]e?",
|
||||
"\\S(?:[aeiom]|lu)b",
|
||||
"(?:u|\\S[aei]|[^o]o)p",
|
||||
"(?:^i|[^auh]i|\\Su|[^ei][ae]|[^oi]o)t",
|
||||
"(?:\\S[iou]|[^e][ae])c?k",
|
||||
"\\S[aeiou](?:c|ng)",
|
||||
"foot|go+d|b[ai]g|private",
|
||||
"^(?:app|kor)",
|
||||
];
|
||||
const PRE_REG_SPECIAL_RO = [
|
||||
"[178ㄹ]",
|
||||
"^[lr]",
|
||||
"^\\Sr",
|
||||
"\\Sle?",
|
||||
];
|
||||
|
||||
const DEFAULT_POSTPOSITION = {
|
||||
"은": "는",
|
||||
"이": "가",
|
||||
"과": "와",
|
||||
"이나": "나",
|
||||
"을": "를",
|
||||
"으로": "로",
|
||||
"이라": "라",
|
||||
"이랑": "랑",
|
||||
};
|
||||
|
||||
const JONGSUNG_HANJA = [
|
||||
0x523b, 0x5374, 0x5404, 0x606a, 0x6164, 0x6bbc, 0x73cf, 0x811a,
|
||||
0x89ba, 0x89d2, 0x95a3, 0x4f83, 0x520a, 0x58be, 0x5978, 0x59e6,
|
||||
0x5e72, 0x5e79, 0x61c7, 0x63c0, 0x6746, 0x67ec, 0x687f, 0x6f97,
|
||||
0x764e, 0x770b, 0x78f5, 0x7a08, 0x7aff, 0x7c21, 0x809d, 0x826e,
|
||||
0x8271, 0x8aeb, 0x9593, 0x4e6b, 0x559d, 0x66f7, 0x6e34, 0x78a3,
|
||||
0x7aed, 0x845b, 0x8910, 0x874e, 0x97a8, 0x52d8, 0x574e, 0x582a,
|
||||
0x5d4c, 0x611f, 0x61be, 0x6221, 0x6562, 0x67d1, 0x6a44, 0x6e1b,
|
||||
0x7518, 0x75b3, 0x76e3, 0x77b0, 0x7d3a, 0x90af, 0x9451, 0x9452,
|
||||
0x9f95, 0x5323, 0x5cac, 0x7532, 0x80db, 0x9240, 0x9598, 0x525b,
|
||||
0x5808, 0x59dc, 0x5ca1, 0x5d17, 0x5eb7, 0x5f3a, 0x5f4a, 0x6177,
|
||||
0x6c5f, 0x757a, 0x7586, 0x7ce0, 0x7d73, 0x7db1, 0x7f8c, 0x8154,
|
||||
0x8221, 0x8591, 0x8941, 0x8b1b, 0x92fc, 0x964d, 0x9c47, 0x5580,
|
||||
0x5ba2, 0x5751, 0xf901, 0x7cb3, 0x7fb9, 0x91b5, 0x4e7e, 0x4ef6,
|
||||
0x5065, 0x5dfe, 0x5efa, 0x6106, 0x6957, 0x8171, 0x8654, 0x8e47,
|
||||
0x9375, 0x9a2b, 0x4e5e, 0x5091, 0x6770, 0x6840, 0x5109, 0x528d,
|
||||
0x5292, 0x6aa2, 0x77bc, 0x9210, 0x9ed4, 0x52ab, 0x602f, 0x8ff2,
|
||||
0x64ca, 0x683c, 0x6a84, 0x6fc0, 0x8188, 0x89a1, 0x9694, 0x5805,
|
||||
0x727d, 0x72ac, 0x7504, 0x7d79, 0x7e6d, 0x80a9, 0x898b, 0x8b74,
|
||||
0x9063, 0x9d51, 0x6289, 0x6c7a, 0x6f54, 0x7d50, 0x7f3a, 0x8a23,
|
||||
0x517c, 0x614a, 0x7b9d, 0x8b19, 0x9257, 0x938c, 0x4eac, 0x4fd3,
|
||||
0x501e, 0x50be, 0x5106, 0x52c1, 0x52cd, 0x537f, 0x5770, 0x5883,
|
||||
0x5e9a, 0x5f91, 0x6176, 0x61ac, 0x64ce, 0x656c, 0x666f, 0x66bb,
|
||||
0x66f4, 0x6897, 0x6d87, 0x7085, 0x70f1, 0x749f, 0x74a5, 0x74ca,
|
||||
0x75d9, 0x786c, 0x78ec, 0x7adf, 0x7af6, 0x7d45, 0x7d93, 0x8015,
|
||||
0x803f, 0x811b, 0x8396, 0x8b66, 0x8f15, 0x9015, 0x93e1, 0x9803,
|
||||
0x9838, 0x9a5a, 0x9be8, 0x54ed, 0x659b, 0x66f2, 0x688f, 0x7a40,
|
||||
0x8c37, 0x9d60, 0x56f0, 0x5764, 0x5d11, 0x6606, 0x68b1, 0x68cd,
|
||||
0x6efe, 0x7428, 0x889e, 0x9be4, 0x6c68, 0xf904, 0x9aa8, 0x4f9b,
|
||||
0x516c, 0x5171, 0x529f, 0x5b54, 0x5de5, 0x6050, 0x606d, 0x62f1,
|
||||
0x63a7, 0x653b, 0x73d9, 0x7a7a, 0x86a3, 0x8ca2, 0x978f, 0x4e32,
|
||||
0x5ed3, 0x69e8, 0x85ff, 0x90ed, 0xf905, 0x51a0, 0x5b98, 0x5bec,
|
||||
0x6163, 0x68fa, 0x6b3e, 0x704c, 0x742f, 0x74d8, 0x7ba1, 0x7f50,
|
||||
0x83c5, 0x89c0, 0x8cab, 0x95dc, 0x9928, 0x522e, 0x605d, 0x62ec,
|
||||
0x9002, 0x4f8a, 0x5149, 0x5321, 0x58d9, 0x5ee3, 0x66e0, 0x6d38,
|
||||
0x709a, 0x72c2, 0x73d6, 0x7b50, 0x80f1, 0x945b, 0x5b8f, 0x7d18,
|
||||
0x80b1, 0x8f5f, 0x570b, 0x5c40, 0x83ca, 0x97a0, 0x97ab, 0x9eb4,
|
||||
0x541b, 0x7a98, 0x7fa4, 0x88d9, 0x8ecd, 0x90e1, 0x5800, 0x5c48,
|
||||
0x6398, 0x7a9f, 0x5bae, 0x5f13, 0x7a79, 0x7aae, 0x828e, 0x8eac,
|
||||
0x5026, 0x5238, 0x52f8, 0x5377, 0x5708, 0x62f3, 0x6372, 0x6b0a,
|
||||
0x6dc3, 0x7737, 0x53a5, 0x7357, 0x8568, 0x8e76, 0x95d5, 0x52fb,
|
||||
0x5747, 0x7547, 0x7b60, 0x83cc, 0x921e, 0xf908, 0x6a58, 0x514b,
|
||||
0x524b, 0x5287, 0x621f, 0x68d8, 0x6975, 0x9699, 0x50c5, 0x52a4,
|
||||
0x52e4, 0x61c3, 0x65a4, 0x6839, 0x69ff, 0x747e, 0x7b4b, 0x82b9,
|
||||
0x83eb, 0x89b2, 0x8b39, 0x8fd1, 0x9949, 0xf909, 0x4eca, 0x5997,
|
||||
0x64d2, 0x6611, 0x6a8e, 0x7434, 0x7981, 0x79bd, 0x82a9, 0x887e,
|
||||
0x887f, 0x895f, 0xf90a, 0x9326, 0x4f0b, 0x53ca, 0x6025, 0x6271,
|
||||
0x6c72, 0x7d1a, 0x7d66, 0x4e98, 0x5162, 0x77dc, 0x80af, 0x7dca,
|
||||
0x4f76, 0x5409, 0x62ee, 0x6854, 0x91d1, 0x55ab, 0xf914, 0xf915,
|
||||
0xf916, 0xf917, 0xf918, 0x8afe, 0xf919, 0xf91a, 0xf91b, 0xf91c,
|
||||
0x6696, 0xf91d, 0x7156, 0xf91e, 0xf91f, 0x96e3, 0xf920, 0x634f,
|
||||
0x637a, 0x5357, 0xf921, 0x678f, 0x6960, 0x6e73, 0xf922, 0x7537,
|
||||
0xf923, 0xf924, 0xf925, 0x7d0d, 0xf926, 0xf927, 0x8872, 0x56ca,
|
||||
0x5a18, 0xf928, 0xf929, 0xf92a, 0xf92b, 0xf92c, 0xf92e, 0x5e74,
|
||||
0x649a, 0x79ca, 0x5ff5, 0x606c, 0x62c8, 0x637b, 0x5be7, 0x5bd7,
|
||||
0xf93b, 0xf93c, 0xf93d, 0xf93e, 0xf93f, 0xf940, 0xf941, 0xf942,
|
||||
0xf943, 0x6fc3, 0xf944, 0xf945, 0x81bf, 0x8fb2, 0x5ae9, 0x8a25,
|
||||
0xf952, 0xf953, 0xf954, 0xf955, 0xf956, 0xf957, 0x80fd, 0xf958,
|
||||
0xf959, 0x533f, 0x6eba, 0x4e39, 0x4eb6, 0x4f46, 0x55ae, 0x5718,
|
||||
0x58c7, 0x5f56, 0x65b7, 0x65e6, 0x6a80, 0x6bb5, 0x6e4d, 0x77ed,
|
||||
0x7aef, 0x7c1e, 0x7dde, 0x86cb, 0x8892, 0x9132, 0x935b, 0x64bb,
|
||||
0x6fbe, 0x737a, 0x75b8, 0x9054, 0x5556, 0x574d, 0x61ba, 0x64d4,
|
||||
0x66c7, 0x6de1, 0x6e5b, 0x6f6d, 0x6fb9, 0x75f0, 0x8043, 0x81bd,
|
||||
0x8541, 0x8983, 0x8ac7, 0x8b5a, 0x931f, 0x6c93, 0x7553, 0x7b54,
|
||||
0x8e0f, 0x905d, 0x5510, 0x5802, 0x5858, 0x5e62, 0x6207, 0x649e,
|
||||
0x68e0, 0x7576, 0x7cd6, 0x87b3, 0x9ee8, 0x5b85, 0x5fb7, 0x60b3,
|
||||
0x6bd2, 0x7006, 0x7258, 0x72a2, 0x7368, 0x7763, 0x79bf, 0x7be4,
|
||||
0x7e9b, 0x8b80, 0x58a9, 0x60c7, 0x6566, 0x65fd, 0x66be, 0x6c8c,
|
||||
0x711e, 0x71c9, 0x8c5a, 0x9813, 0x4e6d, 0x7a81, 0x4edd, 0x51ac,
|
||||
0x51cd, 0x52d5, 0x540c, 0x61a7, 0x6771, 0x6850, 0x68df, 0x6d1e,
|
||||
0x6f7c, 0x75bc, 0x77b3, 0x7ae5, 0x80f4, 0x8463, 0x9285, 0x5c6f,
|
||||
0x81c0, 0x829a, 0x9041, 0x906f, 0x920d, 0x5f97, 0x5d9d, 0x6a59,
|
||||
0x71c8, 0x767b, 0x7b49, 0x85e4, 0x8b04, 0x9127, 0x9a30, 0xf95c,
|
||||
0x6d1b, 0x70d9, 0x73de, 0x7d61, 0x843d, 0xf95d, 0x916a, 0x99f1,
|
||||
0xf95e, 0x4e82, 0x5375, 0x6b04, 0x6b12, 0x703e, 0x721b, 0x862d,
|
||||
0x9e1e, 0x524c, 0x8fa3, 0x5d50, 0x64e5, 0x652c, 0x6b16, 0x6feb,
|
||||
0x7c43, 0x7e9c, 0x85cd, 0x8964, 0x89bd, 0x62c9, 0x81d8, 0x881f,
|
||||
0x5eca, 0x6717, 0x6d6a, 0x72fc, 0x7405, 0x746f, 0x8782, 0x90de,
|
||||
0x51b7, 0x63a0, 0x7565, 0x4eae, 0x5006, 0x5169, 0x51c9, 0x6881,
|
||||
0x6a11, 0x7cae, 0x7cb1, 0x7ce7, 0x826f, 0x8ad2, 0x8f1b, 0x91cf,
|
||||
0x529b, 0x66c6, 0x6b77, 0x701d, 0x792b, 0x8f62, 0x9742, 0x6190,
|
||||
0x6200, 0x6523, 0x6f23, 0x7149, 0x7489, 0x7df4, 0x806f, 0x84ee,
|
||||
0x8f26, 0x9023, 0x934a, 0x51bd, 0x5217, 0x52a3, 0x6d0c, 0x70c8,
|
||||
0x88c2, 0x5ec9, 0x6582, 0x6bae, 0x6fc2, 0x7c3e, 0x7375, 0x4ee4,
|
||||
0x4f36, 0x56f9, 0xf95f, 0x5cba, 0x5dba, 0x601c, 0x73b2, 0x7b2d,
|
||||
0x7f9a, 0x7fce, 0x8046, 0x901e, 0x9234, 0x96f6, 0x9748, 0x9818,
|
||||
0x9f61, 0x788c, 0x797f, 0x7da0, 0x83c9, 0x9304, 0x9e7f, 0x9e93,
|
||||
0x8ad6, 0x58df, 0x5f04, 0x6727, 0x7027, 0x74cf, 0x7c60, 0x807e,
|
||||
0x9f8d, 0x516d, 0x622e, 0x9678, 0x4f96, 0x502b, 0x5d19, 0x6dea,
|
||||
0x7db8, 0x8f2a, 0x5f8b, 0x6144, 0x6817, 0xf961, 0x9686, 0x52d2,
|
||||
0x808b, 0x51dc, 0x51cc, 0x695e, 0x7a1c, 0x7dbe, 0x83f1, 0x9675,
|
||||
0x541d, 0x6f7e, 0x71d0, 0x7498, 0x85fa, 0x8eaa, 0x96a3, 0x9c57,
|
||||
0x9e9f, 0x6797, 0x6dcb, 0x7433, 0x81e8, 0x9716, 0x782c, 0x7acb,
|
||||
0x7b20, 0x7c92, 0x5bde, 0x5e55, 0x6f20, 0x819c, 0x83ab, 0x9088,
|
||||
0x4e07, 0x534d, 0x5a29, 0x5dd2, 0x5f4e, 0x6162, 0x633d, 0x6669,
|
||||
0x66fc, 0x6eff, 0x6f2b, 0x7063, 0x779e, 0x842c, 0x8513, 0x883b,
|
||||
0x8f13, 0x9945, 0x9c3b, 0x551c, 0x62b9, 0x672b, 0x6cab, 0x8309,
|
||||
0x896a, 0x977a, 0x4ea1, 0x5984, 0x5fd8, 0x5fd9, 0x671b, 0x7db2,
|
||||
0x7f54, 0x8292, 0x832b, 0x83bd, 0x8f1e, 0x9099, 0x8108, 0x8c8a,
|
||||
0x964c, 0x9a40, 0x9ea5, 0x5b5f, 0x6c13, 0x731b, 0x76f2, 0x76df,
|
||||
0x840c, 0x51aa, 0x8993, 0x514d, 0x5195, 0x52c9, 0x68c9, 0x6c94,
|
||||
0x7704, 0x7720, 0x7dbf, 0x7dec, 0x9762, 0x9eb5, 0x6ec5, 0x8511,
|
||||
0x51a5, 0x540d, 0x547d, 0x660e, 0x669d, 0x6927, 0x6e9f, 0x76bf,
|
||||
0x7791, 0x8317, 0x84c2, 0x879f, 0x9169, 0x9298, 0x9cf4, 0x6728,
|
||||
0x6c90, 0x7267, 0x76ee, 0x7766, 0x7a46, 0x9da9, 0x6b7f, 0x6c92,
|
||||
0x5922, 0x6726, 0x8499, 0x58a8, 0x9ed8, 0x5011, 0x520e, 0x543b,
|
||||
0x554f, 0x6587, 0x6c76, 0x7d0a, 0x7d0b, 0x805e, 0x868a, 0x9580,
|
||||
0x96ef, 0x52ff, 0x6c95, 0x7269, 0x5cb7, 0x60b6, 0x610d, 0x61ab,
|
||||
0x654f, 0x65fb, 0x65fc, 0x6c11, 0x6cef, 0x739f, 0x73c9, 0x7de1,
|
||||
0x9594, 0x5bc6, 0x871c, 0x8b10, 0x525d, 0x535a, 0x62cd, 0x640f,
|
||||
0x64b2, 0x6734, 0x6a38, 0x6cca, 0x73c0, 0x749e, 0x7b94, 0x7c95,
|
||||
0x7e1b, 0x818a, 0x8236, 0x8584, 0x8feb, 0x96f9, 0x99c1, 0x4f34,
|
||||
0x534a, 0x53cd, 0x53db, 0x62cc, 0x642c, 0x6500, 0x6591, 0x69c3,
|
||||
0x6cee, 0x6f58, 0x73ed, 0x7554, 0x7622, 0x76e4, 0x76fc, 0x78d0,
|
||||
0x78fb, 0x792c, 0x7d46, 0x822c, 0x87e0, 0x8fd4, 0x9812, 0x98ef,
|
||||
0x52c3, 0x62d4, 0x64a5, 0x6e24, 0x6f51, 0x767c, 0x8dcb, 0x91b1,
|
||||
0x9262, 0x9aee, 0x9b43, 0x5023, 0x508d, 0x574a, 0x59a8, 0x5c28,
|
||||
0x5e47, 0x5f77, 0x623f, 0x653e, 0x65b9, 0x65c1, 0x6609, 0x678b,
|
||||
0x699c, 0x6ec2, 0x78c5, 0x7d21, 0x80aa, 0x8180, 0x822b, 0x82b3,
|
||||
0x84a1, 0x868c, 0x8a2a, 0x8b17, 0x90a6, 0x9632, 0x9f90, 0x4f2f,
|
||||
0x4f70, 0x5e1b, 0x67cf, 0x6822, 0x767d, 0x767e, 0x9b44, 0x5e61,
|
||||
0x6a0a, 0x7169, 0x71d4, 0x756a, 0xf964, 0x7e41, 0x8543, 0x85e9,
|
||||
0x98dc, 0x4f10, 0x7b4f, 0x7f70, 0x95a5, 0x51e1, 0x5e06, 0x68b5,
|
||||
0x6c3e, 0x6c4e, 0x6cdb, 0x72af, 0x7bc4, 0x8303, 0x6cd5, 0x743a,
|
||||
0x50fb, 0x5288, 0x58c1, 0x64d8, 0x6a97, 0x74a7, 0x7656, 0x78a7,
|
||||
0x8617, 0x95e2, 0x9739, 0xf965, 0x535e, 0x5f01, 0x8b8a, 0x8fa8,
|
||||
0x8faf, 0x908a, 0x5225, 0x77a5, 0x9c49, 0x9f08, 0x4e19, 0x5002,
|
||||
0x5175, 0x5c5b, 0x5e77, 0x661e, 0x663a, 0x67c4, 0x68c5, 0x70b3,
|
||||
0x7501, 0x75c5, 0x79c9, 0x7add, 0x8f27, 0x9920, 0x9a08, 0x4f0f,
|
||||
0x50d5, 0x5310, 0x535c, 0x5b93, 0x5fa9, 0x670d, 0x798f, 0x8179,
|
||||
0x832f, 0x8514, 0x8907, 0x8986, 0x8f39, 0x8f3b, 0x99a5, 0x9c12,
|
||||
0x672c, 0x4e76, 0x4ff8, 0x5949, 0x5c01, 0x5cef, 0x5cf0, 0x6367,
|
||||
0x68d2, 0x70fd, 0x71a2, 0x742b, 0x7e2b, 0x84ec, 0x8702, 0x9022,
|
||||
0x92d2, 0x9cf3, 0x5317, 0x5206, 0x5429, 0x5674, 0x58b3, 0x5954,
|
||||
0x596e, 0x5fff, 0x61a4, 0x626e, 0x6610, 0x6c7e, 0x711a, 0x76c6,
|
||||
0x7c89, 0x7cde, 0x7d1b, 0x82ac, 0x8cc1, 0x96f0, 0xf967, 0x4f5b,
|
||||
0x5f17, 0x5f7f, 0x62c2, 0x5d29, 0x670b, 0x68da, 0x787c, 0x7e43,
|
||||
0x9d6c, 0x56ac, 0x5b2a, 0x5f6c, 0x658c, 0x6ab3, 0x6baf, 0x6d5c,
|
||||
0x6ff1, 0x7015, 0x725d, 0x73ad, 0x8ca7, 0x8cd3, 0x983b, 0x6191,
|
||||
0x6c37, 0x8058, 0x9a01, 0x524a, 0xf969, 0x6714, 0xf96a, 0x5098,
|
||||
0x522a, 0x5c71, 0x6563, 0x6c55, 0x73ca, 0x7523, 0x759d, 0x7b97,
|
||||
0x849c, 0x9178, 0x9730, 0x4e77, 0x6492, 0x6bba, 0x715e, 0x85a9,
|
||||
0x4e09, 0xf96b, 0x6749, 0x68ee, 0x6e17, 0x829f, 0x8518, 0x886b,
|
||||
0x63f7, 0x6f81, 0x9212, 0x98af, 0x4e0a, 0x50b7, 0x50cf, 0x511f,
|
||||
0x5546, 0x55aa, 0x5617, 0x5b40, 0x5c19, 0x5ce0, 0x5e38, 0x5e8a,
|
||||
0x5ea0, 0x5ec2, 0x60f3, 0x6851, 0x6a61, 0x6e58, 0x723d, 0x7240,
|
||||
0x72c0, 0x76f8, 0x7965, 0x7bb1, 0x7fd4, 0x88f3, 0x89f4, 0x8a73,
|
||||
0x8c61, 0x8cde, 0x971c, 0x55c7, 0xf96c, 0x7a61, 0x7d22, 0x8272,
|
||||
0x7272, 0x751f, 0x7525, 0xf96d, 0x7b19, 0x5915, 0x596d, 0x5e2d,
|
||||
0x60dc, 0x6614, 0x6673, 0x6790, 0x6c50, 0x6dc5, 0x6f5f, 0x77f3,
|
||||
0x78a9, 0x84c6, 0x91cb, 0x932b, 0x4ed9, 0x50ca, 0x5148, 0x5584,
|
||||
0x5b0b, 0x5ba3, 0x6247, 0x657e, 0x65cb, 0x6e32, 0x717d, 0x7401,
|
||||
0x7444, 0x7487, 0x74bf, 0x766c, 0x79aa, 0x7dda, 0x7e55, 0x7fa8,
|
||||
0x817a, 0x81b3, 0x8239, 0x861a, 0x87ec, 0x8a75, 0x8de3, 0x9078,
|
||||
0x9291, 0x9425, 0x994d, 0x9bae, 0x5368, 0x5c51, 0x6954, 0x6cc4,
|
||||
0x6d29, 0x6e2b, 0x820c, 0x859b, 0x893b, 0x8a2d, 0x8aaa, 0x96ea,
|
||||
0x9f67, 0x5261, 0x66b9, 0x6bb2, 0x7e96, 0x87fe, 0x8d0d, 0x9583,
|
||||
0x965d, 0x651d, 0x6d89, 0x71ee, 0xf96e, 0x57ce, 0x59d3, 0x5bac,
|
||||
0x6027, 0x60fa, 0x6210, 0x661f, 0x665f, 0x7329, 0x73f9, 0x76db,
|
||||
0x7701, 0x7b6c, 0x8056, 0x8072, 0x8165, 0x8aa0, 0x9192, 0x4fd7,
|
||||
0x5c6c, 0x675f, 0x6d91, 0x7c9f, 0x7e8c, 0x8b16, 0x8d16, 0x901f,
|
||||
0x5b6b, 0x5dfd, 0x640d, 0x84c0, 0x905c, 0x98e1, 0x7387, 0x5b8b,
|
||||
0x609a, 0x677e, 0x6dde, 0x8a1f, 0x8aa6, 0x9001, 0x980c, 0x53d4,
|
||||
0x587e, 0x5919, 0x5b70, 0x5bbf, 0x6dd1, 0x6f5a, 0x719f, 0x7421,
|
||||
0x74b9, 0x8085, 0x83fd, 0x5de1, 0x5f87, 0x5faa, 0x6042, 0x65ec,
|
||||
0x6812, 0x696f, 0x6a53, 0x6b89, 0x6d35, 0x6df3, 0x73e3, 0x76fe,
|
||||
0x77ac, 0x7b4d, 0x7d14, 0x8123, 0x821c, 0x8340, 0x84f4, 0x8563,
|
||||
0x8a62, 0x8ac4, 0x9187, 0x931e, 0x9806, 0x99b4, 0x620c, 0x8853,
|
||||
0x8ff0, 0x9265, 0x5d07, 0x5d27, 0x5d69, 0x745f, 0x819d, 0x8768,
|
||||
0x6fd5, 0x62fe, 0x7fd2, 0x8936, 0x8972, 0x4e1e, 0x4e58, 0x50e7,
|
||||
0x52dd, 0x5347, 0x627f, 0x6607, 0x7e69, 0x8805, 0x965e, 0x57f4,
|
||||
0x5bd4, 0x5f0f, 0x606f, 0x62ed, 0x690d, 0x6b96, 0x6e5c, 0x7184,
|
||||
0x7bd2, 0x8755, 0x8b58, 0x8efe, 0x98df, 0x98fe, 0x4f38, 0x4f81,
|
||||
0x4fe1, 0x547b, 0x5a20, 0x5bb8, 0x613c, 0x65b0, 0x6668, 0x71fc,
|
||||
0x7533, 0x795e, 0x7d33, 0x814e, 0x81e3, 0x8398, 0x85aa, 0x85ce,
|
||||
0x8703, 0x8a0a, 0x8eab, 0x8f9b, 0xf971, 0x8fc5, 0x5931, 0x5ba4,
|
||||
0x5be6, 0x6089, 0x5be9, 0x5c0b, 0x5fc3, 0x6c81, 0xf972, 0x6df1,
|
||||
0x700b, 0x751a, 0x82af, 0x8af6, 0x4ec0, 0x5341, 0xf973, 0x96d9,
|
||||
0x580a, 0x5cb3, 0x5dbd, 0x5e44, 0x60e1, 0x6115, 0x63e1, 0x6a02,
|
||||
0x6e25, 0x9102, 0x9354, 0x984e, 0x9c10, 0x9f77, 0x5b89, 0x5cb8,
|
||||
0x6309, 0x664f, 0x6848, 0x773c, 0x96c1, 0x978d, 0x9854, 0x9b9f,
|
||||
0x65a1, 0x8b01, 0x8ecb, 0x95bc, 0x5535, 0x5ca9, 0x5dd6, 0x5eb5,
|
||||
0x6697, 0x764c, 0x83f4, 0x95c7, 0x58d3, 0x62bc, 0x72ce, 0x9d28,
|
||||
0x4ef0, 0x592e, 0x600f, 0x663b, 0x6b83, 0x79e7, 0x9d26, 0x5384,
|
||||
0x627c, 0x6396, 0x6db2, 0x7e0a, 0x814b, 0x984d, 0x6afb, 0x7f4c,
|
||||
0x9daf, 0x9e1a, 0x5f31, 0xf975, 0xf976, 0x7d04, 0x82e5, 0x846f,
|
||||
0x84bb, 0x85e5, 0x8e8d, 0xf977, 0x4f6f, 0xf978, 0xf979, 0x58e4,
|
||||
0x5b43, 0x6059, 0x63da, 0x6518, 0x656d, 0x6698, 0xf97a, 0x694a,
|
||||
0x6a23, 0x6d0b, 0x7001, 0x716c, 0x75d2, 0x760d, 0x79b3, 0x7a70,
|
||||
0xf97b, 0x7f8a, 0xf97c, 0x8944, 0xf97d, 0x8b93, 0x91c0, 0x967d,
|
||||
0xf97e, 0x990a, 0x5104, 0x61b6, 0x6291, 0x6a8d, 0x81c6, 0x5043,
|
||||
0x5830, 0x5f66, 0x7109, 0x8a00, 0x8afa, 0x5b7c, 0x8616, 0x4ffa,
|
||||
0x513c, 0x56b4, 0x5944, 0x63a9, 0x6df9, 0x5daa, 0x696d, 0x5186,
|
||||
0x4ea6, 0xf98a, 0x57df, 0x5f79, 0x6613, 0xf98b, 0xf98c, 0x75ab,
|
||||
0x7e79, 0x8b6f, 0xf98d, 0x9006, 0x9a5b, 0x56a5, 0x5827, 0x59f8,
|
||||
0x5a1f, 0x5bb4, 0xf98e, 0x5ef6, 0xf98f, 0xf990, 0x6350, 0x633b,
|
||||
0xf991, 0x693d, 0x6c87, 0x6cbf, 0x6d8e, 0x6d93, 0x6df5, 0x6f14,
|
||||
0xf992, 0x70df, 0x7136, 0x7159, 0xf993, 0x71c3, 0x71d5, 0xf994,
|
||||
0x784f, 0x786f, 0xf995, 0x7b75, 0x7de3, 0xf996, 0x7e2f, 0xf997,
|
||||
0x884d, 0x8edf, 0xf998, 0xf999, 0xf99a, 0x925b, 0xf99b, 0x9cf6,
|
||||
0xf99c, 0xf99d, 0xf99e, 0x6085, 0x6d85, 0xf99f, 0x71b1, 0xf9a0,
|
||||
0xf9a1, 0x95b1, 0x53ad, 0xf9a2, 0xf9a3, 0xf9a4, 0x67d3, 0xf9a5,
|
||||
0x708e, 0x7130, 0x7430, 0x8276, 0x82d2, 0xf9a6, 0x95bb, 0x9ae5,
|
||||
0x9e7d, 0x66c4, 0xf9a7, 0x71c1, 0x8449, 0xf9a8, 0xf9a9, 0x584b,
|
||||
0xf9aa, 0xf9ab, 0x5db8, 0x5f71, 0xf9ac, 0x6620, 0x668e, 0x6979,
|
||||
0x69ae, 0x6c38, 0x6cf3, 0x6e36, 0x6f41, 0x6fda, 0x701b, 0x702f,
|
||||
0x7150, 0x71df, 0x7370, 0xf9ad, 0x745b, 0xf9ae, 0x74d4, 0x76c8,
|
||||
0x7a4e, 0x7e93, 0xf9af, 0xf9b0, 0x82f1, 0x8a60, 0x8fce, 0xf9b1,
|
||||
0x9348, 0xf9b2, 0x9719, 0xf9b3, 0xf9b4, 0x5c4b, 0x6c83, 0x7344,
|
||||
0x7389, 0x923a, 0x6eab, 0x7465, 0x761f, 0x7a69, 0x7e15, 0x860a,
|
||||
0x5140, 0x58c5, 0x64c1, 0x74ee, 0x7515, 0x7670, 0x7fc1, 0x9095,
|
||||
0x96cd, 0x9954, 0x5a49, 0x5b8c, 0x5b9b, 0x68a1, 0x6900, 0x6d63,
|
||||
0x73a9, 0x7413, 0x742c, 0x7897, 0x7de9, 0x7feb, 0x8118, 0x8155,
|
||||
0x839e, 0x8c4c, 0x962e, 0x9811, 0x66f0, 0x5f80, 0x65fa, 0x6789,
|
||||
0x6c6a, 0x738b, 0x617e, 0x6b32, 0x6d74, 0x7e1f, 0x8925, 0x8fb1,
|
||||
0x4fd1, 0x50ad, 0x5197, 0x52c7, 0x57c7, 0x5889, 0x5bb9, 0x5eb8,
|
||||
0x6142, 0x6995, 0x6d8c, 0x6e67, 0x6eb6, 0x7194, 0x7462, 0x7528,
|
||||
0x752c, 0x8073, 0x8338, 0x84c9, 0x8e0a, 0x9394, 0x93de, 0xf9c4,
|
||||
0x52d6, 0x5f67, 0x65ed, 0x6631, 0x682f, 0x715c, 0x7a36, 0x90c1,
|
||||
0x980a, 0x4e91, 0xf9c5, 0x6a52, 0x6b9e, 0x6f90, 0x7189, 0x8018,
|
||||
0x82b8, 0x8553, 0x904b, 0x9695, 0x96f2, 0x97fb, 0x851a, 0x9b31,
|
||||
0x4e90, 0x718a, 0x96c4, 0x5143, 0x539f, 0x54e1, 0x5713, 0x5712,
|
||||
0x57a3, 0x5a9b, 0x5ac4, 0x5bc3, 0x6028, 0x613f, 0x63f4, 0x6c85,
|
||||
0x6d39, 0x6e72, 0x6e90, 0x7230, 0x733f, 0x7457, 0x82d1, 0x8881,
|
||||
0x8f45, 0x9060, 0xf9c6, 0x9662, 0x9858, 0x9d1b, 0x6708, 0x8d8a,
|
||||
0x925e, 0xf9d1, 0x5809, 0xf9d2, 0x6bd3, 0x8089, 0x80b2, 0xf9d3,
|
||||
0xf9d4, 0x5141, 0x596b, 0x5c39, 0xf9d5, 0xf9d6, 0x6f64, 0x73a7,
|
||||
0x80e4, 0x8d07, 0xf9d7, 0x9217, 0x958f, 0xf9d8, 0xf9d9, 0xf9da,
|
||||
0xf9db, 0x807f, 0x620e, 0x701c, 0x7d68, 0x878d, 0xf9dc, 0x57a0,
|
||||
0x6069, 0x6147, 0x6bb7, 0x8abe, 0x9280, 0x96b1, 0x4e59, 0x541f,
|
||||
0x6deb, 0x852d, 0x9670, 0x97f3, 0x98ee, 0x63d6, 0x6ce3, 0x9091,
|
||||
0x51dd, 0x61c9, 0x81ba, 0x9df9, 0xf9eb, 0xf9ec, 0x7037, 0x76ca,
|
||||
0x7fca, 0x7fcc, 0x7ffc, 0x8b1a, 0x4eba, 0x4ec1, 0x5203, 0x5370,
|
||||
0xf9ed, 0x54bd, 0x56e0, 0x59fb, 0x5bc5, 0x5f15, 0x5fcd, 0x6e6e,
|
||||
0xf9ee, 0xf9ef, 0x7d6a, 0x8335, 0xf9f0, 0x8693, 0x8a8d, 0xf9f1,
|
||||
0x976d, 0x9777, 0xf9f2, 0xf9f3, 0x4e00, 0x4f5a, 0x4f7e, 0x58f9,
|
||||
0x65e5, 0x6ea2, 0x9038, 0x93b0, 0x99b9, 0x4efb, 0x58ec, 0x598a,
|
||||
0x59d9, 0x6041, 0xf9f4, 0xf9f5, 0x7a14, 0xf9f6, 0x834f, 0x8cc3,
|
||||
0x5165, 0x5344, 0xf9f7, 0xf9f8, 0xf9f9, 0x4ecd, 0x5269, 0x5b55,
|
||||
0x82bf, 0x4f5c, 0x52fa, 0x56bc, 0x65ab, 0x6628, 0x707c, 0x70b8,
|
||||
0x7235, 0x7dbd, 0x828d, 0x914c, 0x96c0, 0x9d72, 0x5b71, 0x68e7,
|
||||
0x6b98, 0x6f7a, 0x76de, 0x5c91, 0x66ab, 0x6f5b, 0x7bb4, 0x7c2a,
|
||||
0x8836, 0x96dc, 0x4e08, 0x4ed7, 0x5320, 0x5834, 0x58bb, 0x58ef,
|
||||
0x596c, 0x5c07, 0x5e33, 0x5e84, 0x5f35, 0x638c, 0x66b2, 0x6756,
|
||||
0x6a1f, 0x6aa3, 0x6b0c, 0x6f3f, 0x7246, 0xf9fa, 0x7350, 0x748b,
|
||||
0x7ae0, 0x7ca7, 0x8178, 0x81df, 0x81e7, 0x838a, 0x846c, 0x8523,
|
||||
0x8594, 0x85cf, 0x88dd, 0x8d13, 0x91ac, 0x9577, 0x969c, 0x722d,
|
||||
0x7b8f, 0x8acd, 0x931a, 0x52e3, 0x540a, 0x5ae1, 0x5bc2, 0x6458,
|
||||
0x6575, 0x6ef4, 0x72c4, 0xf9fb, 0x7684, 0x7a4d, 0x7b1b, 0x7c4d,
|
||||
0x7e3e, 0x7fdf, 0x837b, 0x8b2b, 0x8cca, 0x8d64, 0x8de1, 0x8e5f,
|
||||
0x8fea, 0x8ff9, 0x9069, 0x93d1, 0x4f43, 0x4f7a, 0x50b3, 0x5168,
|
||||
0x5178, 0x524d, 0x526a, 0x5861, 0x587c, 0x5960, 0x5c08, 0x5c55,
|
||||
0x5edb, 0x609b, 0x6230, 0x6813, 0x6bbf, 0x6c08, 0x6fb1, 0x714e,
|
||||
0x7420, 0x7530, 0x7538, 0x7551, 0x7672, 0x7b4c, 0x7b8b, 0x7bad,
|
||||
0x7bc6, 0x7e8f, 0x8a6e, 0x8f3e, 0x8f49, 0x923f, 0x9293, 0x9322,
|
||||
0x942b, 0x96fb, 0x985a, 0x986b, 0x991e, 0x5207, 0x622a, 0x6298,
|
||||
0x6d59, 0x7664, 0x7aca, 0x7bc0, 0x7d76, 0x5360, 0x5cbe, 0x5e97,
|
||||
0x6f38, 0x70b9, 0x7c98, 0x9711, 0x9b8e, 0x9ede, 0x63a5, 0x647a,
|
||||
0x8776, 0x4e01, 0x4e95, 0x4ead, 0x505c, 0x5075, 0x5448, 0x59c3,
|
||||
0x5b9a, 0x5e40, 0x5ead, 0x5ef7, 0x5f81, 0x60c5, 0x633a, 0x653f,
|
||||
0x6574, 0x65cc, 0x6676, 0x6678, 0x67fe, 0x6968, 0x6a89, 0x6b63,
|
||||
0x6c40, 0x6dc0, 0x6de8, 0x6e1f, 0x6e5e, 0x701e, 0x70a1, 0x738e,
|
||||
0x73fd, 0x753a, 0x775b, 0x7887, 0x798e, 0x7a0b, 0x7a7d, 0x7cbe,
|
||||
0x7d8e, 0x8247, 0x8a02, 0x8aea, 0x8c9e, 0x912d, 0x914a, 0x91d8,
|
||||
0x9266, 0x92cc, 0x9320, 0x9706, 0x9756, 0x975c, 0x9802, 0x9f0e,
|
||||
0x65cf, 0x7c07, 0x8db3, 0x93c3, 0x5b58, 0x5c0a, 0x5352, 0x62d9,
|
||||
0x731d, 0x5027, 0x5b97, 0x5f9e, 0x60b0, 0x616b, 0x68d5, 0x6dd9,
|
||||
0x742e, 0x7a2e, 0x7d42, 0x7d9c, 0x7e31, 0x816b, 0x8e2a, 0x8e35,
|
||||
0x937e, 0x9418, 0x7af9, 0x7ca5, 0x4fca, 0x5101, 0x51c6, 0x57c8,
|
||||
0x5bef, 0x5cfb, 0x6659, 0x6a3d, 0x6d5a, 0x6e96, 0x6fec, 0x710c,
|
||||
0x756f, 0x7ae3, 0x8822, 0x9021, 0x9075, 0x96cb, 0x99ff, 0x8301,
|
||||
0x4e2d, 0x4ef2, 0x8846, 0x91cd, 0x537d, 0x6adb, 0x696b, 0x6c41,
|
||||
0x847a, 0x589e, 0x618e, 0x66fe, 0x62ef, 0x70dd, 0x7511, 0x75c7,
|
||||
0x7e52, 0x84b8, 0x8b49, 0x8d08, 0x76f4, 0x7a19, 0x7a37, 0x7e54,
|
||||
0x8077, 0x5507, 0x55d4, 0x5875, 0x632f, 0x6422, 0x6649, 0x664b,
|
||||
0x686d, 0x699b, 0x6b84, 0x6d25, 0x6eb1, 0x73cd, 0x7468, 0x74a1,
|
||||
0x755b, 0x75b9, 0x76e1, 0x771e, 0x778b, 0x79e6, 0x7e09, 0x7e1d,
|
||||
0x81fb, 0x852f, 0x8897, 0x8a3a, 0x8cd1, 0x8eeb, 0x8fb0, 0x9032,
|
||||
0x93ad, 0x9663, 0x9673, 0x9707, 0x4f84, 0x53f1, 0x59ea, 0x5ac9,
|
||||
0x5e19, 0x684e, 0x74c6, 0x75be, 0x79e9, 0x7a92, 0x81a3, 0x86ed,
|
||||
0x8cea, 0x8dcc, 0x8fed, 0x659f, 0x6715, 0xf9fd, 0x57f7, 0x6f57,
|
||||
0x7ddd, 0x8f2f, 0x93f6, 0x96c6, 0x5fb5, 0x61f2, 0x6f84, 0x6349,
|
||||
0x643e, 0x7740, 0x7a84, 0x932f, 0x947f, 0x9f6a, 0x64b0, 0x6faf,
|
||||
0x71e6, 0x74a8, 0x74da, 0x7ac4, 0x7c12, 0x7e82, 0x7cb2, 0x7e98,
|
||||
0x8b9a, 0x8d0a, 0x947d, 0x9910, 0x994c, 0x5239, 0x5bdf, 0x64e6,
|
||||
0x672d, 0x7d2e, 0x50ed, 0x53c3, 0x5879, 0x6158, 0x6159, 0x61fa,
|
||||
0x65ac, 0x7ad9, 0x8b92, 0x8b96, 0x5009, 0x5021, 0x5275, 0x5531,
|
||||
0x5a3c, 0x5ee0, 0x5f70, 0x6134, 0x655e, 0x660c, 0x6636, 0x66a2,
|
||||
0x69cd, 0x6ec4, 0x6f32, 0x7316, 0x7621, 0x7a93, 0x8139, 0x8259,
|
||||
0x83d6, 0x84bc, 0x518a, 0x67f5, 0x7b56, 0x8cac, 0x501c, 0xf9ff,
|
||||
0x5254, 0x5c3a, 0x617d, 0x621a, 0x62d3, 0x64f2, 0x65a5, 0x6ecc,
|
||||
0x7620, 0x810a, 0x8e60, 0x965f, 0x96bb, 0x4edf, 0x5343, 0x5598,
|
||||
0x5929, 0x5ddd, 0x64c5, 0x6cc9, 0x6dfa, 0x7394, 0x7a7f, 0x821b,
|
||||
0x85a6, 0x8ce4, 0x8e10, 0x9077, 0x91e7, 0x95e1, 0x9621, 0x97c6,
|
||||
0x51f8, 0x54f2, 0x5586, 0x5fb9, 0x64a4, 0x6f88, 0x7db4, 0x8f1f,
|
||||
0x8f4d, 0x9435, 0x50c9, 0x5c16, 0x6cbe, 0x6dfb, 0x751b, 0x77bb,
|
||||
0x7c3d, 0x7c64, 0x8a79, 0x8ac2, 0x581e, 0x59be, 0x5e16, 0x6377,
|
||||
0x7252, 0x758a, 0x776b, 0x8adc, 0x8cbc, 0x8f12, 0x5ef3, 0x6674,
|
||||
0x6df8, 0x807d, 0x83c1, 0x8acb, 0x9751, 0x9bd6, 0x4fc3, 0x56d1,
|
||||
0x71ed, 0x77d7, 0x8700, 0x89f8, 0x5bf8, 0x5fd6, 0x6751, 0x90a8,
|
||||
0x53e2, 0x585a, 0x5bf5, 0x60a4, 0x6181, 0x6460, 0x7e3d, 0x8070,
|
||||
0x8525, 0x9283, 0x64ae, 0x4e11, 0x755c, 0x795d, 0x7afa, 0x7b51,
|
||||
0x7bc9, 0x7e2e, 0x84c4, 0x8e59, 0x8e74, 0x8ef8, 0x9010, 0x6625,
|
||||
0x693f, 0x7443, 0x51fa, 0x672e, 0x9edc, 0x5145, 0x5fe0, 0x6c96,
|
||||
0x87f2, 0x885d, 0x8877, 0x5074, 0x4ec4, 0x53a0, 0x60fb, 0x6e2c,
|
||||
0x5c64, 0x5247, 0x52c5, 0x98ed, 0x89aa, 0x4e03, 0x67d2, 0x6f06,
|
||||
0x4fb5, 0x5be2, 0x6795, 0x6c88, 0x6d78, 0x741b, 0x7827, 0x91dd,
|
||||
0x937c, 0x87c4, 0x79e4, 0x7a31, 0x502c, 0x5353, 0x5544, 0x577c,
|
||||
0xfa01, 0x6258, 0xfa02, 0x64e2, 0x666b, 0x67dd, 0x6fc1, 0x6fef,
|
||||
0x7422, 0x7438, 0x8a17, 0x9438, 0x5451, 0x5606, 0x5766, 0x5f48,
|
||||
0x619a, 0x6b4e, 0x7058, 0x70ad, 0x7dbb, 0x8a95, 0x596a, 0x812b,
|
||||
0x63a2, 0x7708, 0x803d, 0x8caa, 0x5854, 0x642d, 0x69bb, 0x5b95,
|
||||
0x5e11, 0x6e6f, 0xfa03, 0x8569, 0xfa04, 0x64c7, 0x6fa4, 0x6491,
|
||||
0x615f, 0x6876, 0xfa05, 0x75db, 0x7b52, 0x7d71, 0x901a, 0x615d,
|
||||
0x7279, 0x95d6, 0x5224, 0x5742, 0x677f, 0x7248, 0x74e3, 0x8ca9,
|
||||
0x8fa6, 0x9211, 0x962a, 0x516b, 0x53ed, 0x634c, 0x5f6d, 0x6f8e,
|
||||
0x70f9, 0x81a8, 0x610e, 0x4fbf, 0x504f, 0x6241, 0x7247, 0x7bc7,
|
||||
0x7de8, 0x7fe9, 0x904d, 0x97ad, 0x9a19, 0x8cb6, 0x576a, 0x5e73,
|
||||
0x67b0, 0x840d, 0x8a55, 0x5e45, 0x66b4, 0x66dd, 0x7011, 0x7206,
|
||||
0xfa07, 0x54c1, 0x7a1f, 0x6953, 0x8af7, 0x8c4a, 0x98a8, 0x99ae,
|
||||
0x5339, 0x5f3c, 0x5fc5, 0x6ccc, 0x73cc, 0x7562, 0x758b, 0x7b46,
|
||||
0x82fe, 0x999d, 0x4e4f, 0x903c, 0x58d1, 0x5b78, 0x8650, 0x8b14,
|
||||
0x9db4, 0x5bd2, 0x6068, 0x608d, 0x65f1, 0x6c57, 0x6f22, 0x6fa3,
|
||||
0x701a, 0x7f55, 0x7ff0, 0x9591, 0x9592, 0x9650, 0x97d3, 0x5272,
|
||||
0x8f44, 0x51fd, 0x542b, 0x54b8, 0x5563, 0x558a, 0x6abb, 0x6db5,
|
||||
0x7dd8, 0x8266, 0x929c, 0x9677, 0x9e79, 0x5408, 0x54c8, 0x76d2,
|
||||
0x86e4, 0x95a4, 0x95d4, 0x965c, 0x4ea2, 0x4f09, 0x59ee, 0x5ae6,
|
||||
0x5df7, 0x6052, 0x6297, 0x676d, 0x6841, 0x6c86, 0x6e2f, 0x7f38,
|
||||
0x809b, 0x822a, 0xfa08, 0xfa09, 0x9805, 0x52be, 0x6838, 0x5016,
|
||||
0x5e78, 0x674f, 0x8347, 0x884c, 0x4eab, 0x5411, 0x56ae, 0x73e6,
|
||||
0x9115, 0x97ff, 0x9909, 0x9957, 0x9999, 0x61b2, 0x6af6, 0x737b,
|
||||
0x8ed2, 0x6b47, 0x96aa, 0x9a57, 0x5955, 0x7200, 0x8d6b, 0x9769,
|
||||
0x4fd4, 0x5cf4, 0x5f26, 0x61f8, 0x665b, 0x6ceb, 0x70ab, 0x7384,
|
||||
0x73b9, 0x73fe, 0x7729, 0x774d, 0x7d43, 0x7d62, 0x7e23, 0x8237,
|
||||
0x8852, 0xfa0a, 0x8ce2, 0x9249, 0x986f, 0x5b51, 0x7a74, 0x8840,
|
||||
0x9801, 0x5acc, 0x4fe0, 0x5354, 0x593e, 0x5cfd, 0x633e, 0x6d79,
|
||||
0x72f9, 0x8105, 0x8107, 0x83a2, 0x92cf, 0x9830, 0x4ea8, 0x5144,
|
||||
0x5211, 0x578b, 0x5f62, 0x6cc2, 0x6ece, 0x7005, 0x7050, 0x70af,
|
||||
0x7192, 0x73e9, 0x7469, 0x834a, 0x87a2, 0x8861, 0x9008, 0x90a2,
|
||||
0x93a3, 0x99a8, 0x60d1, 0x6216, 0x9177, 0x5a5a, 0x660f, 0x6df7,
|
||||
0x6e3e, 0x743f, 0x9b42, 0x5ffd, 0x60da, 0x7b0f, 0x54c4, 0x5f18,
|
||||
0x6c5e, 0x6cd3, 0x6d2a, 0x70d8, 0x7d05, 0x8679, 0x8a0c, 0x9d3b,
|
||||
0xfa0b, 0x64f4, 0x652b, 0x78ba, 0x78bb, 0x7a6b, 0x4e38, 0x559a,
|
||||
0x5950, 0x5ba6, 0x5e7b, 0x60a3, 0x63db, 0x6b61, 0x6665, 0x6853,
|
||||
0x6e19, 0x7165, 0x74b0, 0x7d08, 0x9084, 0x9a69, 0x9c25, 0x6d3b,
|
||||
0x6ed1, 0x733e, 0x8c41, 0x95ca, 0x51f0, 0x5e4c, 0x5fa8, 0x604d,
|
||||
0x60f6, 0x6130, 0x614c, 0x6643, 0x6644, 0x69a5, 0x6cc1, 0x6e5f,
|
||||
0x6ec9, 0x6f62, 0x714c, 0x749c, 0x7687, 0x7bc1, 0x7c27, 0x8352,
|
||||
0x8757, 0x9051, 0x968d, 0x9ec3, 0x5283, 0x7372, 0x5b96, 0x6a6b,
|
||||
0x9404, 0x52db, 0x52f3, 0x5864, 0x58ce, 0x7104, 0x718f, 0x71fb,
|
||||
0x85b0, 0x8a13, 0x6688, 0x85a8, 0x55a7, 0x6684, 0x714a, 0x8431,
|
||||
0x6064, 0x8b4e, 0x9df8, 0x5147, 0x51f6, 0x5308, 0x6d36, 0x80f8,
|
||||
0x9ed1, 0x6615, 0x6b23, 0x7098, 0x75d5, 0x5403, 0x5c79, 0x7d07,
|
||||
0x8a16, 0x6b20, 0x6b3d, 0x6b46, 0x5438, 0x6070, 0x6d3d, 0x7fd5,
|
||||
0x8208, 0x8a70, 0xfa0b
|
||||
];
|
||||
|
||||
const RO_HANJA = [
|
||||
0x4e6b, 0x559d, 0x66f7, 0x6e34, 0x78a3, 0x7aed, 0x845b, 0x8910,
|
||||
0x874e, 0x97a8, 0x4e5e, 0x5091, 0x6770, 0x6840, 0x6289, 0x6c7a,
|
||||
0x6f54, 0x7d50, 0x7f3a, 0x8a23, 0x6c68, 0xf904, 0x9aa8, 0x522e,
|
||||
0x605d, 0x62ec, 0x9002, 0x5800, 0x5c48, 0x6398, 0x7a9f, 0x53a5,
|
||||
0x7357, 0x8568, 0x8e76, 0x95d5, 0x6a58, 0xf909, 0x4f76, 0x5409,
|
||||
0x62ee, 0x6854, 0x634f, 0x637a, 0x8a25, 0x64bb, 0x6fbe, 0x737a,
|
||||
0x75b8, 0x9054, 0x4e6d, 0x7a81, 0x524c, 0x8fa3, 0x51bd, 0x5217,
|
||||
0x52a3, 0x6d0c, 0x70c8, 0x88c2, 0x5f8b, 0x6144, 0x6817, 0xf961,
|
||||
0x551c, 0x62b9, 0x672b, 0x6cab, 0x8309, 0x896a, 0x977a, 0x6ec5,
|
||||
0x8511, 0x6b7f, 0x6c92, 0x52ff, 0x6c95, 0x7269, 0x5bc6, 0x871c,
|
||||
0x8b10, 0x52c3, 0x62d4, 0x64a5, 0x6e24, 0x6f51, 0x767c, 0x8dcb,
|
||||
0x91b1, 0x9262, 0x9aee, 0x9b43, 0x4f10, 0x7b4f, 0x7f70, 0x95a5,
|
||||
0x5225, 0x77a5, 0x9c49, 0x9f08, 0x4e76, 0xf967, 0x4f5b, 0x5f17,
|
||||
0x5f7f, 0x62c2, 0x4e77, 0x6492, 0x6bba, 0x715e, 0x85a9, 0x5368,
|
||||
0x5c51, 0x6954, 0x6cc4, 0x6d29, 0x6e2b, 0x820c, 0x859b, 0x893b,
|
||||
0x8a2d, 0x8aaa, 0x96ea, 0x9f67, 0x7387, 0x620c, 0x8853, 0x8ff0,
|
||||
0x9265, 0x745f, 0x819d, 0x8768, 0x5931, 0x5ba4, 0x5be6, 0x6089,
|
||||
0x65a1, 0x8b01, 0x8ecb, 0x95bc, 0x5b7c, 0x8616, 0xf99c, 0xf99d,
|
||||
0xf99e, 0x6085, 0x6d85, 0xf99f, 0x71b1, 0xf9a0, 0xf9a1, 0x95b1,
|
||||
0x5140, 0x66f0, 0x851a, 0x9b31, 0x4e90, 0x6708, 0x8d8a, 0x925e,
|
||||
0xf9d8, 0xf9d9, 0xf9da, 0xf9db, 0x807f, 0x4e59, 0x4e00, 0x4f5a,
|
||||
0x4f7e, 0x58f9, 0x65e5, 0x6ea2, 0x9038, 0x93b0, 0x99b9, 0x5207,
|
||||
0x622a, 0x6298, 0x6d59, 0x7664, 0x7aca, 0x7bc0, 0x7d76, 0x5352,
|
||||
0x62d9, 0x731d, 0x8301, 0x6adb, 0x4f84, 0x53f1, 0x59ea, 0x5ac9,
|
||||
0x5e19, 0x684e, 0x74c6, 0x75be, 0x79e9, 0x7a92, 0x81a3, 0x86ed,
|
||||
0x8cea, 0x8dcc, 0x8fed, 0x5239, 0x5bdf, 0x64e6, 0x672d, 0x7d2e,
|
||||
0x51f8, 0x54f2, 0x5586, 0x5fb9, 0x64a4, 0x6f88, 0x7db4, 0x8f1f,
|
||||
0x8f4d, 0x9435, 0x64ae, 0x51fa, 0x672e, 0x9edc, 0x4e03, 0x67d2,
|
||||
0x6f06, 0x596a, 0x812b, 0x516b, 0x53ed, 0x634c, 0x5339, 0x5f3c,
|
||||
0x5fc5, 0x6ccc, 0x73cc, 0x7562, 0x758b, 0x7b46, 0x82fe, 0x999d,
|
||||
0x5272, 0x8f44, 0x6b47, 0x5b51, 0x7a74, 0x8840, 0x9801, 0x5ffd,
|
||||
0x60da, 0x7b0f, 0x6d3b, 0x6ed1, 0x733e, 0x8c41, 0x95ca, 0x6064,
|
||||
0x8b4e, 0x9df8, 0x5403, 0x5c79, 0x7d07, 0x8a16, 0x8a70,
|
||||
];
|
||||
|
||||
const regNormalFixed = new RegExp(`/(?:${PRE_REG_NORMAL_FIXED.join('|')})$/iu`);
|
||||
const regSpecialChar = new RegExp(`/(?:${PRE_REG_SPECIAL_CHAR.join('|')})$/iu`);
|
||||
const regSpecialRo = new RegExp(`/(?:${PRE_REG_SPECIAL_RO.join('|')})$/iu`);
|
||||
|
||||
const jongsungHanja = new Set<number>();
|
||||
for (const hanjaCode of JONGSUNG_HANJA) {
|
||||
jongsungHanja.add(hanjaCode);
|
||||
}
|
||||
const roHanja = new Set<number>();
|
||||
for (const hanjaCode of RO_HANJA) {
|
||||
roHanja.add(hanjaCode);
|
||||
}
|
||||
const mapPostPosition = new Map<string, string>();
|
||||
for (const [key, val] of Object.entries(DEFAULT_POSTPOSITION)) {
|
||||
mapPostPosition.set(`(${key})${val}`, key);
|
||||
mapPostPosition.set(key, key);
|
||||
mapPostPosition.set(val, key);
|
||||
}
|
||||
|
||||
function checkText(text: string, isRo: boolean): boolean {
|
||||
if (regNormalFixed.test(text)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (regSpecialChar.test(text)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!isRo && regSpecialRo.test(text)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkCode(code: number, isRo: boolean): boolean {
|
||||
const jongsung = (code - KO_START_CODE) % 28;
|
||||
if (jongsung === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isRo && jongsung === 8) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export function check(text: string, type: string): boolean {
|
||||
|
||||
const htarget = text.replace(REG_INVALID_CHAR_W_HANJA, ' ').replace(REG_TARGET_CHAR, '$1');
|
||||
if (!htarget) {
|
||||
return false;
|
||||
}
|
||||
const hcode = htarget.charAt(htarget.length - 1).charCodeAt(0);
|
||||
const isRo = type === '로' || type === '으로';
|
||||
|
||||
if (HANJA_START_CODE <= hcode && hcode <= HANJA_FINISH_CODE) {
|
||||
if (isRo && roHanja.has(hcode)) {
|
||||
return false;
|
||||
}
|
||||
if (jongsungHanja.has(hcode)) {
|
||||
return true;
|
||||
}
|
||||
if (hcode < KO_START_CODE || KO_FINISH_CODE < hcode) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const target = text.replace(REG_INVALID_CHAR, ' ').replace(REG_TARGET_CHAR, '$1');
|
||||
const code = target.charAt(target.length - 1).charCodeAt(0);
|
||||
|
||||
const isKorean = KO_START_CODE <= code && code <= KO_FINISH_CODE;
|
||||
|
||||
return isKorean ? checkCode(code, isRo) : checkText(target, isRo);
|
||||
}
|
||||
|
||||
export function pick(text: string|number, wJongsung: string, woJongsung = ''): string {
|
||||
/* NOTE:원본 코드와 인자 순서가 다름.
|
||||
* 원본은 pick('바람', '랑', '이랑'); 이었다면 pick('바람', '이랑', '랑'); 으로 바뀜.
|
||||
* pick('바람', '은', '는'); JosaUtil.pick('바람', '이', '가');처럼 쓰기 위해서임.
|
||||
*/
|
||||
if (!text) {
|
||||
text = '';
|
||||
} else if(typeof text === 'number'){
|
||||
text = String(text);
|
||||
}
|
||||
|
||||
if(!woJongsung){
|
||||
if(!mapPostPosition.has(wJongsung)){
|
||||
throw `올바르지 않은 조사 지정: ${wJongsung}`;
|
||||
}
|
||||
wJongsung = unwrap_err(mapPostPosition.get(wJongsung), Error, `올바르지 않은 조사 지정: ${wJongsung}`);
|
||||
woJongsung = DEFAULT_POSTPOSITION[wJongsung as keyof typeof DEFAULT_POSTPOSITION];
|
||||
}
|
||||
|
||||
return check(text, wJongsung) ? wJongsung : woJongsung;
|
||||
}
|
||||
|
||||
export function put(text: string, wJongsung: string, woJongsung = ''): string{
|
||||
return `${text}${pick(text, wJongsung, woJongsung)}`;
|
||||
}
|
||||
|
||||
export function fix(wJongsung: string, woJongsung = ''){
|
||||
if(!woJongsung){
|
||||
if(!mapPostPosition.has(wJongsung)){
|
||||
throw `올바르지 않은 조사 지정: ${wJongsung}`;
|
||||
}
|
||||
wJongsung = unwrap_err(mapPostPosition.get(wJongsung), Error, `올바르지 않은 조사 지정: ${wJongsung}`);
|
||||
woJongsung = DEFAULT_POSTPOSITION[wJongsung as keyof typeof DEFAULT_POSTPOSITION];
|
||||
}
|
||||
return function(text: string){
|
||||
return put(text, wJongsung, woJongsung);
|
||||
}
|
||||
}
|
||||
|
||||
export function batch(text: string, decorator = ';'){
|
||||
const regExp = new RegExp(`${decorator}([^${decorator}]+)${decorator}([^${decorator}]*)${decorator}([^${decorator}]+)${decorator}`, 'g');
|
||||
|
||||
let matchRes;
|
||||
let lastIndex = 0;
|
||||
|
||||
const result: string[] = [];
|
||||
|
||||
while ((matchRes = regExp.exec(text)) !== null) {
|
||||
const {
|
||||
0: partAll,
|
||||
1: body,
|
||||
2: filler,
|
||||
3: wJongsung,
|
||||
index,
|
||||
} = matchRes;
|
||||
if(lastIndex != index){
|
||||
result.push(text.slice(lastIndex, index));
|
||||
}
|
||||
|
||||
result.push(body, filler, pick(body, wJongsung));
|
||||
|
||||
lastIndex = index + partAll.length;
|
||||
}
|
||||
if(lastIndex != text.length){
|
||||
result.push(text.slice(lastIndex));
|
||||
}
|
||||
|
||||
return result.join('');
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
import type { RNG } from "./RNG";
|
||||
|
||||
import { sha512 } from 'js-sha512';
|
||||
|
||||
import { convertBytesLikeToUint8Array } from "./convertBytesLikeToUint8Array";
|
||||
import type { BytesLike } from "./BytesLike";
|
||||
|
||||
const maxRngSupportBit = 53;
|
||||
const maxInt = 0x1f_ffff_ffff_ffff; // NOTE: b 0, 10000110011, 11...11
|
||||
const maxIntMore1 = 0x20_0000_0000_0000n; //NOTE: b 0, 10000110100, 00...00
|
||||
const maxIntMore1f = Number(maxIntMore1);
|
||||
export const bufferByteSize = 512 / 8; //SHA512
|
||||
|
||||
const intBitMapMask = new Map([
|
||||
[0x1n, 1],
|
||||
[0x3n, 2],
|
||||
[0x7n, 3],
|
||||
[0xfn, 4],
|
||||
[0x1fn, 5],
|
||||
[0x3fn, 6],
|
||||
[0x7fn, 7],
|
||||
[0xffn, 8],
|
||||
[0x1ffn, 9],
|
||||
[0x3ffn, 10],
|
||||
[0x7ffn, 11],
|
||||
[0xfffn, 12],
|
||||
[0x1fffn, 13],
|
||||
[0x3fffn, 14],
|
||||
[0x7fffn, 15],
|
||||
[0xffffn, 16],
|
||||
[0x1ffffn, 17],
|
||||
[0x3ffffn, 18],
|
||||
[0x7ffffn, 19],
|
||||
[0xfffffn, 20],
|
||||
[0x1fffffn, 21],
|
||||
[0x3fffffn, 22],
|
||||
[0x7fffffn, 23],
|
||||
[0xffffffn, 24],
|
||||
[0x1ffffffn, 25],
|
||||
[0x3ffffffn, 26],
|
||||
[0x7ffffffn, 27],
|
||||
[0xfffffffn, 28],
|
||||
[0x1fffffffn, 29],
|
||||
[0x3fffffffn, 30],
|
||||
[0x7fffffffn, 31],
|
||||
[0xffffffffn, 32],
|
||||
[0x1ffffffffn, 33],
|
||||
[0x3ffffffffn, 34],
|
||||
[0x7ffffffffn, 35],
|
||||
[0xfffffffffn, 36],
|
||||
[0x1fffffffffn, 37],
|
||||
[0x3fffffffffn, 38],
|
||||
[0x7fffffffffn, 39],
|
||||
[0xffffffffffn, 40],
|
||||
[0x1ffffffffffn, 41],
|
||||
[0x3ffffffffffn, 42],
|
||||
[0x7ffffffffffn, 43],
|
||||
[0xfffffffffffn, 44],
|
||||
[0x1fffffffffffn, 45],
|
||||
[0x3fffffffffffn, 46],
|
||||
[0x7fffffffffffn, 47],
|
||||
[0xffffffffffffn, 48],
|
||||
[0x1ffffffffffffn, 49],
|
||||
[0x3ffffffffffffn, 50],
|
||||
[0x7ffffffffffffn, 51],
|
||||
[0xfffffffffffffn, 52],
|
||||
[0x1fffffffffffffn, 53],
|
||||
]);
|
||||
|
||||
function calcBitMask(n: bigint): bigint {
|
||||
n |= n >> 1n;
|
||||
n |= n >> 2n;
|
||||
n |= n >> 4n;
|
||||
n |= n >> 8n;
|
||||
n |= n >> 16n;
|
||||
n |= n >> 32n;
|
||||
|
||||
return n;
|
||||
}
|
||||
export class LiteHashDRBG implements RNG {
|
||||
|
||||
protected buffer!: ArrayBuffer;
|
||||
protected bufferIdx!: number;
|
||||
protected hq: DataView;
|
||||
protected hqIdxPos: number;
|
||||
|
||||
public constructor(protected seed: BytesLike, protected stateIdx = 0, bufferIdx = 0) {
|
||||
if(bufferIdx < 0){
|
||||
throw new Error(`bufferIdx ${bufferIdx} < 0`);
|
||||
}
|
||||
if(bufferIdx >= bufferByteSize){
|
||||
throw new Error(`bufferidx ${bufferIdx} >= ${bufferByteSize}`);
|
||||
}
|
||||
if(stateIdx < 0){
|
||||
throw new Error(`stateIdx ${stateIdx} < 0`);
|
||||
}
|
||||
|
||||
const seedU8 = convertBytesLikeToUint8Array(seed);
|
||||
const hqBuffer = new ArrayBuffer(seedU8.byteLength + 4);
|
||||
const hqU8 = new Uint8Array(hqBuffer);
|
||||
|
||||
hqU8.set(seedU8, 0);
|
||||
this.hq = new DataView(hqBuffer);
|
||||
this.hqIdxPos = seedU8.byteLength;
|
||||
|
||||
this.genNextBlock();
|
||||
this.bufferIdx = bufferIdx;
|
||||
}
|
||||
|
||||
protected genNextBlock(): void {
|
||||
this.hq.setUint32(this.hqIdxPos, this.stateIdx, true);
|
||||
const digest = sha512.arrayBuffer(this.hq.buffer);
|
||||
this.buffer = digest;
|
||||
this.bufferIdx = 0;
|
||||
this.stateIdx += 1;
|
||||
}
|
||||
|
||||
public getMaxInt(): number {
|
||||
return maxInt;
|
||||
}
|
||||
|
||||
public nextBytes(bytes: number, baseBytes?: number): Uint8Array {
|
||||
bytes |= 0;
|
||||
if (bytes <= 0) {
|
||||
throw new Error(`${bytes} <= 0`);
|
||||
}
|
||||
|
||||
if (this.bufferIdx + bytes <= bufferByteSize) {
|
||||
if(baseBytes === undefined || bytes >= baseBytes){
|
||||
const result = this.buffer.slice(this.bufferIdx, this.bufferIdx + bytes);
|
||||
this.bufferIdx += bytes;
|
||||
if (this.bufferIdx === bufferByteSize) {
|
||||
this.genNextBlock();
|
||||
}
|
||||
return new Uint8Array(result);
|
||||
}
|
||||
|
||||
const resultBuffer = new ArrayBuffer(Math.max(bytes, baseBytes));
|
||||
const result = new Uint8Array(resultBuffer);
|
||||
result.set(new Uint8Array(this.buffer, this.bufferIdx, bytes));
|
||||
this.bufferIdx += bytes;
|
||||
if( this.bufferIdx === bufferByteSize){
|
||||
this.genNextBlock();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const resultBuffer = new ArrayBuffer(baseBytes ? Math.max(bytes, baseBytes) : bytes);
|
||||
const result = new Uint8Array(resultBuffer);
|
||||
|
||||
result.set(new Uint8Array(this.buffer, this.bufferIdx));
|
||||
let offset = bufferByteSize - this.bufferIdx;
|
||||
let remain = bytes - offset;
|
||||
|
||||
while (remain > bufferByteSize) {
|
||||
this.genNextBlock();
|
||||
result.set(new Uint8Array(this.buffer), offset);
|
||||
offset += bufferByteSize;
|
||||
remain -= bufferByteSize;
|
||||
}
|
||||
|
||||
this.genNextBlock();
|
||||
if (remain === 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result.set(new Uint8Array(this.buffer, 0, remain), offset);
|
||||
this.bufferIdx = remain;
|
||||
return result;
|
||||
}
|
||||
|
||||
public nextBits(bits: number, baseBytes?: number): Uint8Array {
|
||||
bits |= 0;
|
||||
const bytes = (bits + 7) >> 3;
|
||||
const headBits = bits & 0x7;
|
||||
|
||||
const result = this.nextBytes(bytes, baseBytes);
|
||||
if (headBits === 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result[bytes - 1] &= 0xff >> (8 - headBits);
|
||||
return result;
|
||||
}
|
||||
|
||||
protected _nextInt(bits: number): bigint{
|
||||
const buffer = this.nextBits(bits, 8);
|
||||
const dataView = new DataView(buffer.buffer);
|
||||
return dataView.getBigUint64(0, true);
|
||||
}
|
||||
|
||||
public nextInt(max?: number): number {
|
||||
if (max === undefined || max === maxInt) {
|
||||
return Number(this._nextInt(maxRngSupportBit));
|
||||
}
|
||||
if (max > maxInt) {
|
||||
throw new Error('Over max int');
|
||||
}
|
||||
if (max === 0) {
|
||||
return 0;
|
||||
}
|
||||
if (max < 0) {
|
||||
return -this.nextInt(-max);
|
||||
}
|
||||
|
||||
const mask = calcBitMask(BigInt(max));
|
||||
const bits = intBitMapMask.get(mask) as number;
|
||||
|
||||
let n = Number(this._nextInt(bits));
|
||||
while (n > max){
|
||||
n = Number(this._nextInt(bits));
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
public nextFloat1(): number {
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while(true){
|
||||
const nInt = this._nextInt(maxRngSupportBit + 1);
|
||||
if(nInt < maxIntMore1){
|
||||
return Number(nInt) / maxIntMore1f;
|
||||
}
|
||||
if(nInt === maxIntMore1){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static build(seed: BytesLike, stateIdx = 0): LiteHashDRBG{
|
||||
return new LiteHashDRBG(seed, stateIdx);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
export class NotNullExpected extends TypeError {
|
||||
public name = 'NotNullExpected';
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export type Nullable<T> = T | null | undefined;
|
||||
@@ -0,0 +1,173 @@
|
||||
import type { TurnObj } from "@/defs";
|
||||
import { clone, isString, range } from "lodash-es";
|
||||
import { ref, type Ref } from "vue";
|
||||
import { unwrap } from "./unwrap";
|
||||
|
||||
export type TurnObjWithTime = TurnObj & {
|
||||
time: string;
|
||||
year?: number;
|
||||
month?: number;
|
||||
tooltip?: string;
|
||||
style?: Record<string, string>;
|
||||
};
|
||||
|
||||
export const getEmptyTurn = (maxTurn: number): TurnObjWithTime[] => Array.from<TurnObjWithTime>({
|
||||
length: maxTurn,
|
||||
}).fill({
|
||||
arg: {},
|
||||
brief: "",
|
||||
action: "",
|
||||
year: undefined,
|
||||
month: undefined,
|
||||
time: "",
|
||||
});
|
||||
|
||||
export class QueryActionHelper {
|
||||
public readonly reservedCommandList: Ref<TurnObjWithTime[]>;
|
||||
public readonly selectedTurnList: Ref<Set<number>>;
|
||||
public readonly prevSelectedTurnList: Ref<Set<number>>;
|
||||
|
||||
constructor(
|
||||
protected maxTurn: number,
|
||||
) {
|
||||
this.reservedCommandList = ref(getEmptyTurn(maxTurn));
|
||||
this.selectedTurnList = ref(new Set());
|
||||
this.prevSelectedTurnList = ref(new Set([0]));
|
||||
}
|
||||
|
||||
toggleTurn(...reqTurnList: number[] | string[]) {
|
||||
for (let turnIdx of reqTurnList) {
|
||||
if (isString(turnIdx)) {
|
||||
turnIdx = parseInt(turnIdx);
|
||||
}
|
||||
if (this.selectedTurnList.value.has(turnIdx)) {
|
||||
this.selectedTurnList.value.delete(turnIdx);
|
||||
} else {
|
||||
this.selectedTurnList.value.add(turnIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
selectTurn(...reqTurnList: number[] | string[]) {
|
||||
this.selectedTurnList.value.clear();
|
||||
for (const turnIdx of reqTurnList) {
|
||||
if (isString(turnIdx)) {
|
||||
this.selectedTurnList.value.add(parseInt(turnIdx));
|
||||
} else {
|
||||
this.selectedTurnList.value.add(turnIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
selectStep(begin: number, step: number) {
|
||||
this.selectedTurnList.value.clear();
|
||||
for (const idx of range(0, this.maxTurn)) {
|
||||
if ((idx - begin) % step == 0) {
|
||||
this.selectedTurnList.value.add(idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
selectAll() {
|
||||
for (let i = 0; i < this.maxTurn; i++) {
|
||||
this.selectedTurnList.value.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
getSelectedTurnList(useSort = true): number[] {
|
||||
let result: number[];
|
||||
if (this.selectedTurnList.value.size) {
|
||||
result = Array.from(this.selectedTurnList.value);
|
||||
}
|
||||
else if (this.prevSelectedTurnList.value.size) {
|
||||
result = Array.from(this.prevSelectedTurnList.value);
|
||||
}
|
||||
else {
|
||||
return [0];
|
||||
}
|
||||
|
||||
if (useSort) {
|
||||
return result.sort((a, b) => a - b);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
releaseSelectedTurnList() {
|
||||
if (this.selectedTurnList.value.size > 0) {
|
||||
this.prevSelectedTurnList.value.clear();
|
||||
for (const v of this.selectedTurnList.value) {
|
||||
this.prevSelectedTurnList.value.add(v);
|
||||
}
|
||||
this.selectedTurnList.value.clear();
|
||||
}
|
||||
}
|
||||
|
||||
extractQueryActions(): [number[], TurnObj][] {
|
||||
const reqTurnList = this.getSelectedTurnList();
|
||||
const selectedMinTurnIdx = unwrap(Math.min(...reqTurnList));
|
||||
|
||||
const buffer = new Map<string, [number[], TurnObj]>();
|
||||
for (const rawTurnIdx of reqTurnList) {
|
||||
const turnIdx = rawTurnIdx - selectedMinTurnIdx;
|
||||
const rawAction = this.reservedCommandList.value[rawTurnIdx]
|
||||
const actionStr = JSON.stringify([rawAction.action, rawAction.arg]);
|
||||
if (buffer.has(actionStr)) {
|
||||
const items = unwrap(buffer.get(actionStr));
|
||||
items[0].push(turnIdx);
|
||||
}
|
||||
else {
|
||||
buffer.set(actionStr, [[turnIdx], {
|
||||
action: rawAction.action,
|
||||
arg: clone(rawAction.arg),
|
||||
brief: rawAction.brief
|
||||
}])
|
||||
}
|
||||
}
|
||||
return Array.from(buffer.values());
|
||||
}
|
||||
|
||||
amplifyQueryActions(rawActions: [number[], TurnObj][], reqTurnList: number[]): [number[], TurnObj][] {
|
||||
if (reqTurnList.length < 1) {
|
||||
return [];
|
||||
}
|
||||
|
||||
let minQueryIdx = this.maxTurn;
|
||||
let maxQueryIdx = 0;
|
||||
for (const [turnList] of rawActions) {
|
||||
for (const turnIdx of turnList) {
|
||||
minQueryIdx = Math.min(minQueryIdx, turnIdx);
|
||||
maxQueryIdx = Math.max(maxQueryIdx, turnIdx);
|
||||
}
|
||||
}
|
||||
const queryLength = maxQueryIdx - minQueryIdx + 1;
|
||||
|
||||
const queryTurnList: number[] = [reqTurnList[0]];
|
||||
for (const reqTurnIdx of reqTurnList) {
|
||||
const last = queryTurnList[queryTurnList.length - 1];
|
||||
if (reqTurnIdx < last + queryLength) {
|
||||
continue;
|
||||
}
|
||||
queryTurnList.push(reqTurnIdx);
|
||||
}
|
||||
|
||||
const actions: [number[], TurnObj][] = [];
|
||||
for (const [baseTurnList, action] of rawActions) {
|
||||
const subTurnList: number[] = [];
|
||||
for (const baseTurnIdx of baseTurnList) {
|
||||
for (const queryTurnIdx of queryTurnList) {
|
||||
const targetTurn = baseTurnIdx + queryTurnIdx;
|
||||
if (targetTurn >= this.maxTurn) {
|
||||
continue;
|
||||
}
|
||||
subTurnList.push(baseTurnIdx + queryTurnIdx);
|
||||
}
|
||||
}
|
||||
if (subTurnList.length == 0) {
|
||||
continue;
|
||||
}
|
||||
actions.push([subTurnList, action]);
|
||||
}
|
||||
|
||||
return actions;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
export interface RNG {
|
||||
|
||||
/**
|
||||
* nextInt()가 반환 가능한 최댓값
|
||||
*/
|
||||
getMaxInt(): number;
|
||||
|
||||
nextBytes(bytes: number): Uint8Array;
|
||||
nextBits(bits: number): Uint8Array;
|
||||
|
||||
nextInt(max?: number): number;
|
||||
nextFloat1(): number;
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
import type { RNG } from './RNG';
|
||||
|
||||
export class RandUtil {
|
||||
constructor(protected rng: RNG) {
|
||||
|
||||
}
|
||||
|
||||
public nextFloat1(): number {
|
||||
return this.rng.nextFloat1();
|
||||
}
|
||||
|
||||
public nextRange(min: number, max: number): number {
|
||||
const range = max - min;
|
||||
return this.nextFloat1() * (range) + min;
|
||||
}
|
||||
|
||||
public nextRangeInt(min: number, max: number): number {
|
||||
const range = max - min;
|
||||
return this.rng.nextInt(range) + min;
|
||||
}
|
||||
|
||||
public nextInt(max?: number): number {
|
||||
return this.rng.nextInt(max);
|
||||
}
|
||||
|
||||
public nextBit(): boolean {
|
||||
const view = new DataView(this.rng.nextBits(1) as ArrayBufferLike);
|
||||
return view.getUint8(0) != 0;
|
||||
}
|
||||
|
||||
public nextBool(prob = 0.5): boolean {
|
||||
if (prob >= 1) {
|
||||
return true;
|
||||
}
|
||||
if (prob === 0.5){
|
||||
return this.nextBit();
|
||||
}
|
||||
if (prob <= 0){
|
||||
return false;
|
||||
}
|
||||
return this.nextFloat1() < prob;
|
||||
}
|
||||
|
||||
public shuffle<T>(srcArray: T[]): T[] {
|
||||
const cnt = srcArray.length;
|
||||
if(cnt === 0){
|
||||
return [];
|
||||
}
|
||||
if (cnt > this.rng.getMaxInt()) {
|
||||
throw 'Invalid random int range';
|
||||
}
|
||||
|
||||
const result: T[] = Array.from(srcArray);
|
||||
for (let srcIdx = 0; srcIdx < cnt; srcIdx += 1) {
|
||||
const destIdx = this.rng.nextInt(cnt - srcIdx - 1) + srcIdx;
|
||||
if(srcIdx === destIdx){
|
||||
continue;
|
||||
}
|
||||
[result[srcIdx], result[destIdx]] = [result[destIdx], result[srcIdx]];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//Object는 integer key에 예외가 있어 shuffleAssoc은 없음
|
||||
|
||||
public choice<T>(items: T[] | Record<string | number, T> | Set<T>): T {
|
||||
if (items instanceof Array) {
|
||||
if(items.length === 0){
|
||||
throw new Error('Empty items');
|
||||
}
|
||||
const idx = this.rng.nextInt(items.length - 1);
|
||||
return items[idx];
|
||||
}
|
||||
|
||||
if (items instanceof Set) {
|
||||
return this.choice(Array.from(items.values()));
|
||||
}
|
||||
|
||||
return items[this.choice(Array.from(Object.keys(items)))];
|
||||
}
|
||||
|
||||
public choiceUsingWeight(items: Record<string | number, number>): string | number {
|
||||
if(Object.keys(items).length === 0){
|
||||
throw new Error('Empty items');
|
||||
}
|
||||
let sum = 0;
|
||||
for (const value of Object.values(items)) {
|
||||
if (value <= 0) {
|
||||
continue;
|
||||
}
|
||||
sum += value;
|
||||
}
|
||||
|
||||
let rd = this.nextFloat1() * sum;
|
||||
|
||||
for (const [item, value] of Object.entries(items)) {
|
||||
if (value <= 0) {
|
||||
if (rd <= 0) {
|
||||
return item;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rd <= value) {
|
||||
return item;
|
||||
}
|
||||
rd -= value;
|
||||
}
|
||||
|
||||
throw new Error('Unreacheable');
|
||||
}
|
||||
|
||||
public choiceUsingWeightPair<T>(items: [T, number][]): T {
|
||||
if(items.length === 0){
|
||||
throw new Error('Empty items');
|
||||
}
|
||||
let sum = 0;
|
||||
for (const [, value] of items) {
|
||||
if (value <= 0) {
|
||||
continue;
|
||||
}
|
||||
sum += value;
|
||||
}
|
||||
|
||||
let rd = this.nextFloat1() * sum;
|
||||
|
||||
for (const [item, value] of items) {
|
||||
if (value <= 0) {
|
||||
if (rd <= 0) {
|
||||
return item;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rd <= value) {
|
||||
return item;
|
||||
}
|
||||
rd -= value;
|
||||
}
|
||||
|
||||
throw new Error('Unreacheable');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
export class RuntimeError extends Error {
|
||||
public name = 'RuntimeError';
|
||||
constructor(public message: string = '') {
|
||||
super(message);
|
||||
}
|
||||
toString(): string {
|
||||
if (this.message) {
|
||||
return this.name + ': ' + this.message;
|
||||
}
|
||||
else {
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
import type { TurnObj } from '@/defs';
|
||||
import { ref, watch, type Ref } from 'vue';
|
||||
|
||||
|
||||
export class StoredActionsHelper {
|
||||
public readonly recentActions: Ref<Map<string, TurnObj>>;
|
||||
public readonly storedActions = ref(new Map<string, [number[], TurnObj][]>());
|
||||
public readonly clipboard = ref<[number[], TurnObj][] | undefined>(undefined);
|
||||
public readonly activatedCategory = ref<string>("");
|
||||
public readonly isEditMode = ref(false);
|
||||
|
||||
public readonly recentActionsKey: string;
|
||||
public readonly storedActionsKey: string;
|
||||
public readonly clipboardKey: string;
|
||||
public readonly activatedCategoryKey: string;
|
||||
public readonly editModeKey: string;
|
||||
|
||||
constructor(protected serverNick: string, protected type: 'general' | 'nation', protected mapName: string, protected unitSet: string, protected maxRecent = 10) {
|
||||
this.recentActions = ref(new Map());
|
||||
const typeKey = `${serverNick}_${mapName}_${unitSet}_${type}`;
|
||||
this.recentActionsKey = `${typeKey}RecentActions`;
|
||||
this.storedActionsKey = `${typeKey}StoredActions`;
|
||||
this.clipboardKey = `${typeKey}Clipboard`;
|
||||
this.activatedCategoryKey = `${typeKey}ActivatedCategory`;
|
||||
this.editModeKey = `${serverNick}_${type}_isEditMode`;
|
||||
|
||||
this.loadRecentActions();
|
||||
this.loadStoredActions();
|
||||
|
||||
const rawClipboard = localStorage.getItem(this.clipboardKey);
|
||||
if (rawClipboard !== null) {
|
||||
this.clipboard.value = JSON.parse(rawClipboard);
|
||||
}
|
||||
watch(this.clipboard, (newValue) => {
|
||||
localStorage.setItem(this.clipboardKey, JSON.stringify(newValue));
|
||||
});
|
||||
|
||||
const rawActivatedCategory = localStorage.getItem(this.activatedCategoryKey);
|
||||
if (rawActivatedCategory !== null) {
|
||||
this.activatedCategory.value = JSON.parse(rawActivatedCategory);
|
||||
}
|
||||
watch(this.activatedCategory, (newValue) => {
|
||||
localStorage.setItem(this.activatedCategoryKey, JSON.stringify(newValue));
|
||||
});
|
||||
|
||||
this.isEditMode.value = localStorage.getItem(this.editModeKey) === '1';
|
||||
watch(this.isEditMode, (newValue) => {
|
||||
localStorage.setItem(this.editModeKey, newValue ? '1' : '0')
|
||||
})
|
||||
}
|
||||
|
||||
loadRecentActions() {
|
||||
try {
|
||||
const rawRecentActions = JSON.parse(localStorage.getItem(this.recentActionsKey) ?? '[]') as TurnObj[];
|
||||
const recentActions = new Map<string, TurnObj>();
|
||||
for (const action of rawRecentActions) {
|
||||
const actionKey = JSON.stringify([action.action, action.arg]);
|
||||
recentActions.set(actionKey, action);
|
||||
}
|
||||
this.recentActions.value = recentActions;
|
||||
}
|
||||
catch(e){
|
||||
console.log(`loadRecentActions error ${e}`);
|
||||
}
|
||||
}
|
||||
|
||||
pushRecentActions(action: TurnObj) {
|
||||
const actionKey = JSON.stringify([action.action, action.arg]);
|
||||
if (this.recentActions.value.has(actionKey)) {
|
||||
this.recentActions.value.delete(actionKey);
|
||||
}
|
||||
else if (this.recentActions.value.size > this.maxRecent) {
|
||||
const firstKey = this.recentActions.value.keys().next().value;
|
||||
this.recentActions.value.delete(firstKey);
|
||||
}
|
||||
this.recentActions.value.set(actionKey, action);
|
||||
this.saveRecentActions();
|
||||
}
|
||||
|
||||
saveRecentActions() {
|
||||
localStorage.setItem(this.recentActionsKey, JSON.stringify(Array.from(this.recentActions.value.values())));
|
||||
}
|
||||
|
||||
loadStoredActions() {
|
||||
try {
|
||||
const rawValue: [string, [number[], TurnObj][]][] = JSON.parse(
|
||||
localStorage.getItem(this.storedActionsKey) ?? '[]'
|
||||
);
|
||||
this.storedActions.value = new Map(rawValue);
|
||||
}
|
||||
catch(e){
|
||||
console.log(`loadStoredActions error ${e}`);
|
||||
}
|
||||
}
|
||||
|
||||
setStoredActions(actionKey: string, actions: [number[], TurnObj][]) {
|
||||
this.storedActions.value.set(actionKey, actions);
|
||||
console.log(this.storedActions.value);
|
||||
this.saveStoredActions();
|
||||
}
|
||||
|
||||
deleteStoredActions(actionKey: string) {
|
||||
if (this.storedActions.value.delete(actionKey)) {
|
||||
this.saveStoredActions();
|
||||
}
|
||||
}
|
||||
|
||||
saveStoredActions() {
|
||||
localStorage.setItem(
|
||||
this.storedActionsKey,
|
||||
JSON.stringify(Array.from(this.storedActions.value.entries()))
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import { escapeHtml } from '@/legacy/escapeHtml';
|
||||
import linkifyStr from 'linkify-string';
|
||||
/**
|
||||
* 단순한 Template 함수. <%변수명%>으로 template 가능
|
||||
* @see https://github.com/krasimir/absurd/blob/master/lib/processors/html/helpers/TemplateEngine.js
|
||||
* @param {string} html
|
||||
* @param {object} options
|
||||
* @returns {string}
|
||||
*/
|
||||
|
||||
export function TemplateEngine(html: string, options: Record<string | number, unknown> = {}): string {
|
||||
const re = /<%(.+?)%>/g;
|
||||
const reExp = /(^( )?(var|if|for|else|switch|case|break|{|}|;))(.*)?/g;
|
||||
const code = ['with(obj) { var r=[];\n'];
|
||||
let cursor = 0;
|
||||
const add = function (line: string, js?: boolean) {
|
||||
js ? code.push(line.match(reExp) ? line + '\n' : 'r.push(' + line + ');\n') :
|
||||
code.push(line != '' ? 'r.push("' + line.replace(/"/g, '\\"') + '");\n' : '');
|
||||
return add;
|
||||
};
|
||||
options.e = escapeHtml;
|
||||
options.linkifyStr = linkifyStr;
|
||||
for (; ;) {
|
||||
const match = re.exec(html);
|
||||
if (!match) {
|
||||
break;
|
||||
}
|
||||
add(html.slice(cursor, match.index))(match[1], true);
|
||||
cursor = match.index + match[0].length;
|
||||
}
|
||||
add(html.substr(cursor, html.length - cursor));
|
||||
|
||||
code.push('return r.join(""); }');
|
||||
const compiledCode = code.join('').replace(/[\r\t\n]/g, ' ');
|
||||
try {
|
||||
return new Function('obj', compiledCode).apply(options, [options]);
|
||||
} catch (err: unknown) {
|
||||
console.error(err, " in \n\nCode:\n", code, "\n");
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
import { htmlReady } from "@util/htmlReady";
|
||||
import { unwrap } from "@util/unwrap";
|
||||
import { keyScreenMode, type ScreenModeType } from "@/defs";
|
||||
|
||||
export function auto500px(targetHeight = 700): void {
|
||||
let deviceWidth = -1;
|
||||
let viewportMeta!: HTMLMetaElement;
|
||||
let oldMode: ScreenModeType = 'auto';
|
||||
|
||||
|
||||
function init() {
|
||||
let _viewPortMeta = document.querySelector<HTMLMetaElement>("meta[name=viewport]");
|
||||
if (_viewPortMeta) {
|
||||
viewportMeta = _viewPortMeta;
|
||||
return;
|
||||
}
|
||||
|
||||
const htmlTag = unwrap(document.querySelector("head"));
|
||||
_viewPortMeta = document.createElement("meta");
|
||||
_viewPortMeta.name = 'viewport';
|
||||
_viewPortMeta.content = 'width=500';
|
||||
htmlTag.appendChild(_viewPortMeta);
|
||||
viewportMeta = _viewPortMeta;
|
||||
}
|
||||
|
||||
function adjustViewportWidth() {
|
||||
const screenMode = (localStorage.getItem(keyScreenMode) as ScreenModeType)??'auto';
|
||||
if(screenMode != oldMode){
|
||||
oldMode = screenMode;
|
||||
deviceWidth = window.screen.availWidth;
|
||||
|
||||
if(screenMode == '500px'){
|
||||
viewportMeta.content = 'width=500';
|
||||
return;
|
||||
}
|
||||
|
||||
if(screenMode == '1000px'){
|
||||
viewportMeta.content = 'width=1000';
|
||||
return;
|
||||
}
|
||||
|
||||
if(screenMode == 'auto'){
|
||||
deviceWidth = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (deviceWidth == window.screen.availWidth) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(oldMode != 'auto'){
|
||||
oldMode = 'auto';
|
||||
adjustViewportWidth();
|
||||
return;
|
||||
}
|
||||
deviceWidth = window.screen.availWidth;
|
||||
const innerHeight = window.innerHeight;
|
||||
const selectorHeight = targetHeight;
|
||||
|
||||
if (deviceWidth < 500) {
|
||||
viewportMeta.content = 'width=500';
|
||||
return;
|
||||
}
|
||||
|
||||
if (innerHeight < selectorHeight) {
|
||||
const maybeNextWidth = deviceWidth / innerHeight * selectorHeight;
|
||||
if (maybeNextWidth >= 700) {
|
||||
viewportMeta.content = 'width=1000';
|
||||
}
|
||||
else {
|
||||
viewportMeta.content = `height=${Math.ceil(selectorHeight)}`;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if(deviceWidth >= 700){
|
||||
viewportMeta.content = 'width=1000';
|
||||
}
|
||||
else{
|
||||
viewportMeta.content = 'width=device-width, initial-scale=1';
|
||||
}
|
||||
}
|
||||
|
||||
htmlReady(() => {
|
||||
init();
|
||||
adjustViewportWidth();
|
||||
window.addEventListener('scroll', adjustViewportWidth, true);
|
||||
window.addEventListener('orientationchange', adjustViewportWidth, true);
|
||||
document.addEventListener('tryChangeScreenMode', adjustViewportWidth, false);
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import { unwrap } from "@util/unwrap";
|
||||
|
||||
export function autoResizeTextarea(e: Event): void {
|
||||
const el = unwrap(e.target) as HTMLInputElement;
|
||||
el.style.height = 'auto';
|
||||
el.style.height = `${el.scrollHeight + 1}px`;
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
const convListLevel1: Record<string, Record<string, string>> = {
|
||||
'ㄱ': {
|
||||
'ㅅ': 'ㄳ',
|
||||
},
|
||||
'ㄴ': {
|
||||
'ㅈ': 'ㄵ',
|
||||
'ㅎ': 'ㄶ',
|
||||
},
|
||||
'ㄹ': {
|
||||
'ㅂ': 'ㄼ',
|
||||
'ㄱ': 'ㄺ',
|
||||
'ㅅ': 'ㄽ',
|
||||
'ㅁ': 'ㄻ',
|
||||
'ㅎ': 'ㅀ',
|
||||
'ㅌ': 'ㄾ',
|
||||
'ㅍ': 'ㄿ',
|
||||
},
|
||||
'ㅂ': {
|
||||
'ㅅ': 'ㅄ',
|
||||
},
|
||||
}
|
||||
|
||||
const convListLevel2: Record<string, Record<string, string>> = {
|
||||
'ㄱ': {
|
||||
'ㄱ': 'ㄲ',
|
||||
'ㅅ': 'ㄳ',
|
||||
},
|
||||
'ㄴ': {
|
||||
'ㅈ': 'ㄵ',
|
||||
'ㅎ': 'ㄶ',
|
||||
},
|
||||
'ㄷ': {
|
||||
'ㄷ': 'ㄸ',
|
||||
},
|
||||
'ㄹ': {
|
||||
'ㅂ': 'ㄼ',
|
||||
'ㄱ': 'ㄺ',
|
||||
'ㅅ': 'ㄽ',
|
||||
'ㅁ': 'ㄻ',
|
||||
'ㅎ': 'ㅀ',
|
||||
'ㅌ': 'ㄾ',
|
||||
'ㅍ': 'ㄿ',
|
||||
},
|
||||
'ㅂ': {
|
||||
'ㅂ': 'ㅃ',
|
||||
'ㅅ': 'ㅄ',
|
||||
},
|
||||
'ㅅ': {
|
||||
'ㅅ': 'ㅆ',
|
||||
},
|
||||
'ㅈ': {
|
||||
'ㅈ': 'ㅉ',
|
||||
}
|
||||
}
|
||||
|
||||
function automata초성(text: string, convList: Record<string, Record<string, string>>): string{
|
||||
const result: string[] = [];
|
||||
let head: undefined | string = undefined;
|
||||
for (const ch of text) {
|
||||
if (head === undefined) {
|
||||
if(!(ch in convList)){
|
||||
result.push(ch);
|
||||
continue;
|
||||
}
|
||||
head = ch;
|
||||
continue;
|
||||
}
|
||||
|
||||
const nextConv = convList[head];
|
||||
if(ch in nextConv){
|
||||
result.push(nextConv[ch]);
|
||||
head = undefined;
|
||||
continue;
|
||||
}
|
||||
|
||||
result.push(head);
|
||||
if(!(ch in convList)){
|
||||
result.push(ch);
|
||||
head = undefined;
|
||||
continue;
|
||||
}
|
||||
head = ch;
|
||||
}
|
||||
if(head !== undefined){
|
||||
result.push(head);
|
||||
head = undefined;
|
||||
}
|
||||
return result.join('');
|
||||
}
|
||||
|
||||
export function automata초성All(text: string): [string, string]{
|
||||
return [automata초성(text, convListLevel1), automata초성(text, convListLevel2)];
|
||||
}
|
||||
|
||||
export function automata초성Level1(text: string): string{
|
||||
return automata초성(text, convListLevel1);
|
||||
}
|
||||
|
||||
export function automata초성Level2(text: string): string {
|
||||
return automata초성(text, convListLevel2);
|
||||
}
|
||||
@@ -0,0 +1,274 @@
|
||||
import ky from "ky";
|
||||
import { isArray, isEmpty } from "lodash-es";
|
||||
|
||||
export type ValidResponse = {
|
||||
result: true;
|
||||
};
|
||||
|
||||
export type APIRecoveryType = "login" | "2fa" | "gateway" | "game_login" | "game_quota";
|
||||
export const APIRecoveryConst = {
|
||||
Login: 'login',
|
||||
TwoFactorAuth: '2fa',
|
||||
Gateway: 'gateway',
|
||||
GameLogin: 'game_login',
|
||||
GameQuota: 'game_quota',
|
||||
} as const;
|
||||
|
||||
export type InvalidResponse = {
|
||||
result: false;
|
||||
reason: string;
|
||||
recovery?: APIRecoveryType;
|
||||
recovery_arg?: string | number;
|
||||
};
|
||||
|
||||
export type RawArgType = Record<string, unknown> | Record<string, unknown>[] | undefined;
|
||||
|
||||
interface BasicAPICallT<
|
||||
ArgType extends RawArgType,
|
||||
ResultType extends ValidResponse,
|
||||
ErrorType extends InvalidResponse
|
||||
> {
|
||||
(args: ArgType): Promise<ResultType>;
|
||||
(args: ArgType, returnError: false): Promise<ResultType>;
|
||||
(args: ArgType, returnError: true): Promise<ResultType | ErrorType>;
|
||||
}
|
||||
|
||||
interface EmptyAPICallT<ResultType extends ValidResponse, ErrorType extends InvalidResponse> {
|
||||
(): Promise<ResultType>;
|
||||
(args: undefined): Promise<ResultType>;
|
||||
(args: undefined, returnError: false): Promise<ResultType>;
|
||||
(args: undefined, returnError: true): Promise<ResultType | ErrorType>;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export type ArgTypeOf<T> = T extends APICallT<infer A, any, any> ? A : never;
|
||||
|
||||
export type APICallT<
|
||||
ArgType extends RawArgType,
|
||||
ResultType extends ValidResponse = ValidResponse,
|
||||
ErrorType extends InvalidResponse = InvalidResponse
|
||||
> = ArgType extends undefined ? EmptyAPICallT<ResultType, ErrorType> : BasicAPICallT<ArgType, ResultType, ErrorType>;
|
||||
|
||||
type HttpMethod = "get" | "post" | "put" | "patch" | "head" | "delete";
|
||||
export type APITail = typeof GET | typeof POST | typeof PUT | typeof PATCH | typeof HEAD | typeof DELETE;
|
||||
|
||||
const httpMethodMap = new Map<APITail, HttpMethod>([
|
||||
[GET, "get"],
|
||||
[POST, "post"],
|
||||
[PUT, "put"],
|
||||
[PATCH, "patch"],
|
||||
[HEAD, "head"],
|
||||
[DELETE, "delete"],
|
||||
]);
|
||||
|
||||
export function extractHttpMethod(tail: APITail): HttpMethod {
|
||||
return httpMethodMap.get(tail) ?? "post";
|
||||
}
|
||||
|
||||
const apiTarget = "api.php";
|
||||
let apiPath = apiTarget;
|
||||
|
||||
export function setSammoAPIPrefix(prefix: string) {
|
||||
apiPath = `${prefix}/${apiTarget}`;
|
||||
}
|
||||
|
||||
export async function callSammoAPI<ResultType extends ValidResponse>(
|
||||
method: HttpMethod,
|
||||
path: string | string[],
|
||||
args: RawArgType,
|
||||
paramArgs: Record<string, string | number> | undefined
|
||||
): Promise<ResultType>;
|
||||
export async function callSammoAPI<ResultType extends ValidResponse>(
|
||||
method: HttpMethod,
|
||||
path: string | string[],
|
||||
args: RawArgType,
|
||||
paramArgs: Record<string, string | number> | undefined,
|
||||
returnError: false
|
||||
): Promise<ResultType>;
|
||||
export async function callSammoAPI<ResultType extends ValidResponse, ErrorType extends InvalidResponse>(
|
||||
method: HttpMethod,
|
||||
path: string | string[],
|
||||
args: RawArgType,
|
||||
paramArgs: Record<string, string | number> | undefined,
|
||||
returnError: true
|
||||
): Promise<ResultType | ErrorType>;
|
||||
export async function callSammoAPI<ResultType extends ValidResponse, ErrorType extends InvalidResponse>(
|
||||
method: HttpMethod,
|
||||
path: string | string[],
|
||||
args: RawArgType,
|
||||
paramArgs: Record<string, string | number> | undefined,
|
||||
returnError = false
|
||||
): Promise<ResultType | ErrorType> {
|
||||
if (isArray(path)) {
|
||||
path = path.join("/");
|
||||
}
|
||||
|
||||
if (args && isEmpty(args)) {
|
||||
args = undefined;
|
||||
}
|
||||
|
||||
const result = (await (() => {
|
||||
if (method == "get") {
|
||||
return ky(apiPath, {
|
||||
searchParams: {
|
||||
...paramArgs,
|
||||
...(args as typeof paramArgs),
|
||||
path,
|
||||
},
|
||||
method,
|
||||
headers: {
|
||||
"content-type": "application/json",
|
||||
},
|
||||
timeout: 30000,
|
||||
retry: 0,
|
||||
});
|
||||
}
|
||||
return ky("api.php", {
|
||||
searchParams: {
|
||||
...paramArgs,
|
||||
path,
|
||||
},
|
||||
method,
|
||||
json: args,
|
||||
headers: {
|
||||
"content-type": "application/json",
|
||||
},
|
||||
timeout: 30000,
|
||||
retry: 0,
|
||||
});
|
||||
})().json()) as ErrorType | ResultType;
|
||||
|
||||
if (!result.result) {
|
||||
if (returnError) {
|
||||
return result;
|
||||
}
|
||||
throw result.reason;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function GET<ResultType extends ValidResponse, ArgType extends undefined = undefined>(
|
||||
args?: ArgType
|
||||
): Promise<ResultType>;
|
||||
export async function GET<ResultType extends ValidResponse, ArgType extends undefined = undefined>(
|
||||
args: ArgType | undefined,
|
||||
returnError: false
|
||||
): Promise<ResultType>;
|
||||
export async function GET<
|
||||
ResultType extends ValidResponse,
|
||||
ErrorType extends InvalidResponse,
|
||||
ArgType extends undefined = undefined
|
||||
>(args: ArgType | undefined, returnError: true): Promise<ResultType | ErrorType>;
|
||||
export async function GET<
|
||||
ResultType extends ValidResponse,
|
||||
ErrorType extends InvalidResponse,
|
||||
ArgType extends undefined = undefined
|
||||
>(args?: ArgType, returnError = false): Promise<ResultType | ErrorType> {
|
||||
console.error(`Can't directly call GET. ${args}, ${returnError}. Use auto-generated path API.`);
|
||||
return callSammoAPI<ResultType, ErrorType>("get", [], args, undefined, true);
|
||||
}
|
||||
|
||||
export async function POST<ResultType extends ValidResponse, ArgType extends RawArgType = RawArgType>(
|
||||
args?: ArgType
|
||||
): Promise<ResultType>;
|
||||
export async function POST<ResultType extends ValidResponse, ArgType extends RawArgType = RawArgType>(
|
||||
args: ArgType | undefined,
|
||||
returnError: false
|
||||
): Promise<ResultType>;
|
||||
export async function POST<
|
||||
ResultType extends ValidResponse,
|
||||
ErrorType extends InvalidResponse,
|
||||
ArgType extends RawArgType = RawArgType
|
||||
>(args: ArgType | undefined, returnError: true): Promise<ResultType | ErrorType>;
|
||||
export async function POST<
|
||||
ResultType extends ValidResponse,
|
||||
ErrorType extends InvalidResponse,
|
||||
ArgType extends RawArgType = RawArgType
|
||||
>(args?: ArgType, returnError = false): Promise<ResultType | ErrorType> {
|
||||
console.error(`Can't directly call POST. ${args}, ${returnError}. Use auto-generated path API.`);
|
||||
return callSammoAPI<ResultType, ErrorType>("post", [], args, undefined, true);
|
||||
}
|
||||
|
||||
export async function PUT<ResultType extends ValidResponse, ArgType extends RawArgType = RawArgType>(
|
||||
args?: ArgType
|
||||
): Promise<ResultType>;
|
||||
export async function PUT<ResultType extends ValidResponse, ArgType extends RawArgType = RawArgType>(
|
||||
args: ArgType | undefined,
|
||||
returnError: false
|
||||
): Promise<ResultType>;
|
||||
export async function PUT<
|
||||
ResultType extends ValidResponse,
|
||||
ErrorType extends InvalidResponse,
|
||||
ArgType extends RawArgType = RawArgType
|
||||
>(args: ArgType | undefined, returnError: true): Promise<ResultType | ErrorType>;
|
||||
export async function PUT<
|
||||
ResultType extends ValidResponse,
|
||||
ErrorType extends InvalidResponse,
|
||||
ArgType extends RawArgType = RawArgType
|
||||
>(args?: ArgType, returnError = false): Promise<ResultType | ErrorType> {
|
||||
console.error(`Can't directly call PUT. ${args}, ${returnError}. Use auto-generated path API.`);
|
||||
return callSammoAPI<ResultType, ErrorType>("put", [], args, undefined, true);
|
||||
}
|
||||
|
||||
export async function PATCH<ResultType extends ValidResponse, ArgType extends RawArgType = RawArgType>(
|
||||
args?: ArgType
|
||||
): Promise<ResultType>;
|
||||
export async function PATCH<ResultType extends ValidResponse, ArgType extends RawArgType = RawArgType>(
|
||||
args: ArgType | undefined,
|
||||
returnError: false
|
||||
): Promise<ResultType>;
|
||||
export async function PATCH<
|
||||
ResultType extends ValidResponse,
|
||||
ErrorType extends InvalidResponse,
|
||||
ArgType extends RawArgType = RawArgType
|
||||
>(args: ArgType | undefined, returnError: true): Promise<ResultType | ErrorType>;
|
||||
export async function PATCH<
|
||||
ResultType extends ValidResponse,
|
||||
ErrorType extends InvalidResponse,
|
||||
ArgType extends RawArgType = RawArgType
|
||||
>(args?: ArgType, returnError = false): Promise<ResultType | ErrorType> {
|
||||
console.error(`Can't directly call PATCH. ${args}, ${returnError}. Use auto-generated path API.`);
|
||||
return callSammoAPI<ResultType, ErrorType>("patch", [], args, undefined, true);
|
||||
}
|
||||
|
||||
export async function HEAD<ResultType extends ValidResponse, ArgType extends undefined = undefined>(
|
||||
args?: ArgType
|
||||
): Promise<ResultType>;
|
||||
export async function HEAD<ResultType extends ValidResponse, ArgType extends undefined = undefined>(
|
||||
args: ArgType | undefined,
|
||||
returnError: false
|
||||
): Promise<ResultType>;
|
||||
export async function HEAD<
|
||||
ResultType extends ValidResponse,
|
||||
ErrorType extends InvalidResponse,
|
||||
ArgType extends undefined = undefined
|
||||
>(args: ArgType | undefined, returnError: true): Promise<ResultType | ErrorType>;
|
||||
export async function HEAD<
|
||||
ResultType extends ValidResponse,
|
||||
ErrorType extends InvalidResponse,
|
||||
ArgType extends undefined = undefined
|
||||
>(args?: ArgType, returnError = false): Promise<ResultType | ErrorType> {
|
||||
console.error(`Can't directly call HEAD. ${args}, ${returnError}. Use auto-generated path API.`);
|
||||
return callSammoAPI<ResultType, ErrorType>("head", [], args, undefined, true);
|
||||
}
|
||||
|
||||
export async function DELETE<ResultType extends ValidResponse, ArgType extends RawArgType = RawArgType>(
|
||||
args?: ArgType
|
||||
): Promise<ResultType>;
|
||||
export async function DELETE<ResultType extends ValidResponse, ArgType extends RawArgType = RawArgType>(
|
||||
args: ArgType | undefined,
|
||||
returnError: false
|
||||
): Promise<ResultType>;
|
||||
export async function DELETE<
|
||||
ResultType extends ValidResponse,
|
||||
ErrorType extends InvalidResponse,
|
||||
ArgType extends RawArgType = RawArgType
|
||||
>(args: ArgType | undefined, returnError: true): Promise<ResultType | ErrorType>;
|
||||
export async function DELETE<
|
||||
ResultType extends ValidResponse,
|
||||
ErrorType extends InvalidResponse,
|
||||
ArgType extends RawArgType = RawArgType
|
||||
>(args?: ArgType, returnError = false): Promise<ResultType | ErrorType> {
|
||||
console.error(`Can't directly call DELETE. ${args}, ${returnError}. Use auto-generated path API.`);
|
||||
return callSammoAPI<ResultType, ErrorType>("patch", [], args, undefined, true);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { combineObject } from "../common_legacy";
|
||||
|
||||
|
||||
export function combineArray<K extends string, V>(array: V[][], columnList: K[]): Record<K, V>[] {
|
||||
const result: Record<K, V>[] = [];
|
||||
for (const key of array.keys()) {
|
||||
const item = array[key];
|
||||
result[key] = combineObject(item, columnList);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import type { BytesLike } from "./BytesLike";
|
||||
|
||||
export function convertBytesLikeToArrayBuffer(data: BytesLike, encodeUTF8 = true): ArrayBuffer{
|
||||
if (data instanceof ArrayBuffer) {
|
||||
return data;
|
||||
}
|
||||
if (data instanceof Uint8Array) {
|
||||
return data.buffer;
|
||||
}
|
||||
if (typeof(data) === 'string'){
|
||||
if(encodeUTF8){
|
||||
return (new TextEncoder()).encode(data);
|
||||
}
|
||||
return new Uint8Array(data.split('').map(s=>s.codePointAt(0) as number));
|
||||
}
|
||||
return data.buffer;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import type { BytesLike } from "./BytesLike";
|
||||
|
||||
export function convertBytesLikeToUint8Array(data: BytesLike, encodeUTF8 = true): Uint8Array {
|
||||
if (data instanceof Uint8Array) {
|
||||
return data;
|
||||
}
|
||||
if (data instanceof ArrayBuffer) {
|
||||
return new Uint8Array(data);
|
||||
}
|
||||
if (typeof (data) === 'string') {
|
||||
if(encodeUTF8){
|
||||
return (new TextEncoder()).encode(data);
|
||||
}
|
||||
return new Uint8Array(data.split('').map(s=>s.codePointAt(0) as number));
|
||||
}
|
||||
return new Uint8Array(data.buffer);
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { isArray, isString, isNumber, isBoolean } from "lodash-es";
|
||||
|
||||
export function convertFormData(values: Record<string, null | number[] | string[] | boolean[] | number | string | boolean>): FormData {
|
||||
const formData = new FormData();
|
||||
|
||||
const simpleConv = (v: unknown, key: string): string => {
|
||||
if (isString(v)) {
|
||||
return v;
|
||||
}
|
||||
if (isNumber(v)) {
|
||||
return v.toString();
|
||||
}
|
||||
if (isBoolean(v)) {
|
||||
return v ? 'true' : 'false';
|
||||
}
|
||||
if (v === null) {
|
||||
return '';
|
||||
}
|
||||
throw new TypeError(`지원하지 않는 formData Type: ${key}`);
|
||||
}
|
||||
|
||||
for (const [key, value] of Object.entries(values)) {
|
||||
if (isArray(value)) {
|
||||
const arrKey = `${key}[]`;
|
||||
for (const subValue of value) {
|
||||
formData.append(arrKey, simpleConv(subValue, key));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
formData.append(key, simpleConv(value, key));
|
||||
}
|
||||
|
||||
return formData;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import type { IDItem } from '@/defs';
|
||||
|
||||
export function convertIDArray<T>(array: Iterable<T>): IDItem<T>[] {
|
||||
const result: IDItem<T>[] = [];
|
||||
for (const id of array) {
|
||||
result.push({ id });
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
export function convertIterableToMap<T extends object, K extends keyof T, V extends T[K] & (string | number | symbol)>(
|
||||
values: Iterable<T>,
|
||||
key: K
|
||||
): Map<V, T> {
|
||||
const result = new Map<V, T>();
|
||||
for (const obj of values) {
|
||||
result.set(obj[key] as V, obj);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { automata초성All } from "./automata초성";
|
||||
import { filter초성withAlphabet } from "./filter초성withAlphabet";
|
||||
|
||||
export function convertSearch초성(text: string): string[]{
|
||||
const [filteredTextH, filteredTextA] = filter초성withAlphabet(text.replace(/\s+/g, ""));
|
||||
const [filteredTextHL1, filteredTextHL2] = automata초성All(filteredTextH);
|
||||
|
||||
return [text, filteredTextA, filteredTextH, filteredTextHL1, filteredTextHL2];
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
export function insertCustomCSS(key = 'sam_customCSS'){
|
||||
const customCSS = localStorage.getItem(key);
|
||||
if (customCSS) {
|
||||
const css = document.createElement('style');
|
||||
css.innerHTML = customCSS;
|
||||
console.log(css);
|
||||
document.getElementsByTagName('head')[0].appendChild(css);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export function delay(ms: number): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve();
|
||||
}, ms);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
type Entries<T> = {
|
||||
[K in keyof T]: [K, T[K]];
|
||||
}[keyof T][];
|
||||
|
||||
export function entriesWithType<T extends object>(value: T): Entries<T>{
|
||||
return Object.entries(value) as unknown as Entries<T>;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export function exportWindow(obj:unknown, objName: string, targetWindow?: unknown):void{
|
||||
const target:unknown = targetWindow ?? window;
|
||||
(target as {[v: string]: unknown})[objName] = obj;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
export function filter초성(text: string): string {
|
||||
const 초성 = [
|
||||
"ㄱ", "ㄲ", "ㄴ", "ㄷ", "ㄸ", "ㄹ", "ㅁ", "ㅂ", "ㅃ",
|
||||
"ㅅ", "ㅆ", "ㅇ", "ㅈ", "ㅉ", "ㅊ", "ㅋ", "ㅌ", "ㅍ", "ㅎ"
|
||||
];
|
||||
const result: string[] = [];
|
||||
for (const char of text) {
|
||||
const code = (char.codePointAt(0) ?? 0) - 44032;
|
||||
if (0 <= code && code < 11172) {
|
||||
result.push(초성[~~(code / 588)]);
|
||||
}
|
||||
else {
|
||||
result.push(char);
|
||||
}
|
||||
}
|
||||
return result.join('');
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
export function filter초성withAlphabet(text: string): [string, string] {
|
||||
const 초성 = [
|
||||
"ㄱ", "ㄲ", "ㄴ", "ㄷ", "ㄸ", "ㄹ", "ㅁ", "ㅂ", "ㅃ",
|
||||
"ㅅ", "ㅆ", "ㅇ", "ㅈ", "ㅉ", "ㅊ", "ㅋ", "ㅌ", "ㅍ", "ㅎ"
|
||||
];
|
||||
const alphabets = [
|
||||
"r", "R", "s", "e", "E", "f", "a", "q", "Q",
|
||||
"t", "T", "d", "w", "W", "c", "z", "x", "v", "g"
|
||||
];
|
||||
const resultH: string[] = [];
|
||||
const resultA: string[] = [];
|
||||
for (const char of text) {
|
||||
const code = (char.codePointAt(0) ?? 0) - 44032;
|
||||
if (0 <= code && code < 11172) {
|
||||
resultH.push(초성[~~(code / 588)]);
|
||||
resultA.push(alphabets[~~(code / 588)]);
|
||||
}
|
||||
else {
|
||||
resultH.push(char);
|
||||
resultA.push(char);
|
||||
}
|
||||
}
|
||||
return [resultH.join(''), resultA.join('')];
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { format, formatISO9075 } from 'date-fns';
|
||||
//const DATE_TIME_FORMAT = 'yyyy-MM-dd HH:mm:ss';
|
||||
const DATE_TIME_FORMAT_WITH_FRACTION = 'yyyy-MM-dd HH:mm:ss.SSS';
|
||||
|
||||
export function formatTime(time: Date, withFraction?:boolean): string;
|
||||
export function formatTime(time: Date, format:string): string;
|
||||
|
||||
export function formatTime(time: Date, withFractionOrFormat:string|boolean = false): string {
|
||||
if (typeof withFractionOrFormat === "string") {
|
||||
return format(time, withFractionOrFormat);
|
||||
}
|
||||
else if(withFractionOrFormat){
|
||||
return format(time, DATE_TIME_FORMAT_WITH_FRACTION);
|
||||
}
|
||||
else {
|
||||
return formatISO9075(time);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
interface Stats { min: number, max: number, total: number };
|
||||
|
||||
export function abilityRand(stats: Stats): [number, number, number] {
|
||||
let leadership = Math.random() * 65 + 10;
|
||||
let strength = Math.random() * 65 + 10;
|
||||
let intel = Math.random() * 65 + 10;
|
||||
const rate = leadership + strength + intel;
|
||||
|
||||
leadership = Math.floor((leadership / rate) * stats.total);
|
||||
strength = Math.floor((strength / rate) * stats.total);
|
||||
intel = Math.floor((intel / rate) * stats.total);
|
||||
|
||||
while (leadership + strength + intel < stats.total) {
|
||||
leadership += 1;
|
||||
}
|
||||
|
||||
if (
|
||||
leadership > stats.max ||
|
||||
strength > stats.max ||
|
||||
intel > stats.max ||
|
||||
leadership < stats.min ||
|
||||
strength < stats.min ||
|
||||
intel < stats.min
|
||||
) {
|
||||
return abilityRand(stats);
|
||||
}
|
||||
|
||||
return [leadership, strength, intel];
|
||||
}
|
||||
|
||||
export function abilityLeadpow(stats: Stats): [number, number, number] {
|
||||
let leadership = Math.random() * 6;
|
||||
let strength = Math.random() * 6;
|
||||
let intel = Math.random() * 1;
|
||||
const rate = leadership + strength + intel;
|
||||
|
||||
leadership = Math.floor((leadership / rate) * stats.total);
|
||||
strength = Math.floor((strength / rate) * stats.total);
|
||||
intel = Math.floor((intel / rate) * stats.total);
|
||||
|
||||
while (leadership + strength + intel < stats.total) {
|
||||
strength += 1;
|
||||
}
|
||||
|
||||
if (intel < stats.min) {
|
||||
leadership -= stats.min - intel;
|
||||
intel = stats.min;
|
||||
}
|
||||
|
||||
if (leadership > stats.max) {
|
||||
strength += leadership - stats.max;
|
||||
leadership = stats.max;
|
||||
}
|
||||
|
||||
if (strength > stats.max) {
|
||||
leadership += strength - stats.max;
|
||||
strength = stats.max;
|
||||
}
|
||||
|
||||
if (leadership > stats.max) {
|
||||
intel += leadership - stats.max;
|
||||
leadership = stats.max;
|
||||
}
|
||||
|
||||
return [leadership, strength, intel];
|
||||
}
|
||||
|
||||
export function abilityLeadint(stats: Stats): [number, number, number] {
|
||||
let leadership = Math.random() * 6;
|
||||
let strength = Math.random() * 1;
|
||||
let intel = Math.random() * 6;
|
||||
const rate = leadership + strength + intel;
|
||||
|
||||
leadership = Math.floor((leadership / rate) * stats.total);
|
||||
strength = Math.floor((strength / rate) * stats.total);
|
||||
intel = Math.floor((intel / rate) * stats.total);
|
||||
|
||||
while (leadership + strength + intel < stats.total) {
|
||||
intel += 1;
|
||||
}
|
||||
|
||||
if (strength < stats.min) {
|
||||
leadership -= stats.min - strength;
|
||||
strength = stats.min;
|
||||
}
|
||||
|
||||
if (leadership > stats.max) {
|
||||
intel += leadership - stats.max;
|
||||
leadership = stats.max;
|
||||
}
|
||||
|
||||
if (intel > stats.max) {
|
||||
leadership += intel - stats.max;
|
||||
intel = stats.max;
|
||||
}
|
||||
|
||||
if (leadership > stats.max) {
|
||||
strength += leadership - stats.max;
|
||||
leadership = stats.max;
|
||||
}
|
||||
|
||||
return [leadership, strength, intel];
|
||||
}
|
||||
|
||||
export function abilityPowint(stats: Stats): [number, number, number] {
|
||||
let leadership = Math.random() * 1;
|
||||
let strength = Math.random() * 6;
|
||||
let intel = Math.random() * 6;
|
||||
const rate = leadership + strength + intel;
|
||||
|
||||
leadership = Math.floor((leadership / rate) * stats.total);
|
||||
strength = Math.floor((strength / rate) * stats.total);
|
||||
intel = Math.floor((intel / rate) * stats.total);
|
||||
|
||||
while (leadership + strength + intel < stats.total) {
|
||||
intel += 1;
|
||||
}
|
||||
|
||||
if (leadership < stats.min) {
|
||||
strength -= stats.min - leadership;
|
||||
leadership = stats.min;
|
||||
}
|
||||
|
||||
if (strength > stats.max) {
|
||||
intel += strength - stats.max;
|
||||
strength = stats.max;
|
||||
}
|
||||
|
||||
if (intel > stats.max) {
|
||||
strength += intel - stats.max;
|
||||
intel = stats.max;
|
||||
}
|
||||
|
||||
if (strength > stats.max) {
|
||||
leadership += strength - stats.max;
|
||||
strength = stats.max;
|
||||
}
|
||||
|
||||
return [leadership, strength, intel];
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { unwrap } from "./unwrap";
|
||||
|
||||
//https://stackoverflow.com/questions/36280818/how-to-convert-file-to-base64-in-javascript
|
||||
export function getBase64FromFileObject(file: File): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(file);
|
||||
reader.onload = () => {
|
||||
let encoded = unwrap(reader.result).toString().replace(/^data:(.*,)?/, '');
|
||||
if ((encoded.length % 4) > 0) {
|
||||
encoded += '='.repeat(4 - (encoded.length % 4));
|
||||
}
|
||||
resolve(encoded);
|
||||
};
|
||||
reader.onerror = error => reject(error);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import { formatTime } from '@util/formatTime';
|
||||
export function getDateTimeNow(withFraction = false): string {
|
||||
return formatTime(new Date(), withFraction);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
export function getIconPath(imgsvr: boolean | 1 | 0, picture: string): string {
|
||||
// ../d_shared/common_path.js 필요
|
||||
if (!imgsvr) {
|
||||
return `${window.pathConfig.sharedIcon}/${picture}`;
|
||||
} else {
|
||||
return `${window.pathConfig.root}/d_pic/${picture}`;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
export function hexToRgb(hex: string): { r: number; g: number; b: number; } | null {
|
||||
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||
return result ? {
|
||||
r: parseInt(result[1], 16),
|
||||
g: parseInt(result[2], 16),
|
||||
b: parseInt(result[3], 16)
|
||||
} : null;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export function htmlReady(fn: () => unknown): void {
|
||||
if (document.readyState != 'loading') {
|
||||
fn();
|
||||
} else {
|
||||
document.addEventListener('DOMContentLoaded', fn);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { BootstrapVueNext, BToastPlugin } from "bootstrap-vue-next";
|
||||
import { Directives } from "bootstrap-vue-next";
|
||||
import type { App } from "vue";
|
||||
import Multiselect from "vue-multiselect";
|
||||
|
||||
export function installVue3Components<T>(app: App<T>): App<T> {
|
||||
|
||||
app.use(BootstrapVueNext).use(BToastPlugin).component('v-multiselect', Multiselect);
|
||||
for (const [name, directive] of Object.entries(Directives)) {
|
||||
//BVN 0.7.3 directive 이름 hack
|
||||
if (!name.startsWith('v')) {
|
||||
continue;
|
||||
}
|
||||
app.directive(name.substring(1), directive);
|
||||
}
|
||||
return app;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { unwrap } from "@util/unwrap";
|
||||
import { hexToRgb } from "@util/hexToRgb";
|
||||
|
||||
export function isBrightColor(color: string): boolean {
|
||||
const cv = unwrap(hexToRgb(color));
|
||||
if ((cv.r * 0.299 + cv.g * 0.587 + cv.b * 0.114) > 140) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export function isNotNull<T>(value: T|null|undefined):value is T{
|
||||
return value !== null && value !== undefined;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export function joinYearMonth(year: number, month: number): number {
|
||||
return year * 12 + month - 1;
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
import Schema, { type Rule, type Values } from "async-validator";
|
||||
import { isArray } from "lodash-es";
|
||||
import { mergeKVArray } from "@util/mergeKVArray";
|
||||
import $ from 'jquery';
|
||||
|
||||
type Option = {
|
||||
preParse?: ($target?: JQuery<HTMLElement>)=>void,
|
||||
postParse?: (values:Record<string, string | string[]>, $target?: JQuery<HTMLElement>)=>[Record<string, string | string[]>, Map<string, string>]
|
||||
}
|
||||
|
||||
type DefaultFormDataType = Record<string, null|number[]|string[]|boolean[]|number|string|boolean>;
|
||||
|
||||
export type NamedRules<T extends Record<string, unknown>> = {
|
||||
[v in keyof T]: Rule
|
||||
}
|
||||
|
||||
export class JQValidateForm<TypedValue extends Values = DefaultFormDataType> {
|
||||
|
||||
public readonly validator: Schema;
|
||||
public readonly inputs: JQuery<HTMLElement>;
|
||||
constructor(public readonly target: JQuery<HTMLElement>, public readonly rule: NamedRules<TypedValue>, public readonly option?:Option) {
|
||||
this.validator = new Schema(rule);
|
||||
this.inputs = target.find(':input');
|
||||
}
|
||||
|
||||
public clearErrMsg():void {
|
||||
this.inputs.removeClass('is-invalid');
|
||||
this.inputs.removeClass('is-valid');
|
||||
this.target.find('.invalid-feedback').detach();
|
||||
}
|
||||
|
||||
public installChangeHandler():this{
|
||||
this.inputs.on('change', ()=>{
|
||||
void this.validate();
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
public async validate(): Promise<undefined | TypedValue> {
|
||||
if(this.option?.preParse !== undefined){
|
||||
this.option.preParse(this.target);
|
||||
}
|
||||
let rawValues = mergeKVArray(this.inputs.serializeArray());
|
||||
let optMap: Map<string, string>;
|
||||
if(this.option?.postParse !== undefined){
|
||||
[rawValues, optMap] = this.option.postParse(rawValues, this.target);
|
||||
}
|
||||
else{
|
||||
optMap = new Map();
|
||||
}
|
||||
console.log(rawValues);
|
||||
|
||||
const validateResult = await this.validator.validate(rawValues).catch(({fields }) => {
|
||||
if(fields === undefined){
|
||||
console.error('validator 에러, 조건 검사 구문을 확인하세요.');
|
||||
return;
|
||||
}
|
||||
this.clearErrMsg();
|
||||
for(const rawKey of Object.keys(fields)){
|
||||
let $item: JQuery<HTMLElement>;
|
||||
const key = rawKey.split('.')[0];
|
||||
console.log(`ErrorType: ${key}:${rawValues[key]}`);
|
||||
const errMsg = fields[rawKey][0].message;
|
||||
|
||||
if(optMap.has(key)){
|
||||
$item = this.target.find(optMap.get(key) as string);
|
||||
}
|
||||
else if(isArray(rawValues[key])){
|
||||
$item = this.target.find(`:input[name='${key}[]']`);
|
||||
}
|
||||
else{
|
||||
$item = this.target.find(`:input[name='${key}']`);
|
||||
}
|
||||
|
||||
if($item.length == 0){
|
||||
continue;
|
||||
}
|
||||
|
||||
const $error = $(`<span>${errMsg}</span>`);
|
||||
|
||||
$error.addClass( "invalid-feedback" );
|
||||
|
||||
if ("radio" == $item.prop( "type" )) {
|
||||
const $target = $item.parents( ".btn-group" );
|
||||
$error.insertAfter( $target );
|
||||
$target.addClass('is-invalid');
|
||||
}
|
||||
else if ("checkbox" == $item.prop( "type" )) {
|
||||
let $target = $item.parent( "label" );
|
||||
if($target.parent(".btn-group").length){
|
||||
$target = $target.parent('.btn-group');
|
||||
}
|
||||
$error.insertAfter( $target );
|
||||
$target.addClass('is-invalid');
|
||||
} else {
|
||||
$error.insertAfter( $item );
|
||||
$item.addClass('is-invalid');
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
this.inputs.each(function(){
|
||||
const name = (this as HTMLInputElement).name;
|
||||
if(name in fields){
|
||||
return;
|
||||
}
|
||||
this.classList.add('is-valid');
|
||||
});
|
||||
return undefined;
|
||||
});
|
||||
if(validateResult === undefined){
|
||||
return undefined;
|
||||
}
|
||||
this.clearErrMsg();
|
||||
this.inputs.addClass('is-valid');
|
||||
return validateResult as TypedValue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { mb_strwidth } from "@util/mb_strwidth";
|
||||
|
||||
/**
|
||||
* mb_strimwidth
|
||||
* @param String
|
||||
* @param int
|
||||
* @param int
|
||||
* @param String
|
||||
* @return String
|
||||
* @see http://www.php.net/manual/function.mb-strimwidth.php
|
||||
*/
|
||||
export function mb_strimwidth(str: string, start: number, width: number, trimmarker = ''): string {
|
||||
const trimmakerWidth = mb_strwidth(trimmarker);
|
||||
const l = str.length;
|
||||
let trimmedLength = 0;
|
||||
const trimmedStr: string[] = [];
|
||||
for (let i = start; i < l; i++) {
|
||||
const c = str.charAt(i);
|
||||
const charWidth = mb_strwidth(c);
|
||||
const next = str.charAt(i + 1);
|
||||
const nextWidth = mb_strwidth(next);
|
||||
|
||||
trimmedLength += charWidth;
|
||||
trimmedStr.push(c);
|
||||
if (trimmedLength + trimmakerWidth + nextWidth > width) {
|
||||
trimmedStr.push(trimmarker);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return trimmedStr.join('');
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
//https://gist.github.com/demouth/3217440
|
||||
/**
|
||||
* mb_strwidth
|
||||
* @see http://php.net/manual/function.mb-strwidth.php
|
||||
*/
|
||||
export function mb_strwidth(str: string): number {
|
||||
const l = str.length;
|
||||
let length = 0;
|
||||
for (let i = 0; i < l; i++) {
|
||||
const c = str.charCodeAt(i);
|
||||
if (0x0000 <= c && c <= 0x0019) {
|
||||
length += 0;
|
||||
} else if (0x0020 <= c && c <= 0x1FFF) {
|
||||
length += 1;
|
||||
} else if (0x2000 <= c && c <= 0xFF60) {
|
||||
length += 2;
|
||||
} else if (0xFF61 <= c && c <= 0xFF9F) {
|
||||
length += 1;
|
||||
} else if (0xFFA0 <= c) {
|
||||
length += 2;
|
||||
}
|
||||
}
|
||||
return length;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
import type { ValuesOf } from "@/defs";
|
||||
import { zip } from "lodash-es";
|
||||
|
||||
export function merge2DArrToObjectArr<T extends Record<string, unknown>>(column: (keyof T)[], list: ValuesOf<T>[][]): T[]{
|
||||
const result: T[] = [];
|
||||
for(const rawItem of list){
|
||||
const item: Record<string, unknown> = {};
|
||||
|
||||
if(column.length != rawItem.length){
|
||||
throw `column과 item의 길이가 같지 않습니다: ${column.length} != ${list.length}, ${JSON.stringify(item)}`;
|
||||
}
|
||||
|
||||
for(const [key, value] of zip(column, rawItem)){
|
||||
item[key as string] = value;
|
||||
}
|
||||
result.push(item as T);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { isString } from "lodash-es";
|
||||
|
||||
interface NameValuePair {
|
||||
name: string,
|
||||
value: string
|
||||
}
|
||||
|
||||
export function mergeKVArray(array : NameValuePair[]):Record<string, string|string[]>{
|
||||
const result:Record<string, string|string[]> = {};
|
||||
|
||||
for(const {name, value} of array){
|
||||
if(!isString(name)){
|
||||
throw new TypeError(`${name} is not string`);
|
||||
}
|
||||
if(!isString(value)){
|
||||
throw new TypeError(`${value} is not string`);
|
||||
}
|
||||
|
||||
if(name === '' || name === '[]'){
|
||||
continue;
|
||||
}
|
||||
if(name.length > 2 && name.slice(-2) == '[]'){
|
||||
const keyHead = name.slice(0, -2);
|
||||
if(!(keyHead in result)){
|
||||
result[keyHead] = [value];
|
||||
}
|
||||
else{
|
||||
(result[keyHead] as string[]).push(value);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
result[name] = value;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
export function nl2br(text: string): string {
|
||||
return text.replace(/\n/g, "<br>");
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
|
||||
export function numberWithCommas(x: number): string {
|
||||
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import {parseISO} from 'date-fns';
|
||||
|
||||
export function parseTime(dateString: string): Date{
|
||||
return parseISO(dateString);
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export function parseYearMonth(yearMonth: number): [number, number] {
|
||||
return [(yearMonth / 12) | 0, yearMonth % 12 + 1];
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
const charList = [
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
|
||||
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
|
||||
'u', 'v', 'w', 'x', 'y', 'z',
|
||||
];
|
||||
|
||||
export function randStr(len: number): string {
|
||||
const result = [];
|
||||
const charListLen = charList.length;
|
||||
let isStart = true;
|
||||
|
||||
while(len > 0){
|
||||
const randChrIdx = Math.floor(Math.random() * charListLen);
|
||||
if(isStart){
|
||||
if(randChrIdx == 0){
|
||||
continue;
|
||||
}
|
||||
isStart = false;
|
||||
}
|
||||
result.push(charList[randChrIdx]);
|
||||
len -= 1;
|
||||
}
|
||||
return result.join('');
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
/** @deprecated */
|
||||
export function scrollHardTo(elementId: string): void {
|
||||
const element = document.getElementById(elementId);
|
||||
if(!element){
|
||||
return;
|
||||
}
|
||||
element.scrollIntoView({
|
||||
behavior: 'auto',
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
export function scrollToSelector(selector: string): void {
|
||||
const element = document.querySelector(selector);
|
||||
if(!element){
|
||||
return;
|
||||
}
|
||||
element.scrollIntoView({
|
||||
behavior: 'auto',
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import axios from "axios";
|
||||
|
||||
export function setAxiosXMLHttpRequest(): void{
|
||||
axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
|
||||
//TODO: X-Requested-With 믿지 말자.
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { isInteger, isString } from "lodash-es";
|
||||
|
||||
export function simpleSerialize(...values : (string|number)[]): string{
|
||||
const result = [];
|
||||
for(const value of values){
|
||||
if(isString(value)){
|
||||
result.push(`str(${value.length},${value})`);
|
||||
continue;
|
||||
}
|
||||
if(isInteger(value)){
|
||||
result.push(`int(${value})`);
|
||||
continue;
|
||||
}
|
||||
const float6 = value.toLocaleString("en-US", {maximumFractionDigits: 6});
|
||||
result.push(`float(${float6})`);
|
||||
}
|
||||
return result.join('|');
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import type { Nullable } from "@util/Nullable";
|
||||
import { NotNullExpected } from "@util/NotNullExpected";
|
||||
|
||||
export function unwrap<T>(result: Nullable<T>): T {
|
||||
if (result === null || result === undefined) {
|
||||
throw new NotNullExpected();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import type { Nullable } from "@util/Nullable";
|
||||
import { NotNullExpected } from "@util/NotNullExpected";
|
||||
|
||||
|
||||
export function unwrap_any<T>(result: Nullable<unknown>): T {
|
||||
if (result === null || result === undefined) {
|
||||
throw new NotNullExpected();
|
||||
}
|
||||
return result as T;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import type { Nullable } from "@util/Nullable";
|
||||
|
||||
type ErrType<T> = { new(msg?: string): T }
|
||||
|
||||
export function unwrap_err<T, ErrT extends Error>(result: Nullable<T>, errType: ErrType<ErrT>, errMsg?: string): T {
|
||||
if (result === null || result === undefined) {
|
||||
throw new errType(errMsg);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"files": [],
|
||||
//"files": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.node.json"
|
||||
@@ -12,11 +12,11 @@
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"resolveJsonModule": true,
|
||||
"noImplicitOverride": true,
|
||||
//"noImplicitOverride": true,
|
||||
"noImplicitReturns": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
//"noPropertyAccessFromIndexSignature": true,
|
||||
"isolatedModules": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
//"verbatimModuleSyntax": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
|
||||
Reference in New Issue
Block a user