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'])
+ cy.get('.action-select-multiple')
+ // 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')
+ cy.get('.action-select')
+ // 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'])
+ cy.get('.action-select-multiple')
+ .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()
+ cy.get('#scroll-horizontal button')
+ .should('be.visible')
+
+ cy.get('#scroll-vertical button')
+ .should('not.be.visible')
+
+ // Cypress handles the scroll direction needed
+ cy.get('#scroll-vertical button').scrollIntoView()
+ cy.get('#scroll-vertical button')
+ .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()
+ cy.get('#scroll-both button')
+ .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)
+ cy.get('.trigger-input-range')
+ .trigger('change')
+ cy.get('.trigger-input-range')
+ .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/cypress/e2e/2-advanced-examples/aliasing.cy.js b/cypress/e2e/2-advanced-examples/aliasing.cy.js
new file mode 100644
index 0000000..a02fb2b
--- /dev/null
+++ b/cypress/e2e/2-advanced-examples/aliasing.cy.js
@@ -0,0 +1,39 @@
+///
+
+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/cypress/e2e/2-advanced-examples/assertions.cy.js b/cypress/e2e/2-advanced-examples/assertions.cy.js
new file mode 100644
index 0000000..79e3d0e
--- /dev/null
+++ b/cypress/e2e/2-advanced-examples/assertions.cy.js
@@ -0,0 +1,176 @@
+///
+
+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
+ 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/cypress/e2e/2-advanced-examples/connectors.cy.js b/cypress/e2e/2-advanced-examples/connectors.cy.js
new file mode 100644
index 0000000..f24cf52
--- /dev/null
+++ b/cypress/e2e/2-advanced-examples/connectors.cy.js
@@ -0,0 +1,98 @@
+///
+
+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()
+ cy.get('.connectors-div').should('be.hidden')
+
+ // https://on.cypress.io/invoke
+ // call the jquery method 'show' on the 'div.container'
+ cy.get('.connectors-div').invoke('show')
+
+ cy.get('.connectors-div').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/cypress/e2e/2-advanced-examples/cookies.cy.js b/cypress/e2e/2-advanced-examples/cookies.cy.js
new file mode 100644
index 0000000..3ad6657
--- /dev/null
+++ b/cypress/e2e/2-advanced-examples/cookies.cy.js
@@ -0,0 +1,118 @@
+///
+
+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 for the current domain', () => {
+ // 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.getAllCookies() - get all browser cookies', () => {
+ // https://on.cypress.io/getallcookies
+ cy.getAllCookies().should('be.empty')
+
+ cy.setCookie('key', 'value')
+ cy.setCookie('key', 'value', { domain: '.example.com' })
+
+ // cy.getAllCookies() yields an array of cookies
+ cy.getAllCookies().should('have.length', 2).should((cookies) => {
+ // each cookie has these properties
+ expect(cookies[0]).to.have.property('name', 'key')
+ expect(cookies[0]).to.have.property('value', 'value')
+ 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')
+
+ expect(cookies[1]).to.have.property('name', 'key')
+ expect(cookies[1]).to.have.property('value', 'value')
+ expect(cookies[1]).to.have.property('httpOnly', false)
+ expect(cookies[1]).to.have.property('secure', false)
+ expect(cookies[1]).to.have.property('domain', '.example.com')
+ expect(cookies[1]).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')
+
+ cy.getCookie('token').should('be.null')
+ })
+
+ it('cy.clearCookies() - clear browser cookies for the current domain', () => {
+ // 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')
+ })
+
+ it('cy.clearAllCookies() - clear all browser cookies', () => {
+ // https://on.cypress.io/clearallcookies
+ cy.getAllCookies().should('be.empty')
+
+ cy.setCookie('key', 'value')
+ cy.setCookie('key', 'value', { domain: '.example.com' })
+
+ cy.getAllCookies().should('have.length', 2)
+
+ // cy.clearAllCookies() yields null
+ cy.clearAllCookies()
+
+ cy.getAllCookies().should('be.empty')
+ })
+})
diff --git a/cypress/e2e/2-advanced-examples/cypress_api.cy.js b/cypress/e2e/2-advanced-examples/cypress_api.cy.js
new file mode 100644
index 0000000..2b367ae
--- /dev/null
+++ b/cypress/e2e/2-advanced-examples/cypress_api.cy.js
@@ -0,0 +1,184 @@
+///
+
+context('Cypress APIs', () => {
+ 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
+ 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
+ })
+
+ 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')
+ })
+ })
+
+ 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/cypress/e2e/2-advanced-examples/files.cy.js b/cypress/e2e/2-advanced-examples/files.cy.js
new file mode 100644
index 0000000..1be9d44
--- /dev/null
+++ b/cypress/e2e/2-advanced-examples/files.cy.js
@@ -0,0 +1,85 @@
+///
+
+/// JSON fixture file can be loaded directly using
+// the built-in JavaScript bundler
+const requiredExample = require('../../fixtures/example')
+
+context('Files', () => {
+ beforeEach(() => {
+ cy.visit('https://example.cypress.io/commands/files')
+
+ // 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.config('configFile')).then((config) => {
+ expect(config).to.be.an('string')
+ })
+ })
+
+ 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/cypress/e2e/2-advanced-examples/location.cy.js b/cypress/e2e/2-advanced-examples/location.cy.js
new file mode 100644
index 0000000..299867d
--- /dev/null
+++ b/cypress/e2e/2-advanced-examples/location.cy.js
@@ -0,0 +1,32 @@
+///
+
+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/cypress/e2e/2-advanced-examples/misc.cy.js b/cypress/e2e/2-advanced-examples/misc.cy.js
new file mode 100644
index 0000000..598aef2
--- /dev/null
+++ b/cypress/e2e/2-advanced-examples/misc.cy.js
@@ -0,0 +1,98 @@
+///
+
+context('Misc', () => {
+ beforeEach(() => {
+ cy.visit('https://example.cypress.io/commands/misc')
+ })
+
+ 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.config('configFile')}`)
+ .its('stderr').should('be.empty')
+ }
+ else {
+ cy.exec(`cat ${Cypress.config('configFile')}`)
+ .its('stderr').should('be.empty')
+
+ cy.log(`Cypress version ${Cypress.version}`)
+ if (Cypress.version.split('.').map(Number)[0] < 15) {
+ cy.exec('pwd')
+ .its('code').should('eq', 0)
+ }
+ else {
+ cy.exec('pwd')
+ .its('exitCode').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/cypress/e2e/2-advanced-examples/navigation.cy.js b/cypress/e2e/2-advanced-examples/navigation.cy.js
new file mode 100644
index 0000000..d9c9d7d
--- /dev/null
+++ b/cypress/e2e/2-advanced-examples/navigation.cy.js
@@ -0,0 +1,55 @@
+///
+
+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/cypress/e2e/2-advanced-examples/network_requests.cy.js b/cypress/e2e/2-advanced-examples/network_requests.cy.js
new file mode 100644
index 0000000..11213a0
--- /dev/null
+++ b/cypress/e2e/2-advanced-examples/network_requests.cy.js
@@ -0,0 +1,163 @@
+///
+
+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/cypress/e2e/2-advanced-examples/querying.cy.js b/cypress/e2e/2-advanced-examples/querying.cy.js
new file mode 100644
index 0000000..0097048
--- /dev/null
+++ b/cypress/e2e/2-advanced-examples/querying.cy.js
@@ -0,0 +1,114 @@
+///
+
+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/cypress/e2e/2-advanced-examples/spies_stubs_clocks.cy.js b/cypress/e2e/2-advanced-examples/spies_stubs_clocks.cy.js
new file mode 100644
index 0000000..6186f3a
--- /dev/null
+++ b/cypress/e2e/2-advanced-examples/spies_stubs_clocks.cy.js
@@ -0,0 +1,204 @@
+///
+
+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 it's 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()
+ cy.get('#clock-div')
+ .should('have.text', '1489449600')
+ })
+
+ it('cy.tick() - move time in the browser', () => {
+ // https://on.cypress.io/tick
+
+ // create the date in UTC so it's 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()
+ cy.get('#tick-div')
+ .should('have.text', '1489449600')
+
+ cy.tick(10000) // 10 seconds passed
+ cy.get('#tick-div').click()
+ cy.get('#tick-div')
+ .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')
+ expect(() => greeter.greet(42)).to.throw('Invalid name')
+ expect(greeter.greet).to.have.been.calledTwice
+
+ // non-matched calls goes the actual method
+ 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 even
+ * @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/cypress/e2e/2-advanced-examples/storage.cy.js b/cypress/e2e/2-advanced-examples/storage.cy.js
new file mode 100644
index 0000000..9e888b0
--- /dev/null
+++ b/cypress/e2e/2-advanced-examples/storage.cy.js
@@ -0,0 +1,117 @@
+///
+
+context('Local Storage / Session Storage', () => {
+ beforeEach(() => {
+ cy.visit('https://example.cypress.io/commands/storage')
+ })
+ // Although localStorage is automatically cleared
+ // in between tests to maintain a clean state
+ // sometimes we need to clear localStorage manually
+
+ it('cy.clearLocalStorage() - clear all data in localStorage for the current origin', () => {
+ // https://on.cypress.io/clearlocalstorage
+ cy.get('.ls-btn').click()
+ cy.get('.ls-btn').should(() => {
+ expect(localStorage.getItem('prop1')).to.eq('red')
+ expect(localStorage.getItem('prop2')).to.eq('blue')
+ expect(localStorage.getItem('prop3')).to.eq('magenta')
+ })
+
+ cy.clearLocalStorage()
+ cy.getAllLocalStorage().should(() => {
+ expect(localStorage.getItem('prop1')).to.be.null
+ expect(localStorage.getItem('prop2')).to.be.null
+ expect(localStorage.getItem('prop3')).to.be.null
+ })
+
+ cy.get('.ls-btn').click()
+ cy.get('.ls-btn').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 localStorage
+ cy.clearLocalStorage('prop1')
+ cy.getAllLocalStorage().should(() => {
+ expect(localStorage.getItem('prop1')).to.be.null
+ expect(localStorage.getItem('prop2')).to.eq('blue')
+ expect(localStorage.getItem('prop3')).to.eq('magenta')
+ })
+
+ cy.get('.ls-btn').click()
+ cy.get('.ls-btn').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 localStorage
+ cy.clearLocalStorage(/prop1|2/)
+ cy.getAllLocalStorage().should(() => {
+ expect(localStorage.getItem('prop1')).to.be.null
+ expect(localStorage.getItem('prop2')).to.be.null
+ expect(localStorage.getItem('prop3')).to.eq('magenta')
+ })
+ })
+
+ it('cy.getAllLocalStorage() - get all data in localStorage for all origins', () => {
+ // https://on.cypress.io/getalllocalstorage
+ cy.get('.ls-btn').click()
+
+ // getAllLocalStorage() yields a map of origins to localStorage values
+ cy.getAllLocalStorage().should((storageMap) => {
+ expect(storageMap).to.deep.equal({
+ // other origins will also be present if localStorage is set on them
+ 'https://example.cypress.io': {
+ prop1: 'red',
+ prop2: 'blue',
+ prop3: 'magenta',
+ },
+ })
+ })
+ })
+
+ it('cy.clearAllLocalStorage() - clear all data in localStorage for all origins', () => {
+ // https://on.cypress.io/clearalllocalstorage
+ cy.get('.ls-btn').click()
+
+ // clearAllLocalStorage() yields null
+ cy.clearAllLocalStorage()
+ cy.getAllLocalStorage().should(() => {
+ expect(localStorage.getItem('prop1')).to.be.null
+ expect(localStorage.getItem('prop2')).to.be.null
+ expect(localStorage.getItem('prop3')).to.be.null
+ })
+ })
+
+ it('cy.getAllSessionStorage() - get all data in sessionStorage for all origins', () => {
+ // https://on.cypress.io/getallsessionstorage
+ cy.get('.ls-btn').click()
+
+ // getAllSessionStorage() yields a map of origins to sessionStorage values
+ cy.getAllSessionStorage().should((storageMap) => {
+ expect(storageMap).to.deep.equal({
+ // other origins will also be present if sessionStorage is set on them
+ 'https://example.cypress.io': {
+ prop4: 'cyan',
+ prop5: 'yellow',
+ prop6: 'black',
+ },
+ })
+ })
+ })
+
+ it('cy.clearAllSessionStorage() - clear all data in sessionStorage for all origins', () => {
+ // https://on.cypress.io/clearallsessionstorage
+ cy.get('.ls-btn').click()
+
+ // clearAllSessionStorage() yields null
+ cy.clearAllSessionStorage()
+ cy.getAllSessionStorage().should(() => {
+ expect(sessionStorage.getItem('prop4')).to.be.null
+ expect(sessionStorage.getItem('prop5')).to.be.null
+ expect(sessionStorage.getItem('prop6')).to.be.null
+ })
+ })
+})
diff --git a/cypress/e2e/2-advanced-examples/traversal.cy.js b/cypress/e2e/2-advanced-examples/traversal.cy.js
new file mode 100644
index 0000000..0a3b9d3
--- /dev/null
+++ b/cypress/e2e/2-advanced-examples/traversal.cy.js
@@ -0,0 +1,121 @@
+///
+
+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/cypress/e2e/2-advanced-examples/utilities.cy.js b/cypress/e2e/2-advanced-examples/utilities.cy.js
new file mode 100644
index 0000000..50b224f
--- /dev/null
+++ b/cypress/e2e/2-advanced-examples/utilities.cy.js
@@ -0,0 +1,107 @@
+///
+
+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')
+ cy.wrap($li).click()
+ cy.wrap($li).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()
+ cy.get('.utility-blob img').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
+ 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
+ return waitOneSecond().then((str) => {
+ expect(str).to.eq('foo')
+ expect(waited).to.be.true
+ })
+ })
+ })
+})
diff --git a/cypress/e2e/2-advanced-examples/viewport.cy.js b/cypress/e2e/2-advanced-examples/viewport.cy.js
new file mode 100644
index 0000000..a06ae20
--- /dev/null
+++ b/cypress/e2e/2-advanced-examples/viewport.cy.js
@@ -0,0 +1,58 @@
+///
+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.config.{js|ts})
+ })
+})
diff --git a/cypress/e2e/2-advanced-examples/waiting.cy.js b/cypress/e2e/2-advanced-examples/waiting.cy.js
new file mode 100644
index 0000000..21998f9
--- /dev/null
+++ b/cypress/e2e/2-advanced-examples/waiting.cy.js
@@ -0,0 +1,30 @@
+///
+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/cypress/e2e/2-advanced-examples/window.cy.js b/cypress/e2e/2-advanced-examples/window.cy.js
new file mode 100644
index 0000000..f94b649
--- /dev/null
+++ b/cypress/e2e/2-advanced-examples/window.cy.js
@@ -0,0 +1,22 @@
+///
+
+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/cypress/e2e/Sign-up/signup_test.cy.js b/cypress/e2e/Sign-up/signup_test.cy.js
new file mode 100644
index 0000000..edbc55c
--- /dev/null
+++ b/cypress/e2e/Sign-up/signup_test.cy.js
@@ -0,0 +1,327 @@
+
+// for duplicate email use moayman@20001@gmail.com
+it('signup_test1', () => {
+ cy.visit('https://hankers-frontend.myaddr.tools');
+ cy.contains('button', 'Create account').click();
+ cy.get('[data-testid="auth-input-name"]').type('mohamed');
+ cy.get('[data-testid="auth-email-input"]').type('omarayman740@yahoo.com');
+ cy.get('[data-testid="auth-select-month"]').select('January');
+ cy.get('[data-testid="auth-select-day"]').select('8');
+ cy.get('[data-testid="auth-select-year"]').select('2004');
+ cy.get('[data-testid="auth-button-primary-lg"]').click();
+ cy.contains('Email has already been taken', { timeout: 10000 }).should('be.visible');
+ //failing test for duplicate email
+});
+
+
+// // // invlid email format
+// it('signup_test2', () => {
+// cy.visit('https://hankers-frontend.myaddr.tools');
+// cy.contains('button','Create account').click();
+// cy.get('[data-testid="auth-input-name"]').type('mohamed');
+// cy.get('[data-testid="auth-email-input"]').type('test2001');
+// cy.get('[data-testid="auth-select-month"]').select('January');
+// cy.get('[data-testid="auth-select-day"]').select('8');
+// cy.get('[data-testid="auth-select-year"]').select('2004');
+// cy.get('[data-testid="auth-button-primary-lg"]').click();
+// cy.contains('Please enter a valid email', { timeout: 1000 }).should('be.visible');
+// });
+// //passing
+
+// // //missing name
+// it('signup_test3', () => {
+// cy.visit('https://hankers-frontend.myaddr.tools');
+// cy.contains('button','Create account').click();
+// // cy.get('[data-testid="auth-input-name"]').type('mohamed');
+// cy.get('[data-testid="auth-email-input"]').type('mohamed.azeim04@eng-st.cu.edu.eg');
+// cy.get('[data-testid="auth-select-month"]').select('January');
+// cy.get('[data-testid="auth-select-day"]').select('8');
+// cy.get('[data-testid="auth-select-year"]').select('2004');
+// cy.get('[data-testid="auth-button-primary-lg"]').should('be.disabled');
+
+// });
+// //pass
+
+// // //missing date of birth
+// it('signup_test4', () => {
+// cy.visit('https://hankers-frontend.myaddr.tools');
+// cy.contains('button','Create account').click();
+// cy.get('[data-testid="auth-input-name"]').type('mohamed');
+// cy.get('[data-testid="auth-email-input"]').type('mohamed.azeim04@eng-st.cu.edu.eg');
+// cy.get('[data-testid="auth-button-primary-lg"]').should('be.disabled');
+// });
+// //pass
+
+
+// // //missing email
+// it('signup_test5', () => {
+// cy.visit('https://hankers-frontend.myaddr.tools');
+// cy.contains('button','Create account').click();
+// cy.get('[data-testid="auth-input-name"]').type('mohamed');
+// //cy.get('[data-testid="auth-email-input"]').type('mohamed.azeim04@eng-st.cu.edu.eg');
+// cy.get('[data-testid="auth-select-month"]').select('January');
+// cy.get('[data-testid="auth-select-day"]').select('8');
+// cy.get('[data-testid="auth-select-year"]').select('2004');
+// cy.get('[data-testid="auth-button-primary-lg"]').should('be.disabled');
+// });
+// //pass
+
+// // // short name
+// it('signup_test6', () => {
+// cy.visit('https://hankers-frontend.myaddr.tools');
+// cy.contains('button','Create account').click();
+// cy.get('[data-testid="auth-input-name"]').type('m');
+// cy.get('[data-testid="auth-email-input"]').type('mohamed.azeim04@eng-st.cu.edu.eg');
+// cy.get('[data-testid="auth-select-month"]').select('January');
+// cy.get('[data-testid="auth-select-day"]').select('8');
+// cy.get('[data-testid="auth-select-year"]').select('2004');
+// cy.get('[data-testid="auth-button-primary-lg"]').click();
+// });
+// //pass
+
+// //short name and leading and trailing spaces in email
+// it('signup_test7', () => {
+// cy.visit('https://hankers-frontend.myaddr.tools');
+// cy.contains('button','Create account').click();
+// cy.get('[data-testid="auth-input-name"]').type('m');
+// cy.get('[data-testid="auth-email-input"]').type(' mohamed.azeim04@eng-st.cu.edu.eg ');
+// cy.get('[data-testid="auth-select-month"]').select('January');
+// cy.get('[data-testid="auth-select-day"]').select('8');
+// cy.get('[data-testid="auth-select-year"]').select('2004');
+// cy.get('[data-testid="auth-button-primary-lg"]').click();
+// });
+// // pass
+
+
+// //leading and trailing spaces in email and name
+// it('signup_test8', () => {
+// cy.visit('https://hankers-frontend.myaddr.tools');
+// cy.contains('button','Create account').click();
+// cy.get('[data-testid="auth-input-name"]').type(' mohamed ayman ');
+// cy.get('[data-testid="auth-email-input"]').type(' mohamed.azeim04@eng-st.cu.edu.eg ');
+// cy.get('[data-testid="auth-select-month"]').select('January');
+// cy.get('[data-testid="auth-select-day"]').select('8');
+// cy.get('[data-testid="auth-select-year"]').select('2004');
+// cy.get('[data-testid="auth-button-primary-lg"]').click();
+// });
+// // pass
+
+// // // date of birth not logical
+// it('signup_test9', () => {
+// cy.visit('https://hankers-frontend.myaddr.tools');
+// cy.contains('button','Create account').click();
+// cy.get('[data-testid="auth-input-name"]').type(' mohamed ayman ');
+// cy.get('[data-testid="auth-email-input"]').type('mohamed.azeim04@eng-st.cu.edu.eg');
+// cy.get('[data-testid="auth-select-month"]').select('January');
+// cy.get('[data-testid="auth-select-day"]').select('8');
+// cy.get('[data-testid="auth-select-year"]').select('2025');
+// cy.get('[data-testid="auth-button-primary-lg"]').click();
+// });
+// // pass notice (like twitter so i dont know )
+
+
+
+// // //make refresh in the middle of filling the form
+// it('signup_test10', () => {
+// cy.visit('https://hankers-frontend.myaddr.tools');
+// cy.contains('button', 'Create account').click();
+// cy.get('[data-testid="auth-input-name"]').type('mohamed ayman');
+// cy.get('[data-testid="auth-email-input"]').type('mohamed.azeim04@eng-st.cu.edu.eg');
+// cy.reload();
+// cy.wait(1000);
+// cy.get('body').then(($body) => {
+// if ($body.find('[data-testid="auth-input-name"]').length > 0) {
+// cy.log(' Still on signup form after refresh');
+// } else {
+// cy.log(' Signup form not found after refresh β probably redirected');
+// }
+// });
+// cy.get('[data-testid="auth-input-name"]').type('mohamed ayman');
+// cy.get('[data-testid="auth-email-input"]').type('mohamed.azeim04@eng-st.cu.edu.eg');
+// cy.get('[data-testid="auth-select-month"]').select('January');
+// cy.get('[data-testid="auth-select-day"]').select('8');
+// cy.get('[data-testid="auth-select-year"]').select('2020');
+// cy.get('[data-testid="auth-button-primary-lg"]').click();
+// });
+// //fail notice(as it redirects to home page after refresh not keep me at the same page)
+
+// //check case insensitivity of email
+// it('signup_test11', () => {
+// cy.visit('https://hankers-frontend.myaddr.tools');
+// cy.contains('button','Create account').click();
+// cy.get('[data-testid="auth-input-name"]').type('mohamed ayman');
+// cy.get('[data-testid="auth-email-input"]').type('Omarayman740@yahoo.com');
+// cy.get('[data-testid="auth-select-month"]').select('January');
+// cy.get('[data-testid="auth-select-day"]').select('8');
+// cy.get('[data-testid="auth-select-year"]').select('2020');
+// cy.get('[data-testid="auth-button-primary-lg"]').click();
+// cy.get('body').then(($body) => {
+// if ($body.find('[data-testid="auth-input-name"]').length > 0) {
+// cy.log(' Still on signup form after refresh');
+// } else {
+// cy.log(' Signup form not found after refresh β probably redirected');
+// }
+// });
+// });
+// // fail
+
+// // uncomplete email format
+// it('signup_test12', () => {
+// cy.visit('https://hankers-frontend.myaddr.tools');
+// cy.contains('button','Create account').click();
+// cy.get('[data-testid="auth-input-name"]').type('mohamed ayman');
+// cy.get('[data-testid="auth-email-input"]').type('Omarayman740@');
+// cy.get('[data-testid="auth-select-month"]').select('January');
+// cy.get('[data-testid="auth-select-day"]').select('8');
+// cy.get('[data-testid="auth-select-year"]').select('2020');
+// cy.get('[data-testid="auth-button-primary-lg"]').click();
+// });
+// // partial as the message did not appear from the FE it came from the field itself
+
+// //check emoji in name field and special char in name and email
+// it('signup_test13', () => {
+// cy.visit('https://hankers-frontend.myaddr.tools');
+// cy.contains('button','Create account').click();
+// cy.get('[data-testid="auth-input-name"]').type('@momoβ€');
+// cy.get('[data-testid="auth-email-input"]').type('Omarayman740@yahoo.comβ€');
+// cy.get('[data-testid="auth-select-month"]').select('January');
+// cy.get('[data-testid="auth-select-day"]').select('8');
+// cy.get('[data-testid="auth-select-year"]').select('2020');
+// cy.get('[data-testid="auth-button-primary-lg"]').click();
+// });
+// // partial as it didnt show message the message came from the field itself not from the FE
+
+// // try an valid random password
+// it('signup_test14', () => {
+// cy.visit('https://hankers-frontend.myaddr.tools');
+// cy.contains('button','Create account').click();
+// cy.get('[data-testid="auth-input-name"]').type('m');
+// cy.get('[data-testid="auth-email-input"]').type('mohamed.azeim04@eng-st.cu.edu.eg');
+// cy.get('[data-testid="auth-select-month"]').select('January');
+// cy.get('[data-testid="auth-select-day"]').select('8');
+// cy.get('[data-testid="auth-select-year"]').select('2004');
+// cy.get('[data-testid="auth-button-primary-lg"]').click();
+// cy.get('[data-testid="auth-input-new-password"]').type('Password123!');
+// cy.get('[data-testid="auth-input-confirm-new-password"]').type('Password123!');
+// cy.get('[data-testid="auth-button-primary-lg"]').click();
+// });
+// //fail & the page i think it is wrong as it name reset the password and the twitter itself does not have an confirm password field it only password field only
+
+
+
+// //unmatched passwords
+// it('signup_test15', () => {
+// cy.visit('https://hankers-frontend.myaddr.tools');
+// cy.contains('button','Create account').click();
+// cy.get('[data-testid="auth-input-name"]').type('m');
+// cy.get('[data-testid="auth-email-input"]').type('mohamed.azeim04@eng-st.cu.edu.eg');
+// cy.get('[data-testid="auth-select-month"]').select('January');
+// cy.get('[data-testid="auth-select-day"]').select('8');
+// cy.get('[data-testid="auth-select-year"]').select('2004');
+// cy.get('[data-testid="auth-button-primary-lg"]').click();
+// cy.get('[data-testid="auth-input-new-password"]').type('Password12!');
+// cy.get('[data-testid="auth-input-confirm-new-password"]').type('Password123!');
+// cy.get('[data-testid="auth-button-primary-lg"]').should('be.disabled');
+// cy.contains('Passwords do not match',{timeout:10000}).should('be.visible');
+// });
+// //pass same page issue as above
+
+
+// //missing confirm password
+// it('signup_test16', () => {
+// cy.visit('https://hankers-frontend.myaddr.tools');
+// cy.contains('button','Create account').click();
+// cy.get('[data-testid="auth-input-name"]').type('m');
+// cy.get('[data-testid="auth-email-input"]').type('mohamed.azeim04@eng-st.cu.edu.eg');
+// cy.get('[data-testid="auth-select-month"]').select('January');
+// cy.get('[data-testid="auth-select-day"]').select('8');
+// cy.get('[data-testid="auth-select-year"]').select('2004');
+// cy.get('[data-testid="auth-button-primary-lg"]').click();
+// cy.get('[data-testid="auth-input-new-password"]').type('Password12345@');
+// //cy.get('[data-testid="auth-input-confirm-new-password"]').type('Password12345@');
+// cy.get('[data-testid="auth-button-primary-lg"]').should('be.disabled');
+// });
+// //pass same page issue as above
+
+// // 8spaces only in password fields
+// it('signup_test17', () => {
+// cy.visit('https://hankers-frontend.myaddr.tools');
+// cy.contains('button','Create account').click();
+// cy.get('[data-testid="auth-input-name"]').type('m');
+// cy.get('[data-testid="auth-email-input"]').type('mohamed.azeim04@eng-st.cu.edu.eg');
+// cy.get('[data-testid="auth-select-month"]').select('January');
+// cy.get('[data-testid="auth-select-day"]').select('8');
+// cy.get('[data-testid="auth-select-year"]').select('2004');
+// cy.get('[data-testid="auth-button-primary-lg"]').click();
+// cy.get('[data-testid="auth-input-new-password"]').type(' ');
+// cy.get('[data-testid="auth-input-confirm-new-password"]').type(' ');
+// cy.get('[data-testid="auth-button-primary-lg"]').should('be.disabled');
+// });
+// //fail nothing happen no message shown
+
+// it('signup_test18', () => {
+// cy.visit('https://hankers-frontend.myaddr.tools');
+// cy.contains('button','Create account').click();
+// cy.get('[data-testid="auth-input-name"]').type('m');
+// cy.get('[data-testid="auth-email-input"]').type('mohamed.azeim04@eng-st.cu.edu.eg');
+// cy.get('[data-testid="auth-select-month"]').select('January');
+// cy.get('[data-testid="auth-select-day"]').select('8');
+// cy.get('[data-testid="auth-select-year"]').select('2004');
+// cy.get('[data-testid="auth-button-primary-lg"]').click();
+// cy.get('[data-testid="auth-input-new-password"]').type(' Moh@1 ');
+// cy.get('[data-testid="auth-input-confirm-new-password"]').type(' Moh@1 ');
+// cy.get('[data-testid="auth-button-primary-lg"]').should('be.disabled');
+// });
+// //fail uncorrect message appeared
+
+// //minimum valid password length
+// it('signup_test19', () => {
+// cy.visit('https://hankers-frontend.myaddr.tools');
+// cy.contains('button','Create account').click();
+// cy.get('[data-testid="auth-input-name"]').type('m');
+// cy.get('[data-testid="auth-email-input"]').type('mohamed.azeim04@eng-st.cu.edu.eg');
+// cy.get('[data-testid="auth-select-month"]').select('January');
+// cy.get('[data-testid="auth-select-day"]').select('8');
+// cy.get('[data-testid="auth-select-year"]').select('2004');
+// cy.get('[data-testid="auth-button-primary-lg"]').click();
+// cy.get('[data-testid="auth-input-new-password"]').type('Mohame@1');
+// cy.get('[data-testid="auth-input-confirm-new-password"]').type('Mohame@1');
+// cy.get('[data-testid="auth-button-primary-lg"]').should('be.disabled');
+// });
+// //fail
+
+// //weak password
+// it('signup_test20', () => {
+// cy.visit('https://hankers-frontend.myaddr.tools');
+// cy.contains('button','Create account').click();
+// cy.get('[data-testid="auth-input-name"]').type('m');
+// cy.get('[data-testid="auth-email-input"]').type('mohamed.azeim04@eng-st.cu.edu.eg');
+// cy.get('[data-testid="auth-select-month"]').select('January');
+// cy.get('[data-testid="auth-select-day"]').select('8');
+// cy.get('[data-testid="auth-select-year"]').select('2004');
+// cy.get('[data-testid="auth-button-primary-lg"]').click();
+// cy.get('[data-testid="auth-input-new-password"]').type('M123');
+// cy.get('[data-testid="auth-input-confirm-new-password"]').type('M123');
+// cy.get('[data-testid="auth-button-primary-lg"]').should('be.disabled');
+// });
+
+// // pass partial (the data inside the password field dissapeared so the button became disabled)
+
+
+// //redirect to sign in page
+// it('signup_test21', () => {
+// cy.visit('https://hankers-frontend.myaddr.tools');
+// cy.contains('button','Create account').click();
+// cy.get('[data-testid="auth-input-name"]').type('m');
+// cy.get('[data-testid="auth-email-input"]').type('mohamed.azeim04@eng-st.cu.edu.eg');
+// cy.get('[data-testid="auth-select-month"]').select('January');
+// cy.get('[data-testid="auth-select-day"]').select('8');
+// cy.get('[data-testid="auth-select-year"]').select('2004');
+// cy.get('[data-testid="auth-button-primary-lg"]').click();
+// //cy.get('[data-testid="auth-input-new-password"]').type('Password12345@');
+// //cy.get('[data-testid="auth-input-confirm-new-password"]').type('Password12345@');
+// cy.contains('a', 'Sign in').click();
+// });
+// pass
+
+
diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json
new file mode 100644
index 0000000..02e4254
--- /dev/null
+++ b/cypress/fixtures/example.json
@@ -0,0 +1,5 @@
+{
+ "name": "Using fixtures to represent data",
+ "email": "hello@cypress.io",
+ "body": "Fixtures are a great way to mock data for responses to routes"
+}
diff --git a/cypress/support/commands.js b/cypress/support/commands.js
new file mode 100644
index 0000000..66ea16e
--- /dev/null
+++ b/cypress/support/commands.js
@@ -0,0 +1,25 @@
+// ***********************************************
+// This example commands.js shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add('login', (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
\ No newline at end of file
diff --git a/cypress/support/e2e.js b/cypress/support/e2e.js
new file mode 100644
index 0000000..3eaffff
--- /dev/null
+++ b/cypress/support/e2e.js
@@ -0,0 +1,17 @@
+// ***********************************************************
+// This example support/e2e.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
\ No newline at end of file
From dc3ac1149dfc5a280671378c0eaffad198743b18 Mon Sep 17 00:00:00 2001
From: omar <141494327+MoMoAymn@users.noreply.github.com>
Date: Wed, 29 Oct 2025 16:53:41 +0300
Subject: [PATCH 02/19] setup
---
package-lock.json | 2217 +++++++++++++++++++++++++++++++++++++++++++++
package.json | 23 +
2 files changed, 2240 insertions(+)
create mode 100644 package-lock.json
create mode 100644 package.json
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..ac6df3e
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,2217 @@
+{
+ "name": "testing",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "testing",
+ "version": "1.0.0",
+ "license": "ISC",
+ "devDependencies": {
+ "cypress": "^15.5.0"
+ }
+ },
+ "node_modules/@cypress/request": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.9.tgz",
+ "integrity": "sha512-I3l7FdGRXluAS44/0NguwWlO83J18p0vlr2FYHrJkWdNYhgVoiYo61IXPqaOsL+vNxU1ZqMACzItGK3/KKDsdw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "aws-sign2": "~0.7.0",
+ "aws4": "^1.8.0",
+ "caseless": "~0.12.0",
+ "combined-stream": "~1.0.6",
+ "extend": "~3.0.2",
+ "forever-agent": "~0.6.1",
+ "form-data": "~4.0.4",
+ "http-signature": "~1.4.0",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.19",
+ "performance-now": "^2.1.0",
+ "qs": "6.14.0",
+ "safe-buffer": "^5.1.2",
+ "tough-cookie": "^5.0.0",
+ "tunnel-agent": "^0.6.0",
+ "uuid": "^8.3.2"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/@cypress/xvfb": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz",
+ "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^3.1.0",
+ "lodash.once": "^4.1.1"
+ }
+ },
+ "node_modules/@cypress/xvfb/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/@types/node": {
+ "version": "24.9.1",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.9.1.tgz",
+ "integrity": "sha512-QoiaXANRkSXK6p0Duvt56W208du4P9Uye9hWLWgGMDTEoKPhuenzNcC4vGUmrNkiOKTlIrBoyNQYNpSwfEZXSg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "undici-types": "~7.16.0"
+ }
+ },
+ "node_modules/@types/sinonjs__fake-timers": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz",
+ "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/sizzle": {
+ "version": "2.3.10",
+ "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.10.tgz",
+ "integrity": "sha512-TC0dmN0K8YcWEAEfiPi5gJP14eJe30TTGjkvek3iM/1NdHHsdCA/Td6GvNndMOo/iSnIsZ4HuuhrYPDAmbxzww==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/tmp": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.2.6.tgz",
+ "integrity": "sha512-chhaNf2oKHlRkDGt+tiKE2Z5aJ6qalm7Z9rlLdBwmOiAAf09YQvvoLXjWK4HWPF1xU/fqvMgfNfpVoBscA/tKA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/yauzl": {
+ "version": "2.10.3",
+ "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz",
+ "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/aggregate-error": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
+ "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "clean-stack": "^2.0.0",
+ "indent-string": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-colors": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
+ "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ansi-escapes": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
+ "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^0.21.3"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ansi-escapes/node_modules/type-fest": {
+ "version": "0.21.3",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
+ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/arch": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz",
+ "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/asn1": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
+ "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": "~2.1.0"
+ }
+ },
+ "node_modules/assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/astral-regex": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
+ "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/at-least-node": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
+ "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
+ "node_modules/aws-sign2": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/aws4": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz",
+ "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/bcrypt-pbkdf": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+ "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "tweetnacl": "^0.14.3"
+ }
+ },
+ "node_modules/blob-util": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz",
+ "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/bluebird": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
+ "node_modules/buffer-crc32": {
+ "version": "0.2.13",
+ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+ "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/cachedir": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz",
+ "integrity": "sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/chalk/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ci-info": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz",
+ "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/sibiraj-s"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/clean-stack": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/cli-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
+ "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "restore-cursor": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cli-table3": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.1.tgz",
+ "integrity": "sha512-w0q/enDHhPLq44ovMGdQeeDLvwxwavsJX7oQGYt/LrBlYsyaxyDnp6z3QzFut/6kLLKnlcUVJLrpB7KBfgG/RA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "string-width": "^4.2.0"
+ },
+ "engines": {
+ "node": "10.* || >= 12.*"
+ },
+ "optionalDependencies": {
+ "colors": "1.4.0"
+ }
+ },
+ "node_modules/cli-truncate": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz",
+ "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "slice-ansi": "^3.0.0",
+ "string-width": "^4.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/colorette": {
+ "version": "2.0.20",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
+ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/colors": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
+ "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=0.1.90"
+ }
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/commander": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
+ "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/common-tags": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz",
+ "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/cypress": {
+ "version": "15.5.0",
+ "resolved": "https://registry.npmjs.org/cypress/-/cypress-15.5.0.tgz",
+ "integrity": "sha512-7jXBsh5hTfjxr9QQONC2IbdTj0nxSyU8x4eiarMZBzXzCj3pedKviUx8JnLcE4vL8e0TsOzp70WSLRORjEssRA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "@cypress/request": "^3.0.9",
+ "@cypress/xvfb": "^1.2.4",
+ "@types/sinonjs__fake-timers": "8.1.1",
+ "@types/sizzle": "^2.3.2",
+ "@types/tmp": "^0.2.3",
+ "arch": "^2.2.0",
+ "blob-util": "^2.0.2",
+ "bluebird": "^3.7.2",
+ "buffer": "^5.7.1",
+ "cachedir": "^2.3.0",
+ "chalk": "^4.1.0",
+ "ci-info": "^4.1.0",
+ "cli-cursor": "^3.1.0",
+ "cli-table3": "0.6.1",
+ "commander": "^6.2.1",
+ "common-tags": "^1.8.0",
+ "dayjs": "^1.10.4",
+ "debug": "^4.3.4",
+ "enquirer": "^2.3.6",
+ "eventemitter2": "6.4.7",
+ "execa": "4.1.0",
+ "executable": "^4.1.1",
+ "extract-zip": "2.0.1",
+ "figures": "^3.2.0",
+ "fs-extra": "^9.1.0",
+ "hasha": "5.2.2",
+ "is-installed-globally": "~0.4.0",
+ "listr2": "^3.8.3",
+ "lodash": "^4.17.21",
+ "log-symbols": "^4.0.0",
+ "minimist": "^1.2.8",
+ "ospath": "^1.2.2",
+ "pretty-bytes": "^5.6.0",
+ "process": "^0.11.10",
+ "proxy-from-env": "1.0.0",
+ "request-progress": "^3.0.0",
+ "semver": "^7.7.1",
+ "supports-color": "^8.1.1",
+ "systeminformation": "5.27.7",
+ "tmp": "~0.2.4",
+ "tree-kill": "1.2.2",
+ "untildify": "^4.0.0",
+ "yauzl": "^2.10.0"
+ },
+ "bin": {
+ "cypress": "bin/cypress"
+ },
+ "engines": {
+ "node": "^20.1.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assert-plus": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/dayjs": {
+ "version": "1.11.18",
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.18.tgz",
+ "integrity": "sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/ecc-jsbn": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+ "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.1.0"
+ }
+ },
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/end-of-stream": {
+ "version": "1.4.5",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
+ "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "once": "^1.4.0"
+ }
+ },
+ "node_modules/enquirer": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz",
+ "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-colors": "^4.1.1",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/eventemitter2": {
+ "version": "6.4.7",
+ "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz",
+ "integrity": "sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/execa": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
+ "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cross-spawn": "^7.0.0",
+ "get-stream": "^5.0.0",
+ "human-signals": "^1.1.1",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.0",
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2",
+ "strip-final-newline": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/executable": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz",
+ "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pify": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/extract-zip": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
+ "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "debug": "^4.1.1",
+ "get-stream": "^5.1.0",
+ "yauzl": "^2.10.0"
+ },
+ "bin": {
+ "extract-zip": "cli.js"
+ },
+ "engines": {
+ "node": ">= 10.17.0"
+ },
+ "optionalDependencies": {
+ "@types/yauzl": "^2.9.1"
+ }
+ },
+ "node_modules/extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==",
+ "dev": true,
+ "engines": [
+ "node >=0.6.0"
+ ],
+ "license": "MIT"
+ },
+ "node_modules/fd-slicer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
+ "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pend": "~1.2.0"
+ }
+ },
+ "node_modules/figures": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
+ "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "escape-string-regexp": "^1.0.5"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/form-data": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
+ "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "es-set-tostringtag": "^2.1.0",
+ "hasown": "^2.0.2",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fs-extra": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
+ "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "at-least-node": "^1.0.0",
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pump": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "node_modules/global-dirs": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz",
+ "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ini": "2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasha": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz",
+ "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-stream": "^2.0.0",
+ "type-fest": "^0.8.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/http-signature": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.4.0.tgz",
+ "integrity": "sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assert-plus": "^1.0.0",
+ "jsprim": "^2.0.2",
+ "sshpk": "^1.18.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/human-signals": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
+ "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=8.12.0"
+ }
+ },
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/indent-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ini": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz",
+ "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-installed-globally": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz",
+ "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "global-dirs": "^3.0.0",
+ "is-path-inside": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-path-inside": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-unicode-supported": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
+ "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-schema": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
+ "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
+ "dev": true,
+ "license": "(AFL-2.1 OR BSD-3-Clause)"
+ },
+ "node_modules/json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/jsonfile": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz",
+ "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/jsprim": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz",
+ "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==",
+ "dev": true,
+ "engines": [
+ "node >=0.6.0"
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.4.0",
+ "verror": "1.10.0"
+ }
+ },
+ "node_modules/listr2": {
+ "version": "3.14.0",
+ "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz",
+ "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cli-truncate": "^2.1.0",
+ "colorette": "^2.0.16",
+ "log-update": "^4.0.0",
+ "p-map": "^4.0.0",
+ "rfdc": "^1.3.0",
+ "rxjs": "^7.5.1",
+ "through": "^2.3.8",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "enquirer": ">= 2.3.0 < 3"
+ },
+ "peerDependenciesMeta": {
+ "enquirer": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.once": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
+ "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/log-symbols": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
+ "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.1.0",
+ "is-unicode-supported": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-update": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz",
+ "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-escapes": "^4.3.0",
+ "cli-cursor": "^3.1.0",
+ "slice-ansi": "^4.0.0",
+ "wrap-ansi": "^6.2.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-update/node_modules/slice-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
+ "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "astral-regex": "^2.0.0",
+ "is-fullwidth-code-point": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+ }
+ },
+ "node_modules/log-update/node_modules/wrap-ansi": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+ "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ospath": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz",
+ "integrity": "sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/p-map": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
+ "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "aggregate-error": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pend": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+ "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/pretty-bytes": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
+ "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/process": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+ "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6.0"
+ }
+ },
+ "node_modules/proxy-from-env": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz",
+ "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/pump": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz",
+ "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "node_modules/qs": {
+ "version": "6.14.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
+ "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/request-progress": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz",
+ "integrity": "sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "throttleit": "^1.0.0"
+ }
+ },
+ "node_modules/restore-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
+ "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/rfdc": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
+ "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/rxjs": {
+ "version": "7.8.2",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
+ "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/semver": {
+ "version": "7.7.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
+ "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/side-channel": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-list": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/slice-ansi": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz",
+ "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "astral-regex": "^2.0.0",
+ "is-fullwidth-code-point": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/sshpk": {
+ "version": "1.18.0",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz",
+ "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "asn1": "~0.2.3",
+ "assert-plus": "^1.0.0",
+ "bcrypt-pbkdf": "^1.0.0",
+ "dashdash": "^1.12.0",
+ "ecc-jsbn": "~0.1.1",
+ "getpass": "^0.1.1",
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.0.2",
+ "tweetnacl": "~0.14.0"
+ },
+ "bin": {
+ "sshpk-conv": "bin/sshpk-conv",
+ "sshpk-sign": "bin/sshpk-sign",
+ "sshpk-verify": "bin/sshpk-verify"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-final-newline": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/systeminformation": {
+ "version": "5.27.7",
+ "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.27.7.tgz",
+ "integrity": "sha512-saaqOoVEEFaux4v0K8Q7caiauRwjXC4XbD2eH60dxHXbpKxQ8kH9Rf7Jh+nryKpOUSEFxtCdBlSUx0/lO6rwRg==",
+ "dev": true,
+ "license": "MIT",
+ "os": [
+ "darwin",
+ "linux",
+ "win32",
+ "freebsd",
+ "openbsd",
+ "netbsd",
+ "sunos",
+ "android"
+ ],
+ "bin": {
+ "systeminformation": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ },
+ "funding": {
+ "type": "Buy me a coffee",
+ "url": "https://www.buymeacoffee.com/systeminfo"
+ }
+ },
+ "node_modules/throttleit": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.1.tgz",
+ "integrity": "sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tldts": {
+ "version": "6.1.86",
+ "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz",
+ "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tldts-core": "^6.1.86"
+ },
+ "bin": {
+ "tldts": "bin/cli.js"
+ }
+ },
+ "node_modules/tldts-core": {
+ "version": "6.1.86",
+ "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz",
+ "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tmp": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz",
+ "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.14"
+ }
+ },
+ "node_modules/tough-cookie": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz",
+ "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "tldts": "^6.1.32"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/tree-kill": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
+ "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "tree-kill": "cli.js"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "dev": true,
+ "license": "0BSD"
+ },
+ "node_modules/tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==",
+ "dev": true,
+ "license": "Unlicense"
+ },
+ "node_modules/type-fest": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "7.16.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
+ "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/universalify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+ "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/untildify": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz",
+ "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/verror": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==",
+ "dev": true,
+ "engines": [
+ "node >=0.6.0"
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "assert-plus": "^1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "^1.2.0"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/yauzl": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
+ "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-crc32": "~0.2.3",
+ "fd-slicer": "~1.1.0"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..61895a1
--- /dev/null
+++ b/package.json
@@ -0,0 +1,23 @@
+{
+ "name": "testing",
+ "version": "1.0.0",
+ "description": "Contains automated tests to ensure quality and reliability of all components.",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/SWEProject25/testing.git"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "bugs": {
+ "url": "https://github.com/SWEProject25/testing/issues"
+ },
+ "homepage": "https://github.com/SWEProject25/testing#readme",
+ "devDependencies": {
+ "cypress": "^15.5.0"
+ }
+}
From f636a4a9471359685fc612a05acbaf0206b0271b Mon Sep 17 00:00:00 2001
From: omar <141494327+MoMoAymn@users.noreply.github.com>
Date: Mon, 3 Nov 2025 20:47:56 +0200
Subject: [PATCH 03/19] performance test
---
signup_login.jmx | 1116 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 1116 insertions(+)
create mode 100644 signup_login.jmx
diff --git a/signup_login.jmx b/signup_login.jmx
new file mode 100644
index 0000000..0e7b82a
--- /dev/null
+++ b/signup_login.jmx
@@ -0,0 +1,1116 @@
+
+
+
+
+
+
+
+ false
+ false
+
+
+
+
+
+ Content-Type
+ application/json
+
+
+
+
+
+ api.hankers.myaddr.tools
+ https
+
+
+
+ HttpClient4
+
+
+
+ 200
+ 400
+ true
+ continue
+
+ 1
+ false
+
+
+
+
+ true
+
+
+ import java.io.*
+
+// Generate only once per thread/user
+if (vars.get("email") == null) {
+ def ts = System.currentTimeMillis().toString().substring(5)
+ def letters = ('A'..'Z') + ('a'..'z')
+ def randomName = (1..8).collect { letters[new Random().nextInt(letters.size())] }.join()
+
+ vars.put("email", "loaduser${ts}@example.com")
+ vars.put("password", "Password123!")
+ vars.put("name", randomName)
+ vars.put("birthDate", "2000-01-01")
+
+ def filePath = "D:/user_data_jmeter.csv"
+ def file = new File(filePath)
+
+ // Create file and header if missing
+ if (!file.exists() || file.length() == 0) {
+ file.text = "email,password,name,birthDate,userId\n"
+ }
+
+ // Ensure last line ends with newline
+ def content = file.text
+ if (!content.endsWith("\n")) {
+ file.append("\n")
+ }
+
+ // Append new user row safely
+ file.withWriterAppend { writer ->
+ writer.writeLine("${vars.get('email')},${vars.get('password')},${vars.get('name')},${vars.get('birthDate')},-1")
+ }
+
+ log.info("β
Added new user: ${vars.get('email')}")
+}
+
+ groovy
+
+
+
+ /api/v1.0/auth/check-email
+ true
+ POST
+ true
+ true
+
+
+
+ false
+ {
+ "email": "${email}"
+}
+ =
+
+
+
+
+
+
+
+ 200
+
+
+ Assertion.response_code
+ false
+ 16
+
+
+
+
+ /api/v1.0/auth/verification-otp
+ true
+ POST
+ true
+ true
+
+
+
+ false
+ {
+ "email": "${email}"
+}
+ =
+
+
+
+
+
+
+
+ 201
+
+
+ Assertion.response_code
+ false
+ 16
+
+
+
+
+ /api/v1.0/auth/verify-otp
+ true
+ POST
+ true
+ true
+
+
+
+ false
+ {
+
+ "otp": "123456",
+ "email": "${email}"
+}
+
+ =
+
+
+
+
+
+
+
+ 201
+
+
+ Assertion.response_code
+ false
+ 16
+
+
+
+
+ /api/v1.0/auth/register
+ true
+ POST
+ true
+ true
+
+
+
+ false
+ {
+ "name": "${name}",
+ "email": "${email}",
+ "password": "${password}",
+ "birthDate": "${birthDate}"
+}
+ =
+
+
+
+
+
+
+
+ 201
+
+
+ Assertion.response_code
+ false
+ 16
+
+
+
+
+ /api/v1.0/auth/login
+ true
+ POST
+ true
+ true
+
+
+
+ false
+ {
+ "email": "${email}",
+ "password": "${password}"
+}
+ =
+
+
+
+
+
+
+
+ 200
+
+
+ Assertion.response_code
+ false
+ 16
+
+
+
+ userId
+ $.data.user.id
+ 1
+
+
+
+ true
+
+
+ import java.io.*
+
+def email = vars.get("email")
+def userId = vars.get("userId")
+def filePath = "D:/user_data_jmeter.csv"
+
+if (email && userId && userId != "NOT_FOUND") {
+ def file = new File(filePath)
+ if (!file.exists()) {
+ log.warn("β οΈ CSV file not found: ${filePath}")
+ return
+ }
+
+ def lines = file.readLines()
+ if (lines.isEmpty()) {
+ log.warn("β οΈ CSV file is empty.")
+ return
+ }
+
+ def header = lines[0]
+ def updated = [header]
+ def found = false
+
+ for (int i = 1; i < lines.size(); i++) {
+ def cols = lines[i].split(",", -1) // keep empty columns
+ if (cols[0] == email) {
+ cols[-1] = userId.trim()
+ updated << cols.join(",")
+ found = true
+ } else {
+ updated << lines[i]
+ }
+ }
+
+ if (found) {
+ file.text = updated.join("\n") + "\n"
+ log.info("β
Updated userId=${userId} for ${email}")
+ } else {
+ log.warn("β οΈ Email not found in CSV: ${email}")
+ }
+}
+
+ groovy
+
+
+
+ false
+ true
+ true
+ false
+
+
+
+
+ /api/v1.0/auth/me
+ true
+ GET
+ true
+ false
+
+
+
+
+
+
+
+ 200
+
+
+ Assertion.response_code
+ false
+ 16
+
+
+
+
+ /api/v1.0/auth/logout
+ true
+ POST
+ true
+ false
+
+
+
+
+
+
+
+ 200
+
+
+ Assertion.response_code
+ false
+ 16
+
+
+
+
+ false
+
+ saveConfig
+
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ false
+ true
+ true
+ false
+ false
+ false
+ true
+ false
+ false
+ false
+ true
+ 0
+ true
+ true
+ true
+ true
+ true
+ true
+
+
+
+
+
+
+ false
+
+ saveConfig
+
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ false
+ true
+ true
+ false
+ false
+ false
+ true
+ false
+ false
+ false
+ true
+ 0
+ true
+ true
+ true
+ true
+ true
+ true
+
+
+
+
+
+
+ false
+
+ saveConfig
+
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ false
+ true
+ true
+ false
+ false
+ false
+ true
+ false
+ false
+ false
+ true
+ 0
+ true
+ true
+ true
+ true
+ true
+ true
+
+
+
+
+
+
+
+ true
+ false
+
+
+
+ false
+ true
+ false
+
+
+
+
+ 1
+ 1
+ true
+ continue
+
+ 1
+ false
+
+
+
+
+ D:/user_data_jmeter.csv
+
+ email,password,name,birthDate,userId
+ true
+ ,
+ false
+ false
+ true
+ shareMode.all
+
+
+
+ /api/v1.0/auth/login
+ true
+ POST
+ true
+ true
+
+
+
+ false
+ {
+ "email": "${email}",
+ "password": "${password}"
+}
+ =
+
+
+
+
+
+
+
+ 200
+
+
+ Assertion.response_code
+ false
+ 16
+
+
+
+
+ /api/v1.0/auth/me
+ true
+ GET
+ true
+ false
+
+
+
+
+
+
+
+ 200
+
+
+ Assertion.response_code
+ false
+ 16
+
+
+
+
+ /api/v1.0/auth/logout
+ true
+ POST
+ true
+ false
+
+
+
+
+
+
+
+ 200
+
+
+ Assertion.response_code
+ false
+ 16
+
+
+
+
+
+ true
+ false
+
+
+
+ false
+
+ saveConfig
+
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ false
+ true
+ true
+ false
+ false
+ false
+ true
+ false
+ false
+ false
+ true
+ 0
+ true
+ true
+ true
+ true
+ true
+ true
+
+
+
+
+
+
+ false
+
+ saveConfig
+
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ false
+ true
+ true
+ false
+ false
+ false
+ true
+ false
+ false
+ false
+ true
+ 0
+ true
+ true
+ true
+ true
+ true
+ true
+
+
+
+
+
+
+ false
+
+ saveConfig
+
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ false
+ true
+ true
+ false
+ false
+ false
+ true
+ false
+ false
+ false
+ true
+ 0
+ true
+ true
+ true
+ true
+ true
+ true
+
+
+
+
+
+
+
+ 1
+ 1
+ true
+ continue
+
+ 1
+ false
+
+
+
+
+ D:/user_data_jmeter.csv
+
+ email,password,name,birthDate,userId
+ true
+ ,
+ false
+ false
+ true
+ shareMode.all
+
+
+
+ /api/v1.0/auth/forgotPassword
+ true
+ POST
+ true
+ true
+
+
+
+ false
+ {
+ "email": "${email}",
+ "Type": "WEB"
+}
+ =
+
+
+
+
+
+
+
+ 200
+
+
+ Assertion.response_code
+ false
+ 16
+
+
+
+
+ /api/v1.0/auth/verifyResetToken
+ true
+ GET
+ true
+ true
+
+
+
+ false
+ { "userId": ${userId},
+ "token":"testToken"
+}
+ =
+
+
+
+
+
+
+
+ 200
+
+
+ Assertion.response_code
+ false
+ 16
+
+
+
+
+ /api/v1.0/auth/resetPassword
+ true
+ POST
+ true
+ true
+
+
+
+ false
+ {
+ "token":"testToken",
+ "newPassword": "NewSecurePassword12!",
+ "email": "${email}",
+ "userId": ${userId}
+}
+ =
+
+
+
+
+
+
+
+ 200
+
+
+ Assertion.response_code
+ false
+ 16
+
+
+
+
+ false
+
+ saveConfig
+
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ false
+ true
+ true
+ false
+ false
+ false
+ true
+ false
+ false
+ false
+ true
+ 0
+ true
+ true
+ true
+ true
+ true
+ true
+
+
+
+
+
+
+ false
+
+ saveConfig
+
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ false
+ true
+ true
+ false
+ false
+ false
+ true
+ false
+ false
+ false
+ true
+ 0
+ true
+ true
+ true
+ true
+ true
+ true
+
+
+
+
+
+
+ false
+
+ saveConfig
+
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ false
+ true
+ true
+ false
+ false
+ false
+ true
+ false
+ false
+ false
+ true
+ 0
+ true
+ true
+ true
+ true
+ true
+ true
+
+
+
+
+
+
+
+ 1
+ 1
+ true
+ continue
+
+ 1
+ false
+
+
+
+
+ ,
+
+ D:/user_data_jmeter.csv
+ true
+ false
+ false
+ shareMode.thread
+ true
+ email,password,name,birthDate,userId
+
+
+
+ /api/v1.0/auth/verification-otp
+ true
+ POST
+ true
+ true
+
+
+
+ false
+ {
+ "email": "${email}"
+}
+ =
+
+
+
+
+
+
+
+ 201
+
+
+ Assertion.response_code
+ false
+ 16
+
+
+
+
+ /api/v1.0/auth/resend-otp
+ true
+ POST
+ true
+ true
+
+
+
+ false
+ {
+ "email": "${email}"
+}
+ =
+
+
+
+
+
+
+ 60000
+
+
+
+
+ 201
+
+
+ Assertion.response_code
+ false
+ 16
+
+
+
+
+ false
+
+ saveConfig
+
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ false
+ true
+ true
+ false
+ false
+ false
+ true
+ false
+ false
+ false
+ true
+ 0
+ true
+ true
+ true
+ true
+ true
+ true
+
+
+
+
+
+
+ false
+
+ saveConfig
+
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ false
+ true
+ true
+ false
+ false
+ false
+ true
+ false
+ false
+ false
+ true
+ 0
+ true
+ true
+ true
+ true
+ true
+ true
+
+
+
+
+
+
+ false
+
+ saveConfig
+
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ false
+ true
+ true
+ false
+ false
+ false
+ true
+ false
+ false
+ false
+ true
+ 0
+ true
+ true
+ true
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
From 95dbedd6a5c51f39fd5f7763d0f29727b1fb053d Mon Sep 17 00:00:00 2001
From: omar <141494327+MoMoAymn@users.noreply.github.com>
Date: Mon, 3 Nov 2025 21:03:22 +0200
Subject: [PATCH 04/19] Create performance_test.zip
---
performance_test.zip | Bin 0 -> 1082706 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 performance_test.zip
diff --git a/performance_test.zip b/performance_test.zip
new file mode 100644
index 0000000000000000000000000000000000000000..9d2ea39983d432896ef003ee3caec2527b9b6144
GIT binary patch
literal 1082706
zcmbq*bF47F(&n+xdu-dbZQHhO+qP}nwryMQvAw_h?f$dLxA(irHt9^$G|x1XX)>MZ
zR9*@g1R3C8?YKu*>%Rv7hadpp1K685n%X(q7}y$_=sBA>In%kgLjwSU{A(c5V(}U)Pu%*0CPSIs%@Rx=5|i
zaf>0QUZLiA8j9qAQJPhaUu-#_IB-#(Dh8KSY0)yFHI=ps7g4PA&kuR3$0;KH(k+)X^bYLq>
zq)G4jm83I8d+_t;@(g0YtqU{Ci_0j5{1`EOs?b+QBbUPBeryKF>&;uaj~Gav9SGjhWsxh{#UQ@F>^Xl2>_DBkemW?>?p-!XRzHQE5r}c3RDDxXd!KL>ILhC)pCT{
zR{}s%2lU7U@5LLWXg%p_ZLq)YFCdZ1uReX5O(9@WES}`GcQygl{-~V_?ZKamwW7l>
z+SPVVvL3DR2(1kb&n?nYeFMsPJx{X1>XqGkP3s?~CZg!s2#NXA3c8^PU0QRwiMx7*
z3&>UfJKL)d(`|BsyfOB`0Wr`J_M79CK2h?MJ9#vu|Fxw|EAW#}w-xu)O
znXKaVS#5qZdvLV%Gv=tFZo)!Lnpp@`tUzBAUZ
z_hKH^{ypYu^9D{vsU-AEMrly(>Cxs-3`{#Dy$H<&3C9Rj1v#6Ms5oR8tRjb9s#bjx
z0uoO-ZgnAE;xdRP1|uSx%H_FSVn(|xa3!$?Md;zAD2*v4txl*MACFd4aUOm}fTc`?
zhZR+CFCd@)scoXp6EGBxstIlZmcn31}eIWJz#Me4+9Yvd)SnRQOgeSSB{Q@3yD9ysD;3Nv1Vl
zwZffTWDo?!gphjrAtCkhKU^e3e#~lx-8-X)@m*@Zd!7M(1OW5-rK@;)`$%(sCZ)4c3WX!uuWSs--K33v
zyYrK4?Jfk@))5+bpLBhpMU-Rzv%47pItIlKao}$=g#R}YK{U)L_S!Qo1Y8F&6?}Qn
z=(pxB@6qq~YVVgbXn-9PI7%wq!oRNY0>uaGK_wYQ_-?R~#y*4UJtRJ@-`-zK`?3_>;pKp&Y4Z!7Z;orZsG8;PQt0D+I
zL~-*lUS0y_I-HG_m#aXF_SWpk1g-n!rdR=Rv~8W2bO<5DX!hkGKWHQxlKW!Q>j8G>
zsQz;2eTL)X8Yhcks0zw}$}QMY!a;{LgWQ1H{7660hwgVPdsz5n03!g6RTo`R9P|3I
z4wIFMEO_mDPz`rcd_V0lB@s-plg0`GN0oow_X)lAS%oYL)}lC?Lx|_eK;8<01g*n*
zgy(v%^Jj+~(kN6pVFo#6*z}>%Y=$%@{gmK76h30N7PQyH>gEbz)H2$1)PRdRnz8ay>${|
z3SodlT?_;t{T~QDX$x^t=87@tkAB(#{yfpQBGnMG7W7BaJPp-1byQc&$C_5m2V&!Y
z#*=*nV+0jy1K>T1p??fMR0%jJ;@){RKw5--8MPC)$~*+rg^QIF=a)VYtYVZRmQ?9=
z$d+CS;muvKvYsw#a7#e
zNi!&;7I=bJh;$dqEYpE0G7HokPEI?hL_xADL6;7vs%i~SccE^O57LlSAfv%APDbz(
zrp(>>UR_5kT9}`_s}x3t3Bw>?3xpa0+A*{pXNCzzn)G7?6I+@Syo6;8X-uwbCQ_1E
zAfF14aP|%+6&O7-&*lzdXpVm?0~E6K1VMHb0&lI0$Ci$UTFd~6m`{jVcSQD4;Km0*
zTCxZYRw7{JsnmC7#`>9rnTcrNlLTKhjART57bPG}JtBZpTK3T&tq>JGXJ8ZANk-cz
zw2$fg_20jVqKfm^OB8%kWj(Z-s3k?LByX`7gPe1CuMRl91oySoCWxNg4p
z>SMBQ!}9Y!vsc;fY)oQY6@M;Jrj&mb=Q;mvqNK-2R`v->MIEGFjc*CARh5h-sgS08
z3NTF0L%@<^<7Wh&Q3bk9Rv~eP5s#
zyN1_dIf2u#YYjpmBUa+aXJ$pSoScJ$-GL}iq
z5jyw^PwuY(4y3Xj@Gkir0hkpw2O!2(VZN4Atw^JrMiJ(XTTRx7mxefC_U-on)+E`x
zheDQ55|I+7)ZmW^N$DliB$&vu!SKpNPpWSgVvT0zuR%>cRuWCdr6#}=fioQ-@5Xof
zDAAJLAA_aOl1!vz=-@DRCm)+8&2l%k5_KwLfB#A`1!ptd2#*kEQqV4T>~9sciRk`v
z0;Ja>zSc*}pV>c4wq|^45HZUk+S(rhZ578BiF7}CWUh+j7U!mk0SPEc)vow9?1GwN
zb7~LyRU1c5NC490%T~izDOpyPBI>1P>*A^QKbjcxh#K@#~Vj
zfY4K41+}3Tpge02+1?dl~NJd&a*85o_sit*d%kx)>k6EXL+U|Ue9#UY9Qn<
z5SC^?wA;MC{rDsZG%Y1aXaQI54UT?KIeP2ZW?zBTA_}Ewa_J&~jwJ3snt3UjyifiU
z;J6vrn&Y@srcD@v1W3HBev$Ef!47l0Dben0dLP+z=0G7CXCE0WLuFVim|m1+x02k@
zfH9F)_(;dGhpLc2K%PROB1GEwsj1;OLGvN6aFEM_$0|*Act;2Dk{G-sK>+QYm7lZT
zZI(m|j=b)o<(os&-y{fz*>KJJP@1*b7ss?G)brS?r?BV^u^I`9Hy?(gAOjF8HkvLF
zsTpFiWS-1kid{j)v(;~#2+5?eEO^?}o)ClI0-MeSPB8cfZkyQqJ6vb|({;=CbwSpu
z8QRNNrE(|MHm_DsG-pe!r_;vnzV`3K@yW@b+f7{?2KG^#wmQ|N>m|>_N;Q^?j~3-L
zthlzOABpGIwT{lVx`8*}#@(#Bs~gX@4kxmv_oLeTQ!28pRpWcw9aqXx{a;4xy>5x`
zt=gYm#;Hs%9!J-v48=UFp6k-ey81ji8#uQc%YctHTdumesEn1BR6V{t{~jDS+uSd-=i?ghwud|^maE5inVu|+p^sCaS7uzlXj#_Vqmwra
zmfoG4=+*HI*Z@uy<|01#covP+Or({ooLd?pg~@@(bI(?<3plA)#cSaUJ)Mk~52)qo
z8%Ngp{-(ZWiCSKnHJ1tgZ-K5Ws_r6Lw>6t(vGS1xmp;xN
zsm19_KG?j~);1a!R@k2I_19gsHayr*60Qsy9U+;X)R?sUNAvxj=B_vNwYW{|dbSf$`1R0I
z8o7_5Om172WZij>yluBzveEA_7sr~{(YVPcSzXmU$RggUY6n>qp4e)gg+-)9zC!1@^jAuM=utCsoIR}5zT|HZpP%Bp1CA+duY!9)6-gg
z`&2)er4pI;tXuA9j@lm;f4Xlm;l4}S7VUCpP?h)X8?jW(@{ZUn_OP6D?vHj|&qjOh
zkD0wpZ%ut|wPkpd9gJ*0lFm+t(~4L1nQ>EDv{L%rzl)y($Kobd9xL~J7Gde9tegCxKeYmbTcd-qbykB2i=u^=>
zJI+L)8p}J>}7B(Q%>pCg+Zz8W~=z7@1?Uzpa_UJ=tULEbzn-u?2qZ@(JXM6
zMTx894^X9>$qr@;>WYpD%yau+ti>^7`(M(Y?C4!9%;uR_Ul~k`rk>W$tJ+k@@1gA6
z@dspC&NZ^psByHhoSz;h(2}spr;DE%U9T-SqeqJi=$6ivu$9k~>7G}u+gVMwOOqZK
zr44RdSD_ZOX*=8JtcX@inXRDp9
ztm!l#1E#wx2IWk3)E;d~I288BRT*u(6m`Nr+1^iCIX>4)RkdJUZ3$c+m>5|P#l@_j
zI~uP)1D=khy&K;4T9ck2fdf~fSkYKDSE=4ROMH2$Yi^yMTw1)>D_9;J{vj??tlwR5
zWq-kcdcK);Z8o2~T3E4po_6Q-c3C*gF&1kVYE)JlO`A1aau#n}S0+9buDB;Ed0f(Z
zkl1av-C)d)r(^ad^U~v1r9E|2yK2&b8z}mE
z|D3XsHI2-ZyLq-Xk+mJb)E&=MuVP4@R5oX;ZpxkI8SOE(G#)pTcHu;agg)x0=)ie@
zY#P55yo~wCJXl)p?fFXIazS^s=q+dO9zNPWxB_>MQUjzm`LX8QMEUTc*Zt$F5cO$Z
zd7-C#EY`Shzny1O2PVbQE+4^PIy7Tr=9)-c>X?}NYi-=y?YvK{3}ZKgy^y(=$26a*
zR<&8grN#c#Qf{RzU8rO#*7W35-p=f7ZMvV+ep78(b-l*TiY85+9?65%ESPdH@rz}e
z&r#j!XP%Va*E;jcW@lRRu<(&KO*ZfKXvhW)bg9%#ysSJ=Qmmzk*8DQ`YKzs-A1mwri0=hZxZA?f3NiBDr)2_&Mp!zebwtWfXJ?-*
zP#II&jFnx{R_w%Y*YbPbmY~kS-fPHoyW_a#OwZjhGkH{!w$#KM0vM}`HNul?%vI+V
z$CmC-eArPV6N{V0ogAOeZI47avO~+t3qkWN1j_lg^r6ccj-QB+4gy@=K?2ea$9)Ao
z9c*AwY%-)Ia+NA}kMYM<{Hz{)a1+&9(+GPfCuM2G3^NE8j+$c-A6OzZ+*ywa5uuM<%?Di
zM!2SG=(dLm?f#Ucb^Yg3yAP?uB5u=@Hpo&3LoI~be5GMv9H(;VFU
zZE15z4~8r~Xfok}6*|WlH~L@~%`kUIl9hiJf*7XlSQQA>35l+0YsjNUNX9+L!t_Ae
zT_lW}c=U!dx-5^COoE9!RIV5oQ;@pbAX|$?8anjV>%?nrOsI4!?=6~35mho)Xbd*i
z(WD@pJ5i%83aW82w_PTc-9DKiqR`TY@hSMa4VRrAu@7}1w2;X5ZWS1@#ATfvSa5cO
zL5#YMaU^|sPNa)Qx(uD6b7S5_%U#e=GK(AvXpNB!0d}G
zF>i@YM!^}VnR=~+fNK=Yfr`>67=h2~R9KknUyOKnct8LMGZ
zcjDF)h3mwMJJ{G8qYr{k>90n`H?cmSRf%G#&J){IZK*{EheB>&x(~!J6#~I{yzAt7
zJ$$&L$P%D!wEe$Y?<`X1O)oG0hIa+w>2aPh^Al)-R3rS(qyc+
zJRw~#kVA>IhBphD7Q*gA0@5PkegzOzD!J4&xDxe!7{#Kq_hNF@F}Aqu2!rqoEoPee
zA7U})(0v_MLN~gHPBJ|Ni7Grl4B={Dn1{J#xn8qG6f4R1=3_#ts(NlCL<5J1MO8ss
zip6GPF;42a_&-q?t)dd+90X+_6KxgCCF#TO-p$R51!RvqBVV_w&&}FaxsoTBufg--
zOi|aQa7j$qP>FwqfuhtBN6Nsn)K^1#S
zzrde6Kmz@&DiuaOosQhz4I|16@G1&h@b|_ea!93``13lD*wTV0T0scai<*3a)+*Oc
zj5VWYhVu@n4Cn2CXxRP`*Yj18oJ&ZHbsCp4re_H;8Ur+RjYy^2ljy$j6c%7(chNM)
zW?RfUxNNO_^LY9{j`P%UAZQnMP_LsgnMLPwpUraEbA38v1~t4nlf)?_UvZ?(6ng67ZKQQE
z{t2af`6b39{-jvB~-ZszY?lB2$Pdh+_x&?gh<Kp6baVkXxgL}hRR;|A|0Y#8AA3Ayg?&eZ)vIARh=>%r_saJCMVIZ|>X!lqs5AX>!~#
z#$rS{O5`{q8Hq!QkVA(L@G-qVxVa?`T;Zev>(L(Sg5XH_P(9NAWUed-gkyV^VRyl@
zWcw1k$w`h-&e>*>fYEn4w!m*#VM5EgF9^1c3ok*S
zuG_lAo`)-x9$3tYjHZj;r3RE@U_&AiNfW)*T6E*A{jV}4p>-LMp@LOf9xtid>RPXSaj2F?d{
zK2Q`!9XTP7rWGh2D2So#BybF)_W3e#TWA!*)Lr5E;~uqSL_%-8clyMkZ6j{vv)MWk
zwRFHJggf-dy;R5Kc^kN~>Mpu#_L2)5l7?0^XyqGppCZds2+S9<{j#(-{yKQh%AZpZ
zESFDLQEmKUP7z=$H=a$rqI-n_NH>%}I0<}=D19Dhk$s-p-A3L|zaJX2fHy&uFwYtO
z9Ryf+UOZ~$6J>myJZ9sVAl%1OB55(XM79wQ&d&6_U5j;Zt{{9<_z0SWL81uWT>;mp}k->
z0W3@-rZ#-7dI{oO>05A2Jm?4sPB2e=NN9-(K#YBvViDqaDY5%+@yI2U$O3bNQE>wH
z4kvwrAwKq9IE>(j7gUB$q_X4nI3U|e(bWCLI}iZXg9Z7)sW2|MUxZ{kQ^FV^>R4ID
zAO^X)I|5ZsK=DQGtCo20Ov5&+l<7XOJ&{-jNqvk>zeGrXEph6&Ahm;M&Prbo=-+$v
z4M`#%p?S1aYwYX?#)jb2MA7uAUbtmI%{l+at~Hnk@6qr*ut(zz_$)C
zL}w{OeF#NxN(<6Ve2n}D(?Ss}y+c@GhFW{bPk>r?I)!MeKbz9pje$hDH<9#k)|626
zaDV?H9a0!T7?5S8umS$VOv$PI{DB3W)86XtxfEET^K$g8Sl9VY5cY7M(qL;^;Ei74
zI+yf7%79bD1|aR=Og}I;K&Fu*4^y#+Q`OuQQYyHXhqU$L%P>H1*`@6l^6T1vg=&-{
z&h8_o2c7b^aX2YmRA1o=6br=4kJS_gy|>t9x(B-n-Xm*&ODbcIVP(E(L_Q8)_Xw{<
z%`%5P*(B1m&$uJ$I~d3fJ#35pkoxWHbI5Xyyl+g)nLOscPJ7k)(EL`fs>Q
z+R3DBrnz%Xbe9^2FH}eG2U(o~)`+f#i&wCLmW1M$d&>)q8<)D60Wz!V2bN`7k0${#
zv>QmS%@;t9^2=u-^=zSqFGlYd=*J9nwzUq($J{qtB~z{UcNiiBj$C>Ber3zcLPd=Y
zGY(K9FlIqw{tBD6;Z}cZX%Ojz&v6z(vc(Oe-{ehs+fZbY=7z79Zmq%B@O{MgIU91p;-k26-Fuz?Q>`~s1ywX2eJ~n>PxJy
z2pyqB-Bc08ria=OU)K-KPKGxF0!=~|T|v4cDv9hE6XW
zgq8s0C>{fVm$-+}t}tXq7=m{BA`_ZxrFL7#cylL!T?DWq$nGWsXBeKusmK1(4z~UC
zOFk?M2Y%KgFI4aImE*Cn;;!^`fVv+Z4D!~_-Dq;kFHlLN!(e1bL3p(H&6JyJQ$9U{
zMi_CqRkt2&&!o56L5=M@3a(*X0zW2jy4`F7X-3{lOL2pL*P$e$EbM-24iqw~?Mj-T
z&WrrWfb5(}t>Oy+@#gOjH?9+Nz>d15b0zswiw#YNH%$RMx>9DApAN`s3WO6VJoO!7
z?2nb&Emmm9Lo^RmJPo4y46n`;svoQ)(E!??Y!>j2C@lyTuG}vq4*3F}FAb0Y>=-*&
zcka@#Y$^=Z>>ifG0PSh5OZ#0MJB_!Tp-lz42@0I;f
zZ5=A}^hKlyxrPVs`vAHzuYFuc$ynh4_XdwO*RbPl4-zQQ8xIkFwxO-_r<$%6oRA{+z=y#qiUD(opc&=`;dh6Pa?u7N_F
zu?rY>%ir%Owves$pu6ve7_b8eNqLg*Ok_Q)SEzx*sx>pH^z-cT`T2RVOmimo@#7%2
zHFNeepT&-~s_(ZwNaet|UQ=2Fc;Qo02j{MP5YiehQKepnSY!>LldKZIYOPv=mw~og-EJcth}PM{)xT!@$WAm_SpLZ5}0w;
zcwE?mQ!q-yPVd$dSA5F2N&TVrRw0%_Q{L0U+-=s+dAElKVD$W)U)%2UO952`vE_C>
zr=g=IK|o79@2eIEwmWqvzK08)Scsr|z61o@kQsF^G3aUV@EYltn)}wcdS+DL$6EX6
zK_~PB7I`LMEFYenLi|Dxl6kxV;&BP8D9G#-5*FHE```PQn_;Zo#keaxAy*>vhpmo3
zHnkKVzK-FI&_7)BYpV%a1JyBXPD28fYe_<&NPQzOK{OlG|ez$0Y|6CQ4s
zY^W|3j|>IgP0=LjlJO(aZX-zrk58x_UBH7%ECX%QPHCIV
z_4th#?SfYzc&O9q@fR7ucAu!m9l7e4?3Q~KUK$N#X@@#kkYry|UTlZHziag36N4Jx
zQqV`CluD^`)N`z45-KzP$Ssg_guhi}$F$*QvtdEWe*C+OVW+bDC{?&!wYR@oU(b#`
z?TyjElz&mTb4XAtyKX5_7{;*bSla;{4~noDZ8V5-5NBmw_5$K%nK(N3wHXIOk=%Vj
zVKKsp<*-LVg8&32m`EP6mZ7ngXR1G9(voOBtcMLM&GMrbz~T)naYcgFIJuu^e*`ut
zTzn)!6=m`LGccie67v4c@LT4MFUS$s-7ItO;)aOHhToK{`fE>!%u@BH7)_?ehtX1F6Jr70BfAOVTivo@X4OU;2LHrfJ=f!H?
z%8&oPcK*$J(9by}l81F^%T(P_|K^SM?kk$*-U-Zq@9L0*c*F7_2V5Q(?lYlY68F#~
zsLEwogmDSm&v?tCt9`Q>;vj`&O481h>PCyDZZGITJar{Ij-hY2*F{=vUKvN
zsu4hWY0)X}thzb&X|;42Q+!|M=1|dK;LC!|skHe#mUdfZ&AJ{sWnNeV+bbP^6=@h$
z9n&$5r*r$Pc@g&ke=@JpJC^Gy%Zn2-nz0@`yG$E7k$Zl&m2lM}Vegqfbv}#2cJ^9q
zq(ut6?_HdQ8B%E#{B@>w8aDmb;DD$45nP?PX>H_QAFFLyjeR=YoPMR-_FUJiE!j22
zk8wNh7EG)7kS*{M^c%bd|KRFb4A>?c5XiD!_?2HeFPRnZQ~>O*U1~CQ!pG*k#wc`J
zWyU$&k0yMrc#RNs
z1yWAdxssvI#QQ4(1Gj3Hpjexy_Z1)TIO*V#JOAXH!bfY7kc)kOa{+Tj6_Ww%I|OM@
z|E&+2N@8WT`?pUQdE6oRyTj9LwrQZ7ov?zN&AiP-#SU2VCSqC{AZtXim{!Qvo#79R
zjMd-n(JCQD8aYgND(yX6nzf=`b67Dil3&{A
z3x+m~Mnez9;H($)KV?=DS2M7ZXKt5=Q}Y)gx&>YF-R6{C*1U-XTmL+%#pC)>$yDt^
z+C1!J9^V>#>S@b^u4E?O7!usx)YszH0IqaTi7Ia8$pz_TD%D~->58sd+ZDu}LuY=`1`8&VL}z
ze~y@M8~b$me55~@A%-YjW_Pi3^9rn`{{XVKapsp>u2l8bA;J{PcfHQ#rOKh@`6k@=
zdX;DL%;^yK_K_*2WUGSr>F7?KKw+o*+;s6vP*dDHw=J0sgA7h7P+lbxXc*V%dCk;&
zL?mCky5g0)nKV>UEaP$5!LnV^Rnnl-jNIgmVMP;Ayry9y{*-jEox@P|pH>c34iPAp
zyfklEO@*_G;mo>vEOKlGUl~f&k2p!(d`K>#?oZZ;Y7`XkR9+<0dvchao6TeS9&dfD
zLvv;7sx4bteH*9cda$2O>y@_H-p(NNXk%SAser4+fq;niy9TP`D8;33afZ(soY;
z(#YrN5%Wp(~MI@lo;IyHT38?U|2IpMcL5x0zo$AfO_4v}C~k(63PJ)-KZEQ(}L
z2kX@^E(X0H=X82zQUNVj@!V=&${A!J>UBzHw)0jGRzB3tq||k`Fb#QPzDCP|o040C
zT{JZ(4TJH}4ck^1L)>oY(k?#g@9|>L5EvWE&yx~aJc~;09DS8|V$aradpJBh)EU?D
zl~mBV!k&^>TO3loH=QlHGQD<^iMFbA;#{*eGH3N1u4qS?UFysg=$Ks#&WVguz>HrT_SV}TxVZXm2{>jG
zu+h^;)A@iO+f7gpeWHcYPFY;SHN-!l@Ey1+K)9qyG8FOi(B=WN@nuc
z5ZGRvE0QTxZTj$-3kd}+>-S*dygY{~EbU4!(&WlzM2d!8@vE>nRV*%6PzsGbKR$2w
z{DwD2du;7jFTh?ihkr>c@C=6Dpe0Cz7|(8EQYR7vZ!X;iyQZZSi$51FN*uc$7HNF;
zvCaJ#h+iz+pAcS%%XB~(BUThJ)mu{e7&Wgj-l
zc6#zS)~3zXWU8y-g#d^fi6$`E)#Z-m3~MN6O}^0(K@sLBTC
zvPOq&;V5AO%7IcDa4P!HQM`3eMQUdvS$BRa@Pl6i>q6>U+yhB{)ZpM4qQ_>MtyV(M+r^c}IcB*Iy%XsNKjq9oWy
zExgW_!!*#H{VOlOZuDUmm~fNxmxP17#Mca7qTTE*L;R{J3C*?O3{mAKe;vVMR_1lf
zvi#WNHKkfIF3
z6gNbAHK6WqF!%{MA6~g38X`5^F=(>w1DYw0GG>4^K!`DY;^;(ZRh0q~3jyJ1F8`Y_
z@bjt+F;P{%(gSE^>Z^$`so3e
zVhO1*IHg38UWPjTtyEHRy-%mh`#tpebenl@dfnUO-t&U68$2gv&MU;<{ur2zbG_a3
zd6897`P=9H{vrlkGa^$sJ9E%ib*K?_RB;LZ9#;97tRi@VJEbJ2LRQ-&e3F9dphKav
z>+y>WIVY9t+4uXh^7(c0-Sv8FYk9yI`7~aYHm(01ofG1{>$k#Pn}k%?z4zPnHYs~K
zjrx1UX~LoPRSB9Dm3UI3=Sb7om8u?j>usmKe}=cl&~tx>GdU98U0yY^&p$yTmraD?
zSDAil?LN(}Qt?%$e!cGWeav=w-|ZQZBHOVWHj<=9NuhWvlt|2{3o5dl=kjcyp9@3cc9A)9XrEk^{t{DRVMI(E7U>4Rdvj)*z1Unn%yA}8pp3BV*Razhj0V%iYk<9$%UUH>;P(d?ax+=8wzf$hsjM!1Ie-%}W^)dr-s0Tat7qc3Z{M
zVKhhA(^J;{^aJofsg!(NAmQi|`J^bq(Uc0~9)We{Im`SS3&hpwUcbl^5y>mJPn1kN
zKdx7aFfBZq#e7q=%&BHo2CM;4hV(LFz77YhdOvpEkxe@^5I$mszE}#A#>a{T@oSj9
z*Li)Ii9RJHbum|cibYMv54Ev=h?C{0Tso@<&IgA$y$>b83I3{`82BB;7i-`FNuZuB
z0ym6a9sC+C~EpZaaD|gBB>Zc!spiPqXZE#
z_=(9P;*u#ili4+VksKP~KyI}d5SLzJhKH(4$53gsGnkCpc??FKQh<#o<(AotZN@GA
zq*-F5rK%OrR2kK4YAl6nDxKt*s+AR55#jD@%QQm5*c9rtb-No9#rMm`X;3?-qAW>;wD`v{u>kQkl9H&l
zT&0O~#7U(b6GVk}DZw;(i_|oXwYS7hVC-8Bot%Rz2MF_cij2&6L=qCJ$86@oxF1jhw4(&9Yv5D(iTka+t&H~(7`n#y2<
znW&g(DT!qawJBOC+M@kV{C
zD?XW)#5cBf+>gOpE7z~rMDms~{%AR=5jtaDN-timK;+U-WMQ2j*Mu{O5CJx|;cK@~
zEC`ENVvioNeI&KvXnRvig7gY;%UVuQhP-X>+1P9BrEnTuIs0W9Ov3GP1^hip7F%sSZK-9h$e>&_w5y*F#zpMBlynT1Xin_HiHB^RleKbNE;h
zSXB$14`&Q+;Y3q|rx`5*Weu$Y`;(D2upA_AUI$b|0?0`>26gwH%{fc7-@SMUYD*a#
z{jC}#Nr@nrDrv~4HaHVOpek)p@rI?$hnmiUJ??(5Q4dVH`h%G7v&x?qD&-DOq2_E8
zy|P%?Uug%~VUy}qtethJ&iP$G&NPgvg-yHd%tBajtI-vVlm@DSPTTEs^p99HJ4HE1
zVQejAT7f2Ia=a^9*Z8^AL=$I&_F}$Af&tuQ
zW;7IGU6FWWo+#V8v3s>R?A^F5?TvOdh{JRy4zCI5#&Kr{NQNrP+PrUnX|!~t#CISk
zLdFOBvs9SADT!cN;xVrn(Q_RT`ta2OO4!A4)Ba1?MOwJtbMSEHwC)g|p^`k3MQzUo
zu#O!Z><`B@!&z=+;&diC6i8A}s-XGsZsrYmpanH@E>vUEv
zY7nb;$!gt-Uwu#h1bi#UBFE<8adW{~CuORSkWBI%Cz}tO4s>r8
zpP{>|V~vyS)R&o6u=QLUuIbM0J_~gpkFpNFy0D|xGCekX>%!XEnvl1%
zlTvCIB?Y-HdU#*4OTTs(IN;^xWSd3hVhJ318ca(P#ZY(WL@CRI_1tS#XY*elGcplvXFu06NC*BuY%O)emRtlWa;^dO~uRS2aS#t$jw14~nQQ%f4B)AmGrZW&WDelg~M
zz6D^Erw9W4=UV`b+*%w^5n#w_=5Q2AvoHWi!~Q(F)cX?_WNrN8ZB~)x-cwtY`0Yro
z@)VEYzr}zCz1*{
z%N@##aN8dAemS5Ao7pfkz^iq=%eIT32~g{bZbPm3$$?EnaI8GW<=An=CQ0a7<4_%k
zPuk-Np{PQ|v2uS)Cl&S#hwqhVu>SebqUVW
zgMXL<*e{0KERg;L`8(p%_0ip=+Vl1FkWiXR(h>)RWbr>;Nb~71M+D{y7{A+P_rH1LliD@w
zZ$WNQwGZFy1gdDupAHEY1qVxf7G%{f)V+Wxk~&8I-Yel+k|_v>D8k9yo^On02J4iu
z1)K>qm(a3%lagiSgsK%6Dwkj1AM)o}WcqDGbIgBp1na#bP>bBl<&D-EXujP?`D7qX
z#%m6|D8p$(k!dhi$i&K8<#w%r%+7I#=b_vqa-WCMYe_xYYXu~1S!Rp3wEg;hU<)ML
z5P2?>{dvGf@#=2_zQIC3Eca9Y6p=_N2#M6xx$TSo2ER3rOL36yEd8PTkA61wuZSl9
z0STf&|114a{onNS|5Rg!)-ERhm4yBWR-;Gb%I=UI;kTRW@9+N7MY9hzg079lN)iwa
zjSuaPVAuEQulj
zi5V1apwLs9iH76wNWcuY#07jpXrziCIlh=P#tFR{D~yAsh-5ef#5Cf^x^b>gc=Lr&
zycyEFs0acw)U0?Uv4ZGK{)8OHms!GP!lTWBQDO9^J}rwBw-I;RLzWQ3ym32?mF+~b
zxjrNvkdWk0y*xL-foDJcZ>X<6-E;`E{$xoaIa~g;tN$v3c12pd&QfzUXvGRl)J=(W
z0ATEQJYL~(7S0m`;pBJ9vSbJxnPGf-O+i2FovK8Yx6qQGrmr8@(rqXKF}-60I5lCR
z^y_d?gV(7GaJuO9Ft>mr$rm;3!~G_8w$bT?JM4*beIXdQSYb_Xndk&7QQ^Pp1w7#2
zWTR|XX2&|1+Y4~7h0j-9sH+8%Vs;CZ*^
zn%u!ag>Olfn%bJz-GZmL?cd9yfG|H#*)z>w4PtCR(iwwkN9pd+IT_llc-
z14NzLTINe)EGZl4-;hycm*s4#WF@_!K+RZfLtVTl>Eq&cpi3o~f`f?rwGRI~k#Qn2
z06MZ~{RssEAq%`uaZr8IpQND4HcBo93NCvFwSYBvK}@|~eZ_UCuWx@bTt6KYThW>@
z)9g{S;a(Ho)ftLIoO_XXjlcGurP
zx9Arb7COa~533lmY99gp_vuYO#h7J?+U
zK1_1l8AFYzq#kA{dBLxUe4GmPcrCisTF|4N;-nTOk4!0YC!pdtBpO~~Zb|L3#;%h{
zZ|{fseQf0`|4$ZL3@Mq~j4zZ3(UVA^IQpI7isgCMbUoCla
z=k5YsLH+K{>uX0G{&jojWz3_XP!(&}OjeR>+itgMN&s&>sJff$)?d$|RcueAeDM^R
zeRIB@p2$^+WjeUpP28M5?OnGpI^eU0k;~nPp4TQpu_35F?{Z$<8~8vfPYqudT{v1v
z_>@m58qc-ZUj%NJo1%xihl_l(uvQt`ZCPaJgppsQNFEeFC0R%w|1WEo&S##{m%RI?
zo%v5(Hl(_t^982}<#Ll}+2_`I7cF?X&3w8$@|2t|*(tX}{03VspR#%}S-#uGq
z{L|~M1n%d6OAf5E71uRy&tB$E!@28}C)1isRcNng{Qa~iZGL#~f@5Hdwwy;tx^*j~
zoiD^}o_WKz8MmD)*(zQuH7Ri1Kd$$xLoP2okGgGo>rQm%dG%{Pbx%&av~M1~Emb=f
zIRQG!@@1sDnQ>}qtFKzPd?i45TY_YcHHrL=L=Qk&S}sbfqn)k&f2*z>}dZWK8j
z8swDiAa>n)DsD`_w4O<)p2n2&rx>J)%`Gw<
z#d(WM@5U{C{y5)eTU6dlN*Kpks=7qXCS3QcR%OTcIOSH1R)GM5wSWXc@shom9I9bR
z^wx!NMNI$%fXN@#|yZ9UEJlP>5NaZis{ylP;77`y}F0Ip5w(oIH(__`G4SbrO^G
zAg1xGBMX>3e>UjkIRaZgsV7GPU6Z;nlA>F@8-|m|!qYj`zO|5*sK?pj7Wy3uIr(ju
zA)`t9B{ZNKFds6;*|bW&N1$9763z`5Ef7j;sfhJQ-XS~`-|pAkpF5~*$=V_E5cW)u
z_$Njr!V!b?bB@Y2{zGfkaNjApHS$niUtdq};#d0?yrmMJvKZ_cPW^?3UU2^5tzC@{tQarkbIm7SVS^3`|o*vx!MNcPDZTm)wH9HO^9vY_q^`Ane$l-}Tqo
zIySfOsB=rMLLRt38U2&y(d0zxhQ2wis?3$ShD6UF{K_Ku9bc%1#u(%fQq8~!V`<1S
zTnI8&VC@|PGC)CY3aqe|3qVUYP8mcgh_>EGZxoiS$*AzJC0Pg{(%x9>}``=;+(
zmfKS%*Ui}h8E6w=P<*R3dGeq@DTQg64!uD~>f=2F6h~G;;pGl_6bRC;dZR`Bw`S5k
zV?s8Ek0c&5Moq)eSPD;f+&x%l;fdYwbLOMSdzwks-k&A!Xd#OU>nl1e94tURyV}%9
zY+*+RdMS{ziJlT&wVr3Fas^4I@hq4p{qjW--Tl$ciQwSBXFAnkGRgg*^oI+BY%$7$IzWpt(G^jY|GeZdqlAF~^E5YVr9BZh1CXOXoPHApfnm8DWw}%B*Ofon|2!6~d6Q-$dD9RXRd_}ow{jC_f=SUG&!hH!k052+3HcOIWL8Arp
zoG{T6wF2?5B6z+6{c8d|6K;9NBC|cm1RN{e1Z29h_LMU;&J`Sirb3bfs;k;UVopai97}*hQkz8Wy@CRHG47(|>Ji0@zAy0~I
z4*`Nu1u1y33dFem{57Qj-XhF3zehlLQE+&w+m;f|&|~hoUU<{vz}}}=
z5Apr^J`gWoWz_5UR9lc+8W6!Oyeu7G_=H&)LQ+6Gl1^`_$@$l8Zc2s!m}58_)W2!?;9E~UiS_DD;?h|;7Zod
z3B{og6FWNi;r0Gkqu<-j+rD;o4;LS{_LF}IF~9dFpN|uqv*(|lr75!c5Qc?ME^h>M
zJNVeR1PpyHcW^IuG1`%X{p%x--`BRZ!@v7)<={beUi~`*S4VirK{dE|_)l_|hv)mp
z`>%L4SO9q2gg}gOhu>Rxa6~h}Z?|`ieC#7LIB>Fba|cGaFP^>@=zX_(PnU=L-F^Xv
z9!|XM12%>F1~dNi{gX?0M*;=tF2DqD?>i!Mg(zY@K}P*xk(@LYNXehYAyBqF@AqL@
z;9v0$)TO#){fH=<)$a6}3*7G{-$tl`4uLXWL~y6b;c!Ov%MJ)82+Z*aZ#5)l!1%Gi
zcAyFVs=@U{IU^|`NcXRrA-Y%Gn()&q8lM!ymb^10T6}*S|
zd3bs0@%`@deOdQhcK6A5nRD~}oC~_Z3DQ2N8QgV8H5h(3-b92T1(jul^7@PfN*5cHlH1i+i(PB!1)oX=
zEpX&fPJkJ);r+uDUFdHDxLV=^>qF`Gr>DTis=0v{n7An-hAB$r
z0(O0fBqq4LBrHVwu6McU{z!)OA-Vpa+EMvn@&0rp#f{2P6|iJzfCKvQTpK@cj?(;K
z)*1nkYtnsK|6SvCiWK;L5{8g4qzif^NA6K5ff#7)fqW1Jzz&EcXiYEC-1e%Da%D=|
zZ+l*BMuodk_IiVY$_@Po78re@44UHL`POhKxH&5Ev|f;m=<<1{R6g1K^8o-@0Yw3S
zkk>2btr=DKb2ItnztF@$W>!5zCo?7ER`=4GA1`wXXX<;#XX5Rx<)t2Bso^5L;VM~tF*tPR%p
z+z)V7NcSrpOG_y$6iNUrCsC$oa>mq+yZS9i&=X#q*Ii^!DQuIFi{O2)KKI+|C*jLc
zheD&=F+3?iXt)5OIDm@8X)?|H$r7T3O%OsRag?&s^|RE0YnQ0i8>qzQjmVeD-kD2{
zqeY>0Z3Tl@9S;@Y#&8dO^Q)rE_T@FuW-Ql(ND-(RiK_*!4Zcu@-iICEy88*;wa9qz
z*$U}Z3v%1vqX~MAlEWGai*x01(56I=5rzXCB7Bt8ti@JEJot)_F3A)0jVscHxBWR9
z37U+EOCAuhju0vv2;CQP;}i2Iqd%DuVBVUB11C&Ep$kLWbILHexcckzF{HUIciVMG
zpdj84@Zd5Z7|;sW^A_lVGZ3_3mve+KKA=bh7ps}FI70=x&cvcJOKNOjO8|QsU6&1-
zn;rcCqr&C8-l;ehVQlG@0V}~dB#Ftl`Q`X6FV>f$P8Fwy(Cclct;i#tK}L$hm03>JzdJ%9Psi{nO9~N0DLXYcPUKM8
zbh8?u&?W9Xu0boRuLPrjap8yTP@&bDj-Y(a3yn%-{<;9~Yz#j-YtqCz$Y@qHYevp2UbLu#MP&Qu_=~RU
zU@)`9g!4_wB62aLuJvhl@>f`9(x{3qDF`NAVC}mgc4mnqjYPi^dy`F@}v|)tg
z_tAWAH%H;*>_RwcxlzInk!@0myv+i9Z0zoLK!x{wUjSV)ryd|2`U^$Op)?
z;al4T-1WJOM4Z$vp=kNjOWWX>H{cm$$!lL@;-tY8<}vz1%z3o;2tK8KmJ1=dxGBlRpW-XmFkxH>}JLucEwXRExh~pwk2RoeC^|
zPF~@@+O6$YTr=0XiLBbP0{8ThQgf>pZpV1(1%o+VqoBzzu%o#=je^lDak;}JSoG%K
z0AzBeGxir_KcVUS^6NU{3cwwA2x^
z@=LY6o#DH&AMDJ+b8Xg!uzdUMc^F{eFYO3r7Wl_e}gj`G@%gcg^M5X+SUYnd~0fue!
z{70UwMvYTu#!3{Rc-{Ru(|rI)!Y^yuemN8C@V=oYeTO
z=4lWjCqaC9+D)*;h6QsO^WMa`BRunPcI-|qS?QsQ?yKH
zllx~1ZY%#JQD?LKCe{)Nj;|!CSAsuGpTxfK-q!Yf&y38$gRqkO!e3sW
z)px7c4i2NB?X*~=5%7G1Of~}G{c4AEQb1nUfpkS<<5QC*(@c*du8w1;x>NGZmLG;R
zig&rIjYr$FHPw6eD#RG!|!xr_1$0Gq#cB$9?~AI|)`ISrXRUVQgJvE4gx7JKnv&&NmGDJKOgK9$5RB-ko|e
zf3>5XYFNyj!bV!9xN+4}vQ
zDII>q6yR{;y|Kxm1Lu>dxal=lClM2J@udIuKtV}*B}?{u&MY`n4quAW{etTh~xSw0C2#{YXm%3y*#(bR;a7kjXT{GRIFfO
zl)wQBhWRT>3R0cdqb7q)tO6);ad|KjZ4oW)&~2tKxhD>hJS@$i@n53C(zA$yybkL;
zIp%c|0e+QPBB?%BV6A>Jr-I#0U<9S$T(#REn{=EVTjs#{^fjBbd9-G&LusvpeF`!I
zlLD0MHXRw($0Io2tBWe@JaG+XhwuZGyRsSfbBGCZ6|Uo4QrlZr;wslvFf7UuN$
zP7&ki9?SJ;L(HtfiCYOjl684{J7t35|0z(@|EloP)2i!MPhfQ=%xqSg6k=X?0h0)k
zy?l?&4|1nJyg55ycva@{Kn8zohB(06@)lcP1iu&?-QhCd*BTTW*hpx}$qox8EB?Ld
zFkz1hXDM6ba|q}BWvw)OzmKdGs7_;zH@6w8!+FGWN{8$#y=j*!)Z9J=$#c_F)OZ(+M;hS^R8_n*Y>gZi&wlNaM4Glt9
zRh^E*u4VWJ0+*s~ewkE4|LxC&H^`mGht`Kvh*#k$`|VG}J?-JXTLyR-Gh;QyLT3v}
z;(2w@;zFiFA)9#Wto4C~QT%O^`gPtZqJ^@uCO*|YP>H0;xEZ_NF~PWB!a9+P!|OlP
z0@B&ox8dc3_h;n!hbWX5h(n%{K#>8mB{S?qu&7|pF~XGl?zfxob?%}|N73;%K0N^I
z`GI;<33+@VtLv+14@DDLeEyB!Lp{DtgL*xobnaCkP&Dl9c;COgDzno2OZqcy8)(aO
zrcPol$7NNQ{qU8f7diTF0iMHq2Z^-vvJ}*iy=^(9j5ow#$I9t-Ge5Q%&!PUI8No@b
zTw2XnP9Yi%>z}DFWd=gow{g-2{>V;a~8=+zY-GB~PJ@6bl
zRf#atBtHjd+$60IW7SR?wgf4aPA_;=H{0G8WFqE{EZB2~fc0q0z0T4^BV?<&)dYVF
z{m#s(@%-HB8)sQOS#W-ZX14)VrET&L>+^@VZ%3^05Xa!ZAz+xZE_-FltxQ}`v@lvF
zU;a-3t6!tgFSGH{jkF}t`eo8Rmq_37hE=mh${DE~OZJ;E(Q
z%}n5$wCs=dz}3G30Tq#H{?4nipC_sSQ{3MR&B72-343DTR$U3*@rnGR?vh1ELb>^o
zM+M0r3IUq7_3oSXJ)2C(U^7z=3i(0_HIOe*ir3#^jAvu7x?5
zr>-zl|H#!wIxgUMuIMIk?
zTS>8ETQqss7hB!+c=vmi}x6ZC(kG2@XHZ%-j3~qK@zft0^we&f)4a;NKx~aZP
z(^@Awo5kTh_pil`nq(afSQZ$gXyDt3(c|x;dRf*9?o3YOB-o
zVtqs)38}p-i_t+PD&J?*L^nR{A&E%5Bz~=e_zFhv`@-G-OzY=pJG|}a?0?hVPu>ze_^O?c|Jc&2)95$l~1)6^MGSw-bto)){+VObO+R*Sm(#H;i5@zk%a>v_jc
zl=0=PiF2`dgdlc>OvWR@Gmkd%ba%2S@M*#luY?7g?D?mUBfZqCp=<`P#HC~&P
z+Ie$ZNI*T>>0lxQq`6kroC>^C$=sSWlVso8hhbx;eDtM1AWgDo
z>971m@%ca$#}^5K+#|y~LcJkA3hdazHPbakkExgZrht`0U`!kbYwU1hV`oBO1y0!r
zuKIXV7of;3P7w%NB%qG;kblQgQv4NPiqlNlN#j*#Fz8GK>xm<^!+TD(j@epNJ{QTi
zJW>s5pKse>{7e^5eW>w?wU{C4l{dOj(I7~C2kDWbQAi3KY>dEesSwV61YFU_6Z+SRQm&Y&3@ZQE6~3)Y=#3m4$3XIyWoH8rPy
zA(HUB28LcRB+Blh@lUWgWR}Rgqrf0L92=0Ax
z1!(lq$zIx+^4YZAsb0{sKetA;kE?Re)C}WqytJArpV#hSejnwp4#~&I_uqq%e=PJ9
zHJ6g*;W9Dc?s-wn{NQFlrOOw=p}GbGTNX!}=Ej8h3?p2;A|!UPs%Au%%?}8R2rn&Q
z{DSh9uo(;BrRUDSN41dP_Q&3cHHu*G+eJh|<8w6iNY$Y&R$SPRsR1T9!DuqNCp$n5kbPg8k%
zh__8$A=@cAlVg{R{1*Lv+#|t@{gwDD!qfB~LG5Llwq!!#Kx#tG-l1aP>-TgLfN4%L
z)v&lYcMlrfl$m^9YtkOwcdaBlK^!+XkQ?FEQ^teUAiEA=r}poKg$P+!*f
zAI1LG*o|`n0{|?6{a1>m|G%`6{^uqb8Y4R!8#~+oQ_JW7t=k%|Z>KHRMm{~W4?cqK
zW8oD>le1?=pO*@rwOFM+QrA&OUAnZ1ZGIAxf>QAm0vf8C-`6c2Z-g)V!{e2V1_}L!
zu64R=+Vp!iJ--nQFAAdsiiCPbvlGSoB9^#=Ip(}HY+VS~Of`)`sSGn}?#x^`%20aXt|2$^g%6GAf;$e;?*iMK)oL()b?k!YC^g0C}lHM6m~4eioEQpF1qeqZ7#
zQUl5~#ReH&?Iw=>LkXe;cDamcef<&*is3-?h-ox__a2&KLybo7qzFNp6HX#-wf2mQ
ziW5$@09r
zH_J*B)Ayj5PXGdz+=hMg$=OoC&wF!ER$Ro?yt!K6PIspfU*67cZq7bVFJ2S$wClIS
zujA{>>qDGf*^PyFt(Uo`$A4=w2p9-RY}Y_<05MX?WfII!G_4w?^DFkdG^5mKO<=mF
z&`|XtTF32#6ADVIMH&*Jo-6%Fg71nQNu?MmR(7!BKTN-#)!4fA|A^WBK3YOSlU;Y2
z?cE&A732o+=qxS=H~e~>&UJHg`8hpr&oaDBPy2kYykS4}*sWV6)QML>HD`unC!F>h
zH&617GoKV|C&VOis~+WzSbxF$4wX3&uARIoPKyxsH;>XSdXFysYESzjI#i6-xp&~8
zpEn5)c(mqgEhdhKeNBq!k0fJbV$w@(kX_UYe#;%2OWy?$LiPxo+6x;Vy^{ytzTnd=
zM{X5@H;tV~TpeOHo~dz`wAJ&
zt@mkax>*HKaboH}b*4BoakA1>GpVhi!x4oNl){7??w=eK^laQ*knY{`nsdeQAGBj?
z{LTIDAH;oata|qBcfG&0cV9mSou=&l(GHyk!=D|FH3@VlpmxLX3WvX{WR;I6!#gk~
z#@ei#8N~;Y&G~#)uRm(ExChqcF~{gxNj#|
zVqZL!i1Q(oYJWSz*?}D@;1DG5m8*K!-c@uwg5$%ECcgrRt7gQx0yW!CtuV}1
zq&HUtis0mr{DLxf^4-&e*o4UY_EJ}mwb;i4c6E@vZbXIpWcNKx07WC(=2m4h4SFu0
zRX>Kv%PwD~i#sAgREj2Va4ik8ymk?mFp1wa_5Od=JTs6%<%&l*^tNRJ@o3keH!p7-t1_
z<%LBRCnZ$*Kh5rV%?XPK>J6DZbHgc*^#
z3rE4@4_K)@+E1H~kn{iD4qL4}IxwGsGRDNa9lBb6#(Z#r!`F8|7l5h!X-KqKbPzk5
z=Y7$0%m_h%59=woMJu$QG$XQ6<3xBw1DzuP;YaGS2`djF&nxqW1?^AKjz|k9c)
zXZ!*IODAN0B!nlIZzIwLMh1B_m>=_sXn&HFEUys$VxJTLNmhMwjQV&O-FQV-%JTrX
z?kW4Tb)U5ICV_;*=#rA2g4r_hBMmd(xIW{Vw#7)L#dDSs#
zE&;Jb-1C9K_zy|U24p7l4P&xSfZ_fJzB*PhfrcP2_$|D82m*~Ty?*&>x*fb{>P3rx
zrx|Pj)fIp68_}w^1ro_qe2+6ZF%M4902}VpR^Jm!iJ1y40Bumg*}K%R0!3~8L6M_a
z>K~!8z7HezMc5Q#b;5~7@&4#VZw!vI7_^`H+h>y%i6>HVb7k)H&ieUMop)x5dC&hc
z`6zW$DIG@KdU-&Luzo^ZrZZ$*IN&08uvMjcer!!jq+3PQ7vFtr9Qn!&7!TZd09C11
zv&>M^A3zapnLGbxp@LR{-Wg!4s^y`{+#`y?MDnPh6quGik4iyv%>&24@ro=bPs09m
z3o)rgokg%FVCJXxs4rvSn64u
zRkWS4I|diKm(Ncj?m7sd&Ivs#(lLjg0IJ>t5Zs_BY?P^ZBJ>Z=HT%55kT|@ReR=Yv
zQSOd?G#ER!!K?sq0sJ4e_0l}|JB5rqfLXRQI^2BF!ajmR7pMx>aB#gbtMXJr$Td0-
z?MO%TS+D^$Sx#L<7$P~RT$~gWhMLuOH~Te6Xkad6{nhwmhG#LN%jBptiXEd6K=@FX
z1-#uL>%tA$sEF*B~S=NPh&>5lbYtDE@_4#bgy
zWQAD_fi=fgJ}?0@($~L~X@*o)O@p&v)JcvW{V!QfZZtSngaBF;F7g+aPA^A
z0-hsd^|bvIoa|}kX44}uhd(7Ixn(8VZ2C8uf4#(|ZKd`(hu`Q8`*v7V*e$(+r#{EbA5)_I~2cc?tdZnAvvir~
zmP*SnYCRHV<-{*vBkY2c>5%i4&ZWksr8_D$o^hWP$kC)$9WKIE64AsUpnnl^
z?-dd?twtGb34vdsZR|nF>{Mp~aw`hm9f)WTW*n5r+r7>@S?)??%B_ViUqGwnZ7Zh3
z_@ki-p;A)vZ2Em_rm?Fz4aJGGRbA3s{Z)owMfp*ey
z)NFdu@%sDZm8*38aI(zI(fb8;4Qrf%RIZNqk(r9h0s=j?F6Yh53Z`8wARrZNPj>2|
z7G<>gr9_}MM*{jy!d!<|%IJ9NrEF;LsBKl62$exoX%m>BZlXP?lsT9!%1_(}ai+^~
z4m)Z6w{QNG*D~nONLFL5%6k7<=gjz9ReyM@+^#Q&
zVj0@f*Im=seZi2o;E=cE7#9!@ByOhaJSekx6IYew9wGcR1FDH56tuL9Xp4$oY`uYw
z2OKEf8Cp(};o!Bp(rugEHI6gB2rSDiGPH&=zjyT4%N?v#Gi_$^oNS%pzrci|ET{Z>
z`)9ijZ;jgXR-^(%G=tP4?UPgX%Q&7)X3g$&O?tN3FkXn)5_nrbPIh_6uwIsTUdjVn
zYQaDMT~;>HcDDg;&$72I0bG>i1%P5%kkXIJEsJ{=Npa^@SSvM%^<0;W)$SQn>Ns1c
zU@*#+AZ?%e57xi-{FYF4F*9kTvPEwqkrK}>c-Dm$KWYFCkW|lsXc9|EX&arC@P^$8
zfIM(6ysA`>y;E4n&~)ba^o0}QX(otZn0gVSk6Du#09I_UD4l1+r)nP$^S~R_q}lmM
zfp~zONGCbobxaN~=7BIUSqbtt*UV15Q3W{*M9>Z@`+xnrz8q2Dvg%cTKC}`?D-EDg
z$Xii2Y_3`eZpO~dxZm{q$eF&HZL?+?*Lp?Iwpj4$(;})M2@tvBnN(6Z`TW%WI
zgLl&2MNuGtf4+FKT10*IKi^8Od%GrU>a;7Ke-byn4aO$#{eqSeXI8;SEeC?;y)B2p
zzd4J>7`%kS#fj<+f0PgQFYpvBd0tXnWEVk1T|~rmW70jPyF&6S&w+Wh&J6knmhG2a
z!Aot+ZL$9p`dU~+QMj`CqwTtKMZ6-|n33ILj~n~vU}%-BtHccr>?ux+?!jxWV%$Gt
zJqH7zKmfdx^xq~0jKg7r6eI8i?#c?i%^Z>Bhciss0h=0zVFnTmKBW*Xd_oBP9R&bU
z0mn|3kA{H@heCOK?Dj|3KfJ+%QS;bp=j6POa}!2A)XtuKO>nrp~#4+JXc9BO~KSIiDrjJu$9@;`0e&8=MCo
zkO0c3umfilnQ2RDA9zaPgK+9YEQ}Gm$edhTSJ#$5)=l+0>IRRS>CE#&keOF(j(pPf
z3-lj*3dRhDkq`+0p!|QCN&Mdp<^OUf@t>jmKkcdi4|ej5=9SZ?IMQ!!J+{)gFmI00e$Rii86om$4=kP1)!U+
z`%g52BOVy@>_t2ZBn4UWlOmsgn=d2fsjujS1!Gj0FCrO3g4g#FT0k5#v4pflVuD4Y
z0vVb3ArZ8l87Q@=Hp%@MW{DCOdWWERo+8=rp`*R4x1gwj@C5xd2Xc8{*hsJhC7FTj
zsl-c0G=C}|PH6ddoH)kNU~*RCLPH+xkULD|k_cMtA5e)?hM5P6bV})2fSijw)zxEd
z`X%VvpUi1VIgqj`_2vmbeuT;e)Rc+D1aV4ysT$%&fR~Cs0tdx-4O!5QC)#`qz|laH
zC1$8^_WVL8DH?<%Jt>L_n*-pWxopA-aS~$R`!CF+e@$oHk3V74wxdr@I1Aii?%#H3rU<87p!Z7jRR7pD>*IMwXc~nWK>d*(V1RLBHi>Bn
z`i{fOHHWGj5VKJr2poK5igj|cA4nc+S9#A{(vx&%L3y-(c=39kYHB@E0~-=~+PVox
zQ&F#GK}}Q8Z_bjQ=zWRsX6UzD!Gg>Dh&@tFPk=D64290)$l8RJj6es0d5_6p2jnpQ
zUGChEW69A;bj(qRG!!$X2C*G81H*(#$RSJh`t_4+I>0J?&bfS_hh`*sB#%bH9!Mho
zaZ~J?@odJ&VjMh_6y|7)U(C@^2oIs+iXFU$RMADZLD0=}5CO&GrsH2<8sJs;;EULB
z6Tu(mAjL#tO%Fsc0NvDj@dXa4(~68G2-fPM&S1U*V-l_UU)_RtXum-RMH)EukrQT1
z6?rsZ!9l@e!(>eW1Q6<
z4+0Er$Wt=a6-s0q4dLYzec!FHL*J!gA7@#CBzat^L3W=>t+`Vdc
zshgHA5Jm;7Vxe3Uo1HU)L0`dn|QW*z;uk#$MO2@%TK<*r`
z!1Elqp8DPlf~~Vja3*GC>t%Gj6Xn(|95
zBY7J=xN?L7S@kl+_Ox-0DjfXF%SIrctTIlfFq1YDnUtu4wLVD=umr$3_DOzYKbKE(
z4ZV2|hNM@YbW6jtonox6R$EBFH6~8%;{9t|%V_;w8Upin#6Q_TMggYL*=GfwSQ
z!Ol1lVTARo62+-4NR&)Wj@iimDiOSeGDl+EhCC%FWsoL2)MX6tT_OcHPYN
zFtxX(DW-Lh5pkmtW13Q{lPQLuxa=^cs0zD&{wb$LI#r4H>|r#6%}0V^XHFy#ShTpk
z)_#iM5ygB<7VxR?%z^5UHrxYah++xY@lF@8
zciC#R#mRs)?i=S7*<$fcaro<1{L2CUx3{V
zTL7_dbbRBjzH5M+Nboev2+|V4Bjq1GiZe`*3lm|r-fd7M$T6*_W8vpE?T#)VT!$)(
zXsy)%hlv{WgOZ9+3ZcnUkk;i>8XK(Q4)<)9)P;qz^F=rr(ua
z0UH8v!6|fQt!TpjvJas`V*iV_S;%&WRDN{(HVRc}wizhw)kfOE+?wIcSQqb#<;{yt
z_5gBJ1u11|>j_b>V29@~%#*S9;@jDxQdRQR>LtShUN`m&PFb==E7jj&BhZbd49&uE*nDrg*fUWA@1?kOxAZMM2J13gd8+gaH@xTnHAO001r}ci+$omuz
zE0{y$MwR4+g>toneBHhDjemEzVOl=JExn2aWBw8hbKe`gaF#mrYF{uwY=s07I$CIf
z36JdTgb@#DlMXl~Ot8W%1%ju~jhw(gi(of$wy
z1u-uz@#-|%%CzA0YKc~HI$;g6pE(V;*BMz>6}Ru0=`0|MxirV2%Pb{eWv16fw>NT_
zoCMrawV6`1;g7tqM5Db-1;&>__HLve+Sd)xUUKGHap6{Dvi9M_uY{Y^ncwf56*LQy
zNj-}&7d^(NL<<=r*B%jq>oVmotFV4$z7u9qo?&&_VaUi)hbT3uY`y6$wZzzV2mf+b
z9#X+Ahg;g6dvgrhsK?FhpyC&$n^I+BCNQCJ#2rEDaZ<+}VpV*^z(~zK$0O-i(GkzG
zauSo)aw<@_f#7-q%AvVLYd7!$AQ#W5{reZZYP1tOUS8!M1Y-k7G_(d2#uzRv;ef)h
z6oD76nqx3=rX!WbKnrhQCrHx&tDza7l^Qu8cy@#H)ZfFX6M$5$1<)1&%ZSfzxF_v1
zcqg{&7_iz!btRsRS<1fi^ukoHy
zS>3Pq(|^d$lk0dIL36jk=kBhYkM_aDdnxo?zTJJVO~LkW83Sc#PnK5)Dcq$^OrGD@
z4*dx2egAzLuQYK*ZIH3^+LT>u1dg*G?6vh?o<3!|@`pXTfWb+A`I8OAXZ!gxz?Y(#
zJ5$7rRv#fASKa5fKL=I;ydLT-drk`<9o|g1cc#pKlU=sW>{fSso+*#nzF_tPIs@&N
zDHZ3ER>QeM{Rj=!Hl6`6fTm#X+NjrtX;5MCDn`>VNDouPu5?ur5(PQ9S8>1dq2)Cl
zW`VEG^9y5guT%1$h7P7xg1XY*YvIu){F<|61ixY2vG*mYYcJ`FF3M%Sv^i-BsU$h6
zh)z8w<(Jl1%{_f!B_?(;rX%#>R)yAuS&
zUw=#{d&Tj83Yby|VB&627f-7nZPxW7-Zp7I7S(us!*>^6`n+@<3*lj>jq>_YNe-r5
zZtZ+wB)PGs-C_>a7EyDMc>7aJoP}!JgAFFF4j^l*Y(DKQd3t^Fk0-nw5o0jyIe;oR~9dLsTyJ#1JOTel-_yQQujyVgO^^gOe)7@tP$9|LW+
znB=Zv>z;OWk4z2>PI@~mnH8?ib%;}|$DOHeRAMp~*zzsYjSezYyvEvjM7M+_|m
z$$$Z2NRqOzy(dBdFSH3MeZSNZmN+t+htCF0G%Z)T;Yn8WCd7r5S|LWuF|B~H$c%wJ
zEwGHX3?eEgbb2DcEp#Y4Y`#yg%n>X77KzBOZ4L&&8H1Zq+6FOM_5#iKnN(B+(I8C2%hg9t5-Hp&D%ql9
z84Z!B!ijX~W<@Y;F%&`H43GxnB4*hQGJ^ofPwV4r-A|X$z2(KL7(DIPdAA^rJD6oS
z>XT%NWUL*Jf=Y9WUhSf0MgSs!q?HMBahbJW2TYo{T!Hw3@5C=hcO(vtrD(a$k|yUW
zmhMiCFHBZXOpaF&0vZSbV4R05G!OYz3e!wn$G6#k+VpF)uX(f-ZC%*`Cl7E{j#iGL
zpmP<2IF5MaTe~Fsl<39KM*CKxD{QTQ&^pMu3V|+Yt}B`o*WDc1G&yuSF)+cjUDzg2)Hk@L_J!Bg+9cOkq!kYMMz;sb~@R;Nw=TqZ6-__nHUQ>7yw1=JM$ANY=RfX&9
zG%l3CJbAT;l}7ZC&8aS)95tiF&+0B)2YedYa*>CrRsF*ALhV@M8TsphKFl=2hfGfWIB+I9fw@%ZIz!k8
zzIxT8BdJ0D3HunI$Qd2i{#BTZ@Kh~xruwLB$em74VCzs54y*i-!^3|l;8$VeYgqs}
znEw8hrkbx6kAjQF5%U~o{`~Ky%o1mnRB4h@{V!|C
zN~9;6q(0^}I;g!T;;%wpNhc^Gk4?Z_Lbu+rAZ+9TZ$pcEL}C)Z!p{@WD0Tl)JH$^D
zu}A4i(r0xe-keiEs*KO&jMcPHZ7b4pG_?8n86plTJx{7sH~vvQ!uYh>NO)Ue9*4;N
zNB!N*OL|i-9lrN2{NcA6XA8@%_o!>CGHB3f{#9H{YS7VK=KWTwVPVdaFC5$bPB>YW
zQ{$lKjqqOuL;4}j=jk^z6Vg>RQ~5N0R29S3lQej@6`E=38k*^Rn&Ih+nn~&EKdPrS
z<-^s?w-uU+>1rLRRvK5+Su|gz%m1j3Xh>)(hu_;)#HK52rljBNNSoAfNte|8QKeK_
zl|i**#s&>Jlz%B)=Ut7>9ZOe>Kwc`94^k_Da(W=&uOiA4!M{S;Kijqase5C-fpdH%{~h!D$-=B{?_y7z?*G-pKb7Ad-k4wB
z1$?gawm$QYsc7=nlNf4Fr9b0KP)t4XSCQ^f6j`KV%$R)nV%ytS6W^Kwg~R!h6w}nx
z!~QC);%2I;)S>9&A057>&N}6-oYQ0YQtHzj|0=d_Wj#&N@^A0?QV*s3r2kdCw<6ex
zVJNL3SY0`4LjLUn0HU1qUNeiD{J?h2naiuAA1)T9a
z1m_)R-i-y+dMA%`QRwQm;ITuNJhCeBUAo^aD}yO6?0f-CEk}?O0DO%8rg8qA<;5l;
zrr;nIbVl=R3uZ8QGCFR+xY95%bGD8BdQ@G^+_~@N(`R5S|m;4_eJqLx1
z+d&>+o(HPcd>5W%7L{kMsvS4|a`q1|OXYUoqWyHIDZCsHmCKbgdWYt%cBEY4cFvTI
zE-&pHd=#E!$I@hr7GaMFr&zgn&T@k3q;Xo>-@7f%qOl4g(|==MGbQr~f^)<2@M?mR
z)m?*odXrles+IO9ox^QA1QRDDl=pAU%M}u~V|vM~N$(KPg{9%CI&>(U8?1ti^Ojlr
zaUfua945M2n{h4+q)})XF&w%>FnzGFsy+9qW&l_G4%vENOxBE^I>nT-t+U)A#d=`O
z3e}C5hY366$Bny+KMJN@b-8Psre~#sy+qQoJrWngN-qdm(S7xDOR@~=hSP)2IAi5zcI|Ob6+2NAz
z0(S^ZR~^ZNeb!`tVmBOx7zsWdCuTic82mC(Nn+g$i(oAb}`J
z%tB5a)tLTfK0Tckg6o1vDIG(h4NFp-s2a(M8HUEGk1JGO_m41~DlX@lMc+oj0N8be
zOY1uI4&aZ#nJSXL4$!h%aY%CgyJCAV{g<1^xU~A6(74W<{^3Z6YS3hA%ekBb{CfgE
zZ!4%n(uh6VqUk?l>m4B}A5}!X6<=SbZ>Ngie?`-O#@0zyt;Q2M&f1dv>=ATIem|-d
z5%pGlZBp=UD#}ekVobA9_HVI(Z9(*ZVrt4jdaJfQi2gICrVONi)L8hBM(kI5npDwh
z^f2ejk1915P))7$k2Y)r0)D~*%mM_@er(3R#*8O^d^~cRVF@htYV23b-1
z^L#dho}Pq#nyUWkJhE5A5+$v2G`?Z|OZ0@@E{@t&_h!9CFgO*P;P3w*9Bi60Y+Rv)
zbGD;2KQWu11M;hVKdMwM4A^N@6FK|%cPo89@v9Kl9bHP1-3AM_KiCc|{e)`%V@7{M
zGe4@-;EbB~CAXta=>OM#xEU5dgn)g1nH_`dL8@6!2|NAKRBGsqhZ1)BIb$erv!5gK
z%}I<3gQGCGALd6f!~dA@l*6%GDKNsLd`NYh%2##wF_z&GLoPUW_&VMl>sC93lrmhw
z&X>*xp&@Q%`1P_N2g-T09rpXVQ02Wt%;ZR_Zb$8SsGzgz|4j1jHnn4+G8b{v>yCVX
zNKuW!Jk{4xL!nyrHw}pGr)~gM@U(Rq%s}itnqRYv&sUuS?fbDvdEh($39uye7E*p>
zWZM+~W5N@9XV$l`^vryeXrhpF@3i#l}d><-PwVT^n5eHmfvhD`)Ip8ezc$l{%AYEhK10X)wPb$>b8#c
z5o>s{w=LkZ{Atz?4JlW@zdk%
z;KSp8SNt}b?h*t`g>5sMSJe2m+<#!-?Muye@b{+&8zC(e!u61@l*UeXxbKF}97ny6
zm>OeQKwiIX7|m=Vzx#Rf3Mt;heTr*8{>Xs(k0?F;R_!m~`IiQi@cCBl7x4TS4!sRK
z{}V}{*}5O39E>c=&=R0-H9zb9|C|4PJ39C&O@lAP|L`9t1olFCZz+1Ueal)9o?Z=T
zy6xU3vD&C2Z@}NYYU=_QBaUkEvu10H>gU>gGU;UM7aw^4n?Y6Y)&J`s*p&u!
z-_Pzix^y=J&aSv^iIhJaaa4?-)lOTqH^=6aardLDya8YHs-q3QtUpgcfA(Ram^QU>
z{da!&4>e|%BH>4=24j1MDgWbcw&$3B?usLVlAPIg<$K!5ViMVasjxxydQY6c^X8YF1
z>hV~Cu_bHM?a7B%+tMIElOk3k0ZCz$VE9h-F81(@BvX%zV8N9B19ZvvY^MZ+u^Wh{
z=dOR8*p_?xxw<>3l14O@dZ2Ebs~c+_Q<)Di_&kByt5+Hvjy5{#%jUD8zw_^`{wKLf
z5mkk$&8d)lZSts+jm%AiVztNN%-S!WxG-z`KG9^>e)i-lv$oF@24>q+MkJaDu+b6?
zBiLw$Cc@BYgoe@32ul-TVAMgwXkgSx6QOTZO~a^fR8AA2XH;12t?IsV=qzgmkOH(7
zzxmtH%O{-SzyB}dO=G!wsA-NNX5gZDmDVF)c>fV_#c8C^zdGSQdUx(ybpJcC3K4rB
z%f5ZhWe4LtPD&HF{?!SBf6-jk2@#51R4io*i7&-U#659}GSPHodj@GMsj(;BV?^)S
z3`M5t4n@-IM+%G&Lo&fq;YYfmDmw(u1-^@n^1ixewa_t~QKuF9;{Z@;ryz@#*zaR*
zQ>H(DhtCo_Evcc7-{F7+tMasUYT)X3kQrv3o|pQ9*1t#0_Dzu~(-oHzr%4Yc5C`RZeE6O!fS3RAxxE
zcscp0Dy$(lbni#%L%7qRmj9uQ&5IlLoTyJc&QB!%O(l4g`Q|DCZ#uLrA3
zQ{%Y5YZ9gxmWpp0i;cWQiDUmZ3)KsI5c;zH
zj5L(N^1K`xJ!Xfu?TSr!b})0^tw^~lb&r+@Q2>)W$vJ)TUFBafWnvB#QTBhcb^Ux!
z$;j;BEB=Z%oYHywZbclcJ8?m$@`BQPv)kJkI)CzY8mqQ8CzgamQ^MOhKmQe1r$f5H
z4gO42=nKbo*2d259^s6A=|9jKtPEesByUUS-k|0e{X4P_6}#w1m5N^!u2vX3qYsub
z+r~#}+s1nNV*^u^Ps)kV`FjRQk6?_QEoH*{5CtV_tHV27i>PQeJ9!v?aiRWFo|<2D
z`4<=JFKQI^Myo!pr)e4aPrZyt^|-Zd!}e@DwdfC`QBl4O71fK1#Fa!%;reYS|E1?2
z6s{jtY7&=nhcpIK@{bz#yRVe`V3ulRw}&0iDOpi`+gN9RkW)1vCGqSh4~>Eq^>a@e{s0}Vs!0b%xO|k&;E$Hq%aUl
zLzJW<%{MPYD
zmquN3DB|B8#<4}d)1_?u4un#*@vwftGG&bXd-56DH6EQ8w4D&RbNOhrL1U}3Jg}47
zSF7J}6q(W@x+rO5l$^?~TH(8y#vaP031*TC;=gFG23v~
zE1QFbeby_-sF7AGPVgTDq^>*DE3<`C)p+9(`JCX(zCmiWIl?{6KzYFVtw%yqQGS19
zDJz!CUFj)+pq;c?(Wj0mGZ++(rEt7EaMSK<2S5NiQXl*!=rZp2M4oF@O-2H&;7ucU1_zUOm<07=LG-AE&m$7tyJ^2WZ=(K
z&X))8BBd$u;GLE?T7sdV%IPCyE>NLb19L{9ZYn(bX1wu8fNj0
z0=E$3m{zl$KB)*9*f7={7Yo)u3P5f&){Q(32u_Qs*@nxbY4Z#2vl
ze_CB{h?kCXg(+(VYgy9Umrdsrf}2$0K?V&CSHa~iw%N}4N!jFQv~Bx=KnXpA4afO>
z*gLp=@jxfWw#x>Dh+WGVf-Bqgv1xJBZxW+Bo`$BhS-gc>h`sM*nnx@NSP+GSK%cZA
zM3g}`P!hO4xVm7C8X={?q#?8MaT~A+|9{k7>Q;S)J6mKfX<^aYQ;>@AqyPTo8^uec>|3qX>0Z-PLLNJ=Nqb3P?CHB
zmVTIu$lAz&c%(M&kex!Qer&dAmAyr7=)ZKzG}d0Yxy8e00+j#nimU~_oDgoq+2APl|N%v^-AbN2)MxFegD
zgHu>>lM4&0^H!unz{aWqg0-56AJu@|D!$D!rMeIomzAd3
z<`nSygnE%%Re+F6b{s!PY>Z)+AQUo&Y9g=BbGhNVaA?@t`Y3{ElnV=dRM=-$1#cet
zT&^t>W#^<~_sNC*#gtx0U3Vg3$#!y(sIqBB8W1pBf4b^yT83DwOq}O(S$MFj&^H;Z
ztYsOTV!wz+8S>{o|71S9(J(ef5AI#n6W;hZ<|l>_C_rphV?!I(LJT2ZNH=?zKpQk&gqk{P1{VJK&!0=rg?ih~ud+P4X{Gl39p1(MLY;kgV4
zN1<1p@x2Brd0q&U>Sg2(-IH7!<2w+eHU2YaJSE
zy8WC6-nNraSm
z6?$Sa`%7$9AguJ&(%O8rCt%a})lz*ladCv~urO!UGrw61Zdy@L%U;U|`R4(iL`y(n
z^BqjJZ7{ISCIY%juIre52>l|n+1*sS#KgZjHP|#zRMt)BmJGw_&yAXbvsXevU;{{r
zZmcbEu>+qG)XZVGIe=dV`vP#~jof#h4r`&$XGpE0c;=N#dOSM0zO=kNGlC^8<%1##vNP*b
z3b)B?-Yy<4CGL(J)y{4utFUIlxx-7aO;2H&>A3xUqXVk~$bM8~JnHm^Hl_wrRb-?d
zWNno}5?Z}@z|O_N0qS5$7>9Yaf8ZZs@DmV?&s__lor+&1wydGP_yI`r4Y69Y`*Ds#
zy;jW@dkx~1H=Eul^P#XfTkO6rnK0@DHdPZ0P>QLBi6hL-x*xZN)HRK~M
zZ#`}}qGA4JTmdhg*KU9v)F)sj_)+dAhbUqglP{#duAIU;-UvpO1Zv6n
z>yW#pH@duAkGee*^Pbt1?#1YnXJ$>o>-)N9-nmQ}!`iBHmTHp~q*Q`aYLB-C+miA(
z+(X?^`0>qht#~CVgD!iO;CO>?Hr!
zVyCDKHkYFtI-pktP=@u9fncapqY%)0W7TBIofzo{Cp^0kM$y%l;YtjhQBd|6N$nL@
zJ!jIMvsKErID5l4Bg<@UqU4QEd$jOIZZSk~rr@?%LmpZPc!t&*MOrHBuF*w(?p=NL
z5M%#o>0+UPA92^iRCD
zhDVJ{vln!=mMvJVNP|T~5Q_qmuP&;-ZGfvF&{!%9e6|0P&_w0HqO0;5*a&2RSm1D~EYm
z;1lxI;F$v&+(Y;LyUHHH~4WQN7@?O
z1p33r-lCkZ2-tVJxinQYezzYQ*C7hlR#|xL)%PkpLYy6P$ZH1cXLTY8W5My#UeG1~
zdnXyufXiD?$m=z9kn{;#l3F`Dws%#aS>eHy8@Kh4$3ApS&|K?tl(S?d@uTl~*5D^)
z#3$>hY_aCWi}OZTu~O3dD937NrFZ!2cI94A?Qgmv_z%ubi2>c$Qmc$smZJ9!A`qM;
zN0R^9Vk4Lox7xSls>Yd)6gB=D#MhN|Za)y{JpsT73iI2rhbTPUgy?{VJ?5Tv3zd$@
z6YV0dZA>k>`4#udmd*gtL(ZI^B(qDHh5)I6Xk54rr=VRRkp#(
z6ODcV<5rO#s>KDbN-w(9dUo1l#N$R!3RyRVSnk0Ny3H7%;<{{u-^@L)HnfhdTOT_A
zV8slg+#~adRHSfUdT$xTz{mSSkMam>y7j0SmfL3VxI`9Eqvo1h14Wfr$B?=)NAL
zkdPGFjy|D`nBF(HOVRUoG+e^_@(IJCuDV94B;3H^Oanv%tm-5VH)P1bA^no2djrKH?IM_40K?JCzZDKwx_iS)`8A#pKA-cTJvw)_V*2WN+lLI}!
z?(n8TpbOWLz)~xmgo*VdZ)!K?X=F(WIQ
zjo_ZuvXZ`qT@4F8vL`pRFl3CI)4mY_R#eOGkYbxPE(Mvs%Ok98X!rFHF&VqF=zE5n
zOP@wn_1Lh341CB5hXA+v^<^1x!TA>Hp}zh*Z&v)cd_lM=*^>Zvd~F{f>MMDf=*Km8
zajV5&8h*6+Ww0Sse0ekHOGeu4M$VUI;{}Aw-C;eTs6(UejFhybL)NGPTfBP*L;1jQ
z|0#f3nfL3#s0>uKv46B{8**eX1KJKTi%#&LvhSFkHmc4j`daMpX;8At{qrE%e%8t>
zrsl~U_~6LLnR5qhdmt0H$M*$@E1S5ykn8npgM2OOwsq+)veFHL_M_rw%GS);R17D5
zIpy}aM!RzabI(f;&38Q$rq|h}RV4hNf?El4M0AlYK~DRs>=)Uam-3vl)E=HSJ=#K$
zf2#CYsrps)M0+7QYp`X;me6guA&8#5o-v
zzSg>1-9Gg8UUAx?__)#X01rR74Vkfkm`{563gAY&KN2(r7rrty}M|1mNs$xyxpBAbK^y+Z*!`mH6J5-
z7(b{!Jq7+Se8rXbirS;H`kP*5hm7xselXg1arf-qPxWhI0Y~#p=7%a?XVAmyB3t5P
z2$tU8P5dpCT~CU{?(#^7c(YYjOVAp}7%d5|CY~JxsIo1^q7Jx4@7cHXVnDV3xv(NT
z`^E{0I@Ph8&36`ze6+6N{a+eP59c=Z_nzFVcJbW9JiW7p+1wUo)?}|wrAxAwb?jMj
zk1UW}me*M=K&Y5ta0g0Zbve&>ao-EHD%;wl*KFg$<4KRFnBA4n)(X!>Pv3>82WG!*
z9Df_w>mN~ZMUUH%QSXcVojW&8&b~D8UmrKMx)C=J`6eRd>)T}K1+H^syi9Bv(o<^T
zEp85vU3=i&vhEjc*VZjs0;tkDqMvj;F64C3SLL~H`x+DvF(33xcFc0H@l~2aE|T{?MD-5gW2P7PN_D3RkTifr
zHk=XIDSCgA@0s?t4*;i|{E8JBOWM=*UBts>Lf*?Z@@h?Kw5hZd-H5%{h`;D;Xg(%c
z9n@v~$q&-m+uyQTc$$m!R+P0;S@h$1k5`IVM{P`X5XQE$(IRnQwp5Ellu%Jit&vle
zw6FS0FWLE=#MPLOgI9pf>@O{)OvTQn=e-ZRiax2QB{Fqt%|b{=_4^x<_`Z|;&JN#i
ze=oQieh``5pdJD=h-lrN7q(z(Hxau2m5#HLx4|w#T`1w?>~khgI$lBUx`~jGdVt)p
z=k#v(+l@H3XFTD77sPc$2_ZL6N*OYSJR3SDq2PI(K_u|)>}y&-4f%7oZVuC>#hG5b
z{JgzmZ?_d)fz_Fpxn;U@hOYNqBKBp|9Y7a6&^!YVxqO(fHSCF$e9Ri(JwM^n8}%iN
zPm1(;vi2^q2{vkcVLieZ5&l@z=Sc6%JH8qkV@YcvV$2bH-`!$4&v>_KzhPmK`NE6W
zS0pc^5g)j~A=57ULS$!s6}L6hVb6y>6{hFCvw9<28~n}Z@*NYy;HKUOY9gay5%njV
zS@;;j;)4|fk2w_8C)`iCa4#RRpYyQ2BPs3u%pq%)`8lRsX*G`Yh3A8w#Xe)ZpL1V0
zDRHbhbVOT7^y~|!sXGte%yV+B2IziS%HvEEaDbePKbZY(ZT|`T)2Dg+KeMM5_w)20
ztJvK!y1QuPtoSi4(>b}ky7F_pHgrYK2S2EPNIUhQFguCe`r4*J44c+%q>1;4d|}9V
zULv1C^8IIL1a4!m0W_^^1?k(KejK%uS-&UwSW}-pqe@ri;sIS1^`uRKh^$;2l{&6#
zXqs$G=K6+HLg4I?1|DzX9|Iu-&8044Wr?TQfH>I`N?N@Eygwz&swk
z@Xr@iEI4#*@){HBnveNSp9`}{rER?ZB+hsA+?$9KgT`%ntZ&+l9$dckkWuX{koVIu
zIb%gt$#c4C!R$KO?HOudgw@jIowaLk?&T}n>{B&9<;~U+C_YB*-wU-^IaC3juakUq~kyI9K+m*w`T?1X>7hs^X-dhJ@NhhjAJq#0X!eQUTPny
z8X|SwynK9>NdSrHZEf8Zus&jS@&djZA$O~6(FDID?b0wV>+o@!p~;`F8hQC((LpUf
z?SAcJEJ61o2$w#Y+9&*Q{Nu>;kqr@Kx@_VB%#u>XpiKjr4=
zsmPgA{IvB1=>lBn)gq7#tg}(va43qxr#|^Kz^AO>F!r%Ut30JRierBCbnxDf^!+)7`Xy0znvSus~PxunY(#_9YfXulEWk7r*5IT%rb*J!I{kG
zgX&rQ17&WePhOo@Mea8iU_GLd~+1IUq#5H?hScnauayO
z(9akq>=kDim*>qgqT{!DGsZp2KNMtHpVJw(d%w?VZPm|Nd>5`hc(QN5qaFVhf=(ZiQ137o
z=={ll*
z(}$b)FMJJjPH?#1U{!z4dd*EpVSjp;xW3fsYRDbC3gn)GN@AOZby5Q_;jH(rEI!x;mC&>;E~=V
zr%77H$+t-}f4nJImceWB^u1lXjFb25QdQc!@6^_Nau4j<