Compare commits

..

20 Commits

Author SHA1 Message Date
kvan7
292e2de2dd fix lint 2024-12-11 17:23:42 -06:00
kvan7
3cda3a74b8 Add lots more testing code 2024-12-11 17:21:18 -06:00
kvan7
32215e5c03 fix name 2024-12-11 17:21:18 -06:00
kvan7
fd4917ca7f style(Update to 2): Update branding
Renamed to Exalted PoE2 Trade
2024-12-11 17:21:18 -06:00
kvan7
c3d6c69d9d change to node 18 2024-12-11 17:21:18 -06:00
Kvan7
0774814912 Update issue templates 2024-12-11 06:34:12 -06:00
kvan7
20b695b1b3 Fixes Config file name updated #14 2024-12-11 06:25:11 -06:00
kvan7
e0a3b34c22 Update Names 2024-12-10 23:46:20 -06:00
kvan7
ed2a93a82f add a lot more logging 2024-12-10 18:28:47 -06:00
kvan7
14ecde0c71 test(Update to 2): Test for more informative logs 2024-12-10 18:16:11 -06:00
Kvan7
dd91dea7b1 Merge pull request #11 from Kvan7:dev
Attempt at bugfix for leagues missing
2024-12-10 17:51:48 -06:00
kvan7
a6ace8e234 build(Update to 2): Version bump 2024-12-10 17:51:10 -06:00
kvan7
68ee7016d1 fix(Update to 2): Remove unused ref
removes unused imports that were added back for some reason
2024-12-10 17:42:43 -06:00
kvan7
46e70400b6 fix(Update to 2): Solving league bug
solve bug by commenting ocut problem code

uhhhh some other stuff may break
2024-12-10 17:42:43 -06:00
kvan7
4a37528500 Merge branch 'dev' of github.com:Kvan7/awakened-poe-trade into dev 2024-12-10 17:16:53 -06:00
kvan7
b36954d0a9 fix(Update to 2): Fixes linting yay
linters, am i right
2024-12-10 17:16:47 -06:00
Alexander Drozdov
932ebd3b44 switch main to npm too 2024-12-10 17:08:03 -06:00
Kvan7
e18ddda81a Update README.md 2024-12-09 22:33:09 -06:00
Kvan7
ef592e0cf4 Update README.md 2024-12-09 22:31:57 -06:00
kvan7
de5444fa04 docs: Update readme 2024-12-09 22:30:02 -06:00
68 changed files with 14584 additions and 14053 deletions

View File

@@ -0,0 +1,24 @@
---
name: Something Broken in PoE2
about: Use this for things that worked in PoE 1 and do not in PoE 2
title: "[PoE2]"
labels: bug
assignees: Kvan7
---
**Describe the problem**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem. This is very helpful for comparing the PoE1 vs 2 problems

View File

@@ -20,8 +20,8 @@ jobs:
working-directory: ./renderer
- run: npm run make-index-files
working-directory: ./renderer
# - run: npm run lint
# working-directory: ./renderer
- run: npm run lint
working-directory: ./renderer
- run: npm run build
working-directory: ./renderer
- uses: actions/upload-artifact@v4
@@ -43,11 +43,11 @@ jobs:
with:
name: renderer-dist
path: ./renderer/dist
- run: yarn --frozen-lockfile
- run: npm ci
working-directory: ./main
- run: yarn build
- run: npm run build
working-directory: ./main
- run: yarn package -p onTagOrDraft
- run: npm run package "--" -p onTagOrDraft
working-directory: ./main
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -11,32 +11,32 @@ Note that these 2 both depend on each other, and one cannot run without the othe
The most up-to-date instructions can always be derived from CI:
[.github/workflows/main.yml](https://github.com/Kvan7/awakened-poe2-trade2/blob/master/.github/workflows/main.yml)
[.github/workflows/main.yml](https://github.com/Kvan7/exiled-exchange-2/blob/master/.github/workflows/main.yml)
Here's what that looks like as of 2023-12-03.
```shell
cd renderer
yarn install
yarn make-index-files
yarn dev
npm install
npm run make-index-files
npm run dev
# In a second shell
cd main
yarn install
yarn dev
npm install
npm run dev
```
# How to build
```shell
cd renderer
yarn install
yarn make-index-files
yarn build
npm install
npm run make-index-files
npm run build
cd ../main
yarn build
npm run build
# We want to sign with a distribution certificate to ensure other users can
# install without errors
CSC_NAME="Certificate name in Keychain" yarn package

View File

@@ -1,11 +1,16 @@
# ![Awakener's Orb](https://web.poecdn.com/image/Art/2DItems/Currency/TransferOrb.png) Awakened PoE2 Trade2
# ![Exalted Orb](./renderer/dist/images/exa.png) Exile's Exchange
[![](https://user-images.githubusercontent.com/4292308/153364874-dde23599-278c-4350-8d86-dadbc4b978b3.svg)](https://somsubhra.github.io/github-release-stats/?username=SnosMe&repository=awakened-poe-trade)
[![](https://user-images.githubusercontent.com/4292308/153364769-e4fe1e82-1bbc-46ac-8a3c-f5a98a5667cc.svg)](https://patreon.com/awakened_poe_trade)
## Moving from POE1
➡ [Download for Windows & Linux](https://snosme.github.io/awakened-poe-trade/download) ⬅
1. Download latest release from [releases](https://github.com/Kvan7/exiled-exchange-2/releases)
- Currently only Windows is supported
- Only available as pre-release right now
2. Run installer
3. Copy `apt-data` from `%APPDATA%\awakened-poe-trade` to `%APPDATA%\exiled-exchange-2` to copy your previous settings
- Resulting directory structure should look like this:
- `%APPDATA%\exiled-exchange-2\apt-data\`
- `config.json`
4. Run Exiled Exchange 2
## Tool showcase
@@ -19,6 +24,7 @@ See [DEVELOPING.md](./DEVELOPING.md)
### Acknowledgments
- [awakened-poe-trade](https://github.com/SnosMe/awakened-poe-trade)
- [libuiohook](https://github.com/kwhat/libuiohook)
- [RePoE](https://github.com/brather1ng/RePoE)
- [poeprices.info](https://www.poeprices.info/)

View File

@@ -1,9 +1,9 @@
import { defineConfig } from 'vitepress'
const BASE = '/awakened-poe2-trade2/'
const BASE = '/exiled-exchange-2/'
export default defineConfig({
title: 'Awakened PoE2 Trade2',
title: 'Exiled Exchange 2',
description: 'App for price-checking items in Path of Exile 2',
base: BASE,
mpa: true,
@@ -22,7 +22,7 @@ export default defineConfig({
// logo: 'TODO', https://github.com/vuejs/vitepress/issues/1401
appVersion: '3.25.101',
github: {
releasesUrl: 'https://github.com/Kvan7/awakened-poe2-trade2/releases'
releasesUrl: 'https://github.com/Kvan7/exiled-exchange-2/releases'
},
socialLinks: [
{
@@ -33,7 +33,7 @@ export default defineConfig({
{
text: 'GitHub',
color: '#181717',
link: 'https://github.com/Kvan7/awakened-poe2-trade2'
link: 'https://github.com/Kvan7/exiled-exchange-2'
}
],
sidebar: [

View File

@@ -8,15 +8,15 @@ import { useData } from 'vitepress'
const { theme } = useData()
</script>
You can download Awakened Poe Trade here. Any other mirrors are not known
You can download Exalted Poe Trade here. Any other mirrors are not known
to the developer, downloading from them may be unsafe.
| Download link | Automatic updates | Startup time |
| ----------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | ------------ |
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/Awakened-PoE2-Trade2-Setup-${theme.appVersion}.exe`">Windows 10+ (installer)</a> | ✔ | Fast |
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/Awakened-PoE2-Trade2-${theme.appVersion}.exe`">Windows 10+ (portable)</a> | ❌ | Slower |
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/Awakened-PoE2-Trade2-${theme.appVersion}.AppImage`">Linux (AppImage)</a> | ✔ | n/a |
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/Awakened-PoE2-Trade2-${theme.appVersion}-universal.dmg`">macOS (dmg)</a> | ❌ | n/a |
| -------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | ------------ |
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/exiled-exchange-2-Setup-${theme.appVersion}.exe`">Windows 10+ (installer)</a> | ✔ | Fast |
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/exiled-exchange-2-${theme.appVersion}.exe`">Windows 10+ (portable)</a> | ❌ | Slower |
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/exiled-exchange-2-${theme.appVersion}.AppImage`">Linux (AppImage)</a> | ✔ | n/a |
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/exiled-exchange-2-${theme.appVersion}-universal.dmg`">macOS (dmg)</a> | ❌ | n/a |
Latest version is <span class="bg-gray-100 border rounded px-1">{{ theme.appVersion }}</span>
@@ -36,6 +36,6 @@ warnings on Windows and [macOS](https://support.apple.com/en-us/HT202491#openany
No Administrator rights required, but\
⚠ **If you run PoE client as Admin, OS security boundaries take effect.
In order for Awakened PoE2 Trade2 to have access to the PoE window, it must be started with Administrator rights.**
In order for Exiled Exchange 2 to have access to the PoE window, it must be started with Administrator rights.**
**Not compatible with "GeForce Now" or any other cloud gaming service that do not forward clipboard data.**

View File

@@ -14,7 +14,7 @@ title: Common issues
If Awakened works for you with DirectX11/12 renderer,
then problem is old Vulkan drivers for sure.
4. Delete `%appdata%\awakened-poe2-trade2`
4. Delete `%appdata%\exiled-exchange-2`
If needed, backup `apt-data` folder with your configuration inside.
@@ -22,7 +22,7 @@ title: Common issues
Launch them later one at a time to identify **conflict**.
6. Restart Awakened PoE2 Trade2.
6. Restart Exiled Exchange 2.
*(don't forget to quit first, otherwise launching second instance will do nothing).*

View File

@@ -5,7 +5,7 @@ title: Quick Start
#### First of all, how does it work? {:style="margin-top: 0;"}
When you press `Ctrl + C` Path of Exile 2 copies the item's text (under cursor, if any) to the clipboard.
All that remains is to parse text in Awakened PoE2 Trade2 and show to you in a fancy way.
All that remains is to parse text in Exiled Exchange 2 and show to you in a fancy way.
### Usage

View File

@@ -25,6 +25,7 @@
"dist/": true
},
"editor.tabSize": 2,
"editor.insertSpaces": true,
"conventionalCommits.scopes": [
"Update to 2"
]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 841 KiB

After

Width:  |  Height:  |  Size: 712 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 791 B

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 280 KiB

After

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 353 KiB

After

Width:  |  Height:  |  Size: 66 KiB

BIN
main/build/icons/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -1,6 +1,6 @@
publish:
- "github"
productName: "Awakened PoE2 Trade2"
productName: "Exiled Exchange 2"
npmRebuild: false
files:
- "package.json"

5656
main/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,18 +1,20 @@
{
"name": "awakened-poe2-trade2",
"version": "0.0.1",
"name": "exiled-exchange-2",
"version": "0.0.9",
"private": true,
"scripts": {
"dev": "node build/script.mjs",
"build": "tsc --noEmit && node build/script.mjs --prod",
"package": "electron-builder build"
"package": "electron-builder build",
"lint": "eslint src",
"fix": "eslint src --fix"
},
"author": {
"name": "Alexander Drozdov"
"name": "Garrett Parker"
},
"repository": {
"type": "git",
"url": "https://github.com/Kvan7/awakened-poe2-trade2.git"
"url": "https://github.com/Kvan7/exiled-exchange-2.git"
},
"main": "dist/main.js",
"dependencies": {
@@ -25,15 +27,12 @@
"@types/ws": "^8.5.3",
"@wokwi/bmp-ts": "^3.0.0",
"comlink": "^4.3.1",
"electron": "31.3.1",
"electron-builder": "24.13.3",
"electron-updater": "^6.1.0",
"esbuild": "^0.23.0",
"ini": "^4.0.0",
"typescript": "5.5.x",
"electron": "33.2.1",
"electron-builder": "25.1.8",
"electron-updater": "^6.3.0",
"esbuild": "^0.24.0",
"ini": "^5.0.0",
"typescript": "5.6.x",
"ws": "^8.16.0"
},
"engines": {
"node": ">=16"
}
}

View File

@@ -23,7 +23,7 @@ export class AppTray {
}
this.tray = new Tray(trayImage);
this.tray.setToolTip(`Awakened PoE2 Trade2 v${app.getVersion()}`);
this.tray.setToolTip(`Exiled Exchange 2 v${app.getVersion()}`);
this.rebuildMenu();
server.onEventAnyClient("CLIENT->MAIN::user-action", ({ action }) => {

View File

@@ -12,25 +12,25 @@ const POSSIBLE_PATH =
? [
path.join(
app.getPath("documents"),
"My Games\\Path of Exile 2\\production_Config.ini"
"My Games\\Path of Exile 2\\poe2_production_Config.ini"
),
]
: process.platform === "linux"
? [
path.join(
app.getPath("documents"),
"My Games/Path of Exile 2/production_Config.ini"
"My Games/Path of Exile 2/poe2_production_Config.ini"
),
path.join(
app.getPath("home"),
".local/share/Steam/steamapps/compatdata/238960/pfx/drive_c/users/steamuser/Documents/My Games/Path of Exile 2/production_Config.ini"
".local/share/Steam/steamapps/compatdata/238960/pfx/drive_c/users/steamuser/Documents/My Games/Path of Exile 2/poe2_production_Config.ini"
),
]
: process.platform === "darwin"
? [
path.join(
app.getPath("appData"),
"Path of Exile 2/Preferences/production_Config.ini"
"Path of Exile 2/Preferences/poe2_production_Config.ini"
),
]
: [];

View File

@@ -1,6 +1,7 @@
import type { Server } from 'http'
import { app, net } from 'electron'
import type { Logger } from './RemoteLogger'
import { exec } from 'child_process';
const PROXY_HOSTS = [
{ host: 'www.pathofexile.com', official: true },
@@ -9,6 +10,7 @@ const PROXY_HOSTS = [
{ host: 'poe.game.daum.net', official: true },
{ host: 'poe.ninja', official: false },
{ host: 'www.poeprices.info', official: false },
{ host: 'kvan.dev', official: false },
]
export class HttpProxy {
@@ -18,11 +20,18 @@ export class HttpProxy {
) {
server.addListener('request', (req, res) => {
if (!req.url?.startsWith('/proxy/')) return
const fullPath = req.url.slice('/proxy/'.length)
const host = req.url.split('/', 3)[2]
if (fullPath.startsWith('www.pathofexile.com/api/trade2/search/Standard') || fullPath.startsWith('kvan.dev')) {
this.executeCurl(fullPath, logger)
}
const official = PROXY_HOSTS.find(entry => entry.host === host)?.official
if (official === undefined) return req.destroy()
this.pingHost(host, logger); // Add this line to use ping
for (const key in req.headers) {
if (key.startsWith('sec-') || key === 'host' || key === 'origin' || key === 'content-length') {
delete req.headers[key]
@@ -39,17 +48,68 @@ export class HttpProxy {
useSessionCookies: true
})
proxyReq.addListener('response', (proxyRes) => {
logger.write(`response [proxy] ${proxyRes.statusCode} ${proxyRes.statusMessage} (${host})`)
const resHeaders = { ...proxyRes.headers }
// `net.request` returns an already decoded body
delete resHeaders['content-encoding']
res.writeHead(proxyRes.statusCode, proxyRes.statusMessage, resHeaders)
;(proxyRes as unknown as NodeJS.ReadableStream).pipe(res)
})
proxyReq.addListener('error', (err) => {
logger.write(`error [cors-proxy] ${err.message} (${host})`)
logger.write(`error [proxy] ${err.message} (${host})`)
logger.write(`error-[proxy]-(${err.name}) ${err.stack}`)
res.destroy(err)
})
req.pipe(proxyReq as unknown as NodeJS.WritableStream)
logger.write(`Full request details: ${JSON.stringify(proxyReq, null, 2)}`);
})
}
pingHost(host: string, logger: Logger) {
const pingCommand = process.platform === 'win32' ? `ping -n 1 ${host}` : `ping -c 1 ${host}`;
exec(pingCommand, (error, stdout, stderr) => {
if (error) {
logger.write(`ping error [${host}] ${error.message}`)
return;
}
if (stderr) {
logger.write(`ping stderr [${host}] ${stderr}`)
return;
}
logger.write(`ping success [${host}] ${stdout}`)
})
}
executeCurl(path: string, logger: Logger) {
const postData = {
"query": {
"status": { "option": "online" },
"stats": [{ "type": "and", "filters": [] }],
"filters": {
"trade_filters": { "filters": { "collapse": { "option": "true" }}},
"type_filters": { "filters": {
"rarity": { "option": "nonunique" },
"category": { "option": "accessory.ring" }}},
"misc_filters": { "filters": {
"corrupted": { "option": "false" },
"mirrored": { "option": "false" }}}
}
},
"sort": { "price": "asc" }
};
const postDataStr = JSON.stringify(postData);
const curlCommand = `curl -X POST --data '${postDataStr}' https://${path}`;
exec(curlCommand, (error, stdout, stderr) => {
if (error) {
logger.write(`curl error [${path}] ${error.message}`);
return;
}
if (stderr) {
logger.write(`curl stderr [${path}] ${stderr}`);
return;
}
logger.write(`curl output [${path}] ${stdout}`);
});
}
}

