Merge branch 'master' of https://github.com/ethereum/remix-project into git4refactor2

pull/4791/head
filip mertens 6 months ago
commit b93dea9325
  1. 6
      apps/circuit-compiler/src/app/components/container.tsx
  2. 2
      apps/circuit-compiler/src/app/components/feedbackAlert.tsx
  3. 5
      apps/remix-ide/src/app.js
  4. 15
      apps/remix-ide/src/app/components/pinned-panel.tsx
  5. 2
      apps/remix-ide/src/app/components/side-panel.tsx
  6. 17
      apps/remix-ide/src/app/components/vertical-icons.tsx
  7. 49
      apps/remix-ide/src/app/plugins/openaigpt.tsx
  8. 44
      apps/remix-ide/src/app/plugins/solcoderAI.tsx
  9. 2
      apps/remix-ide/src/app/tabs/locale-module.js
  10. 1
      apps/remix-ide/src/app/tabs/locales/en/udapp.json
  11. 10
      apps/remix-ide/src/app/tabs/locales/es/panel.json
  12. 10
      apps/remix-ide/src/app/tabs/locales/fr/panel.json
  13. 10
      apps/remix-ide/src/app/tabs/locales/it/panel.json
  14. 15
      apps/remix-ide/src/app/tabs/locales/ko/circuit.json
  15. 26
      apps/remix-ide/src/app/tabs/locales/ko/debugger.json
  16. 134
      apps/remix-ide/src/app/tabs/locales/ko/filePanel.json
  17. 69
      apps/remix-ide/src/app/tabs/locales/ko/home.json
  18. 17
      apps/remix-ide/src/app/tabs/locales/ko/index.js
  19. 10
      apps/remix-ide/src/app/tabs/locales/ko/panel.json
  20. 13
      apps/remix-ide/src/app/tabs/locales/ko/permissionHandler.json
  21. 43
      apps/remix-ide/src/app/tabs/locales/ko/pluginManager.json
  22. 3
      apps/remix-ide/src/app/tabs/locales/ko/remixApp.json
  23. 7
      apps/remix-ide/src/app/tabs/locales/ko/remixUiTabs.json
  24. 24
      apps/remix-ide/src/app/tabs/locales/ko/search.json
  25. 44
      apps/remix-ide/src/app/tabs/locales/ko/settings.json
  26. 81
      apps/remix-ide/src/app/tabs/locales/ko/solidity.json
  27. 41
      apps/remix-ide/src/app/tabs/locales/ko/solidityUnitTesting.json
  28. 43
      apps/remix-ide/src/app/tabs/locales/ko/terminal.json
  29. 139
      apps/remix-ide/src/app/tabs/locales/ko/udapp.json
  30. 10
      apps/remix-ide/src/app/tabs/locales/ru/panel.json
  31. 10
      apps/remix-ide/src/app/tabs/locales/zh/panel.json
  32. 1
      apps/remix-ide/src/remixAppManager.js
  33. 1
      apps/remix-ide/src/remixEngine.js
  34. 2
      apps/vyper/src/app/components/CompileErrorCard.tsx
  35. 4
      apps/vyper/src/app/utils/remix-client.tsx
  36. 3
      libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts
  37. 8
      libs/remix-ui/editor/src/lib/remix-ui-editor.tsx
  38. 2
      libs/remix-ui/home-tab/src/lib/components/homeTablangOptions.tsx
  39. 36
      libs/remix-ui/panel/src/lib/plugins/panel-header.tsx
  40. 24
      libs/remix-ui/panel/src/lib/plugins/panel-plugin.tsx
  41. 4
      libs/remix-ui/panel/src/lib/plugins/panel.css
  42. 3
      libs/remix-ui/panel/src/lib/plugins/remix-ui-panel.tsx
  43. 6
      libs/remix-ui/renderer/src/lib/renderer.tsx
  44. 11
      libs/remix-ui/run-tab/src/lib/components/universalDappUI.tsx
  45. 5
      libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx
  46. 3
      libs/remix-ui/terminal/src/lib/terminalWelcome.tsx
  47. 16
      libs/remix-ui/vertical-icons-panel/src/lib/components/Icon.tsx
  48. 1
      libs/remix-ui/vertical-icons-panel/src/lib/types/index.ts
  49. 10
      releaseDetails.json

@ -73,7 +73,7 @@ export function Container () {
explain why the error occurred and how to fix it.
`
// @ts-ignore
await circuitApp.plugin.call('openaigpt', 'message', message)
await circuitApp.plugin.call('solcoder', 'error_explaining', message)
} else {
const message = `
error message: ${error}
@ -81,7 +81,7 @@ export function Container () {
explain why the error occurred and how to fix it.
`
// @ts-ignore
await circuitApp.plugin.call('openaigpt', 'message', message)
await circuitApp.plugin.call('solcoder', 'error_explaining', message)
}
} else {
const error = report.message
@ -91,7 +91,7 @@ export function Container () {
explain why the error occurred and how to fix it.
`
// @ts-ignore
await circuitApp.plugin.call('openaigpt', 'message', message)
await circuitApp.plugin.call('solcoder', 'error_explaining', message)
}
}

@ -24,7 +24,7 @@ export function FeedbackAlert ({ message, askGPT }: FeedbackAlertProps) {
<span className="border border-success text-success btn-sm" onClick={(e) => {
e.stopPropagation()
askGPT()
}}>ASK GPT</span>
}}>Ask RemixAI</span>
</div>
</>
</RenderIf>

