• Stars
    star
    677
  • Rank 66,694 (Top 2 %)
  • Language
  • License
    MIT License
  • Created over 9 years ago
  • Updated about 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

stage-0 to stage-4 ECMAscript proposals.

stage-0 to stage-4 ECMAscript proposals.

TOC:

Stage 0:

Defensible Classes

Stage-0

// const class

const class Point { 
  constructor(x, y) {
    public getX() { return x; }
    public getY() { return y; }
  }
  toString() { 
    return `<${this.getX()}, ${this.getY()}>`;
  }
}

Relationships

Stage-0

x @ r // The object x is in the r relationship with what value?
x @ r = y; // Store that x is in the r relationship with value y.

String.prototype.at

Stage-0

'abcπŒ†def'.at(3)
// β†’ 'πŒ†'

Reflect.isCallable

Stage-0

Reflect.isCallable(argument);

Reflect.isConstructor

Stage-0

Reflect.isConstructor(argument)

Additional metaproperties

Stage-0

function.callee; // function object that is currently being evaluated by the running execution context.
function.count; // number of arguments pass to the function. 
function.arguments; // array containing the actual arguments passed to the function.

Function Bind Syntax

Stage-0

// :: which performs this binding and method extraction.

Promise.resolve(123).then(::console.log);

64-Bit Integer Operations

Stage-0

// return the high 32 bit part of the 64 bit addition of (hi0, lo0) and (hi1, lo1)
Math.iaddh(lo0, hi0, lo1, hi1);

// return the high 32 bit part of the 64 bit subtraction of (hi0, lo0) and (hi1, lo1)
Math.isubh(lo0, hi0, lo1, hi1);

// return the high 32 bit part of the signed 64 bit product of the 32 bit numbers a and b
Math.imulh(a, b);

// return the high 32 bit part of the unsigned 64 bit product of the 32 bit numbers a and b
Math.umulh(a, b);

Method Parameter Decorators

Stage-0

//decorators that operate on method and constructor parameters.

class MyComponent {
  refresh(@lastRefreshTime timeStamp) { … }
}

export function lastRefreshTime(...) {
  // at minimum, the arguments of this function should contain:
  // - reference to owner of the parameter (the method)
  // - parameter index
  // - parameter name
  // - is parameter a rest parameter?

  // store parameter metadata using the same storage mechanism
  // as the one used for methods
}

Function Expression Decorators

Stage-0

scheduleForFrequentReexecution(@memoize function(value) { 
  value++
});

export function memoize(...) {
  // at minimum, the arguments of this function should contain:
  // - reference to the decorated function expression
  // - arguments passed into the memoize function (if any)

  // wrap the decorated function expression memoization implementation and return it
}

Zones

Stage-0

//a primitive for context propagation across multiple logically-connected async operations

class Zone {
  constructor({ name, parent });

  name;
  get parent();

  fork({ name });
  run(callback);
  wrap(callback);

  static get current();
}

const loadZone = Zone.current.fork({ name: "loading zone" });
window.onload = loadZone.wrap(e => { ... });

Object enumerables

Stage-0

Object.enumerableKeys(obj); // Ordered list of keys.
Object.enumerableValues(obj); // Ordered list of Values.
Object.enumerableEntries(obj); //Ordered list of key value pairs.

Nested import declarations

Stage-0

describe("fancy feature #5", () => {
  import { strictEqual } from "assert";

  it("should work on the client", () => {
    import { check } from "./client.js";
    strictEqual(check(), "client ok");
  });

  it("should work on the client", () => {
    import { check } from "./server.js";
    strictEqual(check(), "server ok");
  });

  it("should work on both client and server", () => {
    import { check } from "./both.js";
    strictEqual(check(), "both ok");
  });
});

is{Type} APIs

Stage-0

Builtin.is(Date, vm.runInNewContext('Date'));     // false


Builtin.typeOf([]);                             // 'Array'
Builtin.typeOf(new ArrayBuffer());              // 'ArrayBuffer'
Builtin.typeOf(async function foo() {}); 
// So on.

Orthogonal Class Member Syntax

Stage-0

