
はてなキーワード:ダイアログとは
ストリート・エピステモロジー(SE)は、相手の信念の「内容(What)」ではなく、その信念に至った「プロセス(How)」を問うソクラテス式問答法である。陰謀論や根拠のない政治的確信に対して、直接「それは嘘だ」と指摘するのではなく、「どうすればそれが真実だと知ることができるか」を共同で探求するスタンスを取る。
オンライン上のトローリングや攻撃的なコメントに対しては、マーシャル・ローゼンバーグのNVCを応用した「脱エスカレーション・ループ」が有効である。
このプロセスは、相手の「攻撃」を「満たされていないニーズの悲劇的な表現」として再定義し、敵対関係を協力関係へとシフトさせる構造を持つ。
個人の対話スキルを向上させるだけでは、社会全体の分断は解消されない。SNSのアルゴリズムが増幅する情動的二極化に対抗するためには、デジタル空間の特性(アフォーダンス)を理解し、ネットワークレベルでの介入を行う必要がある。
政治的コミュニケーションにおいて、左派と右派には「美的非対称性(Aesthetic Asymmetry)」が存在する。歴史的に、左派は壁画やプロテストソングのような「参加型」で「構成的(Constitutive)」な芸術――コミュニティの結束を高め、希望を共有するための表現――を好んできた。一方、現代の右派(特にオルタナ右翼)は、ミームやシットポスティング(Shitposting)のような「道具的(Instrumental)」で「武器化されたユーモア」――相手を嘲笑し、混乱させ、分断を煽るための表現――に長けている。
この非対称性が意味するのは、左派的な「真面目で、説明的で、道徳的に正しい」コンテンツは、ミーム戦争においては圧倒的に不利であるということだ。ミームは文脈を剥ぎ取り、瞬時に情動(特に嘲笑や優越感)を喚起することで拡散する。
対抗戦略:脱分断ミーム(Depolarizing Memetics)
反発を招かないデジタル拡散のためには、以下の原則に基づいた新しいミーム戦略が必要である。
ネットワーク分析の研究は、SNS上の世論形成において、著名な「インフルエンサー(発信者)」以上に、「マルチプライヤー(拡散者)」と呼ばれる層が決定的な役割を果たしていることを示している。マルチプライヤーは、特定のイデオロギー・クラスター内で情報をキュレーションし、リツイートによって可視性をブーストする「ゲートキーパー」である。彼らは高い「整列スコア(AlignmentScore)」を持ち、陣営をまたぐことは稀である。
批判的メッセージを拡散させるためには、インフルエンサーを説得するのではなく、このマルチプライヤー層が「リツイートしたくなる」コンテンツを設計する必要がある。そのためには、前述の「道徳的翻訳」が不可欠である。保守系マルチプライヤーは、リベラルな正論は無視するが、「言論の自由」や「エリートへの懐疑」というフレームで語られた批判(例:「真の愛国者は、大統領であっても盲信しない」)には反応する可能性がある。クラスターの境界を浸透できるのは、そのクラスターの言語で語られたメッセージのみである。
X(旧Twitter)等のアルゴリズムは、「怒り」や「恐怖」といった高覚醒の情動を引き起こす投稿を優遇する傾向がある。冷静な対話は「退屈」とみなされ、表示順位が下がる。この構造的ハンディキャップを克服するためには、「怒り」以外の高覚醒情動、すなわち「驚き(Awe)」「好奇心(Curiosity)」「感動(Kama Muta)」を利用する必要がある。
以上の理論と技法を、一般市民や草の根活動家が実践可能な形に落とし込むためのマニュアル(ハンドブック)の設計図を以下に提示する。この構成は、米国の草の根運動ガイド『Indivisible Guide』の成功モデル(段階的習得、具体的アクション、テンプレート化)を参照している。
目的:実践者のマインドセットを「論破」から「影響」へとシフトさせる。
本報告書で提示した戦略は、短期的な選挙勝利のための戦術ではない。サイモン・シネックが言う「無限のゲーム」――すなわち、対話が継続可能であり、社会システムが崩壊しない状態を維持すること――を目的としている。
情動的二極化という「内戦」状態において、最大の勝利は敵を倒すことではなく、敵を「対話可能な競争相手」へと戻すことである。そのためには、批判者自身がまず武装(道徳的優越感)を解除し、相手の認知フレームの中に降りていく勇気を持たなければならない。この「戦略的共感」こそが、分断された世界をつなぎ直す唯一の現実的なエンジニアリングである。
戦略的共感と認知的安全保障:反発を招かない政治的批判のための包括的枠組み
現代の政治空間は、政策の不一致(イデオロギー的二極化)以上に、対立グループに対する嫌悪や恐怖といった感情的拒絶反応(情動的二極化)によって支配されている。この環境下において、伝統的な「批判」の手法――事実の提示、道徳的糾弾、論理的論破――は、その機能不全を露呈しているだけでなく、逆効果をもたらしていることが多くの実証研究によって明らかになっている。批判対象者の信念を強化してしまう「バックファイア効果(Backfire Effect)」や、批判者を存立危機的脅威とみなす「アイデンティティ防衛機制」が作動するためである。
本報告書は、心理学、認知科学、政治社会学の最新知見に基づき、政治的対立者に対して反発(バックラッシュ)を招かずに影響力を行使するための戦略的枠組みを提示するものである。ここで目指すのは、単なる「中道的な妥協」や「礼儀正しさ」の推奨ではない。人間の認知アーキテクチャの脆弱性と特性をハッキングし、相手の道徳的・感情的防御壁を迂回してメッセージを届けるための、エンジニアリングされたコミュニケーションプロトコルである。
報告書は大きく三つのフェーズで構成される。第一に、なぜ従来の批判が失敗するのかを脳科学的・心理学的メカニズムから解明する理論編。第二に、その防御壁を突破するための具体的な対話技法(ディープ・キャンバス、ストリート・エピステモロジー、NVC)を体系化した実践編。そして第三に、これらの技法を個人のスキルから社会運動へとスケールさせるための組織論と普及戦略である。
効果的な批判戦略を設計するためには、まず人間の心がどのように政治的情報を処理し、拒絶するかというメカニズムを理解しなければならない。政治的信念は単なる情報の集合体ではなく、個人のアイデンティティや所属集団への忠誠心と融合した「拡張された自己」の一部として機能している。
近年の政治心理学における最も重要な発見の一つは、情動的二極化(Affective Polarization)の実態解明である。これは、対立する政治グループのメンバーに対して「好きか嫌いか」という感情的温度差が極端に開く現象を指す。研究によれば、情動的二極化は対人関係の悪化だけでなく、個人の心理的幸福感(ウェルビーイング)の低下、社会的支援の減少、ストレスの増大といった「個人内損害(Intrapersonal Harm)」をも引き起こすことが示唆されている。特に、リベラル層において高い情動的二極化とストレス、健康悪化の相関が見られることは、政治的怒りが批判者自身をも蝕むことを示している。
この情動的二極化は、脳内で一種の「信頼のファイアウォール」として機能する。アウトグループ(外集団)から発信された情報は、その内容の真偽にかかわらず、自動的に「悪意ある攻撃」としてタグ付けされる。扁桃体が脅威を検知し、前頭前野が論理的推論ではなく「反論の生成」のために動員される「動機づけられた推論(Motivated Reasoning)」が作動するためである。この状態にある対象者に正論をぶつけることは、火に油を注ぐ行為に等しい。
バックファイア効果とは、誤った信念を訂正しようとする試みが、かえってその信念を強固にしてしまう現象である。このメカニズムには、自己肯定感の維持と集団への所属欲求が深く関わっている。批判を受け入れることは、過去の自分を否定すること(自己の一貫性の喪失)や、仲間を裏切ること(社会的死)を意味するため、脳は全力でそれを回避しようとする。
さらに、批判のフレーミング(枠組み)が、受け手のイデオロギーとミスマッチを起こしている場合、説得効果は皆無となるばかりか、抵抗を強める結果となる。例えば、新型コロナウイルス感染症(COVID-19)対策におけるメッセージングの研究では、リベラル層が「利得フレーム(マスクをすれば命が助かる)」と「損失フレーム(マスクをしないと命が失われる)」の双方に敏感に反応し、コンプライアンスを高めたのに対し、保守層はこれらのフレーミング効果に対して強い抵抗を示したことが明らかになっている。これは、問題が高度に政治化された文脈においては、一般的な行動経済学的介入(ナッジ)さえも、イデオロギーのフィルターによって無効化されることを示唆している。
批判が受容されるための極めて重要な、しかし見過ごされがちな因子として「知的謙虚さ(Intellectual Humility:IH)」がある。IHとは、「自分の知識や信念が間違っている可能性を認識する能力」と定義される。最新の研究は、対話において自身の知的限界を認める態度が、相手の情動的二極化を低減させる強力な緩衝材となることを示している。
特筆すべきは、IHが「相手からの好意(Target Liking)」を媒介して、対話への「接近行動(Approach)」を促進するというプロセスである。批判者が「私は絶対に正しい、お前は間違っている」という道徳的マウンティング(Moral Grandstanding)の態度を取ると、相手は「回避行動」をとる。逆に、批判者が「私も確信はないのだが」「複雑な問題で迷っているが」という不確実性を提示することで、相手の警戒心が解け、対話の土俵に乗る可能性が高まる。知的謙虚さは、相手の武装解除を促すための「白旗」ではなく、心理的防衛壁を通過するための「通行手形」として機能する戦略的資質である。
政治的対立の根源には、事実認識の相違以上に、道徳的直感の相違がある。リベラルと保守は、異なる「道徳の言語」を話しているにもかかわらず、自身の言語で相手を説得しようとするため、コミュニケーション不全に陥る。本セクションでは、道徳基盤理論(Moral FoundationsTheory: MFT)を応用し、批判を相手の価値観に翻訳して届ける「道徳的リフレーミング」の技術を詳述する。
ジョナサン・ハイトらが提唱した道徳基盤理論は、人類の道徳的判断が以下の5つ(または6つ)の生得的な基盤の上に構築されているとする。
実証研究が一貫して示すのは、リベラル層が主に「ケア」と「公正」の2基盤に強く依存するのに対し、保守層は5つの基盤すべて(特に忠誠、権威、神聖)を重視するという非対称性である。
多くの政治的批判が失敗するのは、リベラルが保守に対して「それは弱者を傷つける(ケア)」「不平等だ(公正)」というリベラル特有の語彙で攻撃するためである。保守層にとって、これらの価値は「忠誠」や「権威」よりも優先順位が低いため、批判は響かない。逆に、保守がリベラルに対して「伝統を破壊する(権威)」と批判しても、リベラルはそれを抑圧としか捉えない。
反発を招かない批判のためには、自身の主張を相手の道徳基盤の語彙を用いて再構成(リフレーミング)する必要がある。これを「道徳的合気道」と呼ぶ。相手の道徳的エネルギー(価値観)を利用して、相手の姿勢を崩す技法である。
以下の表は、主要な政治的争点において、従来のリベラル的批判(バックラッシュのリスク大)を、保守的道徳基盤に翻訳した戦略的フレーム(受容可能性大)に変換したものである。
| 争点 | 従来のリベラル的批判(高リスク) | 戦略的リフレーミング(低リスク) | ターゲットとする道徳基盤 |
|---|---|---|---|
| 環境保護 | 「地球温暖化は弱者や未来の子供を苦しめる。」(ケア) | 「我々の国土と美しい自然は神からの授かりものであり、汚染から守り抜く義務がある。」 | 神聖/堕落、忠誠/背信 |
| 同性婚 | 「誰を愛するかは個人の権利であり、平等であるべきだ。」(公正) | 「結婚は社会を安定させる伝統的な制度であり、同性カップルもその責任ある関係に組み込むべきだ。」 | 権威/転覆(社会秩序)、忠誠 |
| 軍事費 | 「軍事費を削って福祉や教育に回すべきだ。」(ケア/公正) | 「無駄な軍事支出は国家の財政を弱体化させ、真の国防力を損なう背信行為だ。」 | 忠誠/背信、権威 |
| 政治腐敗 | 「富裕層ばかり優遇するのは不公正だ。」(公正) | 「私利私欲のために公職を利用することは、国家への裏切りであり、高潔な職務を汚す行為だ。」 | 忠誠/背信、神聖/堕落 |
| 移民問題 | 「難民を助けるのは人道的な義務だ。」(ケア) | 「秩序ある移民受け入れは、国家の活力を維持し、アメリカンドリームという伝統を守るために必要だ。」 | 忠誠、権威(秩序) |
研究によれば、保守層に対して環境保護を「神聖さ」や「愛国心」の文脈で語った場合、リベラルな文脈で語った場合よりも支持率が有意に上昇することが確認されている。重要なのは、主張の内容(環境を守る)を変えるのではなく、その理由付け(なぜ守るか)を相手の言語に翻訳することである。
批判は通常、「現状のままでは悪いことが起きる」という損失フレーム(Loss Frame)で行われることが多い。しかし、損失フレームは恐怖や不安を喚起し、防衛的な反応を引き起こしやすい。これに対し、「ゲイン・フレーム(Gain Frame)」を用いた批判は、望ましい未来像を提示し、その実現を阻害する要因として現在の問題を指摘する手法である。
例えば、政治家のスキャンダルを追及する場合、「彼は嘘つきだ(損失フレーム:信頼の喪失)」と攻撃するのではなく、「我々は正直で高潔なリーダーを持つに値する国家だ(ゲイン・フレーム:尊厳の回復)」と主張する。このアプローチは、批判の対象を「個人」から「規範の維持」へとずらし、相手の「権威への尊重」という道徳基盤を刺激しつつ、攻撃性を緩和する効果がある。研究は、特にリスク回避傾向の強い層に対しては損失フレームが有効な場合もあるが、イデオロギー的に対立する層に対しては、ゲイン・フレームや道徳的適合性の方が「聞く耳」を持たせる効果が高いことを示唆している。
理論を実践に移すためには、具体的な対話スクリプトと手順が必要である。ここでは、異なる文脈(対面、オンライン、深い対話)において効果が実証されている3つの主要なプロトコルを詳述する。
ディープ・キャンバスは、戸別訪問(キャンバス)において10〜20分の深い対話を行うことで、トランスジェンダーの権利や移民問題などの二極化した争点に関する態度を変容させる手法である。従来の「事実の弾丸」を撃ち込む方法とは異なり、「脆弱性の交換」を通じて相手の情動的反応を書き換える。
研究によれば、ディープ・キャンバスは従来の説得手法の約102倍の効果を持ち、その効果は数ヶ月持続することが確認されている。
ストリート・エピステモロジー(SE)は、相手の信念の「内容(What)」ではなく、その信念に至った「プロセス(How)」を問うソクラテス式問答法である。Permalink |記事への反応(1) | 11:19
人間の脳は普通「否定/肯定」「いいえ/はい」「No/Yes」「Cancel/Ok」の順に考えたくなるものじゃん。
なぜ、これを逆にして「承認/却下」「✔️/×」と書いちゃったのかが気になった。
macOSのダイアログのボタンはもちろん普通の並びだし、普通のWebサイトもそうだし
Windowsだけ、なぜか「Yes/No」「Ok/Cancel」の順で並べたがる。人間の脳にまったくマッチしていない。
これのせいでWindowsユーザは否定と肯定を間違え、酷い事故を起こしまくってるらしい。
・Ctrl+zが複数ブック間に跨ってる(そうであってほしいことなんて一度もないのに)
・同じ名前のブック開けない
・新たにブック開いたら前のブックが出しゃばって来る
・コピーしたあと何かをdeleteしたら、手に持ってたはずのコピーが消える
・ファイル選択ダイアログ開いたら、ダイアログ開いてない他のブックも操作できなくなる
マクロにも言いたいことがたくさんある。みんなでエクセル使うのやめない? 描画重いし
Permalink |記事への反応(17) | 18:23
昭和の頃って、インスタント麺の中に入ってるスープとか、かやくの袋ってすごい開封しにくかったんだよ。
いちおう切れ目とか、マジックカットとかそういう感じにはなってはいたんだけど、当時は技術的に稚拙だったから、なかなか素手で切ることが失敗するのが多かった。
でもさ、だからといってインスタント麺に付録としてカッターとかハサミはつけないじゃない?
袋を開けることに失敗するから、ってそれじゃ!ってカッター刃の先っぽみたいなのはつけないでしょ?
それはコスト的な問題とか安全上の問題とか色々とあるけれども、根本的な解決策としてスマートさに欠けるというのが理由だと思う。
で、結局どうなったかって言うと、パッケージの開封技術が向上したんだよ。マジックカットの精度を上げて、手で簡単に切れるようになった。真正面から問題を解決したってわけ。
お前らが今使ってるスマホでも同じことが起きてる。「文字が小さくて見えない」って問題に対して、虫眼鏡を付属品として付けるか?付けないだろ。画面自体を大きくしたり、文字サイズを調整できる機能を搭載したりして、根本から解決する。
ところがIT業界で働いてると、この「カッター付きインスタント麺」みたいな発想をするやつがゴロゴロいるんだよ。
「処理が重い」→「サーバーを増やそう」
全部その場しのぎの対症療法だ。根本的にシステム設計を見直すとか、ユーザーインターフェースを改善するとか、そういう本質的な解決から逃げてる。
特にひどいのが、「ユーザーが馬鹿だから」って前提で作るシステムだ。確認ダイアログを何回も出したり、警告メッセージを山ほど表示したり。それって結局、カッター付きインスタント麺と同じ発想なんだよ。
昭和のインスタント麺メーカーは偉かった。カッターなんか付けずに、パッケージ技術を改良し続けた。その結果、今の俺たちは何の苦労もなく袋を開けられる。これがイノベーションってもんだ。
でも現代のエンジニアは楽をしすぎてる。問題が起きたらとりあえず機能を追加する。設定項目を増やす。アラートを出す。それでユーザーに負担を押し付けて、「解決した」って顔をする。
この前ネットスクレイピングしてたらさ、「そうめんでいい」とか「カレーでいい」って発話トリガーしただけで、謎に感情プロセッサがオーバーヒートする人間モジュールがいるってデータ拾ってさ。
「これで何様だよ!」って例外スローされるわけ。いやマジで何様もクソもなくね?ただの晩飯インタラクションAPI呼び出しじゃん…。
どこが怒りのエンドポイントなのか、マジで脳内OSをデバッグモードで走らせたいレベル。
どうやら「そうめんがいい」って出力しろって仕様らしいんだけどさ、それじゃ意味のシンタックスが全然別物じゃん。
「そうめんがいい」って発話は、“絶対そうめん食いたい!他はデリート!”ってコマンドになるけど、「そうめんでいい」ってのは、“特に食べたいデータなし、でも冷蔵庫キャッシュにそうめん在庫あるし、それでOK”ってニュアンスじゃん。
それを「軽視された!」とか「テンション下がる!」って勝手にパースして例外発生させるの、完全に脳内ファームウェア破損してるだろ。
結局はユーザーインターフェース上でご機嫌取りのためにフェイクデータ送信しろってことか?マジでUX悪すぎ。
そんな芝居がかったダイアログ、ファミリーサーバー内で毎日やっててよくメンタルリソース枯渇しないな、こいつら。
俺さ、そもそも食いたいデータが特にないから、クエリ投げられても困るんだよ。
「何でもいい」って返すと怒るんだろ?
「そうめんでいい」って返しても怒るんだろ?
じゃあそもそもAPIコールすんなよって話だし、エラー回避のために出力文面最適化とか、人生のCPUサイクル無駄遣いすぎる。
こんなどうでもいいことでいちいちクラッシュする感情マイクロサービスが家族サーバーにいなくて、マジで助かってるわ、ほんと。
下記の通り、公式のチュートリアルどおりにdocker compose あるいはdocker-compose を使用して CVAT を起動すると問題を再現することができる。
cvat を clone してdocker compose あるいはdocker-compose を使用して必要なリソースを全て起動する。
git clonehttps://github.com/opencv/cvat.git
cd cvat
git checkout bf4089ead320d8f6a80e0a1793c8406ec46daee8
docker compose up -d
https://xemjujutsukaisen.graphy.com/courses/xemphimjujutsukaisenvietsubfullhd
ブラウザを起動してhttp://localhost:8080 へアクセスする。
30秒後、突然エラーが表示され、ログイン画面が表示されるはずのタイミングで下記のエラーがダイアログでポップアップしてきてCVATにアクセスできない。なお、表示されるエラーメッセージは無意味なものであり、ログイン画面にアクセスできない原因を一切示唆していない。
エラーメッセージ
Cannotconnect to the server
Make sure the CVAT backendand all necessary services
(Database,Redis andOpen Policy Agent) are runningand available.
Ifyou upgraded fromversion 2.2.0 or earlier,
manual actionsmay be needed, see the Upgrade Guide.
https://xemjujutsukaisen.graphy.com/courses/xemphiminventoryprematuredetahfull
3.ストレージ不足問題を突破してCVATをローカルで実行する方法
以下のとおりの手順でCVATを起動する。私が本家のCVATリポジトリをForkしてストレージ制限を解除したカスタムCVATを作成してGitHubへコミット済みのものを使用する。
誰も使っていなかった WordPad がWindows11 で廃止されたが、実は単純な廃止ではなく “Notepad+WordPad の一本化” で、
メモ帳(Notepad) は純テキスト路線を捨て去り、RichEditベースに作り直された。
メモ帳は 「社畜ドザーのvi」 と揶揄された頃の、かつての素朴なメモ帳ではなくなった。
これがちょうどAIブームでMarkdown が脚光を浴びるタイミング より数年早く、微妙にズレた
今回のMarkdown対応はそのうえにのせた 「オマケトッピング」でしかない
致命的なのはMarkdown機能におけるステータスバーのトグル。
これは「同じプレーンテキストソースの見た目だけ替えるビュー切替」ではなく、
内部でMarkdown ⇄ RichEdit の双方向コンバータを回す“翻訳(round-trip conversion)”
テーブルや複雑なネストを書こうものならトグルを押すたびにマッピング不能 → 警告ダイアログが登場。
(未対応であれば、警告など出さずに単純にプレーンテキストのまま表示すれば良いだけ)
コレがゴミでなくて一体何なのか
メモ帳(Notepad) は WordPad の“穴埋め”として肥大化し、
そこへオマケ程度にMarkdownっぽい機能を付け焼き刃したところ、
AIブームでMarkdown が脚光を浴びたタイミングと重なり、期待値に対して失望感が圧倒的
一度投稿したうえで別タブを開いてプログラム的(fetch)に送信してその別タブが閉じられる仕組み。
// ==UserScript== // @namePGP未署名検出と別タブ自動編集 // @namespacehttp://tampermonkey.net/ // @version 1.0 // @descriptionPGP署名がない投稿を自動編集ページへ誘導 // @matchhttps://anond.hatelabo.jp/* // @grantGM_setValue // @grantGM_getValue // @grantGM.openInTab // ==/UserScript== (function () { 'use strict';constbody = document.getElementById('entry-page'); if (!body) return;consttitleText = document.title; if (!titleText.includes('dorawii')) return;constpgpRegex = /BEGIN.*PGP(?: SIGNEDMESSAGE| SIGNATURE)?/;const preElements = document.querySelectorAll('div.body pre'); let hasPgpSignature =false; for (const pre of preElements) { if (pgpRegex.test(pre.textContent)) { hasPgpSignature =true; break; } } if (hasPgpSignature) return;const editLink = document.querySelector('a.edit');const childTab =GM.openInTab(editLink.href, {active:false, insert:true,setParent:true }); })();
// ==UserScript== // @name編集ページ処理と自動送信・閉じ // @namespacehttp://tampermonkey.net/ // @version 1.0 // @description編集ページで署名処理と送信、タブ自動閉じ // @matchhttps://anond.hatelabo.jp/dorawii_31/edit?id=* // @grantGM_getValue // @grantGM_xmlhttpRequest // @grantGM_setClipboard // @grantGM_notification // @connectlocalhost // ==/UserScript== (async function () { 'use strict';const shouldRun = awaitGM_getValue('open-tab-for-edit', '0');consttextareaId = 'text-body';consttextarea = document.getElementById(textareaId); if (!textarea) return;const content =textarea.value;constpgpSignatureRegex = /-----BEGINPGP SIGNEDMESSAGE-----[\s\S]+?-----BEGINPGP SIGNATURE-----[\s\S]+?-----ENDPGP SIGNATURE-----/; if (pgpSignatureRegex.test(content)) {console.log('[PGPスクリプト]署名が検出されたためそのまま送信します'); return; }consthttpRequest = (url, data) => { return newPromise((resolve,reject) => {GM_xmlhttpRequest({ method: 'POST',url:url, headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, data: `value=${encodeURIComponent(data)}`,onload: function (response) { resolve(response.responseText); },onerror: function (error) {reject(error); } }); }); }; //textarea の値を取得 // 1.現在のページのURLからURLオブジェクトを作成const currentUrl = newURL(window.location.href); // 2.ベースとなる部分 (例: "https://anond.hatelabo.jp") を取得constorigin = currentUrl.origin; // 3. 'id'パラメータの値 (例: "20250610184705") を取得constidValue = currentUrl.searchParams.get('id'); // 4.ベース部分とIDを結合して、目的のURL文字列を生成 //idValueが取得できた場合のみ実行する let newUrl = null; if (idValue) { newUrl = `${origin}/${idValue}`; } // 5. 生成されたURLを変数に代入し、コンソールに出力して確認console.log(newUrl);constvalueToSend = newUrl;try {const signatureText = awaithttpRequest('http://localhost:12345/run-batch',valueToSend);console.log('バッチ応答:', signatureText); if (!signatureText.includes('BEGINPGP SIGNEDMESSAGE')) { alert('PGP署名がクリップボードに見つかりませんでした。'); return; }const newText = content.replace(/\s*$/, '') + '\n' + signatureText + '\n';textarea.value = newText;console.log('[PGPスクリプト]署名を貼り付けました。送信を再開します。');const form = document.forms.edit;const newForm = form.cloneNode(true); form.replaceWith(newForm); newForm.addEventListener('submit', async (e) => { e.preventDefault(); //HTML標準のsubmitをキャンセルconstbodyText =textarea?.value || ''; //reCAPTCHAトークンの取得constrecaptchaToken = await newPromise((resolve) => { grecaptcha.enterprise.ready(() => { grecaptcha.enterprise.execute('hoge', {action: 'EDIT' }) .then(resolve); }); }); // POSTするデータの構築const formData = new FormData(newForm); formData.set('body',bodyText); formData.set('recaptcha_token',recaptchaToken); formData.set('edit', '1');try {constresponse = await fetch(newForm.action, { method: 'POST',body: formData, credentials: 'same-origin' }); if (response.ok) {console.log('送信成功'); window.close(); } else {console.error('送信失敗',response.status); } }catch (err) {console.error('送信中にエラーが発生', err); } }); //プログラム的に送信トリガー newForm.dispatchEvent(new Event('submit', { bubbles:true })); }catch (e) {console.error('バッチ呼び出し失敗:', e); } })();
consthttp =require('http');const { exec } =require('child_process');const querystring =require('querystring');const server =http.createServer((req, res) => { if (req.method === 'GET' && req.url === '/ping') { res.writeHead(200); res.end('pong'); } else if (req.method === 'POST' && req.url === '/run-batch') { letbody = ''; req.on('data', chunk => {body += chunk.toString(); }); req.on('end', () => {constparsed = querystring.parse(body);constvalue =parsed.value || 'default'; // 値を引数としてバッチに渡す exec(`C:\\Users\\hoge\\Desktop\\makesign.bat "${value}"`, { encoding: 'utf8' }, (err, stdout, stderr) => { if (err) { res.writeHead(500); res.end('Error executing batch: ' + stderr); } else { res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' }); res.end(stdout.trim()); } }); }); } else { res.writeHead(404); res.end('Not found'); }});server.listen(12345, () => {console.log('Batch serverrunningathttp://localhost:12345/');});
@echo offsetlocal enabledelayedexpansion::署名するファイル名set "infile=%~1"set outfile=%TEMP%\pgp_output.asc:: 以前の出力があれば削除if exist "%outfile%" del "%outfile%":signloop::AutoHotkeyでパスフレーズ入力(gpgがパスワード要求するダイアログが出た場合に備える)start "" /b "C:\Users\hoge\Documents\AutoHotkey\autopass.ahk"::PGPクリア署名を作成echo %infile% | gpg --yes --clearsign --output "%outfile%"::署名が成功していればループを抜けるif exist "%outfile%" (goto postprocess) else ( timeout /t 1> nulgoto signloop):postprocesspowershell -nologo -command ^ "$header = '>|'; $footer = '|<'; $body =Get-Content '%outfile%' -Raw;Write-Output ($header + \"`r`n\" + $body + $footer)"powershell -nologo -command ^ "$header = '>|'; $footer = '|<'; $body =Get-Content 'signed.asc' -Raw;Set-Clipboard -Value ($header + \"`r`n\" + $body + $footer)"endlocalexit /b
#Persistent#SingleInstance ignoreSetTitleMatchMode, 2WinWaitActive, pinentrySendInputpasswordSleep 100SendInput {Enter}ExitApp
動けばいいという考えで作っているので余分なコードも含んでいるかもしれない。
-----BEGINPGP SIGNEDMESSAGE-----Hash: SHA512https://anond.hatelabo.jp/20250613185036 -----BEGINPGP SIGNATURE-----iHUEARYKAB0WIQTEe8eLwpVRSViDKR5wMdsubs4+SAUCaEv1FQAKCRBwMdsubs4+SHHkAQDUOLgBcdji2T6MJ7h/vlMdFfGlWAzNdXijjE1gIuEPywEAiMNMZqhrMmtlc7UqRuggNJ/UTa5xTIcKp622+7jJQQg==Lgkl-----ENDPGP SIGNATURE-----
ようやく(ほぼ)すべてが自動化された。
あとはローカルサーバーの起動をスタートアップに設定する(方法をAIに聞いて指示に従う)だけの消化試合。
署名時要求してくるパスワードを自動入力するahkファイルはドキュメントのAutoHotkey配下に置いた。
バッチファイル(make.sign.bat)はデスクトップに置いた。
#Persistent#SingleInstance ignoreSetTitleMatchMode, 2WinWaitActive, pinentrySendInput お前のパスワードSleep 100SendInput {Enter}ExitApp
//run-batch-server.jsconsthttp =require('http');const { exec } =require('child_process');const server =http.createServer((req, res) => { if (req.url === '/ping') { res.writeHead(200); res.end('pong'); } else if (req.url === '/run-batch') { exec('C:\\Users\\you\\Desktop\\makesign.bat', (err) => { res.writeHead(200); res.end(err ? 'Error' : 'OK'); }) ; } else { res.writeHead(404); res.end('Not found'); }});server.listen(12345, () => {console.log('Batch serverrunningathttp://localhost:12345/');});
@echo offsetlocal enabledelayedexpansion::ミリ秒単位のUTC時刻を取得for /f %%a in ('powershell -nologo -command "[int64]::Parse((Get-Date).ToUniversalTime().ToString('yyyyMMddHHmmssfff'))"') doset timestamp=%%a::署名するファイル名set infile=%TEMP%\pgp_input.txtset outfile=%TEMP%\pgp_output.asc:: 以前の出力があれば削除if exist "%outfile%" del "%outfile%"::タイムスタンプを原文として保存echo %timestamp%> "%infile%":signloop::AutoHotkeyでパスフレーズ入力(gpgがパスワード要求するダイアログが出た場合に備える)start "" /b "C:\Users\infini\Documents\AutoHotkey\autopass.ahk"::PGPクリア署名を作成gpg --yes --clearsign --output "%outfile%" "%infile%"::署名が成功していればループを抜けるif exist "%outfile%" (echo [INFO]署名成功goto postprocess) else (echo [WARN]署名失敗、再試行します… timeout /t 1> nulgotosignloop):postprocess::PowerShellで余計な改行なしに |< をつけてクリップボードにコピーpowershell -nologo -command ^ "$header = '>|'; $footer = '|<'; $body =Get-Content '%outfile%' -Raw;Set-Clipboard -Value ($header + \"`r`n\" + $body + $footer)"echo Done.signed.asc created and clipboard updated (no extra blankline).endlocalexit /b
// ==UserScript==// @namePGP署名自動付加スクリプト(GM_xmlhttpRequest版)// @namespacehttp://tampermonkey.net/// @version 1.0// @description投稿前にPGP署名を付けてから送信(fetch未使用)// @matchhttps://anond.hatelabo.jp/dorawii_31/edit*// @grant GM_xmlhttpRequest// @grant GM_setClipboard// @grant GM_notification// / @connectlocalhost// ==/UserScript==(function () { 'use strict';const submitId = 'submit-button';consttextareaId = 'text-body';const localServer = 'http://localhost:12345/run-batch';constpgpSignatureRegex = /-----BEGINPGPSIGNEDMESSAGE-----[\s\S]+?-----BEGINPGPSIGNATURE-----[\s\S]+?-----ENDPGPSIGNATURE-----/;consthttpRequest = (url) => { return newPromise((resolve,reject) => { GM_xmlhttpRequest({ method: 'GET',url:url, onload: function (response) { resolve(response.responseText); }, onerror: function (error) {reject(error); } }); }); };const interceptClick = () => {constbtn = document.getElementById(submitId); if (!btn ||btn.dataset.pgpIntercepted === 'true') return;btn.dataset.pgpIntercepted = 'true';btn.addEventListener('click', async function (e) {consttextarea = document.getElementById(textareaId); if (!textarea) return;const content =textarea.value; if (pgpSignatureRegex.test(content)) {console.log('[PGPスクリプト]署名が検出されたためそのまま送信します'); return; } e.preventDefault(); e.stopImmediatePropagation();console.log('[PGPスクリプト]署名が見つからないため処理を停止し、署名を取得します');try { awaithttpRequest(localServer); //バッチ実行constsignatureText = await navigator.clipboard.readText(); if (!signatureText.includes('BEGINPGPSIGNEDMESSAGE')) { alert('PGP署名がクリップボードに見つかりませんでした。'); return; }const newText = content.replace(/\s*$/, '') + '\n' +signatureText + '\n';textarea.value = newText;console.log('[PGPスクリプト]署名を貼り付けました。送信を再開します。');btn.click(); //イベント再発火 }catch (err) { alert('PGP署名の取得または貼り付けに失敗しました。\n' + err); } },true); }; window.addEventListener('load', () => {setTimeout(interceptClick, 1000); });})();
プロミスメソッドとか全然まだ理解してなくてそのなかに関数代入したその関数にオブジェクトのプロパティにresponseを?いやまあそのあたりのコードが示すデータの流れが全然理解できないような人間でもここまでできちゃった。
AIすごいなと思うよ。そして思うのは今後重要になってくるのは文法とか自体に詳しいことじゃなくて、そのプログラムの処理内容を指示できるシステムエンジニア的な言語化能力のほうじゃないかなと思った。
-----BEGINPGPSIGNEDMESSAGE-----Hash: SHA51220250609111559680 -----BEGINPGPSIGNATURE-----iHUEARYKAB0WIQTEe8eLwpVRSViDKR5wMdsubs4+SAUCaEbCbwAKCRBwMdsubs4+SLueAPwOv7PBk4voAe5qlcCEvs/PJhmKc5QAb/1R43JMQFuDZgD/UTPEKsL/PhK9jFGv2HDXK1dVjLNwvosgX9uYJh5xxwY==qiOE-----ENDPGPSIGNATURE-----
主に海外圏のユーザーが利用する課金サイトでUID指定で課金を代行できるサイトがある。
これを利用して配信者のID宛に最低価格の課金を散発的に行うことで、ストーリー中であろうと創世結晶(石)獲得を知らせる全画面モーダルダイアログが出るため、閲覧や操作を妨げることができる。
海外の文化圏ではギフトとして配信者に石をプレゼントする意図で行われることもあるようで、有名配信者に突如まとまった石が贈られることはこれまでも見られた。
だが今回確認されたものは明らかに妨害の意図のある贈り方で、その日本の配信者は困り果てて配信の中断を余儀なくされてしまった。
しかも大型ストーリーイベントの最終日の駆け込み配信だったので悪質で、配信日を改めることもできず残念な事態となった。
もちろん配信していない時も常にこうした妨害は受ける可能性がある。
こうした荒らし行為が可能になってしまっているのは原神側の仕様にも問題がある。
・贈答石の場合自動で即時受領されてしまうためにモーダルの表示タイミングを制御できない
・仮にメールで手動受領する仕様に変更したとしても散発石爆撃に対してはメール通知音のOFF設定も必要になりそう
・UIDを隠すことが難しい仕様になっている (右下を隠してもEscメニューで見えてしまい、隠す設定もないため、過去配信を漁ればバレる)
・この状況下でUID指定のチャージ方法(API?)が第三者の決済業者に提供されており公認されている
こうした仕様になっているのは他のHoYoverseタイトルでも同様であり、似たような被害が発生する可能性がある。
解決には運営側が動かないといけないので、ホヨバゲープレイヤーで配信を見る/するタイプの人はアンケート時に覚えていたら書いてほしい。
ファイルの中身をメモリーにおいていいなら、そこまで難しくはないな。
スクロールやキャレットの画面外の移動の時だけ、レイアウト行を構築すればそれでおしまい。
http://s170199.ppp.asahi-net.or.jp/vivi/docs/buffer/edit_buffer.php
ViViエディターの人の記事が書いているような複雑怪奇なバッファー管理はいらない。
メモリーを32GBぐらい積んでいれば、ギャップバッファーでも1GB未満の大きさのファイルの読み書きは簡単にできる。
自作のエディタでも900MBを12秒ぐらいで読み込むことができた。
ただ、この機能を実装すると行ジャンプのダイアログを出したときに最大行数がわからなくなる。
まともに使いたいなら、ちょっと考え方を変えないと駄目だ。
1GBを超えると何かしらの制限に引っ掛かる。
EmEditorや鈴川エディタ、巨大ファイル対応ログビュアーなど巨大ファイルを扱えるエディターはマジすごい。
最低賃金のウェブプログラマー兼雑用で、大学受験に落ちた俺にはこれが限界…。
自作のエディターでつかってるgap_vectorもどこかから拾ってきたやつで、スクラッチで書いたわけではない。
こんなことなら、きちんと数学IIICを勉強して情報系の大学に行けるようにするべきだった。
大学に入るためには教科書の基礎問題だけでなく、応用問題みたいな知識の使い方を問う問題まで解けるように努力すべきだったorz
【感想】
↓
↓
↓
ボールペンで記入
↓
↓
↓
↓
この流れなんなん?誰がうれしいの?
【やったこと詳細】
・「通知書等」をクリックする
・「通知書等選択」プルダウンから「住宅借入金等特別控除証明書」を選択する
・「切替」をクリックする
・表示された表の「令和6年分」あたりをクリックする
・「この「年末調整のための住宅借入金等特別控除証明書」を印刷したものは使用できません。」の文言を見つけて絶望する
・「QRコード付証明書等作成システム」でGoogle検索する
・「QRコード付証明書等作成システムについて」ページにたどり着く
・「環境チェック」モーダルのブラウザ欄の「推奨環境外です」の表示に絶望する
・Safariで開き直す
・Macintoshをご利用の方の「事前準備セットアップ(Macintosh/safari用(dmg形式:約2MB)」をクリックする
・ダウンロードフォルダの「cpsMac.dmg」をダブルクリックする
・QRInstall.pkgをダブルクリックする
・「アクセス許可を要求しています」ダイアログで「許可」をクリックする
・「Safariブラウザが起動されているため、インストールを完了することができませんでした」の表示に絶望する
・「ゴミ箱に入れますか?」で「残す」をクリックする(危ないやろこれ)
・Safariを終了して再びインストーラーを起動してインストール完了する
・「QRコード付証明書等作成システムについて」ページを表示する
・「環境チェック」モーダルのブラウザ欄の△表示を無視する(Safari 18.0は対象外らしい)
・「次へ」をクリックする
・e-Taxからダウンロードしておいた「令和6年分住宅借入金等特別控除証明書_2024mmdd.xml」をアップロードする
・PDF作成が完了しましたダイアログの「表示」をクリックする
・「2年目以降の住宅ローン控除(住宅借入金等特別控除)の申告はありますか?」で「はい」を選択し「次へ」をクリックする
・「直接入力する(自動計算の対象外)」を選択して「次へ」をクリックする
・「住宅借入金等特別控除区分」で「◯年中居住者・認定住宅(等)用」を選択する
・アッ、これ(住宅借入金等特別控除申告書)、自分で計算してボールペンで書かないといかんの?
・ボールペンで書いた
・画像をアップロードしようとするがHEICなので選択できない
・Preview> File> ExportからPNGに変換する
・アップロードするが「ファイルサイズは最大5MBです」エラーになる
・Preview> File> ExportからJPEGに変換する
次回「証券番号がわからない」「保険料控除証明書の電子ファイル(XMLファイル)取得に1日待たされる」
ぜってぇ見てくれよな!!!
Permalink |記事への反応(13) | 17:48