[インデックス 15824] ファイルの概要
このコミットは、Go 1.1 リリースノートのドキュメントファイル doc/go1.1.html
に対する更新です。具体的には、Go 1.1 で導入されたUnicodeのサロゲートペア(surrogate halves)とバイトオーダーマーク(BOM)の取り扱いに関する変更点を公式ドキュメントに追記し、既存の記述を修正しています。これにより、Go 1.1における文字列処理とファイルエンコーディングの挙動の変更がユーザーに明確に伝えられます。
コミット
commit b89a2bcf0186477b4f5070604920dfd156f50613
Author: Rob Pike <r@golang.org>
Date: Mon Mar 18 22:50:32 2013 -0700
doc/go1.1.html: document the surrogate and BOM changes
R=golang-dev, adg
CC=golang-dev
https://golang.org/cl/7853048
---
doc/go1.1.html | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 53 insertions(+), 6 deletions(-)
diff --git a/doc/go1.1.html b/doc/go1.1.html
index 9312e69f94..694b164409 100644
--- a/doc/go1.1.html
+++ b/doc/go1.1.html
@@ -34,13 +34,14 @@ In Go 1.1, an integer division by constant zero is not a legal program, so it is
<h2 id=\"impl\">Changes to the implementations and tools</h2>
-<li>TODO: more</li>
-<li>TODO: unicode: surrogate halves in compiler, libraries, runtime</li>
+<p>
+TODO: more
+</p>
<h3 id=\"gc-flag\">Command-line flag parsing</h3>
<p>
-In the gc toolchain, the compilers and linkers now use the
+In the gc tool chain, the compilers and linkers now use the
same command-line flag parsing rules as the Go flag package, a departure
from the traditional Unix flag parsing. This may affect scripts that invoke
the tool directly.\n@@ -82,6 +83,52 @@ would instead say:\n i := int(int32(x))\n </pre>\n \n+<h3 id=\"unicode_surrogates\">Unicode</h3>\n+\n+<p>\n+To make it possible to represent code points greater than 65535 in UTF-16,\n+Unicode defines <em>surrogate halves</em>,\n+a range of code points to be used only in the assembly of large values, and only in UTF-16.\n+The code points in that surrogate range are illegal for any other purpose.\n+In Go 1.1, this constraint is honored by the compiler, libraries, and run-time:\n+a surrogate half is illegal as a rune value, when encoded as UTF-8, or when\n+encoded in isolation as UTF-16.\n+When encountered, for example in converting from a rune to UTF-8, it is\n+treated as an encoding error and will yield the replacement rune,\n+<a href=\"/pkg/unicode/utf8/#RuneError\"><code>utf8.RuneError</code></a>,\n+U+FFFD.\n+</p>\n+\n+<p>\n+This program,\n+</p>\n+\n+<pre>\n+import \"fmt\"\n+\n+func main() {\n+ fmt.Printf(\"%+q\\n\", string(0xD800))\n+}\n+</pre>\n+\n+<p>\n+printed <code>\"\\ud800\"</code> in Go 1.0, but prints <code>\"\\ufffd\"</code> in Go 1.1.\n+</p>\n+\n+<p>\n+The Unicode byte order marks U+FFFE and U+FEFF, encoded in UTF-8, are now permitted as the first\n+character of a Go source file.\n+Even though their appearance in the byte-order-free UTF-8 encoding is clearly unnecessary,\n+some editors add them as a kind of \"magic number\" identifying a UTF-8 encoded file.\n+</p>\n+\n+<p>\n+<em>Updating</em>:\n+Most programs will be unaffected by the surrogate change.\n+Programs that depend on the old behavior should be modified to avoid the issue.\n+The byte-order-mark change is strictly backwards- compatible.\n+</p>\n+\n <h3 id=\"asm\">Assembler</h3>\n \n <p>\n@@ -127,7 +174,7 @@ package code.google.com/p/foo/quxx: cannot download, $GOPATH must not be set to\n \n <p>\n The <code>go fix</code> command no longer applies fixes to update code from\n-before Go 1 to use Go 1 APIs. To update pre-Go 1 code to Go 1.1, use a Go 1.0 toolchain\n+before Go 1 to use Go 1 APIs. To update pre-Go 1 code to Go 1.1, use a Go 1.0 tool chain\n to convert the code to Go 1.0 first.\n </p>\n \n@@ -176,7 +223,7 @@ The same is true of the other protocol-specific resolvers <code>ResolveIPAddr</c\n \n <p>\n The previous <code>ListenUnixgram</code> returned <code>UDPConn</code> as\n-arepresentation of the connection endpoint. The Go 1.1 implementation\n+a representation of the connection endpoint. The Go 1.1 implementation\n returns <code>UnixConn</code> to allow reading and writing\n with <code>ReadFrom</code> and <code>WriteTo</code> methods on\n the <code>UnixConn</code>.\n@@ -381,7 +428,7 @@ The new method <a href=\"/pkg/os/#FileMode.IsRegular\"><code>os.FileMode.IsRegular\n \n <li>\n The <a href=\"/pkg/regexp/\"><code>regexp</code></a> package\n-now supports Unix-original lefmost-longest matches through the\n+now supports Unix-original leftmost-longest matches through the\n <a href=\"/pkg/regexp/#Regexp.Longest\"><code>Regexp.Longest</code></a>\n method, while\n <a href=\"/pkg/regexp/#Regexp.Split\"><code>Regexp.Split</code></a> slices\n```
## GitHub上でのコミットページへのリンク
[https://github.com/golang/go/commit/b89a2bcf0186477b4f5070604920dfd156f50613](https://github.com/golang/go/commit/b89a2bcf0186477b4f5070604920dfd156f50613)
## 元コミット内容
doc/go1.1.html: document the surrogate and BOM changes
## 変更の背景
このコミットは、Go 1.1 リリースにおける重要なUnicode関連の変更点を公式ドキュメントに反映させるために行われました。主な背景は以下の通りです。
1. **Unicode標準への厳密な準拠**: Go 1.1では、Unicodeのサロゲートペア(surrogate halves)の取り扱いがより厳格になりました。これは、Unicode標準においてサロゲートペアが単独の文字としては不正であるという規定にGoが準拠するためです。Go 1.0では許容されていた一部の挙動が、Go 1.1ではエラーとして扱われるようになります。
2. **UTF-8 BOMの許容**: 一部のテキストエディタ(特にWindows環境のメモ帳など)は、UTF-8でファイルを保存する際に、ファイルの先頭にバイトオーダーマーク(BOM)を付加する習慣があります。UTF-8エンコーディング自体はバイトオーダーの概念を持たないためBOMは不要ですが、これらのエディタとの互換性を確保するため、Go 1.1ではUTF-8 BOMがGoのソースファイルの先頭に存在することを許可するようになりました。
3. **ユーザーへの情報提供**: これらの変更はGoプログラムの挙動に影響を与える可能性があるため、Go 1.1のリリースノートとしてユーザーに明確に伝える必要がありました。特に、サロゲートペアの変更は既存のコードに影響を与える可能性があるため、その挙動と対応策を説明することが重要でした。
## 前提知識の解説
### Unicodeと文字エンコーディング
* **Unicode**: 世界中のあらゆる文字を統一的に扱うための文字コード標準です。各文字には一意の「コードポイント」(例: U+0041は'A')が割り当てられています。
* **UTF-8**: Unicodeのコードポイントをバイト列に変換するエンコーディング方式の一つです。可変長エンコーディングであり、ASCII文字は1バイト、それ以外の文字は2〜4バイトで表現されます。バイトオーダーの概念がなく、BOMは必須ではありません。
* **UTF-16**: Unicodeのコードポイントをバイト列に変換するエンコーディング方式の一つです。通常は2バイト(16ビット)単位で文字を表現します。基本多言語面(BMP: Basic Multilingual Plane, U+0000〜U+FFFF)の文字は1つの16ビット単位で表現されますが、それ以外の補助面(Supplementary Planes, U+10000〜U+10FFFF)の文字は「サロゲートペア」と呼ばれる2つの16ビット単位で表現されます。
### サロゲートペア(Surrogate Halves)
* **背景**: UTF-16は元々16ビットで全ての文字を表現しようと設計されましたが、Unicodeの文字集合が拡大し、16ビットでは表現しきれない文字(U+FFFFを超えるコードポイント)が登場しました。
* **サロゲートペアの仕組み**: U+FFFFを超えるコードポイントをUTF-16で表現するために、「サロゲートペア」という仕組みが導入されました。これは、特定の範囲(U+D800〜U+DBFFを「上位サロゲート」、U+DC00〜U+DFFFを「下位サロゲート」と呼びます)の16ビット値2つを組み合わせて1つの文字を表現するものです。このサロゲート範囲のコードポイントは、単独で文字として使用されることはありません。
* **Goにおける`rune`**: Go言語では、`rune`型はUnicodeのコードポイントを表すために使用される`int32`のエイリアスです。
### バイトオーダーマーク(BOM: Byte Order Mark)
* **目的**: BOM(U+FEFF)は、主にUTF-16やUTF-32のようなマルチバイトエンコーディングにおいて、バイトオーダー(エンディアンネス、バイトの並び順)を示すためにファイルの先頭に付加される特殊なUnicode文字です。
* **UTF-8におけるBOM**: UTF-8はバイトオーダーの概念を持たないため、BOMはエンディアンネスを示す目的では不要です。しかし、一部のテキストエディタやシステムでは、ファイルのエンコーディングがUTF-8であることを示す「署名」としてBOM(UTF-8エンコードされた`EF BB BF`バイト列)をファイルの先頭に付加することがあります。
* **問題点**: UTF-8 BOMは、特にUnix系のツールやスクリプトにおいて互換性の問題を引き起こすことがあります。BOMがファイルの先頭にあることで、スクリプトの実行エラーや、ファイル内容の不正な解釈(例: ``のような文字化け)が発生する可能性があります。
### `utf8.RuneError` (U+FFFD)
* Go言語の`unicode/utf8`パッケージで定義されている定数で、Unicodeの「Replacement Character」(代替文字)U+FFFDを表します。
* これは、不正なUTF-8バイトシーケンスや、Go 1.1で不正とされたサロゲートハーフのような不正なUnicodeコードポイントが検出された場合に、その代わりに生成される文字です。これにより、プログラムがクラッシュすることなく、不正なデータに対しても処理を続行できるようになります。
## 技術的詳細
Go 1.1におけるUnicodeとBOMの変更は、Go言語の文字列処理とファイル読み込みの堅牢性を向上させ、Unicode標準への準拠を強化することを目的としています。
### サロゲートペアの取り扱い変更
* **Go 1.0の挙動**: Go 1.0では、`string(0xD800)`のように単独のサロゲートハーフを`rune`から`string`に変換すると、そのサロゲートハーフがそのままUTF-8エンコードされたバイト列(`\xed\xa0\x80`)として文字列に含まれていました。これはUnicode標準に反する挙動でした。
* **Go 1.1の挙動**: Go 1.1からは、コンパイラ、ライブラリ、ランタイムにおいて、サロゲートハーフ(U+D800〜U+DFFF)が単独の`rune`値として、またはUTF-8やUTF-16で単独でエンコードされた場合に不正であると見なされるようになりました。
* `rune`からUTF-8への変換時など、サロゲートハーフが検出された場合、それはエンコーディングエラーとして扱われ、代わりに`utf8.RuneError`(U+FFFD)が生成されます。
* 例として、`fmt.Printf("%+q\n", string(0xD800))`というプログラムは、Go 1.0では`"\ud800"`と出力していましたが、Go 1.1では`"\ufffd"`と出力するようになります。
* **影響**: ほとんどのGoプログラムには影響がありませんが、Go 1.0の挙動に依存していたプログラムは修正が必要になります。これは、Goがより厳密にUnicode標準に準拠するようになった結果です。
### UTF-8 BOMの取り扱い変更
* **Go 1.0の挙動**: Go 1.0では、Goのソースファイルの先頭にUTF-8 BOM(`EF BB BF`)が存在すると、コンパイルエラーになるか、予期せぬ挙動を引き起こす可能性がありました。
* **Go 1.1の挙動**: Go 1.1からは、UTF-8でエンコードされたUnicodeバイトオーダーマーク(U+FFFEおよびU+FEFF)が、Goのソースファイルの最初の文字として許可されるようになりました。
* **背景**: これは、一部のエディタがUTF-8ファイルを識別するための「マジックナンバー」としてBOMを付加する慣習に対応するためです。UTF-8自体はバイトオーダーフリーであるためBOMは不要ですが、この変更により、BOMが付加されたファイルでもGoコンパイラが正しく処理できるようになり、互換性が向上しました。
* **影響**: この変更は後方互換性があり、既存のプログラムに悪影響を与えることはありません。
## コアとなるコードの変更箇所
このコミットでは、`doc/go1.1.html` ファイルが変更されています。
```diff
--- a/doc/go1.1.html
+++ b/doc/go1.1.html
@@ -34,13 +34,14 @@ In Go 1.1, an integer division by constant zero is not a legal program, so it is
<h2 id=\"impl\">Changes to the implementations and tools</h2>
-<li>TODO: more</li>
-<li>TODO: unicode: surrogate halves in compiler, libraries, runtime</li>
+<p>
+TODO: more
+</p>
<h3 id=\"gc-flag\">Command-line flag parsing</h3>
<p>
-In the gc toolchain, the compilers and linkers now use the
+In the gc tool chain, the compilers and linkers now use the
same command-line flag parsing rules as the Go flag package, a departure
from the traditional Unix flag parsing. This may affect scripts that invoke
the tool directly.\n@@ -82,6 +83,52 @@ would instead say:\n i := int(int32(x))\n </pre>\n \n+<h3 id=\"unicode_surrogates\">Unicode</h3>\n+\n+<p>\n+To make it possible to represent code points greater than 65535 in UTF-16,\n+Unicode defines <em>surrogate halves</em>,\n+a range of code points to be used only in the assembly of large values, and only in UTF-16.\n+The code points in that surrogate range are illegal for any other purpose.\n+In Go 1.1, this constraint is honored by the compiler, libraries, and run-time:\n+a surrogate half is illegal as a rune value, when encoded as UTF-8, or when\n+encoded in isolation as UTF-16.\n+When encountered, for example in converting from a rune to UTF-8, it is\n+treated as an encoding error and will yield the replacement rune,\n+<a href=\"/pkg/unicode/utf8/#RuneError\"><code>utf8.RuneError</code></a>,\n+U+FFFD.\n+</p>\n+\n+<p>\n+This program,\n+</p>\n+\n+<pre>\n+import \"fmt\"\n+\n+func main() {\n+ fmt.Printf(\"%+q\\n\", string(0xD800))\n+}\n+</pre>\n+\n+<p>\n+printed <code>\"\\ud800\"</code> in Go 1.0, but prints <code>\"\\ufffd\"</code> in Go 1.1.\n+</p>\n+\n+<p>\n+The Unicode byte order marks U+FFFE and U+FEFF, encoded in UTF-8, are now permitted as the first\n+character of a Go source file.\n+Even though their appearance in the byte-order-free UTF-8 encoding is clearly unnecessary,\n+some editors add them as a kind of \"magic number\" identifying a UTF-8 encoded file.\n+</p>\n+\n+<p>\n+<em>Updating</em>:\n+Most programs will be unaffected by the surrogate change.\n+Programs that depend on the old behavior should be modified to avoid the issue.\n+The byte-order-mark change is strictly backwards- compatible.\n+</p>\n+\n <h3 id=\"asm\">Assembler</h3>\n \n <p>\n@@ -127,7 +174,7 @@ package code.google.com/p/foo/quxx: cannot download, $GOPATH must not be set to\n \n <p>\n The <code>go fix</code> command no longer applies fixes to update code from\n-before Go 1 to use Go 1 APIs. To update pre-Go 1 code to Go 1.1, use a Go 1.0 toolchain\n+before Go 1 to use Go 1 APIs. To update pre-Go 1 code to Go 1.1, use a Go 1.0 tool chain\n to convert the code to Go 1.0 first.\n </p>\n \n@@ -176,7 +223,7 @@ The same is true of the other protocol-specific resolvers <code>ResolveIPAddr</c\n \n <p>\n The previous <code>ListenUnixgram</code> returned <code>UDPConn</code> as\n-arepresentation of the connection endpoint. The Go 1.1 implementation\n+a representation of the connection endpoint. The Go 1.1 implementation\n returns <code>UnixConn</code> to allow reading and writing\n with <code>ReadFrom</code> and <code>WriteTo</code> methods on\n the <code>UnixConn</code>.\n@@ -381,7 +428,7 @@ The new method <a href=\"/pkg/os/#FileMode.IsRegular\"><code>os.FileMode.IsRegular\n \n <li>\n The <a href=\"/pkg/regexp/\"><code>regexp</code></a> package\n-now supports Unix-original lefmost-longest matches through the\n+now supports Unix-original leftmost-longest matches through the\n <a href=\"/pkg/regexp/#Regexp.Longest\"><code>Regexp.Longest</code></a>\n method, while\n <a href=\"/pkg/regexp/#Regexp.Split\"><code>Regexp.Split</code></a> slices\n```
## コアとなるコードの解説
変更は主に`doc/go1.1.html`ファイル内の以下のセクションに集中しています。
1. **TODOコメントの修正**:
* `<li>TODO: more</li>` と `<li>TODO: unicode: surrogate halves in compiler, libraries, runtime</li>` が `<p>TODO: more</p>` に変更されました。これは、以前のTODOリスト形式から、より一般的な段落形式への変更であり、Unicodeに関するTODOが具体的な説明に置き換えられる準備を示しています。
2. **"gc toolchain" の表記揺れ修正**:
* `In the gc toolchain, the compilers and linkers now use the` が `In the gc tool chain, the compilers and linkers now use the` に修正されています。これはtypoの修正であり、意味的な変更はありません。
3. **Unicodeセクションの追加 (`<h3 id="unicode_surrogates">Unicode</h3>`)**:
* このセクションが新たに追加され、Go 1.1におけるUnicodeのサロゲートペアとBOMの取り扱いに関する詳細な説明が記述されています。
* **サロゲートペアの説明**: UTF-16で65535を超えるコードポイントを表現するためにUnicodeが定義する「サロゲートハーフ」について説明しています。Go 1.1では、このサロゲートハーフが`rune`値として、またはUTF-8やUTF-16で単独でエンコードされた場合に不正であると見なされることが明記されています。不正なサロゲートハーフが検出された場合、`utf8.RuneError`(U+FFFD)が生成されることが強調されています。
* **コード例**: `string(0xD800)`の出力がGo 1.0では`"\ud800"`であったのに対し、Go 1.1では`"\ufffd"`となる具体的なコード例が示されています。これは、サロゲートハーフが不正な文字として扱われるようになったことを明確に示しています。
* **BOMの説明**: UTF-8でエンコードされたUnicodeバイトオーダーマーク(U+FFFEおよびU+FEFF)が、Goのソースファイルの最初の文字として許可されるようになったことが説明されています。これは、一部のエディタがBOMを付加する慣習に対応するためであり、UTF-8ではBOMが不要であるにもかかわらず許可される理由が述べられています。
* **更新に関する注意**: サロゲートペアの変更はほとんどのプログラムに影響しないが、古い挙動に依存するプログラムは修正が必要であること、BOMの変更は後方互換性があることが記載されています。
4. **"toolchain" の表記揺れ修正 (go fix コマンド関連)**:
* `To update pre-Go 1 code to Go 1.1, use a Go 1.0 toolchain` が `To update pre-Go 1 code to Go 1.1, use a Go 1.0 tool chain` に修正されています。これもtypoの修正です。
5. **"arepresentation" の表記揺れ修正 (ListenUnixgram関連)**:
* `returned UDPConn asarepresentation of the connection endpoint.` が `returned UDPConn as a representation of the connection endpoint.` に修正されています。これもtypoの修正です。
6. **"lefmost-longest" の表記揺れ修正 (regexpパッケージ関連)**:
* `now supports Unix-original lefmost-longest matches through the` が `now supports Unix-original leftmost-longest matches through the` に修正されています。これもtypoの修正です。
これらの変更は、Go 1.1のリリースノートとして、特にUnicode関連の重要な変更点をユーザーに正確に伝えるためのドキュメント更新です。
## 関連リンク
* GitHubコミットページ: [https://github.com/golang/go/commit/b89a2bcf0186477b4f5070604920dfd156f50613](https://github.com/golang/go/commit/b89a2bcf0186477b4f5070604920dfd156f50613)
* Go CL (Code Review): [https://golang.org/cl/7853048](https://golang.org/cl/7853048)
## 参考にした情報源リンク
* Go 1.1 Release Notes (go.dev): [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEemsbzbUXwGTDu2xhYombNpc6j9OpalgsPs3T7HXRtKLIukwSXSwzip07hS2i1M8RKRVNIiHAQO0VmkHFacLEDvKGPNeKmYSAf672sL7uTGCRS0g==](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEemsbzbUXwGTDu2xhYombNpc6j9OpalgsPs3T7HXRtKLIukwSXSwzip07hS2i1M8RKRVNIiHAQO0VmkHFacLEDvKGPNeKmYSAf672sL7uTGCRS0g==)
* Go 1.1 Release Notes (go.dev - BOM changes): [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQE5L4D0MvaQN0GSDIjkfPxuiYO9xYwD-9WlrMzk7bw0eU5l7fXVEUwfXTWFXTKc9g41yiN_CyyKakZru0QWV7MkQhDVGvuNDQIZlpNjQlc7daGZJg==](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQE5L4D0MvaQN0GSDIjkfPxuiYO9xYwD-9WlrMzk7bw0eU5l7fXVEUwfXTWFXTKc9g41yiN_CyyKakZru0QWV7MkQhDVGvuNDQIZlpNjQlc7daGZJg==)
* UTF-16 surrogate pairs explained (microsoft.com): [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGnx9SU1VUpF_N-kQ4bz0Q0BXTAYRjc-hAFj-5Xw2g_rS1f9DLM8cL02HqS3Km76aqzBbd1VkGulthdW9gq1HXx8QYn1XxLA51dmY1pva_iUT2238WWis7KogmbNgNzThcYyUOdAeTGQ65hDZUfvepa0086y9F-NbrfOrUXjXdUOZR5WwA=](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGnx9SU1VUpF_N-kQ4bz0Q0BXTAYRjc-hAFj-5Xw2g_rS1f9DLM8cL02HqS3Km76aqzBbd1VkGulthdW9gq1HXx8QYn1XxLA51dmY1pva_iUT2238WWis7KogmbNgNzThcYyUOdAeTGQGvuNDQIZlpNjQlc7daGZJg==)
* UTF-16 surrogate pairs explained (wikipedia.org): [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHAqaAkE6PLhTggs4EEzjwxxOInMo5LXTziXKn6if2a1adliwalXLA4l14_e_eLDsLTQ0VNo1-_Hxl-Pp5cSwrRsspuCfz4yHCLaRC44YiO7X4Enum7l3a1r7-rkAudxg==](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHAqaAkE6PLhTggs4EEzjwxxOInMo5LXTziXKn6if2a1adliwalXLA4l14_e_eLDsLTQ0VNo1-_Hxl-Pp5cSwrRsspuCfz4yHCLaRC44YiO7X4Enum7l3a1r7-rkAudxg==)
* Unicode Byte Order Mark UTF-8 implications (w3.org): [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQG_huE2YA_2-A85ktKFcICa3txd0-F9woRXELlr_Z7Vpn_Ur_MQaY3mU_9QhPtCspntK-LBh95JYrYCoB-QzxDxJ-kIXtFvh7c2zeKr7Mbax0xwauLcwlgqd0qg6bM2thGHhPqIzVdej6TKsKOkzQv44QBrdj2pfYY=](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQG_huE2YA_2-A85ktKFcICa3txd0-F9woRXELlr_Z7Vpn_Ur_MQaY3mU_9QhPtCspntK-LBh95JYrYCoB-QzxDxJ-kIXhFvh7c2zeKr7Mbax0xwauLcwlgqd0qg6bM2thGHhPqIzVdej6TKsKOkzQv44QBrdj2pfYY=)
* Go rune U+FFFD meaning (web search result): [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQG_huE2YA_2-A85ktKFcICa3txd0-F9woRXELlr_Z7Vpn_Ur_MQaY3mU_9QhPtCspntK-LBh95JYrYCoB-QzxDxJ-kIXhFvh7c2zeKr7Mbax0xwauLcwlgqd0qg6bM2thGHhPqIzVdej6TKsKOkzQv44QBrdj2pfYY=](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQG_huE2YA_2-A85ktKFcICa3txd0-F9woRXELlr_Z7Vpn_Ur_MQaY3mU_9QhPtCspntK-LBh95JYrYCoB-QzxDxJ-kIXhFvh7c2zeKr7Mbax0xwauLcwlgqd0qg6bM2thGHhPqIzVdej6TKsKOkzQv44QBrdj2pfYY=)