View File

@@ -93,7 +93,7 @@ export async function startServer (
socket.on('close', () => {
const clients = websocketServer.clients
if (clients.size === 1) {
lastActiveClient = clients.values().next().value
lastActiveClient = clients.values().next().value!
evBus.emit('CLIENT->MAIN::used-recently', { isOverlay: true })
}
})

View File

@@ -161,7 +161,7 @@ export class OverlayWindow {
// ----------------------
"Path of Exile 2 is running with administrator rights.\n" +
"\n" +
"You need to restart Awakened PoE2 Trade2 with administrator rights."
"You need to restart Exiled Exchange 2 with administrator rights."
);
} else {
this.server.sendEventTo("broadcast", {

File diff suppressed because it is too large Load Diff

View File

@@ -5,14 +5,11 @@ module.exports = {
},
plugins: [
'@typescript-eslint',
'prettier'
// 'only-warn'
],
extends: [
'plugin:vue/base',
'standard-with-typescript',
'plugin:prettier/recommended',
'eslint-plugin-prettier/recommended',
],
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
@@ -40,7 +37,6 @@ module.exports = {
'func-call-spacing': 'off',
// TODO: refactor IPC and enable
'@typescript-eslint/consistent-type-assertions': 'off',
"indent": ["error", "tab"]
},
overrides: [{
files: ['src/main/**/*'],

View File

@@ -1,7 +0,0 @@
{
"singleQuote": true,
"endOfLine": "lf",
"tabWidth": 2,
"useTabs": true,
"trailingComma": "es5"
}

View File

@@ -1,15 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta name="color-scheme" content="dark">
<link rel="icon" href="/icon.ico">
<title>Awakened PoE Trade2</title>
<title>Exiled Exchange 2</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

View File

@@ -1,11 +1,11 @@
{
"name": "awakened-poe2-trade2",
"name": "exiled-exchange-2",
"version": "0.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "awakened-poe2-trade2",
"name": "exiled-exchange-2",
"version": "0.0.0",
"dependencies": {
"@fortawesome/fontawesome-free": "6.x.x",
@@ -33,10 +33,7 @@
"@types/object-hash": "^3.0.0",
"@vitejs/plugin-vue": "^4.0.0",
"autoprefixer": "^10.0.2",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.2.1",
"postcss": "^8.2.14",
"prettier": "3.4.2",
"typescript": "5.6.x",
"vite": "^5.0.0",
"vue-tsc": "^2.0.0"
@@ -505,8 +502,8 @@
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz",
"integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==",
"devOptional": true,
"license": "MIT",
"optional": true,
"dependencies": {
"eslint-visitor-keys": "^3.4.3"
},
@@ -524,8 +521,8 @@
"version": "4.12.1",
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
"integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
"devOptional": true,
"license": "MIT",
"optional": true,
"engines": {
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
}
@@ -534,8 +531,8 @@
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
"integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
"devOptional": true,
"license": "MIT",
"optional": true,
"dependencies": {
"ajv": "^6.12.4",
"debug": "^4.3.2",
@@ -558,8 +555,8 @@
"version": "8.57.1",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz",
"integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==",
"devOptional": true,
"license": "MIT",
"optional": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
@@ -578,8 +575,8 @@
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
"integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==",
"deprecated": "Use @eslint/config-array instead",
"devOptional": true,
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"@humanwhocodes/object-schema": "^2.0.3",
"debug": "^4.3.1",
@@ -593,8 +590,8 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
"integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
"devOptional": true,
"license": "Apache-2.0",
"optional": true,
"engines": {
"node": ">=12.22"
},
@@ -608,8 +605,8 @@
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
"integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
"deprecated": "Use @eslint/object-schema instead",
"devOptional": true,
"license": "BSD-3-Clause"
"license": "BSD-3-Clause",
"optional": true
},
"node_modules/@intlify/core-base": {
"version": "10.0.4",
@@ -792,19 +789,6 @@
"node": ">=14"
}
},
"node_modules/@pkgr/core": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz",
"integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^12.20.0 || ^14.18.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/unts"
}
},
"node_modules/@popperjs/core": {
"version": "2.11.8",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
@@ -1399,8 +1383,8 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
"integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
"devOptional": true,
"license": "ISC"
"license": "ISC",
"optional": true
},
"node_modules/@vitejs/plugin-vue": {
"version": "4.6.2",
@@ -1755,8 +1739,8 @@
"version": "8.14.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
"integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
"devOptional": true,
"license": "MIT",
"optional": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -1768,8 +1752,8 @@
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
"devOptional": true,
"license": "MIT",
"optional": true,
"peerDependencies": {
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
@@ -1778,8 +1762,8 @@
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"devOptional": true,
"license": "MIT",
"optional": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
@@ -1871,8 +1855,8 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"devOptional": true,
"license": "Python-2.0"
"license": "Python-2.0",
"optional": true
},
"node_modules/array-buffer-byte-length": {
"version": "1.0.1",
@@ -2087,8 +2071,8 @@
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"devOptional": true,
"license": "MIT",
"optional": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -2173,8 +2157,8 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
"devOptional": true,
"license": "MIT",
"optional": true,
"engines": {
"node": ">=6"
}
@@ -2213,8 +2197,8 @@
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"devOptional": true,
"license": "MIT",
"optional": true,
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
@@ -2293,8 +2277,8 @@
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"devOptional": true,
"license": "MIT"
"license": "MIT",
"optional": true
},
"node_modules/cross-spawn": {
"version": "7.0.6",
@@ -2393,8 +2377,8 @@
"version": "4.3.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
"devOptional": true,
"license": "MIT",
"optional": true,
"dependencies": {
"ms": "^2.1.3"
},
@@ -2411,8 +2395,8 @@
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
"devOptional": true,
"license": "MIT"
"license": "MIT",
"optional": true
},
"node_modules/define-data-property": {
"version": "1.1.4",
@@ -2479,8 +2463,8 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
"integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
"devOptional": true,
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"esutils": "^2.0.2"
},
@@ -2728,8 +2712,8 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"devOptional": true,
"license": "MIT",
"optional": true,
"engines": {
"node": ">=10"
},
@@ -2742,8 +2726,8 @@
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz",
"integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
"deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
"devOptional": true,
"license": "MIT",
"optional": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
@@ -2794,19 +2778,6 @@
"url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint-config-prettier": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz",
"integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==",
"dev": true,
"license": "MIT",
"bin": {
"eslint-config-prettier": "bin/cli.js"
},
"peerDependencies": {
"eslint": ">=7.0.0"
}
},
"node_modules/eslint-config-standard": {
"version": "17.0.0",
"resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.0.0.tgz",
@@ -3043,37 +3014,6 @@
"eslint": ">=7.0.0"
}
},
"node_modules/eslint-plugin-prettier": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz",
"integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==",
"dev": true,
"license": "MIT",
"dependencies": {
"prettier-linter-helpers": "^1.0.0",
"synckit": "^0.9.1"
},
"engines": {
"node": "^14.18.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/eslint-plugin-prettier"
},
"peerDependencies": {
"@types/eslint": ">=8.0.0",
"eslint": ">=8.0.0",
"eslint-config-prettier": "*",
"prettier": ">=3.0.0"
},
"peerDependenciesMeta": {
"@types/eslint": {
"optional": true
},
"eslint-config-prettier": {
"optional": true
}
}
},
"node_modules/eslint-plugin-promise": {
"version": "6.6.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.6.0.tgz",
@@ -3160,8 +3100,8 @@
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
"devOptional": true,
"license": "Apache-2.0",
"optional": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
@@ -3173,8 +3113,8 @@
"version": "7.2.2",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
"integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
"devOptional": true,
"license": "BSD-2-Clause",
"optional": true,
"dependencies": {
"esrecurse": "^4.3.0",
"estraverse": "^5.2.0"
@@ -3190,8 +3130,8 @@
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"devOptional": true,
"license": "BSD-2-Clause",
"optional": true,
"engines": {
"node": ">=4.0"
}
@@ -3200,8 +3140,8 @@
"version": "9.6.1",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
"integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
"devOptional": true,
"license": "BSD-2-Clause",
"optional": true,
"dependencies": {
"acorn": "^8.9.0",
"acorn-jsx": "^5.3.2",
@@ -3218,8 +3158,8 @@
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
"integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
"devOptional": true,
"license": "BSD-3-Clause",
"optional": true,
"dependencies": {
"estraverse": "^5.1.0"
},
@@ -3231,8 +3171,8 @@
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"devOptional": true,
"license": "BSD-2-Clause",
"optional": true,
"engines": {
"node": ">=4.0"
}
@@ -3241,8 +3181,8 @@
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
"devOptional": true,
"license": "BSD-2-Clause",
"optional": true,
"dependencies": {
"estraverse": "^5.2.0"
},
@@ -3254,8 +3194,8 @@
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"devOptional": true,
"license": "BSD-2-Clause",
"optional": true,
"engines": {
"node": ">=4.0"
}
@@ -3280,8 +3220,8 @@
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"devOptional": true,
"license": "BSD-2-Clause",
"optional": true,
"engines": {
"node": ">=0.10.0"
}
@@ -3292,13 +3232,6 @@
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"license": "MIT"
},
"node_modules/fast-diff": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
"integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/fast-glob": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
@@ -3331,15 +3264,15 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
"devOptional": true,
"license": "MIT"
"license": "MIT",
"optional": true
},
"node_modules/fast-levenshtein": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
"devOptional": true,
"license": "MIT"
"license": "MIT",
"optional": true
},
"node_modules/fastest-levenshtein": {
"version": "1.0.16",
@@ -3363,8 +3296,8 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
"integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
"devOptional": true,
"license": "MIT",
"optional": true,
"dependencies": {
"flat-cache": "^3.0.4"
},
@@ -3388,8 +3321,8 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
"integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
"devOptional": true,
"license": "MIT",
"optional": true,
"dependencies": {
"locate-path": "^6.0.0",
"path-exists": "^4.0.0"
@@ -3405,8 +3338,8 @@
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
"integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
"devOptional": true,
"license": "MIT",
"optional": true,
"dependencies": {
"flatted": "^3.2.9",
"keyv": "^4.5.3",
@@ -3420,8 +3353,8 @@
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz",
"integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==",
"devOptional": true,
"license": "ISC"
"license": "ISC",
"optional": true
},
"node_modules/for-each": {
"version": "0.3.3",
@@ -3467,8 +3400,8 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
"devOptional": true,
"license": "ISC"
"license": "ISC",
"optional": true
},
"node_modules/fsevents": {
"version": "2.3.3",
@@ -3565,8 +3498,8 @@
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"deprecated": "Glob versions prior to v9 are no longer supported",
"devOptional": true,
"license": "ISC",
"optional": true,
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@@ -3598,8 +3531,8 @@
"version": "13.24.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
"integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
"devOptional": true,
"license": "MIT",
"optional": true,
"dependencies": {
"type-fest": "^0.20.2"
},
@@ -3614,8 +3547,8 @@
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
"devOptional": true,
"license": "(MIT OR CC0-1.0)",
"optional": true,
"engines": {
"node": ">=10"
},
@@ -3678,8 +3611,8 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
"integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
"devOptional": true,
"license": "MIT"
"license": "MIT",
"optional": true
},
"node_modules/has-bigints": {
"version": "1.0.2",
@@ -3695,8 +3628,8 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"devOptional": true,
"license": "MIT",
"optional": true,
"engines": {
"node": ">=8"
}
@@ -3782,8 +3715,8 @@
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
"integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
"devOptional": true,
"license": "MIT",
"optional": true,
"engines": {
"node": ">= 4"
}
@@ -3792,8 +3725,8 @@
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
"devOptional": true,
"license": "MIT",
"optional": true,
"dependencies": {
"parent-module": "^1.0.0",
"resolve-from": "^4.0.0"
@@ -3809,8 +3742,8 @@
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
"integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
"devOptional": true,
"license": "MIT",
"optional": true,
"engines": {
"node": ">=0.8.19"
}
@@ -3820,8 +3753,8 @@
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
"devOptional": true,
"license": "ISC",
"optional": true,
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
@@ -3831,8 +3764,8 @@
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"devOptional": true,
"license": "ISC"
"license": "ISC",
"optional": true
},
"node_modules/internal-slot": {
"version": "1.0.7",
@@ -4098,8 +4031,8 @@
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
"integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
"devOptional": true,
"license": "MIT",
"optional": true,
"engines": {
"node": ">=8"
}
@@ -4282,8 +4215,8 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"devOptional": true,
"license": "MIT",
"optional": true,
"dependencies": {
"argparse": "^2.0.1"
},
@@ -4295,22 +4228,22 @@
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
"devOptional": true,
"license": "MIT"
"license": "MIT",
"optional": true
},
"node_modules/json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"devOptional": true,
"license": "MIT"
"license": "MIT",
"optional": true
},
"node_modules/json-stable-stringify-without-jsonify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
"integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
"devOptional": true,
"license": "MIT"
"license": "MIT",
"optional": true
},
"node_modules/json5": {
"version": "1.0.2",
@@ -4329,8 +4262,8 @@
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
"integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
"devOptional": true,
"license": "MIT",
"optional": true,
"dependencies": {
"json-buffer": "3.0.1"
}
@@ -4339,8 +4272,8 @@
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
"integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
"devOptional": true,
"license": "MIT",
"optional": true,
"dependencies": {
"prelude-ls": "^1.2.1",
"type-check": "~0.4.0"
@@ -4368,8 +4301,8 @@
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
"integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
"devOptional": true,
"license": "MIT",
"optional": true,
"dependencies": {
"p-locate": "^5.0.0"
},
@@ -4391,8 +4324,8 @@
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
"devOptional": true,
"license": "MIT"
"license": "MIT",
"optional": true
},
"node_modules/lru-cache": {
"version": "10.4.3",
@@ -4444,8 +4377,8 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"devOptional": true,
"license": "ISC",
"optional": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -4476,8 +4409,8 @@
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"devOptional": true,
"license": "MIT"
"license": "MIT",
"optional": true
},
"node_modules/muggle-string": {
"version": "0.4.1",
@@ -4519,8 +4452,8 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
"devOptional": true,
"license": "MIT"
"license": "MIT",
"optional": true
},
"node_modules/natural-compare-lite": {
"version": "1.4.0",
@@ -4696,8 +4629,8 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"devOptional": true,
"license": "ISC",
"optional": true,
"dependencies": {
"wrappy": "1"
}
@@ -4706,8 +4639,8 @@
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
"integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
"devOptional": true,
"license": "MIT",
"optional": true,
"dependencies": {
"deep-is": "^0.1.3",
"fast-levenshtein": "^2.0.6",
@@ -4724,8 +4657,8 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
"integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
"devOptional": true,
"license": "MIT",
"optional": true,
"dependencies": {
"yocto-queue": "^0.1.0"
},
@@ -4740,8 +4673,8 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
"integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
"devOptional": true,
"license": "MIT",
"optional": true,
"dependencies": {
"p-limit": "^3.0.2"
},
@@ -4762,8 +4695,8 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
"devOptional": true,
"license": "MIT",
"optional": true,
"dependencies": {
"callsites": "^3.0.0"
},
@@ -4782,8 +4715,8 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"devOptional": true,
"license": "MIT",
"optional": true,
"engines": {
"node": ">=8"
}
@@ -4792,8 +4725,8 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
"devOptional": true,
"license": "MIT",
"optional": true,
"engines": {
"node": ">=0.10.0"
}
@@ -5044,47 +4977,18 @@
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
"devOptional": true,
"license": "MIT",
"optional": true,
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/prettier": {
"version": "3.4.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz",
"integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==",
"dev": true,
"license": "MIT",
"bin": {
"prettier": "bin/prettier.cjs"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/prettier-linter-helpers": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
"integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
"dev": true,
"license": "MIT",
"dependencies": {
"fast-diff": "^1.1.2"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
"devOptional": true,
"license": "MIT",
"optional": true,
"engines": {
"node": ">=6"
}
@@ -5205,8 +5109,8 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
"devOptional": true,
"license": "MIT",
"optional": true,
"engines": {
"node": ">=4"
}
@@ -5226,8 +5130,8 @@
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"deprecated": "Rimraf versions prior to v4 are no longer supported",
"devOptional": true,
"license": "ISC",
"optional": true,
"dependencies": {
"glob": "^7.1.3"
},
@@ -5638,8 +5542,8 @@
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
"devOptional": true,
"license": "MIT",
"optional": true,
"engines": {
"node": ">=8"
},
@@ -5717,8 +5621,8 @@
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"devOptional": true,
"license": "MIT",
"optional": true,
"dependencies": {
"has-flag": "^4.0.0"
},
@@ -5738,30 +5642,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/synckit": {
"version": "0.9.2",
"resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz",
"integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@pkgr/core": "^0.1.0",
"tslib": "^2.6.2"
},
"engines": {
"node": "^14.18.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/unts"
}
},
"node_modules/synckit/node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"dev": true,
"license": "0BSD"
},
"node_modules/tailwindcss": {
"version": "3.4.15",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.15.tgz",
@@ -5803,8 +5683,8 @@
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
"devOptional": true,
"license": "MIT"
"license": "MIT",
"optional": true
},
"node_modules/thenify": {
"version": "3.3.1",
@@ -5894,8 +5774,8 @@
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
"integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
"devOptional": true,
"license": "MIT",
"optional": true,
"dependencies": {
"prelude-ls": "^1.2.1"
},
@@ -6065,8 +5945,8 @@
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"devOptional": true,
"license": "BSD-2-Clause",
"optional": true,
"dependencies": {
"punycode": "^2.1.0"
}
@@ -6371,8 +6251,8 @@
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
"integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
"devOptional": true,
"license": "MIT",
"optional": true,
"engines": {
"node": ">=0.10.0"
}
@@ -6475,8 +6355,8 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"devOptional": true,
"license": "ISC"
"license": "ISC",
"optional": true
},
"node_modules/xml-name-validator": {
"version": "4.0.0",
@@ -6504,8 +6384,8 @@
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
"devOptional": true,
"license": "MIT",
"optional": true,
"engines": {
"node": ">=10"
},

View File

@@ -1,10 +1,11 @@
{
"name": "awakened-poe2-trade2",
"version": "0.0.1",
"name": "exiled-exchange-2",
"version": "0.0.0",
"private": true,
"scripts": {
"dev": "vite",
"lint": "eslint --ext .ts,.vue src",
"lint-fix": "eslint --ext .ts,.vue src --fix",
"build": "vue-tsc --noEmit && vite build",
"make-index-files": "node src/assets/make-index-files.mjs"
},
@@ -34,10 +35,7 @@
"@types/object-hash": "^3.0.0",
"@vitejs/plugin-vue": "^4.0.0",
"autoprefixer": "^10.0.2",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.2.1",
"postcss": "^8.2.14",
"prettier": "3.4.2",
"typescript": "5.6.x",
"vite": "^5.0.0",
"vue-tsc": "^2.0.0"

View File

@@ -269,7 +269,7 @@
"stack": "Stack"
},
"settings": {
"title": "Settings - Awakened PoE2 Trade2",
"title": "Settings - Exiled Exchange 2",
"language": "Language",
"private_league": "or Private League",
"account_name": "Account name",

View File

@@ -266,7 +266,7 @@
"stack": "스택"
},
"settings": {
"title": "세팅 - Awakened PoE2 Trade2",
"title": "세팅 - Exiled Exchange 2",
"language": "언어",
"private_league": "개인리그",
"account_name": "계정명",

View File

@@ -282,7 +282,7 @@
"stack": "Стак"
},
"settings": {
"title": "Настройки - Awakened PoE2 Trade2",
"title": "Настройки - Exiled Exchange 2",
"language": "Язык",
"private_league": "или Приватная лига",
"account_name": "Имя учетной записи",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 353 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -299,8 +299,8 @@ function parseNamePlate (section: string[]) {
const item: ParserState = {
rarity: undefined,
category: undefined,
name: name,
baseType: baseType,
name,
baseType,
isUnidentified: false,
isCorrupted: false,
newMods: [],

View File

@@ -57,41 +57,41 @@ export const WEAPON_ONE_HANDED_MELEE = new Set([
ItemCategory.Claw,
ItemCategory.Dagger,
ItemCategory.RuneDagger,
ItemCategory.Sceptre,
]);
ItemCategory.Sceptre
])
export const WEAPON_ONE_HANDED = new Set([
ItemCategory.Wand,
...WEAPON_ONE_HANDED_MELEE,
]);
...WEAPON_ONE_HANDED_MELEE
])
export const WEAPONE_TWO_HANDED_MELEE = new Set([
ItemCategory.TwoHandedAxe,
ItemCategory.TwoHandedMace,
ItemCategory.TwoHandedSword,
ItemCategory.Staff,
ItemCategory.Warstaff,
]);
ItemCategory.Warstaff
])
export const WEAPON = new Set([
ItemCategory.FishingRod,
ItemCategory.Bow,
...WEAPON_ONE_HANDED,
...WEAPONE_TWO_HANDED_MELEE,
]);
...WEAPONE_TWO_HANDED_MELEE
])
export const ARMOUR = new Set([
ItemCategory.BodyArmour,
ItemCategory.Boots,
ItemCategory.Gloves,
ItemCategory.Helmet,
ItemCategory.Shield,
]);
ItemCategory.Shield
])
export const ACCESSORY = new Set([
ItemCategory.Amulet,
ItemCategory.Belt,
ItemCategory.Ring,
ItemCategory.Trinket,
ItemCategory.Trinket
// ItemCategory.Quiver
]);
])