//A kitchen sink example
class Foo {
  //instance members
  own x=0, y=0;  // two data properties
  own #secret;   // a private field
                 // initial value undefined
  own *[Symbol.iterator](){yield this.#secret}
                 // a generator method
  own #callback(){}  //a private instance method  
  //class constructor members               
  static #p=new Set(), q=Foo.#p;
                // a private field and a property
                // of the class constructor                     
  static get p(){return Foo.#p} //accessor method     
  //prototype methods                
  setCallback(f){this.#callback=f}
  constructor(s){
     this.#secret = s;
  }
}

Pattern Matching Syntax

Stage-0

let getLength = vector => match (vector) {
    { x, y, z }: Math.sqrt(x ** 2 + y ** 2 + z ** 2),
    { x, y }:    Math.sqrt(x ** 2 + y ** 2),
    [...]:       vector.length,
    else: {
        throw new Error("Unknown vector type");
    }
}

Structured cloning and transfer

Stage-0

StructuredClone(input, transferList, targetRealm)

WHATWG URL

Stage-0

const base = new URL('http://example.org/foo');
const url = new URL('bar', base);

Stage 1:

export v from "mod"; statements

Stage-1

export v, {x, y as w} from "mod";

export v, * as ns from "mod";

Observable

Stage-1

// Observable as a Constructor:
function listen(element, eventName) {
    return new Observable(observer => {
        // Create an event handler which sends data to the sink
        let handler = event => observer.next(event);

        // Attach the event handler
        element.addEventListener(eventName, handler, true);

        // Return a function which will cancel the event stream
        return () => {
            // Detach the event handler from the element
            element.removeEventListener(eventName, handler, true);
        };
    });
}

// Observable.of creates an Observable of the values provided as arguments
Observable.of("R", "G", "B").subscribe({
    next(color) {
        console.log(color);
    }
});

// Observable.from converts its argument to an Observable.
Observable.from(["R", "G", "B"]).subscribe({
    next(color) {
        console.log(color);
    }
});

String.prototype.matchAll

Stage-1

var str = 'Hello world!!!';
var regexp = /(\w+)\W*/g;
console.log(str.matchAll(regexp));

/*
[
  {
    0: "Hello ",
    1: "Hello"
    index: 0,
    input: "Hello world!!!"
  },
  {
    0: "world!!!",
    1: "world"
    index: 6,
    input: "Hello world!!!"
  }
]
*/

WeakRefs

Stage-1

// Make a new weak reference.
// The target is a strong pointer to the object that will be pointed
// at weakly by the result.
// The executor is an optional argument that will be invoked after the
// target becomes unreachable.
// The holdings is an optional argument that will be provided to the
// executor when it is invoked for target.
makeWeakRef(target, executor, holdings);

Frozen Realms

Stage-1

class Realm {
  // From the prior Realm API proposal
  const global -> object                // access this realm's global object
  eval(stringable) -> any               // do an indirect eval in this realm

  // We expect the rest of earlier proposal to be re-proposed eventually in
  // some form, but do not rely here on any of the remainder.

  // New with this proposal
  static immutableRoot() -> Realm       // transitively immutable realm
  spawn(endowments) -> Realm            // lightweight child realm
}

Math Extensions

Stage-1

// Possible ones:
Math.map
Math.scale
Math.remap
Math.clamp
Math.constrain
Math.toDegrees(double angrad)
Math.toRadians(double angdeg)

of and from on collection constructors

Stage-1

Map.of( ...items );
Map.from( ...items );

Set.of( ...items );
Set.from( ...items );

WeakMap.of( ...items );
WeakMap.from( ...items );

WeakSet.of( ...items );
WeakSet.from( ...items );

Generator arrow functions.

Stage-1

let cat = *() => { yield 'meow'; }

Date.parse fallback semantics

Stage-1

//  New grammar should be used as the "fallback" 
//  when date strings do not conform to the 
//  regular Date Time String Format.

Generator arrow functions (=>*)

Stage-1

// current
x => x * x;
(...) => { statements }
(...) => ( expr )

// proposed generator arrows...

// Irregular
() =*>

// Hostile to ! (async function)
() => * { ...yield... }

// Not good
() => * (yield a, yield b)

// Ok if 1 token
x *=> x * x;

// Bad (ASI)
*() => ...

// Hostile to !
(x) =* {...}

Promise.try

Stage-1

// Promise.try(function() fn) -> Promise

of and from on collection

Stage-1

CollectionCreate ( C, source [ , mapfn [ , thisArg ] ] )

Map.of ( ...items )
Set.of ( ...items )
WeakMap.of ( ...items )
WeakSet.of ( ...items )

Map.from ( source [ , mapFn [ , thisArg ] ] )
Set.from ( source [ , mapFn [ , thisArg ] ] )
WeakMap.from ( source [ , mapFn [ , thisArg ] ] )
WeakSet.from ( source [ , mapFn [ , thisArg ] ] )

Optional Chaining

Stage-1

obj?.prop         // optional property access
obj?.[expr]       // ditto
func?.(...args)   // optional function or method call
new C?.(...args)  // optional constructor invocation

Math.signbit: IEEE-754 sign bit

Stage-1

Math.signbit(x);

/*
Returns whether the sign bit of x is set.

If n is NaN, the result is false.
If n is -0, the result is true.
If n is negative, the result is true.
Otherwise, the result is false.
*/

Error Stacks

Stage-1

Error.prototype.stack;
System.getStack;
System.getStackString;


Object.getOwnPropertyDescriptor(new Error(), 'stack');
Object.getOwnPropertyDescriptor(Error.prototype, 'stack');

do expressions

Stage-1

let x = do {
  let tmp = f();
  tmp * tmp + 1
};

let x = do {
  if (foo()) { f() }
  else if (bar()) { g() }
  else { h() }
};

Realms

Stage-1

let realm = new Realm();

let outerGlobal = window;
let innerGlobal = realm.global;

let f = realm.evalScript("(function() { return 17 })");

f() === 17 // true

Reflect.getPrototypeOf(f) === outerGlobal.Function.prototype // false
Reflect.getPrototypeOf(f) === innerGlobal.Function.prototype // true


class EmptyRealm extends Realm {
  constructor(...args) { super(...args); }
  init() { /* do nothing */ }
}


class FakeWindow extends Realm {
  init() {
    super.init(); // install the standard primordials
    let global = this.global;

    global.document = new FakeDocument(...);
    global.alert = new Proxy(fakeAlert, { ... });
    ...
  }
}

Stage 2:

Template Literal Revision

Stage-2

// The proposal is about fixing those Illegal token errors, avoid restrictions on escape sequences. 
let document = latex`
\newcommand{\fun}{\textbf{Fun!}}  // works just fine
\newcommand{\unicode}{\textbf{Unicode!}} // Illegal token!
\newcommand{\xerxes}{\textbf{King!}} // Illegal token!

Breve over the h goes \u{h}ere // Illegal token!

function.sent Meta Property

Stage-2

// Avoid ingnoring the first `next` call.
function *adder(total=0) {
   let increment=1;
   do {
       switch (request = function.sent){
          case undefined: break;
          case "done": return total;
          default: increment = Number(request);
       }
       yield total += increment;
   } while (true)
}

let tally = adder();
tally.next(0.1); // argument no longer ignored
tally.next(0.1);
tally.next(0.1);
let last=tally.next("done");
console.log(last.value);  //0.3

Class Property Declarations

Stage-2

// Class instance field
class MyClass {
  myProp = 42;

  constructor() {
    console.log(this.myProp); // Prints '42'
  }
}


// Static property
class MyClass {
  static myStaticProp = 42;

  constructor() {
    console.log(MyClass.myStaticProp); // Prints '42'
  }
}
// Class Static Properties

class MyClass {
  static myStaticProp = 42;

  constructor() {
    console.log(MyClass.myStaticProp); // Prints '42'
  }
}

Class and Property Decorators

Stage-2

class C {
  @writable(false)
  method() { }
}

function writable(value) {
  return function (target, key, descriptor) {
     descriptor.writable = value;
     return descriptor;
  }
}

String.prototype.{trimStart,trimEnd}

Stage-2

"    Hey JS!".trimStart(); // "Hey JS!"

"    Hey JS!    ".trimEnd();// "    Hey JS!"

// P.S: trimLeft/trimRight are aliases.

Legacy RegExp features

Stage-2

RegExpAlloc( newTarget );

RegExpBuiltInExec( R, S );

RegExp.input;

RegExp.prototype.compile( pattern, flags ); // modifications

Intl.Segmenter: Unicode segmentation

Stage-2

// Create a segmenter in your locale
let segmenter = Intl.Segmenter("fr", {type: "word"});

// Get an iterator over a string
let iterator = segmenter.segment("Ceci n'est pas une pipe");

// Iterate over it!
for (let {segment, breakType} of iterator) {
  console.log(`segment: ${segment} breakType: ${breakType}`);
  break;
}

// logs the following to the console:
// index: Ceci breakType: letter

export * as ns from "mod"; statements

Stage-2

export * as ns from "mod";  // Exporting the ModuleNameSpace object as a named export.

Stage 3:

global

Stage-3

// global to rule them all.

var getGlobal = function () {
    // the only reliable means to get the global object is
    // `Function('return this')()`
    // However, this causes CSP violations in Chrome apps.
    if (typeof self !== 'undefined') { return self; }
    if (typeof window !== 'undefined') { return window; }
    if (typeof global !== 'undefined') { return global; }
    throw new Error('unable to locate global object');
};

Rest and Spread properties

Stage-3

let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 }; // Rest.


let n = { x, y, ...z }; // Spread.

Async-iteration

Stage-3

asyncIterator
  .next()
  .then(({ value, done }) => /* ... */);

Function.prototype.toString revision

Stage-3

// String's parse must contains the same
// function body and parameter list as the original.

O.gOPD({ get a(){} }, "a").get // "function a(){}"

O.gOPD({ set a(b){} }, "a").set // "function a(b){}"

SIMD APIs

Stage-3

/*a meta-variable ranging over all SIMD types:
  Float32x4, Int32x4, Int16x8 Int8x16, Uint32x4, 
  Uint16x8, Uint8x16, Bool32x4, Bool16x8 and Bool8x16. */

Lifting Template Literal Restriction

Stage-3

function tag(strs) {
  strs[0] === undefined
  strs.raw[0] === "\\unicode and \\u{55}";
}
tag`\unicode and \u{55}`

let bad = `bad escape sequence: \unicode`; // throws early error

Shared memory and atomics

Stage-3

var sab = new SharedArrayBuffer(1024);  // 1KiB shared memory

w.postMessage(sab, [sab])

// In the worker:

var sab;
onmessage = function (ev) {
   sab = ev.data;  // 1KiB shared memory, the same memory as in the parent
}

global

stage 3

typeof global; // object, helps in writing a portable code.

import()

stage 3

import(`./language-packs/${navigator.language}.js`) // import(specifier)

RegExp Lookbehind Assertions

Stage-3

const str = '1947';

// (?<=(\d+)(\d+))$/ => (947) and (1)
// Greediness proceeds from right to left


// match[1] => 947 and match[2] => 1
// Numbering capture groups

// /(?<=\1(.))/
// Referring to capture groups

// /(?<!.)/
// Negative assertions

Unicode property escapes in RE

Stage-3

const regexGreekSymbol = /\p{Script=Greek}/u;
regexGreekSymbol.test('Ο€');

RegExp Named Capture Groups

Stage-3

let {one, two} = /^(?<one>.*):(?<two>.*)$/u.exec('foo:bar');
console.log(`one: ${one}, two: ${two}`);  // prints one: foo, two: bar

s (dotAll) flag for regular expressions

Stage-3

const re = /foo.bar/s; // Or, `const re = new RegExp('foo.bar', 's');`.
re.test('foo\nbar');
// β†’ true
re.dotAll
// β†’ true
re.flags
// β†’ 's'

/foo.bar/s.test('foo\nbar');
// β†’ true

Asynchronous Iterators

Stage-3

asyncIterator.next().then(result => console.log(result.value));


for await (let line of readLines(filePath)) {
    print(line);
}

async function *readLines(path) {

    let file = await fileOpen(path);

    try {

        while (!file.EOF)
            yield file.readLine();

    } finally {

        await file.close();
    }
}

Promise.prototype.finally

Stage-3

somePromise()
.then(() => {})
.catch(() => {})
.finally(() => {})

Class Fields

Stage-3

class Point {
    #x = 0;  // private fields start with #
    myProp = 42; // public field

    constructor() {
        this.#x; // 0
        this.myProp; // 0
    }
}

More Repositories

1

functional-programming-jargon

Jargon from the functional programming world in simple terms!
18,586
star
2

awesome-pwa

Awesome list of progressive web apps! (PR welcomed ;))
4,416
star
3

paws-on-es6

Minimalist examples of ES6 functionalities.
JavaScript
332
star
4

awesome-now

Awesome list of `now.sh` deployments.
238
star
5

node-nightly

node-nightly at your fingertips!
JavaScript
233
star
6

koa-rest

REST demo with koa.
JavaScript
218
star
7

coffeescript-equivalents-in-es6

CoffeeScript Equivalents In ES6
157
star
8

jsfeatures.in

All javascript features under one hood!
HTML
104
star
9

cors-now

reverse proxy with CORS headers.
JavaScript
96
star
10

awesome-dev-domains

List of awesome `.dev` domains.
53
star
11

generator-pwa

Yeoman generator for a progressive webapp.
JavaScript
51
star
12

is-pwa

Detects if a given URL is a Progressive WebApp (PWA.)
JavaScript
46
star
13

nmotw.in

Node Module Of The Week
HTML
40
star
14

head-it

Easy interface for `head`
JavaScript
40
star
15

generator-atom

Yeoman generator for atom editor packages.
JavaScript
39
star
16

cds

Chrome DevSummit Notes
37
star
17

node-prepend-file

Prepend data to a file.
JavaScript
34
star
18

power-off

Cross OS power-off.
JavaScript
33
star
19

ollama-models

Repository of Ollama Models!
Python
30
star
20

interview-time

Prepare for your technical interviews!
JavaScript
29
star
21

futhark

Collection of all my old and new scripts written in bash, python, ruby and more
PHP
29
star
22

bangalore-startups

Ever growing list of startups in Bangalore.
JavaScript
28
star
23

config-hyperterm

Easily set/get `hyperterm` config.
JavaScript
28
star
24

es6-lab-setup

Setup your ES6 Lab.
JavaScript
27
star
25

ramda-repl

Ramdajs REPL.
JavaScript
27
star
26

curl-to-fetch

Parse curl commands and returns `fetch` API equivalent.
JavaScript
25
star
27

hello-falcor

A simple faclor.js example.
HTML
22
star
28

manifest-json

Creates manifest.json for your PWA.
JavaScript
22
star
29

why-babies-cry

A desperate attempt to list them all!
21
star
30

blns

Big List of Naughty Strings.
JavaScript
21
star
31

gulp-cleanhtml

remove unneeded whitespaces, line-breaks, comments, etc from the HTML.
JavaScript
19
star
32

atom-mdurl

Convert normal url to md style. My birthday gift for @sindresorhus using his own module ;)
CoffeeScript
19
star
33

greener

Fetches all your node modules and keeps them green, with greenkeeper.
JavaScript
19
star
34

grunt-usemin-example

Minimalist example of grunt-usemin.
JavaScript
18
star
35

quotes

My fav quotes.
HTML
18
star
36

algorithms

Implementations of most commonly used algorithms in various languages. Thanks a ton to the wiki's which provided pesudo codes
Java
17
star
37

graphql-demo

Simple graphql server app.
JavaScript
17
star
38

gulp-jstransform

Gulp plugin to transform ES6 to ES5.
JavaScript
16
star
39

video-in-view

Play/Pause video when in/out of the view.
JavaScript
16
star
40

algorithms-es6

Basic Algorithm Implementation with ES6.
16
star
41

p2pu

Scripting 101 on p2pu
Shell
16
star
42

react-mui-base

BaseComponent for react-material-ui
JavaScript
15
star
43

joel-test

Rate the quality of a software team!
JavaScript
14
star
44

haskell-rascal

Learning haskell with a rascal!
14
star
45

blood-donor

Donors for a blood type.
JavaScript
13
star
46

test-card

Credit, Debit and Prepaid cards for testing.
JavaScript
13
star
47

speech-synthesis

Speaks using the Web Speech API.
JavaScript
13
star
48

liked

I liked
12
star
49

xkcd-img

Custom Polymer element for displaying random images from XKCD!
HTML
12
star
50

video-bg

Custom polymer element to set a responsive video as your HTML background.
HTML
12
star
51

life-expectancy

Life expectancy of humans across the global.
JavaScript
12
star
52

is-iterable

Checks if a given object is iterable.
JavaScript
11
star
53

flat-xkcd

Exploring Flat Data Workflow
JavaScript
11
star
54

is-incognito

Detects incognito mode.
JavaScript
11
star
55

battery-status

Custom Polymer element for dispalying battery status.
HTML
11
star
56

node-yoda-said

Yoda quotes on CLI a trribute to Master Yoda!
JavaScript
11
star
57

react-suspense-sample

Async Image Loading with React Suspense
JavaScript
11
star
58

gulp-html2txt

gulp plugin to convert html file to txt.
JavaScript
10
star
59

node-rsj

rss as json
JavaScript
10
star
60

debug-yeoman-generator

Simple bash util script that helps you to debug yeoman generators.
Shell
10
star
61

is-mp3

Check if a Buffer/Uint8Array is MP3 file.
JavaScript
10
star
62

nw-wiki-app

A simple sample app to demo the usage of node-webkit.
JavaScript
10
star
63

tc39-members

TC39 members list.
10
star
64

github-upstreamer

Auto configure a remote for a fork!
JavaScript
10
star
65

fetch-task

fetch API as a Task.
JavaScript
10
star
66

rgbot

XMPP Gmail Bot in rb ; rb+gmail+bot => rgbot
Ruby
10
star
67

make-quote

Type a quote and get an image of the same.
CSS
9
star
68

get-hosts

`etc/hosts` as an array of objects.
JavaScript
9
star
69

orly-cover-bot

The source that is governing https://twitter.com/OreillyCover
JavaScript
9
star
70

gulp-html2jade

gulp plugin to convert HTML to Jade format.
JavaScript
9
star
71

gulp-html2jsx

Converts HTML to JSX for use with React.
JavaScript
9
star
72

react-currency-conversion

Component to convert currency on the current exchange rates.
JavaScript
9
star
73

xkcd-gem

XCKD ruby gem to get random img url or comic urls
Ruby
9
star
74

sanskrit-dict

Sanskrit dictionary.
JavaScript
8
star
75

node-octodex

Get random octodex images from github's octodex.
JavaScript
8
star
76

node-xkcd-img

xkcd-img module for node.js
JavaScript
8
star
77

time-taken

Get the execution time of a function.
JavaScript
8
star
78

local-time

Custom Polymer time element, to convert UTC to local time.
HTML
8
star
79

network-type

Get the network type.
JavaScript
8
star
80

node-systemize

Systemize your junkyard. (Organise your files.)
JavaScript
8
star
81

generator-amp

generator for AMP.
JavaScript
7
star
82

react-native-xkcd

Loads random XKCD comics (WIP)
Objective-C
7
star
83

gulp-hogan

gulp plugin to compile mustache templates
JavaScript
7
star
84

github-avatar-url

Get github's avatar URL either by `username` or `email`.
JavaScript
7
star
85

gandhi-quotes

Gandhi quotes on CLI a trribute to Gandhi!
JavaScript
7
star
86

GandhiSaid

Simple react-native app to get random quotes of Gandhi on each tap.
Objective-C
7
star
87

Map.prototype.toJSON

ES7 Map.prototype.toJSON polyfill.
JavaScript
7
star
88

gntr

Tree traversal with ES6 generator
JavaScript
7
star
89

inline-elements

Array of "inline elements" defined by the HTML specification.
JavaScript
7
star
90

exude

Execute the OS specific command.
JavaScript
7
star
91

node-lie-fs

Promise wrappers for Node's file system.
JavaScript
6
star
92

PaLM-CLI-Bot

CLI Chat bot using PaLM API
Python
6
star
93

crypto-jargon

Lingo from cryptocurrencies, trading, blockchain et.al. [WIP]
6
star
94

screen-type

Simple util to detect the screen-type.
JavaScript
6
star
95

grunt-html2jsx

Converts HTML to JSX for use with React.
JavaScript
6
star
96

is-flac

Check if a Buffer/Uint8Array is a FLAC file.
JavaScript
6
star
97

math-pad

Simple electron app for doing your math.
CSS
6
star
98

is-wav

Check if a Buffer/Uint8Array is a WAV file.
JavaScript
6
star
99

wikiquote-gem

Quote of the day from wikiquotes
Ruby
6
star
100

is-ogg

Check if a Buffer/Uint8Array is a OGG file.
JavaScript
6
star