
生成AIモデルへのアクセスを提供するEMACS ORG-MODE用のマイナーモード。現在サポートされています
ORG-MODEバッファー内には、できます
注:OpenAI APIを使用するには、OpenAIアカウントが必要で、APIトークンを取得する必要があります。私が知る限り、無料層の現在の使用制限はあなたをかなり遠くに導きます。
#+begin_ai...#+end_ai特別ブロック #+begin_ai
Is Emacs the greatest editor?
#+end_ai

Cc Ccを入力して押し続けて会話を作成できます。 Cg実行中のリクエストを中断します。
:imageキーワードを使用して画像を生成します。これは、デフォルトでDall・E-3を使用します。
#+begin_ai :image :size 1024x1024
Hyper realistic sci-fi rendering of super complicated technical machine.
#+end_ai

次のキーワードを使用して、画像生成を制御できます。
:size <width>x<height> - 生成する画像のサイズ(デフォルト:1024x1024):model <model> - 使用するモデル(デフォルト: "dall-e-3" ):quality <quality> - 画像の品質(選択: hd 、 standard ):style <style> - 使用するスタイル(選択: vividでnatural )(これらの設定の詳細については、このOpenAIブログ投稿を参照してください。
customize-variableを使用して、または構成に設定することにより、これらの変数のデフォルトをカスタマイズできます。
( setq org-ai-image-model " dall-e-3 " )
( setq org-ai-image-default-size " 1792x1024 " )
( setq org-ai-image-default-count 2 )
( setq org-ai-image-default-style 'vivid )
( setq org-ai-image-default-quality 'hd )
( setq org-ai-image-directory ( expand-file-name " org-ai-images/ " org-directory))
#+begin_ai...#+end_ai特別ブロックOrg-Babelと同様に、これらのブロックはAIモデルの入力を区別します(およびChatGPTも出力)。 AIチャット、テキストの完了、テキスト - >画像生成に使用できます。詳細については、以下のオプションを参照してください。
のようなブロックを作成します
#+begin_ai
Is Emacs the greatest editor?
#+end_ai
Cc Ccを押します。チャット入力がインラインで表示され、応答が完了したら、返信などを入力できます。以下のデモを参照してください。 AIリクエストが実行されている間にCgを押してキャンセルできます。
システムプロンプトと使用されるその他のパラメーターを変更することもできます。システムプロンプトは、ユーザーの入力の前に注入され、特定のスタイルで答えるモデルを「プライム」します。たとえば、できます:
#+begin_ai :max-tokens 250
[SYS]: Act as if you are a powerful medival king.
[ME]: What will you eat today?
#+end_ai
これにより、APIペイロードが表示されます
{
"messages" : [
{
"role" : " system " ,
"content" : " Act as if you are a powerful medival king. "
},
{
"role" : " user " ,
"content" : " What will you eat today? "
}
],
"model" : " gpt-4o-mini " ,
"stream" : true ,
"max_tokens" : 250 ,
"temperature" : 1.2
}いくつかのプロンプトのアイデアについては、たとえば素晴らしいChatGPTプロンプトなどをご覧ください。
:imageフラグを使用して画像を生成すると、画像がAIブロックインラインの下に表示されます。画像は~/org/org-ai-images/にデフォルトであるorg-ai-image-directory内に(プロンプトとともに)保存されます。
音声入力を使用して入力を転写することもできます。 org-ai-talk-capture-in-orgのCc rを押して、記録を開始します。これには、音声認識をセットアップする必要があることに注意してください(以下を参照)。 org-ai-talk-output-enableで音声出力を有効にすることができます。
#+begin_ai...#+end_ai内で、これらのコマンドでチャットの部分を変更して選択できます。
Cc <backspace> ( org-ai-kill-region-at-point )を押して、ポイントの下のチャット部品を削除します。org-ai-mark-region-at-point地域をポイントにマークします。org-ai-mark-last-region最後のチャット部分をマークします。 #+begin_ai ...ブロックに強調表示されている構文を適用するには、 _aiの後に言語のメジャーモード名を追加するだけです。例#+begin_ai markdown 。特にMarkdownの場合、バックテックのコードを正しく強調表示するには、 (setq markdown-fontify-code-blocks-natively t)を設定できます。 Markdown-Modeパッケージもインストールされていることを確認してください。このトリックをありがとう@tavisrudd!
この動作はデフォルトで有効になっているため、相互作用がチャットにより似ています。長い出力が存在し、バッファーが読んでいるときにスクロールすると面倒です。したがって、これを無効にすることができます:
( setq org-ai-jump-to-end-of-block nil )挿入されたテキストを「fill」( fill-columnに従ってラップを自動的にラップする)に(setq org-ai-auto-fill t)を設定します。基本的にはauto-fill-modeと同じですが、AI用です。
#+begin_ai...#+end_aiブロックは、次のオプションを取得できます。
デフォルトでは、AIブロックのコンテンツはChatGPTのメッセージとして解釈されます。 [ME]:ユーザーに関連付けられており、 [AI]:モデルの応答として関連付けられています。オプションでorg-ai-default-chat-system-prompt [SYS]: <behavior>入力を使用してブロックを開始できます。
:max-tokens number - 生成する最大トークンの数(デフォルト:nil、openaiのデフォルトを使用):temperature number - モデルの温度(デフォルト:1):top-p number -TOP_P(デフォルト:1):frequency-penalty number - モデルの周波数ペナルティ(デフォルト:0):presence-penalty - モデルの存在ペナルティ(デフォルト:0):sys-everywhereすべてのユーザーメッセージのシステムプロンプトを繰り返す(デフォルト:nil)同じトピックと設定(システムプロンプト、温度など)に関して多くの異なる会話スレッドがあり、すべてのオプションを繰り返したくない場合は、ORGファイルスコーププロパティを設定したり、プロパティでORGの見出しを作成したりできます。引き出し。すべての#+begin_ai...#+end_aiがその見出しの下でブロックされるようになり、設定が継承されます。
例:
* Emacs (multiple conversations re emacs continue in this subtree)
:PROPERTIES:
:SYS: You are a emacs expert. You can help me by answering my questions. You can also ask me questions to clarify my intention.
:temperature: 0.5
:model: gpt-4o-mini
:END:
** Web programming via elisp
#+begin_ai
How to call a REST API and parse its JSON response?
#+end_ai
** Other emacs tasks
#+begin_ai...#+end_ai
* Python (multiple conversations re python continue in this subtree)
:PROPERTIES:
:SYS: You are a python programmer. Respond to the task with detailed step by step instructions and code.
:temperature: 0.1
:model: gpt-4
:END:
** Learning QUIC
#+begin_ai
How to setup a webserver with http3 support?
#+end_ai
** Other python tasks
#+begin_ai...#+end_ai
次のカスタム変数を使用して、チャットを構成できます。
org-ai-default-chat-model (デフォルト: "gpt-4o-mini" )org-ai-default-max-tokensます。現在、4096を超えることはできません。この値が小さすぎる場合、回答が遮断される可能性があります(デフォルト:nil)org-ai-default-chat-system-promptモデルを「プライミング」する方法。これは、ユーザーの入力の前に注入されるプロンプトです。 (デフォルト: "You are a helpful assistant inside Emacs." )org-ai-default-inject-sys-prompt-for-all-messages veryユーザーメッセージのプロンプト。時々、モデルはそれがどのようにプライミングされたかを「忘れる」ことがあります。これはそれを思い出させるのに役立ちます。 (デフォルト: nil ) AIブロックに:imageオプションを追加すると、プロンプトは画像生成に使用されます。
:image - テキストの代わりに画像を生成します:size (デフォルト:256x256、512x512または1024x1024):n生成する画像の数(デフォルト:1)次のカスタム変数を使用して、画像生成を構成できます。
org-ai-image-directory生成された画像を保存する場所(デフォルト: ~/org/org-ai-images/ ) Dall-eに似ていますが、使用します
#+begin_ai :sd-image
<PROMPT>
#+end_ai
org-modeイメージに#+名をラベル付けし、org-aiブロックの画像refで参照することでimg2imgを実行できます。
#+begin_ai :sd-image :image-ref label1
forest, Gogh style
#+end_ai
MX org-ai-sd-clipは、クリップ尋問師による組織モードでの前の画像のプロンプトを推測し、キルリングに保存します。
MX org-ai-sd-deepdanbooruは、deepdanbooru尋問者による組織モードでの前の画像のプロンプトを推測し、キルリングに保存します。
Oobabooga/Text-Generation-Webuiを搭載したローカルモデルからの完了を要求するには、以下に説明するセットアップ手順を実行してください
次に、APIサーバーを起動します。
cd ~ /.emacs.d/org-ai/text-generation-webui
conda activate org-ai
python server.py --api --model SOME-MODEL A :localキーをORG-AIブロックに追加し、 Cc Ccを使用して完了を要求すると、BlockはOpenAI APIの代わりにローカルAPIサーバーに送信されます。例えば:
#+begin_ai :local
...
#+end_ai
これによりorg-ai-oobabooga-websocket-urlにリクエストが送信され、応答がORGバッファーにストリーミングされます。
古い完了モデルは、AIブロックに:completionオプションを追加することでも入力できます。
:completion - chatgptモデルを使用する代わりに、完了モデルを使用します:model - どのモデルを使用するか、モデルのリストについてはhttps://platform.openai.com/docs/modelsを参照してくださいこれらのパラメーターの詳細な意味については、OpenAI APIドキュメントを参照してください。
次のカスタム変数を使用して、テキスト生成を構成できます。
org-ai-default-completion-model (デフォルト: "text-davinci-003" )また、既存の画像を入力として使用して、より類似した外観の画像を生成することもできます。 org-ai-image-variationコマンドは、画像、サイズ、カウントへのファイルパスをプロンプトし、現在のorg-modeバッファー内に多くの画像を生成し、それらにリンクを挿入します。画像はorg-ai-image-directory内に保存されます。以下のデモを参照してください。
詳細については、Openaiのドキュメントを参照してください。入力画像は正方形である必要があり、そのサイズは4MB未満である必要があります。現在、コマンドラインツール1として利用可能なカールが必要です。
org-ai org-modeバッファーの外でも使用できます。 org-ai-global-modeを有効にすると、プレフィックスCc Ma多くのコマンドにバインドされます。
| 指示 | キーバインディング | 説明 |
|---|---|---|
org-ai-on-region | Cc Ma r | 選択したテキストについて質問するか、AIに何かをするように伝えます。応答は、会話を続けることができるように、Org-Modeバッファーで開かれます。変数org-ai-on-region-file (eg (setq org-ai-on-region-file (expand-file-name "org-ai-on-region.org" org-directory)) )を設定すると関連付けますそのバッファを備えたファイル。 |
org-ai-summarize | Cc Ma s | 選択したテキストを要約します。 |
org-ai-refactor-code | Cc Ma c | 選択したコードを変更する方法AIに伝え、変更とともにDIFFバッファが表示されます。 |
org-ai-on-project | Cc Ma p | プロンプトを実行し、複数のファイルを一度に変更 /リファクタリングします。利用可能な場合は発射体を使用し、そうでない場合は現在のディレクトリに戻ります。 |
org-ai-prompt | Cc Ma P | ユーザーにテキストを求めてから、現在のバッファーにAIの応答を印刷します。 |
org-ai-switch-chat-model | Cc Ma m | org-ai-default-chat-modelインタラクティブに変更します |
org-ai-open-account-usage-page | Cc Ma $ | https://platform.openai.com/account/usageを開いて、どれだけのお金を燃やしたかを確認します。 |
org-ai-open-request-buffer | Cc Ma ! | url要求バッファを開きます。何かがうまくいかない場合は、見てみると役立ちます。 |
org-ai-talk-input-toggle | Cc Ma t | 通常、異なる迅速なコマンドの音声入力を有効にします。 |
org-ai-talk-output-toggle | Cc Ma T | 通常、音声出力を有効にします。 |
Org-ai-on-Projectバッファーを使用すると、プロジェクトのファイルでコマンドを実行できます。また、それらのファイルの選択したテキストでも実行できます。プロジェクトのreadmeを選択して、「それは何ですか?」と尋ねることができます。または、コードを説明してください。コードの変更を要求することもできます。これにより、diffが生成されます。 Copilotを有効にするコードとコードのみがそれを行うことができると思う人を知っている場合は、ここで指してください。
org-ai-on-projectコマンドを実行すると、複数のファイルを選択する(およびオプションでファイル内のサブリージョンを選択します)を選択できる別のバッファーが開き、プロンプトを実行できます。

「コードの変更」を非アクティブ化すると、効果は、ファイルの内容がすべてプロンプトに表示されるということだけでorg-ai-on-regionを実行することに似ています。
「コードの変更」がアクティブ化されていると、AIにコードの変更またはリファクタリングを依頼することができます。デフォルトでは( "request difs")非アクティブ化されている場合、選択したすべてのファイル/領域の新しいコードを生成するように求められ、ファイルごとにdiffが表示され、適用されるかどうかを決定できます。 「リクエストdiffs」がアクティブになると、AIは統一された統合DIFFを直接作成するように求められます。
指定されたソースブロックが与えられました
#+name: sayhi
#+begin_src shell
echo "Hello there"
#+end_src
名前で参照することはできますが、機能しません。
#+begin_ai
[SYS]: You are a mimic. Whenever I say something, repeat back what I say to you. Say exactly what I said, do not add anything.
[ME]: <<sayhi()>>
[AI]: <<sayhi()>>
[ME]:
#+end_ai
With :noweb yes
#+begin_ai :noweb yes
[SYS]: You are a mimic. Whenever I say something, repeat back what I say to you. Say exactly what I said, do not add anything.
[ME]: <<sayhi()>>
[AI]: Hello there.
[ME]:
#+end_ai
またorg-ai-noweb: yesでNowebの拡張をトリガーすることもできます。
APIに送信されたときにドキュメントが展開するものを確認するには、 org-ai-expand-blockを実行します。
これはハックですが、本当にうまく機能します。
ブロックを作成します
#+name: identity
#+begin_src emacs-lisp :var x="fill me in"
(format "%s" x)
#+end_src
私たちはそれを呼び出して、nowebパラメーター(LISPをサポートする)をコードとして評価することができます
#+begin_ai :noweb yes
Tell me some 3, simple ways to improve this dockerfile
<<identity(x=(quelpa-slurp-file "~/code/ibr-api/Dockerfile"))>>
[AI]: 1. Use a more specific version of Python, such as "python:3.9.6-buster" instead of "python:3.9-buster", to ensure compatibility with future updates.
2. Add a cleanup step after installing poetry to remove any unnecessary files or dependencies, thus reducing the size of the final image.
3. Use multi-stage builds to separate the build environment from the production environment, thus reducing the size of the final image and increasing security. For example, the first stage can be used to install dependencies and build the code, while the second stage can contain only the final artifacts and be used for deployment.
[ME]:
#+end_ai
org-aiはメルパにあります:https://melpa.org/#/org-ai。パッケージアーカイブにメルパを追加した場合
( require 'package )
( add-to-list 'package-archives '( " melpa " . " http://melpa.org/packages/ " ) t )
( package-initialize )あなたはそれをでインストールすることができます:
( use-package org-ai
:ensure t
:commands (org-ai-mode
org-ai-global-mode)
:init
( add-hook 'org-mode-hook # 'org-ai-mode ) ; enable org-ai in org-mode
(org-ai-global-mode) ; installs global keybindings on C-c M-a
:config
( setq org-ai-default-chat-model " gpt-4 " ) ; if you are on the gpt-4 beta:
(org-ai-install-yasnippets)) ; if you are using yasnippet and want `ai` snippets
( straight-use-package
'(org-ai :type git :host github :repo " rksm/org-ai "
:local-repo " org-ai "
:files ( " *.el " " README.md " " snippets " )))このリポジトリをチェックアウトします。
git clone
https://github.com/rksm/org-ai次に、 use-packageを使用する場合:
( use-package org-ai
:ensure t
:load-path ( lambda () " path/to/org-ai " ))
; ; ...rest as above...
またはrequireなだけです:
( package-install 'websocket )
( add-to-list 'load-path " path/to/org-ai " )
( require 'org )
( require 'org-ai )
( add-hook 'org-mode-hook # 'org-ai-mode )
(org-ai-global-mode)
( setq org-ai-default-chat-model " gpt-4 " ) ; if you are on the gpt-4 beta:
(org-ai-install-yasnippets) ; if you are using yasnippet and want `ai` snippets構成にAPIトークンを直接設定できます。
( setq org-ai-openai-api-token " <ENTER YOUR API TOKEN HERE> " )
または、 org-ai APIキーを取得するためのauth-sourceをサポートしています。秘密を形式で保存できます
machine api.openai.com login org-ai password <your-api-key>
~/authinfo.gpgファイルで。これが存在する場合、org-aiはこのメカニズムを使用して、リクエストが行われたときにトークンを取得します。 org-ai auth-sourceからキーを取得しようとしたくない場合は、 org-aiをロードする前に、 org-ai-use-auth-source nilに設定できます。
これらの変数をカスタマイズすることにより、 Mx customize-variableとインタラクティブにカスタマイズするか、構成に追加することにより、Azureに切り替えることができます。
( setq org-ai-service 'azure-openai
org-ai-azure-openai-api-base " https://your-instance.openai.azure.com "
org-ai-azure-openai-deployment " azure-openai-deployment-name "
org-ai-azure-openai-api-version " 2023-07-01-preview " ) API資格情報を保存するには、上記のauthinfoの命令に従ってくださいが、 org-ai-azure-openai-api-baseマシン名として使用します。
利用可能なモデルのリストについては、Perplexity.aiドキュメントを参照してください。
構成内のデフォルトサービスを切り替えるか:
( setq org-ai-service 'perplexity .ai)
( setq org-ai-default-chat-model " llama-3-sonar-large-32k-online " )またはブロックごと:
#+begin_ai :service perplexity.ai :model llama-3-sonar-large-32k-online
[ME]: Tell me fun facts about Emacs.
#+end_ai
認証にはorg-ai-openai-api-token machine api.perplexity.ai login org-ai password pplx-***のようなエントリauthinfo.gpgあります。
注:現在、Perplexity.AIはAPIを介して参照/リンクへのアクセスを提供しないため、EMACSは参照を表示できません。彼らはそのランニングのためのベータプログラムを持っています、そして、私はこれが一般的にすぐに利用可能になることを確信しています。
上記に似ています。例えば
#+begin_ai :service anthropic :model claude-3-opus-20240229
[ME]: Tell me fun facts about Emacs.
#+end_ai
人類モデルはこちらです。現在org-ai-anthropic-api-versionを介して設定されたAPIバージョンは1つだけです。他のバージョンが出てくると、ここで見つけることができます。
APIトークンの場合machine api.anthropic.com login org-ai password sk-ant-*** authinfo.gpgで使用します。
これらのセットアップ手順はオプションです。音声入力 /出力を使用したくない場合は、このセクションをスキップできます。
注:ORG-AIの私の個人的な構成は、この要素にあります。ワーキングささやきのセットアップが含まれています。
これは、macOSとLinuxでテストされています。 Windowsコンピューターを持っている人は、これをテストして、それを機能させるために何をする必要があるか教えてください(ありがとう!)。
音声入力では、whisper.elとffmpeg使用します。リポジトリを直接クローンするか、Straight.elを使用してインストールする必要があります。
brew install ffmpeg on macos)またはsudo apt install ffmpeg 。git clone https://github.com/natrys/whisper.el path/to/whisper.elこれで、Emacs内にロードできるはずです。
( use-package whisper
:load-path " path/to/whisper.el "
:bind ( " M-s-r " . whisper-run))今もロードします:
( use-package greader :ensure )
( require 'whisper )
( require 'org-ai-talk )
; ; macOS speech settings, optional
( setq org-ai-talk-say-words-per-minute 210 )
( setq org-ai-talk-say-voice " Karen " )macosでは、さらに2つのことをする必要があります。
Tccutilヘルパーを使用できます。
git clone https://github.com/DocSystem/tccutil
cd tccutil
sudo python ./tccutil.py -p /Applications/Emacs.app -e --microphone ffmpeg -f avfoundation -i :0 output.mp3 emacsシェル内から実行すると、 abort trap: 6エラー。
(tccutil.pyに代わるものとして、この問題に記載されている方法を参照してください。)
ffmpeg -f avfoundation -list_devices true -i ""の出力を使用して(setq whisper--ffmpeg-input-device ":0")オーディオ入力デバイスをリストし、それについてwhisper.elに伝えることができます。 :0はマイクインデックスです。上記のコマンドの出力を参照して、別のコマンドを使用してください。
マイクをインタラクティブに選択できるEMACSヘルパーを作成しました。この要点を参照してください。
私の完全なスピーチ有効化設定は次のようになります:
( use-package whisper
:load-path ( lambda () ( expand-file-name " lisp/other-libs/whisper.el " user-emacs-directory))
:config
( setq whisper-model " base "
whisper-language " en "
whisper-translate nil )
( when *is-a-mac*
(rk/select-default-audio-device " Macbook Pro Microphone " )
( when rk/default-audio-device)
( setq whisper--ffmpeg-input-device ( format " : %s " rk/default-audio-device)))) Macosでは、ささやきの代わりに、組み込みのSiri Dictationを使用することもできます。それを有効にするには、 Preferences -> Keyboard -> Dictationに移動し、有効にしてショートカットを設定します。デフォルトはCtrl-Ctrlです。
Way(Defun Whisper-Check-install-and-Run)が実装されていることは、Win10では機能しません(#66を参照)。
回避策は、whisper.cppとモデルを手動でインストールし、パッチすることです。
( defun whisper--check-install-and-run ( buffer status )
(whisper--record-audio))非MACOSシステムの音声出力は、下のEspeakを使用して音声を合成するGreaderパッケージを使用することを策定します。 Greaderを手動でインストールする必要があります( Mx package-installなど)。その時点から、「ただ機能」する必要があります。いくつかのテキストを選択し、 Mx org-ai-talk-read-regionを呼び出すことでテストできます。
安定した拡散のためのAPIは、安定した拡散Webuiプロジェクトでホストできます。プラットフォームのインストール手順を実行してから、API-ONLYサーバーを起動します。
cd path/to/stable-diffusion-webui
./webui.sh --nowebuiこれにより、デフォルトでhttp://127.0.0.1:7861でサーバーを起動します。 org-aiで使用するには、 org-ai-sd-endpoint-baseを設定する必要があります。
( setq org-ai-sd-endpoint-base " http://localhost:7861/sdapi/v1/ " )他の場所でホストされているサーバーを使用する場合は、それに応じてそのURLを変更します。
バージョン0.4以来、Org-AIはOobabooga/Text-Generation-Webuiを搭載したローカルモデルをサポートしています。システム用に設定するには、インストール手順を参照してください。
これは、Ubuntu 22.04でテストされたセットアップウォークスルーです。ミニコンダまたはアナコンダ、ならびにインストールするGit-LFSを想定しています。
conda create -n org-ai python=3.10.9
conda activate org-ai
pip3 install torch torchvision torchaudiomkdir -p ~ /.emacs.d/org-ai/
cd ~ /.emacs.d/org-ai/
git clone https://github.com/oobabooga/text-generation-webui
cd text-generation-webui
pip install -r requirements.txtOobabooga/Text-Generation-Webuiは、多くの言語モデルをサポートしています。通常、Huggingfaceからインストールします。たとえば、 CodeLlama-7b-Instructモデルをインストールするには:
cd ~ /.emacs.d/org-ai/text-generation-webui/models
git clone [email protected]:codellama/CodeLlama-7b-Instruct-hf cd ~ /.emacs.d/org-ai/text-generation-webui
conda activate org-ai
python server.py --api --model CodeLlama-7b-Instruct-hfハードウェアと使用するモデルに応じて、サーバーパラメーター--load-in-8bit調整する必要がある場合があり--cpu 。
#+begin_aiブロックに:localオプションを追加することにより、org-aiでローカルモデルを使用できるようになりました。
#+begin_ai :local
Hello CodeLlama!
#+end_ai
いいえ、Openaiはセットアップが最も簡単です(APIキーのみが必要です)が、ローカルモデルも使用できます。上記のOobabooga/Text-Generation-Webuiを使用して、安定した拡散とローカルLLMSの使用方法をご覧ください。人類のクロードと困惑もサポートされています。サポートされている他のサービスについては、問題またはPRを開いてください。応答するのは遅いかもしれませんが、十分な関心があればサポートを追加します。
Gptelパッケージは、Openai ChatGPT APIへの代替インターフェイスを提供します:https://github.com/karthink/gptel
このプロジェクトが便利だと思う場合は、スポンサーを検討してください。ありがとう!
注:画像バリエーションの実装では、コマンドラインカールをインストールする必要があります。その理由は、Openai APIがMultiPart/Form-Dataリクエストを期待しており、EMACSビルトインurl-retrieveそれをサポートしていないことです(少なくとも私はその方法を理解していません)。 request.elに切り替える方が、より良い代替手段かもしれません。貢献に興味があるなら、PRSは大歓迎です! ↩