View File

@@ -109,7 +109,7 @@ export function translateStatWithRoll (
calc.sources.some(s => s.stat.stat.ref === calc.stat.ref && s.stat.roll!.dp)
: undefined
return { string: translation.string, negate: translation.negate || false, dp: dp }
return { string: translation.string, negate: translation.negate || false, dp }
}
export enum ModifierType {

View File

@@ -1,128 +1,128 @@
import { reactive as deepReactive, shallowRef, toRaw } from 'vue';
import isDeepEqual from 'fast-deep-equal';
import { Host } from '@/web/background/IPC';
import { HostConfig, ShortcutAction } from '@ipc/types';
import type * as widget from './overlay/widgets';
import type { StashSearchWidget } from './stash-search/widget';
import type { ItemCheckWidget } from './item-check/widget';
import type { ItemSearchWidget } from './item-search/widget';
import { reactive as deepReactive, shallowRef, toRaw } from 'vue'
import isDeepEqual from 'fast-deep-equal'
import { Host } from '@/web/background/IPC'
import { HostConfig, ShortcutAction } from '@ipc/types'
import type * as widget from './overlay/widgets'
import type { StashSearchWidget } from './stash-search/widget'
import type { ItemCheckWidget } from './item-check/widget'
import type { ItemSearchWidget } from './item-search/widget'
const _config = shallowRef<Config | null>(null);
let _lastSavedConfig: Config | null = null;
const _config = shallowRef<Config | null>(null)
let _lastSavedConfig: Config | null = null
export function AppConfig(): Config;
export function AppConfig<T extends widget.Widget>(type: string): T | undefined;
export function AppConfig (): Config
export function AppConfig<T extends widget.Widget> (type: string): T | undefined
export function AppConfig (type?: string) {
if (!type) {
return _config.value!;
return _config.value!
} else {
return _config.value!.widgets.find((w) => w.wmType === type);
return _config.value!.widgets.find((w) => w.wmType === type)
}
}
export function updateConfig (updates: Config) {
_config.value = deepReactive(JSON.parse(JSON.stringify(updates)));
document.documentElement.style.fontSize = `${_config.value!.fontSize}px`;
_config.value = deepReactive(JSON.parse(JSON.stringify(updates)))
document.documentElement.style.fontSize = `${_config.value!.fontSize}px`
}
export function saveConfig (opts?: { isTemporary: boolean }) {
const rawConfig = toRaw(_config.value!);
const rawConfig = toRaw(_config.value!)
if (
rawConfig.widgets.some(
(w) => w.wmZorder === 'exclusive' && w.wmWants === 'show'
)
) {
return;
return
}
if (!isDeepEqual(rawConfig, _lastSavedConfig)) {
_lastSavedConfig = JSON.parse(JSON.stringify(rawConfig));
_lastSavedConfig = JSON.parse(JSON.stringify(rawConfig))
Host.sendEvent({
name: 'CLIENT->MAIN::save-config',
payload: {
contents: JSON.stringify(AppConfig()),
isTemporary: opts?.isTemporary ?? false,
},
});
isTemporary: opts?.isTemporary ?? false
}
})
}
}
export function pushHostConfig () {
Host.sendEvent({
name: 'CLIENT->MAIN::update-host-config',
payload: getConfigForHost(),
});
payload: getConfigForHost()
})
}
export async function initConfig () {
Host.onEvent('MAIN->CLIENT::config-changed', (e) => {
_lastSavedConfig = JSON.parse(e.contents); // should be a deep copy
updateConfig(JSON.parse(e.contents));
});
_lastSavedConfig = JSON.parse(e.contents) // should be a deep copy
updateConfig(JSON.parse(e.contents))
})
const contents = await Host.getConfig();
const contents = await Host.getConfig()
if (!contents) {
updateConfig(defaultConfig());
return;
updateConfig(defaultConfig())
return
}
let config: Config;
let config: Config
try {
config = JSON.parse(contents);
config = JSON.parse(contents)
} catch {
updateConfig(defaultConfig());
saveConfig({ isTemporary: true });
return;
updateConfig(defaultConfig())
saveConfig({ isTemporary: true })
return
// TODO
// dialog.showErrorBox(
// 'Awakened PoE2 Trade2 - Incompatible configuration',
// 'Exiled Exchange 2 - Incompatible configuration',
// // ----------------------
// 'You are trying to use an older version of Awakened PoE2 Trade2 with a newer incompatible configuration file.\n' +
// 'You are trying to use an older version of Exiled Exchange 2 with a newer incompatible configuration file.\n' +
// 'You need to install the latest version to continue using it.'
// )
}
updateConfig(upgradeConfig(config));
updateConfig(upgradeConfig(config))
}
export function poeWebApi () {
const { language, realm } = AppConfig();
const { language, realm } = AppConfig()
switch (language) {
case 'en':
return 'www.pathofexile.com';
return 'www.pathofexile.com'
case 'ru':
return 'ru.pathofexile.com';
return 'ru.pathofexile.com'
case 'cmn-Hant':
return realm === 'pc-garena' ? 'pathofexile.tw' : 'www.pathofexile.com';
return realm === 'pc-garena' ? 'pathofexile.tw' : 'www.pathofexile.com'
case 'ko':
return 'poe.game.daum.net';
return 'poe.game.daum.net'
}
}
export interface Config {
configVersion: number;
leagueId?: string;
overlayKey: string;
overlayBackground: string;
overlayBackgroundClose: boolean;
restoreClipboard: boolean;
configVersion: number
leagueId?: string
overlayKey: string
overlayBackground: string
overlayBackgroundClose: boolean
restoreClipboard: boolean
commands: Array<{
text: string;
hotkey: string | null;
send: boolean;
}>;
clientLog: string | null;
gameConfig: string | null;
windowTitle: string;
logKeys: boolean;
accountName: string;
stashScroll: boolean;
language: 'en' | 'ru' | 'cmn-Hant' | 'ko';
realm: 'pc-ggg' | 'pc-garena';
widgets: widget.Widget[];
fontSize: number;
showAttachNotification: boolean;
text: string
hotkey: string | null
send: boolean
}>
clientLog: string | null
gameConfig: string | null
windowTitle: string
logKeys: boolean
accountName: string
stashScroll: boolean
language: 'en' | 'ru' | 'cmn-Hant' | 'ko'
realm: 'pc-ggg' | 'pc-garena'
widgets: widget.Widget[]
fontSize: number
showAttachNotification: boolean
}
export const defaultConfig = (): Config => ({
@@ -136,33 +136,33 @@ export const defaultConfig = (): Config => ({
{
text: '/hideout',
hotkey: 'F5',
send: true,
send: true
},
{
text: '/exit',
hotkey: 'F9',
send: true,
send: true
},
{
text: '@last ty',
hotkey: null,
send: true,
send: true
},
{
text: '/invite @last',
hotkey: null,
send: true,
send: true
},
{
text: '/tradewith @last',
hotkey: null,
send: true,
send: true
},
{
text: '/hideout @last',
hotkey: null,
send: true,
},
send: true
}
],
clientLog: null,
gameConfig: null,
@@ -185,9 +185,9 @@ export const defaultConfig = (): Config => ({
anchor: {
pos: 'tl',
x: 5,
y: 5,
y: 5
},
alwaysShow: false,
alwaysShow: false
} as widget.WidgetMenu,
{
wmId: 2,
@@ -210,7 +210,7 @@ export const defaultConfig = (): Config => ({
searchStatRange: 10,
showCursor: true,
requestPricePrediction: false,
rememberCurrency: false,
rememberCurrency: false
} as widget.PriceCheckWidget,
{
wmId: 3,
@@ -230,22 +230,22 @@ export const defaultConfig = (): Config => ({
selectedStats: [
{
matcher: '#% maximum Player Resistances',
decision: 'w--',
decision: 'w--'
},
{
matcher: 'Monsters reflect #% of Physical Damage',
decision: 'd--',
decision: 'd--'
},
{
matcher: 'Monsters reflect #% of Elemental Damage',
decision: 'd--',
decision: 'd--'
},
{
matcher: 'Area contains two Unique Bosses',
decision: 'g--',
},
],
},
decision: 'g--'
}
]
}
} as ItemCheckWidget,
{
wmId: 4,
@@ -254,7 +254,7 @@ export const defaultConfig = (): Config => ({
wmWants: 'hide',
wmZorder: 4,
wmFlags: ['hide-on-focus', 'skip-menu'],
toggleKey: null,
toggleKey: null
} as widget.DelveGridWidget,
{
wmId: 5,
@@ -262,7 +262,7 @@ export const defaultConfig = (): Config => ({
wmTitle: '',
wmWants: 'hide',
wmZorder: 'exclusive',
wmFlags: ['invisible-on-blur', 'ignore-ui-visibility'],
wmFlags: ['invisible-on-blur', 'ignore-ui-visibility']
},
{
wmId: 6,
@@ -274,8 +274,8 @@ export const defaultConfig = (): Config => ({
anchor: {
pos: 'tl',
x: 10,
y: 20,
},
y: 20
}
} as ItemSearchWidget,
// --- DEFAULT ---
{
@@ -288,14 +288,14 @@ export const defaultConfig = (): Config => ({
anchor: {
pos: 'tl',
x: 35,
y: 46,
y: 46
},
entries: [
{ id: 1, name: '', text: '"Pack Size: +3"', hotkey: null },
{ id: 2, name: '', text: 'Reflect', hotkey: null },
{ id: 3, name: '', text: '"Cannot Leech Life"', hotkey: null },
{ id: 4, name: '', text: '"Cannot Leech Mana"', hotkey: null },
],
{ id: 4, name: '', text: '"Cannot Leech Mana"', hotkey: null }
]
} as StashSearchWidget,
{
wmId: 102,
@@ -307,7 +307,7 @@ export const defaultConfig = (): Config => ({
anchor: {
pos: 'tl',
x: 34,
y: 56,
y: 56
},
entries: [
{ id: 1, name: '', text: 'Currency', hotkey: null },
@@ -318,10 +318,10 @@ export const defaultConfig = (): Config => ({
id: 5,
name: '',
text: '"Map Device" "Rarity: Normal"',
hotkey: null,
hotkey: null
},
{ id: 6, name: '', text: 'Tane Laboratory', hotkey: null },
],
{ id: 6, name: '', text: 'Tane Laboratory', hotkey: null }
]
} as StashSearchWidget,
{
wmId: 103,
@@ -333,90 +333,90 @@ export const defaultConfig = (): Config => ({
anchor: {
pos: 'tc',
x: 50,
y: 10,
y: 10
},
images: [{ id: 1, url: 'syndicate.jpg' }],
} as widget.ImageStripWidget,
],
});
images: [{ id: 1, url: 'syndicate.jpg' }]
} as widget.ImageStripWidget
]
})
function upgradeConfig (_config: Config): Config {
const config = _config as Omit<Config, 'widgets'> & {
widgets: Array<Record<string, any>>;
};
widgets: Array<Record<string, any>>
}
if (config.configVersion < 3) {
config.widgets.push({
...defaultConfig().widgets.find((w) => w.wmType === 'image-strip')!,
wmId: Math.max(0, ...config.widgets.map((_) => _.wmId)) + 1,
wmZorder: null,
});
wmZorder: null
})
config.widgets.push({
...defaultConfig().widgets.find((w) => w.wmType === 'delve-grid')!,
wmId: Math.max(0, ...config.widgets.map((_) => _.wmId)) + 1,
wmZorder: null,
});
wmZorder: null
})
config.widgets.find((w) => w.wmType === 'menu')!.alwaysShow = false;
config.widgets.find((w) => w.wmType === 'menu')!.alwaysShow = false
config.configVersion = 3;
config.configVersion = 3
}
if (config.configVersion < 4) {
config.widgets.find(
(w) => w.wmType === 'price-check'
)!.chaosPriceThreshold = 0.05;
)!.chaosPriceThreshold = 0.05
const mapCheck = config.widgets.find((w) => w.wmType === 'map-check')!;
(mapCheck as any).selectedStats.forEach((e: any) => {
e.matcher = e.matchRef;
e.matchRef = undefined;
});
e.matcher = e.matchRef
e.matchRef = undefined
})
{
const widgets = config.widgets.filter((w) => w.wmType === 'image-strip')!;
const widgets = config.widgets.filter((w) => w.wmType === 'image-strip')!
widgets.forEach((imgStrip: any) => {
imgStrip.images.forEach((e: any, idx: number) => {
e.id = idx;
});
});
e.id = idx
})
})
}
config.configVersion = 4;
config.configVersion = 4
}
if (config.configVersion < 5) {
config.commands.forEach((cmd) => {
cmd.send = true;
});
cmd.send = true
})
config.configVersion = 5;
config.configVersion = 5
}
if (config.configVersion < 6) {
config.widgets.find((w) => w.wmType === 'price-check')!.showRateLimitState =
(config as any).logLevel === 'debug';
(config as any).logLevel === 'debug'
config.widgets.find((w) => w.wmType === 'price-check')!.apiLatencySeconds =
2;
2
config.configVersion = 6;
config.configVersion = 6
}
if (config.configVersion < 7) {
const mapCheck = config.widgets.find((w) => w.wmType === 'map-check')!;
mapCheck.wmType = 'item-check';
mapCheck.maps = { selectedStats: mapCheck.selectedStats };
const mapCheck = config.widgets.find((w) => w.wmType === 'map-check')!
mapCheck.wmType = 'item-check'
mapCheck.maps = { selectedStats: mapCheck.selectedStats }
mapCheck.selectedStats = undefined;
(config as any).itemCheckKey = (config as any).mapCheckKey || null;
(config as any).mapCheckKey = undefined;
(config as any).mapCheckKey = undefined
config.configVersion = 7;
config.configVersion = 7
}
if (config.configVersion < 8) {
const itemCheck = config.widgets.find((w) => w.wmType === 'item-check')!;
(itemCheck as ItemCheckWidget).maps.showNewStats = false;
(itemCheck as ItemCheckWidget).maps.showNewStats = false
itemCheck.maps.selectedStats = (
itemCheck as ItemCheckWidget
).maps.selectedStats.map((entry) => ({
@@ -427,120 +427,120 @@ function upgradeConfig(_config: Config): Config {
? 'warning'
: (entry as any).valueDesirable
? 'desirable'
: 'seen',
}));
: 'seen'
}))
config.configVersion = 8;
config.configVersion = 8
}
if (config.configVersion < 9) {
config.widgets.find((w) => w.wmType === 'price-check')!.collapseListings =
'api';
'api'
config.widgets.find((w) => w.wmType === 'price-check')!.smartInitialSearch =
true;
true
config.widgets.find(
(w) => w.wmType === 'price-check'
)!.lockedInitialSearch = true;
)!.lockedInitialSearch = true
config.widgets.find(
(w) => w.wmType === 'price-check'
)!.activateStockFilter = false;
)!.activateStockFilter = false
config.configVersion = 9;
config.configVersion = 9
}
if (config.configVersion < 10) {
config.widgets.push({
...defaultConfig().widgets.find((w) => w.wmType === 'settings')!,
wmId: Math.max(0, ...config.widgets.map((_) => _.wmId)) + 1,
});
wmId: Math.max(0, ...config.widgets.map((_) => _.wmId)) + 1
})
const priceCheck = config.widgets.find((w) => w.wmType === 'price-check')!;
priceCheck.hotkey = (config as any).priceCheckKey;
priceCheck.hotkeyHold = (config as any).priceCheckKeyHold;
priceCheck.hotkeyLocked = (config as any).priceCheckLocked;
priceCheck.showSeller = (config as any).showSeller;
priceCheck.searchStatRange = (config as any).searchStatRange;
priceCheck.showCursor = (config as any).priceCheckShowCursor;
const priceCheck = config.widgets.find((w) => w.wmType === 'price-check')!
priceCheck.hotkey = (config as any).priceCheckKey
priceCheck.hotkeyHold = (config as any).priceCheckKeyHold
priceCheck.hotkeyLocked = (config as any).priceCheckLocked
priceCheck.showSeller = (config as any).showSeller
priceCheck.searchStatRange = (config as any).searchStatRange
priceCheck.showCursor = (config as any).priceCheckShowCursor
if (priceCheck.chaosPriceThreshold === 0.05) {
priceCheck.chaosPriceThreshold = 0;
priceCheck.chaosPriceThreshold = 0
}
config.configVersion = 10;
config.configVersion = 10
}
if (config.configVersion < 11) {
config.widgets.find(
(w) => w.wmType === 'price-check'
)!.requestPricePrediction = false;
)!.requestPricePrediction = false
config.configVersion = 11;
config.configVersion = 11
}
if (config.configVersion < 12) {
const afterSettings = config.widgets.findIndex(
(w) => w.wmType === 'settings'
);
)
config.widgets.splice(afterSettings + 1, 0, {
...defaultConfig().widgets.find((w) => w.wmType === 'item-search')!,
wmWants: 'show',
wmId: Math.max(0, ...config.widgets.map((_) => _.wmId)) + 1,
});
wmId: Math.max(0, ...config.widgets.map((_) => _.wmId)) + 1
})
config.realm = 'pc-ggg';
config.realm = 'pc-ggg'
if (config.language === ('zh_TW' as string)) {
config.language = 'cmn-Hant';
config.language = 'cmn-Hant'
}
config.configVersion = 12;
config.configVersion = 12
}
if (config.configVersion < 13) {
config.showAttachNotification = true;
config.showAttachNotification = true
config.configVersion = 13;
config.configVersion = 13
}
if (config.configVersion < 14) {
const imgWidgets = config.widgets.filter(
(w) => w.wmType === 'image-strip'
) as widget.ImageStripWidget[];
) as widget.ImageStripWidget[]
imgWidgets.forEach((imgStrip) => {
imgStrip.images.forEach((e) => {
e.url = e.url.startsWith('app-file://')
? e.url.slice('app-file://'.length)
: e.url;
});
});
: e.url
})
})
const itemCheck = config.widgets.find(
(w) => w.wmType === 'item-check'
) as ItemCheckWidget;
itemCheck.wikiKey = (config as any).wikiKey;
itemCheck.poedbKey = null;
itemCheck.craftOfExileKey = (config as any).craftOfExileKey;
itemCheck.stashSearchKey = null;
) as ItemCheckWidget
itemCheck.wikiKey = (config as any).wikiKey
itemCheck.poedbKey = null
itemCheck.craftOfExileKey = (config as any).craftOfExileKey
itemCheck.stashSearchKey = null
config.configVersion = 14;
config.configVersion = 14
}
if (config.configVersion < 15) {
const priceCheck = config.widgets.find(
(w) => w.wmType === 'price-check'
) as widget.PriceCheckWidget;
priceCheck.builtinBrowser = false;
) as widget.PriceCheckWidget
priceCheck.builtinBrowser = false
const itemSearch = config.widgets.find(
(w) => w.wmType === 'item-search'
) as ItemSearchWidget;
itemSearch.ocrGemsKey = null;
) as ItemSearchWidget
itemSearch.ocrGemsKey = null
const itemCheck = config.widgets.find(
(w) => w.wmType === 'item-check'
) as ItemCheckWidget;
itemCheck.maps.profile = 1;
) as ItemCheckWidget
itemCheck.maps.profile = 1
for (const stat of itemCheck.maps.selectedStats) {
const p1decision =
stat.decision === 'danger'
@@ -549,114 +549,114 @@ function upgradeConfig(_config: Config): Config {
? 'w'
: stat.decision === 'desirable'
? 'g'
: 's';
: 's'
stat.decision = `${p1decision}--`;
stat.decision = `${p1decision}--`
}
config.configVersion = 15;
config.configVersion = 15
}
if (config.configVersion < 16) {
const delve = config.widgets.find(
(w) => w.wmType === 'delve-grid'
) as widget.DelveGridWidget;
delve.toggleKey = (config as any).delveGridKey;
) as widget.DelveGridWidget
delve.toggleKey = (config as any).delveGridKey
const itemCheck = config.widgets.find(
(w) => w.wmType === 'item-check'
) as ItemCheckWidget;
itemCheck.hotkey = (config as any).itemCheckKey;
) as ItemCheckWidget
itemCheck.hotkey = (config as any).itemCheckKey
if (itemCheck.maps.profile === undefined) {
itemCheck.maps.profile = 1;
itemCheck.maps.selectedStats = [];
itemCheck.maps.profile = 1
itemCheck.maps.selectedStats = []
}
config.configVersion = 16;
config.configVersion = 16
}
if (config.logKeys === undefined) {
config.logKeys = false;
config.logKeys = false
}
const priceCheck = config.widgets.find(
(w) => w.wmType === 'price-check'
) as widget.PriceCheckWidget;
) as widget.PriceCheckWidget
if (priceCheck.rememberCurrency === undefined) {
priceCheck.rememberCurrency = false;
priceCheck.rememberCurrency = false
}
for (const widget of config.widgets) {
if (widget.wmType === 'stash-search') {
(widget as StashSearchWidget).enableHotkeys ??= true;
(widget as StashSearchWidget).enableHotkeys ??= true
}
}
return config as unknown as Config;
return config as unknown as Config
}
function getConfigForHost (): HostConfig {
const actions: ShortcutAction[] = [];
const actions: ShortcutAction[] = []
const config = AppConfig();
const priceCheck = AppConfig('price-check') as widget.PriceCheckWidget;
const config = AppConfig()
const priceCheck = AppConfig('price-check') as widget.PriceCheckWidget
if (priceCheck.hotkey) {
actions.push({
shortcut: `${priceCheck.hotkeyHold} + ${priceCheck.hotkey}`,
action: { type: 'copy-item', target: 'price-check', focusOverlay: false },
keepModKeys: true,
});
keepModKeys: true
})
}
if (priceCheck.hotkeyLocked) {
actions.push({
shortcut: priceCheck.hotkeyLocked,
action: { type: 'copy-item', target: 'price-check', focusOverlay: true },
});
action: { type: 'copy-item', target: 'price-check', focusOverlay: true }
})
}
actions.push({
shortcut: config.overlayKey,
action: { type: 'toggle-overlay' },
keepModKeys: true,
});
const itemCheck = AppConfig('item-check') as ItemCheckWidget;
keepModKeys: true
})
const itemCheck = AppConfig('item-check') as ItemCheckWidget
if (itemCheck.wikiKey) {
actions.push({
shortcut: itemCheck.wikiKey,
action: { type: 'copy-item', target: 'open-wiki' },
});
action: { type: 'copy-item', target: 'open-wiki' }
})
}
if (itemCheck.craftOfExileKey) {
actions.push({
shortcut: itemCheck.craftOfExileKey,
action: { type: 'copy-item', target: 'open-craft-of-exile' },
});
action: { type: 'copy-item', target: 'open-craft-of-exile' }
})
}
if (itemCheck.poedbKey) {
actions.push({
shortcut: itemCheck.poedbKey,
action: { type: 'copy-item', target: 'open-poedb' },
});
action: { type: 'copy-item', target: 'open-poedb' }
})
}
if (itemCheck.stashSearchKey) {
actions.push({
shortcut: itemCheck.stashSearchKey,
action: { type: 'copy-item', target: 'search-similar' },
});
action: { type: 'copy-item', target: 'search-similar' }
})
}
if (itemCheck.hotkey) {
actions.push({
shortcut: itemCheck.hotkey,
action: { type: 'copy-item', target: 'item-check', focusOverlay: true },
});
action: { type: 'copy-item', target: 'item-check', focusOverlay: true }
})
}
const delveGrid = AppConfig('delve-grid') as widget.DelveGridWidget;
const delveGrid = AppConfig('delve-grid') as widget.DelveGridWidget
if (delveGrid.toggleKey) {
actions.push({
shortcut: delveGrid.toggleKey,
action: { type: 'trigger-event', target: 'delve-grid' },
keepModKeys: true,
});
keepModKeys: true
})
}
for (const command of config.commands) {
if (command.hotkey) {
@@ -665,35 +665,35 @@ function getConfigForHost(): HostConfig {
action: {
type: 'paste-in-chat',
text: command.text,
send: command.send,
},
});
send: command.send
}
})
}
}
for (const widget of config.widgets) {
if (widget.wmType === 'stash-search') {
const stashSearch = widget as StashSearchWidget;
if (!stashSearch.enableHotkeys) continue;
const stashSearch = widget as StashSearchWidget
if (!stashSearch.enableHotkeys) continue
for (const entry of stashSearch.entries) {
if (entry.hotkey) {
actions.push({
shortcut: entry.hotkey,
action: { type: 'stash-search', text: entry.text },
});
action: { type: 'stash-search', text: entry.text }
})
}
}
} else if (widget.wmType === 'timer') {
const stopwatch = widget as widget.StopwatchWidget;
const stopwatch = widget as widget.StopwatchWidget
if (stopwatch.toggleKey) {
actions.push({
shortcut: stopwatch.toggleKey,
keepModKeys: true,
action: {
type: 'trigger-event',
target: `stopwatch-start-stop:${widget.wmId}`,
},
});
target: `stopwatch-start-stop:${widget.wmId}`
}
})
}
if (stopwatch.resetKey) {
actions.push({
@@ -701,18 +701,18 @@ function getConfigForHost(): HostConfig {
keepModKeys: true,
action: {
type: 'trigger-event',
target: `stopwatch-reset:${widget.wmId}`,
},
});
target: `stopwatch-reset:${widget.wmId}`
}
})
}
} else if (widget.wmType === 'item-search') {
const itemSearch = widget as ItemSearchWidget;
const itemSearch = widget as ItemSearchWidget
if (itemSearch.ocrGemsKey) {
actions.push({
shortcut: itemSearch.ocrGemsKey,
keepModKeys: true,
action: { type: 'ocr-text', target: 'heist-gems' },
});
action: { type: 'ocr-text', target: 'heist-gems' }
})
}
}
}
@@ -726,6 +726,6 @@ function getConfigForHost(): HostConfig {
overlayKey: config.overlayKey,
logKeys: config.logKeys,
windowTitle: config.windowTitle,
language: config.language,
};
language: config.language
}
}

View File

@@ -1,72 +1,71 @@
import { computed, shallowRef, readonly } from 'vue';
import { createGlobalState } from '@vueuse/core';
import { AppConfig, poeWebApi } from '@/web/Config';
import { Host } from './IPC';
import { computed, shallowRef, readonly } from 'vue'
import { createGlobalState } from '@vueuse/core'
import { AppConfig } from '@/web/Config'
// pc-ggg, pc-garena
// const PERMANENT_SC = ['Standard', '標準模式']
const PERMANENT_HC = ['Hardcore', '專家模式'];
const PERMANENT_HC = ['Hardcore', '專家模式']
interface ApiLeague {
id: string;
event?: boolean;
rules: Array<{ id: string }>;
id: string
event?: boolean
rules: Array<{ id: string }>
}
interface League {
id: string
isPopular: boolean
}
export const useLeagues = createGlobalState(() => {
const isLoading = shallowRef(false)
const error = shallowRef<string | null>(null)
const tradeLeagues = shallowRef<League[]>([])
const DEFAULT_POE2_LEAGUES: ApiLeague[] = [
{ id: 'Standard', rules: [] },
{
id: 'Hardcore',
rules: [
{
id: 'Hardcore',
},
],
},
];
interface League {
id: string;
isPopular: boolean;
id: 'Hardcore'
}
export const useLeagues = createGlobalState(() => {
const isLoading = shallowRef(false);
const error = shallowRef<string | null>(null);
const tradeLeagues = shallowRef<League[]>([]);
]
}
]
const selectedId = computed<string | undefined>({
get () {
return tradeLeagues.value.length ? AppConfig().leagueId : undefined;
return tradeLeagues.value.length ? AppConfig().leagueId : undefined
},
set (id) {
AppConfig().leagueId = id;
},
});
AppConfig().leagueId = id
}
})
const selected = computed(() => {
const { leagueId } = AppConfig();
if (!tradeLeagues.value || !leagueId) return undefined;
const listed = tradeLeagues.value.find((league) => league.id === leagueId);
const { leagueId } = AppConfig()
if (!tradeLeagues.value || !leagueId) return undefined
const listed = tradeLeagues.value.find((league) => league.id === leagueId)
return {
id: leagueId,
realm: AppConfig().realm,
isPopular: !isPrivateLeague(leagueId) && Boolean(listed?.isPopular),
};
});
isPopular: !isPrivateLeague(leagueId) && Boolean(listed?.isPopular)
}
})
async function load () {
isLoading.value = true;
error.value = null;
isLoading.value = true
error.value = null
try {
const response = await Host.proxy(
`${poeWebApi()}/api/leagues?type=main&realm=pc`
);
if (!response.ok)
throw new Error(JSON.stringify(Object.fromEntries(response.headers)));
// const response = await Host.proxy(
// `${poeWebApi()}/api/leagues?type=main&realm=pc`
// );
// if (!response.ok)
// throw new Error(JSON.stringify(Object.fromEntries(response.headers)));
// const leagues: ApiLeague[] = await response.json();
const leagues: ApiLeague[] = DEFAULT_POE2_LEAGUES;
const leagues: ApiLeague[] = DEFAULT_POE2_LEAGUES
tradeLeagues.value = leagues
.filter(
(league) =>
@@ -78,25 +77,25 @@ export const useLeagues = createGlobalState(() => {
)
)
.map((league) => {
return { id: league.id, isPopular: true };
});
return { id: league.id, isPopular: true }
})
const leagueIsAlive = tradeLeagues.value.some(
(league) => league.id === selectedId.value
);
)
if (!leagueIsAlive && !isPrivateLeague(selectedId.value ?? '')) {
if (tradeLeagues.value.length > 1) {
const TMP_CHALLENGE = 1;
selectedId.value = tradeLeagues.value[TMP_CHALLENGE].id;
const TMP_CHALLENGE = 1
selectedId.value = tradeLeagues.value[TMP_CHALLENGE].id
} else {
const STANDARD = 0;
selectedId.value = tradeLeagues.value[STANDARD].id;
const STANDARD = 0
selectedId.value = tradeLeagues.value[STANDARD].id
}
}
} catch (e) {
error.value = (e as Error).message;
error.value = (e as Error).message
} finally {
isLoading.value = false;
isLoading.value = false
}
}
@@ -106,13 +105,13 @@ export const useLeagues = createGlobalState(() => {
selectedId,
selected,
list: readonly(tradeLeagues),
load,
};
});
load
}
})
function isPrivateLeague (id: string) {
if (id.includes('Ruthless')) {
return true;
return true
}
return /\(PL\d+\)$/.test(id);
return /\(PL\d+\)$/.test(id)
}

