├── resources
├── icon.icns
└── icon.ico
├── renderer
├── public
│ └── images
│ │ └── logo.png
├── layouts
│ └── main
│ │ ├── assets
│ │ └── styled.ts
│ │ └── index.tsx
├── tsconfig.json
├── next-env.d.ts
├── next.config.js
├── pages
│ ├── _app.tsx
│ └── home.tsx
├── components
│ └── Titlebar
│ │ ├── index.tsx
│ │ └── assets
│ │ └── titlebar.ts
├── styles
│ └── globals.sass
└── _document.tsx
├── main
├── helpers
│ ├── index.ts
│ ├── logger.ts
│ ├── ipc.ts
│ └── create-window.ts
└── background.ts
├── _templates
├── layout
│ ├── interface.ts.t
│ ├── asset
│ │ └── styled.ts.t
│ └── index.tsx.t
├── component
│ ├── interface.ts.t
│ ├── assets
│ │ └── styled.ts.t
│ └── index.tsx.t
└── state
│ └── index.ts.t
├── .yarnrc.yml
├── .gitignore
├── electron-builder.yml
├── README.md
├── tsconfig.json
├── .eslintrc.js
├── package.json
└── .yarn
└── plugins
└── @yarnpkg
└── plugin-typescript.cjs
/resources/icon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HextechDocs/lcu-explorer/HEAD/resources/icon.icns
--------------------------------------------------------------------------------
/resources/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HextechDocs/lcu-explorer/HEAD/resources/icon.ico
--------------------------------------------------------------------------------
/renderer/public/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HextechDocs/lcu-explorer/HEAD/renderer/public/images/logo.png
--------------------------------------------------------------------------------
/main/helpers/index.ts:
--------------------------------------------------------------------------------
1 | import createWindow from "./create-window";
2 | import ipc from "./ipc";
3 |
4 | export { createWindow, ipc };
5 |
--------------------------------------------------------------------------------
/main/helpers/logger.ts:
--------------------------------------------------------------------------------
1 | import tracer from "tracer";
2 |
3 | const logger = tracer.colorConsole();
4 |
5 | export default logger;
6 |
--------------------------------------------------------------------------------
/renderer/layouts/main/assets/styled.ts:
--------------------------------------------------------------------------------
1 | import styled from "styled-components";
2 |
3 | const Styled = styled.div``;
4 |
5 | export default Styled;
6 |
--------------------------------------------------------------------------------
/_templates/layout/interface.ts.t:
--------------------------------------------------------------------------------
1 | ---
2 | to: renderer/interfaces/layouts/<%= h.capitalize(name) %>/props.tsx
3 | ---
4 | export default interface <%= h.capitalize(name) %>Props {
5 |
6 | }
7 |
--------------------------------------------------------------------------------
/_templates/component/interface.ts.t:
--------------------------------------------------------------------------------
1 | ---
2 | to: renderer/interfaces/components/<%= h.capitalize(name) %>/props.tsx
3 | ---
4 | export default interface <%= h.capitalize(name) %>Props {
5 |
6 | }
7 |
--------------------------------------------------------------------------------
/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | nodeLinker: node-modules
2 |
3 | plugins:
4 | - path: .yarn/plugins/@yarnpkg/plugin-typescript.cjs
5 | spec: "@yarnpkg/plugin-typescript"
6 |
7 | yarnPath: .yarn/releases/yarn-3.0.2.cjs
8 |
--------------------------------------------------------------------------------
/renderer/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "include": [
4 | "next-env.d.ts",
5 | "**/*.ts",
6 | "**/*.tsx"
7 | ],
8 | "exclude": [
9 | "node_modules"
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | *.log
3 | .next
4 | app
5 | dist
6 | renderer/.next
7 | .idea
8 | .vscode
9 |
10 | .pnp.*
11 | .yarn/*
12 | !.yarn/patches
13 | !.yarn/plugins
14 | !.yarn/releases
15 | !.yarn/sdks
16 | !.yarn/versions
17 |
--------------------------------------------------------------------------------
/_templates/state/index.ts.t:
--------------------------------------------------------------------------------
1 | ---
2 | to: renderer/state/<%= h.capitalize(name) %>.ts
3 | ---
4 | import {atom} from "recoil";
5 |
6 | const <%= h.capitalize(name) %>Atom = atom({key: '<%= h.capitalize(name) %>State',default:''})
7 |
8 | export default <%= h.capitalize(name) %>Atom
9 |
--------------------------------------------------------------------------------
/renderer/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 | ///
4 |
5 | // NOTE: This file should not be edited
6 | // see https://nextjs.org/docs/basic-features/typescript for more information.
7 |
--------------------------------------------------------------------------------
/renderer/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | webpack: (config, { isServer }) => {
3 |
4 | if (!isServer) {
5 | config.target = 'electron-renderer';
6 | config.node = {
7 | __dirname: true,
8 | }
9 | }
10 | return config;
11 | },
12 | };
--------------------------------------------------------------------------------
/electron-builder.yml:
--------------------------------------------------------------------------------
1 | appId: dev.hextechdocs.lcuexplorer
2 | productName: LCU Explorer
3 | copyright: Copyright © 2022 HextechDocs
4 | directories:
5 | output: dist
6 | buildResources: resources
7 | files:
8 | - from: .
9 | filter:
10 | - package.json
11 | - app
12 | publish: null
13 |
--------------------------------------------------------------------------------
/_templates/layout/asset/styled.ts.t:
--------------------------------------------------------------------------------
1 | ---
2 | to: renderer/layouts/<%= h.capitalize(name) %>/assets/Styled.ts
3 | ---
4 | import styled from 'styled-components';
5 | import theme from 'styled-theming';
6 |
7 | const backgroundColor = theme('mode', {
8 | light: '#ddd',
9 | dark: '#222',
10 | });
11 |
12 | const Styled = styled.div`
13 | background-color: ${backgroundColor};
14 | `;
15 |
16 | export default Styled
17 |
--------------------------------------------------------------------------------
/_templates/component/assets/styled.ts.t:
--------------------------------------------------------------------------------
1 | ---
2 | to: renderer/components/<%= h.capitalize(name) %>/assets/Styled.ts
3 | ---
4 | import styled from 'styled-components';
5 | import theme from 'styled-theming';
6 |
7 | const backgroundColor = theme('mode', {
8 | light: '#ddd',
9 | dark: '#222',
10 | });
11 |
12 | const Styled = styled.div`
13 | background-color: ${backgroundColor};
14 | `;
15 |
16 | export default Styled
17 |
--------------------------------------------------------------------------------
/_templates/component/index.tsx.t:
--------------------------------------------------------------------------------
1 | ---
2 | to: renderer/components/<%= h.capitalize(name) %>/index.tsx
3 | ---
4 | import Styled from './assets/Styled'
5 |
6 | import Props from '@Interfaces/components/<%= h.capitalize(name) %>/props'
7 |
8 | const <%= h.capitalize(name) %> = ({}: Props): JSX.Element => {
9 | return (
10 |
11 | Content
12 |
13 | )
14 | }
15 |
16 | export default <%= h.capitalize(name) %>
17 |
--------------------------------------------------------------------------------
/main/helpers/ipc.ts:
--------------------------------------------------------------------------------
1 | import { ipcRenderer as ipc } from "electron";
2 | import logger from "./logger";
3 |
4 | // ipc.on("close", () => {
5 | // logger.warn("Close event triggered via close button.");
6 | // });
7 | //
8 | // ipc.on("minmax", () => {
9 | // logger.debug("Window min/max via minmax button.");
10 | // });
11 | //
12 | // ipc.on("min", () => {
13 | // logger.debug("Window minimized via button.");
14 | // });
15 |
16 | export default {};
17 |
--------------------------------------------------------------------------------
/renderer/pages/_app.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import type { AppProps } from "next/app";
3 | import { RecoilRoot } from "recoil";
4 |
5 | import "css-reset-and-normalize/css/button-reset.min.css";
6 | import "css-reset-and-normalize/css/link-reset.min.css";
7 | import "css-reset-and-normalize/css/reset-and-normalize.min.css";
8 |
9 | import "swagger-ui/dist/swagger-ui.css";
10 | import "../styles/globals.sass";
11 |
12 | const LCUExplorer = ({ Component, pageProps }: AppProps): JSX.Element => {
13 | return (
14 |
15 |
16 |
17 | );
18 | };
19 |
20 | export default LCUExplorer;
21 |
--------------------------------------------------------------------------------
/renderer/layouts/main/index.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import { ThemeProvider } from "styled-components";
4 | import { useRecoilState } from "recoil";
5 |
6 | import Header from "@components/Titlebar";
7 | import ThemeAtom from "@state/Theme";
8 |
9 | import Styled from "./assets/styled";
10 |
11 | interface MainLayoutProps {
12 | children: never;
13 | }
14 |
15 | const MainLayout = ({ children }: MainLayoutProps): JSX.Element => {
16 | const [theme, setTheme] = useRecoilState(ThemeAtom);
17 |
18 | return (
19 |
20 |
21 |
22 | {children}
23 |
24 |
25 | );
26 | };
27 |
28 | export default MainLayout;
29 |
--------------------------------------------------------------------------------
/_templates/layout/index.tsx.t:
--------------------------------------------------------------------------------
1 | ---
2 | to: renderer/layouts/<%= h.capitalize(name) %>/index.tsx
3 | ---
4 | import { ThemeProvider } from 'styled-components';
5 | import { useRecoilState } from 'recoil';
6 | import Styled from './assets/Styled'
7 |
8 | import Header from '@Components/Header';
9 | import ThemeAtom from '@State/Theme';
10 |
11 | import Props from '@Interfaces/layouts/<%= h.capitalize(name) %>/props'
12 |
13 | const <%= h.capitalize(name) %> = ({}: Props): JSX.Element => {
14 | const [theme, setTheme] = useRecoilState(ThemeAtom);
15 |
16 | return (
17 |
18 |
19 |
20 | {children}
21 |
22 |
23 | );
24 | };
25 |
26 | export default <%= h.capitalize(name) %>
27 |
--------------------------------------------------------------------------------
/renderer/components/Titlebar/index.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { ipcRenderer as ipc } from "electron";
3 |
4 | import TitlebarStyled from "./assets/titlebar";
5 |
6 | const Titlebar = (): JSX.Element => {
7 | const onClose = () => {
8 | ipc.send("process:close");
9 | };
10 |
11 | const onMin = () => {
12 | ipc.send("process:min");
13 | };
14 |
15 | const onMax = () => {
16 | ipc.send("process:minmax");
17 | };
18 |
19 | return (
20 |
21 |
22 |
26 |
27 | );
28 | };
29 |
30 | export default Titlebar;
31 |
--------------------------------------------------------------------------------
/renderer/styles/globals.sass:
--------------------------------------------------------------------------------
1 | *
2 | color: #aaa!important
3 | html,
4 | body
5 | padding: 0
6 | margin: 0
7 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif
8 | background: #222
9 | color: white
10 |
11 | .scheme-container, .information-container, .errors-wrapper
12 | display: none
13 |
14 | .opblock-tag, div
15 | color: #aaa!important
16 | background: #222!important
17 |
18 | .btn
19 | display: flex
20 | justify-content: center
21 | align-items: center
22 |
23 | /* width */
24 | ::-webkit-scrollbar
25 | width: 10px
26 |
27 |
28 | /* Track */
29 | ::-webkit-scrollbar-track
30 | background: transparent
31 | margin-top: 2rem
32 |
33 |
34 | /* Handle */
35 | ::-webkit-scrollbar-thumb
36 | background: #888
37 |
38 |
39 | /* Handle on hover */
40 | ::-webkit-scrollbar-thumb:hover
41 | background: #555
42 |
--------------------------------------------------------------------------------
/renderer/components/Titlebar/assets/titlebar.ts:
--------------------------------------------------------------------------------
1 | import styled from "styled-components";
2 |
3 | const TitlebarStyled = styled.div`
4 | display: flex;
5 | width: 100%;
6 | height: 2rem;
7 | -webkit-app-region: drag;
8 | flex-direction: row;
9 |
10 | .buttons {
11 | margin: 0.3rem;
12 | -webkit-app-region: no-drag;
13 | button {
14 | width: 1.25rem;
15 | height: 1.25rem;
16 | margin: 0 0.2rem;
17 | border-radius: 100%;
18 | -webkit-app-region: no-drag;
19 | transition-duration: 250ms;
20 | &:focus {
21 | border: none;
22 | outline: none;
23 | }
24 | &:hover {
25 | filter: grayscale(0.3);
26 | transition-duration: 250ms;
27 | }
28 | }
29 |
30 | #close {
31 | background-color: crimson;
32 | }
33 |
34 | #minmax {
35 | background-color: darkorange;
36 | }
37 |
38 | #max {
39 | background: mediumspringgreen;
40 | }
41 | }
42 | `;
43 |
44 | export default TitlebarStyled;
45 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ⚠️ Deprecated in favour of:
2 | [Needlework.Net](https://github.com/BlossomiShymae/Needlework.Net)
3 |
4 | # LCU Explorer
5 |
6 | ---
7 |
8 | A replacement for rift explorer which doesn't need restarting from the original contributors
9 |
10 | ## Usage
11 |
12 | - Download the [latest release from GitHub](https://github.com/HextechDocs/lcu-explorer/releases/latest) (exe installer or unpacked standalone zip).
13 | - LCU Explorer should start after installing, or start manually after unzipping.
14 | - If the LoL client is not already running, start it now.
15 | - Endpoints will show immediately after launching, but "try it out" is hidden unless the client is running.
16 |
17 | ## Development
18 |
19 | ### Install dependencies
20 | ```
21 | yarn
22 | ```
23 | then...
24 |
25 | ### Run in dev mode
26 | ```
27 | yarn dev
28 | ```
29 |
30 | ### Build
31 | ```
32 | yarn build
33 | ```
34 |
35 | ## Credits
36 |
37 | **Massive thank you to [Mingwei Samuel](https://github.com/MingweiSamuel)** for his work on this app and the backend driving it.
38 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "esnext",
5 | "moduleResolution": "node",
6 | "jsx": "preserve",
7 | "lib": [
8 | "dom",
9 | "dom.iterable",
10 | "esnext"
11 | ],
12 | "allowJs": true,
13 | "skipLibCheck": true,
14 | "strict": false,
15 | "forceConsistentCasingInFileNames": true,
16 | "allowSyntheticDefaultImports": true,
17 | "noEmit": true,
18 | "esModuleInterop": true,
19 | "resolveJsonModule": true,
20 | "isolatedModules": true,
21 | "baseUrl": "./",
22 | "paths": {
23 | "@pages/*": ["renderer/pages/*"],
24 | "@public/*": ["renderer/public/*"],
25 | "@components/*": ["renderer/components/*"],
26 | "@layouts/*": ["renderer/layouts/*"],
27 | "@state/*": ["renderer/state/*"],
28 | "@styles/*": ["renderer/styles/*"],
29 | "@renderer": ["renderer/*"],
30 | "@helpers/*": ["main/helpers/*"],
31 | "@main/*": ["main/*"]
32 | }
33 | },
34 | "exclude": [
35 | "node_modules",
36 | "renderer/next.config.js",
37 | "app",
38 | "dist"
39 | ]
40 | }
41 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | const {off} = require("./renderer/.next/static/chunks/main");
2 | module.exports = {
3 | extends: [
4 | 'airbnb-typescript',
5 | 'airbnb/hooks',
6 | 'plugin:@typescript-eslint/recommended',
7 | 'plugin:prettier/recommended'
8 | ],
9 | plugins: ['react', '@typescript-eslint'],
10 | env: {
11 | browser: true,
12 | es6: true,
13 | jest: true,
14 | },
15 | globals: {
16 | Atomics: 'readonly',
17 | SharedArrayBuffer: 'readonly',
18 | },
19 | parser: '@typescript-eslint/parser',
20 | parserOptions: {
21 | ecmaFeatures: {
22 | jsx: true,
23 | },
24 | ecmaVersion: 2018,
25 | sourceType: 'module',
26 | project: './tsconfig.json',
27 | },
28 | rules: {
29 | '@typescript-eslint/no-explicit-any': 'off',
30 | 'react/require-default-props': 'off',
31 | 'react/jsx-props-no-spreading': 'off',
32 | 'linebreak-style': 'off',
33 | 'import/no-extraneous-dependencies': 'off',
34 | 'react/button-has-type': 'off',
35 | '@typescript-eslint/ban-ts-comment': 'off',
36 | "no-console": 'off',
37 | 'react-hooks/exhaustive-deps': 'off',
38 | 'jsx-a11y/control-has-associated-label': 'off',
39 | 'prettier/prettier': [
40 | 'error',
41 | {
42 | endOfLine: 'auto',
43 | },
44 | ],
45 | },
46 | };
47 |
--------------------------------------------------------------------------------
/renderer/_document.tsx:
--------------------------------------------------------------------------------
1 | import { RenderPage } from "next/dist/shared/lib/utils";
2 | import React from "react";
3 | import Document, {
4 | DocumentContext,
5 | Head,
6 | Html,
7 | Main,
8 | NextScript,
9 | } from "next/document";
10 | import { ServerStyleSheet } from "styled-components";
11 |
12 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment
13 | // @ts-ignore
14 | export default class MyDocument extends Document {
15 | static async getInitialProps(
16 | ctx: DocumentContext
17 | ): Promise<
18 | RenderPage | { styles: JSX.Element; html: string; head?: JSX.Element[] }
19 | > {
20 | const sheet = new ServerStyleSheet();
21 | const originalRenderPage = ctx.renderPage;
22 |
23 | try {
24 | ctx.renderPage = () =>
25 | originalRenderPage({
26 | enhanceApp: (App) => (props) =>
27 | sheet.collectStyles(),
28 | });
29 |
30 | const initialProps = await Document.getInitialProps(ctx);
31 | return {
32 | ...initialProps,
33 | styles: (
34 | <>
35 | {initialProps.styles}
36 | {sheet.getStyleElement()}
37 | >
38 | ),
39 | };
40 | } finally {
41 | sheet.seal();
42 | }
43 | }
44 |
45 | render(): JSX.Element {
46 | return (
47 |
48 |
49 | Treeline Explorer
50 |
51 |
52 |
53 |
54 |
55 |
56 | );
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/main/helpers/create-window.ts:
--------------------------------------------------------------------------------
1 | import {
2 | screen,
3 | BrowserWindow,
4 | BrowserWindowConstructorOptions,
5 | } from "electron";
6 | import Store from "electron-store";
7 |
8 | export default (
9 | windowName: string,
10 | options: BrowserWindowConstructorOptions
11 | ): BrowserWindow => {
12 | const key = "window-state";
13 | const name = `window-state-${windowName}`;
14 | const store = new Store({ name });
15 | const defaultSize = {
16 | width: options.width,
17 | height: options.height,
18 | };
19 | let state = {};
20 | let win;
21 |
22 | const restore = () => store.get(key, defaultSize);
23 |
24 | const getCurrentPosition = () => {
25 | const position = win.getPosition();
26 | const size = win.getSize();
27 | return {
28 | x: position[0],
29 | y: position[1],
30 | width: size[0],
31 | height: size[1],
32 | };
33 | };
34 |
35 | const windowWithinBounds = (windowState, bounds) => {
36 | return (
37 | windowState.x >= bounds.x &&
38 | windowState.y >= bounds.y &&
39 | windowState.x + windowState.width <= bounds.x + bounds.width &&
40 | windowState.y + windowState.height <= bounds.y + bounds.height
41 | );
42 | };
43 |
44 | const resetToDefaults = () => {
45 | const { bounds } = screen.getPrimaryDisplay();
46 | return {
47 | ...defaultSize,
48 | x: (bounds.width - defaultSize.width) / 2,
49 | y: (bounds.height - defaultSize.height) / 2,
50 | };
51 | };
52 |
53 | const ensureVisibleOnSomeDisplay = (windowState) => {
54 | const visible = screen.getAllDisplays().some((display) => {
55 | return windowWithinBounds(windowState, display.bounds);
56 | });
57 | if (!visible) {
58 | // Window is partially or fully not visible now.
59 | // Reset it to safe defaults.
60 | return resetToDefaults();
61 | }
62 | return windowState;
63 | };
64 |
65 | const saveState = () => {
66 | if (!win.isMinimized() && !win.isMaximized()) {
67 | Object.assign(state, getCurrentPosition());
68 | }
69 | store.set(key, state);
70 | };
71 |
72 | state = ensureVisibleOnSomeDisplay(restore());
73 |
74 | const browserOptions: BrowserWindowConstructorOptions = {
75 | ...options,
76 | ...state,
77 | webPreferences: {
78 | nodeIntegration: true,
79 | contextIsolation: false,
80 | ...options.webPreferences,
81 | },
82 | };
83 | win = new BrowserWindow(browserOptions);
84 |
85 | win.on("close", saveState);
86 |
87 | return win;
88 | };
89 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "lcu-explorer",
4 | "description": "Interactive lcu documentation",
5 | "version": "1.2.0",
6 | "author": {
7 | "name": "hextechdocs",
8 | "url": "https://hextechdocs.dev",
9 | "email": "team@hextechdocs.dev"
10 | },
11 | "contributors": [
12 | {
13 | "name": "Ray",
14 | "url": "https://hiray.me",
15 | "email": "dev@hiray.me"
16 | },
17 | {
18 | "name": "Mingwei Samuel",
19 | "url": "https://www.mingweisamuel.com",
20 | "email": "mingwei.samuel@gmail.com"
21 | }
22 | ],
23 | "main": "app/background.js",
24 | "scripts": {
25 | "dev": "nextron",
26 | "build": "nextron build",
27 | "postinstall": "electron-builder install-app-deps",
28 | "format": "prettier --write {main,renderer}/**/*.ts{,x}",
29 | "lint": "tsc --noEmit && eslint {main,renderer}/**/*.ts{,x}",
30 | "update:deps": "npx npm-check-updates -u && yarn",
31 | "create:component": "npx hygen component new",
32 | "create:layout": "npx hygen layout new",
33 | "create:state": "npx hygen state new"
34 | },
35 | "dependencies": {
36 | "@types/swagger-ui": "^3.52.0",
37 | "axios": "^0.22.0",
38 | "css-reset-and-normalize": "^2.3.5",
39 | "electron-serve": "^1.1.0",
40 | "electron-store": "^8.0.0",
41 | "lcu-connector": "^2.1.3",
42 | "lodash": "^4.17.21",
43 | "recoil": "^0.4.0",
44 | "sass": "^1.37.5",
45 | "styled-components": "^5.3.0",
46 | "styled-theming": "^2.2.0",
47 | "swagger-ui": "^3.52.3",
48 | "tracer": "^1.1.5"
49 | },
50 | "devDependencies": {
51 | "@types/lodash": "^4",
52 | "@types/node": "^16.6.1",
53 | "@types/react": "^17.0.17",
54 | "@types/styled-components": "^5.1.12",
55 | "@types/styled-theming": "^2.2.5",
56 | "@typescript-eslint/eslint-plugin": "^4.29.1",
57 | "@typescript-eslint/parser": "^4.29.1",
58 | "electron": "^13.1.9",
59 | "electron-builder": "^22.11.7",
60 | "eslint": "7.32.0",
61 | "eslint-config-airbnb": "18.2.1",
62 | "eslint-config-airbnb-typescript": "^12.3.1",
63 | "eslint-config-prettier": "^8.3.0",
64 | "eslint-plugin-import": "2.24.0",
65 | "eslint-plugin-jsx-a11y": "6.4.1",
66 | "eslint-plugin-prettier": "^3.4.0",
67 | "eslint-plugin-react": "7.24.0",
68 | "eslint-plugin-react-hooks": "4.2.0",
69 | "next": "^11.1.1",
70 | "nextron": "^7.0.0",
71 | "prettier": "^2.3.2",
72 | "react": "^17.0.2",
73 | "react-dom": "^17.0.2",
74 | "typescript": "^4.3.5"
75 | },
76 | "packageManager": "yarn@3.0.2"
77 | }
78 |
--------------------------------------------------------------------------------
/main/background.ts:
--------------------------------------------------------------------------------
1 | import { app, ipcMain as ipc } from "electron";
2 | import serve from "electron-serve";
3 | import Store from "electron-store";
4 | import LCUConnector from "lcu-connector";
5 | import { createWindow } from "./helpers";
6 |
7 | import "./helpers/ipc";
8 |
9 | type Credentials = {
10 | address: string;
11 | port: number;
12 | username: string;
13 | password: string;
14 | protocol: string;
15 | };
16 |
17 | const store = new Store();
18 | const isProd: boolean = process.env.NODE_ENV === "production";
19 |
20 | if (isProd) {
21 | serve({ directory: "app" });
22 | } else {
23 | app.setPath("userData", `${app.getPath("userData")} (development)`);
24 | }
25 |
26 | app.on(
27 | "certificate-error",
28 | (event, _webContents, _url, _error, certificate, callback) => {
29 | if (
30 | certificate.fingerprint ===
31 | "sha256/TQ1pFVrt3Msu+IVgubjrrixp75XCuDFovDbcTcqTJjw="
32 | ) {
33 | event.preventDefault();
34 | callback(true);
35 | } else {
36 | callback(false);
37 | }
38 | }
39 | );
40 |
41 | (async () => {
42 | await app.whenReady();
43 |
44 | const backgroundColor = (): string => {
45 | if (!store.get("theme")) {
46 | store.set("theme", "dark");
47 | }
48 | const dark = "#222";
49 | const light = "#DDD";
50 |
51 | if (store.get("theme") === "dark") {
52 | return light;
53 | }
54 | return dark;
55 | };
56 |
57 | const mainWindow = createWindow("main", {
58 | width: 1280,
59 | height: 720,
60 | minWidth: 1280,
61 | minHeight: 720,
62 | title: "LCU Explorer",
63 | frame: false,
64 | backgroundColor: backgroundColor(),
65 | webPreferences: {
66 | nodeIntegration: true,
67 | allowRunningInsecureContent: true,
68 | webSecurity: false,
69 | },
70 | });
71 |
72 | (() => {
73 | const feReady = new Promise((resolve) => ipc.on("fe-ready", resolve));
74 | function sendCredentials(credentials: Credentials) {
75 | console.log(
76 | `BE received credentials update: ${JSON.stringify(credentials)}`
77 | );
78 | feReady.then(() => {
79 | console.log(`BE sending credentials: ${JSON.stringify(credentials)}`);
80 | mainWindow.webContents.send("credentialspass", credentials);
81 | });
82 | }
83 | const connector = new LCUConnector();
84 | connector.on("connect", sendCredentials);
85 | connector.on("disconnect", () => sendCredentials(null));
86 | connector.start();
87 | })();
88 |
89 | ipc.on("process:min", () => {
90 | mainWindow.minimize();
91 | });
92 |
93 | ipc.on("process:minmax", () => {
94 | // eslint-disable-next-line @typescript-eslint/no-unused-expressions
95 | mainWindow.maximizable ? mainWindow.maximize() : mainWindow.unmaximize();
96 | });
97 |
98 | if (isProd) {
99 | await mainWindow.loadURL("app://./home.html");
100 | } else {
101 | const port = process.argv[2];
102 | await mainWindow.loadURL(`http://localhost:${port}/home`);
103 | mainWindow.webContents.openDevTools({ mode: "detach" });
104 | }
105 | })();
106 |
107 | app.on("window-all-closed", () => {
108 | app.quit();
109 | });
110 |
111 | ipc.on("process:close", () => {
112 | process.exit(0);
113 | });
114 |
--------------------------------------------------------------------------------
/renderer/pages/home.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import { ipcRenderer } from "electron";
3 | import Swagger from "swagger-ui";
4 | import axios, { AxiosResponse } from "axios";
5 | import { isEmpty } from "lodash";
6 |
7 | import Titlebar from "@components/Titlebar";
8 |
9 | type Credentials = {
10 | address?: string;
11 | port?: number;
12 | username?: string;
13 | password?: string;
14 | protocol?: string;
15 | };
16 | type SwaggerUIPlugged = Swagger & {
17 | updateSpec: (specUpdates: any) => void;
18 | };
19 |
20 | const BASIC_AUTH = "BasicAuth";
21 |
22 | const Home: React.FC = () => {
23 | const [swagger, SetSwagger] = useState({});
24 | const [credentials, SetCredentials] = useState({});
25 | const [spec, SetSpec] = useState({});
26 |
27 | // Get spec.
28 | useEffect(() => {
29 | if (!isEmpty(spec)) {
30 | console.log("spec is not empty returning");
31 | return;
32 | }
33 | console.warn("spec is empty fetching");
34 | axios
35 | .get("https://www.mingweisamuel.com/lcu-schema/lcu/openapi.json")
36 | .then((res: AxiosResponse) => SetSpec(res.data));
37 | }, []);
38 |
39 | // Setup credentials listener.
40 | useEffect(() => {
41 | ipcRenderer.on("credentialspass", (_event, newCredentials) => {
42 | console.log(`FE received credentials: ${JSON.stringify(newCredentials)}`);
43 | if (isEmpty(credentials)) {
44 | SetCredentials(newCredentials);
45 | }
46 | });
47 | ipcRenderer.send("fe-ready");
48 | }, []);
49 |
50 | // Setup Swagger UI.
51 | useEffect(() => {
52 | const swaggerInst = Swagger({
53 | syntaxHighlight: false,
54 | dom_id: "#swagger",
55 | spec: {
56 | openapi: "3.0.0",
57 | security: [
58 | {
59 | [BASIC_AUTH]: [],
60 | },
61 | ],
62 | components: {
63 | securitySchemes: {
64 | [BASIC_AUTH]: {
65 | type: "http",
66 | scheme: "basic",
67 | },
68 | },
69 | },
70 | servers: [],
71 | },
72 | operationsSorter: "alpha",
73 | tagsSorter: "alpha",
74 | docExpansion: "none",
75 | defaultModelExpandDepth: 10,
76 | maxDisplayedTags: 100,
77 | tryItOutEnabled: true,
78 | displayRequestDuration: true,
79 | pluginsOptions: {
80 | pluginLoadType: "chain",
81 | },
82 | filter: "",
83 | deepLinking: false, // @ts-ignore
84 | requestInterceptor: (request: any) => {
85 | request.curlOptions = ["--insecure"];
86 | return request;
87 | },
88 | plugins: [
89 | (system) => ({
90 | statePlugins: {
91 | spec: {
92 | wrapSelectors: {
93 | allowTryItOutFor: () => () => {
94 | // const jsonSpec = system.getState().toJSON().spec.json;
95 | console.log("rerendering");
96 | return true;
97 | },
98 | },
99 | },
100 | },
101 | rootInjects: {
102 | updateSpec: (specUpdates: any) => {
103 | const jsonSpec = system.getState().toJSON().spec.json;
104 | const newJsonSpec = { ...jsonSpec, ...specUpdates };
105 | // Preserve securitySchemes.
106 | newJsonSpec.components.securitySchemes =
107 | jsonSpec.components.securitySchemes;
108 | return system.specActions.updateJsonSpec(newJsonSpec);
109 | },
110 | },
111 | }),
112 | ],
113 | onComplete: () => {
114 | console.log("Swagger UI loading complete.");
115 | if (isEmpty(swagger)) {
116 | console.log("swagger is empty applying instance");
117 | SetSwagger(swaggerInst);
118 | } else {
119 | console.log("swagger instance is present");
120 | }
121 | },
122 | }) as SwaggerUIPlugged;
123 | }, []);
124 |
125 | useEffect(() => {
126 | console.log(
127 | `Updating FE: swagger ${swagger != null}, spec ${
128 | spec != null
129 | }, credentials ${JSON.stringify(credentials)}.`
130 | );
131 |
132 | // If Swagger UI not ready, nothing to update.
133 | if (swagger == null) {
134 | return;
135 | }
136 |
137 | // Update credentials/port from connector.
138 | if (credentials != null) {
139 | if (isEmpty(swagger)) {
140 | console.log("swager is empty and credentials arent null");
141 | return;
142 | }
143 | console.log("updating spec...");
144 | swagger.updateSpec({
145 | servers: [
146 | {
147 | url: `https://127.0.0.1:${credentials.port}`,
148 | description: "default",
149 | },
150 | ],
151 | });
152 | swagger.preauthorizeBasic(
153 | BASIC_AUTH,
154 | credentials.username,
155 | credentials.password
156 | );
157 | } else {
158 | if (isEmpty(swagger)) {
159 | return;
160 | }
161 | console.log("updating spec");
162 | swagger.updateSpec({
163 | servers: [],
164 | });
165 | }
166 |
167 | // Update OpenAPI spec lcu-schema.
168 | if (spec != null) {
169 | console.log("updating spec");
170 | swagger.updateSpec(spec);
171 | }
172 | }, [swagger, credentials, spec]);
173 |
174 | return (
175 | <>
176 |
177 |
178 | >
179 | );
180 | };
181 |
182 | export default Home;
183 |
--------------------------------------------------------------------------------
/.yarn/plugins/@yarnpkg/plugin-typescript.cjs:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | //prettier-ignore
3 | module.exports = {
4 | name: "@yarnpkg/plugin-typescript",
5 | factory: function (require) {
6 | var plugin=(()=>{var Ft=Object.create,H=Object.defineProperty,Bt=Object.defineProperties,Kt=Object.getOwnPropertyDescriptor,zt=Object.getOwnPropertyDescriptors,Gt=Object.getOwnPropertyNames,Q=Object.getOwnPropertySymbols,$t=Object.getPrototypeOf,ne=Object.prototype.hasOwnProperty,De=Object.prototype.propertyIsEnumerable;var Re=(e,t,r)=>t in e?H(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,u=(e,t)=>{for(var r in t||(t={}))ne.call(t,r)&&Re(e,r,t[r]);if(Q)for(var r of Q(t))De.call(t,r)&&Re(e,r,t[r]);return e},g=(e,t)=>Bt(e,zt(t)),Lt=e=>H(e,"__esModule",{value:!0});var R=(e,t)=>{var r={};for(var s in e)ne.call(e,s)&&t.indexOf(s)<0&&(r[s]=e[s]);if(e!=null&&Q)for(var s of Q(e))t.indexOf(s)<0&&De.call(e,s)&&(r[s]=e[s]);return r};var I=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),Vt=(e,t)=>{for(var r in t)H(e,r,{get:t[r],enumerable:!0})},Qt=(e,t,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Gt(t))!ne.call(e,s)&&s!=="default"&&H(e,s,{get:()=>t[s],enumerable:!(r=Kt(t,s))||r.enumerable});return e},C=e=>Qt(Lt(H(e!=null?Ft($t(e)):{},"default",e&&e.__esModule&&"default"in e?{get:()=>e.default,enumerable:!0}:{value:e,enumerable:!0})),e);var xe=I(J=>{"use strict";Object.defineProperty(J,"__esModule",{value:!0});function _(e){let t=[...e.caches],r=t.shift();return r===void 0?ve():{get(s,n,a={miss:()=>Promise.resolve()}){return r.get(s,n,a).catch(()=>_({caches:t}).get(s,n,a))},set(s,n){return r.set(s,n).catch(()=>_({caches:t}).set(s,n))},delete(s){return r.delete(s).catch(()=>_({caches:t}).delete(s))},clear(){return r.clear().catch(()=>_({caches:t}).clear())}}}function ve(){return{get(e,t,r={miss:()=>Promise.resolve()}){return t().then(n=>Promise.all([n,r.miss(n)])).then(([n])=>n)},set(e,t){return Promise.resolve(t)},delete(e){return Promise.resolve()},clear(){return Promise.resolve()}}}J.createFallbackableCache=_;J.createNullCache=ve});var Ee=I(($s,qe)=>{qe.exports=xe()});var Te=I(ae=>{"use strict";Object.defineProperty(ae,"__esModule",{value:!0});function Jt(e={serializable:!0}){let t={};return{get(r,s,n={miss:()=>Promise.resolve()}){let a=JSON.stringify(r);if(a in t)return Promise.resolve(e.serializable?JSON.parse(t[a]):t[a]);let o=s(),d=n&&n.miss||(()=>Promise.resolve());return o.then(y=>d(y)).then(()=>o)},set(r,s){return t[JSON.stringify(r)]=e.serializable?JSON.stringify(s):s,Promise.resolve(s)},delete(r){return delete t[JSON.stringify(r)],Promise.resolve()},clear(){return t={},Promise.resolve()}}}ae.createInMemoryCache=Jt});var we=I((Vs,Me)=>{Me.exports=Te()});var Ce=I(M=>{"use strict";Object.defineProperty(M,"__esModule",{value:!0});function Xt(e,t,r){let s={"x-algolia-api-key":r,"x-algolia-application-id":t};return{headers(){return e===oe.WithinHeaders?s:{}},queryParameters(){return e===oe.WithinQueryParameters?s:{}}}}function Yt(e){let t=0,r=()=>(t++,new Promise(s=>{setTimeout(()=>{s(e(r))},Math.min(100*t,1e3))}));return e(r)}function ke(e,t=(r,s)=>Promise.resolve()){return Object.assign(e,{wait(r){return ke(e.then(s=>Promise.all([t(s,r),s])).then(s=>s[1]))}})}function Zt(e){let t=e.length-1;for(t;t>0;t--){let r=Math.floor(Math.random()*(t+1)),s=e[t];e[t]=e[r],e[r]=s}return e}function er(e,t){return Object.keys(t!==void 0?t:{}).forEach(r=>{e[r]=t[r](e)}),e}function tr(e,...t){let r=0;return e.replace(/%s/g,()=>encodeURIComponent(t[r++]))}var rr="4.2.0",sr=e=>()=>e.transporter.requester.destroy(),oe={WithinQueryParameters:0,WithinHeaders:1};M.AuthMode=oe;M.addMethods=er;M.createAuth=Xt;M.createRetryablePromise=Yt;M.createWaitablePromise=ke;M.destroy=sr;M.encode=tr;M.shuffle=Zt;M.version=rr});var F=I((Js,Ue)=>{Ue.exports=Ce()});var Ne=I(ie=>{"use strict";Object.defineProperty(ie,"__esModule",{value:!0});var nr={Delete:"DELETE",Get:"GET",Post:"POST",Put:"PUT"};ie.MethodEnum=nr});var B=I((Ys,We)=>{We.exports=Ne()});var Ze=I(A=>{"use strict";Object.defineProperty(A,"__esModule",{value:!0});var He=B();function ce(e,t){let r=e||{},s=r.data||{};return Object.keys(r).forEach(n=>{["timeout","headers","queryParameters","data","cacheable"].indexOf(n)===-1&&(s[n]=r[n])}),{data:Object.entries(s).length>0?s:void 0,timeout:r.timeout||t,headers:r.headers||{},queryParameters:r.queryParameters||{},cacheable:r.cacheable}}var X={Read:1,Write:2,Any:3},U={Up:1,Down:2,Timeouted:3},_e=2*60*1e3;function ue(e,t=U.Up){return g(u({},e),{status:t,lastUpdate:Date.now()})}function Fe(e){return e.status===U.Up||Date.now()-e.lastUpdate>_e}function Be(e){return e.status===U.Timeouted&&Date.now()-e.lastUpdate<=_e}function le(e){return{protocol:e.protocol||"https",url:e.url,accept:e.accept||X.Any}}function ar(e,t){return Promise.all(t.map(r=>e.get(r,()=>Promise.resolve(ue(r))))).then(r=>{let s=r.filter(d=>Fe(d)),n=r.filter(d=>Be(d)),a=[...s,...n],o=a.length>0?a.map(d=>le(d)):t;return{getTimeout(d,y){return(n.length===0&&d===0?1:n.length+3+d)*y},statelessHosts:o}})}var or=({isTimedOut:e,status:t})=>!e&&~~t==0,ir=e=>{let t=e.status;return e.isTimedOut||or(e)||~~(t/100)!=2&&~~(t/100)!=4},cr=({status:e})=>~~(e/100)==2,ur=(e,t)=>ir(e)?t.onRetry(e):cr(e)?t.onSucess(e):t.onFail(e);function Qe(e,t,r,s){let n=[],a=$e(r,s),o=Le(e,s),d=r.method,y=r.method!==He.MethodEnum.Get?{}:u(u({},r.data),s.data),b=u(u(u({"x-algolia-agent":e.userAgent.value},e.queryParameters),y),s.queryParameters),f=0,p=(h,S)=>{let O=h.pop();if(O===void 0)throw Ve(de(n));let P={data:a,headers:o,method:d,url:Ge(O,r.path,b),connectTimeout:S(f,e.timeouts.connect),responseTimeout:S(f,s.timeout)},x=j=>{let T={request:P,response:j,host:O,triesLeft:h.length};return n.push(T),T},v={onSucess:j=>Ke(j),onRetry(j){let T=x(j);return j.isTimedOut&&f++,Promise.all([e.logger.info("Retryable failure",pe(T)),e.hostsCache.set(O,ue(O,j.isTimedOut?U.Timeouted:U.Down))]).then(()=>p(h,S))},onFail(j){throw x(j),ze(j,de(n))}};return e.requester.send(P).then(j=>ur(j,v))};return ar(e.hostsCache,t).then(h=>p([...h.statelessHosts].reverse(),h.getTimeout))}function lr(e){let{hostsCache:t,logger:r,requester:s,requestsCache:n,responsesCache:a,timeouts:o,userAgent:d,hosts:y,queryParameters:b,headers:f}=e,p={hostsCache:t,logger:r,requester:s,requestsCache:n,responsesCache:a,timeouts:o,userAgent:d,headers:f,queryParameters:b,hosts:y.map(h=>le(h)),read(h,S){let O=ce(S,p.timeouts.read),P=()=>Qe(p,p.hosts.filter(j=>(j.accept&X.Read)!=0),h,O);if((O.cacheable!==void 0?O.cacheable:h.cacheable)!==!0)return P();let v={request:h,mappedRequestOptions:O,transporter:{queryParameters:p.queryParameters,headers:p.headers}};return p.responsesCache.get(v,()=>p.requestsCache.get(v,()=>p.requestsCache.set(v,P()).then(j=>Promise.all([p.requestsCache.delete(v),j]),j=>Promise.all([p.requestsCache.delete(v),Promise.reject(j)])).then(([j,T])=>T)),{miss:j=>p.responsesCache.set(v,j)})},write(h,S){return Qe(p,p.hosts.filter(O=>(O.accept&X.Write)!=0),h,ce(S,p.timeouts.write))}};return p}function dr(e){let t={value:`Algolia for JavaScript (${e})`,add(r){let s=`; ${r.segment}${r.version!==void 0?` (${r.version})`:""}`;return t.value.indexOf(s)===-1&&(t.value=`${t.value}${s}`),t}};return t}function Ke(e){try{return JSON.parse(e.content)}catch(t){throw Je(t.message,e)}}function ze({content:e,status:t},r){let s=e;try{s=JSON.parse(e).message}catch(n){}return Xe(s,t,r)}function pr(e,...t){let r=0;return e.replace(/%s/g,()=>encodeURIComponent(t[r++]))}function Ge(e,t,r){let s=Ye(r),n=`${e.protocol}://${e.url}/${t.charAt(0)==="/"?t.substr(1):t}`;return s.length&&(n+=`?${s}`),n}function Ye(e){let t=r=>Object.prototype.toString.call(r)==="[object Object]"||Object.prototype.toString.call(r)==="[object Array]";return Object.keys(e).map(r=>pr("%s=%s",r,t(e[r])?JSON.stringify(e[r]):e[r])).join("&")}function $e(e,t){if(e.method===He.MethodEnum.Get||e.data===void 0&&t.data===void 0)return;let r=Array.isArray(e.data)?e.data:u(u({},e.data),t.data);return JSON.stringify(r)}function Le(e,t){let r=u(u({},e.headers),t.headers),s={};return Object.keys(r).forEach(n=>{let a=r[n];s[n.toLowerCase()]=a}),s}function de(e){return e.map(t=>pe(t))}function pe(e){let t=e.request.headers["x-algolia-api-key"]?{"x-algolia-api-key":"*****"}:{};return g(u({},e),{request:g(u({},e.request),{headers:u(u({},e.request.headers),t)})})}function Xe(e,t,r){return{name:"ApiError",message:e,status:t,transporterStackTrace:r}}function Je(e,t){return{name:"DeserializationError",message:e,response:t}}function Ve(e){return{name:"RetryError",message:"Unreachable hosts - your application id may be incorrect. If the error persists, contact support@algolia.com.",transporterStackTrace:e}}A.CallEnum=X;A.HostStatusEnum=U;A.createApiError=Xe;A.createDeserializationError=Je;A.createMappedRequestOptions=ce;A.createRetryError=Ve;A.createStatefulHost=ue;A.createStatelessHost=le;A.createTransporter=lr;A.createUserAgent=dr;A.deserializeFailure=ze;A.deserializeSuccess=Ke;A.isStatefulHostTimeouted=Be;A.isStatefulHostUp=Fe;A.serializeData=$e;A.serializeHeaders=Le;A.serializeQueryParameters=Ye;A.serializeUrl=Ge;A.stackFrameWithoutCredentials=pe;A.stackTraceWithoutCredentials=de});var K=I((en,et)=>{et.exports=Ze()});var tt=I(w=>{"use strict";Object.defineProperty(w,"__esModule",{value:!0});var N=F(),mr=K(),z=B(),hr=e=>{let t=e.region||"us",r=N.createAuth(N.AuthMode.WithinHeaders,e.appId,e.apiKey),s=mr.createTransporter(g(u({hosts:[{url:`analytics.${t}.algolia.com`}]},e),{headers:u(g(u({},r.headers()),{"content-type":"application/json"}),e.headers),queryParameters:u(u({},r.queryParameters()),e.queryParameters)})),n=e.appId;return N.addMethods({appId:n,transporter:s},e.methods)},yr=e=>(t,r)=>e.transporter.write({method:z.MethodEnum.Post,path:"2/abtests",data:t},r),gr=e=>(t,r)=>e.transporter.write({method:z.MethodEnum.Delete,path:N.encode("2/abtests/%s",t)},r),fr=e=>(t,r)=>e.transporter.read({method:z.MethodEnum.Get,path:N.encode("2/abtests/%s",t)},r),br=e=>t=>e.transporter.read({method:z.MethodEnum.Get,path:"2/abtests"},t),Pr=e=>(t,r)=>e.transporter.write({method:z.MethodEnum.Post,path:N.encode("2/abtests/%s/stop",t)},r);w.addABTest=yr;w.createAnalyticsClient=hr;w.deleteABTest=gr;w.getABTest=fr;w.getABTests=br;w.stopABTest=Pr});var st=I((rn,rt)=>{rt.exports=tt()});var at=I(G=>{"use strict";Object.defineProperty(G,"__esModule",{value:!0});var me=F(),jr=K(),nt=B(),Or=e=>{let t=e.region||"us",r=me.createAuth(me.AuthMode.WithinHeaders,e.appId,e.apiKey),s=jr.createTransporter(g(u({hosts:[{url:`recommendation.${t}.algolia.com`}]},e),{headers:u(g(u({},r.headers()),{"content-type":"application/json"}),e.headers),queryParameters:u(u({},r.queryParameters()),e.queryParameters)}));return me.addMethods({appId:e.appId,transporter:s},e.methods)},Ir=e=>t=>e.transporter.read({method:nt.MethodEnum.Get,path:"1/strategies/personalization"},t),Ar=e=>(t,r)=>e.transporter.write({method:nt.MethodEnum.Post,path:"1/strategies/personalization",data:t},r);G.createRecommendationClient=Or;G.getPersonalizationStrategy=Ir;G.setPersonalizationStrategy=Ar});var it=I((nn,ot)=>{ot.exports=at()});var jt=I(i=>{"use strict";Object.defineProperty(i,"__esModule",{value:!0});var l=F(),q=K(),m=B(),Sr=require("crypto");function Y(e){let t=r=>e.request(r).then(s=>{if(e.batch!==void 0&&e.batch(s.hits),!e.shouldStop(s))return s.cursor?t({cursor:s.cursor}):t({page:(r.page||0)+1})});return t({})}var Dr=e=>{let t=e.appId,r=l.createAuth(e.authMode!==void 0?e.authMode:l.AuthMode.WithinHeaders,t,e.apiKey),s=q.createTransporter(g(u({hosts:[{url:`${t}-dsn.algolia.net`,accept:q.CallEnum.Read},{url:`${t}.algolia.net`,accept:q.CallEnum.Write}].concat(l.shuffle([{url:`${t}-1.algolianet.com`},{url:`${t}-2.algolianet.com`},{url:`${t}-3.algolianet.com`}]))},e),{headers:u(g(u({},r.headers()),{"content-type":"application/x-www-form-urlencoded"}),e.headers),queryParameters:u(u({},r.queryParameters()),e.queryParameters)})),n={transporter:s,appId:t,addAlgoliaAgent(a,o){s.userAgent.add({segment:a,version:o})},clearCache(){return Promise.all([s.requestsCache.clear(),s.responsesCache.clear()]).then(()=>{})}};return l.addMethods(n,e.methods)};function ct(){return{name:"MissingObjectIDError",message:"All objects must have an unique objectID (like a primary key) to be valid. Algolia is also able to generate objectIDs automatically but *it's not recommended*. To do it, use the `{'autoGenerateObjectIDIfNotExist': true}` option."}}function ut(){return{name:"ObjectNotFoundError",message:"Object not found."}}function lt(){return{name:"ValidUntilNotFoundError",message:"ValidUntil not found in given secured api key."}}var Rr=e=>(t,r)=>{let d=r||{},{queryParameters:s}=d,n=R(d,["queryParameters"]),a=u({acl:t},s!==void 0?{queryParameters:s}:{}),o=(y,b)=>l.createRetryablePromise(f=>$(e)(y.key,b).catch(p=>{if(p.status!==404)throw p;return f()}));return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:"1/keys",data:a},n),o)},vr=e=>(t,r,s)=>{let n=q.createMappedRequestOptions(s);return n.queryParameters["X-Algolia-User-ID"]=t,e.transporter.write({method:m.MethodEnum.Post,path:"1/clusters/mapping",data:{cluster:r}},n)},xr=e=>(t,r,s)=>e.transporter.write({method:m.MethodEnum.Post,path:"1/clusters/mapping/batch",data:{users:t,cluster:r}},s),Z=e=>(t,r,s)=>{let n=(a,o)=>L(e)(t,{methods:{waitTask:D}}).waitTask(a.taskID,o);return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/operation",t),data:{operation:"copy",destination:r}},s),n)},qr=e=>(t,r,s)=>Z(e)(t,r,g(u({},s),{scope:[ee.Rules]})),Er=e=>(t,r,s)=>Z(e)(t,r,g(u({},s),{scope:[ee.Settings]})),Tr=e=>(t,r,s)=>Z(e)(t,r,g(u({},s),{scope:[ee.Synonyms]})),Mr=e=>(t,r)=>{let s=(n,a)=>l.createRetryablePromise(o=>$(e)(t,a).then(o).catch(d=>{if(d.status!==404)throw d}));return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Delete,path:l.encode("1/keys/%s",t)},r),s)},wr=()=>(e,t)=>{let r=q.serializeQueryParameters(t),s=Sr.createHmac("sha256",e).update(r).digest("hex");return Buffer.from(s+r).toString("base64")},$=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Get,path:l.encode("1/keys/%s",t)},r),kr=e=>t=>e.transporter.read({method:m.MethodEnum.Get,path:"1/logs"},t),Cr=()=>e=>{let t=Buffer.from(e,"base64").toString("ascii"),r=/validUntil=(\d+)/,s=t.match(r);if(s===null)throw lt();return parseInt(s[1],10)-Math.round(new Date().getTime()/1e3)},Ur=e=>t=>e.transporter.read({method:m.MethodEnum.Get,path:"1/clusters/mapping/top"},t),Nr=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Get,path:l.encode("1/clusters/mapping/%s",t)},r),Wr=e=>t=>{let n=t||{},{retrieveMappings:r}=n,s=R(n,["retrieveMappings"]);return r===!0&&(s.getClusters=!0),e.transporter.read({method:m.MethodEnum.Get,path:"1/clusters/mapping/pending"},s)},L=e=>(t,r={})=>{let s={transporter:e.transporter,appId:e.appId,indexName:t};return l.addMethods(s,r.methods)},Hr=e=>t=>e.transporter.read({method:m.MethodEnum.Get,path:"1/keys"},t),_r=e=>t=>e.transporter.read({method:m.MethodEnum.Get,path:"1/clusters"},t),Fr=e=>t=>e.transporter.read({method:m.MethodEnum.Get,path:"1/indexes"},t),Br=e=>t=>e.transporter.read({method:m.MethodEnum.Get,path:"1/clusters/mapping"},t),Kr=e=>(t,r,s)=>{let n=(a,o)=>L(e)(t,{methods:{waitTask:D}}).waitTask(a.taskID,o);return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/operation",t),data:{operation:"move",destination:r}},s),n)},zr=e=>(t,r)=>{let s=(n,a)=>Promise.all(Object.keys(n.taskID).map(o=>L(e)(o,{methods:{waitTask:D}}).waitTask(n.taskID[o],a)));return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:"1/indexes/*/batch",data:{requests:t}},r),s)},Gr=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Post,path:"1/indexes/*/objects",data:{requests:t}},r),$r=e=>(t,r)=>{let s=t.map(n=>g(u({},n),{params:q.serializeQueryParameters(n.params||{})}));return e.transporter.read({method:m.MethodEnum.Post,path:"1/indexes/*/queries",data:{requests:s},cacheable:!0},r)},Lr=e=>(t,r)=>Promise.all(t.map(s=>{let d=s.params,{facetName:n,facetQuery:a}=d,o=R(d,["facetName","facetQuery"]);return L(e)(s.indexName,{methods:{searchForFacetValues:dt}}).searchForFacetValues(n,a,u(u({},r),o))})),Vr=e=>(t,r)=>{let s=q.createMappedRequestOptions(r);return s.queryParameters["X-Algolia-User-ID"]=t,e.transporter.write({method:m.MethodEnum.Delete,path:"1/clusters/mapping"},s)},Qr=e=>(t,r)=>{let s=(n,a)=>l.createRetryablePromise(o=>$(e)(t,a).catch(d=>{if(d.status!==404)throw d;return o()}));return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/keys/%s/restore",t)},r),s)},Jr=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Post,path:"1/clusters/mapping/search",data:{query:t}},r),Xr=e=>(t,r)=>{let s=Object.assign({},r),f=r||{},{queryParameters:n}=f,a=R(f,["queryParameters"]),o=n?{queryParameters:n}:{},d=["acl","indexes","referers","restrictSources","queryParameters","description","maxQueriesPerIPPerHour","maxHitsPerQuery"],y=p=>Object.keys(s).filter(h=>d.indexOf(h)!==-1).every(h=>p[h]===s[h]),b=(p,h)=>l.createRetryablePromise(S=>$(e)(t,h).then(O=>y(O)?Promise.resolve():S()));return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Put,path:l.encode("1/keys/%s",t),data:o},a),b)},pt=e=>(t,r)=>{let s=(n,a)=>D(e)(n.taskID,a);return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/batch",e.indexName),data:{requests:t}},r),s)},Yr=e=>t=>Y(g(u({},t),{shouldStop:r=>r.cursor===void 0,request:r=>e.transporter.read({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/browse",e.indexName),data:r},t)})),Zr=e=>t=>{let r=u({hitsPerPage:1e3},t);return Y(g(u({},r),{shouldStop:s=>s.hits.lengthg(u({},n),{hits:n.hits.map(a=>(delete a._highlightResult,a))}))}}))},es=e=>t=>{let r=u({hitsPerPage:1e3},t);return Y(g(u({},r),{shouldStop:s=>s.hits.lengthg(u({},n),{hits:n.hits.map(a=>(delete a._highlightResult,a))}))}}))},te=e=>(t,r,s)=>{let y=s||{},{batchSize:n}=y,a=R(y,["batchSize"]),o={taskIDs:[],objectIDs:[]},d=(b=0)=>{let f=[],p;for(p=b;p({action:r,body:h})),a).then(h=>(o.objectIDs=o.objectIDs.concat(h.objectIDs),o.taskIDs.push(h.taskID),p++,d(p)))};return l.createWaitablePromise(d(),(b,f)=>Promise.all(b.taskIDs.map(p=>D(e)(p,f))))},ts=e=>t=>l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/clear",e.indexName)},t),(r,s)=>D(e)(r.taskID,s)),rs=e=>t=>{let a=t||{},{forwardToReplicas:r}=a,s=R(a,["forwardToReplicas"]),n=q.createMappedRequestOptions(s);return r&&(n.queryParameters.forwardToReplicas=1),l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/rules/clear",e.indexName)},n),(o,d)=>D(e)(o.taskID,d))},ss=e=>t=>{let a=t||{},{forwardToReplicas:r}=a,s=R(a,["forwardToReplicas"]),n=q.createMappedRequestOptions(s);return r&&(n.queryParameters.forwardToReplicas=1),l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/synonyms/clear",e.indexName)},n),(o,d)=>D(e)(o.taskID,d))},ns=e=>(t,r)=>l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/deleteByQuery",e.indexName),data:t},r),(s,n)=>D(e)(s.taskID,n)),as=e=>t=>l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Delete,path:l.encode("1/indexes/%s",e.indexName)},t),(r,s)=>D(e)(r.taskID,s)),os=e=>(t,r)=>l.createWaitablePromise(yt(e)([t],r).then(s=>({taskID:s.taskIDs[0]})),(s,n)=>D(e)(s.taskID,n)),yt=e=>(t,r)=>{let s=t.map(n=>({objectID:n}));return te(e)(s,k.DeleteObject,r)},is=e=>(t,r)=>{let o=r||{},{forwardToReplicas:s}=o,n=R(o,["forwardToReplicas"]),a=q.createMappedRequestOptions(n);return s&&(a.queryParameters.forwardToReplicas=1),l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Delete,path:l.encode("1/indexes/%s/rules/%s",e.indexName,t)},a),(d,y)=>D(e)(d.taskID,y))},cs=e=>(t,r)=>{let o=r||{},{forwardToReplicas:s}=o,n=R(o,["forwardToReplicas"]),a=q.createMappedRequestOptions(n);return s&&(a.queryParameters.forwardToReplicas=1),l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Delete,path:l.encode("1/indexes/%s/synonyms/%s",e.indexName,t)},a),(d,y)=>D(e)(d.taskID,y))},us=e=>t=>gt(e)(t).then(()=>!0).catch(r=>{if(r.status!==404)throw r;return!1}),ls=e=>(t,r)=>{let y=r||{},{query:s,paginate:n}=y,a=R(y,["query","paginate"]),o=0,d=()=>ft(e)(s||"",g(u({},a),{page:o})).then(b=>{for(let[f,p]of Object.entries(b.hits))if(t(p))return{object:p,position:parseInt(f,10),page:o};if(o++,n===!1||o>=b.nbPages)throw ut();return d()});return d()},ds=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Get,path:l.encode("1/indexes/%s/%s",e.indexName,t)},r),ps=()=>(e,t)=>{for(let[r,s]of Object.entries(e.hits))if(s.objectID===t)return parseInt(r,10);return-1},ms=e=>(t,r)=>{let o=r||{},{attributesToRetrieve:s}=o,n=R(o,["attributesToRetrieve"]),a=t.map(d=>u({indexName:e.indexName,objectID:d},s?{attributesToRetrieve:s}:{}));return e.transporter.read({method:m.MethodEnum.Post,path:"1/indexes/*/objects",data:{requests:a}},n)},hs=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Get,path:l.encode("1/indexes/%s/rules/%s",e.indexName,t)},r),gt=e=>t=>e.transporter.read({method:m.MethodEnum.Get,path:l.encode("1/indexes/%s/settings",e.indexName),data:{getVersion:2}},t),ys=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Get,path:l.encode("1/indexes/%s/synonyms/%s",e.indexName,t)},r),bt=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Get,path:l.encode("1/indexes/%s/task/%s",e.indexName,t.toString())},r),gs=e=>(t,r)=>l.createWaitablePromise(Pt(e)([t],r).then(s=>({objectID:s.objectIDs[0],taskID:s.taskIDs[0]})),(s,n)=>D(e)(s.taskID,n)),Pt=e=>(t,r)=>{let o=r||{},{createIfNotExists:s}=o,n=R(o,["createIfNotExists"]),a=s?k.PartialUpdateObject:k.PartialUpdateObjectNoCreate;return te(e)(t,a,n)},fs=e=>(t,r)=>{let O=r||{},{safe:s,autoGenerateObjectIDIfNotExist:n,batchSize:a}=O,o=R(O,["safe","autoGenerateObjectIDIfNotExist","batchSize"]),d=(P,x,v,j)=>l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/operation",P),data:{operation:v,destination:x}},j),(T,V)=>D(e)(T.taskID,V)),y=Math.random().toString(36).substring(7),b=`${e.indexName}_tmp_${y}`,f=he({appId:e.appId,transporter:e.transporter,indexName:b}),p=[],h=d(e.indexName,b,"copy",g(u({},o),{scope:["settings","synonyms","rules"]}));p.push(h);let S=(s?h.wait(o):h).then(()=>{let P=f(t,g(u({},o),{autoGenerateObjectIDIfNotExist:n,batchSize:a}));return p.push(P),s?P.wait(o):P}).then(()=>{let P=d(b,e.indexName,"move",o);return p.push(P),s?P.wait(o):P}).then(()=>Promise.all(p)).then(([P,x,v])=>({objectIDs:x.objectIDs,taskIDs:[P.taskID,...x.taskIDs,v.taskID]}));return l.createWaitablePromise(S,(P,x)=>Promise.all(p.map(v=>v.wait(x))))},bs=e=>(t,r)=>ye(e)(t,g(u({},r),{clearExistingRules:!0})),Ps=e=>(t,r)=>ge(e)(t,g(u({},r),{replaceExistingSynonyms:!0})),js=e=>(t,r)=>l.createWaitablePromise(he(e)([t],r).then(s=>({objectID:s.objectIDs[0],taskID:s.taskIDs[0]})),(s,n)=>D(e)(s.taskID,n)),he=e=>(t,r)=>{let o=r||{},{autoGenerateObjectIDIfNotExist:s}=o,n=R(o,["autoGenerateObjectIDIfNotExist"]),a=s?k.AddObject:k.UpdateObject;if(a===k.UpdateObject){for(let d of t)if(d.objectID===void 0)return l.createWaitablePromise(Promise.reject(ct()))}return te(e)(t,a,n)},Os=e=>(t,r)=>ye(e)([t],r),ye=e=>(t,r)=>{let d=r||{},{forwardToReplicas:s,clearExistingRules:n}=d,a=R(d,["forwardToReplicas","clearExistingRules"]),o=q.createMappedRequestOptions(a);return s&&(o.queryParameters.forwardToReplicas=1),n&&(o.queryParameters.clearExistingRules=1),l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/rules/batch",e.indexName),data:t},o),(y,b)=>D(e)(y.taskID,b))},Is=e=>(t,r)=>ge(e)([t],r),ge=e=>(t,r)=>{let d=r||{},{forwardToReplicas:s,replaceExistingSynonyms:n}=d,a=R(d,["forwardToReplicas","replaceExistingSynonyms"]),o=q.createMappedRequestOptions(a);return s&&(o.queryParameters.forwardToReplicas=1),n&&(o.queryParameters.replaceExistingSynonyms=1),l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/synonyms/batch",e.indexName),data:t},o),(y,b)=>D(e)(y.taskID,b))},ft=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/query",e.indexName),data:{query:t},cacheable:!0},r),dt=e=>(t,r,s)=>e.transporter.read({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/facets/%s/query",e.indexName,t),data:{facetQuery:r},cacheable:!0},s),mt=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/rules/search",e.indexName),data:{query:t}},r),ht=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/synonyms/search",e.indexName),data:{query:t}},r),As=e=>(t,r)=>{let o=r||{},{forwardToReplicas:s}=o,n=R(o,["forwardToReplicas"]),a=q.createMappedRequestOptions(n);return s&&(a.queryParameters.forwardToReplicas=1),l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Put,path:l.encode("1/indexes/%s/settings",e.indexName),data:t},a),(d,y)=>D(e)(d.taskID,y))},D=e=>(t,r)=>l.createRetryablePromise(s=>bt(e)(t,r).then(n=>n.status!=="published"?s():void 0)),Ss={AddObject:"addObject",Analytics:"analytics",Browser:"browse",DeleteIndex:"deleteIndex",DeleteObject:"deleteObject",EditSettings:"editSettings",ListIndexes:"listIndexes",Logs:"logs",Recommendation:"recommendation",Search:"search",SeeUnretrievableAttributes:"seeUnretrievableAttributes",Settings:"settings",Usage:"usage"},k={AddObject:"addObject",UpdateObject:"updateObject",PartialUpdateObject:"partialUpdateObject",PartialUpdateObjectNoCreate:"partialUpdateObjectNoCreate",DeleteObject:"deleteObject"},ee={Settings:"settings",Synonyms:"synonyms",Rules:"rules"},Ds={None:"none",StopIfEnoughMatches:"stopIfEnoughMatches"},Rs={Synonym:"synonym",OneWaySynonym:"oneWaySynonym",AltCorrection1:"altCorrection1",AltCorrection2:"altCorrection2",Placeholder:"placeholder"};i.ApiKeyACLEnum=Ss;i.BatchActionEnum=k;i.ScopeEnum=ee;i.StrategyEnum=Ds;i.SynonymEnum=Rs;i.addApiKey=Rr;i.assignUserID=vr;i.assignUserIDs=xr;i.batch=pt;i.browseObjects=Yr;i.browseRules=Zr;i.browseSynonyms=es;i.chunkedBatch=te;i.clearObjects=ts;i.clearRules=rs;i.clearSynonyms=ss;i.copyIndex=Z;i.copyRules=qr;i.copySettings=Er;i.copySynonyms=Tr;i.createBrowsablePromise=Y;i.createMissingObjectIDError=ct;i.createObjectNotFoundError=ut;i.createSearchClient=Dr;i.createValidUntilNotFoundError=lt;i.deleteApiKey=Mr;i.deleteBy=ns;i.deleteIndex=as;i.deleteObject=os;i.deleteObjects=yt;i.deleteRule=is;i.deleteSynonym=cs;i.exists=us;i.findObject=ls;i.generateSecuredApiKey=wr;i.getApiKey=$;i.getLogs=kr;i.getObject=ds;i.getObjectPosition=ps;i.getObjects=ms;i.getRule=hs;i.getSecuredApiKeyRemainingValidity=Cr;i.getSettings=gt;i.getSynonym=ys;i.getTask=bt;i.getTopUserIDs=Ur;i.getUserID=Nr;i.hasPendingMappings=Wr;i.initIndex=L;i.listApiKeys=Hr;i.listClusters=_r;i.listIndices=Fr;i.listUserIDs=Br;i.moveIndex=Kr;i.multipleBatch=zr;i.multipleGetObjects=Gr;i.multipleQueries=$r;i.multipleSearchForFacetValues=Lr;i.partialUpdateObject=gs;i.partialUpdateObjects=Pt;i.removeUserID=Vr;i.replaceAllObjects=fs;i.replaceAllRules=bs;i.replaceAllSynonyms=Ps;i.restoreApiKey=Qr;i.saveObject=js;i.saveObjects=he;i.saveRule=Os;i.saveRules=ye;i.saveSynonym=Is;i.saveSynonyms=ge;i.search=ft;i.searchForFacetValues=dt;i.searchRules=mt;i.searchSynonyms=ht;i.searchUserIDs=Jr;i.setSettings=As;i.updateApiKey=Xr;i.waitTask=D});var It=I((on,Ot)=>{Ot.exports=jt()});var At=I(re=>{"use strict";Object.defineProperty(re,"__esModule",{value:!0});function vs(){return{debug(e,t){return Promise.resolve()},info(e,t){return Promise.resolve()},error(e,t){return Promise.resolve()}}}var xs={Debug:1,Info:2,Error:3};re.LogLevelEnum=xs;re.createNullLogger=vs});var Dt=I((un,St)=>{St.exports=At()});var xt=I(fe=>{"use strict";Object.defineProperty(fe,"__esModule",{value:!0});var Rt=require("http"),vt=require("https"),qs=require("url");function Es(){let e={keepAlive:!0},t=new Rt.Agent(e),r=new vt.Agent(e);return{send(s){return new Promise(n=>{let a=qs.parse(s.url),o=a.query===null?a.pathname:`${a.pathname}?${a.query}`,d=u({agent:a.protocol==="https:"?r:t,hostname:a.hostname,path:o,method:s.method,headers:s.headers},a.port!==void 0?{port:a.port||""}:{}),y=(a.protocol==="https:"?vt:Rt).request(d,h=>{let S="";h.on("data",O=>S+=O),h.on("end",()=>{clearTimeout(f),clearTimeout(p),n({status:h.statusCode||0,content:S,isTimedOut:!1})})}),b=(h,S)=>setTimeout(()=>{y.abort(),n({status:0,content:S,isTimedOut:!0})},h*1e3),f=b(s.connectTimeout,"Connection timeout"),p;y.on("error",h=>{clearTimeout(f),clearTimeout(p),n({status:0,content:h.message,isTimedOut:!1})}),y.once("response",()=>{clearTimeout(f),p=b(s.responseTimeout,"Socket timeout")}),s.data!==void 0&&y.write(s.data),y.end()})},destroy(){return t.destroy(),r.destroy(),Promise.resolve()}}}fe.createNodeHttpRequester=Es});var Et=I((dn,qt)=>{qt.exports=xt()});var kt=I((pn,Tt)=>{"use strict";var Mt=Ee(),Ts=we(),W=st(),be=F(),Pe=it(),c=It(),Ms=Dt(),ws=Et(),ks=K();function wt(e,t,r){let s={appId:e,apiKey:t,timeouts:{connect:2,read:5,write:30},requester:ws.createNodeHttpRequester(),logger:Ms.createNullLogger(),responsesCache:Mt.createNullCache(),requestsCache:Mt.createNullCache(),hostsCache:Ts.createInMemoryCache(),userAgent:ks.createUserAgent(be.version).add({segment:"Node.js",version:process.versions.node})};return c.createSearchClient(g(u(u({},s),r),{methods:{search:c.multipleQueries,searchForFacetValues:c.multipleSearchForFacetValues,multipleBatch:c.multipleBatch,multipleGetObjects:c.multipleGetObjects,multipleQueries:c.multipleQueries,copyIndex:c.copyIndex,copySettings:c.copySettings,copyRules:c.copyRules,copySynonyms:c.copySynonyms,moveIndex:c.moveIndex,listIndices:c.listIndices,getLogs:c.getLogs,listClusters:c.listClusters,multipleSearchForFacetValues:c.multipleSearchForFacetValues,getApiKey:c.getApiKey,addApiKey:c.addApiKey,listApiKeys:c.listApiKeys,updateApiKey:c.updateApiKey,deleteApiKey:c.deleteApiKey,restoreApiKey:c.restoreApiKey,assignUserID:c.assignUserID,assignUserIDs:c.assignUserIDs,getUserID:c.getUserID,searchUserIDs:c.searchUserIDs,listUserIDs:c.listUserIDs,getTopUserIDs:c.getTopUserIDs,removeUserID:c.removeUserID,hasPendingMappings:c.hasPendingMappings,generateSecuredApiKey:c.generateSecuredApiKey,getSecuredApiKeyRemainingValidity:c.getSecuredApiKeyRemainingValidity,destroy:be.destroy,initIndex:n=>a=>c.initIndex(n)(a,{methods:{batch:c.batch,delete:c.deleteIndex,getObject:c.getObject,getObjects:c.getObjects,saveObject:c.saveObject,saveObjects:c.saveObjects,search:c.search,searchForFacetValues:c.searchForFacetValues,waitTask:c.waitTask,setSettings:c.setSettings,getSettings:c.getSettings,partialUpdateObject:c.partialUpdateObject,partialUpdateObjects:c.partialUpdateObjects,deleteObject:c.deleteObject,deleteObjects:c.deleteObjects,deleteBy:c.deleteBy,clearObjects:c.clearObjects,browseObjects:c.browseObjects,getObjectPosition:c.getObjectPosition,findObject:c.findObject,exists:c.exists,saveSynonym:c.saveSynonym,saveSynonyms:c.saveSynonyms,getSynonym:c.getSynonym,searchSynonyms:c.searchSynonyms,browseSynonyms:c.browseSynonyms,deleteSynonym:c.deleteSynonym,clearSynonyms:c.clearSynonyms,replaceAllObjects:c.replaceAllObjects,replaceAllSynonyms:c.replaceAllSynonyms,searchRules:c.searchRules,getRule:c.getRule,deleteRule:c.deleteRule,saveRule:c.saveRule,saveRules:c.saveRules,replaceAllRules:c.replaceAllRules,browseRules:c.browseRules,clearRules:c.clearRules}}),initAnalytics:()=>n=>W.createAnalyticsClient(g(u(u({},s),n),{methods:{addABTest:W.addABTest,getABTest:W.getABTest,getABTests:W.getABTests,stopABTest:W.stopABTest,deleteABTest:W.deleteABTest}})),initRecommendation:()=>n=>Pe.createRecommendationClient(g(u(u({},s),n),{methods:{getPersonalizationStrategy:Pe.getPersonalizationStrategy,setPersonalizationStrategy:Pe.setPersonalizationStrategy}}))}}))}wt.version=be.version;Tt.exports=wt});var Ut=I((mn,je)=>{var Ct=kt();je.exports=Ct;je.exports.default=Ct});var Ws={};Vt(Ws,{default:()=>Ks});var Oe=C(require("@yarnpkg/core")),E=C(require("@yarnpkg/core")),Ie=C(require("@yarnpkg/plugin-essentials")),Ht=C(require("semver"));var se=C(require("@yarnpkg/core")),Nt=C(Ut()),Cs="e8e1bd300d860104bb8c58453ffa1eb4",Us="OFCNCOG2CU",Wt=async(e,t)=>{var a;let r=se.structUtils.stringifyIdent(e),n=Ns(t).initIndex("npm-search");try{return((a=(await n.getObject(r,{attributesToRetrieve:["types"]})).types)==null?void 0:a.ts)==="definitely-typed"}catch(o){return!1}},Ns=e=>(0,Nt.default)(Us,Cs,{requester:{async send(r){try{let s=await se.httpUtils.request(r.url,r.data||null,{configuration:e,headers:r.headers});return{content:s.body,isTimedOut:!1,status:s.statusCode}}catch(s){return{content:s.response.body,isTimedOut:!1,status:s.response.statusCode}}}}});var _t=e=>e.scope?`${e.scope}__${e.name}`:`${e.name}`,Hs=async(e,t,r,s)=>{if(r.scope==="types")return;let{project:n}=e,{configuration:a}=n,o=a.makeResolver(),d={project:n,resolver:o,report:new E.ThrowReport};if(!await Wt(r,a))return;let b=_t(r),f=E.structUtils.parseRange(r.range).selector;if(!E.semverUtils.validRange(f)){let P=await o.getCandidates(r,new Map,d);f=E.structUtils.parseRange(P[0].reference).selector}let p=Ht.default.coerce(f);if(p===null)return;let h=`${Ie.suggestUtils.Modifier.CARET}${p.major}`,S=E.structUtils.makeDescriptor(E.structUtils.makeIdent("types",b),h),O=E.miscUtils.mapAndFind(n.workspaces,P=>{var T,V;let x=(T=P.manifest.dependencies.get(r.identHash))==null?void 0:T.descriptorHash,v=(V=P.manifest.devDependencies.get(r.identHash))==null?void 0:V.descriptorHash;if(x!==r.descriptorHash&&v!==r.descriptorHash)return E.miscUtils.mapAndFind.skip;let j=[];for(let Ae of Oe.Manifest.allDependencies){let Se=P.manifest[Ae].get(S.identHash);typeof Se!="undefined"&&j.push([Ae,Se])}return j.length===0?E.miscUtils.mapAndFind.skip:j});if(typeof O!="undefined")for(let[P,x]of O)e.manifest[P].set(x.identHash,x);else{try{if((await o.getCandidates(S,new Map,d)).length===0)return}catch{return}e.manifest[Ie.suggestUtils.Target.DEVELOPMENT].set(S.identHash,S)}},_s=async(e,t,r)=>{if(r.scope==="types")return;let s=_t(r),n=E.structUtils.makeIdent("types",s);for(let a of Oe.Manifest.allDependencies)typeof e.manifest[a].get(n.identHash)!="undefined"&&e.manifest[a].delete(n.identHash)},Fs=(e,t)=>{t.publishConfig&&t.publishConfig.typings&&(t.typings=t.publishConfig.typings),t.publishConfig&&t.publishConfig.types&&(t.types=t.publishConfig.types)},Bs={hooks:{afterWorkspaceDependencyAddition:Hs,afterWorkspaceDependencyRemoval:_s,beforeWorkspacePacking:Fs}},Ks=Bs;return Ws;})();
7 | return plugin;
8 | }
9 | };
10 |
--------------------------------------------------------------------------------