This Ecma Standard defines the Source map format, used for mapping transpiled source code back to the original sources.
The source map format has the following goals:
The original source map format (v1) was created by Joseph Schorr for use by Closure Inspector to enable source-level debugging of optimized JavaScript code (although the format itself is language agnostic). However, as the size of the projects using source maps expanded, the verbosity of the format started to become a problem. The v2 format ( Source Map Revision 2 Proposal ) was created by trading some simplicity and flexibility to reduce the overall size of the source map. Even with the changes made with the v2 version of the format, the source map file size was limiting its usefulness. The v3 format is based on suggestions made by Pavel Podivilov (Google).
The source map format does not have version numbers anymore, and it is instead hard-coded to always be "3".
In 2023-2024, the source map format was developed into a more precise Ecma standard, with significant contributions from many people. Further iteration on the source map format is expected to come from TC39-TG4.
Asumu Takikawa, Nicolò Ribaudo, Jon Kuperman
ECMA-426, 1st edition, Project Editors
This Standard defines the source map format, used by different types of developer tools to improve the debugging experience of code compiled to JavaScript, WebAssembly, and CSS.
2 ConformanceA conforming source map document is a JSON document that conforms to the structure detailed in this specification.
A conforming source map generator should generate documents which are conforming source map documents, and can be decoded by the algorithms in this specification without reporting any errors (even those which are specified as optional).
A conforming source map consumer should implement the algorithms specified in this specification for retrieving (where applicable) and decoding source map documents. A conforming consumer is permitted to ignore errors or report them without terminating where the specification indicates that an algorithm may optionally report an error .
3 ReferencesThe following documents are referred to in the text in such a way that some or all of their content constitutes requirements of this document. For dated references, only the edition cited applies. For undated references, the latest edition of the referenced document (including any amendments) applies.
3.1 Normative ReferencesECMA-262, ECMAScript® Language Specification.
https://tc39.es/ecma262/
ECMA-404, The JSON Data Interchange Format.
https://www.ecma-international.org/publications-and-standards/standards/ecma-404/
IETF RFC 4648, The Base16, Base32, and Base64 Data Encodings.
https://datatracker.ietf.org/doc/html/rfc4648
WebAssembly Core Specification.
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/
This specification follows the same notational conventions as defined by ECMA-262 (Notational conventions), with the extensions defined in this section.
4.1 Algorithm Conventions 4.1.1 Implicit CompletionsAll abstract operations declared in this specification are implicitly assumed to either return a normal completion containing the algorithm's declared return type, or a throw completion . For example, an abstract operation declared as
4.1.1.1 GetTheAnswer ( input )The abstract operation GetTheAnswer takes argument input (an integer ) and returns an integer .
is equivalent to:
4.1.1.2 GetTheAnswer2 ( input )The abstract operation GetTheAnswer2 takes argument input (an integer ) and returns either a normal completion containing an integer or a throw completion .
All calls to abstract operations that return completion records are implicitly assumed to be wrapped by a ReturnIfAbrupt macro, unless they are explicitly wrapped by an explicit Completion call. For example:
is equivalent to:
Whenever an algorithm is to optionally report an error, an implementation may choose one of the following behaviours:
An implementation can choose different behaviours for different optional errors.
4.2 Grammar NotationThis specification follows the same grammar notation convention as defined by ECMA-262 (Grammar Notation), with the following caveats:
For the purposes of this document, the following terms and definitions apply.
code which is generated by the compiler or transpiler.
source code which has not been passed through a compiler or transpiler.
URL referencing the location of a source map from the generated code .
zero-based indexed offset within a line of the generated code , computed as UTF-16 code units for JavaScript and CSS source maps, and as byte indices in the binary content (represented as a single line) for WebAssembly source maps.
NoteThat means that "A" (LATIN CAPITAL LETTER A
) measures as 1 code unit, and "🔥" (FIRE
) measures as 2 code units. Source maps for other content types may diverge from this.
A base64 VLQ is a base64 -encoded variable-length quantity , where the most significant bit (the 6th bit) is used as the continuation bit, and the "digits" are encoded into the string least significant first, and where the least significant bit of the first digit is used as the sign bit.
Note 1The values that can be represented by the base64 VLQ encoding are limited to 32-bit quantities until some use case for larger values is presented. This means that values exceeding 32-bits are invalid and implementations may reject them. The sign bit is counted towards the limit, but the continuation bits are not.
Note 2The string "iB"
represents a base64 VLQ with two digits. The first digit "i"
encodes the bit pattern 0x100010
, which has a continuation bit of 1
(the VLQ continues), a sign bit of 0
(non-negative), and the value bits 0x0001
. The second digit B
encodes the bit pattern 0x000001
, which has a continuation bit of 0
, no sign bit, and value bits 0x00001
. The decoding of this VLQ string is the number 17.
The string "V"
represents a base64 VLQ with one digit. The digit "V"
encodes the bit pattern 0x010101
, which has a continuation bit of 0
(no continuation), a sign bit of 1
(negative), and the value bits 0x1010
. The decoding of this VLQ string is the number -10.
A base64 VLQ adheres to the following lexical grammar:
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 VLQSignedValueThe syntax-directed operation VLQSignedValue takes no arguments and returns an integer . It is defined piecewise over the following productions:
Vlq :: VlqDigitListThe check in step
6is needed because
unsignedis the
VLQUnsignedValueof
VlqDigitList, not of
Vlq.
6.2 VLQUnsignedValueThe syntax-directed operation VLQUnsignedValue takes no arguments and returns an non-negative integer . It is defined piecewise over the following productions:
Vlq :: VlqDigitListWhile this specification's algorithms are defined on top of ECMA-262 internals, it is meant to be easily implementable by non-JavaScript platforms. This section contains utilities for working with JSON values , abstracting away ECMA-262 details from the rest of the document.
A JSON value is either a JSON object , a JSON array , a String , a Number , a Boolean , or null .
A JSON object is an Object such that each of its properties:
A JSON array is a JSON object such that:
The abstract operation ParseJSON takes argument string (a String) and returns a JSON value . It performs the following steps when called:
This abstract operation is in the process of being exposed by ECMA-262 itself, at
tc39/ecma262#3540.
7.2 JSONObjectGet ( object, key )The abstract operation JSONObjectGet takes arguments object (a JSON object ) and key (a String) and returns a JSON value or missing . It returns the value associated with the specified key in object. It performs the following steps when called:
The abstract operation JSONArrayIterate takes argument array (a JSON array ) and returns a List of JSON values . It returns a List containing all elements of array, so that it can be iterated by algorithms using "For each". It performs the following steps when called:
The abstract operation StringSplit takes arguments string (a String) and separators (a List of String) and returns a List of Strings. It splits the string in substrings separated by any of the elements of separators. If multiple separators match, those appearing first in separators have higher priority. It performs the following steps when called:
A Position Record is a tuple of a non-negative line and non-negative column number:
Table 1: Position Record Fields 8.2 Original Position RecordA Original Position Record is a tuple of a Decoded Source Record , a non-negative line and non-negative column number. It is similar to a Position Record but describes a source position in a concrete original source file.
Table 2: Original Position Record Fields 8.3 ComparePositions ( first, second )The abstract operation ComparePositions takes arguments first (a Position Record or a Original Position Record ) and second (a Position Record or a Original Position Record ) and returns lesser , equal or greater . It returns lesser , equal or greater depending whether first occurs before, is equal or occurs after second respectively. The [[Source]] field of Original Position Records are ignored. It performs the following steps when called:
A source map is a JSON document containing a top-level JSON object with the following structure:
{
"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
field shall always be the number 3 as an integer . The source map may be rejected if the field has any other value.file
field is an optional name of the generated code that this source map is associated with. It's not specified if this can be an URL , relative path name, or just a base name. Source map generators may choose the appropriate interpretation for their contexts of use.sourceRoot
field is an optional source root string, used for relocating source files on a server or removing repeated values in the sources entry. This value is prepended to the individual entries in the sources field .sources
field is a list of original sources used by the mappings field . Each entry is either a string that is a (potentially relative) URL or null if the source name is not known.sourcesContent
field is an optional list of source content (i.e. the original source ) strings, used when the source cannot be hosted. The contents are listed in the same order as in the sources field . Entries may be null if some original sources should be retrieved by name.names
field is an optional list of symbol names which may be used by the mappings field .mappings
field is a string with the encoded mapping data (see section 9.2 ).ignoreList
field is an optional list of indices of files that should be considered third party code, such as framework code or bundler- generated code . This allows developer tools to avoid code that developers likely don't want to see or step through, without requiring developers to configure this beforehand. It refers to the sources field and lists the indices of all the known third-party sources in the source map. Some browsers may also use the deprecated x_google_ignoreList
field if ignoreList
is not present.A Decoded Source Map Record has the following fields:
Table 3: Fields of Decoded Source Map RecordsA Decoded Source Record has the following fields:
Table 4: Fields of Decoded Source Records Field Name Value Type [[URL]] a URL or null [[Content]] a String or null [[Ignored]] a Boolean 9.1.1 ParseSourceMap ( string, baseURL )The abstract operation ParseSourceMap takes arguments string (a String) and baseURL (an URL ) and returns a Decoded Source Map Record . It performs the following steps when called:
The abstract operation DecodeSourceMap takes arguments json (a JSON object ) and baseURL (an URL ) and returns a Decoded Source Map Record . It performs the following steps when called:
The abstract operation GetOptionalString takes arguments object (a JSON object ) and key (a String) and returns a String or null . It performs the following steps when called:
The abstract operation GetOptionalListOfStrings takes arguments object (a JSON object ) and key (a String) and returns a List of Strings. It performs the following steps when called:
The abstract operation GetOptionalListOfOptionalStrings takes arguments object (a JSON object ) and key (a String) and returns a List of either Strings or null . It performs the following steps when called:
The abstract operation GetOptionalListOfArrayIndexes takes arguments object (an Object) and key (a String) and returns a List of non-negative integers . It performs the following steps when called:
The mappings field data is broken down as follows:
;
),
)The fields in each segment are:
;
), then this field holds the whole base64 VLQ . Otherwise, this field contains a base64 VLQ that is relative to the previous occurrence of this field. Note that this is different from the subsequent fields below because the previous value is reset after every generated line.The purpose of this encoding is to reduce the source map size. VLQ encoding reduced source maps by 50% relative to the
Source Map Revision 2 Proposalin tests performed using Google Calendar.
Note 2Segments with one field are intended to represent
generated codethat is unmapped because there is no corresponding
original sourcecode, such as code that is generated by a compiler. Segments with four fields represent mapped code where a corresponding name does not exist. Segments with five fields represent mapped code that also has a mapped name.
Note 3Using file offsets was considered but rejected in favor of using line/ column data to avoid becoming misaligned with the original due to platform-specific line endings.
A Decoded Mapping Record has the following fields:
Table 5: Fields of Decoded Mapping Records 9.2.1 Mappings grammarThe mappings String must adhere to the following grammar:
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 : VlqA Decode Mapping State Record has the following fields:
Table 6: Fields of Decode Mapping State Records Field Name Value Type [[GeneratedLine]] a non-negative integer [[GeneratedColumn]] a non-negative integer [[SourceIndex]] a non-negative integer [[OriginalLine]] a non-negative integer [[OriginalColumn]] a non-negative integer [[NameIndex]] a non-negative integer 9.2.1.1 DecodeMappingsFieldThe syntax-directed operation DecodeMappingsField takes arguments state (a Decode Mapping State Record ), mappings (a List of Decoded Mapping Records ), names (a List of Strings), and sources (a List of Decoded Source Records ). It is defined piecewise over the following productions:
LineList : Line ; LineListThe abstract operation DecodeMappings takes arguments rawMappings (a String), names (a List of Strings), and sources (a List of Decoded Source Records ) and returns a List of Decoded Mapping Record . It performs the following steps when called:
Generated code positions that may have mapping entries are defined in terms of input elements, as per the ECMAScript Lexical Grammar. Mapping entries shall point to either:
Source map generators should create a mapping entry with a [[Name]] field for a JavaScript token, if:
Then the [[Name]] of the mapping entry should be the name of the original source language construct. A mapping with a non-null [[Name]] is called a named mapping.
Note 1A minifier renaming functions and variables or removing function names from immediately invoked function expressions.
The following enumeration lists productions of the ECMAScript Syntactic Grammar and the respective token or non-terminal (on the right-hand side of the production) for which source map generators should emit a named mapping. The mapping entry created for such tokens shall follow section 9.2.3 .
The enumeration should be understood as the "minimum". In general, source map generators are free to emit any additional named mappings.
Note 2The enumeration also lists tokens where generators "may" emit named mappings in addition to the tokens where they "should". These reflect the reality where existing tooling emits or expects named mappings. The duplicated named mapping is comparably cheap: Indices into names are encoded relative to each other so subsequent mappings to the same name are encoded as 0 (A
).
The BindingIdentifier (s) for LexicalDeclaration , VariableStatement and FormalParameterList .
The BindingIdentifier for FunctionDeclaration , FunctionExpression , AsyncFunctionDeclaration , AsyncFunctionExpression , GeneratorDeclaration , GeneratorExpression , AsyncGeneratorDeclaration , and AsyncGeneratorExpression if it exists, or the opening parenthesis (
preceding the FormalParameters otherwise.
Source map generators may chose to emit a named mapping on the opening parenthesis regardless of the presence of the BindingIdentifier .
For an ArrowFunction or AsyncArrowFunction :
The =>
token where ArrowFunction is produced with a single BindingIdentifier for ArrowParameters or AsyncArrowFunction is produced with an AsyncArrowBindingIdentifier .
This describes the case of (async) arrow functions with a single parameter, where that single parameter is not wrapped in parenthesis.
The opening parenthesis (
where ArrowFunction or AsyncArrowFunction is produced with ArrowFormalParameters .
Source map generators may chose to additionally emit a named mapping on the =>
token for consistency with the previous case.
The ClassElementName for MethodDefinition . This includes generators, async methods, async generators and accessors. For MethodDefinition where ClassElementName is "constructor" , the [[Name]] should be the original class name if applicable.
Source map generators may chose to additionally emit a named mapping on the opening parenthesis (
.
Source map generators may emit named mapping for IdentifierReference in Expression .
If the sources are not absolute URLs after prepending the sourceRoot, the sources are resolved relative to the source map (like resolving the script src
attribute in an HTML document).
The abstract operation DecodeSourceMapSources takes arguments baseURL (an URL ), sourceRoot (a String or null ), sources (a List of either Strings or null ), sourcesContent (a List of either Strings or null ), and ignoreList (a List of non-negative integers ) and returns a Decoded Source Record . It performs the following steps when called:
Implementations that support showing source contents but do not support showing multiple sources with the same
URLand different content will arbitrarily choose one of the various contents corresponding to the given
URL.
9.4 ExtensionsSource map consumers shall ignore any additional unrecognized properties, rather than causing the source map to be rejected, so that additional features can be added to this format without breaking existing users.
10 Index source mapTo support concatenating generated code and other common post-processing, an alternate representation of a source map is supported:
{
"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"
}
}
]
}
The index map follows the form of the standard map. Like the regular source map, the file format is JSON with a top-level object. It shares the version and file field from the regular source map, but gains a new sections field .
The sections
field is an array of objects with the following fields:
offset
field is an object with two fields, line
and column
, that represent the offset into generated code that the referenced source map represents.map
field is an embedded complete source map object. An embedded map does not inherit any values from the containing index map.The sections shall be sorted by starting position and the represented sections shall not overlap.
10.1 DecodeIndexSourceMap ( json, baseURL )The abstract operation DecodeIndexSourceMap takes arguments json (an Object) and baseURL (an URL ) and returns a Decoded Source Map Record . It performs the following steps when called:
Implementations may choose to represent index source map sections without appending the mappings together, for example, by storing each section separately and conducting a binary search.
11 Retrieving source maps 11.1 Linking generated code to source mapsWhile the source map format is intended to be language and platform agnostic, it is useful to define how to reference to them for the expected use-case of web server-hosted JavaScript.
There are two possible ways to link source maps to the output. The first requires server support in order to add an HTTP header and the second requires an annotation in the source.
Source maps are linked through URLs as defined in WHATWG URL ; in particular, characters outside the set permitted to appear in URIs shall be percent-encoded and it may be a data URI. Using a data URI along with sourcesContent allows for a completely self-contained source map.
The HTTP sourcemap
header has precedence over a source annotation, and if both are present, the header URL should be used to resolve the source map file.
Regardless of the method used to retrieve the source map URL the same process is used to resolve it, which is as follows.
When the source map URL is not absolute, then it is relative to the generated code 's source origin. The source origin is determined by one of the following cases:
If the generated source is not associated with a script element that has a src
attribute and there exists a //# sourceURL
comment in the generated code , that comment should be used to determine the source origin .
Previously, this was //@ sourceURL
, as with //@ sourceMappingURL
, it is reasonable to accept both but //#
is preferred.
src
attribute, the src
attribute of the script element will be the source origin .src
attribute, then the source origin will be the page's origin.eval()
function or via new Function()
, then the source origin will be the page's origin.The generated code should include a comment, or the equivalent construct depending on its language or format, named sourceMappingURL
and that contains the URL of the source map. This specification defines how the comment should look like for JavaScript, CSS, and WebAssembly. Other languages should follow a similar convention.
For a given language there can be multiple ways of detecting the sourceMappingURL
comment, to allow for different implementations to choose what is less complex for them. The generated code unambiguously links to a source map if the result of all the extraction methods is the same.
If a tool consumes one or more source files that unambiguously links to a source map and it produces an output file that links to a source map, it shall do so unambiguously .
Note 1The following JavaScript code links to a source map, but it does not do so unambiguously :
let a = `
//# sourceMappingURL=foo.js.map
//`
Extracting a source map URL from it through parsing gives null , while without parsing gives foo.js.map
.
Having multiple ways to extract a source map URL , that can lead to different results, can have negative security and privacy implications. Implementations that need to detect which source maps are potentially going to be loaded are strongly encouraged to always apply both algorithms, rather than just assuming that they will give the same result.
A fix to this problem is being worked on, and is expected to be included in a future version of the standard. It will likely involve early returning from the below algorithms whenever there is a comment (or comment-like) that contains the characters U+0060 (`), U+0022 ("), or U+0027 ('), or the the sequence U+002A U+002F (*/).
name
of customSection.bytes
of customSection.Since WebAssembly is not a textual format and it does not support comments, it supports a single unambiguous extraction method. The URL is encoded as a WebAssembly name , and it's placed as the content of the custom section . It is invalid for tools that generate WebAssembly code to generate two or more custom sections with the sourceMappingURL
name.
The abstract operation FetchSourceMap takes argument url (an URL ) and returns a Promise. It performs the following steps when called:
)]}'
` is a byte-sequence-prefix of bodyBytes, then
For historic reasons, when delivering source maps over HTTP(S), servers may prepend a line starting with the string )]}'
to the source map.
)]}'garbage here
{"version": 3, ...}
is interpreted as
{"version": 3, ...}
Annex A (informative) Conventions
The following conventions should be followed when working with source maps or when generating them.
A.1 Source map namingCommonly, a source map will have the same name as the generated file but with a .map
extension. For example, for page.js
a source map named page.js.map
would be generated.
There is an existing convention that should be supported for the use of source maps with eval'd code, it has the following form:
It is described in Give your eval a name with //@ sourceURL .
Annex B (informative) Notes B.1 Language neutral stack mappingStack tracing mapping without knowledge of the source language is not covered by this document.
B.2 Multi-level mappingIt is getting more common to have tools generate sources from some DSL (templates) or compile TypeScript → JavaScript → minified JavaScript, resulting in multiple translations before the final source map is created. This problem can be handled in one of two ways. The easy but lossy way is to ignore the intermediate steps in the process for the purposes of debugging, the source location information from the translation is either ignored (the intermediate translation is considered the “Original Source”) or the source location information is carried through (the intermediate translation hidden). The more complete way is to support multiple levels of mapping: if the Original Source also has a source map reference, the user is given the choice of using that as well.
However, it is unclear what a "source map reference" looks like in anything other than JavaScript. More specifically, what a source map reference looks like in a language that doesn't support JavaScript-style single-line comments.
Annex C (informative) Terms defined in other specificationsThis section lists all terms and algorithms used by this document defined by external specifications other than ECMA-262.
This specification is authored on GitHub in a plaintext source format called Ecmarkup. Ecmarkup is an HTML and Markdown dialect that provides a framework and toolset for authoring ECMAScript specifications in plaintext and processing the specification into a full-featured HTML rendering that follows the editorial conventions for this document. Ecmarkup builds on and integrates a number of other formats and technologies including Grammarkdown for defining syntax and Ecmarkdown for authoring algorithm steps. PDF renderings of this specification are produced by printing the HTML rendering to a PDF.
The first edition of this specification was authored using Bikeshed, a different plaintext source format based on HTML and Markdown.
Pre-standard versions of this document were authored using Google Docs.
Copyright & Software LicenseEcma 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 LicenseAll 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:
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.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4