element', () => {
- // https://on.cypress.io/select
-
- // at first, no option should be selected
- cy.get('.action-select')
- .should('have.value', '--Select a fruit--')
-
- // Select option(s) with matching text content
- cy.get('.action-select').select('apples')
- // confirm the apples were selected
- // note that each value starts with "fr-" in our HTML
- cy.get('.action-select').should('have.value', 'fr-apples')
-
- cy.get('.action-select-multiple')
- .select(['apples', 'oranges', 'bananas'])
- // when getting multiple values, invoke "val" method first
- .invoke('val')
- .should('deep.equal', ['fr-apples', 'fr-oranges', 'fr-bananas'])
-
- // Select option(s) with matching value
- cy.get('.action-select').select('fr-bananas')
- // can attach an assertion right away to the element
- .should('have.value', 'fr-bananas')
-
- cy.get('.action-select-multiple')
- .select(['fr-apples', 'fr-oranges', 'fr-bananas'])
- .invoke('val')
- .should('deep.equal', ['fr-apples', 'fr-oranges', 'fr-bananas'])
-
- // assert the selected values include oranges
- cy.get('.action-select-multiple')
- .invoke('val').should('include', 'fr-oranges')
- })
-
- it('.scrollIntoView() - scroll an element into view', () => {
- // https://on.cypress.io/scrollintoview
-
- // normally all of these buttons are hidden,
- // because they're not within
- // the viewable area of their parent
- // (we need to scroll to see them)
- cy.get('#scroll-horizontal button')
- .should('not.be.visible')
-
- // scroll the button into view, as if the user had scrolled
- cy.get('#scroll-horizontal button').scrollIntoView()
- .should('be.visible')
-
- cy.get('#scroll-vertical button')
- .should('not.be.visible')
-
- // Cypress handles the scroll direction needed
- cy.get('#scroll-vertical button').scrollIntoView()
- .should('be.visible')
-
- cy.get('#scroll-both button')
- .should('not.be.visible')
-
- // Cypress knows to scroll to the right and down
- cy.get('#scroll-both button').scrollIntoView()
- .should('be.visible')
- })
-
- it('.trigger() - trigger an event on a DOM element', () => {
- // https://on.cypress.io/trigger
-
- // To interact with a range input (slider)
- // we need to set its value & trigger the
- // event to signal it changed
-
- // Here, we invoke jQuery's val() method to set
- // the value and trigger the 'change' event
- cy.get('.trigger-input-range')
- .invoke('val', 25)
- .trigger('change')
- .get('input[type=range]').siblings('p')
- .should('have.text', '25')
- })
-
- it('cy.scrollTo() - scroll the window or element to a position', () => {
- // https://on.cypress.io/scrollto
-
- // You can scroll to 9 specific positions of an element:
- // -----------------------------------
- // | topLeft top topRight |
- // | |
- // | |
- // | |
- // | left center right |
- // | |
- // | |
- // | |
- // | bottomLeft bottom bottomRight |
- // -----------------------------------
-
- // if you chain .scrollTo() off of cy, we will
- // scroll the entire window
- cy.scrollTo('bottom')
-
- cy.get('#scrollable-horizontal').scrollTo('right')
-
- // or you can scroll to a specific coordinate:
- // (x axis, y axis) in pixels
- cy.get('#scrollable-vertical').scrollTo(250, 250)
-
- // or you can scroll to a specific percentage
- // of the (width, height) of the element
- cy.get('#scrollable-both').scrollTo('75%', '25%')
-
- // control the easing of the scroll (default is 'swing')
- cy.get('#scrollable-vertical').scrollTo('center', { easing: 'linear' })
-
- // control the duration of the scroll (in ms)
- cy.get('#scrollable-both').scrollTo('center', { duration: 2000 })
- })
-})
diff --git a/client/cypress/integration/2-advanced-examples/aliasing.spec.js b/client/cypress/integration/2-advanced-examples/aliasing.spec.js
deleted file mode 100644
index a02fb2bb9..000000000
--- a/client/cypress/integration/2-advanced-examples/aliasing.spec.js
+++ /dev/null
@@ -1,39 +0,0 @@
-///
-
-context('Aliasing', () => {
- beforeEach(() => {
- cy.visit('https://example.cypress.io/commands/aliasing')
- })
-
- it('.as() - alias a DOM element for later use', () => {
- // https://on.cypress.io/as
-
- // Alias a DOM element for use later
- // We don't have to traverse to the element
- // later in our code, we reference it with @
-
- cy.get('.as-table').find('tbody>tr')
- .first().find('td').first()
- .find('button').as('firstBtn')
-
- // when we reference the alias, we place an
- // @ in front of its name
- cy.get('@firstBtn').click()
-
- cy.get('@firstBtn')
- .should('have.class', 'btn-success')
- .and('contain', 'Changed')
- })
-
- it('.as() - alias a route for later use', () => {
- // Alias the route to wait for its response
- cy.intercept('GET', '**/comments/*').as('getComment')
-
- // we have code that gets a comment when
- // the button is clicked in scripts.js
- cy.get('.network-btn').click()
-
- // https://on.cypress.io/wait
- cy.wait('@getComment').its('response.statusCode').should('eq', 200)
- })
-})
diff --git a/client/cypress/integration/2-advanced-examples/assertions.spec.js b/client/cypress/integration/2-advanced-examples/assertions.spec.js
deleted file mode 100644
index 5ba93d1db..000000000
--- a/client/cypress/integration/2-advanced-examples/assertions.spec.js
+++ /dev/null
@@ -1,177 +0,0 @@
-///
-
-context('Assertions', () => {
- beforeEach(() => {
- cy.visit('https://example.cypress.io/commands/assertions')
- })
-
- describe('Implicit Assertions', () => {
- it('.should() - make an assertion about the current subject', () => {
- // https://on.cypress.io/should
- cy.get('.assertion-table')
- .find('tbody tr:last')
- .should('have.class', 'success')
- .find('td')
- .first()
- // checking the text of the element in various ways
- .should('have.text', 'Column content')
- .should('contain', 'Column content')
- .should('have.html', 'Column content')
- // chai-jquery uses "is()" to check if element matches selector
- .should('match', 'td')
- // to match text content against a regular expression
- // first need to invoke jQuery method text()
- // and then match using regular expression
- .invoke('text')
- .should('match', /column content/i)
-
- // a better way to check element's text content against a regular expression
- // is to use "cy.contains"
- // https://on.cypress.io/contains
- cy.get('.assertion-table')
- .find('tbody tr:last')
- // finds first element with text content matching regular expression
- .contains('td', /column content/i)
- .should('be.visible')
-
- // for more information about asserting element's text
- // see https://on.cypress.io/using-cypress-faq#How-do-I-get-an-element’s-text-contents
- })
-
- it('.and() - chain multiple assertions together', () => {
- // https://on.cypress.io/and
- cy.get('.assertions-link')
- .should('have.class', 'active')
- .and('have.attr', 'href')
- .and('include', 'cypress.io')
- })
- })
-
- describe('Explicit Assertions', () => {
- // https://on.cypress.io/assertions
- it('expect - make an assertion about a specified subject', () => {
- // We can use Chai's BDD style assertions
- expect(true).to.be.true
- const o = { foo: 'bar' }
-
- expect(o).to.equal(o)
- expect(o).to.deep.equal({ foo: 'bar' })
- // matching text using regular expression
- expect('FooBar').to.match(/bar$/i)
- })
-
- it('pass your own callback function to should()', () => {
- // Pass a function to should that can have any number
- // of explicit assertions within it.
- // The ".should(cb)" function will be retried
- // automatically until it passes all your explicit assertions or times out.
- cy.get('.assertions-p')
- .find('p')
- .should(($p) => {
- // https://on.cypress.io/$
- // return an array of texts from all of the p's
- // @ts-ignore TS6133 unused variable
- const texts = $p.map((i, el) => Cypress.$(el).text())
-
- // jquery map returns jquery object
- // and .get() convert this to simple array
- const paragraphs = texts.get()
-
- // array should have length of 3
- expect(paragraphs, 'has 3 paragraphs').to.have.length(3)
-
- // use second argument to expect(...) to provide clear
- // message with each assertion
- expect(paragraphs, 'has expected text in each paragraph').to.deep.eq([
- 'Some text from first p',
- 'More text from second p',
- 'And even more text from third p',
- ])
- })
- })
-
- it('finds element by class name regex', () => {
- cy.get('.docs-header')
- .find('div')
- // .should(cb) callback function will be retried
- .should(($div) => {
- expect($div).to.have.length(1)
-
- const className = $div[0].className
-
- expect(className).to.match(/heading-/)
- })
- // .then(cb) callback is not retried,
- // it either passes or fails
- .then(($div) => {
- expect($div, 'text content').to.have.text('Introduction')
- })
- })
-
- it('can throw any error', () => {
- cy.get('.docs-header')
- .find('div')
- .should(($div) => {
- if ($div.length !== 1) {
- // you can throw your own errors
- throw new Error('Did not find 1 element')
- }
-
- const className = $div[0].className
-
- if (!className.match(/heading-/)) {
- throw new Error(`Could not find class "heading-" in ${className}`)
- }
- })
- })
-
- it('matches unknown text between two elements', () => {
- /**
- * Text from the first element.
- * @type {string}
- */
- let text
-
- /**
- * Normalizes passed text,
- * useful before comparing text with spaces and different capitalization.
- * @param {string} s Text to normalize
- */
- const normalizeText = (s) => s.replace(/\s/g, '').toLowerCase()
-
- cy.get('.two-elements')
- .find('.first')
- .then(($first) => {
- // save text from the first element
- text = normalizeText($first.text())
- })
-
- cy.get('.two-elements')
- .find('.second')
- .should(($div) => {
- // we can massage text before comparing
- const secondText = normalizeText($div.text())
-
- expect(secondText, 'second text').to.equal(text)
- })
- })
-
- it('assert - assert shape of an object', () => {
- const person = {
- name: 'Joe',
- age: 20,
- }
-
- assert.isObject(person, 'value is object')
- })
-
- it('retries the should callback until assertions pass', () => {
- cy.get('#random-number')
- .should(($div) => {
- const n = parseFloat($div.text())
-
- expect(n).to.be.gte(1).and.be.lte(10)
- })
- })
- })
-})
diff --git a/client/cypress/integration/2-advanced-examples/connectors.spec.js b/client/cypress/integration/2-advanced-examples/connectors.spec.js
deleted file mode 100644
index ae8799181..000000000
--- a/client/cypress/integration/2-advanced-examples/connectors.spec.js
+++ /dev/null
@@ -1,97 +0,0 @@
-///
-
-context('Connectors', () => {
- beforeEach(() => {
- cy.visit('https://example.cypress.io/commands/connectors')
- })
-
- it('.each() - iterate over an array of elements', () => {
- // https://on.cypress.io/each
- cy.get('.connectors-each-ul>li')
- .each(($el, index, $list) => {
- console.log($el, index, $list)
- })
- })
-
- it('.its() - get properties on the current subject', () => {
- // https://on.cypress.io/its
- cy.get('.connectors-its-ul>li')
- // calls the 'length' property yielding that value
- .its('length')
- .should('be.gt', 2)
- })
-
- it('.invoke() - invoke a function on the current subject', () => {
- // our div is hidden in our script.js
- // $('.connectors-div').hide()
-
- // https://on.cypress.io/invoke
- cy.get('.connectors-div').should('be.hidden')
- // call the jquery method 'show' on the 'div.container'
- .invoke('show')
- .should('be.visible')
- })
-
- it('.spread() - spread an array as individual args to callback function', () => {
- // https://on.cypress.io/spread
- const arr = ['foo', 'bar', 'baz']
-
- cy.wrap(arr).spread((foo, bar, baz) => {
- expect(foo).to.eq('foo')
- expect(bar).to.eq('bar')
- expect(baz).to.eq('baz')
- })
- })
-
- describe('.then()', () => {
- it('invokes a callback function with the current subject', () => {
- // https://on.cypress.io/then
- cy.get('.connectors-list > li')
- .then(($lis) => {
- expect($lis, '3 items').to.have.length(3)
- expect($lis.eq(0), 'first item').to.contain('Walk the dog')
- expect($lis.eq(1), 'second item').to.contain('Feed the cat')
- expect($lis.eq(2), 'third item').to.contain('Write JavaScript')
- })
- })
-
- it('yields the returned value to the next command', () => {
- cy.wrap(1)
- .then((num) => {
- expect(num).to.equal(1)
-
- return 2
- })
- .then((num) => {
- expect(num).to.equal(2)
- })
- })
-
- it('yields the original subject without return', () => {
- cy.wrap(1)
- .then((num) => {
- expect(num).to.equal(1)
- // note that nothing is returned from this callback
- })
- .then((num) => {
- // this callback receives the original unchanged value 1
- expect(num).to.equal(1)
- })
- })
-
- it('yields the value yielded by the last Cypress command inside', () => {
- cy.wrap(1)
- .then((num) => {
- expect(num).to.equal(1)
- // note how we run a Cypress command
- // the result yielded by this Cypress command
- // will be passed to the second ".then"
- cy.wrap(2)
- })
- .then((num) => {
- // this callback receives the value yielded by "cy.wrap(2)"
- expect(num).to.equal(2)
- })
- })
- })
-})
diff --git a/client/cypress/integration/2-advanced-examples/cookies.spec.js b/client/cypress/integration/2-advanced-examples/cookies.spec.js
deleted file mode 100644
index 31587ff90..000000000
--- a/client/cypress/integration/2-advanced-examples/cookies.spec.js
+++ /dev/null
@@ -1,77 +0,0 @@
-///
-
-context('Cookies', () => {
- beforeEach(() => {
- Cypress.Cookies.debug(true)
-
- cy.visit('https://example.cypress.io/commands/cookies')
-
- // clear cookies again after visiting to remove
- // any 3rd party cookies picked up such as cloudflare
- cy.clearCookies()
- })
-
- it('cy.getCookie() - get a browser cookie', () => {
- // https://on.cypress.io/getcookie
- cy.get('#getCookie .set-a-cookie').click()
-
- // cy.getCookie() yields a cookie object
- cy.getCookie('token').should('have.property', 'value', '123ABC')
- })
-
- it('cy.getCookies() - get browser cookies', () => {
- // https://on.cypress.io/getcookies
- cy.getCookies().should('be.empty')
-
- cy.get('#getCookies .set-a-cookie').click()
-
- // cy.getCookies() yields an array of cookies
- cy.getCookies().should('have.length', 1).should((cookies) => {
- // each cookie has these properties
- expect(cookies[0]).to.have.property('name', 'token')
- expect(cookies[0]).to.have.property('value', '123ABC')
- expect(cookies[0]).to.have.property('httpOnly', false)
- expect(cookies[0]).to.have.property('secure', false)
- expect(cookies[0]).to.have.property('domain')
- expect(cookies[0]).to.have.property('path')
- })
- })
-
- it('cy.setCookie() - set a browser cookie', () => {
- // https://on.cypress.io/setcookie
- cy.getCookies().should('be.empty')
-
- cy.setCookie('foo', 'bar')
-
- // cy.getCookie() yields a cookie object
- cy.getCookie('foo').should('have.property', 'value', 'bar')
- })
-
- it('cy.clearCookie() - clear a browser cookie', () => {
- // https://on.cypress.io/clearcookie
- cy.getCookie('token').should('be.null')
-
- cy.get('#clearCookie .set-a-cookie').click()
-
- cy.getCookie('token').should('have.property', 'value', '123ABC')
-
- // cy.clearCookies() yields null
- cy.clearCookie('token').should('be.null')
-
- cy.getCookie('token').should('be.null')
- })
-
- it('cy.clearCookies() - clear browser cookies', () => {
- // https://on.cypress.io/clearcookies
- cy.getCookies().should('be.empty')
-
- cy.get('#clearCookies .set-a-cookie').click()
-
- cy.getCookies().should('have.length', 1)
-
- // cy.clearCookies() yields null
- cy.clearCookies()
-
- cy.getCookies().should('be.empty')
- })
-})
diff --git a/client/cypress/integration/2-advanced-examples/cypress_api.spec.js b/client/cypress/integration/2-advanced-examples/cypress_api.spec.js
deleted file mode 100644
index ec8ceaeda..000000000
--- a/client/cypress/integration/2-advanced-examples/cypress_api.spec.js
+++ /dev/null
@@ -1,202 +0,0 @@
-///
-
-context('Cypress.Commands', () => {
- beforeEach(() => {
- cy.visit('https://example.cypress.io/cypress-api')
- })
-
- // https://on.cypress.io/custom-commands
-
- it('.add() - create a custom command', () => {
- Cypress.Commands.add('console', {
- prevSubject: true,
- }, (subject, method) => {
- // the previous subject is automatically received
- // and the commands arguments are shifted
-
- // allow us to change the console method used
- method = method || 'log'
-
- // log the subject to the console
- // @ts-ignore TS7017
- console[method]('The subject is', subject)
-
- // whatever we return becomes the new subject
- // we don't want to change the subject so
- // we return whatever was passed in
- return subject
- })
-
- // @ts-ignore TS2339
- cy.get('button').console('info').then(($button) => {
- // subject is still $button
- })
- })
-})
-
-context('Cypress.Cookies', () => {
- beforeEach(() => {
- cy.visit('https://example.cypress.io/cypress-api')
- })
-
- // https://on.cypress.io/cookies
- it('.debug() - enable or disable debugging', () => {
- Cypress.Cookies.debug(true)
-
- // Cypress will now log in the console when
- // cookies are set or cleared
- cy.setCookie('fakeCookie', '123ABC')
- cy.clearCookie('fakeCookie')
- cy.setCookie('fakeCookie', '123ABC')
- cy.clearCookie('fakeCookie')
- cy.setCookie('fakeCookie', '123ABC')
- })
-
- it('.preserveOnce() - preserve cookies by key', () => {
- // normally cookies are reset after each test
- cy.getCookie('fakeCookie').should('not.be.ok')
-
- // preserving a cookie will not clear it when
- // the next test starts
- cy.setCookie('lastCookie', '789XYZ')
- Cypress.Cookies.preserveOnce('lastCookie')
- })
-
- it('.defaults() - set defaults for all cookies', () => {
- // now any cookie with the name 'session_id' will
- // not be cleared before each new test runs
- Cypress.Cookies.defaults({
- preserve: 'session_id',
- })
- })
-})
-
-context('Cypress.arch', () => {
- beforeEach(() => {
- cy.visit('https://example.cypress.io/cypress-api')
- })
-
- it('Get CPU architecture name of underlying OS', () => {
- // https://on.cypress.io/arch
- expect(Cypress.arch).to.exist
- })
-})
-
-context('Cypress.config()', () => {
- beforeEach(() => {
- cy.visit('https://example.cypress.io/cypress-api')
- })
-
- it('Get and set configuration options', () => {
- // https://on.cypress.io/config
- let myConfig = Cypress.config()
-
- expect(myConfig).to.have.property('animationDistanceThreshold', 5)
- expect(myConfig).to.have.property('baseUrl', null)
- expect(myConfig).to.have.property('defaultCommandTimeout', 4000)
- expect(myConfig).to.have.property('requestTimeout', 5000)
- expect(myConfig).to.have.property('responseTimeout', 30000)
- expect(myConfig).to.have.property('viewportHeight', 660)
- expect(myConfig).to.have.property('viewportWidth', 1000)
- expect(myConfig).to.have.property('pageLoadTimeout', 60000)
- expect(myConfig).to.have.property('waitForAnimations', true)
-
- expect(Cypress.config('pageLoadTimeout')).to.eq(60000)
-
- // this will change the config for the rest of your tests!
- Cypress.config('pageLoadTimeout', 20000)
-
- expect(Cypress.config('pageLoadTimeout')).to.eq(20000)
-
- Cypress.config('pageLoadTimeout', 60000)
- })
-})
-
-context('Cypress.dom', () => {
- beforeEach(() => {
- cy.visit('https://example.cypress.io/cypress-api')
- })
-
- // https://on.cypress.io/dom
- it('.isHidden() - determine if a DOM element is hidden', () => {
- let hiddenP = Cypress.$('.dom-p p.hidden').get(0)
- let visibleP = Cypress.$('.dom-p p.visible').get(0)
-
- // our first paragraph has css class 'hidden'
- expect(Cypress.dom.isHidden(hiddenP)).to.be.true
- expect(Cypress.dom.isHidden(visibleP)).to.be.false
- })
-})
-
-context('Cypress.env()', () => {
- beforeEach(() => {
- cy.visit('https://example.cypress.io/cypress-api')
- })
-
- // We can set environment variables for highly dynamic values
-
- // https://on.cypress.io/environment-variables
- it('Get environment variables', () => {
- // https://on.cypress.io/env
- // set multiple environment variables
- Cypress.env({
- host: 'veronica.dev.local',
- api_server: 'http://localhost:8888/v1/',
- })
-
- // get environment variable
- expect(Cypress.env('host')).to.eq('veronica.dev.local')
-
- // set environment variable
- Cypress.env('api_server', 'http://localhost:8888/v2/')
- expect(Cypress.env('api_server')).to.eq('http://localhost:8888/v2/')
-
- // get all environment variable
- expect(Cypress.env()).to.have.property('host', 'veronica.dev.local')
- expect(Cypress.env()).to.have.property('api_server', 'http://localhost:8888/v2/')
- })
-})
-
-context('Cypress.log', () => {
- beforeEach(() => {
- cy.visit('https://example.cypress.io/cypress-api')
- })
-
- it('Control what is printed to the Command Log', () => {
- // https://on.cypress.io/cypress-log
- })
-})
-
-context('Cypress.platform', () => {
- beforeEach(() => {
- cy.visit('https://example.cypress.io/cypress-api')
- })
-
- it('Get underlying OS name', () => {
- // https://on.cypress.io/platform
- expect(Cypress.platform).to.be.exist
- })
-})
-
-context('Cypress.version', () => {
- beforeEach(() => {
- cy.visit('https://example.cypress.io/cypress-api')
- })
-
- it('Get current version of Cypress being run', () => {
- // https://on.cypress.io/version
- expect(Cypress.version).to.be.exist
- })
-})
-
-context('Cypress.spec', () => {
- beforeEach(() => {
- cy.visit('https://example.cypress.io/cypress-api')
- })
-
- it('Get current spec information', () => {
- // https://on.cypress.io/spec
- // wrap the object so we can inspect it easily by clicking in the command log
- cy.wrap(Cypress.spec).should('include.keys', ['name', 'relative', 'absolute'])
- })
-})
diff --git a/client/cypress/integration/2-advanced-examples/files.spec.js b/client/cypress/integration/2-advanced-examples/files.spec.js
deleted file mode 100644
index b8273430c..000000000
--- a/client/cypress/integration/2-advanced-examples/files.spec.js
+++ /dev/null
@@ -1,88 +0,0 @@
-///
-
-/// JSON fixture file can be loaded directly using
-// the built-in JavaScript bundler
-// @ts-ignore
-const requiredExample = require('../../fixtures/example')
-
-context('Files', () => {
- beforeEach(() => {
- cy.visit('https://example.cypress.io/commands/files')
- })
-
- beforeEach(() => {
- // load example.json fixture file and store
- // in the test context object
- cy.fixture('example.json').as('example')
- })
-
- it('cy.fixture() - load a fixture', () => {
- // https://on.cypress.io/fixture
-
- // Instead of writing a response inline you can
- // use a fixture file's content.
-
- // when application makes an Ajax request matching "GET **/comments/*"
- // Cypress will intercept it and reply with the object in `example.json` fixture
- cy.intercept('GET', '**/comments/*', { fixture: 'example.json' }).as('getComment')
-
- // we have code that gets a comment when
- // the button is clicked in scripts.js
- cy.get('.fixture-btn').click()
-
- cy.wait('@getComment').its('response.body')
- .should('have.property', 'name')
- .and('include', 'Using fixtures to represent data')
- })
-
- it('cy.fixture() or require - load a fixture', function () {
- // we are inside the "function () { ... }"
- // callback and can use test context object "this"
- // "this.example" was loaded in "beforeEach" function callback
- expect(this.example, 'fixture in the test context')
- .to.deep.equal(requiredExample)
-
- // or use "cy.wrap" and "should('deep.equal', ...)" assertion
- cy.wrap(this.example)
- .should('deep.equal', requiredExample)
- })
-
- it('cy.readFile() - read file contents', () => {
- // https://on.cypress.io/readfile
-
- // You can read a file and yield its contents
- // The filePath is relative to your project's root.
- cy.readFile('cypress.json').then((json) => {
- expect(json).to.be.an('object')
- })
- })
-
- it('cy.writeFile() - write to a file', () => {
- // https://on.cypress.io/writefile
-
- // You can write to a file
-
- // Use a response from a request to automatically
- // generate a fixture file for use later
- cy.request('https://jsonplaceholder.cypress.io/users')
- .then((response) => {
- cy.writeFile('cypress/fixtures/users.json', response.body)
- })
-
- cy.fixture('users').should((users) => {
- expect(users[0].name).to.exist
- })
-
- // JavaScript arrays and objects are stringified
- // and formatted into text.
- cy.writeFile('cypress/fixtures/profile.json', {
- id: 8739,
- name: 'Jane',
- email: 'jane@example.com',
- })
-
- cy.fixture('profile').should((profile) => {
- expect(profile.name).to.eq('Jane')
- })
- })
-})
diff --git a/client/cypress/integration/2-advanced-examples/local_storage.spec.js b/client/cypress/integration/2-advanced-examples/local_storage.spec.js
deleted file mode 100644
index 534d8bd9d..000000000
--- a/client/cypress/integration/2-advanced-examples/local_storage.spec.js
+++ /dev/null
@@ -1,52 +0,0 @@
-///
-
-context('Local Storage', () => {
- beforeEach(() => {
- cy.visit('https://example.cypress.io/commands/local-storage')
- })
- // Although local storage is automatically cleared
- // in between tests to maintain a clean state
- // sometimes we need to clear the local storage manually
-
- it('cy.clearLocalStorage() - clear all data in local storage', () => {
- // https://on.cypress.io/clearlocalstorage
- cy.get('.ls-btn').click().should(() => {
- expect(localStorage.getItem('prop1')).to.eq('red')
- expect(localStorage.getItem('prop2')).to.eq('blue')
- expect(localStorage.getItem('prop3')).to.eq('magenta')
- })
-
- // clearLocalStorage() yields the localStorage object
- cy.clearLocalStorage().should((ls) => {
- expect(ls.getItem('prop1')).to.be.null
- expect(ls.getItem('prop2')).to.be.null
- expect(ls.getItem('prop3')).to.be.null
- })
-
- cy.get('.ls-btn').click().should(() => {
- expect(localStorage.getItem('prop1')).to.eq('red')
- expect(localStorage.getItem('prop2')).to.eq('blue')
- expect(localStorage.getItem('prop3')).to.eq('magenta')
- })
-
- // Clear key matching string in Local Storage
- cy.clearLocalStorage('prop1').should((ls) => {
- expect(ls.getItem('prop1')).to.be.null
- expect(ls.getItem('prop2')).to.eq('blue')
- expect(ls.getItem('prop3')).to.eq('magenta')
- })
-
- cy.get('.ls-btn').click().should(() => {
- expect(localStorage.getItem('prop1')).to.eq('red')
- expect(localStorage.getItem('prop2')).to.eq('blue')
- expect(localStorage.getItem('prop3')).to.eq('magenta')
- })
-
- // Clear keys matching regex in Local Storage
- cy.clearLocalStorage(/prop1|2/).should((ls) => {
- expect(ls.getItem('prop1')).to.be.null
- expect(ls.getItem('prop2')).to.be.null
- expect(ls.getItem('prop3')).to.eq('magenta')
- })
- })
-})
diff --git a/client/cypress/integration/2-advanced-examples/location.spec.js b/client/cypress/integration/2-advanced-examples/location.spec.js
deleted file mode 100644
index 299867da0..000000000
--- a/client/cypress/integration/2-advanced-examples/location.spec.js
+++ /dev/null
@@ -1,32 +0,0 @@
-///
-
-context('Location', () => {
- beforeEach(() => {
- cy.visit('https://example.cypress.io/commands/location')
- })
-
- it('cy.hash() - get the current URL hash', () => {
- // https://on.cypress.io/hash
- cy.hash().should('be.empty')
- })
-
- it('cy.location() - get window.location', () => {
- // https://on.cypress.io/location
- cy.location().should((location) => {
- expect(location.hash).to.be.empty
- expect(location.href).to.eq('https://example.cypress.io/commands/location')
- expect(location.host).to.eq('example.cypress.io')
- expect(location.hostname).to.eq('example.cypress.io')
- expect(location.origin).to.eq('https://example.cypress.io')
- expect(location.pathname).to.eq('/commands/location')
- expect(location.port).to.eq('')
- expect(location.protocol).to.eq('https:')
- expect(location.search).to.be.empty
- })
- })
-
- it('cy.url() - get the current URL', () => {
- // https://on.cypress.io/url
- cy.url().should('eq', 'https://example.cypress.io/commands/location')
- })
-})
diff --git a/client/cypress/integration/2-advanced-examples/misc.spec.js b/client/cypress/integration/2-advanced-examples/misc.spec.js
deleted file mode 100644
index 7222bf4bd..000000000
--- a/client/cypress/integration/2-advanced-examples/misc.spec.js
+++ /dev/null
@@ -1,104 +0,0 @@
-///
-
-context('Misc', () => {
- beforeEach(() => {
- cy.visit('https://example.cypress.io/commands/misc')
- })
-
- it('.end() - end the command chain', () => {
- // https://on.cypress.io/end
-
- // cy.end is useful when you want to end a chain of commands
- // and force Cypress to re-query from the root element
- cy.get('.misc-table').within(() => {
- // ends the current chain and yields null
- cy.contains('Cheryl').click().end()
-
- // queries the entire table again
- cy.contains('Charles').click()
- })
- })
-
- it('cy.exec() - execute a system command', () => {
- // execute a system command.
- // so you can take actions necessary for
- // your test outside the scope of Cypress.
- // https://on.cypress.io/exec
-
- // we can use Cypress.platform string to
- // select appropriate command
- // https://on.cypress/io/platform
- cy.log(`Platform ${Cypress.platform} architecture ${Cypress.arch}`)
-
- // on CircleCI Windows build machines we have a failure to run bash shell
- // https://github.com/cypress-io/cypress/issues/5169
- // so skip some of the tests by passing flag "--env circle=true"
- const isCircleOnWindows = Cypress.platform === 'win32' && Cypress.env('circle')
-
- if (isCircleOnWindows) {
- cy.log('Skipping test on CircleCI')
-
- return
- }
-
- // cy.exec problem on Shippable CI
- // https://github.com/cypress-io/cypress/issues/6718
- const isShippable = Cypress.platform === 'linux' && Cypress.env('shippable')
-
- if (isShippable) {
- cy.log('Skipping test on ShippableCI')
-
- return
- }
-
- cy.exec('echo Jane Lane')
- .its('stdout').should('contain', 'Jane Lane')
-
- if (Cypress.platform === 'win32') {
- cy.exec('print cypress.json')
- .its('stderr').should('be.empty')
- } else {
- cy.exec('cat cypress.json')
- .its('stderr').should('be.empty')
-
- cy.exec('pwd')
- .its('code').should('eq', 0)
- }
- })
-
- it('cy.focused() - get the DOM element that has focus', () => {
- // https://on.cypress.io/focused
- cy.get('.misc-form').find('#name').click()
- cy.focused().should('have.id', 'name')
-
- cy.get('.misc-form').find('#description').click()
- cy.focused().should('have.id', 'description')
- })
-
- context('Cypress.Screenshot', function () {
- it('cy.screenshot() - take a screenshot', () => {
- // https://on.cypress.io/screenshot
- cy.screenshot('my-image')
- })
-
- it('Cypress.Screenshot.defaults() - change default config of screenshots', function () {
- Cypress.Screenshot.defaults({
- blackout: ['.foo'],
- capture: 'viewport',
- clip: { x: 0, y: 0, width: 200, height: 200 },
- scale: false,
- disableTimersAndAnimations: true,
- screenshotOnRunFailure: true,
- onBeforeScreenshot () { },
- onAfterScreenshot () { },
- })
- })
- })
-
- it('cy.wrap() - wrap an object', () => {
- // https://on.cypress.io/wrap
- cy.wrap({ foo: 'bar' })
- .should('have.property', 'foo')
- .and('include', 'bar')
- })
-})
diff --git a/client/cypress/integration/2-advanced-examples/navigation.spec.js b/client/cypress/integration/2-advanced-examples/navigation.spec.js
deleted file mode 100644
index b85a46890..000000000
--- a/client/cypress/integration/2-advanced-examples/navigation.spec.js
+++ /dev/null
@@ -1,56 +0,0 @@
-///
-
-context('Navigation', () => {
- beforeEach(() => {
- cy.visit('https://example.cypress.io')
- cy.get('.navbar-nav').contains('Commands').click()
- cy.get('.dropdown-menu').contains('Navigation').click()
- })
-
- it('cy.go() - go back or forward in the browser\'s history', () => {
- // https://on.cypress.io/go
-
- cy.location('pathname').should('include', 'navigation')
-
- cy.go('back')
- cy.location('pathname').should('not.include', 'navigation')
-
- cy.go('forward')
- cy.location('pathname').should('include', 'navigation')
-
- // clicking back
- cy.go(-1)
- cy.location('pathname').should('not.include', 'navigation')
-
- // clicking forward
- cy.go(1)
- cy.location('pathname').should('include', 'navigation')
- })
-
- it('cy.reload() - reload the page', () => {
- // https://on.cypress.io/reload
- cy.reload()
-
- // reload the page without using the cache
- cy.reload(true)
- })
-
- it('cy.visit() - visit a remote url', () => {
- // https://on.cypress.io/visit
-
- // Visit any sub-domain of your current domain
-
- // Pass options to the visit
- cy.visit('https://example.cypress.io/commands/navigation', {
- timeout: 50000, // increase total time for the visit to resolve
- onBeforeLoad (contentWindow) {
- // contentWindow is the remote page's window object
- expect(typeof contentWindow === 'object').to.be.true
- },
- onLoad (contentWindow) {
- // contentWindow is the remote page's window object
- expect(typeof contentWindow === 'object').to.be.true
- },
- })
- })
-})
diff --git a/client/cypress/integration/2-advanced-examples/network_requests.spec.js b/client/cypress/integration/2-advanced-examples/network_requests.spec.js
deleted file mode 100644
index 11213a0e8..000000000
--- a/client/cypress/integration/2-advanced-examples/network_requests.spec.js
+++ /dev/null
@@ -1,163 +0,0 @@
-///
-
-context('Network Requests', () => {
- beforeEach(() => {
- cy.visit('https://example.cypress.io/commands/network-requests')
- })
-
- // Manage HTTP requests in your app
-
- it('cy.request() - make an XHR request', () => {
- // https://on.cypress.io/request
- cy.request('https://jsonplaceholder.cypress.io/comments')
- .should((response) => {
- expect(response.status).to.eq(200)
- // the server sometimes gets an extra comment posted from another machine
- // which gets returned as 1 extra object
- expect(response.body).to.have.property('length').and.be.oneOf([500, 501])
- expect(response).to.have.property('headers')
- expect(response).to.have.property('duration')
- })
- })
-
- it('cy.request() - verify response using BDD syntax', () => {
- cy.request('https://jsonplaceholder.cypress.io/comments')
- .then((response) => {
- // https://on.cypress.io/assertions
- expect(response).property('status').to.equal(200)
- expect(response).property('body').to.have.property('length').and.be.oneOf([500, 501])
- expect(response).to.include.keys('headers', 'duration')
- })
- })
-
- it('cy.request() with query parameters', () => {
- // will execute request
- // https://jsonplaceholder.cypress.io/comments?postId=1&id=3
- cy.request({
- url: 'https://jsonplaceholder.cypress.io/comments',
- qs: {
- postId: 1,
- id: 3,
- },
- })
- .its('body')
- .should('be.an', 'array')
- .and('have.length', 1)
- .its('0') // yields first element of the array
- .should('contain', {
- postId: 1,
- id: 3,
- })
- })
-
- it('cy.request() - pass result to the second request', () => {
- // first, let's find out the userId of the first user we have
- cy.request('https://jsonplaceholder.cypress.io/users?_limit=1')
- .its('body') // yields the response object
- .its('0') // yields the first element of the returned list
- // the above two commands its('body').its('0')
- // can be written as its('body.0')
- // if you do not care about TypeScript checks
- .then((user) => {
- expect(user).property('id').to.be.a('number')
- // make a new post on behalf of the user
- cy.request('POST', 'https://jsonplaceholder.cypress.io/posts', {
- userId: user.id,
- title: 'Cypress Test Runner',
- body: 'Fast, easy and reliable testing for anything that runs in a browser.',
- })
- })
- // note that the value here is the returned value of the 2nd request
- // which is the new post object
- .then((response) => {
- expect(response).property('status').to.equal(201) // new entity created
- expect(response).property('body').to.contain({
- title: 'Cypress Test Runner',
- })
-
- // we don't know the exact post id - only that it will be > 100
- // since JSONPlaceholder has built-in 100 posts
- expect(response.body).property('id').to.be.a('number')
- .and.to.be.gt(100)
-
- // we don't know the user id here - since it was in above closure
- // so in this test just confirm that the property is there
- expect(response.body).property('userId').to.be.a('number')
- })
- })
-
- it('cy.request() - save response in the shared test context', () => {
- // https://on.cypress.io/variables-and-aliases
- cy.request('https://jsonplaceholder.cypress.io/users?_limit=1')
- .its('body').its('0') // yields the first element of the returned list
- .as('user') // saves the object in the test context
- .then(function () {
- // NOTE 👀
- // By the time this callback runs the "as('user')" command
- // has saved the user object in the test context.
- // To access the test context we need to use
- // the "function () { ... }" callback form,
- // otherwise "this" points at a wrong or undefined object!
- cy.request('POST', 'https://jsonplaceholder.cypress.io/posts', {
- userId: this.user.id,
- title: 'Cypress Test Runner',
- body: 'Fast, easy and reliable testing for anything that runs in a browser.',
- })
- .its('body').as('post') // save the new post from the response
- })
- .then(function () {
- // When this callback runs, both "cy.request" API commands have finished
- // and the test context has "user" and "post" objects set.
- // Let's verify them.
- expect(this.post, 'post has the right user id').property('userId').to.equal(this.user.id)
- })
- })
-
- it('cy.intercept() - route responses to matching requests', () => {
- // https://on.cypress.io/intercept
-
- let message = 'whoa, this comment does not exist'
-
- // Listen to GET to comments/1
- cy.intercept('GET', '**/comments/*').as('getComment')
-
- // we have code that gets a comment when
- // the button is clicked in scripts.js
- cy.get('.network-btn').click()
-
- // https://on.cypress.io/wait
- cy.wait('@getComment').its('response.statusCode').should('be.oneOf', [200, 304])
-
- // Listen to POST to comments
- cy.intercept('POST', '**/comments').as('postComment')
-
- // we have code that posts a comment when
- // the button is clicked in scripts.js
- cy.get('.network-post').click()
- cy.wait('@postComment').should(({ request, response }) => {
- expect(request.body).to.include('email')
- expect(request.headers).to.have.property('content-type')
- expect(response && response.body).to.have.property('name', 'Using POST in cy.intercept()')
- })
-
- // Stub a response to PUT comments/ ****
- cy.intercept({
- method: 'PUT',
- url: '**/comments/*',
- }, {
- statusCode: 404,
- body: { error: message },
- headers: { 'access-control-allow-origin': '*' },
- delayMs: 500,
- }).as('putComment')
-
- // we have code that puts a comment when
- // the button is clicked in scripts.js
- cy.get('.network-put').click()
-
- cy.wait('@putComment')
-
- // our 404 statusCode logic in scripts.js executed
- cy.get('.network-put-comment').should('contain', message)
- })
-})
diff --git a/client/cypress/integration/2-advanced-examples/querying.spec.js b/client/cypress/integration/2-advanced-examples/querying.spec.js
deleted file mode 100644
index 00970480f..000000000
--- a/client/cypress/integration/2-advanced-examples/querying.spec.js
+++ /dev/null
@@ -1,114 +0,0 @@
-///
-
-context('Querying', () => {
- beforeEach(() => {
- cy.visit('https://example.cypress.io/commands/querying')
- })
-
- // The most commonly used query is 'cy.get()', you can
- // think of this like the '$' in jQuery
-
- it('cy.get() - query DOM elements', () => {
- // https://on.cypress.io/get
-
- cy.get('#query-btn').should('contain', 'Button')
-
- cy.get('.query-btn').should('contain', 'Button')
-
- cy.get('#querying .well>button:first').should('contain', 'Button')
- // ↲
- // Use CSS selectors just like jQuery
-
- cy.get('[data-test-id="test-example"]').should('have.class', 'example')
-
- // 'cy.get()' yields jQuery object, you can get its attribute
- // by invoking `.attr()` method
- cy.get('[data-test-id="test-example"]')
- .invoke('attr', 'data-test-id')
- .should('equal', 'test-example')
-
- // or you can get element's CSS property
- cy.get('[data-test-id="test-example"]')
- .invoke('css', 'position')
- .should('equal', 'static')
-
- // or use assertions directly during 'cy.get()'
- // https://on.cypress.io/assertions
- cy.get('[data-test-id="test-example"]')
- .should('have.attr', 'data-test-id', 'test-example')
- .and('have.css', 'position', 'static')
- })
-
- it('cy.contains() - query DOM elements with matching content', () => {
- // https://on.cypress.io/contains
- cy.get('.query-list')
- .contains('bananas')
- .should('have.class', 'third')
-
- // we can pass a regexp to `.contains()`
- cy.get('.query-list')
- .contains(/^b\w+/)
- .should('have.class', 'third')
-
- cy.get('.query-list')
- .contains('apples')
- .should('have.class', 'first')
-
- // passing a selector to contains will
- // yield the selector containing the text
- cy.get('#querying')
- .contains('ul', 'oranges')
- .should('have.class', 'query-list')
-
- cy.get('.query-button')
- .contains('Save Form')
- .should('have.class', 'btn')
- })
-
- it('.within() - query DOM elements within a specific element', () => {
- // https://on.cypress.io/within
- cy.get('.query-form').within(() => {
- cy.get('input:first').should('have.attr', 'placeholder', 'Email')
- cy.get('input:last').should('have.attr', 'placeholder', 'Password')
- })
- })
-
- it('cy.root() - query the root DOM element', () => {
- // https://on.cypress.io/root
-
- // By default, root is the document
- cy.root().should('match', 'html')
-
- cy.get('.query-ul').within(() => {
- // In this within, the root is now the ul DOM element
- cy.root().should('have.class', 'query-ul')
- })
- })
-
- it('best practices - selecting elements', () => {
- // https://on.cypress.io/best-practices#Selecting-Elements
- cy.get('[data-cy=best-practices-selecting-elements]').within(() => {
- // Worst - too generic, no context
- cy.get('button').click()
-
- // Bad. Coupled to styling. Highly subject to change.
- cy.get('.btn.btn-large').click()
-
- // Average. Coupled to the `name` attribute which has HTML semantics.
- cy.get('[name=submission]').click()
-
- // Better. But still coupled to styling or JS event listeners.
- cy.get('#main').click()
-
- // Slightly better. Uses an ID but also ensures the element
- // has an ARIA role attribute
- cy.get('#main[role=button]').click()
-
- // Much better. But still coupled to text content that may change.
- cy.contains('Submit').click()
-
- // Best. Insulated from all changes.
- cy.get('[data-cy=submit]').click()
- })
- })
-})
diff --git a/client/cypress/integration/2-advanced-examples/spies_stubs_clocks.spec.js b/client/cypress/integration/2-advanced-examples/spies_stubs_clocks.spec.js
deleted file mode 100644
index 18b643ecd..000000000
--- a/client/cypress/integration/2-advanced-examples/spies_stubs_clocks.spec.js
+++ /dev/null
@@ -1,205 +0,0 @@
-///
-// remove no check once Cypress.sinon is typed
-// https://github.com/cypress-io/cypress/issues/6720
-
-context('Spies, Stubs, and Clock', () => {
- it('cy.spy() - wrap a method in a spy', () => {
- // https://on.cypress.io/spy
- cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
-
- const obj = {
- foo () {},
- }
-
- const spy = cy.spy(obj, 'foo').as('anyArgs')
-
- obj.foo()
-
- expect(spy).to.be.called
- })
-
- it('cy.spy() retries until assertions pass', () => {
- cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
-
- const obj = {
- /**
- * Prints the argument passed
- * @param x {any}
- */
- foo (x) {
- console.log('obj.foo called with', x)
- },
- }
-
- cy.spy(obj, 'foo').as('foo')
-
- setTimeout(() => {
- obj.foo('first')
- }, 500)
-
- setTimeout(() => {
- obj.foo('second')
- }, 2500)
-
- cy.get('@foo').should('have.been.calledTwice')
- })
-
- it('cy.stub() - create a stub and/or replace a function with stub', () => {
- // https://on.cypress.io/stub
- cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
-
- const obj = {
- /**
- * prints both arguments to the console
- * @param a {string}
- * @param b {string}
- */
- foo (a, b) {
- console.log('a', a, 'b', b)
- },
- }
-
- const stub = cy.stub(obj, 'foo').as('foo')
-
- obj.foo('foo', 'bar')
-
- expect(stub).to.be.called
- })
-
- it('cy.clock() - control time in the browser', () => {
- // https://on.cypress.io/clock
-
- // create the date in UTC so its always the same
- // no matter what local timezone the browser is running in
- const now = new Date(Date.UTC(2017, 2, 14)).getTime()
-
- cy.clock(now)
- cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
- cy.get('#clock-div').click()
- .should('have.text', '1489449600')
- })
-
- it('cy.tick() - move time in the browser', () => {
- // https://on.cypress.io/tick
-
- // create the date in UTC so its always the same
- // no matter what local timezone the browser is running in
- const now = new Date(Date.UTC(2017, 2, 14)).getTime()
-
- cy.clock(now)
- cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
- cy.get('#tick-div').click()
- .should('have.text', '1489449600')
-
- cy.tick(10000) // 10 seconds passed
- cy.get('#tick-div').click()
- .should('have.text', '1489449610')
- })
-
- it('cy.stub() matches depending on arguments', () => {
- // see all possible matchers at
- // https://sinonjs.org/releases/latest/matchers/
- const greeter = {
- /**
- * Greets a person
- * @param {string} name
- */
- greet (name) {
- return `Hello, ${name}!`
- },
- }
-
- cy.stub(greeter, 'greet')
- .callThrough() // if you want non-matched calls to call the real method
- .withArgs(Cypress.sinon.match.string).returns('Hi')
- .withArgs(Cypress.sinon.match.number).throws(new Error('Invalid name'))
-
- expect(greeter.greet('World')).to.equal('Hi')
- // @ts-ignore
- expect(() => greeter.greet(42)).to.throw('Invalid name')
- expect(greeter.greet).to.have.been.calledTwice
-
- // non-matched calls goes the actual method
- // @ts-ignore
- expect(greeter.greet()).to.equal('Hello, undefined!')
- })
-
- it('matches call arguments using Sinon matchers', () => {
- // see all possible matchers at
- // https://sinonjs.org/releases/latest/matchers/
- const calculator = {
- /**
- * returns the sum of two arguments
- * @param a {number}
- * @param b {number}
- */
- add (a, b) {
- return a + b
- },
- }
-
- const spy = cy.spy(calculator, 'add').as('add')
-
- expect(calculator.add(2, 3)).to.equal(5)
-
- // if we want to assert the exact values used during the call
- expect(spy).to.be.calledWith(2, 3)
-
- // let's confirm "add" method was called with two numbers
- expect(spy).to.be.calledWith(Cypress.sinon.match.number, Cypress.sinon.match.number)
-
- // alternatively, provide the value to match
- expect(spy).to.be.calledWith(Cypress.sinon.match(2), Cypress.sinon.match(3))
-
- // match any value
- expect(spy).to.be.calledWith(Cypress.sinon.match.any, 3)
-
- // match any value from a list
- expect(spy).to.be.calledWith(Cypress.sinon.match.in([1, 2, 3]), 3)
-
- /**
- * Returns true if the given number is event
- * @param {number} x
- */
- const isEven = (x) => x % 2 === 0
-
- // expect the value to pass a custom predicate function
- // the second argument to "sinon.match(predicate, message)" is
- // shown if the predicate does not pass and assertion fails
- expect(spy).to.be.calledWith(Cypress.sinon.match(isEven, 'isEven'), 3)
-
- /**
- * Returns a function that checks if a given number is larger than the limit
- * @param {number} limit
- * @returns {(x: number) => boolean}
- */
- const isGreaterThan = (limit) => (x) => x > limit
-
- /**
- * Returns a function that checks if a given number is less than the limit
- * @param {number} limit
- * @returns {(x: number) => boolean}
- */
- const isLessThan = (limit) => (x) => x < limit
-
- // you can combine several matchers using "and", "or"
- expect(spy).to.be.calledWith(
- Cypress.sinon.match.number,
- Cypress.sinon.match(isGreaterThan(2), '> 2').and(Cypress.sinon.match(isLessThan(4), '< 4')),
- )
-
- expect(spy).to.be.calledWith(
- Cypress.sinon.match.number,
- Cypress.sinon.match(isGreaterThan(200), '> 200').or(Cypress.sinon.match(3)),
- )
-
- // matchers can be used from BDD assertions
- cy.get('@add').should('have.been.calledWith',
- Cypress.sinon.match.number, Cypress.sinon.match(3))
-
- // you can alias matchers for shorter test code
- const { match: M } = Cypress.sinon
-
- cy.get('@add').should('have.been.calledWith', M.number, M(3))
- })
-})
diff --git a/client/cypress/integration/2-advanced-examples/traversal.spec.js b/client/cypress/integration/2-advanced-examples/traversal.spec.js
deleted file mode 100644
index 0a3b9d330..000000000
--- a/client/cypress/integration/2-advanced-examples/traversal.spec.js
+++ /dev/null
@@ -1,121 +0,0 @@
-///
-
-context('Traversal', () => {
- beforeEach(() => {
- cy.visit('https://example.cypress.io/commands/traversal')
- })
-
- it('.children() - get child DOM elements', () => {
- // https://on.cypress.io/children
- cy.get('.traversal-breadcrumb')
- .children('.active')
- .should('contain', 'Data')
- })
-
- it('.closest() - get closest ancestor DOM element', () => {
- // https://on.cypress.io/closest
- cy.get('.traversal-badge')
- .closest('ul')
- .should('have.class', 'list-group')
- })
-
- it('.eq() - get a DOM element at a specific index', () => {
- // https://on.cypress.io/eq
- cy.get('.traversal-list>li')
- .eq(1).should('contain', 'siamese')
- })
-
- it('.filter() - get DOM elements that match the selector', () => {
- // https://on.cypress.io/filter
- cy.get('.traversal-nav>li')
- .filter('.active').should('contain', 'About')
- })
-
- it('.find() - get descendant DOM elements of the selector', () => {
- // https://on.cypress.io/find
- cy.get('.traversal-pagination')
- .find('li').find('a')
- .should('have.length', 7)
- })
-
- it('.first() - get first DOM element', () => {
- // https://on.cypress.io/first
- cy.get('.traversal-table td')
- .first().should('contain', '1')
- })
-
- it('.last() - get last DOM element', () => {
- // https://on.cypress.io/last
- cy.get('.traversal-buttons .btn')
- .last().should('contain', 'Submit')
- })
-
- it('.next() - get next sibling DOM element', () => {
- // https://on.cypress.io/next
- cy.get('.traversal-ul')
- .contains('apples').next().should('contain', 'oranges')
- })
-
- it('.nextAll() - get all next sibling DOM elements', () => {
- // https://on.cypress.io/nextall
- cy.get('.traversal-next-all')
- .contains('oranges')
- .nextAll().should('have.length', 3)
- })
-
- it('.nextUntil() - get next sibling DOM elements until next el', () => {
- // https://on.cypress.io/nextuntil
- cy.get('#veggies')
- .nextUntil('#nuts').should('have.length', 3)
- })
-
- it('.not() - remove DOM elements from set of DOM elements', () => {
- // https://on.cypress.io/not
- cy.get('.traversal-disabled .btn')
- .not('[disabled]').should('not.contain', 'Disabled')
- })
-
- it('.parent() - get parent DOM element from DOM elements', () => {
- // https://on.cypress.io/parent
- cy.get('.traversal-mark')
- .parent().should('contain', 'Morbi leo risus')
- })
-
- it('.parents() - get parent DOM elements from DOM elements', () => {
- // https://on.cypress.io/parents
- cy.get('.traversal-cite')
- .parents().should('match', 'blockquote')
- })
-
- it('.parentsUntil() - get parent DOM elements from DOM elements until el', () => {
- // https://on.cypress.io/parentsuntil
- cy.get('.clothes-nav')
- .find('.active')
- .parentsUntil('.clothes-nav')
- .should('have.length', 2)
- })
-
- it('.prev() - get previous sibling DOM element', () => {
- // https://on.cypress.io/prev
- cy.get('.birds').find('.active')
- .prev().should('contain', 'Lorikeets')
- })
-
- it('.prevAll() - get all previous sibling DOM elements', () => {
- // https://on.cypress.io/prevall
- cy.get('.fruits-list').find('.third')
- .prevAll().should('have.length', 2)
- })
-
- it('.prevUntil() - get all previous sibling DOM elements until el', () => {
- // https://on.cypress.io/prevuntil
- cy.get('.foods-list').find('#nuts')
- .prevUntil('#veggies').should('have.length', 3)
- })
-
- it('.siblings() - get all sibling DOM elements', () => {
- // https://on.cypress.io/siblings
- cy.get('.traversal-pills .active')
- .siblings().should('have.length', 2)
- })
-})
diff --git a/client/cypress/integration/2-advanced-examples/utilities.spec.js b/client/cypress/integration/2-advanced-examples/utilities.spec.js
deleted file mode 100644
index 24e61a6a7..000000000
--- a/client/cypress/integration/2-advanced-examples/utilities.spec.js
+++ /dev/null
@@ -1,110 +0,0 @@
-///
-
-context('Utilities', () => {
- beforeEach(() => {
- cy.visit('https://example.cypress.io/utilities')
- })
-
- it('Cypress._ - call a lodash method', () => {
- // https://on.cypress.io/_
- cy.request('https://jsonplaceholder.cypress.io/users')
- .then((response) => {
- let ids = Cypress._.chain(response.body).map('id').take(3).value()
-
- expect(ids).to.deep.eq([1, 2, 3])
- })
- })
-
- it('Cypress.$ - call a jQuery method', () => {
- // https://on.cypress.io/$
- let $li = Cypress.$('.utility-jquery li:first')
-
- cy.wrap($li)
- .should('not.have.class', 'active')
- .click()
- .should('have.class', 'active')
- })
-
- it('Cypress.Blob - blob utilities and base64 string conversion', () => {
- // https://on.cypress.io/blob
- cy.get('.utility-blob').then(($div) => {
- // https://github.com/nolanlawson/blob-util#imgSrcToDataURL
- // get the dataUrl string for the javascript-logo
- return Cypress.Blob.imgSrcToDataURL('https://example.cypress.io/assets/img/javascript-logo.png', undefined, 'anonymous')
- .then((dataUrl) => {
- // create an element and set its src to the dataUrl
- let img = Cypress.$(' ', { src: dataUrl })
-
- // need to explicitly return cy here since we are initially returning
- // the Cypress.Blob.imgSrcToDataURL promise to our test
- // append the image
- $div.append(img)
-
- cy.get('.utility-blob img').click()
- .should('have.attr', 'src', dataUrl)
- })
- })
- })
-
- it('Cypress.minimatch - test out glob patterns against strings', () => {
- // https://on.cypress.io/minimatch
- let matching = Cypress.minimatch('/users/1/comments', '/users/*/comments', {
- matchBase: true,
- })
-
- expect(matching, 'matching wildcard').to.be.true
-
- matching = Cypress.minimatch('/users/1/comments/2', '/users/*/comments', {
- matchBase: true,
- })
-
- expect(matching, 'comments').to.be.false
-
- // ** matches against all downstream path segments
- matching = Cypress.minimatch('/foo/bar/baz/123/quux?a=b&c=2', '/foo/**', {
- matchBase: true,
- })
-
- expect(matching, 'comments').to.be.true
-
- // whereas * matches only the next path segment
-
- matching = Cypress.minimatch('/foo/bar/baz/123/quux?a=b&c=2', '/foo/*', {
- matchBase: false,
- })
-
- expect(matching, 'comments').to.be.false
- })
-
- it('Cypress.Promise - instantiate a bluebird promise', () => {
- // https://on.cypress.io/promise
- let waited = false
-
- /**
- * @return Bluebird
- */
- function waitOneSecond () {
- // return a promise that resolves after 1 second
- // @ts-ignore TS2351 (new Cypress.Promise)
- return new Cypress.Promise((resolve, reject) => {
- setTimeout(() => {
- // set waited to true
- waited = true
-
- // resolve with 'foo' string
- resolve('foo')
- }, 1000)
- })
- }
-
- cy.then(() => {
- // return a promise to cy.then() that
- // is awaited until it resolves
- // @ts-ignore TS7006
- return waitOneSecond().then((str) => {
- expect(str).to.eq('foo')
- expect(waited).to.be.true
- })
- })
- })
-})
diff --git a/client/cypress/integration/2-advanced-examples/viewport.spec.js b/client/cypress/integration/2-advanced-examples/viewport.spec.js
deleted file mode 100644
index dbcd7eedd..000000000
--- a/client/cypress/integration/2-advanced-examples/viewport.spec.js
+++ /dev/null
@@ -1,59 +0,0 @@
-///
-
-context('Viewport', () => {
- beforeEach(() => {
- cy.visit('https://example.cypress.io/commands/viewport')
- })
-
- it('cy.viewport() - set the viewport size and dimension', () => {
- // https://on.cypress.io/viewport
-
- cy.get('#navbar').should('be.visible')
- cy.viewport(320, 480)
-
- // the navbar should have collapse since our screen is smaller
- cy.get('#navbar').should('not.be.visible')
- cy.get('.navbar-toggle').should('be.visible').click()
- cy.get('.nav').find('a').should('be.visible')
-
- // lets see what our app looks like on a super large screen
- cy.viewport(2999, 2999)
-
- // cy.viewport() accepts a set of preset sizes
- // to easily set the screen to a device's width and height
-
- // We added a cy.wait() between each viewport change so you can see
- // the change otherwise it is a little too fast to see :)
-
- cy.viewport('macbook-15')
- cy.wait(200)
- cy.viewport('macbook-13')
- cy.wait(200)
- cy.viewport('macbook-11')
- cy.wait(200)
- cy.viewport('ipad-2')
- cy.wait(200)
- cy.viewport('ipad-mini')
- cy.wait(200)
- cy.viewport('iphone-6+')
- cy.wait(200)
- cy.viewport('iphone-6')
- cy.wait(200)
- cy.viewport('iphone-5')
- cy.wait(200)
- cy.viewport('iphone-4')
- cy.wait(200)
- cy.viewport('iphone-3')
- cy.wait(200)
-
- // cy.viewport() accepts an orientation for all presets
- // the default orientation is 'portrait'
- cy.viewport('ipad-2', 'portrait')
- cy.wait(200)
- cy.viewport('iphone-4', 'landscape')
- cy.wait(200)
-
- // The viewport will be reset back to the default dimensions
- // in between tests (the default can be set in cypress.json)
- })
-})
diff --git a/client/cypress/integration/2-advanced-examples/waiting.spec.js b/client/cypress/integration/2-advanced-examples/waiting.spec.js
deleted file mode 100644
index c8f0d7c67..000000000
--- a/client/cypress/integration/2-advanced-examples/waiting.spec.js
+++ /dev/null
@@ -1,31 +0,0 @@
-///
-
-context('Waiting', () => {
- beforeEach(() => {
- cy.visit('https://example.cypress.io/commands/waiting')
- })
- // BE CAREFUL of adding unnecessary wait times.
- // https://on.cypress.io/best-practices#Unnecessary-Waiting
-
- // https://on.cypress.io/wait
- it('cy.wait() - wait for a specific amount of time', () => {
- cy.get('.wait-input1').type('Wait 1000ms after typing')
- cy.wait(1000)
- cy.get('.wait-input2').type('Wait 1000ms after typing')
- cy.wait(1000)
- cy.get('.wait-input3').type('Wait 1000ms after typing')
- cy.wait(1000)
- })
-
- it('cy.wait() - wait for a specific route', () => {
- // Listen to GET to comments/1
- cy.intercept('GET', '**/comments/*').as('getComment')
-
- // we have code that gets a comment when
- // the button is clicked in scripts.js
- cy.get('.network-btn').click()
-
- // wait for GET comments/1
- cy.wait('@getComment').its('response.statusCode').should('be.oneOf', [200, 304])
- })
-})
diff --git a/client/cypress/integration/2-advanced-examples/window.spec.js b/client/cypress/integration/2-advanced-examples/window.spec.js
deleted file mode 100644
index f94b64971..000000000
--- a/client/cypress/integration/2-advanced-examples/window.spec.js
+++ /dev/null
@@ -1,22 +0,0 @@
-///
-
-context('Window', () => {
- beforeEach(() => {
- cy.visit('https://example.cypress.io/commands/window')
- })
-
- it('cy.window() - get the global window object', () => {
- // https://on.cypress.io/window
- cy.window().should('have.property', 'top')
- })
-
- it('cy.document() - get the document object', () => {
- // https://on.cypress.io/document
- cy.document().should('have.property', 'charset').and('eq', 'UTF-8')
- })
-
- it('cy.title() - get the title', () => {
- // https://on.cypress.io/title
- cy.title().should('include', 'Kitchen Sink')
- })
-})
diff --git a/client/cypress/plugins/index.js b/client/cypress/plugins/index.js
deleted file mode 100644
index 59b2bab6e..000000000
--- a/client/cypress/plugins/index.js
+++ /dev/null
@@ -1,22 +0,0 @@
-///
-// ***********************************************************
-// This example plugins/index.js can be used to load plugins
-//
-// You can change the location of this file or turn off loading
-// the plugins file with the 'pluginsFile' configuration option.
-//
-// You can read more here:
-// https://on.cypress.io/plugins-guide
-// ***********************************************************
-
-// This function is called when a project is opened or re-opened (e.g. due to
-// the project's config changing)
-
-/**
- * @type {Cypress.PluginConfig}
- */
-// eslint-disable-next-line no-unused-vars
-module.exports = (on, config) => {
- // `on` is used to hook into various events Cypress emits
- // `config` is the resolved Cypress config
-}
diff --git a/client/cypress/support/commands.js b/client/cypress/support/commands.js
index 81f195804..66ea16ef0 100644
--- a/client/cypress/support/commands.js
+++ b/client/cypress/support/commands.js
@@ -22,6 +22,4 @@
//
//
// -- This will overwrite an existing command --
-// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
-
-import "@testing-library/cypress/add-commands";
+// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
\ No newline at end of file
diff --git a/client/cypress/support/index.js b/client/cypress/support/e2e.js
similarity index 88%
rename from client/cypress/support/index.js
rename to client/cypress/support/e2e.js
index d68db96df..0e7290a13 100644
--- a/client/cypress/support/index.js
+++ b/client/cypress/support/e2e.js
@@ -1,5 +1,5 @@
// ***********************************************************
-// This example support/index.js is processed and
+// This example support/e2e.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
@@ -17,4 +17,4 @@
import './commands'
// Alternatively you can use CommonJS syntax:
-// require('./commands')
+// require('./commands')
\ No newline at end of file
diff --git a/client/cypress/tsconfig.json b/client/cypress/tsconfig.json
deleted file mode 100644
index 36de33dee..000000000
--- a/client/cypress/tsconfig.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "compilerOptions": {
- "allowJs": true,
- "baseUrl": "../node_modules",
- "types": ["cypress"]
- },
- "include": ["**/*.*"]
-}
diff --git a/client/package.json b/client/package.json
index c6eda0caa..c4983c53c 100644
--- a/client/package.json
+++ b/client/package.json
@@ -20,7 +20,6 @@
"axios": "^0.27.2",
"craco-less": "^1.20.0",
"dinero.js": "^1.9.1",
- "dotenv": "^16.0.1",
"enquire-js": "^0.2.1",
"env-cmd": "^10.1.0",
"exifr": "^7.1.3",
@@ -82,8 +81,7 @@
"workbox-range-requests": "^6.5.3",
"workbox-routing": "^6.5.3",
"workbox-strategies": "^6.5.3",
- "workbox-streams": "^6.5.3",
- "yauzl": "^2.10.0"
+ "workbox-streams": "^6.5.3"
},
"scripts": {
"analyze": "source-map-explorer 'build/static/js/*.js'",
@@ -93,8 +91,7 @@
"build-deploy:test": "yarn run build:test && s3cmd sync build/* s3://imex-online-test && echo '🚀 TESTING Deployed!'",
"buildcra": "REACT_APP_GIT_SHA=`git rev-parse --short HEAD` craco build",
"test": "cypress open",
- "eject": "react-scripts eject",
- "madge": "madge --image ./madge-graph.svg --extensions js,jsx,ts,tsx --circular ."
+ "eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
@@ -120,9 +117,7 @@
},
"devDependencies": {
"@sentry/webpack-plugin": "^1.19.0",
- "@testing-library/cypress": "^8.0.3",
- "cypress": "^10.3.1",
- "eslint-plugin-cypress": "^2.12.1",
+ "cypress": "^12.2.0",
"react-error-overlay": "6.0.11",
"redux-logger": "^3.0.6",
"source-map-explorer": "^2.5.2"
diff --git a/client/patches/peerjs+1.3.2.patch b/client/patches/peerjs+1.3.2.patch
deleted file mode 100644
index 197ede2f2..000000000
--- a/client/patches/peerjs+1.3.2.patch
+++ /dev/null
@@ -1,13087 +0,0 @@
-diff --git a/node_modules/peerjs/dist/adapter.js b/node_modules/peerjs/dist/adapter.js
-new file mode 100644
-index 0000000..6bfbeb8
---- /dev/null
-+++ b/node_modules/peerjs/dist/adapter.js
-@@ -0,0 +1,8 @@
-+"use strict";
-+var __importDefault = (this && this.__importDefault) || function (mod) {
-+ return (mod && mod.__esModule) ? mod : { "default": mod };
-+};
-+Object.defineProperty(exports, "__esModule", { value: true });
-+exports.webRTCAdapter = void 0;
-+var webrtc_adapter_1 = __importDefault(require("webrtc-adapter"));
-+exports.webRTCAdapter = webrtc_adapter_1.default;
-diff --git a/node_modules/peerjs/dist/api.js b/node_modules/peerjs/dist/api.js
-new file mode 100644
-index 0000000..8c091c2
---- /dev/null
-+++ b/node_modules/peerjs/dist/api.js
-@@ -0,0 +1,142 @@
-+"use strict";
-+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
-+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
-+ return new (P || (P = Promise))(function (resolve, reject) {
-+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
-+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
-+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
-+ step((generator = generator.apply(thisArg, _arguments || [])).next());
-+ });
-+};
-+var __generator = (this && this.__generator) || function (thisArg, body) {
-+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
-+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
-+ function verb(n) { return function (v) { return step([n, v]); }; }
-+ function step(op) {
-+ if (f) throw new TypeError("Generator is already executing.");
-+ while (_) try {
-+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
-+ if (y = 0, t) op = [op[0] & 2, t.value];
-+ switch (op[0]) {
-+ case 0: case 1: t = op; break;
-+ case 4: _.label++; return { value: op[1], done: false };
-+ case 5: _.label++; y = op[1]; op = [0]; continue;
-+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
-+ default:
-+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
-+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
-+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
-+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
-+ if (t[2]) _.ops.pop();
-+ _.trys.pop(); continue;
-+ }
-+ op = body.call(thisArg, _);
-+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
-+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
-+ }
-+};
-+var __importDefault = (this && this.__importDefault) || function (mod) {
-+ return (mod && mod.__esModule) ? mod : { "default": mod };
-+};
-+Object.defineProperty(exports, "__esModule", { value: true });
-+exports.API = void 0;
-+var util_1 = require("./util");
-+var logger_1 = __importDefault(require("./logger"));
-+var API = /** @class */ (function () {
-+ function API(_options) {
-+ this._options = _options;
-+ }
-+ API.prototype._buildUrl = function (method) {
-+ var protocol = this._options.secure ? "https://" : "http://";
-+ var url = protocol +
-+ this._options.host +
-+ ":" +
-+ this._options.port +
-+ this._options.path +
-+ this._options.key +
-+ "/" +
-+ method;
-+ var queryString = "?ts=" + new Date().getTime() + "" + Math.random();
-+ url += queryString;
-+ return url;
-+ };
-+ /** Get a unique ID from the server via XHR and initialize with it. */
-+ API.prototype.retrieveId = function () {
-+ return __awaiter(this, void 0, void 0, function () {
-+ var url, response, error_1, pathError;
-+ return __generator(this, function (_a) {
-+ switch (_a.label) {
-+ case 0:
-+ url = this._buildUrl("id");
-+ _a.label = 1;
-+ case 1:
-+ _a.trys.push([1, 3, , 4]);
-+ return [4 /*yield*/, fetch(url)];
-+ case 2:
-+ response = _a.sent();
-+ if (response.status !== 200) {
-+ throw new Error("Error. Status:" + response.status);
-+ }
-+ return [2 /*return*/, response.text()];
-+ case 3:
-+ error_1 = _a.sent();
-+ logger_1.default.error("Error retrieving ID", error_1);
-+ pathError = "";
-+ if (this._options.path === "/" &&
-+ this._options.host !== util_1.util.CLOUD_HOST) {
-+ pathError =
-+ " If you passed in a `path` to your self-hosted PeerServer, " +
-+ "you'll also need to pass in that same path when creating a new " +
-+ "Peer.";
-+ }
-+ throw new Error("Could not get an ID from the server." + pathError);
-+ case 4: return [2 /*return*/];
-+ }
-+ });
-+ });
-+ };
-+ /** @deprecated */
-+ API.prototype.listAllPeers = function () {
-+ return __awaiter(this, void 0, void 0, function () {
-+ var url, response, helpfulError, error_2;
-+ return __generator(this, function (_a) {
-+ switch (_a.label) {
-+ case 0:
-+ url = this._buildUrl("peers");
-+ _a.label = 1;
-+ case 1:
-+ _a.trys.push([1, 3, , 4]);
-+ return [4 /*yield*/, fetch(url)];
-+ case 2:
-+ response = _a.sent();
-+ if (response.status !== 200) {
-+ if (response.status === 401) {
-+ helpfulError = "";
-+ if (this._options.host === util_1.util.CLOUD_HOST) {
-+ helpfulError =
-+ "It looks like you're using the cloud server. You can email " +
-+ "team@peerjs.com to enable peer listing for your API key.";
-+ }
-+ else {
-+ helpfulError =
-+ "You need to enable `allow_discovery` on your self-hosted " +
-+ "PeerServer to use this feature.";
-+ }
-+ throw new Error("It doesn't look like you have permission to list peers IDs. " +
-+ helpfulError);
-+ }
-+ throw new Error("Error. Status:" + response.status);
-+ }
-+ return [2 /*return*/, response.json()];
-+ case 3:
-+ error_2 = _a.sent();
-+ logger_1.default.error("Error retrieving list peers", error_2);
-+ throw new Error("Could not get list peers from the server." + error_2);
-+ case 4: return [2 /*return*/];
-+ }
-+ });
-+ });
-+ };
-+ return API;
-+}());
-+exports.API = API;
-diff --git a/node_modules/peerjs/dist/baseconnection.js b/node_modules/peerjs/dist/baseconnection.js
-new file mode 100644
-index 0000000..0c4e504
---- /dev/null
-+++ b/node_modules/peerjs/dist/baseconnection.js
-@@ -0,0 +1,40 @@
-+"use strict";
-+var __extends = (this && this.__extends) || (function () {
-+ var extendStatics = function (d, b) {
-+ extendStatics = Object.setPrototypeOf ||
-+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
-+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
-+ return extendStatics(d, b);
-+ };
-+ return function (d, b) {
-+ if (typeof b !== "function" && b !== null)
-+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
-+ extendStatics(d, b);
-+ function __() { this.constructor = d; }
-+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
-+ };
-+})();
-+Object.defineProperty(exports, "__esModule", { value: true });
-+exports.BaseConnection = void 0;
-+var eventemitter3_1 = require("eventemitter3");
-+var BaseConnection = /** @class */ (function (_super) {
-+ __extends(BaseConnection, _super);
-+ function BaseConnection(peer, provider, options) {
-+ var _this = _super.call(this) || this;
-+ _this.peer = peer;
-+ _this.provider = provider;
-+ _this.options = options;
-+ _this._open = false;
-+ _this.metadata = options.metadata;
-+ return _this;
-+ }
-+ Object.defineProperty(BaseConnection.prototype, "open", {
-+ get: function () {
-+ return this._open;
-+ },
-+ enumerable: false,
-+ configurable: true
-+ });
-+ return BaseConnection;
-+}(eventemitter3_1.EventEmitter));
-+exports.BaseConnection = BaseConnection;
-diff --git a/node_modules/peerjs/dist/dataconnection.js b/node_modules/peerjs/dist/dataconnection.js
-new file mode 100644
-index 0000000..64262ac
---- /dev/null
-+++ b/node_modules/peerjs/dist/dataconnection.js
-@@ -0,0 +1,298 @@
-+"use strict";
-+var __extends = (this && this.__extends) || (function () {
-+ var extendStatics = function (d, b) {
-+ extendStatics = Object.setPrototypeOf ||
-+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
-+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
-+ return extendStatics(d, b);
-+ };
-+ return function (d, b) {
-+ if (typeof b !== "function" && b !== null)
-+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
-+ extendStatics(d, b);
-+ function __() { this.constructor = d; }
-+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
-+ };
-+})();
-+var __importDefault = (this && this.__importDefault) || function (mod) {
-+ return (mod && mod.__esModule) ? mod : { "default": mod };
-+};
-+Object.defineProperty(exports, "__esModule", { value: true });
-+exports.DataConnection = void 0;
-+var util_1 = require("./util");
-+var logger_1 = __importDefault(require("./logger"));
-+var negotiator_1 = require("./negotiator");
-+var enums_1 = require("./enums");
-+var baseconnection_1 = require("./baseconnection");
-+var encodingQueue_1 = require("./encodingQueue");
-+/**
-+ * Wraps a DataChannel between two Peers.
-+ */
-+// @ts-ignore
-+var DataConnection = /** @class */ (function (_super) {
-+ __extends(DataConnection, _super);
-+ function DataConnection(peerId, provider, options) {
-+ var _this = _super.call(this, peerId, provider, options) || this;
-+ _this.stringify = JSON.stringify;
-+ _this.parse = JSON.parse;
-+ _this._buffer = [];
-+ _this._bufferSize = 0;
-+ _this._buffering = false;
-+ _this._chunkedData = {};
-+ _this._encodingQueue = new encodingQueue_1.EncodingQueue();
-+ _this.connectionId =
-+ _this.options.connectionId || DataConnection.ID_PREFIX + util_1.util.randomToken();
-+ _this.label = _this.options.label || _this.connectionId;
-+ _this.serialization = _this.options.serialization || enums_1.SerializationType.Binary;
-+ _this.reliable = !!_this.options.reliable;
-+ _this._encodingQueue.on('done', function (ab) {
-+ _this._bufferedSend(ab);
-+ });
-+ _this._encodingQueue.on('error', function () {
-+ logger_1.default.error("DC#" + _this.connectionId + ": Error occured in encoding from blob to arraybuffer, close DC");
-+ _this.close();
-+ });
-+ _this._negotiator = new negotiator_1.Negotiator(_this);
-+ _this._negotiator.startConnection(_this.options._payload || {
-+ originator: true
-+ });
-+ return _this;
-+ }
-+ Object.defineProperty(DataConnection.prototype, "type", {
-+ get: function () {
-+ return enums_1.ConnectionType.Data;
-+ },
-+ enumerable: false,
-+ configurable: true
-+ });
-+ Object.defineProperty(DataConnection.prototype, "dataChannel", {
-+ get: function () {
-+ return this._dc;
-+ },
-+ enumerable: false,
-+ configurable: true
-+ });
-+ Object.defineProperty(DataConnection.prototype, "bufferSize", {
-+ get: function () { return this._bufferSize; },
-+ enumerable: false,
-+ configurable: true
-+ });
-+ /** Called by the Negotiator when the DataChannel is ready. */
-+ DataConnection.prototype.initialize = function (dc) {
-+ this._dc = dc;
-+ this._configureDataChannel();
-+ };
-+ DataConnection.prototype._configureDataChannel = function () {
-+ var _this = this;
-+ if (!util_1.util.supports.binaryBlob || util_1.util.supports.reliable) {
-+ this.dataChannel.binaryType = "arraybuffer";
-+ }
-+ this.dataChannel.onopen = function () {
-+ logger_1.default.log("DC#" + _this.connectionId + " dc connection success");
-+ _this._open = true;
-+ _this.emit(enums_1.ConnectionEventType.Open);
-+ };
-+ this.dataChannel.onmessage = function (e) {
-+ logger_1.default.log("DC#" + _this.connectionId + " dc onmessage:", e.data);
-+ _this._handleDataMessage(e);
-+ };
-+ this.dataChannel.onclose = function () {
-+ logger_1.default.log("DC#" + _this.connectionId + " dc closed for:", _this.peer);
-+ _this.close();
-+ };
-+ };
-+ // Handles a DataChannel message.
-+ DataConnection.prototype._handleDataMessage = function (_a) {
-+ var _this = this;
-+ var data = _a.data;
-+ var datatype = data.constructor;
-+ var isBinarySerialization = this.serialization === enums_1.SerializationType.Binary ||
-+ this.serialization === enums_1.SerializationType.BinaryUTF8;
-+ var deserializedData = data;
-+ if (isBinarySerialization) {
-+ if (datatype === Blob) {
-+ // Datatype should never be blob
-+ util_1.util.blobToArrayBuffer(data, function (ab) {
-+ // @ts-ignore
-+ var unpackedData = util_1.util.unpack(ab);
-+ _this.emit(enums_1.ConnectionEventType.Data, unpackedData);
-+ });
-+ return;
-+ }
-+ else if (datatype === ArrayBuffer) {
-+ deserializedData = util_1.util.unpack(data);
-+ }
-+ else if (datatype === String) {
-+ // String fallback for binary data for browsers that don't support binary yet
-+ var ab = util_1.util.binaryStringToArrayBuffer(data);
-+ deserializedData = util_1.util.unpack(ab);
-+ }
-+ }
-+ else if (this.serialization === enums_1.SerializationType.JSON) {
-+ deserializedData = this.parse(data);
-+ }
-+ // Check if we've chunked--if so, piece things back together.
-+ // We're guaranteed that this isn't 0.
-+ if (deserializedData.__peerData) {
-+ this._handleChunk(deserializedData);
-+ return;
-+ }
-+ _super.prototype.emit.call(this, enums_1.ConnectionEventType.Data, deserializedData);
-+ };
-+ DataConnection.prototype._handleChunk = function (data) {
-+ var id = data.__peerData;
-+ var chunkInfo = this._chunkedData[id] || {
-+ data: [],
-+ count: 0,
-+ total: data.total
-+ };
-+ chunkInfo.data[data.n] = data.data;
-+ chunkInfo.count++;
-+ this._chunkedData[id] = chunkInfo;
-+ if (chunkInfo.total === chunkInfo.count) {
-+ // Clean up before making the recursive call to `_handleDataMessage`.
-+ delete this._chunkedData[id];
-+ // We've received all the chunks--time to construct the complete data.
-+ var data_1 = new Blob(chunkInfo.data);
-+ this._handleDataMessage({ data: data_1 });
-+ }
-+ };
-+ /**
-+ * Exposed functionality for users.
-+ */
-+ /** Allows user to close connection. */
-+ DataConnection.prototype.close = function () {
-+ this._buffer = [];
-+ this._bufferSize = 0;
-+ this._chunkedData = {};
-+ if (this._negotiator) {
-+ this._negotiator.cleanup();
-+ // @ts-ignore
-+ this._negotiator = null;
-+ }
-+ if (this.provider) {
-+ this.provider._removeConnection(this);
-+ // @ts-ignore
-+ this.provider = null;
-+ }
-+ if (this.dataChannel) {
-+ this.dataChannel.onopen = null;
-+ this.dataChannel.onmessage = null;
-+ this.dataChannel.onclose = null;
-+ // @ts-ignore
-+ this._dc = null;
-+ }
-+ if (this._encodingQueue) {
-+ this._encodingQueue.destroy();
-+ this._encodingQueue.removeAllListeners();
-+ // @ts-ignore
-+ this._encodingQueue = null;
-+ }
-+ if (!this.open) {
-+ return;
-+ }
-+ this._open = false;
-+ _super.prototype.emit.call(this, enums_1.ConnectionEventType.Close);
-+ };
-+ /** Allows user to send data. */
-+ DataConnection.prototype.send = function (data, chunked) {
-+ if (!this.open) {
-+ _super.prototype.emit.call(this, enums_1.ConnectionEventType.Error, new Error("Connection is not open. You should listen for the `open` event before sending messages."));
-+ return;
-+ }
-+ if (this.serialization === enums_1.SerializationType.JSON) {
-+ this._bufferedSend(this.stringify(data));
-+ }
-+ else if (this.serialization === enums_1.SerializationType.Binary ||
-+ this.serialization === enums_1.SerializationType.BinaryUTF8) {
-+ var blob = util_1.util.pack(data);
-+ if (!chunked && blob.size > util_1.util.chunkedMTU) {
-+ this._sendChunks(blob);
-+ return;
-+ }
-+ if (!util_1.util.supports.binaryBlob) {
-+ // We only do this if we really need to (e.g. blobs are not supported),
-+ // because this conversion is costly.
-+ this._encodingQueue.enque(blob);
-+ }
-+ else {
-+ this._bufferedSend(blob);
-+ }
-+ }
-+ else {
-+ this._bufferedSend(data);
-+ }
-+ };
-+ DataConnection.prototype._bufferedSend = function (msg) {
-+ if (this._buffering || !this._trySend(msg)) {
-+ this._buffer.push(msg);
-+ this._bufferSize = this._buffer.length;
-+ }
-+ };
-+ // Returns true if the send succeeds.
-+ DataConnection.prototype._trySend = function (msg) {
-+ var _this = this;
-+ if (!this.open) {
-+ return false;
-+ }
-+ if (this.dataChannel.bufferedAmount > DataConnection.MAX_BUFFERED_AMOUNT) {
-+ this._buffering = true;
-+ setTimeout(function () {
-+ _this._buffering = false;
-+ _this._tryBuffer();
-+ }, 50);
-+ return false;
-+ }
-+ try {
-+ this.dataChannel.send(msg);
-+ }
-+ catch (e) {
-+ logger_1.default.error("DC#:" + this.connectionId + " Error when sending:", e);
-+ this._buffering = true;
-+ this.close();
-+ return false;
-+ }
-+ return true;
-+ };
-+ // Try to send the first message in the buffer.
-+ DataConnection.prototype._tryBuffer = function () {
-+ if (!this.open) {
-+ return;
-+ }
-+ if (this._buffer.length === 0) {
-+ return;
-+ }
-+ var msg = this._buffer[0];
-+ if (this._trySend(msg)) {
-+ this._buffer.shift();
-+ this._bufferSize = this._buffer.length;
-+ this._tryBuffer();
-+ }
-+ };
-+ DataConnection.prototype._sendChunks = function (blob) {
-+ var blobs = util_1.util.chunk(blob);
-+ logger_1.default.log("DC#" + this.connectionId + " Try to send " + blobs.length + " chunks...");
-+ for (var _i = 0, blobs_1 = blobs; _i < blobs_1.length; _i++) {
-+ var blob_1 = blobs_1[_i];
-+ this.send(blob_1, true);
-+ }
-+ };
-+ DataConnection.prototype.handleMessage = function (message) {
-+ var payload = message.payload;
-+ switch (message.type) {
-+ case enums_1.ServerMessageType.Answer:
-+ this._negotiator.handleSDP(message.type, payload.sdp);
-+ break;
-+ case enums_1.ServerMessageType.Candidate:
-+ this._negotiator.handleCandidate(payload.candidate);
-+ break;
-+ default:
-+ logger_1.default.warn("Unrecognized message type:", message.type, "from peer:", this.peer);
-+ break;
-+ }
-+ };
-+ DataConnection.ID_PREFIX = "dc_";
-+ DataConnection.MAX_BUFFERED_AMOUNT = 8 * 1024 * 1024;
-+ return DataConnection;
-+}(baseconnection_1.BaseConnection));
-+exports.DataConnection = DataConnection;
-diff --git a/node_modules/peerjs/dist/encodingQueue.js b/node_modules/peerjs/dist/encodingQueue.js
-new file mode 100644
-index 0000000..c9ca6b5
---- /dev/null
-+++ b/node_modules/peerjs/dist/encodingQueue.js
-@@ -0,0 +1,88 @@
-+"use strict";
-+var __extends = (this && this.__extends) || (function () {
-+ var extendStatics = function (d, b) {
-+ extendStatics = Object.setPrototypeOf ||
-+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
-+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
-+ return extendStatics(d, b);
-+ };
-+ return function (d, b) {
-+ if (typeof b !== "function" && b !== null)
-+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
-+ extendStatics(d, b);
-+ function __() { this.constructor = d; }
-+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
-+ };
-+})();
-+var __importDefault = (this && this.__importDefault) || function (mod) {
-+ return (mod && mod.__esModule) ? mod : { "default": mod };
-+};
-+Object.defineProperty(exports, "__esModule", { value: true });
-+exports.EncodingQueue = void 0;
-+var eventemitter3_1 = require("eventemitter3");
-+var logger_1 = __importDefault(require("./logger"));
-+var EncodingQueue = /** @class */ (function (_super) {
-+ __extends(EncodingQueue, _super);
-+ function EncodingQueue() {
-+ var _this = _super.call(this) || this;
-+ _this.fileReader = new FileReader();
-+ _this._queue = [];
-+ _this._processing = false;
-+ _this.fileReader.onload = function (evt) {
-+ _this._processing = false;
-+ if (evt.target) {
-+ _this.emit('done', evt.target.result);
-+ }
-+ _this.doNextTask();
-+ };
-+ _this.fileReader.onerror = function (evt) {
-+ logger_1.default.error("EncodingQueue error:", evt);
-+ _this._processing = false;
-+ _this.destroy();
-+ _this.emit('error', evt);
-+ };
-+ return _this;
-+ }
-+ Object.defineProperty(EncodingQueue.prototype, "queue", {
-+ get: function () {
-+ return this._queue;
-+ },
-+ enumerable: false,
-+ configurable: true
-+ });
-+ Object.defineProperty(EncodingQueue.prototype, "size", {
-+ get: function () {
-+ return this.queue.length;
-+ },
-+ enumerable: false,
-+ configurable: true
-+ });
-+ Object.defineProperty(EncodingQueue.prototype, "processing", {
-+ get: function () {
-+ return this._processing;
-+ },
-+ enumerable: false,
-+ configurable: true
-+ });
-+ EncodingQueue.prototype.enque = function (blob) {
-+ this.queue.push(blob);
-+ if (this.processing)
-+ return;
-+ this.doNextTask();
-+ };
-+ EncodingQueue.prototype.destroy = function () {
-+ this.fileReader.abort();
-+ this._queue = [];
-+ };
-+ EncodingQueue.prototype.doNextTask = function () {
-+ if (this.size === 0)
-+ return;
-+ if (this.processing)
-+ return;
-+ this._processing = true;
-+ // @ts-ignore
-+ this.fileReader.readAsArrayBuffer(this.queue.shift());
-+ };
-+ return EncodingQueue;
-+}(eventemitter3_1.EventEmitter));
-+exports.EncodingQueue = EncodingQueue;
-diff --git a/node_modules/peerjs/dist/enums.js b/node_modules/peerjs/dist/enums.js
-new file mode 100644
-index 0000000..9e551a4
---- /dev/null
-+++ b/node_modules/peerjs/dist/enums.js
-@@ -0,0 +1,67 @@
-+"use strict";
-+Object.defineProperty(exports, "__esModule", { value: true });
-+exports.ServerMessageType = exports.SocketEventType = exports.SerializationType = exports.PeerErrorType = exports.PeerEventType = exports.ConnectionType = exports.ConnectionEventType = void 0;
-+var ConnectionEventType;
-+(function (ConnectionEventType) {
-+ ConnectionEventType["Open"] = "open";
-+ ConnectionEventType["Stream"] = "stream";
-+ ConnectionEventType["Data"] = "data";
-+ ConnectionEventType["Close"] = "close";
-+ ConnectionEventType["Error"] = "error";
-+ ConnectionEventType["IceStateChanged"] = "iceStateChanged";
-+})(ConnectionEventType = exports.ConnectionEventType || (exports.ConnectionEventType = {}));
-+var ConnectionType;
-+(function (ConnectionType) {
-+ ConnectionType["Data"] = "data";
-+ ConnectionType["Media"] = "media";
-+})(ConnectionType = exports.ConnectionType || (exports.ConnectionType = {}));
-+var PeerEventType;
-+(function (PeerEventType) {
-+ PeerEventType["Open"] = "open";
-+ PeerEventType["Close"] = "close";
-+ PeerEventType["Connection"] = "connection";
-+ PeerEventType["Call"] = "call";
-+ PeerEventType["Disconnected"] = "disconnected";
-+ PeerEventType["Error"] = "error";
-+})(PeerEventType = exports.PeerEventType || (exports.PeerEventType = {}));
-+var PeerErrorType;
-+(function (PeerErrorType) {
-+ PeerErrorType["BrowserIncompatible"] = "browser-incompatible";
-+ PeerErrorType["Disconnected"] = "disconnected";
-+ PeerErrorType["InvalidID"] = "invalid-id";
-+ PeerErrorType["InvalidKey"] = "invalid-key";
-+ PeerErrorType["Network"] = "network";
-+ PeerErrorType["PeerUnavailable"] = "peer-unavailable";
-+ PeerErrorType["SslUnavailable"] = "ssl-unavailable";
-+ PeerErrorType["ServerError"] = "server-error";
-+ PeerErrorType["SocketError"] = "socket-error";
-+ PeerErrorType["SocketClosed"] = "socket-closed";
-+ PeerErrorType["UnavailableID"] = "unavailable-id";
-+ PeerErrorType["WebRTC"] = "webrtc";
-+})(PeerErrorType = exports.PeerErrorType || (exports.PeerErrorType = {}));
-+var SerializationType;
-+(function (SerializationType) {
-+ SerializationType["Binary"] = "binary";
-+ SerializationType["BinaryUTF8"] = "binary-utf8";
-+ SerializationType["JSON"] = "json";
-+})(SerializationType = exports.SerializationType || (exports.SerializationType = {}));
-+var SocketEventType;
-+(function (SocketEventType) {
-+ SocketEventType["Message"] = "message";
-+ SocketEventType["Disconnected"] = "disconnected";
-+ SocketEventType["Error"] = "error";
-+ SocketEventType["Close"] = "close";
-+})(SocketEventType = exports.SocketEventType || (exports.SocketEventType = {}));
-+var ServerMessageType;
-+(function (ServerMessageType) {
-+ ServerMessageType["Heartbeat"] = "HEARTBEAT";
-+ ServerMessageType["Candidate"] = "CANDIDATE";
-+ ServerMessageType["Offer"] = "OFFER";
-+ ServerMessageType["Answer"] = "ANSWER";
-+ ServerMessageType["Open"] = "OPEN";
-+ ServerMessageType["Error"] = "ERROR";
-+ ServerMessageType["IdTaken"] = "ID-TAKEN";
-+ ServerMessageType["InvalidKey"] = "INVALID-KEY";
-+ ServerMessageType["Leave"] = "LEAVE";
-+ ServerMessageType["Expire"] = "EXPIRE"; // The offer sent to a peer has expired without response.
-+})(ServerMessageType = exports.ServerMessageType || (exports.ServerMessageType = {}));
-diff --git a/node_modules/peerjs/dist/exports.js b/node_modules/peerjs/dist/exports.js
-new file mode 100644
-index 0000000..d6e2666
---- /dev/null
-+++ b/node_modules/peerjs/dist/exports.js
-@@ -0,0 +1,13 @@
-+"use strict";
-+Object.defineProperty(exports, "__esModule", { value: true });
-+exports.peerjs = void 0;
-+var util_1 = require("./util");
-+var peer_1 = require("./peer");
-+exports.peerjs = {
-+ Peer: peer_1.Peer,
-+ util: util_1.util
-+};
-+exports.default = peer_1.Peer;
-+window.peerjs = exports.peerjs;
-+/** @deprecated Should use peerjs namespace */
-+window.Peer = peer_1.Peer;
-diff --git a/node_modules/peerjs/dist/index.js b/node_modules/peerjs/dist/index.js
-new file mode 100644
-index 0000000..e7d6ac1
---- /dev/null
-+++ b/node_modules/peerjs/dist/index.js
-@@ -0,0 +1,27 @@
-+"use strict";
-+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
-+ if (k2 === undefined) k2 = k;
-+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
-+}) : (function(o, m, k, k2) {
-+ if (k2 === undefined) k2 = k;
-+ o[k2] = m[k];
-+}));
-+var __exportStar = (this && this.__exportStar) || function(m, exports) {
-+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
-+};
-+Object.defineProperty(exports, "__esModule", { value: true });
-+__exportStar(require("./adapter"), exports);
-+__exportStar(require("./api"), exports);
-+__exportStar(require("./baseconnection"), exports);
-+__exportStar(require("./dataconnection"), exports);
-+__exportStar(require("./encodingQueue"), exports);
-+__exportStar(require("./enums"), exports);
-+__exportStar(require("./exports"), exports);
-+__exportStar(require("./logger"), exports);
-+__exportStar(require("./mediaconnection"), exports);
-+__exportStar(require("./negotiator"), exports);
-+__exportStar(require("./peer"), exports);
-+__exportStar(require("./servermessage"), exports);
-+__exportStar(require("./socket"), exports);
-+__exportStar(require("./supports"), exports);
-+__exportStar(require("./util"), exports);
-diff --git a/node_modules/peerjs/dist/logger.js b/node_modules/peerjs/dist/logger.js
-new file mode 100644
-index 0000000..9a5e883
---- /dev/null
-+++ b/node_modules/peerjs/dist/logger.js
-@@ -0,0 +1,87 @@
-+"use strict";
-+var __spreadArray = (this && this.__spreadArray) || function (to, from) {
-+ for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
-+ to[j] = from[i];
-+ return to;
-+};
-+Object.defineProperty(exports, "__esModule", { value: true });
-+exports.LogLevel = void 0;
-+var LOG_PREFIX = 'PeerJS: ';
-+/*
-+Prints log messages depending on the debug level passed in. Defaults to 0.
-+0 Prints no logs.
-+1 Prints only errors.
-+2 Prints errors and warnings.
-+3 Prints all logs.
-+*/
-+var LogLevel;
-+(function (LogLevel) {
-+ LogLevel[LogLevel["Disabled"] = 0] = "Disabled";
-+ LogLevel[LogLevel["Errors"] = 1] = "Errors";
-+ LogLevel[LogLevel["Warnings"] = 2] = "Warnings";
-+ LogLevel[LogLevel["All"] = 3] = "All";
-+})(LogLevel = exports.LogLevel || (exports.LogLevel = {}));
-+var Logger = /** @class */ (function () {
-+ function Logger() {
-+ this._logLevel = LogLevel.Disabled;
-+ }
-+ Object.defineProperty(Logger.prototype, "logLevel", {
-+ get: function () { return this._logLevel; },
-+ set: function (logLevel) { this._logLevel = logLevel; },
-+ enumerable: false,
-+ configurable: true
-+ });
-+ Logger.prototype.log = function () {
-+ var args = [];
-+ for (var _i = 0; _i < arguments.length; _i++) {
-+ args[_i] = arguments[_i];
-+ }
-+ if (this._logLevel >= LogLevel.All) {
-+ this._print.apply(this, __spreadArray([LogLevel.All], args));
-+ }
-+ };
-+ Logger.prototype.warn = function () {
-+ var args = [];
-+ for (var _i = 0; _i < arguments.length; _i++) {
-+ args[_i] = arguments[_i];
-+ }
-+ if (this._logLevel >= LogLevel.Warnings) {
-+ this._print.apply(this, __spreadArray([LogLevel.Warnings], args));
-+ }
-+ };
-+ Logger.prototype.error = function () {
-+ var args = [];
-+ for (var _i = 0; _i < arguments.length; _i++) {
-+ args[_i] = arguments[_i];
-+ }
-+ if (this._logLevel >= LogLevel.Errors) {
-+ this._print.apply(this, __spreadArray([LogLevel.Errors], args));
-+ }
-+ };
-+ Logger.prototype.setLogFunction = function (fn) {
-+ this._print = fn;
-+ };
-+ Logger.prototype._print = function (logLevel) {
-+ var rest = [];
-+ for (var _i = 1; _i < arguments.length; _i++) {
-+ rest[_i - 1] = arguments[_i];
-+ }
-+ var copy = __spreadArray([LOG_PREFIX], rest);
-+ for (var i in copy) {
-+ if (copy[i] instanceof Error) {
-+ copy[i] = "(" + copy[i].name + ") " + copy[i].message;
-+ }
-+ }
-+ if (logLevel >= LogLevel.All) {
-+ console.log.apply(console, copy);
-+ }
-+ else if (logLevel >= LogLevel.Warnings) {
-+ console.warn.apply(console, __spreadArray(["WARNING"], copy));
-+ }
-+ else if (logLevel >= LogLevel.Errors) {
-+ console.error.apply(console, __spreadArray(["ERROR"], copy));
-+ }
-+ };
-+ return Logger;
-+}());
-+exports.default = new Logger();
-diff --git a/node_modules/peerjs/dist/mediaconnection.js b/node_modules/peerjs/dist/mediaconnection.js
-new file mode 100644
-index 0000000..2318160
---- /dev/null
-+++ b/node_modules/peerjs/dist/mediaconnection.js
-@@ -0,0 +1,148 @@
-+"use strict";
-+var __extends = (this && this.__extends) || (function () {
-+ var extendStatics = function (d, b) {
-+ extendStatics = Object.setPrototypeOf ||
-+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
-+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
-+ return extendStatics(d, b);
-+ };
-+ return function (d, b) {
-+ if (typeof b !== "function" && b !== null)
-+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
-+ extendStatics(d, b);
-+ function __() { this.constructor = d; }
-+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
-+ };
-+})();
-+var __assign = (this && this.__assign) || function () {
-+ __assign = Object.assign || function(t) {
-+ for (var s, i = 1, n = arguments.length; i < n; i++) {
-+ s = arguments[i];
-+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
-+ t[p] = s[p];
-+ }
-+ return t;
-+ };
-+ return __assign.apply(this, arguments);
-+};
-+var __importDefault = (this && this.__importDefault) || function (mod) {
-+ return (mod && mod.__esModule) ? mod : { "default": mod };
-+};
-+Object.defineProperty(exports, "__esModule", { value: true });
-+exports.MediaConnection = void 0;
-+var util_1 = require("./util");
-+var logger_1 = __importDefault(require("./logger"));
-+var negotiator_1 = require("./negotiator");
-+var enums_1 = require("./enums");
-+var baseconnection_1 = require("./baseconnection");
-+/**
-+ * Wraps the streaming interface between two Peers.
-+ */
-+var MediaConnection = /** @class */ (function (_super) {
-+ __extends(MediaConnection, _super);
-+ function MediaConnection(peerId, provider, options) {
-+ var _this = _super.call(this, peerId, provider, options) || this;
-+ _this._localStream = _this.options._stream;
-+ _this.connectionId =
-+ _this.options.connectionId ||
-+ MediaConnection.ID_PREFIX + util_1.util.randomToken();
-+ _this._negotiator = new negotiator_1.Negotiator(_this);
-+ if (_this._localStream) {
-+ _this._negotiator.startConnection({
-+ _stream: _this._localStream,
-+ originator: true
-+ });
-+ }
-+ return _this;
-+ }
-+ Object.defineProperty(MediaConnection.prototype, "type", {
-+ get: function () {
-+ return enums_1.ConnectionType.Media;
-+ },
-+ enumerable: false,
-+ configurable: true
-+ });
-+ Object.defineProperty(MediaConnection.prototype, "localStream", {
-+ get: function () { return this._localStream; },
-+ enumerable: false,
-+ configurable: true
-+ });
-+ Object.defineProperty(MediaConnection.prototype, "remoteStream", {
-+ get: function () { return this._remoteStream; },
-+ enumerable: false,
-+ configurable: true
-+ });
-+ // @ts-ignore
-+ MediaConnection.prototype.addStream = function (remoteStream) {
-+ logger_1.default.log("Receiving stream", remoteStream);
-+ this._remoteStream = remoteStream;
-+ _super.prototype.emit.call(this, enums_1.ConnectionEventType.Stream, remoteStream); // Should we call this `open`?
-+ };
-+ MediaConnection.prototype.handleMessage = function (message) {
-+ var type = message.type;
-+ var payload = message.payload;
-+ switch (message.type) {
-+ case enums_1.ServerMessageType.Answer:
-+ // Forward to negotiator
-+ this._negotiator.handleSDP(type, payload.sdp);
-+ this._open = true;
-+ break;
-+ case enums_1.ServerMessageType.Candidate:
-+ this._negotiator.handleCandidate(payload.candidate);
-+ break;
-+ default:
-+ logger_1.default.warn("Unrecognized message type:" + type + " from peer:" + this.peer);
-+ break;
-+ }
-+ };
-+ MediaConnection.prototype.answer = function (stream, options) {
-+ if (options === void 0) { options = {}; }
-+ if (this._localStream) {
-+ logger_1.default.warn("Local stream already exists on this MediaConnection. Are you answering a call twice?");
-+ return;
-+ }
-+ this._localStream = stream;
-+ if (options && options.sdpTransform) {
-+ this.options.sdpTransform = options.sdpTransform;
-+ }
-+ this._negotiator.startConnection(__assign(__assign({}, this.options._payload), { _stream: stream }));
-+ // Retrieve lost messages stored because PeerConnection not set up.
-+ var messages = this.provider._getMessages(this.connectionId);
-+ for (var _i = 0, messages_1 = messages; _i < messages_1.length; _i++) {
-+ var message = messages_1[_i];
-+ this.handleMessage(message);
-+ }
-+ this._open = true;
-+ };
-+ /**
-+ * Exposed functionality for users.
-+ */
-+ /** Allows user to close connection. */
-+ MediaConnection.prototype.close = function () {
-+ if (this._negotiator) {
-+ this._negotiator.cleanup();
-+ // @ts-ignore
-+ this._negotiator = null;
-+ }
-+ // @ts-ignore
-+ this._localStream = null;
-+ // @ts-ignore
-+ this._remoteStream = null;
-+ if (this.provider) {
-+ this.provider._removeConnection(this);
-+ // @ts-ignore
-+ this.provider = null;
-+ }
-+ if (this.options && this.options._stream) {
-+ this.options._stream = null;
-+ }
-+ if (!this.open) {
-+ return;
-+ }
-+ this._open = false;
-+ _super.prototype.emit.call(this, enums_1.ConnectionEventType.Close);
-+ };
-+ MediaConnection.ID_PREFIX = "mc_";
-+ return MediaConnection;
-+}(baseconnection_1.BaseConnection));
-+exports.MediaConnection = MediaConnection;
-diff --git a/node_modules/peerjs/dist/negotiator.js b/node_modules/peerjs/dist/negotiator.js
-new file mode 100644
-index 0000000..afd9687
---- /dev/null
-+++ b/node_modules/peerjs/dist/negotiator.js
-@@ -0,0 +1,385 @@
-+"use strict";
-+var __assign = (this && this.__assign) || function () {
-+ __assign = Object.assign || function(t) {
-+ for (var s, i = 1, n = arguments.length; i < n; i++) {
-+ s = arguments[i];
-+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
-+ t[p] = s[p];
-+ }
-+ return t;
-+ };
-+ return __assign.apply(this, arguments);
-+};
-+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
-+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
-+ return new (P || (P = Promise))(function (resolve, reject) {
-+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
-+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
-+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
-+ step((generator = generator.apply(thisArg, _arguments || [])).next());
-+ });
-+};
-+var __generator = (this && this.__generator) || function (thisArg, body) {
-+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
-+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
-+ function verb(n) { return function (v) { return step([n, v]); }; }
-+ function step(op) {
-+ if (f) throw new TypeError("Generator is already executing.");
-+ while (_) try {
-+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
-+ if (y = 0, t) op = [op[0] & 2, t.value];
-+ switch (op[0]) {
-+ case 0: case 1: t = op; break;
-+ case 4: _.label++; return { value: op[1], done: false };
-+ case 5: _.label++; y = op[1]; op = [0]; continue;
-+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
-+ default:
-+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
-+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
-+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
-+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
-+ if (t[2]) _.ops.pop();
-+ _.trys.pop(); continue;
-+ }
-+ op = body.call(thisArg, _);
-+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
-+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
-+ }
-+};
-+var __importDefault = (this && this.__importDefault) || function (mod) {
-+ return (mod && mod.__esModule) ? mod : { "default": mod };
-+};
-+Object.defineProperty(exports, "__esModule", { value: true });
-+exports.Negotiator = void 0;
-+var util_1 = require("./util");
-+var logger_1 = __importDefault(require("./logger"));
-+var enums_1 = require("./enums");
-+/**
-+ * Manages all negotiations between Peers.
-+ */
-+var Negotiator = /** @class */ (function () {
-+ function Negotiator(connection) {
-+ this.connection = connection;
-+ }
-+ /** Returns a PeerConnection object set up correctly (for data, media). */
-+ Negotiator.prototype.startConnection = function (options) {
-+ var peerConnection = this._startPeerConnection();
-+ // Set the connection's PC.
-+ this.connection.peerConnection = peerConnection;
-+ if (this.connection.type === enums_1.ConnectionType.Media && options._stream) {
-+ this._addTracksToConnection(options._stream, peerConnection);
-+ }
-+ // What do we need to do now?
-+ if (options.originator) {
-+ if (this.connection.type === enums_1.ConnectionType.Data) {
-+ var dataConnection = this.connection;
-+ var config = { ordered: !!options.reliable };
-+ var dataChannel = peerConnection.createDataChannel(dataConnection.label, config);
-+ dataConnection.initialize(dataChannel);
-+ }
-+ this._makeOffer();
-+ }
-+ else {
-+ this.handleSDP("OFFER", options.sdp);
-+ }
-+ };
-+ /** Start a PC. */
-+ Negotiator.prototype._startPeerConnection = function () {
-+ logger_1.default.log("Creating RTCPeerConnection.");
-+ var peerConnection = new RTCPeerConnection(this.connection.provider.options.config);
-+ this._setupListeners(peerConnection);
-+ return peerConnection;
-+ };
-+ /** Set up various WebRTC listeners. */
-+ Negotiator.prototype._setupListeners = function (peerConnection) {
-+ var _this = this;
-+ var peerId = this.connection.peer;
-+ var connectionId = this.connection.connectionId;
-+ var connectionType = this.connection.type;
-+ var provider = this.connection.provider;
-+ // ICE CANDIDATES.
-+ logger_1.default.log("Listening for ICE candidates.");
-+ peerConnection.onicecandidate = function (evt) {
-+ if (!evt.candidate || !evt.candidate.candidate)
-+ return;
-+ logger_1.default.log("Received ICE candidates for " + peerId + ":", evt.candidate);
-+ provider.socket.send({
-+ type: enums_1.ServerMessageType.Candidate,
-+ payload: {
-+ candidate: evt.candidate,
-+ type: connectionType,
-+ connectionId: connectionId
-+ },
-+ dst: peerId
-+ });
-+ };
-+ peerConnection.oniceconnectionstatechange = function () {
-+ switch (peerConnection.iceConnectionState) {
-+ case "failed":
-+ logger_1.default.log("iceConnectionState is failed, closing connections to " +
-+ peerId);
-+ _this.connection.emit(enums_1.ConnectionEventType.Error, new Error("Negotiation of connection to " + peerId + " failed."));
-+ _this.connection.close();
-+ break;
-+ case "closed":
-+ logger_1.default.log("iceConnectionState is closed, closing connections to " +
-+ peerId);
-+ _this.connection.emit(enums_1.ConnectionEventType.Error, new Error("Connection to " + peerId + " closed."));
-+ _this.connection.close();
-+ break;
-+ case "disconnected":
-+ logger_1.default.log("iceConnectionState changed to disconnected on the connection with " +
-+ peerId);
-+ break;
-+ case "completed":
-+ peerConnection.onicecandidate = util_1.util.noop;
-+ break;
-+ }
-+ _this.connection.emit(enums_1.ConnectionEventType.IceStateChanged, peerConnection.iceConnectionState);
-+ };
-+ // DATACONNECTION.
-+ logger_1.default.log("Listening for data channel");
-+ // Fired between offer and answer, so options should already be saved
-+ // in the options hash.
-+ peerConnection.ondatachannel = function (evt) {
-+ logger_1.default.log("Received data channel");
-+ var dataChannel = evt.channel;
-+ var connection = (provider.getConnection(peerId, connectionId));
-+ connection.initialize(dataChannel);
-+ };
-+ // MEDIACONNECTION.
-+ logger_1.default.log("Listening for remote stream");
-+ peerConnection.ontrack = function (evt) {
-+ logger_1.default.log("Received remote stream");
-+ var stream = evt.streams[0];
-+ var connection = provider.getConnection(peerId, connectionId);
-+ // @ts-ignore
-+ if (connection.type === enums_1.ConnectionType.Media) {
-+ var mediaConnection = connection;
-+ _this._addStreamToMediaConnection(stream, mediaConnection);
-+ }
-+ };
-+ };
-+ Negotiator.prototype.cleanup = function () {
-+ logger_1.default.log("Cleaning up PeerConnection to " + this.connection.peer);
-+ var peerConnection = this.connection.peerConnection;
-+ if (!peerConnection) {
-+ return;
-+ }
-+ // @ts-ignore
-+ this.connection.peerConnection = null;
-+ //unsubscribe from all PeerConnection's events
-+ peerConnection.onicecandidate = peerConnection.oniceconnectionstatechange = peerConnection.ondatachannel = peerConnection.ontrack = function () { };
-+ var peerConnectionNotClosed = peerConnection.signalingState !== "closed";
-+ var dataChannelNotClosed = false;
-+ if (this.connection.type === enums_1.ConnectionType.Data) {
-+ var dataConnection = this.connection;
-+ var dataChannel = dataConnection.dataChannel;
-+ if (dataChannel) {
-+ dataChannelNotClosed = !!dataChannel.readyState && dataChannel.readyState !== "closed";
-+ }
-+ }
-+ if (peerConnectionNotClosed || dataChannelNotClosed) {
-+ peerConnection.close();
-+ }
-+ };
-+ Negotiator.prototype._makeOffer = function () {
-+ return __awaiter(this, void 0, void 0, function () {
-+ var peerConnection, provider, offer, payload, dataConnection, err_2, err_1_1;
-+ return __generator(this, function (_a) {
-+ switch (_a.label) {
-+ case 0:
-+ peerConnection = this.connection.peerConnection;
-+ provider = this.connection.provider;
-+ _a.label = 1;
-+ case 1:
-+ _a.trys.push([1, 7, , 8]);
-+ return [4 /*yield*/, peerConnection.createOffer(this.connection.options.constraints)];
-+ case 2:
-+ offer = _a.sent();
-+ logger_1.default.log("Created offer.");
-+ if (this.connection.options.sdpTransform && typeof this.connection.options.sdpTransform === 'function') {
-+ offer.sdp = this.connection.options.sdpTransform(offer.sdp) || offer.sdp;
-+ }
-+ _a.label = 3;
-+ case 3:
-+ _a.trys.push([3, 5, , 6]);
-+ return [4 /*yield*/, peerConnection.setLocalDescription(offer)];
-+ case 4:
-+ _a.sent();
-+ logger_1.default.log("Set localDescription:", offer, "for:" + this.connection.peer);
-+ payload = {
-+ sdp: offer,
-+ type: this.connection.type,
-+ connectionId: this.connection.connectionId,
-+ metadata: this.connection.metadata,
-+ browser: util_1.util.browser
-+ };
-+ if (this.connection.type === enums_1.ConnectionType.Data) {
-+ dataConnection = this.connection;
-+ payload = __assign(__assign({}, payload), { label: dataConnection.label, reliable: dataConnection.reliable, serialization: dataConnection.serialization });
-+ }
-+ provider.socket.send({
-+ type: enums_1.ServerMessageType.Offer,
-+ payload: payload,
-+ dst: this.connection.peer
-+ });
-+ return [3 /*break*/, 6];
-+ case 5:
-+ err_2 = _a.sent();
-+ // TODO: investigate why _makeOffer is being called from the answer
-+ if (err_2 !=
-+ "OperationError: Failed to set local offer sdp: Called in wrong state: kHaveRemoteOffer") {
-+ provider.emitError(enums_1.PeerErrorType.WebRTC, err_2);
-+ logger_1.default.log("Failed to setLocalDescription, ", err_2);
-+ }
-+ return [3 /*break*/, 6];
-+ case 6: return [3 /*break*/, 8];
-+ case 7:
-+ err_1_1 = _a.sent();
-+ provider.emitError(enums_1.PeerErrorType.WebRTC, err_1_1);
-+ logger_1.default.log("Failed to createOffer, ", err_1_1);
-+ return [3 /*break*/, 8];
-+ case 8: return [2 /*return*/];
-+ }
-+ });
-+ });
-+ };
-+ Negotiator.prototype._makeAnswer = function () {
-+ return __awaiter(this, void 0, void 0, function () {
-+ var peerConnection, provider, answer, err_3, err_1_2;
-+ return __generator(this, function (_a) {
-+ switch (_a.label) {
-+ case 0:
-+ peerConnection = this.connection.peerConnection;
-+ provider = this.connection.provider;
-+ _a.label = 1;
-+ case 1:
-+ _a.trys.push([1, 7, , 8]);
-+ return [4 /*yield*/, peerConnection.createAnswer()];
-+ case 2:
-+ answer = _a.sent();
-+ logger_1.default.log("Created answer.");
-+ if (this.connection.options.sdpTransform && typeof this.connection.options.sdpTransform === 'function') {
-+ answer.sdp = this.connection.options.sdpTransform(answer.sdp) || answer.sdp;
-+ }
-+ _a.label = 3;
-+ case 3:
-+ _a.trys.push([3, 5, , 6]);
-+ return [4 /*yield*/, peerConnection.setLocalDescription(answer)];
-+ case 4:
-+ _a.sent();
-+ logger_1.default.log("Set localDescription:", answer, "for:" + this.connection.peer);
-+ provider.socket.send({
-+ type: enums_1.ServerMessageType.Answer,
-+ payload: {
-+ sdp: answer,
-+ type: this.connection.type,
-+ connectionId: this.connection.connectionId,
-+ browser: util_1.util.browser
-+ },
-+ dst: this.connection.peer
-+ });
-+ return [3 /*break*/, 6];
-+ case 5:
-+ err_3 = _a.sent();
-+ provider.emitError(enums_1.PeerErrorType.WebRTC, err_3);
-+ logger_1.default.log("Failed to setLocalDescription, ", err_3);
-+ return [3 /*break*/, 6];
-+ case 6: return [3 /*break*/, 8];
-+ case 7:
-+ err_1_2 = _a.sent();
-+ provider.emitError(enums_1.PeerErrorType.WebRTC, err_1_2);
-+ logger_1.default.log("Failed to create answer, ", err_1_2);
-+ return [3 /*break*/, 8];
-+ case 8: return [2 /*return*/];
-+ }
-+ });
-+ });
-+ };
-+ /** Handle an SDP. */
-+ Negotiator.prototype.handleSDP = function (type, sdp) {
-+ return __awaiter(this, void 0, void 0, function () {
-+ var peerConnection, provider, self, err_4;
-+ return __generator(this, function (_a) {
-+ switch (_a.label) {
-+ case 0:
-+ sdp = new RTCSessionDescription(sdp);
-+ peerConnection = this.connection.peerConnection;
-+ provider = this.connection.provider;
-+ logger_1.default.log("Setting remote description", sdp);
-+ self = this;
-+ _a.label = 1;
-+ case 1:
-+ _a.trys.push([1, 5, , 6]);
-+ return [4 /*yield*/, peerConnection.setRemoteDescription(sdp)];
-+ case 2:
-+ _a.sent();
-+ logger_1.default.log("Set remoteDescription:" + type + " for:" + this.connection.peer);
-+ if (!(type === "OFFER")) return [3 /*break*/, 4];
-+ return [4 /*yield*/, self._makeAnswer()];
-+ case 3:
-+ _a.sent();
-+ _a.label = 4;
-+ case 4: return [3 /*break*/, 6];
-+ case 5:
-+ err_4 = _a.sent();
-+ provider.emitError(enums_1.PeerErrorType.WebRTC, err_4);
-+ logger_1.default.log("Failed to setRemoteDescription, ", err_4);
-+ return [3 /*break*/, 6];
-+ case 6: return [2 /*return*/];
-+ }
-+ });
-+ });
-+ };
-+ /** Handle a candidate. */
-+ Negotiator.prototype.handleCandidate = function (ice) {
-+ return __awaiter(this, void 0, void 0, function () {
-+ var candidate, sdpMLineIndex, sdpMid, peerConnection, provider, err_5;
-+ return __generator(this, function (_a) {
-+ switch (_a.label) {
-+ case 0:
-+ logger_1.default.log("handleCandidate:", ice);
-+ candidate = ice.candidate;
-+ sdpMLineIndex = ice.sdpMLineIndex;
-+ sdpMid = ice.sdpMid;
-+ peerConnection = this.connection.peerConnection;
-+ provider = this.connection.provider;
-+ _a.label = 1;
-+ case 1:
-+ _a.trys.push([1, 3, , 4]);
-+ return [4 /*yield*/, peerConnection.addIceCandidate(new RTCIceCandidate({
-+ sdpMid: sdpMid,
-+ sdpMLineIndex: sdpMLineIndex,
-+ candidate: candidate
-+ }))];
-+ case 2:
-+ _a.sent();
-+ logger_1.default.log("Added ICE candidate for:" + this.connection.peer);
-+ return [3 /*break*/, 4];
-+ case 3:
-+ err_5 = _a.sent();
-+ provider.emitError(enums_1.PeerErrorType.WebRTC, err_5);
-+ logger_1.default.log("Failed to handleCandidate, ", err_5);
-+ return [3 /*break*/, 4];
-+ case 4: return [2 /*return*/];
-+ }
-+ });
-+ });
-+ };
-+ Negotiator.prototype._addTracksToConnection = function (stream, peerConnection) {
-+ logger_1.default.log("add tracks from stream " + stream.id + " to peer connection");
-+ if (!peerConnection.addTrack) {
-+ return logger_1.default.error("Your browser does't support RTCPeerConnection#addTrack. Ignored.");
-+ }
-+ stream.getTracks().forEach(function (track) {
-+ peerConnection.addTrack(track, stream);
-+ });
-+ };
-+ Negotiator.prototype._addStreamToMediaConnection = function (stream, mediaConnection) {
-+ logger_1.default.log("add stream " + stream.id + " to media connection " + mediaConnection.connectionId);
-+ mediaConnection.addStream(stream);
-+ };
-+ return Negotiator;
-+}());
-+exports.Negotiator = Negotiator;
-diff --git a/node_modules/peerjs/dist/peer.js b/node_modules/peerjs/dist/peer.js
-new file mode 100644
-index 0000000..8928729
---- /dev/null
-+++ b/node_modules/peerjs/dist/peer.js
-@@ -0,0 +1,519 @@
-+"use strict";
-+var __extends = (this && this.__extends) || (function () {
-+ var extendStatics = function (d, b) {
-+ extendStatics = Object.setPrototypeOf ||
-+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
-+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
-+ return extendStatics(d, b);
-+ };
-+ return function (d, b) {
-+ if (typeof b !== "function" && b !== null)
-+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
-+ extendStatics(d, b);
-+ function __() { this.constructor = d; }
-+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
-+ };
-+})();
-+var __assign = (this && this.__assign) || function () {
-+ __assign = Object.assign || function(t) {
-+ for (var s, i = 1, n = arguments.length; i < n; i++) {
-+ s = arguments[i];
-+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
-+ t[p] = s[p];
-+ }
-+ return t;
-+ };
-+ return __assign.apply(this, arguments);
-+};
-+var __importDefault = (this && this.__importDefault) || function (mod) {
-+ return (mod && mod.__esModule) ? mod : { "default": mod };
-+};
-+Object.defineProperty(exports, "__esModule", { value: true });
-+exports.Peer = void 0;
-+var eventemitter3_1 = require("eventemitter3");
-+var util_1 = require("./util");
-+var logger_1 = __importDefault(require("./logger"));
-+var socket_1 = require("./socket");
-+var mediaconnection_1 = require("./mediaconnection");
-+var dataconnection_1 = require("./dataconnection");
-+var enums_1 = require("./enums");
-+var api_1 = require("./api");
-+var PeerOptions = /** @class */ (function () {
-+ function PeerOptions() {
-+ }
-+ return PeerOptions;
-+}());
-+/**
-+ * A peer who can initiate connections with other peers.
-+ */
-+var Peer = /** @class */ (function (_super) {
-+ __extends(Peer, _super);
-+ function Peer(id, options) {
-+ var _this = _super.call(this) || this;
-+ _this._id = null;
-+ _this._lastServerId = null;
-+ // States.
-+ _this._destroyed = false; // Connections have been killed
-+ _this._disconnected = false; // Connection to PeerServer killed but P2P connections still active
-+ _this._open = false; // Sockets and such are not yet open.
-+ _this._connections = new Map(); // All connections for this peer.
-+ _this._lostMessages = new Map(); // src => [list of messages]
-+ var userId;
-+ // Deal with overloading
-+ if (id && id.constructor == Object) {
-+ options = id;
-+ }
-+ else if (id) {
-+ userId = id.toString();
-+ }
-+ // Configurize options
-+ options = __assign({ debug: 0, host: util_1.util.CLOUD_HOST, port: util_1.util.CLOUD_PORT, path: "/", key: Peer.DEFAULT_KEY, token: util_1.util.randomToken(), config: util_1.util.defaultConfig }, options);
-+ _this._options = options;
-+ // Detect relative URL host.
-+ if (_this._options.host === "/") {
-+ _this._options.host = window.location.hostname;
-+ }
-+ // Set path correctly.
-+ if (_this._options.path) {
-+ if (_this._options.path[0] !== "/") {
-+ _this._options.path = "/" + _this._options.path;
-+ }
-+ if (_this._options.path[_this._options.path.length - 1] !== "/") {
-+ _this._options.path += "/";
-+ }
-+ }
-+ // Set whether we use SSL to same as current host
-+ if (_this._options.secure === undefined && _this._options.host !== util_1.util.CLOUD_HOST) {
-+ _this._options.secure = util_1.util.isSecure();
-+ }
-+ else if (_this._options.host == util_1.util.CLOUD_HOST) {
-+ _this._options.secure = true;
-+ }
-+ // Set a custom log function if present
-+ if (_this._options.logFunction) {
-+ logger_1.default.setLogFunction(_this._options.logFunction);
-+ }
-+ logger_1.default.logLevel = _this._options.debug || 0;
-+ _this._api = new api_1.API(options);
-+ _this._socket = _this._createServerConnection();
-+ // Sanity checks
-+ // Ensure WebRTC supported
-+ if (!util_1.util.supports.audioVideo && !util_1.util.supports.data) {
-+ _this._delayedAbort(enums_1.PeerErrorType.BrowserIncompatible, "The current browser does not support WebRTC");
-+ return _this;
-+ }
-+ // Ensure alphanumeric id
-+ if (!!userId && !util_1.util.validateId(userId)) {
-+ _this._delayedAbort(enums_1.PeerErrorType.InvalidID, "ID \"" + userId + "\" is invalid");
-+ return _this;
-+ }
-+ if (userId) {
-+ _this._initialize(userId);
-+ }
-+ else {
-+ _this._api.retrieveId()
-+ .then(function (id) { return _this._initialize(id); })
-+ .catch(function (error) { return _this._abort(enums_1.PeerErrorType.ServerError, error); });
-+ }
-+ return _this;
-+ }
-+ Object.defineProperty(Peer.prototype, "id", {
-+ get: function () {
-+ return this._id;
-+ },
-+ enumerable: false,
-+ configurable: true
-+ });
-+ Object.defineProperty(Peer.prototype, "options", {
-+ get: function () {
-+ return this._options;
-+ },
-+ enumerable: false,
-+ configurable: true
-+ });
-+ Object.defineProperty(Peer.prototype, "open", {
-+ get: function () {
-+ return this._open;
-+ },
-+ enumerable: false,
-+ configurable: true
-+ });
-+ Object.defineProperty(Peer.prototype, "socket", {
-+ get: function () {
-+ return this._socket;
-+ },
-+ enumerable: false,
-+ configurable: true
-+ });
-+ Object.defineProperty(Peer.prototype, "connections", {
-+ /**
-+ * @deprecated
-+ * Return type will change from Object to Map
-+ */
-+ get: function () {
-+ var plainConnections = Object.create(null);
-+ // @ts-ignore
-+ for (var _i = 0, _a = this._connections; _i < _a.length; _i++) {
-+ var _b = _a[_i], k = _b[0], v = _b[1];
-+ plainConnections[k] = v;
-+ }
-+ return plainConnections;
-+ },
-+ enumerable: false,
-+ configurable: true
-+ });
-+ Object.defineProperty(Peer.prototype, "destroyed", {
-+ get: function () {
-+ return this._destroyed;
-+ },
-+ enumerable: false,
-+ configurable: true
-+ });
-+ Object.defineProperty(Peer.prototype, "disconnected", {
-+ get: function () {
-+ return this._disconnected;
-+ },
-+ enumerable: false,
-+ configurable: true
-+ });
-+ Peer.prototype._createServerConnection = function () {
-+ var _this = this;
-+ var socket = new socket_1.Socket(this._options.secure, this._options.host, this._options.port, this._options.path, this._options.key, this._options.pingInterval);
-+ socket.on(enums_1.SocketEventType.Message, function (data) {
-+ _this._handleMessage(data);
-+ });
-+ socket.on(enums_1.SocketEventType.Error, function (error) {
-+ _this._abort(enums_1.PeerErrorType.SocketError, error);
-+ });
-+ socket.on(enums_1.SocketEventType.Disconnected, function () {
-+ if (_this.disconnected) {
-+ return;
-+ }
-+ _this.emitError(enums_1.PeerErrorType.Network, "Lost connection to server.");
-+ _this.disconnect();
-+ });
-+ socket.on(enums_1.SocketEventType.Close, function () {
-+ if (_this.disconnected) {
-+ return;
-+ }
-+ _this._abort(enums_1.PeerErrorType.SocketClosed, "Underlying socket is already closed.");
-+ });
-+ return socket;
-+ };
-+ /** Initialize a connection with the server. */
-+ Peer.prototype._initialize = function (id) {
-+ this._id = id;
-+ this.socket.start(id, this._options.token);
-+ };
-+ /** Handles messages from the server. */
-+ Peer.prototype._handleMessage = function (message) {
-+ var type = message.type;
-+ var payload = message.payload;
-+ var peerId = message.src;
-+ switch (type) {
-+ case enums_1.ServerMessageType.Open: // The connection to the server is open.
-+ this._lastServerId = this.id;
-+ this._open = true;
-+ this.emit(enums_1.PeerEventType.Open, this.id);
-+ break;
-+ case enums_1.ServerMessageType.Error: // Server error.
-+ this._abort(enums_1.PeerErrorType.ServerError, payload.msg);
-+ break;
-+ case enums_1.ServerMessageType.IdTaken: // The selected ID is taken.
-+ this._abort(enums_1.PeerErrorType.UnavailableID, "ID \"" + this.id + "\" is taken");
-+ break;
-+ case enums_1.ServerMessageType.InvalidKey: // The given API key cannot be found.
-+ this._abort(enums_1.PeerErrorType.InvalidKey, "API KEY \"" + this._options.key + "\" is invalid");
-+ break;
-+ case enums_1.ServerMessageType.Leave: // Another peer has closed its connection to this peer.
-+ logger_1.default.log("Received leave message from " + peerId);
-+ this._cleanupPeer(peerId);
-+ this._connections.delete(peerId);
-+ break;
-+ case enums_1.ServerMessageType.Expire: // The offer sent to a peer has expired without response.
-+ this.emitError(enums_1.PeerErrorType.PeerUnavailable, "Could not connect to peer " + peerId);
-+ break;
-+ case enums_1.ServerMessageType.Offer: {
-+ // we should consider switching this to CALL/CONNECT, but this is the least breaking option.
-+ var connectionId = payload.connectionId;
-+ var connection = this.getConnection(peerId, connectionId);
-+ if (connection) {
-+ connection.close();
-+ logger_1.default.warn("Offer received for existing Connection ID:" + connectionId);
-+ }
-+ // Create a new connection.
-+ if (payload.type === enums_1.ConnectionType.Media) {
-+ connection = new mediaconnection_1.MediaConnection(peerId, this, {
-+ connectionId: connectionId,
-+ _payload: payload,
-+ metadata: payload.metadata
-+ });
-+ this._addConnection(peerId, connection);
-+ this.emit(enums_1.PeerEventType.Call, connection);
-+ }
-+ else if (payload.type === enums_1.ConnectionType.Data) {
-+ connection = new dataconnection_1.DataConnection(peerId, this, {
-+ connectionId: connectionId,
-+ _payload: payload,
-+ metadata: payload.metadata,
-+ label: payload.label,
-+ serialization: payload.serialization,
-+ reliable: payload.reliable
-+ });
-+ this._addConnection(peerId, connection);
-+ this.emit(enums_1.PeerEventType.Connection, connection);
-+ }
-+ else {
-+ logger_1.default.warn("Received malformed connection type:" + payload.type);
-+ return;
-+ }
-+ // Find messages.
-+ var messages = this._getMessages(connectionId);
-+ for (var _i = 0, messages_1 = messages; _i < messages_1.length; _i++) {
-+ var message_1 = messages_1[_i];
-+ connection.handleMessage(message_1);
-+ }
-+ break;
-+ }
-+ default: {
-+ if (!payload) {
-+ logger_1.default.warn("You received a malformed message from " + peerId + " of type " + type);
-+ return;
-+ }
-+ var connectionId = payload.connectionId;
-+ var connection = this.getConnection(peerId, connectionId);
-+ if (connection && connection.peerConnection) {
-+ // Pass it on.
-+ connection.handleMessage(message);
-+ }
-+ else if (connectionId) {
-+ // Store for possible later use
-+ this._storeMessage(connectionId, message);
-+ }
-+ else {
-+ logger_1.default.warn("You received an unrecognized message:", message);
-+ }
-+ break;
-+ }
-+ }
-+ };
-+ /** Stores messages without a set up connection, to be claimed later. */
-+ Peer.prototype._storeMessage = function (connectionId, message) {
-+ if (!this._lostMessages.has(connectionId)) {
-+ this._lostMessages.set(connectionId, []);
-+ }
-+ // @ts-ignore
-+ this._lostMessages.get(connectionId).push(message);
-+ };
-+ /** Retrieve messages from lost message store */
-+ //TODO Change it to private
-+ Peer.prototype._getMessages = function (connectionId) {
-+ var messages = this._lostMessages.get(connectionId);
-+ if (messages) {
-+ this._lostMessages.delete(connectionId);
-+ return messages;
-+ }
-+ return [];
-+ };
-+ /**
-+ * Returns a DataConnection to the specified peer. See documentation for a
-+ * complete list of options.
-+ */
-+ Peer.prototype.connect = function (peer, options) {
-+ if (options === void 0) { options = {}; }
-+ if (this.disconnected) {
-+ logger_1.default.warn("You cannot connect to a new Peer because you called " +
-+ ".disconnect() on this Peer and ended your connection with the " +
-+ "server. You can create a new Peer to reconnect, or call reconnect " +
-+ "on this peer if you believe its ID to still be available.");
-+ this.emitError(enums_1.PeerErrorType.Disconnected, "Cannot connect to new Peer after disconnecting from server.");
-+ // @ts-ignore
-+ return;
-+ }
-+ var dataConnection = new dataconnection_1.DataConnection(peer, this, options);
-+ this._addConnection(peer, dataConnection);
-+ return dataConnection;
-+ };
-+ /**
-+ * Returns a MediaConnection to the specified peer. See documentation for a
-+ * complete list of options.
-+ */
-+ Peer.prototype.call = function (peer, stream, options) {
-+ if (options === void 0) { options = {}; }
-+ if (this.disconnected) {
-+ logger_1.default.warn("You cannot connect to a new Peer because you called " +
-+ ".disconnect() on this Peer and ended your connection with the " +
-+ "server. You can create a new Peer to reconnect.");
-+ this.emitError(enums_1.PeerErrorType.Disconnected, "Cannot connect to new Peer after disconnecting from server.");
-+ // @ts-ignore
-+ return;
-+ }
-+ if (!stream) {
-+ logger_1.default.error("To call a peer, you must provide a stream from your browser's `getUserMedia`.");
-+ // @ts-ignore
-+ return;
-+ }
-+ options._stream = stream;
-+ var mediaConnection = new mediaconnection_1.MediaConnection(peer, this, options);
-+ this._addConnection(peer, mediaConnection);
-+ return mediaConnection;
-+ };
-+ /** Add a data/media connection to this peer. */
-+ Peer.prototype._addConnection = function (peerId, connection) {
-+ logger_1.default.log("add connection " + connection.type + ":" + connection.connectionId + " to peerId:" + peerId);
-+ if (!this._connections.has(peerId)) {
-+ this._connections.set(peerId, []);
-+ }
-+ // @ts-ignore
-+ this._connections.get(peerId).push(connection);
-+ };
-+ //TODO should be private
-+ Peer.prototype._removeConnection = function (connection) {
-+ var connections = this._connections.get(connection.peer);
-+ if (connections) {
-+ var index = connections.indexOf(connection);
-+ if (index !== -1) {
-+ connections.splice(index, 1);
-+ }
-+ }
-+ //remove from lost messages
-+ this._lostMessages.delete(connection.connectionId);
-+ };
-+ /** Retrieve a data/media connection for this peer. */
-+ Peer.prototype.getConnection = function (peerId, connectionId) {
-+ var connections = this._connections.get(peerId);
-+ if (!connections) {
-+ return null;
-+ }
-+ for (var _i = 0, connections_1 = connections; _i < connections_1.length; _i++) {
-+ var connection = connections_1[_i];
-+ if (connection.connectionId === connectionId) {
-+ return connection;
-+ }
-+ }
-+ return null;
-+ };
-+ Peer.prototype._delayedAbort = function (type, message) {
-+ var _this = this;
-+ setTimeout(function () {
-+ _this._abort(type, message);
-+ }, 0);
-+ };
-+ /**
-+ * Emits an error message and destroys the Peer.
-+ * The Peer is not destroyed if it's in a disconnected state, in which case
-+ * it retains its disconnected state and its existing connections.
-+ */
-+ Peer.prototype._abort = function (type, message) {
-+ logger_1.default.error("Aborting!");
-+ this.emitError(type, message);
-+ if (!this._lastServerId) {
-+ this.destroy();
-+ }
-+ else {
-+ this.disconnect();
-+ }
-+ };
-+ /** Emits a typed error message. */
-+ Peer.prototype.emitError = function (type, err) {
-+ logger_1.default.error("Error:", err);
-+ var error;
-+ if (typeof err === "string") {
-+ error = new Error(err);
-+ }
-+ else {
-+ error = err;
-+ }
-+ error.type = type;
-+ this.emit(enums_1.PeerEventType.Error, error);
-+ };
-+ /**
-+ * Destroys the Peer: closes all active connections as well as the connection
-+ * to the server.
-+ * Warning: The peer can no longer create or accept connections after being
-+ * destroyed.
-+ */
-+ Peer.prototype.destroy = function () {
-+ if (this.destroyed) {
-+ return;
-+ }
-+ logger_1.default.log("Destroy peer with ID:" + this.id);
-+ this.disconnect();
-+ this._cleanup();
-+ this._destroyed = true;
-+ this.emit(enums_1.PeerEventType.Close);
-+ };
-+ /** Disconnects every connection on this peer. */
-+ Peer.prototype._cleanup = function () {
-+ // @ts-ignore
-+ for (var _i = 0, _a = this._connections.keys(); _i < _a.length; _i++) {
-+ var peerId = _a[_i];
-+ this._cleanupPeer(peerId);
-+ this._connections.delete(peerId);
-+ }
-+ this.socket.removeAllListeners();
-+ };
-+ /** Closes all connections to this peer. */
-+ Peer.prototype._cleanupPeer = function (peerId) {
-+ var connections = this._connections.get(peerId);
-+ if (!connections)
-+ return;
-+ for (var _i = 0, connections_2 = connections; _i < connections_2.length; _i++) {
-+ var connection = connections_2[_i];
-+ connection.close();
-+ }
-+ };
-+ /**
-+ * Disconnects the Peer's connection to the PeerServer. Does not close any
-+ * active connections.
-+ * Warning: The peer can no longer create or accept connections after being
-+ * disconnected. It also cannot reconnect to the server.
-+ */
-+ Peer.prototype.disconnect = function () {
-+ if (this.disconnected) {
-+ return;
-+ }
-+ var currentId = this.id;
-+ logger_1.default.log("Disconnect peer with ID:" + currentId);
-+ this._disconnected = true;
-+ this._open = false;
-+ this.socket.close();
-+ this._lastServerId = currentId;
-+ this._id = null;
-+ this.emit(enums_1.PeerEventType.Disconnected, currentId);
-+ };
-+ /** Attempts to reconnect with the same ID. */
-+ Peer.prototype.reconnect = function () {
-+ if (this.disconnected && !this.destroyed) {
-+ logger_1.default.log("Attempting reconnection to server with ID " + this._lastServerId);
-+ this._disconnected = false;
-+ this._initialize(this._lastServerId);
-+ }
-+ else if (this.destroyed) {
-+ throw new Error("This peer cannot reconnect to the server. It has already been destroyed.");
-+ }
-+ else if (!this.disconnected && !this.open) {
-+ // Do nothing. We're still connecting the first time.
-+ logger_1.default.error("In a hurry? We're still trying to make the initial connection!");
-+ }
-+ else {
-+ throw new Error("Peer " + this.id + " cannot reconnect because it is not disconnected from the server!");
-+ }
-+ };
-+ /**
-+ * Get a list of available peer IDs. If you're running your own server, you'll
-+ * want to set allow_discovery: true in the PeerServer options. If you're using
-+ * the cloud server, email team@peerjs.com to get the functionality enabled for
-+ * your key.
-+ */
-+ Peer.prototype.listAllPeers = function (cb) {
-+ var _this = this;
-+ if (cb === void 0) { cb = function (_) { }; }
-+ this._api.listAllPeers()
-+ .then(function (peers) { return cb(peers); })
-+ .catch(function (error) { return _this._abort(enums_1.PeerErrorType.ServerError, error); });
-+ };
-+ Peer.DEFAULT_KEY = "peerjs";
-+ return Peer;
-+}(eventemitter3_1.EventEmitter));
-+exports.Peer = Peer;
-diff --git a/node_modules/peerjs/dist/peerjs.js b/node_modules/peerjs/dist/peerjs.js
-deleted file mode 100644
-index b902845..0000000
---- a/node_modules/peerjs/dist/peerjs.js
-+++ /dev/null
-@@ -1,10318 +0,0 @@
--// modules are defined as an array
--// [ module function, map of requires ]
--//
--// map of requires is short require name -> numeric require
--//
--// anything defined in a previous bundle is accessed via the
--// orig method which is the require for previous bundles
--parcelRequire = (function (modules, cache, entry, globalName) {
-- // Save the require from previous bundle to this closure if any
-- var previousRequire = typeof parcelRequire === 'function' && parcelRequire;
-- var nodeRequire = typeof require === 'function' && require;
--
-- function newRequire(name, jumped) {
-- if (!cache[name]) {
-- if (!modules[name]) {
-- // if we cannot find the module within our internal map or
-- // cache jump to the current global require ie. the last bundle
-- // that was added to the page.
-- var currentRequire = typeof parcelRequire === 'function' && parcelRequire;
-- if (!jumped && currentRequire) {
-- return currentRequire(name, true);
-- }
--
-- // If there are other bundles on this page the require from the
-- // previous one is saved to 'previousRequire'. Repeat this as
-- // many times as there are bundles until the module is found or
-- // we exhaust the require chain.
-- if (previousRequire) {
-- return previousRequire(name, true);
-- }
--
-- // Try the node require function if it exists.
-- if (nodeRequire && typeof name === 'string') {
-- return nodeRequire(name);
-- }
--
-- var err = new Error('Cannot find module \'' + name + '\'');
-- err.code = 'MODULE_NOT_FOUND';
-- throw err;
-- }
--
-- localRequire.resolve = resolve;
-- localRequire.cache = {};
--
-- var module = cache[name] = new newRequire.Module(name);
--
-- modules[name][0].call(module.exports, localRequire, module, module.exports, this);
-- }
--
-- return cache[name].exports;
--
-- function localRequire(x){
-- return newRequire(localRequire.resolve(x));
-- }
--
-- function resolve(x){
-- return modules[name][1][x] || x;
-- }
-- }
--
-- function Module(moduleName) {
-- this.id = moduleName;
-- this.bundle = newRequire;
-- this.exports = {};
-- }
--
-- newRequire.isParcelRequire = true;
-- newRequire.Module = Module;
-- newRequire.modules = modules;
-- newRequire.cache = cache;
-- newRequire.parent = previousRequire;
-- newRequire.register = function (id, exports) {
-- modules[id] = [function (require, module) {
-- module.exports = exports;
-- }, {}];
-- };
--
-- var error;
-- for (var i = 0; i < entry.length; i++) {
-- try {
-- newRequire(entry[i]);
-- } catch (e) {
-- // Save first error but execute all entries
-- if (!error) {
-- error = e;
-- }
-- }
-- }
--
-- if (entry.length) {
-- // Expose entry point to Node, AMD or browser globals
-- // Based on https://github.com/ForbesLindesay/umd/blob/master/template.js
-- var mainExports = newRequire(entry[entry.length - 1]);
--
-- // CommonJS
-- if (typeof exports === "object" && typeof module !== "undefined") {
-- module.exports = mainExports;
--
-- // RequireJS
-- } else if (typeof define === "function" && define.amd) {
-- define(function () {
-- return mainExports;
-- });
--
-- //