Created
February 22, 2016 04:49
-
-
Save cb1kenobi/b176efe4d2ab971ee1b6 to your computer and use it in GitHub Desktop.
ES2015/6 Examples
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const koa = require('koa'); | |
const app = koa(); | |
// logger | |
app.use(async (ctx, next) => { | |
const start = new Date; | |
await next(); | |
const ms = new Date - start; | |
console.log('%s %s - %s', this.method, this.url, ms); | |
}); | |
// response | |
app.use(async ctx => { | |
this.body = 'Hello World'; | |
}); | |
app.listen(3000); | |
function sleep(ms) { | |
return new Promise((resolve, reject) => { | |
setTimeout(resolve, ms); | |
}); | |
} | |
async function noClueWhatImDoing(ms) { | |
await sleep(ms); | |
} | |
Promise.resolve() | |
.then(noClueWhatImDoing) | |
.then(() => { | |
console.log('This should work. No idea. Too tired to test.'); | |
}); | |
import thingsThatTakeForever from './foo'; | |
import { add, subtract } from './foo'; | |
import { bar } from './foo'; | |
export * from './foo'; | |
thingsThatTakeForever(); | |
console.log(add(3, 5)); // 8 | |
console.log(subtract(10, 3)); // 7 | |
console.log(typeof bar); // undefined | |
export default () => { | |
console.log('This presentation'); | |
} | |
export function add(x, y) { | |
return x + y; | |
} | |
export function subtract(x, y) { | |
return x - y; | |
} | |
const movies = { | |
adventure: 'Sleepy Hollow', | |
fantasy: 'Sleeping Beauty', | |
romantic: 'Sleepless in San Jose' | |
}; | |
Object.entries(movies).forEach(([genre, title]) => { | |
console.log(`${title} is a ${genre}`); | |
}); | |
const top3 = { | |
'no time for': 'sleep', | |
'hope to be done by': '5am', | |
'probably be done by': 'Feb 10th' | |
}; | |
Object.values(top3).forEach(v => console.log(v)); | |
const people = {}; | |
Object.assign(people, { gotSleep: 'Rick' }, { didntGetSleep: 'Chris' }); | |
console.log(people); // Object { gotSleep: 'Rick', didntGetSleep: 'Chris' } | |
const thingsImStartingToSee = Object.assign({}, { | |
unicorns: true, | |
'a bed': false, | |
'Trump as president': NaN | |
}); | |
// ES7 | |
class WouldKillFor { | |
constructor(killFor) { | |
console.log('You would kill for %s', killFor.join(', ')); | |
} | |
call constructor(killFor) { | |
return new WouldKillFor(killFor); | |
} | |
} | |
const zzz = new WouldKillFor(['bed', 'pillow']); | |
const zzzz = WouldKillFor(['8 hours of sleep', 'my teddy bear']); | |
// ES6 | |
function WantList(expensiveShit) { | |
if (!new.target) { | |
throw new Error(`Uh ah cupcake, you can't get none`); | |
} | |
this.expensiveShit = expensiveShit; | |
} | |
let want = WantList([ | |
'Winning Powerball numbers', | |
`Small island shaped like Rick's head` | |
]); | |
// ES5 | |
function NeedList(crap) { | |
// don't do this | |
if (!(this instanceof NeedList)) { | |
return new NeedList(crap); | |
} | |
this.crap = crap; | |
} | |
let need = NeedList(['sleep', 'sleep', 'sleep']); | |
let settleFor = new NeedList(['caffiene', 'caffiene', 'caffiene']); | |
const rick = new Promise((resolve, reject) => { | |
setTimeout(() => { | |
console.log('Rick finished!'); | |
resolve('Rick'); | |
}, 3000); | |
}); | |
const chris = new Promise((resolve, reject) => { | |
setTimeout(() => { | |
console.log('Chris finished!'); | |
resolve('Chris'); | |
}, 500); | |
}); | |
Promise.race([rick, chris]) | |
.then(winner => { | |
console.log(`The winner is ${winner}`); | |
}); | |
function executor(resolve, reject) { | |
setTimeout(resolve, 100); | |
} | |
const p1 = new Promise(executor); | |
const p2 = new Promise(executor); | |
const p3 = new Promise(executor); | |
Promise.all([p1, p2, p3]) | |
.then(() => { | |
console.log('Done!'); | |
}); | |
Promise.resolve('coffee') | |
.then(drink => { | |
return new Promise((resolve, reject) => { | |
console.log(`Slamming down some ${drink}`); | |
setTimeout(() => resolve('Mountain Dew'), 100); | |
}); | |
}) | |
.then(drink => { | |
console.log(`Slamming down some ${drink}`); | |
return Promise.resolve('Red Bull'); | |
}) | |
.then(drink => { | |
return new Promise((resolve, reject) => { | |
console.log(`Slamming down some ${drink}`); | |
reject(new Error('Heart attack!')); | |
}); | |
}) | |
.catch(err => { | |
console.error(err); | |
}); | |
function sleep(ms) { | |
return new Promise((resolve, reject) => { | |
setTimeout(resolve, ms); | |
}); | |
} | |
sleep(8 * 60 * 60 1000) | |
.then(wakeUp) | |
.then(goPotty) | |
.then(shower) | |
.then(sprintToPresentation) | |
.then(returnForClothes) | |
.then(rambleForTwoHours) | |
.catch(cry); | |
import autobind from 'autobind-decorator'; | |
import { readonly } from 'core-decorators'; | |
class Car { | |
constructor(type) { | |
this.type = type; | |
} | |
@readonly | |
tires = 4; | |
baldTires = 0; | |
@autobind | |
burnRubber() { | |
this.baldTires = this.tires; | |
} | |
} | |
const car = new Car('Tesla'); | |
function burnBabyBurn(burn) { | |
burn(); | |
} | |
burnBabyBurn(car.burnRubber); | |
class Employee { | |
coolAs = Employee.coolness[0]; | |
constructor(name) { | |
this.name = name; | |
} | |
static setCoolness(emp, coolFactor) { | |
emp.coolAs = Employee.coolness[coolFactor]; | |
} | |
static coolness = { | |
0: 'Vanilla Ice', | |
1: 'Coolio', | |
2: 'Ice Cube', | |
Infinity: 'Ice Motherfuckin T' | |
}; | |
} | |
const emp = new Employee('Chris'); | |
Employee.setCoolness(emp, Infinity); | |
console.log(`${emp.name} is as cool as ${emp.coolAs}`); | |
class Employee { | |
constructor(name, location) { | |
this.name = name; | |
this.location = location; | |
} | |
get name() { | |
return this.upper(this._name); | |
} | |
set name(name) { | |
this._name = this.lower(name); | |
} | |
location: null; | |
upper(s) { | |
return s.toUpperCase(); | |
} | |
lower(s) { | |
return s.toLowerCase(); | |
} | |
} | |
const e = new Employee('Rick', 'FL'); | |
console.log(e.name); // 'RICK' | |
console.log(e.location); // 'FL' | |
e.name = 'Jeff'; | |
e.location = 'CA'; | |
console.log(e.name); // 'JEFF' | |
console.log(e.location); // 'CA' | |
// ES6 | |
class Vehicle { | |
constructor(wheels) { | |
this.wheels = wheels; | |
} | |
get wheels { | |
} | |
} | |
class Car extends Vehicle { | |
constructor(type) { | |
super(4); | |
this.type = type; | |
} | |
} | |
console.log(typeof Car); // 'function' | |
const chrisWants = new Car('tesla'); | |
console.log(chrisWants); // Car { wheels: 4, type: 'tesla' } | |
// ES5 | |
function Vehicle(wheels) { | |
this.wheels = wheels; | |
} | |
function Car(type) { | |
Vehicle.call(this, 4); | |
this.type = type; | |
} | |
Car.prototype = Object.create(Vehicle.prototype); | |
Car.prototype.constructor = Car; | |
Car.prototype.toString = function () { | |
return '[object Car]'; | |
}; | |
console.log(typeof Car); // 'function' | |
var jeffsCar = new Car('tesla'); | |
console.log(jeffsCar); // Car { wheels: 4, type: 'tesla' } | |
// ES5 | |
[1, 2, 3].indexOf(2) !== -1 // true | |
[1, 2, 3].indexOf(4) !== -1 // false | |
// ES7 | |
[1, 2, 3].includes(2); // true | |
[1, 2, 3].includes(4); // false | |
[1, 2, 3].includes(3, 3); // false | |
[1, 2, 3].includes(3, -1); // true | |
[1, 2, NaN].includes(NaN); // true | |
// of() | |
console.log(Array.of()); // [] | |
console.log(Array.of('a', 'b', 'c')); // ['a', 'b', 'c'] | |
function foo() { | |
console.log(Array.of.apply(null, arguments)); // ['a', 'b', 'c'] | |
} | |
foo('a', 'b', 'c'); | |
// entries() | |
const arr = ['a', 'b', 'c']; | |
const eArr = arr.entries(); | |
console.log(eArr.next().value); // [0, 'a'] | |
console.log(eArr.next().value); // [1, 'b'] | |
console.log(eArr.next().value); // [2, 'c'] | |
// fill() | |
console.log(new Array(5).fill('?')); // ['?', '?', '?', '?', '?'] | |
function foo() { | |
const args = Array.prototype.slice.call(arguments); | |
console.log(args); // ['a', 'b', 'c'] | |
console.log(Array.from(arguments)); // ['a', 'b', 'c'] | |
console.log(Array.from(arguments, s => s.toUpperCase())); // ['A', 'B', 'C'] | |
} | |
foo('a', 'b', 'c'); | |
const a = Symbol.for('abc'); | |
const b = Symbol.for('abc'); | |
const c = Symbol('abc'); | |
console.log(a === b); // true | |
console.log(a === c); // false | |
Symbol('foo') == Symbol('foo'); // false | |
Symbol('foo') === Symbol('foo'); // false | |
const bar = Symbol('bar'); | |
console.log(bar); // Symbol(foo) | |
console.log(typeof bar); // 'symbol' | |
const obj = { | |
[bar]: 'secret' | |
}; | |
console.log(obj); // { Symbol(bar): 'secret' } | |
console.log(Object.keys(obj).length); // 0 | |
console.log(Object.getOwnPropertyNames(obj).length); // 0 | |
const foo = new Symbol('foo'); // TypeError: Symbol is not a constructor | |
const key = 'foo'; | |
const obj = {}; | |
obj[key] = 'bar'; | |
const obj2 = { | |
[key]: 'bar' | |
}; | |
console.log(obj2); // { foo: 'bar' } | |
function fn() { return 'woot'; } | |
const obj3 = { | |
[fn()]: 'baz' | |
}; | |
console.log(obj3); // { woot: 'baz' } | |
const x = 1; | |
const y = 2; | |
const obj = { | |
x: x, | |
y: y | |
}; | |
const obj2 = { | |
x, | |
y | |
}; | |
const { x, y, ...rest } = { x: 1, y: 2, a: 'a', b: 'b', c: 'c' }; | |
console.log(x); // 1 | |
console.log(y); // 2 | |
console.log(rest); // { a: 'a', b: 'b', c: 'c' }; | |
const obj = { x: 1, y: 2, a: 'a', b: 'b', c: 'c' }; | |
console.log({ ...obj }); // { x: 1, y: 2, a: 'a', b: 'b', c: 'c' } | |
console.log(Math.max(...[1, 2, 3])); // 3 | |
const arr = [1, 2, 3]; | |
console.log(arr.concat(4, 5, 6)); // [1, 2, 3, 4, 5, 6] | |
console.log(arr.concat([4, 5, 6])); // [1, 2, 3, 4, 5, 6] | |
console.log([...arr, 4, 5, 6]); // [1, 2, 3, 4, 5, 6] | |
console.log([...arr, ...[4, 5, 6]]); // [1, 2, 3, 4, 5, 6] | |
function sum(x, y, ...n) { | |
return x + y + n.reduce((a, b) => a + b); | |
} | |
console.log(sum(1, 2, 3, 4)); // 10 | |
console.log(sum.length); // 2 | |
function holla(fn) { | |
return (...args) => { | |
console.log(args.join(' ')); | |
} | |
} | |
holla()('Hello', 'world!'); // 'Hello world!' | |
let a = { | |
x: 'foo', | |
y: 'bar' | |
}; | |
let {x, y, z} = a; | |
console.log(x); // foo | |
console.log(y); // bar | |
console.log(z); // bar | |
let { x: foo, y: bar } = a; | |
console.log(foo); // foo | |
console.log(bar); // bar | |
let a = [ | |
'foo', 'bar' | |
]; | |
let {m, n} = a; // can't destructure an array as an object | |
console.log(m); // undefined | |
console.log(n); // undefined | |
let [s, t] = a; | |
console.log(s); // foo | |
console.log(t); // bar | |
function print(msg = 'hello') { | |
console.log(msg); | |
} | |
print(); // hello | |
print('howdy'); // howdy | |
// default to object | |
function print2(opts = { msg: 'hello' }) { | |
console.log(opts.msg); | |
} | |
print2(); // hello | |
print2('howdy'); // undefined | |
print2({}); // undefined | |
print2({ msg: 'howdy' }); // howdy | |
// default object destructuring | |
function print3({ msg = 'hello' } = {}) { | |
console.log(msg); | |
} | |
print3(); // hello | |
print3('howdy'); // hello | |
print3({}); // hello | |
print3({ msg: 'howdy' }); // howdy | |
const add = (x, y) => { | |
return x + y; | |
}; | |
const add2 = (x, y) => x + y; | |
const toUpper = s => s.toUpperCase(); | |
function add(x, y) { | |
return x + y; | |
} | |
const addFn = function add2(x, y) { | |
console.log(typeof addFn); // 'function' | |
console.log(typeof add); // 'function' | |
return x + y; | |
}; | |
console.log(typeof addFn); // 'function' | |
console.log(typeof add2); // undefined | |
addFn(1, 2); | |
console.log(2 ** 3); // 8 | |
console.log(5 ** 2); // 25 | |
let x = 5; | |
x **= 2; | |
console.log(x); // 25 | |
function foo(strings, ...values) { | |
console.log(strings[0]); // 'Rick likes ' | |
console.log(strings[1]); // ', but does not like ' | |
console.log(values[0]); // 'JavaScript' | |
console.log(values[1]); // 'ill tempered sea bass' | |
return strings[0] + values[1] + strings[1] + values[0]; // 'Rick likes ill tempered sea bass, but does not like JavaScript' | |
} | |
let likes = 'JavaScript'; | |
let doesnotlike = 'ill tempered sea bass'; | |
console.log(foo`Rick likes ${likes}, but does not like ${doesnotlike}`); | |
let x = 10; | |
let y = 'foo'; | |
console.log(`x = ${x} and y = '${y}'`); // "x = 10 and y = 'foo'" | |
console.log(`${x} + 5 = ${x + 5}`); // '10 + 5 = 15' | |
const obj = { | |
foo: 'bar' | |
}; | |
console.log(`foo = "${obj.foo}"`); // 'foo = "bar"' | |
let a = 'Hello\nworld!'; | |
let b = 'Hello \ | |
world!'; | |
let c = [ | |
'Hello', | |
'world!' | |
].join('\n'); | |
let s = ('a', 'b'); | |
console.log(s); // 'b' | |
function foo() { | |
return 'foo', 123, 'bar', null, 'baz'; | |
} | |
console.log(foo()); // 'baz' | |
const arr = []; | |
for (let i = 0; i < 10; i++) { | |
arr.push(function () { | |
console.log(i); | |
}); | |
} | |
arr.forEach(function (fn) { | |
fn(); | |
}); | |
var arr = []; | |
for (var i = 0; i < 10; i++) { | |
(function (j) { | |
arr.push(function () { | |
console.log(j); | |
}); | |
}(i)); | |
} | |
arr.forEach(function (fn) { | |
fn(); | |
}); | |
var arr = []; | |
for (var i = 0; i < 10; i++) { | |
arr.push(function () { | |
console.log(i); | |
}); | |
} | |
arr.forEach(function (fn) { | |
fn(); | |
}); | |
console.log(3**3); // 27 | |
function foo() { | |
x = 10; // ReferenceError: x is not defined | |
} | |
foo(); | |
function foo() { | |
bar(); | |
function bar() { | |
console.log('hi from bar'); | |
} | |
} | |
foo(); | |
function foo() { | |
console.log(y); // ReferenceError: y is not defined | |
// temporal dead zone | |
let y = 10; | |
console.log(y); | |
} | |
foo(); | |
let x = 123; | |
x = 'foo'; | |
x = ['bar']; // bad | |
x = { foo: 'bar' }; // bad | |
x = function () {}; // bad | |
x = new Date(); // bad | |
const obj = { | |
x: 10 | |
}; | |
obj.x = 15; // ok | |
obj = null; // SyntaxError: "obj" is read-only | |
let x = 10; | |
if (x > 0) { | |
let y = x + 5; | |
console.log(y); // 15 | |
} | |
console.log(y); // ReferenceError: y is not defined | |
let x = 10; | |
x = 15; | |
const y = 10; | |
y = 15; // SyntaxError: "y" is read-only | |
let x = 5; | |
function add(n) { | |
n += 10; | |
} | |
add(x); | |
console.log(x); // 5 | |
let y = 'abc'; | |
function append(s) { | |
s += 'def'; | |
} | |
append(y); | |
console.log(y); // 'abc' | |
let z = { foo: 5, bar: 'abc' }; | |
function add2(o) { | |
o.foo += 10; | |
o.bar += 'def'; | |
} | |
add2(z); | |
console.log(z.foo); // 15 | |
console.log(z.bar); // 'abcdef' | |
let x = new Boolean('false'); // true | |
let myFalse = new Boolean(false); // initial value of false | |
let g = new Boolean(myFalse); // initial value of true | |
let myString = new String('Hello'); // string object | |
let s = new Boolean(myString); // initial value of true | |
let x = 'foo'; | |
let y = !!x; // true | |
// truthy | |
true | |
'true' | |
'false' | |
[] | |
{} | |
// falsey | |
0 | |
void 0 | |
null | |
undefined | |
'' | |
false | |
let str = 'abc'; | |
let iter = str[Symbol.iterator](); | |
console.log(iter.next()); // Object {value: "a", done: false} | |
console.log(iter.next()); // Object {value: "b", done: false} | |
console.log(iter.next()); // Object {value: "c", done: false} | |
console.log(iter.next()); // Object {value: undefined, done: true} | |
for (let s of str) { | |
console.log(s); // a, b, c | |
} | |
let a = '\u00E5'; | |
let b = 'å'; // 2 byte sequence | |
let c = 'å'; // 3 byte sequence | |
a.charAt(0) // å | |
a.charCodeAt(0) // 229 | |
a.codePointAt(0) // 229 | |
a.length // 1 | |
b.charAt(0) // å | |
b.charCodeAt(0) // 229 | |
b.codePointAt(0) // 229 | |
a === b // true | |
c.charAt(0) // å | |
c.charCodeAt(0) // 97 | |
c.codePointAt(0) // 97 | |
a === c // false | |
b === c // false | |
a === c.normalize() // true | |
a.normalize('NFKD') === c // true | |
let a = 'a'; | |
let b = 'å'; | |
let c = 'â'; | |
a < b // true | |
a < c // true | |
b < c // false; | |
a.localeCompare(b) // -1 | |
a.localeCompare(c) // -1 | |
b.localeCompare(c) // 1 | |
let s = 'Hello world!'; | |
s.replace('l', 'L') // 'HeLlo world!' | |
s.replace(/l/, 'L') // 'HeLlo world!' | |
s.replace(/l/g, 'L') // 'HeLLo worLd!' | |
s.replace(/l/g, function (match, index, original) { | |
return 'L'; | |
}); | |
s.match(/world/) // ['world', index: 6, input: 'Hello world!'] | |
s.search('world') // 6 | |
s.search(/world/) // 6 | |
let s = 'foo'; | |
console.log(s); // 'foo'; | |
console.log(s.concat('bar')); // 'foobar' | |
console.log(s); // 'foo' | |
s += 'bar'; | |
console.log(s); // 'foobar' | |
let t = 'Hello world!'; | |
s.slice(2, 4) // 'el' | |
s.substring(2, 4) // 'el' | |
s.substr(2, 4) // 'ell' | |
s.split('l') // ['He', '', 'o wor', 'd!'] | |
s.split(/l/) // ['He', '', 'o wor', 'd!'] | |
s.split(/[lw]/) // ["He", "", "o ", "or", "d!"] | |
let s = 'Hello world!'; | |
s.length // 12 | |
s[0] // 'H' | |
s[100] // undefined | |
s.charAt(6) // 'w' | |
s.charCodeAt(5) // 32 | |
s.indexOf('l') // 2 | |
s.indexOf('foo') // -1 | |
s.lastIndexOf('l') // 9 | |
s.toString() // 'Hello world!' | |
s.valueOf() // 'Hello world!' | |
s.toUpperCase() // 'ABC' | |
s.toLowerCase() // 'abc' | |
' abc '.trim() // 'abc' | |
// new in ES6 | |
s.codePointAt(5) // 32 | |
s.startsWith('Hel') // true | |
s.endsWith('world!') // true | |
s.includes('world') // true | |
'abc'.repeat(2); // 'abcabc' | |
' abc '.trimStart() // 'abc ' | |
' abc '.trimEnd() // ' abc' | |
'Rick\'s got "skills"?\nHmm...' | |
let a = 'hello '; | |
a += "world"; | |
let b = 123; | |
console.log(b + ' foo'); // "123 foo" | |
console.log(String(b) + ' foo'); // "123 foo" | |
console.log('' + b + ' foo'); // "123 foo" | |
let c = 456; | |
console.log(b + c); // 579 | |
console.log(String(b) + c); // "123456" | |
console.log('' + b + c); // "123456" | |
console.log(String(b + c)); // "579" | |
let d = String(123); | |
let e = new String(123); | |
console.log(d == e); // true | |
console.log(d === e); // false | |
console.log(typeof d); // string | |
console.log(typeof e); // object | |
console.log(String(null)); // 'null' | |
let f = {}; | |
console.log(String(f.foo)); // 'undefined' | |
let x = { a: '3.14', b: 'foo' }; | |
Number(x.a); // 3.14 | |
Number(x.b); // NaN | |
Number(x.c); // NaN | |
Number(x.a) + 1 // 4.140000000000001 | |
let x = new Number(x.a); // [Number: 3.14] | |
x + 1 // 4.140000000000001 | |
Number(1) == new Number(1) // true | |
Number(1) === new Number(1) // false | |
Number.MIN_VALUE // 5e-324 | |
Number.MAX_VALUE // 1.7976931348623157e+308 | |
1 / 0 // Infinity | |
'3.14' | 0 // 3 | |
~~'3.14' // 3 | |
~~undefined // 0 | |
~~'' // 0 | |
~~null // 0 | |
'3.14' - 0 // 3.14 | |
+'3.14' // 3.14 | |
let x = { a: '3.14', b: 'foo' }; | |
~~x.a // 3 | |
~~x.b // 0 | |
~~x.c // 0 | |
x.a - 0 // 3.14 | |
x.b - 0 // NaN | |
x.a + 0 // "3.140" | |
parseInt(x.a); // 3 | |
parseFloat(x.a); // 3.14 | |
let x = Math.random() * 1e9; // 533584263.17572594 | |
parseInt(x); // 533584263 | |
parseInt('123'); // 123 | |
parseInt('3.14'); // 3.14 | |
parseInt('a'); // NaN | |
isNaN(parseInt('a')); // true | |
0.2 + 0.1 == 0.3 // false | |
5e3 // 5000 | |
0135 // 93 | |
0xFF // 255 | |
Infinity | |
-Infinity | |
NaN | |
let x = { | |
a: { c: 'd' }, | |
e: { f: 'g' } | |
}; | |
x.a = null; | |
// { | |
// a: null, | |
// e: { f: 'g' } | |
// } | |
delete x.b; | |
// { | |
// a: null | |
// } | |
console.log(typeof null === 'object'); // true | |
console.log(null == undefined); // true | |
console.log(null === undefined); // false | |
(function () { | |
let foo = 123; | |
// amazing code here | |
foo = null; // pointless! | |
}()); | |
let bar = 123; | |
// too cool for school code here | |
bar = null; // ok | |
console.log(undefined); | |
console.log(void 0); // undefined | |
let a; | |
console.log(a); // undefined | |
console.log(a === undefined); // true | |
console.log(b); // ReferenceError: b is not defined | |
console.log(b === undefined); // ReferenceError: b is not defined | |
console.log(typeof b === 'undefined'); // true | |
console.log({}.foo); // undefined | |
console.log([][0]); // undefined | |
(function (foo, bar, undefined) { | |
console.log(foo === undefined); // false | |
console.log(bar === undefined); // true | |
}('baz')); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment