mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-05-05 13:57:10 -04:00
WIP(translate): translate web category all tools
This commit is contained in:
parent
c6583ef013
commit
9db4b41daf
33 changed files with 1091 additions and 329 deletions
|
@ -1,12 +1,12 @@
|
|||
tools:
|
||||
hash-text:
|
||||
title: 文本转哈希
|
||||
description: 使用所需的函数对文本字符串进行哈希计算:MD5、SHA1、SHA256、SHA224、SHA512、SHA384、SHA3或RIPEMD160
|
||||
description: '使用所需的函数对文本字符串进行哈希计算:MD5、SHA1、SHA256、SHA224、SHA512、SHA384、SHA3或RIPEMD160'
|
||||
|
||||
textLabel: '要进行哈希的文本:'
|
||||
textPlaceholder: '要进行哈希的字符串...'
|
||||
hashLabel: 摘要编码
|
||||
binary: 二进制(基数2)
|
||||
hexadecimal: 十六进制(基数16)
|
||||
base64: Base64(基数64)
|
||||
base64url: Base64url(带有URL安全字符的基数64)
|
||||
hashLabel: '摘要编码'
|
||||
binary: '二进制(基数2)'
|
||||
hexadecimal: '十六进制(基数16)'
|
||||
base64: 'Base64(基数64)'
|
||||
base64url: 'Base64url(带有URL安全字符的基数64)'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
tools:
|
||||
html-entities:
|
||||
title: Escape html entities
|
||||
description: Escape or unescape html entities (replace <,>, &, " and \' to their html version)
|
||||
description: Escape or unescape html entities (replace <,>, &, " and ' to their html version)
|
||||
|
||||
escape:
|
||||
title: Escape html entities
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
tools:
|
||||
html-entities:
|
||||
title: 转义 HTML 实体
|
||||
description: 转义或取消转义 HTML 实体(将 <,>, &, " 和 \' 替换为它们的 HTML 版本)
|
||||
description: 转义或取消转义 HTML 实体(将 <,>, &, " 和 ' 替换为它们的 HTML 版本)
|
||||
|
||||
escape:
|
||||
title: 转义 HTML 实体
|
||||
|
|
|
@ -20,6 +20,7 @@ import {
|
|||
} from '@vicons/tabler';
|
||||
import type { Component } from 'vue';
|
||||
import MenuBarItem from './menu-bar-item.vue';
|
||||
import { translate as t } from '@/plugins/i18n.plugin';
|
||||
|
||||
const props = defineProps<{ editor: Editor }>();
|
||||
const { editor } = toRefs(props);
|
||||
|
@ -38,28 +39,28 @@ const items: MenuItem[] = [
|
|||
{
|
||||
type: 'button',
|
||||
icon: Bold,
|
||||
title: 'Bold',
|
||||
title: t('tools.html-wysiwyg-editor.bold'),
|
||||
action: () => editor.value.chain().focus().toggleBold().run(),
|
||||
isActive: () => editor.value.isActive('bold'),
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
icon: Italic,
|
||||
title: 'Italic',
|
||||
title: t('tools.html-wysiwyg-editor.italic'),
|
||||
action: () => editor.value.chain().focus().toggleItalic().run(),
|
||||
isActive: () => editor.value.isActive('italic'),
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
icon: Strikethrough,
|
||||
title: 'Strike',
|
||||
title: t('tools.html-wysiwyg-editor.strike'),
|
||||
action: () => editor.value.chain().focus().toggleStrike().run(),
|
||||
isActive: () => editor.value.isActive('strike'),
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
icon: Code,
|
||||
title: 'Inline code',
|
||||
title: t('tools.html-wysiwyg-editor.inlineCode'),
|
||||
action: () => editor.value.chain().focus().toggleCode().run(),
|
||||
isActive: () => editor.value.isActive('code'),
|
||||
},
|
||||
|
@ -69,28 +70,28 @@ const items: MenuItem[] = [
|
|||
{
|
||||
type: 'button',
|
||||
icon: H1,
|
||||
title: 'Heading 1',
|
||||
title: t('tools.html-wysiwyg-editor.heading1'),
|
||||
action: () => editor.value.chain().focus().toggleHeading({ level: 1 }).run(),
|
||||
isActive: () => editor.value.isActive('heading', { level: 1 }),
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
icon: H2,
|
||||
title: 'Heading 2',
|
||||
title: t('tools.html-wysiwyg-editor.heading2'),
|
||||
action: () => editor.value.chain().focus().toggleHeading({ level: 2 }).run(),
|
||||
isActive: () => editor.value.isActive('heading', { level: 2 }),
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
icon: H3,
|
||||
title: 'Heading 3',
|
||||
title: t('tools.html-wysiwyg-editor.heading3'),
|
||||
action: () => editor.value.chain().focus().toggleHeading({ level: 4 }).run(),
|
||||
isActive: () => editor.value.isActive('heading', { level: 4 }),
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
icon: H4,
|
||||
title: 'Heading 4',
|
||||
title: t('tools.html-wysiwyg-editor.heading4'),
|
||||
action: () => editor.value.chain().focus().toggleHeading({ level: 4 }).run(),
|
||||
isActive: () => editor.value.isActive('heading', { level: 4 }),
|
||||
},
|
||||
|
@ -100,21 +101,21 @@ const items: MenuItem[] = [
|
|||
{
|
||||
type: 'button',
|
||||
icon: List,
|
||||
title: 'Bullet list',
|
||||
title: t('tools.html-wysiwyg-editor.bulletList'),
|
||||
action: () => editor.value.chain().focus().toggleBulletList().run(),
|
||||
isActive: () => editor.value.isActive('bulletList'),
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
icon: ListNumbers,
|
||||
title: 'Ordered list',
|
||||
title: t('tools.html-wysiwyg-editor.orderedList'),
|
||||
action: () => editor.value.chain().focus().toggleOrderedList().run(),
|
||||
isActive: () => editor.value.isActive('orderedList'),
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
icon: CodePlus,
|
||||
title: 'Code block',
|
||||
title: t('tools.html-wysiwyg-editor.codeBlock'),
|
||||
action: () => editor.value.chain().focus().toggleCodeBlock().run(),
|
||||
isActive: () => editor.value.isActive('codeBlock'),
|
||||
},
|
||||
|
@ -122,7 +123,7 @@ const items: MenuItem[] = [
|
|||
{
|
||||
type: 'button',
|
||||
icon: Blockquote,
|
||||
title: 'Blockquote',
|
||||
title: t('tools.html-wysiwyg-editor.blockquote'),
|
||||
action: () => editor.value.chain().focus().toggleBlockquote().run(),
|
||||
isActive: () => editor.value.isActive('blockquote'),
|
||||
},
|
||||
|
@ -132,26 +133,26 @@ const items: MenuItem[] = [
|
|||
{
|
||||
type: 'button',
|
||||
icon: TextWrap,
|
||||
title: 'Hard break',
|
||||
title: t('tools.html-wysiwyg-editor.hardBreak'),
|
||||
action: () => editor.value.chain().focus().setHardBreak().run(),
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
icon: ClearFormatting,
|
||||
title: 'Clear format',
|
||||
title: t('tools.html-wysiwyg-editor.clearFormat'),
|
||||
action: () => editor.value.chain().focus().clearNodes().unsetAllMarks().run(),
|
||||
},
|
||||
|
||||
{
|
||||
type: 'button',
|
||||
icon: ArrowBack,
|
||||
title: 'Undo',
|
||||
title: t('tools.html-wysiwyg-editor.undo'),
|
||||
action: () => editor.value.chain().focus().undo().run(),
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
icon: ArrowForwardUp,
|
||||
title: 'Redo',
|
||||
title: t('tools.html-wysiwyg-editor.redo'),
|
||||
action: () => editor.value.chain().focus().redo().run(),
|
||||
},
|
||||
];
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import { Edit } from '@vicons/tabler';
|
||||
import { defineTool } from '../tool';
|
||||
import { translate as t } from '@/plugins/i18n.plugin';
|
||||
|
||||
export const tool = defineTool({
|
||||
name: 'HTML WYSIWYG editor',
|
||||
name: t('tools.html-wysiwyg-editor.title'),
|
||||
path: '/html-wysiwyg-editor',
|
||||
description: 'Online HTML editor with feature-rich WYSIWYG editor, get the source code of the content immediately.',
|
||||
description: t('tools.html-wysiwyg-editor.description'),
|
||||
keywords: ['html', 'wysiwyg', 'editor', 'p', 'ul', 'ol', 'converter', 'live'],
|
||||
component: () => import('./html-wysiwyg-editor.vue'),
|
||||
icon: Edit,
|
||||
|
|
|
@ -2,3 +2,20 @@ tools:
|
|||
html-wysiwyg-editor:
|
||||
title: HTML WYSIWYG editor
|
||||
description: Online HTML editor with feature-rich WYSIWYG editor, get the source code of the content immediately.
|
||||
|
||||
bold: Bold
|
||||
italic: Italic
|
||||
strike: Strike
|
||||
inlineCode: Inline code
|
||||
heading1: Heading 1
|
||||
heading2: Heading 2
|
||||
heading3: Heading 3
|
||||
heading4: Heading 4
|
||||
bulletList: Bullet list
|
||||
orderedList: Ordered list
|
||||
codeBlock: Code block
|
||||
blockquote: Blockquote
|
||||
hardBreak: Hard break
|
||||
clearFormat: Clear format
|
||||
undo: Undo
|
||||
redo: Redo
|
||||
|
|
21
src/tools/html-wysiwyg-editor/locales/zh.yml
Normal file
21
src/tools/html-wysiwyg-editor/locales/zh.yml
Normal file
|
@ -0,0 +1,21 @@
|
|||
tools:
|
||||
html-wysiwyg-editor:
|
||||
title: HTML所见即所得编辑器
|
||||
description: 在线 HTML 编辑器,具有功能丰富的所见即所得编辑器,可立即获取内容的源代码。
|
||||
|
||||
bold: 粗体
|
||||
italic: 斜体
|
||||
strike: 删除线
|
||||
inlineCode: 行内代码
|
||||
heading1: 标题 1
|
||||
heading2: 标题 2
|
||||
heading3: 标题 3
|
||||
heading4: 标题 4
|
||||
bulletList: 无序列表
|
||||
orderedList: 有序列表
|
||||
codeBlock: 代码块
|
||||
blockquote: 引用块
|
||||
hardBreak: 强制换行
|
||||
clearFormat: 清除格式
|
||||
undo: 撤销
|
||||
redo: 重做
|
|
@ -1,3 +1,5 @@
|
|||
import { translate as t } from '@/plugins/i18n.plugin';
|
||||
|
||||
export const codesByCategories: {
|
||||
category: string
|
||||
codes: {
|
||||
|
@ -8,423 +10,404 @@ export const codesByCategories: {
|
|||
}[]
|
||||
}[] = [
|
||||
{
|
||||
category: '1xx informational response',
|
||||
category: t('tools.http-status-codes.1xx'),
|
||||
codes: [
|
||||
{
|
||||
code: 100,
|
||||
name: 'Continue',
|
||||
description: 'Waiting for the client to emit the body of the request.',
|
||||
name: t('tools.http-status-codes.100.name'),
|
||||
description: t('tools.http-status-codes.100.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 101,
|
||||
name: 'Switching Protocols',
|
||||
description: 'The server has agreed to change protocol.',
|
||||
name: t('tools.http-status-codes.101.name'),
|
||||
description: t('tools.http-status-codes.101.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 102,
|
||||
name: 'Processing',
|
||||
description: 'The server is processing the request, but no response is available yet.',
|
||||
name: t('tools.http-status-codes.102.name'),
|
||||
description: t('tools.http-status-codes.102.description'),
|
||||
type: 'WebDav',
|
||||
},
|
||||
{
|
||||
code: 103,
|
||||
name: 'Early Hints',
|
||||
description: 'The server returns some response headers before final HTTP message.',
|
||||
name: t('tools.http-status-codes.103.name'),
|
||||
description: t('tools.http-status-codes.103.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
category: '2xx success',
|
||||
category: t('tools.http-status-codes.2xx'),
|
||||
codes: [
|
||||
{
|
||||
code: 200,
|
||||
name: 'OK',
|
||||
description: 'Standard response for successful HTTP requests.',
|
||||
name: t('tools.http-status-codes.200.name'),
|
||||
description: t('tools.http-status-codes.200.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 201,
|
||||
name: 'Created',
|
||||
description: 'The request has been fulfilled, resulting in the creation of a new resource.',
|
||||
name: t('tools.http-status-codes.201.name'),
|
||||
description: t('tools.http-status-codes.201.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 202,
|
||||
name: 'Accepted',
|
||||
description: 'The request has been accepted for processing, but the processing has not been completed.',
|
||||
name: t('tools.http-status-codes.202.name'),
|
||||
description: t('tools.http-status-codes.202.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 203,
|
||||
name: 'Non-Authoritative Information',
|
||||
description:
|
||||
'The request is successful but the content of the original request has been modified by a transforming proxy.',
|
||||
name: t('tools.http-status-codes.203.name'),
|
||||
description: t('tools.http-status-codes.203.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 204,
|
||||
name: 'No Content',
|
||||
description: 'The server successfully processed the request and is not returning any content.',
|
||||
name: t('tools.http-status-codes.204.name'),
|
||||
description: t('tools.http-status-codes.204.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 205,
|
||||
name: 'Reset Content',
|
||||
description: 'The server indicates to reinitialize the document view which sent this request.',
|
||||
name: t('tools.http-status-codes.205.name'),
|
||||
description: t('tools.http-status-codes.205.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 206,
|
||||
name: 'Partial Content',
|
||||
description: 'The server is delivering only part of the resource due to a range header sent by the client.',
|
||||
name: t('tools.http-status-codes.206.name'),
|
||||
description: t('tools.http-status-codes.206.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 207,
|
||||
name: 'Multi-Status',
|
||||
description:
|
||||
'The message body that follows is an XML message and can contain a number of separate response codes.',
|
||||
name: t('tools.http-status-codes.207.name'),
|
||||
description: t('tools.http-status-codes.207.description'),
|
||||
type: 'WebDav',
|
||||
},
|
||||
{
|
||||
code: 208,
|
||||
name: 'Already Reported',
|
||||
description:
|
||||
'The members of a DAV binding have already been enumerated in a preceding part of the (multistatus) response.',
|
||||
name: t('tools.http-status-codes.208.name'),
|
||||
description: t('tools.http-status-codes.208.description'),
|
||||
type: 'WebDav',
|
||||
},
|
||||
{
|
||||
code: 226,
|
||||
name: 'IM Used',
|
||||
description:
|
||||
'The server has fulfilled a request for the resource, and the response is a representation of the result.',
|
||||
name: t('tools.http-status-codes.226.name'),
|
||||
description: t('tools.http-status-codes.226.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
category: '3xx redirection',
|
||||
category: t('tools.http-status-codes.3xx'),
|
||||
codes: [
|
||||
{
|
||||
code: 300,
|
||||
name: 'Multiple Choices',
|
||||
description: 'Indicates multiple options for the resource that the client may follow.',
|
||||
name: t('tools.http-status-codes.300.name'),
|
||||
description: t('tools.http-status-codes.300.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 301,
|
||||
name: 'Moved Permanently',
|
||||
description: 'This and all future requests should be directed to the given URI.',
|
||||
name: t('tools.http-status-codes.301.name'),
|
||||
description: t('tools.http-status-codes.301.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 302,
|
||||
name: 'Found',
|
||||
description: 'Redirect to another URL. This is an example of industry practice contradicting the standard.',
|
||||
name: t('tools.http-status-codes.302.name'),
|
||||
description: t('tools.http-status-codes.302.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 303,
|
||||
name: 'See Other',
|
||||
description: 'The response to the request can be found under another URI using a GET method.',
|
||||
name: t('tools.http-status-codes.303.name'),
|
||||
description: t('tools.http-status-codes.303.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 304,
|
||||
name: 'Not Modified',
|
||||
description:
|
||||
'Indicates that the resource has not been modified since the version specified by the request headers.',
|
||||
name: t('tools.http-status-codes.304.name'),
|
||||
description: t('tools.http-status-codes.304.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 305,
|
||||
name: 'Use Proxy',
|
||||
description:
|
||||
'The requested resource is available only through a proxy, the address for which is provided in the response.',
|
||||
name: t('tools.http-status-codes.305.name'),
|
||||
description: t('tools.http-status-codes.305.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 306,
|
||||
name: 'Switch Proxy',
|
||||
description: 'No longer used. Originally meant "Subsequent requests should use the specified proxy."',
|
||||
name: t('tools.http-status-codes.306.name'),
|
||||
description: t('tools.http-status-codes.306.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 307,
|
||||
name: 'Temporary Redirect',
|
||||
description:
|
||||
'In this case, the request should be repeated with another URI; however, future requests should still use the original URI.',
|
||||
name: t('tools.http-status-codes.307.name'),
|
||||
description: t('tools.http-status-codes.307.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 308,
|
||||
name: 'Permanent Redirect',
|
||||
description: 'The request and all future requests should be repeated using another URI.',
|
||||
name: t('tools.http-status-codes.308.name'),
|
||||
description: t('tools.http-status-codes.308.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
category: '4xx client error',
|
||||
category: t('tools.http-status-codes.4xx'),
|
||||
codes: [
|
||||
{
|
||||
code: 400,
|
||||
name: 'Bad Request',
|
||||
description: 'The server cannot or will not process the request due to an apparent client error.',
|
||||
name: t('tools.http-status-codes.400.name'),
|
||||
description: t('tools.http-status-codes.400.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 401,
|
||||
name: 'Unauthorized',
|
||||
description:
|
||||
'Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided.',
|
||||
name: t('tools.http-status-codes.401.name'),
|
||||
description: t('tools.http-status-codes.401.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 402,
|
||||
name: 'Payment Required',
|
||||
description:
|
||||
'Reserved for future use. The original intention was that this code might be used as part of some form of digital cash or micropayment scheme.',
|
||||
name: t('tools.http-status-codes.402.name'),
|
||||
description: t('tools.http-status-codes.402.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 403,
|
||||
name: 'Forbidden',
|
||||
description:
|
||||
'The request was valid, but the server is refusing action. The user might not have the necessary permissions for a resource.',
|
||||
name: t('tools.http-status-codes.403.name'),
|
||||
description: t('tools.http-status-codes.403.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 404,
|
||||
name: 'Not Found',
|
||||
description: 'The requested resource could not be found but may be available in the future.',
|
||||
name: t('tools.http-status-codes.404.name'),
|
||||
description: t('tools.http-status-codes.404.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 405,
|
||||
name: 'Method Not Allowed',
|
||||
description: 'A request method is not supported for the requested resource.',
|
||||
name: t('tools.http-status-codes.405.name'),
|
||||
description: t('tools.http-status-codes.405.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 406,
|
||||
name: 'Not Acceptable',
|
||||
description:
|
||||
'The requested resource is capable of generating only content not acceptable according to the Accept headers sent in the request.',
|
||||
name: t('tools.http-status-codes.406.name'),
|
||||
description: t('tools.http-status-codes.406.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 407,
|
||||
name: 'Proxy Authentication Required',
|
||||
description: 'The client must first authenticate itself with the proxy.',
|
||||
name: t('tools.http-status-codes.407.name'),
|
||||
description: t('tools.http-status-codes.407.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 408,
|
||||
name: 'Request Timeout',
|
||||
description: 'The server timed out waiting for the request.',
|
||||
name: t('tools.http-status-codes.408.name'),
|
||||
description: t('tools.http-status-codes.408.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 409,
|
||||
name: 'Conflict',
|
||||
description:
|
||||
'Indicates that the request could not be processed because of conflict in the request, such as an edit conflict.',
|
||||
name: t('tools.http-status-codes.409.name'),
|
||||
description: t('tools.http-status-codes.409.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 410,
|
||||
name: 'Gone',
|
||||
description: 'Indicates that the resource requested is no longer available and will not be available again.',
|
||||
name: t('tools.http-status-codes.410.name'),
|
||||
description: t('tools.http-status-codes.410.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 411,
|
||||
name: 'Length Required',
|
||||
description:
|
||||
'The request did not specify the length of its content, which is required by the requested resource.',
|
||||
name: t('tools.http-status-codes.411.name'),
|
||||
description: t('tools.http-status-codes.411.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 412,
|
||||
name: 'Precondition Failed',
|
||||
description: 'The server does not meet one of the preconditions that the requester put on the request.',
|
||||
name: t('tools.http-status-codes.412.name'),
|
||||
description: t('tools.http-status-codes.412.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 413,
|
||||
name: 'Payload Too Large',
|
||||
description: 'The request is larger than the server is willing or able to process.',
|
||||
name: t('tools.http-status-codes.413.name'),
|
||||
description: t('tools.http-status-codes.413.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 414,
|
||||
name: 'URI Too Long',
|
||||
description: 'The URI provided was too long for the server to process.',
|
||||
name: t('tools.http-status-codes.414.name'),
|
||||
description: t('tools.http-status-codes.414.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 415,
|
||||
name: 'Unsupported Media Type',
|
||||
description: 'The request entity has a media type which the server or resource does not support.',
|
||||
name: t('tools.http-status-codes.415.name'),
|
||||
description: t('tools.http-status-codes.415.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 416,
|
||||
name: 'Range Not Satisfiable',
|
||||
description: 'The client has asked for a portion of the file, but the server cannot supply that portion.',
|
||||
name: t('tools.http-status-codes.416.name'),
|
||||
description: t('tools.http-status-codes.416.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 417,
|
||||
name: 'Expectation Failed',
|
||||
description: 'The server cannot meet the requirements of the Expect request-header field.',
|
||||
name: t('tools.http-status-codes.417.name'),
|
||||
description: t('tools.http-status-codes.417.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 418,
|
||||
name: 'I\'m a teapot',
|
||||
description: 'The server refuses the attempt to brew coffee with a teapot.',
|
||||
name: t('tools.http-status-codes.418.name'),
|
||||
description: t('tools.http-status-codes.418.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 421,
|
||||
name: 'Misdirected Request',
|
||||
description: 'The request was directed at a server that is not able to produce a response.',
|
||||
name: t('tools.http-status-codes.421.name'),
|
||||
description: t('tools.http-status-codes.421.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 422,
|
||||
name: 'Unprocessable Entity',
|
||||
description: 'The request was well-formed but was unable to be followed due to semantic errors.',
|
||||
name: t('tools.http-status-codes.422.name'),
|
||||
description: t('tools.http-status-codes.422.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 423,
|
||||
name: 'Locked',
|
||||
description: 'The resource that is being accessed is locked.',
|
||||
name: t('tools.http-status-codes.423.name'),
|
||||
description: t('tools.http-status-codes.423.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 424,
|
||||
name: 'Failed Dependency',
|
||||
description: 'The request failed due to failure of a previous request.',
|
||||
name: t('tools.http-status-codes.424.name'),
|
||||
description: t('tools.http-status-codes.424.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 425,
|
||||
name: 'Too Early',
|
||||
description: 'Indicates that the server is unwilling to risk processing a request that might be replayed.',
|
||||
name: t('tools.http-status-codes.425.name'),
|
||||
description: t('tools.http-status-codes.425.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 426,
|
||||
name: 'Upgrade Required',
|
||||
description: 'The client should switch to a different protocol such as TLS/1.0.',
|
||||
name: t('tools.http-status-codes.426.name'),
|
||||
description: t('tools.http-status-codes.426.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 428,
|
||||
name: 'Precondition Required',
|
||||
description: 'The origin server requires the request to be conditional.',
|
||||
name: t('tools.http-status-codes.428.name'),
|
||||
description: t('tools.http-status-codes.428.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 429,
|
||||
name: 'Too Many Requests',
|
||||
description: 'The user has sent too many requests in a given amount of time.',
|
||||
name: t('tools.http-status-codes.429.name'),
|
||||
description: t('tools.http-status-codes.429.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 431,
|
||||
name: 'Request Header Fields Too Large',
|
||||
description:
|
||||
'The server is unwilling to process the request because either an individual header field, or all the header fields collectively, are too large.',
|
||||
name: t('tools.http-status-codes.431.name'),
|
||||
description: t('tools.http-status-codes.431.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 451,
|
||||
name: 'Unavailable For Legal Reasons',
|
||||
description:
|
||||
'A server operator has received a legal demand to deny access to a resource or to a set of resources that includes the requested resource.',
|
||||
name: t('tools.http-status-codes.451.name'),
|
||||
description: t('tools.http-status-codes.451.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
category: '5xx server error',
|
||||
category: t('tools.http-status-codes.5xx'),
|
||||
codes: [
|
||||
{
|
||||
code: 500,
|
||||
name: 'Internal Server Error',
|
||||
description:
|
||||
'A generic error message, given when an unexpected condition was encountered and no more specific message is suitable.',
|
||||
name: t('tools.http-status-codes.500.name'),
|
||||
description: t('tools.http-status-codes.500.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 501,
|
||||
name: 'Not Implemented',
|
||||
description:
|
||||
'The server either does not recognize the request method, or it lacks the ability to fulfill the request.',
|
||||
name: t('tools.http-status-codes.501.name'),
|
||||
description: t('tools.http-status-codes.501.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 502,
|
||||
name: 'Bad Gateway',
|
||||
description:
|
||||
'The server was acting as a gateway or proxy and received an invalid response from the upstream server.',
|
||||
name: t('tools.http-status-codes.502.name'),
|
||||
description: t('tools.http-status-codes.502.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 503,
|
||||
name: 'Service Unavailable',
|
||||
description: 'The server is currently unavailable (because it is overloaded or down for maintenance).',
|
||||
name: t('tools.http-status-codes.503.name'),
|
||||
description: t('tools.http-status-codes.503.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 504,
|
||||
name: 'Gateway Timeout',
|
||||
description:
|
||||
'The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.',
|
||||
name: t('tools.http-status-codes.504.name'),
|
||||
description: t('tools.http-status-codes.504.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 505,
|
||||
name: 'HTTP Version Not Supported',
|
||||
description: 'The server does not support the HTTP protocol version used in the request.',
|
||||
name: t('tools.http-status-codes.505.name'),
|
||||
description: t('tools.http-status-codes.505.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 506,
|
||||
name: 'Variant Also Negotiates',
|
||||
description: 'Transparent content negotiation for the request results in a circular reference.',
|
||||
name: t('tools.http-status-codes.506.name'),
|
||||
description: t('tools.http-status-codes.506.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 507,
|
||||
name: 'Insufficient Storage',
|
||||
description: 'The server is unable to store the representation needed to complete the request.',
|
||||
name: t('tools.http-status-codes.507.name'),
|
||||
description: t('tools.http-status-codes.507.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 508,
|
||||
name: 'Loop Detected',
|
||||
description: 'The server detected an infinite loop while processing the request.',
|
||||
name: t('tools.http-status-codes.508.name'),
|
||||
description: t('tools.http-status-codes.508.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 510,
|
||||
name: 'Not Extended',
|
||||
description: 'Further extensions to the request are required for the server to fulfill it.',
|
||||
name: t('tools.http-status-codes.510.name'),
|
||||
description: t('tools.http-status-codes.510.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
{
|
||||
code: 511,
|
||||
name: 'Network Authentication Required',
|
||||
description: 'The client needs to authenticate to gain network access.',
|
||||
name: t('tools.http-status-codes.511.name'),
|
||||
description: t('tools.http-status-codes.511.description'),
|
||||
type: 'HTTP',
|
||||
},
|
||||
],
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
<script setup lang="ts">
|
||||
import { codesByCategories } from './http-status-codes.constants';
|
||||
import * as status from './http-status-codes.constants';
|
||||
import { useFuzzySearch } from '@/composable/fuzzySearch';
|
||||
|
||||
const search = ref('');
|
||||
const { t } = useI18n();
|
||||
const { codesByCategories } = status;
|
||||
|
||||
const { searchResult } = useFuzzySearch({
|
||||
search,
|
||||
|
@ -17,7 +19,7 @@ const codesByCategoryFiltered = computed(() => {
|
|||
return codesByCategories;
|
||||
}
|
||||
|
||||
return [{ category: 'Search results', codes: searchResult.value }];
|
||||
return [{ category: t('tools.http-status-codes.searchResults'), codes: searchResult.value }];
|
||||
});
|
||||
</script>
|
||||
|
||||
|
@ -25,7 +27,7 @@ const codesByCategoryFiltered = computed(() => {
|
|||
<div>
|
||||
<c-input-text
|
||||
v-model:value="search"
|
||||
placeholder="Search http status..."
|
||||
:placeholder="t('tools.http-status-codes.searchPlaceholder')"
|
||||
autofocus raw-text mb-10
|
||||
/>
|
||||
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
import { HttpRound } from '@vicons/material';
|
||||
import { defineTool } from '../tool';
|
||||
|
||||
import { codesByCategories } from './http-status-codes.constants';
|
||||
// import { codesByCategories } from './http-status-codes.constants';
|
||||
import { translate as t } from '@/plugins/i18n.plugin';
|
||||
|
||||
export const tool = defineTool({
|
||||
name: 'HTTP status codes',
|
||||
name: t('tools.http-status-codes.title'),
|
||||
path: '/http-status-codes',
|
||||
description: 'The list of all HTTP status codes their name and their meaning.',
|
||||
description: t('tools.http-status-codes.description'),
|
||||
keywords: [
|
||||
'http',
|
||||
'status',
|
||||
'codes',
|
||||
...codesByCategories.flatMap(({ codes }) => codes.flatMap(({ code, name }) => [String(code), name])),
|
||||
// ...codesByCategories.flatMap(({ codes }) => codes.flatMap(({ code, name }) => [String(code), name])),
|
||||
],
|
||||
component: () => import('./http-status-codes.vue'),
|
||||
icon: HttpRound,
|
||||
|
|
|
@ -2,3 +2,201 @@ tools:
|
|||
http-status-codes:
|
||||
title: HTTP status codes
|
||||
description: The list of all HTTP status codes their name and their meaning.
|
||||
|
||||
searchPlaceholder: Search http status...
|
||||
searchResults: Search results
|
||||
|
||||
1xx: 1xx informational response
|
||||
100:
|
||||
name: Continue
|
||||
description: Waiting for the client to emit the body of the request.
|
||||
101:
|
||||
name: Switching Protocols
|
||||
description: The server has agreed to change protocol.
|
||||
102:
|
||||
name: Processing
|
||||
description: The server is processing the request, but no response is available yet.
|
||||
103:
|
||||
name: Early Hints
|
||||
description: The server returns some response headers before final HTTP message.
|
||||
2xx: 2xx success
|
||||
200:
|
||||
name: OK
|
||||
description: Standard response for successful HTTP requests.
|
||||
201:
|
||||
name: Created
|
||||
description: The request has been fulfilled, resulting in the creation of a new resource.
|
||||
202:
|
||||
name: Accepted
|
||||
description: The request has been accepted for processing, but the processing has not been completed.
|
||||
203:
|
||||
name: Non-Authoritative Information
|
||||
description: The request is successful but the content of the original request has been modified by a transforming proxy.
|
||||
204:
|
||||
name: No Content
|
||||
description: The server successfully processed the request and is not returning any content.
|
||||
205:
|
||||
name: Reset Content
|
||||
description: The server indicates to reinitialize the document view which sent this request.
|
||||
206:
|
||||
name: Partial Content
|
||||
description: The server is delivering only part of the resource due to a range header sent by the client.
|
||||
207:
|
||||
name: Multi-Status
|
||||
description: The message body that follows is an XML message and can contain a number of separate response codes.
|
||||
208:
|
||||
name: Already Reported
|
||||
description: The members of a DAV binding have already been enumerated in a preceding part of the (multistatus) response.
|
||||
226:
|
||||
name: IM Used
|
||||
description: The server has fulfilled a request for the resource, and the response is a representation of the result.
|
||||
3xx: 3xx redirection
|
||||
300:
|
||||
name: Multiple Choices
|
||||
description: Indicates multiple options for the resource that the client may follow.
|
||||
301:
|
||||
name: Moved Permanently
|
||||
description: This and all future requests should be directed to the given URI.
|
||||
302:
|
||||
name: Found
|
||||
description: Redirect to another URL. This is an example of industry practice contradicting the standard.
|
||||
303:
|
||||
name: See Other
|
||||
description: The response to the request can be found under another URI using a GET method.
|
||||
304:
|
||||
name: Not Modified
|
||||
description: Indicates that the resource has not been modified since the version specified by the request headers.
|
||||
305:
|
||||
name: Use Proxy
|
||||
description: The requested resource is available only through a proxy, the address for which is provided in the response.
|
||||
306:
|
||||
name: Switch Proxy
|
||||
description: No longer used. Originally meant "Subsequent requests should use the specified proxy."
|
||||
307:
|
||||
name: Temporary Redirect
|
||||
description: In this case, the request should be repeated with another URI; however, future requests should still use the original URI.
|
||||
308:
|
||||
name: Permanent Redirect
|
||||
description: The request and all future requests should be repeated using another URI.
|
||||
4xx: 4xx client error
|
||||
400:
|
||||
name: Bad Request
|
||||
description: The server cannot or will not process the request due to an apparent client error.
|
||||
401:
|
||||
name: Unauthorized
|
||||
description: Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided.
|
||||
402:
|
||||
name: Payment Required
|
||||
description: Reserved for future use. The original intention was that this code might be used as part of some form of digital cash or micropayment scheme.
|
||||
403:
|
||||
name: Forbidden
|
||||
description: The request was valid, but the server is refusing action. The user might not have the necessary permissions for a resource.
|
||||
404:
|
||||
name: Not Found
|
||||
description: The requested resource could not be found but may be available in the future.
|
||||
405:
|
||||
name: Method Not Allowed
|
||||
description: A request method is not supported for the requested resource.
|
||||
406:
|
||||
name: Not Acceptable
|
||||
description: The requested resource is capable of generating only content not acceptable according to the Accept headers sent in the request.
|
||||
407:
|
||||
name: Proxy Authentication Required
|
||||
description: The client must first authenticate itself with the proxy.
|
||||
408:
|
||||
name: Request Timeout
|
||||
description: The server timed out waiting for the request.
|
||||
409:
|
||||
name: Conflict
|
||||
description: Indicates that the request could not be processed because of conflict in the request, such as an edit conflict.
|
||||
410:
|
||||
name: Gone
|
||||
description: Indicates that the resource requested is no longer available and will not be available again.
|
||||
411:
|
||||
name: Length Required
|
||||
description: The request did not specify the length of its content, which is required by the requested resource.
|
||||
412:
|
||||
name: Precondition Failed
|
||||
description: The server does not meet one of the preconditions that the requester put on the request.
|
||||
413:
|
||||
name: Payload Too Large
|
||||
description: The request is larger than the server is willing or able to process.
|
||||
414:
|
||||
name: URI Too Long
|
||||
description: The URI provided was too long for the server to process.
|
||||
415:
|
||||
name: Unsupported Media Type
|
||||
description: The request entity has a media type which the server or resource does not support.
|
||||
416:
|
||||
name: Range Not Satisfiable
|
||||
description: The client has asked for a portion of the file, but the server cannot supply that portion.
|
||||
417:
|
||||
name: Expectation Failed
|
||||
description: The server cannot meet the requirements of the Expect request-header field.
|
||||
418:
|
||||
name: I'm a teapot
|
||||
description: The server refuses the attempt to brew coffee with a teapot.
|
||||
421:
|
||||
name: Misdirected Request
|
||||
description: The request was directed at a server that is not able to produce a response.
|
||||
422:
|
||||
name: Unprocessable Entity
|
||||
description: The request was well-formed but was unable to be followed due to semantic errors.
|
||||
423:
|
||||
name: Locked
|
||||
description: The resource that is being accessed is locked.
|
||||
424:
|
||||
name: Failed Dependency
|
||||
description: The request failed due to failure of a previous request.
|
||||
425:
|
||||
name: Too Early
|
||||
description: Indicates that the server is unwilling to risk processing a request that might be replayed.
|
||||
426:
|
||||
name: Upgrade Required
|
||||
description: The client should switch to a different protocol such as TLS/1.0.
|
||||
428:
|
||||
name: Precondition Required
|
||||
description: The origin server requires the request to be conditional.
|
||||
429:
|
||||
name: Too Many Requests
|
||||
description: The user has sent too many requests in a given amount of time.
|
||||
431:
|
||||
name: Request Header Fields Too Large
|
||||
description: The server is unwilling to process the request because either an individual header field, or all the header fields collectively, are too large.
|
||||
451:
|
||||
name: Unavailable For Legal Reasons
|
||||
description: A server operator has received a legal demand to deny access to a resource or to a set of resources that includes the requested resource.
|
||||
5xx: 5xx server error
|
||||
500:
|
||||
name: Internal Server Error
|
||||
description: A generic error message, given when an unexpected condition was encountered and no more specific message is suitable.
|
||||
501:
|
||||
name: Not Implemented
|
||||
description: The server either does not recognize the request method, or it lacks the ability to fulfill the request.
|
||||
502:
|
||||
name: Bad Gateway
|
||||
description: The server was acting as a gateway or proxy and received an invalid response from the upstream server.
|
||||
503:
|
||||
name: Service Unavailable
|
||||
description: The server is currently unavailable (because it is overloaded or down for maintenance).
|
||||
504:
|
||||
name: Gateway Timeout
|
||||
description: The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.
|
||||
505:
|
||||
name: HTTP Version Not Supported
|
||||
description: The server does not support the HTTP protocol version used in the request.
|
||||
506:
|
||||
name: Variant Also Negotiates
|
||||
description: Transparent content negotiation for the request results in a circular reference.
|
||||
507:
|
||||
name: Insufficient Storage
|
||||
description: The server is unable to store the representation needed to complete the request.
|
||||
508:
|
||||
name: Loop Detected
|
||||
description: The server detected an infinite loop while processing the request.
|
||||
510:
|
||||
name: Not Extended
|
||||
description: Further extensions to the request are required for the server to fulfill it.
|
||||
511:
|
||||
name: Network Authentication Required
|
||||
description: The client needs to authenticate to gain network access.
|
||||
|
|
202
src/tools/http-status-codes/locales/zh.yml
Normal file
202
src/tools/http-status-codes/locales/zh.yml
Normal file
|
@ -0,0 +1,202 @@
|
|||
tools:
|
||||
http-status-codes:
|
||||
title: HTTP 状态码
|
||||
description: 所有 HTTP 状态码及其名称和含义的列表。
|
||||
|
||||
searchPlaceholder: 搜索 HTTP 状态码...
|
||||
searchResults: 搜索结果
|
||||
|
||||
1xx: 1xx 信息性响应
|
||||
100:
|
||||
name: 继续
|
||||
description: 等待客户端发送请求主体。
|
||||
101:
|
||||
name: 切换协议
|
||||
description: 服务器已同意切换协议。
|
||||
102:
|
||||
name: 处理中
|
||||
description: 服务器正在处理请求,但尚未有响应可用。
|
||||
103:
|
||||
name: 早期提示
|
||||
description: 服务器在最终 HTTP 消息之前返回一些响应头。
|
||||
2xx: 2xx 成功
|
||||
200:
|
||||
name: OK
|
||||
description: 成功的标准 HTTP 请求响应。
|
||||
201:
|
||||
name: 已创建
|
||||
description: 请求已成功,导致创建新资源。
|
||||
202:
|
||||
name: 已接受
|
||||
description: 请求已被接受处理,但处理尚未完成。
|
||||
203:
|
||||
name: 非权威信息
|
||||
description: 请求成功,但原始请求的内容已被转换代理修改。
|
||||
204:
|
||||
name: 无内容
|
||||
description: 服务器成功处理请求,但未返回任何内容。
|
||||
205:
|
||||
name: 重置内容
|
||||
description: 服务器指示重新初始化发送此请求的文档视图。
|
||||
206:
|
||||
name: 部分内容
|
||||
description: 服务器仅因客户端发送的范围头而传送资源的部分。
|
||||
207:
|
||||
name: 多状态
|
||||
description: 接下来的消息主体是 XML 消息,可以包含许多独立的响应代码。
|
||||
208:
|
||||
name: 已报告
|
||||
description: DAV 绑定的成员已在响应的前一部分中枚举。
|
||||
226:
|
||||
name: 使用 IM
|
||||
description: 服务器已满足对资源的请求,响应是结果的表示。
|
||||
3xx: 3xx 重定向
|
||||
300:
|
||||
name: 多种选择
|
||||
description: 表示客户端可以跟随的资源的多个选项。
|
||||
301:
|
||||
name: 永久移动
|
||||
description: 此次及所有后续请求应重定向到给定的 URI。
|
||||
302:
|
||||
name: 找到
|
||||
description: 重定向到另一个 URL。这是一个违反标准的行业实践示例。
|
||||
303:
|
||||
name: 查看其他
|
||||
description: 请求的响应可以在另一个 URI 下使用 GET 方法找到。
|
||||
304:
|
||||
name: 未修改
|
||||
description: 表示资源自请求标头指定的版本以来未被修改。
|
||||
305:
|
||||
name: 使用代理
|
||||
description: 请求的资源仅通过代理提供,响应中提供了代理的地址。
|
||||
306:
|
||||
name: 切换代理
|
||||
description: 不再使用。最初的含义是“后续请求应使用指定的代理”。
|
||||
307:
|
||||
name: 临时重定向
|
||||
description: 在这种情况下,应重复使用另一个 URI 进行请求;但是,将来的请求仍应使用原始 URI。
|
||||
308:
|
||||
name: 永久重定向
|
||||
description: 请求和所有后续请求应重复使用另一个 URI。
|
||||
4xx: 4xx 客户端错误
|
||||
400:
|
||||
name: 错误请求
|
||||
description: 由于明显的客户端错误,服务器无法处理请求或不会处理请求。
|
||||
401:
|
||||
name: 未经授权
|
||||
description: 类似于 403 Forbidden,但专门用于在需要验证但验证失败或尚未提供的情况下使用。
|
||||
402:
|
||||
name: 需要付款
|
||||
description: 保留以备将来使用。最初的意图是,该代码可能作为某种数字货币或微支付方案的一部分使用。
|
||||
403:
|
||||
name: 禁止
|
||||
description: 请求有效,但服务器拒绝执行操作。用户可能没有资源所需的必要权限。
|
||||
404:
|
||||
name: 未找到
|
||||
description: 请求的资源未找到,但将来可能会可用。
|
||||
405:
|
||||
name: 方法不允许
|
||||
description: 请求方法不受请求资源支持。
|
||||
406:
|
||||
name: 不可接受
|
||||
description: 请求的资源能够生成的内容不符合请求中发送的 Accept 标头。
|
||||
407:
|
||||
name: 需要代理身份验证
|
||||
description: 客户端必须首先通过代理进行身份验证。
|
||||
408:
|
||||
name: 请求超时
|
||||
description: 服务器在等待请求时超时。
|
||||
409:
|
||||
name: 冲突
|
||||
description: 表示由于请求中的冲突(如编辑冲突)无法处理请求。
|
||||
410:
|
||||
name: 已消失
|
||||
description: 表示请求的资源不再可用,也不会再次可用。
|
||||
411:
|
||||
name: 需要长度
|
||||
description: 请求未指定所需资源的长度。
|
||||
412:
|
||||
name: 前提条件失败
|
||||
description: 服务器未满足请求者对请求的其中一个前提条件。
|
||||
413:
|
||||
name: 负载过大
|
||||
description: 请求的大小超过服务器愿意或能够处理的范围。
|
||||
414:
|
||||
name: URI 过长
|
||||
description: 提供的 URI 对服务器来说太长,无法处理。
|
||||
415:
|
||||
name: 不支持的媒体类型
|
||||
description: 请求实体具有服务器或资源不支持的媒体类型。
|
||||
416:
|
||||
name: 范围不可满足
|
||||
description: 客户端请求文件的一部分,但服务器无法提供该部分。
|
||||
417:
|
||||
name: 预期失败
|
||||
description: 服务器无法满足 Expect 请求标头字段的要求。
|
||||
418:
|
||||
name: 我是茶壶
|
||||
description: 服务器拒绝使用茶壶煮咖啡。
|
||||
421:
|
||||
name: 请求错误
|
||||
description: 请求指向无法生成响应的服务器。
|
||||
422:
|
||||
name: 无法处理的实体
|
||||
description: 请求格式正确,但由于语义错误无法进行后续处理。
|
||||
423:
|
||||
name: 已锁定
|
||||
description: 正在访问的资源已被锁定。
|
||||
424:
|
||||
name: 失败的依赖
|
||||
description: 由于先前请求的失败,请求失败。
|
||||
425:
|
||||
name: 太早
|
||||
description: 表示服务器不愿冒险处理可能会被重播的请求。
|
||||
426:
|
||||
name: 需要升级
|
||||
description: 客户端应切换到其他协议,如 TLS/1.0。
|
||||
428:
|
||||
name: 需要前提条件
|
||||
description: 源服务器要求请求是有条件的。
|
||||
429:
|
||||
name: 请求过多
|
||||
description: 用户在一定时间内发送了太多请求。
|
||||
431:
|
||||
name: 请求头字段太大
|
||||
description: 服务器不愿处理请求,因为单个标头字段或所有标头字段的总和太大。
|
||||
451:
|
||||
name: 因法律原因不可用
|
||||
description: 服务器操作员收到法律要求拒绝访问资源或包含请求的资源集。
|
||||
5xx: 5xx 服务器错误
|
||||
500:
|
||||
name: 内部服务器错误
|
||||
description: 遇到意外情况并且没有更具体消息适用时给出的通用错误消息。
|
||||
501:
|
||||
name: 未实现
|
||||
description: 服务器不识别请求方法,或缺乏实现请求的能力。
|
||||
502:
|
||||
name: 错误网关
|
||||
description: 服务器作为网关或代理行事,并从上游服务器接收到无效响应。
|
||||
503:
|
||||
name: 服务不可用
|
||||
description: 服务器当前不可用(因为过载或正在维护)。
|
||||
504:
|
||||
name: 网关超时
|
||||
description: 服务器作为网关或代理行事,未从上游服务器收到及时响应。
|
||||
505:
|
||||
name: 不支持的 HTTP 版本
|
||||
description: 服务器不支持请求中使用的 HTTP 协议版本。
|
||||
506:
|
||||
name: 变体也进行协商
|
||||
description: 用于请求结果的透明内容协商导致循环引用。
|
||||
507:
|
||||
name: 存储空间不足
|
||||
description: 服务器无法存储完成请求所需的表示。
|
||||
508:
|
||||
name: 检测到循环
|
||||
description: 服务器在处理请求时检测到无限循环。
|
||||
510:
|
||||
name: 未扩展
|
||||
description: 服务器需要进一步扩展请求才能满足它。
|
||||
511:
|
||||
name: 需要网络认证
|
||||
description: 客户端需要进行身份验证以获得网络访问权限。
|
|
@ -5,6 +5,8 @@ import { DiffRootViewer } from './diff-viewer.models';
|
|||
import { useAppTheme } from '@/ui/theme/themes';
|
||||
|
||||
const props = defineProps<{ leftJson: unknown; rightJson: unknown }>();
|
||||
|
||||
const { t } = useI18n();
|
||||
const onlyShowDifferences = ref(false);
|
||||
const { leftJson, rightJson } = toRefs(props);
|
||||
const appTheme = useAppTheme();
|
||||
|
@ -20,14 +22,14 @@ const showResults = computed(() => !_.isUndefined(leftJson.value) && !_.isUndefi
|
|||
<template>
|
||||
<div v-if="showResults">
|
||||
<div flex justify-center>
|
||||
<n-form-item label="Only show differences" label-placement="left">
|
||||
<n-form-item :label="t('tools.json-diff.onlyShowDifferences')" label-placement="left">
|
||||
<n-switch v-model:value="onlyShowDifferences" />
|
||||
</n-form-item>
|
||||
</div>
|
||||
|
||||
<c-card data-test-id="diff-result">
|
||||
<div v-if="jsonAreTheSame" text-center op-70>
|
||||
The provided JSONs are the same
|
||||
{{ t('tools.json-diff.jsonAreTheSame') }}
|
||||
</div>
|
||||
<DiffRootViewer v-else :diff="result" />
|
||||
</c-card>
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import { CompareArrowsRound } from '@vicons/material';
|
||||
import { defineTool } from '../tool';
|
||||
import { translate as t } from '@/plugins/i18n.plugin';
|
||||
|
||||
export const tool = defineTool({
|
||||
name: 'JSON diff',
|
||||
name: t('tools.json-diff.title'),
|
||||
path: '/json-diff',
|
||||
description: 'Compare two JSON objects and get the differences between them.',
|
||||
description: t('tools.json-diff.description'),
|
||||
keywords: ['json', 'diff', 'compare', 'difference', 'object', 'data'],
|
||||
component: () => import('./json-diff.vue'),
|
||||
icon: CompareArrowsRound,
|
||||
|
|
|
@ -5,6 +5,8 @@ import DiffsViewer from './diff-viewer/diff-viewer.vue';
|
|||
import { withDefaultOnError } from '@/utils/defaults';
|
||||
import { isNotThrowing } from '@/utils/boolean';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const rawLeftJson = ref('');
|
||||
const rawRightJson = ref('');
|
||||
|
||||
|
@ -14,7 +16,7 @@ const rightJson = computed(() => withDefaultOnError(() => JSON5.parse(rawRightJs
|
|||
const jsonValidationRules = [
|
||||
{
|
||||
validator: (value: string) => value === '' || isNotThrowing(() => JSON5.parse(value)),
|
||||
message: 'Invalid JSON format',
|
||||
message: t('tools.json-diff.invalidJSONFormat'),
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
@ -23,8 +25,8 @@ const jsonValidationRules = [
|
|||
<c-input-text
|
||||
v-model:value="rawLeftJson"
|
||||
:validation-rules="jsonValidationRules"
|
||||
label="Your first JSON"
|
||||
placeholder="Paste your first JSON here..."
|
||||
:label="t('tools.json-diff.inputLable')"
|
||||
:placeholder="t('tools.json-diff.inputPlaceholder')"
|
||||
rows="20"
|
||||
multiline
|
||||
test-id="leftJson"
|
||||
|
@ -35,8 +37,8 @@ const jsonValidationRules = [
|
|||
<c-input-text
|
||||
v-model:value="rawRightJson"
|
||||
:validation-rules="jsonValidationRules"
|
||||
label="Your JSON to compare"
|
||||
placeholder="Paste your JSON to compare here..."
|
||||
:label="t('tools.json-diff.outputLable')"
|
||||
:placeholder="t('tools.json-diff.outputPlaceholder')"
|
||||
rows="20"
|
||||
multiline
|
||||
test-id="rightJson"
|
||||
|
|
|
@ -2,3 +2,12 @@ tools:
|
|||
json-diff:
|
||||
title: JSON diff
|
||||
description: Compare two JSON objects and get the differences between them.
|
||||
|
||||
inputLable: Your first JSON
|
||||
inputPlaceholder: Paste your first JSON here...
|
||||
outputLable: Your JSON to compare
|
||||
outputPlaceholder: Paste your JSON to compare here...
|
||||
onlyShowDifferences: Only show differences
|
||||
jsonAreTheSame: The provided JSONs are the same
|
||||
|
||||
invalidJSONFormat: Invalid JSON format
|
||||
|
|
13
src/tools/json-diff/locales/zh.yml
Normal file
13
src/tools/json-diff/locales/zh.yml
Normal file
|
@ -0,0 +1,13 @@
|
|||
tools:
|
||||
json-diff:
|
||||
title: JSON 对比
|
||||
description: 比较两个 JSON 对象并获取它们之间的差异。
|
||||
|
||||
inputLable: 您的第一个 JSON
|
||||
inputPlaceholder: 在此粘贴您的第一个 JSON...
|
||||
outputLable: 您要比较的 JSON
|
||||
outputPlaceholder: 在此粘贴要比较的 JSON...
|
||||
onlyShowDifferences: 仅显示差异
|
||||
jsonAreTheSame: 提供的 JSON 相同
|
||||
|
||||
invalidJSONFormat: 无效的 JSON 格式
|
|
@ -1,92 +1,94 @@
|
|||
import { translate as t } from '@/plugins/i18n.plugin';
|
||||
|
||||
// From https://datatracker.ietf.org/doc/html/rfc7518#section-3.1
|
||||
export const ALGORITHM_DESCRIPTIONS: { [k: string]: string } = {
|
||||
HS256: 'HMAC using SHA-256',
|
||||
HS384: 'HMAC using SHA-384',
|
||||
HS512: 'HMAC using SHA-512',
|
||||
RS256: 'RSASSA-PKCS1-v1_5 using SHA-256',
|
||||
RS384: 'RSASSA-PKCS1-v1_5 using SHA-384',
|
||||
RS512: 'RSASSA-PKCS1-v1_5 using SHA-512',
|
||||
ES256: 'ECDSA using P-256 and SHA-256',
|
||||
ES384: 'ECDSA using P-384 and SHA-384',
|
||||
ES512: 'ECDSA using P-521 and SHA-512',
|
||||
PS256: 'RSASSA-PSS using SHA-256 and MGF1 with SHA-256',
|
||||
PS384: 'RSASSA-PSS using SHA-384 and MGF1 with SHA-384',
|
||||
PS512: 'RSASSA-PSS using SHA-512 and MGF1 with SHA-512',
|
||||
none: 'No digital signature or MAC performed',
|
||||
HS256: t('tools.jwt-parser.HS256'),
|
||||
HS384: t('tools.jwt-parser.HS384'),
|
||||
HS512: t('tools.jwt-parser.HS512'),
|
||||
RS256: t('tools.jwt-parser.RS256'),
|
||||
RS384: t('tools.jwt-parser.RS384'),
|
||||
RS512: t('tools.jwt-parser.RS512'),
|
||||
ES256: t('tools.jwt-parser.ES256'),
|
||||
ES384: t('tools.jwt-parser.ES384'),
|
||||
ES512: t('tools.jwt-parser.ES512'),
|
||||
PS256: t('tools.jwt-parser.PS256'),
|
||||
PS384: t('tools.jwt-parser.PS384'),
|
||||
PS512: t('tools.jwt-parser.PS512'),
|
||||
none: t('tools.jwt-parser.none'),
|
||||
};
|
||||
|
||||
// List extracted from IANA: https://www.iana.org/assignments/jwt/jwt.xhtml
|
||||
export const CLAIM_DESCRIPTIONS: Record<string, string> = {
|
||||
typ: 'Type',
|
||||
alg: 'Algorithm',
|
||||
iss: 'Issuer',
|
||||
sub: 'Subject',
|
||||
aud: 'Audience',
|
||||
exp: 'Expiration Time',
|
||||
nbf: 'Not Before',
|
||||
iat: 'Issued At',
|
||||
jti: 'JWT ID',
|
||||
name: 'Full name',
|
||||
given_name: 'Given name(s) or first name(s)',
|
||||
family_name: 'Surname(s) or last name(s)',
|
||||
middle_name: 'Middle name(s)',
|
||||
nickname: 'Casual name',
|
||||
preferred_username: 'Shorthand name by which the End-User wishes to be referred to',
|
||||
profile: 'Profile page URL',
|
||||
picture: 'Profile picture URL',
|
||||
website: 'Web page or blog URL',
|
||||
email: 'Preferred e-mail address',
|
||||
email_verified: 'True if the e-mail address has been verified; otherwise false',
|
||||
gender: 'Gender',
|
||||
birthdate: 'Birthday',
|
||||
zoneinfo: 'Time zone',
|
||||
locale: 'Locale',
|
||||
phone_number: 'Preferred telephone number',
|
||||
phone_number_verified: 'True if the phone number has been verified; otherwise false',
|
||||
address: 'Preferred postal address',
|
||||
updated_at: 'Time the information was last updated',
|
||||
azp: 'Authorized party - the party to which the ID Token was issued',
|
||||
nonce: 'Value used to associate a Client session with an ID Token',
|
||||
auth_time: 'Time when the authentication occurred',
|
||||
at_hash: 'Access Token hash value',
|
||||
c_hash: 'Code hash value',
|
||||
acr: 'Authentication Context Class Reference',
|
||||
amr: 'Authentication Methods References',
|
||||
sub_jwk: 'Public key used to check the signature of an ID Token',
|
||||
cnf: 'Confirmation',
|
||||
sip_from_tag: 'SIP From tag header field parameter value',
|
||||
sip_date: 'SIP Date header field value',
|
||||
sip_callid: 'SIP Call-Id header field value',
|
||||
sip_cseq_num: 'SIP CSeq numeric header field parameter value',
|
||||
sip_via_branch: 'SIP Via branch header field parameter value',
|
||||
orig: 'Originating Identity String',
|
||||
dest: 'Destination Identity String',
|
||||
mky: 'Media Key Fingerprint String',
|
||||
events: 'Security Events',
|
||||
toe: 'Time of Event',
|
||||
txn: 'Transaction Identifier',
|
||||
rph: 'Resource Priority Header Authorization',
|
||||
sid: 'Session ID',
|
||||
vot: 'Vector of Trust value',
|
||||
vtm: 'Vector of Trust trustmark URL',
|
||||
attest: 'Attestation level as defined in SHAKEN framework',
|
||||
origid: 'Originating Identifier as defined in SHAKEN framework',
|
||||
act: 'Actor',
|
||||
scope: 'Scope Values',
|
||||
client_id: 'Client Identifier',
|
||||
may_act: 'Authorized Actor - the party that is authorized to become the actor',
|
||||
jcard: 'jCard data',
|
||||
at_use_nbr: 'Number of API requests for which the access token can be used',
|
||||
div: 'Diverted Target of a Call',
|
||||
opt: 'Original PASSporT (in Full Form)',
|
||||
vc: 'Verifiable Credential as specified in the W3C Recommendation',
|
||||
vp: 'Verifiable Presentation as specified in the W3C Recommendation',
|
||||
sph: 'SIP Priority header field',
|
||||
ace_profile: 'ACE profile a token is supposed to be used with.',
|
||||
cnonce: 'Client nonce',
|
||||
exi: 'Expires in',
|
||||
roles: 'Roles',
|
||||
groups: 'Groups',
|
||||
entitlements: 'Entitlements',
|
||||
token_introspection: 'Token introspection response',
|
||||
typ: t('tools.jwt-parser.typ'),
|
||||
alg: t('tools.jwt-parser.alg'),
|
||||
iss: t('tools.jwt-parser.iss'),
|
||||
sub: t('tools.jwt-parser.sub'),
|
||||
aud: t('tools.jwt-parser.aud'),
|
||||
exp: t('tools.jwt-parser.exp'),
|
||||
nbf: t('tools.jwt-parser.nbf'),
|
||||
iat: t('tools.jwt-parser.iat'),
|
||||
jti: t('tools.jwt-parser.jti'),
|
||||
name: t('tools.jwt-parser.name'),
|
||||
given_name: t('tools.jwt-parser.givenName'),
|
||||
family_name: t('tools.jwt-parser.familyName'),
|
||||
middle_name: t('tools.jwt-parser.middleName'),
|
||||
nickname: t('tools.jwt-parser.nickname'),
|
||||
preferred_username: t('tools.jwt-parser.preferredUsername'),
|
||||
profile: t('tools.jwt-parser.profile'),
|
||||
picture: t('tools.jwt-parser.picture'),
|
||||
website: t('tools.jwt-parser.website'),
|
||||
email: t('tools.jwt-parser.email'),
|
||||
email_verified: t('tools.jwt-parser.emailVerified'),
|
||||
gender: t('tools.jwt-parser.gender'),
|
||||
birthdate: t('tools.jwt-parser.birthdate'),
|
||||
zoneinfo: t('tools.jwt-parser.zoneinfo'),
|
||||
locale: t('tools.jwt-parser.locale'),
|
||||
phone_number: t('tools.jwt-parser.phoneNumber'),
|
||||
phone_number_verified: t('tools.jwt-parser.phoneNumberVerified'),
|
||||
address: t('tools.jwt-parser.address'),
|
||||
updated_at: t('tools.jwt-parser.updatedAt'),
|
||||
azp: t('tools.jwt-parser.azp'),
|
||||
nonce: t('tools.jwt-parser.nonce'),
|
||||
auth_time: t('tools.jwt-parser.authTime'),
|
||||
at_hash: t('tools.jwt-parser.atHash'),
|
||||
c_hash: t('tools.jwt-parser.cHash'),
|
||||
acr: t('tools.jwt-parser.acr'),
|
||||
amr: t('tools.jwt-parser.amr'),
|
||||
sub_jwk: t('tools.jwt-parser.subJwk'),
|
||||
cnf: t('tools.jwt-parser.cnf'),
|
||||
sip_from_tag: t('tools.jwt-parser.sipFromTag'),
|
||||
sip_date: t('tools.jwt-parser.sipDate'),
|
||||
sip_callid: t('tools.jwt-parser.sipCallid'),
|
||||
sip_cseq_num: t('tools.jwt-parser.sipCseqNum'),
|
||||
sip_via_branch: t('tools.jwt-parser.sipViaBranch'),
|
||||
orig: t('tools.jwt-parser.orig'),
|
||||
dest: t('tools.jwt-parser.dest'),
|
||||
mky: t('tools.jwt-parser.mky'),
|
||||
events: t('tools.jwt-parser.events'),
|
||||
toe: t('tools.jwt-parser.toe'),
|
||||
txn: t('tools.jwt-parser.txn'),
|
||||
rph: t('tools.jwt-parser.rph'),
|
||||
sid: t('tools.jwt-parser.sid'),
|
||||
vot: t('tools.jwt-parser.vot'),
|
||||
vtm: t('tools.jwt-parser.vtm'),
|
||||
attest: t('tools.jwt-parser.attest'),
|
||||
origid: t('tools.jwt-parser.origid'),
|
||||
act: t('tools.jwt-parser.act'),
|
||||
scope: t('tools.jwt-parser.scope'),
|
||||
client_id: t('tools.jwt-parser.clientId'),
|
||||
may_act: t('tools.jwt-parser.mayAct'),
|
||||
jcard: t('tools.jwt-parser.jcard'),
|
||||
at_use_nbr: t('tools.jwt-parser.atUseNbr'),
|
||||
div: t('tools.jwt-parser.div'),
|
||||
opt: t('tools.jwt-parser.opt'),
|
||||
vc: t('tools.jwt-parser.vc'),
|
||||
vp: t('tools.jwt-parser.vp'),
|
||||
sph: t('tools.jwt-parser.sph'),
|
||||
ace_profile: t('tools.jwt-parser.aceProfile'),
|
||||
cnonce: t('tools.jwt-parser.cnonce'),
|
||||
exi: t('tools.jwt-parser.exi'),
|
||||
roles: t('tools.jwt-parser.roles'),
|
||||
groups: t('tools.jwt-parser.groups'),
|
||||
entitlements: t('tools.jwt-parser.entitlements'),
|
||||
token_introspection: t('tools.jwt-parser.tokenIntrospection'),
|
||||
};
|
||||
|
|
|
@ -4,6 +4,8 @@ import { useValidation } from '@/composable/validation';
|
|||
import { isNotThrowing } from '@/utils/boolean';
|
||||
import { withDefaultOnError } from '@/utils/defaults';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const rawJwt = ref(
|
||||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c',
|
||||
);
|
||||
|
@ -13,8 +15,8 @@ const decodedJWT = computed(() =>
|
|||
);
|
||||
|
||||
const sections = [
|
||||
{ key: 'header', title: 'Header' },
|
||||
{ key: 'payload', title: 'Payload' },
|
||||
{ key: 'header', title: t('tools.jwt-parser.header') },
|
||||
{ key: 'payload', title: t('tools.jwt-parser.payload') },
|
||||
] as const;
|
||||
|
||||
const validation = useValidation({
|
||||
|
@ -22,7 +24,7 @@ const validation = useValidation({
|
|||
rules: [
|
||||
{
|
||||
validator: value => value.length > 0 && isNotThrowing(() => decodeJwt({ jwt: rawJwt.value })),
|
||||
message: 'Invalid JWT',
|
||||
message: t('tools.jwt-parser.invalidJWT'),
|
||||
},
|
||||
],
|
||||
});
|
||||
|
@ -30,7 +32,7 @@ const validation = useValidation({
|
|||
|
||||
<template>
|
||||
<c-card>
|
||||
<c-input-text v-model:value="rawJwt" label="JWT to decode" :validation="validation" placeholder="Put your token here..." rows="5" multiline raw-text autofocus mb-3 />
|
||||
<c-input-text v-model:value="rawJwt" :label="t('tools.jwt-parser.label')" :validation="validation" :placeholder="t('tools.jwt-parser.placeholder')" rows="5" multiline raw-text autofocus mb-3 />
|
||||
|
||||
<n-table v-if="validation.isValid">
|
||||
<tbody>
|
||||
|
|
|
@ -2,3 +2,97 @@ tools:
|
|||
jwt-parser:
|
||||
title: JWT parser
|
||||
description: Parse and decode your JSON Web Token (jwt) and display its content.
|
||||
|
||||
label: JWT to decode
|
||||
placeholder: Put your token here...
|
||||
header: Header
|
||||
payload: Payload
|
||||
|
||||
invalidJWT: Invalid JWT
|
||||
|
||||
HS256: 'HMAC using SHA-256'
|
||||
HS384: 'HMAC using SHA-384'
|
||||
HS512: 'HMAC using SHA-512'
|
||||
RS256: 'RSASSA-PKCS1-v1_5 using SHA-256'
|
||||
RS384: 'RSASSA-PKCS1-v1_5 using SHA-384'
|
||||
RS512: 'RSASSA-PKCS1-v1_5 using SHA-512'
|
||||
ES256: 'ECDSA using P-256 and SHA-256'
|
||||
ES384: 'ECDSA using P-384 and SHA-384'
|
||||
ES512: 'ECDSA using P-521 and SHA-512'
|
||||
PS256: 'RSASSA-PSS using SHA-256 and MGF1 with SHA-256'
|
||||
PS384: 'RSASSA-PSS using SHA-384 and MGF1 with SHA-384'
|
||||
PS512: 'RSASSA-PSS using SHA-512 and MGF1 with SHA-512'
|
||||
none: 'No digital signature or MAC performed'
|
||||
|
||||
typ: 'Type'
|
||||
alg: 'Algorithm'
|
||||
iss: 'Issuer'
|
||||
sub: 'Subject'
|
||||
aud: 'Audience'
|
||||
exp: 'Expiration Time'
|
||||
nbf: 'Not Before'
|
||||
iat: 'Issued At'
|
||||
jti: 'JWT ID'
|
||||
name: 'Full name'
|
||||
givenName: 'Given name(s) or first name(s)'
|
||||
familyName: 'Surname(s) or last name(s)'
|
||||
middleName: 'Middle name(s)'
|
||||
nickname: 'Casual name'
|
||||
preferredUsername: 'Shorthand name by which the End-User wishes to be referred to'
|
||||
profile: 'Profile page URL'
|
||||
picture: 'Profile picture URL'
|
||||
website: 'Web page or blog URL'
|
||||
email: 'Preferred e-mail address'
|
||||
emailVerified: 'True if the e-mail address has been verified; otherwise false'
|
||||
gender: 'Gender'
|
||||
birthdate: 'Birthday'
|
||||
zoneinfo: 'Time zone'
|
||||
locale: 'Locale'
|
||||
phoneNumber: 'Preferred telephone number'
|
||||
phoneNumberVerified: 'True if the phone number has been verified; otherwise false'
|
||||
address: 'Preferred postal address'
|
||||
updatedAt: 'Time the information was last updated'
|
||||
azp: 'Authorized party - the party to which the ID Token was issued'
|
||||
nonce: 'Value used to associate a Client session with an ID Token'
|
||||
authTime: 'Time when the authentication occurred'
|
||||
atHash: 'Access Token hash value'
|
||||
cHash: 'Code hash value'
|
||||
acr: 'Authentication Context Class Reference'
|
||||
amr: 'Authentication Methods References'
|
||||
subJwk: 'Public key used to check the signature of an ID Token'
|
||||
cnf: 'Confirmation'
|
||||
sipFromTag: 'SIP From tag header field parameter value'
|
||||
sipDate: 'SIP Date header field value'
|
||||
sipCallid: 'SIP Call-Id header field value'
|
||||
sipCseqNum: 'SIP CSeq numeric header field parameter value'
|
||||
sipViaBranch: 'SIP Via branch header field parameter value'
|
||||
orig: 'Originating Identity String'
|
||||
dest: 'Destination Identity String'
|
||||
mky: 'Media Key Fingerprint String'
|
||||
events: 'Security Events'
|
||||
toe: 'Time of Event'
|
||||
txn: 'Transaction Identifier'
|
||||
rph: 'Resource Priority Header Authorization'
|
||||
sid: 'Session ID'
|
||||
vot: 'Vector of Trust value'
|
||||
vtm: 'Vector of Trust trustmark URL'
|
||||
attest: 'Attestation level as defined in SHAKEN framework'
|
||||
origid: 'Originating Identifier as defined in SHAKEN framework'
|
||||
act: 'Actor'
|
||||
scope: 'Scope Values'
|
||||
clientId: 'Client Identifier'
|
||||
mayAct: 'Authorized Actor - the party that is authorized to become the actor'
|
||||
jcard: 'jCard data'
|
||||
atUseNbr: 'Number of API requests for which the access token can be used'
|
||||
div: 'Diverted Target of a Call'
|
||||
opt: 'Original PASSporT (in Full Form)'
|
||||
vc: 'Verifiable Credential as specified in the W3C Recommendation'
|
||||
vp: 'Verifiable Presentation as specified in the W3C Recommendation'
|
||||
sph: 'SIP Priority header field'
|
||||
aceProfile: 'ACE profile a token is supposed to be used with.'
|
||||
cnonce: 'Client nonce'
|
||||
exi: 'Expires in'
|
||||
roles: 'Roles'
|
||||
groups: 'Groups'
|
||||
entitlements: 'Entitlements'
|
||||
tokenIntrospection: 'Token introspection response'
|
||||
|
|
98
src/tools/jwt-parser/locales/zh.yml
Normal file
98
src/tools/jwt-parser/locales/zh.yml
Normal file
|
@ -0,0 +1,98 @@
|
|||
tools:
|
||||
jwt-parser:
|
||||
title: JWT 解析器
|
||||
description: 解析和解码您的 JSON Web Token (jwt) 并显示其内容。
|
||||
|
||||
label: 要解码的 JWT
|
||||
placeholder: 在这里放置您的令牌...
|
||||
header: 头部
|
||||
payload: 负载
|
||||
|
||||
invalidJWT: 无效的 JWT
|
||||
|
||||
HS256: '使用 SHA-256 的 HMAC'
|
||||
HS384: '使用 SHA-384 的 HMAC'
|
||||
HS512: '使用 SHA-512 的 HMAC'
|
||||
RS256: '使用 SHA-256 的 RSASSA-PKCS1-v1_5'
|
||||
RS384: '使用 SHA-384 的 RSASSA-PKCS1-v1_5'
|
||||
RS512: '使用 SHA-512 的 RSASSA-PKCS1-v1_5'
|
||||
ES256: '使用 P-256 和 SHA-256 的 ECDSA'
|
||||
ES384: '使用 P-384 和 SHA-384 的 ECDSA'
|
||||
ES512: '使用 P-521 和 SHA-512 的 ECDSA'
|
||||
PS256: '使用 SHA-256 和具有 SHA-256 的 MGF1 的 RSASSA-PSS'
|
||||
PS384: '使用 SHA-384 和具有 SHA-384 的 MGF1 的 RSASSA-PSS'
|
||||
PS512: '使用 SHA-512 和具有 SHA-512 的 MGF1 的 RSASSA-PSS'
|
||||
none: '未执行数字签名或 MAC'
|
||||
|
||||
typ: '类型'
|
||||
alg: '算法'
|
||||
iss: '签发者'
|
||||
sub: '主题'
|
||||
aud: '受众'
|
||||
exp: '过期时间'
|
||||
nbf: '不早于'
|
||||
iat: '签发时间'
|
||||
jti: 'JWT ID'
|
||||
name: '全名'
|
||||
givenName: '名字'
|
||||
familyName: '姓氏'
|
||||
middleName: '中间名'
|
||||
nickname: '昵称'
|
||||
preferredUsername: '用户希望被称呼的简称'
|
||||
profile: '个人资料页面 URL'
|
||||
picture: '个人资料图片 URL'
|
||||
website: '网页或博客 URL'
|
||||
email: '首选电子邮件地址'
|
||||
emailVerified: '如果电子邮件地址已经验证为 true;否则为 false'
|
||||
gender: '性别'
|
||||
birthdate: '生日'
|
||||
zoneinfo: '时区'
|
||||
locale: '区域设置'
|
||||
phoneNumber: '首选电话号码'
|
||||
phoneNumberVerified: '如果电话号码已经验证为 true;否则为 false'
|
||||
address: '首选邮寄地址'
|
||||
updatedAt: '信息上次更新时间'
|
||||
azp: '授权方 - 发出 ID 令牌的一方'
|
||||
nonce: '用于将客户端会话与 ID 令牌关联的值'
|
||||
authTime: '认证发生时间'
|
||||
atHash: '访问令牌哈希值'
|
||||
cHash: '代码哈希值'
|
||||
acr: '认证上下文类引用'
|
||||
amr: '认证方法引用'
|
||||
subJwk: '用于验证 ID 令牌签名的公钥'
|
||||
cnf: '确认'
|
||||
sipFromTag: 'SIP From 标签头字段参数值'
|
||||
sipDate: 'SIP 日期头字段值'
|
||||
sipCallid: 'SIP Call-Id 头字段值'
|
||||
sipCseqNum: 'SIP CSeq 数字头字段参数值'
|
||||
sipViaBranch: 'SIP Via 分支头字段参数值'
|
||||
orig: '原始身份字符串'
|
||||
dest: '目标身份字符串'
|
||||
mky: '媒体密钥指纹字符串'
|
||||
events: '安全事件'
|
||||
toe: '事件时间'
|
||||
txn: '交易标识符'
|
||||
rph: '资源优先级头授权'
|
||||
sid: '会话 ID'
|
||||
vot: '信任向量值'
|
||||
vtm: '信任向量标记 URL'
|
||||
attest: 'SHAKEN 框架中定义的证明级别'
|
||||
origid: 'SHAKEN 框架中定义的起始标识符'
|
||||
act: '操作者'
|
||||
scope: '范围值'
|
||||
clientId: '客户端标识符'
|
||||
mayAct: '授权操作者 - 被授权成为操作者的一方'
|
||||
jcard: 'jCard 数据'
|
||||
atUseNbr: '访问令牌可用于的 API 请求次数'
|
||||
div: '呼叫的被转移目标'
|
||||
opt: '原始 PASSporT(完整形式)'
|
||||
vc: '根据 W3C 推荐规范指定的可验证凭证'
|
||||
vp: '根据 W3C 推荐规范指定的可验证展示'
|
||||
sph: 'SIP 优先级头字段'
|
||||
aceProfile: 'ACE 配置文件应与之一起使用的令牌'
|
||||
cnonce: '客户端随机数'
|
||||
exi: '剩余时间'
|
||||
roles: '角色'
|
||||
groups: '组'
|
||||
entitlements: '权利'
|
||||
tokenIntrospection: '令牌内省响应'
|
|
@ -1,10 +1,11 @@
|
|||
import { Keyboard } from '@vicons/tabler';
|
||||
import { defineTool } from '../tool';
|
||||
import { translate as t } from '@/plugins/i18n.plugin';
|
||||
|
||||
export const tool = defineTool({
|
||||
name: 'Keycode info',
|
||||
name: t('tools.keycode-info.title'),
|
||||
path: '/keycode-info',
|
||||
description: 'Find the javascript keycode, code, location and modifiers of any pressed key.',
|
||||
description: t('tools.keycode-info.description'),
|
||||
keywords: [
|
||||
'keycode',
|
||||
'info',
|
||||
|
|
|
@ -5,6 +5,8 @@ import InputCopyable from '../../components/InputCopyable.vue';
|
|||
|
||||
const event = ref<KeyboardEvent>();
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
useEventListener(document, 'keydown', (e) => {
|
||||
event.value = e;
|
||||
});
|
||||
|
@ -16,28 +18,28 @@ const fields = computed(() => {
|
|||
|
||||
return [
|
||||
{
|
||||
label: 'Key :',
|
||||
label: t('tools.keycode-info.keyLabel'),
|
||||
value: event.value.key,
|
||||
placeholder: 'Key name...',
|
||||
placeholder: t('tools.keycode-info.keyPlaceholder'),
|
||||
},
|
||||
{
|
||||
label: 'Keycode :',
|
||||
label: t('tools.keycode-info.keycodeLabel'),
|
||||
value: String(event.value.keyCode),
|
||||
placeholder: 'Keycode...',
|
||||
placeholder: t('tools.keycode-info.keycodePlaceholder'),
|
||||
},
|
||||
{
|
||||
label: 'Code :',
|
||||
label: t('tools.keycode-info.codeLabel'),
|
||||
value: event.value.code,
|
||||
placeholder: 'Code...',
|
||||
placeholder: t('tools.keycode-info.codePlaceholder'),
|
||||
},
|
||||
{
|
||||
label: 'Location :',
|
||||
label: t('tools.keycode-info.locationLabel'),
|
||||
value: String(event.value.location),
|
||||
placeholder: 'Code...',
|
||||
placeholder: t('tools.keycode-info.locationPlaceholder'),
|
||||
},
|
||||
|
||||
{
|
||||
label: 'Modifiers :',
|
||||
label: t('tools.keycode-info.modifiersLabel'),
|
||||
value: [
|
||||
event.value.metaKey && 'Meta',
|
||||
event.value.shiftKey && 'Shift',
|
||||
|
@ -46,7 +48,7 @@ const fields = computed(() => {
|
|||
]
|
||||
.filter(Boolean)
|
||||
.join(' + '),
|
||||
placeholder: 'None',
|
||||
placeholder: t('tools.keycode-info.modifiersPlaceholder'),
|
||||
},
|
||||
];
|
||||
});
|
||||
|
@ -59,7 +61,7 @@ const fields = computed(() => {
|
|||
{{ event.key }}
|
||||
</div>
|
||||
<span lh-1 op-70>
|
||||
Press the key on your keyboard you want to get info about this key
|
||||
{{ t('tools.keycode-info.tips') }}
|
||||
</span>
|
||||
</c-card>
|
||||
|
||||
|
|
|
@ -2,3 +2,16 @@ tools:
|
|||
keycode-info:
|
||||
title: Keycode info
|
||||
description: Find the javascript keycode, code, location and modifiers of any pressed key.
|
||||
|
||||
keyLabel: 'Key :'
|
||||
keyPlaceholder: 'Key name...'
|
||||
keycodeLabel: 'Keycode :'
|
||||
keycodePlaceholder: 'Keycode...'
|
||||
codeLabel: 'Code :'
|
||||
codePlaceholder: 'Code...'
|
||||
locationLabel: 'Location :'
|
||||
locationPlaceholder: 'Code...'
|
||||
modifiersLabel: 'Modifiers :'
|
||||
modifiersPlaceholder: 'None'
|
||||
|
||||
tips: Press the key on your keyboard you want to get info about this key
|
||||
|
|
17
src/tools/keycode-info/locales/zh.yml
Normal file
17
src/tools/keycode-info/locales/zh.yml
Normal file
|
@ -0,0 +1,17 @@
|
|||
tools:
|
||||
keycode-info:
|
||||
title: 按键信息
|
||||
description: 查找任何按键的 JavaScript 按键码、代码、位置和修饰键。
|
||||
|
||||
keyLabel: '按键:'
|
||||
keyPlaceholder: '按键名称...'
|
||||
keycodeLabel: '按键码:'
|
||||
keycodePlaceholder: '按键码...'
|
||||
codeLabel: '代码:'
|
||||
codePlaceholder: '代码...'
|
||||
locationLabel: '位置:'
|
||||
locationPlaceholder: '位置...'
|
||||
modifiersLabel: '修饰键:'
|
||||
modifiersPlaceholder: '无'
|
||||
|
||||
tips: 按下您键盘上想要获取信息的按键
|
|
@ -1,10 +1,11 @@
|
|||
import { AbcRound } from '@vicons/material';
|
||||
import { defineTool } from '../tool';
|
||||
import { translate as t } from '@/plugins/i18n.plugin';
|
||||
|
||||
export const tool = defineTool({
|
||||
name: 'Slugify string',
|
||||
name: t('tools.slugify-string.title'),
|
||||
path: '/slugify-string',
|
||||
description: 'Make a string url, filename and id safe.',
|
||||
description: t('tools.slugify-string.description'),
|
||||
keywords: ['slugify', 'string', 'escape', 'emoji', 'special', 'character', 'space', 'trim'],
|
||||
component: () => import('./slugify-string.vue'),
|
||||
icon: AbcRound,
|
||||
|
|
|
@ -2,3 +2,11 @@ tools:
|
|||
slugify-string:
|
||||
title: Slugify string
|
||||
description: Make a string url, filename and id safe.
|
||||
|
||||
inputLabel: Your string to slugify
|
||||
inputPlaceholder: 'Put your string here (ex: My file path)'
|
||||
outputLabel: Your slug
|
||||
outputPlaceholder: 'You slug will be generated here (ex: my-file-path)'
|
||||
copyBtn: Copy slug
|
||||
|
||||
copied: Slug copied to clipboard
|
||||
|
|
12
src/tools/slugify-string/locales/zh.yml
Normal file
12
src/tools/slugify-string/locales/zh.yml
Normal file
|
@ -0,0 +1,12 @@
|
|||
tools:
|
||||
slugify-string:
|
||||
title: 字符串转换为 Slug
|
||||
description: 将字符串转换为 URL、文件名和 ID 安全的格式。
|
||||
|
||||
inputLabel: 要转换为 Slug 的字符串
|
||||
inputPlaceholder: '在此输入您的字符串(例如:我的文件路径)'
|
||||
outputLabel: 您的 Slug
|
||||
outputPlaceholder: '您的 Slug 将在此生成(例如:my-file-path)'
|
||||
copyBtn: 复制 Slug
|
||||
|
||||
copied: Slug 已复制到剪贴板
|
|
@ -3,20 +3,21 @@ import slugify from '@sindresorhus/slugify';
|
|||
import { withDefaultOnError } from '@/utils/defaults';
|
||||
import { useCopy } from '@/composable/copy';
|
||||
|
||||
const { t } = useI18n();
|
||||
const input = ref('');
|
||||
const slug = computed(() => withDefaultOnError(() => slugify(input.value), ''));
|
||||
const { copy } = useCopy({ source: slug, text: 'Slug copied to clipboard' });
|
||||
const { copy } = useCopy({ source: slug, text: t('tools.slugify-string.copied') });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<c-input-text v-model:value="input" multiline placeholder="Put your string here (ex: My file path)" label="Your string to slugify" autofocus raw-text mb-5 />
|
||||
<c-input-text v-model:value="input" multiline :placeholder="t('tools.slugify-string.inputPlaceholder')" :label="t('tools.slugify-string.inputLabel')" autofocus raw-text mb-5 />
|
||||
|
||||
<c-input-text :value="slug" multiline readonly placeholder="You slug will be generated here (ex: my-file-path)" label="Your slug" mb-5 />
|
||||
<c-input-text :value="slug" multiline readonly :placeholder="t('tools.slugify-string.outputPlaceholder')" :label="t('tools.slugify-string.outputLabel')" mb-5 />
|
||||
|
||||
<div flex justify-center>
|
||||
<c-button :disabled="slug.length === 0" @click="copy()">
|
||||
Copy slug
|
||||
{{ t('tools.slugify-string.copyBtn') }}
|
||||
</c-button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import { Browser } from '@vicons/tabler';
|
||||
import { defineTool } from '../tool';
|
||||
import { translate as t } from '@/plugins/i18n.plugin';
|
||||
|
||||
export const tool = defineTool({
|
||||
name: 'User-agent parser',
|
||||
name: t('tools.user-agent-parser.title'),
|
||||
path: '/user-agent-parser',
|
||||
description: 'Detect and parse Browser, Engine, OS, CPU, and Device type/model from an user-agent string.',
|
||||
description: t('tools.user-agent-parser.description'),
|
||||
keywords: ['user', 'agent', 'parser', 'browser', 'engine', 'os', 'cpu', 'device', 'user-agent', 'client'],
|
||||
component: () => import('./user-agent-parser.vue'),
|
||||
icon: Browser,
|
||||
|
|
|
@ -2,3 +2,29 @@ tools:
|
|||
user-agent-parser:
|
||||
title: User-agent parser
|
||||
description: Detect and parse Browser, Engine, OS, CPU, and Device type/model from an user-agent string.
|
||||
|
||||
name: Name
|
||||
version: Version
|
||||
model: Model
|
||||
type: Type
|
||||
vendor: Vendor
|
||||
architecture: Architecture
|
||||
|
||||
browser: Browser
|
||||
browserNameFallback: No browser name available
|
||||
browserVersionFallback: No browser version available
|
||||
engine: Engine
|
||||
engineNameFallback: No engine name available
|
||||
engineVersionFallback: No engine version available
|
||||
os: OS
|
||||
osNameFallback: No OS name available
|
||||
osVersionFallback: No OS version available
|
||||
device: Device
|
||||
deviceModelFallback: No device model available
|
||||
deviceTypeFallback: No device type available
|
||||
deviceVendorFallback: No device vendor available
|
||||
cpu: CPU
|
||||
cpuArchitectureFallback: No CPU architecture available
|
||||
|
||||
label: User agent string
|
||||
placeholder: Put your user-agent here...
|
||||
|
|
30
src/tools/user-agent-parser/locales/zh.yml
Normal file
30
src/tools/user-agent-parser/locales/zh.yml
Normal file
|
@ -0,0 +1,30 @@
|
|||
tools:
|
||||
user-agent-parser:
|
||||
title: User-agent 解析器
|
||||
description: 从用户代理字符串中检测和解析浏览器、引擎、操作系统、CPU 和设备类型/型号。
|
||||
|
||||
name: 名称
|
||||
version: 版本
|
||||
model: 型号
|
||||
type: 类型
|
||||
vendor: 供应商
|
||||
architecture: 架构
|
||||
|
||||
browser: 浏览器
|
||||
browserNameFallback: 没有可用的浏览器名称
|
||||
browserVersionFallback: 没有可用的浏览器版本
|
||||
engine: 引擎
|
||||
engineNameFallback: 没有可用的引擎名称
|
||||
engineVersionFallback: 没有可用的引擎版本
|
||||
os: 操作系统
|
||||
osNameFallback: 没有可用的操作系统名称
|
||||
osVersionFallback: 没有可用的操作系统版本
|
||||
device: 设备
|
||||
deviceModelFallback: 没有可用的设备型号
|
||||
deviceTypeFallback: 没有可用的设备类型
|
||||
deviceVendorFallback: 没有可用的设备供应商
|
||||
cpu: 中央处理器
|
||||
cpuArchitectureFallback: 没有可用的 CPU 架构
|
||||
|
||||
label: 用户代理字符串
|
||||
placeholder: 在此处输入您的用户代理字符串...
|
|
@ -6,6 +6,7 @@ import type { UserAgentResultSection } from './user-agent-parser.types';
|
|||
import { withDefaultOnError } from '@/utils/defaults';
|
||||
|
||||
const ua = ref(navigator.userAgent as string);
|
||||
const { t } = useI18n();
|
||||
|
||||
// If not input in the ua field is present return an empty object of type UAParser.IResult because otherwise
|
||||
// UAParser returns the values for the current Browser. This is confusing because results are shown for an empty
|
||||
|
@ -19,82 +20,82 @@ const userAgentInfo = computed(() => withDefaultOnError(() => getUserAgentInfo(u
|
|||
|
||||
const sections: UserAgentResultSection[] = [
|
||||
{
|
||||
heading: 'Browser',
|
||||
heading: t('tools.user-agent-parser.browser'),
|
||||
icon: Browser,
|
||||
content: [
|
||||
{
|
||||
label: 'Name',
|
||||
label: t('tools.user-agent-parser.name'),
|
||||
getValue: block => block?.browser.name,
|
||||
undefinedFallback: 'No browser name available',
|
||||
undefinedFallback: t('tools.user-agent-parser.browserNameFallback'),
|
||||
},
|
||||
{
|
||||
label: 'Version',
|
||||
label: t('tools.user-agent-parser.version'),
|
||||
getValue: block => block?.browser.version,
|
||||
undefinedFallback: 'No browser version available',
|
||||
undefinedFallback: t('tools.user-agent-parser.browserVersionFallback'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: 'Engine',
|
||||
heading: t('tools.user-agent-parser.engine'),
|
||||
icon: Engine,
|
||||
content: [
|
||||
{
|
||||
label: 'Name',
|
||||
label: t('tools.user-agent-parser.name'),
|
||||
getValue: block => block?.engine.name,
|
||||
undefinedFallback: 'No engine name available',
|
||||
undefinedFallback: t('tools.user-agent-parser.engineNameFallback'),
|
||||
},
|
||||
{
|
||||
label: 'Version',
|
||||
label: t('tools.user-agent-parser.version'),
|
||||
getValue: block => block?.engine.version,
|
||||
undefinedFallback: 'No engine version available',
|
||||
undefinedFallback: t('tools.user-agent-parser.engineVersionFallback'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: 'OS',
|
||||
heading: t('tools.user-agent-parser.os'),
|
||||
icon: Adjustments,
|
||||
content: [
|
||||
{
|
||||
label: 'Name',
|
||||
label: t('tools.user-agent-parser.name'),
|
||||
getValue: block => block?.os.name,
|
||||
undefinedFallback: 'No OS name available',
|
||||
undefinedFallback: t('tools.user-agent-parser.osNameFallback'),
|
||||
},
|
||||
{
|
||||
label: 'Version',
|
||||
label: t('tools.user-agent-parser.version'),
|
||||
getValue: block => block?.os.version,
|
||||
undefinedFallback: 'No OS version available',
|
||||
undefinedFallback: t('tools.user-agent-parser.osVersionFallback'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: 'Device',
|
||||
heading: t('tools.user-agent-parser.device'),
|
||||
icon: Devices,
|
||||
content: [
|
||||
{
|
||||
label: 'Model',
|
||||
label: t('tools.user-agent-parser.model'),
|
||||
getValue: block => block?.device.model,
|
||||
undefinedFallback: 'No device model available',
|
||||
undefinedFallback: t('tools.user-agent-parser.deviceModelFallback'),
|
||||
},
|
||||
{
|
||||
label: 'Type',
|
||||
label: t('tools.user-agent-parser.type'),
|
||||
getValue: block => block?.device.type,
|
||||
undefinedFallback: 'No device type available',
|
||||
undefinedFallback: t('tools.user-agent-parser.deviceTypeFallback'),
|
||||
},
|
||||
{
|
||||
label: 'Vendor',
|
||||
label: t('tools.user-agent-parser.vendor'),
|
||||
getValue: block => block?.device.vendor,
|
||||
undefinedFallback: 'No device vendor available',
|
||||
undefinedFallback: t('tools.user-agent-parser.deviceVendorFallback'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: 'CPU',
|
||||
heading: t('tools.user-agent-parser.cpu'),
|
||||
icon: Cpu,
|
||||
content: [
|
||||
{
|
||||
label: 'Architecture',
|
||||
label: t('tools.user-agent-parser.architecture'),
|
||||
getValue: block => block?.cpu.architecture,
|
||||
undefinedFallback: 'No CPU architecture available',
|
||||
undefinedFallback: t('tools.user-agent-parser.cpuArchitectureFallback'),
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -105,9 +106,9 @@ const sections: UserAgentResultSection[] = [
|
|||
<div>
|
||||
<c-input-text
|
||||
v-model:value="ua"
|
||||
label="User agent string"
|
||||
:label="t('tools.user-agent-parser.label')"
|
||||
multiline
|
||||
placeholder="Put your user-agent here..."
|
||||
:placeholder="t('tools.user-agent-parser.placeholder')"
|
||||
clearable
|
||||
raw-text
|
||||
rows="2"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue