mirror of https://gitee.com/namelin2022/ollama
31 changed files with 11875 additions and 9976 deletions
@ -1,6 +0,0 @@ |
|||
# build the client |
|||
|
|||
# build the go app |
|||
|
|||
# build the desktop app |
|||
|
|||
@ -1,3 +1,16 @@ |
|||
{ |
|||
"extends": "next/core-web-vitals" |
|||
"env": { |
|||
"browser": true, |
|||
"es6": true, |
|||
"node": true |
|||
}, |
|||
"extends": [ |
|||
"eslint:recommended", |
|||
"plugin:@typescript-eslint/eslint-recommended", |
|||
"plugin:@typescript-eslint/recommended", |
|||
"plugin:import/recommended", |
|||
"plugin:import/electron", |
|||
"plugin:import/typescript" |
|||
], |
|||
"parser": "@typescript-eslint/parser" |
|||
} |
|||
|
|||
@ -1,35 +1,92 @@ |
|||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. |
|||
# Logs |
|||
logs |
|||
*.log |
|||
npm-debug.log* |
|||
yarn-debug.log* |
|||
yarn-error.log* |
|||
lerna-debug.log* |
|||
|
|||
# dependencies |
|||
/node_modules |
|||
/.pnp |
|||
.pnp.js |
|||
# Diagnostic reports (https://nodejs.org/api/report.html) |
|||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json |
|||
|
|||
# testing |
|||
/coverage |
|||
# Runtime data |
|||
pids |
|||
*.pid |
|||
*.seed |
|||
*.pid.lock |
|||
.DS_Store |
|||
|
|||
# next.js |
|||
/.next/ |
|||
/out/ |
|||
# Directory for instrumented libs generated by jscoverage/JSCover |
|||
lib-cov |
|||
|
|||
# production |
|||
/build |
|||
# Coverage directory used by tools like istanbul |
|||
coverage |
|||
*.lcov |
|||
|
|||
# misc |
|||
.DS_Store |
|||
*.pem |
|||
# nyc test coverage |
|||
.nyc_output |
|||
|
|||
# debug |
|||
npm-debug.log* |
|||
yarn-debug.log* |
|||
yarn-error.log* |
|||
# node-waf configuration |
|||
.lock-wscript |
|||
|
|||
# Compiled binary addons (https://nodejs.org/api/addons.html) |
|||
build/Release |
|||
|
|||
# local env files |
|||
.env*.local |
|||
# Dependency directories |
|||
node_modules/ |
|||
jspm_packages/ |
|||
|
|||
# vercel |
|||
.vercel |
|||
# TypeScript v1 declaration files |
|||
typings/ |
|||
|
|||
# typescript |
|||
# TypeScript cache |
|||
*.tsbuildinfo |
|||
next-env.d.ts |
|||
|
|||
# Optional npm cache directory |
|||
.npm |
|||
|
|||
# Optional eslint cache |
|||
.eslintcache |
|||
|
|||
# Optional REPL history |
|||
.node_repl_history |
|||
|
|||
# Output of 'npm pack' |
|||
*.tgz |
|||
|
|||
# Yarn Integrity file |
|||
.yarn-integrity |
|||
|
|||
# dotenv environment variables file |
|||
.env |
|||
.env.test |
|||
|
|||
# parcel-bundler cache (https://parceljs.org/) |
|||
.cache |
|||
|
|||
# next.js build output |
|||
.next |
|||
|
|||
# nuxt.js build output |
|||
.nuxt |
|||
|
|||
# vuepress build output |
|||
.vuepress/dist |
|||
|
|||
# Serverless directories |
|||
.serverless/ |
|||
|
|||
# FuseBox cache |
|||
.fusebox/ |
|||
|
|||
# DynamoDB Local files |
|||
.dynamodb/ |
|||
|
|||
# Webpack |
|||
.webpack/ |
|||
|
|||
# Vite |
|||
.vite/ |
|||
|
|||
# Electron-Forge |
|||
out/ |
|||
|
|||
@ -1,34 +0,0 @@ |
|||
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). |
|||
|
|||
## Getting Started |
|||
|
|||
First, run the development server: |
|||
|
|||
```bash |
|||
npm run dev |
|||
# or |
|||
yarn dev |
|||
# or |
|||
pnpm dev |
|||
``` |
|||
|
|||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. |
|||
|
|||
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. |
|||
|
|||
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. |
|||
|
|||
## Learn More |
|||
|
|||
To learn more about Next.js, take a look at the following resources: |
|||
|
|||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. |
|||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. |
|||
|
|||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! |
|||
|
|||
## Deploy on Vercel |
|||
|
|||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. |
|||
|
|||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. |
|||
|
Before Width: | Height: | Size: 25 KiB |
@ -1,31 +0,0 @@ |
|||
import { Metadata } from 'next' |
|||
|
|||
import '@/app/globals.css' |
|||
|
|||
export const metadata: Metadata = { |
|||
title: { |
|||
default: 'Keypair', |
|||
template: `%s - Keypair`, |
|||
}, |
|||
themeColor: [ |
|||
{ media: '(prefers-color-scheme: light)', color: 'white' }, |
|||
{ media: '(prefers-color-scheme: dark)', color: 'black' }, |
|||
], |
|||
icons: { |
|||
icon: '/favicon.ico', |
|||
shortcut: '/favicon-16x16.png', |
|||
apple: '/apple-touch-icon.png', |
|||
}, |
|||
} |
|||
|
|||
interface RootLayoutProps { |
|||
children: React.ReactNode |
|||
} |
|||
|
|||
export default function RootLayout({ children }: RootLayoutProps) { |
|||
return ( |
|||
<html lang='en' suppressHydrationWarning> |
|||
<body className='flex min-h-screen w-full bg-white font-sans antialiased'>{children}</body> |
|||
</html> |
|||
) |
|||
} |
|||
@ -0,0 +1,40 @@ |
|||
import type { ForgeConfig } from '@electron-forge/shared-types' |
|||
import { MakerSquirrel } from '@electron-forge/maker-squirrel' |
|||
import { MakerZIP } from '@electron-forge/maker-zip' |
|||
import { MakerDeb } from '@electron-forge/maker-deb' |
|||
import { MakerRpm } from '@electron-forge/maker-rpm' |
|||
import { AutoUnpackNativesPlugin } from '@electron-forge/plugin-auto-unpack-natives' |
|||
import { WebpackPlugin } from '@electron-forge/plugin-webpack' |
|||
|
|||
import { mainConfig } from './webpack.main.config' |
|||
import { rendererConfig } from './webpack.renderer.config' |
|||
|
|||
const config: ForgeConfig = { |
|||
packagerConfig: { |
|||
asar: true, |
|||
}, |
|||
rebuildConfig: {}, |
|||
makers: [new MakerSquirrel({}), new MakerZIP({}, ['darwin']), new MakerRpm({}), new MakerDeb({})], |
|||
plugins: [ |
|||
new AutoUnpackNativesPlugin({}), |
|||
new WebpackPlugin({ |
|||
mainConfig, |
|||
devContentSecurityPolicy: `default-src * 'unsafe-eval' 'unsafe-inline'`, |
|||
renderer: { |
|||
config: rendererConfig, |
|||
entryPoints: [ |
|||
{ |
|||
html: './src/index.html', |
|||
js: './src/renderer.tsx', |
|||
name: 'main_window', |
|||
preload: { |
|||
js: './src/preload.ts', |
|||
}, |
|||
}, |
|||
], |
|||
}, |
|||
}), |
|||
], |
|||
} |
|||
|
|||
export default config |
|||
@ -1,5 +0,0 @@ |
|||
/// <reference types="next" />
|
|||
/// <reference types="next/image-types/global" />
|
|||
|
|||
// NOTE: This file should not be edited
|
|||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
|||
@ -1,4 +0,0 @@ |
|||
/** @type {import('next').NextConfig} */ |
|||
const nextConfig = {} |
|||
|
|||
module.exports = nextConfig |
|||
File diff suppressed because it is too large
@ -1,40 +1,61 @@ |
|||
{ |
|||
"name": "client", |
|||
"version": "0.1.0", |
|||
"private": true, |
|||
"productName": "client", |
|||
"version": "1.0.0", |
|||
"description": "Proto", |
|||
"main": ".webpack/main", |
|||
"scripts": { |
|||
"dev": "next dev", |
|||
"build": "next build", |
|||
"start": "next start", |
|||
"lint": "next lint", |
|||
"package": "next build && pkg --target latest server.js" |
|||
"start": "electron-forge start", |
|||
"package": "electron-forge package", |
|||
"make": "electron-forge make", |
|||
"publish": "electron-forge publish", |
|||
"lint": "eslint --ext .ts,.tsx ." |
|||
}, |
|||
"pkg": { |
|||
"assets": [ |
|||
".next/**/*", |
|||
"static/**/*" |
|||
], |
|||
"scripts": [ |
|||
".next/**/*.js" |
|||
] |
|||
}, |
|||
"dependencies": { |
|||
"next": "13.4.7", |
|||
"react": "18.2.0", |
|||
"react-dom": "18.2.0" |
|||
"keywords": [], |
|||
"author": { |
|||
"name": "Jeffrey Morgan", |
|||
"email": "jmorganca@gmail.com" |
|||
}, |
|||
"license": "MIT", |
|||
"devDependencies": { |
|||
"@types/node": "20.3.1", |
|||
"@types/react": "18.2.13", |
|||
"@types/react-dom": "18.2.6", |
|||
"autoprefixer": "10.4.14", |
|||
"eslint": "8.43.0", |
|||
"eslint-config-next": "13.4.7", |
|||
"pkg": "^5.8.1", |
|||
"postcss": "8.4.24", |
|||
"prettier": "^2.8.8", |
|||
"prettier-plugin-tailwindcss": "^0.3.0", |
|||
"tailwindcss": "3.3.2", |
|||
"typescript": "5.1.3" |
|||
"@babel/core": "^7.22.5", |
|||
"@babel/preset-react": "^7.22.5", |
|||
"@electron-forge/cli": "^6.2.1", |
|||
"@electron-forge/maker-deb": "^6.2.1", |
|||
"@electron-forge/maker-rpm": "^6.2.1", |
|||
"@electron-forge/maker-squirrel": "^6.2.1", |
|||
"@electron-forge/maker-zip": "^6.2.1", |
|||
"@electron-forge/plugin-auto-unpack-natives": "^6.2.1", |
|||
"@electron-forge/plugin-webpack": "^6.2.1", |
|||
"@types/react": "^18.2.14", |
|||
"@types/react-dom": "^18.2.6", |
|||
"@typescript-eslint/eslint-plugin": "^5.60.0", |
|||
"@typescript-eslint/parser": "^5.60.0", |
|||
"@vercel/webpack-asset-relocator-loader": "^1.7.3", |
|||
"babel-loader": "^9.1.2", |
|||
"css-loader": "^6.8.1", |
|||
"electron": "25.2.0", |
|||
"eslint": "^8.43.0", |
|||
"eslint-plugin-import": "^2.27.5", |
|||
"fork-ts-checker-webpack-plugin": "^7.3.0", |
|||
"node-loader": "^2.0.0", |
|||
"postcss": "^8.4.24", |
|||
"postcss-import": "^15.1.0", |
|||
"postcss-loader": "^7.3.3", |
|||
"postcss-preset-env": "^8.5.1", |
|||
"style-loader": "^3.3.3", |
|||
"tailwindcss": "^3.3.2", |
|||
"ts-loader": "^9.4.3", |
|||
"ts-node": "^10.9.1", |
|||
"typescript": "~4.5.4", |
|||
"webpack": "^5.88.0", |
|||
"webpack-cli": "^5.1.4", |
|||
"webpack-dev-server": "^4.15.1" |
|||
}, |
|||
"dependencies": { |
|||
"@types/node": "^20.3.1", |
|||
"electron-squirrel-startup": "^1.0.0", |
|||
"react": "^18.2.0", |
|||
"react-dom": "^18.2.0" |
|||
} |
|||
} |
|||
|
|||
@ -1,17 +0,0 @@ |
|||
const { createServer } = require('http') |
|||
const { parse } = require('url') |
|||
const next = require('next') |
|||
|
|||
const dev = process.env.NODE_ENV !== 'production' |
|||
const app = next({ dev }) |
|||
const handle = app.getRequestHandler() |
|||
|
|||
app.prepare().then(() => { |
|||
createServer((req, res) => { |
|||
const parsedUrl = parse(req.url, true) |
|||
handle(req, res, parsedUrl) |
|||
}).listen(process.env.PORT || 3000, err => { |
|||
if (err) throw err |
|||
console.log('> Ready on http://localhost:3000') |
|||
}) |
|||
}) |
|||
@ -0,0 +1,9 @@ |
|||
<!DOCTYPE html> |
|||
<html> |
|||
<head> |
|||
<meta charset="UTF-8" /> |
|||
</head> |
|||
<body> |
|||
<div id="app"></div> |
|||
</body> |
|||
</html> |
|||
@ -0,0 +1,2 @@ |
|||
// See the Electron documentation for details on how to use preload scripts:
|
|||
// https://www.electronjs.org/docs/latest/tutorial/process-model#preload-scripts
|
|||
@ -0,0 +1,7 @@ |
|||
import App from './app' |
|||
import './app.css' |
|||
import { createRoot } from 'react-dom/client' |
|||
|
|||
const container = document.getElementById('app') |
|||
const root = createRoot(container) |
|||
root.render(<App />) |
|||
@ -1,10 +1,6 @@ |
|||
/** @type {import('tailwindcss').Config} */ |
|||
module.exports = { |
|||
content: [ |
|||
'./pages/**/*.{js,ts,jsx,tsx,mdx}', |
|||
'./components/**/*.{js,ts,jsx,tsx,mdx}', |
|||
'./app/**/*.{js,ts,jsx,tsx,mdx}', |
|||
], |
|||
content: ['./src/**/*.{js,ts,jsx,tsx,mdx}'], |
|||
theme: {}, |
|||
plugins: [], |
|||
} |
|||
|
|||
@ -1,28 +1,20 @@ |
|||
{ |
|||
"compilerOptions": { |
|||
"target": "es5", |
|||
"lib": ["dom", "dom.iterable", "esnext"], |
|||
"target": "ES6", |
|||
"allowJs": true, |
|||
"module": "commonjs", |
|||
"skipLibCheck": true, |
|||
"strict": true, |
|||
"forceConsistentCasingInFileNames": true, |
|||
"noEmit": true, |
|||
"esModuleInterop": true, |
|||
"module": "esnext", |
|||
"noImplicitAny": true, |
|||
"sourceMap": true, |
|||
"baseUrl": ".", |
|||
"outDir": "dist", |
|||
"moduleResolution": "node", |
|||
"resolveJsonModule": true, |
|||
"isolatedModules": true, |
|||
"jsx": "preserve", |
|||
"incremental": true, |
|||
"plugins": [ |
|||
{ |
|||
"name": "next" |
|||
} |
|||
], |
|||
"paths": { |
|||
"@/*": ["./*"] |
|||
} |
|||
"*": ["node_modules/*"] |
|||
}, |
|||
"jsx": "react-jsx" |
|||
}, |
|||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], |
|||
"exclude": ["node_modules"] |
|||
"include": ["src/**/*"] |
|||
} |
|||
|
|||
@ -0,0 +1,18 @@ |
|||
import type { Configuration } from 'webpack' |
|||
|
|||
import { rules } from './webpack.rules' |
|||
|
|||
export const mainConfig: Configuration = { |
|||
/** |
|||
* This is the main entry point for your application, it's the first file |
|||
* that runs in the main process. |
|||
*/ |
|||
entry: './src/index.ts', |
|||
// Put your normal webpack config below here
|
|||
module: { |
|||
rules, |
|||
}, |
|||
resolve: { |
|||
extensions: ['.js', '.ts', '.jsx', '.tsx', '.css', '.json'], |
|||
}, |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
import type IForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin' |
|||
|
|||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|||
const ForkTsCheckerWebpackPlugin: typeof IForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin') |
|||
|
|||
export const plugins = [ |
|||
new ForkTsCheckerWebpackPlugin({ |
|||
logger: 'webpack-infrastructure', |
|||
}), |
|||
] |
|||
@ -0,0 +1,19 @@ |
|||
import type { Configuration } from 'webpack' |
|||
|
|||
import { rules } from './webpack.rules' |
|||
import { plugins } from './webpack.plugins' |
|||
|
|||
rules.push({ |
|||
test: /\.css$/, |
|||
use: [{ loader: 'style-loader' }, { loader: 'css-loader' }, { loader: 'postcss-loader' }], |
|||
}) |
|||
|
|||
export const rendererConfig: Configuration = { |
|||
module: { |
|||
rules, |
|||
}, |
|||
plugins, |
|||
resolve: { |
|||
extensions: ['.js', '.ts', '.jsx', '.tsx', '.css'], |
|||
}, |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
import type { ModuleOptions } from 'webpack' |
|||
|
|||
export const rules: Required<ModuleOptions>['rules'] = [ |
|||
// Add support for native node modules
|
|||
{ |
|||
// We're specifying native_modules in the test because the asset relocator loader generates a
|
|||
// "fake" .node file which is really a cjs file.
|
|||
test: /native_modules[/\\].+\.node$/, |
|||
use: 'node-loader', |
|||
}, |
|||
{ |
|||
test: /[/\\]node_modules[/\\].+\.(m?js|node)$/, |
|||
parser: { amd: false }, |
|||
use: { |
|||
loader: '@vercel/webpack-asset-relocator-loader', |
|||
options: { |
|||
outputAssetBase: 'native_modules', |
|||
}, |
|||
}, |
|||
}, |
|||
{ |
|||
test: /\.tsx?$/, |
|||
exclude: /(node_modules|\.webpack)/, |
|||
use: { |
|||
loader: 'ts-loader', |
|||
options: { |
|||
transpileOnly: true, |
|||
}, |
|||
}, |
|||
}, |
|||
] |
|||
@ -1,92 +0,0 @@ |
|||
# Logs |
|||
logs |
|||
*.log |
|||
npm-debug.log* |
|||
yarn-debug.log* |
|||
yarn-error.log* |
|||
lerna-debug.log* |
|||
|
|||
# Diagnostic reports (https://nodejs.org/api/report.html) |
|||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json |
|||
|
|||
# Runtime data |
|||
pids |
|||
*.pid |
|||
*.seed |
|||
*.pid.lock |
|||
.DS_Store |
|||
|
|||
# Directory for instrumented libs generated by jscoverage/JSCover |
|||
lib-cov |
|||
|
|||
# Coverage directory used by tools like istanbul |
|||
coverage |
|||
*.lcov |
|||
|
|||
# nyc test coverage |
|||
.nyc_output |
|||
|
|||
# node-waf configuration |
|||
.lock-wscript |
|||
|
|||
# Compiled binary addons (https://nodejs.org/api/addons.html) |
|||
build/Release |
|||
|
|||
# Dependency directories |
|||
node_modules/ |
|||
jspm_packages/ |
|||
|
|||
# TypeScript v1 declaration files |
|||
typings/ |
|||
|
|||
# TypeScript cache |
|||
*.tsbuildinfo |
|||
|
|||
# Optional npm cache directory |
|||
.npm |
|||
|
|||
# Optional eslint cache |
|||
.eslintcache |
|||
|
|||
# Optional REPL history |
|||
.node_repl_history |
|||
|
|||
# Output of 'npm pack' |
|||
*.tgz |
|||
|
|||
# Yarn Integrity file |
|||
.yarn-integrity |
|||
|
|||
# dotenv environment variables file |
|||
.env |
|||
.env.test |
|||
|
|||
# parcel-bundler cache (https://parceljs.org/) |
|||
.cache |
|||
|
|||
# next.js build output |
|||
.next |
|||
|
|||
# nuxt.js build output |
|||
.nuxt |
|||
|
|||
# vuepress build output |
|||
.vuepress/dist |
|||
|
|||
# Serverless directories |
|||
.serverless/ |
|||
|
|||
# FuseBox cache |
|||
.fusebox/ |
|||
|
|||
# DynamoDB Local files |
|||
.dynamodb/ |
|||
|
|||
# Webpack |
|||
.webpack/ |
|||
|
|||
# Vite |
|||
.vite/ |
|||
|
|||
# Electron-Forge |
|||
out/ |
|||
@ -1,30 +0,0 @@ |
|||
module.exports = { |
|||
packagerConfig: { |
|||
asar: true, |
|||
}, |
|||
rebuildConfig: {}, |
|||
makers: [ |
|||
{ |
|||
name: '@electron-forge/maker-squirrel', |
|||
config: {}, |
|||
}, |
|||
{ |
|||
name: '@electron-forge/maker-zip', |
|||
platforms: ['darwin'], |
|||
}, |
|||
{ |
|||
name: '@electron-forge/maker-deb', |
|||
config: {}, |
|||
}, |
|||
{ |
|||
name: '@electron-forge/maker-rpm', |
|||
config: {}, |
|||
}, |
|||
], |
|||
plugins: [ |
|||
{ |
|||
name: '@electron-forge/plugin-auto-unpack-natives', |
|||
config: {}, |
|||
}, |
|||
], |
|||
} |
|||
File diff suppressed because it is too large
@ -1,32 +0,0 @@ |
|||
{ |
|||
"name": "desktop", |
|||
"productName": "desktop", |
|||
"version": "1.0.0", |
|||
"description": "My Electron application description", |
|||
"main": "src/index.js", |
|||
"scripts": { |
|||
"start": "electron-forge start", |
|||
"package": "electron-forge package", |
|||
"make": "electron-forge make", |
|||
"publish": "electron-forge publish", |
|||
"lint": "echo \"No linting configured\"" |
|||
}, |
|||
"keywords": [], |
|||
"author": { |
|||
"name": "Jeffrey Morgan", |
|||
"email": "jeff@keypair.com" |
|||
}, |
|||
"license": "MIT", |
|||
"dependencies": { |
|||
"electron-squirrel-startup": "^1.0.0" |
|||
}, |
|||
"devDependencies": { |
|||
"@electron-forge/cli": "^6.2.1", |
|||
"@electron-forge/maker-deb": "^6.2.1", |
|||
"@electron-forge/maker-rpm": "^6.2.1", |
|||
"@electron-forge/maker-squirrel": "^6.2.1", |
|||
"@electron-forge/maker-zip": "^6.2.1", |
|||
"@electron-forge/plugin-auto-unpack-natives": "^6.2.1", |
|||
"electron": "25.1.1" |
|||
} |
|||
} |
|||
@ -1,17 +0,0 @@ |
|||
#!/bin/bash |
|||
|
|||
# Function to handle Ctrl+C |
|||
handle_sigint() { |
|||
kill $pid1 $pid2 |
|||
exit |
|||
} |
|||
|
|||
# Trap Ctrl+C signal |
|||
trap 'handle_sigint' SIGINT |
|||
|
|||
# Start three processes in the background |
|||
npm run dev --prefix ./client & pid1=$! |
|||
npm start --prefix ./desktop & pid2=$! |
|||
|
|||
# Wait for all processes to finish |
|||
wait |
|||
@ -1,2 +0,0 @@ |
|||
npm install --prefix ./client |
|||
npm install --prefix ./desktop |
|||
Loading…
Reference in new issue