From 1fb33ca60cbf05a571100be6e0981d58ba7995e5 Mon Sep 17 00:00:00 2001 From: pocteo <47368369+pocteo@users.noreply.github.com> Date: Wed, 13 Nov 2019 14:37:33 +0100 Subject: [PATCH 01/41] Add missing vote namespace --- k8s-specifications/vote-namespace.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 k8s-specifications/vote-namespace.yml diff --git a/k8s-specifications/vote-namespace.yml b/k8s-specifications/vote-namespace.yml new file mode 100644 index 0000000000..a071655eaf --- /dev/null +++ b/k8s-specifications/vote-namespace.yml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: vote + From 6494a7a7e0450bc4c2f0599b9f0942d3a8e688f3 Mon Sep 17 00:00:00 2001 From: DanArlowski <59116108+DanArlowski@users.noreply.github.com> Date: Wed, 4 Nov 2020 10:14:53 +0200 Subject: [PATCH 02/41] Version Was invalid, Fix to Version3 docker-compose replicas cant be 2 because of port allocation --- docker-compose-k8s.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose-k8s.yml b/docker-compose-k8s.yml index 47897420e1..2c756dd8b1 100644 --- a/docker-compose-k8s.yml +++ b/docker-compose-k8s.yml @@ -1,4 +1,4 @@ -version: ':8080' +version: '3' services: redis: @@ -17,7 +17,7 @@ services: ports: - "5000:80" deploy: - replicas: 2 + replicas: 1 result: image: dockersamples/examplevotingapp_result:before ports: From ad6e9f1f699a007e94e31ba1c258e71476fa5607 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Jan 2021 10:46:13 +0000 Subject: [PATCH 03/41] Bump socket.io from 2.2.0 to 2.4.0 in /result Bumps [socket.io](https://github.com/socketio/socket.io) from 2.2.0 to 2.4.0. - [Release notes](https://github.com/socketio/socket.io/releases) - [Changelog](https://github.com/socketio/socket.io/blob/2.4.0/CHANGELOG.md) - [Commits](https://github.com/socketio/socket.io/compare/2.2.0...2.4.0) Signed-off-by: dependabot[bot] --- result/package-lock.json | 250 ++++++++++++++++----------------------- 1 file changed, 99 insertions(+), 151 deletions(-) diff --git a/result/package-lock.json b/result/package-lock.json index 56c3eae104..e879f96601 100644 --- a/result/package-lock.json +++ b/result/package-lock.json @@ -33,33 +33,20 @@ "resolved": "https://registry.npmjs.org/async/-/async-3.1.0.tgz", "integrity": "sha512-4vx/aaY6j/j3Lw3fbCHNWP0pPaTCew3F6F3hYyl/tHs/ndmV1q7NW9T5yuJ2XAGwdQrP+6Wu20x06U4APo/iQQ==" }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" - }, "backo2": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" }, "base64-arraybuffer": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", - "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=" + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", + "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=" }, "base64id": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", - "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=" - }, - "better-assert": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", - "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", - "requires": { - "callsite": "1.0.0" - } + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==" }, "blob": { "version": "0.0.5", @@ -93,20 +80,15 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" }, - "callsite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", - "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=" - }, "component-bind": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=" }, "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" }, "component-inherit": { "version": "0.0.3", @@ -163,11 +145,6 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, - "double-ended-queue": { - "version": "2.1.0-0", - "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", - "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" - }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -179,42 +156,52 @@ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, "engine.io": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.3.2.tgz", - "integrity": "sha512-AsaA9KG7cWPXWHp5FvHdDWY3AMWeZ8x+2pUVLcn71qE5AtAzgGbxuclOytygskw8XGmiQafTmnI9Bix3uihu2w==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.5.0.tgz", + "integrity": "sha512-21HlvPUKaitDGE4GXNtQ7PLP0Sz4aWLddMPw2VTyFz1FVZqu/kZsJUO8WNpKuE/OCL7nkfRaOui2ZCJloGznGA==", "requires": { "accepts": "~1.3.4", - "base64id": "1.0.0", - "cookie": "0.3.1", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.0", - "ws": "~6.1.0" + "base64id": "2.0.0", + "cookie": "~0.4.1", + "debug": "~4.1.0", + "engine.io-parser": "~2.2.0", + "ws": "~7.4.2" }, "dependencies": { + "cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" + }, "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" } } }, "engine.io-client": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.3.2.tgz", - "integrity": "sha512-y0CPINnhMvPuwtqXfsGuWE8BB66+B6wTtCofQDRecMQPYX3MYUZXFNKDhdrSe3EVjgOu4V3rxdeqN/Tr91IgbQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.0.tgz", + "integrity": "sha512-12wPRfMrugVw/DNyJk34GQ5vIVArEcVMXWugQGGuw2XxUSztFNmJggZmv8IZlLyEdnpO1QB9LkcjeWewO2vxtA==", "requires": { - "component-emitter": "1.2.1", + "component-emitter": "~1.3.0", "component-inherit": "0.0.3", "debug": "~3.1.0", - "engine.io-parser": "~2.1.1", + "engine.io-parser": "~2.2.0", "has-cors": "1.1.0", "indexof": "0.0.1", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "ws": "~6.1.0", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "ws": "~7.4.2", "xmlhttprequest-ssl": "~1.5.4", "yeast": "0.1.2" }, @@ -230,13 +217,13 @@ } }, "engine.io-parser": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz", - "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.1.tgz", + "integrity": "sha512-x+dN/fBH8Ro8TFwJ+rkB2AmuVw9Yu2mockR/p3W8f8YtExwFgDvBDi0GWyb4ZLkpahtDGZgtr3zLovanJghPqg==", "requires": { "after": "0.8.2", "arraybuffer.slice": "~0.0.7", - "base64-arraybuffer": "0.1.5", + "base64-arraybuffer": "0.1.4", "blob": "0.0.5", "has-binary2": "~1.0.2" } @@ -436,16 +423,6 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" }, - "notepack.io": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/notepack.io/-/notepack.io-2.1.3.tgz", - "integrity": "sha512-AgSt+cP5XMooho1Ppn8NB3FFaVWefV+qZoZncYTUSch2GAEwlYLcIIbT5YVkMlFeNHnfwOvc4HDlbvrB5BRxXA==" - }, - "object-component": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", - "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=" - }, "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", @@ -460,20 +437,14 @@ "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" }, "parseqs": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", - "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", - "requires": { - "better-assert": "~1.0.0" - } + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz", + "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==" }, "parseuri": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", - "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", - "requires": { - "better-assert": "~1.0.0" - } + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz", + "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==" }, "parseurl": { "version": "1.3.3", @@ -587,26 +558,6 @@ "unpipe": "1.0.0" } }, - "redis": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz", - "integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==", - "requires": { - "double-ended-queue": "^2.1.0-0", - "redis-commands": "^1.2.0", - "redis-parser": "^2.6.0" - } - }, - "redis-commands": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.5.0.tgz", - "integrity": "sha512-6KxamqpZ468MeQC3bkWmCB1fp56XL64D4Kf0zJSwDZbVLLm7KFkoIcHrgRvQ+sk8dnhySs7+yBg94yIkAK7aJg==" - }, - "redis-parser": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz", - "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=" - }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -666,16 +617,16 @@ "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" }, "socket.io": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.2.0.tgz", - "integrity": "sha512-wxXrIuZ8AILcn+f1B4ez4hJTPG24iNgxBBDaJfT6MsyOhVYiTXWexGoPkd87ktJG8kQEcL/NBvRi64+9k4Kc0w==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.4.0.tgz", + "integrity": "sha512-9UPJ1UTvKayuQfVv2IQ3k7tCQC/fboDyIK62i99dAQIyHKaBsNdTpwHLgKJ6guRWxRtC9H+138UwpaGuQO9uWQ==", "requires": { "debug": "~4.1.0", - "engine.io": "~3.3.1", + "engine.io": "~3.5.0", "has-binary2": "~1.0.2", "socket.io-adapter": "~1.1.0", - "socket.io-client": "2.2.0", - "socket.io-parser": "~3.3.0" + "socket.io-client": "2.4.0", + "socket.io-parser": "~3.4.0" }, "dependencies": { "debug": { @@ -687,34 +638,31 @@ } }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" } } }, "socket.io-adapter": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", - "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz", + "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==" }, "socket.io-client": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.2.0.tgz", - "integrity": "sha512-56ZrkTDbdTLmBIyfFYesgOxsjcLnwAKoN4CiPyTVkMQj3zTUh0QAx3GbvIvLpFEOvQWu92yyWICxB0u7wkVbYA==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.4.0.tgz", + "integrity": "sha512-M6xhnKQHuuZd4Ba9vltCLT9oa+YvTsP8j9NcEiLElfIg8KeYPyhWOes6x4t+LTAC8enQbE/995AdTem2uNyKKQ==", "requires": { "backo2": "1.0.2", - "base64-arraybuffer": "0.1.5", "component-bind": "1.0.0", - "component-emitter": "1.2.1", + "component-emitter": "~1.3.0", "debug": "~3.1.0", - "engine.io-client": "~3.3.1", + "engine.io-client": "~3.5.0", "has-binary2": "~1.0.2", - "has-cors": "1.1.0", "indexof": "0.0.1", - "object-component": "0.0.3", - "parseqs": "0.0.5", - "parseuri": "0.0.5", + "parseqs": "0.0.6", + "parseuri": "0.0.6", "socket.io-parser": "~3.3.0", "to-array": "0.1.4" }, @@ -726,41 +674,49 @@ "requires": { "ms": "2.0.0" } + }, + "socket.io-parser": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.2.tgz", + "integrity": "sha512-FJvDBuOALxdCI9qwRrO/Rfp9yfndRtc1jSgVgV8FDraihmSP/MLGD5PEuJrNfjALvcQ+vMDM/33AWOYP/JSjDg==", + "requires": { + "component-emitter": "~1.3.0", + "debug": "~3.1.0", + "isarray": "2.0.1" + } } } }, "socket.io-parser": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz", - "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.1.tgz", + "integrity": "sha512-11hMgzL+WCLWf1uFtHSNvliI++tcRUWdoeYuwIl+Axvwy9z2gQM+7nJyN3STj1tLj5JyIUH8/gpDGxzAlDdi0A==", "requires": { "component-emitter": "1.2.1", - "debug": "~3.1.0", + "debug": "~4.1.0", "isarray": "2.0.1" }, "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" } } }, - "socket.io-redis": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/socket.io-redis/-/socket.io-redis-5.2.0.tgz", - "integrity": "sha1-j+KtlEX8UIhvtwq8dZ1nQD1Ymd8=", - "requires": { - "debug": "~2.6.8", - "notepack.io": "~2.1.2", - "redis": "~2.8.0", - "socket.io-adapter": "~1.1.0", - "uid2": "0.0.3" - } - }, "split": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", @@ -803,11 +759,6 @@ "mime-types": "~2.1.24" } }, - "uid2": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz", - "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I=" - }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -824,12 +775,9 @@ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, "ws": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz", - "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==", - "requires": { - "async-limiter": "~1.0.0" - } + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz", + "integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==" }, "xmlhttprequest-ssl": { "version": "1.5.5", From 69c11f95a3b6dc93f4d70d311241187181009661 Mon Sep 17 00:00:00 2001 From: Bret Fisher Date: Fri, 29 Jan 2021 16:47:09 -0500 Subject: [PATCH 04/41] update deps, add tini and curl, use COPY not ADD --- result/Dockerfile | 14 +++++++++++++- vote/Dockerfile | 12 +++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/result/Dockerfile b/result/Dockerfile index 4ab503bd54..ff635a25f9 100644 --- a/result/Dockerfile +++ b/result/Dockerfile @@ -1,7 +1,19 @@ FROM node:10-slim +# add curl for healthcheck +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + curl \ + && rm -rf /var/lib/apt/lists/* + +# Add Tini for proper init of signals +ENV TINI_VERSION v0.19.0 +ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini +RUN chmod +x /tini + WORKDIR /app +# have nodemon available for local dev use (file watching) RUN npm install -g nodemon COPY package*.json ./ @@ -16,4 +28,4 @@ ENV PORT 80 EXPOSE 80 -CMD ["node", "server.js"] +CMD ["/tini", "--", "node", "server.js"] diff --git a/vote/Dockerfile b/vote/Dockerfile index ad14ad92fb..9b04d669de 100644 --- a/vote/Dockerfile +++ b/vote/Dockerfile @@ -1,15 +1,21 @@ # Using official python runtime base image -FROM python:2.7-alpine +FROM python:3.9-slim + +# add curl for healthcheck +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + curl \ + && rm -rf /var/lib/apt/lists/* # Set the application directory WORKDIR /app # Install our requirements.txt -ADD requirements.txt /app/requirements.txt +COPY requirements.txt /app/requirements.txt RUN pip install -r requirements.txt # Copy our code from the current folder to /app inside the container -ADD . /app +COPY . . # Make port 80 available for links and/or publish EXPOSE 80 From 383b74158e66f1d2f2c35a06aa6a86b1e7445484 Mon Sep 17 00:00:00 2001 From: Bret Fisher Date: Fri, 29 Jan 2021 16:47:31 -0500 Subject: [PATCH 05/41] healthchecks! move to compose spec version! --- docker-compose.yml | 29 ++++++++++++++++++++++++----- healthchecks/postgres.sh | 21 +++++++++++++++++++++ healthchecks/redis.sh | 10 ++++++++++ 3 files changed, 55 insertions(+), 5 deletions(-) create mode 100755 healthchecks/postgres.sh create mode 100755 healthchecks/redis.sh diff --git a/docker-compose.yml b/docker-compose.yml index 1f39d53618..46f53d7cb0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,9 +1,15 @@ -version: "3" +# version is now using "compose spec" +# v2 and v3 are now combined! +# docker-compose v1.27+ required services: vote: build: ./vote + # use python rather than gunicorn for local dev command: python app.py + depends_on: + redis: + condition: service_healthy volumes: - ./vote:/app ports: @@ -14,7 +20,11 @@ services: result: build: ./result + # use nodemon rather than node for local dev command: nodemon server.js + depends_on: + db: + condition: service_healthy volumes: - ./result:/app ports: @@ -28,26 +38,35 @@ services: build: context: ./worker depends_on: - - "redis" - - "db" + redis: + condition: service_healthy + db: + condition: service_healthy networks: - back-tier redis: image: redis:5.0-alpine3.10 - container_name: redis + volumes: + - "./healthchecks:/healthchecks" + healthcheck: + test: /healthchecks/redis.sh + interval: "5s" ports: ["6379"] networks: - back-tier db: image: postgres:9.4 - container_name: db environment: POSTGRES_USER: "postgres" POSTGRES_PASSWORD: "postgres" volumes: - "db-data:/var/lib/postgresql/data" + - "./healthchecks:/healthchecks" + healthcheck: + test: /healthchecks/postgres.sh + interval: "5s" networks: - back-tier diff --git a/healthchecks/postgres.sh b/healthchecks/postgres.sh new file mode 100755 index 0000000000..299416740e --- /dev/null +++ b/healthchecks/postgres.sh @@ -0,0 +1,21 @@ +#!/bin/bash +set -eo pipefail + +host="$(hostname -i || echo '127.0.0.1')" +user="${POSTGRES_USER:-postgres}" +db="${POSTGRES_DB:-$POSTGRES_USER}" +export PGPASSWORD="${POSTGRES_PASSWORD:-}" + +args=( + # force postgres to not use the local unix socket (test "external" connectibility) + --host "$host" + --username "$user" + --dbname "$db" + --quiet --no-align --tuples-only +) + +if select="$(echo 'SELECT 1' | psql "${args[@]}")" && [ "$select" = '1' ]; then + exit 0 +fi + +exit 1 diff --git a/healthchecks/redis.sh b/healthchecks/redis.sh new file mode 100755 index 0000000000..3953758f94 --- /dev/null +++ b/healthchecks/redis.sh @@ -0,0 +1,10 @@ +#!/bin/sh +set -eo pipefail + +host="$(hostname -i || echo '127.0.0.1')" + +if ping="$(redis-cli -h "$host" ping)" && [ "$ping" = 'PONG' ]; then + exit 0 +fi + +exit 1 From af94bc5c089edc3fa99b0aed972f5daa3fd9f221 Mon Sep 17 00:00:00 2001 From: Bret Fisher Date: Fri, 29 Jan 2021 17:01:55 -0500 Subject: [PATCH 06/41] added new maintainers! --- MAINTAINERS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 628d7a8ab4..a7f9d7c983 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1,3 +1,7 @@ +Bret Fisher +Michael Irwin + +# Alumni, thanks for your work! Aanand Prasad Ben Firshman Fernando Mayo From d1920ed44a7ce2e81eb9be55d2778da4fb1ae276 Mon Sep 17 00:00:00 2001 From: Bret Fisher Date: Fri, 29 Jan 2021 17:06:20 -0500 Subject: [PATCH 07/41] added vote logging --- vote/app.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/vote/app.py b/vote/app.py index 1d194b649b..596546612a 100644 --- a/vote/app.py +++ b/vote/app.py @@ -4,6 +4,7 @@ import socket import random import json +import logging option_a = os.getenv('OPTION_A', "Cats") option_b = os.getenv('OPTION_B', "Dogs") @@ -11,6 +12,10 @@ app = Flask(__name__) +gunicorn_error_logger = logging.getLogger('gunicorn.error') +app.logger.handlers.extend(gunicorn_error_logger.handlers) +app.logger.setLevel(logging.INFO) + def get_redis(): if not hasattr(g, 'redis'): g.redis = Redis(host="redis", db=0, socket_timeout=5) @@ -27,6 +32,7 @@ def hello(): if request.method == 'POST': redis = get_redis() vote = request.form['vote'] + app.logger.info('Received vote for %s', vote) data = json.dumps({'voter_id': voter_id, 'vote': vote}) redis.rpush('votes', data) From a33c638b2fb619b1b325eae9a75b2308f26f1c13 Mon Sep 17 00:00:00 2001 From: Bret Fisher Date: Fri, 29 Jan 2021 17:38:20 -0500 Subject: [PATCH 08/41] adding data seeding Just run "docker-compose -f docker-compose.seed.yml up" to seed (you need to "docker-compose up -d" first) --- docker-compose.seed.yml | 9 +++++++++ seed-data/Dockerfile | 16 ++++++++++++++++ seed-data/generate-votes.sh | 6 ++++++ seed-data/make-data.py | 13 +++++++++++++ 4 files changed, 44 insertions(+) create mode 100644 docker-compose.seed.yml create mode 100644 seed-data/Dockerfile create mode 100755 seed-data/generate-votes.sh create mode 100644 seed-data/make-data.py diff --git a/docker-compose.seed.yml b/docker-compose.seed.yml new file mode 100644 index 0000000000..355c8570c2 --- /dev/null +++ b/docker-compose.seed.yml @@ -0,0 +1,9 @@ +services: + seed: + build: ./seed-data + networks: + - front-tier + restart: "no" + +networks: + front-tier: \ No newline at end of file diff --git a/seed-data/Dockerfile b/seed-data/Dockerfile new file mode 100644 index 0000000000..18e55e8429 --- /dev/null +++ b/seed-data/Dockerfile @@ -0,0 +1,16 @@ +FROM python:3.9-slim + +# add apache bench (ab) tool +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + apache2-utils \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /seed + +COPY . . + +# create POST data files with ab friendly formats +RUN python make-data.py + +CMD /seed/generate-votes.sh \ No newline at end of file diff --git a/seed-data/generate-votes.sh b/seed-data/generate-votes.sh new file mode 100755 index 0000000000..2f82563ccd --- /dev/null +++ b/seed-data/generate-votes.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +# create 3000 votes (2000 for option a, 1000 for option b) +ab -n 1000 -c 50 -p posta -T "application/x-www-form-urlencoded" http://vote/ +ab -n 1000 -c 50 -p postb -T "application/x-www-form-urlencoded" http://vote/ +ab -n 1000 -c 50 -p posta -T "application/x-www-form-urlencoded" http://vote/ diff --git a/seed-data/make-data.py b/seed-data/make-data.py new file mode 100644 index 0000000000..def9f9755d --- /dev/null +++ b/seed-data/make-data.py @@ -0,0 +1,13 @@ +# this creates urlencode-friendly files without EOL +import urllib.parse + +outfile = open('postb', 'w') +params = ({ 'vote': 'b' }) +encoded = urllib.parse.urlencode(params) +outfile.write(encoded) +outfile.close() +outfile = open('posta', 'w') +params = ({ 'vote': 'a' }) +encoded = urllib.parse.urlencode(params) +outfile.write(encoded) +outfile.close() From e433be5d16aa4ea3aa8384c96565f4c2cafd9ddc Mon Sep 17 00:00:00 2001 From: Bret Fisher Date: Fri, 29 Jan 2021 17:42:16 -0500 Subject: [PATCH 09/41] remove unused Jenkins --- Jenkinsfile | 54 ----------------------------------------------------- 1 file changed, 54 deletions(-) delete mode 100644 Jenkinsfile diff --git a/Jenkinsfile b/Jenkinsfile deleted file mode 100644 index 906f80ec2c..0000000000 --- a/Jenkinsfile +++ /dev/null @@ -1,54 +0,0 @@ -pipeline { - agent { - node { - label 'ubuntu-1604-aufs-stable' - } - } - stages { - stage('Build result') { - steps { - sh 'docker build -t dockersamples/result ./result' - } - } - stage('Build vote') { - steps { - sh 'docker build -t dockersamples/vote ./vote' - } - } - stage('Build worker') { - steps { - sh 'docker build -t dockersamples/worker ./worker' - } - } - stage('Push result image') { - when { - branch 'master' - } - steps { - withDockerRegistry(credentialsId: 'dockerbuildbot-index.docker.io', url:'') { - sh 'docker push dockersamples/result' - } - } - } - stage('Push vote image') { - when { - branch 'master' - } - steps { - withDockerRegistry(credentialsId: 'dockerbuildbot-index.docker.io', url:'') { - sh 'docker push dockersamples/vote' - } - } - } - stage('Push worker image') { - when { - branch 'master' - } - steps { - withDockerRegistry(credentialsId: 'dockerbuildbot-index.docker.io', url:'') { - sh 'docker push dockersamples/worker' - } - } - } - } -} \ No newline at end of file From 4553484152883d6c23e5a4b763395dd3a836e5e8 Mon Sep 17 00:00:00 2001 From: Stefan Scherer Date: Fri, 12 Feb 2021 18:28:07 +0100 Subject: [PATCH 10/41] Update dotnet 3.1 --- result/dotnet/Dockerfile.1809 | 4 ++-- vote/dotnet/Dockerfile.1809 | 4 ++-- worker/Dockerfile | 4 ++-- worker/dotnet/Dockerfile.1809 | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/result/dotnet/Dockerfile.1809 b/result/dotnet/Dockerfile.1809 index 8595143299..9020c04d76 100644 --- a/result/dotnet/Dockerfile.1809 +++ b/result/dotnet/Dockerfile.1809 @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/dotnet/core/sdk:2.1 as builder +FROM mcr.microsoft.com/dotnet/core/sdk:3.1 as builder WORKDIR /Result COPY Result/Result.csproj . @@ -8,7 +8,7 @@ COPY /Result . RUN dotnet publish -c Release -o /out Result.csproj # app image -FROM mcr.microsoft.com/dotnet/core/aspnet:2.1 +FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 WORKDIR /app ENTRYPOINT ["dotnet", "Result.dll"] diff --git a/vote/dotnet/Dockerfile.1809 b/vote/dotnet/Dockerfile.1809 index a4f8685b06..a4acef36fc 100644 --- a/vote/dotnet/Dockerfile.1809 +++ b/vote/dotnet/Dockerfile.1809 @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/dotnet/core/sdk:2.1 as builder +FROM mcr.microsoft.com/dotnet/core/sdk:3.1 as builder WORKDIR /Vote COPY Vote/Vote.csproj . @@ -8,7 +8,7 @@ COPY /Vote . RUN dotnet publish -c Release -o /out Vote.csproj # app image -FROM mcr.microsoft.com/dotnet/core/aspnet:2.1 +FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 WORKDIR /app ENTRYPOINT ["dotnet", "Vote.dll"] diff --git a/worker/Dockerfile b/worker/Dockerfile index 788a738803..89739f868a 100644 --- a/worker/Dockerfile +++ b/worker/Dockerfile @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/dotnet/core/sdk:2.1 as builder +FROM mcr.microsoft.com/dotnet/core/sdk:3.1 as builder WORKDIR /Worker COPY src/Worker/Worker.csproj . @@ -8,7 +8,7 @@ COPY src/Worker/ . RUN dotnet publish -c Release -o /out Worker.csproj # app image -FROM mcr.microsoft.com/dotnet/core/runtime:2.1 +FROM mcr.microsoft.com/dotnet/core/runtime:3.1 WORKDIR /app ENTRYPOINT ["dotnet", "Worker.dll"] diff --git a/worker/dotnet/Dockerfile.1809 b/worker/dotnet/Dockerfile.1809 index c5f52c3804..4f1b9d28ac 100644 --- a/worker/dotnet/Dockerfile.1809 +++ b/worker/dotnet/Dockerfile.1809 @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/dotnet/core/sdk:2.1 as builder +FROM mcr.microsoft.com/dotnet/core/sdk:3.1 as builder WORKDIR /Worker COPY Worker/Worker.csproj . @@ -8,7 +8,7 @@ COPY /Worker . RUN dotnet publish -c Release -o /out Worker.csproj # app image -FROM mcr.microsoft.com/dotnet/core/runtime:2.1 +FROM mcr.microsoft.com/dotnet/core/runtime:3.1 WORKDIR /app ENTRYPOINT ["dotnet", "Worker.dll"] From 89e063d04724ba9f514cd99b3f6a3c51cf6379fa Mon Sep 17 00:00:00 2001 From: Stefan Scherer Date: Wed, 5 May 2021 18:16:17 +0200 Subject: [PATCH 11/41] Update TargetFramework to 3.1 Signed-off-by: Stefan Scherer --- result/dotnet/Result/Result.csproj | 2 +- vote/dotnet/Vote/Vote.csproj | 2 +- worker/dotnet/Worker/Worker.csproj | 2 +- worker/src/Worker/Worker.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/result/dotnet/Result/Result.csproj b/result/dotnet/Result/Result.csproj index c004a5588b..d48265fc29 100644 --- a/result/dotnet/Result/Result.csproj +++ b/result/dotnet/Result/Result.csproj @@ -1,7 +1,7 @@ - netcoreapp2.1 + netcoreapp3.1 diff --git a/vote/dotnet/Vote/Vote.csproj b/vote/dotnet/Vote/Vote.csproj index 479b76eba6..3a80a2a8f8 100644 --- a/vote/dotnet/Vote/Vote.csproj +++ b/vote/dotnet/Vote/Vote.csproj @@ -1,7 +1,7 @@ - netcoreapp2.1 + netcoreapp3.1 diff --git a/worker/dotnet/Worker/Worker.csproj b/worker/dotnet/Worker/Worker.csproj index 46ec2dbcfd..d85a98c1a8 100644 --- a/worker/dotnet/Worker/Worker.csproj +++ b/worker/dotnet/Worker/Worker.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp2.1 + netcoreapp3.1 diff --git a/worker/src/Worker/Worker.csproj b/worker/src/Worker/Worker.csproj index 03d43df38c..88e9a90eda 100644 --- a/worker/src/Worker/Worker.csproj +++ b/worker/src/Worker/Worker.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp2.1 + netcoreapp3.1 From 19a15ef6a9b8c67d79e315d341c9177443874f08 Mon Sep 17 00:00:00 2001 From: Alirezaarabi Date: Mon, 25 Jul 2022 23:58:07 +0430 Subject: [PATCH 12/41] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2aeaac973b..bde7c9a3db 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ The Linux stack uses Python, Node.js, .NET Core (or optionally Java), with Redis Run in this directory: ``` -docker-compose up +docker compose up ``` The app will be running at [http://localhost:5000](http://localhost:5000), and the results will be at [http://localhost:5001](http://localhost:5001). @@ -37,13 +37,13 @@ An alternative version of the app uses Windows containers based on Nano Server. You can build from source using: ``` -docker-compose -f docker-compose-windows.yml build +docker compose -f docker-compose-windows.yml build ``` Then run the app using: ``` -docker-compose -f docker-compose-windows.yml up -d +docker compose -f docker-compose-windows.yml up -d ``` > Or in a Windows swarm, run `docker stack deploy -c docker-stack-windows.yml vote` From 5b2987f956baeef3064bc103a10f5b6e58fa7cc4 Mon Sep 17 00:00:00 2001 From: Bret Fisher Date: Fri, 2 Dec 2022 19:14:35 -0500 Subject: [PATCH 13/41] docker build gha init --- .github/dependabot.yml | 7 ++ .../workflows/call-docker-build-result.yaml | 83 +++++++++++++++++++ .github/workflows/call-docker-build-vote.yaml | 83 +++++++++++++++++++ .../workflows/call-docker-build-worker.yaml | 83 +++++++++++++++++++ 4 files changed, 256 insertions(+) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/call-docker-build-result.yaml create mode 100644 .github/workflows/call-docker-build-vote.yaml create mode 100644 .github/workflows/call-docker-build-worker.yaml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..f9ecf576e1 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +version: 2 +updates: + # Maintain dependencies for GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" diff --git a/.github/workflows/call-docker-build-result.yaml b/.github/workflows/call-docker-build-result.yaml new file mode 100644 index 0000000000..71201bd828 --- /dev/null +++ b/.github/workflows/call-docker-build-result.yaml @@ -0,0 +1,83 @@ +name: Build Result +# template source: https://github.com/dockersamples/.github/blob/main/templates/call-docker-build.yaml + +on: + # we want pull requests so we can build(test) but not push to image registry + push: + branches: + - 'main' + # only build when important files change + paths: + - 'result/**' + - '.github/workflows/call-docker-build-result.yaml' + pull_request: + branches: + - 'main' + # only build when important files change + paths: + - 'result/**' + - '.github/workflows/call-docker-build-result.yaml' + +jobs: + call-docker-build: + + name: Call Docker Build + + uses: dockersamples/.github/.github/workflows/reusable-docker-build.yaml@gha-reusable-init + + permissions: + contents: read + packages: write # needed to push docker image to ghcr.io + pull-requests: write # needed to create and update comments in PRs + + secrets: + + # Only needed if with:dockerhub-enable is true below + dockerhub-username: ${{ secrets.DOCKERHUB_USERNAME }} + + # Only needed if with:dockerhub-enable is true below + dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }} + + with: + + ### REQUIRED + ### ENABLE ONE OR BOTH REGISTRIES + ### tell docker where to push. + ### NOTE if Docker Hub is set to true, you must set secrets above and also add account/repo/tags below + dockerhub-enable: false + ghcr-enable: true + + ### REQUIRED + ### A list of the account/repo names for docker build. List should match what's enabled above + ### defaults to: + image-names: | + dockersamples/examplevotingapp_result + ghcr.io/dockersamples/example-voting-app-result + + ### REQUIRED set rules for tagging images, based on special action syntax: + ### https://github.com/docker/metadata-action#tags-input + ### defaults to: + tag-rules: | + type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }} + type=ref,event=pr + type=ref,event=branch + type=semver,pattern={{version}} + type=raw,value=gha-${{ github.run_id }} + + ### path to where docker should copy files into image + ### defaults to root of repository (.) + context: result + + ### Dockerfile alternate name. Default is Dockerfile (relative to context path) + # file: Containerfile + + ### build stage to target, defaults to empty, which builds to last stage in Dockerfile + # target: + + ### platforms to build for, defaults to linux/amd64 + ### other options: linux/amd64,linux/arm64,linux/arm/v7 + platforms: linux/amd64,linux/arm64,linux/arm/v7 + + ### Create a PR comment with image tags and labels + ### defaults to false + # comment-enable: false diff --git a/.github/workflows/call-docker-build-vote.yaml b/.github/workflows/call-docker-build-vote.yaml new file mode 100644 index 0000000000..d47c499f5d --- /dev/null +++ b/.github/workflows/call-docker-build-vote.yaml @@ -0,0 +1,83 @@ +name: Build Vote +# template source: https://github.com/dockersamples/.github/blob/main/templates/call-docker-build.yaml + +on: + # we want pull requests so we can build(test) but not push to image registry + push: + branches: + - 'main' + # only build when important files change + paths: + - 'vote/**' + - '.github/workflows/call-docker-build-vote.yaml' + pull_request: + branches: + - 'main' + # only build when important files change + paths: + - 'vote/**' + - '.github/workflows/call-docker-build-vote.yaml' + +jobs: + call-docker-build: + + name: Call Docker Build + + uses: dockersamples/.github/.github/workflows/reusable-docker-build.yaml@gha-reusable-init + + permissions: + contents: read + packages: write # needed to push docker image to ghcr.io + pull-requests: write # needed to create and update comments in PRs + + secrets: + + # Only needed if with:dockerhub-enable is true below + dockerhub-username: ${{ secrets.DOCKERHUB_USERNAME }} + + # Only needed if with:dockerhub-enable is true below + dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }} + + with: + + ### REQUIRED + ### ENABLE ONE OR BOTH REGISTRIES + ### tell docker where to push. + ### NOTE if Docker Hub is set to true, you must set secrets above and also add account/repo/tags below + dockerhub-enable: false + ghcr-enable: true + + ### REQUIRED + ### A list of the account/repo names for docker build. List should match what's enabled above + ### defaults to: + image-names: | + dockersamples/examplevotingapp_vote + ghcr.io/dockersamples/example-voting-app-vote + + ### REQUIRED set rules for tagging images, based on special action syntax: + ### https://github.com/docker/metadata-action#tags-input + ### defaults to: + # tag-rules: | + # type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }} + # type=ref,event=pr + # type=ref,event=branch + # type=semver,pattern={{version}} + # type=raw,value=gha-${{ github.run_id }} + + ### path to where docker should copy files into image + ### defaults to root of repository (.) + context: vote + + ### Dockerfile alternate name. Default is Dockerfile (relative to context path) + # file: Containerfile + + ### build stage to target, defaults to empty, which builds to last stage in Dockerfile + # target: + + ### platforms to build for, defaults to linux/amd64 + ### other options: linux/amd64,linux/arm64,linux/arm/v7 + platforms: linux/amd64,linux/arm64,linux/arm/v7 + + ### Create a PR comment with image tags and labels + ### defaults to false + # comment-enable: false diff --git a/.github/workflows/call-docker-build-worker.yaml b/.github/workflows/call-docker-build-worker.yaml new file mode 100644 index 0000000000..893788437a --- /dev/null +++ b/.github/workflows/call-docker-build-worker.yaml @@ -0,0 +1,83 @@ +name: Build Worker +# template source: https://github.com/dockersamples/.github/blob/main/templates/call-docker-build.yaml + +on: + # we want pull requests so we can build(test) but not push to image registry + push: + branches: + - 'main' + # only build when important files change + paths: + - 'worker/**' + - '.github/workflows/call-docker-build-worker.yaml' + pull_request: + branches: + - 'main' + # only build when important files change + paths: + - 'worker/**' + - '.github/workflows/call-docker-build-worker.yaml' + +jobs: + call-docker-build: + + name: Call Docker Build + + uses: dockersamples/.github/.github/workflows/reusable-docker-build.yaml@gha-reusable-init + + permissions: + contents: read + packages: write # needed to push docker image to ghcr.io + pull-requests: write # needed to create and update comments in PRs + + secrets: + + # Only needed if with:dockerhub-enable is true below + dockerhub-username: ${{ secrets.DOCKERHUB_USERNAME }} + + # Only needed if with:dockerhub-enable is true below + dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }} + + with: + + ### REQUIRED + ### ENABLE ONE OR BOTH REGISTRIES + ### tell docker where to push. + ### NOTE if Docker Hub is set to true, you must set secrets above and also add account/repo/tags below + dockerhub-enable: false + ghcr-enable: true + + ### REQUIRED + ### A list of the account/repo names for docker build. List should match what's enabled above + ### defaults to: + image-names: | + dockersamples/examplevotingapp_worker + ghcr.io/dockersamples/example-voting-app-worker + + ### REQUIRED set rules for tagging images, based on special action syntax: + ### https://github.com/docker/metadata-action#tags-input + ### defaults to: + # tag-rules: | + # type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }} + # type=ref,event=pr + # type=ref,event=branch + # type=semver,pattern={{version}} + # type=raw,value=gha-${{ github.run_id }} + + ### path to where docker should copy files into image + ### defaults to root of repository (.) + context: worker + + ### Dockerfile alternate name. Default is Dockerfile (relative to context path) + # file: Containerfile + + ### build stage to target, defaults to empty, which builds to last stage in Dockerfile + # target: + + ### platforms to build for, defaults to linux/amd64 + ### other options: linux/amd64,linux/arm64,linux/arm/v7 + platforms: linux/amd64,linux/arm64,linux/arm/v7 + + ### Create a PR comment with image tags and labels + ### defaults to false + # comment-enable: false From 91640194906e7015249b1f8af34c4625a1812c34 Mon Sep 17 00:00:00 2001 From: Bret Fisher Date: Sat, 3 Dec 2022 09:15:52 -0500 Subject: [PATCH 14/41] disable Hub until bot account works --- .github/workflows/call-docker-build-result.yaml | 4 ++-- .github/workflows/call-docker-build-vote.yaml | 4 ++-- .github/workflows/call-docker-build-worker.yaml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/call-docker-build-result.yaml b/.github/workflows/call-docker-build-result.yaml index 71201bd828..442bff8e36 100644 --- a/.github/workflows/call-docker-build-result.yaml +++ b/.github/workflows/call-docker-build-result.yaml @@ -51,9 +51,9 @@ jobs: ### A list of the account/repo names for docker build. List should match what's enabled above ### defaults to: image-names: | - dockersamples/examplevotingapp_result ghcr.io/dockersamples/example-voting-app-result - + # dockersamples/examplevotingapp_result + ### REQUIRED set rules for tagging images, based on special action syntax: ### https://github.com/docker/metadata-action#tags-input ### defaults to: diff --git a/.github/workflows/call-docker-build-vote.yaml b/.github/workflows/call-docker-build-vote.yaml index d47c499f5d..f8964b080e 100644 --- a/.github/workflows/call-docker-build-vote.yaml +++ b/.github/workflows/call-docker-build-vote.yaml @@ -51,9 +51,9 @@ jobs: ### A list of the account/repo names for docker build. List should match what's enabled above ### defaults to: image-names: | - dockersamples/examplevotingapp_vote ghcr.io/dockersamples/example-voting-app-vote - + # dockersamples/examplevotingapp_vote + ### REQUIRED set rules for tagging images, based on special action syntax: ### https://github.com/docker/metadata-action#tags-input ### defaults to: diff --git a/.github/workflows/call-docker-build-worker.yaml b/.github/workflows/call-docker-build-worker.yaml index 893788437a..4f8f2aca60 100644 --- a/.github/workflows/call-docker-build-worker.yaml +++ b/.github/workflows/call-docker-build-worker.yaml @@ -51,9 +51,9 @@ jobs: ### A list of the account/repo names for docker build. List should match what's enabled above ### defaults to: image-names: | - dockersamples/examplevotingapp_worker ghcr.io/dockersamples/example-voting-app-worker - + # dockersamples/examplevotingapp_worker + ### REQUIRED set rules for tagging images, based on special action syntax: ### https://github.com/docker/metadata-action#tags-input ### defaults to: From db6f956bbde3a53ee525a995b9aea3b25a2f19a0 Mon Sep 17 00:00:00 2001 From: Erjan Gavalji Date: Thu, 8 Dec 2022 11:29:50 +0200 Subject: [PATCH 15/41] Fix the case of losing a vote when actual vote found in Redis and db connection was closed --- worker/src/Worker/Program.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/worker/src/Worker/Program.cs b/worker/src/Worker/Program.cs index e6c66d28b2..58fd7ac7fc 100644 --- a/worker/src/Worker/Program.cs +++ b/worker/src/Worker/Program.cs @@ -48,10 +48,8 @@ public static int Main(string[] args) Console.WriteLine("Reconnecting DB"); pgsql = OpenDbConnection("Server=db;Username=postgres;Password=postgres;"); } - else - { // Normal +1 vote requested - UpdateVote(pgsql, vote.voter_id, vote.vote); - } + // Normal +1 vote requested + UpdateVote(pgsql, vote.voter_id, vote.vote); } else { From 88d04ef0854791068deb5f144b862238f5231178 Mon Sep 17 00:00:00 2001 From: Bret Fisher Date: Fri, 9 Dec 2022 15:57:14 -0500 Subject: [PATCH 16/41] updating GHA paths --- .github/workflows/call-docker-build-result.yaml | 4 ++-- .github/workflows/call-docker-build-vote.yaml | 4 ++-- .github/workflows/call-docker-build-worker.yaml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/call-docker-build-result.yaml b/.github/workflows/call-docker-build-result.yaml index 442bff8e36..acc3c21edc 100644 --- a/.github/workflows/call-docker-build-result.yaml +++ b/.github/workflows/call-docker-build-result.yaml @@ -21,9 +21,9 @@ on: jobs: call-docker-build: - name: Call Docker Build + name: Result Call Docker Build - uses: dockersamples/.github/.github/workflows/reusable-docker-build.yaml@gha-reusable-init + uses: dockersamples/.github/.github/workflows/reusable-docker-build.yaml@main permissions: contents: read diff --git a/.github/workflows/call-docker-build-vote.yaml b/.github/workflows/call-docker-build-vote.yaml index f8964b080e..af8dbe734d 100644 --- a/.github/workflows/call-docker-build-vote.yaml +++ b/.github/workflows/call-docker-build-vote.yaml @@ -21,9 +21,9 @@ on: jobs: call-docker-build: - name: Call Docker Build + name: Vote Call Docker Build - uses: dockersamples/.github/.github/workflows/reusable-docker-build.yaml@gha-reusable-init + uses: dockersamples/.github/.github/workflows/reusable-docker-build.yaml@main permissions: contents: read diff --git a/.github/workflows/call-docker-build-worker.yaml b/.github/workflows/call-docker-build-worker.yaml index 4f8f2aca60..94cce546ce 100644 --- a/.github/workflows/call-docker-build-worker.yaml +++ b/.github/workflows/call-docker-build-worker.yaml @@ -21,9 +21,9 @@ on: jobs: call-docker-build: - name: Call Docker Build + name: Worker Call Docker Build - uses: dockersamples/.github/.github/workflows/reusable-docker-build.yaml@gha-reusable-init + uses: dockersamples/.github/.github/workflows/reusable-docker-build.yaml@main permissions: contents: read From 6f953ce289161eac95d0ad24761d66edcf24aa49 Mon Sep 17 00:00:00 2001 From: Bret Fisher Date: Fri, 9 Dec 2022 16:18:40 -0500 Subject: [PATCH 17/41] enable docker hub --- .github/workflows/call-docker-build-result.yaml | 2 +- .github/workflows/call-docker-build-vote.yaml | 2 +- .github/workflows/call-docker-build-worker.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/call-docker-build-result.yaml b/.github/workflows/call-docker-build-result.yaml index acc3c21edc..a869ecd975 100644 --- a/.github/workflows/call-docker-build-result.yaml +++ b/.github/workflows/call-docker-build-result.yaml @@ -44,7 +44,7 @@ jobs: ### ENABLE ONE OR BOTH REGISTRIES ### tell docker where to push. ### NOTE if Docker Hub is set to true, you must set secrets above and also add account/repo/tags below - dockerhub-enable: false + dockerhub-enable: true ghcr-enable: true ### REQUIRED diff --git a/.github/workflows/call-docker-build-vote.yaml b/.github/workflows/call-docker-build-vote.yaml index af8dbe734d..3c8f57f55e 100644 --- a/.github/workflows/call-docker-build-vote.yaml +++ b/.github/workflows/call-docker-build-vote.yaml @@ -44,7 +44,7 @@ jobs: ### ENABLE ONE OR BOTH REGISTRIES ### tell docker where to push. ### NOTE if Docker Hub is set to true, you must set secrets above and also add account/repo/tags below - dockerhub-enable: false + dockerhub-enable: true ghcr-enable: true ### REQUIRED diff --git a/.github/workflows/call-docker-build-worker.yaml b/.github/workflows/call-docker-build-worker.yaml index 94cce546ce..2c5f9f962f 100644 --- a/.github/workflows/call-docker-build-worker.yaml +++ b/.github/workflows/call-docker-build-worker.yaml @@ -44,7 +44,7 @@ jobs: ### ENABLE ONE OR BOTH REGISTRIES ### tell docker where to push. ### NOTE if Docker Hub is set to true, you must set secrets above and also add account/repo/tags below - dockerhub-enable: false + dockerhub-enable: true ghcr-enable: true ### REQUIRED From 5a23ae2245a040a91b2131156dd17df6b8dece9d Mon Sep 17 00:00:00 2001 From: Bret Fisher Date: Fri, 9 Dec 2022 16:47:00 -0500 Subject: [PATCH 18/41] disable worker arm/v7 support for now --- .github/workflows/call-docker-build-worker.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/call-docker-build-worker.yaml b/.github/workflows/call-docker-build-worker.yaml index 2c5f9f962f..c10d9c6e09 100644 --- a/.github/workflows/call-docker-build-worker.yaml +++ b/.github/workflows/call-docker-build-worker.yaml @@ -76,7 +76,9 @@ jobs: ### platforms to build for, defaults to linux/amd64 ### other options: linux/amd64,linux/arm64,linux/arm/v7 - platforms: linux/amd64,linux/arm64,linux/arm/v7 + # FIXME worker arm/v7 support doesn't build in .net core 3.1 with QEMU + # a fix would likely run the .net build on amd64 but with a target of arm/v7 + platforms: linux/amd64,linux/arm64 ### Create a PR comment with image tags and labels ### defaults to false From 3ccc624fd7085238b3c9740ab8b39acde3c749d0 Mon Sep 17 00:00:00 2001 From: Bret Fisher Date: Fri, 9 Dec 2022 17:56:20 -0500 Subject: [PATCH 19/41] update result node.js deps for multi-arch --- docker-compose.yml | 2 +- result/Dockerfile | 12 +- result/package-lock.json | 1586 ++++++++++++++++++++++++++++++++------ result/package.json | 4 +- 4 files changed, 1362 insertions(+), 242 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 46f53d7cb0..197d657151 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -21,7 +21,7 @@ services: result: build: ./result # use nodemon rather than node for local dev - command: nodemon server.js + entrypoint: nodemon server.js depends_on: db: condition: service_healthy diff --git a/result/Dockerfile b/result/Dockerfile index ff635a25f9..4f7f4bcf79 100644 --- a/result/Dockerfile +++ b/result/Dockerfile @@ -1,16 +1,12 @@ -FROM node:10-slim +FROM node:18-slim # add curl for healthcheck RUN apt-get update \ && apt-get install -y --no-install-recommends \ curl \ + tini \ && rm -rf /var/lib/apt/lists/* -# Add Tini for proper init of signals -ENV TINI_VERSION v0.19.0 -ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini -RUN chmod +x /tini - WORKDIR /app # have nodemon available for local dev use (file watching) @@ -25,7 +21,7 @@ RUN npm ci \ COPY . . ENV PORT 80 - EXPOSE 80 -CMD ["/tini", "--", "node", "server.js"] +ENTRYPOINT ["/usr/bin/tini", "--"] +CMD ["node", "server.js"] diff --git a/result/package-lock.json b/result/package-lock.json index e879f96601..5a5fdd4c27 100644 --- a/result/package-lock.json +++ b/result/package-lock.json @@ -1,27 +1,1104 @@ { "name": "result", "version": "1.0.0", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "result", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "async": "^3.1.0", + "body-parser": "^1.19.0", + "cookie-parser": "^1.4.4", + "express": "^4.17.1", + "method-override": "^3.0.0", + "pg": "^8.8.0", + "socket.io": "^2.5.0", + "stoppable": "^1.1.0" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha512-QbJ0NTQ/I9DI3uSJA4cbexiwQeRAfjPScqIbSjUDd9TOrcg6pTkdgziesOqxBMBzit8vFCTwrP27t13vFOORRA==" + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==" + }, + "node_modules/async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + }, + "node_modules/backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==" + }, + "node_modules/base64-arraybuffer": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", + "integrity": "sha512-a1eIFi4R9ySrbiMuyTGx5e92uRH5tQY6kArNcFaKBUleIoLjdjBg7Zxm3Mqm3Kmkf27HLR/1fnxX9q8GQ7Iavg==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, + "node_modules/blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==" + }, + "node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/buffer-writer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha512-WZveuKPeKAG9qY+FkYDeADzdHyTYdIboXS59ixDeRJL5ZhxpqUnxSOwop4FQjMsiYm3/Or8cegVbpAHNA7pHxw==" + }, + "node_modules/component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, + "node_modules/component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha512-w+LhYREhatpVqTESyGFg3NlP6Iu0kEKUHETY9GoZP/pQyW4mHFZuFWRUCIqVPZ36ueVLtoOEZaAqbCF2RDndaA==" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-parser": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz", + "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==", + "dependencies": { + "cookie": "0.4.1", + "cookie-signature": "1.0.6" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/engine.io": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.6.1.tgz", + "integrity": "sha512-dfs8EVg/i7QjFsXxn7cCRQ+Wai1G1TlEvHhdYEi80fxn5R1vZ2K661O6v/rezj1FP234SZ14r9CmJke99iYDGg==", + "dependencies": { + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "debug": "~4.1.0", + "engine.io-parser": "~2.2.0", + "ws": "~7.4.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/engine.io-client": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.3.tgz", + "integrity": "sha512-qsgyc/CEhJ6cgMUwxRRtOndGVhIu5hpL5tR4umSpmX/MvkFoIxUTM7oFMDQumHNzlNLwSVy6qhstFPoWTf7dOw==", + "dependencies": { + "component-emitter": "~1.3.0", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.2.0", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "ws": "~7.4.2", + "xmlhttprequest-ssl": "~1.6.2", + "yeast": "0.1.2" + } + }, + "node_modules/engine.io-client/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/engine.io-parser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.1.tgz", + "integrity": "sha512-x+dN/fBH8Ro8TFwJ+rkB2AmuVw9Yu2mockR/p3W8f8YtExwFgDvBDi0GWyb4ZLkpahtDGZgtr3zLovanJghPqg==", + "dependencies": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.4", + "blob": "0.0.5", + "has-binary2": "~1.0.2" + } + }, + "node_modules/engine.io/node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/engine.io/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==" + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/get-intrinsic": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "dependencies": { + "isarray": "2.0.1" + } + }, + "node_modules/has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha512-g5VNKdkFuUuVCP9gYfDJHjK2nqdQJ7aDLTnycnc2+RvsOQbuLdF5pm7vuE5J76SEBIQjs4kQY/BWq74JUmjbXA==" + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha512-i0G7hLJ1z0DE8dsqJa2rycj9dBmNKgXBvotXtZYXakU9oivfB9Uj2ZBC27qqef2U58/ZLwalxa1X/RDCdkHtVg==" + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/method-override": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/method-override/-/method-override-3.0.0.tgz", + "integrity": "sha512-IJ2NNN/mSl9w3kzWB92rcdHpz+HjkxhDJWNDBqSlas+zQdP8wBiJzITPg08M/k2uVvMow7Sk41atndNtt/PHSA==", + "dependencies": { + "debug": "3.1.0", + "methods": "~1.1.2", + "parseurl": "~1.3.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/method-override/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "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==", + "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==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/packet-reader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" + }, + "node_modules/parseqs": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz", + "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==" + }, + "node_modules/parseuri": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz", + "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==" + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/pg": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.8.0.tgz", + "integrity": "sha512-UXYN0ziKj+AeNNP7VDMwrehpACThH7LUl/p8TDFpEUuSejCUIwGSfxpHsPvtM6/WXFy6SU4E5RG4IJV/TZAGjw==", + "dependencies": { + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-connection-string": "^2.5.0", + "pg-pool": "^3.5.2", + "pg-protocol": "^1.5.0", + "pg-types": "^2.1.0", + "pgpass": "1.x" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-connection-string": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", + "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-pool": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.5.2.tgz", + "integrity": "sha512-His3Fh17Z4eg7oANLob6ZvH8xIVen3phEZh2QuyrIl4dQSDVEabNducv6ysROKpDNPSD+12tONZVWfSgMvDD9w==", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.5.0.tgz", + "integrity": "sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ==" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "dependencies": { + "split2": "^4.1.0" + } + }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "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==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/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==" + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/socket.io": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.5.0.tgz", + "integrity": "sha512-gGunfS0od3VpwDBpGwVkzSZx6Aqo9uOcf1afJj2cKnKFAoyl16fvhpsUhmUFd4Ldbvl5JvRQed6eQw6oQp6n8w==", + "dependencies": { + "debug": "~4.1.0", + "engine.io": "~3.6.0", + "has-binary2": "~1.0.2", + "socket.io-adapter": "~1.1.0", + "socket.io-client": "2.5.0", + "socket.io-parser": "~3.4.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz", + "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==" + }, + "node_modules/socket.io-client": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.5.0.tgz", + "integrity": "sha512-lOO9clmdgssDykiOmVQQitwBAF3I6mYcQAo7hQ7AM6Ny5X7fp8hIJ3HcQs3Rjz4SoggoxA1OgrQyY8EgTbcPYw==", + "dependencies": { + "backo2": "1.0.2", + "component-bind": "1.0.0", + "component-emitter": "~1.3.0", + "debug": "~3.1.0", + "engine.io-client": "~3.5.0", + "has-binary2": "~1.0.2", + "indexof": "0.0.1", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "socket.io-parser": "~3.3.0", + "to-array": "0.1.4" + } + }, + "node_modules/socket.io-client/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/socket.io-client/node_modules/socket.io-parser": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.3.tgz", + "integrity": "sha512-qOg87q1PMWWTeO01768Yh9ogn7chB9zkKtQnya41Y355S0UmpXgpcrFwAgjYJxu9BdKug5r5e9YtVSeWhKBUZg==", + "dependencies": { + "component-emitter": "~1.3.0", + "debug": "~3.1.0", + "isarray": "2.0.1" + } + }, + "node_modules/socket.io-parser": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.2.tgz", + "integrity": "sha512-QFZBaZDNqZXeemwejc7D39jrq2eGK/qZuVDiMPKzZK1hLlNvjGilGt4ckfQZeVX4dGmuPzCytN9ZW1nQlEWjgA==", + "dependencies": { + "component-emitter": "1.2.1", + "debug": "~4.1.0", + "isarray": "2.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser/node_modules/component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha512-jPatnhd33viNplKjqXKRkGU345p263OIWzDL2wH3LGIGp5Kojo+uXizHmOADRvhGFFTnJqX3jBAKP6vvmSDKcA==" + }, + "node_modules/socket.io-parser/node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/socket.io-parser/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==" + }, + "node_modules/socket.io/node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/socket.io/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==" + }, + "node_modules/split2": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.1.0.tgz", + "integrity": "sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ==", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stoppable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", + "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==", + "engines": { + "node": ">=4", + "npm": ">=6" + } + }, + "node_modules/to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha512-LhVdShQD/4Mk4zXNroIQZJC+Ap3zgLcDuwEdcmLv9CCO73NWockQDwyUnW/m8VX/EElfL6FcYx7EeutN4HJA6A==" + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xmlhttprequest-ssl": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz", + "integrity": "sha512-3XfeQE/wNkvrIktn2Kf0869fC0BN6UpydVasGIeSm2B1Llihf7/0UfZM+eCkOw3P7bP4+qPgqhm7ZoxuJtFU0Q==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha512-8HFIh676uyGYP6wP13R/j6OJ/1HwJ46snpvzE7aHAN3Ryqh2yX6Xox2B4CUmTwwOIzlG3Bs7ocsP5dZH/R1Qbg==" + } + }, "dependencies": { "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" } }, "after": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", - "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=" + "integrity": "sha512-QbJ0NTQ/I9DI3uSJA4cbexiwQeRAfjPScqIbSjUDd9TOrcg6pTkdgziesOqxBMBzit8vFCTwrP27t13vFOORRA==" }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, "arraybuffer.slice": { "version": "0.0.7", @@ -29,19 +1106,19 @@ "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==" }, "async": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/async/-/async-3.1.0.tgz", - "integrity": "sha512-4vx/aaY6j/j3Lw3fbCHNWP0pPaTCew3F6F3hYyl/tHs/ndmV1q7NW9T5yuJ2XAGwdQrP+6Wu20x06U4APo/iQQ==" + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" }, "backo2": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" + "integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==" }, "base64-arraybuffer": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", - "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=" + "integrity": "sha512-a1eIFi4R9ySrbiMuyTGx5e92uRH5tQY6kArNcFaKBUleIoLjdjBg7Zxm3Mqm3Kmkf27HLR/1fnxX9q8GQ7Iavg==" }, "base64id": { "version": "2.0.0", @@ -54,20 +1131,22 @@ "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==" }, "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "requires": { - "bytes": "3.1.0", + "bytes": "3.1.2", "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" } }, "buffer-writer": { @@ -76,14 +1155,23 @@ "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==" }, "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } }, "component-bind": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", - "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=" + "integrity": "sha512-WZveuKPeKAG9qY+FkYDeADzdHyTYdIboXS59ixDeRJL5ZhxpqUnxSOwop4FQjMsiYm3/Or8cegVbpAHNA7pHxw==" }, "component-emitter": { "version": "1.3.0", @@ -93,14 +1181,14 @@ "component-inherit": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", - "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=" + "integrity": "sha512-w+LhYREhatpVqTESyGFg3NlP6Iu0kEKUHETY9GoZP/pQyW4mHFZuFWRUCIqVPZ36ueVLtoOEZaAqbCF2RDndaA==" }, "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "requires": { - "safe-buffer": "5.1.2" + "safe-buffer": "5.2.1" } }, "content-type": { @@ -109,23 +1197,23 @@ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" }, "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" }, "cookie-parser": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.4.tgz", - "integrity": "sha512-lo13tqF3JEtFO7FyA49CqbhaFkskRJ0u/UAiINgrIXeRCY41c88/zxtrECl8AKH3B0hj9q10+h3Kt8I7KlW4tw==", + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz", + "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==", "requires": { - "cookie": "0.3.1", + "cookie": "0.4.1", "cookie-signature": "1.0.6" } }, "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "debug": { "version": "2.6.9", @@ -136,29 +1224,29 @@ } }, "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" }, "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" }, "engine.io": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.5.0.tgz", - "integrity": "sha512-21HlvPUKaitDGE4GXNtQ7PLP0Sz4aWLddMPw2VTyFz1FVZqu/kZsJUO8WNpKuE/OCL7nkfRaOui2ZCJloGznGA==", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.6.1.tgz", + "integrity": "sha512-dfs8EVg/i7QjFsXxn7cCRQ+Wai1G1TlEvHhdYEi80fxn5R1vZ2K661O6v/rezj1FP234SZ14r9CmJke99iYDGg==", "requires": { "accepts": "~1.3.4", "base64id": "2.0.0", @@ -168,11 +1256,6 @@ "ws": "~7.4.2" }, "dependencies": { - "cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" - }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -189,9 +1272,9 @@ } }, "engine.io-client": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.0.tgz", - "integrity": "sha512-12wPRfMrugVw/DNyJk34GQ5vIVArEcVMXWugQGGuw2XxUSztFNmJggZmv8IZlLyEdnpO1QB9LkcjeWewO2vxtA==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.3.tgz", + "integrity": "sha512-qsgyc/CEhJ6cgMUwxRRtOndGVhIu5hpL5tR4umSpmX/MvkFoIxUTM7oFMDQumHNzlNLwSVy6qhstFPoWTf7dOw==", "requires": { "component-emitter": "~1.3.0", "component-inherit": "0.0.3", @@ -202,7 +1285,7 @@ "parseqs": "0.0.6", "parseuri": "0.0.6", "ws": "~7.4.2", - "xmlhttprequest-ssl": "~1.5.4", + "xmlhttprequest-ssl": "~1.6.2", "yeast": "0.1.2" }, "dependencies": { @@ -231,80 +1314,104 @@ "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" }, "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "requires": { - "accepts": "~1.3.7", + "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.4.0", + "cookie": "0.5.0", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "~1.1.2", + "depd": "2.0.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "~1.1.2", + "finalhandler": "1.2.0", "fresh": "0.5.2", + "http-errors": "2.0.0", "merge-descriptors": "1.0.1", "methods": "~1.1.2", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" }, "dependencies": { "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" } } }, "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "requires": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", - "statuses": "~1.5.0", + "statuses": "2.0.1", "unpipe": "~1.0.0" } }, "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" }, "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "get-intrinsic": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } }, "has-binary2": { "version": "1.0.3", @@ -317,18 +1424,23 @@ "has-cors": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", - "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" + "integrity": "sha512-g5VNKdkFuUuVCP9gYfDJHjK2nqdQJ7aDLTnycnc2+RvsOQbuLdF5pm7vuE5J76SEBIQjs4kQY/BWq74JUmjbXA==" + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" }, "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" } }, "iconv-lite": { @@ -342,32 +1454,32 @@ "indexof": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" + "integrity": "sha512-i0G7hLJ1z0DE8dsqJa2rycj9dBmNKgXBvotXtZYXakU9oivfB9Uj2ZBC27qqef2U58/ZLwalxa1X/RDCdkHtVg==" }, "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ipaddr.js": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", - "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, "isarray": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==" }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, "method-override": { "version": "3.0.0", @@ -393,7 +1505,7 @@ "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" }, "mime": { "version": "1.6.0", @@ -401,32 +1513,37 @@ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" }, "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" }, "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "requires": { - "mime-db": "1.40.0" + "mime-db": "1.52.0" } }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" + }, + "object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" }, "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "requires": { "ee-first": "1.1.1" } @@ -454,26 +1571,26 @@ "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, "pg": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/pg/-/pg-7.12.1.tgz", - "integrity": "sha512-l1UuyfEvoswYfcUe6k+JaxiN+5vkOgYcVSbSuw3FvdLqDbaoa2RJo1zfJKfPsSYPFVERd4GHvX3s2PjG1asSDA==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.8.0.tgz", + "integrity": "sha512-UXYN0ziKj+AeNNP7VDMwrehpACThH7LUl/p8TDFpEUuSejCUIwGSfxpHsPvtM6/WXFy6SU4E5RG4IJV/TZAGjw==", "requires": { "buffer-writer": "2.0.0", "packet-reader": "1.0.0", - "pg-connection-string": "0.1.3", - "pg-pool": "^2.0.4", + "pg-connection-string": "^2.5.0", + "pg-pool": "^3.5.2", + "pg-protocol": "^1.5.0", "pg-types": "^2.1.0", - "pgpass": "1.x", - "semver": "4.3.2" + "pgpass": "1.x" } }, "pg-connection-string": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-0.1.3.tgz", - "integrity": "sha1-2hhHsglA5C7hSSvq9l1J2RskXfc=" + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", + "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" }, "pg-int8": { "version": "1.0.1", @@ -481,9 +1598,15 @@ "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" }, "pg-pool": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-2.0.7.tgz", - "integrity": "sha512-UiJyO5B9zZpu32GSlP0tXy8J2NsJ9EFGFfz5v6PSbdz/1hBLX1rNiiy5+mAm5iJJYwfCv4A0EBcQLGWwjbpzZw==" + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.5.2.tgz", + "integrity": "sha512-His3Fh17Z4eg7oANLob6ZvH8xIVen3phEZh2QuyrIl4dQSDVEabNducv6ysROKpDNPSD+12tONZVWfSgMvDD9w==", + "requires": {} + }, + "pg-protocol": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.5.0.tgz", + "integrity": "sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ==" }, "pg-types": { "version": "2.2.0", @@ -498,11 +1621,11 @@ } }, "pgpass": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.2.tgz", - "integrity": "sha1-Knu0G2BltnkH6R2hsHwYR8h3swY=", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", "requires": { - "split": "^1.0.0" + "split2": "^4.1.0" } }, "postgres-array": { @@ -513,12 +1636,12 @@ "postgres-bytea": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", - "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=" + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==" }, "postgres-date": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.4.tgz", - "integrity": "sha512-bESRvKVuTrjoBluEcpv2346+6kgB7UlnqWZsnbnCccTNq/pqfj1j6oBaN5+b/NrDXepYUT/HKadqv3iS9lJuVA==" + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==" }, "postgres-interval": { "version": "1.2.0", @@ -529,18 +1652,21 @@ } }, "proxy-addr": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", - "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.0" + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" } }, "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "requires": { + "side-channel": "^1.0.4" + } }, "range-parser": { "version": "1.2.1", @@ -548,84 +1674,89 @@ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", + "bytes": "3.1.2", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" } }, "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "semver": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.2.tgz", - "integrity": "sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c=" - }, "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "requires": { "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", + "depd": "2.0.0", + "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "~1.7.2", + "http-errors": "2.0.0", "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", + "ms": "2.1.3", + "on-finished": "2.4.1", "range-parser": "~1.2.1", - "statuses": "~1.5.0" + "statuses": "2.0.1" }, "dependencies": { "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" } } }, "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "requires": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.17.1" + "send": "0.18.0" } }, "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } }, "socket.io": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.4.0.tgz", - "integrity": "sha512-9UPJ1UTvKayuQfVv2IQ3k7tCQC/fboDyIK62i99dAQIyHKaBsNdTpwHLgKJ6guRWxRtC9H+138UwpaGuQO9uWQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.5.0.tgz", + "integrity": "sha512-gGunfS0od3VpwDBpGwVkzSZx6Aqo9uOcf1afJj2cKnKFAoyl16fvhpsUhmUFd4Ldbvl5JvRQed6eQw6oQp6n8w==", "requires": { "debug": "~4.1.0", - "engine.io": "~3.5.0", + "engine.io": "~3.6.0", "has-binary2": "~1.0.2", "socket.io-adapter": "~1.1.0", - "socket.io-client": "2.4.0", + "socket.io-client": "2.5.0", "socket.io-parser": "~3.4.0" }, "dependencies": { @@ -650,9 +1781,9 @@ "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==" }, "socket.io-client": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.4.0.tgz", - "integrity": "sha512-M6xhnKQHuuZd4Ba9vltCLT9oa+YvTsP8j9NcEiLElfIg8KeYPyhWOes6x4t+LTAC8enQbE/995AdTem2uNyKKQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.5.0.tgz", + "integrity": "sha512-lOO9clmdgssDykiOmVQQitwBAF3I6mYcQAo7hQ7AM6Ny5X7fp8hIJ3HcQs3Rjz4SoggoxA1OgrQyY8EgTbcPYw==", "requires": { "backo2": "1.0.2", "component-bind": "1.0.0", @@ -676,9 +1807,9 @@ } }, "socket.io-parser": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.2.tgz", - "integrity": "sha512-FJvDBuOALxdCI9qwRrO/Rfp9yfndRtc1jSgVgV8FDraihmSP/MLGD5PEuJrNfjALvcQ+vMDM/33AWOYP/JSjDg==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.3.tgz", + "integrity": "sha512-qOg87q1PMWWTeO01768Yh9ogn7chB9zkKtQnya41Y355S0UmpXgpcrFwAgjYJxu9BdKug5r5e9YtVSeWhKBUZg==", "requires": { "component-emitter": "~1.3.0", "debug": "~3.1.0", @@ -688,9 +1819,9 @@ } }, "socket.io-parser": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.1.tgz", - "integrity": "sha512-11hMgzL+WCLWf1uFtHSNvliI++tcRUWdoeYuwIl+Axvwy9z2gQM+7nJyN3STj1tLj5JyIUH8/gpDGxzAlDdi0A==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.2.tgz", + "integrity": "sha512-QFZBaZDNqZXeemwejc7D39jrq2eGK/qZuVDiMPKzZK1hLlNvjGilGt4ckfQZeVX4dGmuPzCytN9ZW1nQlEWjgA==", "requires": { "component-emitter": "1.2.1", "debug": "~4.1.0", @@ -700,7 +1831,7 @@ "component-emitter": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + "integrity": "sha512-jPatnhd33viNplKjqXKRkGU345p263OIWzDL2wH3LGIGp5Kojo+uXizHmOADRvhGFFTnJqX3jBAKP6vvmSDKcA==" }, "debug": { "version": "4.1.1", @@ -717,38 +1848,30 @@ } } }, - "split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", - "requires": { - "through": "2" - } + "split2": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.1.0.tgz", + "integrity": "sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ==" }, "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" }, "stoppable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==" }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, "to-array": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", - "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=" + "integrity": "sha512-LhVdShQD/4Mk4zXNroIQZJC+Ap3zgLcDuwEdcmLv9CCO73NWockQDwyUnW/m8VX/EElfL6FcYx7EeutN4HJA6A==" }, "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" }, "type-is": { "version": "1.6.18", @@ -762,27 +1885,28 @@ "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" }, "ws": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz", - "integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==" + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "requires": {} }, "xmlhttprequest-ssl": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", - "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=" + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz", + "integrity": "sha512-3XfeQE/wNkvrIktn2Kf0869fC0BN6UpydVasGIeSm2B1Llihf7/0UfZM+eCkOw3P7bP4+qPgqhm7ZoxuJtFU0Q==" }, "xtend": { "version": "4.0.2", @@ -792,7 +1916,7 @@ "yeast": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", - "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" + "integrity": "sha512-8HFIh676uyGYP6wP13R/j6OJ/1HwJ46snpvzE7aHAN3Ryqh2yX6Xox2B4CUmTwwOIzlG3Bs7ocsP5dZH/R1Qbg==" } } } diff --git a/result/package.json b/result/package.json index 53a37e57d8..2d20641f58 100644 --- a/result/package.json +++ b/result/package.json @@ -14,8 +14,8 @@ "cookie-parser": "^1.4.4", "express": "^4.17.1", "method-override": "^3.0.0", - "pg": "^7.12.1", - "socket.io": "^2.2.0", + "pg": "^8.8.0", + "socket.io": "^2.5.0", "stoppable": "^1.1.0" } } From 7e7445a6010659f40ce150c145b695fc77081a91 Mon Sep 17 00:00:00 2001 From: Michael Irwin Date: Fri, 16 Dec 2022 17:27:32 -0500 Subject: [PATCH 20/41] Clean up worker service (#272) * Remove Java project from worker * Update .NET Core and remove old dotnet codebase from worker service * Remove Windows-based Compose files and info from README * Update .NET to 7.0 --- README.md | 24 +---- docker-compose-javaworker.yml | 57 ---------- docker-compose-windows-1809.yml | 48 --------- docker-compose-windows.yml | 45 -------- docker-stack-windows-1809.yml | 49 --------- docker-stack-windows.yml | 61 ----------- worker/.classpath | 44 -------- worker/.project | 23 ---- .../.settings/org.eclipse.jdt.apt.core.prefs | 2 - worker/.settings/org.eclipse.jdt.core.prefs | 7 -- worker/.settings/org.eclipse.m2e.core.prefs | 4 - worker/Dockerfile | 38 +++++-- worker/Dockerfile.j | 17 --- worker/{src/Worker => }/Program.cs | 8 +- worker/Worker.csproj | 14 +++ worker/dotnet/Dockerfile | 16 --- worker/dotnet/Dockerfile.1809 | 16 --- worker/dotnet/Worker/Data/IVoteData.cs | 7 -- worker/dotnet/Worker/Data/MySqlVoteData.cs | 35 ------ worker/dotnet/Worker/Entities/Vote.cs | 16 --- worker/dotnet/Worker/Entities/VoteContext.cs | 19 ---- .../dotnet/Worker/Messaging/IMessageQueue.cs | 12 --- .../dotnet/Worker/Messaging/MessageHelper.cs | 23 ---- .../dotnet/Worker/Messaging/MessageQueue.cs | 35 ------ .../Messages/Events/VoteCastEvent.cs | 15 --- .../Worker/Messaging/Messages/Message.cs | 16 --- worker/dotnet/Worker/Program.cs | 39 ------- worker/dotnet/Worker/Worker.csproj | 30 ------ worker/dotnet/Worker/Workers/QueueWorker.cs | 62 ----------- worker/dotnet/Worker/appsettings.json | 14 --- worker/pom.xml | 84 --------------- worker/src/Worker/Worker.csproj | 14 --- worker/src/main/java/worker/Worker.java | 102 ------------------ worker/target/classes/worker/Worker.class | Bin 4102 -> 0 bytes 34 files changed, 48 insertions(+), 948 deletions(-) delete mode 100644 docker-compose-javaworker.yml delete mode 100644 docker-compose-windows-1809.yml delete mode 100644 docker-compose-windows.yml delete mode 100644 docker-stack-windows-1809.yml delete mode 100644 docker-stack-windows.yml delete mode 100644 worker/.classpath delete mode 100644 worker/.project delete mode 100644 worker/.settings/org.eclipse.jdt.apt.core.prefs delete mode 100644 worker/.settings/org.eclipse.jdt.core.prefs delete mode 100644 worker/.settings/org.eclipse.m2e.core.prefs delete mode 100644 worker/Dockerfile.j rename worker/{src/Worker => }/Program.cs (96%) create mode 100644 worker/Worker.csproj delete mode 100644 worker/dotnet/Dockerfile delete mode 100644 worker/dotnet/Dockerfile.1809 delete mode 100644 worker/dotnet/Worker/Data/IVoteData.cs delete mode 100644 worker/dotnet/Worker/Data/MySqlVoteData.cs delete mode 100644 worker/dotnet/Worker/Entities/Vote.cs delete mode 100644 worker/dotnet/Worker/Entities/VoteContext.cs delete mode 100644 worker/dotnet/Worker/Messaging/IMessageQueue.cs delete mode 100644 worker/dotnet/Worker/Messaging/MessageHelper.cs delete mode 100644 worker/dotnet/Worker/Messaging/MessageQueue.cs delete mode 100644 worker/dotnet/Worker/Messaging/Messages/Events/VoteCastEvent.cs delete mode 100644 worker/dotnet/Worker/Messaging/Messages/Message.cs delete mode 100644 worker/dotnet/Worker/Program.cs delete mode 100644 worker/dotnet/Worker/Worker.csproj delete mode 100644 worker/dotnet/Worker/Workers/QueueWorker.cs delete mode 100644 worker/dotnet/Worker/appsettings.json delete mode 100644 worker/pom.xml delete mode 100644 worker/src/Worker/Worker.csproj delete mode 100644 worker/src/main/java/worker/Worker.java delete mode 100644 worker/target/classes/worker/Worker.class diff --git a/README.md b/README.md index bde7c9a3db..4e5fc23e59 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Download [Docker Desktop](https://www.docker.com/products/docker-desktop) for Ma ## Linux Containers -The Linux stack uses Python, Node.js, .NET Core (or optionally Java), with Redis for messaging and Postgres for storage. +The Linux stack uses Python, Node.js, .NET Core, with Redis for messaging and Postgres for storage. > If you're using [Docker Desktop on Windows](https://store.docker.com/editions/community/docker-ce-desktop-windows), you can run the Linux version by [switching to Linux containers](https://docs.docker.com/docker-for-windows/#switch-between-windows-and-linux-containers), or run the Windows containers version. @@ -30,26 +30,6 @@ Once you have your swarm, in this directory run: docker stack deploy --compose-file docker-stack.yml vote ``` -## Windows Containers - -An alternative version of the app uses Windows containers based on Nano Server. This stack runs on .NET Core, using [NATS](https://nats.io) for messaging and [TiDB](https://github.com/pingcap/tidb) for storage. - -You can build from source using: - -``` -docker compose -f docker-compose-windows.yml build -``` - -Then run the app using: - -``` -docker compose -f docker-compose-windows.yml up -d -``` - -> Or in a Windows swarm, run `docker stack deploy -c docker-stack-windows.yml vote` - -The app will be running at [http://localhost:5000](http://localhost:5000), and the results will be at [http://localhost:5001](http://localhost:5001). - Run the app in Kubernetes ------------------------- @@ -85,7 +65,7 @@ Architecture * A front-end web app in [Python](/vote) or [ASP.NET Core](/vote/dotnet) which lets you vote between two options * A [Redis](https://hub.docker.com/_/redis/) or [NATS](https://hub.docker.com/_/nats/) queue which collects new votes -* A [.NET Core](/worker/src/Worker), [Java](/worker/src/main) or [.NET Core 2.1](/worker/dotnet) worker which consumes votes and stores them in… +* A [.NET Core](/worker/) worker which consumes votes and stores them in… * A [Postgres](https://hub.docker.com/_/postgres/) or [TiDB](https://hub.docker.com/r/dockersamples/tidb/tags/) database backed by a Docker volume * A [Node.js](/result) or [ASP.NET Core SignalR](/result/dotnet) webapp which shows the results of the voting in real time diff --git a/docker-compose-javaworker.yml b/docker-compose-javaworker.yml deleted file mode 100644 index 544865b986..0000000000 --- a/docker-compose-javaworker.yml +++ /dev/null @@ -1,57 +0,0 @@ -version: "3" - -services: - vote: - build: ./vote - command: python app.py - volumes: - - ./vote:/app - ports: - - "5000:80" - networks: - - front-tier - - back-tier - - result: - build: ./result - command: nodemon server.js - volumes: - - ./result:/app - ports: - - "5001:80" - - "5858:5858" - networks: - - front-tier - - back-tier - - worker: - build: - context: ./worker - dockerfile: Dockerfile.j - networks: - - back-tier - - redis: - image: redis:alpine - container_name: redis - ports: ["6379"] - networks: - - back-tier - - db: - image: postgres:9.4 - container_name: db - environment: - POSTGRES_USER: "postgres" - POSTGRES_PASSWORD: "postgres" - volumes: - - "db-data:/var/lib/postgresql/data" - networks: - - back-tier - -volumes: - db-data: - -networks: - front-tier: - back-tier: diff --git a/docker-compose-windows-1809.yml b/docker-compose-windows-1809.yml deleted file mode 100644 index 8c5c11e44b..0000000000 --- a/docker-compose-windows-1809.yml +++ /dev/null @@ -1,48 +0,0 @@ -version: "3.2" - -services: - vote: - image: dockersamples/examplevotingapp_vote:dotnet-nanoserver-1809 - build: - context: ./vote/dotnet - dockerfile: Dockerfile.1809 - ports: - - "5000:80" - depends_on: - - message-queue - - result: - image: dockersamples/examplevotingapp_result:dotnet-nanoserver-1809 - build: - context: ./result/dotnet - dockerfile: Dockerfile.1809 - ports: - - "5001:80" - environment: - - "ConnectionStrings:ResultData=Server=db;Port=4000;Database=votes;User=root;SslMode=None" - depends_on: - - db - - worker: - image: dockersamples/examplevotingapp_worker:dotnet-nanoserver-1809 - build: - context: ./worker/dotnet - dockerfile: Dockerfile.1809 - environment: - - "ConnectionStrings:VoteData=Server=db;Port=4000;Database=votes;User=root;SslMode=None" - depends_on: - - message-queue - - db - - message-queue: - image: nats:2.0.4 - - db: - image: dockersamples/tidb:nanoserver-1809 - ports: - - "3306:4000" - -networks: - default: - external: - name: nat diff --git a/docker-compose-windows.yml b/docker-compose-windows.yml deleted file mode 100644 index 40372381b7..0000000000 --- a/docker-compose-windows.yml +++ /dev/null @@ -1,45 +0,0 @@ -version: "3.2" - -services: - vote: - image: dockersamples/examplevotingapp_vote:dotnet-nanoserver-sac2016 - build: - context: ./vote/dotnet - ports: - - "5000:80" - depends_on: - - message-queue - - result: - image: dockersamples/examplevotingapp_result:dotnet-nanoserver-sac2016 - build: - context: ./result/dotnet - ports: - - "5001:80" - environment: - - "ConnectionStrings:ResultData=Server=db;Port=4000;Database=votes;User=root;SslMode=None" - depends_on: - - db - - worker: - image: dockersamples/examplevotingapp_worker:dotnet-nanoserver-sac2016 - build: - context: ./worker/dotnet - environment: - - "ConnectionStrings:VoteData=Server=db;Port=4000;Database=votes;User=root;SslMode=None" - depends_on: - - message-queue - - db - - message-queue: - image: nats:nanoserver - - db: - image: dockersamples/tidb:nanoserver - ports: - - "3306:4000" - -networks: - default: - external: - name: nat \ No newline at end of file diff --git a/docker-stack-windows-1809.yml b/docker-stack-windows-1809.yml deleted file mode 100644 index 20017023ef..0000000000 --- a/docker-stack-windows-1809.yml +++ /dev/null @@ -1,49 +0,0 @@ -version: "3.2" - -services: - vote: - image: dockersamples/examplevotingapp_vote:dotnet-nanoserver-1809 - ports: - - "5000:80" - deploy: - mode: replicated - replicas: 4 - networks: - - frontend - - backend - - result: - image: dockersamples/examplevotingapp_result:dotnet-nanoserver-1809 - environment: - - "ConnectionStrings:ResultData=Server=db;Port=4000;Database=votes;User=root;SslMode=None" - ports: - - "5001:80" - networks: - - frontend - - backend - - worker: - image: dockersamples/examplevotingapp_worker:dotnet-nanoserver-1809 - environment: - - "ConnectionStrings:VoteData=Server=db;Port=4000;Database=votes;User=root;SslMode=None" - deploy: - mode: replicated - replicas: 3 - networks: - - backend - - message-queue: - image: dockersamples/nats:nanoserver-1809 - networks: - - backend - - db: - image: dockersamples/tidb:nanoserver-1809 - ports: - - "3306:4000" - networks: - - backend - -networks: - frontend: - backend: \ No newline at end of file diff --git a/docker-stack-windows.yml b/docker-stack-windows.yml deleted file mode 100644 index 1cd6e81b72..0000000000 --- a/docker-stack-windows.yml +++ /dev/null @@ -1,61 +0,0 @@ -version: "3.2" - -services: - vote: - image: dockersamples/examplevotingapp_vote:dotnet-nanoserver-sac2016 - ports: - - mode: host - target: 80 - published: 5000 - deploy: - endpoint_mode: dnsrr - networks: - - frontend - - backend - - result: - image: dockersamples/examplevotingapp_result:dotnet-nanoserver-sac2016 - environment: - - "ConnectionStrings:ResultData=Server=db;Port=4000;Database=votes;User=root;SslMode=None" - ports: - - mode: host - target: 80 - published: 5001 - deploy: - endpoint_mode: dnsrr - networks: - - frontend - - backend - - worker: - image: dockersamples/examplevotingapp_worker:dotnet-nanoserver-sac2016 - environment: - - "ConnectionStrings:VoteData=Server=db;Port=4000;Database=votes;User=root;SslMode=None" - deploy: - endpoint_mode: dnsrr - mode: replicated - replicas: 3 - networks: - - backend - - message-queue: - image: nats:nanoserver - deploy: - endpoint_mode: dnsrr - networks: - - backend - - db: - image: dockersamples/tidb:nanoserver - ports: - - mode: host - target: 4000 - published: 3306 - deploy: - endpoint_mode: dnsrr - networks: - - backend - -networks: - frontend: - backend: \ No newline at end of file diff --git a/worker/.classpath b/worker/.classpath deleted file mode 100644 index 71f5fefe42..0000000000 --- a/worker/.classpath +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/worker/.project b/worker/.project deleted file mode 100644 index 49e0d9af10..0000000000 --- a/worker/.project +++ /dev/null @@ -1,23 +0,0 @@ - - - worker - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.m2e.core.maven2Nature - - diff --git a/worker/.settings/org.eclipse.jdt.apt.core.prefs b/worker/.settings/org.eclipse.jdt.apt.core.prefs deleted file mode 100644 index d4313d4b25..0000000000 --- a/worker/.settings/org.eclipse.jdt.apt.core.prefs +++ /dev/null @@ -1,2 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.apt.aptEnabled=false diff --git a/worker/.settings/org.eclipse.jdt.core.prefs b/worker/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 1eb325ec7e..0000000000 --- a/worker/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,7 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 -org.eclipse.jdt.core.compiler.compliance=1.7 -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.processAnnotations=disabled -org.eclipse.jdt.core.compiler.release=disabled -org.eclipse.jdt.core.compiler.source=1.7 diff --git a/worker/.settings/org.eclipse.m2e.core.prefs b/worker/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f1cb..0000000000 --- a/worker/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/worker/Dockerfile b/worker/Dockerfile index 89739f868a..b53da1b89d 100644 --- a/worker/Dockerfile +++ b/worker/Dockerfile @@ -1,16 +1,32 @@ -FROM mcr.microsoft.com/dotnet/core/sdk:3.1 as builder +# because of dotnet, we always build on amd64, and target platforms in cli +# dotnet doesn't support QEMU for building or running. +# (errors common in arm/v7 32bit) https://github.com/dotnet/dotnet-docker/issues/1537 +# https://hub.docker.com/_/microsoft-dotnet +# hadolint ignore=DL3029 +FROM --platform=${BUILDPLATFORM} mcr.microsoft.com/dotnet/sdk:7.0 as build +ARG TARGETPLATFORM +ARG BUILDPLATFORM +RUN echo "I am running on $BUILDPLATFORM, building for $TARGETPLATFORM" -WORKDIR /Worker -COPY src/Worker/Worker.csproj . -RUN dotnet restore +WORKDIR /source +COPY *.csproj . +RUN case ${TARGETPLATFORM} in \ + "linux/amd64") ARCH=x64 ;; \ + "linux/arm64") ARCH=arm64 ;; \ + "linux/arm/v7") ARCH=arm ;; \ + esac \ + && dotnet restore -r linux-${ARCH} -COPY src/Worker/ . -RUN dotnet publish -c Release -o /out Worker.csproj +COPY . . +RUN case ${TARGETPLATFORM} in \ + "linux/amd64") ARCH=x64 ;; \ + "linux/arm64") ARCH=arm64 ;; \ + "linux/arm/v7") ARCH=arm ;; \ + esac \ + && dotnet publish -c release -o /app -r linux-${ARCH} --self-contained false --no-restore # app image -FROM mcr.microsoft.com/dotnet/core/runtime:3.1 - +FROM mcr.microsoft.com/dotnet/runtime:7.0 WORKDIR /app -ENTRYPOINT ["dotnet", "Worker.dll"] - -COPY --from=builder /out . \ No newline at end of file +COPY --from=build /app . +ENTRYPOINT ["dotnet", "Worker.dll"] \ No newline at end of file diff --git a/worker/Dockerfile.j b/worker/Dockerfile.j deleted file mode 100644 index 85c33a5e9e..0000000000 --- a/worker/Dockerfile.j +++ /dev/null @@ -1,17 +0,0 @@ -FROM maven:3.5-jdk-8-alpine AS build - -WORKDIR /code - -COPY pom.xml /code/pom.xml -RUN ["mvn", "dependency:resolve"] -RUN ["mvn", "verify"] - -# Adding source, compile and package into a fat jar -COPY ["src/main", "/code/src/main"] -RUN ["mvn", "package"] - -FROM openjdk:8-jre-alpine - -COPY --from=build /code/target/worker-jar-with-dependencies.jar / - -CMD ["java", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseCGroupMemoryLimitForHeap", "-jar", "/worker-jar-with-dependencies.jar"] diff --git a/worker/src/Worker/Program.cs b/worker/Program.cs similarity index 96% rename from worker/src/Worker/Program.cs rename to worker/Program.cs index 58fd7ac7fc..9b5fb74d1a 100644 --- a/worker/src/Worker/Program.cs +++ b/worker/Program.cs @@ -48,8 +48,10 @@ public static int Main(string[] args) Console.WriteLine("Reconnecting DB"); pgsql = OpenDbConnection("Server=db;Username=postgres;Password=postgres;"); } - // Normal +1 vote requested - UpdateVote(pgsql, vote.voter_id, vote.vote); + else + { // Normal +1 vote requested + UpdateVote(pgsql, vote.voter_id, vote.vote); + } } else { @@ -149,4 +151,4 @@ private static void UpdateVote(NpgsqlConnection connection, string voterId, stri } } } -} +} \ No newline at end of file diff --git a/worker/Worker.csproj b/worker/Worker.csproj new file mode 100644 index 0000000000..00845078ef --- /dev/null +++ b/worker/Worker.csproj @@ -0,0 +1,14 @@ + + + + Exe + net7.0 + + + + + + + + + \ No newline at end of file diff --git a/worker/dotnet/Dockerfile b/worker/dotnet/Dockerfile deleted file mode 100644 index f87478ebb2..0000000000 --- a/worker/dotnet/Dockerfile +++ /dev/null @@ -1,16 +0,0 @@ -FROM microsoft/dotnet:2.1-sdk-nanoserver-sac2016 as builder - -WORKDIR /Worker -COPY Worker/Worker.csproj . -RUN dotnet restore - -COPY /Worker . -RUN dotnet publish -c Release -o /out Worker.csproj - -# app image -FROM microsoft/dotnet:2.1-runtime-nanoserver-sac2016 - -WORKDIR /app -ENTRYPOINT ["dotnet", "Worker.dll"] - -COPY --from=builder /out . \ No newline at end of file diff --git a/worker/dotnet/Dockerfile.1809 b/worker/dotnet/Dockerfile.1809 deleted file mode 100644 index 4f1b9d28ac..0000000000 --- a/worker/dotnet/Dockerfile.1809 +++ /dev/null @@ -1,16 +0,0 @@ -FROM mcr.microsoft.com/dotnet/core/sdk:3.1 as builder - -WORKDIR /Worker -COPY Worker/Worker.csproj . -RUN dotnet restore - -COPY /Worker . -RUN dotnet publish -c Release -o /out Worker.csproj - -# app image -FROM mcr.microsoft.com/dotnet/core/runtime:3.1 - -WORKDIR /app -ENTRYPOINT ["dotnet", "Worker.dll"] - -COPY --from=builder /out . \ No newline at end of file diff --git a/worker/dotnet/Worker/Data/IVoteData.cs b/worker/dotnet/Worker/Data/IVoteData.cs deleted file mode 100644 index b0e67cb4ac..0000000000 --- a/worker/dotnet/Worker/Data/IVoteData.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Worker.Data -{ - public interface IVoteData - { - void Set(string voterId, string vote); - } -} \ No newline at end of file diff --git a/worker/dotnet/Worker/Data/MySqlVoteData.cs b/worker/dotnet/Worker/Data/MySqlVoteData.cs deleted file mode 100644 index 46ce13116b..0000000000 --- a/worker/dotnet/Worker/Data/MySqlVoteData.cs +++ /dev/null @@ -1,35 +0,0 @@ -using Microsoft.Extensions.Logging; -using Worker.Entities; - -namespace Worker.Data -{ - public class MySqlVoteData : IVoteData - { - private readonly VoteContext _context; - private readonly ILogger _logger; - - public MySqlVoteData(VoteContext context, ILogger logger) - { - _context = context; - _logger = logger; - } - - public void Set(string voterId, string vote) - { - var currentVote = _context.Votes.Find(voterId); - if (currentVote == null) - { - _context.Votes.Add(new Vote - { - VoterId = voterId, - VoteOption = vote - }); - } - else if (currentVote.VoteOption != vote) - { - currentVote.VoteOption = vote; - } - _context.SaveChanges(); - } - } -} \ No newline at end of file diff --git a/worker/dotnet/Worker/Entities/Vote.cs b/worker/dotnet/Worker/Entities/Vote.cs deleted file mode 100644 index 72a66ca39e..0000000000 --- a/worker/dotnet/Worker/Entities/Vote.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; - -namespace Worker.Entities -{ - [Table("votes")] - public class Vote - { - [Column("id")] - [Key] - public string VoterId { get; set; } - - [Column("vote")] - public string VoteOption { get; set; } - } -} diff --git a/worker/dotnet/Worker/Entities/VoteContext.cs b/worker/dotnet/Worker/Entities/VoteContext.cs deleted file mode 100644 index cdd61e725e..0000000000 --- a/worker/dotnet/Worker/Entities/VoteContext.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Microsoft.EntityFrameworkCore; - -namespace Worker.Entities -{ - public class VoteContext : DbContext - { - private static bool _EnsureCreated; - public VoteContext(DbContextOptions options) : base(options) - { - if (!_EnsureCreated) - { - Database.EnsureCreated(); - _EnsureCreated = true; - } - } - - public DbSet Votes { get; set; } - } -} diff --git a/worker/dotnet/Worker/Messaging/IMessageQueue.cs b/worker/dotnet/Worker/Messaging/IMessageQueue.cs deleted file mode 100644 index 8c81029b5c..0000000000 --- a/worker/dotnet/Worker/Messaging/IMessageQueue.cs +++ /dev/null @@ -1,12 +0,0 @@ -using NATS.Client; -using Worker.Messaging.Messages; - -namespace Worker.Messaging -{ - public interface IMessageQueue - { - IConnection CreateConnection(); - - void Publish(TMessage message) where TMessage : Message; - } -} \ No newline at end of file diff --git a/worker/dotnet/Worker/Messaging/MessageHelper.cs b/worker/dotnet/Worker/Messaging/MessageHelper.cs deleted file mode 100644 index 909166b44c..0000000000 --- a/worker/dotnet/Worker/Messaging/MessageHelper.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Newtonsoft.Json; -using Worker.Messaging.Messages; -using System.Text; - -namespace Worker.Messaging -{ - public class MessageHelper - { - public static byte[] ToData(TMessage message) - where TMessage : Message - { - var json = JsonConvert.SerializeObject(message); - return Encoding.Unicode.GetBytes(json); - } - - public static TMessage FromData(byte[] data) - where TMessage : Message - { - var json = Encoding.Unicode.GetString(data); - return (TMessage)JsonConvert.DeserializeObject(json); - } - } -} diff --git a/worker/dotnet/Worker/Messaging/MessageQueue.cs b/worker/dotnet/Worker/Messaging/MessageQueue.cs deleted file mode 100644 index 639497ea8d..0000000000 --- a/worker/dotnet/Worker/Messaging/MessageQueue.cs +++ /dev/null @@ -1,35 +0,0 @@ -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; -using NATS.Client; -using Worker.Messaging.Messages; - -namespace Worker.Messaging -{ - public class MessageQueue : IMessageQueue - { - protected readonly IConfiguration _configuration; - protected readonly ILogger _logger; - - public MessageQueue(IConfiguration configuration, ILogger logger) - { - _configuration = configuration; - _logger = logger; - } - - public void Publish(TMessage message) - where TMessage : Message - { - using (var connection = CreateConnection()) - { - var data = MessageHelper.ToData(message); - connection.Publish(message.Subject, data); - } - } - - public IConnection CreateConnection() - { - var url = _configuration.GetValue("MessageQueue:Url"); - return new ConnectionFactory().CreateConnection(url); - } - } -} diff --git a/worker/dotnet/Worker/Messaging/Messages/Events/VoteCastEvent.cs b/worker/dotnet/Worker/Messaging/Messages/Events/VoteCastEvent.cs deleted file mode 100644 index a9f6755b68..0000000000 --- a/worker/dotnet/Worker/Messaging/Messages/Events/VoteCastEvent.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace Worker.Messaging.Messages -{ - public class VoteCastEvent : Message - { - public override string Subject { get { return MessageSubject; } } - - public string VoterId {get; set;} - - public string Vote {get; set; } - - public static string MessageSubject = "events.vote.votecast"; - } -} \ No newline at end of file diff --git a/worker/dotnet/Worker/Messaging/Messages/Message.cs b/worker/dotnet/Worker/Messaging/Messages/Message.cs deleted file mode 100644 index 6265fee9ae..0000000000 --- a/worker/dotnet/Worker/Messaging/Messages/Message.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; - -namespace Worker.Messaging.Messages -{ - public abstract class Message - { - public string CorrelationId { get; set; } - - public abstract string Subject { get; } - - public Message() - { - CorrelationId = Guid.NewGuid().ToString(); - } - } -} diff --git a/worker/dotnet/Worker/Program.cs b/worker/dotnet/Worker/Program.cs deleted file mode 100644 index 2f0e5990b6..0000000000 --- a/worker/dotnet/Worker/Program.cs +++ /dev/null @@ -1,39 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using System; -using Worker.Data; -using Worker.Entities; -using Worker.Messaging; -using Worker.Workers; - -namespace Worker -{ - class Program - { - static void Main(string[] args) - { - var config = new ConfigurationBuilder() - .AddJsonFile("appsettings.json") - .AddEnvironmentVariables() - .Build(); - - var loggerFactory = new LoggerFactory() - .AddConsole(); - - var services = new ServiceCollection() - .AddSingleton(loggerFactory) - .AddLogging() - .AddSingleton(config) - .AddTransient() - .AddTransient() - .AddSingleton() - .AddDbContext(builder => builder.UseMySQL(config.GetConnectionString("VoteData"))); - - var provider = services.BuildServiceProvider(); - var worker = provider.GetService(); - worker.Start(); - } - } -} diff --git a/worker/dotnet/Worker/Worker.csproj b/worker/dotnet/Worker/Worker.csproj deleted file mode 100644 index d85a98c1a8..0000000000 --- a/worker/dotnet/Worker/Worker.csproj +++ /dev/null @@ -1,30 +0,0 @@ - - - - Exe - netcoreapp3.1 - - - - - - - - - PreserveNewest - PreserveNewest - - - - - - - - - - - - - - - diff --git a/worker/dotnet/Worker/Workers/QueueWorker.cs b/worker/dotnet/Worker/Workers/QueueWorker.cs deleted file mode 100644 index cd62c45c63..0000000000 --- a/worker/dotnet/Worker/Workers/QueueWorker.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Threading; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; -using NATS.Client; -using Worker.Data; -using Worker.Messaging; -using Worker.Messaging.Messages; - -namespace Worker.Workers -{ - public class QueueWorker - { - private static ManualResetEvent _ResetEvent = new ManualResetEvent(false); - private const string QUEUE_GROUP = "save-handler"; - - private readonly IMessageQueue _messageQueue; - private readonly IConfiguration _config; - private readonly IVoteData _data; - protected readonly ILogger _logger; - - public QueueWorker(IMessageQueue messageQueue, IVoteData data, IConfiguration config, ILogger logger) - { - _messageQueue = messageQueue; - _data = data; - _config = config; - _logger = logger; - } - - public void Start() - { - _logger.LogInformation($"Connecting to message queue url: {_config.GetValue("MessageQueue:Url")}"); - using (var connection = _messageQueue.CreateConnection()) - { - var subscription = connection.SubscribeAsync(VoteCastEvent.MessageSubject, QUEUE_GROUP); - subscription.MessageHandler += SaveVote; - subscription.Start(); - _logger.LogInformation($"Listening on subject: {VoteCastEvent.MessageSubject}, queue: {QUEUE_GROUP}"); - - _ResetEvent.WaitOne(); - connection.Close(); - } - } - - private void SaveVote(object sender, MsgHandlerEventArgs e) - { - _logger.LogDebug($"Received message, subject: {e.Message.Subject}"); - var voteMessage = MessageHelper.FromData(e.Message.Data); - _logger.LogInformation($"Processing vote for '{voteMessage.Vote}' by '{voteMessage.VoterId}'"); - try - { - _data.Set(voteMessage.VoterId, voteMessage.Vote); - _logger.LogDebug($"Succesffuly processed vote by '{voteMessage.VoterId}'"); - } - catch (Exception ex) - { - _logger.LogError($"Vote processing FAILED for '{voteMessage.VoterId}', exception: {ex}"); - } - - } - } -} \ No newline at end of file diff --git a/worker/dotnet/Worker/appsettings.json b/worker/dotnet/Worker/appsettings.json deleted file mode 100644 index ecdb339833..0000000000 --- a/worker/dotnet/Worker/appsettings.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "MessageQueue": { - "Url": "nats://message-queue:4222" - }, - "ConnectionStrings": { - "VoteData": "Server=mysql;Port=4000;Database=votes;User=root;SslMode=None" - }, - "Logging": { - "LogLevel": { - "Default": "Information" - } - }, - "AllowedHosts": "*" -} diff --git a/worker/pom.xml b/worker/pom.xml deleted file mode 100644 index 1fea098797..0000000000 --- a/worker/pom.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - 4.0.0 - - worker - worker - 1.0-SNAPSHOT - - - - - org.json - json - 20140107 - - - - redis.clients - jedis - 2.7.2 - jar - compile - - - - org.postgresql - postgresql - 9.4-1200-jdbc41 - - - - - - - org.apache.maven.plugins - maven-jar-plugin - 2.4 - - worker - - - true - worker.Worker - dependency-jars/ - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.1 - - 1.7 - 1.7 - - - - org.apache.maven.plugins - maven-assembly-plugin - - - - attached - - package - - worker - - jar-with-dependencies - - - - worker.Worker - - - - - - - - - diff --git a/worker/src/Worker/Worker.csproj b/worker/src/Worker/Worker.csproj deleted file mode 100644 index 88e9a90eda..0000000000 --- a/worker/src/Worker/Worker.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - - Exe - netcoreapp3.1 - - - - - - - - - \ No newline at end of file diff --git a/worker/src/main/java/worker/Worker.java b/worker/src/main/java/worker/Worker.java deleted file mode 100644 index 8121430cd7..0000000000 --- a/worker/src/main/java/worker/Worker.java +++ /dev/null @@ -1,102 +0,0 @@ -package worker; - -import redis.clients.jedis.Jedis; -import redis.clients.jedis.exceptions.JedisConnectionException; -import java.sql.*; -import org.json.JSONObject; - -class Worker { - public static void main(String[] args) { - try { - Jedis redis = connectToRedis("redis"); - Connection dbConn = connectToDB("db"); - - System.err.println("Watching vote queue"); - - while (true) { - String voteJSON = redis.blpop(0, "votes").get(1); - JSONObject voteData = new JSONObject(voteJSON); - String voterID = voteData.getString("voter_id"); - String vote = voteData.getString("vote"); - - System.err.printf("Processing vote for '%s' by '%s'\n", vote, voterID); - updateVote(dbConn, voterID, vote); - } - } catch (SQLException e) { - e.printStackTrace(); - System.exit(1); - } - } - - static void updateVote(Connection dbConn, String voterID, String vote) throws SQLException { - PreparedStatement insert = dbConn.prepareStatement( - "INSERT INTO votes (id, vote) VALUES (?, ?)"); - insert.setString(1, voterID); - insert.setString(2, vote); - - try { - insert.executeUpdate(); - } catch (SQLException e) { - PreparedStatement update = dbConn.prepareStatement( - "UPDATE votes SET vote = ? WHERE id = ?"); - update.setString(1, vote); - update.setString(2, voterID); - update.executeUpdate(); - } - } - - static Jedis connectToRedis(String host) { - Jedis conn = new Jedis(host); - - while (true) { - try { - conn.keys("*"); - break; - } catch (JedisConnectionException e) { - System.err.println("Waiting for redis"); - sleep(1000); - } - } - - System.err.println("Connected to redis"); - return conn; - } - - static Connection connectToDB(String host) throws SQLException { - Connection conn = null; - - try { - - Class.forName("org.postgresql.Driver"); - String url = "jdbc:postgresql://" + host + "/postgres"; - - while (conn == null) { - try { - conn = DriverManager.getConnection(url, "postgres", "postgres"); - } catch (SQLException e) { - System.err.println("Waiting for db"); - sleep(1000); - } - } - - PreparedStatement st = conn.prepareStatement( - "CREATE TABLE IF NOT EXISTS votes (id VARCHAR(255) NOT NULL UNIQUE, vote VARCHAR(255) NOT NULL)"); - st.executeUpdate(); - - } catch (ClassNotFoundException e) { - e.printStackTrace(); - System.exit(1); - } - - System.err.println("Connected to db"); - return conn; - } - - static void sleep(long duration) { - try { - Thread.sleep(duration); - } catch (InterruptedException e) { - System.exit(1); - } - } -} diff --git a/worker/target/classes/worker/Worker.class b/worker/target/classes/worker/Worker.class deleted file mode 100644 index 0191c3845dc96c15824785c4a2ca9f5e95d2ad18..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4102 zcma)9340UQ6+I(M9$5?ognbV-};ZMwHk_mHN>geFb5v`zan`hD$>XzHH#Mo2amZ86`>o0+?wd+vQtZ~gn# z*8x0?zp3yk*!XnGxnw!?KXXb>_h=!fmrC>wd=dQXT`Kms;Xd52 zV$T}*GS@1uwV**q2cfeZN5M8PM7tCpV|Ffcw2TEtvX6O98*ct0Q`WDPTuZ-PwWm! zEQkb&D2xShMnT7zQ_5SFO1&PlB}YHdSvjERuE~2y)F!E61n1ZwvIMgVjyG|(n$)$F zYbdNOXTKogsD?DoD+pD~rr}ysjHhAs4$`epV*Q)gR0!k9sF)!9b>?QqQ;Dm2tL&1y z8nUv7WeOSB$Y07jMxNBW4^tYZae=T{S8bNh&+>`(H=H@P+t$^2)j(9R>%TM{aWZqF zY3hA&M?$q~idu^iBEyw~sBT_Xd)ROdVWJ5+$Qe}eX3eJ+9^>VJ0(%_=X zHmEe(V0+U(o)YGs)^HWqh=_I7%2!=$Qc_P&`(zOBVGB);4G(4$wM;XKtT&>slf-TdA?TStnO)3XlfO{POwfs}`)Uz5sg->&&RSK5Hk>-z%h+XBgcjQ=`2X!~NRB3dOcX@0C}H~b%lnAev`aWed1nFi+^ zi)=VJ?ATWAMt)i)*_kTEDW1fjFlBn_9 zwuQwXY4|aI!eQW+JXr zu%{74vdC@Psg_-<5d*7dRvkm^LL31jjCz&JW(ph~p-idjS5 zzHIweUU@L(v&vPRcQONkt{Vtm=fX#pKz;^-*ub^s3Glv=Pi@$Qdpu?32<3#4h4AKO zZb{+o%eZ&+W$X^`UBUz1E#a;u^!RV$kPmO*X!;iVW_oYnc%MJw51&}VqkRD`hQ*>) zD4hfZaCW*U5{R@eBel5lN~(JaWBz4KUYFtIk>}RkB7^N?NMNX~ z3{m5{9b0((2s5{>ILfC%Y{v!cz`L-SS`nB$&R)bW6u66v1Sgm%lfVof+imaatnF`J>LB$t|*vZM6A!> z6@IrAB8maO_c;;>c=C~eCn&Iru=e}zz)G;8gWhzOb1$>qN2&dMI>1b$T*Y{eGS@C< z+0FcVki`i3>yJ2~S`k7&Ia=@X_KR-i!CqdM6%`X!vPqC*IF@0f|clz7@Lk z6BZRm<^RhPmrer1pD#2gSoI=J2+GE9p?8M#d?wW${=gDG#PqjGmVJyYYsV*+@yW%N ze+UMBM$qmhs<*MyTk#y#1)2Br8LV3y4)gsZ{BneDj$${CG5d!Z=K%ND6EZ*DbBWJ0 zD?#@CcwTa$oxIB93#^%_>_)Ww3vH}yQpIyy7&U(%tt;mMP5CK2tE9qTT*jBDZ{dZR z@V9Q@JM4?^hJVP*5?&l##Gan;Ps2Z7#!IP1gwrCCrFv%FZ?62kJG@+@!|n2GqdiM_ z)z5Aa(yw`G`&iO0CNj=Q#*pE(^U@z-D}YCTA5JsUGuXpocHkUkQ!MHz0ZHRH-#yAk z7^L11?@69}$1ue!&$#@1f*_c@igxiRFk6Gj$M?^(NjT4N2)`k0K3WxEne?AzCEt)_ z$kKNnzvWi}UId;UR751o4Qejq5;Z~61JeSm{kfWNQ!p1$z_}wCcqat;0 z5cuigkF`w05^vF*Iq6NKFA*_K3uXKXf95^N?|J;C772gppP>cOg>Uhr4}bj+ekt)W From f0fb81f707b900848d65a0fada7f6356d2890895 Mon Sep 17 00:00:00 2001 From: Bret Fisher Date: Fri, 16 Dec 2022 17:32:18 -0500 Subject: [PATCH 21/41] Adding docker hub to push list (#271) * adding docker hub to push list * adding back arm builds to worker --- .github/workflows/call-docker-build-result.yaml | 5 +---- .github/workflows/call-docker-build-vote.yaml | 11 ++++------- .github/workflows/call-docker-build-worker.yaml | 13 +++++-------- 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/.github/workflows/call-docker-build-result.yaml b/.github/workflows/call-docker-build-result.yaml index a869ecd975..8c6d8e5bf2 100644 --- a/.github/workflows/call-docker-build-result.yaml +++ b/.github/workflows/call-docker-build-result.yaml @@ -52,7 +52,7 @@ jobs: ### defaults to: image-names: | ghcr.io/dockersamples/example-voting-app-result - # dockersamples/examplevotingapp_result + dockersamples/examplevotingapp_result ### REQUIRED set rules for tagging images, based on special action syntax: ### https://github.com/docker/metadata-action#tags-input @@ -60,9 +60,6 @@ jobs: tag-rules: | type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }} type=ref,event=pr - type=ref,event=branch - type=semver,pattern={{version}} - type=raw,value=gha-${{ github.run_id }} ### path to where docker should copy files into image ### defaults to root of repository (.) diff --git a/.github/workflows/call-docker-build-vote.yaml b/.github/workflows/call-docker-build-vote.yaml index 3c8f57f55e..678d0cc16a 100644 --- a/.github/workflows/call-docker-build-vote.yaml +++ b/.github/workflows/call-docker-build-vote.yaml @@ -52,17 +52,14 @@ jobs: ### defaults to: image-names: | ghcr.io/dockersamples/example-voting-app-vote - # dockersamples/examplevotingapp_vote + dockersamples/examplevotingapp_vote ### REQUIRED set rules for tagging images, based on special action syntax: ### https://github.com/docker/metadata-action#tags-input ### defaults to: - # tag-rules: | - # type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }} - # type=ref,event=pr - # type=ref,event=branch - # type=semver,pattern={{version}} - # type=raw,value=gha-${{ github.run_id }} + tag-rules: | + type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }} + type=ref,event=pr ### path to where docker should copy files into image ### defaults to root of repository (.) diff --git a/.github/workflows/call-docker-build-worker.yaml b/.github/workflows/call-docker-build-worker.yaml index c10d9c6e09..5abfb6bc9c 100644 --- a/.github/workflows/call-docker-build-worker.yaml +++ b/.github/workflows/call-docker-build-worker.yaml @@ -52,17 +52,14 @@ jobs: ### defaults to: image-names: | ghcr.io/dockersamples/example-voting-app-worker - # dockersamples/examplevotingapp_worker + dockersamples/examplevotingapp_worker ### REQUIRED set rules for tagging images, based on special action syntax: ### https://github.com/docker/metadata-action#tags-input ### defaults to: - # tag-rules: | - # type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }} - # type=ref,event=pr - # type=ref,event=branch - # type=semver,pattern={{version}} - # type=raw,value=gha-${{ github.run_id }} + tag-rules: | + type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }} + type=ref,event=pr ### path to where docker should copy files into image ### defaults to root of repository (.) @@ -78,7 +75,7 @@ jobs: ### other options: linux/amd64,linux/arm64,linux/arm/v7 # FIXME worker arm/v7 support doesn't build in .net core 3.1 with QEMU # a fix would likely run the .net build on amd64 but with a target of arm/v7 - platforms: linux/amd64,linux/arm64 + platforms: linux/amd64,linux/arm64,linux/arm/v7 ### Create a PR comment with image tags and labels ### defaults to false From 226edf018477fb429a415357afafcbf6a07509dc Mon Sep 17 00:00:00 2001 From: Bret Fisher Date: Fri, 16 Dec 2022 21:50:40 -0500 Subject: [PATCH 22/41] compose and K8s file cleanup (#273) --- ExampleVotingApp.sln | 37 ---- README.md | 72 ++++--- docker-compose-k8s.yml | 30 --- docker-compose-simple.yml | 32 ---- docker-compose.images.yml | 70 +++++++ docker-compose.seed.yml | 9 - docker-compose.yml | 25 ++- docker-stack-simple.yml | 84 --------- docker-stack.yml | 66 ++----- k8s-specifications/db-deployment.yaml | 2 +- k8s-specifications/result-deployment.yaml | 2 +- k8s-specifications/vote-deployment.yaml | 2 +- kube-deployment.yml | 217 ---------------------- 13 files changed, 139 insertions(+), 509 deletions(-) delete mode 100644 ExampleVotingApp.sln delete mode 100644 docker-compose-k8s.yml delete mode 100644 docker-compose-simple.yml create mode 100644 docker-compose.images.yml delete mode 100644 docker-compose.seed.yml delete mode 100644 docker-stack-simple.yml delete mode 100644 kube-deployment.yml diff --git a/ExampleVotingApp.sln b/ExampleVotingApp.sln deleted file mode 100644 index 4e2906d4ad..0000000000 --- a/ExampleVotingApp.sln +++ /dev/null @@ -1,37 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.28010.2036 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vote", "vote\dotnet\Vote\Vote.csproj", "{9687EAF5-BFF3-4F8D-9C78-1B8EE12CE091}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker", "worker\dotnet\Worker\Worker.csproj", "{083764E8-4C34-43FB-A468-F80CE0ADE10A}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Result", "result\dotnet\Result\Result.csproj", "{9AD16D72-E3F5-4A76-814C-40EBD1EE7892}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {9687EAF5-BFF3-4F8D-9C78-1B8EE12CE091}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9687EAF5-BFF3-4F8D-9C78-1B8EE12CE091}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9687EAF5-BFF3-4F8D-9C78-1B8EE12CE091}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9687EAF5-BFF3-4F8D-9C78-1B8EE12CE091}.Release|Any CPU.Build.0 = Release|Any CPU - {083764E8-4C34-43FB-A468-F80CE0ADE10A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {083764E8-4C34-43FB-A468-F80CE0ADE10A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {083764E8-4C34-43FB-A468-F80CE0ADE10A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {083764E8-4C34-43FB-A468-F80CE0ADE10A}.Release|Any CPU.Build.0 = Release|Any CPU - {9AD16D72-E3F5-4A76-814C-40EBD1EE7892}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9AD16D72-E3F5-4A76-814C-40EBD1EE7892}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9AD16D72-E3F5-4A76-814C-40EBD1EE7892}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9AD16D72-E3F5-4A76-814C-40EBD1EE7892}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {9DEFC158-1225-4393-8A38-22256211D43D} - EndGlobalSection -EndGlobal diff --git a/README.md b/README.md index 4e5fc23e59..496be3d65b 100644 --- a/README.md +++ b/README.md @@ -1,50 +1,43 @@ -Example Voting App -========= +# Example Voting App A simple distributed application running across multiple Docker containers. -Getting started ---------------- +## Getting started -Download [Docker Desktop](https://www.docker.com/products/docker-desktop) for Mac or Windows. [Docker Compose](https://docs.docker.com/compose) will be automatically installed. On Linux, make sure you have the latest version of [Compose](https://docs.docker.com/compose/install/). +Download [Docker Desktop](https://www.docker.com/products/docker-desktop) for Mac or Windows. [Docker Compose](https://docs.docker.com/compose) will be automatically installed. On Linux, make sure you have the latest version of [Compose](https://docs.docker.com/compose/install/). +This solution uses Python, Node.js, .NET, with Redis for messaging and Postgres for storage. -## Linux Containers +Run in this directory to build and run the app: -The Linux stack uses Python, Node.js, .NET Core, with Redis for messaging and Postgres for storage. - -> If you're using [Docker Desktop on Windows](https://store.docker.com/editions/community/docker-ce-desktop-windows), you can run the Linux version by [switching to Linux containers](https://docs.docker.com/docker-for-windows/#switch-between-windows-and-linux-containers), or run the Windows containers version. - -Run in this directory: -``` +```shell docker compose up ``` -The app will be running at [http://localhost:5000](http://localhost:5000), and the results will be at [http://localhost:5001](http://localhost:5001). + +The `vote` app will be running at [http://localhost:5000](http://localhost:5000), and the `results` will be at [http://localhost:5001](http://localhost:5001). Alternately, if you want to run it on a [Docker Swarm](https://docs.docker.com/engine/swarm/), first make sure you have a swarm. If you don't, run: -``` + +```shell docker swarm init ``` + Once you have your swarm, in this directory run: -``` + +```shell docker stack deploy --compose-file docker-stack.yml vote ``` +## Run the app in Kubernetes -Run the app in Kubernetes -------------------------- - -The folder k8s-specifications contains the yaml specifications of the Voting App's services. +The folder k8s-specifications contains the YAML specifications of the Voting App's services. -First create the vote namespace - -``` -$ kubectl create namespace vote -``` +Run the following command to create the deployments and services objects in the vote namespace: -Run the following command to create the deployments and services objects: -``` -$ kubectl create -f k8s-specifications/ +```shell +kubectl create -f k8s-specifications/ +vote "vote" created +deployment "db" created deployment "db" created service "db" created deployment "redis" created @@ -58,23 +51,20 @@ deployment "worker" created The vote interface is then available on port 31000 on each host of the cluster, the result one is available on port 31001. -Architecture ------ +## Architecture ![Architecture diagram](architecture.png) -* A front-end web app in [Python](/vote) or [ASP.NET Core](/vote/dotnet) which lets you vote between two options -* A [Redis](https://hub.docker.com/_/redis/) or [NATS](https://hub.docker.com/_/nats/) queue which collects new votes -* A [.NET Core](/worker/) worker which consumes votes and stores them in… -* A [Postgres](https://hub.docker.com/_/postgres/) or [TiDB](https://hub.docker.com/r/dockersamples/tidb/tags/) database backed by a Docker volume -* A [Node.js](/result) or [ASP.NET Core SignalR](/result/dotnet) webapp which shows the results of the voting in real time - +* A front-end web app in [Python](/vote) which lets you vote between two options +* A [Redis](https://hub.docker.com/_/redis/) which collects new votes +* A [.NET](/worker/) worker which consumes votes and stores them in… +* A [Postgres](https://hub.docker.com/_/postgres/) database backed by a Docker volume +* A [Node.js](/result) web app which shows the results of the voting in real time -Notes ------ +## Notes -The voting application only accepts one vote per client. It does not register votes if a vote has already been submitted from a client. +The voting application only accepts one vote per client browser. It does not register additional votes if a vote has already been submitted from a client. -This isn't an example of a properly architected perfectly designed distributed app... it's just a simple -example of the various types of pieces and languages you might see (queues, persistent data, etc), and how to -deal with them in Docker at a basic level. +This isn't an example of a properly architected perfectly designed distributed app... it's just a simple +example of the various types of pieces and languages you might see (queues, persistent data, etc), and how to +deal with them in Docker at a basic level. diff --git a/docker-compose-k8s.yml b/docker-compose-k8s.yml deleted file mode 100644 index 2c756dd8b1..0000000000 --- a/docker-compose-k8s.yml +++ /dev/null @@ -1,30 +0,0 @@ -version: '3' - -services: - redis: - image: redis:alpine - ports: - - "6379:6379" - db: - image: postgres:9.4 - environment: - POSTGRES_USER: "postgres" - POSTGRES_PASSWORD: "postgres" - ports: - - "5432:5432" - vote: - image: dockersamples/examplevotingapp_vote:before - ports: - - "5000:80" - deploy: - replicas: 1 - result: - image: dockersamples/examplevotingapp_result:before - ports: - - "5001:80" - worker: - image: dockersamples/examplevotingapp_worker - visualizer: - image: dockersamples/visualizer:stable - ports: - - "8080:8080" diff --git a/docker-compose-simple.yml b/docker-compose-simple.yml deleted file mode 100644 index f8454efa1d..0000000000 --- a/docker-compose-simple.yml +++ /dev/null @@ -1,32 +0,0 @@ -version: "3" - -services: - vote: - build: ./vote - command: python app.py - volumes: - - ./vote:/app - ports: - - "5000:80" - - redis: - image: redis:alpine - ports: ["6379"] - - worker: - build: ./worker - - db: - image: postgres:9.4 - environment: - POSTGRES_USER: "postgres" - POSTGRES_PASSWORD: "postgres" - - result: - build: ./result - command: nodemon server.js - volumes: - - ./result:/app - ports: - - "5001:80" - - "5858:5858" diff --git a/docker-compose.images.yml b/docker-compose.images.yml new file mode 100644 index 0000000000..a0281f3a42 --- /dev/null +++ b/docker-compose.images.yml @@ -0,0 +1,70 @@ +# for running in docker compose with prebuilt images + +# version is now using "compose spec" +# v2 and v3 are now combined! +# docker-compose v1.27+ required + +services: + vote: + image: dockersamples/examplevotingapp_vote + depends_on: + redis: + condition: service_healthy + ports: + - "5000:80" + networks: + - front-tier + - back-tier + + result: + image: dockersamples/examplevotingapp_result + depends_on: + db: + condition: service_healthy + ports: + - "5001:80" + networks: + - front-tier + - back-tier + + worker: + image: dockersamples/examplevotingapp_worker + depends_on: + redis: + condition: service_healthy + db: + condition: service_healthy + networks: + - back-tier + + redis: + image: redis:alpine + volumes: + - "./healthchecks:/healthchecks" + healthcheck: + test: /healthchecks/redis.sh + interval: "5s" + ports: ["6379"] + networks: + - back-tier + + db: + image: postgres:15-alpine + environment: + POSTGRES_USER: "postgres" + POSTGRES_PASSWORD: "postgres" + volumes: + - "db-data:/var/lib/postgresql/data" + - "./healthchecks:/healthchecks" + healthcheck: + test: /healthchecks/postgres.sh + interval: "5s" + networks: + - back-tier + +volumes: + db-data: + +networks: + front-tier: + back-tier: diff --git a/docker-compose.seed.yml b/docker-compose.seed.yml deleted file mode 100644 index 355c8570c2..0000000000 --- a/docker-compose.seed.yml +++ /dev/null @@ -1,9 +0,0 @@ -services: - seed: - build: ./seed-data - networks: - - front-tier - restart: "no" - -networks: - front-tier: \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 197d657151..fa82c037a6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,7 +9,13 @@ services: command: python app.py depends_on: redis: - condition: service_healthy + condition: service_healthy + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost"] + interval: 15s + timeout: 5s + retries: 3 + start_period: 10s volumes: - ./vote:/app ports: @@ -46,7 +52,7 @@ services: - back-tier redis: - image: redis:5.0-alpine3.10 + image: redis:alpine volumes: - "./healthchecks:/healthchecks" healthcheck: @@ -57,7 +63,7 @@ services: - back-tier db: - image: postgres:9.4 + image: postgres:15-alpine environment: POSTGRES_USER: "postgres" POSTGRES_PASSWORD: "postgres" @@ -70,6 +76,19 @@ services: networks: - back-tier + # this service runs once to seed the database with votes + # it won't run unless you specify the "seed" profile + # docker compose --profile seed up -d + seed: + build: ./seed-data + profiles: ["seed"] + depends_on: + vote: + condition: service_healthy + networks: + - front-tier + restart: "no" + volumes: db-data: diff --git a/docker-stack-simple.yml b/docker-stack-simple.yml deleted file mode 100644 index 04f5dd948d..0000000000 --- a/docker-stack-simple.yml +++ /dev/null @@ -1,84 +0,0 @@ -version: "3" -services: - - redis: - image: redis:alpine - ports: - - "6379" - networks: - - frontend - deploy: - replicas: 1 - update_config: - parallelism: 2 - delay: 10s - restart_policy: - condition: on-failure - db: - image: postgres:9.4 - environment: - POSTGRES_USER: "postgres" - POSTGRES_PASSWORD: "postgres" - volumes: - - db-data:/var/lib/postgresql/data - networks: - - backend - deploy: - placement: - constraints: [node.role == manager] - vote: - image: dockersamples/examplevotingapp_vote:before - ports: - - 5000:80 - networks: - - frontend - depends_on: - - redis - deploy: - replicas: 1 - update_config: - parallelism: 2 - restart_policy: - condition: on-failure - result: - image: dockersamples/examplevotingapp_result:before - ports: - - 5001:80 - networks: - - backend - depends_on: - - db - deploy: - replicas: 1 - update_config: - parallelism: 2 - delay: 10s - restart_policy: - condition: on-failure - - worker: - image: dockersamples/examplevotingapp_worker - networks: - - frontend - - backend - depends_on: - - db - - redis - deploy: - mode: replicated - replicas: 1 - labels: [APP=VOTING] - restart_policy: - condition: on-failure - delay: 10s - max_attempts: 3 - window: 120s - placement: - constraints: [node.role == manager] - -networks: - frontend: - backend: - -volumes: - db-data: diff --git a/docker-stack.yml b/docker-stack.yml index e80f8c2861..0d00b6a202 100644 --- a/docker-stack.yml +++ b/docker-stack.yml @@ -1,19 +1,18 @@ -version: "3" +# this file is meant for Docker Swarm stacks only +# trying it in compose will fail because of multiple replicas trying to bind to the same port +# Swarm currently does not support Compose Spec, so we'll pin to the older version 3.9 + +version: "3.9" + services: redis: image: redis:alpine networks: - frontend - deploy: - replicas: 1 - update_config: - parallelism: 2 - delay: 10s - restart_policy: - condition: on-failure + db: - image: postgres:9.4 + image: postgres:15-alpine environment: POSTGRES_USER: "postgres" POSTGRES_PASSWORD: "postgres" @@ -21,69 +20,30 @@ services: - db-data:/var/lib/postgresql/data networks: - backend - deploy: - placement: - constraints: [node.role == manager] + vote: - image: dockersamples/examplevotingapp_vote:before + image: dockersamples/examplevotingapp_vote ports: - 5000:80 networks: - frontend - depends_on: - - redis deploy: replicas: 2 - update_config: - parallelism: 2 - restart_policy: - condition: on-failure + result: - image: dockersamples/examplevotingapp_result:before + image: dockersamples/examplevotingapp_result ports: - 5001:80 networks: - backend - depends_on: - - db - deploy: - replicas: 1 - update_config: - parallelism: 2 - delay: 10s - restart_policy: - condition: on-failure worker: image: dockersamples/examplevotingapp_worker networks: - frontend - backend - depends_on: - - db - - redis - deploy: - mode: replicated - replicas: 1 - labels: [APP=VOTING] - restart_policy: - condition: on-failure - delay: 10s - max_attempts: 3 - window: 120s - placement: - constraints: [node.role == manager] - - visualizer: - image: dockersamples/visualizer:stable - ports: - - "8080:8080" - stop_grace_period: 1m30s - volumes: - - "/var/run/docker.sock:/var/run/docker.sock" deploy: - placement: - constraints: [node.role == manager] + replicas: 2 networks: frontend: diff --git a/k8s-specifications/db-deployment.yaml b/k8s-specifications/db-deployment.yaml index 55622bb4b1..f08a22d86f 100644 --- a/k8s-specifications/db-deployment.yaml +++ b/k8s-specifications/db-deployment.yaml @@ -16,7 +16,7 @@ spec: app: db spec: containers: - - image: postgres:9.4 + - image: postgres:15-alpine name: postgres env: - name: POSTGRES_USER diff --git a/k8s-specifications/result-deployment.yaml b/k8s-specifications/result-deployment.yaml index 9939db1a34..55aeae92b2 100644 --- a/k8s-specifications/result-deployment.yaml +++ b/k8s-specifications/result-deployment.yaml @@ -16,7 +16,7 @@ spec: app: result spec: containers: - - image: dockersamples/examplevotingapp_result:before + - image: dockersamples/examplevotingapp_result name: result ports: - containerPort: 80 diff --git a/k8s-specifications/vote-deployment.yaml b/k8s-specifications/vote-deployment.yaml index c2120d4aa0..e052e6d2ef 100644 --- a/k8s-specifications/vote-deployment.yaml +++ b/k8s-specifications/vote-deployment.yaml @@ -16,7 +16,7 @@ spec: app: vote spec: containers: - - image: dockersamples/examplevotingapp_vote:before + - image: dockersamples/examplevotingapp_vote name: vote ports: - containerPort: 80 diff --git a/kube-deployment.yml b/kube-deployment.yml deleted file mode 100644 index c567e38cd2..0000000000 --- a/kube-deployment.yml +++ /dev/null @@ -1,217 +0,0 @@ -# redis ---- -apiVersion: v1 -kind: Service -metadata: - labels: - app: redis - name: redis -spec: - clusterIP: None - ports: - - name: redis-service - port: 6379 - targetPort: 6379 - selector: - app: redis ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: redis - labels: - app: redis -spec: - replicas: 1 - selector: - matchLabels: - app: redis - template: - metadata: - labels: - app: redis - spec: - containers: - - name: redis - image: redis:alpine - ports: - - containerPort: 6379 - name: redis - -# db ---- -apiVersion: v1 -kind: Service -metadata: - labels: - app: db - name: db -spec: - clusterIP: None - ports: - - name: db - port: 5432 - targetPort: 5432 - selector: - app: db ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: db - labels: - app: db -spec: - replicas: 1 - selector: - matchLabels: - app: db - template: - metadata: - labels: - app: db - spec: - containers: - - name: db - image: postgres:9.4 - env: - - name: PGDATA - value: /var/lib/postgresql/data/pgdata - - name: POSTGRES_USER - value: postgres - - name: POSTGRES_PASSWORD - value: postgres - ports: - - containerPort: 5432 - name: db - volumeMounts: - - name: db-data - mountPath: /var/lib/postgresql/data - volumes: - - name: db-data - persistentVolumeClaim: - claimName: postgres-pv-claim ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: postgres-pv-claim -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi - -# result ---- -apiVersion: v1 -kind: Service -metadata: - name: result - labels: - app: result -spec: - type: LoadBalancer - ports: - - port: 5001 - targetPort: 80 - name: result-service - selector: - app: result ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: result - labels: - app: result -spec: - replicas: 1 - selector: - matchLabels: - app: result - template: - metadata: - labels: - app: result - spec: - containers: - - name: result - image: dockersamples/examplevotingapp_result:before - ports: - - containerPort: 80 - name: result - -# vote ---- -apiVersion: v1 -kind: Service -metadata: - name: vote - labels: - apps: vote -spec: - type: LoadBalancer - ports: - - port: 5000 - targetPort: 80 - name: vote-service - selector: - app: vote ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: vote - labels: - app: vote -spec: - replicas: 2 - selector: - matchLabels: - app: vote - template: - metadata: - labels: - app: vote - spec: - containers: - - name: vote - image: dockersamples/examplevotingapp_vote:before - ports: - - containerPort: 80 - name: vote - -# worker ---- -apiVersion: v1 -kind: Service -metadata: - labels: - apps: worker - name: worker -spec: - clusterIP: None - selector: - app: worker ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: worker - name: worker -spec: - replicas: 1 - selector: - matchLabels: - app: worker - template: - metadata: - labels: - app: worker - spec: - containers: - - image: dockersamples/examplevotingapp_worker - name: worker From 93ee0a516c55d78fa924dc77e97e596f591513a6 Mon Sep 17 00:00:00 2001 From: Bret Fisher Date: Fri, 16 Dec 2022 22:06:39 -0500 Subject: [PATCH 23/41] fix dotnet build (#274) --- worker/Dockerfile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/worker/Dockerfile b/worker/Dockerfile index b53da1b89d..fff3913361 100644 --- a/worker/Dockerfile +++ b/worker/Dockerfile @@ -3,6 +3,9 @@ # (errors common in arm/v7 32bit) https://github.com/dotnet/dotnet-docker/issues/1537 # https://hub.docker.com/_/microsoft-dotnet # hadolint ignore=DL3029 +# to build for a different platform than your host, use --platform= +# for example, if you were on Intel (amd64) and wanted to build for ARM, you would use: +# docker buildx build --platform "linux/arm64/v8" . FROM --platform=${BUILDPLATFORM} mcr.microsoft.com/dotnet/sdk:7.0 as build ARG TARGETPLATFORM ARG BUILDPLATFORM @@ -13,6 +16,7 @@ COPY *.csproj . RUN case ${TARGETPLATFORM} in \ "linux/amd64") ARCH=x64 ;; \ "linux/arm64") ARCH=arm64 ;; \ + "linux/arm64/v8") ARCH=arm64 ;; \ "linux/arm/v7") ARCH=arm ;; \ esac \ && dotnet restore -r linux-${ARCH} @@ -21,6 +25,7 @@ COPY . . RUN case ${TARGETPLATFORM} in \ "linux/amd64") ARCH=x64 ;; \ "linux/arm64") ARCH=arm64 ;; \ + "linux/arm64/v8") ARCH=arm64 ;; \ "linux/arm/v7") ARCH=arm ;; \ esac \ && dotnet publish -c release -o /app -r linux-${ARCH} --self-contained false --no-restore From c76fbd6494d89604b26b1c55fbf783eab9a18c3d Mon Sep 17 00:00:00 2001 From: Bret Fisher Date: Fri, 16 Dec 2022 22:12:11 -0500 Subject: [PATCH 24/41] Remove namespace from k8s example (#275) * remove namespace from k8s example * add remove step --- README.md | 21 ++++++++------------- k8s-specifications/db-deployment.yaml | 1 - k8s-specifications/db-service.yaml | 1 - k8s-specifications/redis-deployment.yaml | 1 - k8s-specifications/redis-service.yaml | 1 - k8s-specifications/result-deployment.yaml | 1 - k8s-specifications/result-service.yaml | 1 - k8s-specifications/vote-deployment.yaml | 1 - k8s-specifications/vote-namespace.yml | 5 ----- k8s-specifications/vote-service.yaml | 1 - k8s-specifications/worker-deployment.yaml | 1 - 11 files changed, 8 insertions(+), 27 deletions(-) delete mode 100644 k8s-specifications/vote-namespace.yml diff --git a/README.md b/README.md index 496be3d65b..082d04be68 100644 --- a/README.md +++ b/README.md @@ -32,24 +32,19 @@ docker stack deploy --compose-file docker-stack.yml vote The folder k8s-specifications contains the YAML specifications of the Voting App's services. -Run the following command to create the deployments and services objects in the vote namespace: +Run the following command to create the deployments and services. Note it will create these resources in your current namespace (`default` if you haven't changed it.) ```shell kubectl create -f k8s-specifications/ -vote "vote" created -deployment "db" created -deployment "db" created -service "db" created -deployment "redis" created -service "redis" created -deployment "result" created -service "result" created -deployment "vote" created -service "vote" created -deployment "worker" created ``` -The vote interface is then available on port 31000 on each host of the cluster, the result one is available on port 31001. +The `vote` web app is then available on port 31000 on each host of the cluster, the `result` web app is available on port 31001. + +To remove them, run: + +```shell +kubectl delete -f k8s-specifications/ +``` ## Architecture diff --git a/k8s-specifications/db-deployment.yaml b/k8s-specifications/db-deployment.yaml index f08a22d86f..bc94ca7368 100644 --- a/k8s-specifications/db-deployment.yaml +++ b/k8s-specifications/db-deployment.yaml @@ -4,7 +4,6 @@ metadata: labels: app: db name: db - namespace: vote spec: replicas: 1 selector: diff --git a/k8s-specifications/db-service.yaml b/k8s-specifications/db-service.yaml index ba64baf4cc..104f1e8268 100644 --- a/k8s-specifications/db-service.yaml +++ b/k8s-specifications/db-service.yaml @@ -4,7 +4,6 @@ metadata: labels: app: db name: db - namespace: vote spec: type: ClusterIP ports: diff --git a/k8s-specifications/redis-deployment.yaml b/k8s-specifications/redis-deployment.yaml index 53fe35c99c..24aa52135f 100644 --- a/k8s-specifications/redis-deployment.yaml +++ b/k8s-specifications/redis-deployment.yaml @@ -4,7 +4,6 @@ metadata: labels: app: redis name: redis - namespace: vote spec: replicas: 1 selector: diff --git a/k8s-specifications/redis-service.yaml b/k8s-specifications/redis-service.yaml index 050c66cb73..809d31d875 100644 --- a/k8s-specifications/redis-service.yaml +++ b/k8s-specifications/redis-service.yaml @@ -4,7 +4,6 @@ metadata: labels: app: redis name: redis - namespace: vote spec: type: ClusterIP ports: diff --git a/k8s-specifications/result-deployment.yaml b/k8s-specifications/result-deployment.yaml index 55aeae92b2..b85488a667 100644 --- a/k8s-specifications/result-deployment.yaml +++ b/k8s-specifications/result-deployment.yaml @@ -4,7 +4,6 @@ metadata: labels: app: result name: result - namespace: vote spec: replicas: 1 selector: diff --git a/k8s-specifications/result-service.yaml b/k8s-specifications/result-service.yaml index 14a8760bc1..f20e3b1fc6 100644 --- a/k8s-specifications/result-service.yaml +++ b/k8s-specifications/result-service.yaml @@ -4,7 +4,6 @@ metadata: labels: app: result name: result - namespace: vote spec: type: NodePort ports: diff --git a/k8s-specifications/vote-deployment.yaml b/k8s-specifications/vote-deployment.yaml index e052e6d2ef..165a9478f8 100644 --- a/k8s-specifications/vote-deployment.yaml +++ b/k8s-specifications/vote-deployment.yaml @@ -4,7 +4,6 @@ metadata: labels: app: vote name: vote - namespace: vote spec: replicas: 1 selector: diff --git a/k8s-specifications/vote-namespace.yml b/k8s-specifications/vote-namespace.yml deleted file mode 100644 index a071655eaf..0000000000 --- a/k8s-specifications/vote-namespace.yml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: vote - diff --git a/k8s-specifications/vote-service.yaml b/k8s-specifications/vote-service.yaml index c9d4972b53..eae29ffcc3 100644 --- a/k8s-specifications/vote-service.yaml +++ b/k8s-specifications/vote-service.yaml @@ -4,7 +4,6 @@ metadata: labels: app: vote name: vote - namespace: vote spec: type: NodePort ports: diff --git a/k8s-specifications/worker-deployment.yaml b/k8s-specifications/worker-deployment.yaml index ebec08d356..9e35450aec 100644 --- a/k8s-specifications/worker-deployment.yaml +++ b/k8s-specifications/worker-deployment.yaml @@ -4,7 +4,6 @@ metadata: labels: app: worker name: worker - namespace: vote spec: replicas: 1 selector: From 07376881e7e58c8aadad5600f5fe8e497441b835 Mon Sep 17 00:00:00 2001 From: Bret Fisher Date: Fri, 16 Dec 2022 22:23:45 -0500 Subject: [PATCH 25/41] add before and after tags for demos (#276) --- .github/workflows/call-docker-build-result.yaml | 2 ++ .github/workflows/call-docker-build-vote.yaml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/call-docker-build-result.yaml b/.github/workflows/call-docker-build-result.yaml index 8c6d8e5bf2..a946a87b03 100644 --- a/.github/workflows/call-docker-build-result.yaml +++ b/.github/workflows/call-docker-build-result.yaml @@ -59,6 +59,8 @@ jobs: ### defaults to: tag-rules: | type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }} + type=raw,value=before,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }} + type=raw,value=after,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }} type=ref,event=pr ### path to where docker should copy files into image diff --git a/.github/workflows/call-docker-build-vote.yaml b/.github/workflows/call-docker-build-vote.yaml index 678d0cc16a..cb4a484a2a 100644 --- a/.github/workflows/call-docker-build-vote.yaml +++ b/.github/workflows/call-docker-build-vote.yaml @@ -59,6 +59,8 @@ jobs: ### defaults to: tag-rules: | type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }} + type=raw,value=before,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }} + type=raw,value=after,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }} type=ref,event=pr ### path to where docker should copy files into image From f1445f43b173c9262ecceee6f2b112f52d12ea82 Mon Sep 17 00:00:00 2001 From: Bret Fisher Date: Fri, 16 Dec 2022 22:37:25 -0500 Subject: [PATCH 26/41] remove dupe dotnet voting and result apps (#277) --- result/.vscode/launch.json | 18 - result/dotnet/Dockerfile | 16 - result/dotnet/Dockerfile.1809 | 16 - result/dotnet/Result/Data/IResultData.cs | 9 - result/dotnet/Result/Data/MySqlResultData.cs | 40 - result/dotnet/Result/Hubs/ResultsHub.cs | 9 - result/dotnet/Result/Models/ResultsModel.cs | 11 - result/dotnet/Result/Pages/Index.cshtml | 45 - result/dotnet/Result/Pages/Index.cshtml.cs | 33 - result/dotnet/Result/Program.cs | 24 - .../Result/Properties/launchSettings.json | 27 - result/dotnet/Result/Result.csproj | 13 - result/dotnet/Result/Startup.cs | 52 - .../Result/Timers/PublishResultsTimer.cs | 41 - .../Result/appsettings.Development.json | 9 - result/dotnet/Result/appsettings.json | 18 - result/dotnet/Result/libman.json | 14 - result/dotnet/Result/wwwroot/css/site.css | 121 - result/dotnet/Result/wwwroot/css/site.min.css | 1 - result/dotnet/Result/wwwroot/js/results.js | 41 - .../lib/signalr/dist/browser/signalr.js | 3441 ----------------- .../lib/signalr/dist/browser/signalr.min.js | 17 - vote/dotnet/Dockerfile | 16 - vote/dotnet/Dockerfile.1809 | 16 - vote/dotnet/Vote/Messaging/IMessageQueue.cs | 12 - vote/dotnet/Vote/Messaging/MessageHelper.cs | 23 - vote/dotnet/Vote/Messaging/MessageQueue.cs | 35 - .../Messages/Events/VoteCastEvent.cs | 15 - .../dotnet/Vote/Messaging/Messages/Message.cs | 16 - vote/dotnet/Vote/Pages/Index.cshtml | 50 - vote/dotnet/Vote/Pages/Index.cshtml.cs | 75 - vote/dotnet/Vote/Program.cs | 24 - .../Vote/Properties/launchSettings.json | 27 - vote/dotnet/Vote/Startup.cs | 45 - vote/dotnet/Vote/Vote.csproj | 12 - vote/dotnet/Vote/Vote.sln | 25 - vote/dotnet/Vote/appsettings.Development.json | 12 - vote/dotnet/Vote/appsettings.json | 16 - vote/dotnet/Vote/wwwroot/css/site.css | 135 - vote/dotnet/Vote/wwwroot/css/site.min.css | 1 - .../Vote/wwwroot/js/jquery-1.11.1-min.js | 13 - 41 files changed, 4584 deletions(-) delete mode 100644 result/.vscode/launch.json delete mode 100644 result/dotnet/Dockerfile delete mode 100644 result/dotnet/Dockerfile.1809 delete mode 100644 result/dotnet/Result/Data/IResultData.cs delete mode 100644 result/dotnet/Result/Data/MySqlResultData.cs delete mode 100644 result/dotnet/Result/Hubs/ResultsHub.cs delete mode 100644 result/dotnet/Result/Models/ResultsModel.cs delete mode 100644 result/dotnet/Result/Pages/Index.cshtml delete mode 100644 result/dotnet/Result/Pages/Index.cshtml.cs delete mode 100644 result/dotnet/Result/Program.cs delete mode 100644 result/dotnet/Result/Properties/launchSettings.json delete mode 100644 result/dotnet/Result/Result.csproj delete mode 100644 result/dotnet/Result/Startup.cs delete mode 100644 result/dotnet/Result/Timers/PublishResultsTimer.cs delete mode 100644 result/dotnet/Result/appsettings.Development.json delete mode 100644 result/dotnet/Result/appsettings.json delete mode 100644 result/dotnet/Result/libman.json delete mode 100644 result/dotnet/Result/wwwroot/css/site.css delete mode 100644 result/dotnet/Result/wwwroot/css/site.min.css delete mode 100644 result/dotnet/Result/wwwroot/js/results.js delete mode 100644 result/dotnet/Result/wwwroot/lib/signalr/dist/browser/signalr.js delete mode 100644 result/dotnet/Result/wwwroot/lib/signalr/dist/browser/signalr.min.js delete mode 100644 vote/dotnet/Dockerfile delete mode 100644 vote/dotnet/Dockerfile.1809 delete mode 100644 vote/dotnet/Vote/Messaging/IMessageQueue.cs delete mode 100644 vote/dotnet/Vote/Messaging/MessageHelper.cs delete mode 100644 vote/dotnet/Vote/Messaging/MessageQueue.cs delete mode 100644 vote/dotnet/Vote/Messaging/Messages/Events/VoteCastEvent.cs delete mode 100644 vote/dotnet/Vote/Messaging/Messages/Message.cs delete mode 100644 vote/dotnet/Vote/Pages/Index.cshtml delete mode 100644 vote/dotnet/Vote/Pages/Index.cshtml.cs delete mode 100644 vote/dotnet/Vote/Program.cs delete mode 100644 vote/dotnet/Vote/Properties/launchSettings.json delete mode 100644 vote/dotnet/Vote/Startup.cs delete mode 100644 vote/dotnet/Vote/Vote.csproj delete mode 100644 vote/dotnet/Vote/Vote.sln delete mode 100644 vote/dotnet/Vote/appsettings.Development.json delete mode 100644 vote/dotnet/Vote/appsettings.json delete mode 100644 vote/dotnet/Vote/wwwroot/css/site.css delete mode 100644 vote/dotnet/Vote/wwwroot/css/site.min.css delete mode 100644 vote/dotnet/Vote/wwwroot/js/jquery-1.11.1-min.js diff --git a/result/.vscode/launch.json b/result/.vscode/launch.json deleted file mode 100644 index c081024453..0000000000 --- a/result/.vscode/launch.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Attach", - "type": "node", - "request": "attach", - "port": 5858, - "address": "localhost", - "restart": true, - "sourceMaps": false, - "outDir": null, - "localRoot": "${workspaceRoot}", - "remoteRoot": "/app", - "timeout": 10000 - } - ] -} diff --git a/result/dotnet/Dockerfile b/result/dotnet/Dockerfile deleted file mode 100644 index a55f9484df..0000000000 --- a/result/dotnet/Dockerfile +++ /dev/null @@ -1,16 +0,0 @@ -FROM microsoft/dotnet:2.1-sdk-nanoserver-sac2016 as builder - -WORKDIR /Result -COPY Result/Result.csproj . -RUN dotnet restore - -COPY /Result . -RUN dotnet publish -c Release -o /out Result.csproj - -# app image -FROM microsoft/dotnet:2.1-aspnetcore-runtime-nanoserver-sac2016 - -WORKDIR /app -ENTRYPOINT ["dotnet", "Result.dll"] - -COPY --from=builder /out . \ No newline at end of file diff --git a/result/dotnet/Dockerfile.1809 b/result/dotnet/Dockerfile.1809 deleted file mode 100644 index 9020c04d76..0000000000 --- a/result/dotnet/Dockerfile.1809 +++ /dev/null @@ -1,16 +0,0 @@ -FROM mcr.microsoft.com/dotnet/core/sdk:3.1 as builder - -WORKDIR /Result -COPY Result/Result.csproj . -RUN dotnet restore - -COPY /Result . -RUN dotnet publish -c Release -o /out Result.csproj - -# app image -FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 - -WORKDIR /app -ENTRYPOINT ["dotnet", "Result.dll"] - -COPY --from=builder /out . \ No newline at end of file diff --git a/result/dotnet/Result/Data/IResultData.cs b/result/dotnet/Result/Data/IResultData.cs deleted file mode 100644 index f172f3b6ed..0000000000 --- a/result/dotnet/Result/Data/IResultData.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Result.Models; - -namespace Result.Data -{ - public interface IResultData - { - ResultsModel GetResults(); - } -} diff --git a/result/dotnet/Result/Data/MySqlResultData.cs b/result/dotnet/Result/Data/MySqlResultData.cs deleted file mode 100644 index 3c8ed67b2d..0000000000 --- a/result/dotnet/Result/Data/MySqlResultData.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System.Linq; -using Dapper; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; -using MySql.Data.MySqlClient; -using Result.Models; - -namespace Result.Data -{ - public class MySqlResultData : IResultData - { - private readonly string _connectionString; - private readonly ILogger _logger; - - public MySqlResultData(IConfiguration config, ILogger logger) - { - _connectionString = config.GetConnectionString("ResultData"); - _logger = logger; - } - - public ResultsModel GetResults() - { - var model = new ResultsModel(); - using (var connection = new MySqlConnection(_connectionString)) - { - var results = connection.Query("SELECT vote, COUNT(id) AS count FROM votes GROUP BY vote ORDER BY vote"); - if (results.Any(x => x.vote == "a")) - { - model.OptionA = (int) results.First(x => x.vote == "a").count; - } - if (results.Any(x => x.vote == "b")) - { - model.OptionB = (int) results.First(x => x.vote == "b").count; - } - model.VoteCount = model.OptionA + model.OptionB; - } - return model; - } - } -} diff --git a/result/dotnet/Result/Hubs/ResultsHub.cs b/result/dotnet/Result/Hubs/ResultsHub.cs deleted file mode 100644 index f85280331b..0000000000 --- a/result/dotnet/Result/Hubs/ResultsHub.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Microsoft.AspNetCore.SignalR; - -namespace Result.Hubs -{ - public class ResultsHub : Hub - { - //no public methods, only used for push from PublishRTesultsTimer - } -} diff --git a/result/dotnet/Result/Models/ResultsModel.cs b/result/dotnet/Result/Models/ResultsModel.cs deleted file mode 100644 index 65309bd6a4..0000000000 --- a/result/dotnet/Result/Models/ResultsModel.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Result.Models -{ - public class ResultsModel - { - public int OptionA { get; set; } - - public int OptionB { get; set; } - - public int VoteCount { get; set; } - } -} diff --git a/result/dotnet/Result/Pages/Index.cshtml b/result/dotnet/Result/Pages/Index.cshtml deleted file mode 100644 index 4b3dcdf09f..0000000000 --- a/result/dotnet/Result/Pages/Index.cshtml +++ /dev/null @@ -1,45 +0,0 @@ -@page -@model Result.Pages.IndexModel - - - - - - @Model.OptionA vs @Model.OptionB -- Result - - - - - - - -
-
-
- -
-
-
-
-
-
-
-
@Model.OptionA
-
50%
-
-
-
-
@Model.OptionB
-
50%
-
-
-
-
-
- No votes yet -
- - - - diff --git a/result/dotnet/Result/Pages/Index.cshtml.cs b/result/dotnet/Result/Pages/Index.cshtml.cs deleted file mode 100644 index 3d9cca2090..0000000000 --- a/result/dotnet/Result/Pages/Index.cshtml.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.RazorPages; -using Microsoft.Extensions.Configuration; - -namespace Result.Pages -{ - public class IndexModel : PageModel - { - private string _optionA; - private string _optionB; - protected readonly IConfiguration _configuration; - - public string OptionA { get; private set; } - public string OptionB { get; private set; } - - public IndexModel(IConfiguration configuration) - { - _configuration = configuration; - _optionA = _configuration.GetValue("Voting:OptionA"); - _optionB = _configuration.GetValue("Voting:OptionB"); - } - - public void OnGet() - { - OptionA = _optionA; - OptionB = _optionB; - } - } -} diff --git a/result/dotnet/Result/Program.cs b/result/dotnet/Result/Program.cs deleted file mode 100644 index 0360bc2d00..0000000000 --- a/result/dotnet/Result/Program.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; - -namespace Result -{ - public class Program - { - public static void Main(string[] args) - { - CreateWebHostBuilder(args).Build().Run(); - } - - public static IWebHostBuilder CreateWebHostBuilder(string[] args) => - WebHost.CreateDefaultBuilder(args) - .UseStartup(); - } -} diff --git a/result/dotnet/Result/Properties/launchSettings.json b/result/dotnet/Result/Properties/launchSettings.json deleted file mode 100644 index 1f33ca1105..0000000000 --- a/result/dotnet/Result/Properties/launchSettings.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:56785", - "sslPort": 0 - } - }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "Result": { - "commandName": "Project", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "applicationUrl": "https://localhost:5001;http://localhost:5000" - } - } -} \ No newline at end of file diff --git a/result/dotnet/Result/Result.csproj b/result/dotnet/Result/Result.csproj deleted file mode 100644 index d48265fc29..0000000000 --- a/result/dotnet/Result/Result.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - netcoreapp3.1 - - - - - - - - - diff --git a/result/dotnet/Result/Startup.cs b/result/dotnet/Result/Startup.cs deleted file mode 100644 index 5a53ddc9d3..0000000000 --- a/result/dotnet/Result/Startup.cs +++ /dev/null @@ -1,52 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Result.Data; -using Result.Hubs; -using Result.Timers; - -namespace Result -{ - public class Startup - { - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } - - public IConfiguration Configuration { get; } - - public void ConfigureServices(IServiceCollection services) - { - services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); - services.AddSignalR(); - - services.AddTransient() - .AddSingleton(); - } - - public void Configure(IApplicationBuilder app, IHostingEnvironment env) - { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - else - { - app.UseExceptionHandler("/Error"); - } - - app.UseStaticFiles(); - app.UseSignalR(routes => - { - routes.MapHub("/resultsHub"); - }); - app.UseMvc(); - - var timer = app.ApplicationServices.GetService(); - timer.Start(); - } - } -} diff --git a/result/dotnet/Result/Timers/PublishResultsTimer.cs b/result/dotnet/Result/Timers/PublishResultsTimer.cs deleted file mode 100644 index 28b2325fe6..0000000000 --- a/result/dotnet/Result/Timers/PublishResultsTimer.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Timers; -using Microsoft.AspNetCore.SignalR; -using Microsoft.Extensions.Configuration; -using Result.Data; -using Result.Hubs; - -namespace Result.Timers -{ - public class PublishResultsTimer - { - private readonly IHubContext _hubContext; - private readonly IResultData _resultData; - private readonly Timer _timer; - - public PublishResultsTimer(IHubContext hubContext, IResultData resultData, IConfiguration configuration) - { - _hubContext = hubContext; - _resultData = resultData; - var publishMilliseconds = configuration.GetValue("ResultsTimer:PublishMilliseconds"); - _timer = new Timer(publishMilliseconds) - { - Enabled = false - }; - _timer.Elapsed += PublishResults; - } - - public void Start() - { - if (!_timer.Enabled) - { - _timer.Start(); - } - } - - private void PublishResults(object sender, ElapsedEventArgs e) - { - var model = _resultData.GetResults(); - _hubContext.Clients.All.SendAsync("UpdateResults", model); - } - } -} diff --git a/result/dotnet/Result/appsettings.Development.json b/result/dotnet/Result/appsettings.Development.json deleted file mode 100644 index e203e9407e..0000000000 --- a/result/dotnet/Result/appsettings.Development.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" - } - } -} diff --git a/result/dotnet/Result/appsettings.json b/result/dotnet/Result/appsettings.json deleted file mode 100644 index b266aed9cf..0000000000 --- a/result/dotnet/Result/appsettings.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "Voting": { - "OptionA": "Cats", - "OptionB": "Dogs" - }, - "ResultsTimer": { - "PublishMilliseconds": 2500 - }, - "ConnectionStrings": { - "ResultData": "Server=mysql;Port=4000;Database=votes;User=root;SslMode=None" - }, - "Logging": { - "LogLevel": { - "Default": "Warning" - } - }, - "AllowedHosts": "*" -} diff --git a/result/dotnet/Result/libman.json b/result/dotnet/Result/libman.json deleted file mode 100644 index 7c20ba4c22..0000000000 --- a/result/dotnet/Result/libman.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "version": "1.0", - "defaultProvider": "unpkg", - "libraries": [ - { - "library": "@aspnet/signalr@1.0.3", - "destination": "wwwroot/lib/signalr/", - "files": [ - "dist/browser/signalr.js", - "dist/browser/signalr.min.js" - ] - } - ] -} \ No newline at end of file diff --git a/result/dotnet/Result/wwwroot/css/site.css b/result/dotnet/Result/wwwroot/css/site.css deleted file mode 100644 index 1ecece32ee..0000000000 --- a/result/dotnet/Result/wwwroot/css/site.css +++ /dev/null @@ -1,121 +0,0 @@ -@import url(//fonts.googleapis.com/css?family=Open+Sans:400,700,600); - -* { - box-sizing: border-box; -} - -html, body { - margin: 0; - padding: 0; - height: 100%; - font-family: 'Open Sans'; -} - -body { - opacity: 0; - transition: all 1s linear; -} - -.divider { - height: 150px; - width: 2px; - background-color: #C0C9CE; - position: relative; - top: 50%; - float: left; - transform: translateY(-50%); -} - -#background-stats-1 { - background-color: #2196f3; -} - -#background-stats-2 { - background-color: #00cbca; -} - -#content-container { - z-index: 2; - position: relative; - margin: 0 auto; - display: table; - padding: 10px; - max-width: 940px; - height: 100%; -} - -#content-container-center { - display: table-cell; - text-align: center; - vertical-align: middle; -} - -#result { - z-index: 3; - position: absolute; - bottom: 40px; - right: 20px; - color: #fff; - opacity: 0.5; - font-size: 45px; - font-weight: 600; -} - -#choice { - transition: all 300ms linear; - line-height: 1.3em; - background: #fff; - box-shadow: 10px 0 0 #fff, -10px 0 0 #fff; - vertical-align: middle; - font-size: 40px; - font-weight: 600; - width: 450px; - height: 200px; -} - - #choice a { - text-decoration: none; - } - - #choice a:hover, #choice a:focus { - outline: 0; - text-decoration: underline; - } - - #choice .choice { - width: 49%; - position: relative; - top: 50%; - transform: translateY(-50%); - text-align: left; - padding-left: 50px; - } - - #choice .choice .label { - text-transform: uppercase; - } - - #choice .choice.resultb { - color: #00cbca; - float: right; - } - - #choice .choice.resulta { - color: #2196f3; - float: left; - } - -#background-stats { - z-index: 1; - height: 100%; - width: 100%; - position: absolute; -} - - #background-stats div { - transition: width 400ms ease-in-out; - display: inline-block; - margin-bottom: -4px; - width: 50%; - height: 100%; - } diff --git a/result/dotnet/Result/wwwroot/css/site.min.css b/result/dotnet/Result/wwwroot/css/site.min.css deleted file mode 100644 index 5e93e30ae3..0000000000 --- a/result/dotnet/Result/wwwroot/css/site.min.css +++ /dev/null @@ -1 +0,0 @@ -body{padding-top:50px;padding-bottom:20px}.body-content{padding-left:15px;padding-right:15px}.carousel-caption p{font-size:20px;line-height:1.4}.carousel-inner .item img[src$=".svg"]{width:100%}#qrCode{margin:15px}@media screen and (max-width:767px){.carousel-caption{display:none}} \ No newline at end of file diff --git a/result/dotnet/Result/wwwroot/js/results.js b/result/dotnet/Result/wwwroot/js/results.js deleted file mode 100644 index e08e90dc86..0000000000 --- a/result/dotnet/Result/wwwroot/js/results.js +++ /dev/null @@ -1,41 +0,0 @@ -"use strict"; - -var connection = new signalR.HubConnectionBuilder().withUrl("/resultsHub").build(); - -connection.on("UpdateResults", function (results) { - document.body.style.opacity=1; - - var a = parseInt(results.optionA || 0); - var b = parseInt(results.optionB || 0); - var percentages = getPercentages(a, b); - - document.getElementById("optionA").innerText = percentages.a + "%"; - document.getElementById("optionB").innerText = percentages.b + "%"; - var totalVotes = 'No votes yet'; - if (results.voteCount > 0) { - totalVotes = results.voteCount + (results.voteCount > 1 ? " votes" : " vote"); - } - document.getElementById("totalVotes").innerText = totalVotes; - - var bg1 = document.getElementById('background-stats-1'); - var bg2 = document.getElementById('background-stats-2'); - bg1.style.width = (percentages.a-0.2) + "%"; - bg2.style.width = (percentages.b-0.2) + "%"; -}); - -connection.start().catch(function (err) { - return console.error(err.toString()); -}); - -function getPercentages(a, b) { - var result = {}; - - if (a + b > 0) { - result.a = Math.round(a / (a + b) * 100); - result.b = 100 - result.a; - } else { - result.a = result.b = 50; - } - - return result; -} \ No newline at end of file diff --git a/result/dotnet/Result/wwwroot/lib/signalr/dist/browser/signalr.js b/result/dotnet/Result/wwwroot/lib/signalr/dist/browser/signalr.js deleted file mode 100644 index 16b0954256..0000000000 --- a/result/dotnet/Result/wwwroot/lib/signalr/dist/browser/signalr.js +++ /dev/null @@ -1,3441 +0,0 @@ -/** - * @overview ASP.NET Core SignalR JavaScript Client. - * @version 1.0.3. - * @license - * Copyright (c) .NET Foundation. All rights reserved. - * Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - */ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global.signalR = factory()); -}(this, (function () { 'use strict'; - -var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; - -function commonjsRequire () { - throw new Error('Dynamic requires are not currently supported by rollup-plugin-commonjs'); -} - -function unwrapExports (x) { - return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; -} - -function createCommonjsModule(fn, module) { - return module = { exports: {} }, fn(module, module.exports), module.exports; -} - -/*! ***************************************************************************** -Copyright (c) Microsoft Corporation. All rights reserved. -Licensed under the Apache License, Version 2.0 (the "License"); you may not use -this file except in compliance with the License. You may obtain a copy of the -License at http://www.apache.org/licenses/LICENSE-2.0 - -THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED -WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, -MERCHANTABLITY OR NON-INFRINGEMENT. - -See the Apache Version 2.0 License for specific language governing permissions -and limitations under the License. -***************************************************************************** */ -/* global Reflect, Promise */ - -var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - -function __extends(d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -} - -var __assign = Object.assign || function __assign(t) { - for (var s, i = 1, n = arguments.length; i < n; i++) { - s = arguments[i]; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; - } - return t; -}; - -function __rest(s, e) { - var t = {}; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) - t[p] = s[p]; - if (s != null && typeof Object.getOwnPropertySymbols === "function") - for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) - t[p[i]] = s[p[i]]; - return t; -} - -function __decorate(decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; -} - -function __param(paramIndex, decorator) { - return function (target, key) { decorator(target, key, paramIndex); } -} - -function __metadata(metadataKey, metadataValue) { - if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); -} - -function __awaiter(thisArg, _arguments, P, generator) { - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -} - -function __generator(thisArg, body) { - var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; - return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; - function verb(n) { return function (v) { return step([n, v]); }; } - function step(op) { - if (f) throw new TypeError("Generator is already executing."); - while (_) try { - if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [0, t.value]; - switch (op[0]) { - case 0: case 1: t = op; break; - case 4: _.label++; return { value: op[1], done: false }; - case 5: _.label++; y = op[1]; op = [0]; continue; - case 7: op = _.ops.pop(); _.trys.pop(); continue; - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } - if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } - if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } - if (t[2]) _.ops.pop(); - _.trys.pop(); continue; - } - op = body.call(thisArg, _); - } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } - if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; - } -} - -function __exportStar(m, exports) { - for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; -} - -function __values(o) { - var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; - if (m) return m.call(o); - return { - next: function () { - if (o && i >= o.length) o = void 0; - return { value: o && o[i++], done: !o }; - } - }; -} - -function __read(o, n) { - var m = typeof Symbol === "function" && o[Symbol.iterator]; - if (!m) return o; - var i = m.call(o), r, ar = [], e; - try { - while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); - } - catch (error) { e = { error: error }; } - finally { - try { - if (r && !r.done && (m = i["return"])) m.call(i); - } - finally { if (e) throw e.error; } - } - return ar; -} - -function __spread() { - for (var ar = [], i = 0; i < arguments.length; i++) - ar = ar.concat(__read(arguments[i])); - return ar; -} - -function __await(v) { - return this instanceof __await ? (this.v = v, this) : new __await(v); -} - -function __asyncGenerator(thisArg, _arguments, generator) { - if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); - var g = generator.apply(thisArg, _arguments || []), i, q = []; - return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; - function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } - function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } - function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } - function fulfill(value) { resume("next", value); } - function reject(value) { resume("throw", value); } - function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } -} - -function __asyncDelegator(o) { - var i, p; - return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; - function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; } -} - -function __asyncValues(o) { - if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); - var m = o[Symbol.asyncIterator]; - return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); -} - -function __makeTemplateObject(cooked, raw) { - if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } - return cooked; -} - -function __importStar(mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; - result.default = mod; - return result; -} - -function __importDefault(mod) { - return (mod && mod.__esModule) ? mod : { default: mod }; -} - - -var tslib_1 = Object.freeze({ - __extends: __extends, - __assign: __assign, - __rest: __rest, - __decorate: __decorate, - __param: __param, - __metadata: __metadata, - __awaiter: __awaiter, - __generator: __generator, - __exportStar: __exportStar, - __values: __values, - __read: __read, - __spread: __spread, - __await: __await, - __asyncGenerator: __asyncGenerator, - __asyncDelegator: __asyncDelegator, - __asyncValues: __asyncValues, - __makeTemplateObject: __makeTemplateObject, - __importStar: __importStar, - __importDefault: __importDefault -}); - -var es6Promise_auto = createCommonjsModule(function (module, exports) { -/*! - * @overview es6-promise - a tiny implementation of Promises/A+. - * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald) - * @license Licensed under MIT license - * See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE - * @version v4.2.2+97478eb6 - */ - -(function (global, factory) { - module.exports = factory(); -}(commonjsGlobal, (function () { function objectOrFunction(x) { - var type = typeof x; - return x !== null && (type === 'object' || type === 'function'); -} - -function isFunction(x) { - return typeof x === 'function'; -} - - - -var _isArray = void 0; -if (Array.isArray) { - _isArray = Array.isArray; -} else { - _isArray = function (x) { - return Object.prototype.toString.call(x) === '[object Array]'; - }; -} - -var isArray = _isArray; - -var len = 0; -var vertxNext = void 0; -var customSchedulerFn = void 0; - -var asap = function asap(callback, arg) { - queue[len] = callback; - queue[len + 1] = arg; - len += 2; - if (len === 2) { - // If len is 2, that means that we need to schedule an async flush. - // If additional callbacks are queued before the queue is flushed, they - // will be processed by this flush that we are scheduling. - if (customSchedulerFn) { - customSchedulerFn(flush); - } else { - scheduleFlush(); - } - } -}; - -function setScheduler(scheduleFn) { - customSchedulerFn = scheduleFn; -} - -function setAsap(asapFn) { - asap = asapFn; -} - -var browserWindow = typeof window !== 'undefined' ? window : undefined; -var browserGlobal = browserWindow || {}; -var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver; -var isNode = typeof self === 'undefined' && typeof process !== 'undefined' && {}.toString.call(process) === '[object process]'; - -// test for web worker but not in IE10 -var isWorker = typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined'; - -// node -function useNextTick() { - // node version 0.10.x displays a deprecation warning when nextTick is used recursively - // see https://github.com/cujojs/when/issues/410 for details - return function () { - return process.nextTick(flush); - }; -} - -// vertx -function useVertxTimer() { - if (typeof vertxNext !== 'undefined') { - return function () { - vertxNext(flush); - }; - } - - return useSetTimeout(); -} - -function useMutationObserver() { - var iterations = 0; - var observer = new BrowserMutationObserver(flush); - var node = document.createTextNode(''); - observer.observe(node, { characterData: true }); - - return function () { - node.data = iterations = ++iterations % 2; - }; -} - -// web worker -function useMessageChannel() { - var channel = new MessageChannel(); - channel.port1.onmessage = flush; - return function () { - return channel.port2.postMessage(0); - }; -} - -function useSetTimeout() { - // Store setTimeout reference so es6-promise will be unaffected by - // other code modifying setTimeout (like sinon.useFakeTimers()) - var globalSetTimeout = setTimeout; - return function () { - return globalSetTimeout(flush, 1); - }; -} - -var queue = new Array(1000); -function flush() { - for (var i = 0; i < len; i += 2) { - var callback = queue[i]; - var arg = queue[i + 1]; - - callback(arg); - - queue[i] = undefined; - queue[i + 1] = undefined; - } - - len = 0; -} - -function attemptVertx() { - try { - var r = commonjsRequire; - var vertx = r('vertx'); - vertxNext = vertx.runOnLoop || vertx.runOnContext; - return useVertxTimer(); - } catch (e) { - return useSetTimeout(); - } -} - -var scheduleFlush = void 0; -// Decide what async method to use to triggering processing of queued callbacks: -if (isNode) { - scheduleFlush = useNextTick(); -} else if (BrowserMutationObserver) { - scheduleFlush = useMutationObserver(); -} else if (isWorker) { - scheduleFlush = useMessageChannel(); -} else if (browserWindow === undefined && typeof commonjsRequire === 'function') { - scheduleFlush = attemptVertx(); -} else { - scheduleFlush = useSetTimeout(); -} - -function then(onFulfillment, onRejection) { - var parent = this; - - var child = new this.constructor(noop); - - if (child[PROMISE_ID] === undefined) { - makePromise(child); - } - - var _state = parent._state; - - - if (_state) { - var callback = arguments[_state - 1]; - asap(function () { - return invokeCallback(_state, child, callback, parent._result); - }); - } else { - subscribe(parent, child, onFulfillment, onRejection); - } - - return child; -} - -/** - `Promise.resolve` returns a promise that will become resolved with the - passed `value`. It is shorthand for the following: - - ```javascript - let promise = new Promise(function(resolve, reject){ - resolve(1); - }); - - promise.then(function(value){ - // value === 1 - }); - ``` - - Instead of writing the above, your code now simply becomes the following: - - ```javascript - let promise = Promise.resolve(1); - - promise.then(function(value){ - // value === 1 - }); - ``` - - @method resolve - @static - @param {Any} value value that the returned promise will be resolved with - Useful for tooling. - @return {Promise} a promise that will become fulfilled with the given - `value` -*/ -function resolve$1(object) { - /*jshint validthis:true */ - var Constructor = this; - - if (object && typeof object === 'object' && object.constructor === Constructor) { - return object; - } - - var promise = new Constructor(noop); - resolve(promise, object); - return promise; -} - -var PROMISE_ID = Math.random().toString(36).substring(16); - -function noop() {} - -var PENDING = void 0; -var FULFILLED = 1; -var REJECTED = 2; - -var GET_THEN_ERROR = new ErrorObject(); - -function selfFulfillment() { - return new TypeError("You cannot resolve a promise with itself"); -} - -function cannotReturnOwn() { - return new TypeError('A promises callback cannot return that same promise.'); -} - -function getThen(promise) { - try { - return promise.then; - } catch (error) { - GET_THEN_ERROR.error = error; - return GET_THEN_ERROR; - } -} - -function tryThen(then$$1, value, fulfillmentHandler, rejectionHandler) { - try { - then$$1.call(value, fulfillmentHandler, rejectionHandler); - } catch (e) { - return e; - } -} - -function handleForeignThenable(promise, thenable, then$$1) { - asap(function (promise) { - var sealed = false; - var error = tryThen(then$$1, thenable, function (value) { - if (sealed) { - return; - } - sealed = true; - if (thenable !== value) { - resolve(promise, value); - } else { - fulfill(promise, value); - } - }, function (reason) { - if (sealed) { - return; - } - sealed = true; - - reject(promise, reason); - }, 'Settle: ' + (promise._label || ' unknown promise')); - - if (!sealed && error) { - sealed = true; - reject(promise, error); - } - }, promise); -} - -function handleOwnThenable(promise, thenable) { - if (thenable._state === FULFILLED) { - fulfill(promise, thenable._result); - } else if (thenable._state === REJECTED) { - reject(promise, thenable._result); - } else { - subscribe(thenable, undefined, function (value) { - return resolve(promise, value); - }, function (reason) { - return reject(promise, reason); - }); - } -} - -function handleMaybeThenable(promise, maybeThenable, then$$1) { - if (maybeThenable.constructor === promise.constructor && then$$1 === then && maybeThenable.constructor.resolve === resolve$1) { - handleOwnThenable(promise, maybeThenable); - } else { - if (then$$1 === GET_THEN_ERROR) { - reject(promise, GET_THEN_ERROR.error); - GET_THEN_ERROR.error = null; - } else if (then$$1 === undefined) { - fulfill(promise, maybeThenable); - } else if (isFunction(then$$1)) { - handleForeignThenable(promise, maybeThenable, then$$1); - } else { - fulfill(promise, maybeThenable); - } - } -} - -function resolve(promise, value) { - if (promise === value) { - reject(promise, selfFulfillment()); - } else if (objectOrFunction(value)) { - handleMaybeThenable(promise, value, getThen(value)); - } else { - fulfill(promise, value); - } -} - -function publishRejection(promise) { - if (promise._onerror) { - promise._onerror(promise._result); - } - - publish(promise); -} - -function fulfill(promise, value) { - if (promise._state !== PENDING) { - return; - } - - promise._result = value; - promise._state = FULFILLED; - - if (promise._subscribers.length !== 0) { - asap(publish, promise); - } -} - -function reject(promise, reason) { - if (promise._state !== PENDING) { - return; - } - promise._state = REJECTED; - promise._result = reason; - - asap(publishRejection, promise); -} - -function subscribe(parent, child, onFulfillment, onRejection) { - var _subscribers = parent._subscribers; - var length = _subscribers.length; - - - parent._onerror = null; - - _subscribers[length] = child; - _subscribers[length + FULFILLED] = onFulfillment; - _subscribers[length + REJECTED] = onRejection; - - if (length === 0 && parent._state) { - asap(publish, parent); - } -} - -function publish(promise) { - var subscribers = promise._subscribers; - var settled = promise._state; - - if (subscribers.length === 0) { - return; - } - - var child = void 0, - callback = void 0, - detail = promise._result; - - for (var i = 0; i < subscribers.length; i += 3) { - child = subscribers[i]; - callback = subscribers[i + settled]; - - if (child) { - invokeCallback(settled, child, callback, detail); - } else { - callback(detail); - } - } - - promise._subscribers.length = 0; -} - -function ErrorObject() { - this.error = null; -} - -var TRY_CATCH_ERROR = new ErrorObject(); - -function tryCatch(callback, detail) { - try { - return callback(detail); - } catch (e) { - TRY_CATCH_ERROR.error = e; - return TRY_CATCH_ERROR; - } -} - -function invokeCallback(settled, promise, callback, detail) { - var hasCallback = isFunction(callback), - value = void 0, - error = void 0, - succeeded = void 0, - failed = void 0; - - if (hasCallback) { - value = tryCatch(callback, detail); - - if (value === TRY_CATCH_ERROR) { - failed = true; - error = value.error; - value.error = null; - } else { - succeeded = true; - } - - if (promise === value) { - reject(promise, cannotReturnOwn()); - return; - } - } else { - value = detail; - succeeded = true; - } - - if (promise._state !== PENDING) { - // noop - } else if (hasCallback && succeeded) { - resolve(promise, value); - } else if (failed) { - reject(promise, error); - } else if (settled === FULFILLED) { - fulfill(promise, value); - } else if (settled === REJECTED) { - reject(promise, value); - } -} - -function initializePromise(promise, resolver) { - try { - resolver(function resolvePromise(value) { - resolve(promise, value); - }, function rejectPromise(reason) { - reject(promise, reason); - }); - } catch (e) { - reject(promise, e); - } -} - -var id = 0; -function nextId() { - return id++; -} - -function makePromise(promise) { - promise[PROMISE_ID] = id++; - promise._state = undefined; - promise._result = undefined; - promise._subscribers = []; -} - -function validationError() { - return new Error('Array Methods must be provided an Array'); -} - -function validationError() { - return new Error('Array Methods must be provided an Array'); -} - -var Enumerator = function () { - function Enumerator(Constructor, input) { - this._instanceConstructor = Constructor; - this.promise = new Constructor(noop); - - if (!this.promise[PROMISE_ID]) { - makePromise(this.promise); - } - - if (isArray(input)) { - this.length = input.length; - this._remaining = input.length; - - this._result = new Array(this.length); - - if (this.length === 0) { - fulfill(this.promise, this._result); - } else { - this.length = this.length || 0; - this._enumerate(input); - if (this._remaining === 0) { - fulfill(this.promise, this._result); - } - } - } else { - reject(this.promise, validationError()); - } - } - - Enumerator.prototype._enumerate = function _enumerate(input) { - for (var i = 0; this._state === PENDING && i < input.length; i++) { - this._eachEntry(input[i], i); - } - }; - - Enumerator.prototype._eachEntry = function _eachEntry(entry, i) { - var c = this._instanceConstructor; - var resolve$$1 = c.resolve; - - - if (resolve$$1 === resolve$1) { - var _then = getThen(entry); - - if (_then === then && entry._state !== PENDING) { - this._settledAt(entry._state, i, entry._result); - } else if (typeof _then !== 'function') { - this._remaining--; - this._result[i] = entry; - } else if (c === Promise$2) { - var promise = new c(noop); - handleMaybeThenable(promise, entry, _then); - this._willSettleAt(promise, i); - } else { - this._willSettleAt(new c(function (resolve$$1) { - return resolve$$1(entry); - }), i); - } - } else { - this._willSettleAt(resolve$$1(entry), i); - } - }; - - Enumerator.prototype._settledAt = function _settledAt(state, i, value) { - var promise = this.promise; - - - if (promise._state === PENDING) { - this._remaining--; - - if (state === REJECTED) { - reject(promise, value); - } else { - this._result[i] = value; - } - } - - if (this._remaining === 0) { - fulfill(promise, this._result); - } - }; - - Enumerator.prototype._willSettleAt = function _willSettleAt(promise, i) { - var enumerator = this; - - subscribe(promise, undefined, function (value) { - return enumerator._settledAt(FULFILLED, i, value); - }, function (reason) { - return enumerator._settledAt(REJECTED, i, reason); - }); - }; - - return Enumerator; -}(); - -/** - `Promise.all` accepts an array of promises, and returns a new promise which - is fulfilled with an array of fulfillment values for the passed promises, or - rejected with the reason of the first passed promise to be rejected. It casts all - elements of the passed iterable to promises as it runs this algorithm. - - Example: - - ```javascript - let promise1 = resolve(1); - let promise2 = resolve(2); - let promise3 = resolve(3); - let promises = [ promise1, promise2, promise3 ]; - - Promise.all(promises).then(function(array){ - // The array here would be [ 1, 2, 3 ]; - }); - ``` - - If any of the `promises` given to `all` are rejected, the first promise - that is rejected will be given as an argument to the returned promises's - rejection handler. For example: - - Example: - - ```javascript - let promise1 = resolve(1); - let promise2 = reject(new Error("2")); - let promise3 = reject(new Error("3")); - let promises = [ promise1, promise2, promise3 ]; - - Promise.all(promises).then(function(array){ - // Code here never runs because there are rejected promises! - }, function(error) { - // error.message === "2" - }); - ``` - - @method all - @static - @param {Array} entries array of promises - @param {String} label optional string for labeling the promise. - Useful for tooling. - @return {Promise} promise that is fulfilled when all `promises` have been - fulfilled, or rejected if any of them become rejected. - @static -*/ -function all(entries) { - return new Enumerator(this, entries).promise; -} - -/** - `Promise.race` returns a new promise which is settled in the same way as the - first passed promise to settle. - - Example: - - ```javascript - let promise1 = new Promise(function(resolve, reject){ - setTimeout(function(){ - resolve('promise 1'); - }, 200); - }); - - let promise2 = new Promise(function(resolve, reject){ - setTimeout(function(){ - resolve('promise 2'); - }, 100); - }); - - Promise.race([promise1, promise2]).then(function(result){ - // result === 'promise 2' because it was resolved before promise1 - // was resolved. - }); - ``` - - `Promise.race` is deterministic in that only the state of the first - settled promise matters. For example, even if other promises given to the - `promises` array argument are resolved, but the first settled promise has - become rejected before the other promises became fulfilled, the returned - promise will become rejected: - - ```javascript - let promise1 = new Promise(function(resolve, reject){ - setTimeout(function(){ - resolve('promise 1'); - }, 200); - }); - - let promise2 = new Promise(function(resolve, reject){ - setTimeout(function(){ - reject(new Error('promise 2')); - }, 100); - }); - - Promise.race([promise1, promise2]).then(function(result){ - // Code here never runs - }, function(reason){ - // reason.message === 'promise 2' because promise 2 became rejected before - // promise 1 became fulfilled - }); - ``` - - An example real-world use case is implementing timeouts: - - ```javascript - Promise.race([ajax('foo.json'), timeout(5000)]) - ``` - - @method race - @static - @param {Array} promises array of promises to observe - Useful for tooling. - @return {Promise} a promise which settles in the same way as the first passed - promise to settle. -*/ -function race(entries) { - /*jshint validthis:true */ - var Constructor = this; - - if (!isArray(entries)) { - return new Constructor(function (_, reject) { - return reject(new TypeError('You must pass an array to race.')); - }); - } else { - return new Constructor(function (resolve, reject) { - var length = entries.length; - for (var i = 0; i < length; i++) { - Constructor.resolve(entries[i]).then(resolve, reject); - } - }); - } -} - -/** - `Promise.reject` returns a promise rejected with the passed `reason`. - It is shorthand for the following: - - ```javascript - let promise = new Promise(function(resolve, reject){ - reject(new Error('WHOOPS')); - }); - - promise.then(function(value){ - // Code here doesn't run because the promise is rejected! - }, function(reason){ - // reason.message === 'WHOOPS' - }); - ``` - - Instead of writing the above, your code now simply becomes the following: - - ```javascript - let promise = Promise.reject(new Error('WHOOPS')); - - promise.then(function(value){ - // Code here doesn't run because the promise is rejected! - }, function(reason){ - // reason.message === 'WHOOPS' - }); - ``` - - @method reject - @static - @param {Any} reason value that the returned promise will be rejected with. - Useful for tooling. - @return {Promise} a promise rejected with the given `reason`. -*/ -function reject$1(reason) { - /*jshint validthis:true */ - var Constructor = this; - var promise = new Constructor(noop); - reject(promise, reason); - return promise; -} - -function needsResolver() { - throw new TypeError('You must pass a resolver function as the first argument to the promise constructor'); -} - -function needsNew() { - throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function."); -} - -/** - Promise objects represent the eventual result of an asynchronous operation. The - primary way of interacting with a promise is through its `then` method, which - registers callbacks to receive either a promise's eventual value or the reason - why the promise cannot be fulfilled. - - Terminology - ----------- - - - `promise` is an object or function with a `then` method whose behavior conforms to this specification. - - `thenable` is an object or function that defines a `then` method. - - `value` is any legal JavaScript value (including undefined, a thenable, or a promise). - - `exception` is a value that is thrown using the throw statement. - - `reason` is a value that indicates why a promise was rejected. - - `settled` the final resting state of a promise, fulfilled or rejected. - - A promise can be in one of three states: pending, fulfilled, or rejected. - - Promises that are fulfilled have a fulfillment value and are in the fulfilled - state. Promises that are rejected have a rejection reason and are in the - rejected state. A fulfillment value is never a thenable. - - Promises can also be said to *resolve* a value. If this value is also a - promise, then the original promise's settled state will match the value's - settled state. So a promise that *resolves* a promise that rejects will - itself reject, and a promise that *resolves* a promise that fulfills will - itself fulfill. - - - Basic Usage: - ------------ - - ```js - let promise = new Promise(function(resolve, reject) { - // on success - resolve(value); - - // on failure - reject(reason); - }); - - promise.then(function(value) { - // on fulfillment - }, function(reason) { - // on rejection - }); - ``` - - Advanced Usage: - --------------- - - Promises shine when abstracting away asynchronous interactions such as - `XMLHttpRequest`s. - - ```js - function getJSON(url) { - return new Promise(function(resolve, reject){ - let xhr = new XMLHttpRequest(); - - xhr.open('GET', url); - xhr.onreadystatechange = handler; - xhr.responseType = 'json'; - xhr.setRequestHeader('Accept', 'application/json'); - xhr.send(); - - function handler() { - if (this.readyState === this.DONE) { - if (this.status === 200) { - resolve(this.response); - } else { - reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']')); - } - } - }; - }); - } - - getJSON('/posts.json').then(function(json) { - // on fulfillment - }, function(reason) { - // on rejection - }); - ``` - - Unlike callbacks, promises are great composable primitives. - - ```js - Promise.all([ - getJSON('/posts'), - getJSON('/comments') - ]).then(function(values){ - values[0] // => postsJSON - values[1] // => commentsJSON - - return values; - }); - ``` - - @class Promise - @param {Function} resolver - Useful for tooling. - @constructor -*/ - -var Promise$2 = function () { - function Promise(resolver) { - this[PROMISE_ID] = nextId(); - this._result = this._state = undefined; - this._subscribers = []; - - if (noop !== resolver) { - typeof resolver !== 'function' && needsResolver(); - this instanceof Promise ? initializePromise(this, resolver) : needsNew(); - } - } - - /** - The primary way of interacting with a promise is through its `then` method, - which registers callbacks to receive either a promise's eventual value or the - reason why the promise cannot be fulfilled. - ```js - findUser().then(function(user){ - // user is available - }, function(reason){ - // user is unavailable, and you are given the reason why - }); - ``` - Chaining - -------- - The return value of `then` is itself a promise. This second, 'downstream' - promise is resolved with the return value of the first promise's fulfillment - or rejection handler, or rejected if the handler throws an exception. - ```js - findUser().then(function (user) { - return user.name; - }, function (reason) { - return 'default name'; - }).then(function (userName) { - // If `findUser` fulfilled, `userName` will be the user's name, otherwise it - // will be `'default name'` - }); - findUser().then(function (user) { - throw new Error('Found user, but still unhappy'); - }, function (reason) { - throw new Error('`findUser` rejected and we're unhappy'); - }).then(function (value) { - // never reached - }, function (reason) { - // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'. - // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'. - }); - ``` - If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream. - ```js - findUser().then(function (user) { - throw new PedagogicalException('Upstream error'); - }).then(function (value) { - // never reached - }).then(function (value) { - // never reached - }, function (reason) { - // The `PedgagocialException` is propagated all the way down to here - }); - ``` - Assimilation - ------------ - Sometimes the value you want to propagate to a downstream promise can only be - retrieved asynchronously. This can be achieved by returning a promise in the - fulfillment or rejection handler. The downstream promise will then be pending - until the returned promise is settled. This is called *assimilation*. - ```js - findUser().then(function (user) { - return findCommentsByAuthor(user); - }).then(function (comments) { - // The user's comments are now available - }); - ``` - If the assimliated promise rejects, then the downstream promise will also reject. - ```js - findUser().then(function (user) { - return findCommentsByAuthor(user); - }).then(function (comments) { - // If `findCommentsByAuthor` fulfills, we'll have the value here - }, function (reason) { - // If `findCommentsByAuthor` rejects, we'll have the reason here - }); - ``` - Simple Example - -------------- - Synchronous Example - ```javascript - let result; - try { - result = findResult(); - // success - } catch(reason) { - // failure - } - ``` - Errback Example - ```js - findResult(function(result, err){ - if (err) { - // failure - } else { - // success - } - }); - ``` - Promise Example; - ```javascript - findResult().then(function(result){ - // success - }, function(reason){ - // failure - }); - ``` - Advanced Example - -------------- - Synchronous Example - ```javascript - let author, books; - try { - author = findAuthor(); - books = findBooksByAuthor(author); - // success - } catch(reason) { - // failure - } - ``` - Errback Example - ```js - function foundBooks(books) { - } - function failure(reason) { - } - findAuthor(function(author, err){ - if (err) { - failure(err); - // failure - } else { - try { - findBoooksByAuthor(author, function(books, err) { - if (err) { - failure(err); - } else { - try { - foundBooks(books); - } catch(reason) { - failure(reason); - } - } - }); - } catch(error) { - failure(err); - } - // success - } - }); - ``` - Promise Example; - ```javascript - findAuthor(). - then(findBooksByAuthor). - then(function(books){ - // found books - }).catch(function(reason){ - // something went wrong - }); - ``` - @method then - @param {Function} onFulfilled - @param {Function} onRejected - Useful for tooling. - @return {Promise} - */ - - /** - `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same - as the catch block of a try/catch statement. - ```js - function findAuthor(){ - throw new Error('couldn't find that author'); - } - // synchronous - try { - findAuthor(); - } catch(reason) { - // something went wrong - } - // async with promises - findAuthor().catch(function(reason){ - // something went wrong - }); - ``` - @method catch - @param {Function} onRejection - Useful for tooling. - @return {Promise} - */ - - - Promise.prototype.catch = function _catch(onRejection) { - return this.then(null, onRejection); - }; - - /** - `finally` will be invoked regardless of the promise's fate just as native - try/catch/finally behaves - - Synchronous example: - - ```js - findAuthor() { - if (Math.random() > 0.5) { - throw new Error(); - } - return new Author(); - } - - try { - return findAuthor(); // succeed or fail - } catch(error) { - return findOtherAuther(); - } finally { - // always runs - // doesn't affect the return value - } - ``` - - Asynchronous example: - - ```js - findAuthor().catch(function(reason){ - return findOtherAuther(); - }).finally(function(){ - // author was either found, or not - }); - ``` - - @method finally - @param {Function} callback - @return {Promise} - */ - - - Promise.prototype.finally = function _finally(callback) { - var promise = this; - var constructor = promise.constructor; - - return promise.then(function (value) { - return constructor.resolve(callback()).then(function () { - return value; - }); - }, function (reason) { - return constructor.resolve(callback()).then(function () { - throw reason; - }); - }); - }; - - return Promise; -}(); - -Promise$2.prototype.then = then; -Promise$2.all = all; -Promise$2.race = race; -Promise$2.resolve = resolve$1; -Promise$2.reject = reject$1; -Promise$2._setScheduler = setScheduler; -Promise$2._setAsap = setAsap; -Promise$2._asap = asap; - -/*global self*/ -function polyfill() { - var local = void 0; - - if (typeof commonjsGlobal !== 'undefined') { - local = commonjsGlobal; - } else if (typeof self !== 'undefined') { - local = self; - } else { - try { - local = Function('return this')(); - } catch (e) { - throw new Error('polyfill failed because global object is unavailable in this environment'); - } - } - - var P = local.Promise; - - if (P) { - var promiseToString = null; - try { - promiseToString = Object.prototype.toString.call(P.resolve()); - } catch (e) { - // silently ignored - } - - if (promiseToString === '[object Promise]' && !P.cast) { - return; - } - } - - local.Promise = Promise$2; -} - -// Strange compat.. -Promise$2.polyfill = polyfill; -Promise$2.Promise = Promise$2; - -Promise$2.polyfill(); - -return Promise$2; - -}))); - - - - -}); - -var Errors = createCommonjsModule(function (module, exports) { -Object.defineProperty(exports, "__esModule", { value: true }); - -/** Error thrown when an HTTP request fails. */ -var HttpError = /** @class */ (function (_super) { - tslib_1.__extends(HttpError, _super); - /** Constructs a new instance of {@link HttpError}. - * - * @param {string} errorMessage A descriptive error message. - * @param {number} statusCode The HTTP status code represented by this error. - */ - function HttpError(errorMessage, statusCode) { - var _newTarget = this.constructor; - var _this = this; - var trueProto = _newTarget.prototype; - _this = _super.call(this, errorMessage) || this; - _this.statusCode = statusCode; - // Workaround issue in Typescript compiler - // https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200 - _this.__proto__ = trueProto; - return _this; - } - return HttpError; -}(Error)); -exports.HttpError = HttpError; -/** Error thrown when a timeout elapses. */ -var TimeoutError = /** @class */ (function (_super) { - tslib_1.__extends(TimeoutError, _super); - /** Constructs a new instance of {@link TimeoutError}. - * - * @param {string} errorMessage A descriptive error message. - */ - function TimeoutError(errorMessage) { - var _newTarget = this.constructor; - if (errorMessage === void 0) { errorMessage = "A timeout occurred."; } - var _this = this; - var trueProto = _newTarget.prototype; - _this = _super.call(this, errorMessage) || this; - // Workaround issue in Typescript compiler - // https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200 - _this.__proto__ = trueProto; - return _this; - } - return TimeoutError; -}(Error)); -exports.TimeoutError = TimeoutError; - -}); - -unwrapExports(Errors); -var Errors_1 = Errors.HttpError; -var Errors_2 = Errors.TimeoutError; - -var ILogger = createCommonjsModule(function (module, exports) { -Object.defineProperty(exports, "__esModule", { value: true }); -// These values are designed to match the ASP.NET Log Levels since that's the pattern we're emulating here. -/** Indicates the severity of a log message. - * - * Log Levels are ordered in increasing severity. So `Debug` is more severe than `Trace`, etc. - */ -var LogLevel; -(function (LogLevel) { - /** Log level for very low severity diagnostic messages. */ - LogLevel[LogLevel["Trace"] = 0] = "Trace"; - /** Log level for low severity diagnostic messages. */ - LogLevel[LogLevel["Debug"] = 1] = "Debug"; - /** Log level for informational diagnostic messages. */ - LogLevel[LogLevel["Information"] = 2] = "Information"; - /** Log level for diagnostic messages that indicate a non-fatal problem. */ - LogLevel[LogLevel["Warning"] = 3] = "Warning"; - /** Log level for diagnostic messages that indicate a failure in the current operation. */ - LogLevel[LogLevel["Error"] = 4] = "Error"; - /** Log level for diagnostic messages that indicate a failure that will terminate the entire application. */ - LogLevel[LogLevel["Critical"] = 5] = "Critical"; - /** The highest possible log level. Used when configuring logging to indicate that no log messages should be emitted. */ - LogLevel[LogLevel["None"] = 6] = "None"; -})(LogLevel = exports.LogLevel || (exports.LogLevel = {})); - -}); - -unwrapExports(ILogger); -var ILogger_1 = ILogger.LogLevel; - -var HttpClient_1 = createCommonjsModule(function (module, exports) { -Object.defineProperty(exports, "__esModule", { value: true }); - - - -/** Represents an HTTP response. */ -var HttpResponse = /** @class */ (function () { - function HttpResponse(statusCode, statusText, content) { - this.statusCode = statusCode; - this.statusText = statusText; - this.content = content; - } - return HttpResponse; -}()); -exports.HttpResponse = HttpResponse; -/** Abstraction over an HTTP client. - * - * This class provides an abstraction over an HTTP client so that a different implementation can be provided on different platforms. - */ -var HttpClient = /** @class */ (function () { - function HttpClient() { - } - HttpClient.prototype.get = function (url, options) { - return this.send(tslib_1.__assign({}, options, { method: "GET", url: url })); - }; - HttpClient.prototype.post = function (url, options) { - return this.send(tslib_1.__assign({}, options, { method: "POST", url: url })); - }; - HttpClient.prototype.delete = function (url, options) { - return this.send(tslib_1.__assign({}, options, { method: "DELETE", url: url })); - }; - return HttpClient; -}()); -exports.HttpClient = HttpClient; -/** Default implementation of {@link HttpClient}. */ -var DefaultHttpClient = /** @class */ (function (_super) { - tslib_1.__extends(DefaultHttpClient, _super); - /** Creates a new instance of the {@link DefaultHttpClient}, using the provided {@link ILogger} to log messages. */ - function DefaultHttpClient(logger) { - var _this = _super.call(this) || this; - _this.logger = logger; - return _this; - } - /** @inheritDoc */ - DefaultHttpClient.prototype.send = function (request) { - var _this = this; - return new Promise(function (resolve, reject) { - var xhr = new XMLHttpRequest(); - xhr.open(request.method, request.url, true); - xhr.withCredentials = true; - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - // Explicitly setting the Content-Type header for React Native on Android platform. - xhr.setRequestHeader("Content-Type", "text/plain;charset=UTF-8"); - if (request.headers) { - Object.keys(request.headers) - .forEach(function (header) { return xhr.setRequestHeader(header, request.headers[header]); }); - } - if (request.responseType) { - xhr.responseType = request.responseType; - } - if (request.abortSignal) { - request.abortSignal.onabort = function () { - xhr.abort(); - }; - } - if (request.timeout) { - xhr.timeout = request.timeout; - } - xhr.onload = function () { - if (request.abortSignal) { - request.abortSignal.onabort = null; - } - if (xhr.status >= 200 && xhr.status < 300) { - resolve(new HttpResponse(xhr.status, xhr.statusText, xhr.response || xhr.responseText)); - } - else { - reject(new Errors.HttpError(xhr.statusText, xhr.status)); - } - }; - xhr.onerror = function () { - _this.logger.log(ILogger.LogLevel.Warning, "Error from HTTP request. " + xhr.status + ": " + xhr.statusText); - reject(new Errors.HttpError(xhr.statusText, xhr.status)); - }; - xhr.ontimeout = function () { - _this.logger.log(ILogger.LogLevel.Warning, "Timeout from HTTP request."); - reject(new Errors.TimeoutError()); - }; - xhr.send(request.content || ""); - }); - }; - return DefaultHttpClient; -}(HttpClient)); -exports.DefaultHttpClient = DefaultHttpClient; - -}); - -unwrapExports(HttpClient_1); -var HttpClient_2 = HttpClient_1.HttpResponse; -var HttpClient_3 = HttpClient_1.HttpClient; -var HttpClient_4 = HttpClient_1.DefaultHttpClient; - -var TextMessageFormat_1 = createCommonjsModule(function (module, exports) { -Object.defineProperty(exports, "__esModule", { value: true }); -// Not exported from index -var TextMessageFormat = /** @class */ (function () { - function TextMessageFormat() { - } - TextMessageFormat.write = function (output) { - return "" + output + TextMessageFormat.RecordSeparator; - }; - TextMessageFormat.parse = function (input) { - if (input[input.length - 1] !== TextMessageFormat.RecordSeparator) { - throw new Error("Message is incomplete."); - } - var messages = input.split(TextMessageFormat.RecordSeparator); - messages.pop(); - return messages; - }; - TextMessageFormat.RecordSeparatorCode = 0x1e; - TextMessageFormat.RecordSeparator = String.fromCharCode(TextMessageFormat.RecordSeparatorCode); - return TextMessageFormat; -}()); -exports.TextMessageFormat = TextMessageFormat; - -}); - -unwrapExports(TextMessageFormat_1); -var TextMessageFormat_2 = TextMessageFormat_1.TextMessageFormat; - -var HandshakeProtocol_1 = createCommonjsModule(function (module, exports) { -Object.defineProperty(exports, "__esModule", { value: true }); - -var HandshakeProtocol = /** @class */ (function () { - function HandshakeProtocol() { - } - // Handshake request is always JSON - HandshakeProtocol.prototype.writeHandshakeRequest = function (handshakeRequest) { - return TextMessageFormat_1.TextMessageFormat.write(JSON.stringify(handshakeRequest)); - }; - HandshakeProtocol.prototype.parseHandshakeResponse = function (data) { - var responseMessage; - var messageData; - var remainingData; - if (data instanceof ArrayBuffer) { - // Format is binary but still need to read JSON text from handshake response - var binaryData = new Uint8Array(data); - var separatorIndex = binaryData.indexOf(TextMessageFormat_1.TextMessageFormat.RecordSeparatorCode); - if (separatorIndex === -1) { - throw new Error("Message is incomplete."); - } - // content before separator is handshake response - // optional content after is additional messages - var responseLength = separatorIndex + 1; - messageData = String.fromCharCode.apply(null, binaryData.slice(0, responseLength)); - remainingData = (binaryData.byteLength > responseLength) ? binaryData.slice(responseLength).buffer : null; - } - else { - var textData = data; - var separatorIndex = textData.indexOf(TextMessageFormat_1.TextMessageFormat.RecordSeparator); - if (separatorIndex === -1) { - throw new Error("Message is incomplete."); - } - // content before separator is handshake response - // optional content after is additional messages - var responseLength = separatorIndex + 1; - messageData = textData.substring(0, responseLength); - remainingData = (textData.length > responseLength) ? textData.substring(responseLength) : null; - } - // At this point we should have just the single handshake message - var messages = TextMessageFormat_1.TextMessageFormat.parse(messageData); - responseMessage = JSON.parse(messages[0]); - // multiple messages could have arrived with handshake - // return additional data to be parsed as usual, or null if all parsed - return [remainingData, responseMessage]; - }; - return HandshakeProtocol; -}()); -exports.HandshakeProtocol = HandshakeProtocol; - -}); - -unwrapExports(HandshakeProtocol_1); -var HandshakeProtocol_2 = HandshakeProtocol_1.HandshakeProtocol; - -var IHubProtocol = createCommonjsModule(function (module, exports) { -Object.defineProperty(exports, "__esModule", { value: true }); -/** Defines the type of a Hub Message. */ -var MessageType; -(function (MessageType) { - /** Indicates the message is an Invocation message and implements the {@link InvocationMessage} interface. */ - MessageType[MessageType["Invocation"] = 1] = "Invocation"; - /** Indicates the message is a StreamItem message and implements the {@link StreamItemMessage} interface. */ - MessageType[MessageType["StreamItem"] = 2] = "StreamItem"; - /** Indicates the message is a Completion message and implements the {@link CompletionMessage} interface. */ - MessageType[MessageType["Completion"] = 3] = "Completion"; - /** Indicates the message is a Stream Invocation message and implements the {@link StreamInvocationMessage} interface. */ - MessageType[MessageType["StreamInvocation"] = 4] = "StreamInvocation"; - /** Indicates the message is a Cancel Invocation message and implements the {@link CancelInvocationMessage} interface. */ - MessageType[MessageType["CancelInvocation"] = 5] = "CancelInvocation"; - /** Indicates the message is a Ping message and implements the {@link PingMessage} interface. */ - MessageType[MessageType["Ping"] = 6] = "Ping"; - /** Indicates the message is a Close message and implements the {@link CloseMessage} interface. */ - MessageType[MessageType["Close"] = 7] = "Close"; -})(MessageType = exports.MessageType || (exports.MessageType = {})); - -}); - -unwrapExports(IHubProtocol); -var IHubProtocol_1 = IHubProtocol.MessageType; - -var Loggers = createCommonjsModule(function (module, exports) { -Object.defineProperty(exports, "__esModule", { value: true }); -/** A logger that does nothing when log messages are sent to it. */ -var NullLogger = /** @class */ (function () { - function NullLogger() { - } - /** @inheritDoc */ - NullLogger.prototype.log = function (logLevel, message) { - }; - /** The singleton instance of the {@link NullLogger}. */ - NullLogger.instance = new NullLogger(); - return NullLogger; -}()); -exports.NullLogger = NullLogger; - -}); - -unwrapExports(Loggers); -var Loggers_1 = Loggers.NullLogger; - -var Utils = createCommonjsModule(function (module, exports) { -Object.defineProperty(exports, "__esModule", { value: true }); - - - -var Arg = /** @class */ (function () { - function Arg() { - } - Arg.isRequired = function (val, name) { - if (val === null || val === undefined) { - throw new Error("The '" + name + "' argument is required."); - } - }; - Arg.isIn = function (val, values, name) { - // TypeScript enums have keys for **both** the name and the value of each enum member on the type itself. - if (!(val in values)) { - throw new Error("Unknown " + name + " value: " + val + "."); - } - }; - return Arg; -}()); -exports.Arg = Arg; -function getDataDetail(data, includeContent) { - var length = null; - if (data instanceof ArrayBuffer) { - length = "Binary data of length " + data.byteLength; - if (includeContent) { - length += ". Content: '" + formatArrayBuffer(data) + "'"; - } - } - else if (typeof data === "string") { - length = "String data of length " + data.length; - if (includeContent) { - length += ". Content: '" + data + "'."; - } - } - return length; -} -exports.getDataDetail = getDataDetail; -function formatArrayBuffer(data) { - var view = new Uint8Array(data); - // Uint8Array.map only supports returning another Uint8Array? - var str = ""; - view.forEach(function (num) { - var pad = num < 16 ? "0" : ""; - str += "0x" + pad + num.toString(16) + " "; - }); - // Trim of trailing space. - return str.substr(0, str.length - 1); -} -exports.formatArrayBuffer = formatArrayBuffer; -function sendMessage(logger, transportName, httpClient, url, accessTokenFactory, content, logMessageContent) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - var headers, token, response, _a; - return tslib_1.__generator(this, function (_b) { - switch (_b.label) { - case 0: return [4 /*yield*/, accessTokenFactory()]; - case 1: - token = _b.sent(); - if (token) { - headers = (_a = {}, _a["Authorization"] = "Bearer " + token, _a); - } - logger.log(ILogger.LogLevel.Trace, "(" + transportName + " transport) sending data. " + getDataDetail(content, logMessageContent) + "."); - return [4 /*yield*/, httpClient.post(url, { - content: content, - headers: headers, - })]; - case 2: - response = _b.sent(); - logger.log(ILogger.LogLevel.Trace, "(" + transportName + " transport) request complete. Response status: " + response.statusCode + "."); - return [2 /*return*/]; - } - }); - }); -} -exports.sendMessage = sendMessage; -function createLogger(logger) { - if (logger === undefined) { - return new ConsoleLogger(ILogger.LogLevel.Information); - } - if (logger === null) { - return Loggers.NullLogger.instance; - } - if (logger.log) { - return logger; - } - return new ConsoleLogger(logger); -} -exports.createLogger = createLogger; -var Subject = /** @class */ (function () { - function Subject(cancelCallback) { - this.observers = []; - this.cancelCallback = cancelCallback; - } - Subject.prototype.next = function (item) { - for (var _i = 0, _a = this.observers; _i < _a.length; _i++) { - var observer = _a[_i]; - observer.next(item); - } - }; - Subject.prototype.error = function (err) { - for (var _i = 0, _a = this.observers; _i < _a.length; _i++) { - var observer = _a[_i]; - if (observer.error) { - observer.error(err); - } - } - }; - Subject.prototype.complete = function () { - for (var _i = 0, _a = this.observers; _i < _a.length; _i++) { - var observer = _a[_i]; - if (observer.complete) { - observer.complete(); - } - } - }; - Subject.prototype.subscribe = function (observer) { - this.observers.push(observer); - return new SubjectSubscription(this, observer); - }; - return Subject; -}()); -exports.Subject = Subject; -var SubjectSubscription = /** @class */ (function () { - function SubjectSubscription(subject, observer) { - this.subject = subject; - this.observer = observer; - } - SubjectSubscription.prototype.dispose = function () { - var index = this.subject.observers.indexOf(this.observer); - if (index > -1) { - this.subject.observers.splice(index, 1); - } - if (this.subject.observers.length === 0) { - this.subject.cancelCallback().catch(function (_) { }); - } - }; - return SubjectSubscription; -}()); -exports.SubjectSubscription = SubjectSubscription; -var ConsoleLogger = /** @class */ (function () { - function ConsoleLogger(minimumLogLevel) { - this.minimumLogLevel = minimumLogLevel; - } - ConsoleLogger.prototype.log = function (logLevel, message) { - if (logLevel >= this.minimumLogLevel) { - switch (logLevel) { - case ILogger.LogLevel.Critical: - case ILogger.LogLevel.Error: - console.error(ILogger.LogLevel[logLevel] + ": " + message); - break; - case ILogger.LogLevel.Warning: - console.warn(ILogger.LogLevel[logLevel] + ": " + message); - break; - case ILogger.LogLevel.Information: - console.info(ILogger.LogLevel[logLevel] + ": " + message); - break; - default: - // console.debug only goes to attached debuggers in Node, so we use console.log for Trace and Debug - console.log(ILogger.LogLevel[logLevel] + ": " + message); - break; - } - } - }; - return ConsoleLogger; -}()); -exports.ConsoleLogger = ConsoleLogger; - -}); - -unwrapExports(Utils); -var Utils_1 = Utils.Arg; -var Utils_2 = Utils.getDataDetail; -var Utils_3 = Utils.formatArrayBuffer; -var Utils_4 = Utils.sendMessage; -var Utils_5 = Utils.createLogger; -var Utils_6 = Utils.Subject; -var Utils_7 = Utils.SubjectSubscription; -var Utils_8 = Utils.ConsoleLogger; - -var HubConnection_1 = createCommonjsModule(function (module, exports) { -Object.defineProperty(exports, "__esModule", { value: true }); - - - - - -var DEFAULT_TIMEOUT_IN_MS = 30 * 1000; -/** Represents a connection to a SignalR Hub. */ -var HubConnection = /** @class */ (function () { - function HubConnection(connection, logger, protocol) { - var _this = this; - Utils.Arg.isRequired(connection, "connection"); - Utils.Arg.isRequired(logger, "logger"); - Utils.Arg.isRequired(protocol, "protocol"); - this.serverTimeoutInMilliseconds = DEFAULT_TIMEOUT_IN_MS; - this.logger = logger; - this.protocol = protocol; - this.connection = connection; - this.handshakeProtocol = new HandshakeProtocol_1.HandshakeProtocol(); - this.connection.onreceive = function (data) { return _this.processIncomingData(data); }; - this.connection.onclose = function (error) { return _this.connectionClosed(error); }; - this.callbacks = {}; - this.methods = {}; - this.closedCallbacks = []; - this.id = 0; - } - /** @internal */ - // Using a public static factory method means we can have a private constructor and an _internal_ - // create method that can be used by HubConnectionBuilder. An "internal" constructor would just - // be stripped away and the '.d.ts' file would have no constructor, which is interpreted as a - // public parameter-less constructor. - HubConnection.create = function (connection, logger, protocol) { - return new HubConnection(connection, logger, protocol); - }; - /** Starts the connection. - * - * @returns {Promise} A Promise that resolves when the connection has been successfully established, or rejects with an error. - */ - HubConnection.prototype.start = function () { - return tslib_1.__awaiter(this, void 0, void 0, function () { - var handshakeRequest; - return tslib_1.__generator(this, function (_a) { - switch (_a.label) { - case 0: - handshakeRequest = { - protocol: this.protocol.name, - version: this.protocol.version, - }; - this.logger.log(ILogger.LogLevel.Debug, "Starting HubConnection."); - this.receivedHandshakeResponse = false; - return [4 /*yield*/, this.connection.start(this.protocol.transferFormat)]; - case 1: - _a.sent(); - this.logger.log(ILogger.LogLevel.Debug, "Sending handshake request."); - return [4 /*yield*/, this.connection.send(this.handshakeProtocol.writeHandshakeRequest(handshakeRequest))]; - case 2: - _a.sent(); - this.logger.log(ILogger.LogLevel.Information, "Using HubProtocol '" + this.protocol.name + "'."); - // defensively cleanup timeout in case we receive a message from the server before we finish start - this.cleanupTimeout(); - this.configureTimeout(); - return [2 /*return*/]; - } - }); - }); - }; - /** Stops the connection. - * - * @returns {Promise} A Promise that resolves when the connection has been successfully terminated, or rejects with an error. - */ - HubConnection.prototype.stop = function () { - this.logger.log(ILogger.LogLevel.Debug, "Stopping HubConnection."); - this.cleanupTimeout(); - return this.connection.stop(); - }; - /** Invokes a streaming hub method on the server using the specified name and arguments. - * - * @typeparam T The type of the items returned by the server. - * @param {string} methodName The name of the server method to invoke. - * @param {any[]} args The arguments used to invoke the server method. - * @returns {IStreamResult} An object that yields results from the server as they are received. - */ - HubConnection.prototype.stream = function (methodName) { - var _this = this; - var args = []; - for (var _i = 1; _i < arguments.length; _i++) { - args[_i - 1] = arguments[_i]; - } - var invocationDescriptor = this.createStreamInvocation(methodName, args); - var subject = new Utils.Subject(function () { - var cancelInvocation = _this.createCancelInvocation(invocationDescriptor.invocationId); - var cancelMessage = _this.protocol.writeMessage(cancelInvocation); - delete _this.callbacks[invocationDescriptor.invocationId]; - return _this.connection.send(cancelMessage); - }); - this.callbacks[invocationDescriptor.invocationId] = function (invocationEvent, error) { - if (error) { - subject.error(error); - return; - } - if (invocationEvent.type === IHubProtocol.MessageType.Completion) { - if (invocationEvent.error) { - subject.error(new Error(invocationEvent.error)); - } - else { - subject.complete(); - } - } - else { - subject.next((invocationEvent.item)); - } - }; - var message = this.protocol.writeMessage(invocationDescriptor); - this.connection.send(message) - .catch(function (e) { - subject.error(e); - delete _this.callbacks[invocationDescriptor.invocationId]; - }); - return subject; - }; - /** Invokes a hub method on the server using the specified name and arguments. Does not wait for a response from the receiver. - * - * The Promise returned by this method resolves when the client has sent the invocation to the server. The server may still - * be processing the invocation. - * - * @param {string} methodName The name of the server method to invoke. - * @param {any[]} args The arguments used to invoke the server method. - * @returns {Promise} A Promise that resolves when the invocation has been successfully sent, or rejects with an error. - */ - HubConnection.prototype.send = function (methodName) { - var args = []; - for (var _i = 1; _i < arguments.length; _i++) { - args[_i - 1] = arguments[_i]; - } - var invocationDescriptor = this.createInvocation(methodName, args, true); - var message = this.protocol.writeMessage(invocationDescriptor); - return this.connection.send(message); - }; - /** Invokes a hub method on the server using the specified name and arguments. - * - * The Promise returned by this method resolves when the server indicates it has finished invoking the method. When the promise - * resolves, the server has finished invoking the method. If the server method returns a result, it is produced as the result of - * resolving the Promise. - * - * @typeparam T The expected return type. - * @param {string} methodName The name of the server method to invoke. - * @param {any[]} args The arguments used to invoke the server method. - * @returns {Promise} A Promise that resolves with the result of the server method (if any), or rejects with an error. - */ - HubConnection.prototype.invoke = function (methodName) { - var _this = this; - var args = []; - for (var _i = 1; _i < arguments.length; _i++) { - args[_i - 1] = arguments[_i]; - } - var invocationDescriptor = this.createInvocation(methodName, args, false); - var p = new Promise(function (resolve, reject) { - _this.callbacks[invocationDescriptor.invocationId] = function (invocationEvent, error) { - if (error) { - reject(error); - return; - } - if (invocationEvent.type === IHubProtocol.MessageType.Completion) { - var completionMessage = invocationEvent; - if (completionMessage.error) { - reject(new Error(completionMessage.error)); - } - else { - resolve(completionMessage.result); - } - } - else { - reject(new Error("Unexpected message type: " + invocationEvent.type)); - } - }; - var message = _this.protocol.writeMessage(invocationDescriptor); - _this.connection.send(message) - .catch(function (e) { - reject(e); - delete _this.callbacks[invocationDescriptor.invocationId]; - }); - }); - return p; - }; - /** Registers a handler that will be invoked when the hub method with the specified method name is invoked. - * - * @param {string} methodName The name of the hub method to define. - * @param {Function} newMethod The handler that will be raised when the hub method is invoked. - */ - HubConnection.prototype.on = function (methodName, newMethod) { - if (!methodName || !newMethod) { - return; - } - methodName = methodName.toLowerCase(); - if (!this.methods[methodName]) { - this.methods[methodName] = []; - } - // Preventing adding the same handler multiple times. - if (this.methods[methodName].indexOf(newMethod) !== -1) { - return; - } - this.methods[methodName].push(newMethod); - }; - HubConnection.prototype.off = function (methodName, method) { - if (!methodName) { - return; - } - methodName = methodName.toLowerCase(); - var handlers = this.methods[methodName]; - if (!handlers) { - return; - } - if (method) { - var removeIdx = handlers.indexOf(method); - if (removeIdx !== -1) { - handlers.splice(removeIdx, 1); - if (handlers.length === 0) { - delete this.methods[methodName]; - } - } - } - else { - delete this.methods[methodName]; - } - }; - /** Registers a handler that will be invoked when the connection is closed. - * - * @param {Function} callback The handler that will be invoked when the connection is closed. Optionally receives a single argument containing the error that caused the connection to close (if any). - */ - HubConnection.prototype.onclose = function (callback) { - if (callback) { - this.closedCallbacks.push(callback); - } - }; - HubConnection.prototype.processIncomingData = function (data) { - this.cleanupTimeout(); - if (!this.receivedHandshakeResponse) { - data = this.processHandshakeResponse(data); - this.receivedHandshakeResponse = true; - } - // Data may have all been read when processing handshake response - if (data) { - // Parse the messages - var messages = this.protocol.parseMessages(data, this.logger); - for (var _i = 0, messages_1 = messages; _i < messages_1.length; _i++) { - var message = messages_1[_i]; - switch (message.type) { - case IHubProtocol.MessageType.Invocation: - this.invokeClientMethod(message); - break; - case IHubProtocol.MessageType.StreamItem: - case IHubProtocol.MessageType.Completion: - var callback = this.callbacks[message.invocationId]; - if (callback != null) { - if (message.type === IHubProtocol.MessageType.Completion) { - delete this.callbacks[message.invocationId]; - } - callback(message); - } - break; - case IHubProtocol.MessageType.Ping: - // Don't care about pings - break; - case IHubProtocol.MessageType.Close: - this.logger.log(ILogger.LogLevel.Information, "Close message received from server."); - this.connection.stop(message.error ? new Error("Server returned an error on close: " + message.error) : null); - break; - default: - this.logger.log(ILogger.LogLevel.Warning, "Invalid message type: " + message.type); - break; - } - } - } - this.configureTimeout(); - }; - HubConnection.prototype.processHandshakeResponse = function (data) { - var responseMessage; - var remainingData; - try { - _a = this.handshakeProtocol.parseHandshakeResponse(data), remainingData = _a[0], responseMessage = _a[1]; - } - catch (e) { - var message = "Error parsing handshake response: " + e; - this.logger.log(ILogger.LogLevel.Error, message); - var error = new Error(message); - this.connection.stop(error); - throw error; - } - if (responseMessage.error) { - var message = "Server returned handshake error: " + responseMessage.error; - this.logger.log(ILogger.LogLevel.Error, message); - this.connection.stop(new Error(message)); - } - else { - this.logger.log(ILogger.LogLevel.Debug, "Server handshake complete."); - } - return remainingData; - var _a; - }; - HubConnection.prototype.configureTimeout = function () { - var _this = this; - if (!this.connection.features || !this.connection.features.inherentKeepAlive) { - // Set the timeout timer - this.timeoutHandle = setTimeout(function () { return _this.serverTimeout(); }, this.serverTimeoutInMilliseconds); - } - }; - HubConnection.prototype.serverTimeout = function () { - // The server hasn't talked to us in a while. It doesn't like us anymore ... :( - // Terminate the connection - this.connection.stop(new Error("Server timeout elapsed without receiving a message from the server.")); - }; - HubConnection.prototype.invokeClientMethod = function (invocationMessage) { - var _this = this; - var methods = this.methods[invocationMessage.target.toLowerCase()]; - if (methods) { - methods.forEach(function (m) { return m.apply(_this, invocationMessage.arguments); }); - if (invocationMessage.invocationId) { - // This is not supported in v1. So we return an error to avoid blocking the server waiting for the response. - var message = "Server requested a response, which is not supported in this version of the client."; - this.logger.log(ILogger.LogLevel.Error, message); - this.connection.stop(new Error(message)); - } - } - else { - this.logger.log(ILogger.LogLevel.Warning, "No client method with the name '" + invocationMessage.target + "' found."); - } - }; - HubConnection.prototype.connectionClosed = function (error) { - var _this = this; - var callbacks = this.callbacks; - this.callbacks = {}; - Object.keys(callbacks) - .forEach(function (key) { - var callback = callbacks[key]; - callback(undefined, error ? error : new Error("Invocation canceled due to connection being closed.")); - }); - this.cleanupTimeout(); - this.closedCallbacks.forEach(function (c) { return c.apply(_this, [error]); }); - }; - HubConnection.prototype.cleanupTimeout = function () { - if (this.timeoutHandle) { - clearTimeout(this.timeoutHandle); - } - }; - HubConnection.prototype.createInvocation = function (methodName, args, nonblocking) { - if (nonblocking) { - return { - arguments: args, - target: methodName, - type: IHubProtocol.MessageType.Invocation, - }; - } - else { - var id = this.id; - this.id++; - return { - arguments: args, - invocationId: id.toString(), - target: methodName, - type: IHubProtocol.MessageType.Invocation, - }; - } - }; - HubConnection.prototype.createStreamInvocation = function (methodName, args) { - var id = this.id; - this.id++; - return { - arguments: args, - invocationId: id.toString(), - target: methodName, - type: IHubProtocol.MessageType.StreamInvocation, - }; - }; - HubConnection.prototype.createCancelInvocation = function (id) { - return { - invocationId: id, - type: IHubProtocol.MessageType.CancelInvocation, - }; - }; - return HubConnection; -}()); -exports.HubConnection = HubConnection; - -}); - -unwrapExports(HubConnection_1); -var HubConnection_2 = HubConnection_1.HubConnection; - -var ITransport = createCommonjsModule(function (module, exports) { -Object.defineProperty(exports, "__esModule", { value: true }); -// This will be treated as a bit flag in the future, so we keep it using power-of-two values. -/** Specifies a specific HTTP transport type. */ -var HttpTransportType; -(function (HttpTransportType) { - /** Specifies no transport preference. */ - HttpTransportType[HttpTransportType["None"] = 0] = "None"; - /** Specifies the WebSockets transport. */ - HttpTransportType[HttpTransportType["WebSockets"] = 1] = "WebSockets"; - /** Specifies the Server-Sent Events transport. */ - HttpTransportType[HttpTransportType["ServerSentEvents"] = 2] = "ServerSentEvents"; - /** Specifies the Long Polling transport. */ - HttpTransportType[HttpTransportType["LongPolling"] = 4] = "LongPolling"; -})(HttpTransportType = exports.HttpTransportType || (exports.HttpTransportType = {})); -/** Specifies the transfer format for a connection. */ -var TransferFormat; -(function (TransferFormat) { - /** Specifies that only text data will be transmitted over the connection. */ - TransferFormat[TransferFormat["Text"] = 1] = "Text"; - /** Specifies that binary data will be transmitted over the connection. */ - TransferFormat[TransferFormat["Binary"] = 2] = "Binary"; -})(TransferFormat = exports.TransferFormat || (exports.TransferFormat = {})); - -}); - -unwrapExports(ITransport); -var ITransport_1 = ITransport.HttpTransportType; -var ITransport_2 = ITransport.TransferFormat; - -var AbortController_1 = createCommonjsModule(function (module, exports) { -Object.defineProperty(exports, "__esModule", { value: true }); -// Rough polyfill of https://developer.mozilla.org/en-US/docs/Web/API/AbortController -// We don't actually ever use the API being polyfilled, we always use the polyfill because -// it's a very new API right now. -// Not exported from index. -var AbortController = /** @class */ (function () { - function AbortController() { - this.isAborted = false; - } - AbortController.prototype.abort = function () { - if (!this.isAborted) { - this.isAborted = true; - if (this.onabort) { - this.onabort(); - } - } - }; - Object.defineProperty(AbortController.prototype, "signal", { - get: function () { - return this; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(AbortController.prototype, "aborted", { - get: function () { - return this.isAborted; - }, - enumerable: true, - configurable: true - }); - return AbortController; -}()); -exports.AbortController = AbortController; - -}); - -unwrapExports(AbortController_1); -var AbortController_2 = AbortController_1.AbortController; - -var LongPollingTransport_1 = createCommonjsModule(function (module, exports) { -Object.defineProperty(exports, "__esModule", { value: true }); - - - - - - -var SHUTDOWN_TIMEOUT = 5 * 1000; -// Not exported from 'index', this type is internal. -var LongPollingTransport = /** @class */ (function () { - function LongPollingTransport(httpClient, accessTokenFactory, logger, logMessageContent, shutdownTimeout) { - this.httpClient = httpClient; - this.accessTokenFactory = accessTokenFactory || (function () { return null; }); - this.logger = logger; - this.pollAbort = new AbortController_1.AbortController(); - this.logMessageContent = logMessageContent; - this.shutdownTimeout = shutdownTimeout || SHUTDOWN_TIMEOUT; - } - Object.defineProperty(LongPollingTransport.prototype, "pollAborted", { - // This is an internal type, not exported from 'index' so this is really just internal. - get: function () { - return this.pollAbort.aborted; - }, - enumerable: true, - configurable: true - }); - LongPollingTransport.prototype.connect = function (url, transferFormat) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - var pollOptions, token, closeError, pollUrl, response; - return tslib_1.__generator(this, function (_a) { - switch (_a.label) { - case 0: - Utils.Arg.isRequired(url, "url"); - Utils.Arg.isRequired(transferFormat, "transferFormat"); - Utils.Arg.isIn(transferFormat, ITransport.TransferFormat, "transferFormat"); - this.url = url; - this.logger.log(ILogger.LogLevel.Trace, "(LongPolling transport) Connecting"); - if (transferFormat === ITransport.TransferFormat.Binary && (typeof new XMLHttpRequest().responseType !== "string")) { - // This will work if we fix: https://github.com/aspnet/SignalR/issues/742 - throw new Error("Binary protocols over XmlHttpRequest not implementing advanced features are not supported."); - } - pollOptions = { - abortSignal: this.pollAbort.signal, - headers: {}, - timeout: 90000, - }; - if (transferFormat === ITransport.TransferFormat.Binary) { - pollOptions.responseType = "arraybuffer"; - } - return [4 /*yield*/, this.accessTokenFactory()]; - case 1: - token = _a.sent(); - this.updateHeaderToken(pollOptions, token); - pollUrl = url + "&_=" + Date.now(); - this.logger.log(ILogger.LogLevel.Trace, "(LongPolling transport) polling: " + pollUrl); - return [4 /*yield*/, this.httpClient.get(pollUrl, pollOptions)]; - case 2: - response = _a.sent(); - if (response.statusCode !== 200) { - this.logger.log(ILogger.LogLevel.Error, "(LongPolling transport) Unexpected response code: " + response.statusCode); - // Mark running as false so that the poll immediately ends and runs the close logic - closeError = new Errors.HttpError(response.statusText, response.statusCode); - this.running = false; - } - else { - this.running = true; - } - this.poll(this.url, pollOptions, closeError); - return [2 /*return*/, Promise.resolve()]; - } - }); - }); - }; - LongPollingTransport.prototype.updateHeaderToken = function (request, token) { - if (token) { - // tslint:disable-next-line:no-string-literal - request.headers["Authorization"] = "Bearer " + token; - return; - } - // tslint:disable-next-line:no-string-literal - if (request.headers["Authorization"]) { - // tslint:disable-next-line:no-string-literal - delete request.headers["Authorization"]; - } - }; - LongPollingTransport.prototype.poll = function (url, pollOptions, closeError) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - var token, pollUrl, response, e_1; - return tslib_1.__generator(this, function (_a) { - switch (_a.label) { - case 0: - _a.trys.push([0, , 8, 9]); - _a.label = 1; - case 1: - if (!this.running) return [3 /*break*/, 7]; - return [4 /*yield*/, this.accessTokenFactory()]; - case 2: - token = _a.sent(); - this.updateHeaderToken(pollOptions, token); - _a.label = 3; - case 3: - _a.trys.push([3, 5, , 6]); - pollUrl = url + "&_=" + Date.now(); - this.logger.log(ILogger.LogLevel.Trace, "(LongPolling transport) polling: " + pollUrl); - return [4 /*yield*/, this.httpClient.get(pollUrl, pollOptions)]; - case 4: - response = _a.sent(); - if (response.statusCode === 204) { - this.logger.log(ILogger.LogLevel.Information, "(LongPolling transport) Poll terminated by server"); - this.running = false; - } - else if (response.statusCode !== 200) { - this.logger.log(ILogger.LogLevel.Error, "(LongPolling transport) Unexpected response code: " + response.statusCode); - // Unexpected status code - closeError = new Errors.HttpError(response.statusText, response.statusCode); - this.running = false; - } - else { - // Process the response - if (response.content) { - this.logger.log(ILogger.LogLevel.Trace, "(LongPolling transport) data received. " + Utils.getDataDetail(response.content, this.logMessageContent)); - if (this.onreceive) { - this.onreceive(response.content); - } - } - else { - // This is another way timeout manifest. - this.logger.log(ILogger.LogLevel.Trace, "(LongPolling transport) Poll timed out, reissuing."); - } - } - return [3 /*break*/, 6]; - case 5: - e_1 = _a.sent(); - if (!this.running) { - // Log but disregard errors that occur after we were stopped by DELETE - this.logger.log(ILogger.LogLevel.Trace, "(LongPolling transport) Poll errored after shutdown: " + e_1.message); - } - else { - if (e_1 instanceof Errors.TimeoutError) { - // Ignore timeouts and reissue the poll. - this.logger.log(ILogger.LogLevel.Trace, "(LongPolling transport) Poll timed out, reissuing."); - } - else { - // Close the connection with the error as the result. - closeError = e_1; - this.running = false; - } - } - return [3 /*break*/, 6]; - case 6: return [3 /*break*/, 1]; - case 7: return [3 /*break*/, 9]; - case 8: - // Indicate that we've stopped so the shutdown timer doesn't get registered. - this.stopped = true; - // Clean up the shutdown timer if it was registered - if (this.shutdownTimer) { - clearTimeout(this.shutdownTimer); - } - // Fire our onclosed event - if (this.onclose) { - this.logger.log(ILogger.LogLevel.Trace, "(LongPolling transport) Firing onclose event. Error: " + (closeError || "")); - this.onclose(closeError); - } - this.logger.log(ILogger.LogLevel.Trace, "(LongPolling transport) Transport finished."); - return [7 /*endfinally*/]; - case 9: return [2 /*return*/]; - } - }); - }); - }; - LongPollingTransport.prototype.send = function (data) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - return tslib_1.__generator(this, function (_a) { - if (!this.running) { - return [2 /*return*/, Promise.reject(new Error("Cannot send until the transport is connected"))]; - } - return [2 /*return*/, Utils.sendMessage(this.logger, "LongPolling", this.httpClient, this.url, this.accessTokenFactory, data, this.logMessageContent)]; - }); - }); - }; - LongPollingTransport.prototype.stop = function () { - return tslib_1.__awaiter(this, void 0, void 0, function () { - var _this = this; - var deleteOptions, token, response; - return tslib_1.__generator(this, function (_a) { - switch (_a.label) { - case 0: - _a.trys.push([0, , 3, 4]); - this.running = false; - this.logger.log(ILogger.LogLevel.Trace, "(LongPolling transport) sending DELETE request to " + this.url + "."); - deleteOptions = { - headers: {}, - }; - return [4 /*yield*/, this.accessTokenFactory()]; - case 1: - token = _a.sent(); - this.updateHeaderToken(deleteOptions, token); - return [4 /*yield*/, this.httpClient.delete(this.url, deleteOptions)]; - case 2: - response = _a.sent(); - this.logger.log(ILogger.LogLevel.Trace, "(LongPolling transport) DELETE request accepted."); - return [3 /*break*/, 4]; - case 3: - // Abort the poll after the shutdown timeout if the server doesn't stop the poll. - if (!this.stopped) { - this.shutdownTimer = setTimeout(function () { - _this.logger.log(ILogger.LogLevel.Warning, "(LongPolling transport) server did not terminate after DELETE request, canceling poll."); - // Abort any outstanding poll - _this.pollAbort.abort(); - }, this.shutdownTimeout); - } - return [7 /*endfinally*/]; - case 4: return [2 /*return*/]; - } - }); - }); - }; - return LongPollingTransport; -}()); -exports.LongPollingTransport = LongPollingTransport; - -}); - -unwrapExports(LongPollingTransport_1); -var LongPollingTransport_2 = LongPollingTransport_1.LongPollingTransport; - -var ServerSentEventsTransport_1 = createCommonjsModule(function (module, exports) { -Object.defineProperty(exports, "__esModule", { value: true }); - - - - -var ServerSentEventsTransport = /** @class */ (function () { - function ServerSentEventsTransport(httpClient, accessTokenFactory, logger, logMessageContent) { - this.httpClient = httpClient; - this.accessTokenFactory = accessTokenFactory || (function () { return null; }); - this.logger = logger; - this.logMessageContent = logMessageContent; - } - ServerSentEventsTransport.prototype.connect = function (url, transferFormat) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - var _this = this; - var token; - return tslib_1.__generator(this, function (_a) { - switch (_a.label) { - case 0: - Utils.Arg.isRequired(url, "url"); - Utils.Arg.isRequired(transferFormat, "transferFormat"); - Utils.Arg.isIn(transferFormat, ITransport.TransferFormat, "transferFormat"); - if (typeof (EventSource) === "undefined") { - throw new Error("'EventSource' is not supported in your environment."); - } - this.logger.log(ILogger.LogLevel.Trace, "(SSE transport) Connecting"); - return [4 /*yield*/, this.accessTokenFactory()]; - case 1: - token = _a.sent(); - if (token) { - url += (url.indexOf("?") < 0 ? "?" : "&") + ("access_token=" + encodeURIComponent(token)); - } - this.url = url; - return [2 /*return*/, new Promise(function (resolve, reject) { - var opened = false; - if (transferFormat !== ITransport.TransferFormat.Text) { - reject(new Error("The Server-Sent Events transport only supports the 'Text' transfer format")); - } - var eventSource = new EventSource(url, { withCredentials: true }); - try { - eventSource.onmessage = function (e) { - if (_this.onreceive) { - try { - _this.logger.log(ILogger.LogLevel.Trace, "(SSE transport) data received. " + Utils.getDataDetail(e.data, _this.logMessageContent) + "."); - _this.onreceive(e.data); - } - catch (error) { - if (_this.onclose) { - _this.onclose(error); - } - return; - } - } - }; - eventSource.onerror = function (e) { - var error = new Error(e.message || "Error occurred"); - if (opened) { - _this.close(error); - } - else { - reject(error); - } - }; - eventSource.onopen = function () { - _this.logger.log(ILogger.LogLevel.Information, "SSE connected to " + _this.url); - _this.eventSource = eventSource; - opened = true; - resolve(); - }; - } - catch (e) { - return Promise.reject(e); - } - })]; - } - }); - }); - }; - ServerSentEventsTransport.prototype.send = function (data) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - return tslib_1.__generator(this, function (_a) { - if (!this.eventSource) { - return [2 /*return*/, Promise.reject(new Error("Cannot send until the transport is connected"))]; - } - return [2 /*return*/, Utils.sendMessage(this.logger, "SSE", this.httpClient, this.url, this.accessTokenFactory, data, this.logMessageContent)]; - }); - }); - }; - ServerSentEventsTransport.prototype.stop = function () { - this.close(); - return Promise.resolve(); - }; - ServerSentEventsTransport.prototype.close = function (e) { - if (this.eventSource) { - this.eventSource.close(); - this.eventSource = null; - if (this.onclose) { - this.onclose(e); - } - } - }; - return ServerSentEventsTransport; -}()); -exports.ServerSentEventsTransport = ServerSentEventsTransport; - -}); - -unwrapExports(ServerSentEventsTransport_1); -var ServerSentEventsTransport_2 = ServerSentEventsTransport_1.ServerSentEventsTransport; - -var WebSocketTransport_1 = createCommonjsModule(function (module, exports) { -Object.defineProperty(exports, "__esModule", { value: true }); - - - - -var WebSocketTransport = /** @class */ (function () { - function WebSocketTransport(accessTokenFactory, logger, logMessageContent) { - this.logger = logger; - this.accessTokenFactory = accessTokenFactory || (function () { return null; }); - this.logMessageContent = logMessageContent; - } - WebSocketTransport.prototype.connect = function (url, transferFormat) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - var _this = this; - var token; - return tslib_1.__generator(this, function (_a) { - switch (_a.label) { - case 0: - Utils.Arg.isRequired(url, "url"); - Utils.Arg.isRequired(transferFormat, "transferFormat"); - Utils.Arg.isIn(transferFormat, ITransport.TransferFormat, "transferFormat"); - if (typeof (WebSocket) === "undefined") { - throw new Error("'WebSocket' is not supported in your environment."); - } - this.logger.log(ILogger.LogLevel.Trace, "(WebSockets transport) Connecting"); - return [4 /*yield*/, this.accessTokenFactory()]; - case 1: - token = _a.sent(); - if (token) { - url += (url.indexOf("?") < 0 ? "?" : "&") + ("access_token=" + encodeURIComponent(token)); - } - return [2 /*return*/, new Promise(function (resolve, reject) { - url = url.replace(/^http/, "ws"); - var webSocket = new WebSocket(url); - if (transferFormat === ITransport.TransferFormat.Binary) { - webSocket.binaryType = "arraybuffer"; - } - webSocket.onopen = function (event) { - _this.logger.log(ILogger.LogLevel.Information, "WebSocket connected to " + url); - _this.webSocket = webSocket; - resolve(); - }; - webSocket.onerror = function (event) { - reject(event.error); - }; - webSocket.onmessage = function (message) { - _this.logger.log(ILogger.LogLevel.Trace, "(WebSockets transport) data received. " + Utils.getDataDetail(message.data, _this.logMessageContent) + "."); - if (_this.onreceive) { - _this.onreceive(message.data); - } - }; - webSocket.onclose = function (event) { - // webSocket will be null if the transport did not start successfully - _this.logger.log(ILogger.LogLevel.Trace, "(WebSockets transport) socket closed."); - if (_this.onclose) { - if (event.wasClean === false || event.code !== 1000) { - _this.onclose(new Error("Websocket closed with status code: " + event.code + " (" + event.reason + ")")); - } - else { - _this.onclose(); - } - } - }; - })]; - } - }); - }); - }; - WebSocketTransport.prototype.send = function (data) { - if (this.webSocket && this.webSocket.readyState === WebSocket.OPEN) { - this.logger.log(ILogger.LogLevel.Trace, "(WebSockets transport) sending data. " + Utils.getDataDetail(data, this.logMessageContent) + "."); - this.webSocket.send(data); - return Promise.resolve(); - } - return Promise.reject("WebSocket is not in the OPEN state"); - }; - WebSocketTransport.prototype.stop = function () { - if (this.webSocket) { - this.webSocket.close(); - this.webSocket = null; - } - return Promise.resolve(); - }; - return WebSocketTransport; -}()); -exports.WebSocketTransport = WebSocketTransport; - -}); - -unwrapExports(WebSocketTransport_1); -var WebSocketTransport_2 = WebSocketTransport_1.WebSocketTransport; - -var HttpConnection_1 = createCommonjsModule(function (module, exports) { -Object.defineProperty(exports, "__esModule", { value: true }); - - - - - - - - -var MAX_REDIRECTS = 100; -var HttpConnection = /** @class */ (function () { - function HttpConnection(url, options) { - if (options === void 0) { options = {}; } - this.features = {}; - Utils.Arg.isRequired(url, "url"); - this.logger = Utils.createLogger(options.logger); - this.baseUrl = this.resolveUrl(url); - options = options || {}; - options.accessTokenFactory = options.accessTokenFactory || (function () { return null; }); - options.logMessageContent = options.logMessageContent || false; - this.httpClient = options.httpClient || new HttpClient_1.DefaultHttpClient(this.logger); - this.connectionState = 2 /* Disconnected */; - this.options = options; - } - HttpConnection.prototype.start = function (transferFormat) { - transferFormat = transferFormat || ITransport.TransferFormat.Binary; - Utils.Arg.isIn(transferFormat, ITransport.TransferFormat, "transferFormat"); - this.logger.log(ILogger.LogLevel.Debug, "Starting connection with transfer format '" + ITransport.TransferFormat[transferFormat] + "'."); - if (this.connectionState !== 2 /* Disconnected */) { - return Promise.reject(new Error("Cannot start a connection that is not in the 'Disconnected' state.")); - } - this.connectionState = 0 /* Connecting */; - this.startPromise = this.startInternal(transferFormat); - return this.startPromise; - }; - HttpConnection.prototype.send = function (data) { - if (this.connectionState !== 1 /* Connected */) { - throw new Error("Cannot send data if the connection is not in the 'Connected' State."); - } - return this.transport.send(data); - }; - HttpConnection.prototype.stop = function (error) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - var e_1; - return tslib_1.__generator(this, function (_a) { - switch (_a.label) { - case 0: - this.connectionState = 2 /* Disconnected */; - _a.label = 1; - case 1: - _a.trys.push([1, 3, , 4]); - return [4 /*yield*/, this.startPromise]; - case 2: - _a.sent(); - return [3 /*break*/, 4]; - case 3: - e_1 = _a.sent(); - return [3 /*break*/, 4]; - case 4: - if (!this.transport) return [3 /*break*/, 6]; - this.stopError = error; - return [4 /*yield*/, this.transport.stop()]; - case 5: - _a.sent(); - this.transport = null; - _a.label = 6; - case 6: return [2 /*return*/]; - } - }); - }); - }; - HttpConnection.prototype.startInternal = function (transferFormat) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - var _this = this; - var url, negotiateResponse, redirects, _loop_1, this_1, state_1, e_2; - return tslib_1.__generator(this, function (_a) { - switch (_a.label) { - case 0: - url = this.baseUrl; - this.accessTokenFactory = this.options.accessTokenFactory; - _a.label = 1; - case 1: - _a.trys.push([1, 12, , 13]); - if (!this.options.skipNegotiation) return [3 /*break*/, 5]; - if (!(this.options.transport === ITransport.HttpTransportType.WebSockets)) return [3 /*break*/, 3]; - // No need to add a connection ID in this case - this.transport = this.constructTransport(ITransport.HttpTransportType.WebSockets); - // We should just call connect directly in this case. - // No fallback or negotiate in this case. - return [4 /*yield*/, this.transport.connect(url, transferFormat)]; - case 2: - // We should just call connect directly in this case. - // No fallback or negotiate in this case. - _a.sent(); - return [3 /*break*/, 4]; - case 3: throw Error("Negotiation can only be skipped when using the WebSocket transport directly."); - case 4: return [3 /*break*/, 11]; - case 5: - negotiateResponse = null; - redirects = 0; - _loop_1 = function () { - var accessToken_1; - return tslib_1.__generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, this_1.getNegotiationResponse(url)]; - case 1: - negotiateResponse = _a.sent(); - // the user tries to stop the connection when it is being started - if (this_1.connectionState === 2 /* Disconnected */) { - return [2 /*return*/, { value: void 0 }]; - } - if (negotiateResponse.url) { - url = negotiateResponse.url; - } - if (negotiateResponse.accessToken) { - accessToken_1 = negotiateResponse.accessToken; - this_1.accessTokenFactory = function () { return accessToken_1; }; - } - redirects++; - return [2 /*return*/]; - } - }); - }; - this_1 = this; - _a.label = 6; - case 6: return [5 /*yield**/, _loop_1()]; - case 7: - state_1 = _a.sent(); - if (typeof state_1 === "object") - return [2 /*return*/, state_1.value]; - _a.label = 8; - case 8: - if (negotiateResponse.url && redirects < MAX_REDIRECTS) return [3 /*break*/, 6]; - _a.label = 9; - case 9: - if (redirects === MAX_REDIRECTS && negotiateResponse.url) { - throw Error("Negotiate redirection limit exceeded."); - } - return [4 /*yield*/, this.createTransport(url, this.options.transport, negotiateResponse, transferFormat)]; - case 10: - _a.sent(); - _a.label = 11; - case 11: - if (this.transport instanceof LongPollingTransport_1.LongPollingTransport) { - this.features.inherentKeepAlive = true; - } - this.transport.onreceive = this.onreceive; - this.transport.onclose = function (e) { return _this.stopConnection(e); }; - // only change the state if we were connecting to not overwrite - // the state if the connection is already marked as Disconnected - this.changeState(0 /* Connecting */, 1 /* Connected */); - return [3 /*break*/, 13]; - case 12: - e_2 = _a.sent(); - this.logger.log(ILogger.LogLevel.Error, "Failed to start the connection: " + e_2); - this.connectionState = 2 /* Disconnected */; - this.transport = null; - throw e_2; - case 13: return [2 /*return*/]; - } - }); - }); - }; - HttpConnection.prototype.getNegotiationResponse = function (url) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - var token, headers, negotiateUrl, response, e_3, _a; - return tslib_1.__generator(this, function (_b) { - switch (_b.label) { - case 0: return [4 /*yield*/, this.accessTokenFactory()]; - case 1: - token = _b.sent(); - if (token) { - headers = (_a = {}, _a["Authorization"] = "Bearer " + token, _a); - } - negotiateUrl = this.resolveNegotiateUrl(url); - this.logger.log(ILogger.LogLevel.Debug, "Sending negotiation request: " + negotiateUrl); - _b.label = 2; - case 2: - _b.trys.push([2, 4, , 5]); - return [4 /*yield*/, this.httpClient.post(negotiateUrl, { - content: "", - headers: headers, - })]; - case 3: - response = _b.sent(); - if (response.statusCode !== 200) { - throw Error("Unexpected status code returned from negotiate " + response.statusCode); - } - return [2 /*return*/, JSON.parse(response.content)]; - case 4: - e_3 = _b.sent(); - this.logger.log(ILogger.LogLevel.Error, "Failed to complete negotiation with the server: " + e_3); - throw e_3; - case 5: return [2 /*return*/]; - } - }); - }); - }; - HttpConnection.prototype.createConnectUrl = function (url, connectionId) { - return url + (url.indexOf("?") === -1 ? "?" : "&") + ("id=" + connectionId); - }; - HttpConnection.prototype.createTransport = function (url, requestedTransport, negotiateResponse, requestedTransferFormat) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - var connectUrl, transports, _i, transports_1, endpoint, transport, ex_1; - return tslib_1.__generator(this, function (_a) { - switch (_a.label) { - case 0: - connectUrl = this.createConnectUrl(url, negotiateResponse.connectionId); - if (!this.isITransport(requestedTransport)) return [3 /*break*/, 2]; - this.logger.log(ILogger.LogLevel.Debug, "Connection was provided an instance of ITransport, using that directly."); - this.transport = requestedTransport; - return [4 /*yield*/, this.transport.connect(connectUrl, requestedTransferFormat)]; - case 1: - _a.sent(); - // only change the state if we were connecting to not overwrite - // the state if the connection is already marked as Disconnected - this.changeState(0 /* Connecting */, 1 /* Connected */); - return [2 /*return*/]; - case 2: - transports = negotiateResponse.availableTransports; - _i = 0, transports_1 = transports; - _a.label = 3; - case 3: - if (!(_i < transports_1.length)) return [3 /*break*/, 9]; - endpoint = transports_1[_i]; - this.connectionState = 0 /* Connecting */; - transport = this.resolveTransport(endpoint, requestedTransport, requestedTransferFormat); - if (!(typeof transport === "number")) return [3 /*break*/, 8]; - this.transport = this.constructTransport(transport); - if (!(negotiateResponse.connectionId === null)) return [3 /*break*/, 5]; - return [4 /*yield*/, this.getNegotiationResponse(url)]; - case 4: - negotiateResponse = _a.sent(); - connectUrl = this.createConnectUrl(url, negotiateResponse.connectionId); - _a.label = 5; - case 5: - _a.trys.push([5, 7, , 8]); - return [4 /*yield*/, this.transport.connect(connectUrl, requestedTransferFormat)]; - case 6: - _a.sent(); - this.changeState(0 /* Connecting */, 1 /* Connected */); - return [2 /*return*/]; - case 7: - ex_1 = _a.sent(); - this.logger.log(ILogger.LogLevel.Error, "Failed to start the transport '" + ITransport.HttpTransportType[transport] + "': " + ex_1); - this.connectionState = 2 /* Disconnected */; - negotiateResponse.connectionId = null; - return [3 /*break*/, 8]; - case 8: - _i++; - return [3 /*break*/, 3]; - case 9: throw new Error("Unable to initialize any of the available transports."); - } - }); - }); - }; - HttpConnection.prototype.constructTransport = function (transport) { - switch (transport) { - case ITransport.HttpTransportType.WebSockets: - return new WebSocketTransport_1.WebSocketTransport(this.accessTokenFactory, this.logger, this.options.logMessageContent); - case ITransport.HttpTransportType.ServerSentEvents: - return new ServerSentEventsTransport_1.ServerSentEventsTransport(this.httpClient, this.accessTokenFactory, this.logger, this.options.logMessageContent); - case ITransport.HttpTransportType.LongPolling: - return new LongPollingTransport_1.LongPollingTransport(this.httpClient, this.accessTokenFactory, this.logger, this.options.logMessageContent); - default: - throw new Error("Unknown transport: " + transport + "."); - } - }; - HttpConnection.prototype.resolveTransport = function (endpoint, requestedTransport, requestedTransferFormat) { - var transport = ITransport.HttpTransportType[endpoint.transport]; - if (transport === null || transport === undefined) { - this.logger.log(ILogger.LogLevel.Debug, "Skipping transport '" + endpoint.transport + "' because it is not supported by this client."); - } - else { - var transferFormats = endpoint.transferFormats.map(function (s) { return ITransport.TransferFormat[s]; }); - if (transportMatches(requestedTransport, transport)) { - if (transferFormats.indexOf(requestedTransferFormat) >= 0) { - if ((transport === ITransport.HttpTransportType.WebSockets && typeof WebSocket === "undefined") || - (transport === ITransport.HttpTransportType.ServerSentEvents && typeof EventSource === "undefined")) { - this.logger.log(ILogger.LogLevel.Debug, "Skipping transport '" + ITransport.HttpTransportType[transport] + "' because it is not supported in your environment.'"); - } - else { - this.logger.log(ILogger.LogLevel.Debug, "Selecting transport '" + ITransport.HttpTransportType[transport] + "'"); - return transport; - } - } - else { - this.logger.log(ILogger.LogLevel.Debug, "Skipping transport '" + ITransport.HttpTransportType[transport] + "' because it does not support the requested transfer format '" + ITransport.TransferFormat[requestedTransferFormat] + "'."); - } - } - else { - this.logger.log(ILogger.LogLevel.Debug, "Skipping transport '" + ITransport.HttpTransportType[transport] + "' because it was disabled by the client."); - } - } - return null; - }; - HttpConnection.prototype.isITransport = function (transport) { - return transport && typeof (transport) === "object" && "connect" in transport; - }; - HttpConnection.prototype.changeState = function (from, to) { - if (this.connectionState === from) { - this.connectionState = to; - return true; - } - return false; - }; - HttpConnection.prototype.stopConnection = function (error) { - return tslib_1.__awaiter(this, void 0, void 0, function () { - return tslib_1.__generator(this, function (_a) { - this.transport = null; - // If we have a stopError, it takes precedence over the error from the transport - error = this.stopError || error; - if (error) { - this.logger.log(ILogger.LogLevel.Error, "Connection disconnected with error '" + error + "'."); - } - else { - this.logger.log(ILogger.LogLevel.Information, "Connection disconnected."); - } - this.connectionState = 2 /* Disconnected */; - if (this.onclose) { - this.onclose(error); - } - return [2 /*return*/]; - }); - }); - }; - HttpConnection.prototype.resolveUrl = function (url) { - // startsWith is not supported in IE - if (url.lastIndexOf("https://", 0) === 0 || url.lastIndexOf("http://", 0) === 0) { - return url; - } - if (typeof window === "undefined" || !window || !window.document) { - throw new Error("Cannot resolve '" + url + "'."); - } - // Setting the url to the href propery of an anchor tag handles normalization - // for us. There are 3 main cases. - // 1. Relative path normalization e.g "b" -> "http://localhost:5000/a/b" - // 2. Absolute path normalization e.g "/a/b" -> "http://localhost:5000/a/b" - // 3. Networkpath reference normalization e.g "//localhost:5000/a/b" -> "http://localhost:5000/a/b" - var aTag = window.document.createElement("a"); - aTag.href = url; - this.logger.log(ILogger.LogLevel.Information, "Normalizing '" + url + "' to '" + aTag.href + "'."); - return aTag.href; - }; - HttpConnection.prototype.resolveNegotiateUrl = function (url) { - var index = url.indexOf("?"); - var negotiateUrl = url.substring(0, index === -1 ? url.length : index); - if (negotiateUrl[negotiateUrl.length - 1] !== "/") { - negotiateUrl += "/"; - } - negotiateUrl += "negotiate"; - negotiateUrl += index === -1 ? "" : url.substring(index); - return negotiateUrl; - }; - return HttpConnection; -}()); -exports.HttpConnection = HttpConnection; -function transportMatches(requestedTransport, actualTransport) { - return !requestedTransport || ((actualTransport & requestedTransport) !== 0); -} - -}); - -unwrapExports(HttpConnection_1); -var HttpConnection_2 = HttpConnection_1.HttpConnection; - -var JsonHubProtocol_1 = createCommonjsModule(function (module, exports) { -Object.defineProperty(exports, "__esModule", { value: true }); - - - - - -var JSON_HUB_PROTOCOL_NAME = "json"; -/** Implements the JSON Hub Protocol. */ -var JsonHubProtocol = /** @class */ (function () { - function JsonHubProtocol() { - /** @inheritDoc */ - this.name = JSON_HUB_PROTOCOL_NAME; - /** @inheritDoc */ - this.version = 1; - /** @inheritDoc */ - this.transferFormat = ITransport.TransferFormat.Text; - } - /** Creates an array of {@link HubMessage} objects from the specified serialized representation. - * - * @param {string} input A string containing the serialized representation. - * @param {ILogger} logger A logger that will be used to log messages that occur during parsing. - */ - JsonHubProtocol.prototype.parseMessages = function (input, logger) { - // The interface does allow "ArrayBuffer" to be passed in, but this implementation does not. So let's throw a useful error. - if (typeof input !== "string") { - throw new Error("Invalid input for JSON hub protocol. Expected a string."); - } - if (!input) { - return []; - } - if (logger === null) { - logger = Loggers.NullLogger.instance; - } - // Parse the messages - var messages = TextMessageFormat_1.TextMessageFormat.parse(input); - var hubMessages = []; - for (var _i = 0, messages_1 = messages; _i < messages_1.length; _i++) { - var message = messages_1[_i]; - var parsedMessage = JSON.parse(message); - if (typeof parsedMessage.type !== "number") { - throw new Error("Invalid payload."); - } - switch (parsedMessage.type) { - case IHubProtocol.MessageType.Invocation: - this.isInvocationMessage(parsedMessage); - break; - case IHubProtocol.MessageType.StreamItem: - this.isStreamItemMessage(parsedMessage); - break; - case IHubProtocol.MessageType.Completion: - this.isCompletionMessage(parsedMessage); - break; - case IHubProtocol.MessageType.Ping: - // Single value, no need to validate - break; - case IHubProtocol.MessageType.Close: - // All optional values, no need to validate - break; - default: - // Future protocol changes can add message types, old clients can ignore them - logger.log(ILogger.LogLevel.Information, "Unknown message type '" + parsedMessage.type + "' ignored."); - continue; - } - hubMessages.push(parsedMessage); - } - return hubMessages; - }; - /** Writes the specified {@link HubMessage} to a string and returns it. - * - * @param {HubMessage} message The message to write. - * @returns {string} A string containing the serialized representation of the message. - */ - JsonHubProtocol.prototype.writeMessage = function (message) { - return TextMessageFormat_1.TextMessageFormat.write(JSON.stringify(message)); - }; - JsonHubProtocol.prototype.isInvocationMessage = function (message) { - this.assertNotEmptyString(message.target, "Invalid payload for Invocation message."); - if (message.invocationId !== undefined) { - this.assertNotEmptyString(message.invocationId, "Invalid payload for Invocation message."); - } - }; - JsonHubProtocol.prototype.isStreamItemMessage = function (message) { - this.assertNotEmptyString(message.invocationId, "Invalid payload for StreamItem message."); - if (message.item === undefined) { - throw new Error("Invalid payload for StreamItem message."); - } - }; - JsonHubProtocol.prototype.isCompletionMessage = function (message) { - if (message.result && message.error) { - throw new Error("Invalid payload for Completion message."); - } - if (!message.result && message.error) { - this.assertNotEmptyString(message.error, "Invalid payload for Completion message."); - } - this.assertNotEmptyString(message.invocationId, "Invalid payload for Completion message."); - }; - JsonHubProtocol.prototype.assertNotEmptyString = function (value, errorMessage) { - if (typeof value !== "string" || value === "") { - throw new Error(errorMessage); - } - }; - return JsonHubProtocol; -}()); -exports.JsonHubProtocol = JsonHubProtocol; - -}); - -unwrapExports(JsonHubProtocol_1); -var JsonHubProtocol_2 = JsonHubProtocol_1.JsonHubProtocol; - -var HubConnectionBuilder_1 = createCommonjsModule(function (module, exports) { -Object.defineProperty(exports, "__esModule", { value: true }); - - - - - -/** A builder for configuring {@link HubConnection} instances. */ -var HubConnectionBuilder = /** @class */ (function () { - function HubConnectionBuilder() { - } - HubConnectionBuilder.prototype.configureLogging = function (logging) { - Utils.Arg.isRequired(logging, "logging"); - if (isLogger(logging)) { - this.logger = logging; - } - else { - this.logger = new Utils.ConsoleLogger(logging); - } - return this; - }; - HubConnectionBuilder.prototype.withUrl = function (url, transportTypeOrOptions) { - Utils.Arg.isRequired(url, "url"); - this.url = url; - // Flow-typing knows where it's at. Since HttpTransportType is a number and IHttpConnectionOptions is guaranteed - // to be an object, we know (as does TypeScript) this comparison is all we need to figure out which overload was called. - if (typeof transportTypeOrOptions === "object") { - this.httpConnectionOptions = transportTypeOrOptions; - } - else { - this.httpConnectionOptions = { - transport: transportTypeOrOptions, - }; - } - return this; - }; - /** Configures the {@link HubConnection} to use the specified Hub Protocol. - * - * @param {IHubProtocol} protocol The {@link IHubProtocol} implementation to use. - */ - HubConnectionBuilder.prototype.withHubProtocol = function (protocol) { - Utils.Arg.isRequired(protocol, "protocol"); - this.protocol = protocol; - return this; - }; - /** Creates a {@link HubConnection} from the configuration options specified in this builder. - * - * @returns {HubConnection} The configured {@link HubConnection}. - */ - HubConnectionBuilder.prototype.build = function () { - // If httpConnectionOptions has a logger, use it. Otherwise, override it with the one - // provided to configureLogger - var httpConnectionOptions = this.httpConnectionOptions || {}; - // If it's 'null', the user **explicitly** asked for null, don't mess with it. - if (httpConnectionOptions.logger === undefined) { - // If our logger is undefined or null, that's OK, the HttpConnection constructor will handle it. - httpConnectionOptions.logger = this.logger; - } - // Now create the connection - if (!this.url) { - throw new Error("The 'HubConnectionBuilder.withUrl' method must be called before building the connection."); - } - var connection = new HttpConnection_1.HttpConnection(this.url, httpConnectionOptions); - return HubConnection_1.HubConnection.create(connection, this.logger || Loggers.NullLogger.instance, this.protocol || new JsonHubProtocol_1.JsonHubProtocol()); - }; - return HubConnectionBuilder; -}()); -exports.HubConnectionBuilder = HubConnectionBuilder; -function isLogger(logger) { - return logger.log !== undefined; -} - -}); - -unwrapExports(HubConnectionBuilder_1); -var HubConnectionBuilder_2 = HubConnectionBuilder_1.HubConnectionBuilder; - -var cjs = createCommonjsModule(function (module, exports) { -Object.defineProperty(exports, "__esModule", { value: true }); -// Version token that will be replaced by the prepack command -/** The version of the SignalR client. */ -exports.VERSION = "0.0.0-DEV_BUILD"; - -exports.HttpError = Errors.HttpError; -exports.TimeoutError = Errors.TimeoutError; - -exports.DefaultHttpClient = HttpClient_1.DefaultHttpClient; -exports.HttpClient = HttpClient_1.HttpClient; -exports.HttpResponse = HttpClient_1.HttpResponse; - -exports.HubConnection = HubConnection_1.HubConnection; - -exports.HubConnectionBuilder = HubConnectionBuilder_1.HubConnectionBuilder; - -exports.MessageType = IHubProtocol.MessageType; - -exports.LogLevel = ILogger.LogLevel; - -exports.HttpTransportType = ITransport.HttpTransportType; -exports.TransferFormat = ITransport.TransferFormat; - -exports.NullLogger = Loggers.NullLogger; - -exports.JsonHubProtocol = JsonHubProtocol_1.JsonHubProtocol; - -}); - -unwrapExports(cjs); -var cjs_1 = cjs.VERSION; -var cjs_2 = cjs.HttpError; -var cjs_3 = cjs.TimeoutError; -var cjs_4 = cjs.DefaultHttpClient; -var cjs_5 = cjs.HttpClient; -var cjs_6 = cjs.HttpResponse; -var cjs_7 = cjs.HubConnection; -var cjs_8 = cjs.HubConnectionBuilder; -var cjs_9 = cjs.MessageType; -var cjs_10 = cjs.LogLevel; -var cjs_11 = cjs.HttpTransportType; -var cjs_12 = cjs.TransferFormat; -var cjs_13 = cjs.NullLogger; -var cjs_14 = cjs.JsonHubProtocol; - -var browserIndex = createCommonjsModule(function (module, exports) { -Object.defineProperty(exports, "__esModule", { value: true }); - -// This is where we add any polyfills we'll need for the browser. It is the entry module for browser-specific builds. - -// Copy from Array.prototype into Uint8Array to polyfill on IE. It's OK because the implementations of indexOf and slice use properties -// that exist on Uint8Array with the same name, and JavaScript is magic. -// We make them 'writable' because the Buffer polyfill messes with it as well. -if (!Uint8Array.prototype.indexOf) { - Object.defineProperty(Uint8Array.prototype, "indexOf", { - value: Array.prototype.indexOf, - writable: true, - }); -} -if (!Uint8Array.prototype.slice) { - Object.defineProperty(Uint8Array.prototype, "slice", { - value: Array.prototype.slice, - writable: true, - }); -} -if (!Uint8Array.prototype.forEach) { - Object.defineProperty(Uint8Array.prototype, "forEach", { - value: Array.prototype.forEach, - writable: true, - }); -} -tslib_1.__exportStar(cjs, exports); - -}); - -var browserIndex$1 = unwrapExports(browserIndex); - -return browserIndex$1; - -}))); -//# sourceMappingURL=signalr.js.map diff --git a/result/dotnet/Result/wwwroot/lib/signalr/dist/browser/signalr.min.js b/result/dotnet/Result/wwwroot/lib/signalr/dist/browser/signalr.min.js deleted file mode 100644 index 261be267c6..0000000000 --- a/result/dotnet/Result/wwwroot/lib/signalr/dist/browser/signalr.min.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * @overview ASP.NET Core SignalR JavaScript Client. - * @version 1.0.3. - * @license - * Copyright (c) .NET Foundation. All rights reserved. - * Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - */ -(function(global,factory){typeof exports==="object"&&typeof module!=="undefined"?module.exports=factory():typeof define==="function"&&define.amd?define(factory):global.signalR=factory()})(this,function(){"use strict";var commonjsGlobal=typeof window!=="undefined"?window:typeof global!=="undefined"?global:typeof self!=="undefined"?self:{};function commonjsRequire(){throw new Error("Dynamic requires are not currently supported by rollup-plugin-commonjs")}function unwrapExports(x){return x&&x.__esModule&&Object.prototype.hasOwnProperty.call(x,"default")?x["default"]:x}function createCommonjsModule(fn,module){return module={exports:{}},fn(module,module.exports),module.exports}var extendStatics=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(d,b){d.__proto__=b}||function(d,b){for(var p in b)if(b.hasOwnProperty(p))d[p]=b[p]};function __extends(d,b){extendStatics(d,b);function __(){this.constructor=d}d.prototype=b===null?Object.create(b):(__.prototype=b.prototype,new __)}var __assign=Object.assign||function __assign(t){for(var s,i=1,n=arguments.length;i=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r}function __param(paramIndex,decorator){return function(target,key){decorator(target,key,paramIndex)}}function __metadata(metadataKey,metadataValue){if(typeof Reflect==="object"&&typeof Reflect.metadata==="function")return Reflect.metadata(metadataKey,metadataValue)}function __awaiter(thisArg,_arguments,P,generator){return new(P||(P=Promise))(function(resolve,reject){function fulfilled(value){try{step(generator.next(value))}catch(e){reject(e)}}function rejected(value){try{step(generator["throw"](value))}catch(e){reject(e)}}function step(result){result.done?resolve(result.value):new P(function(resolve){resolve(result.value)}).then(fulfilled,rejected)}step((generator=generator.apply(thisArg,_arguments||[])).next())})}function __generator(thisArg,body){var _={label:0,sent:function(){if(t[0]&1)throw t[1];return t[1]},trys:[],ops:[]},f,y,t,g;return g={next:verb(0),throw:verb(1),return:verb(2)},typeof Symbol==="function"&&(g[Symbol.iterator]=function(){return this}),g;function verb(n){return function(v){return step([n,v])}}function step(op){if(f)throw new TypeError("Generator is already executing.");while(_)try{if(f=1,y&&(t=y[op[0]&2?"return":op[0]?"throw":"next"])&&!(t=t.call(y,op[1])).done)return t;if(y=0,t)op=[0,t.value];switch(op[0]){case 0:case 1:t=op;break;case 4:_.label++;return{value:op[1],done:false};case 5:_.label++;y=op[1];op=[0];continue;case 7:op=_.ops.pop();_.trys.pop();continue;default:if(!(t=_.trys,t=t.length>0&&t[t.length-1])&&(op[0]===6||op[0]===2)){_=0;continue}if(op[0]===3&&(!t||op[1]>t[0]&&op[1]=o.length)o=void 0;return{value:o&&o[i++],done:!o}}}}function __read(o,n){var m=typeof Symbol==="function"&&o[Symbol.iterator];if(!m)return o;var i=m.call(o),r,ar=[],e;try{while((n===void 0||n-- >0)&&!(r=i.next()).done)ar.push(r.value)}catch(error){e={error:error}}finally{try{if(r&&!r.done&&(m=i["return"]))m.call(i)}finally{if(e)throw e.error}}return ar}function __spread(){for(var ar=[],i=0;i1||resume(n,v)})}}function resume(n,v){try{step(g[n](v))}catch(e){settle(q[0][3],e)}}function step(r){r.value instanceof __await?Promise.resolve(r.value.v).then(fulfill,reject):settle(q[0][2],r)}function fulfill(value){resume("next",value)}function reject(value){resume("throw",value)}function settle(f,v){if(f(v),q.shift(),q.length)resume(q[0][0],q[0][1])}}function __asyncDelegator(o){var i,p;return i={},verb("next"),verb("throw",function(e){throw e}),verb("return"),i[Symbol.iterator]=function(){return this},i;function verb(n,f){if(o[n])i[n]=function(v){return(p=!p)?{value:__await(o[n](v)),done:n==="return"}:f?f(v):v}}}function __asyncValues(o){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var m=o[Symbol.asyncIterator];return m?m.call(o):typeof __values==="function"?__values(o):o[Symbol.iterator]()}function __makeTemplateObject(cooked,raw){if(Object.defineProperty){Object.defineProperty(cooked,"raw",{value:raw})}else{cooked.raw=raw}return cooked}function __importStar(mod){if(mod&&mod.__esModule)return mod;var result={};if(mod!=null)for(var k in mod)if(Object.hasOwnProperty.call(mod,k))result[k]=mod[k];result.default=mod;return result}function __importDefault(mod){return mod&&mod.__esModule?mod:{default:mod}}var tslib_1=Object.freeze({__extends:__extends,__assign:__assign,__rest:__rest,__decorate:__decorate,__param:__param,__metadata:__metadata,__awaiter:__awaiter,__generator:__generator,__exportStar:__exportStar,__values:__values,__read:__read,__spread:__spread,__await:__await,__asyncGenerator:__asyncGenerator,__asyncDelegator:__asyncDelegator,__asyncValues:__asyncValues,__makeTemplateObject:__makeTemplateObject,__importStar:__importStar,__importDefault:__importDefault});var es6Promise_auto=createCommonjsModule(function(module,exports){ -/*! - * @overview es6-promise - a tiny implementation of Promises/A+. - * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald) - * @license Licensed under MIT license - * See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE - * @version v4.2.2+97478eb6 - */ -(function(global,factory){module.exports=factory()})(commonjsGlobal,function(){function objectOrFunction(x){var type=typeof x;return x!==null&&(type==="object"||type==="function")}function isFunction(x){return typeof x==="function"}var _isArray=void 0;if(Array.isArray){_isArray=Array.isArray}else{_isArray=function(x){return Object.prototype.toString.call(x)==="[object Array]"}}var isArray=_isArray;var len=0;var vertxNext=void 0;var customSchedulerFn=void 0;var asap=function asap(callback,arg){queue[len]=callback;queue[len+1]=arg;len+=2;if(len===2){if(customSchedulerFn){customSchedulerFn(flush)}else{scheduleFlush()}}};function setScheduler(scheduleFn){customSchedulerFn=scheduleFn}function setAsap(asapFn){asap=asapFn}var browserWindow=typeof window!=="undefined"?window:undefined;var browserGlobal=browserWindow||{};var BrowserMutationObserver=browserGlobal.MutationObserver||browserGlobal.WebKitMutationObserver;var isNode=typeof self==="undefined"&&typeof process!=="undefined"&&{}.toString.call(process)==="[object process]";var isWorker=typeof Uint8ClampedArray!=="undefined"&&typeof importScripts!=="undefined"&&typeof MessageChannel!=="undefined";function useNextTick(){return function(){return process.nextTick(flush)}}function useVertxTimer(){if(typeof vertxNext!=="undefined"){return function(){vertxNext(flush)}}return useSetTimeout()}function useMutationObserver(){var iterations=0;var observer=new BrowserMutationObserver(flush);var node=document.createTextNode("");observer.observe(node,{characterData:true});return function(){node.data=iterations=++iterations%2}}function useMessageChannel(){var channel=new MessageChannel;channel.port1.onmessage=flush;return function(){return channel.port2.postMessage(0)}}function useSetTimeout(){var globalSetTimeout=setTimeout;return function(){return globalSetTimeout(flush,1)}}var queue=new Array(1e3);function flush(){for(var i=0;i=200&&xhr.status<300){resolve(new HttpResponse(xhr.status,xhr.statusText,xhr.response||xhr.responseText))}else{reject(new Errors.HttpError(xhr.statusText,xhr.status))}};xhr.onerror=function(){_this.logger.log(ILogger.LogLevel.Warning,"Error from HTTP request. "+xhr.status+": "+xhr.statusText);reject(new Errors.HttpError(xhr.statusText,xhr.status))};xhr.ontimeout=function(){_this.logger.log(ILogger.LogLevel.Warning,"Timeout from HTTP request.");reject(new Errors.TimeoutError)};xhr.send(request.content||"")})};return DefaultHttpClient}(HttpClient);exports.DefaultHttpClient=DefaultHttpClient});unwrapExports(HttpClient_1);var HttpClient_2=HttpClient_1.HttpResponse;var HttpClient_3=HttpClient_1.HttpClient;var HttpClient_4=HttpClient_1.DefaultHttpClient;var TextMessageFormat_1=createCommonjsModule(function(module,exports){Object.defineProperty(exports,"__esModule",{value:true});var TextMessageFormat=function(){function TextMessageFormat(){}TextMessageFormat.write=function(output){return""+output+TextMessageFormat.RecordSeparator};TextMessageFormat.parse=function(input){if(input[input.length-1]!==TextMessageFormat.RecordSeparator){throw new Error("Message is incomplete.")}var messages=input.split(TextMessageFormat.RecordSeparator);messages.pop();return messages};TextMessageFormat.RecordSeparatorCode=30;TextMessageFormat.RecordSeparator=String.fromCharCode(TextMessageFormat.RecordSeparatorCode);return TextMessageFormat}();exports.TextMessageFormat=TextMessageFormat});unwrapExports(TextMessageFormat_1);var TextMessageFormat_2=TextMessageFormat_1.TextMessageFormat;var HandshakeProtocol_1=createCommonjsModule(function(module,exports){Object.defineProperty(exports,"__esModule",{value:true});var HandshakeProtocol=function(){function HandshakeProtocol(){}HandshakeProtocol.prototype.writeHandshakeRequest=function(handshakeRequest){return TextMessageFormat_1.TextMessageFormat.write(JSON.stringify(handshakeRequest))};HandshakeProtocol.prototype.parseHandshakeResponse=function(data){var responseMessage;var messageData;var remainingData;if(data instanceof ArrayBuffer){var binaryData=new Uint8Array(data);var separatorIndex=binaryData.indexOf(TextMessageFormat_1.TextMessageFormat.RecordSeparatorCode);if(separatorIndex===-1){throw new Error("Message is incomplete.")}var responseLength=separatorIndex+1;messageData=String.fromCharCode.apply(null,binaryData.slice(0,responseLength));remainingData=binaryData.byteLength>responseLength?binaryData.slice(responseLength).buffer:null}else{var textData=data;var separatorIndex=textData.indexOf(TextMessageFormat_1.TextMessageFormat.RecordSeparator);if(separatorIndex===-1){throw new Error("Message is incomplete.")}var responseLength=separatorIndex+1;messageData=textData.substring(0,responseLength);remainingData=textData.length>responseLength?textData.substring(responseLength):null}var messages=TextMessageFormat_1.TextMessageFormat.parse(messageData);responseMessage=JSON.parse(messages[0]);return[remainingData,responseMessage]};return HandshakeProtocol}();exports.HandshakeProtocol=HandshakeProtocol});unwrapExports(HandshakeProtocol_1);var HandshakeProtocol_2=HandshakeProtocol_1.HandshakeProtocol;var IHubProtocol=createCommonjsModule(function(module,exports){Object.defineProperty(exports,"__esModule",{value:true});var MessageType;(function(MessageType){MessageType[MessageType["Invocation"]=1]="Invocation";MessageType[MessageType["StreamItem"]=2]="StreamItem";MessageType[MessageType["Completion"]=3]="Completion";MessageType[MessageType["StreamInvocation"]=4]="StreamInvocation";MessageType[MessageType["CancelInvocation"]=5]="CancelInvocation";MessageType[MessageType["Ping"]=6]="Ping";MessageType[MessageType["Close"]=7]="Close"})(MessageType=exports.MessageType||(exports.MessageType={}))});unwrapExports(IHubProtocol);var IHubProtocol_1=IHubProtocol.MessageType;var Loggers=createCommonjsModule(function(module,exports){Object.defineProperty(exports,"__esModule",{value:true});var NullLogger=function(){function NullLogger(){}NullLogger.prototype.log=function(logLevel,message){};NullLogger.instance=new NullLogger;return NullLogger}();exports.NullLogger=NullLogger});unwrapExports(Loggers);var Loggers_1=Loggers.NullLogger;var Utils=createCommonjsModule(function(module,exports){Object.defineProperty(exports,"__esModule",{value:true});var Arg=function(){function Arg(){}Arg.isRequired=function(val,name){if(val===null||val===undefined){throw new Error("The '"+name+"' argument is required.")}};Arg.isIn=function(val,values,name){if(!(val in values)){throw new Error("Unknown "+name+" value: "+val+".")}};return Arg}();exports.Arg=Arg;function getDataDetail(data,includeContent){var length=null;if(data instanceof ArrayBuffer){length="Binary data of length "+data.byteLength;if(includeContent){length+=". Content: '"+formatArrayBuffer(data)+"'"}}else if(typeof data==="string"){length="String data of length "+data.length;if(includeContent){length+=". Content: '"+data+"'."}}return length}exports.getDataDetail=getDataDetail;function formatArrayBuffer(data){var view=new Uint8Array(data);var str="";view.forEach(function(num){var pad=num<16?"0":"";str+="0x"+pad+num.toString(16)+" "});return str.substr(0,str.length-1)}exports.formatArrayBuffer=formatArrayBuffer;function sendMessage(logger,transportName,httpClient,url,accessTokenFactory,content,logMessageContent){return tslib_1.__awaiter(this,void 0,void 0,function(){var headers,token,response,_a;return tslib_1.__generator(this,function(_b){switch(_b.label){case 0:return[4,accessTokenFactory()];case 1:token=_b.sent();if(token){headers=(_a={},_a["Authorization"]="Bearer "+token,_a)}logger.log(ILogger.LogLevel.Trace,"("+transportName+" transport) sending data. "+getDataDetail(content,logMessageContent)+".");return[4,httpClient.post(url,{content:content,headers:headers})];case 2:response=_b.sent();logger.log(ILogger.LogLevel.Trace,"("+transportName+" transport) request complete. Response status: "+response.statusCode+".");return[2]}})})}exports.sendMessage=sendMessage;function createLogger(logger){if(logger===undefined){return new ConsoleLogger(ILogger.LogLevel.Information)}if(logger===null){return Loggers.NullLogger.instance}if(logger.log){return logger}return new ConsoleLogger(logger)}exports.createLogger=createLogger;var Subject=function(){function Subject(cancelCallback){this.observers=[];this.cancelCallback=cancelCallback}Subject.prototype.next=function(item){for(var _i=0,_a=this.observers;_i<_a.length;_i++){var observer=_a[_i];observer.next(item)}};Subject.prototype.error=function(err){for(var _i=0,_a=this.observers;_i<_a.length;_i++){var observer=_a[_i];if(observer.error){observer.error(err)}}};Subject.prototype.complete=function(){for(var _i=0,_a=this.observers;_i<_a.length;_i++){var observer=_a[_i];if(observer.complete){observer.complete()}}};Subject.prototype.subscribe=function(observer){this.observers.push(observer);return new SubjectSubscription(this,observer)};return Subject}();exports.Subject=Subject;var SubjectSubscription=function(){function SubjectSubscription(subject,observer){this.subject=subject;this.observer=observer}SubjectSubscription.prototype.dispose=function(){var index=this.subject.observers.indexOf(this.observer);if(index>-1){this.subject.observers.splice(index,1)}if(this.subject.observers.length===0){this.subject.cancelCallback().catch(function(_){})}};return SubjectSubscription}();exports.SubjectSubscription=SubjectSubscription;var ConsoleLogger=function(){function ConsoleLogger(minimumLogLevel){this.minimumLogLevel=minimumLogLevel}ConsoleLogger.prototype.log=function(logLevel,message){if(logLevel>=this.minimumLogLevel){switch(logLevel){case ILogger.LogLevel.Critical:case ILogger.LogLevel.Error:console.error(ILogger.LogLevel[logLevel]+": "+message);break;case ILogger.LogLevel.Warning:console.warn(ILogger.LogLevel[logLevel]+": "+message);break;case ILogger.LogLevel.Information:console.info(ILogger.LogLevel[logLevel]+": "+message);break;default:console.log(ILogger.LogLevel[logLevel]+": "+message);break}}};return ConsoleLogger}();exports.ConsoleLogger=ConsoleLogger});unwrapExports(Utils);var Utils_1=Utils.Arg;var Utils_2=Utils.getDataDetail;var Utils_3=Utils.formatArrayBuffer;var Utils_4=Utils.sendMessage;var Utils_5=Utils.createLogger;var Utils_6=Utils.Subject;var Utils_7=Utils.SubjectSubscription;var Utils_8=Utils.ConsoleLogger;var HubConnection_1=createCommonjsModule(function(module,exports){Object.defineProperty(exports,"__esModule",{value:true});var DEFAULT_TIMEOUT_IN_MS=30*1e3;var HubConnection=function(){function HubConnection(connection,logger,protocol){var _this=this;Utils.Arg.isRequired(connection,"connection");Utils.Arg.isRequired(logger,"logger");Utils.Arg.isRequired(protocol,"protocol");this.serverTimeoutInMilliseconds=DEFAULT_TIMEOUT_IN_MS;this.logger=logger;this.protocol=protocol;this.connection=connection;this.handshakeProtocol=new HandshakeProtocol_1.HandshakeProtocol;this.connection.onreceive=function(data){return _this.processIncomingData(data)};this.connection.onclose=function(error){return _this.connectionClosed(error)};this.callbacks={};this.methods={};this.closedCallbacks=[];this.id=0}HubConnection.create=function(connection,logger,protocol){return new HubConnection(connection,logger,protocol)};HubConnection.prototype.start=function(){return tslib_1.__awaiter(this,void 0,void 0,function(){var handshakeRequest;return tslib_1.__generator(this,function(_a){switch(_a.label){case 0:handshakeRequest={protocol:this.protocol.name,version:this.protocol.version};this.logger.log(ILogger.LogLevel.Debug,"Starting HubConnection.");this.receivedHandshakeResponse=false;return[4,this.connection.start(this.protocol.transferFormat)];case 1:_a.sent();this.logger.log(ILogger.LogLevel.Debug,"Sending handshake request.");return[4,this.connection.send(this.handshakeProtocol.writeHandshakeRequest(handshakeRequest))];case 2:_a.sent();this.logger.log(ILogger.LogLevel.Information,"Using HubProtocol '"+this.protocol.name+"'.");this.cleanupTimeout();this.configureTimeout();return[2]}})})};HubConnection.prototype.stop=function(){this.logger.log(ILogger.LogLevel.Debug,"Stopping HubConnection.");this.cleanupTimeout();return this.connection.stop()};HubConnection.prototype.stream=function(methodName){var _this=this;var args=[];for(var _i=1;_i"));this.onclose(closeError)}this.logger.log(ILogger.LogLevel.Trace,"(LongPolling transport) Transport finished.");return[7];case 9:return[2]}})})};LongPollingTransport.prototype.send=function(data){return tslib_1.__awaiter(this,void 0,void 0,function(){return tslib_1.__generator(this,function(_a){if(!this.running){return[2,Promise.reject(new Error("Cannot send until the transport is connected"))]}return[2,Utils.sendMessage(this.logger,"LongPolling",this.httpClient,this.url,this.accessTokenFactory,data,this.logMessageContent)]})})};LongPollingTransport.prototype.stop=function(){return tslib_1.__awaiter(this,void 0,void 0,function(){var _this=this;var deleteOptions,token,response;return tslib_1.__generator(this,function(_a){switch(_a.label){case 0:_a.trys.push([0,,3,4]);this.running=false;this.logger.log(ILogger.LogLevel.Trace,"(LongPolling transport) sending DELETE request to "+this.url+".");deleteOptions={headers:{}};return[4,this.accessTokenFactory()];case 1:token=_a.sent();this.updateHeaderToken(deleteOptions,token);return[4,this.httpClient.delete(this.url,deleteOptions)];case 2:response=_a.sent();this.logger.log(ILogger.LogLevel.Trace,"(LongPolling transport) DELETE request accepted.");return[3,4];case 3:if(!this.stopped){this.shutdownTimer=setTimeout(function(){_this.logger.log(ILogger.LogLevel.Warning,"(LongPolling transport) server did not terminate after DELETE request, canceling poll.");_this.pollAbort.abort()},this.shutdownTimeout)}return[7];case 4:return[2]}})})};return LongPollingTransport}();exports.LongPollingTransport=LongPollingTransport});unwrapExports(LongPollingTransport_1);var LongPollingTransport_2=LongPollingTransport_1.LongPollingTransport;var ServerSentEventsTransport_1=createCommonjsModule(function(module,exports){Object.defineProperty(exports,"__esModule",{value:true});var ServerSentEventsTransport=function(){function ServerSentEventsTransport(httpClient,accessTokenFactory,logger,logMessageContent){this.httpClient=httpClient;this.accessTokenFactory=accessTokenFactory||function(){return null};this.logger=logger;this.logMessageContent=logMessageContent}ServerSentEventsTransport.prototype.connect=function(url,transferFormat){return tslib_1.__awaiter(this,void 0,void 0,function(){var _this=this;var token;return tslib_1.__generator(this,function(_a){switch(_a.label){case 0:Utils.Arg.isRequired(url,"url");Utils.Arg.isRequired(transferFormat,"transferFormat");Utils.Arg.isIn(transferFormat,ITransport.TransferFormat,"transferFormat");if(typeof EventSource==="undefined"){throw new Error("'EventSource' is not supported in your environment.")}this.logger.log(ILogger.LogLevel.Trace,"(SSE transport) Connecting");return[4,this.accessTokenFactory()];case 1:token=_a.sent();if(token){url+=(url.indexOf("?")<0?"?":"&")+("access_token="+encodeURIComponent(token))}this.url=url;return[2,new Promise(function(resolve,reject){var opened=false;if(transferFormat!==ITransport.TransferFormat.Text){reject(new Error("The Server-Sent Events transport only supports the 'Text' transfer format"))}var eventSource=new EventSource(url,{withCredentials:true});try{eventSource.onmessage=function(e){if(_this.onreceive){try{_this.logger.log(ILogger.LogLevel.Trace,"(SSE transport) data received. "+Utils.getDataDetail(e.data,_this.logMessageContent)+".");_this.onreceive(e.data)}catch(error){if(_this.onclose){_this.onclose(error)}return}}};eventSource.onerror=function(e){var error=new Error(e.message||"Error occurred");if(opened){_this.close(error)}else{reject(error)}};eventSource.onopen=function(){_this.logger.log(ILogger.LogLevel.Information,"SSE connected to "+_this.url);_this.eventSource=eventSource;opened=true;resolve()}}catch(e){return Promise.reject(e)}})]}})})};ServerSentEventsTransport.prototype.send=function(data){return tslib_1.__awaiter(this,void 0,void 0,function(){return tslib_1.__generator(this,function(_a){if(!this.eventSource){return[2,Promise.reject(new Error("Cannot send until the transport is connected"))]}return[2,Utils.sendMessage(this.logger,"SSE",this.httpClient,this.url,this.accessTokenFactory,data,this.logMessageContent)]})})};ServerSentEventsTransport.prototype.stop=function(){this.close();return Promise.resolve()};ServerSentEventsTransport.prototype.close=function(e){if(this.eventSource){this.eventSource.close();this.eventSource=null;if(this.onclose){this.onclose(e)}}};return ServerSentEventsTransport}();exports.ServerSentEventsTransport=ServerSentEventsTransport});unwrapExports(ServerSentEventsTransport_1);var ServerSentEventsTransport_2=ServerSentEventsTransport_1.ServerSentEventsTransport;var WebSocketTransport_1=createCommonjsModule(function(module,exports){Object.defineProperty(exports,"__esModule",{value:true});var WebSocketTransport=function(){function WebSocketTransport(accessTokenFactory,logger,logMessageContent){this.logger=logger;this.accessTokenFactory=accessTokenFactory||function(){return null};this.logMessageContent=logMessageContent}WebSocketTransport.prototype.connect=function(url,transferFormat){return tslib_1.__awaiter(this,void 0,void 0,function(){var _this=this;var token;return tslib_1.__generator(this,function(_a){switch(_a.label){case 0:Utils.Arg.isRequired(url,"url");Utils.Arg.isRequired(transferFormat,"transferFormat");Utils.Arg.isIn(transferFormat,ITransport.TransferFormat,"transferFormat");if(typeof WebSocket==="undefined"){throw new Error("'WebSocket' is not supported in your environment.")}this.logger.log(ILogger.LogLevel.Trace,"(WebSockets transport) Connecting");return[4,this.accessTokenFactory()];case 1:token=_a.sent();if(token){url+=(url.indexOf("?")<0?"?":"&")+("access_token="+encodeURIComponent(token))}return[2,new Promise(function(resolve,reject){url=url.replace(/^http/,"ws");var webSocket=new WebSocket(url);if(transferFormat===ITransport.TransferFormat.Binary){webSocket.binaryType="arraybuffer"}webSocket.onopen=function(event){_this.logger.log(ILogger.LogLevel.Information,"WebSocket connected to "+url);_this.webSocket=webSocket;resolve()};webSocket.onerror=function(event){reject(event.error)};webSocket.onmessage=function(message){_this.logger.log(ILogger.LogLevel.Trace,"(WebSockets transport) data received. "+Utils.getDataDetail(message.data,_this.logMessageContent)+".");if(_this.onreceive){_this.onreceive(message.data)}};webSocket.onclose=function(event){_this.logger.log(ILogger.LogLevel.Trace,"(WebSockets transport) socket closed.");if(_this.onclose){if(event.wasClean===false||event.code!==1e3){_this.onclose(new Error("Websocket closed with status code: "+event.code+" ("+event.reason+")"))}else{_this.onclose()}}}})]}})})};WebSocketTransport.prototype.send=function(data){if(this.webSocket&&this.webSocket.readyState===WebSocket.OPEN){this.logger.log(ILogger.LogLevel.Trace,"(WebSockets transport) sending data. "+Utils.getDataDetail(data,this.logMessageContent)+".");this.webSocket.send(data);return Promise.resolve()}return Promise.reject("WebSocket is not in the OPEN state")};WebSocketTransport.prototype.stop=function(){if(this.webSocket){this.webSocket.close();this.webSocket=null}return Promise.resolve()};return WebSocketTransport}();exports.WebSocketTransport=WebSocketTransport});unwrapExports(WebSocketTransport_1);var WebSocketTransport_2=WebSocketTransport_1.WebSocketTransport;var HttpConnection_1=createCommonjsModule(function(module,exports){Object.defineProperty(exports,"__esModule",{value:true});var MAX_REDIRECTS=100;var HttpConnection=function(){function HttpConnection(url,options){if(options===void 0){options={}}this.features={};Utils.Arg.isRequired(url,"url");this.logger=Utils.createLogger(options.logger);this.baseUrl=this.resolveUrl(url);options=options||{};options.accessTokenFactory=options.accessTokenFactory||function(){return null};options.logMessageContent=options.logMessageContent||false;this.httpClient=options.httpClient||new HttpClient_1.DefaultHttpClient(this.logger);this.connectionState=2;this.options=options}HttpConnection.prototype.start=function(transferFormat){transferFormat=transferFormat||ITransport.TransferFormat.Binary;Utils.Arg.isIn(transferFormat,ITransport.TransferFormat,"transferFormat");this.logger.log(ILogger.LogLevel.Debug,"Starting connection with transfer format '"+ITransport.TransferFormat[transferFormat]+"'.");if(this.connectionState!==2){return Promise.reject(new Error("Cannot start a connection that is not in the 'Disconnected' state."))}this.connectionState=0;this.startPromise=this.startInternal(transferFormat);return this.startPromise};HttpConnection.prototype.send=function(data){if(this.connectionState!==1){throw new Error("Cannot send data if the connection is not in the 'Connected' State.")}return this.transport.send(data)};HttpConnection.prototype.stop=function(error){return tslib_1.__awaiter(this,void 0,void 0,function(){var e_1;return tslib_1.__generator(this,function(_a){switch(_a.label){case 0:this.connectionState=2;_a.label=1;case 1:_a.trys.push([1,3,,4]);return[4,this.startPromise];case 2:_a.sent();return[3,4];case 3:e_1=_a.sent();return[3,4];case 4:if(!this.transport)return[3,6];this.stopError=error;return[4,this.transport.stop()];case 5:_a.sent();this.transport=null;_a.label=6;case 6:return[2]}})})};HttpConnection.prototype.startInternal=function(transferFormat){return tslib_1.__awaiter(this,void 0,void 0,function(){var _this=this;var url,negotiateResponse,redirects,_loop_1,this_1,state_1,e_2;return tslib_1.__generator(this,function(_a){switch(_a.label){case 0:url=this.baseUrl;this.accessTokenFactory=this.options.accessTokenFactory;_a.label=1;case 1:_a.trys.push([1,12,,13]);if(!this.options.skipNegotiation)return[3,5];if(!(this.options.transport===ITransport.HttpTransportType.WebSockets))return[3,3];this.transport=this.constructTransport(ITransport.HttpTransportType.WebSockets);return[4,this.transport.connect(url,transferFormat)];case 2:_a.sent();return[3,4];case 3:throw Error("Negotiation can only be skipped when using the WebSocket transport directly.");case 4:return[3,11];case 5:negotiateResponse=null;redirects=0;_loop_1=function(){var accessToken_1;return tslib_1.__generator(this,function(_a){switch(_a.label){case 0:return[4,this_1.getNegotiationResponse(url)];case 1:negotiateResponse=_a.sent();if(this_1.connectionState===2){return[2,{value:void 0}]}if(negotiateResponse.url){url=negotiateResponse.url}if(negotiateResponse.accessToken){accessToken_1=negotiateResponse.accessToken;this_1.accessTokenFactory=function(){return accessToken_1}}redirects++;return[2]}})};this_1=this;_a.label=6;case 6:return[5,_loop_1()];case 7:state_1=_a.sent();if(typeof state_1==="object")return[2,state_1.value];_a.label=8;case 8:if(negotiateResponse.url&&redirects=0){if(transport===ITransport.HttpTransportType.WebSockets&&typeof WebSocket==="undefined"||transport===ITransport.HttpTransportType.ServerSentEvents&&typeof EventSource==="undefined"){this.logger.log(ILogger.LogLevel.Debug,"Skipping transport '"+ITransport.HttpTransportType[transport]+"' because it is not supported in your environment.'")}else{this.logger.log(ILogger.LogLevel.Debug,"Selecting transport '"+ITransport.HttpTransportType[transport]+"'");return transport}}else{this.logger.log(ILogger.LogLevel.Debug,"Skipping transport '"+ITransport.HttpTransportType[transport]+"' because it does not support the requested transfer format '"+ITransport.TransferFormat[requestedTransferFormat]+"'.")}}else{this.logger.log(ILogger.LogLevel.Debug,"Skipping transport '"+ITransport.HttpTransportType[transport]+"' because it was disabled by the client.")}}return null};HttpConnection.prototype.isITransport=function(transport){return transport&&typeof transport==="object"&&"connect"in transport};HttpConnection.prototype.changeState=function(from,to){if(this.connectionState===from){this.connectionState=to;return true}return false};HttpConnection.prototype.stopConnection=function(error){return tslib_1.__awaiter(this,void 0,void 0,function(){return tslib_1.__generator(this,function(_a){this.transport=null;error=this.stopError||error;if(error){this.logger.log(ILogger.LogLevel.Error,"Connection disconnected with error '"+error+"'.")}else{this.logger.log(ILogger.LogLevel.Information,"Connection disconnected.")}this.connectionState=2;if(this.onclose){this.onclose(error)}return[2]})})};HttpConnection.prototype.resolveUrl=function(url){if(url.lastIndexOf("https://",0)===0||url.lastIndexOf("http://",0)===0){return url}if(typeof window==="undefined"||!window||!window.document){throw new Error("Cannot resolve '"+url+"'.")}var aTag=window.document.createElement("a");aTag.href=url;this.logger.log(ILogger.LogLevel.Information,"Normalizing '"+url+"' to '"+aTag.href+"'.");return aTag.href};HttpConnection.prototype.resolveNegotiateUrl=function(url){var index=url.indexOf("?");var negotiateUrl=url.substring(0,index===-1?url.length:index);if(negotiateUrl[negotiateUrl.length-1]!=="/"){negotiateUrl+="/"}negotiateUrl+="negotiate";negotiateUrl+=index===-1?"":url.substring(index);return negotiateUrl};return HttpConnection}();exports.HttpConnection=HttpConnection;function transportMatches(requestedTransport,actualTransport){return!requestedTransport||(actualTransport&requestedTransport)!==0}});unwrapExports(HttpConnection_1);var HttpConnection_2=HttpConnection_1.HttpConnection;var JsonHubProtocol_1=createCommonjsModule(function(module,exports){Object.defineProperty(exports,"__esModule",{value:true});var JSON_HUB_PROTOCOL_NAME="json";var JsonHubProtocol=function(){function JsonHubProtocol(){this.name=JSON_HUB_PROTOCOL_NAME;this.version=1;this.transferFormat=ITransport.TransferFormat.Text}JsonHubProtocol.prototype.parseMessages=function(input,logger){if(typeof input!=="string"){throw new Error("Invalid input for JSON hub protocol. Expected a string.")}if(!input){return[]}if(logger===null){logger=Loggers.NullLogger.instance}var messages=TextMessageFormat_1.TextMessageFormat.parse(input);var hubMessages=[];for(var _i=0,messages_1=messages;_i(TMessage message) where TMessage : Message; - } -} \ No newline at end of file diff --git a/vote/dotnet/Vote/Messaging/MessageHelper.cs b/vote/dotnet/Vote/Messaging/MessageHelper.cs deleted file mode 100644 index 06422d3d35..0000000000 --- a/vote/dotnet/Vote/Messaging/MessageHelper.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Newtonsoft.Json; -using Vote.Messaging.Messages; -using System.Text; - -namespace Vote.Messaging -{ - public class MessageHelper - { - public static byte[] ToData(TMessage message) - where TMessage : Message - { - var json = JsonConvert.SerializeObject(message); - return Encoding.Unicode.GetBytes(json); - } - - public static TMessage FromData(byte[] data) - where TMessage : Message - { - var json = Encoding.Unicode.GetString(data); - return (TMessage)JsonConvert.DeserializeObject(json); - } - } -} diff --git a/vote/dotnet/Vote/Messaging/MessageQueue.cs b/vote/dotnet/Vote/Messaging/MessageQueue.cs deleted file mode 100644 index 77c8834a68..0000000000 --- a/vote/dotnet/Vote/Messaging/MessageQueue.cs +++ /dev/null @@ -1,35 +0,0 @@ -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; -using NATS.Client; -using Vote.Messaging.Messages; - -namespace Vote.Messaging -{ - public class MessageQueue : IMessageQueue - { - protected readonly IConfiguration _configuration; - protected readonly ILogger _logger; - - public MessageQueue(IConfiguration configuration, ILogger logger) - { - _configuration = configuration; - _logger = logger; - } - - public void Publish(TMessage message) - where TMessage : Message - { - using (var connection = CreateConnection()) - { - var data = MessageHelper.ToData(message); - connection.Publish(message.Subject, data); - } - } - - public IConnection CreateConnection() - { - var url = _configuration.GetValue("MessageQueue:Url"); - return new ConnectionFactory().CreateConnection(url); - } - } -} diff --git a/vote/dotnet/Vote/Messaging/Messages/Events/VoteCastEvent.cs b/vote/dotnet/Vote/Messaging/Messages/Events/VoteCastEvent.cs deleted file mode 100644 index a398765af9..0000000000 --- a/vote/dotnet/Vote/Messaging/Messages/Events/VoteCastEvent.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace Vote.Messaging.Messages -{ - public class VoteCastEvent : Message - { - public override string Subject { get { return MessageSubject; } } - - public string VoterId {get; set;} - - public string Vote {get; set; } - - public static string MessageSubject = "events.vote.votecast"; - } -} \ No newline at end of file diff --git a/vote/dotnet/Vote/Messaging/Messages/Message.cs b/vote/dotnet/Vote/Messaging/Messages/Message.cs deleted file mode 100644 index 1e5f7d52a7..0000000000 --- a/vote/dotnet/Vote/Messaging/Messages/Message.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; - -namespace Vote.Messaging.Messages -{ - public abstract class Message - { - public string CorrelationId { get; set; } - - public abstract string Subject { get; } - - public Message() - { - CorrelationId = Guid.NewGuid().ToString(); - } - } -} diff --git a/vote/dotnet/Vote/Pages/Index.cshtml b/vote/dotnet/Vote/Pages/Index.cshtml deleted file mode 100644 index 2c85b0688b..0000000000 --- a/vote/dotnet/Vote/Pages/Index.cshtml +++ /dev/null @@ -1,50 +0,0 @@ -@page -@model Vote.Pages.IndexModel - - - - - - @Model.OptionA vs @Model.OptionB! - - - - - - - - -
-
-

@Model.OptionA vs @Model.OptionB!

-
- - -
-
- (Tip: you can change your vote) -
-
- Processed by container ID @System.Environment.MachineName -
-
-
- - @**@ - - - - diff --git a/vote/dotnet/Vote/Pages/Index.cshtml.cs b/vote/dotnet/Vote/Pages/Index.cshtml.cs deleted file mode 100644 index c735302565..0000000000 --- a/vote/dotnet/Vote/Pages/Index.cshtml.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.RazorPages; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; -using Vote.Messaging; -using Vote.Messaging.Messages; - -namespace Vote.Pages -{ - public class IndexModel : PageModel - { - private string _optionA; - private string _optionB; - - protected readonly IMessageQueue _messageQueue; - protected readonly IConfiguration _configuration; - protected readonly ILogger _logger; - - public IndexModel(IMessageQueue messageQueue, IConfiguration configuration, ILogger logger) - { - _messageQueue = messageQueue; - _configuration = configuration; - _logger = logger; - - _optionA = _configuration.GetValue("Voting:OptionA"); - _optionB = _configuration.GetValue("Voting:OptionB"); - } - - public string OptionA { get; private set; } - - public string OptionB { get; private set; } - - [BindProperty] - public string Vote { get; private set; } - - private string _voterId - { - get { return TempData.Peek("VoterId") as string; } - set { TempData["VoterId"] = value; } - } - - public void OnGet() - { - OptionA = _optionA; - OptionB = _optionB; - } - - public IActionResult OnPost(string vote) - { - Vote = vote; - OptionA = _optionA; - OptionB = _optionB; - if (_configuration.GetValue("MessageQueue:Enabled")) - { - PublishVote(vote); - } - return Page(); - } - - private void PublishVote(string vote) - { - if (string.IsNullOrEmpty(_voterId)) - { - _voterId = Guid.NewGuid().ToString(); - } - var message = new VoteCastEvent - { - VoterId = _voterId, - Vote = vote - }; - _messageQueue.Publish(message); - } - } -} diff --git a/vote/dotnet/Vote/Program.cs b/vote/dotnet/Vote/Program.cs deleted file mode 100644 index 8c97e8c4f4..0000000000 --- a/vote/dotnet/Vote/Program.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; - -namespace Vote -{ - public class Program - { - public static void Main(string[] args) - { - CreateWebHostBuilder(args).Build().Run(); - } - - public static IWebHostBuilder CreateWebHostBuilder(string[] args) => - WebHost.CreateDefaultBuilder(args) - .UseStartup(); - } -} diff --git a/vote/dotnet/Vote/Properties/launchSettings.json b/vote/dotnet/Vote/Properties/launchSettings.json deleted file mode 100644 index 157d42bd05..0000000000 --- a/vote/dotnet/Vote/Properties/launchSettings.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:6116", - "sslPort": 44316 - } - }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "Vote": { - "commandName": "Project", - "launchBrowser": true, - "applicationUrl": "https://localhost:5001;http://localhost:5000", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} \ No newline at end of file diff --git a/vote/dotnet/Vote/Startup.cs b/vote/dotnet/Vote/Startup.cs deleted file mode 100644 index 28ac848543..0000000000 --- a/vote/dotnet/Vote/Startup.cs +++ /dev/null @@ -1,45 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Vote.Messaging; - -namespace Vote -{ - public class Startup - { - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } - - public IConfiguration Configuration { get; } - - public void ConfigureServices(IServiceCollection services) - { - services.AddMvc() - .SetCompatibilityVersion(CompatibilityVersion.Version_2_1) - .AddRazorPagesOptions(options => - { - options.Conventions.ConfigureFilter(new IgnoreAntiforgeryTokenAttribute()); - }); - services.AddTransient(); - } - - public void Configure(IApplicationBuilder app, IHostingEnvironment env) - { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - else - { - app.UseExceptionHandler("/Error"); - } - - app.UseStaticFiles(); - app.UseMvc(); - } - } -} \ No newline at end of file diff --git a/vote/dotnet/Vote/Vote.csproj b/vote/dotnet/Vote/Vote.csproj deleted file mode 100644 index 3a80a2a8f8..0000000000 --- a/vote/dotnet/Vote/Vote.csproj +++ /dev/null @@ -1,12 +0,0 @@ - - - - netcoreapp3.1 - - - - - - - - diff --git a/vote/dotnet/Vote/Vote.sln b/vote/dotnet/Vote/Vote.sln deleted file mode 100644 index d7a5867d8e..0000000000 --- a/vote/dotnet/Vote/Vote.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27703.2042 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vote", "Vote.csproj", "{DA159FEC-BE4D-4704-ACB2-E03FFA6F2D3B}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {DA159FEC-BE4D-4704-ACB2-E03FFA6F2D3B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DA159FEC-BE4D-4704-ACB2-E03FFA6F2D3B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DA159FEC-BE4D-4704-ACB2-E03FFA6F2D3B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DA159FEC-BE4D-4704-ACB2-E03FFA6F2D3B}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {BEABFEFC-9957-41E3-96A1-7F501F69411D} - EndGlobalSection -EndGlobal diff --git a/vote/dotnet/Vote/appsettings.Development.json b/vote/dotnet/Vote/appsettings.Development.json deleted file mode 100644 index 0e134b259a..0000000000 --- a/vote/dotnet/Vote/appsettings.Development.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "MessageQueue": { - "Enabled": false - }, - "Logging": { - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" - } - } -} diff --git a/vote/dotnet/Vote/appsettings.json b/vote/dotnet/Vote/appsettings.json deleted file mode 100644 index fb2aa2b28c..0000000000 --- a/vote/dotnet/Vote/appsettings.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "Voting": { - "OptionA": "Cats", - "OptionB": "Dogs" - }, - "MessageQueue": { - "Enabled": true, - "Url": "nats://message-queue:4222" - }, - "Logging": { - "LogLevel": { - "Default": "Information" - } - }, - "AllowedHosts": "*" -} diff --git a/vote/dotnet/Vote/wwwroot/css/site.css b/vote/dotnet/Vote/wwwroot/css/site.css deleted file mode 100644 index b69271d869..0000000000 --- a/vote/dotnet/Vote/wwwroot/css/site.css +++ /dev/null @@ -1,135 +0,0 @@ -@import url(//fonts.googleapis.com/css?family=Open+Sans:400,700,600); - -* { - box-sizing: border-box; -} - -html, body { - margin: 0; - padding: 0; - background-color: #F7F8F9; - height: 100vh; - font-family: 'Open Sans'; -} - -button { - border-radius: 0; - width: 100%; - height: 50%; -} - - button[type="submit"] { - -webkit-appearance: none; - -webkit-border-radius: 0; - } - - button i { - float: right; - padding-right: 30px; - margin-top: 3px; - } - - button.a { - background-color: #1aaaf8; - } - - button.b { - background-color: #00cbca; - } - -#tip { - text-align: left; - color: #c0c9ce; - font-size: 14px; -} - -#hostname { - position: absolute; - bottom: 100px; - right: 0; - left: 0; - color: #8f9ea8; - font-size: 24px; -} - -#content-container { - z-index: 2; - position: relative; - margin: 0 auto; - display: table; - padding: 10px; - max-width: 940px; - height: 100%; -} - -#content-container-center { - display: table-cell; - text-align: center; -} - - #content-container-center h3 { - color: #254356; - } - -#choice { - transition: all 300ms linear; - line-height: 1.3em; - display: inline; - vertical-align: middle; - font-size: 3em; -} - - #choice a { - text-decoration: none; - } - - #choice a:hover, #choice a:focus { - outline: 0; - text-decoration: underline; - } - - #choice button { - display: block; - height: 80px; - width: 330px; - border: none; - color: white; - text-transform: uppercase; - font-size: 18px; - font-weight: 700; - margin-top: 10px; - margin-bottom: 10px; - text-align: left; - padding-left: 50px; - } - - #choice button.a:hover { - background-color: #1488c6; - } - - #choice button.b:hover { - background-color: #00a2a1; - } - - #choice button.a:focus { - background-color: #1488c6; - } - - #choice button.b:focus { - background-color: #00a2a1; - } - -#background-stats { - z-index: 1; - height: 100%; - width: 100%; - position: absolute; -} - - #background-stats div { - transition: width 400ms ease-in-out; - display: inline-block; - margin-bottom: -4px; - width: 50%; - height: 100%; - } diff --git a/vote/dotnet/Vote/wwwroot/css/site.min.css b/vote/dotnet/Vote/wwwroot/css/site.min.css deleted file mode 100644 index 5e93e30ae3..0000000000 --- a/vote/dotnet/Vote/wwwroot/css/site.min.css +++ /dev/null @@ -1 +0,0 @@ -body{padding-top:50px;padding-bottom:20px}.body-content{padding-left:15px;padding-right:15px}.carousel-caption p{font-size:20px;line-height:1.4}.carousel-inner .item img[src$=".svg"]{width:100%}#qrCode{margin:15px}@media screen and (max-width:767px){.carousel-caption{display:none}} \ No newline at end of file diff --git a/vote/dotnet/Vote/wwwroot/js/jquery-1.11.1-min.js b/vote/dotnet/Vote/wwwroot/js/jquery-1.11.1-min.js deleted file mode 100644 index a7c78ce623..0000000000 --- a/vote/dotnet/Vote/wwwroot/js/jquery-1.11.1-min.js +++ /dev/null @@ -1,13 +0,0 @@ -/*! jQuery v1.11.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ -!function (a, b) { "object" == typeof module && "object" == typeof module.exports ? module.exports = a.document ? b(a, !0) : function (a) { if (!a.document) throw new Error("jQuery requires a window with a document"); return b(a) } : b(a) }("undefined" != typeof window ? window : this, function (a, b) { - var c = [], d = c.slice, e = c.concat, f = c.push, g = c.indexOf, h = {}, i = h.toString, j = h.hasOwnProperty, k = {}, l = "1.11.1", m = function (a, b) { return new m.fn.init(a, b) }, n = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, o = /^-ms-/, p = /-([\da-z])/gi, q = function (a, b) { return b.toUpperCase() }; m.fn = m.prototype = { jquery: l, constructor: m, selector: "", length: 0, toArray: function () { return d.call(this) }, get: function (a) { return null != a ? 0 > a ? this[a + this.length] : this[a] : d.call(this) }, pushStack: function (a) { var b = m.merge(this.constructor(), a); return b.prevObject = this, b.context = this.context, b }, each: function (a, b) { return m.each(this, a, b) }, map: function (a) { return this.pushStack(m.map(this, function (b, c) { return a.call(b, c, b) })) }, slice: function () { return this.pushStack(d.apply(this, arguments)) }, first: function () { return this.eq(0) }, last: function () { return this.eq(-1) }, eq: function (a) { var b = this.length, c = +a + (0 > a ? b : 0); return this.pushStack(c >= 0 && b > c ? [this[c]] : []) }, end: function () { return this.prevObject || this.constructor(null) }, push: f, sort: c.sort, splice: c.splice }, m.extend = m.fn.extend = function () { var a, b, c, d, e, f, g = arguments[0] || {}, h = 1, i = arguments.length, j = !1; for ("boolean" == typeof g && (j = g, g = arguments[h] || {}, h++), "object" == typeof g || m.isFunction(g) || (g = {}), h === i && (g = this, h--); i > h; h++)if (null != (e = arguments[h])) for (d in e) a = g[d], c = e[d], g !== c && (j && c && (m.isPlainObject(c) || (b = m.isArray(c))) ? (b ? (b = !1, f = a && m.isArray(a) ? a : []) : f = a && m.isPlainObject(a) ? a : {}, g[d] = m.extend(j, f, c)) : void 0 !== c && (g[d] = c)); return g }, m.extend({ expando: "jQuery" + (l + Math.random()).replace(/\D/g, ""), isReady: !0, error: function (a) { throw new Error(a) }, noop: function () { }, isFunction: function (a) { return "function" === m.type(a) }, isArray: Array.isArray || function (a) { return "array" === m.type(a) }, isWindow: function (a) { return null != a && a == a.window }, isNumeric: function (a) { return !m.isArray(a) && a - parseFloat(a) >= 0 }, isEmptyObject: function (a) { var b; for (b in a) return !1; return !0 }, isPlainObject: function (a) { var b; if (!a || "object" !== m.type(a) || a.nodeType || m.isWindow(a)) return !1; try { if (a.constructor && !j.call(a, "constructor") && !j.call(a.constructor.prototype, "isPrototypeOf")) return !1 } catch (c) { return !1 } if (k.ownLast) for (b in a) return j.call(a, b); for (b in a); return void 0 === b || j.call(a, b) }, type: function (a) { return null == a ? a + "" : "object" == typeof a || "function" == typeof a ? h[i.call(a)] || "object" : typeof a }, globalEval: function (b) { b && m.trim(b) && (a.execScript || function (b) { a.eval.call(a, b) })(b) }, camelCase: function (a) { return a.replace(o, "ms-").replace(p, q) }, nodeName: function (a, b) { return a.nodeName && a.nodeName.toLowerCase() === b.toLowerCase() }, each: function (a, b, c) { var d, e = 0, f = a.length, g = r(a); if (c) { if (g) { for (; f > e; e++)if (d = b.apply(a[e], c), d === !1) break } else for (e in a) if (d = b.apply(a[e], c), d === !1) break } else if (g) { for (; f > e; e++)if (d = b.call(a[e], e, a[e]), d === !1) break } else for (e in a) if (d = b.call(a[e], e, a[e]), d === !1) break; return a }, trim: function (a) { return null == a ? "" : (a + "").replace(n, "") }, makeArray: function (a, b) { var c = b || []; return null != a && (r(Object(a)) ? m.merge(c, "string" == typeof a ? [a] : a) : f.call(c, a)), c }, inArray: function (a, b, c) { var d; if (b) { if (g) return g.call(b, a, c); for (d = b.length, c = c ? 0 > c ? Math.max(0, d + c) : c : 0; d > c; c++)if (c in b && b[c] === a) return c } return -1 }, merge: function (a, b) { var c = +b.length, d = 0, e = a.length; while (c > d) a[e++] = b[d++]; if (c !== c) while (void 0 !== b[d]) a[e++] = b[d++]; return a.length = e, a }, grep: function (a, b, c) { for (var d, e = [], f = 0, g = a.length, h = !c; g > f; f++)d = !b(a[f], f), d !== h && e.push(a[f]); return e }, map: function (a, b, c) { var d, f = 0, g = a.length, h = r(a), i = []; if (h) for (; g > f; f++)d = b(a[f], f, c), null != d && i.push(d); else for (f in a) d = b(a[f], f, c), null != d && i.push(d); return e.apply([], i) }, guid: 1, proxy: function (a, b) { var c, e, f; return "string" == typeof b && (f = a[b], b = a, a = f), m.isFunction(a) ? (c = d.call(arguments, 2), e = function () { return a.apply(b || this, c.concat(d.call(arguments))) }, e.guid = a.guid = a.guid || m.guid++ , e) : void 0 }, now: function () { return +new Date }, support: k }), m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function (a, b) { h["[object " + b + "]"] = b.toLowerCase() }); function r(a) { var b = a.length, c = m.type(a); return "function" === c || m.isWindow(a) ? !1 : 1 === a.nodeType && b ? !0 : "array" === c || 0 === b || "number" == typeof b && b > 0 && b - 1 in a } var s = function (a) { var b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u = "sizzle" + -new Date, v = a.document, w = 0, x = 0, y = gb(), z = gb(), A = gb(), B = function (a, b) { return a === b && (l = !0), 0 }, C = "undefined", D = 1 << 31, E = {}.hasOwnProperty, F = [], G = F.pop, H = F.push, I = F.push, J = F.slice, K = F.indexOf || function (a) { for (var b = 0, c = this.length; c > b; b++)if (this[b] === a) return b; return -1 }, L = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", M = "[\\x20\\t\\r\\n\\f]", N = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", O = N.replace("w", "w#"), P = "\\[" + M + "*(" + N + ")(?:" + M + "*([*^$|!~]?=)" + M + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + O + "))|)" + M + "*\\]", Q = ":(" + N + ")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|" + P + ")*)|.*)\\)|)", R = new RegExp("^" + M + "+|((?:^|[^\\\\])(?:\\\\.)*)" + M + "+$", "g"), S = new RegExp("^" + M + "*," + M + "*"), T = new RegExp("^" + M + "*([>+~]|" + M + ")" + M + "*"), U = new RegExp("=" + M + "*([^\\]'\"]*?)" + M + "*\\]", "g"), V = new RegExp(Q), W = new RegExp("^" + O + "$"), X = { ID: new RegExp("^#(" + N + ")"), CLASS: new RegExp("^\\.(" + N + ")"), TAG: new RegExp("^(" + N.replace("w", "w*") + ")"), ATTR: new RegExp("^" + P), PSEUDO: new RegExp("^" + Q), CHILD: new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + M + "*(even|odd|(([+-]|)(\\d*)n|)" + M + "*(?:([+-]|)" + M + "*(\\d+)|))" + M + "*\\)|)", "i"), bool: new RegExp("^(?:" + L + ")$", "i"), needsContext: new RegExp("^" + M + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + M + "*((?:-\\d)?\\d*)" + M + "*\\)|)(?=[^-]|$)", "i") }, Y = /^(?:input|select|textarea|button)$/i, Z = /^h\d$/i, $ = /^[^{]+\{\s*\[native \w/, _ = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, ab = /[+~]/, bb = /'|\\/g, cb = new RegExp("\\\\([\\da-f]{1,6}" + M + "?|(" + M + ")|.)", "ig"), db = function (a, b, c) { var d = "0x" + b - 65536; return d !== d || c ? b : 0 > d ? String.fromCharCode(d + 65536) : String.fromCharCode(d >> 10 | 55296, 1023 & d | 56320) }; try { I.apply(F = J.call(v.childNodes), v.childNodes), F[v.childNodes.length].nodeType } catch (eb) { I = { apply: F.length ? function (a, b) { H.apply(a, J.call(b)) } : function (a, b) { var c = a.length, d = 0; while (a[c++] = b[d++]); a.length = c - 1 } } } function fb(a, b, d, e) { var f, h, j, k, l, o, r, s, w, x; if ((b ? b.ownerDocument || b : v) !== n && m(b), b = b || n, d = d || [], !a || "string" != typeof a) return d; if (1 !== (k = b.nodeType) && 9 !== k) return []; if (p && !e) { if (f = _.exec(a)) if (j = f[1]) { if (9 === k) { if (h = b.getElementById(j), !h || !h.parentNode) return d; if (h.id === j) return d.push(h), d } else if (b.ownerDocument && (h = b.ownerDocument.getElementById(j)) && t(b, h) && h.id === j) return d.push(h), d } else { if (f[2]) return I.apply(d, b.getElementsByTagName(a)), d; if ((j = f[3]) && c.getElementsByClassName && b.getElementsByClassName) return I.apply(d, b.getElementsByClassName(j)), d } if (c.qsa && (!q || !q.test(a))) { if (s = r = u, w = b, x = 9 === k && a, 1 === k && "object" !== b.nodeName.toLowerCase()) { o = g(a), (r = b.getAttribute("id")) ? s = r.replace(bb, "\\$&") : b.setAttribute("id", s), s = "[id='" + s + "'] ", l = o.length; while (l--) o[l] = s + qb(o[l]); w = ab.test(a) && ob(b.parentNode) || b, x = o.join(",") } if (x) try { return I.apply(d, w.querySelectorAll(x)), d } catch (y) { } finally { r || b.removeAttribute("id") } } } return i(a.replace(R, "$1"), b, d, e) } function gb() { var a = []; function b(c, e) { return a.push(c + " ") > d.cacheLength && delete b[a.shift()], b[c + " "] = e } return b } function hb(a) { return a[u] = !0, a } function ib(a) { var b = n.createElement("div"); try { return !!a(b) } catch (c) { return !1 } finally { b.parentNode && b.parentNode.removeChild(b), b = null } } function jb(a, b) { var c = a.split("|"), e = a.length; while (e--) d.attrHandle[c[e]] = b } function kb(a, b) { var c = b && a, d = c && 1 === a.nodeType && 1 === b.nodeType && (~b.sourceIndex || D) - (~a.sourceIndex || D); if (d) return d; if (c) while (c = c.nextSibling) if (c === b) return -1; return a ? 1 : -1 } function lb(a) { return function (b) { var c = b.nodeName.toLowerCase(); return "input" === c && b.type === a } } function mb(a) { return function (b) { var c = b.nodeName.toLowerCase(); return ("input" === c || "button" === c) && b.type === a } } function nb(a) { return hb(function (b) { return b = +b, hb(function (c, d) { var e, f = a([], c.length, b), g = f.length; while (g--) c[e = f[g]] && (c[e] = !(d[e] = c[e])) }) }) } function ob(a) { return a && typeof a.getElementsByTagName !== C && a } c = fb.support = {}, f = fb.isXML = function (a) { var b = a && (a.ownerDocument || a).documentElement; return b ? "HTML" !== b.nodeName : !1 }, m = fb.setDocument = function (a) { var b, e = a ? a.ownerDocument || a : v, g = e.defaultView; return e !== n && 9 === e.nodeType && e.documentElement ? (n = e, o = e.documentElement, p = !f(e), g && g !== g.top && (g.addEventListener ? g.addEventListener("unload", function () { m() }, !1) : g.attachEvent && g.attachEvent("onunload", function () { m() })), c.attributes = ib(function (a) { return a.className = "i", !a.getAttribute("className") }), c.getElementsByTagName = ib(function (a) { return a.appendChild(e.createComment("")), !a.getElementsByTagName("*").length }), c.getElementsByClassName = $.test(e.getElementsByClassName) && ib(function (a) { return a.innerHTML = "
", a.firstChild.className = "i", 2 === a.getElementsByClassName("i").length }), c.getById = ib(function (a) { return o.appendChild(a).id = u, !e.getElementsByName || !e.getElementsByName(u).length }), c.getById ? (d.find.ID = function (a, b) { if (typeof b.getElementById !== C && p) { var c = b.getElementById(a); return c && c.parentNode ? [c] : [] } }, d.filter.ID = function (a) { var b = a.replace(cb, db); return function (a) { return a.getAttribute("id") === b } }) : (delete d.find.ID, d.filter.ID = function (a) { var b = a.replace(cb, db); return function (a) { var c = typeof a.getAttributeNode !== C && a.getAttributeNode("id"); return c && c.value === b } }), d.find.TAG = c.getElementsByTagName ? function (a, b) { return typeof b.getElementsByTagName !== C ? b.getElementsByTagName(a) : void 0 } : function (a, b) { var c, d = [], e = 0, f = b.getElementsByTagName(a); if ("*" === a) { while (c = f[e++]) 1 === c.nodeType && d.push(c); return d } return f }, d.find.CLASS = c.getElementsByClassName && function (a, b) { return typeof b.getElementsByClassName !== C && p ? b.getElementsByClassName(a) : void 0 }, r = [], q = [], (c.qsa = $.test(e.querySelectorAll)) && (ib(function (a) { a.innerHTML = "", a.querySelectorAll("[msallowclip^='']").length && q.push("[*^$]=" + M + "*(?:''|\"\")"), a.querySelectorAll("[selected]").length || q.push("\\[" + M + "*(?:value|" + L + ")"), a.querySelectorAll(":checked").length || q.push(":checked") }), ib(function (a) { var b = e.createElement("input"); b.setAttribute("type", "hidden"), a.appendChild(b).setAttribute("name", "D"), a.querySelectorAll("[name=d]").length && q.push("name" + M + "*[*^$|!~]?="), a.querySelectorAll(":enabled").length || q.push(":enabled", ":disabled"), a.querySelectorAll("*,:x"), q.push(",.*:") })), (c.matchesSelector = $.test(s = o.matches || o.webkitMatchesSelector || o.mozMatchesSelector || o.oMatchesSelector || o.msMatchesSelector)) && ib(function (a) { c.disconnectedMatch = s.call(a, "div"), s.call(a, "[s!='']:x"), r.push("!=", Q) }), q = q.length && new RegExp(q.join("|")), r = r.length && new RegExp(r.join("|")), b = $.test(o.compareDocumentPosition), t = b || $.test(o.contains) ? function (a, b) { var c = 9 === a.nodeType ? a.documentElement : a, d = b && b.parentNode; return a === d || !(!d || 1 !== d.nodeType || !(c.contains ? c.contains(d) : a.compareDocumentPosition && 16 & a.compareDocumentPosition(d))) } : function (a, b) { if (b) while (b = b.parentNode) if (b === a) return !0; return !1 }, B = b ? function (a, b) { if (a === b) return l = !0, 0; var d = !a.compareDocumentPosition - !b.compareDocumentPosition; return d ? d : (d = (a.ownerDocument || a) === (b.ownerDocument || b) ? a.compareDocumentPosition(b) : 1, 1 & d || !c.sortDetached && b.compareDocumentPosition(a) === d ? a === e || a.ownerDocument === v && t(v, a) ? -1 : b === e || b.ownerDocument === v && t(v, b) ? 1 : k ? K.call(k, a) - K.call(k, b) : 0 : 4 & d ? -1 : 1) } : function (a, b) { if (a === b) return l = !0, 0; var c, d = 0, f = a.parentNode, g = b.parentNode, h = [a], i = [b]; if (!f || !g) return a === e ? -1 : b === e ? 1 : f ? -1 : g ? 1 : k ? K.call(k, a) - K.call(k, b) : 0; if (f === g) return kb(a, b); c = a; while (c = c.parentNode) h.unshift(c); c = b; while (c = c.parentNode) i.unshift(c); while (h[d] === i[d]) d++; return d ? kb(h[d], i[d]) : h[d] === v ? -1 : i[d] === v ? 1 : 0 }, e) : n }, fb.matches = function (a, b) { return fb(a, null, null, b) }, fb.matchesSelector = function (a, b) { if ((a.ownerDocument || a) !== n && m(a), b = b.replace(U, "='$1']"), !(!c.matchesSelector || !p || r && r.test(b) || q && q.test(b))) try { var d = s.call(a, b); if (d || c.disconnectedMatch || a.document && 11 !== a.document.nodeType) return d } catch (e) { } return fb(b, n, null, [a]).length > 0 }, fb.contains = function (a, b) { return (a.ownerDocument || a) !== n && m(a), t(a, b) }, fb.attr = function (a, b) { (a.ownerDocument || a) !== n && m(a); var e = d.attrHandle[b.toLowerCase()], f = e && E.call(d.attrHandle, b.toLowerCase()) ? e(a, b, !p) : void 0; return void 0 !== f ? f : c.attributes || !p ? a.getAttribute(b) : (f = a.getAttributeNode(b)) && f.specified ? f.value : null }, fb.error = function (a) { throw new Error("Syntax error, unrecognized expression: " + a) }, fb.uniqueSort = function (a) { var b, d = [], e = 0, f = 0; if (l = !c.detectDuplicates, k = !c.sortStable && a.slice(0), a.sort(B), l) { while (b = a[f++]) b === a[f] && (e = d.push(f)); while (e--) a.splice(d[e], 1) } return k = null, a }, e = fb.getText = function (a) { var b, c = "", d = 0, f = a.nodeType; if (f) { if (1 === f || 9 === f || 11 === f) { if ("string" == typeof a.textContent) return a.textContent; for (a = a.firstChild; a; a = a.nextSibling)c += e(a) } else if (3 === f || 4 === f) return a.nodeValue } else while (b = a[d++]) c += e(b); return c }, d = fb.selectors = { cacheLength: 50, createPseudo: hb, match: X, attrHandle: {}, find: {}, relative: { ">": { dir: "parentNode", first: !0 }, " ": { dir: "parentNode" }, "+": { dir: "previousSibling", first: !0 }, "~": { dir: "previousSibling" } }, preFilter: { ATTR: function (a) { return a[1] = a[1].replace(cb, db), a[3] = (a[3] || a[4] || a[5] || "").replace(cb, db), "~=" === a[2] && (a[3] = " " + a[3] + " "), a.slice(0, 4) }, CHILD: function (a) { return a[1] = a[1].toLowerCase(), "nth" === a[1].slice(0, 3) ? (a[3] || fb.error(a[0]), a[4] = +(a[4] ? a[5] + (a[6] || 1) : 2 * ("even" === a[3] || "odd" === a[3])), a[5] = +(a[7] + a[8] || "odd" === a[3])) : a[3] && fb.error(a[0]), a }, PSEUDO: function (a) { var b, c = !a[6] && a[2]; return X.CHILD.test(a[0]) ? null : (a[3] ? a[2] = a[4] || a[5] || "" : c && V.test(c) && (b = g(c, !0)) && (b = c.indexOf(")", c.length - b) - c.length) && (a[0] = a[0].slice(0, b), a[2] = c.slice(0, b)), a.slice(0, 3)) } }, filter: { TAG: function (a) { var b = a.replace(cb, db).toLowerCase(); return "*" === a ? function () { return !0 } : function (a) { return a.nodeName && a.nodeName.toLowerCase() === b } }, CLASS: function (a) { var b = y[a + " "]; return b || (b = new RegExp("(^|" + M + ")" + a + "(" + M + "|$)")) && y(a, function (a) { return b.test("string" == typeof a.className && a.className || typeof a.getAttribute !== C && a.getAttribute("class") || "") }) }, ATTR: function (a, b, c) { return function (d) { var e = fb.attr(d, a); return null == e ? "!=" === b : b ? (e += "", "=" === b ? e === c : "!=" === b ? e !== c : "^=" === b ? c && 0 === e.indexOf(c) : "*=" === b ? c && e.indexOf(c) > -1 : "$=" === b ? c && e.slice(-c.length) === c : "~=" === b ? (" " + e + " ").indexOf(c) > -1 : "|=" === b ? e === c || e.slice(0, c.length + 1) === c + "-" : !1) : !0 } }, CHILD: function (a, b, c, d, e) { var f = "nth" !== a.slice(0, 3), g = "last" !== a.slice(-4), h = "of-type" === b; return 1 === d && 0 === e ? function (a) { return !!a.parentNode } : function (b, c, i) { var j, k, l, m, n, o, p = f !== g ? "nextSibling" : "previousSibling", q = b.parentNode, r = h && b.nodeName.toLowerCase(), s = !i && !h; if (q) { if (f) { while (p) { l = b; while (l = l[p]) if (h ? l.nodeName.toLowerCase() === r : 1 === l.nodeType) return !1; o = p = "only" === a && !o && "nextSibling" } return !0 } if (o = [g ? q.firstChild : q.lastChild], g && s) { k = q[u] || (q[u] = {}), j = k[a] || [], n = j[0] === w && j[1], m = j[0] === w && j[2], l = n && q.childNodes[n]; while (l = ++n && l && l[p] || (m = n = 0) || o.pop()) if (1 === l.nodeType && ++m && l === b) { k[a] = [w, n, m]; break } } else if (s && (j = (b[u] || (b[u] = {}))[a]) && j[0] === w) m = j[1]; else while (l = ++n && l && l[p] || (m = n = 0) || o.pop()) if ((h ? l.nodeName.toLowerCase() === r : 1 === l.nodeType) && ++m && (s && ((l[u] || (l[u] = {}))[a] = [w, m]), l === b)) break; return m -= e, m === d || m % d === 0 && m / d >= 0 } } }, PSEUDO: function (a, b) { var c, e = d.pseudos[a] || d.setFilters[a.toLowerCase()] || fb.error("unsupported pseudo: " + a); return e[u] ? e(b) : e.length > 1 ? (c = [a, a, "", b], d.setFilters.hasOwnProperty(a.toLowerCase()) ? hb(function (a, c) { var d, f = e(a, b), g = f.length; while (g--) d = K.call(a, f[g]), a[d] = !(c[d] = f[g]) }) : function (a) { return e(a, 0, c) }) : e } }, pseudos: { not: hb(function (a) { var b = [], c = [], d = h(a.replace(R, "$1")); return d[u] ? hb(function (a, b, c, e) { var f, g = d(a, null, e, []), h = a.length; while (h--) (f = g[h]) && (a[h] = !(b[h] = f)) }) : function (a, e, f) { return b[0] = a, d(b, null, f, c), !c.pop() } }), has: hb(function (a) { return function (b) { return fb(a, b).length > 0 } }), contains: hb(function (a) { return function (b) { return (b.textContent || b.innerText || e(b)).indexOf(a) > -1 } }), lang: hb(function (a) { return W.test(a || "") || fb.error("unsupported lang: " + a), a = a.replace(cb, db).toLowerCase(), function (b) { var c; do if (c = p ? b.lang : b.getAttribute("xml:lang") || b.getAttribute("lang")) return c = c.toLowerCase(), c === a || 0 === c.indexOf(a + "-"); while ((b = b.parentNode) && 1 === b.nodeType); return !1 } }), target: function (b) { var c = a.location && a.location.hash; return c && c.slice(1) === b.id }, root: function (a) { return a === o }, focus: function (a) { return a === n.activeElement && (!n.hasFocus || n.hasFocus()) && !!(a.type || a.href || ~a.tabIndex) }, enabled: function (a) { return a.disabled === !1 }, disabled: function (a) { return a.disabled === !0 }, checked: function (a) { var b = a.nodeName.toLowerCase(); return "input" === b && !!a.checked || "option" === b && !!a.selected }, selected: function (a) { return a.parentNode && a.parentNode.selectedIndex, a.selected === !0 }, empty: function (a) { for (a = a.firstChild; a; a = a.nextSibling)if (a.nodeType < 6) return !1; return !0 }, parent: function (a) { return !d.pseudos.empty(a) }, header: function (a) { return Z.test(a.nodeName) }, input: function (a) { return Y.test(a.nodeName) }, button: function (a) { var b = a.nodeName.toLowerCase(); return "input" === b && "button" === a.type || "button" === b }, text: function (a) { var b; return "input" === a.nodeName.toLowerCase() && "text" === a.type && (null == (b = a.getAttribute("type")) || "text" === b.toLowerCase()) }, first: nb(function () { return [0] }), last: nb(function (a, b) { return [b - 1] }), eq: nb(function (a, b, c) { return [0 > c ? c + b : c] }), even: nb(function (a, b) { for (var c = 0; b > c; c += 2)a.push(c); return a }), odd: nb(function (a, b) { for (var c = 1; b > c; c += 2)a.push(c); return a }), lt: nb(function (a, b, c) { for (var d = 0 > c ? c + b : c; --d >= 0;)a.push(d); return a }), gt: nb(function (a, b, c) { for (var d = 0 > c ? c + b : c; ++d < b;)a.push(d); return a }) } }, d.pseudos.nth = d.pseudos.eq; for (b in { radio: !0, checkbox: !0, file: !0, password: !0, image: !0 }) d.pseudos[b] = lb(b); for (b in { submit: !0, reset: !0 }) d.pseudos[b] = mb(b); function pb() { } pb.prototype = d.filters = d.pseudos, d.setFilters = new pb, g = fb.tokenize = function (a, b) { var c, e, f, g, h, i, j, k = z[a + " "]; if (k) return b ? 0 : k.slice(0); h = a, i = [], j = d.preFilter; while (h) { (!c || (e = S.exec(h))) && (e && (h = h.slice(e[0].length) || h), i.push(f = [])), c = !1, (e = T.exec(h)) && (c = e.shift(), f.push({ value: c, type: e[0].replace(R, " ") }), h = h.slice(c.length)); for (g in d.filter) !(e = X[g].exec(h)) || j[g] && !(e = j[g](e)) || (c = e.shift(), f.push({ value: c, type: g, matches: e }), h = h.slice(c.length)); if (!c) break } return b ? h.length : h ? fb.error(a) : z(a, i).slice(0) }; function qb(a) { for (var b = 0, c = a.length, d = ""; c > b; b++)d += a[b].value; return d } function rb(a, b, c) { var d = b.dir, e = c && "parentNode" === d, f = x++; return b.first ? function (b, c, f) { while (b = b[d]) if (1 === b.nodeType || e) return a(b, c, f) } : function (b, c, g) { var h, i, j = [w, f]; if (g) { while (b = b[d]) if ((1 === b.nodeType || e) && a(b, c, g)) return !0 } else while (b = b[d]) if (1 === b.nodeType || e) { if (i = b[u] || (b[u] = {}), (h = i[d]) && h[0] === w && h[1] === f) return j[2] = h[2]; if (i[d] = j, j[2] = a(b, c, g)) return !0 } } } function sb(a) { return a.length > 1 ? function (b, c, d) { var e = a.length; while (e--) if (!a[e](b, c, d)) return !1; return !0 } : a[0] } function tb(a, b, c) { for (var d = 0, e = b.length; e > d; d++)fb(a, b[d], c); return c } function ub(a, b, c, d, e) { for (var f, g = [], h = 0, i = a.length, j = null != b; i > h; h++)(f = a[h]) && (!c || c(f, d, e)) && (g.push(f), j && b.push(h)); return g } function vb(a, b, c, d, e, f) { return d && !d[u] && (d = vb(d)), e && !e[u] && (e = vb(e, f)), hb(function (f, g, h, i) { var j, k, l, m = [], n = [], o = g.length, p = f || tb(b || "*", h.nodeType ? [h] : h, []), q = !a || !f && b ? p : ub(p, m, a, h, i), r = c ? e || (f ? a : o || d) ? [] : g : q; if (c && c(q, r, h, i), d) { j = ub(r, n), d(j, [], h, i), k = j.length; while (k--) (l = j[k]) && (r[n[k]] = !(q[n[k]] = l)) } if (f) { if (e || a) { if (e) { j = [], k = r.length; while (k--) (l = r[k]) && j.push(q[k] = l); e(null, r = [], j, i) } k = r.length; while (k--) (l = r[k]) && (j = e ? K.call(f, l) : m[k]) > -1 && (f[j] = !(g[j] = l)) } } else r = ub(r === g ? r.splice(o, r.length) : r), e ? e(null, g, r, i) : I.apply(g, r) }) } function wb(a) { for (var b, c, e, f = a.length, g = d.relative[a[0].type], h = g || d.relative[" "], i = g ? 1 : 0, k = rb(function (a) { return a === b }, h, !0), l = rb(function (a) { return K.call(b, a) > -1 }, h, !0), m = [function (a, c, d) { return !g && (d || c !== j) || ((b = c).nodeType ? k(a, c, d) : l(a, c, d)) }]; f > i; i++)if (c = d.relative[a[i].type]) m = [rb(sb(m), c)]; else { if (c = d.filter[a[i].type].apply(null, a[i].matches), c[u]) { for (e = ++i; f > e; e++)if (d.relative[a[e].type]) break; return vb(i > 1 && sb(m), i > 1 && qb(a.slice(0, i - 1).concat({ value: " " === a[i - 2].type ? "*" : "" })).replace(R, "$1"), c, e > i && wb(a.slice(i, e)), f > e && wb(a = a.slice(e)), f > e && qb(a)) } m.push(c) } return sb(m) } function xb(a, b) { var c = b.length > 0, e = a.length > 0, f = function (f, g, h, i, k) { var l, m, o, p = 0, q = "0", r = f && [], s = [], t = j, u = f || e && d.find.TAG("*", k), v = w += null == t ? 1 : Math.random() || .1, x = u.length; for (k && (j = g !== n && g); q !== x && null != (l = u[q]); q++) { if (e && l) { m = 0; while (o = a[m++]) if (o(l, g, h)) { i.push(l); break } k && (w = v) } c && ((l = !o && l) && p-- , f && r.push(l)) } if (p += q, c && q !== p) { m = 0; while (o = b[m++]) o(r, s, g, h); if (f) { if (p > 0) while (q--) r[q] || s[q] || (s[q] = G.call(i)); s = ub(s) } I.apply(i, s), k && !f && s.length > 0 && p + b.length > 1 && fb.uniqueSort(i) } return k && (w = v, j = t), r }; return c ? hb(f) : f } return h = fb.compile = function (a, b) { var c, d = [], e = [], f = A[a + " "]; if (!f) { b || (b = g(a)), c = b.length; while (c--) f = wb(b[c]), f[u] ? d.push(f) : e.push(f); f = A(a, xb(e, d)), f.selector = a } return f }, i = fb.select = function (a, b, e, f) { var i, j, k, l, m, n = "function" == typeof a && a, o = !f && g(a = n.selector || a); if (e = e || [], 1 === o.length) { if (j = o[0] = o[0].slice(0), j.length > 2 && "ID" === (k = j[0]).type && c.getById && 9 === b.nodeType && p && d.relative[j[1].type]) { if (b = (d.find.ID(k.matches[0].replace(cb, db), b) || [])[0], !b) return e; n && (b = b.parentNode), a = a.slice(j.shift().value.length) } i = X.needsContext.test(a) ? 0 : j.length; while (i--) { if (k = j[i], d.relative[l = k.type]) break; if ((m = d.find[l]) && (f = m(k.matches[0].replace(cb, db), ab.test(j[0].type) && ob(b.parentNode) || b))) { if (j.splice(i, 1), a = f.length && qb(j), !a) return I.apply(e, f), e; break } } } return (n || h(a, o))(f, b, !p, e, ab.test(a) && ob(b.parentNode) || b), e }, c.sortStable = u.split("").sort(B).join("") === u, c.detectDuplicates = !!l, m(), c.sortDetached = ib(function (a) { return 1 & a.compareDocumentPosition(n.createElement("div")) }), ib(function (a) { return a.innerHTML = "", "#" === a.firstChild.getAttribute("href") }) || jb("type|href|height|width", function (a, b, c) { return c ? void 0 : a.getAttribute(b, "type" === b.toLowerCase() ? 1 : 2) }), c.attributes && ib(function (a) { return a.innerHTML = "", a.firstChild.setAttribute("value", ""), "" === a.firstChild.getAttribute("value") }) || jb("value", function (a, b, c) { return c || "input" !== a.nodeName.toLowerCase() ? void 0 : a.defaultValue }), ib(function (a) { return null == a.getAttribute("disabled") }) || jb(L, function (a, b, c) { var d; return c ? void 0 : a[b] === !0 ? b.toLowerCase() : (d = a.getAttributeNode(b)) && d.specified ? d.value : null }), fb }(a); m.find = s, m.expr = s.selectors, m.expr[":"] = m.expr.pseudos, m.unique = s.uniqueSort, m.text = s.getText, m.isXMLDoc = s.isXML, m.contains = s.contains; var t = m.expr.match.needsContext, u = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, v = /^.[^:#\[\.,]*$/; function w(a, b, c) { if (m.isFunction(b)) return m.grep(a, function (a, d) { return !!b.call(a, d, a) !== c }); if (b.nodeType) return m.grep(a, function (a) { return a === b !== c }); if ("string" == typeof b) { if (v.test(b)) return m.filter(b, a, c); b = m.filter(b, a) } return m.grep(a, function (a) { return m.inArray(a, b) >= 0 !== c }) } m.filter = function (a, b, c) { var d = b[0]; return c && (a = ":not(" + a + ")"), 1 === b.length && 1 === d.nodeType ? m.find.matchesSelector(d, a) ? [d] : [] : m.find.matches(a, m.grep(b, function (a) { return 1 === a.nodeType })) }, m.fn.extend({ find: function (a) { var b, c = [], d = this, e = d.length; if ("string" != typeof a) return this.pushStack(m(a).filter(function () { for (b = 0; e > b; b++)if (m.contains(d[b], this)) return !0 })); for (b = 0; e > b; b++)m.find(a, d[b], c); return c = this.pushStack(e > 1 ? m.unique(c) : c), c.selector = this.selector ? this.selector + " " + a : a, c }, filter: function (a) { return this.pushStack(w(this, a || [], !1)) }, not: function (a) { return this.pushStack(w(this, a || [], !0)) }, is: function (a) { return !!w(this, "string" == typeof a && t.test(a) ? m(a) : a || [], !1).length } }); var x, y = a.document, z = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, A = m.fn.init = function (a, b) { var c, d; if (!a) return this; if ("string" == typeof a) { if (c = "<" === a.charAt(0) && ">" === a.charAt(a.length - 1) && a.length >= 3 ? [null, a, null] : z.exec(a), !c || !c[1] && b) return !b || b.jquery ? (b || x).find(a) : this.constructor(b).find(a); if (c[1]) { if (b = b instanceof m ? b[0] : b, m.merge(this, m.parseHTML(c[1], b && b.nodeType ? b.ownerDocument || b : y, !0)), u.test(c[1]) && m.isPlainObject(b)) for (c in b) m.isFunction(this[c]) ? this[c](b[c]) : this.attr(c, b[c]); return this } if (d = y.getElementById(c[2]), d && d.parentNode) { if (d.id !== c[2]) return x.find(a); this.length = 1, this[0] = d } return this.context = y, this.selector = a, this } return a.nodeType ? (this.context = this[0] = a, this.length = 1, this) : m.isFunction(a) ? "undefined" != typeof x.ready ? x.ready(a) : a(m) : (void 0 !== a.selector && (this.selector = a.selector, this.context = a.context), m.makeArray(a, this)) }; A.prototype = m.fn, x = m(y); var B = /^(?:parents|prev(?:Until|All))/, C = { children: !0, contents: !0, next: !0, prev: !0 }; m.extend({ dir: function (a, b, c) { var d = [], e = a[b]; while (e && 9 !== e.nodeType && (void 0 === c || 1 !== e.nodeType || !m(e).is(c))) 1 === e.nodeType && d.push(e), e = e[b]; return d }, sibling: function (a, b) { for (var c = []; a; a = a.nextSibling)1 === a.nodeType && a !== b && c.push(a); return c } }), m.fn.extend({ has: function (a) { var b, c = m(a, this), d = c.length; return this.filter(function () { for (b = 0; d > b; b++)if (m.contains(this, c[b])) return !0 }) }, closest: function (a, b) { for (var c, d = 0, e = this.length, f = [], g = t.test(a) || "string" != typeof a ? m(a, b || this.context) : 0; e > d; d++)for (c = this[d]; c && c !== b; c = c.parentNode)if (c.nodeType < 11 && (g ? g.index(c) > -1 : 1 === c.nodeType && m.find.matchesSelector(c, a))) { f.push(c); break } return this.pushStack(f.length > 1 ? m.unique(f) : f) }, index: function (a) { return a ? "string" == typeof a ? m.inArray(this[0], m(a)) : m.inArray(a.jquery ? a[0] : a, this) : this[0] && this[0].parentNode ? this.first().prevAll().length : -1 }, add: function (a, b) { return this.pushStack(m.unique(m.merge(this.get(), m(a, b)))) }, addBack: function (a) { return this.add(null == a ? this.prevObject : this.prevObject.filter(a)) } }); function D(a, b) { do a = a[b]; while (a && 1 !== a.nodeType); return a } m.each({ parent: function (a) { var b = a.parentNode; return b && 11 !== b.nodeType ? b : null }, parents: function (a) { return m.dir(a, "parentNode") }, parentsUntil: function (a, b, c) { return m.dir(a, "parentNode", c) }, next: function (a) { return D(a, "nextSibling") }, prev: function (a) { return D(a, "previousSibling") }, nextAll: function (a) { return m.dir(a, "nextSibling") }, prevAll: function (a) { return m.dir(a, "previousSibling") }, nextUntil: function (a, b, c) { return m.dir(a, "nextSibling", c) }, prevUntil: function (a, b, c) { return m.dir(a, "previousSibling", c) }, siblings: function (a) { return m.sibling((a.parentNode || {}).firstChild, a) }, children: function (a) { return m.sibling(a.firstChild) }, contents: function (a) { return m.nodeName(a, "iframe") ? a.contentDocument || a.contentWindow.document : m.merge([], a.childNodes) } }, function (a, b) { m.fn[a] = function (c, d) { var e = m.map(this, b, c); return "Until" !== a.slice(-5) && (d = c), d && "string" == typeof d && (e = m.filter(d, e)), this.length > 1 && (C[a] || (e = m.unique(e)), B.test(a) && (e = e.reverse())), this.pushStack(e) } }); var E = /\S+/g, F = {}; function G(a) { var b = F[a] = {}; return m.each(a.match(E) || [], function (a, c) { b[c] = !0 }), b } m.Callbacks = function (a) { a = "string" == typeof a ? F[a] || G(a) : m.extend({}, a); var b, c, d, e, f, g, h = [], i = !a.once && [], j = function (l) { for (c = a.memory && l, d = !0, f = g || 0, g = 0, e = h.length, b = !0; h && e > f; f++)if (h[f].apply(l[0], l[1]) === !1 && a.stopOnFalse) { c = !1; break } b = !1, h && (i ? i.length && j(i.shift()) : c ? h = [] : k.disable()) }, k = { add: function () { if (h) { var d = h.length; !function f(b) { m.each(b, function (b, c) { var d = m.type(c); "function" === d ? a.unique && k.has(c) || h.push(c) : c && c.length && "string" !== d && f(c) }) }(arguments), b ? e = h.length : c && (g = d, j(c)) } return this }, remove: function () { return h && m.each(arguments, function (a, c) { var d; while ((d = m.inArray(c, h, d)) > -1) h.splice(d, 1), b && (e >= d && e-- , f >= d && f--) }), this }, has: function (a) { return a ? m.inArray(a, h) > -1 : !(!h || !h.length) }, empty: function () { return h = [], e = 0, this }, disable: function () { return h = i = c = void 0, this }, disabled: function () { return !h }, lock: function () { return i = void 0, c || k.disable(), this }, locked: function () { return !i }, fireWith: function (a, c) { return !h || d && !i || (c = c || [], c = [a, c.slice ? c.slice() : c], b ? i.push(c) : j(c)), this }, fire: function () { return k.fireWith(this, arguments), this }, fired: function () { return !!d } }; return k }, m.extend({ Deferred: function (a) { var b = [["resolve", "done", m.Callbacks("once memory"), "resolved"], ["reject", "fail", m.Callbacks("once memory"), "rejected"], ["notify", "progress", m.Callbacks("memory")]], c = "pending", d = { state: function () { return c }, always: function () { return e.done(arguments).fail(arguments), this }, then: function () { var a = arguments; return m.Deferred(function (c) { m.each(b, function (b, f) { var g = m.isFunction(a[b]) && a[b]; e[f[1]](function () { var a = g && g.apply(this, arguments); a && m.isFunction(a.promise) ? a.promise().done(c.resolve).fail(c.reject).progress(c.notify) : c[f[0] + "With"](this === d ? c.promise() : this, g ? [a] : arguments) }) }), a = null }).promise() }, promise: function (a) { return null != a ? m.extend(a, d) : d } }, e = {}; return d.pipe = d.then, m.each(b, function (a, f) { var g = f[2], h = f[3]; d[f[1]] = g.add, h && g.add(function () { c = h }, b[1 ^ a][2].disable, b[2][2].lock), e[f[0]] = function () { return e[f[0] + "With"](this === e ? d : this, arguments), this }, e[f[0] + "With"] = g.fireWith }), d.promise(e), a && a.call(e, e), e }, when: function (a) { var b = 0, c = d.call(arguments), e = c.length, f = 1 !== e || a && m.isFunction(a.promise) ? e : 0, g = 1 === f ? a : m.Deferred(), h = function (a, b, c) { return function (e) { b[a] = this, c[a] = arguments.length > 1 ? d.call(arguments) : e, c === i ? g.notifyWith(b, c) : --f || g.resolveWith(b, c) } }, i, j, k; if (e > 1) for (i = new Array(e), j = new Array(e), k = new Array(e); e > b; b++)c[b] && m.isFunction(c[b].promise) ? c[b].promise().done(h(b, k, c)).fail(g.reject).progress(h(b, j, i)) : --f; return f || g.resolveWith(k, c), g.promise() } }); var H; m.fn.ready = function (a) { return m.ready.promise().done(a), this }, m.extend({ isReady: !1, readyWait: 1, holdReady: function (a) { a ? m.readyWait++ : m.ready(!0) }, ready: function (a) { if (a === !0 ? !--m.readyWait : !m.isReady) { if (!y.body) return setTimeout(m.ready); m.isReady = !0, a !== !0 && --m.readyWait > 0 || (H.resolveWith(y, [m]), m.fn.triggerHandler && (m(y).triggerHandler("ready"), m(y).off("ready"))) } } }); function I() { y.addEventListener ? (y.removeEventListener("DOMContentLoaded", J, !1), a.removeEventListener("load", J, !1)) : (y.detachEvent("onreadystatechange", J), a.detachEvent("onload", J)) } function J() { (y.addEventListener || "load" === event.type || "complete" === y.readyState) && (I(), m.ready()) } m.ready.promise = function (b) { if (!H) if (H = m.Deferred(), "complete" === y.readyState) setTimeout(m.ready); else if (y.addEventListener) y.addEventListener("DOMContentLoaded", J, !1), a.addEventListener("load", J, !1); else { y.attachEvent("onreadystatechange", J), a.attachEvent("onload", J); var c = !1; try { c = null == a.frameElement && y.documentElement } catch (d) { } c && c.doScroll && !function e() { if (!m.isReady) { try { c.doScroll("left") } catch (a) { return setTimeout(e, 50) } I(), m.ready() } }() } return H.promise(b) }; var K = "undefined", L; for (L in m(k)) break; k.ownLast = "0" !== L, k.inlineBlockNeedsLayout = !1, m(function () { var a, b, c, d; c = y.getElementsByTagName("body")[0], c && c.style && (b = y.createElement("div"), d = y.createElement("div"), d.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px", c.appendChild(d).appendChild(b), typeof b.style.zoom !== K && (b.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1", k.inlineBlockNeedsLayout = a = 3 === b.offsetWidth, a && (c.style.zoom = 1)), c.removeChild(d)) }), function () { var a = y.createElement("div"); if (null == k.deleteExpando) { k.deleteExpando = !0; try { delete a.test } catch (b) { k.deleteExpando = !1 } } a = null }(), m.acceptData = function (a) { var b = m.noData[(a.nodeName + " ").toLowerCase()], c = +a.nodeType || 1; return 1 !== c && 9 !== c ? !1 : !b || b !== !0 && a.getAttribute("classid") === b }; var M = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, N = /([A-Z])/g; function O(a, b, c) { if (void 0 === c && 1 === a.nodeType) { var d = "data-" + b.replace(N, "-$1").toLowerCase(); if (c = a.getAttribute(d), "string" == typeof c) { try { c = "true" === c ? !0 : "false" === c ? !1 : "null" === c ? null : +c + "" === c ? +c : M.test(c) ? m.parseJSON(c) : c } catch (e) { } m.data(a, b, c) } else c = void 0 } return c } function P(a) { var b; for (b in a) if (("data" !== b || !m.isEmptyObject(a[b])) && "toJSON" !== b) return !1; return !0 } function Q(a, b, d, e) { - if (m.acceptData(a)) { - var f, g, h = m.expando, i = a.nodeType, j = i ? m.cache : a, k = i ? a[h] : a[h] && h; - if (k && j[k] && (e || j[k].data) || void 0 !== d || "string" != typeof b) return k || (k = i ? a[h] = c.pop() || m.guid++ : h), j[k] || (j[k] = i ? {} : { toJSON: m.noop }), ("object" == typeof b || "function" == typeof b) && (e ? j[k] = m.extend(j[k], b) : j[k].data = m.extend(j[k].data, b)), g = j[k], e || (g.data || (g.data = {}), g = g.data), void 0 !== d && (g[m.camelCase(b)] = d), "string" == typeof b ? (f = g[b], null == f && (f = g[m.camelCase(b)])) : f = g, f - } - } function R(a, b, c) { if (m.acceptData(a)) { var d, e, f = a.nodeType, g = f ? m.cache : a, h = f ? a[m.expando] : m.expando; if (g[h]) { if (b && (d = c ? g[h] : g[h].data)) { m.isArray(b) ? b = b.concat(m.map(b, m.camelCase)) : b in d ? b = [b] : (b = m.camelCase(b), b = b in d ? [b] : b.split(" ")), e = b.length; while (e--) delete d[b[e]]; if (c ? !P(d) : !m.isEmptyObject(d)) return } (c || (delete g[h].data, P(g[h]))) && (f ? m.cleanData([a], !0) : k.deleteExpando || g != g.window ? delete g[h] : g[h] = null) } } } m.extend({ cache: {}, noData: { "applet ": !0, "embed ": !0, "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" }, hasData: function (a) { return a = a.nodeType ? m.cache[a[m.expando]] : a[m.expando], !!a && !P(a) }, data: function (a, b, c) { return Q(a, b, c) }, removeData: function (a, b) { return R(a, b) }, _data: function (a, b, c) { return Q(a, b, c, !0) }, _removeData: function (a, b) { return R(a, b, !0) } }), m.fn.extend({ data: function (a, b) { var c, d, e, f = this[0], g = f && f.attributes; if (void 0 === a) { if (this.length && (e = m.data(f), 1 === f.nodeType && !m._data(f, "parsedAttrs"))) { c = g.length; while (c--) g[c] && (d = g[c].name, 0 === d.indexOf("data-") && (d = m.camelCase(d.slice(5)), O(f, d, e[d]))); m._data(f, "parsedAttrs", !0) } return e } return "object" == typeof a ? this.each(function () { m.data(this, a) }) : arguments.length > 1 ? this.each(function () { m.data(this, a, b) }) : f ? O(f, a, m.data(f, a)) : void 0 }, removeData: function (a) { return this.each(function () { m.removeData(this, a) }) } }), m.extend({ queue: function (a, b, c) { var d; return a ? (b = (b || "fx") + "queue", d = m._data(a, b), c && (!d || m.isArray(c) ? d = m._data(a, b, m.makeArray(c)) : d.push(c)), d || []) : void 0 }, dequeue: function (a, b) { b = b || "fx"; var c = m.queue(a, b), d = c.length, e = c.shift(), f = m._queueHooks(a, b), g = function () { m.dequeue(a, b) }; "inprogress" === e && (e = c.shift(), d--), e && ("fx" === b && c.unshift("inprogress"), delete f.stop, e.call(a, g, f)), !d && f && f.empty.fire() }, _queueHooks: function (a, b) { var c = b + "queueHooks"; return m._data(a, c) || m._data(a, c, { empty: m.Callbacks("once memory").add(function () { m._removeData(a, b + "queue"), m._removeData(a, c) }) }) } }), m.fn.extend({ queue: function (a, b) { var c = 2; return "string" != typeof a && (b = a, a = "fx", c--), arguments.length < c ? m.queue(this[0], a) : void 0 === b ? this : this.each(function () { var c = m.queue(this, a, b); m._queueHooks(this, a), "fx" === a && "inprogress" !== c[0] && m.dequeue(this, a) }) }, dequeue: function (a) { return this.each(function () { m.dequeue(this, a) }) }, clearQueue: function (a) { return this.queue(a || "fx", []) }, promise: function (a, b) { var c, d = 1, e = m.Deferred(), f = this, g = this.length, h = function () { --d || e.resolveWith(f, [f]) }; "string" != typeof a && (b = a, a = void 0), a = a || "fx"; while (g--) c = m._data(f[g], a + "queueHooks"), c && c.empty && (d++ , c.empty.add(h)); return h(), e.promise(b) } }); var S = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source, T = ["Top", "Right", "Bottom", "Left"], U = function (a, b) { return a = b || a, "none" === m.css(a, "display") || !m.contains(a.ownerDocument, a) }, V = m.access = function (a, b, c, d, e, f, g) { var h = 0, i = a.length, j = null == c; if ("object" === m.type(c)) { e = !0; for (h in c) m.access(a, b, h, c[h], !0, f, g) } else if (void 0 !== d && (e = !0, m.isFunction(d) || (g = !0), j && (g ? (b.call(a, d), b = null) : (j = b, b = function (a, b, c) { return j.call(m(a), c) })), b)) for (; i > h; h++)b(a[h], c, g ? d : d.call(a[h], h, b(a[h], c))); return e ? a : j ? b.call(a) : i ? b(a[0], c) : f }, W = /^(?:checkbox|radio)$/i; !function () { var a = y.createElement("input"), b = y.createElement("div"), c = y.createDocumentFragment(); if (b.innerHTML = "
a", k.leadingWhitespace = 3 === b.firstChild.nodeType, k.tbody = !b.getElementsByTagName("tbody").length, k.htmlSerialize = !!b.getElementsByTagName("link").length, k.html5Clone = "<:nav>" !== y.createElement("nav").cloneNode(!0).outerHTML, a.type = "checkbox", a.checked = !0, c.appendChild(a), k.appendChecked = a.checked, b.innerHTML = "", k.noCloneChecked = !!b.cloneNode(!0).lastChild.defaultValue, c.appendChild(b), b.innerHTML = "", k.checkClone = b.cloneNode(!0).cloneNode(!0).lastChild.checked, k.noCloneEvent = !0, b.attachEvent && (b.attachEvent("onclick", function () { k.noCloneEvent = !1 }), b.cloneNode(!0).click()), null == k.deleteExpando) { k.deleteExpando = !0; try { delete b.test } catch (d) { k.deleteExpando = !1 } } }(), function () { var b, c, d = y.createElement("div"); for (b in { submit: !0, change: !0, focusin: !0 }) c = "on" + b, (k[b + "Bubbles"] = c in a) || (d.setAttribute(c, "t"), k[b + "Bubbles"] = d.attributes[c].expando === !1); d = null }(); var X = /^(?:input|select|textarea)$/i, Y = /^key/, Z = /^(?:mouse|pointer|contextmenu)|click/, $ = /^(?:focusinfocus|focusoutblur)$/, _ = /^([^.]*)(?:\.(.+)|)$/; function ab() { return !0 } function bb() { return !1 } function cb() { try { return y.activeElement } catch (a) { } } m.event = { global: {}, add: function (a, b, c, d, e) { var f, g, h, i, j, k, l, n, o, p, q, r = m._data(a); if (r) { c.handler && (i = c, c = i.handler, e = i.selector), c.guid || (c.guid = m.guid++), (g = r.events) || (g = r.events = {}), (k = r.handle) || (k = r.handle = function (a) { return typeof m === K || a && m.event.triggered === a.type ? void 0 : m.event.dispatch.apply(k.elem, arguments) }, k.elem = a), b = (b || "").match(E) || [""], h = b.length; while (h--) f = _.exec(b[h]) || [], o = q = f[1], p = (f[2] || "").split(".").sort(), o && (j = m.event.special[o] || {}, o = (e ? j.delegateType : j.bindType) || o, j = m.event.special[o] || {}, l = m.extend({ type: o, origType: q, data: d, handler: c, guid: c.guid, selector: e, needsContext: e && m.expr.match.needsContext.test(e), namespace: p.join(".") }, i), (n = g[o]) || (n = g[o] = [], n.delegateCount = 0, j.setup && j.setup.call(a, d, p, k) !== !1 || (a.addEventListener ? a.addEventListener(o, k, !1) : a.attachEvent && a.attachEvent("on" + o, k))), j.add && (j.add.call(a, l), l.handler.guid || (l.handler.guid = c.guid)), e ? n.splice(n.delegateCount++, 0, l) : n.push(l), m.event.global[o] = !0); a = null } }, remove: function (a, b, c, d, e) { var f, g, h, i, j, k, l, n, o, p, q, r = m.hasData(a) && m._data(a); if (r && (k = r.events)) { b = (b || "").match(E) || [""], j = b.length; while (j--) if (h = _.exec(b[j]) || [], o = q = h[1], p = (h[2] || "").split(".").sort(), o) { l = m.event.special[o] || {}, o = (d ? l.delegateType : l.bindType) || o, n = k[o] || [], h = h[2] && new RegExp("(^|\\.)" + p.join("\\.(?:.*\\.|)") + "(\\.|$)"), i = f = n.length; while (f--) g = n[f], !e && q !== g.origType || c && c.guid !== g.guid || h && !h.test(g.namespace) || d && d !== g.selector && ("**" !== d || !g.selector) || (n.splice(f, 1), g.selector && n.delegateCount-- , l.remove && l.remove.call(a, g)); i && !n.length && (l.teardown && l.teardown.call(a, p, r.handle) !== !1 || m.removeEvent(a, o, r.handle), delete k[o]) } else for (o in k) m.event.remove(a, o + b[j], c, d, !0); m.isEmptyObject(k) && (delete r.handle, m._removeData(a, "events")) } }, trigger: function (b, c, d, e) { var f, g, h, i, k, l, n, o = [d || y], p = j.call(b, "type") ? b.type : b, q = j.call(b, "namespace") ? b.namespace.split(".") : []; if (h = l = d = d || y, 3 !== d.nodeType && 8 !== d.nodeType && !$.test(p + m.event.triggered) && (p.indexOf(".") >= 0 && (q = p.split("."), p = q.shift(), q.sort()), g = p.indexOf(":") < 0 && "on" + p, b = b[m.expando] ? b : new m.Event(p, "object" == typeof b && b), b.isTrigger = e ? 2 : 3, b.namespace = q.join("."), b.namespace_re = b.namespace ? new RegExp("(^|\\.)" + q.join("\\.(?:.*\\.|)") + "(\\.|$)") : null, b.result = void 0, b.target || (b.target = d), c = null == c ? [b] : m.makeArray(c, [b]), k = m.event.special[p] || {}, e || !k.trigger || k.trigger.apply(d, c) !== !1)) { if (!e && !k.noBubble && !m.isWindow(d)) { for (i = k.delegateType || p, $.test(i + p) || (h = h.parentNode); h; h = h.parentNode)o.push(h), l = h; l === (d.ownerDocument || y) && o.push(l.defaultView || l.parentWindow || a) } n = 0; while ((h = o[n++]) && !b.isPropagationStopped()) b.type = n > 1 ? i : k.bindType || p, f = (m._data(h, "events") || {})[b.type] && m._data(h, "handle"), f && f.apply(h, c), f = g && h[g], f && f.apply && m.acceptData(h) && (b.result = f.apply(h, c), b.result === !1 && b.preventDefault()); if (b.type = p, !e && !b.isDefaultPrevented() && (!k._default || k._default.apply(o.pop(), c) === !1) && m.acceptData(d) && g && d[p] && !m.isWindow(d)) { l = d[g], l && (d[g] = null), m.event.triggered = p; try { d[p]() } catch (r) { } m.event.triggered = void 0, l && (d[g] = l) } return b.result } }, dispatch: function (a) { a = m.event.fix(a); var b, c, e, f, g, h = [], i = d.call(arguments), j = (m._data(this, "events") || {})[a.type] || [], k = m.event.special[a.type] || {}; if (i[0] = a, a.delegateTarget = this, !k.preDispatch || k.preDispatch.call(this, a) !== !1) { h = m.event.handlers.call(this, a, j), b = 0; while ((f = h[b++]) && !a.isPropagationStopped()) { a.currentTarget = f.elem, g = 0; while ((e = f.handlers[g++]) && !a.isImmediatePropagationStopped()) (!a.namespace_re || a.namespace_re.test(e.namespace)) && (a.handleObj = e, a.data = e.data, c = ((m.event.special[e.origType] || {}).handle || e.handler).apply(f.elem, i), void 0 !== c && (a.result = c) === !1 && (a.preventDefault(), a.stopPropagation())) } return k.postDispatch && k.postDispatch.call(this, a), a.result } }, handlers: function (a, b) { var c, d, e, f, g = [], h = b.delegateCount, i = a.target; if (h && i.nodeType && (!a.button || "click" !== a.type)) for (; i != this; i = i.parentNode || this)if (1 === i.nodeType && (i.disabled !== !0 || "click" !== a.type)) { for (e = [], f = 0; h > f; f++)d = b[f], c = d.selector + " ", void 0 === e[c] && (e[c] = d.needsContext ? m(c, this).index(i) >= 0 : m.find(c, this, null, [i]).length), e[c] && e.push(d); e.length && g.push({ elem: i, handlers: e }) } return h < b.length && g.push({ elem: this, handlers: b.slice(h) }), g }, fix: function (a) { if (a[m.expando]) return a; var b, c, d, e = a.type, f = a, g = this.fixHooks[e]; g || (this.fixHooks[e] = g = Z.test(e) ? this.mouseHooks : Y.test(e) ? this.keyHooks : {}), d = g.props ? this.props.concat(g.props) : this.props, a = new m.Event(f), b = d.length; while (b--) c = d[b], a[c] = f[c]; return a.target || (a.target = f.srcElement || y), 3 === a.target.nodeType && (a.target = a.target.parentNode), a.metaKey = !!a.metaKey, g.filter ? g.filter(a, f) : a }, props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), fixHooks: {}, keyHooks: { props: "char charCode key keyCode".split(" "), filter: function (a, b) { return null == a.which && (a.which = null != b.charCode ? b.charCode : b.keyCode), a } }, mouseHooks: { props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), filter: function (a, b) { var c, d, e, f = b.button, g = b.fromElement; return null == a.pageX && null != b.clientX && (d = a.target.ownerDocument || y, e = d.documentElement, c = d.body, a.pageX = b.clientX + (e && e.scrollLeft || c && c.scrollLeft || 0) - (e && e.clientLeft || c && c.clientLeft || 0), a.pageY = b.clientY + (e && e.scrollTop || c && c.scrollTop || 0) - (e && e.clientTop || c && c.clientTop || 0)), !a.relatedTarget && g && (a.relatedTarget = g === a.target ? b.toElement : g), a.which || void 0 === f || (a.which = 1 & f ? 1 : 2 & f ? 3 : 4 & f ? 2 : 0), a } }, special: { load: { noBubble: !0 }, focus: { trigger: function () { if (this !== cb() && this.focus) try { return this.focus(), !1 } catch (a) { } }, delegateType: "focusin" }, blur: { trigger: function () { return this === cb() && this.blur ? (this.blur(), !1) : void 0 }, delegateType: "focusout" }, click: { trigger: function () { return m.nodeName(this, "input") && "checkbox" === this.type && this.click ? (this.click(), !1) : void 0 }, _default: function (a) { return m.nodeName(a.target, "a") } }, beforeunload: { postDispatch: function (a) { void 0 !== a.result && a.originalEvent && (a.originalEvent.returnValue = a.result) } } }, simulate: function (a, b, c, d) { var e = m.extend(new m.Event, c, { type: a, isSimulated: !0, originalEvent: {} }); d ? m.event.trigger(e, null, b) : m.event.dispatch.call(b, e), e.isDefaultPrevented() && c.preventDefault() } }, m.removeEvent = y.removeEventListener ? function (a, b, c) { a.removeEventListener && a.removeEventListener(b, c, !1) } : function (a, b, c) { var d = "on" + b; a.detachEvent && (typeof a[d] === K && (a[d] = null), a.detachEvent(d, c)) }, m.Event = function (a, b) { return this instanceof m.Event ? (a && a.type ? (this.originalEvent = a, this.type = a.type, this.isDefaultPrevented = a.defaultPrevented || void 0 === a.defaultPrevented && a.returnValue === !1 ? ab : bb) : this.type = a, b && m.extend(this, b), this.timeStamp = a && a.timeStamp || m.now(), void (this[m.expando] = !0)) : new m.Event(a, b) }, m.Event.prototype = { isDefaultPrevented: bb, isPropagationStopped: bb, isImmediatePropagationStopped: bb, preventDefault: function () { var a = this.originalEvent; this.isDefaultPrevented = ab, a && (a.preventDefault ? a.preventDefault() : a.returnValue = !1) }, stopPropagation: function () { var a = this.originalEvent; this.isPropagationStopped = ab, a && (a.stopPropagation && a.stopPropagation(), a.cancelBubble = !0) }, stopImmediatePropagation: function () { var a = this.originalEvent; this.isImmediatePropagationStopped = ab, a && a.stopImmediatePropagation && a.stopImmediatePropagation(), this.stopPropagation() } }, m.each({ mouseenter: "mouseover", mouseleave: "mouseout", pointerenter: "pointerover", pointerleave: "pointerout" }, function (a, b) { m.event.special[a] = { delegateType: b, bindType: b, handle: function (a) { var c, d = this, e = a.relatedTarget, f = a.handleObj; return (!e || e !== d && !m.contains(d, e)) && (a.type = f.origType, c = f.handler.apply(this, arguments), a.type = b), c } } }), k.submitBubbles || (m.event.special.submit = { setup: function () { return m.nodeName(this, "form") ? !1 : void m.event.add(this, "click._submit keypress._submit", function (a) { var b = a.target, c = m.nodeName(b, "input") || m.nodeName(b, "button") ? b.form : void 0; c && !m._data(c, "submitBubbles") && (m.event.add(c, "submit._submit", function (a) { a._submit_bubble = !0 }), m._data(c, "submitBubbles", !0)) }) }, postDispatch: function (a) { a._submit_bubble && (delete a._submit_bubble, this.parentNode && !a.isTrigger && m.event.simulate("submit", this.parentNode, a, !0)) }, teardown: function () { return m.nodeName(this, "form") ? !1 : void m.event.remove(this, "._submit") } }), k.changeBubbles || (m.event.special.change = { setup: function () { return X.test(this.nodeName) ? (("checkbox" === this.type || "radio" === this.type) && (m.event.add(this, "propertychange._change", function (a) { "checked" === a.originalEvent.propertyName && (this._just_changed = !0) }), m.event.add(this, "click._change", function (a) { this._just_changed && !a.isTrigger && (this._just_changed = !1), m.event.simulate("change", this, a, !0) })), !1) : void m.event.add(this, "beforeactivate._change", function (a) { var b = a.target; X.test(b.nodeName) && !m._data(b, "changeBubbles") && (m.event.add(b, "change._change", function (a) { !this.parentNode || a.isSimulated || a.isTrigger || m.event.simulate("change", this.parentNode, a, !0) }), m._data(b, "changeBubbles", !0)) }) }, handle: function (a) { var b = a.target; return this !== b || a.isSimulated || a.isTrigger || "radio" !== b.type && "checkbox" !== b.type ? a.handleObj.handler.apply(this, arguments) : void 0 }, teardown: function () { return m.event.remove(this, "._change"), !X.test(this.nodeName) } }), k.focusinBubbles || m.each({ focus: "focusin", blur: "focusout" }, function (a, b) { var c = function (a) { m.event.simulate(b, a.target, m.event.fix(a), !0) }; m.event.special[b] = { setup: function () { var d = this.ownerDocument || this, e = m._data(d, b); e || d.addEventListener(a, c, !0), m._data(d, b, (e || 0) + 1) }, teardown: function () { var d = this.ownerDocument || this, e = m._data(d, b) - 1; e ? m._data(d, b, e) : (d.removeEventListener(a, c, !0), m._removeData(d, b)) } } }), m.fn.extend({ on: function (a, b, c, d, e) { var f, g; if ("object" == typeof a) { "string" != typeof b && (c = c || b, b = void 0); for (f in a) this.on(f, b, c, a[f], e); return this } if (null == c && null == d ? (d = b, c = b = void 0) : null == d && ("string" == typeof b ? (d = c, c = void 0) : (d = c, c = b, b = void 0)), d === !1) d = bb; else if (!d) return this; return 1 === e && (g = d, d = function (a) { return m().off(a), g.apply(this, arguments) }, d.guid = g.guid || (g.guid = m.guid++)), this.each(function () { m.event.add(this, a, d, c, b) }) }, one: function (a, b, c, d) { return this.on(a, b, c, d, 1) }, off: function (a, b, c) { var d, e; if (a && a.preventDefault && a.handleObj) return d = a.handleObj, m(a.delegateTarget).off(d.namespace ? d.origType + "." + d.namespace : d.origType, d.selector, d.handler), this; if ("object" == typeof a) { for (e in a) this.off(e, b, a[e]); return this } return (b === !1 || "function" == typeof b) && (c = b, b = void 0), c === !1 && (c = bb), this.each(function () { m.event.remove(this, a, c, b) }) }, trigger: function (a, b) { return this.each(function () { m.event.trigger(a, b, this) }) }, triggerHandler: function (a, b) { var c = this[0]; return c ? m.event.trigger(a, b, c, !0) : void 0 } }); function db(a) { var b = eb.split("|"), c = a.createDocumentFragment(); if (c.createElement) while (b.length) c.createElement(b.pop()); return c } var eb = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", fb = / jQuery\d+="(?:null|\d+)"/g, gb = new RegExp("<(?:" + eb + ")[\\s/>]", "i"), hb = /^\s+/, ib = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, jb = /<([\w:]+)/, kb = /\s*$/g, rb = { option: [1, ""], legend: [1, "
", "
"], area: [1, "", ""], param: [1, "", ""], thead: [1, "", "
"], tr: [2, "", "
"], col: [2, "", "
"], td: [3, "", "
"], _default: k.htmlSerialize ? [0, "", ""] : [1, "X
", "
"] }, sb = db(y), tb = sb.appendChild(y.createElement("div")); rb.optgroup = rb.option, rb.tbody = rb.tfoot = rb.colgroup = rb.caption = rb.thead, rb.th = rb.td; function ub(a, b) { var c, d, e = 0, f = typeof a.getElementsByTagName !== K ? a.getElementsByTagName(b || "*") : typeof a.querySelectorAll !== K ? a.querySelectorAll(b || "*") : void 0; if (!f) for (f = [], c = a.childNodes || a; null != (d = c[e]); e++)!b || m.nodeName(d, b) ? f.push(d) : m.merge(f, ub(d, b)); return void 0 === b || b && m.nodeName(a, b) ? m.merge([a], f) : f } function vb(a) { W.test(a.type) && (a.defaultChecked = a.checked) } function wb(a, b) { return m.nodeName(a, "table") && m.nodeName(11 !== b.nodeType ? b : b.firstChild, "tr") ? a.getElementsByTagName("tbody")[0] || a.appendChild(a.ownerDocument.createElement("tbody")) : a } function xb(a) { return a.type = (null !== m.find.attr(a, "type")) + "/" + a.type, a } function yb(a) { var b = pb.exec(a.type); return b ? a.type = b[1] : a.removeAttribute("type"), a } function zb(a, b) { for (var c, d = 0; null != (c = a[d]); d++)m._data(c, "globalEval", !b || m._data(b[d], "globalEval")) } function Ab(a, b) { if (1 === b.nodeType && m.hasData(a)) { var c, d, e, f = m._data(a), g = m._data(b, f), h = f.events; if (h) { delete g.handle, g.events = {}; for (c in h) for (d = 0, e = h[c].length; e > d; d++)m.event.add(b, c, h[c][d]) } g.data && (g.data = m.extend({}, g.data)) } } function Bb(a, b) { var c, d, e; if (1 === b.nodeType) { if (c = b.nodeName.toLowerCase(), !k.noCloneEvent && b[m.expando]) { e = m._data(b); for (d in e.events) m.removeEvent(b, d, e.handle); b.removeAttribute(m.expando) } "script" === c && b.text !== a.text ? (xb(b).text = a.text, yb(b)) : "object" === c ? (b.parentNode && (b.outerHTML = a.outerHTML), k.html5Clone && a.innerHTML && !m.trim(b.innerHTML) && (b.innerHTML = a.innerHTML)) : "input" === c && W.test(a.type) ? (b.defaultChecked = b.checked = a.checked, b.value !== a.value && (b.value = a.value)) : "option" === c ? b.defaultSelected = b.selected = a.defaultSelected : ("input" === c || "textarea" === c) && (b.defaultValue = a.defaultValue) } } m.extend({ clone: function (a, b, c) { var d, e, f, g, h, i = m.contains(a.ownerDocument, a); if (k.html5Clone || m.isXMLDoc(a) || !gb.test("<" + a.nodeName + ">") ? f = a.cloneNode(!0) : (tb.innerHTML = a.outerHTML, tb.removeChild(f = tb.firstChild)), !(k.noCloneEvent && k.noCloneChecked || 1 !== a.nodeType && 11 !== a.nodeType || m.isXMLDoc(a))) for (d = ub(f), h = ub(a), g = 0; null != (e = h[g]); ++g)d[g] && Bb(e, d[g]); if (b) if (c) for (h = h || ub(a), d = d || ub(f), g = 0; null != (e = h[g]); g++)Ab(e, d[g]); else Ab(a, f); return d = ub(f, "script"), d.length > 0 && zb(d, !i && ub(a, "script")), d = h = e = null, f }, buildFragment: function (a, b, c, d) { for (var e, f, g, h, i, j, l, n = a.length, o = db(b), p = [], q = 0; n > q; q++)if (f = a[q], f || 0 === f) if ("object" === m.type(f)) m.merge(p, f.nodeType ? [f] : f); else if (lb.test(f)) { h = h || o.appendChild(b.createElement("div")), i = (jb.exec(f) || ["", ""])[1].toLowerCase(), l = rb[i] || rb._default, h.innerHTML = l[1] + f.replace(ib, "<$1>") + l[2], e = l[0]; while (e--) h = h.lastChild; if (!k.leadingWhitespace && hb.test(f) && p.push(b.createTextNode(hb.exec(f)[0])), !k.tbody) { f = "table" !== i || kb.test(f) ? "" !== l[1] || kb.test(f) ? 0 : h : h.firstChild, e = f && f.childNodes.length; while (e--) m.nodeName(j = f.childNodes[e], "tbody") && !j.childNodes.length && f.removeChild(j) } m.merge(p, h.childNodes), h.textContent = ""; while (h.firstChild) h.removeChild(h.firstChild); h = o.lastChild } else p.push(b.createTextNode(f)); h && o.removeChild(h), k.appendChecked || m.grep(ub(p, "input"), vb), q = 0; while (f = p[q++]) if ((!d || -1 === m.inArray(f, d)) && (g = m.contains(f.ownerDocument, f), h = ub(o.appendChild(f), "script"), g && zb(h), c)) { e = 0; while (f = h[e++]) ob.test(f.type || "") && c.push(f) } return h = null, o }, cleanData: function (a, b) { for (var d, e, f, g, h = 0, i = m.expando, j = m.cache, l = k.deleteExpando, n = m.event.special; null != (d = a[h]); h++)if ((b || m.acceptData(d)) && (f = d[i], g = f && j[f])) { if (g.events) for (e in g.events) n[e] ? m.event.remove(d, e) : m.removeEvent(d, e, g.handle); j[f] && (delete j[f], l ? delete d[i] : typeof d.removeAttribute !== K ? d.removeAttribute(i) : d[i] = null, c.push(f)) } } }), m.fn.extend({ text: function (a) { return V(this, function (a) { return void 0 === a ? m.text(this) : this.empty().append((this[0] && this[0].ownerDocument || y).createTextNode(a)) }, null, a, arguments.length) }, append: function () { return this.domManip(arguments, function (a) { if (1 === this.nodeType || 11 === this.nodeType || 9 === this.nodeType) { var b = wb(this, a); b.appendChild(a) } }) }, prepend: function () { return this.domManip(arguments, function (a) { if (1 === this.nodeType || 11 === this.nodeType || 9 === this.nodeType) { var b = wb(this, a); b.insertBefore(a, b.firstChild) } }) }, before: function () { return this.domManip(arguments, function (a) { this.parentNode && this.parentNode.insertBefore(a, this) }) }, after: function () { return this.domManip(arguments, function (a) { this.parentNode && this.parentNode.insertBefore(a, this.nextSibling) }) }, remove: function (a, b) { for (var c, d = a ? m.filter(a, this) : this, e = 0; null != (c = d[e]); e++)b || 1 !== c.nodeType || m.cleanData(ub(c)), c.parentNode && (b && m.contains(c.ownerDocument, c) && zb(ub(c, "script")), c.parentNode.removeChild(c)); return this }, empty: function () { for (var a, b = 0; null != (a = this[b]); b++) { 1 === a.nodeType && m.cleanData(ub(a, !1)); while (a.firstChild) a.removeChild(a.firstChild); a.options && m.nodeName(a, "select") && (a.options.length = 0) } return this }, clone: function (a, b) { return a = null == a ? !1 : a, b = null == b ? a : b, this.map(function () { return m.clone(this, a, b) }) }, html: function (a) { return V(this, function (a) { var b = this[0] || {}, c = 0, d = this.length; if (void 0 === a) return 1 === b.nodeType ? b.innerHTML.replace(fb, "") : void 0; if (!("string" != typeof a || mb.test(a) || !k.htmlSerialize && gb.test(a) || !k.leadingWhitespace && hb.test(a) || rb[(jb.exec(a) || ["", ""])[1].toLowerCase()])) { a = a.replace(ib, "<$1>"); try { for (; d > c; c++)b = this[c] || {}, 1 === b.nodeType && (m.cleanData(ub(b, !1)), b.innerHTML = a); b = 0 } catch (e) { } } b && this.empty().append(a) }, null, a, arguments.length) }, replaceWith: function () { var a = arguments[0]; return this.domManip(arguments, function (b) { a = this.parentNode, m.cleanData(ub(this)), a && a.replaceChild(b, this) }), a && (a.length || a.nodeType) ? this : this.remove() }, detach: function (a) { return this.remove(a, !0) }, domManip: function (a, b) { a = e.apply([], a); var c, d, f, g, h, i, j = 0, l = this.length, n = this, o = l - 1, p = a[0], q = m.isFunction(p); if (q || l > 1 && "string" == typeof p && !k.checkClone && nb.test(p)) return this.each(function (c) { var d = n.eq(c); q && (a[0] = p.call(this, c, d.html())), d.domManip(a, b) }); if (l && (i = m.buildFragment(a, this[0].ownerDocument, !1, this), c = i.firstChild, 1 === i.childNodes.length && (i = c), c)) { for (g = m.map(ub(i, "script"), xb), f = g.length; l > j; j++)d = i, j !== o && (d = m.clone(d, !0, !0), f && m.merge(g, ub(d, "script"))), b.call(this[j], d, j); if (f) for (h = g[g.length - 1].ownerDocument, m.map(g, yb), j = 0; f > j; j++)d = g[j], ob.test(d.type || "") && !m._data(d, "globalEval") && m.contains(h, d) && (d.src ? m._evalUrl && m._evalUrl(d.src) : m.globalEval((d.text || d.textContent || d.innerHTML || "").replace(qb, ""))); i = c = null } return this } }), m.each({ appendTo: "append", prependTo: "prepend", insertBefore: "before", insertAfter: "after", replaceAll: "replaceWith" }, function (a, b) { m.fn[a] = function (a) { for (var c, d = 0, e = [], g = m(a), h = g.length - 1; h >= d; d++)c = d === h ? this : this.clone(!0), m(g[d])[b](c), f.apply(e, c.get()); return this.pushStack(e) } }); var Cb, Db = {}; function Eb(b, c) { var d, e = m(c.createElement(b)).appendTo(c.body), f = a.getDefaultComputedStyle && (d = a.getDefaultComputedStyle(e[0])) ? d.display : m.css(e[0], "display"); return e.detach(), f } function Fb(a) { var b = y, c = Db[a]; return c || (c = Eb(a, b), "none" !== c && c || (Cb = (Cb || m("