ドラフト ECMA-426 / 2025年11月13日
ソースマップ形式仕様
はじめに
本Ecma規格は、トランスパイルされたソースコードを元のソースへマッピングするためのソースマップ形式を定義します。
ソースマップ形式の目標は以下の通りです:
ソースレベルのデバッグをサポートし、双方向マッピングを可能にする
サーバーサイドのスタックトレースの難読化解除をサポートする
オリジナルソース マップ形式(v1)は、Closure
Inspectorで最適化されたJavaScriptコードのソースレベルのデバッグを可能にするためにJoseph
Schorrによって作成されました(この形式自体は言語非依存です)。しかし、ソースマップを利用するプロジェクトの規模が拡大するにつれて、フォーマットの冗長性が問題となり始めました。v2形式(Source Map Revision 2
Proposal )は、いくらかの単純さと柔軟性を犠牲にフォーマット全体のサイズを削減するために作成されました。v2による変更を踏まえても、ソースマップファイルサイズが有用性を制限していました。v3形式は、Pavel
Podivilov (Google) の提案に基づいています。
ソースマップ形式はもはやバージョン番号を持たず、常に "3" と固定されています。
2023~2024年にかけて、ソースマップ形式はより正確なEcma規格へと発展し、多くの人々の大きな貢献がありました。さらなるソースマップ形式の改良はTC39-TG4からも期待されています。
Asumu Takikawa、Nicolò Ribaudo、Jon Kuperman
ECMA-426 第1版 プロジェクト編集者
1 適用範囲
本規格は、JavaScript、WebAssembly、CSSへとコンパイルされたコードのデバッグ体験を向上させるために、様々な開発ツールが使用するソースマップ形式を定義します。
2 適合性
適合するソースマップ文書は、本仕様で詳述された構造に準拠したJSON文書です。
適合するソースマップ生成器は、適合するソースマップ文書を生成し、その生成物が本仕様のアルゴリズムで(オプションのものも含めて)エラーの報告なしにデコードできるようにするべきです。
適合するソースマップ消費者は、ソースマップ文書の取得(該当する場合)、およびデコードのために、本仕様で規定されたアルゴリズムを実装する必要があります。適合する消費者は、仕様がアルゴリズムにオプションでエラーを報告 できることを示している場合には、エラーを無視したり、終了せずに報告することが許されます。
3 参考文献
以下の文書は本文中で参照されており、その内容の一部または全体が本書の要求事項となる場合があります。発行日付きの参照については記載された版のみが適用されます。発行日なしの参照については、参照文書の最新の版(および修正版等)が適用されます。
3.1 標準文献
ECMA-262, ECMAScript® 言語仕様 .
https://tc39.es/ecma262/
ECMA-404, JSONデータ交換形式 .
https://www.ecma-international.org/publications-and-standards/standards/ecma-404/
3.2 参考文献(情報提供)
IETF RFC 4648, Base16, Base32, Base64 データエンコーディング .
https://datatracker.ietf.org/doc/html/rfc4648
WebAssembly コア仕様 .
https://www.w3.org/TR/wasm-core-2/
WHATWG Encoding .
https://encoding.spec.whatwg.org/
WHATWG Fetch .
https://fetch.spec.whatwg.org/
WHATWG Infra .
https://infra.spec.whatwg.org/
WHATWG URL .
https://url.spec.whatwg.org/
4 表記規約
この仕様は ECMA-262(表記規約)
で定義される表記規約に従い、本節で示す拡張を含みます。
4.1 アルゴリズム規約
4.1.1 暗黙の完了
この仕様で宣言されるすべての 抽象操作
は、アルゴリズムで宣言された戻り型を含む、正常完了 またはthrow完了 を返すものと暗黙的にみなされます。例えば、次のような抽象操作は:
4.1.1.1 GetTheAnswer ( input )
抽象操作GetTheAnswerは引数input (整数 )を受け取り、整数 を返します。
これは以下と同等です:
4.1.1.2 GetTheAnswer2 ( input )
抽象操作GetTheAnswer2は引数input (整数 )を受け取り、正常完了 を含む整数 、またはthrow完了 のいずれかを返します。
本仕様で完了レコード を返す抽象操作への呼び出しは、明示的にCompletion でラップされていない限り、暗黙的にReturnIfAbrupt マクロでラップされるものとします。例:
result にGetTheAnswer (value )を代入する。
second にCompletion (GetTheAnswer (value ))を代入する。
は以下と同等です:
result にReturnIfAbrupt (GetTheAnswer (value ))を代入する。
second にCompletion (GetTheAnswer (value ))を代入する。
4.1.2 オプションエラー
アルゴリズムがオプションでエラーを報告 する場合、実装は次のいずれかの挙動が選択できます:
アルゴリズムの残りを継続して実行する。
(たとえばブラウザコンソールで)ユーザーにエラーを報告し、アルゴリズムの残りを継続して実行する。
ThrowCompletion を返す。
実装はオプションエラーごとに異なる挙動を選択できます。
4.2 文法表記
この仕様はECMA-262(文法表記) で定義される文法表記慣習に従い、以下に記す留意点があります:
本仕様で定義される文法の終端記号は個々のコードポイントです。これはECMA-262の字句文法 に類似し、ECMA-262の構文文法 とは異なります。
本仕様は文法パラメータ や先読み制約 を使用せず、文法定義の複雑さを低減しています。
5 用語と定義
この文書の目的では、以下の用語と定義が適用されます。
生成コード
コンパイラまたはトランスパイラによって生成されたコード。
オリジナルソース
コンパイラやトランスパイラを通していないソースコード。
ソースマップURL
URL で生成コード からソースマップの場所を参照します。
カラム(column)
生成コード の行内で0始まりのインデックスを持つオフセット。JavaScriptとCSSのソースマップについてはUTF-16コード単位として、WebAssemblyソースマップについてはバイナリ内容(1行に表現)でのバイトインデックスとして算出します。
注
つまり"A"(LATIN CAPITAL LETTER A)は1コード単位、"🔥"(FIRE)は2コード単位で計測されます。他のコンテンツタイプのソースマップではこれと異なる場合があります。
6 base64 VLQ
base64 VLQ はbase64 でエンコードされた可変長数量 であり、最上位ビット(6ビット目)が継続ビットとして使われ、"数字"は文字列において下位から順にエンコードされ、最初の数字の最下位ビットが符号ビットとして使われます。
注1
base64
VLQエンコーディングで表現可能な値は、現時点では32ビット数量に制限されています(より大きな値の利用例が提示されるまで)。このため、32ビットを超える値は無効となり、実装はそれらを拒否する場合があります。符号ビットもこの制限に含まれますが、継続ビットは含みません。
注2
文字列"iB"は2つの数字からなるbase64
VLQを表します。最初の数字"i"はビットパターン0b100010をエンコードしており、これは継続ビットが1(VLQは継続)、符号ビットが0(非負)、値ビットが0b0001です。2つ目の数字Bはビットパターン0b000001をエンコードしており、継続ビットが0、符号ビットなし、値ビットが0b00001です。このVLQ文字列のデコード結果は数値17です。
注3
文字列"V"は1つの数字からなるbase64
VLQを表します。数字"V"はビットパターン0b010101をエンコードしており、継続ビットが0(継続なし)、符号ビットが1(負)、値ビットが0b1010です。このVLQ文字列のデコード結果は数値-10です。
base64 VLQは以下の字句文法に従います:
Vlq ::
VlqDigitList
VlqDigitList ::
TerminalDigit
ContinuationDigit
VlqDigitList
TerminalDigit ::
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
a
b
c
d
e
f
ContinuationDigit ::
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
0
1
2
3
4
5
6
7
8
9
+
/
6.1 VLQSignedValue
構文指示操作 VLQSignedValueは引数を取らず、整数 を返します。次の生成規則に対して分割定義されます:
Vlq :: VlqDigitList
unsigned に、VLQUnsignedValue (VlqDigitList )を代入する。
もしunsigned modulo 2 =
1なら、sign は-1とする。
それ以外なら、sign は1とする。
value にfloor (unsigned /
2)を代入する。
もしvalue が0かつsign が-1なら、-231 を返す。
もしvalue が231 以上なら、エラーを投げる。
sign × value を返す。
注
ステップ
6 のチェックは、
unsigned が
VLQUnsignedValue (
VlqDigitList )の値であり、
Vlq の値でないため必要です。
6.2 VLQUnsignedValue
構文指示操作 VLQUnsignedValueは引数を取らず非負の整数 を返します。次の生成規則に対して分割定義されます:
Vlq :: VlqDigitList
value に、VLQUnsignedValue (VlqDigitList )を代入する。
もしvalue が232 以上なら、エラーを投げる。
value を返す。
VlqDigitList ::
ContinuationDigit
VlqDigitList
left に、VLQUnsignedValue (ContinuationDigit )を代入する。
right に、VLQUnsignedValue (VlqDigitList )を代入する。
left + right × 25 を返す。
TerminalDigit ::
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
a
b
c
d
e
f
この生成規則によりマッチされた文字をdigit とする。
整数 であるdigit に対応する値を、IETF
RFC 4648で定義されるbase64 エンコーディングに従いvalue とする。
アサート :value < 32。
value を返す。
ContinuationDigit ::
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
0
1
2
3
4
5
6
7
8
9
+
/
この生成規則によりマッチされた文字をdigit とする。
整数 であるdigit に対応する値を、IETF
RFC 4648で定義されるbase64 エンコーディングに従いvalue とする。
アサート :32 ≤
value < 64。
value - 32を返す。
7 JSON値ユーティリティ
この仕様のアルゴリズムはECMA-262の内部仕様上で定義されていますが、非JavaScriptプラットフォームでも簡単に実装できるよう設計されています。本節では、JSON値 を扱うためのユーティリティを提供し、ECMA-262の詳細を抽象化します。
JSON値 は、JSONオブジェクト 、JSON配列 、文字列 、数値 、真偽値 、またはnull です。
JSONオブジェクト は、各プロパティについて:
JSON配列 は、以下の条件を満たすJSONオブジェクト です:
キーが"length" で値が数値 のプロパティを持つこと
他のすべてのプロパティのキーが整数インデックス であること
7.1 ParseJSON ( string )
抽象操作ParseJSONは引数string (文字列)を受け取り、JSON値 を返します。処理手順:
result にCall (%JSON.parse% ,
null , « string » )を代入する。
Assert :result はJSON値 であること。
result を返す。
編集者注
この抽象操作はECMA-262自体によって公開される予定です:
tc39/ecma262#3540
7.2 JSONObjectGet ( object , key )
抽象操作JSONObjectGetはobject (JSONオブジェクト )とkey (文字列)を受け取り、JSON値 またはmissing を返します。指定したkey に対応する値を返します。手順:
もしobject がkey の独自プロパティを持たない場合、missing を返す。
prop にobject のkey の独自プロパティを代入する。
prop の[[Value]] 属性を返す。
7.3 JSONArrayIterate ( array )
抽象操作JSONArrayIterateはarray (JSON配列 )を受け取り、List (JSON値 のリスト)を返します。「For
each」による反復用に全ての要素が入ったListを返します。手順:
length にJSONObjectGet (array ,
"length" )を設定する。
アサート :length は非負の整数値 である。
list に新しい空のList を設定する。
i に0を設定する。
i < ℝ (length ) の間繰り返す:
value にJSONObjectGet (array , ToString (𝔽 (i )))を設定する。
アサート :value はmissing でない。
value をlist に追加する。
i をi +1に設定する。
list を返す。
7.4 StringSplit ( string , separators )
抽象操作StringSplitはstring (文字列)、separators (文字列のList )を受け取り、区切り文字のいずれかで分割した部分文字列のList を返します。同時に複数の区切り文字が一致する場合は、separators で先に現れるものが優先されます。手順:
parts に新しい空のリスト を設定する。
strLen にstring の長さを設定する。
lastStart に0を設定する。
i に0を設定する。
i < strLen の間繰り返す:
matched にfalse を設定する。
separators の各String sep について:
sepLen にsep の長さを設定する。
candidate に、substring (string ,
i , min (i
+ sepLen , strLen )) を設定する。
もしcandidate =sep かつ
matched がfalse なら:
chunk にsubstring (string ,
lastStart , i ) を設定する。
chunk をparts に追加する。
lastStart にi + sepLen を設定する。
i にi + sepLen を設定する。
matched にtrue を設定する。
もしmatched がfalse なら、i にi + 1を設定する。
chunk にsubstring (string ,
lastStart , strLen ) を設定する。
chunk をparts に追加する。
parts を返す。
8 位置型
8.1 位置レコード
位置レコード は、非負の行番号と非負のカラム 番号からなるタプルです:
表1: 位置レコード のフィールド
8.2 元位置レコード
元位置レコード は、デコードソースレコード 、非負の行、非負のカラム 番号からなるタプルです。位置レコード に似ていますが、具体的なオリジナルソース ファイル上のソース位置を記述します。
表2: 元位置レコード のフィールド
8.3 ComparePositions ( first , second )
抽象操作ComparePositionsはfirst (位置レコード または元位置レコード )、second (同じ型)を受け取り、lesser 、equal 、またはgreater を返します。first がsecond より前か同じか後かによってそれぞれ返します。なお、元位置レコード の[[Source]] フィールドは無視されます。手順:
もしfirst .[[Line]] < second .[[Line]] であれば、lesser を返す。
もしfirst .[[Line]] > second .[[Line]] であれば、greater を返す。
アサート : first .[[Line]] はsecond .[[Line]] と等しい。
もしfirst .[[Column]] < second .[[Column]] であれば、lesser を返す。
もしfirst .[[Column]] > second .[[Column]] であれば、greater を返す。
equal を返す。
9 ソースマップ形式
ソースマップは、以下の構造をもつトップレベルのJSONオブジェクト を含むJSONドキュメントです:
{
"version" : 3 ,
"file" : "out.js" ,
"sourceRoot" : "" ,
"sources" : [ "foo.js" , "bar.js" ] ,
"sourcesContent" : [ null , null ] ,
"names" : [ "src" , "maps" , "are" , "fun" ] ,
"mappings" : "A,AAAB;;ABCDE" ,
"ignoreList" : [ 0 ]
}
version フィールド は、常に整数 として3でなければなりません。それ以外の値の場合、ソースマップは拒否されることがあります。
file フィールド は、このソースマップが関連付けられている生成コード の名前(オプション)です。この値がURL や相対パス、単なるベース名であるかは明記されていません。ソースマップ生成ツールは利用環境に応じて適切に解釈できます。
sourceRoot
フィールド はサーバ上でソースファイルを移動したり、sourcesエントリで値の重複を避けるためのソースルート文字列(オプション)です。個々のsourcesフィールド 項目の前にこの値が追加されます。
sources フィールド は、mappingsフィールド で使われる元となるソースのリストです。各項目は(相対の可能性もある)URL の文字列か、ソース名がわからない場合はnull になります。
sourcesContent
フィールド は、ソースをホストできない場合に使われる、元ソース(original
source )の文字列リスト(オプション)です。内容はsourcesフィールド と同じ順序で並びます。一部のoriginal
sources は名前で取得するため、エントリがnull になる場合もあります。
names フィールド は、mappingsフィールド で使われる場合がある記号名のリスト(オプション)です。
mappings
フィールド は、マッピングデータがエンコードされた文字列です(セクション9.2 参照)。
ignoreList
フィールド は、フレームワークコードやバンドラーgenerated
code など、サードパーティコードとみなすべきファイルのインデックスのリスト(オプション)です。これにより、開発者ツールは事前設定不要で、開発者が見たりステップ実行したりしたくないコードを回避できます。これはsourcesフィールド を参照し、ソースマップ内で判明しているすべてのサードパーティソースのインデックスを列挙します。ignoreListが存在しない場合、一部のブラウザでは廃止されたx_google_ignoreListフィールドも利用される可能性があります。
9.1 ソースマップのデコード
デコード済みソースマップレコード は以下のフィールドを持ちます:
表3: デコード済みソースマップレコード のフィールド
フィールド名
値の型
[[File]]
String または null
[[Sources]]
List (デコード済みソースレコード の)
[[Mappings]]
List (デコード済みマッピングレコード の)
デコード済みソースレコード は以下のフィールドを持ちます:
表4: デコード済みソースレコード のフィールド
フィールド名
値の型
[[URL]]
URL または
null
[[Content]]
String または null
[[Ignored]]
Boolean
9.1.1 ParseSourceMap ( string , baseURL )
抽象演算 ParseSourceMap は引数 string (String型)と baseURL (URL 型)を取り、デコード済みソースマップレコード を返します。呼び出された際に以下の手順を実行します:
json に ParseJSON (string ) を代入する。
json が JSONオブジェクト
でなければ、エラーを投げる。
JSONObjectGet (json ,
"sections" ) が missing でなければ、
DecodeIndexSourceMap (json ,
baseURL ) を返す。
DecodeSourceMap (json , baseURL ) を返す。
9.1.2 DecodeSourceMap ( json , baseURL )
抽象演算 DecodeSourceMap は引数 json (JSONオブジェクト 型)と baseURL (URL 型)を取り、デコード済みソースマップレコード を返します。呼び出された際に以下の手順を実行します:
JSONObjectGet (json ,
"version" ) が 3 𝔽 でなければ、(任意で)エラー報告を行う 。
mappingsField に JSONObjectGet (json ,
"mappings" ) を代入する。
mappingsField String型でなければ 、エラーを投げる。
JSONObjectGet (json ,
"sources" ) が JSON配列 でなければ、エラーを投げる。
fileField に GetOptionalString (json ,
"file" ) を代入する。
sourceRootField に GetOptionalString (json ,
"sourceRoot" ) を代入する。
sourcesField に GetOptionalListOfOptionalStrings (json ,
"sources" ) を代入する。
sourcesContentField に GetOptionalListOfOptionalStrings (json ,
"sourcesContent" ) を代入する。
ignoreListField に GetOptionalListOfArrayIndexes (json ,
"ignoreList" ) を代入する。
sources に DecodeSourceMapSources (baseURL ,
sourceRootField , sourcesField , sourcesContentField ,
ignoreListField ) を代入する。
namesField に GetOptionalListOfStrings (json ,
"names" ) を代入する。
mappings に DecodeMappings (mappingsField ,
namesField , sources ) を代入する。
mappings を昇順でソートする。デコード済みマッピングレコード a が デコード済みマッピングレコード b
より小さいのは、ComparePositions (a .[[GeneratedPosition]] , b .[[GeneratedPosition]] ) が lesser の場合である。
デコード済みソースマップレコード {
[[File]] : fileField , [[Sources]] : sources , [[Mappings]] : mappings } を返す。
9.1.2.1 GetOptionalString ( object , key )
抽象演算 GetOptionalString は引数 object (JSONオブジェクト 型)と
key (String型)を取り、Stringまたはnull を返します。呼び出された際に以下の手順を実行します:
value に JSONObjectGet (object , key ) を代入する。
value が String型であれば
value を返す。
value が missing でなければ、(任意で)エラー報告を行う 。
null を返す。
9.1.2.2 GetOptionalListOfStrings ( object ,
key )
抽象演算 GetOptionalListOfStrings は引数 object (JSONオブジェクト 型)と key (String型)を取り、StringのList を返します。呼び出された際に以下の手順を実行します:
list に新しい空の List を代入する。
values に JSONObjectGet (object , key ) を代入する。
values が missing であれば list を返す。
values が JSON配列 でなければ、
(任意で)エラー報告を行う 。
list を返す。
JSONArrayIterate (values ) の各要素
item について、
item が String型なら 、
item を list に追加する。
それ以外なら、
(任意で)エラー報告を行う 。
"" を list に追加する。
list を返す。
9.1.2.3 GetOptionalListOfOptionalStrings ( object ,
key )
抽象演算 GetOptionalListOfOptionalStrings は引数 object (JSONオブジェクト 型)と
key (String型)を取り、Stringまたはnull のList を返します。呼び出された際に以下の手順を実行します:
list に新しい空の List を代入する。
values に JSONObjectGet (object , key ) を代入する。
values が missing であれば list を返す。
values が JSON配列 でなければ、
(任意で)エラー報告を行う 。
list を返す。
JSONArrayIterate (values ) の各要素
item について、
item が String型なら 、
item を list に追加する。
それ以外なら、
item ≠ null なら (任意で)エラー報告を行う 。
null を list に追加する。
list を返す。
9.1.2.4 GetOptionalListOfArrayIndexes ( object ,
key )
抽象演算 GetOptionalListOfArrayIndexes は引数 object (Object型)と
key (String型)を取り、非負の整数 のList を返します。呼び出された際に以下の手順を実行します:
list に新しい空の List を代入する。
values に JSONObjectGet (object , key ) を代入する。
values が missing であれば list を返す。
values が JSON配列 でなければ、
(任意で)エラー報告を行う 。
list を返す。
JSONArrayIterate (values ) の各要素
item について、
item が 整数値 であり、item ≠
+0 𝔽 かつ item ≥
+0 𝔽 なら、
ℝ (item ) を list
に追加する。
それ以外なら、
item ≠ null なら (任意で)エラー報告を行う 。
null を list に追加する。
list を返す。
9.2 マッピングの構造
mappingsフィールド のデータは以下のように分割されます:
生成ファイル内の各行はセミコロン(;)で区切られています。
各セグメントはカンマ(,)で区切られています。
各セグメントは、可変長の1個、4個、または5個のフィールドで構成されます。
各セグメントのフィールドは以下の通りです:
このセグメントが表す生成コード 内の行のゼロ始まりカラム。最初のセグメントの最初のフィールド、または新しい生成行(;の後)の最初のセグメントの場合、このフィールドは全体をbase64
VLQ で表します。それ以外の場合は、前回のこのフィールドからの相対値としてbase64 VLQ 値を保持します。これは以降のフィールドとは異なり、前回値が行ごとにリセットされるため注意。
存在する場合、sourcesリストへのゼロ始まりのインデックス。通常前回のこのフィールドからの相対値base64 VLQ ですが、最初の出現時は全体の値で表現されます。
存在する場合、元のソース 内のゼロ始まりの行。通常前回のこのフィールドからの相対値base64 VLQ ですが、最初の出現時は全体の値で表現されます。sourceフィールドがある場合必須。
存在する場合、元のソース 内の行のゼロ始まりカラム。通常前回のこのフィールドからの相対値base64
VLQ ですが、最初の出現時は全体の値で表現されます。sourceフィールドがある場合必須。
存在する場合、このセグメントに紐づくnamesリストのゼロ始まりのインデックス。通常前回のこのフィールドからの相対値base64 VLQ ですが、最初の出現時は全体の値で表現されます。
注1
この符号化の目的はソースマップサイズの縮小です。VLQ符号化により、Googleカレンダーでのテスト時、Source Map Revision 2
Proposal と比較してソースマップが50%縮小されました。
注2
フィールドが1個だけのセグメントは、対応する元ソース が存在せず、コンパイラ等で生成された生成コード としてマッピングされていない部分を表します。フィールド4つは対応名が存在しないマッピング済みコード、フィールド5つは対応名もマッピングされているコードです。
注3
file オフセット値の使用も検討されましたが、プラットフォーム特有の改行による不一致を避けるため行/column データによる設計となりました。
デコード済みマッピングレコード は以下のフィールドを持ちます:
表5: デコード済みマッピングレコード のフィールド
フィールド名
値の型
[[GeneratedPosition]]
Position
Record
[[OriginalPosition]]
Original
Position Record またはnull
[[Name]]
Stringまたはnull
9.2.1 マッピングの文法
mappingsの文字列は以下の文法に従う必要があります:
MappingsField :
LineList
LineList :
Line
Line
;
LineList
Line :
MappingList opt
MappingList :
Mapping
Mapping
,
MappingList
Mapping :
GeneratedColumn
GeneratedColumn
OriginalSource
OriginalLine
OriginalColumn
Name opt
GeneratedColumn :
Vlq
OriginalSource :
Vlq
OriginalLine :
Vlq
OriginalColumn :
Vlq
Name :
Vlq
デコードマッピング状態レコード は以下のフィールドを持ちます:
表6: デコードマッピング状態レコード のフィールド
フィールド名
値の型
[[GeneratedLine]]
非負の整数
[[GeneratedColumn]]
非負の整数
[[SourceIndex]]
非負の整数
[[OriginalLine]]
非負の整数
[[OriginalColumn]]
非負の整数
[[NameIndex]]
非負の整数
9.2.1.1 DecodeMappingsField
構文指示付き演算 DecodeMappingsFieldは、引数state (デコードマッピング状態レコード )、mappings (List (デコード済みマッピングレコード ))、names (List (String))、sources (List (デコード済みソースレコード ))を受け取り、以下の生成規則ごとに定義されます:
LineList :
Line
;
LineList
DecodeMappingsField をLine に対し、引数state 、mappings 、names 、sources で実行する。
state .[[GeneratedLine]] を state .[[GeneratedLine]] + 1 に設定する。
state .[[GeneratedColumn]] を 0 に設定する。
DecodeMappingsField をLineList に対し、引数state 、mappings 、names 、sources で実行する。
Line : [empty]
return。
MappingList :
Mapping
,
MappingList
DecodeMappingsField をMapping に対し、引数state 、mappings 、names 、sources で実行する。
DecodeMappingsField をMappingList に対し、引数state 、mappings 、names 、sources で実行する。
Mapping :
GeneratedColumn
DecodeMappingsField をGeneratedColumn に対し、引数state 、mappings 、names 、sources で実行する。
もしstate .[[GeneratedColumn]] <0なら、
(任意で)エラー報告を行う 。
return。
position を新しいPosition Record {[[Line]] :
state .[[GeneratedLine]] , [[Column]] : state .[[GeneratedColumn]] }とする。
decodedMapping を新しいDecodedMappingRecord{[[GeneratedPosition]] : position , [[OriginalPosition]] : null , [[Name]] : null }とする。
mappings にdecodedMapping を追加する。
Mapping :
GeneratedColumn
OriginalSource
OriginalLine
OriginalColumn
Name opt
DecodeMappingsField をGeneratedColumn に対し、引数state 、mappings 、names 、sources で実行する。
もしstate .[[GeneratedColumn]] <0なら、
(任意で)エラー報告を行う 。
return。
generatedPosition を新しいPosition Record {[[Line]] :
state .[[GeneratedLine]] , [[Column]] : state .[[GeneratedColumn]] }とする。
DecodeMappingsField をOriginalSource に対し、引数state 、mappings 、names 、sources で実行する。
DecodeMappingsField をOriginalLine に対し、引数state 、mappings 、names 、sources で実行する。
DecodeMappingsField をOriginalColumn に対し、引数state 、mappings 、names 、sources で実行する。
もしstate .[[SourceIndex]] <0またはstate .[[SourceIndex]] ≧sources の要素数、またはstate .[[OriginalLine]] <0またはstate .[[OriginalColumn]] <0の場合、
(任意で)エラー報告を行う 。
originalPosition をnull にする。
それ以外の場合は、
originalPosition を新しいOriginal
Position Record {[[Source]] :
sources [state .[[SourceIndex]] ], [[Line]] :
state .[[OriginalLine]] , [[Column]] : state .[[OriginalColumn]] }とする。
name をnull にする。
Name があれば、
DecodeMappingsField をName に対し、引数state 、mappings 、names 、sources で実行する。
もしstate .[[NameIndex]] <0またはstate .[[NameIndex]] ≧names の要素数なら、(任意で)エラー報告を行う 。
それ以外の場合は、name をnames [state .[[NameIndex]] ]にする。
decodedMapping を新しいDecodedMappingRecord{[[GeneratedPosition]] : generatedPosition , [[OriginalPosition]] : originalPosition , [[Name]] : name }とする。
mappings にdecodedMapping を追加する。
GeneratedColumn
:
Vlq
relativeColumn をVLQSignedValue (Vlq )で求める。
state .[[GeneratedColumn]] をstate .[[GeneratedColumn]] +relativeColumn に設定する。
OriginalSource :
Vlq
relativeSourceIndex をVLQSignedValue (Vlq )で求める。
state .[[SourceIndex]] をstate .[[SourceIndex]] +relativeSourceIndex に設定する。
OriginalLine :
Vlq
relativeLine をVLQSignedValue (Vlq )で求める。
state .[[OriginalLine]] をstate .[[OriginalLine]] +relativeLine に設定する。
OriginalColumn :
Vlq
relativeColumn をVLQSignedValue (Vlq )で求める。
state .[[OriginalColumn]] をstate .[[OriginalColumn]] +relativeColumn に設定する。
Name :
Vlq
relativeName をVLQSignedValue (Vlq )で求める。
state .[[NameIndex]] をstate .[[NameIndex]] +relativeName に設定する。
9.2.2 DecodeMappings ( rawMappings , names ,
sources )
抽象操作DecodeMappingsは、引数rawMappings (String型)、names (StringのList )、sources (Decoded Source Records のList )を受け取り、Decoded Mapping Record のList を返します。呼び出すと、以下の手順を実行します:
mappings を新しい空のList とする。
mappingsNode を、rawMappings をMappingsField (goal symbol として)で構文解析したときのルートParse Node とする。
構文解析に失敗した場合、
(任意で)エラー報告を行う 。
mappings を返す。
state を、全フィールドが0の新しいDecode Mapping State Record とする。
DecodeMappingsField をmappingsNode に対して引数state ,
mappings , names , sources で実行する。
mappings を返す。
9.2.3 生成されたJavaScriptコードのマッピング
生成コード の位置でmapping エントリーとなりうるものは、ECMAScript字句文法 に則り、入力要素 で定義されます。マッピングエントリは次のいずれかを指す必要があります:
IdentifierName 、PrivateIdentifier 、Punctuator 、DivPunctuator 、RightBracePunctuator 、NumericLiteral 、RegularExpressionLiteral で一致したソーステキストの最初のコードポイント。
Comment 、HashbangComment 、StringLiteral 、Template 、TemplateSubstitutionTail 、WhiteSpace 、LineTerminator で一致したソーステキストのいずれかのコードポイント。
9.2.4 生成JavaScriptコードの名前
ソースマップ生成ツールは、次の場合、JavaScriptトークンについて[[Name]] フィールドを持つmapping エントリを生成するべきです:
元ソース の言語構造が意味的に生成されたJavaScriptコードに対応する。
元ソース の言語構造が名前を持つ。
その場合、mapping エントリの[[Name]] は元ソース 言語構造の名前となります。非nullな[[Name]] を持つmapping は名前付きマッピング と呼ばれます。
注1
ミニファイアによる関数名や変数名の変更、即時実行関数式からの関数名の削除などのケース。
以下の列挙は、ECMAScript構文文法 の生成規則と、その右辺のトークン・非終端で、ソースマップ生成ツールが名前付きマッピングを出力すべきものです。これらのトークンのために作成されるmapping エントリは、9.2.3 に従います。
この列挙は「最低限」として扱います。一般に、ソースマップ生成ツールは追加の名前付きマッピングを自由に生成して構いません。
注2
この列挙には、生成ツールが「may(推奨)」として名前付きマッピングを出力するケースも含まれています。既存ツールが名前付きマッピングを出力・要求する現実を反映しています。重複した名前付きマッピングはほぼコストゼロです:namesへのインデックスは互いに相対で符号化されるので、同一名への連続したマッピングは0(A)として符号化されます。
LexicalDeclaration 、VariableStatement 、FormalParameterList に含まれるBindingIdentifier 。
FunctionDeclaration 、FunctionExpression 、AsyncFunctionDeclaration 、AsyncFunctionExpression 、GeneratorDeclaration 、GeneratorExpression 、AsyncGeneratorDeclaration 、AsyncGeneratorExpression に存在する場合はBindingIdentifier 、存在しない場合はFormalParameters の直前の開き括弧(。
ソースマップ生成ツールはBindingIdentifier の有無に関わらず、開き括弧にも名前付きマッピングを出力してもよい。
ArrowFunction またはAsyncArrowFunction の場合:
ArrowFunction が単一BindingIdentifier でArrowParameters となる場合またはAsyncArrowFunction がAsyncArrowBindingIdentifier となる場合の=>トークン。
注3
これは(async)アロー関数が単一パラメータかつ括弧で囲まれていないケースを指します。
ArrowFunction またはAsyncArrowFunction がArrowFormalParameters で生成される場合の開き括弧(。
ソースマップ生成ツールは前のケースとの一貫性のため、=>トークンにも追加で名前付きマッピングを出力しても良い。
MethodDefinition のClassElementName (ジェネレータ、asyncメソッド、asyncジェネレータ、アクセサ含む)。MethodDefinition 内でClassElementName が"constructor" なら[[Name]] は元のクラス名(該当する場合)とする。
ソースマップ生成ツールは開き括弧(にも追加で名前付きマッピングを出力してもよい。
ソースマップ生成ツールはExpression 内のIdentifierReference に対して名前付きマッピングを出力してもよい。
9.3 ソースの解決
sourceRootを前に付加した後でも、sourcesが絶対URLでない場合は、HTMLドキュメント内のscriptのsrc属性を解決するように、ソースマップを基準に相対的に解決されます。
9.3.1 DecodeSourceMapSources ( baseURL ,
sourceRoot , sources , sourcesContent , ignoreList )
抽象操作DecodeSourceMapSourcesは、引数baseURL (URL 型)、sourceRoot (Stringまたはnull )、sources (Stringまたはnull のList )、sourcesContent (Stringまたはnull のList )、ignoreList (非負の整数 のList )を受け取り、Decoded Source
Record を返します。呼び出し時には次の手順を実行します:
decodedSources を新しい空のList とする。
sourcesContentCount をsourcesContent の要素数とする。
sourceUrlPrefix を"" とする。
もしsourceRoot ≠null なら、
もしsourceRoot がU+002F(SOLIDUS)で終わっている場合、
sourceUrlPrefix にsourceRoot を設定する。
それ以外の場合、
sourceUrlPrefix にsourceRoot と"/" を文字列連結 した値を設定する。
index を0とする。
index < sources の長さの間、繰り返す:
source をsources [index ]とする。
decodedSource をDecoded Source Record { [[URL]] : null , [[Content]] : null , [[Ignored]] : false }とする。
もしsource ≠null なら、
source にsourceUrlPrefix とsource を文字列連結 した値を設定する。
sourceURL をURL解析 でsource とbaseURL から得る。
もしsourceURL がfailure なら(任意で)エラー報告 を行う。
そうでなければ、decodedSource .[[URL]] にsourceURL を設定する。
もしignoreList がindex を含む場合、decodedSource .[[Ignored]] にtrue を設定する。
もしsourcesContentCount >
index の場合、decodedSource .[[Content]] にsourcesContent [index ]を設定する。
decodedSource をdecodedSources に追加する。
decodedSources を返す。
注
複数のURL を同じ値で異なる内容を持つ複数ソースの表示をサポートしていない実装は、URL ごとにいずれかの内容を任意に選択することになります。
9.4 拡張
ソースマップ利用者は追加の認識されないプロパティを無視し、ソースマップの拒否につなげてはならず、このフォーマットが既存ユーザーを壊すことなく追加機能拡張できるようにすべきです。
10 インデックスソースマップ
生成コード の連結や他の一般的な後処理をサポートするため、ソースマップの別表現がサポートされています:
{
"version" : 3 ,
"file" : "app.js" ,
"sections" : [
{
"offset" : { "line" : 0 , "column" : 0 } ,
"map" : {
"version" : 3 ,
"file" : "section.js" ,
"sources" : [ "foo.js" , "bar.js" ] ,
"names" : [ "src" , "maps" , "are" , "fun" ] ,
"mappings" : "AAAA,E;;ABCDE"
}
} ,
{
"offset" : { "line" : 100 , "column" : 10 } ,
"map" : {
"version" : 3 ,
"file" : "another_section.js" ,
"sources" : [ "more.js" ] ,
"names" : [ "more" , "is" , "better" ] ,
"mappings" : "AAAA,E;AACA,C;ABCDE"
}
}
]
}
インデックスマップは標準のマップと同じ形式に従います。通常のソースマップのように、ファイルフォーマットはJSONでトップレベルはオブジェクトです。通常のソースマップと同じくversionやfileフィールド を持ちますが、さらに新しいsectionsフィールド が追加されています。
sectionsフィールド は、以下のフィールドを持つオブジェクトの配列です:
offsetフィールド は、lineとcolumnの2つのフィールドを持つオブジェクトで、参照されるソースマップが表す生成コード のオフセットを示します。
mapフィールド は埋め込み形式の完全なソースマップオブジェクトです。埋め込みマップは外側のインデックスマップから値を継承しません。
sectionsは開始位置でソートされ、各sectionが表す部分は重なってはいけません。
10.1 DecodeIndexSourceMap ( json , baseURL )
抽象演算DecodeIndexSourceMapは、引数json (Object型)とbaseURL (URL 型)を受け取り、Decoded Source Map
Record を返します。呼び出し時に行う手順は次のとおりです:
sectionsField をJSONObjectGet (json ,
"sections" )とする。
アサート :sectionsField はmissing ではない。
sectionsField がJSON配列 でなければ、エラーを投げる。
JSONObjectGet (json ,
"version" )が3 𝔽 でなければ、(任意)エラー報告 をする。
fileField をGetOptionalString (json ,
"file" )とする。
sourceMap をDecoded
Source Map Record {[[File]] : fileField ,
[[Sources]] : « », [[Mappings]] : « »}とする。
previousOffsetPosition をnull とする。
previousLastMapping をnull とする。
JSONArrayIterate (sectionsField )の各section について:
section がJSONオブジェクト でなければ、(任意)エラー報告 をする。
そうでなければ:
offset をJSONObjectGet (section ,
"offset" )とする。
offset がJSONオブジェクト でなければ、エラーを投げる。
offsetLine をJSONObjectGet (offset ,
"line" )とする。
offsetColumn をJSONObjectGet (offset ,
"column" )とする。
offsetLine が整数値 でなければ、(任意)エラー報告 し、offsetLine を+0 𝔽 にする。
offsetColumn が整数値 でなければ、(任意)エラー報告 し、offsetColumn を+0 𝔽 にする。
offsetPosition を新しいPosition Record {[[Line]] : offsetLine , [[Column]] : offsetColumn }とする。
もしpreviousOffsetPosition ≠null なら、ComparePositions (offsetPosition ,
previousOffsetPosition )がlesser なら(任意)エラー報告 。
もしpreviousLastMapping ≠null なら、ComparePositions (offsetPosition ,
previousLastMapping .[[GeneratedPosition]] )がlesser なら(任意)エラー報告 。 ※この部分はインデックスソースマップのsectionsフィールドが順序付きかつ重複しないことをチェックします。実際は順序だけを確認する実装もありえます。
mapField をJSONObjectGet (section ,
"map" )とする。
mapField がJSONオブジェクト でなければ、エラーを投げる。
decodedSectionCompletion をCompletion (DecodeSourceMap (json ,
baseURL ))とする。
decodedSectionCompletion がthrow
completion なら(任意)エラー報告 。
そうでなければ:
decodedSection をdecodedSectionCompletion .[[Value]] とする。
decodedSection .[[Sources]] の各additionalSource について:
もしsourceMap .[[Sources]] に含まれていなければ追加する。
offsetMappings を新しい空のList とする。
decodedSection .[[Mappings]] の各mapping について:
もしmapping .[[GeneratedPosition]] .[[Line]] ==0なら、mapping .[[GeneratedPosition]] .[[Column]] +=
offsetColumn 。
mapping .[[GeneratedPosition]] .[[Line]] += offsetLine 。
mapping をoffsetMappings に追加する。
sourceMap .[[Mappings]] を、リスト連結 でsourceMap .[[Mappings]] とoffsetMappings に設定する。
previousOffsetPosition をoffsetPosition にする。
もしoffsetMappings が空でなければpreviousLastMapping をoffsetMappings の最後の要素にする。
sourceMap を返す。
注
実装によっては、マッピングを連結せず各sectionを個別に保存しバイナリサーチするなどの方法も選択できます。
11 ソースマップの取得
11.1 生成コードとソースマップのリンク
ソースマップフォーマットは言語非依存・プラットフォーム非依存を目指していますが、WebサーバでホストされるJavaScriptという典型的な利用ケースのため、どのように参照するかを定義すると有用です。
出力にソースマップを紐付ける方法は2つあります。1つめはサーバがHTTPヘッダーを追加する必要があり、2つめはソース内でアノテーションを追加する方法です。
ソースマップはWHATWG
URL としてURL経由でリンクされます。特に、URIに許されていない文字はパーセントエンコードされる必要があり、data URIも利用可能です。data
URIとsourcesContentを組み合わせると完全に自己完結したソースマップが実現できます。
HTTP sourcemapヘッダーはソースアノテーションより優先され、双方が存在する場合はヘッダーのURL がソースマップファイルの解決に使われます。
ソースマップURL の取得方法に関わらず、次の手続きで解決します。
ソースマップURL が絶対パスでない場合、生成コード のソースオリジン を基準とし、ソースオリジン は以下で判定されます:
11.1.2 インラインアノテーションによるリンク
生成コード はsourceMappingURLという名のコメントまたは言語/フォーマットに応じた同等の仕組みを含み、そこにソースマップのURL を記載すべきです。この仕様ではJavaScript、CSS、WebAssemblyについてコメントの記述例を示します。他の言語も類似の慣例に従うべきです。
言語ごとにsourceMappingURLコメント検出方法は複数あり、実装ごとに複雑度が低い方法を選べます。すべての抽出方法で同一結果となる場合、生成コード は一意的にソースマップへリンク されていると見なします。
ツールが一意的にソースマップへリンクされたソースファイルを1つ以上消費し、出力ファイルでもソースマップへリンクする場合は、一意的 でなければなりません。
注1
以下のJavaScriptコードはソースマップへリンクしていますが、一意的 ではありません:
let a = `
//# sourceMappingURL=foo.js.map
//`
このコードからソースマップURL を構文解析で抽出 するとnull となり、構文解析しない抽出 ではfoo.js.mapとなります。
注2
複数のソースマップURL抽出方法が異なる結果を返す場合、セキュリティやプライバシー上の課題につながることがあります。どのソースマップがロードされる可能性があるか検出したい実装は、両アルゴリズムを必ず適用することが強く推奨されます。
この課題に対する修正は現在検討中で、将来標準に取り込まれる見込みです。今後は、コメント(またはコメント的なもの)にU+0060(`)、U+0022(")、U+0027(')、U+002A
U+002F(*/)などが含まれていればアルゴリズムを早期終了する方式が採用される見込みです。
module をmodule_decode (bytes )で取得。
module がWebAssemblyエラー ならnull 。
module の各custom section customSection について:
name をcustomSection のnameとする。
CodePointsToString (name )が"sourceMappingURL" なら:
value をcustomSection のbytesとする。
CodePointsToString (value )を返す。
null を返す。
WebAssemblyはテキスト形式ではなく、コメントもサポートしないため一意的な抽出方法のみ対応しています。URL はWebAssembly名 としてエンコードされ、custom
section の内容として配置されます。WebAssemblyコードを生成するツールはsourceMappingURL名のcustom
section を2つ以上生成してはなりません。
11.2 ソースマップの取得処理
11.2.1 FetchSourceMap ( url )
抽象演算FetchSourceMapは引数url (URL 型)を受け取り、Promiseを返します。呼び出し時の手順:
promiseCapability をNewPromiseCapability (%Promise% )で作成。
request を新しいrequest とし、そのrequest
URL をurl にする。
processResponseConsumeBody を(response ,bodyBytes )引数の新規Abstract
Closure で、promiseCapability とurl をキャプチャ。呼び出し時の手順:
bodyBytes がnull かfailure なら:
Call (promiseCapability .[[Reject]] , undefined ,
«新しいTypeError »)。
Return。
url のscheme がHTTP(S)
scheme であり、byte sequence で)]}'がprefix なら:
byte-sequence-length ≠0かつbodyBytes [0]がHTTP
newline byte でない間:
bodyBytes の0番目要素を削除。
bodyString をCompletion (UTF-8
decode of bodyBytes )で取得。
IfAbruptRejectPromise (bodyString ,
promiseCapability )。
jsonValue をCompletion (ParseJSON (bodyString ))で取得。
IfAbruptRejectPromise (jsonValue ,
promiseCapability )。
Call (promiseCapability .[[Resolve]] , undefined ,
«jsonValue »)。
fetch request をprocessResponseConsumeBody 引数付きで実行。
promiseCapability .[[Promise]] を返す。
注
歴史的理由によりHTTP(S)越しでソースマップを配信する際、ソースマップの先頭に)]}'で始まる行が追加される場合があります。
)] } 'garbage here
{ "version" : 3 , ...}
これは下記とみなされます:
{ "version" : 3 , ...}
12 ソースマップレコードの操作
ソースマップをデコードした後、ソースマップ利用者は得られたデコード済みソースマップレコード を使い、デバッグ等の用途で位置情報を検索できます。本節はソースマップ利用者が典型的にサポートする操作の動作について説明します。
GetOriginalPositions 操作は、生成コード の位置に対応する元ソース の位置を問い合わせるために用います。たとえば、デバッガではユーザーのマウスクリックなどに基づき生成コード から元ソース へナビゲートできます。
12.1 GetOriginalPositions ( sourceMapRecord ,
generatedPosition )
抽象操作GetOriginalPositionsは、引数sourceMapRecord (デコード済みソースマップレコード 型)とgeneratedPosition (Position Record 型)を受け取り、Original Position
Records のList を返します。呼び出し時の手順:
mappings をsourceMapRecord .[[Mappings]] とする。
last をnull とする。
originalPositions を新しい空のList とする。
mappings の各mapping を逆順で:
last がnull の場合:
ComparePositions (mapping .[[GeneratedPosition]] ,
generatedPosition )の結果がlesser またはequal ならlast にmapping を設定。
last がnull でなければ:
mappings の各mapping について:
ComparePositions (last .[[GeneratedPosition]] , mapping .[[GeneratedPosition]] )の結果がequal ならmapping .[[OriginalPosition]] をoriginalPositions に追加。
originalPositions を返す。
Annex A (informative) 慣例
ソースマップの取扱いや生成時には次の慣例に従うべきです。
A.1 ソースマップ命名規則
一般的に、ソースマップは生成されたファイル名に.map拡張子をつけ同名で作成されます。例:page.jsの場合、page.js.mapというソースマップが生成されます。
A.2 evalコードの名前付き生成コードへのリンク
evalコードにソースマップを利用するための既存の慣例があり、次の形式を取ります:
これはGive your eval a name with //@
sourceURL で説明されています。
Annex B (informative) 注釈
B.1 言語非依存のスタックマッピング
ソース言語の知識なしでのスタックトレースマッピングは本書では対象外 です。
B.2 多段階マッピング
DSL(テンプレート)からの生成やTypeScript → JavaScript → minified
JavaScriptといった複数段の変換を経た最終ソースマップが生成されるケースが一般的になっています。この問題は二通りで対応可能です。一つは単純ですが情報損失が発生する方法で、中間ステップをデバッグ用途では無視し、翻訳過程の位置情報を無視して(中間変換を「元ソース」とみなす)、または位置情報を引き継いで(中間変換は隠される)扱う方法です。より完全な方法は多段階のマッピングをサポートするものです。元ソース側もソースマップ参照を持つ場合、ユーザーはそれも利用可能です。
ただし、JavaScript以外で「ソースマップ参照」が何なのかは未定義です。特に、JavaScript形式の一行コメントをサポートしない言語でソースマップ参照がどんな形式になるかは不明です。
Annex C (informative) 他仕様で定義されている用語
本書で使われている用語・アルゴリズムのうち、ECMA-262以外の外部仕様で定義されるものを列挙します。
WebAssembly Core Specification <https://www.w3.org/TR/wasm-core-2/ >
custom section ,
module_decode ,
WebAssembly error ,
WebAssembly names
WHATWG Encoding <https://encoding.spec.whatwg.org/ >
UTF-8 decode
WHATWG Fetch <https://fetch.spec.whatwg.org/ >
fetch ,
HTTP newline byte ,
processResponseConsumeBody ,
request ,
request URL
WHATWG Infra <https://infra.spec.whatwg.org/ >
byte sequence ,
byte-sequence-prefix ,
byte-sequence-length ,
WHATWG URL <https://url.spec.whatwg.org/ >
HTTP(S) scheme ,
scheme ,
URL ,
URL parsing
Annex D (informative) 参考文献
IETF RFC 4648, The Base16, Base32, and Base64 Data Encodings , available at <https://datatracker.ietf.org/doc/html/rfc4648 >
ECMA-262, ECMAScript® Language Specification , available at <https://tc39.es/ecma262/ >
ECMA-404, The JSON Data Interchange Format , available at <https://www.ecma-international.org/publications-and-standards/standards/ecma-404/ >
WebAssembly Core Specification , available at <https://www.w3.org/TR/wasm-core-2/ >
WHATWG Encoding , available at <https://encoding.spec.whatwg.org/ >
WHATWG Fetch , available at <https://fetch.spec.whatwg.org/ >
WHATWG Infra , available at <https://infra.spec.whatwg.org/ >
WHATWG URL , available at <https://url.spec.whatwg.org/ >
Give your eval a name with //@ sourceURL ,
Firebug (2009), available at <http://blog.getfirebug.com/2009/08/11/give-your-eval-a-name-with-sourceurl/ >
Source Map Revision 2 Proposal , John Lenz (2010),
available at <https://docs.google.com/document/d/1xi12LrcqjqIHTtZzrzZKmQ3lbTv9mKrN076UB-j3UZQ/ >
可変長数量 , Wikipedia,
available at <https://en.wikipedia.org/wiki/Variable-length_quantity >
Annex E (informative) コロフォン
この仕様書は、GitHub 上で、Ecmarkup というプレーンテキストソース形式で作成されています。EcmarkupはHTMLとMarkdownの方言であり、プレーンテキストでECMAScript仕様書を執筆し、文書の編集上の慣例に従った本格的なHTMLレンダリングへと処理できるフレームワークとツールセットを提供します。Ecmarkupは、構文定義用のGrammarkdown や、アルゴリズム手順記述用のEcmarkdown など、様々なフォーマットや技術を統合しています。この仕様書のPDFレンダリングは、HTMLレンダリングをPDF印刷することで作成されています。
この仕様書の初版は、Bikeshed という、HTMLとMarkdownをベースにした別のプレーンテキストソース形式で作成されました。
標準化以前のバージョンはGoogle Docsで執筆されました。
Copyright & Software License
Ecma International
Rue du Rhone 114
CH-1204 Geneva
Tel: +41 22 849 6000
Fax: +41 22 849 6001
Web: https://ecma-international.org/
Copyright Notice
© 2025 Ecma International
This draft document may be copied and furnished to others, and derivative works that comment on or
otherwise explain it or assist in its implementation may be prepared, copied, published, and
distributed, in whole or in part, without restriction of any kind, provided that the above copyright
notice and this section are included on all such copies and derivative works. However, this document
itself may not be modified in any way, including by removing the copyright notice or references to
Ecma International, except as needed for the purpose of developing any document or deliverable
produced by Ecma International.
This disclaimer is valid only prior to final version of this document. After approval all rights on
the standard are reserved by Ecma International.
The limited permissions are granted through the standardization phase and will not be revoked by Ecma
International or its successors or assigns during this time.
This document and the information contained herein is provided on an "AS IS" basis and ECMA
INTERNATIONAL DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY
WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY OWNERSHIP RIGHTS OR ANY
IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Software License
All Software contained in this document ("Software") is protected by copyright and is being made
available under the "BSD License", included below. This Software may be subject to third party rights
(rights from parties other than Ecma International), including patent rights, and no licenses under such
third party rights are granted under this license even if the third party concerned is a member of Ecma
International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://ecma-international.org/memento/codeofconduct.htm
FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA
INTERNATIONAL STANDARDS.
Redistribution and use in source and binary forms, with or without modification, are permitted provided
that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and
the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions
and the following disclaimer in the documentation and/or other materials provided with the
distribution.
Neither the name of the authors nor Ecma International may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.