View File

@@ -19,7 +19,7 @@ import type { ItemCheckWidget } from './widget.js'
import Widget from '../overlay/Widget.vue'
import MapCheck from '../map-check/MapCheck.vue'
import ItemInfo from './ItemInfo.vue'
import ConversionWarningBanner from "../conversion-warn-banner/ConversionWarningBanner.vue";
import ConversionWarningBanner from '../conversion-warn-banner/ConversionWarningBanner.vue'
const props = defineProps<{
config: ItemCheckWidget

View File

@@ -1,8 +1,8 @@
import { Host } from '@/web/background/IPC';
import { AppConfig } from '@/web/Config';
import { ParsedItem, parseClipboard } from '@/parser';
import { Host } from '@/web/background/IPC'
import { AppConfig } from '@/web/Config'
import { ParsedItem, parseClipboard } from '@/parser'
const POEDB_LANGS = { en: 'us', ru: 'ru', 'cmn-Hant': 'tw', ko: 'kr' };
const POEDB_LANGS = { 'en': 'us', 'ru': 'ru', 'cmn-Hant': 'tw', 'ko': 'kr' }
export function registerActions () {
Host.onEvent('MAIN->CLIENT::item-text', (e) => {
@@ -11,44 +11,43 @@ export function registerActions() {
'open-wiki',
'open-craft-of-exile',
'open-poedb',
'search-similar',
'search-similar'
].includes(e.target)
)
return;
const parsed = parseClipboard(e.clipboard);
if (!parsed.isOk()) return;
) { return }
const parsed = parseClipboard(e.clipboard)
if (!parsed.isOk()) return
if (e.target === 'open-wiki') {
openWiki(parsed.value);
openWiki(parsed.value)
} else if (e.target === 'open-craft-of-exile') {
openCoE(parsed.value);
openCoE(parsed.value)
} else if (e.target === 'open-poedb') {
openPoedb(parsed.value);
openPoedb(parsed.value)
} else if (e.target === 'search-similar') {
findSimilarItems(parsed.value);
findSimilarItems(parsed.value)
}
});
})
}
export function openWiki (item: ParsedItem) {
window.open(`https://www.poe2wiki.net/wiki/${item.info.refName}`);
window.open(`https://www.poe2wiki.net/wiki/${item.info.refName}`)
}
export function openPoedb (item: ParsedItem) {
window.open(
`https://poe2db.tw/${POEDB_LANGS[AppConfig().language]}/search?q=${item.info.refName}`
);
)
}
export function openCoE (item: ParsedItem) {
const encodedClipboard = encodeURIComponent(item.rawText);
const encodedClipboard = encodeURIComponent(item.rawText)
window.open(
`https://craftofexile.com/?game=poe2&eimport=${encodedClipboard}`
);
)
}
export function findSimilarItems (item: ParsedItem) {
const text = JSON.stringify(item.info.name);
const text = JSON.stringify(item.info.name)
Host.sendEvent({
name: 'CLIENT->MAIN::user-action',
payload: { action: 'stash-search', text },
});
payload: { action: 'stash-search', text }
})
}

