update
This commit is contained in:
parent
df8eef5f64
commit
00257f2e68
@ -2,6 +2,9 @@ package backend_golang
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/minio/selfupdate"
|
||||
)
|
||||
|
||||
// App struct
|
||||
@ -19,3 +22,19 @@ func NewApp() *App {
|
||||
func (a *App) OnStartup(ctx context.Context) {
|
||||
a.ctx = ctx
|
||||
}
|
||||
|
||||
func (a *App) UpdateApp(url string) (broken bool, err error) {
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
err = selfupdate.Apply(resp.Body, selfupdate.Options{})
|
||||
if err != nil {
|
||||
if rerr := selfupdate.RollbackError(err); rerr != nil {
|
||||
return true, rerr
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
@ -6,12 +6,12 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func (a *App) StartServer(port int) (string, error) {
|
||||
func cmd(args ...string) (string, error) {
|
||||
cmdHelper, err := filepath.Abs("./cmd-helper")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
cmd := exec.Command(cmdHelper, "python", "./backend-python/main.py", strconv.Itoa(port))
|
||||
cmd := exec.Command(cmdHelper, args...)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return "", err
|
||||
@ -19,15 +19,10 @@ func (a *App) StartServer(port int) (string, error) {
|
||||
return string(out), nil
|
||||
}
|
||||
|
||||
func (a *App) ConvertModel(modelPath string, strategy string, outPath string) (string, error) {
|
||||
cmdHelper, err := filepath.Abs("./cmd-helper")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
cmd := exec.Command(cmdHelper, "python", "./backend-python/convert_model.py", "--in", modelPath, "--out", outPath, "--strategy", strategy)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(out), nil
|
||||
func (a *App) StartServer(port int) (string, error) {
|
||||
return cmd("python", "./backend-python/main.py", strconv.Itoa(port))
|
||||
}
|
||||
|
||||
func (a *App) ConvertModel(modelPath string, strategy string, outPath string) (string, error) {
|
||||
return cmd("python", "./backend-python/convert_model.py", "--in", modelPath, "--out", outPath, "--strategy", strategy)
|
||||
}
|
||||
|
@ -23,14 +23,16 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
import {FluentProvider, Tab, TabList, webDarkTheme} from '@fluentui/react-components';
|
||||
import {FluentProvider, Tab, TabList, webDarkTheme, webLightTheme} from '@fluentui/react-components';
|
||||
import {FC, useEffect, useState} from 'react';
|
||||
import {Route, Routes, useLocation, useNavigate} from 'react-router';
|
||||
import {pages} from './pages';
|
||||
import {useMediaQuery} from 'usehooks-ts';
|
||||
import {ToastContainer} from 'react-toastify';
|
||||
import commonStore from './stores/commonStore';
|
||||
import {observer} from 'mobx-react-lite';
|
||||
|
||||
const App: FC = () => {
|
||||
const App: FC = observer(() => {
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const mq = useMediaQuery('(min-width: 640px)');
|
||||
@ -43,7 +45,7 @@ const App: FC = () => {
|
||||
useEffect(() => setPath(location.pathname), [location]);
|
||||
|
||||
return (
|
||||
<FluentProvider theme={webDarkTheme} className="h-screen">
|
||||
<FluentProvider theme={commonStore.settings.darkMode ? webDarkTheme : webLightTheme} className="h-screen">
|
||||
<div className="flex h-full">
|
||||
<div className="flex flex-col w-16 sm:w-48 p-2 justify-between">
|
||||
<TabList
|
||||
@ -93,10 +95,10 @@ const App: FC = () => {
|
||||
rtl={false}
|
||||
pauseOnFocusLoss={false}
|
||||
draggable={false}
|
||||
theme={'dark'}
|
||||
theme={commonStore.settings.darkMode ? 'dark' : 'light'}
|
||||
/>
|
||||
</FluentProvider>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
export default App;
|
||||
|
@ -1,9 +1,21 @@
|
||||
import {FC, ReactElement} from 'react';
|
||||
import {Label, Tooltip} from '@fluentui/react-components';
|
||||
|
||||
export const Labeled: FC<{ label: string; desc?: string, content: ReactElement }> = ({label, desc, content}) => {
|
||||
export const Labeled: FC<{
|
||||
label: string; desc?: string, content: ReactElement, flex?: boolean, spaceBetween?: boolean
|
||||
}> = ({
|
||||
label,
|
||||
desc,
|
||||
content,
|
||||
flex,
|
||||
spaceBetween
|
||||
}) => {
|
||||
return (
|
||||
<div className="grid grid-cols-2 items-center">
|
||||
<div className={
|
||||
(flex ? 'flex' : 'grid grid-cols-2') + ' ' +
|
||||
(spaceBetween ? 'justify-between' : '') + ' ' +
|
||||
'items-center'
|
||||
}>
|
||||
{desc ?
|
||||
<Tooltip content={desc} showDelay={0} hideDelay={0} relationship="description">
|
||||
<Label>{label}</Label>
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, {FC, ReactElement} from 'react';
|
||||
import {Divider, Text} from '@fluentui/react-components';
|
||||
|
||||
export const Page: FC<{ title: string; content: ReactElement }> = ({title, content = true}) => {
|
||||
export const Page: FC<{ title: string; content: ReactElement }> = ({title, content}) => {
|
||||
return (
|
||||
<div className="flex flex-col gap-2 p-2 h-full">
|
||||
<Text size={600}>{title}</Text>
|
||||
|
@ -1,10 +1,13 @@
|
||||
import React, {FC} from 'react';
|
||||
import {Text} from '@fluentui/react-components';
|
||||
import {Page} from '../components/Page';
|
||||
import {PresenceBadge} from '@fluentui/react-components';
|
||||
|
||||
export const Chat: FC = () => {
|
||||
return (
|
||||
<div className="flex flex-col box-border gap-5 p-2">
|
||||
<Text size={600}>In Development</Text>
|
||||
</div>
|
||||
<Page title="Chat" content={
|
||||
<div className="flex flex-col gap-2 overflow-hidden">
|
||||
<PresenceBadge/>
|
||||
</div>
|
||||
}/>
|
||||
);
|
||||
};
|
||||
|
@ -21,7 +21,7 @@ import {DownloadFile, OpenFileFolder} from '../../wailsjs/go/backend_golang/App'
|
||||
import manifest from '../../../manifest.json';
|
||||
import {toast} from 'react-toastify';
|
||||
import {Page} from '../components/Page';
|
||||
import {refreshModels} from '../utils';
|
||||
import {refreshModels, saveConfigs} from '../utils';
|
||||
|
||||
const columns: TableColumnDefinition<ModelSourceItem>[] = [
|
||||
createTableColumn<ModelSourceItem>({
|
||||
@ -134,6 +134,7 @@ export const Models: FC = observer(() => {
|
||||
<Text weight="medium">Model Source Manifest List</Text>
|
||||
<ToolTipButton desc="Refresh" icon={<ArrowClockwise20Regular/>} onClick={() => {
|
||||
refreshModels(false);
|
||||
saveConfigs();
|
||||
}}/>
|
||||
</div>
|
||||
<Text size={100}>
|
||||
|
@ -1,10 +1,40 @@
|
||||
import React, {FC} from 'react';
|
||||
import {Text} from '@fluentui/react-components';
|
||||
import {Page} from '../components/Page';
|
||||
import {Dropdown, Option, Switch} from '@fluentui/react-components';
|
||||
import {Labeled} from '../components/Labeled';
|
||||
import commonStore from '../stores/commonStore';
|
||||
import {observer} from 'mobx-react-lite';
|
||||
|
||||
export const Settings: FC = () => {
|
||||
export const Settings: FC = observer(() => {
|
||||
return (
|
||||
<div className="flex flex-col box-border gap-5 p-2">
|
||||
<Text size={600}>In Development</Text>
|
||||
</div>
|
||||
<Page title="Settings" content={
|
||||
<div className="flex flex-col gap-2 overflow-hidden">
|
||||
<Labeled label="Language" flex spaceBetween content={
|
||||
<Dropdown style={{minWidth: 0}} listbox={{style: {minWidth: 0}}}
|
||||
value="English"
|
||||
selectedOptions={['English']}
|
||||
onOptionSelect={(_, data) => {
|
||||
if (data.optionText) {
|
||||
}
|
||||
}}>
|
||||
<Option>English</Option>
|
||||
<Option>简体中文</Option>
|
||||
</Dropdown>
|
||||
}/>
|
||||
<Labeled label="Dark Mode" flex spaceBetween content={
|
||||
<Switch checked={commonStore.settings.darkMode}
|
||||
onChange={(e, data) => {
|
||||
commonStore.setSettings({
|
||||
darkMode: data.checked
|
||||
});
|
||||
}}/>
|
||||
}/>
|
||||
<Labeled label="Automatic Updates Check" flex spaceBetween content={
|
||||
<Switch checked={commonStore.settings.autoUpdatesCheck}
|
||||
onChange={(e, data) => {
|
||||
}}/>
|
||||
}/>
|
||||
</div>
|
||||
}/>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
@ -11,6 +11,10 @@ async function initConfig() {
|
||||
await ReadJson('config.json').then((configData: LocalConfig) => {
|
||||
if (configData.modelSourceManifestList)
|
||||
commonStore.setModelSourceManifestList(configData.modelSourceManifestList);
|
||||
|
||||
if (configData.settings)
|
||||
commonStore.setSettings(configData.settings, false);
|
||||
|
||||
if (configData.modelConfigs && Array.isArray(configData.modelConfigs))
|
||||
commonStore.setModelConfigs(configData.modelConfigs, false);
|
||||
else throw new Error('Invalid config.json');
|
||||
|
@ -1,5 +1,6 @@
|
||||
import {makeAutoObservable} from 'mobx';
|
||||
import {saveConfigs} from '../utils';
|
||||
import {getNavigatorLanguage, isSystemLightMode, saveConfigs, Settings} from '../utils';
|
||||
import {WindowSetDarkTheme, WindowSetLightTheme} from '../../wailsjs/runtime';
|
||||
|
||||
export enum ModelStatus {
|
||||
Offline,
|
||||
@ -82,6 +83,11 @@ class CommonStore {
|
||||
modelConfigs: ModelConfig[] = [];
|
||||
modelSourceManifestList: string = 'https://cdn.jsdelivr.net/gh/josstorer/RWKV-Runner/manifest.json;';
|
||||
modelSourceList: ModelSourceItem[] = [];
|
||||
settings: Settings = {
|
||||
language: getNavigatorLanguage(),
|
||||
darkMode: !isSystemLightMode(),
|
||||
autoUpdatesCheck: true
|
||||
};
|
||||
|
||||
getCurrentModelConfig = () => {
|
||||
return this.modelConfigs[this.currentModelConfigIndex];
|
||||
@ -139,6 +145,18 @@ class CommonStore {
|
||||
setModelSourceList = (value: ModelSourceItem[]) => {
|
||||
this.modelSourceList = value;
|
||||
};
|
||||
|
||||
setSettings = (value: Partial<Settings>, saveConfig: boolean = true) => {
|
||||
this.settings = {...this.settings, ...value};
|
||||
|
||||
if (this.settings.darkMode)
|
||||
WindowSetDarkTheme();
|
||||
else
|
||||
WindowSetLightTheme();
|
||||
|
||||
if (saveConfig)
|
||||
saveConfigs();
|
||||
};
|
||||
}
|
||||
|
||||
export default new CommonStore();
|
@ -6,10 +6,17 @@ export type Cache = {
|
||||
models: ModelSourceItem[]
|
||||
}
|
||||
|
||||
export type Settings = {
|
||||
language: string,
|
||||
darkMode: boolean
|
||||
autoUpdatesCheck: boolean
|
||||
}
|
||||
|
||||
export type LocalConfig = {
|
||||
modelSourceManifestList: string
|
||||
currentModelConfigIndex: number
|
||||
modelConfigs: ModelConfig[]
|
||||
settings: Settings
|
||||
}
|
||||
|
||||
export async function refreshBuiltInModels(readCache: boolean = false) {
|
||||
@ -122,7 +129,8 @@ export const saveConfigs = async () => {
|
||||
const data: LocalConfig = {
|
||||
modelSourceManifestList: commonStore.modelSourceManifestList,
|
||||
currentModelConfigIndex: commonStore.currentModelConfigIndex,
|
||||
modelConfigs: commonStore.modelConfigs
|
||||
modelConfigs: commonStore.modelConfigs,
|
||||
settings: commonStore.settings
|
||||
};
|
||||
return SaveJson('config.json', data);
|
||||
};
|
||||
@ -132,4 +140,14 @@ export const saveCache = async () => {
|
||||
models: commonStore.modelSourceList
|
||||
};
|
||||
return SaveJson('cache.json', data);
|
||||
};
|
||||
};
|
||||
|
||||
export function getNavigatorLanguage() {
|
||||
// const l = navigator.language.toLowerCase();
|
||||
// if (['zh-hk', 'zh-mo', 'zh-tw', 'zh-cht', 'zh-hant'].includes(l)) return 'zhHant'
|
||||
return navigator.language.substring(0, 2);
|
||||
}
|
||||
|
||||
export function isSystemLightMode() {
|
||||
return window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches;
|
||||
}
|
2
frontend/wailsjs/go/backend_golang/App.d.ts
vendored
2
frontend/wailsjs/go/backend_golang/App.d.ts
vendored
@ -19,3 +19,5 @@ export function ReadJson(arg1:string):Promise<any>;
|
||||
export function SaveJson(arg1:string,arg2:any):Promise<void>;
|
||||
|
||||
export function StartServer(arg1:number):Promise<string>;
|
||||
|
||||
export function UpdateApp(arg1:string):Promise<boolean>;
|
||||
|
@ -37,3 +37,7 @@ export function SaveJson(arg1, arg2) {
|
||||
export function StartServer(arg1) {
|
||||
return window['go']['backend_golang']['App']['StartServer'](arg1);
|
||||
}
|
||||
|
||||
export function UpdateApp(arg1) {
|
||||
return window['go']['backend_golang']['App']['UpdateApp'](arg1);
|
||||
}
|
||||
|
2
go.mod
2
go.mod
@ -4,10 +4,12 @@ go 1.20
|
||||
|
||||
require (
|
||||
github.com/cavaliergopher/grab/v3 v3.0.1
|
||||
github.com/minio/selfupdate v0.6.0
|
||||
github.com/wailsapp/wails/v2 v2.5.1
|
||||
)
|
||||
|
||||
require (
|
||||
aead.dev/minisign v0.2.0 // indirect
|
||||
github.com/bep/debounce v1.2.1 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
|
15
go.sum
15
go.sum
@ -1,3 +1,5 @@
|
||||
aead.dev/minisign v0.2.0 h1:kAWrq/hBRu4AARY6AlciO83xhNnW9UaC8YipS2uhLPk=
|
||||
aead.dev/minisign v0.2.0/go.mod h1:zdq6LdSd9TbuSxchxwhpA9zEb9YXcVGoE8JakuiGaIQ=
|
||||
github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY=
|
||||
github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0=
|
||||
github.com/cavaliergopher/grab/v3 v3.0.1 h1:4z7TkBfmPjmLAAmkkAZNX/6QJ1nNFdv3SdIHXju0Fr4=
|
||||
@ -33,6 +35,8 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98=
|
||||
github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/minio/selfupdate v0.6.0 h1:i76PgT0K5xO9+hjzKcacQtO7+MjJ4JKA8Ak8XQ9DDwU=
|
||||
github.com/minio/selfupdate v0.6.0/go.mod h1:bO02GTIPCMQFTEvE5h4DjYB58bCoZ35XLeBf0buTDdM=
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
@ -58,17 +62,26 @@ github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhw
|
||||
github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
|
||||
github.com/wailsapp/wails/v2 v2.5.1 h1:mfG+2kWqQXYOwdgI43HEILjOZDXbk5woPYI3jP2b+js=
|
||||
github.com/wailsapp/wails/v2 v2.5.1/go.mod h1:jbOZbcr/zm79PxXxAjP8UoVlDd9wLW3uDs+isIthDfs=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
|
||||
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
||||
golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc h1:mCRnTeVUjcrhlRmO0VK8a6k6Rrf6TF9htwo2pJVSjIU=
|
||||
golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@ -77,7 +90,9 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
|
Loading…
Reference in New Issue
Block a user