@ -56,7 +56,6 @@ import { ripgrepPlugin } from './app/plugins/electron/ripgrepPlugin'
import { compilerLoaderPlugin, compilerLoaderPluginDesktop } from './app/plugins/electron/compilerLoaderPlugin'
import { GitPlugin } from './app/plugins/git'
import {OpenAIGpt} from './app/plugins/openaigpt'
import {SolCoder} from './app/plugins/solcoderAI'
const isElectron = require('is-electron')
@ -237,7 +236,6 @@ class AppComponent {
const contractFlattener = new ContractFlattener()
// ----------------- AI --------------------------------------
const openaigpt = new OpenAIGpt()
const solcoder = new SolCoder()
// ----------------- import content service ------------------------
@ -356,7 +354,6 @@ class AppComponent {
contractFlattener,
solidityScript,
templates,
openaigpt,
solcoder,
git,
pluginStateLogger
@ -517,7 +514,7 @@ class AppComponent {
await this.appManager.registerContextMenuItems()
}
)
await this.appManager.activatePlugin(['solidity-script', 'openaigpt'])
await this.appManager.activatePlugin(['solidity-script'])
await this.appManager.activatePlugin(['solcoder'])

@ -11,12 +11,13 @@ const pinnedPanel = {
displayName: 'Pinned Panel',
description: 'Remix IDE pinned panel',
version: packageJson.version,
methods: ['addView', 'removeView', 'currentFocus', 'pinView', 'unPinView']
methods: ['addView', 'removeView', 'currentFocus', 'pinView', 'unPinView', 'highlight']
}
export class PinnedPanel extends AbstractPanel {
dispatch: React.Dispatch<any> = () => {}
loggedState: any
loggedState: Record<string, any>
highlightStamp: number
constructor() {
super(pinnedPanel)
@ -61,6 +62,11 @@ export class PinnedPanel extends AbstractPanel {
this.emit('unPinnedPlugin', profile)
}
highlight () {
this.highlightStamp = Date.now()
this.renderComponent()
}
setDispatch (dispatch: React.Dispatch<any>) {
this.dispatch = dispatch
}
@ -72,13 +78,14 @@ export class PinnedPanel extends AbstractPanel {
}
updateComponent(state: any) {
return <RemixPluginPanel header={<RemixUIPanelHeader plugins={state.plugins} pinView={this.pinView.bind(this)} unPinView={this.unPinView.bind(this)}></RemixUIPanelHeader>} plugins={state.plugins} pluginState={state.pluginState} />
return <RemixPluginPanel header={<RemixUIPanelHeader plugins={state.plugins} pinView={this.pinView.bind(this)} unPinView={this.unPinView.bind(this)}></RemixUIPanelHeader>} { ...state } />
}
renderComponent() {
this.dispatch({
plugins: this.plugins,
pluginState: this.loggedState
pluginState: this.loggedState,
highlightStamp: this.highlightStamp
})
}
}

@ -73,7 +73,6 @@ export class SidePanel extends AbstractPanel {
await this.call('pinnedPanel', 'pinView', profile, this.plugins[profile.name].view)
if (this.plugins[profile.name].active) this.call('menuicons', 'select', 'filePanel')
super.remove(profile.name)
this.call('menuicons', 'unlinkContent', profile)
this.renderComponent()
}
@ -85,7 +84,6 @@ export class SidePanel extends AbstractPanel {
super.addView(profile, view)
this.plugins[activePlugin].active = false
this.plugins[profile.name].active = true
await this.call('menuicons', 'linkContent', profile)
this.showContent(profile.name)
}

@ -79,6 +79,22 @@ export class VerticalIcons extends Plugin {
}
this.renderComponent()
})
this.on('pinnedPanel', 'pinnedPlugin', (profile) => {
Object.keys(this.icons).map((icon) => {
if (this.icons[icon].profile.name === profile.name) {
this.icons[icon].pinned = true
} else {
this.icons[icon].pinned = false
}
})
this.renderComponent()
})
this.on('pinnedPanel', 'unPinnedPlugin', (profile) => {
if (this.icons[profile.name]) this.icons[profile.name].pinned = false
this.renderComponent()
})
}
async linkContent(profile: Profile) {
@ -87,6 +103,7 @@ export class VerticalIcons extends Plugin {
this.icons[profile.name] = {
profile: profile,
active: false,
pinned: false,
canbeDeactivated: await this.call('manager', 'canDeactivate', this.profile, profile),
timestamp: Date.now()
}

@ -1,49 +0,0 @@
import { Plugin } from '@remixproject/engine'
import { CreateChatCompletionResponse } from 'openai'
const _paq = (window._paq = window._paq || [])
const profile = {
name: 'openaigpt',
displayName: 'openaigpt',
description: 'openaigpt',
methods: ['message'],
events: [],
maintainedBy: 'Remix',
}
export class OpenAIGpt extends Plugin {
constructor() {
super(profile)
}
async message(prompt): Promise<CreateChatCompletionResponse> {
this.call('layout', 'maximizeTerminal')
this.call('terminal', 'log', { type: 'aitypewriterwarning', value: 'Waiting for GPT answer...' })
let result
try {
result = await (
await fetch('https://openai-gpt.remixproject.org', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({ prompt }),
})
).json()
} catch (e) {
this.call('terminal', 'log', { type: 'typewritererror', value: `Unable to get a response ${e.message}` })
return
}
if (result && result.choices && result.choices.length) {
this.call('terminal', 'log', { type: 'aitypewriterwarning', value: result.choices[0].message.content })
} else if (result.error) {
this.call('terminal', 'log', { type: 'aitypewriterwarning', value: result.error })
} else {
this.call('terminal', 'log', { type: 'aitypewriterwarning', value: 'No response...' })
}
return result.data
}
}

@ -15,7 +15,7 @@ const profile = {
name: 'solcoder',
displayName: 'solcoder',
description: 'solcoder',
methods: ['code_generation', 'code_completion', "solidity_answer", "code_explaining", "code_insertion"],
methods: ['code_generation', 'code_completion', "solidity_answer", "code_explaining", "code_insertion", "error_explaining"],
events: [],
maintainedBy: 'Remix',
}
@ -50,6 +50,8 @@ export class SolCoder extends Plugin {
async code_generation(prompt): Promise<any> {
this.emit("aiInfering")
this.call('layout', 'maximizeTerminal')
_paq.push(['trackEvent', 'ai', 'solcoder', 'code_generation'])
let result
try {
result = await(
@ -78,6 +80,9 @@ export class SolCoder extends Plugin {
async solidity_answer(prompt): Promise<any> {
this.emit("aiInfering")
this.call('layout', 'maximizeTerminal')
this.call('terminal', 'log', { type: 'aitypewriterwarning', value: `\n\nWaiting for RemixAI answer...` })
_paq.push(['trackEvent', 'ai', 'solcoder', 'answering'])
let result
try {
const main_prompt = this._build_solgpt_promt(prompt)
@ -112,6 +117,9 @@ export class SolCoder extends Plugin {
async code_explaining(prompt, context:string=""): Promise<any> {
this.emit("aiInfering")
this.call('layout', 'maximizeTerminal')
this.call('terminal', 'log', { type: 'aitypewriterwarning', value: `\n\nWaiting for RemixAI answer...` })
_paq.push(['trackEvent', 'ai', 'solcoder', 'explaining'])
let result
try {
result = await(
@ -138,6 +146,8 @@ export class SolCoder extends Plugin {
async code_completion(prompt, options:SuggestOptions=null): Promise<any> {
this.emit("aiInfering")
_paq.push(['trackEvent', 'ai', 'solcoder', 'code_completion'])
let result
try {
result = await(
@ -184,6 +194,8 @@ export class SolCoder extends Plugin {
async code_insertion(msg_pfx, msg_sfx): Promise<any> {
this.emit("aiInfering")
_paq.push(['trackEvent', 'ai', 'solcoder', 'code_insertion'])
let result
try {
result = await(
@ -218,6 +230,36 @@ export class SolCoder extends Plugin {
}
}
async error_explaining(prompt): Promise<any> {
this.emit("aiInfering")
this.call('layout', 'maximizeTerminal')
this.call('terminal', 'log', { type: 'aitypewriterwarning', value: `\n\nWaiting for RemixAI answer...` })
_paq.push(['trackEvent', 'ai', 'solcoder', 'explaining'])
let result
try {
result = await(
await fetch(this.api_url, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({ "data":[prompt, "error_explaining", false,2000,0.9,0.8,50]}),
})
).json()
if (result) {
this.call('terminal', 'log', { type: 'aitypewriterwarning', value: result.data[0] })
}
return result.data[0]
} catch (e) {
this.call('terminal', 'log', { type: 'typewritererror', value: `Unable to get a response ${e.message}` })
return
} finally {
this.emit("aiInferingDone")
}
}
_build_solgpt_promt(user_promt:string){
if (this.solgpt_chat_history.length === 0){
return user_promt

@ -8,6 +8,7 @@ import zhJson from './locales/zh'
import esJson from './locales/es'
import frJson from './locales/fr'
import itJson from './locales/it'
import koJson from './locales/ko'
import ruJson from './locales/ru'
const _paq = window._paq = window._paq || []
@ -16,6 +17,7 @@ const locales = [
{ code: 'en', name: 'English', localeName: 'English', messages: enJson },
{ code: 'fr', name: 'French', localeName: 'Français', messages: frJson },
{ code: 'it', name: 'Italian', localeName: 'Italiano', messages: itJson },
{ code: 'ko', name: 'Korean', localeName: '한국인', messages: koJson },
{ code: 'ru', name: 'Russian', localeName: 'Русский', messages: ruJson },
{ code: 'es', name: 'Spanish', localeName: 'Español', messages: esJson }
]

@ -109,6 +109,7 @@
"udapp._comment_universalDappUI.tsx": "libs/remix-ui/run-tab/src/lib/components/universalDappUI.tsx",
"udapp.tooltipTextRemove": "Remove from the list",
"udapp.tooltipTextEdit": "Create a DApp using this contract in the main panel",
"udapp.tooltipTextPin": "Pin contract",
"udapp.tooltipText8": "Click for docs about using 'receive'/'fallback'",
"udapp.tooltipText9": "The Calldata to send to fallback function of the contract.",

@ -0,0 +1,10 @@
{
"panel.author": "Autor",
"panel.maintainedBy": "Mantenido por",
"panel.documentation": "Documentación",
"panel.description": "Descripción",
"panel.maintainedByRemix": "Mantenido por Remix",
"panel.pluginInfo": "Información del Complemento",
"panel.linkToDoc": "Enlace a la documentación",
"panel.makeAnissue": "Crear un asunto"
}

@ -0,0 +1,10 @@
{
"panel.author": "Auteur",
"panel.maintainedBy": "Maintenu par :",
"panel.documentation": "Documentation",
"panel.description": "Description",
"panel.maintainedByRemix": "Maintenu par Remix",
"panel.pluginInfo": "Informations sur l'extension",
"panel.linkToDoc": "Lien vers la documentation",
"panel.makeAnissue": "Faire un ticket"
}

@ -0,0 +1,10 @@
{
"panel.author": "Autore",
"panel.maintainedBy": "Mantenuto Da",
"panel.documentation": "Documentazione",
"panel.description": "Descrizione",
"panel.maintainedByRemix": "Mantenuto da Remix",
"panel.pluginInfo": "Informazioni sul plugin",
"panel.linkToDoc": "Link alla documentazione",
"panel.makeAnissue": "Crea una Issue"
}

@ -0,0 +1,15 @@
{
"circuit.compiler": "컴파일러",
"circuit.autoCompile": "자동 컴파일",
"circuit.hideWarnings": "경고 숨기기",
"circuit.advancedConfigurations": "고급 설정",
"circuit.compilerConfiguration": "컴파일러 설정",
"circuit.prime": "프라임",
"circuit.useConfigurationFile": "설정 파일 사용",
"circuit.compile": "컴파일",
"circuit.noFileSelected": "선택된 파일 없음",
"circuit.generateR1cs": "R1CS 생성",
"circuit.computeWitness": "\b증명 계산",
"circuit.signalInput": "시그널 입력",
"circuit.compute": "계산"
}

@ -0,0 +1,26 @@
{
"debugger.displayName": "디버거",
"debugger.debuggerConfiguration": "디버거 설정",
"debugger.stopDebugging": "디버깅 중지",
"debugger.provideTxNumber": "유효한 트랜잭션 해시를 제공하세요.",
"debugger.startDebugging": "디버깅 시작",
"debugger.placeholder": "트랜잭션 해시는 0x 로 시작합니다",
"debugger.debugLocaNodeLabel": "로컬 노드 강제 사용",
"debugger.useGeneratedSources": "생성된 소스 사용",
"debugger.debugWithGeneratedSources": "선택 시, 컴파일된 .yul 파일이 존재한다면 디버거는 그 파일을 단계별로 처리합니다.",
"debugger.introduction": "트랜잭션 해시를 사용하여 디버깅할 때, 컨트랙트가 검증된 경우 Remix는 Sourcify 또는 Etherscan에서 소스 코드를 가져오려고 시도합니다. Remix 설정에 당신의 Etherscan API 키를 입력하세요. 지원되는 네트워크에 대해서는 다음을 참조해 주세요",
"debugger.forceToUseCurrentLocalNode": "디버거가 현재 로컬 노드를 사용하도록 강제하기",
"debugger.sourceLocationStatus1": "중단점을 찾는 중입니다, 이 과정은 다소 시간이 걸릴 수 있습니다...",
"debugger.sourceLocationStatus2": "Sourcify나 Etherscan에서 소스 위치를 찾을 수 없습니다. 설정에서 Etherscan Api 키가 제공되었는지 확인해 주세요.",
"debugger.sourcifyDocs": "Sourcify 문서",
"debugger.noDataAvailable": "데이터 없음",
"debugger.loadMore": "더 보기",
"debugger.copy": "복사",
"debugger.stepOverBack": "이전 단계 건너뛰기",
"debugger.stepBack": "한 단계 뒤로",
"debugger.stepInto": "내부로 들어가기",
"debugger.stepOverForward": "다음 단계 건너뛰기",
"debugger.jumpPreviousBreakpoint": "이전 중단점으로 이동",
"debugger.jumpOut": "밖으로 빠져나오기",
"debugger.jumpNextBreakpoint": "다음 중단점으로 이동"
}

@ -0,0 +1,134 @@
{
"filePanel.displayName": "파일 탐색기",
"filePanel.workspace": "작업 공간",
"filePanel.create": "만들기",
"filePanel.clone": "복제",
"filePanel.download": "다운로드",
"filePanel.backup": "백업",
"filePanel.restore": "복원",
"filePanel.workspace.create": "작업공간 생성",
"filePanel.workspace.rename": "작업공간 이름 변경",
"filePanel.workspace.save_workspace": "작업공간 저장",
"filePanel.workspace.delete": "작업공간 삭제",
"filePanel.workspace.deleteConfirm": "현재 작업공간을 삭제하시겠습니까?",
"filePanel.workspace.download": "작업공간 다운로드",
"filePanel.workspace.downloadConfirm": "현재 작업 공간을 zip 파일로 다운로드 합니다. 계속하시겠습니까?",
"filePanel.workspace.deleteAll": "전체 작업공간 삭제",
"filePanel.workspace.deleteAllConfirm1": "모든 작업 공간을 정말 삭제하시겠습니까?",
"filePanel.workspace.deleteAllConfirm2": "삭제된 작업공간은 어떤 방식으로도 복구할 수 없습니다.",
"filePanel.workspace.name": "작업공간 이름",
"filePanel.workspace.chooseTemplate": "템플릿 선택",
"filePanel.workspace.backup": "전체 작업공간 백업",
"filePanel.workspace.restore": "백업에서 작업공간 복구하기",
"filePanel.workspace.clone": "Git 저장소 복제",
"filePanel.workspace.cloneMessage": "유효한 git 저장소 url을 제공하세요",
"filePanel.workspace.enterGitUrl": "Git 저장소 url을 입력하세요",
"filePanel.workspace.switch": "작업공간으로 전환",
"filePanel.workspace.solghaction": "Github action CI에서 Solidity 단위 테스트를 실행하기 위해 사전 설정된 yml 파일을 추가합니다.",
"filePanel.solghaction": "Solidity 테스트 워크플로우",
"filePanel.workspace.tssoltestghaction": "Solidity용 mocha 및 chai 테스트를 GitHub Actions CI에서 실행하기 위한 사전 설정된 yml 파일 추가",
"filePanel.tssoltestghaction": "Mocha Chai 테스트 워크플로우",
"filePanel.workspace.addscriptetherscan": "Etherscan API와 상호 작용하는 데 사용할 수 있는 스크립트 추가",
"filePanel.addscriptetherscan": "Etherscan 스크립트 추가",
"filePanel.workspace.addscriptdeployer": "컨트랙트를 배포하는 데 사용할 수 있는 스크립트 추가",
"filePanel.addscriptdeployer": "컨트랙트 배포 스크립트 추가",
"filePanel.workspace.slitherghaction": "GitHub Actions CI에서 slither 분석을 실행하기 위한 사전 설정된 yml 파일 추가",
"filePanel.slitherghaction": "Slither 워크플로우",
"filePanel.workspace.helperscripts": "'scripts' 디렉토리에 편리한 스크립트 추가",
"filePanel.helperscripts": "Web3 스크립트",
"filePanel.newFile": "새 파일",
"filePanel.newFolder": "새 폴더",
"filePanel.rename": "이름 변경",
"filePanel.delete": "삭제",
"filePanel.deleteAll": "전체 삭제",
"filePanel.run": "실행",
"filePanel.pushChangesToGist": "Gist에 변경 사항 푸시",
"filePanel.publishFolderToGist": "폴더를 gist에 게시",
"filePanel.publishFileToGist": "파일을 gist에 게시",
"filePanel.copy": "복사",
"filePanel.copyFileName": "이름 복사",
"filePanel.copyFilePath": "경로 복사",
"filePanel.contractflattener": "평탄화",
"filePanel.nahmii-compiler": "Nahmii용 컴파일",
"filePanel.solidityumlgen": "UML 생성",
"filePanel.doc-gen": "Docs 생성",
"filePanel.solidity": "컴파일",
"filePanel.paste": "붙여넣기",
"filePanel.compile": "컴파일",
"filePanel.compileForNahmii": "Nahmii용 컴파일",
"filePanel.createNewFile": "새 파일 생성",
"filePanel.createNewFolder": "새 폴더 생성",
"filePanel.publishToGist": "모든 파일을 GitHub gist에 게시",
"filePanel.uploadFile": "파일 업로드",
"filePanel.uploadFolder": "폴더 업로드",
"filePanel.updateGist": "현재 [gist] 탐색기 업데이트",
"filePanel.viewAllBranches": "모든 브랜치 보기",
"filePanel.createBranch": "브랜치 생성",
"filePanel.switchBranches": "브랜치 전환",
"filePanel.checkoutGitBranch": "Git 브랜치 체크아웃",
"filePanel.findOrCreateABranch": "브랜치 찾기 또는 생성하기",
"filePanel.initGitRepositoryLabel": "작업공간을 새 git 저장소로 초기화",
"filePanel.initGitRepositoryWarning": "Git 기능을 사용하려면, 설정 패널의 Github 섹션에 사용자 이름과 이메일을 추가하세요.",
"filePanel.workspaceName": "워크스페이스 이름",
"filePanel.customizeTemplate": "사용자 지정 템플릿",
"filePanel.features": "기능",
"filePanel.upgradeability": "업그레이드 가능성",
"filePanel.ok": "확인",
"filePanel.yes": "예",
"filePanel.cancel": "취소",
"filePanel.createNewWorkspace": "새 작업공간 생성",
"filePanel.connectToLocalhost": "로컬호스트에 연결",
"filePanel.copiedToClipboard": "클립보드에 복사됨 {path}",
"filePanel.downloadFailed": "다운로드 실패",
"filePanel.downloadFailedMsg": "다운로드 중 예상치 못한 오류 발생: {error}",
"filePanel.close": "닫기",
"filePanel.copyFileFailed": "파일 복사 실패",
"filePanel.copyFileFailedMsg": "파일 복사 중 예상치 못한 오류 발생: {src}",
"filePanel.copyFolderFailed": "폴더 복사 실패",
"filePanel.copyFolderFailedMsg": "폴더 복사 중 예상치 못한 오류 발생: {src}",
"filePanel.runScriptFailed": "스크립트 실행 실패",
"filePanel.createPublicGist": "공개 gist 생성",
"filePanel.createPublicGistMsg1": "github.com에 원격 gist 파일 변경 사항을 푸시하시겠습니까?",
"filePanel.createPublicGistMsg2": "{path} 폴더의 모든 파일을 공개 gist로 github.com에 익명으로 게시하시겠습니까?",
"filePanel.createPublicGistMsg3": "{path} 파일을 공개 gist로 github.com에 익명으로 게시하시겠습니까?",
"filePanel.createPublicGistMsg4": "{name} 작업 공간의 모든 파일을 공개 gist로 github.com에 익명으로 게시하시겠습니까?",
"filePanel.deleteMsg": "삭제하시겠습니까",
"filePanel.theseItems": "이 항목들",
"filePanel.thisItem": "이 항목",
"filePanel.deleteItems": "아이템 삭제",
"filePanel.deleteItem": "아이템 삭제",
"filePanel.globalToast": "읽기 전용 모드에서 파일 시스템을 쓰거나 수정할 수 없습니다.",
"filePanel.basic": "기본",
"filePanel.blank": "비어 있음",
"filePanel.multiSigWallet": "멀티시그 지갑",
"filePanel.mintable": "발행 가능",
"filePanel.burnable": "소각 가능",
"filePanel.pausable": "일시 정지 가능",
"filePanel.semaphore": "세마포어",
"filePanel.hashchecker": "해시 체커",
"filePanel.rln": "속도 제한 널리파이어",
"filePanel.breakthroughLabsUniswapv4Hooks": "Breakthrough-Labs 훅",
"filePanel.uniswapV4Periphery": "v4 주변기기",
"filePanel.uniswapV4HookBookMultiSigSwapHook": "HookBook MultiSigSwapHook",
"filePanel.transparent": "투명",
"filePanel.initGitRepoTitle": "새 git 저장소로 작업 공간 초기화 옵션 확인",
"filePanel.switchToBranchTitle1": "원격 브랜치에서 새 브랜치 체크아웃",
"filePanel.switchToBranchTitle2": "로컬 브랜치로 체크아웃",
"filePanel.readOnly": "읽기 전용",
"filePanel.renameFileFailed": "파일 이름 변경 실패",
"filePanel.renameFileFailedMsg": "이름 변경 중 예상치 못한 오류 발생: {error}",
"filePanel.fileCreationFailed": "파일 생성 실패",
"filePanel.folderCreationFailed": "폴더 생성 실패",
"filePanel.validationError": "유효성 검사 오류",
"filePanel.validationErrorMsg": "특수 문자 사용 불가",
"filePanel.reservedKeyword": "예약된 키워드",
"filePanel.reservedKeywordMsg": "파일 이름에 Remix 예약 키워드 포함. \"{content}\"",
"filePanel.moveFile": "파일 이동",
"filePanel.moveFileMsg1": "{src}을 {dest}로 이동하시겠습니까?",
"filePanel.movingFileFailed": "파일 이동 실패",
"filePanel.movingFileFailedMsg": "파일 이동 중 예상치 못한 오류 발생: {src}",
"filePanel.movingFolderFailed": "폴더 이동 실패",
"filePanel.movingFolderFailedMsg": "폴더 이동 중 예상치 못한 오류 발생: {src}",
"filePanel.workspaceActions": "작업공간 액션",
"filePanel.saveCodeSample": "이 코드 샘플 작업 공간은 유지되지 않습니다. 여기를 클릭하여 저장하세요."
}

@ -0,0 +1,69 @@
{
"home.scamAlert": "스캠 경고",
"home.scamAlertText": "리믹스가 사용하는 URL은 remix.ethereum.org이 유일합니다",
"home.scamAlertText2": "\"liquidity front runner bots\"을 홍보하는 온라인 동영상을 주의하세요",
"home.scamAlertText3": "추가 안전 팁",
"home.learnMore": "더 알아보기",
"home.here": "여기",
"home.featured": "추천",
"home.jumpIntoWeb3": "JUMP INTO WEB3",
"home.jumpIntoWeb3More": "더 보기",
"home.jumpIntoWeb3Text": "리믹스 IDE는 사용자의 지식 수준에 관계없이 \b컨트랙트 개발의 전체 과정에 사용할 수 있는 리믹스 프로젝트의 일부입니다. 리믹스 프로젝트 웹사이트에서 더 알아보세요.",
"home.remixYouTube": "배우기 위해 시청",
"home.remixYouTubeText1": "리믹스 팀의 동영상 팁",
"home.remixYouTubeMore": "시청",
"home.remixYouTubeText2": "리믹스는 도구 사용에 대한 많은 팁을 담은 동영상 라이브러리를 확장하고 있습니다. 확인하고 최신 업로드된 내용을 구독하세요.",
"home.betaTesting": "BETA 테스팅",
"home.betaTestingText1": "커뮤니티가 우리를 지원합니다.",
"home.betaTestingText2": "방금 릴리즈된 베타 테스트를 통해 새로운 기능을 먼저 사용해보세요!",
"home.betaTestingMore": "가입하기",
"home.featuredPlugins": "추천 플러그인",
"home.solidityPluginDesc": "스마트 컨트랙트를 컴파일, 테스트 및 분석 합니다.",
"home.cookbookDesc": "스마트 컨트랙트와 솔리디티 라이브러리를 찾고, 프로토콜을 발견하세요.",
"home.codeAnalyizerPluginDesc": "리믹스, Solhint 및 Slither를 사용하여 코드를 분석하세요.",
"home.starkNetPluginDesc": "Cairo를 사용하여 StarkNet에 컨트랙트를 컴파일하고 배포하세요. Cairo는 StarkNet의 네이티브 언어입니다.",
"home.solhintPluginDesc": "Solhint는 솔리디티 코드를 린팅하기 위한 오픈 소스 프로젝트입니다.",
"home.sourcifyPluginDesc": "솔리디티 컨트랙트 및 메타데이터 검증 서비스.",
"home.unitTestPluginDesc": "솔리디티로 컨트랙트에 대한 단위 테스트를 작성하고 실행하세요.",
"home.dgitPluginDesc": "프로젝트에 소스 컨트롤을 추가하세요.",
"home.oneClickDappDesc": "스마트 컨트랙트 인터페이스를 빠르게 생성하세요.",
"home.getStarted": "시작하기",
"home.projectTemplates": "프로젝트 템플릿",
"home.blankTemplateDesc": "빈 작업 공간 생성",
"home.remixDefaultTemplateDesc": "샘플이 포함된 작업 공간 생성",
"home.ozerc20TemplateDesc": "OpenZeppelin 라이브러리를 가져와 ERC20 토큰을 만드세요.",
"home.ozerc721TemplateDesc": "OpenZeppelin 라이브러리를 가져와 NFT 토큰을 만드세요.",
"home.ozerc1155TemplateDesc": "OpenZeppelin 라이브러리를 가져와 ERC1155 토큰을 만드세요.",
"home.gnosisSafeMultisigTemplateDesc": "이 템플릿을 사용하여 다중 서명 지갑을 만드세요.",
"home.zeroxErc20TemplateDesc": "0xProject 컨트랙트를 가져와 ERC20 토큰을 만드세요.",
"home.learn": "배우기",
"home.learnEth1": "리믹스 기초",
"home.learnEth1Desc": "리믹스의 인터페이스와 기본 작업에 대한 소개",
"home.learnEth2": "솔리디티 입문",
"home.learnEth2Desc": "솔리디티 기초 개념을 상호작용을 통해 배우세요.",
"home.remixAdvanced": "라이브러리와 함께 배포하기",
"home.remixAdvancedDesc": "리믹스에서 라이브러리와 함께 배포하는 방법을 배우세요",
"home.remixYoutubePlaylist": "리믹스 유튜브 재생목록",
"home.remixTwitterProfile": "리믹스 트위터 프로필",
"home.remixLinkedinProfile": "리믹스 링크드인 프로필",
"home.remixMediumPosts": "리믹스 미디엄 포스트",
"home.joinUsOnDiscord": "디스코드에서 우리와 함께 하세요",
"home.nativeIDE": "웹3 개발을 위한 네이티브 IDE.",
"home.website": "웹사이트",
"home.documentation": "문서",
"home.remixPlugin": "리믹스 플러그인",
"home.remixDesktop": "리믹스 데스크탑",
"home.searchDocumentation": "문서 검색",
"home.files": "파일",
"home.newFile": "새 파일",
"home.startCoding": "코딩 시작",
"home.startCodingPlayground": "프로토타이핑 및 간단한 학습을 위한 플레이그라운드 열기",
"home.openFile": "파일 열기",
"home.openFileTooltip": "파일 시스템에서 파일 열기",
"home.accessFileSystem": "파일 시스템 접근",
"home.loadFrom": "로드 원본 위치",
"home.resources": "리소스",
"home.connectToLocalhost": "로컬호스트에 연결",
"home.seeAllTutorials": "모든 튜토리얼 보기",
"home.maintainedByRemix": "리믹스에 의한 유지 관리"
}

@ -0,0 +1,17 @@
import enJson from '../en'
function readAndCombineJsonFiles() {
const dataContext = require.context('./', true, /\.json$/)
let combinedData = {}
dataContext.keys().forEach((key) => {
const jsonData = dataContext(key)
combinedData = {...combinedData, ...jsonData}
})
return combinedData
}
// There may have some un-translated content. Always fill in the gaps with EN JSON.
// No need for a defaultMessage prop when render a FormattedMessage component.
export default Object.assign({}, enJson, readAndCombineJsonFiles())

@ -0,0 +1,10 @@
{
"panel.author": "작성자",
"panel.maintainedBy": "유지 관리:",
"panel.documentation": "문서",
"panel.description": "상세정보",
"panel.maintainedByRemix": "리믹스에 의한 유지 관리",
"panel.pluginInfo": "플러그인 정보",
"panel.linkToDoc": "문서 링크",
"panel.makeAnissue": "이슈 생성"
}

@ -0,0 +1,13 @@
{
"permissionHandler.allPermissionsReset": "모든 권한이 리셋 되었습니다.",
"permissionHandler.rememberText": "는 변경되었으며",
"permissionHandler.permissionHandlerMessage": "\"{from}\" {rememberText} \"{method}\" 의 \"{to}\" 에 접근하길 원합니다",
"permissionHandler.description": "상세정보",
"permissionHandler.noDescriptionProvided": "제공된 설명이 없습니다",
"permissionHandler.makeSureYouTrustThisPlugin": "이 플러그인을 신뢰하는지 확인한 후 이 호출을 진행하세요. 이 특정 호출에 대한 선택을 저장하기로 선택한 경우, 값은 현재 세션에만 유지됩니다.",
"permissionHandler.rememberThisChoice": "이 선택사항 저장",
"permissionHandler.resetAllPermissions": "모든 권한 초기화",
"permissionHandler.permissionNeededFor": "{to} 에 필요한 권한",
"permissionHandler.accept": "승인",
"permissionHandler.decline": "거절"
}

@ -0,0 +1,43 @@
{
"pluginManager.displayName": "플러그인 관리자",
"pluginManager.activate": "활성화",
"pluginManager.deactivate": "비활성화",
"pluginManager.activeModules": "활성 모듈",
"pluginManager.inactiveModules": "비활성 모듈",
"pluginManager.connectLocal": "로컬 플러그인에 연결",
"pluginManager.localForm.title": "로컬 플러그인",
"pluginManager.localForm.pluginName": "플러그인 이름",
"pluginManager.localForm.shouldBeCamelCase": "camelCase여야 함",
"pluginManager.localForm.displayName": "표시 이름",
"pluginManager.localForm.nameInTheHeader": "헤더 이름",
"pluginManager.localForm.required": "필수",
"pluginManager.localForm.commaSeparatedMethod": "쉼표로 구분된 메소드 이름 리스트",
"pluginManager.localForm.commaSeparatedPlugin": "쉼표로 구분된 플러그인 이름 리스트",
"pluginManager.localForm.pluginsItCanActivate": "활성 가능한 플러그인",
"pluginManager.localForm.typeOfConnection": "연결 유형",
"pluginManager.localForm.locationInRemix": "Remix 내 위치",
"pluginManager.localForm.sidePanel": "사이드 패널",
"pluginManager.localForm.mainPanel": "메인 패널",
"pluginManager.localForm.none": "없음",
"pluginManager.localForm.methods": "메소드",
"pluginManager.localForm.pluginNames": "플러그인 이름",
"pluginManager.localForm.ok": "확인",
"pluginManager.localForm.cancel": "취소",
"pluginManager.Permissions": "권한",
"pluginManager.permissions": "권한",
"pluginManager.pluginManagerPermissions": "플러그인 관리자 권한",
"pluginManager.currentPermissionSettings": "현재 권한 설정",
"pluginManager.noPermissionRequestedYet": "요청된 권한 없음",
"pluginManager.allow": "허용하기",
"pluginManager.toCall": "호출",
"pluginManager.ok": "확인",
"pluginManager.cancel": "취소",
"pluginManager.maintainedByRemix": "Remix에 의해 유지 관리됨",
"pluginManager.linkToDoc": "문서 링크",
"pluginManager.versionAlpha": "알파 버전",
"pluginManager.versionBeta": "베타 버전",
"pluginManager.deactivatePlugin": "{pluginName} 비활성화",
"pluginManager.activatePlugin": "{pluginName} 활성화",
"pluginManager.search": "검색",
"pluginManager.managePluginsPermissions": "플러그인 권한 관리"
}

@ -0,0 +1,3 @@
{
"remixApp.scrollToSeeAllTabs": "모든 탭을 보려면 스크롤하세요"
}

@ -0,0 +1,7 @@
{
"remixUiTabs.tooltipText1": "스크립트 실행 (CTRL + SHIFT + S)",
"remixUiTabs.tooltipText2": "컴파일 CTRL + S",
"remixUiTabs.tooltipText3": "컴파일할 .sol 또는 .yul 파일을 선택하거나 .ts 또는 .js 파일을 선택하고 실행하세요",
"remixUiTabs.zoomOut": "축소",
"remixUiTabs.zoomIn": "확대"
}

@ -0,0 +1,24 @@
{
"search.displayName": "파일에서 검색",
"search.replace": "바꾸기",
"search.replaceAll": "모두 바꾸기",
"search.placeholder1": "검색 (검색하려면 Enter)",
"search.placeholder2": "포함 예 *.sol (포함하려면 Enter)",
"search.placeholder3": "제외 예 .git/**/* (제외하려면 Enter)",
"search.matchCase": "대소문자 구분",
"search.matchWholeWord": "전체 단어 일치",
"search.useRegularExpression": "정규 표현식 사용",
"search.replaceWithoutConfirmation": "확인 없이 바꾸기",
"search.filesToInclude": "포함할 파일",
"search.filesToExclude": "제외할 파일",
"search.toggleReplace": "바꾸기 전환",
"search.replaceInFiles": "파일 내에서 바꾸기",
"search.stop": "중지",
"search.undoChanges": "{path} 에 대한 변경 사항 취소",
"search.confirmreplaceMsg": "{filename} 에서 {find} 를 {replace} 로 바꾸시겠습니까?",
"search.yes": "예",
"search.no": "아니오",
"search.loading": "로딩 중",
"search.text1": "{fileCount} 개의 파일에서 {count} 개의 결과 표시",
"search.text2": "표시할 결과가 너무 많습니다. {br} 검색 범위를 좁혀주세요."
}

@ -0,0 +1,44 @@
{
"settings.displayName": "설정",
"settings.reset": "기본 설정으로 재설정",
"settings.general": "일반 설정",
"settings.generateContractMetadataText": "컨트랙트 메타데이터 생성. 컨트랙트 폴더에 JSON 파일을 생성합니다. 컨트랙트가 의존하는 라이브러리 주소를 지정할 수 있습니다. 아무것도 지정하지 않으면 Remix가 라이브러리를 자동으로 배포합니다.",
"settings.ethereunVMText": "로드 시 항상 Remix VM 사용",
"settings.wordWrapText": "편집기에서 단어 줄바꿈",
"settings.useAutoCompleteText": "편집기에서 코드 완성 활성화",
"settings.useShowGasInEditorText": "편집기에서 가스 추정치 표시",
"settings.displayErrorsText": "타이핑하는 동안 편집기에서 오류 표시",
"settings.matomoAnalytics": "Matomo Analytics 활성화. 개인 식별 정보(PII) 는 수집하지 않습니다. 정보는 사이트의 UX & UI를 개선하는 데 사용됩니다. 더 보기 ",
"settings.enablePersonalModeText": " Web3 provider에 대해 개인 모드 활성화. Web3를 통해 전송된 트랜잭션은 web3.personal API를 사용합니다.\n",
"settings.warnText": "활성화하기 전에 엔드포인트가 열려 있는지 확인하세요. 이 모드는 사용자가 계정을 잠금 해제하지 않고도 Remix 인터페이스에서 암호를 제공할 수 있게 합니다. 이것은 매우 편리하지만, 연결된 백엔드(Geth, Parity, ...) 를 완전히 신뢰해야 합니다. Remix는 어떠한 암호도 영구적으로 저장하지 않습니다",
"settings.gitAccessTokenTitle": "Github 자격 증명",
"settings.gitAccessTokenText": "Gist를 게시하고 GitHub 콘텐츠를 검색하는 데 사용되는 액세스 토큰입니다. 사용자 이름/이메일을 입력해야 할 수도 있습니다.",
"settings.gitAccessTokenText2": "아래 링크의 github 토큰 페이지로 가서 새 토큰을 생성하고 Remix에 저장하세요. 이 토큰이 'gist 생성' 권한만 가지고 있는지 확인하세요",
"settings.etherscanTokenTitle": "EtherScan 액세스 토큰",
"settings.etherscanAccessTokenText": "Etherscan과 상호 작용하는 데 사용되는 api 키를 관리합니다.",
"settings.etherscanAccessTokenText2": "아래 링크의 Etherscan api 키 페이지로 가서 새 api 키를 생성하고 Remix에 저장하세요.",
"settings.save": "저장",
"settings.remove": "삭제",
"settings.themes": "테마",
"settings.locales": "언어",
"settings.swarm": "Swarm 설정",
"settings.ipfs": "IPFS 설정",
"settings.token": "토큰",
"settings.copy": "복사",
"settings.deleteEtherscanToken": "Etherscan 토큰 삭제",
"settings.username": "사용자 이름",
"settings.email": "이메일",
"settings.deleteGithubCredentials": "Github 자격 증명 삭제",
"settings.privateBeeAddress": "개인 BEE 주소",
"settings.postageStampID": "POSTAGE 스탬프 ID",
"settings.host": "호스트",
"settings.protocol": "프로토콜",
"settings.port": "포트",
"settings.projectID": "프로젝트 ID",
"settings.projectSecret": "프로젝트 SECRET",
"settings.analyticsInRemix": "Remix IDE에서의 분석",
"settings.copilot": "Solidity copilot - 알파",
"settings.copilot.activate": "Copilot 로드 및 활성화",
"settings.copilot.max_new_tokens": "생성할 최대 단어 수",
"settings.copilot.temperature": "온도"
}

@ -0,0 +1,81 @@
{
"solidity.displayName": "솔리디티 컴파일러",
"solidity._comment_compiler-container.tsx": "libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx",
"solidity.compiler": "컴파일러",
"solidity.addACustomCompiler": "사용자 정의 컴파일러 추가",
"solidity.addACustomCompilerWithURL": "URL을 사용하여 사용자 정의 컴파일러 추가",
"solidity.includeNightlyBuilds": "Nightly 빌드 포함",
"solidity.autoCompile": "자동 컴파일",
"solidity.hideWarnings": "경고 숨기기",
"solidity.enableHardhat": "하드햇 컴파일 활성화",
"solidity.learnHardhat": "하드햇 컴파일 사용 방법 알아보기",
"solidity.enableTruffle": "트러플 컴파일 활성화",
"solidity.learnTruffle": "트러플 컴파일 사용 방법 알아보기",
"solidity.advancedConfigurations": "고급 설정",
"solidity.compilerConfiguration": "컴파일러 설정",
"solidity.compilationDetails": "컴파일 상세 정보",
"solidity.language": "언어",
"solidity.evmVersion": "EVM 버전",
"solidity.enableOptimization": "최적화 활성화",
"solidity.useConfigurationFile": "설정 파일 사용",
"solidity.change": "변경",
"solidity.compile": "컴파일",
"solidity.noFileSelected": "선택된 파일 없음",
"solidity.compileAndRunScript": "컴파일 및 스크립트 실행",
"solidity.newConfigFileTitle": "새 설정 파일",
"solidity.newConfigFileMessage": "입력하신 파일 \"{configFilePathInput}\"이(가) 존재하지 않습니다. 새로 만드시겠습니까?",
"solidity.create": "생성",
"solidity.ok": "확인",
"solidity.cancel": "취소",
"solidity.noFileSelected1": "선택된 파일 없음.",
"solidity.toCompile": "컴파일 대상",
"solidity.noConfigFileSelected": "설정 파일이 선택되지 않음",
"solidity.copyNatSpecTag": "사용자 정의 NatSpec 태그를 복사하려면 클릭하세요",
"solidity.inputTitle1": "입력한 파일이 존재하지 않는 경우 다음 단계에서 하나를 생성할 수 있습니다.",
"solidity.inputTitle2": "컨트랙트의 수명 동안 배포된 코드의 각 opcode가 실행될 예상 횟수.",
"solidity.tooltipText1": "`dev-run-script` natspec 태그를 추가하여 컴파일 직후 실행할 스크립트를 선택하세요, 예:",
"solidity.tooltipText2": "\"i\" 아이콘을 클릭하여 자세히 알아보세요",
"solidity.tooltipText3": "컴파일 및 스크립트 실행을 위해",
"solidity.tooltipText4": "설정 파일을 열려면 클릭하세요",
"solidity.tooltipText5": "컴파일러 버전 목록을 불러올 수 없습니다. 광고 차단기에 의해 차단되었을 수 있습니다. 이 페이지에서 모든 광고 차단기를 비활성화한 후 새로고침해 보세요. 에러: ",
"solidity.tooltipText6": "컴파일러 >= v0.5.7 부터 사용 가능한 언어 사양",
"solidity.toastMessage": "현재 컨트랙트 파일의 프라그마와 일치하도록 컴파일러 버전을 업데이트 중입니다. 예: {version}",
"solidity.compileIconAttribute": "컴파일러 로딩 중입니다. 잠시만 기다려 주세요.",
"solidity.compilerLicense": "컴파일러 라이센스",
"solidity.compilerLicenseMsg1": "컴파일러가 로딩 중입니다. 로딩이 완료되면 라이센스가 표시됩니다.",
"solidity.compilerLicenseMsg2": "선택한 컴파일러 버전에 대한 라이센스를 검색할 수 없습니다",
"solidity.compilerLicenseMsg3": "라이센스 정보가 없습니다",
"solidity.seeCompilerLicense": "컴파일러 라이센스 보기",
"solidity._comment_contract-selection.tsx": "libs/remix-ui/solidity-compiler/src/lib/contract-selection.tsx",
"solidity.publishOn": "게시 위치",
"solidity.flatten": "UML 생성 전 컨트랙트 플래튼",
"solidity.generateUML": "컨트랙트의 UML 다이어그램 생성",
"solidity.flattenLabel": "평탄화",
"solidity.generateUMLLabel": "UML 다이어그램 생성",
"solidity.copy": "복사",
"solidity.copyABI": "ABI를 클립보드에 복사",
"solidity.copyBytecode": "바이트코드를 클립보드에 복사",
"solidity.unableToDisplay": "표시할 수 없음",
"solidity.download": "다운로드",
"solidity.compileDetails": "컴파일 세부 정보 다운로드 (JSON format)",
"solidity.close": "닫기",
"solidity.contract": "컨트랙트",
"solidity.displayContractDetails": "컨트랙트 세부 정보 표시",
"solidity.noContractCompiled": "아직 컴파일된 컨트랙트 없음",
"solidity.Assembly": "컨트랙트를 설명하는 어셈블리 옵코드 및 해당 솔리디티 소스 코드 포함",
"solidity.Opcodes": "컨트랙트를 설명하는 어셈블리 옵코드",
"solidity.name": "컴파일된 컨트랙트 이름",
"solidity.metadata": "컴파일과 관련된 모든 정보 포함",
"solidity.bytecode": "컨트랙트 생성 중 실행되는 바이트코드",
"solidity.abi": "ABI: 모든 함수(입력/출력 파라미터, 범위...)를 설명함",
"solidity.web3Deploy": "이 코드를 아무 JavaScript/Web3 콘솔에 복사/붙여넣기하여 이 컨트랙트를 배포하세요",
"solidity.metadataHash": "모든 메타데이터 정보를 나타내는 해시",
"solidity.functionHashes": "선언된 함수와 해당 해시 목록",
"solidity.gasEstimates": "각 함수 호출에 대한 가스 추정",
"solidity.Runtime Bytecode": "상태를 저장하고 일반 컨트랙트 호출 중 실행되는 바이트코드",
"solidity.storageLayout": "스토리지 레이아웃 문서를 참조하세요.",
"solidity.devdoc": "개발자 문서(natspec)",
"solidity.userdoc": "사용자 문서(natspec)",
"solidity.compilerInput": "솔리디티 컴파일러 입력",
"solidity.swarmLocation": "모든 메타데이터 정보를 찾을 수 있는 Swarm Url (컨트랙트가 먼저 게시되어야 함)"
}

@ -0,0 +1,41 @@
{
"solidityUnitTesting.displayName": "솔리디티 단위 테스트",
"solidityUnitTesting.testDirectory": "테스트 디렉토리",
"solidityUnitTesting.testYourSmartContract": "솔리디티로 스마트 컨트랙트를 테스트 하세요.",
"solidityUnitTesting.selectDirectory": "테스트 파일을 로드하고 생성할 디렉토리를 선택하세요.",
"solidityUnitTesting.uiPathInputTooltip": "'Enter'를 눌러 테스트 파일의 경로를 변경하세요.",
"solidityUnitTesting.uiPathInputButtonTooltip": "테스트 폴더 생성",
"solidityUnitTesting.create": "생성",
"solidityUnitTesting.generateTestsButtonTooltip": "샘플 테스트 파일 생성",
"solidityUnitTesting.generate": "생성",
"solidityUnitTesting.generateTestsLinkTooltip": "문서 확인",
"solidityUnitTesting.howToUse": "사용 방법...",
"solidityUnitTesting.runButtonTitle1": "테스트 실행",
"solidityUnitTesting.runButtonTitle2": "0.4.12 보다 높은 솔리디티 컴파일러 버전을 선택하세요.",
"solidityUnitTesting.runButtonTitle3": "선택된 솔리디티 파일 없음",
"solidityUnitTesting.runButtonTitle4": "\"솔리디티 플러그인\"이 활성화 되어야 합니다",
"solidityUnitTesting.runButtonTitle5": "선택된 테스트 파일 없음",
"solidityUnitTesting.stopButtonLabel1": "중지",
"solidityUnitTesting.stopButtonLabel2": "중단 중",
"solidityUnitTesting.run": "실행",
"solidityUnitTesting.runTestsTabStopActionTooltip": "테스트 실행 중지",
"solidityUnitTesting.selectAll": "전체 선택",
"solidityUnitTesting.testTabTestsExecutionStopped": "테스트 실행이 중지되었습니다",
"solidityUnitTesting.testTabTestsExecutionStoppedError": "테스트 파일의 에러로 인해 테스트 실행이 중지되었습니다",
"solidityUnitTesting.progress": "진행 상황: {readyTestsNumber} 완료 ({runningTestsNumber} 중)",
"solidityUnitTesting.resultFor": "결과",
"solidityUnitTesting.passed": "통과",
"solidityUnitTesting.failed": "실패",
"solidityUnitTesting.timeTaken": "소요 시간",
"solidityUnitTesting.errorMessage": "에러 메시지",
"solidityUnitTesting.assertion": "단언",
"solidityUnitTesting.expectedValueShouldBe": "예상 값은 다음과 같아야 합니다: ",
"solidityUnitTesting.receivedValue": "받은 값",
"solidityUnitTesting.skippingTheRemainingTests": "함수의 나머지 테스트를 건너뜁니다.",
"solidityUnitTesting.toasterMsg": "폴더가 성공적으로 생성되었습니다",
"solidityUnitTesting.tooltipText1": "적어도 하나의 컨트랙트 테스트가 실패하였습니다",
"solidityUnitTesting.tooltipText2": "모든 컨트랙트 테스트가 통과했습니다",
"solidityUnitTesting.tooltipText3": "디버깅 시작",
"solidityUnitTesting.fail": "실패",
"solidityUnitTesting.pass": "통과"
}

@ -0,0 +1,43 @@
{
"terminal.listen": "모든 트랜잭션 수신",
"terminal.listenTitle": "체크하면 Remix가 당신이 생성한 트랜잭션뿐만 아니라 현재 환경에서 채굴된 모든 트랜잭션을 수신하게 됩니다",
"terminal.search": "트랜잭션 해시나 주소로 검색",
"terminal.used": "사용됨",
"terminal.debug": "디버그",
"terminal.welcomeText1": "환영합니다",
"terminal.welcomeText2": "파일이 저장된 위치는 ",
"terminal.welcomeText3": "이 터미널을 사용하여",
"terminal.welcomeText4": "트랜잭션 세부 정보 확인 및 디버깅 시작",
"terminal.welcomeText5": "JavaScript 스크립트 실행",
"terminal.welcomeText6": "명령 줄 인터페이스에 스트립트를 직접 입력",
"terminal.welcomeText7": "파일 탐색기에서 자바스크립트 파일을 선택한 다음 명령 줄 인터페이스에서 `remix.execute()` 또는 `remix.exeCurrent()` 실행",
"terminal.welcomeText8": "파일 탐색기에서 자바스크립트 파일을 마우스 오른쪽 버튼으로 클릭한 다음 `실행` 클릭",
"terminal.welcomeText9": "다음 라이브러리에 접근 가능",
"terminal.welcomeText10": "사용 가능한 명령을 보려면 라이브러리 이름을 입력하세요",
"terminal.text1": "이 타입의 명령은 더 이상 사용되지 않으며 기능하지 않습니다. 사용 가능한 명령을 나열하려면 remix.help()를 실행하세요.",
"terminal.hideTerminal": "터미널 숨기기",
"terminal.showTerminal": "터미널 보이기",
"terminal.clearConsole": "콘솔 초기화",
"terminal.pendingTransactions": "대기 중인 트랜잭션",
"terminal.toasterMsg1": "실행할 내용 없음",
"terminal.toasterMsg2": "{fileName} 경로의 프로바이더를 찾을 수 없음",
"terminal.vmMode": "VM 모드",
"terminal.vmModeMsg": "이 호출을 디버그할 수 없습니다. 호출 디버깅은 Remix VM 모드에서만 가능합니다.",
"terminal.ok": "확인",
"terminal.cancel": "취소",
"terminal.callWarning": "(컨트랙트에 의해 호출될 때만 비용이 적용됩니다)",
"terminal.msg1": "트랜잭션이 채굴되었지만 실행 실패",
"terminal.msg2": "트랜잭션이 채굴되었고 실행 성공",
"terminal.msg3": "현재 상태를 사용할 수 없음",
"terminal.status": "상태",
"terminal.transactionHash": "트랜잭션 해시",
"terminal.blockHash": "블록 해시",
"terminal.blockNumber": "블록 넘버",
"terminal.contractAddress": "컨트랙트 주소",
"terminal.transactionCost": "트랜잭션 비용",
"terminal.executionCost": "실행 비용",
"terminal.input": "입력",
"terminal.decodedInput": "디코드된 입력",
"terminal.decodedOutput": "디코드된 출력",
"terminal.logs": "로그"
}

@ -0,0 +1,139 @@
{
"udapp.displayName": "트랜잭션 배포 & 실행",
"udapp._comment_gasPrice.tsx": "libs/remix-ui/run-tab/src/lib/components/gasPrice.tsx",
"udapp.gasLimit": "가스 한도",
"udapp.tooltipText4": "기본 가스 한도는 3M입니다. 필요에 따라 조정하세요.",
"udapp._comment_value.tsx": "libs/remix-ui/run-tab/src/lib/components/value.tsx",
"udapp.value": "값",
"udapp.tooltipText5": "금액을 입력하고 단위를 선택하세요",
"udapp._comment_contractDropdownUI.tsx": "libs/remix-ui/run-tab/src/lib/components/contractDropdownUI.tsx",
"udapp.contract": "컨트랙트",
"udapp.compiledBy": "{compilerName} 에 의해 컴파일됨",
"udapp.warningEvmVersion": "현재 네트워크가 이 evm 버전과 호환되는지 확인하세요: {evmVersion}. 그렇지 않으면 모든 배포가 실패할 것입니다.",
"udapp.infoSyncCompiledContractTooltip": "외부 프레임워크에서 컴파일된 컨트랙트를 가져오려면 여기를 클릭하세요. 이 작업은 Remix가 remixd를 통해 외부 프레임워크(hardhat, truffle, foundry)에 연결될 때 활성화됩니다.",
"udapp.remixIpfsUdappTooltip": "소스 코드와 메타데이터를 IPFS에 게시하면 Sourcify를 사용한 소스 코드 검증이 용이해지며 컨트랙트 채택(감사, 디버깅, 호출 등) 이 크게 증진됩니다.",
"udapp.deploy": "배포",
"udapp.publishTo": "게시 위치",
"udapp.atAddress": "주소 사용",
"udapp.atAddressOptionsTitle1": "컨트랙트 주소",
"udapp.atAddressOptionsTitle2": "배포된 컨트랙트와 상호 작용 - .abi 파일이나 컴파일된 .sol 파일을 편집기에서 선택해야 합니다(같은 컴파일러 설정으로).",
"udapp.atAddressOptionsTitle3": "*.sol 파일을 컴파일하거나 *.abi 파일을 선택하세요.",
"udapp.atAddressOptionsTitle4": "배포된 컨트랙트와 상호 작용하려면 해당 주소를 입력하고 소스 *.sol 파일을 컴파일하거나 편집기에서 .abi 파일을 선택하세요. (같은 컴파일러 설정으로) ",
"udapp.contractOptionsTitle1": ".sol 파일을 컴파일하여, 컨트랙트을 배포하거나 엑세스하세요",
"udapp.contractOptionsTitle2": "배포하거나 주소로부터 사용할 컴파일된 컨트랙트를 선택하세요.",
"udapp.contractOptionsTitle3": "*.sol 파일을 선택하고 컴파일하여, 컨트랙트를 배포하거나 엑세스하세요.",
"udapp.contractOptionsTitle4": "컴파일된 .sol 파일이 있을 때, 주소에서 사용하거나 배포할 컨트랙트를 선택하세요.",
"udapp.checkSumWarning": "체크섬이 적용된 주소를 사용하지 않는 것 같습니다. 체크섬이 적용된 주소는 {a}에 명시된 대로 대문자를 포함하는 주소입니다. 체크섬이 적용된 주소는 사용자가 잘못된 주소로 트랜잭션을 보내는 것을 방지하기 위한 목적입니다.",
"udapp.isOverSizePromptEip170": "컨트랙트 생성 초기화가 24576 바이트보다 긴 데이터를 반환합니다. 현재 네트워크에서 eip 170이 활성화된 경우 배포가 실패할 가능성이 높습니다. 자세한 정보: {a}",
"udapp.isOverSizePromptEip3860": "컨트랙트 생성 초기 코드가 허용된 최대 코드 크기인 49152 바이트를 초과합니다. 현재 네트워크에서 eip 3860이 활성화된 경우 배포가 실패할 가능성이 높습니다. 자세한 정보: {a}",
"udapp.thisContractMayBeAbstract": "이 컨트랙트는 추상적일 수 있습니다. 추상 부모의 메서드를 완전히 구현하지 않았거나 상속된 컨트랙트의 생성자를 올바르게 호출하지 않았을 수 있습니다.",
"udapp.noCompiledContracts": "컴파일된 컨트랙트 없음",
"udapp.addressOfContract": "컨트랙트 주소",
"udapp.loadContractFromAddress": "주소에서 컨트랙트 불러오기",
"udapp.ok": "확인",
"udapp.alert": "경고",
"udapp.proceed": "계속",
"udapp.cancel": "취소",
"udapp.abiFileSelected": "ABI 파일 선택됨",
"udapp.evmVersion": "evm 버전",
"udapp.addressNotValid": "주소가 유효하지 않습니다.",
"udapp._comment_account.tsx": "libs/remix-ui/run-tab/src/lib/components/account.tsx",
"udapp.account": "계정",
"udapp.signAMessage": "메시지 서명",
"udapp.enterAMessageToSign": "서명할 메시지 입력",
"udapp.hash": "해시",
"udapp.signature": "서명",
"udapp.injectedTitle": "주입된 프로바이더를 사용하여 계정을 생성하는 것은 불가능합니다. 프로바이더(예: 메타마스크 또는 같은 유형의 다른 프로바이더)에서 직접 계정을 생성하세요.",
"udapp.createNewAccount": "새 계정 생성",
"udapp.web3Title": "계정 생성은 개인 모드에서만 가능합니다. 설정으로 이동해 활성화하세요.",
"udapp.defaultTitle": "외부 지갑({selectExEnv})을 사용하여 계정을 생성하는 것은 불가능 합니다.",
"udapp.text1": "계정 생성을 위한 비밀번호를 제공하세요.",
"udapp.tooltipText1": "계정 목록이 비어있습니다. 현재 프로바이더가 Remix가 제대로 연결되었는지 확인하세요",
"udapp.modalTitle1": "메시지 서명을 위한 비밀번호",
"udapp.modalMessage1": "메시지를 서명하기 위해 이 계정의 비밀번호를 입력하세요",
"udapp.copyAccount": "계정을 클립보드에 복사",
"udapp.signMsgUsingAccount": "이 계정을 사용하여 메시지 서명",
"udapp._comment_environment.tsx": "libs/remix-ui/run-tab/src/lib/components/environment.tsx",
"udapp.environment": "환경",
"udapp.environmentDocs": "환경에 대한 문서를 보려면 클릭하세요",
"udapp.tooltipText2": "chainlist.org을 열고 상호 작용하려는 체인의 연결 사양을 가져옵니다.",
"udapp.tooltipText3": "L1 메인넷 ETH를 선택한 네트워크 통화로 변환하기 위한 브리지를 열기 위해 클릭하세요.",
"udapp._comment_instanceContainerUI.tsx": "libs/remix-ui/run-tab/src/lib/components/instanceContainerUI.tsx",
"udapp.deployedContracts": "배포된 컨트랙트",
"udapp.deployAndRunClearInstances": "인스턴스 목록을 지우고 레코더를 재설정",
"udapp.deployAndRunNoInstanceText": "현재 상호 작용할 컨트랙트 인스턴스가 없습니다.",
"udapp.tooltipText6": "배포된 컨트랙트와 상호 작용하기 위해 자동 생성된 일반 사용자 인터페이스",
"udapp._comment_recorderCardUI.tsx": "libs/remix-ui/run-tab/src/lib/components/recorderCardUI.tsx",
"udapp.transactionsRecorded": "기록된 트랜잭션",
"udapp.transactionsCountTooltip": "기록된 트랙잭션 수",
"udapp.transactionSaveTooltip1": "저장할 트랜잭션이 없습니다",
"udapp.transactionSaveTooltip2": "{count} 트랜잭션을 시나리오 파일로 저장",
"udapp.transactionSaveTooltip3": "{count} 트랜잭션을 시나리오 파일로 저장",
"udapp.transactionsWalkthroughTooltip": "레코더에 대한 연습 투어 시작",
"udapp.infoRecorderTooltip": "트랜잭션(배포된 컨트랙트 및 함수 실행)을 저장하고 다른 환경에서 재생합니다. 예를 들어, Remix VM에서 생성된 트랜잭션은 주입된 프로바이더에서 재생할 수 있습니다.",
"udapp.livemodeRecorderTooltip": "트랜잭션을 기록한 후 컨트랙트가 업데이트된 경우, 이 상자를 체크하면 최신 복사본의 컴파일된 컨트랙트로 기록된 트랜잭션을 실행합니다",
"udapp.livemodeRecorderLabel": "최신 컴파일 결과를 사용하여 트랜잭션 실행",
"udapp.runRecorderTooltip": "현재 시나리오 파일에서 트랜잭션 실행",
"udapp.save": "저장",
"udapp.run": "실행",
"udapp._comment_contractGUI.tsx": "libs/remix-ui/run-tab/src/lib/components/contractGUI.tsx",
"udapp.parameters": "매개변수",
"udapp.copyParameters": "인코딩된 입력 매개변수를 클립보드에 복사",
"udapp.copyCalldata": "calldata를 클립보드에 복사",
"udapp.deployWithProxy": "프록시와 같이 배포",
"udapp.upgradeWithProxy": "프록시와 같이 업그레이드",
"udapp.getEncodedCallError": "빈 인자는 인코딩할 수 없습니다",
"udapp.proxyAddressError1": "프록시 주소는 비워둘 수 없습니다",
"udapp.proxyAddressError2": "유효한 컨트랙트 주소가 아닙니다",
"udapp.tooltipText11": "프록시 주소는 비워둘 수 없습니다",
"udapp.tooltipText12": "입력이 필요합니다",
"udapp.tooltipText13": "{date}에 배포됨",
"udapp._comment_universalDappUI.tsx": "libs/remix-ui/run-tab/src/lib/components/universalDappUI.tsx",
"udapp.tooltipText7": "목록에서 제거",
"udapp.tooltipText8": "'receive'/'fallback' 사용에 대한 문서를 보려면 클릭하세요",
"udapp.tooltipText9": "컨트랙트의 fallback 함수로 보낼 Calldata입니다.",
"udapp.tooltipText10": "컨트랙트에 데이터 보내기",
"udapp.balance": "잔액",
"udapp.lowLevelInteractions": "저수준 상호 작용",
"udapp.llIError1": "보낼 값은 숫자여야 합니다",
"udapp.llIError2": "Ether 전송을 받으려면 컨트랙트에 'receive' 또는 지불 가능한 'fallback' 함수가 있어야 합니다",
"udapp.llIError3": "calldata는 최소한 1 바이트 크기의 유효한 16진수 값이어야 합니다.",
"udapp.llIError4": "calldata는 유효한 16진수 값이어야 합니다.",
"udapp.llIError5": "'Fallback' 함수가 정의되지 않았습니다",
"udapp.llIError6": "'receive'와 'fallback' 함수가 모두 정의되지 않았습니다",
"udapp.llIError7": "calldata를 보내려면 'Fallback' 함수를 정의하고 이더를 보내려면 'Receive' 또는 지불 가능한 'Fallback'을 정의하세요",
"udapp.copy": "복사",
"udapp._comment_mainnet.tsx": "libs/remix-ui/run-tab/src/lib/components/mainnet.tsx",
"udapp.mainnetText1": "{name} 네트워크에서 트랜잭션을 생성하려고 합니다. 세부 정보를 확인하고 프로바이더로 정보를 보내세요.",
"udapp.mainnetText2": "많은 사용자의 프로바이더는 MetaMask입니다. 프로바이더는 {name} 네트워크로 보내기 전에 트랜잭션에 서명하도록 요청할 것입니다.",
"udapp.amount": "금액",
"udapp.gasEstimation": "가스 추정",
"udapp.maxPriorityFee": "최대 우선 순위 수수료",
"udapp.maxFee": "최대 수수료 (기본 수수료 {baseFeePerGas} Gwei보다 낮지 않음)",
"udapp.contractCreation": "컨트랙트 생성",
"udapp.transactionFee": "트랜잭션이 유효하지 않습니다. 최대 수수료는 기본 수수료보다 낮을 수 없습니다",
"udapp.title1": "트랜잭션 수수료의 일부가 채굴자에게 갑니다.",
"udapp.title2": "이 트랜잭션에 대해 지불할 최대 수수료 금액을 나타냅니다. 최소한 기본 수수료로 설정해야 합니다.",
"udapp.gasPrice": "가스 가격",
"udapp.gweiText": "현재 가스 가격 정보를 보려면 {a} 를 방문하세요.",
"udapp.maxTransactionFee": "최대 트랜잭션 수수료",
"udapp.mainnetText3": "이 경고를 다시 표시하지 않음",
"udapp._comment_run-tab.tsx": "libs/remix-ui/run-tab/src/lib/run-tab.tsx",
"udapp.gasEstimationPromptText": "가스 추정이 다음 메시지(아래 참조)로 인해 오류가 발생했습니다. 트랜잭션 실행이 실패할 가능성이 높습니다. 강제로 보내시겠습니까?",
"udapp._comment_custom-dropdown.tsx": "libs/remix-ui/helper/src/lib/components/custom-dropdown.tsx",
"udapp.enterProxyAddress": "프록시 주소 입력",
"udapp._comment_provider": "apps/remix-ide/src/app/providers",
"udapp.customVmForkProviderText": "사용자 정의 포크에 대한 정보를 제공하세요. 노드 URL이 제공되지 않으면 VM이 빈 상태로 시작됩니다.",
"udapp.nodeUrl": "노드 URL",
"udapp.blockNumber": "블록 넘버(또는 최신)",
"udapp.externalHttpProviderText1": "참고: Geth & https://remix.ethereum.org을 사용하려면 Remix에서 요청을 허용하도록 구성하세요:(<a>Geth 문서의 rpc 서버</a> 참조)",
"udapp.externalHttpProviderText2": "Remix & 로컬 Geth 테스트 노드를 실행하려면 다음 명령을 사용하세요: (<a>Geth 문서의 개발 모드</a> 참조)",
"udapp.externalHttpProviderText3": "<b>경고:</b> 와일드카드를 사용하여 --http.corsdomain 플래그를 설정하는 것은 안전하지 않습니다: <b>--http.corsdomain *</b>",
"udapp.externalHttpProviderText4": "자세한 정보: <a>Remix 문서의 외부 HTTP 제공자</a>",
"udapp.foundryProviderText1": "참고: 시스템에서 Anvil을 실행하려면 다음을 실행하세요:",
"udapp.foundryProviderText2": "자세한 정보는 여기를 방문하세요: <a>Foundry 문서</a>",
"udapp.ganacheProviderText1": "참고: 시스템에서 Ganache를 실행하려면 다음을 실행하세요:",
"udapp.ganacheProviderText2": "자세한 정보는 여기를 방문하세요: <a>Ganache 문서</a>",
"udapp.hardhatProviderText1": "참고: 시스템에서 Hardhat 네트워크 노드를 실행하려면 hardhat 프로젝트 폴더로 이동하여 다음 명령을 실행하세요:",
"udapp.hardhatProviderText2": "자세한 정보는 여기를 방문하세요: <a>Hardhat 문서</a>"
}

@ -0,0 +1,10 @@
{
"panel.author": "Автор",
"panel.maintainedBy": "Поддерживается",
"panel.documentation": "Документация",
"panel.description": "Описание",
"panel.maintainedByRemix": "Поддерживается Remix",
"panel.pluginInfo": "Информация о плагине",
"panel.linkToDoc": "Ссылка на документацию",
"panel.makeAnissue": "Создать задачу"
}

@ -0,0 +1,10 @@
{
"panel.author": "作者",
"panel.maintainedBy": "维护者",
"panel.documentation": "文档",
"panel.description": "描述",
"panel.maintainedByRemix": "由 Remix 维护",
"panel.pluginInfo": "插件信息",
"panel.linkToDoc": "文档链接",
"panel.makeAnissue": "提交 issue"
}

@ -71,7 +71,6 @@ let requiredModules = [ // services + layout views + system views
'vyperCompilationDetails',
'contractflattener',
'solidity-script',
'openaigpt',
'solcoder',
'home',
'doc-viewer',

@ -26,7 +26,6 @@ export class RemixEngine extends Engine {
if (name === 'compilerloader') return { queueTimeout: 60000 * 4 }
if (name === 'filePanel') return { queueTimeout: 60000 * 20 }
if (name === 'fileManager') return { queueTimeout: 60000 * 20 }
if (name === 'openaigpt') return { queueTimeout: 60000 * 2 }
if (name === 'solcoder') return { queueTimeout: 60000 * 2 }
if (name === 'cookbookdev') return { queueTimeout: 60000 * 3 }
return { queueTimeout: 10000 }

@ -21,7 +21,7 @@ export function CompileErrorCard(props: { output: any, plugin: RemixClient }) {
<div className="d-flex flex-column pt-3 align-items-end mb-2">
<div>
<span className="border border-ai text-ai btn-sm" onClick={async () => await props.plugin.askGpt(props.output.message)}>
Ask GPT
Ask RemixAI
</span>
<span className="ml-3 pt-1 py-1">
<CopyToClipboard content={props.output.message} className={`p-0 m-0 far fa-copy alert alert-danger`} direction={'top'} />

@ -6,7 +6,6 @@ import {Contract, compileContract} from './compiler'
import {ExampleContract} from '../components/VyperResult'
import EventEmitter from 'events'
export type VyperComplierAddress = 'https://vyper2.remixproject.org/' | 'http://localhost:8000/'
export class RemixClient extends PluginClient {
private client = createClient<Api, Readonly<RemixApi>>(this)
@ -66,11 +65,12 @@ export class RemixClient extends PluginClient {
return
}
try {
// TODO: remove! no formatting required since already handled on server
const formattedMessage = `
${message}
can you explain why this error occurred and how to fix it?
`
await this.client.call('openaigpt' as any, 'message', formattedMessage)
await this.client.call('solcoder' as any, 'error_explaining', message)
} catch (err) {
console.error('unable to askGpt')
console.error(err)

@ -66,7 +66,6 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli
this.props.plugin.call('terminal', 'log', { type: 'aitypewriterwarning', value: 'Solcoder - generating code for following comment: ' + ask.replace('///', '') })
const data = await this.props.plugin.call('solcoder', 'code_generation', word)
_paq.push(['trackEvent', 'ai', 'solcoder', 'code_generation'])
const parsedData = data[0].trimStart() //JSON.parse(data).trimStart()
const item: monacoTypes.languages.InlineCompletion = {
@ -105,7 +104,6 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli
// Code insertion
try {
const output = await this.props.plugin.call('solcoder', 'code_insertion', word, word_after)
_paq.push(['trackEvent', 'ai', 'solcoder', 'code_insertion'])
const generatedText = output[0] // no need to clean it. should already be
const item: monacoTypes.languages.InlineCompletion = {
@ -130,7 +128,6 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli
try {
// Code completion
const output = await this.props.plugin.call('solcoder', 'code_completion', word)
_paq.push(['trackEvent', 'ai', 'solcoder', 'code_completion'])
const generatedText = output[0]
let clean = generatedText

@ -759,8 +759,8 @@ export const EditorUI = (props: EditorUIProps) => {
const file = await props.plugin.call('fileManager', 'getCurrentFile')
const content = await props.plugin.call('fileManager', 'readFile', file)
const message = intl.formatMessage({ id: 'editor.generateDocumentationByAI' }, { content, currentFunction: currentFunction.current })
await props.plugin.call('openaigpt', 'message', message)
_paq.push(['trackEvent', 'ai', 'openai', 'generateDocumentation'])
await props.plugin.call('solcoder', 'code_explaining', message)
_paq.push(['trackEvent', 'ai', 'solcoder', 'generateDocumentation'])
},
}
@ -775,8 +775,8 @@ export const EditorUI = (props: EditorUIProps) => {
const file = await props.plugin.call('fileManager', 'getCurrentFile')
const content = await props.plugin.call('fileManager', 'readFile', file)
const message = intl.formatMessage({ id: 'editor.explainFunctionByAI' }, { content, currentFunction: currentFunction.current })
await props.plugin.call('openaigpt', 'message', message)
_paq.push(['trackEvent', 'ai', 'openai', 'explainFunction'])
await props.plugin.call('solcoder', 'code_explaining', message, content)
_paq.push(['trackEvent', 'ai', 'solcoder', 'explainFunction'])
},
}

@ -30,7 +30,7 @@ export function LanguageOptions({ plugin }: { plugin: any }) {
{langOptions}
</Dropdown.Toggle>
<Dropdown.Menu className="dropdown-menu langSelector" style={{ paddingTop: "0px", paddingBottom: "0px", minWidth: 'fit-content', backgroundColor: 'var(--body-bg)' }}>
{['EN', 'ES', 'FR', 'IT', 'RU', 'ZH'].map((lang, index) => (
{['EN', 'ES', 'FR', 'IT', 'KO', 'RU', 'ZH'].map((lang, index) => (
<DropdownItem as={'span'} className={langOptions === lang ? "border border-primary px-2" : "px-2"} onClick={() =>
{
changeLanguage(lang.toLowerCase())

@ -44,19 +44,6 @@ const RemixUIPanelHeader = (props: RemixPanelProps) => {
{plugin?.profile?.name && <FormattedMessage id={`${plugin.profile.name}.displayName`} defaultMessage={plugin?.profile?.displayName || plugin?.profile?.name} />}
</h6>
<div className="d-flex flex-row">
{
plugin && plugin.profile.name !== 'filePanel' && (
<RenderIfNot condition={plugin.profile.name === 'filePanel'}>
<RenderIf condition={plugin.pinned}>
<div className='d-flex' data-id="movePluginToLeft" onClick={unPinPlugin}>
<CustomTooltip placement="auto-end" tooltipId="unPinnedMsg" tooltipClasses="text-nowrap" tooltipText={<FormattedMessage id="panel.unPinnedMsg" />}>
<i aria-hidden="true" className="mt-1 px-2 fas fa-solid fa-square-left"></i>
</CustomTooltip>
</div>
</RenderIf>
</RenderIfNot>
)
}
<div className="d-flex flex-row">
{plugin?.profile?.maintainedBy?.toLowerCase() === 'remix' ? (
<CustomTooltip placement="auto-end" tooltipId="maintainedByTooltip" tooltipClasses="text-nowrap" tooltipText={<FormattedMessage id="panel.maintainedByRemix" />}>
@ -75,13 +62,22 @@ const RemixUIPanelHeader = (props: RemixPanelProps) => {
{
plugin && plugin.profile.name !== 'filePanel' && (
<RenderIfNot condition={plugin.profile.name === 'filePanel'}>
<RenderIfNot condition={plugin.pinned}>
<div className='d-flex' data-id="movePluginToRight" onClick={pinPlugin}>
<CustomTooltip placement="auto-end" tooltipId="pinnedMsg" tooltipClasses="text-nowrap" tooltipText={<FormattedMessage id="panel.pinnedMsg" />}>
<i aria-hidden="true" className="mt-1 px-1 pl-2 fas fa-solid fa-square-right"></i>
</CustomTooltip>
</div>
</RenderIfNot>
<>
<RenderIf condition={plugin.pinned}>
<div className='d-flex' data-id="movePluginToLeft" onClick={unPinPlugin}>
<CustomTooltip placement="auto-end" tooltipId="unPinnedMsg" tooltipClasses="text-nowrap" tooltipText={<FormattedMessage id="panel.unPinnedMsg" />}>
<i aria-hidden="true" className="mt-1 px-2 fak fa-fa-dock-l"></i>
</CustomTooltip>
</div>
</RenderIf>
<RenderIfNot condition={plugin.pinned}>
<div className='d-flex' data-id="movePluginToRight" onClick={pinPlugin}>
<CustomTooltip placement="auto-end" tooltipId="pinnedMsg" tooltipClasses="text-nowrap" tooltipText={<FormattedMessage id="panel.pinnedMsg" />}>
<i aria-hidden="true" className="mt-1 px-1 pl-2 fak fa-fa-dock-r"></i>
</CustomTooltip>
</div>
</RenderIfNot>
</>
</RenderIfNot>
)
}

@ -5,12 +5,15 @@ import './panel.css'
interface panelPLuginProps {
pluginRecord: PluginRecord,
initialState?: any,
highlightStamp?: number,
children?: any
}
const RemixUIPanelPlugin = (props: panelPLuginProps, panelRef: any) => {
const localRef = useRef<HTMLDivElement>(null)
const [view, setView] = useState<JSX.Element | HTMLDivElement>()
const [showHighlight, setShowHighlight] = useState<boolean>(false)
useEffect(() => {
const ref: any = panelRef || localRef
if (ref.current) {
@ -19,9 +22,12 @@ const RemixUIPanelPlugin = (props: panelPLuginProps, panelRef: any) => {
let view = props.pluginRecord.view
if (props.initialState) {
let hasInitialProps = false
view = React.Children.map((props.pluginRecord.view.props as any).children, child => {
if (React.isValidElement(child) && typeof child.type === 'function') {
// Safe to clone and pass `initialState`
if (React.isValidElement(child) && typeof child.type === 'function' && !hasInitialProps) {
hasInitialProps = true
// Safe to clone and pass `initialState`
return React.cloneElement(child, { ...props, initialState: props.initialState } as any)
}
return child
@ -36,8 +42,20 @@ const RemixUIPanelPlugin = (props: panelPLuginProps, panelRef: any) => {
}
}, [])
useEffect(() => {
if (props.highlightStamp) setShowHighlight(true)
}, [props.highlightStamp])
useEffect(() => {
if (showHighlight) {
setTimeout(() => {
setShowHighlight(false)
}, 500)
}
}, [showHighlight])
return (
<div className={props.pluginRecord.active ? `${props.pluginRecord.class}` : 'd-none'} ref={panelRef || localRef}>
<div className={`${props.pluginRecord.active ? `${props.pluginRecord.class}` : 'd-none'} ${showHighlight ? 'highlight' : ''}`} ref={panelRef || localRef}>
<>{view}</>
</div>
)

@ -106,3 +106,7 @@ iframe {
.terminal-wrap.minimized.desktop {
}
.highlight {
animation: highlight 2s forwards;
}

@ -9,6 +9,7 @@ export interface RemixPanelProps {
plugins: Record<string, PluginRecord>,
header: JSX.Element,
pluginState?: any,
highlightStamp?: number
}
export function RemixPluginPanel(props: RemixPanelProps) {
@ -18,7 +19,7 @@ export function RemixPluginPanel(props: RemixPanelProps) {
<div className="pluginsContainer">
<div className="plugins" id="plugins">
{Object.values(props.plugins).map((pluginRecord) => {
return <RemixUIPanelPlugin key={pluginRecord.profile.name} pluginRecord={pluginRecord} initialState={props.pluginState} />
return <RemixUIPanelPlugin key={pluginRecord.profile.name} pluginRecord={pluginRecord} initialState={props.pluginState} highlightStamp={props.highlightStamp} />
})}
</div>
</div>

@ -75,8 +75,8 @@ export const Renderer = ({ message, opt = {}, plugin }: RendererProps) => {
try {
const content = await plugin.call('fileManager', 'readFile', editorOptions.errFile)
const message = intl.formatMessage({ id: 'solidity.openaigptMessage' }, { content, messageText })
await plugin.call('openaigpt', 'message', message)
_paq.push(['trackEvent', 'ai', 'openai', 'explainSolidityError'])
await plugin.call('solcoder', 'error_explaining', message)
_paq.push(['trackEvent', 'ai', 'solcoder', 'error_explaining_SolidityError'])
} catch (err) {
console.error('unable to askGtp')
console.error(err)
@ -111,7 +111,7 @@ export const Renderer = ({ message, opt = {}, plugin }: RendererProps) => {
onClick={() => { askGtp() }}
style={{ borderColor: "var(--ai)" }}
>
ASK GPT
Ask RemixAI
</span>
</div>

@ -297,7 +297,16 @@ export function UniversalDappUI(props: UdappProps) {
<label>
<b><FormattedMessage id="udapp.balance" />:</b> {instanceBalance} ETH
</label>
{props.exEnvironment && props.exEnvironment.startsWith('injected') && <i className="fas fa-edit btn btn-sm p-0" onClick={() => {props.editInstance(props.instance)}}></i>}
{props.exEnvironment && props.exEnvironment.startsWith('injected') && (
<CustomTooltip placement="top" tooltipClasses="text-nowrap" tooltipId="udapp_udappEditTooltip" tooltipText={<FormattedMessage id="udapp.tooltipTextEdit" />}>
<i
className="fas fa-edit btn btn-sm p-0"
onClick={() => {
props.editInstance(props.instance)
}}
></i>
</CustomTooltip>
)}
</div>
{ props.isPinnedContract && props.instance.pinnedAt ? (
<div className="d-flex" data-id="instanceContractPinnedAt">

@ -235,10 +235,11 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
try {
if (script.trim().startsWith('git')) {
// await this.call('git', 'execute', script) code might be used in the future
// TODO: rm gpt or redirect gpt to sol-pgt
} else if (script.trim().startsWith('gpt')) {
call('terminal', 'log',{ type: 'warn', value: `> ${script}` })
await call('openaigpt', 'message', script)
_paq.push(['trackEvent', 'ai', 'openai', 'askFromTerminal'])
await call('solcoder', 'solidity_answer', script)
_paq.push(['trackEvent', 'ai', 'solcoder', 'askFromTerminal'])
} else if (script.trim().startsWith('sol-gpt')) {
call('terminal', 'log',{ type: 'warn', value: `> ${script}` })
await call('solcoder', 'solidity_answer', script)

@ -54,9 +54,6 @@ const TerminalWelcomeMessage = ({ packageJson, storage }) => {
ethers.js
</a>{' '}
</li>
<li key="gpt">
gpt <i>&lt;your question here&gt;</i> {' '}
</li>
<li key="sol-gpt">
sol-gpt <i>&lt;your Solidity question here&gt;</i> {' '}
</li>

@ -88,10 +88,10 @@ const Icon = ({ iconRecord, verticalIconPlugin, contextMenuAction, theme }: Icon
return (
<>
<div className='d-flex py-1' style={{ width: 'auto', placeContent: stylePC }}>
{iconRecord.active && <div
className='pt-1 bg-primary'
<div
className={`pt-1 ${iconRecord.active ? 'bg-primary' : 'bg-transparent'}`}
style={{ width: "6px", height: "36px", position: 'relative', borderRadius: '24%' }}
></div>}
></div>
<CustomTooltip
placement={name === 'settings' ? 'right' : name === 'search' ? 'top' : name === 'udapp' ? 'bottom' : 'top'}
tooltipText={title}
@ -100,7 +100,11 @@ const Icon = ({ iconRecord, verticalIconPlugin, contextMenuAction, theme }: Icon
<div
className={`remixui_icon m-0 pt-1`}
onClick={() => {
;(verticalIconPlugin as any).toggle(name)
if (iconRecord.pinned) {
verticalIconPlugin.call('pinnedPanel', 'highlight')
} else {
(verticalIconPlugin as any).toggle(name)
}
}}
{...{ plugin: name }}
onContextMenu={(e: any) => {
@ -133,6 +137,10 @@ const Icon = ({ iconRecord, verticalIconPlugin, contextMenuAction, theme }: Icon
contextMenuAction={contextMenuAction}
/>
) : null}
<div
className={`pt-1 ${iconRecord.pinned ? 'bg-primary' : 'bg-transparent'}`}
style={{ width: "6px", height: "36px", position: 'relative', borderRadius: '24%', marginLeft: 'auto' }}
></div>
</div>
</>
)

@ -3,6 +3,7 @@ import { Profile } from '@remixproject/plugin-utils'
export type IconRecord = {
profile: Profile
active: boolean
pinned: boolean
class?: string
canbeDeactivated?: boolean
isRequired?: boolean

@ -1,10 +1,10 @@
{
"version": "v0.49.0",
"version": "v0.50.0",
"title": "RELEASE HIGHLIGHTS",
"highlight1": "Syntax highlighting for .toml files added",
"highlight2": "'Deploy & Run Transactions' plugin's UI improved",
"highlight3": "Remix AI model improved",
"highlight1": "Pin a plugin to the new right side panel",
"highlight2": "'zksync-ethers' NPM module supported in js/ts scripts",
"highlight3": "latest Solidity compiler version set to v0.8.26",
"highlight4": "",
"more": "Read More",
"moreLink": "https://medium.com/remix-ide/remix-release-v0-49-0-b396ab7fff2b?source=friends_link&sk=2e3c6063841bbfa398e3e60d59d4fd48"
"moreLink": "https://medium.com/remix-ide/remix-release-v0-50-0-1b0ca47ce2d9?source=friends_link&sk=a1cec61a506047186cd8e0c4349cdb86"
}

Loading…
Cancel
Save