View File

@@ -4,7 +4,7 @@
<div :class="$style.widget" v-if="show">
<div :class="$style.box">
<div class="py-2 px-4">
<div class="text-base">Awakened PoE2 Trade2</div>
<div class="text-base">Exiled Exchange 2</div>
<p>{{ t('app_is_ready') }}</p>
</div>
</div>
@@ -25,7 +25,9 @@ const show = shallowRef(false)
Host.onEvent('MAIN->OVERLAY::overlay-attached', () => {
if (!show.value && AppConfig().showAttachNotification) {
show.value = true
setTimeout(() => { show.value = false }, 2500)
setTimeout(() => {
show.value = false
}, 2500)
}
})
</script>
@@ -51,7 +53,7 @@ Host.onEvent('MAIN->OVERLAY::overlay-attached', () => {
.box::before {
position: absolute;
content: '';
background: url('/images/TransferOrb.png') no-repeat top right/contain;
background: url('/images/exa.png') no-repeat top right/contain;
right: 100%;
width: 100%;
height: 100%;

View File

@@ -1,23 +1,52 @@
<template>
<div style="top: 0; left: 0; height: 100%; width: 100%; position: absolute;"
class="flex grow h-full pointer-events-none" :class="{
<div
style="top: 0; left: 0; height: 100%; width: 100%; position: absolute"
class="flex grow h-full pointer-events-none"
:class="{
'flex-row': clickPosition === 'stash',
'flex-row-reverse': clickPosition === 'inventory',
}">
<div v-if="!isBrowserShown" class="layout-column shrink-0" style="width: var(--game-panel);">
</div>
<div id="price-window" class="layout-column shrink-0 text-gray-200 pointer-events-auto" style="width: 28.75rem;">
}"
>
<div
v-if="!isBrowserShown"
class="layout-column shrink-0"
style="width: var(--game-panel)"
></div>
<div
id="price-window"
class="layout-column shrink-0 text-gray-200 pointer-events-auto"
style="width: 28.75rem"
>
<ConversionWarningBanner />
<AppTitleBar @close="closePriceCheck" @click="openLeagueSelection" :title="title">
<ui-popover v-if="stableOrbCost" trigger="click" boundary="#price-window">
<AppTitleBar
@close="closePriceCheck"
@click="openLeagueSelection"
:title="title"
>
<ui-popover
v-if="stableOrbCost"
trigger="click"
boundary="#price-window"
>
<template #target>
<button><i class="fas fa-exchange-alt" /> {{ stableOrbCost }}</button>
<button>
<i class="fas fa-exchange-alt" /> {{ stableOrbCost }}
</button>
</template>
<template #content>
<item-quick-price class="text-base" :price="{ min: stableOrbCost, max: stableOrbCost, currency: 'chaos' }"
item-img="/images/divine.png" />
<item-quick-price
class="text-base"
:price="{
min: stableOrbCost,
max: stableOrbCost,
currency: 'chaos',
}"
item-img="/images/divine.png"
/>
<div v-for="i in 9" :key="i">
<div class="pl-1">{{ i / 10 }} div {{ Math.round(stableOrbCost * i / 10) }} c</div>
<div class="pl-1">
{{ i / 10 }} div {{ Math.round((stableOrbCost * i) / 10) }} c
</div>
</div>
</template>
</ui-popover>
@@ -26,33 +55,61 @@
</AppTitleBar>
<div class="grow layout-column min-h-0 bg-gray-800">
<background-info />
<check-position-circle v-if="showCheckPos" :position="checkPosition" style="z-index: -1;" />
<check-position-circle
v-if="showCheckPos"
:position="checkPosition"
style="z-index: -1"
/>
<template v-if="item?.isErr()">
<ui-error-box class="m-4">
<template #name>{{ t(item.error.name) }}</template>
<p>{{ t(item.error.message) }}</p>
</ui-error-box>
<pre class="bg-gray-900 rounded m-4 overflow-x-hidden p-2">{{ item.error.rawText }}</pre>
<pre class="bg-gray-900 rounded m-4 overflow-x-hidden p-2">{{
item.error.rawText
}}</pre>
</template>
<template v-else-if="item?.isOk()">
<unidentified-resolver :item="item.value" @identify="handleIdentification($event)" />
<checked-item v-if="isLeagueSelected" :item="item.value" :advanced-check="advancedCheck" />
<unidentified-resolver
:item="item.value"
@identify="handleIdentification($event)"
/>
<checked-item
v-if="isLeagueSelected"
:item="item.value"
:advanced-check="advancedCheck"
/>
</template>
<div v-if="isBrowserShown" class="bg-gray-900 px-6 py-2 truncate">
<i18n-t keypath="app.toggle_browser_hint" tag="div">
<span class="bg-gray-400 text-gray-900 rounded px-1">{{ overlayKey }}</span>
<span class="bg-gray-400 text-gray-900 rounded px-1">{{
overlayKey
}}</span>
</i18n-t>
</div>
</div>
</div>
<webview v-if="isBrowserShown" ref="iframeEl" class="pointer-events-auto flex-1" width="100%" height="100%" />
<webview
v-if="isBrowserShown"
ref="iframeEl"
class="pointer-events-auto flex-1"
width="100%"
height="100%"
/>
<div v-else class="layout-column flex-1 min-w-0">
<div class="flex" :class="{
<div
class="flex"
:class="{
'flex-row': clickPosition === 'stash',
'flex-row-reverse': clickPosition === 'inventory'
}">
<related-items v-if="item?.isOk()" class="pointer-events-auto" :item="item.value"
:click-position="clickPosition" />
'flex-row-reverse': clickPosition === 'inventory',
}"
>
<related-items
v-if="item?.isOk()"
class="pointer-events-auto"
:item="item.value"
:click-position="clickPosition"
/>
<rate-limiter-state class="pointer-events-auto" />
</div>
</div>
@@ -79,9 +136,13 @@ import CheckPositionCircle from './CheckPositionCircle.vue'
import AppTitleBar from '@/web/ui/AppTitlebar.vue'
import ItemQuickPrice from '@/web/ui/ItemQuickPrice.vue'
import { PriceCheckWidget, WidgetManager } from '../overlay/interfaces'
import ConversionWarningBanner from "../conversion-warn-banner/ConversionWarningBanner.vue";
import ConversionWarningBanner from '../conversion-warn-banner/ConversionWarningBanner.vue'
type ParseError = { name: string; message: string; rawText: ParsedItem['rawText'] }
type ParseError = {
name: string;
message: string;
rawText: ParsedItem['rawText'];
};
export default defineComponent({
components: {
@@ -122,8 +183,12 @@ export default defineComponent({
if (Host.isElectron && !e.focusOverlay) {
// everything in CSS pixels
const width = 28.75 * AppConfig().fontSize
const screenX = ((e.position.x - window.screenX) > window.innerWidth / 2)
? (window.screenX + window.innerWidth) - wm.poePanelWidth.value - width
const screenX =
e.position.x - window.screenX > window.innerWidth / 2
? window.screenX +
window.innerWidth -
wm.poePanelWidth.value -
width
: window.screenX + wm.poePanelWidth.value
MainProcess.sendEvent({
name: 'OVERLAY->MAIN::track-area',
@@ -146,13 +211,18 @@ export default defineComponent({
checkPosition.value = e.position
advancedCheck.value = e.focusOverlay
item.value = (e.item ? ok(e.item as ParsedItem) : parseClipboard(e.clipboard))
.andThen(item => (
(item.category === ItemCategory.HeistContract && item.rarity !== ItemRarity.Unique) ||
(item.category === ItemCategory.Sentinel && item.rarity !== ItemRarity.Unique))
item.value = (
e.item ? ok(e.item as ParsedItem) : parseClipboard(e.clipboard)
)
.andThen((item) =>
(item.category === ItemCategory.HeistContract &&
item.rarity !== ItemRarity.Unique) ||
(item.category === ItemCategory.Sentinel &&
item.rarity !== ItemRarity.Unique)
? err('item.unknown')
: ok(item))
.mapErr(err => ({
: ok(item)
)
.mapErr((err) => ({
name: `${err}`,
message: `${err}_help`,
rawText: e.clipboard
@@ -171,14 +241,17 @@ export default defineComponent({
wm.hide(props.config.wmId)
})
watch(() => props.config.wmWants, (state) => {
watch(
() => props.config.wmWants,
(state) => {
if (state === 'hide') {
closeBrowser()
}
})
}
)
const leagues = useLeagues()
const title = computed(() => leagues.selectedId.value || 'Awakened PoE2 Trade2')
const title = computed(() => leagues.selectedId.value || 'Exiled Exchange 2')
const stableOrbCost = computed(() => (xchgRate.value) ? Math.round(xchgRate.value) : null)
const isBrowserShown = computed(() => props.config.wmFlags.includes('has-browser'))
const overlayKey = computed(() => AppConfig().overlayKey)

View File

@@ -63,7 +63,7 @@ const stats = computed(() => {
if (!parsed.roll) {
return {
text: parsed.translation.string,
contribution: contribution,
contribution,
contributes: true
}
}

View File

@@ -176,7 +176,7 @@ export function createFilters (
}
filters.searchRelaxed = {
category: item.category,
disabled: disabled
disabled
}
}
}

View File

@@ -177,7 +177,7 @@ export function calculatedStatToFilter (
? FilterTag.Enchant
: FilterTag.Variant,
oils: decodeOils(calc),
sources: sources,
sources,
option: {
value: sources[0].contributes!.value
},
@@ -197,7 +197,7 @@ export function calculatedStatToFilter (
text: translation.string,
tag: (type as unknown) as FilterTag,
oils: decodeOils(calc),
sources: sources,
sources,
roll: undefined,
disabled: true
}
@@ -288,7 +288,7 @@ export function calculatedStatToFilter (
bounds: (item.rarity === ItemRarity.Unique && roll.min !== roll.max && calc.stat.better !== StatBetter.NotComparable)
? filterBounds
: undefined,
dp: dp,
dp,
isNegated: false,
tradeInvert: calc.stat.trade.inverted
}

View File

@@ -335,7 +335,7 @@ export function filterPseudo (ctx: FiltersCreationContext) {
const filter = calculatedStatToFilter({
stat: STAT_BY_REF(rule.pseudo)!,
type: ModifierType.Pseudo,
sources: sources
sources
}, ctx.searchInRange, ctx.item)
filter.disabled = rule.disabled ?? true

View File

@@ -257,7 +257,7 @@ function propToFilter (opts: {
better: StatBetter.PositiveRoll
}
const filter = calculatedStatToFilter({
stat: stat,
stat,
type: ModifierType.Pseudo,
sources: [{
modifier: {
@@ -265,7 +265,7 @@ function propToFilter (opts: {
stats: []
},
stat: {
stat: stat,
stat,
translation: stat.matchers[0],
roll: {
dp: opts.dp ?? false,

View File

@@ -1,31 +1,31 @@
import { ParsedItem } from '@/parser';
import { useLeagues } from '@/web/background/Leagues';
import { Host } from '@/web/background/IPC';
import { Cache } from '../trade/Cache';
import { usePoeninja } from '@/web/background/Prices';
import { ParsedItem } from '@/parser'
import { useLeagues } from '@/web/background/Leagues'
import { Host } from '@/web/background/IPC'
import { Cache } from '../trade/Cache'
import { usePoeninja } from '@/web/background/Prices'
const cache = new Cache();
const cache = new Cache()
interface PoepricesApiResponse {
/* eslint-disable camelcase */ currency: 'chaos' | 'divine' | 'exalt';
error: number;
error_msg: string;
warning_msg: string;
max: number;
min: number;
pred_confidence_score: number;
pred_explanation: Array<[string, number]>;
/* eslint-disable camelcase */ currency: 'chaos' | 'divine' | 'exalt'
error: number
error_msg: string
warning_msg: string
max: number
min: number
pred_confidence_score: number
pred_explanation: Array<[string, number]>
}
export interface RareItemPrice {
max: number;
min: number;
confidence: number;
currency: 'chaos' | 'div';
max: number
min: number
confidence: number
currency: 'chaos' | 'div'
explanation: Array<{
name: string;
contrib: number;
}>;
name: string
contrib: number
}>
}
export async function requestPoeprices (
@@ -34,46 +34,46 @@ export async function requestPoeprices(
const query = querystring({
i: utf8ToBase64(transformItemText(item.rawText)),
l: useLeagues().selectedId.value,
s: 'awakened-poe-trade', // might be required name here
});
s: 'awakened-poe-trade' // might be required name here
})
let data = cache.get<PoepricesApiResponse>(query);
let data = cache.get<PoepricesApiResponse>(query)
if (!data) {
const response = await Host.proxy(`www.poeprices.info/api?${query}`);
const response = await Host.proxy(`www.poeprices.info/api?${query}`)
try {
data = (await response.json()) as PoepricesApiResponse;
data = (await response.json()) as PoepricesApiResponse
} catch (e) {
throw new Error(
`${response.status}, poeprices.info API is under load or down.`
);
)
}
if (data.error !== 0) {
throw new Error(data.error_msg);
throw new Error(data.error_msg)
}
cache.set<PoepricesApiResponse>(query, data, 300);
cache.set<PoepricesApiResponse>(query, data, 300)
}
if (data.currency === 'exalt') {
const { findPriceByQuery, autoCurrency } = usePoeninja();
const { findPriceByQuery, autoCurrency } = usePoeninja()
const xchgExalted = findPriceByQuery({
ns: 'ITEM',
name: 'Exalted Orb',
variant: undefined,
});
variant: undefined
})
if (!xchgExalted) {
throw new Error('poeprices.info gave the price in Exalted Orbs.');
throw new Error('poeprices.info gave the price in Exalted Orbs.')
}
const converted = autoCurrency([
data.min * xchgExalted.chaos,
data.max * xchgExalted.chaos,
]);
data.min = converted.min;
data.max = converted.max;
data.currency = converted.currency === 'div' ? 'divine' : 'chaos';
data.max * xchgExalted.chaos
])
data.min = converted.min
data.max = converted.max
data.currency = converted.currency === 'div' ? 'divine' : 'chaos'
} else if (data.currency !== 'divine' && data.currency !== 'chaos') {
throw new Error('poeprices.info gave the price in unknown currency.');
throw new Error('poeprices.info gave the price in unknown currency.')
}
return {
@@ -83,9 +83,9 @@ export async function requestPoeprices(
confidence: Math.round(data.pred_confidence_score),
explanation: data.pred_explanation.map((expl) => ({
name: expl[0],
contrib: Math.round(expl[1] * 100),
})),
};
contrib: Math.round(expl[1] * 100)
}))
}
}
export function getExternalLink (item: ParsedItem): string {
@@ -93,44 +93,44 @@ export function getExternalLink(item: ParsedItem): string {
i: utf8ToBase64(transformItemText(item.rawText)),
l: useLeagues().selectedId.value,
s: 'awakened-poe-trade',
w: 1,
});
return `https://www.poeprices.info/api?${query}`;
w: 1
})
return `https://www.poeprices.info/api?${query}`
}
export async function sendFeedback (
feedback: { text: string; option: 'fair' | 'low' | 'high' },
feedback: { text: string, option: 'fair' | 'low' | 'high' },
prediction: Pick<PoepricesApiResponse, 'min' | 'max' | 'currency'>,
item: ParsedItem
): Promise<void> {
const body = new FormData();
body.append('selector', feedback.option);
body.append('feedbacktxt', feedback.text);
body.append('qitem_txt', utf8ToBase64(transformItemText(item.rawText)));
body.append('source', 'awakened-poe-trade');
body.append('min', String(prediction.min));
body.append('max', String(prediction.max));
body.append('currency', prediction.currency);
body.append('league', useLeagues().selectedId.value!);
const body = new FormData()
body.append('selector', feedback.option)
body.append('feedbacktxt', feedback.text)
body.append('qitem_txt', utf8ToBase64(transformItemText(item.rawText)))
body.append('source', 'awakened-poe-trade')
body.append('min', String(prediction.min))
body.append('max', String(prediction.max))
body.append('currency', prediction.currency)
body.append('league', useLeagues().selectedId.value!)
// body.append('debug', String(1))
const response = await Host.proxy('www.poeprices.info/send_feedback', {
method: 'POST',
body,
});
body
})
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const text = await response.text();
const text = await response.text()
// console.assert(text === `"${feedback.option}"`)
}
function utf8ToBase64 (value: string) {
return btoa(unescape(encodeURIComponent(value)));
return btoa(unescape(encodeURIComponent(value)))
}
function querystring (q: Record<string, any>) {
return Object.entries(q)
.map((pair) => pair.map(encodeURIComponent).join('='))
.join('&');
.join('&')
}
/**
@@ -140,5 +140,5 @@ function transformItemText(rawText: string) {
// this may not account for all cases
return rawText
.replace(/(?<=\d)(\([^)]+\))/gm, '')
.replace(/^\{.+\}$\n/gm, '');
.replace(/^\{.+\}$\n/gm, '')
}

View File

@@ -1,5 +1,5 @@
import { DateTime } from 'luxon';
import { Host } from '@/web/background/IPC';
import { DateTime } from 'luxon'
import { Host } from '@/web/background/IPC'
import {
TradeResponse,
Account,
@@ -7,102 +7,102 @@ import {
RATE_LIMIT_RULES,
adjustRateLimits,
tradeTag,
preventQueueCreation,
} from './common';
import { RateLimiter } from './RateLimiter';
import { ItemFilters } from '../filters/interfaces';
import { ParsedItem } from '@/parser';
import { Cache } from './Cache';
preventQueueCreation
} from './common'
import { RateLimiter } from './RateLimiter'
import { ItemFilters } from '../filters/interfaces'
import { ParsedItem } from '@/parser'
import { Cache } from './Cache'
interface TradeRequest {
/* eslint-disable camelcase */ engine: 'new';
/* eslint-disable camelcase */ engine: 'new'
query: {
status: { option: 'online' | 'onlineleague' | 'any' };
have: string[];
want: string[];
minimum?: number;
fulfillable?: null;
};
sort: { have: 'asc' };
status: { option: 'online' | 'onlineleague' | 'any' }
have: string[]
want: string[]
minimum?: number
fulfillable?: null
}
sort: { have: 'asc' }
}
interface SearchResult {
id: string;
result: Record<string, FetchResult>;
total: number;
id: string
result: Record<string, FetchResult>
total: number
}
interface FetchResult {
id: string;
id: string
listing: {
indexed: string;
indexed: string
offers: Array<{
exchange: {
currency: string;
amount: number;
};
currency: string
amount: number
}
item: {
amount: number;
stock: number;
};
}>;
account: Account;
};
amount: number
stock: number
}
}>
account: Account
}
}
export interface PricingResult {
id: string;
relativeDate: string;
exchangeAmount: number;
itemAmount: number;
stock: number;
accountStatus: 'offline' | 'online' | 'afk';
isMine: boolean;
accountName: string;
ign: string;
id: string
relativeDate: string
exchangeAmount: number
itemAmount: number
stock: number
accountStatus: 'offline' | 'online' | 'afk'
isMine: boolean
accountName: string
ign: string
}
const cache = new Cache();
const cache = new Cache()
async function requestTradeResultList (
body: TradeRequest,
leagueId: string
): Promise<SearchResult> {
let data = cache.get<SearchResult>([body, leagueId]);
let data = cache.get<SearchResult>([body, leagueId])
if (!data) {
preventQueueCreation([{ count: 1, limiters: RATE_LIMIT_RULES.EXCHANGE }]);
preventQueueCreation([{ count: 1, limiters: RATE_LIMIT_RULES.EXCHANGE }])
await RateLimiter.waitMulti(RATE_LIMIT_RULES.EXCHANGE);
await RateLimiter.waitMulti(RATE_LIMIT_RULES.EXCHANGE)
const response = await Host.proxy(
`${getTradeEndpoint()}/api/trade2/exchange/${leagueId}`,
{
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(body),
body: JSON.stringify(body)
}
);
adjustRateLimits(RATE_LIMIT_RULES.EXCHANGE, response.headers);
)
adjustRateLimits(RATE_LIMIT_RULES.EXCHANGE, response.headers)
const _data = (await response.json()) as TradeResponse<SearchResult>;
const _data = (await response.json()) as TradeResponse<SearchResult>
if (_data.error) {
throw new Error(_data.error.message);
throw new Error(_data.error.message)
} else {
data = _data;
data = _data
}
cache.set<SearchResult>(
[body, leagueId],
data,
Cache.deriveTtl(...RATE_LIMIT_RULES.EXCHANGE)
);
)
}
return data;
return data
}
function toPricingResult (
@@ -125,15 +125,15 @@ function toPricingResult(
? result.listing.account.online.status === 'afk'
? 'afk'
: 'online'
: 'offline',
};
: 'offline'
}
}
export interface BulkSearch {
queryId: string;
haveTag: string;
total: number;
listed: PricingResult[];
queryId: string
haveTag: string
total: number
listed: PricingResult[]
}
export function createTradeRequest (
@@ -144,27 +144,27 @@ export function createTradeRequest(
return {
engine: 'new',
query: {
have: have,
have,
want: [tradeTag(item)!],
status: {
option: filters.trade.offline
? 'any'
: filters.trade.onlineInLeague
? 'onlineleague'
: 'online',
: 'online'
},
minimum:
filters.stackSize && !filters.stackSize.disabled
? filters.stackSize.value
: undefined,
: undefined
// fulfillable: null
},
sort: { have: 'asc' },
};
sort: { have: 'asc' }
}
}
const SHOW_RESULTS = 20;
const API_FETCH_LIMIT = 100;
const SHOW_RESULTS = 20
const API_FETCH_LIMIT = 100
export async function execBulkSearch (
item: ParsedItem,
@@ -175,23 +175,23 @@ export async function execBulkSearch(
const query = await requestTradeResultList(
createTradeRequest(filters, item, have),
filters.trade.league
);
)
const offer = 0;
const offer = 0
const results = Object.values(query.result).filter(
(result) => result.listing.offers.length === 1
);
)
const resultByHave = have.map((tradeTag) => {
const resultsTag = results.filter(
(result) => result.listing.offers[offer].exchange.currency === tradeTag
);
)
const loadedOnDemand =
tradeTag === 'chaos' &&
resultsTag.length < SHOW_RESULTS &&
query.total > API_FETCH_LIMIT;
if (loadedOnDemand) return null;
query.total > API_FETCH_LIMIT
if (loadedOnDemand) return null
const listed = resultsTag
.sort(
@@ -202,13 +202,13 @@ export async function execBulkSearch(
b.listing.offers[offer].item.amount
)
.slice(0, SHOW_RESULTS)
.map((result) => toPricingResult(result, opts, offer));
.map((result) => toPricingResult(result, opts, offer))
const chaosIsLoaded =
tradeTag === 'divine' &&
resultsTag.length < results.length &&
(results.length - resultsTag.length >= SHOW_RESULTS ||
query.total <= API_FETCH_LIMIT);
query.total <= API_FETCH_LIMIT)
return {
queryId: query.id,
@@ -217,9 +217,9 @@ export async function execBulkSearch(
total: chaosIsLoaded
? resultsTag.length
: query.total - (results.length - resultsTag.length),
listed: listed,
};
});
return resultByHave;
listed
}
})
return resultByHave
}

File diff suppressed because it is too large Load Diff

View File

@@ -104,7 +104,7 @@ export default defineComponent({
: autoCurrency(trend.chaos)
return {
price: price,
price,
change: deltaFromGraph(trend.graph),
url: trend.url
}

View File

@@ -58,7 +58,7 @@ export default defineComponent({
function select (info: BaseType) {
const newItem: ParsedItem = {
...props.item!,
info: info
info
}
ctx.emit('identify', newItem)
}

View File

@@ -2,12 +2,12 @@
<div class="p-2 flex flex-col h-full items-center">
<div class="flex flex-col items-center p-2 mb-4">
<img class="w-12 h-12" src="/images/TransferOrb.png">
<p class="text-base">Awakened PoE2 Trade2</p>
<p class="text-base">Exiled Exchange 2</p>
<p class="">{{ t('app.version', [version]) }}</p>
<div class="flex gap-2">
<a class="border-b" href="https://github.com/Kvan7/awakened-poe2-trade2/releases" target="_blank">{{
<a class="border-b" href="https://github.com/Kvan7/exiled-exchange-2/releases" target="_blank">{{
t('app.release_notes') }}</a>
<a class="border-b" href="https://github.com/Kvan7/awakened-poe2-trade2/issues" target="_blank">{{
<a class="border-b" href="https://github.com/Kvan7/exiled-exchange-2/issues" target="_blank">{{
t('app.report_bug') }}</a>
</div>
</div>
@@ -43,7 +43,7 @@ function checkForUpdates() {
}
function openDownloadPage () {
window.open('https://snosme.github.io/awakened-poe-trade/download')
window.open('https://github.com/Kvan7/exiled-exchange-2/releases')
}
function quitAndInstall () {
@@ -67,19 +67,50 @@ export default defineComponent({
const rawInfo = Host.updateInfo.value
switch (rawInfo.state) {
case 'initial':
return { str1: t('updates.maybe_outdated'), str2: t('updates.never_checked'), action: checkForUpdates, actionText: t('updates.check_now') }
return {
str1: t('updates.maybe_outdated'),
str2: t('updates.never_checked'),
action: checkForUpdates,
actionText: t('updates.check_now')
}
case 'checking-for-update':
return { str1: t('updates.checking'), str2: t('please_wait') }
case 'update-not-available':
return { str1: t('updates.latest'), str2: t('updates.last_checked', [fmtTime(rawInfo.checkedAt)]), action: checkForUpdates, actionText: t('updates.check_now') }
return {
str1: t('updates.latest'),
str2: t('updates.last_checked', [fmtTime(rawInfo.checkedAt)]),
action: checkForUpdates,
actionText: t('updates.check_now')
}
case 'error':
return { str1: t('updates.maybe_outdated'), str2: t('updates.error'), action: openDownloadPage, actionText: t('updates.downloads_page') }
return {
str1: t('updates.maybe_outdated'),
str2: t('updates.error'),
action: openDownloadPage,
actionText: t('updates.downloads_page')
}
case 'update-downloaded':
return { str1: t('updates.available', [rawInfo.version]), str2: t('updates.installed_on_exit'), action: quitAndInstall, actionText: t('updates.install_now') }
return {
str1: t('updates.available', [rawInfo.version]),
str2: t('updates.installed_on_exit'),
action: quitAndInstall,
actionText: t('updates.install_now')
}
case 'update-available':
return (rawInfo.noDownloadReason)
? { str1: t('updates.available', [rawInfo.version]), str2: (rawInfo.noDownloadReason === 'not-supported') ? t('updates.download_manually') : t('updates.download_disabled'), action: openDownloadPage, actionText: t('updates.downloads_page') }
: { str1: t('updates.available', [rawInfo.version]), str2: t('updates.downloading') }
return rawInfo.noDownloadReason
? {
str1: t('updates.available', [rawInfo.version]),
str2:
rawInfo.noDownloadReason === 'not-supported'
? t('updates.download_manually')
: t('updates.download_disabled'),
action: openDownloadPage,
actionText: t('updates.downloads_page')
}
: {
str1: t('updates.available', [rawInfo.version]),
str2: t('updates.downloading')
}
}
})

View File

@@ -33,7 +33,7 @@
<div class="mb-4">
<div class="flex-1 mb-1">{{ t(':poe_cfg_file') }}</div>
<input v-model.trim="gameConfig"
class="rounded bg-gray-900 px-1 block w-full font-sans" placeholder="...?/My Games/Path of Exile 2/production_Config.ini">
class="rounded bg-gray-900 px-1 block w-full font-sans" placeholder="...?/My Games/Path of Exile 2/poe2_production_Config.ini">
</div>
<hr class="mb-4 mx-8 border-gray-700">
<div class="mb-2">

File diff suppressed because it is too large Load Diff

22
testUpdate.sh Normal file
View File

@@ -0,0 +1,22 @@
#!/bin/bash
# Remove ./renderer/dist if it exists
rm -rf ./renderer/dist
# Remove ./main/dist if it exists
rm -rf ./main/dist
cd ./renderer
npm install
npm run make-index-files
npm run build
cd ..
cd ./main
npm install
npm run build
npm run package